Feature: Real-Time Row Swatch Grid & Delta E00 Quality Indicator #6

Closed
opened 2026-08-21 10:29:33 +01:00 by gronod · 0 comments
Owner

Description

Implement the real-time swatch grid visualization and CIEDE2000 (ΔE₀₀) quality scoring that renders during Stage 3 measurement. Each strip read by chartread -u emits a ROW_COLORS_JSON payload; this issue handles parsing, rendering, and colour math.

Toolchain Context

  • Frontend: Vanilla JS + CSS Grid in Tauri webview
  • Data source: process:json_row Tauri events emitted by the Rust backend (see Issue #5)
  • Math: CIEDE2000 implemented in pure JavaScript (no external dependencies)

Implementation Plan

CIEDE2000 Module (src/js/delta_e.js)

  1. Implement the full CIEDE2000 formula per CIE Technical Report 142-2001:
    • Input: two Lab* triplets [L1, a1, b1], [L2, a2, b2]
    • Output: scalar ΔE₀₀ value
    • Parametric factors: kL=1, kC=1, kH=1 (standard viewing conditions)
  2. Export a computeDeltaE00(lab1, lab2) function.
  3. Include unit tests against published CIE test data (Sharma et al. 2005 test pairs).

Swatch Grid Renderer (src/js/swatch_grid.js)

  1. Listen for process:json_row events.
  2. Parse JSON payload: extract row_id, row_index, total_rows, and patches[] array.
  3. For each patch:
    • Convert device_rgb (or device_cmyk) to CSS colour for the "sent" swatch
    • Convert expected.Lab to approximate sRGB for the "expected" swatch
    • Convert measured.Lab to approximate sRGB for the "measured" swatch
    • Compute deltaE = computeDeltaE00(expected.Lab, measured.Lab)
  4. Render a CSS Grid of patch cells, each showing:
    • Swatch colour tile (measured colour)
    • ΔE₀₀ numeric label
    • Traffic light border: Green (ΔE < 2), Amber (ΔE < 5), Red (ΔE ≥ 5)
  5. Skip spacer patches where is_pad: true.
  6. Progress bar: Show row_index / total_rows as a percentage.

Lab-to-sRGB Conversion (src/js/color_convert.js)

  1. Implement Lab → XYZ → linear sRGB → gamma-corrected sRGB pipeline.
  2. Use D50 illuminant (standard for ICC profiles).
  3. Clamp out-of-gamut values to [0, 255].

New/Modified Files

  • [NEW] src/js/delta_e.js — CIEDE2000 implementation
  • [NEW] src/js/swatch_grid.js — grid renderer and event listener
  • [NEW] src/js/color_convert.js — Lab ↔ sRGB conversion utilities
  • [MODIFY] src/index.html — swatch grid container in Stage 3 panel
  • [MODIFY] src/styles/main.css — grid layout, traffic light colours, progress bar

Acceptance Criteria

  • CIEDE2000 formula produces correct ΔE₀₀ values against Sharma 2005 test data
  • Lab-to-sRGB conversion renders visually plausible patch colours
  • Swatch grid dynamically populates as ROW_COLORS_JSON events arrive
  • Each patch displays measured colour, ΔE value, and traffic light indicator
  • Spacer/padding patches are excluded from the grid
  • Row progress bar updates in real-time
  • Grid is scrollable for large patch sets (1500+ patches)

References

### Description Implement the real-time swatch grid visualization and CIEDE2000 (ΔE₀₀) quality scoring that renders during Stage 3 measurement. Each strip read by `chartread -u` emits a `ROW_COLORS_JSON` payload; this issue handles parsing, rendering, and colour math. ### Toolchain Context - **Frontend**: Vanilla JS + CSS Grid in Tauri webview - **Data source**: `process:json_row` Tauri events emitted by the Rust backend (see Issue #5) - **Math**: CIEDE2000 implemented in pure JavaScript (no external dependencies) ### Implementation Plan #### CIEDE2000 Module (`src/js/delta_e.js`) 1. Implement the full CIEDE2000 formula per CIE Technical Report 142-2001: - Input: two L*a*b* triplets `[L1, a1, b1]`, `[L2, a2, b2]` - Output: scalar ΔE₀₀ value - Parametric factors: kL=1, kC=1, kH=1 (standard viewing conditions) 2. Export a `computeDeltaE00(lab1, lab2)` function. 3. Include unit tests against published CIE test data (Sharma et al. 2005 test pairs). #### Swatch Grid Renderer (`src/js/swatch_grid.js`) 1. **Listen** for `process:json_row` events. 2. **Parse** JSON payload: extract `row_id`, `row_index`, `total_rows`, and `patches[]` array. 3. **For each patch**: - Convert `device_rgb` (or `device_cmyk`) to CSS colour for the "sent" swatch - Convert `expected.Lab` to approximate sRGB for the "expected" swatch - Convert `measured.Lab` to approximate sRGB for the "measured" swatch - Compute `deltaE = computeDeltaE00(expected.Lab, measured.Lab)` 4. **Render** a CSS Grid of patch cells, each showing: - Swatch colour tile (measured colour) - ΔE₀₀ numeric label - Traffic light border: Green (ΔE < 2), Amber (ΔE < 5), Red (ΔE ≥ 5) 5. **Skip** spacer patches where `is_pad: true`. 6. **Progress bar**: Show `row_index / total_rows` as a percentage. #### Lab-to-sRGB Conversion (`src/js/color_convert.js`) 1. Implement Lab → XYZ → linear sRGB → gamma-corrected sRGB pipeline. 2. Use D50 illuminant (standard for ICC profiles). 3. Clamp out-of-gamut values to [0, 255]. #### New/Modified Files - `[NEW]` `src/js/delta_e.js` — CIEDE2000 implementation - `[NEW]` `src/js/swatch_grid.js` — grid renderer and event listener - `[NEW]` `src/js/color_convert.js` — Lab ↔ sRGB conversion utilities - `[MODIFY]` `src/index.html` — swatch grid container in Stage 3 panel - `[MODIFY]` `src/styles/main.css` — grid layout, traffic light colours, progress bar ### Acceptance Criteria - [ ] CIEDE2000 formula produces correct ΔE₀₀ values against Sharma 2005 test data - [ ] Lab-to-sRGB conversion renders visually plausible patch colours - [ ] Swatch grid dynamically populates as ROW_COLORS_JSON events arrive - [ ] Each patch displays measured colour, ΔE value, and traffic light indicator - [ ] Spacer/padding patches are excluded from the grid - [ ] Row progress bar updates in real-time - [ ] Grid is scrollable for large patch sets (1500+ patches) ### References - [chartread_integration_guide.md §4 — JSON Payload Schema](https://git.i3omb.com/gronod/argyllcms/src/branch/feature/chartread-json-output/doc/chartread_integration_guide.md#4-json-payload-schema) - [README.md — Visualising Delta E](README.md#visualising-delta-e)
gronod added this to the Milestone 3: Interactive Reading Engine milestone 2026-08-21 10:29:33 +01:00
Sign in to join this conversation.