Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
d45a46e
fix(mcp): show_scatter_plot writes to the requested file's tab, not t…
SomethingNew71 Oct 23, 2026
968276e
fix(aim): read XRK channel names from the right offset — names lost t…
SomethingNew71 Oct 23, 2026
3999dc6
fix(timeline): look up the cursor record in the active tab's file, no…
SomethingNew71 Oct 23, 2026
f0f6219
fix(tabs): scroll the tab row instead of widening the window past its…
SomethingNew71 Oct 23, 2026
1686d67
fix(haltech): fill "no reading" sentinels before unit scaling — stops…
SomethingNew71 Oct 23, 2026
bf12a2b
fix(ui): center floating tool windows and stop analyzer descriptions …
SomethingNew71 Oct 23, 2026
5a07682
docs(design): add Night Drive design handoff bundle
SomethingNew71 Oct 23, 2026
87833ca
docs(design): Night Drive implementation plan for 3.0.0
SomethingNew71 Oct 23, 2026
aedc844
docs(design): record resolved Night Drive plan decisions
SomethingNew71 Oct 23, 2026
2bb5371
refactor(ui): remove legacy sidebar and channel picker
SomethingNew71 Oct 23, 2026
54784e5
feat(theme): Night Drive tokens and theme runtime
SomethingNew71 Oct 23, 2026
2c73ce7
refactor(theme): status tokens for toasts and menu hints
SomethingNew71 Oct 23, 2026
6e09972
refactor(theme): side panels read theme tokens — tool properties, too…
SomethingNew71 Oct 23, 2026
f8f27b4
refactor(theme): tool windows read theme tokens — analysis, normaliza…
SomethingNew71 Oct 23, 2026
987d54d
feat(settings): Ultra intensity slider and High contrast theme
SomethingNew71 Oct 23, 2026
f89a8ee
feat(fonts): Night Drive type families and scale
SomethingNew71 Oct 23, 2026
bb5bb3a
refactor(fonts): side panels and tool windows use the type scale
SomethingNew71 Oct 23, 2026
c1b7afb
feat(ui): Night Drive buttons, Phosphor icons and the focus ring
SomethingNew71 Oct 23, 2026
991722f
feat(ui): ModeNav and ActivityRail in the Night Drive style
SomethingNew71 Oct 23, 2026
16e214c
feat(ui): FileTabs with ECU source badges and middle-truncated names
SomethingNew71 Oct 23, 2026
b61240a
feat(ui): Night Drive windows, notices, badges and status toasts
SomethingNew71 Oct 23, 2026
38dcf8f
feat(ui): DropZone, segmented control, checkbox and the intensity track
SomethingNew71 Oct 23, 2026
2da8621
feat(ui): FormulaEditor syntax colours and LibraryItem cards
SomethingNew71 Oct 23, 2026
95999db
feat(ui): High contrast outlines, 120 ms motion and sentence-case labels
SomethingNew71 Oct 23, 2026
a3cc9a3
refactor(ui): Phosphor icons replace emoji in the side panels
SomethingNew71 Oct 23, 2026
c027701
docs(design): record the component contract and Phase 4 status
SomethingNew71 Oct 23, 2026
ba1e20c
feat(chart): Night Drive series, plot chrome and legend
SomethingNew71 Oct 24, 2026
b65587a
feat(ui): ChannelCard and ChannelList in the Night Drive style
SomethingNew71 Oct 24, 2026
b8c1a35
feat(ui): heatmaps and tables on the Night Drive colour maps
SomethingNew71 Oct 24, 2026
fb47524
feat(track-map): theme colour maps, casing and cursor dot
SomethingNew71 Oct 24, 2026
5dc361d
feat(ui): PlaybackBar in the Night Drive style
SomethingNew71 Oct 24, 2026
c3b1213
chore(i18n): Phase 5 chart, heatmap and playback strings in 15 locales
SomethingNew71 Oct 24, 2026
d688613
feat(export): ExportSheet layout with embedded fonts for PDF and outl…
SomethingNew71 Oct 24, 2026
0d6808b
feat(export): ExportDialog — every export on the ExportSheet, Paper/G…
SomethingNew71 Oct 24, 2026
5df5134
chore(i18n): ExportDialog strings in 15 locales
SomethingNew71 Oct 24, 2026
2ac5856
docs(export): record the ExportSheet contract
SomethingNew71 Oct 24, 2026
6922a69
feat(brand): Night Drive app icon on every platform
SomethingNew71 Oct 24, 2026
391dd88
feat(ui): About window — lockup on bg_void, version, licence and links
SomethingNew71 Oct 24, 2026
4a0b75c
chore(i18n): About window strings in 15 locales
SomethingNew71 Oct 24, 2026
97916d3
docs(brand): record how the icons and lockups are generated
SomethingNew71 Oct 24, 2026
e6e45ac
ci(theme): colour gate — no hard-coded colours outside src/ui/theme
SomethingNew71 Oct 25, 2026
70b04f8
fix(ui): status labels carry their icon, not colour alone
SomethingNew71 Oct 25, 2026
e07a0da
docs(theme): CLAUDE.md for the finished Night Drive migration
SomethingNew71 Oct 25, 2026
46d6906
docs(readme): Night Drive look, export dialog and new screenshots
SomethingNew71 Oct 25, 2026
ed97a50
chore(release): bump to 3.0.0
SomethingNew71 Oct 25, 2026
8d7d7e8
fix: address 3.0.0 review feedback
SomethingNew71 Oct 25, 2026
ebe6e47
test(ui): slider arrow keys and Esc window order
SomethingNew71 Oct 25, 2026
b63cf04
fix(docs): rustdoc builds with -D warnings — no links to private font…
SomethingNew71 Oct 25, 2026
22db050
Merge branches 'main' and 'release/3.0.0' of https://github.com/Class…
SomethingNew71 Oct 25, 2026
eec6a35
feat(theme): Stealth by default — theme menu in the menu bar
SomethingNew71 Oct 25, 2026
1322087
docs(compare): log compare design and plan — issue #98
SomethingNew71 Oct 25, 2026
86dec6b
feat(compare): log B model — compare state, offset time axis, removal…
SomethingNew71 Oct 25, 2026
c116c28
feat(compare): draw log B on the tab axis — dashed pairs, shared y ra…
SomethingNew71 Oct 25, 2026
3300495
feat(compare): choose log B — Compare row, auto-pairing by name, A | …
SomethingNew71 Oct 25, 2026
1617f67
feat(compare): align log B — offset field, nudges, Align at cursor
SomethingNew71 Oct 25, 2026
b3f8905
feat(compare): export log compare — tab range, shifted log B, shared …
SomethingNew71 Oct 25, 2026
2cbc3fa
docs(compare): log compare strings in 15 languages, contract in CLAUD…
SomethingNew71 Oct 25, 2026
3afdf9c
fix(compare): IPC cursor values read log B's own record — deselect al…
SomethingNew71 Oct 25, 2026
582bfb8
fix(compare): stacked plot list tags A/B rows and counts a pair as one
SomethingNew71 Oct 25, 2026
bb6a2e4
fix(compare): address log compare review feedback
SomethingNew71 Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,33 @@ jobs:
- name: Check formatting
run: cargo fmt --all -- --check

# ============================================
# Design tokens - every guaranteed colour pair, every theme
# ============================================
design-tokens:
name: Design Token Contrast
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout code
uses: actions/checkout@v7

- name: Check contrast
run: python3 -I design/tools/check_contrast.py design/tokens/tokens.json

- name: Colour gate
# Colours come from the theme tokens only. Exceptions: Color32::TRANSPARENT, the export
# back ends converting token colours to PDF/PNG types, and a byte triple in the Link parser.
run: |
hits=$(grep -rnE 'Color32::|Rgba\(|Rgb::new|\[u8; 3\]' src/ \
| grep -v '^src/ui/theme/' \
| grep -v 'Color32::TRANSPARENT' \
| grep -vE '^src/ui/export_sheet/(pdf|png)\.rs:' \
| grep -v '^src/parsers/link.rs:' || true)
if [ -n "$hits" ]; then
echo "Hard-coded colours outside src/ui/theme/:"; echo "$hits"; exit 1
fi

# ============================================
# Lint - Clippy analysis
# ============================================
Expand Down
242 changes: 215 additions & 27 deletions CLAUDE.md

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ultralog"
version = "2.16.2"
version = "3.0.0"
edition = "2024"
# egui/eframe 0.36 is the binding constraint on the minimum supported Rust
# version; edition 2024 itself only needs 1.85.
Expand Down Expand Up @@ -32,6 +32,8 @@ eframe = { version = "0.36.1", default-features = false, features = [
"wayland",
] }
egui_plot = "0.37.0"
# Phosphor icons (regular outline; fill for transport and the favourite star)
egui-phosphor = { version = "0.14", features = ["fill"] }
egui_extras = { version = "0.36.1", features = ["image"] }

