From 16a62ffc5e5bb04f6b9a59c8635b11d0d56da818 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:13:12 +0000 Subject: [PATCH 1/5] feat(muix): implement dumbbell-basic --- .../implementations/javascript/muix.tsx | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 plots/dumbbell-basic/implementations/javascript/muix.tsx diff --git a/plots/dumbbell-basic/implementations/javascript/muix.tsx b/plots/dumbbell-basic/implementations/javascript/muix.tsx new file mode 100644 index 0000000000..7d88af946f --- /dev/null +++ b/plots/dumbbell-basic/implementations/javascript/muix.tsx @@ -0,0 +1,134 @@ +//# anyplot-orientation: landscape +// anyplot.ai +// dumbbell-basic: Basic Dumbbell Chart +// Library: MUI X Charts | React | Node 22 +// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope. +// Quality: pending | Created: 2026-06-30 + +import { ChartContainer } from "@mui/x-charts/ChartContainer"; +import { ChartsXAxis } from "@mui/x-charts/ChartsXAxis"; +import { ChartsYAxis } from "@mui/x-charts/ChartsYAxis"; +import { ChartsGrid } from "@mui/x-charts/ChartsGrid"; +import { ChartsLegend } from "@mui/x-charts/ChartsLegend"; +import { ScatterPlot } from "@mui/x-charts/ScatterChart"; +import { useXScale, useYScale } from "@mui/x-charts/hooks"; + +const t = window.ANYPLOT_TOKENS; + +// Department satisfaction scores (0–10) before/after a wellness program. +// Sorted ascending by "before" score to reveal the baseline-vs-gain pattern. +const departments = [ + "Finance", + "Marketing", + "Legal", + "Operations", + "Engineering", + "Sales", + "HR", + "Design", +]; +const beforeScores = [5.5, 5.8, 6.1, 6.3, 6.7, 7.0, 7.2, 7.5]; +const afterScores = [7.0, 7.2, 7.5, 7.6, 8.0, 8.3, 8.4, 8.7]; +const N = departments.length; + +// Scatter data: { id, x (score), y (category index 0…N-1) } +const beforeData = beforeScores.map((x, i) => ({ id: i, x, y: i })); +const afterData = afterScores.map( (x, i) => ({ id: i + 100, x, y: i })); + +// Dumbbell connecting lines rendered using MUI X coordinate hooks. +// Placed before so dots appear on top of the lines. +function DumbbellLines() { + const xScale = useXScale(); + const yScale = useYScale(); + + return ( + + {departments.map((_, i) => { + const x1 = xScale(beforeScores[i]) ?? 0; + const x2 = xScale(afterScores[i]) ?? 0; + const y = yScale(i) ?? 0; + return ( + + ); + })} + + ); +} + +const TITLE = "dumbbell-basic · javascript · muix · anyplot.ai"; + +export default function Chart() { + const W = window.ANYPLOT_SIZE.width; + const H = window.ANYPLOT_SIZE.height; + + return ( + departments[Math.round(v)] ?? "", + tickLabelStyle: { fontSize: 14, fill: t.inkSoft }, + }]} + margin={{ left: 130, right: 50, top: 70, bottom: 110 }} + > + + + + + + + + {TITLE} + + + ); +} From 85ba9a8f982c43ed9194f6d56e0a421c5d50dcce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:13:35 +0000 Subject: [PATCH 2/5] chore(muix): add metadata for dumbbell-basic --- .../metadata/javascript/muix.yaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 plots/dumbbell-basic/metadata/javascript/muix.yaml diff --git a/plots/dumbbell-basic/metadata/javascript/muix.yaml b/plots/dumbbell-basic/metadata/javascript/muix.yaml new file mode 100644 index 0000000000..b5e55b2a04 --- /dev/null +++ b/plots/dumbbell-basic/metadata/javascript/muix.yaml @@ -0,0 +1,21 @@ +# Per-library metadata for muix implementation of dumbbell-basic +# Auto-generated by impl-generate.yml + +library: muix +language: javascript +specification_id: dumbbell-basic +created: '2026-06-30T23:13:34Z' +updated: '2026-06-30T23:13:34Z' +generated_by: claude-sonnet +workflow_run: 28481532541 +issue: 945 +language_version: 22.23.0 +library_version: 7.29.1 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-dark.html +quality_score: null +review: + strengths: [] + weaknesses: [] From 2401df3ac7e1fd9074e9963b2da9ecc75b4ad334 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:21:28 +0000 Subject: [PATCH 3/5] chore(muix): update quality score 89 and review feedback for dumbbell-basic --- .../implementations/javascript/muix.tsx | 4 + .../metadata/javascript/muix.yaml | 253 +++++++++++++++++- 2 files changed, 250 insertions(+), 7 deletions(-) diff --git a/plots/dumbbell-basic/implementations/javascript/muix.tsx b/plots/dumbbell-basic/implementations/javascript/muix.tsx index 7d88af946f..1462d6cdfb 100644 --- a/plots/dumbbell-basic/implementations/javascript/muix.tsx +++ b/plots/dumbbell-basic/implementations/javascript/muix.tsx @@ -1,3 +1,7 @@ +// anyplot.ai +// dumbbell-basic: Basic Dumbbell Chart +// Library: muix 7.29.1 | JavaScript 22.23.0 +// Quality: 89/100 | Created: 2026-06-30 //# anyplot-orientation: landscape // anyplot.ai // dumbbell-basic: Basic Dumbbell Chart diff --git a/plots/dumbbell-basic/metadata/javascript/muix.yaml b/plots/dumbbell-basic/metadata/javascript/muix.yaml index b5e55b2a04..01839762a5 100644 --- a/plots/dumbbell-basic/metadata/javascript/muix.yaml +++ b/plots/dumbbell-basic/metadata/javascript/muix.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for muix implementation of dumbbell-basic -# Auto-generated by impl-generate.yml - library: muix language: javascript specification_id: dumbbell-basic created: '2026-06-30T23:13:34Z' -updated: '2026-06-30T23:13:34Z' +updated: '2026-06-30T23:21:27Z' generated_by: claude-sonnet workflow_run: 28481532541 issue: 945 @@ -15,7 +12,249 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell- preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/javascript/muix/plot-dark.html -quality_score: null +quality_score: 89 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent use of MUI X coordinate hooks (useXScale/useYScale) to render custom + dumbbell connecting lines — idiomatic and distinctive to MUI X React architecture + - 'Perfect Imprint palette compliance: brand green #009E73 first, lavender #C475FD + second, both themes render with correct warm-off-white / warm-near-black backgrounds' + - Full spec compliance — horizontal orientation, categories on Y-axis, two dots + per category, subtle connecting lines, sorted by baseline score to reveal pattern + - 'Both light and dark renders are fully readable: all text adapts correctly to + the theme, no dark-on-dark or light-on-light failures' + - Clean, deterministic in-memory data with realistic employee wellness scenario; + explicit font sizes at all three hierarchy levels (title 22px, axis label 16px, + ticks 14px) + weaknesses: + - 'DE-01/DE-02: Chart uses MUI X''s default 4-sided border frame with no spine removal; + removing or lightening the top and right axis lines would add visual polish' + - 'DE-03: No focal point or visual emphasis — all categories are visually identical + weight; highlighting the top or bottom performer (e.g., largest-gain or lowest-baseline + department) with a size or color accent would improve storytelling' + - 'DQ-01: Gap sizes between before/after values are too uniform (1.2–1.5 points + across all 8 departments); varying the differences more widely (e.g., 0.5 to 2.5 + points), or including one small-gain or regression department, would better showcase + the dumbbell chart''s utility for comparing differences' + - 'DE-01: Aesthetic sophistication is at ''well-configured default'' level — consider + adding a direct value label at each dot or a gap annotation to add information + density and visual interest' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1) — correct, not pure white. + Chrome: Title "dumbbell-basic · javascript · muix · anyplot.ai" centered at top in dark ink, clearly readable. X-axis label "Employee Satisfaction Score (0 – 10)" in dark ink, readable. Y-axis tick labels (Finance, Marketing, Legal, Operations, Engineering, Sales, HR, Design) in secondary ink, all readable. X-axis tick labels readable. + Data: 8 horizontal dumbbells. Before Program dots are brand green (#009E73). After Program dots are lavender (#C475FD). Connecting lines are subtle gray with 40% opacity. Data sorted ascending by before score (Finance at bottom, Design at top). Vertical grid lines only, subtle. + Legibility verdict: PASS — all text clearly readable against light background. + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17) — correct, not pure black. + Chrome: Title, axis label, Y-axis tick labels, X-axis tick labels all render in light ink against the dark background — fully readable. No dark-on-dark failures observed. + Data: Data colors are identical to the light render — Before Program is still #009E73, After Program is still #C475FD. Connecting lines are visible against the dark background. Legend at bottom reads correctly with light text. + Legibility verdict: PASS — all text clearly readable against dark background, no dark-on-dark issues. + criteria_checklist: + visual_quality: + score: 30 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 8 + max: 8 + passed: true + comment: All font sizes explicitly set (title 22px, axis label 16px, ticks + 14px). Readable in both themes. Good proportional balance. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No text or data element overlap in either render. + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: 8 sparse data points with markerSize=10 — well-sized for the density. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette — CVD-safe, green and purple are distinguishable + across all CVD types. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Good canvas utilization. Explicit margins (left:130, top:70, right:50, + bottom:110). Legend cleanly placed at bottom. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: 'X-axis: ''Employee Satisfaction Score (0 – 10)'' — descriptive with + units. Y-axis uses category names as tick labels — appropriate for dumbbell.' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series #009E73 (brand green), second #C475FD (Imprint position + 2). Light bg #FAF8F1, dark bg #1A1A17. Data colors identical across themes.' + design_excellence: + score: 11 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 4 + max: 8 + passed: false + comment: Well-configured library default. Correct palette and layout but no + standout aesthetic choices or typographic refinement beyond the basics. + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: false + comment: 'Some refinement: vertical-only grid, subtle connecting lines (inkSoft + + opacity:0.4), explicit margin control. Missing: no spine removal (default + 4-sided border frame remains).' + - id: DE-03 + name: Data Storytelling + score: 3 + max: 6 + passed: false + comment: Sorted by baseline score which hints at a pattern, and consistent + two-color contrast helps distinguish before/after. No focal point or emphasis + on highest/lowest performers. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: 'Correct horizontal dumbbell chart: two dots per category connected + by a line.' + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Horizontal orientation, categories on Y-axis, values on X-axis, distinct + colors for start/end dots, sorted by before value. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X = satisfaction score, Y = department category. All 8 departments + visible with correct before/after mapping. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: 'Title: ''dumbbell-basic · javascript · muix · anyplot.ai'' — correct + format. Legend: ''Before Program'' (green) / ''After Program'' (purple) + — correct.' + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + passed: true + comment: 8 departments with two-point comparison, connecting lines, sorted + order. Gap sizes are too uniform (1.2–1.5 range) and all improvements are + positive — more variation would better illustrate the chart type's utility. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Employee satisfaction before/after wellness program — realistic, + neutral, professionally relevant scenario with named departments. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: 'Satisfaction scores on 0–10 scale, before: 5.5–7.5, after: 7.0–8.7 + — plausible range for an employee survey with realistic program improvement.' + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: DumbbellLines sub-component is necessary for the useXScale/useYScale + hooks (must render inside ChartContainer) — not over-engineering. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Hard-coded deterministic data — appropriate for JS/browser context + with no RNG. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: 'All 7 imports are used: ChartContainer, ChartsXAxis, ChartsYAxis, + ChartsGrid, ChartsLegend, ScatterPlot, useXScale, useYScale.' + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean, idiomatic React/MUI X code. No fake UI elements. Comments + explain the non-obvious hook technique. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Output handled by harness (plot-light.png, plot-dark.png, .html). + Community @mui/x-charts only. skipAnimation set. + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: Correctly uses ChartContainer with composed chart component pattern + (ChartsXAxis, ChartsYAxis, ChartsGrid, ChartsLegend, ScatterPlot). Proper + default-export component structure. + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: 'useXScale/useYScale coordinate hooks are distinctively MUI X: React + hooks that expose the chart''s D3 scales for custom SVG rendering — not + available with the same clean API in Chart.js, ECharts, or Highcharts.' + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - layer-composition + - html-export + patterns: + - data-generation + dataprep: [] + styling: [] From 11066d9be19ae659fa1504c40f5a090bb4e7dc8d Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 23:28:01 +0000 Subject: [PATCH 4/5] fix(muix): address review feedback for dumbbell-basic Attempt 1/3 - fixes based on AI review - Vary gap sizes (-0.2 to +2.5) with one regression (Legal) for chart utility - Remove Y-axis left spine (disableLine) for open-chart visual refinement - Highlight Operations (largest gain) with amber connector + focal-point callout - Add gap-value labels on every row for information density --- .../implementations/javascript/muix.tsx | 117 +++++++++++++----- 1 file changed, 85 insertions(+), 32 deletions(-) diff --git a/plots/dumbbell-basic/implementations/javascript/muix.tsx b/plots/dumbbell-basic/implementations/javascript/muix.tsx index 1462d6cdfb..56b9ac98f6 100644 --- a/plots/dumbbell-basic/implementations/javascript/muix.tsx +++ b/plots/dumbbell-basic/implementations/javascript/muix.tsx @@ -1,7 +1,3 @@ -// anyplot.ai -// dumbbell-basic: Basic Dumbbell Chart -// Library: muix 7.29.1 | JavaScript 22.23.0 -// Quality: 89/100 | Created: 2026-06-30 //# anyplot-orientation: landscape // anyplot.ai // dumbbell-basic: Basic Dumbbell Chart @@ -19,49 +15,105 @@ import { useXScale, useYScale } from "@mui/x-charts/hooks"; const t = window.ANYPLOT_TOKENS; -// Department satisfaction scores (0–10) before/after a wellness program. -// Sorted ascending by "before" score to reveal the baseline-vs-gain pattern. -const departments = [ - "Finance", - "Marketing", - "Legal", - "Operations", - "Engineering", - "Sales", - "HR", - "Design", +// Employee satisfaction (0–10) before/after a wellness program. +// Includes a wide range of outcomes — one regression, one standout gain. +const RAW = [ + { dept: "Finance", before: 5.4, after: 5.9 }, // +0.5 modest gain + { dept: "Legal", before: 5.7, after: 5.5 }, // -0.2 regression + { dept: "Marketing", before: 6.0, after: 7.6 }, // +1.6 + { dept: "Sales", before: 6.2, after: 6.7 }, // +0.5 + { dept: "Operations", before: 6.5, after: 9.0 }, // +2.5 ← largest gain + { dept: "Engineering", before: 6.8, after: 7.7 }, // +0.9 + { dept: "HR", before: 7.1, after: 8.4 }, // +1.3 + { dept: "Design", before: 7.4, after: 8.0 }, // +0.6 ]; -const beforeScores = [5.5, 5.8, 6.1, 6.3, 6.7, 7.0, 7.2, 7.5]; -const afterScores = [7.0, 7.2, 7.5, 7.6, 8.0, 8.3, 8.4, 8.7]; -const N = departments.length; -// Scatter data: { id, x (score), y (category index 0…N-1) } +// Sort ascending by before-score to reveal baseline-vs-gain pattern +const DATA = [...RAW].sort((a, b) => a.before - b.before); + +const departments = DATA.map(d => d.dept); +const beforeScores = DATA.map(d => d.before); +const afterScores = DATA.map(d => d.after); +const gaps = DATA.map(d => +(d.after - d.before).toFixed(1)); +const N = DATA.length; + +// Index of the department with the largest gain (focal point) +const maxGapIdx = gaps.indexOf(Math.max(...gaps)); + const beforeData = beforeScores.map((x, i) => ({ id: i, x, y: i })); const afterData = afterScores.map( (x, i) => ({ id: i + 100, x, y: i })); -// Dumbbell connecting lines rendered using MUI X coordinate hooks. -// Placed before so dots appear on top of the lines. -function DumbbellLines() { +// Rendered inside ChartContainer so it can access the D3 coordinate scales. +// Placed before so lines sit below the dots. +function DumbbellOverlay() { const xScale = useXScale(); const yScale = useYScale(); return ( - {departments.map((_, i) => { - const x1 = xScale(beforeScores[i]) ?? 0; - const x2 = xScale(afterScores[i]) ?? 0; + {/* Connecting lines — highlight the biggest-gain row with amber */} + {DATA.map((d, i) => { + const x1 = xScale(d.before) ?? 0; + const x2 = xScale(d.after) ?? 0; const y = yScale(i) ?? 0; + const isHighlight = i === maxGapIdx; return ( ); })} + + {/* Gap labels — showing change magnitude to the right of each dumbbell */} + {DATA.map((d, i) => { + const rightX = Math.max(xScale(d.before) ?? 0, xScale(d.after) ?? 0); + const y = yScale(i) ?? 0; + const g = gaps[i]; + const isHighlight = i === maxGapIdx; + const isRegression = g < 0; + const label = g > 0 ? `+${g.toFixed(1)}` : g.toFixed(1); + return ( + + {label} + + ); + })} + + {/* Callout annotation for the focal-point row */} + {(() => { + const i = maxGapIdx; + const x1 = xScale(beforeScores[i]) ?? 0; + const x2 = xScale(afterScores[i]) ?? 0; + const y = yScale(i) ?? 0; + const xMid = (x1 + x2) / 2; + return ( + + largest gain + + ); + })()} ); } @@ -98,7 +150,7 @@ export default function Chart() { xAxis={[{ id: "xAxis", min: 4.5, - max: 9.5, + max: 9.8, label: "Employee Satisfaction Score (0 – 10)", tickLabelStyle: { fontSize: 14, fill: t.inkSoft }, labelStyle: { fontSize: 16, fill: t.ink }, @@ -111,13 +163,14 @@ export default function Chart() { valueFormatter: (v) => departments[Math.round(v)] ?? "", tickLabelStyle: { fontSize: 14, fill: t.inkSoft }, }]} - margin={{ left: 130, right: 50, top: 70, bottom: 110 }} + margin={{ left: 130, right: 80, top: 70, bottom: 110 }} > - + - + {/* disableLine removes the left spine for a cleaner open-chart look */} + Date: Tue, 30 Jun 2026 23:35:47 +0000 Subject: [PATCH 5/5] chore(muix): update quality score 89 and review feedback for dumbbell-basic --- .../implementations/javascript/muix.tsx | 4 + .../metadata/javascript/muix.yaml | 207 ++++++++++-------- 2 files changed, 114 insertions(+), 97 deletions(-) diff --git a/plots/dumbbell-basic/implementations/javascript/muix.tsx b/plots/dumbbell-basic/implementations/javascript/muix.tsx index 56b9ac98f6..ff12677ee8 100644 --- a/plots/dumbbell-basic/implementations/javascript/muix.tsx +++ b/plots/dumbbell-basic/implementations/javascript/muix.tsx @@ -1,3 +1,7 @@ +// anyplot.ai +// dumbbell-basic: Basic Dumbbell Chart +// Library: muix 7.29.1 | JavaScript 22.23.0 +// Quality: 89/100 | Created: 2026-06-30 //# anyplot-orientation: landscape // anyplot.ai // dumbbell-basic: Basic Dumbbell Chart diff --git a/plots/dumbbell-basic/metadata/javascript/muix.yaml b/plots/dumbbell-basic/metadata/javascript/muix.yaml index 01839762a5..1fb9469bab 100644 --- a/plots/dumbbell-basic/metadata/javascript/muix.yaml +++ b/plots/dumbbell-basic/metadata/javascript/muix.yaml @@ -2,7 +2,7 @@ library: muix language: javascript specification_id: dumbbell-basic created: '2026-06-30T23:13:34Z' -updated: '2026-06-30T23:21:27Z' +updated: '2026-06-30T23:35:47Z' generated_by: claude-sonnet workflow_run: 28481532541 issue: 945 @@ -15,121 +15,131 @@ preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell- quality_score: 89 review: strengths: - - Excellent use of MUI X coordinate hooks (useXScale/useYScale) to render custom - dumbbell connecting lines — idiomatic and distinctive to MUI X React architecture - - 'Perfect Imprint palette compliance: brand green #009E73 first, lavender #C475FD - second, both themes render with correct warm-off-white / warm-near-black backgrounds' - - Full spec compliance — horizontal orientation, categories on Y-axis, two dots - per category, subtle connecting lines, sorted by baseline score to reveal pattern - - 'Both light and dark renders are fully readable: all text adapts correctly to - the theme, no dark-on-dark or light-on-light failures' - - Clean, deterministic in-memory data with realistic employee wellness scenario; - explicit font sizes at all three hierarchy levels (title 22px, axis label 16px, - ticks 14px) + - 'Expert use of MUI X composition pattern: ChartContainer + useXScale/useYScale + hooks + SVG overlay — the idiomatic way to build a custom chart type without dropping + to raw D3' + - 'Strong data storytelling: amber highlight on Operations (largest gain), explicit + ''largest gain'' annotation, italic label for the regression row (Legal, −0.2), + and signed gap labels form a coherent visual narrative' + - 'Perfect spec compliance: horizontal orientation, distinct colors for before/after, + subtle connecting lines, sorted by before-score to reveal baseline-vs-gain pattern' + - 'Data coverage: includes both improvement (most rows) and regression (Legal −0.2), + demonstrating the full range of dumbbell chart use cases' + - Clean, deterministic code — hard-coded data, all imports used, component structure + is idiomatic React/MUI X + - 'Correct Imprint palette: palette[0] (#009E73) for Before, palette[1] (#C475FD) + for After, amber semantic anchor for the highlight; both renders theme-correct' weaknesses: - - 'DE-01/DE-02: Chart uses MUI X''s default 4-sided border frame with no spine removal; - removing or lightening the top and right axis lines would add visual polish' - - 'DE-03: No focal point or visual emphasis — all categories are visually identical - weight; highlighting the top or bottom performer (e.g., largest-gain or lowest-baseline - department) with a size or color accent would improve storytelling' - - 'DQ-01: Gap sizes between before/after values are too uniform (1.2–1.5 points - across all 8 departments); varying the differences more widely (e.g., 0.5 to 2.5 - points), or including one small-gain or regression department, would better showcase - the dumbbell chart''s utility for comparing differences' - - 'DE-01: Aesthetic sophistication is at ''well-configured default'' level — consider - adding a direct value label at each dot or a gap annotation to add information - density and visual interest' + - Gap labels use fontSize=12 CSS px, which is below the library-guide minimum of + ~14 px for secondary text; at 2× DPR that's 24 native px — borderline at mobile + widths. Increase to 13–14 CSS px. + - X-axis spine (bottom horizontal line) is still visible; the Y-axis line was correctly + removed via disableLine, but the X-axis line was not. Removing or softening it + would give a fully open-chart aesthetic consistent with the rest of the design. + - 'DE-02 refinement opportunity: the vertical grid lines could be given explicit + opacity (e.g. strokeOpacity 0.15) via ChartsGrid slotProps to make them more subtle + and match the style-guide''s 10–15% grid-opacity guideline.' image_description: |- Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) — correct, not pure white. - Chrome: Title "dumbbell-basic · javascript · muix · anyplot.ai" centered at top in dark ink, clearly readable. X-axis label "Employee Satisfaction Score (0 – 10)" in dark ink, readable. Y-axis tick labels (Finance, Marketing, Legal, Operations, Engineering, Sales, HR, Design) in secondary ink, all readable. X-axis tick labels readable. - Data: 8 horizontal dumbbells. Before Program dots are brand green (#009E73). After Program dots are lavender (#C475FD). Connecting lines are subtle gray with 40% opacity. Data sorted ascending by before score (Finance at bottom, Design at top). Vertical grid lines only, subtle. - Legibility verdict: PASS — all text clearly readable against light background. + Background: Warm off-white (#FAF8F1) — correct light surface, not pure white. + Chrome: Title "dumbbell-basic · javascript · muix · anyplot.ai" is centered, rendered in dark ink (~#1A1A17) at fontSize 22 CSS px, clearly readable. X-axis label "Employee Satisfaction Score (0 – 10)" in dark ink at fontSize 16, readable. Y-axis tick labels (department names: Finance, Legal, Marketing, Sales, Operations, Engineering, HR, Design) at fontSize 14 in inkSoft — readable but modestly sized. Gap labels (+0.5, −0.2, +1.6, +0.5, +2.5, +0.9, +1.3, +0.6) at fontSize 12/13 — readable but slightly small. Legend ("Before Program" / "After Program") at the bottom, visible. + Data: Brand green (#009E73) dots for "Before Program" and lavender (#C475FD) dots for "After Program", matching Imprint palette[0] and palette[1]. Connecting lines in subtle gray (inkSoft, 35% opacity). Operations row (largest gain +2.5) highlighted with an amber (#DDCC77) line and "largest gain" annotation. Legal row (−0.2 regression) correctly shows the after dot to the left of the before dot, labeled in italic. + Legibility verdict: PASS — all text readable against the off-white background; no light-on-light issues. Dark render (plot-dark.png): - Background: Warm near-black (#1A1A17) — correct, not pure black. - Chrome: Title, axis label, Y-axis tick labels, X-axis tick labels all render in light ink against the dark background — fully readable. No dark-on-dark failures observed. - Data: Data colors are identical to the light render — Before Program is still #009E73, After Program is still #C475FD. Connecting lines are visible against the dark background. Legend at bottom reads correctly with light text. - Legibility verdict: PASS — all text clearly readable against dark background, no dark-on-dark issues. + Background: Warm near-black (#1A1A17) — correct dark surface. + Chrome: Title and all labels rendered in light ink (F0EFE8 / B8B7B0 range) — correctly theme-flipped. Y-axis department labels, X-axis label, tick labels, and gap labels all visible in light colors against the dark background. No dark-on-dark failures observed. + Data: Green and lavender dots are identical to the light render — data colors did not flip, only chrome flipped. The amber highlight on Operations remains clearly visible (#DDCC77 reads well on both surfaces). The "largest gain" annotation is rendered in amber, readable. + Legibility verdict: PASS — all text readable against the near-black background; no dark-on-dark issues detected. criteria_checklist: visual_quality: - score: 30 + score: 29 max: 30 items: - id: VQ-01 name: Text Legibility - score: 8 + score: 7 max: 8 passed: true - comment: All font sizes explicitly set (title 22px, axis label 16px, ticks - 14px). Readable in both themes. Good proportional balance. + comment: All font sizes explicitly set (title 22, x-label 16, ticks 14, gap + labels 12–13 CSS px). Gap labels at 12 px are slightly below the 14 px guideline + for secondary text; borderline at mobile scale. - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No text or data element overlap in either render. + comment: No overlapping text or data elements in either render. - id: VQ-03 name: Element Visibility score: 6 max: 6 passed: true - comment: 8 sparse data points with markerSize=10 — well-sized for the density. + comment: markerSize=10 CSS px (20 native px) for 8 data points — appropriate + density, clearly visible in both themes. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Imprint palette — CVD-safe, green and purple are distinguishable - across all CVD types. + comment: Green (#009E73) vs lavender (#C475FD) — distinct hue families, CVD-safe. + Amber accent for highlight is distinct from both series colors. - id: VQ-05 name: Layout & Canvas score: 4 max: 4 passed: true - comment: Good canvas utilization. Explicit margins (left:130, top:70, right:50, - bottom:110). Legend cleanly placed at bottom. + comment: Canvas gate passed. Margins left=130, right=80, top=70, bottom=110 + — generous and well-balanced. Chart fills ~70% of canvas. Legend near plot + at bottom. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'X-axis: ''Employee Satisfaction Score (0 – 10)'' — descriptive with - units. Y-axis uses category names as tick labels — appropriate for dumbbell.' + comment: X-axis label 'Employee Satisfaction Score (0 – 10)' is descriptive + with units. Y-axis uses department names as categorical tick labels (no + redundant axis label needed). - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First series #009E73 (brand green), second #C475FD (Imprint position - 2). Light bg #FAF8F1, dark bg #1A1A17. Data colors identical across themes.' + comment: palette[0] (#009E73) for Before, palette[1] (#C475FD) for After — + canonical Imprint order. Amber semantic anchor used correctly for the focal + highlight. t.ink/t.inkSoft for chrome — theme-adaptive. Data colors identical + across both renders; only chrome flips. design_excellence: - score: 11 + score: 15 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 4 + score: 6 max: 8 - passed: false - comment: Well-configured library default. Correct palette and layout but no - standout aesthetic choices or typographic refinement beyond the basics. + passed: true + comment: 'Clearly above defaults: amber semantic accent, gap labels, ''largest + gain'' callout, italic for regression, sorted data. Not quite FiveThirtyEight-level + (no custom typography or layout-level hierarchy) but strong design.' - id: DE-02 name: Visual Refinement score: 4 max: 6 - passed: false - comment: 'Some refinement: vertical-only grid, subtle connecting lines (inkSoft - + opacity:0.4), explicit margin control. Missing: no spine removal (default - 4-sided border frame remains).' + passed: true + comment: Y-axis spine removed (disableLine). Vertical grid only (appropriate + for horizontal dumbbell). Connecting lines at 35% opacity and 2.5px width + are subtle. X-axis spine still visible — could be removed for fully open-chart + look. - id: DE-03 name: Data Storytelling - score: 3 + score: 5 max: 6 - passed: false - comment: Sorted by baseline score which hints at a pattern, and consistent - two-color contrast helps distinguish before/after. No focal point or emphasis - on highest/lowest performers. + passed: true + comment: 'Strong storytelling: amber highlight immediately draws eye to Operations + (largest gain), ''largest gain'' annotation confirms the insight, italic + label for regression (Legal), signed gap labels provide quantitative context, + data sorted ascending to reveal baseline-vs-gain pattern. Viewer immediately + sees the story.' spec_compliance: score: 15 max: 15 @@ -139,56 +149,55 @@ review: score: 5 max: 5 passed: true - comment: 'Correct horizontal dumbbell chart: two dots per category connected - by a line.' + comment: 'Correct dumbbell/connected-dot chart: two dots per category connected + by a line, horizontal orientation with categories on Y-axis.' - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: Horizontal orientation, categories on Y-axis, values on X-axis, distinct - colors for start/end dots, sorted by before value. + comment: Distinct colors for before/after dots, connecting lines, horizontal + orientation, categories on Y-axis, sorted by before-score. - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: X = satisfaction score, Y = department category. All 8 departments - visible with correct before/after mapping. + comment: Satisfaction scores on X-axis, department categories on Y-axis. All + 8 departments visible with full data range. - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: 'Title: ''dumbbell-basic · javascript · muix · anyplot.ai'' — correct - format. Legend: ''Before Program'' (green) / ''After Program'' (purple) - — correct.' + comment: Title 'dumbbell-basic · javascript · muix · anyplot.ai' matches required + format. Legend labels 'Before Program' and 'After Program' are descriptive. data_quality: - score: 14 + score: 15 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 5 + score: 6 max: 6 passed: true - comment: 8 departments with two-point comparison, connecting lines, sorted - order. Gap sizes are too uniform (1.2–1.5 range) and all improvements are - positive — more variation would better illustrate the chart type's utility. + comment: Shows improvement (6 of 8 departments), regression (Legal −0.2), + and a standout outlier gain (Operations +2.5). Covers the full range of + dumbbell chart use cases. - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Employee satisfaction before/after wellness program — realistic, - neutral, professionally relevant scenario with named departments. + comment: Employee satisfaction before/after wellness program — neutral, real-world + plausible business scenario with named departments. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 'Satisfaction scores on 0–10 scale, before: 5.5–7.5, after: 7.0–8.7 - — plausible range for an employee survey with realistic program improvement.' + comment: Satisfaction scores 5.4–9.0 on a 0–10 scale are realistic. Changes + from −0.2 to +2.5 are plausible for a workplace wellness program. code_quality: score: 10 max: 10 @@ -198,36 +207,35 @@ review: score: 3 max: 3 passed: true - comment: DumbbellLines sub-component is necessary for the useXScale/useYScale - hooks (must render inside ChartContainer) — not over-engineering. + comment: DumbbellOverlay helper component is necessary (hooks must be called + inside ChartContainer context) — idiomatic React/MUI X, not over-engineering. - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: Hard-coded deterministic data — appropriate for JS/browser context - with no RNG. + comment: Data is fully hard-coded, no random number generation, fully deterministic. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: 'All 7 imports are used: ChartContainer, ChartsXAxis, ChartsYAxis, - ChartsGrid, ChartsLegend, ScatterPlot, useXScale, useYScale.' + comment: 'All 7 imports used: ChartContainer, ChartsXAxis, ChartsYAxis, ChartsGrid, + ChartsLegend, ScatterPlot, useXScale/useYScale.' - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean, idiomatic React/MUI X code. No fake UI elements. Comments - explain the non-obvious hook technique. + comment: Clean, appropriate complexity. No fake UI elements. SVG overlay pattern + is the correct MUI X approach for custom marks. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Output handled by harness (plot-light.png, plot-dark.png, .html). - Community @mui/x-charts only. skipAnimation set. + comment: MUI X harness handles output (plot-light.png, plot-dark.png, HTML). + No manual output code needed — correct per harness contract. library_mastery: score: 9 max: 10 @@ -237,24 +245,29 @@ review: score: 5 max: 5 passed: true - comment: Correctly uses ChartContainer with composed chart component pattern - (ChartsXAxis, ChartsYAxis, ChartsGrid, ChartsLegend, ScatterPlot). Proper - default-export component structure. + comment: Expert use of ChartContainer slot composition, useXScale/useYScale + hooks, ScatterPlot, ChartsGrid with vertical-only setting, disableLine on + Y-axis. All idiomatic MUI X patterns. - id: LM-02 name: Distinctive Features score: 4 max: 5 passed: true - comment: 'useXScale/useYScale coordinate hooks are distinctively MUI X: React - hooks that expose the chart''s D3 scales for custom SVG rendering — not - available with the same clean API in Chart.js, ECharts, or Highcharts.' - verdict: REJECTED + comment: useXScale/useYScale coordinate-scale hooks inside ChartContainer + for SVG overlay is a distinctive MUI X pattern — React component access + to D3 scales is unique to this library's architecture and enables the dumbbell + connecting lines without external SVG libraries. + verdict: APPROVED impl_tags: dependencies: [] techniques: + - annotations + - custom-legend - layer-composition - - html-export patterns: - data-generation + - iteration-over-groups dataprep: [] - styling: [] + styling: + - alpha-blending + - edge-highlighting