Skip to content

feat(highcharts): implement mosaic-categorical - #11052

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/mosaic-categorical/highcharts
Sep 2, 2026
Merged

feat(highcharts): implement mosaic-categorical#11052
MarkusNeusinger merged 6 commits into
mainfrom
implementation/mosaic-categorical/highcharts

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Implementation: mosaic-categorical - javascript/highcharts

Implements the javascript/highcharts version of mosaic-categorical.

File: plots/mosaic-categorical/implementations/javascript/highcharts.js

Parent Issue: #3650


🤖 impl-generate workflow

@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1-consistent). Bold dark title reads "mosaic-categorical · javascript · highcharts · anyplot.ai." Four mosaic columns (Engineering, Sales, Marketing, Support), each split into three stacked cells (Exceeds/Meets/Below). Column widths track department headcount, cell heights track each rating's conditional share within the department. First series (Exceeds) is brand green #009E73, Meets is violet, Below is blue — canonical Imprint order. Percentage y-axis (0–100%), rotated axis title, department labels, a bottom caption explaining the width encoding, and a right-side legend for the rating categories. All text — title, ticks, axis titles, department labels, legend, in-cell counts — is clearly readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17-consistent). Same layout and identical data colors (green/violet/blue) as the light render — only the chrome flipped: title, axis ticks, axis titles, department labels, bottom caption, and legend all render in light/cream text. No dark-on-dark failures anywhere; every element that was dark-on-light in the light render is now light-on-dark and fully legible.

Both renders confirmed readable; data colors are pixel-identical across themes.

Score: 88/100

Category Score Max
Visual Quality 29 30
Design Excellence 15 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 9 10
Library Mastery 6 10
Total 88 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) - All sizes explicit, readable both themes; smallest in-cell counts could shrink further at mobile widths
  • VQ-02: No Overlap (6/6) - No collisions
  • VQ-03: Element Visibility (6/6) - Rectangles well-sized, all counts visible
  • VQ-04: Color Accessibility (2/2) - CVD-safe, auto-contrasted labels
  • VQ-05: Layout & Canvas (4/4) - Plot uses ~67% of canvas, legend adjacent not isolated
  • VQ-06: Axis Labels & Title (2/2) - Descriptive axis title + % ticks, bottom caption explains encoding
  • VQ-07: Palette Compliance (2/2) - Canonical Imprint order, identical across themes, theme-correct chrome

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) - Fully custom-built (no library default exists for mosaic), rounded corners, auto-contrast labeling — clearly above a configured default
  • DE-02: Visual Refinement (5/6) - Axes hidden in favor of minimal hand-drawn gridlines, generous whitespace, polished cell gaps
  • DE-03: Data Storytelling (4/6) - Width/height encoding creates hierarchy, but no explicit callout of the key insight (e.g. Sales' higher "Below" share)

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct mosaic: area proportional to cell frequency
  • SC-02: Required Features (4/4) - Marginal widths, conditional heights, gap spacing, dual-variable labeling all present
  • SC-03: Data Mapping (3/3) - Department on x, rating as stacked segments, all data visible
  • SC-04: Title & Legend (3/3) - Title format exact match, legend labels correct

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - Meaningful variation in both department size and rating splits
  • DQ-02: Realistic Context (5/5) - Neutral, real business scenario
  • DQ-03: Appropriate Scale (4/4) - Plausible headcounts and rating distributions

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) - Mostly linear, one small helper function (textColorFor)
  • CQ-02: Reproducibility (2/2) - Deterministic hardcoded data
  • CQ-03: Clean Imports (2/2) - No unused imports
  • CQ-04: Code Elegance (2/2) - Appropriate complexity, no fake UI
  • CQ-05: Output & API (1/1) - No explicit width/height, animation disabled, credits disabled

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (3/5) - series is empty; whole chart bypasses Highcharts' series/axis system via raw chart.renderer drawing
  • LM-02: Distinctive Features (3/5) - Uses Highcharts' renderer API tied to the chart's coordinate system, a genuine library-specific escape hatch, but shapes drawn are generic rects/text

Score Caps Applied

  • None

Strengths

  • Correct mosaic semantics: widths proportional to department marginal share, heights proportional to conditional rating share, area faithfully proportional to cell frequency.
  • Fully theme-correct chrome with pixel-identical Imprint palette (green/violet/blue, canonical order) between light and dark.
  • Polished custom SVG drawing: rounded corners, auto-contrasted in-cell counts, subtle gridlines, clear encoding captions.
  • Balanced canvas utilization (~67% plot area), legend adjacent to the chart rather than isolated.
  • Realistic, neutral dataset with meaningful variation across departments and ratings.