# Serialization
Expand Down Expand Up @@ -68,6 +70,10 @@ image = { version = "0.25", default-features = false, features = ["png", "jpeg"]

# PDF generation for chart export
printpdf = "0.12"
# Export rasterizing: glyph outlines (skrifa) filled as paths by vello_cpu for PNG text.
# Same versions epaint already builds; vello_cpu without its glyph-atlas "text" feature.
skrifa = "0.44"
vello_cpu = { version = "0.1", default-features = false, features = ["std", "u8_pipeline"] }

# Error handling
thiserror = "2.0.20"
Expand Down
101 changes: 73 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A high-performance, cross-platform ECU log viewer written in Rust.

![CI](https://github.com/ClassicMiniDIY/UltraLog/actions/workflows/ci.yml/badge.svg)
![License](https://img.shields.io/badge/license-AGPL--3.0-blue.svg)
![Version](https://img.shields.io/badge/version-2.16.2-green.svg)
![Version](https://img.shields.io/badge/version-3.0.0-green.svg)

---

Expand All @@ -20,11 +20,26 @@ UltraLog is an **independent, open-source** desktop application designed for aut
- **Fast** - Handles massive log files without lag using LTTB downsampling
- **Universal** - Supports multiple ECU formats in one unified interface for cross-platform data analysis
- **Cross-platform** - Runs natively on Windows, macOS, and Linux
- **Accessible** - Colorblind-friendly palette and clear visualization
- **Accessible** - Color blind mode, High contrast, keyboard focus and status icons on every message
- **Open** - AGPL-3.0 licensed with documented format specifications for community benefit

---

## Screenshots

![Log Viewer in Night Drive](docs/screenshots/chart-night.png)
*Log Viewer in Night Drive: a Haltech pull with RPM, MAP, TPS and ignition timing.*

| Ultra | Color blind mode |
| --- | --- |
| ![The same chart at Ultra intensity](docs/screenshots/chart-ultra.png) | ![The same chart in Color blind mode](docs/screenshots/chart-cvd.png) |

| Lambda Delay table | Export dialog |
| --- | --- |
| ![Lambda Delay table with confidence badges](docs/screenshots/lambda-delay.png) | ![Export dialog with Paper and Graphite sheets](docs/screenshots/export-dialog.png) |

---

## Features

### Data Visualization
Expand All @@ -46,6 +61,7 @@ UltraLog is an **independent, open-source** desktop application designed for aut
- **Drag and drop** - Simply drop files onto the window to load them
- **Per-tab state** - Each tab maintains its own channel selections and view settings
- **Duplicate detection** - Prevents loading the same file twice
- **Log compare** - Overlay a second log in the same tab: channels pair by name, log B is dashed in the same colour on a shared scale, with a time offset and **Align at cursor** to line up two pulls

### Unit Conversion
Configurable units for 8 measurement categories:
Expand All @@ -60,8 +76,11 @@ Configurable units for 8 measurement categories:
- **AFR/Lambda** - Air-Fuel Ratio, Lambda

### Export Options
- **PNG Export** - Save chart views as PNG images
- **PDF Export** - Generate PDF reports of your visualizations
- **Export dialog** - PDF or PNG on a light **Paper** or dark **Graphite** sheet, remembered per format (`Ctrl/Cmd + E`)
- **One sheet for every tool** - lockup, title, time range and record counts, the chart or table, its legend or colour scale, and a footer with version and date
- **PDF with real text** - A4 landscape, fonts embedded, so `−`, `λ`, `°` and non-Latin channel names print and stay selectable; PNG is 1920×1080
- **Copy image** - the chart or table alone, ready to paste into a document
- **Always colour-blind safe** - exports use the colour-blind safe palette whatever your app settings are

### Computed Channels
- **Formula-based virtual channels** - Create custom channels from mathematical expressions
Expand All @@ -77,7 +96,7 @@ Configurable units for 8 measurement categories:

### Additional Tools
- **Scatter Plot** - XY scatter visualization for channel correlation analysis
- **Histogram** - 2D heatmap visualization with configurable grid sizes (10x10 to 25x25) for analyzing channel distributions
- **Histogram** - 2D heatmap visualization with configurable grid sizes for analyzing channel distributions, coloured with the theme's colour-blind safe maps
- **MCP Server** - Built-in Model Context Protocol server lets Claude Desktop (or any MCP client) control UltraLog — load files, select channels, get stats, create computed channels, and run analysis via `http://localhost:52453/mcp`
- **Table Generators** - Mine logged events into tuning tables. Each is a tool tab beside Histogram (⌘4 / ⌘5), with setup in the Tool Properties panel and CSV, clipboard, PNG and PDF export:
- **Lambda Delay Table** - time from injector pulse-width steps to the wideband response, binned by RPM × load, for closed-loop O2 delay tables (ms, engine cycles or ignition events)
Expand All @@ -91,10 +110,16 @@ Configurable units for 8 measurement categories:
- **Normalization Editor** - Create custom field name mappings for cross-ECU comparison
- **Field Normalization** - Maps ECU-specific channel names to standard names (e.g., "Act_AFR" → "AFR")

### Night Drive Look
- **Ultra intensity** - one slider from **Stealth** (quiet greys, the default) through **Night Drive** and **Neon** to **Ultra** (glow, gradients and a grid floor under the chart), in the menu bar and in Settings. It never changes data colours or text contrast
- **Built for data** - one cyan accent, a sunset redline, mono numbers, and heatmaps on perceptual colour maps (no rainbow)

### Accessibility
- **Colorblind mode** - Wong's optimized color palette designed for deuteranopia, protanopia, and tritanopia
- **Color blind mode** - Okabe-Ito series colours, cividis and blue/orange heatmap maps, dashed and labelled lines, a white cursor and stronger text contrast
- **High contrast** - black grounds, white text and outlined controls, with the neon effects off
- **Keyboard focus** - a visible focus ring after Tab or arrow navigation; every status message shows an icon and words, never colour alone
- **Font scaling** - Four font sizes (S, M, L, XL) for improved readability
- **Custom font** - Clear, readable Outfit typeface
- **Fonts** - Outfit for the interface, Saira for titles, JetBrains Mono for numbers, Noto for Devanagari, Bengali and Arabic
- **Toast notifications** - Non-intrusive feedback for user actions
- **Multilingual support** - 15 languages including English, Spanish, German, French, Italian, Portuguese, Chinese, Japanese, Hindi, Arabic, Bengali, Russian, Urdu, and Indonesian

Expand Down Expand Up @@ -316,7 +341,7 @@ cargo build --release
5. **Customize your view** -
- Change units via the **Units** menu
- Enable **Cursor Tracking** to keep the cursor centered
- Enable **Colorblind Mode** for accessible colors
- Set the look in **Settings → Display**: Ultra intensity, **Color blind mode**, **High contrast**

---

Expand Down Expand Up @@ -372,6 +397,18 @@ UltraLog automatically detects the ECU format based on file contents:
- Click and drag to pan the view
- Double-click to reset zoom

### Comparing Two Logs

Overlay a second log on the current tab, for example the same pull before and after a tune change:

1. Load both logs and open the tab of the first one (log **A**)
2. In the Channels panel, choose the second log under **Compare** (or **File → Compare with…**). **Open file…** loads a log that is not open yet
3. Pick channels as usual. Each channel brings its match from log **B** along, paired by name (with field normalization on, `Engine Speed` pairs with `RPM`). Log B is drawn dashed in the same colour, and a pair shares one scale so the higher peak looks higher
4. Use the **Log A | Log B** switch to add a channel that only log B has. A card marked "not in B" has no match
5. Line the logs up with **Log B offset** (drag, type, or −1 / −0.1 / +0.1 / +1 s), or with **Align at cursor**: put the cursor on an event in log A, click **Align at cursor**, then click the same event in log B. Esc cancels

The legend, the direct labels and the channel cards tag every series **A** or **B**. Legend values come from each log at the cursor and stay blank where a log has no data. Exports draw log B dashed, tag the legend and name both files and the offset.

### Timeline and Playback

**Timeline controls (bottom of window):**
Expand Down Expand Up @@ -480,17 +517,18 @@ Boost rate of change (kPa/second)
- Edit or delete templates from the Computed Channels window
- Templates can be reused across different log files

### Exporting Charts
### Exporting

**PNG Export:**
1. File menu → Export → PNG
2. Choose save location
3. Current chart view is saved as a PNG image
1. Open the **Export** dialog: File → Export..., the **Export...** button in the Tools panel, or `Ctrl/Cmd + E`
2. Choose **PDF** or **PNG**
3. Choose the sheet: **Paper** (light, prints cleanly) or **Graphite** (dark grey). UltraLog remembers the theme for each format
4. Click **Export PDF** / **Export PNG** and choose where to save, or **Copy image** to put the chart or table on the clipboard

**PDF Export:**
1. File menu → Export → PDF
2. Choose save location
3. Chart is exported as a PDF document
What each tool exports:
- **Log Viewer** - the visible time range of the chart, every selected channel with its unit in the legend
- **Scatter Plots** - both density plots side by side
- **Histogram** - the grid as the tool shows it (custom ranges, sample filters and minimum hits applied)
- **Lambda Delay / Accel Enrichment** - the table with values, count badges and edge labels

### Scatter Plot Tool

Expand Down Expand Up @@ -522,7 +560,7 @@ The histogram tool creates 2D heatmap visualizations for analyzing channel distr
7. Toggle between "Hit Count" and "Average Z-Value" modes

**Features:**
- Heat gradient from blue (low) to red (high)
- Cells on the theme's sequential colour map (cividis in Color blind mode); empty cells are hatched
- Cell statistics on hover/click
- Cursor position tracking during playback
- Analyze data distributions and correlations
Expand All @@ -547,16 +585,20 @@ The Analysis Tools panel provides built-in signal processing and statistical ana

### Accessibility Features

**Colorblind Mode:**
- Enable via Settings panel → Display → Colorblind Mode
- Uses Wong's optimized 8-color palette
- Designed to be distinguishable for deuteranopia, protanopia, and tritanopia
**Color blind mode:**
- Enable via Settings panel → Display → **Color blind mode**
- Series use the 8 Okabe-Ito colours; heatmaps use cividis and a blue/orange diverging map
- Lines past the palette repeat dashed, then dotted, and the chart labels each line at its end
- The cursor turns white so it never matches a series

**Standard color palette:**
Blue, Orange, Green, Red, Purple, Brown, Pink, Gray, Yellow, Cyan
**High contrast:**
- Enable via Settings panel → Display → **High contrast**
- Black grounds, white text, outlined controls; turns off glow, gradients and the grid floor

**Colorblind palette:**
Black, Orange, Sky Blue, Bluish Green, Yellow, Blue, Vermillion, Reddish Purple
**Ultra intensity:**
- The theme menu at the end of the menu bar (it shows the current level), or Settings panel → Display → **Ultra intensity**
- 0-100 with stops at Stealth (default), Night Drive, Neon and Ultra
- Changes only the chrome; data colours and text contrast stay the same

**Font Scaling:**
- Access via Settings panel → Display → Font Size
Expand All @@ -578,7 +620,7 @@ Black, Orange, Sky Blue, Bluish Green, Yellow, Blue, Vermillion, Reddish Purple
| ---------- | -------------- |
| Open file | `Ctrl/Cmd + O` |
| Close tab | `Ctrl/Cmd + W` |
| Export PNG | `Ctrl/Cmd + E` |
| Export | `Ctrl/Cmd + E` |
| Play/Pause | `Space` |
| Stop | `Escape` |

Expand All @@ -594,6 +636,8 @@ Black, Orange, Sky Blue, Bluish Green, Yellow, Blue, Vermillion, Reddish Purple
| File Dialogs | [rfd](https://github.com/PolyMeilex/rfd) 0.17 |
| Image Processing | [image](https://github.com/image-rs/image) 0.25 |
| PDF Generation | [printpdf](https://github.com/fschutt/printpdf) 0.12 |
| Export rendering | [vello_cpu](https://github.com/linebender/vello) 0.1 / [skrifa](https://github.com/googlefonts/fontations) 0.44 |
| Icons | [Phosphor](https://phosphoricons.com) via egui-phosphor 0.14 |
| Serialization | serde / serde_json 1.0 |
| Error Handling | thiserror 2.0 / anyhow 1.0 |
| Logging | tracing / tracing-subscriber 0.3 |
Expand Down Expand Up @@ -801,5 +845,6 @@ Contributions are welcome! Please feel free to submit a Pull Request.
## Acknowledgments

- [egui](https://github.com/emilk/egui) - The immediate mode GUI library that makes this possible
- Wong's colorblind-safe palette for accessibility research
- Masataka Okabe and Kei Ito's colour-blind safe palette, and the cividis colour map (Nuñez, Anderton and Renslow)
- [Phosphor Icons](https://phosphoricons.com), [Outfit](https://fonts.google.com/specimen/Outfit), [Saira](https://fonts.google.com/specimen/Saira), [JetBrains Mono](https://www.jetbrains.com/lp/mono/) and Noto
- The automotive tuning community for feedback and feature requests
Binary file removed assets/Outfit-Bold.ttf
Binary file not shown.
Binary file removed assets/Outfit-Regular.ttf
Binary file not shown.
Binary file added assets/brand/ultralog-lockup-paper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/brand/ultralog-lockup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/fonts/JetBrainsMono-Medium.ttf
Binary file not shown.
Loading
Loading