Weaknesses

  • series is left empty and the entire chart is hand-drawn via chart.renderer inside events.load, bypassing Highcharts' series/axis system entirely — a defensible workaround given no native mosaic series, but it forgoes Highcharts' higher-level idioms (dataLabels, plotOptions, a real xAxis/yAxis with a custom tickPositioner).
  • Data storytelling relies only on the passive width/height encoding — no explicit callout or annotation highlighting the most notable pattern (e.g. Sales' comparatively higher "Below" share vs. Engineering).
  • Minor layout risk: the bottom caption sits only ~14 CSS px above the canvas bottom edge, and the legend header nearly touches the right canvas edge. Neither is clipped currently, but the margin is thin.
  • The textColorFor() helper function breaks strict KISS structure; small and justified, but could be inlined or replaced with a precomputed lookup.

Issues Found

  1. LM-01 MEDIUM: Chart bypasses Highcharts' series/axis API entirely (series: [], hand-drawn via chart.renderer)
    • Fix: Where feasible, route axis ticks/labels through a real (hidden-line, visible-labels) yAxis with a custom tickPositioner/labels.formatter instead of hand-drawn gridline text, so more of the chart leans on Highcharts' own layout system.
  2. DE-03 LOW: No explicit story emphasis beyond the structural width/height encoding
    • Fix: Add a subtle emphasis (e.g. a slightly bolder border or accent on the cell with the most notable deviation) or a short annotation calling out the standout pattern.
  3. VQ-05/layout LOW: Bottom caption and legend header sit very close to the canvas edges
    • Fix: Add a few more px of bottom/right margin buffer for robustness.

AI Feedback for Next Attempt

Solid, spec-compliant mosaic implementation with correct area semantics and clean theme-adaptive styling. To push past 90: strengthen Library Mastery by leaning more on Highcharts' own axis/label system instead of a fully hand-drawn canvas, add a touch of explicit data storytelling (emphasis or annotation on the standout pattern), and pad the bottom/right margins slightly for safety.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-rejected Quality not OK, triggers update labels Sep 2, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white (#FAF8F1) background. Bold dark title "mosaic-categorical · javascript · highcharts · anyplot.ai" and a subtitle calling out "Sales has the highest 'Below' share, at 19%", both clearly legible. Four mosaic columns (Engineering/Sales/Marketing/Support), widths proportional to headcount, each split into three stacked cells (Exceeds=green #009E73, Meets=violet, Below=blue) with heights proportional to conditional share. The Sales/Below cell has a distinct amber-gold stroke matching the subtitle callout. In-cell counts use luminance-based auto-contrast text and are all legible. Y-axis shows 0–100% ticks with axis title "Rating share within department"; x-axis shows department names plus a caption "Department · column width ∝ headcount". Legend "Performance rating" sits comfortably inside the right margin. All text is readable against the light background.

Dark render (plot-dark.png): Warm near-black (#1A1A17) background. Same title/subtitle in light/cream text, fully legible. Same four mosaic columns with identical cell proportions and data colors (green/violet/blue) — only chrome (background, text, gridlines, cell borders) flipped to the dark theme. The same amber-gold stroke highlights the Sales/Below cell. Y-axis ticks, axis titles, department labels, bottom caption, and legend are all light-colored and clearly legible against the dark background — no dark-on-dark failures anywhere.

Both renders pass the theme-readability check.

Score: 92/100

Category Score Max
Visual Quality 29 30
Design Excellence 18 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 9 10
Library Mastery 7 10
Total 92 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — all font sizes explicit (14/16/22px), readable in both themes; smallest in-cell counts (e.g. 12) could shrink further for guaranteed legibility at ~400px mobile width
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6)
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4) — real xAxis/yAxis now reserve space correctly; bottom caption and legend have comfortable margins (fixed from attempt 1)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (18/20)

  • DE-01: Aesthetic Sophistication (7/8) - Fully custom mosaic with rounded corners, luminance-based auto-contrast labeling, amber standout highlight
  • DE-02: Visual Refinement (5/6) - Minimal gridlines, generous whitespace, rounded cell corners
  • DE-03: Data Storytelling (6/6) - Subtitle names the key insight, paired with an amber-highlighted cell for a clear focal point — fixes attempt-1 weakness

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (4/4)
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6)
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) - Still has one small helper function (luminance)
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Now uses a real linear xAxis/yAxis with custom tickPositions/formatter and Highcharts' own legend system; the core rectangles remain hand-drawn via chart.renderer since Highcharts core has no mosaic series
  • LM-02: Distinctive Features (3/5) - Renderer API tied to the real coordinate system plus a genuine legend/title/subtitle, though the drawn shapes remain generic rects/text

Score Caps Applied

  • None

Strengths

  • Correct mosaic semantics: widths ∝ department headcount share, heights ∝ conditional rating share, area ∝ cell frequency
  • Now routes chrome through Highcharts' real xAxis/yAxis instead of hand-picked pixel margins — fixes attempt-1 LM-01 weakness
  • Explicit data storytelling via subtitle callout + amber-highlighted standout cell — fixes attempt-1 DE-03 weakness
  • Fully theme-correct chrome; identical data colors between light and dark
  • Prior thin-margin risk (bottom caption / legend header) is resolved

Weaknesses

  • Library Mastery still capped: mosaic rectangles are drawn manually via chart.renderer (defensible given no native Highcharts mosaic series), and the series array only carries empty placeholders to drive the legend
  • CQ-01: the luminance() helper is a minor deviation from strict linear script structure
  • In-cell count labels are fixed at 14px regardless of cell size — worth double-checking legibility of the smallest labeled cell at ~400px thumbnail width

Issues Found

None blocking — all remaining items are minor polish opportunities, not defects.

AI Feedback for Next Attempt

No further action required for approval. If revisited: consider whether the luminance() helper can be inlined as a literal per-rating array (removing the last function), and consider a slightly smaller minimum-font floor for in-cell counts to guarantee mobile-thumbnail legibility.

Verdict: APPROVED

@github-actions github-actions Bot added quality:92 Quality score 92/100 ai-approved Quality OK, ready for merge and removed quality:88 Quality score: 88/100 labels Sep 2, 2026
@MarkusNeusinger
MarkusNeusinger merged commit d04b9b1 into main Sep 2, 2026
3 checks passed
@MarkusNeusinger
MarkusNeusinger deleted the implementation/mosaic-categorical/highcharts branch September 2, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:92 Quality score 92/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant