From 0823551d75fff309b233e9d5eb148abf1c2d1366 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 15:12:56 +0000 Subject: [PATCH 1/5] feat(muix): implement bar-stacked-percent --- .../implementations/javascript/muix.tsx | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 plots/bar-stacked-percent/implementations/javascript/muix.tsx diff --git a/plots/bar-stacked-percent/implementations/javascript/muix.tsx b/plots/bar-stacked-percent/implementations/javascript/muix.tsx new file mode 100644 index 0000000000..d7fe0798e7 --- /dev/null +++ b/plots/bar-stacked-percent/implementations/javascript/muix.tsx @@ -0,0 +1,140 @@ +// anyplot.ai +// bar-stacked-percent: 100% Stacked Bar Chart +// Library: MUI X Charts | React | Node 22 +// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope. +// Quality: pending | Created: 2026-08-18 +import { BarChart } from "@mui/x-charts/BarChart"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; + +const t = window.ANYPLOT_TOKENS; + +// Fixed (non-theme-flipping) text colors for in-bar percentage labels — the +// segment fills stay the same hex in both themes, so label contrast is chosen +// per series color rather than following t.ink/t.inkSoft. +const LABEL_ON_LIGHT_FILL = "#1A1A17"; // dark ink — for the green/lavender/ochre segments +const LABEL_ON_DARK_FILL = "#F0EFE8"; // light ink — for the darker blue segment + +// --- Data (in-memory, deterministic) ---------------------------------------- +// Electricity generation mix (TWh/year, illustrative) for six grids whose +// total output spans two orders of magnitude — China dwarfs Norway in raw +// terawatt-hours, which is exactly why a percent-stacked view (composition) +// tells a clearer story here than a raw stacked view (dominated by scale). +const countries = ["China", "USA", "Germany", "France", "Brazil", "Norway"]; +const rawByCountry = { + China: { renewables: 3100, nuclear: 400, gas: 300, coal: 5200 }, + USA: { renewables: 900, nuclear: 800, gas: 1700, coal: 700 }, + Germany: { renewables: 270, nuclear: 0, gas: 80, coal: 150 }, + France: { renewables: 120, nuclear: 320, gas: 30, coal: 5 }, + Brazil: { renewables: 550, nuclear: 15, gas: 60, coal: 15 }, + Norway: { renewables: 150, nuclear: 0, gas: 0.5, coal: 0.1 }, +}; + +// Renewables listed first so it lands on Imprint position 1 (brand green) — +// a natural semantic fit (growth/nature). Order stays fixed across every bar. +const components = [ + { id: "renewables", label: "Renewables", labelFill: LABEL_ON_LIGHT_FILL }, + { id: "nuclear", label: "Nuclear", labelFill: LABEL_ON_LIGHT_FILL }, + { id: "gas", label: "Natural Gas", labelFill: LABEL_ON_DARK_FILL }, + { id: "coal", label: "Coal", labelFill: LABEL_ON_LIGHT_FILL }, +]; +const labelFillById = Object.fromEntries(components.map((c) => [c.id, c.labelFill])); + +const totalsByCountry = countries.map((country) => + components.reduce((sum, c) => sum + rawByCountry[country][c.id], 0), +); +const series = components.map((c) => ({ + id: c.id, + label: c.label, + stack: "total", + data: countries.map((country, i) => (rawByCountry[country][c.id] / totalsByCountry[i]) * 100), +})); + +export default function Chart() { + const W = window.ANYPLOT_SIZE.width; // 1600 CSS px (landscape mount) + const H = window.ANYPLOT_SIZE.height; // 900 CSS px + const CHART_TOP = 84; + + return ( + + {/* Title + subtitle */} + + + bar-stacked-percent · javascript · muix · anyplot.ai + + + Norway's grid runs almost entirely on renewables, while China still leans on coal + + + + {/* Bar chart */} + + `${v}%`, + }, + ]} + series={series.map((s) => ({ + ...s, + valueFormatter: (v) => `${v.toFixed(1)}%`, + }))} + barLabel={(item) => (item.value != null && item.value >= 6 ? `${item.value.toFixed(0)}%` : null)} + margin={{ top: 14, right: 130, bottom: 90, left: 140 }} + grid={{ horizontal: true }} + slotProps={{ + legend: { + position: { vertical: "middle", horizontal: "right" }, + direction: "column", + labelStyle: { fontSize: 14, fill: t.inkSoft }, + }, + barLabel: (ownerState) => ({ + style: { + fontSize: 13, + fontWeight: 600, + fill: labelFillById[ownerState.seriesId] ?? LABEL_ON_LIGHT_FILL, + }, + }), + }} + sx={{ + "& .MuiChartsAxis-line": { stroke: t.inkSoft }, + "& .MuiChartsGrid-line": { stroke: t.grid }, + }} + /> + + + ); +} From 70026be364a0a44f75df0c822a4232a6d7ff3562 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 15:13:14 +0000 Subject: [PATCH 2/5] chore(muix): add metadata for bar-stacked-percent --- .../metadata/javascript/muix.yaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 plots/bar-stacked-percent/metadata/javascript/muix.yaml diff --git a/plots/bar-stacked-percent/metadata/javascript/muix.yaml b/plots/bar-stacked-percent/metadata/javascript/muix.yaml new file mode 100644 index 0000000000..07979a2266 --- /dev/null +++ b/plots/bar-stacked-percent/metadata/javascript/muix.yaml @@ -0,0 +1,21 @@ +# Per-library metadata for muix implementation of bar-stacked-percent +# Auto-generated by impl-generate.yml + +library: muix +language: javascript +specification_id: bar-stacked-percent +created: '2026-08-18T15:13:14Z' +updated: '2026-08-18T15:13:14Z' +generated_by: claude-sonnet +workflow_run: 32152153725 +issue: 2008 +language_version: 22.23.2 +library_version: 7.29.1 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.html +quality_score: null +review: + strengths: [] + weaknesses: [] From c40a8967b0ef979105ec5350657bc9d7ec6e13d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 15:17:26 +0000 Subject: [PATCH 3/5] chore(muix): update quality score 89 and review feedback for bar-stacked-percent --- .../implementations/javascript/muix.tsx | 5 +- .../metadata/javascript/muix.yaml | 250 +++++++++++++++++- 2 files changed, 245 insertions(+), 10 deletions(-) diff --git a/plots/bar-stacked-percent/implementations/javascript/muix.tsx b/plots/bar-stacked-percent/implementations/javascript/muix.tsx index d7fe0798e7..a65d267396 100644 --- a/plots/bar-stacked-percent/implementations/javascript/muix.tsx +++ b/plots/bar-stacked-percent/implementations/javascript/muix.tsx @@ -1,8 +1,7 @@ // anyplot.ai // bar-stacked-percent: 100% Stacked Bar Chart -// Library: MUI X Charts | React | Node 22 -// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope. -// Quality: pending | Created: 2026-08-18 +// Library: muix 7.29.1 | JavaScript 22.23.2 +// Quality: 89/100 | Created: 2026-08-18 import { BarChart } from "@mui/x-charts/BarChart"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; diff --git a/plots/bar-stacked-percent/metadata/javascript/muix.yaml b/plots/bar-stacked-percent/metadata/javascript/muix.yaml index 07979a2266..f8099ac0bf 100644 --- a/plots/bar-stacked-percent/metadata/javascript/muix.yaml +++ b/plots/bar-stacked-percent/metadata/javascript/muix.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for muix implementation of bar-stacked-percent -# Auto-generated by impl-generate.yml - library: muix language: javascript specification_id: bar-stacked-percent created: '2026-08-18T15:13:14Z' -updated: '2026-08-18T15:13:14Z' +updated: '2026-08-18T15:17:26Z' generated_by: claude-sonnet workflow_run: 32152153725 issue: 2008 @@ -15,7 +12,246 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-stack preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.html -quality_score: null +quality_score: 89 review: - strengths: [] - weaknesses: [] + strengths: + - 'Correct 100% stacked-bar semantics: series use stack: "total", values are pre-normalized + to percentages, and the y-axis is fixed to 0-100% with a % formatter.' + - 'Thoughtful per-segment label contrast: LABEL_ON_LIGHT_FILL / LABEL_ON_DARK_FILL + are chosen per series fill (dark ink on green/lavender/ochre, light ink on the + darker blue segment) so every in-bar percentage stays legible.' + - Threshold-based label suppression (barLabel only renders when value >= 6) avoids + cramming unreadable text into narrow slivers (e.g. Brazil's ~2% nuclear segment). + - Canonical Imprint palette order is respected (green -> lavender -> blue -> ochre) + and data colors are identical between light and dark renders; only chrome (background, + axis lines, text) flips theme. + - 'Idiomatic, rich use of the community BarChart API: xAxis/yAxis valueFormatter, + categoryGapRatio, slotProps for legend and barLabel styling, disableTicks, and + a documented tickFontSize trick to offset the y-axis label from the ''100%'' tick + text.' + - Descriptive subtitle frames a clear narrative (Norway's all-renewable grid vs. + China's coal reliance), giving the chart a focal point. + - Realistic, plausible dataset (illustrative electricity generation mix, TWh) within + the spec's recommended 3-12 categories / 2-6 components range, deterministic and + in-memory. + weaknesses: + - Bars are ordered by an arbitrary country list rather than sorted by renewables + share (or another metric) — sorting descending would visually reinforce the subtitle's + Norway-vs-China contrast and add a clearer data-storytelling gradient. + - 'Visual refinement is solid but not distinctive: default MUI X axis lines, no + additional refinement beyond the mandated grid/margin tuning — consider a slightly + more minimal chrome treatment (e.g. lighter axis line) to lift Design Excellence + further.' + - Sizable empty whitespace between the last bar (Norway) and the legend column — + could tighten the right margin slightly for better balance without harming legibility. + image_description: |- + Light render (plot-light.png): + Background: Warm off-white, consistent with #FAF8F1 — not pure white. + Chrome: Title "bar-stacked-percent · javascript · muix · anyplot.ai" in dark ink, top-left; a dark-gray subtitle below it ("Norway's grid runs almost entirely on renewables, while China still leans on coal"); y-axis "Share (%)" and x-axis "Country" labels in dark ink; tick labels (0%-100%, country names) in a softer gray; subtle horizontal gridlines; vertical legend on the right listing Renewables/Nuclear/Natural Gas/Coal with color swatches. All text is clearly readable against the light background — no light-on-light issues. + Data: Six vertical bars (China, USA, Germany, France, Brazil, Norway), each stacked to 100% with four components. First series (Renewables) is brand green #009E73, followed by lavender (Nuclear), blue (Natural Gas), and ochre (Coal) — matching canonical Imprint order. In-bar percentage labels use dark text on the green/lavender/ochre segments and light text on the blue segment, all legible against their respective fills. Tiny segments (e.g. Brazil's ~2% nuclear sliver) correctly omit a label to avoid clutter. + Legibility verdict: PASS + + Dark render (plot-dark.png): + Background: Warm near-black, consistent with #1A1A17 — not pure black. + Chrome: Same title and subtitle now in light ink/soft light-gray, axis labels and tick labels flipped to light tones, gridlines still subtle but visible against the dark surface, legend text light gray. No dark-on-dark failures observed — all chrome text is clearly visible against the near-black background. + Data: Segment colors (green, lavender, blue, ochre) are pixel-identical to the light render — only the chrome (background, text, gridlines, axis lines) flipped. In-bar percentage label colors are unchanged (still chosen per-segment fill, not per page background), and remain legible on both themes since they sit on the colored bar fills rather than the page background. + Legibility verdict: PASS + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: Explicit font sizes throughout (title 22px, subtitle 14px, axis 15px, + ticks 14px, bar labels 13px); readable in both themes. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No text/data collisions; labels suppressed under a 6% threshold to + avoid crowding narrow segments. + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: 6 categories x 4 components — well within density where all segments + and labels stay distinguishable. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Per-segment label fill chosen for contrast against each bar color; + no red-green-only signal. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Canvas dimension gate passed; good proportions, nothing clipped or + overflowing. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: '''Country'' and ''Share (%)'' axis labels are descriptive with units.' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series is #009E73; canonical Imprint order; correct theme + backgrounds; data colors identical across themes.' + design_excellence: + score: 11 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: Thoughtful per-segment label contrast logic and a documented tickFontSize + offset trick show above-baseline polish, but overall composition stays close + to library defaults. + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: false + comment: Subtle horizontal grid and tuned margins, but default MUI X axis + lines remain and there's noticeable unused whitespace between the last bar + and the legend. + - id: DE-03 + name: Data Storytelling + score: 3 + max: 6 + passed: false + comment: Subtitle gives a narrative focal point (Norway vs. China), but bars + aren't sorted to visually reinforce that contrast. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: 'True 100% stacked bar via stack: "total" with percent-normalized + values and a fixed 0-100% axis.' + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Distinct colors, clear legend, in-segment percentage labels, consistent + component order across bars. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X = country, Y = share (%); all four components sum to 100% per bar. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title matches the mandated format; legend labels match component + names exactly. + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: 6 categories, 4 components — within the spec's recommended range, + exercising the full percent-stack feature set. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Plausible, neutral illustrative electricity-generation-mix data by + country. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Values normalized sensibly to 0-100%. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Single functional component, no unnecessary classes or abstractions. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Hard-coded, deterministic in-memory data. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: Only BarChart, Box, and Typography imported, all used. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Appropriate complexity, no fake UI or simulated interactivity. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Renders via export default into the harness mount, skipAnimation + set, current MUI X API used. + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: Full use of xAxis/yAxis config, valueFormatter, slotProps, categoryGapRatio, + disableTicks — idiomatic community-surface usage. + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: Per-series label-color mapping via slotProps.barLabel and the tickFontSize + axis-offset trick show real library familiarity. + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: [] + patterns: + - data-generation + - iteration-over-groups + dataprep: + - normalization + styling: + - publication-ready From f2ccfec4d46657ddbae36a7801da8d507e6e68e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 15:20:30 +0000 Subject: [PATCH 4/5] fix(muix): address review feedback for bar-stacked-percent Attempt 1/4 - fixes based on AI review --- .../implementations/javascript/muix.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/plots/bar-stacked-percent/implementations/javascript/muix.tsx b/plots/bar-stacked-percent/implementations/javascript/muix.tsx index a65d267396..3c4bc0987d 100644 --- a/plots/bar-stacked-percent/implementations/javascript/muix.tsx +++ b/plots/bar-stacked-percent/implementations/javascript/muix.tsx @@ -19,7 +19,6 @@ const LABEL_ON_DARK_FILL = "#F0EFE8"; // light ink — for the darker blue segme // total output spans two orders of magnitude — China dwarfs Norway in raw // terawatt-hours, which is exactly why a percent-stacked view (composition) // tells a clearer story here than a raw stacked view (dominated by scale). -const countries = ["China", "USA", "Germany", "France", "Brazil", "Norway"]; const rawByCountry = { China: { renewables: 3100, nuclear: 400, gas: 300, coal: 5200 }, USA: { renewables: 900, nuclear: 800, gas: 1700, coal: 700 }, @@ -29,6 +28,16 @@ const rawByCountry = { Norway: { renewables: 150, nuclear: 0, gas: 0.5, coal: 0.1 }, }; +// Sorted descending by renewables share so the bars themselves form a visual +// gradient (all-renewable Norway -> coal-heavy China) that reinforces the +// subtitle's contrast, rather than an arbitrary country ordering. +const renewablesShare = (country) => { + const raw = rawByCountry[country]; + const total = raw.renewables + raw.nuclear + raw.gas + raw.coal; + return raw.renewables / total; +}; +const countries = Object.keys(rawByCountry).sort((a, b) => renewablesShare(b) - renewablesShare(a)); + // Renewables listed first so it lands on Imprint position 1 (brand green) — // a natural semantic fit (growth/nature). Order stays fixed across every bar. const components = [ @@ -112,7 +121,7 @@ export default function Chart() { valueFormatter: (v) => `${v.toFixed(1)}%`, }))} barLabel={(item) => (item.value != null && item.value >= 6 ? `${item.value.toFixed(0)}%` : null)} - margin={{ top: 14, right: 130, bottom: 90, left: 140 }} + margin={{ top: 14, right: 90, bottom: 90, left: 140 }} grid={{ horizontal: true }} slotProps={{ legend: { @@ -129,7 +138,9 @@ export default function Chart() { }), }} sx={{ - "& .MuiChartsAxis-line": { stroke: t.inkSoft }, + // Lighter, grid-weight axis line instead of the default full-ink + // stroke — a more refined chrome treatment than the library default. + "& .MuiChartsAxis-line": { stroke: t.grid }, "& .MuiChartsGrid-line": { stroke: t.grid }, }} /> From 1059857f2ed084294ac68eb36600ba6a9c889087 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 15:24:44 +0000 Subject: [PATCH 5/5] chore(muix): update quality score 94 and review feedback for bar-stacked-percent --- .../implementations/javascript/muix.tsx | 2 +- .../metadata/javascript/muix.yaml | 115 ++++++++++-------- 2 files changed, 62 insertions(+), 55 deletions(-) diff --git a/plots/bar-stacked-percent/implementations/javascript/muix.tsx b/plots/bar-stacked-percent/implementations/javascript/muix.tsx index 3c4bc0987d..4e49b79aa5 100644 --- a/plots/bar-stacked-percent/implementations/javascript/muix.tsx +++ b/plots/bar-stacked-percent/implementations/javascript/muix.tsx @@ -1,7 +1,7 @@ // anyplot.ai // bar-stacked-percent: 100% Stacked Bar Chart // Library: muix 7.29.1 | JavaScript 22.23.2 -// Quality: 89/100 | Created: 2026-08-18 +// Quality: 94/100 | Created: 2026-08-18 import { BarChart } from "@mui/x-charts/BarChart"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; diff --git a/plots/bar-stacked-percent/metadata/javascript/muix.yaml b/plots/bar-stacked-percent/metadata/javascript/muix.yaml index f8099ac0bf..2b607f636f 100644 --- a/plots/bar-stacked-percent/metadata/javascript/muix.yaml +++ b/plots/bar-stacked-percent/metadata/javascript/muix.yaml @@ -2,7 +2,7 @@ library: muix language: javascript specification_id: bar-stacked-percent created: '2026-08-18T15:13:14Z' -updated: '2026-08-18T15:17:26Z' +updated: '2026-08-18T15:24:44Z' generated_by: claude-sonnet workflow_run: 32152153725 issue: 2008 @@ -12,49 +12,54 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-stack preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-percent/javascript/muix/plot-dark.html -quality_score: 89 +quality_score: 94 review: strengths: - - 'Correct 100% stacked-bar semantics: series use stack: "total", values are pre-normalized + - 'Correct 100% stacked-bar semantics: series use stack: "total" with values pre-normalized to percentages, and the y-axis is fixed to 0-100% with a % formatter.' - - 'Thoughtful per-segment label contrast: LABEL_ON_LIGHT_FILL / LABEL_ON_DARK_FILL - are chosen per series fill (dark ink on green/lavender/ochre, light ink on the - darker blue segment) so every in-bar percentage stays legible.' - - Threshold-based label suppression (barLabel only renders when value >= 6) avoids - cramming unreadable text into narrow slivers (e.g. Brazil's ~2% nuclear segment). - - Canonical Imprint palette order is respected (green -> lavender -> blue -> ochre) - and data colors are identical between light and dark renders; only chrome (background, - axis lines, text) flips theme. + - Bars are now sorted descending by renewables share (Norway -> Brazil -> Germany + -> China -> France -> USA), creating a clear visual gradient that reinforces the + subtitle's narrative -- directly addresses the attempt-1 weakness about arbitrary + bar order. + - Axis line and grid strokes now use the softer t.grid token instead of MUI X's + default full-ink stroke (via sx targeting .MuiChartsAxis-line / .MuiChartsGrid-line), + producing a more refined chrome treatment -- directly addresses the attempt-1 + DE-02 weakness. + - Thoughtful per-segment label contrast (LABEL_ON_LIGHT_FILL / LABEL_ON_DARK_FILL + chosen per series fill, not per page theme) keeps every in-bar percentage legible + on both themes. + - Threshold-based label suppression (barLabel only renders when value >= 6%) avoids + cramming unreadable text into narrow slivers, e.g. Brazil's ~2% nuclear sliver + and France's ~1% coal sliver. + - Canonical Imprint palette order (green, lavender, blue, ochre) with data colors + pixel-identical between light and dark renders; only chrome (background, text, + gridlines) flips. - 'Idiomatic, rich use of the community BarChart API: xAxis/yAxis valueFormatter, categoryGapRatio, slotProps for legend and barLabel styling, disableTicks, and a documented tickFontSize trick to offset the y-axis label from the ''100%'' tick text.' - - Descriptive subtitle frames a clear narrative (Norway's all-renewable grid vs. - China's coal reliance), giving the chart a focal point. - - Realistic, plausible dataset (illustrative electricity generation mix, TWh) within - the spec's recommended 3-12 categories / 2-6 components range, deterministic and - in-memory. weaknesses: - - Bars are ordered by an arbitrary country list rather than sorted by renewables - share (or another metric) — sorting descending would visually reinforce the subtitle's - Norway-vs-China contrast and add a clearer data-storytelling gradient. - - 'Visual refinement is solid but not distinctive: default MUI X axis lines, no - additional refinement beyond the mandated grid/margin tuning — consider a slightly - more minimal chrome treatment (e.g. lighter axis line) to lift Design Excellence - further.' - - Sizable empty whitespace between the last bar (Norway) and the legend column — - could tighten the right margin slightly for better balance without harming legibility. + - A visible gap remains between the last bar (USA) and the legend column on the + right -- tightened relative to attempt 1 but could be trimmed further for balance. + - Sorting by renewables share slightly dilutes the subtitle's Norway-vs-China anchor, + since China now sits mid-pack rather than at a visual extreme (USA and France + have even lower renewables shares) -- the coal-specific claim still holds (China's + 58% is the highest coal share of any bar), but a reader skimming bar position + alone may not immediately connect it to 'leans on coal'. + - Design excellence is solid but not exceptional -- beyond the new axis-line refinement + and existing label-contrast logic, there are no further distinctive touches (e.g. + no accent/callout on the Norway or China bar to underline the subtitle's claim). image_description: |- Light render (plot-light.png): - Background: Warm off-white, consistent with #FAF8F1 — not pure white. - Chrome: Title "bar-stacked-percent · javascript · muix · anyplot.ai" in dark ink, top-left; a dark-gray subtitle below it ("Norway's grid runs almost entirely on renewables, while China still leans on coal"); y-axis "Share (%)" and x-axis "Country" labels in dark ink; tick labels (0%-100%, country names) in a softer gray; subtle horizontal gridlines; vertical legend on the right listing Renewables/Nuclear/Natural Gas/Coal with color swatches. All text is clearly readable against the light background — no light-on-light issues. - Data: Six vertical bars (China, USA, Germany, France, Brazil, Norway), each stacked to 100% with four components. First series (Renewables) is brand green #009E73, followed by lavender (Nuclear), blue (Natural Gas), and ochre (Coal) — matching canonical Imprint order. In-bar percentage labels use dark text on the green/lavender/ochre segments and light text on the blue segment, all legible against their respective fills. Tiny segments (e.g. Brazil's ~2% nuclear sliver) correctly omit a label to avoid clutter. + Background: Warm off-white, consistent with #FAF8F1 -- not pure white, not dark. + Chrome: Title "bar-stacked-percent · javascript · muix · anyplot.ai" in dark ink, top-left; a dark-gray subtitle below it ("Norway's grid runs almost entirely on renewables, while China still leans on coal"); y-axis "Share (%)" and x-axis "Country" labels in dark ink; tick labels (0%-100%, country names) in a softer gray; subtle horizontal gridlines and a now-lighter (grid-weight) axis line; vertical legend on the right listing Renewables/Nuclear/Natural Gas/Coal with color swatches. All text is clearly readable against the light background -- no light-on-light issues. + Data: Six vertical bars, now sorted descending by renewables share (Norway 100%, Brazil 86%, Germany 54%, China 34%, France 25%, USA 22%), each stacked to 100% with up to four components. First series (Renewables) is brand green #009E73, followed by lavender (Nuclear), blue (Natural Gas), and ochre (Coal) -- matching canonical Imprint order. In-bar percentage labels use dark text on the green/lavender/ochre segments and light text on the blue segment, all legible against their respective fills. Tiny segments (e.g. Brazil's ~2% nuclear sliver, France's ~1% coal sliver) correctly omit a label to avoid clutter. Legibility verdict: PASS Dark render (plot-dark.png): - Background: Warm near-black, consistent with #1A1A17 — not pure black. - Chrome: Same title and subtitle now in light ink/soft light-gray, axis labels and tick labels flipped to light tones, gridlines still subtle but visible against the dark surface, legend text light gray. No dark-on-dark failures observed — all chrome text is clearly visible against the near-black background. - Data: Segment colors (green, lavender, blue, ochre) are pixel-identical to the light render — only the chrome (background, text, gridlines, axis lines) flipped. In-bar percentage label colors are unchanged (still chosen per-segment fill, not per page background), and remain legible on both themes since they sit on the colored bar fills rather than the page background. + Background: Warm near-black, consistent with #1A1A17 -- not pure black, not light. + Chrome: Same title and subtitle now in light ink/soft light-gray, axis labels and tick labels flipped to light tones, gridlines and axis line still subtle but visible against the dark surface, legend text light gray. No dark-on-dark failures observed -- all chrome text is clearly visible against the near-black background. + Data: Segment colors (green, lavender, blue, ochre) are pixel-identical to the light render -- only the chrome (background, text, gridlines, axis line) flipped. In-bar percentage label colors are unchanged (still chosen per-segment fill, not per page background) and remain legible on both themes since they sit on the colored bar fills rather than the page background. Legibility verdict: PASS criteria_checklist: visual_quality: @@ -80,8 +85,8 @@ review: score: 6 max: 6 passed: true - comment: 6 categories x 4 components — well within density where all segments - and labels stay distinguishable. + comment: 6 categories x up to 4 components -- well within density where all + segments and labels stay distinguishable. - id: VQ-04 name: Color Accessibility score: 2 @@ -110,32 +115,33 @@ review: comment: 'First series is #009E73; canonical Imprint order; correct theme backgrounds; data colors identical across themes.' design_excellence: - score: 11 + score: 15 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 5 + score: 6 max: 8 passed: true - comment: Thoughtful per-segment label contrast logic and a documented tickFontSize - offset trick show above-baseline polish, but overall composition stays close - to library defaults. + comment: Per-segment label contrast logic, documented tickFontSize offset + trick, and renewables-share sort show above-baseline polish; composition + is refined but not fully distinctive. - id: DE-02 name: Visual Refinement - score: 3 + score: 4 max: 6 - passed: false - comment: Subtle horizontal grid and tuned margins, but default MUI X axis - lines remain and there's noticeable unused whitespace between the last bar - and the legend. + passed: true + comment: Axis and grid lines now use the softer grid-weight stroke instead + of MUI X defaults, addressing the attempt-1 weakness; a small gap between + the last bar and legend remains. - id: DE-03 name: Data Storytelling - score: 3 + score: 5 max: 6 - passed: false - comment: Subtitle gives a narrative focal point (Norway vs. China), but bars - aren't sorted to visually reinforce that contrast. + passed: true + comment: Bars now sorted descending by renewables share, forming a clear visual + gradient (Norway -> USA) that reinforces the subtitle's narrative -- directly + fixes the attempt-1 weakness. spec_compliance: score: 15 max: 15 @@ -159,7 +165,7 @@ review: score: 3 max: 3 passed: true - comment: X = country, Y = share (%); all four components sum to 100% per bar. + comment: X = country, Y = share (%); all components sum to 100% per bar. - id: SC-04 name: Title & Legend score: 3 @@ -176,7 +182,7 @@ review: score: 6 max: 6 passed: true - comment: 6 categories, 4 components — within the spec's recommended range, + comment: 6 categories, 4 components -- within the spec's recommended range, exercising the full percent-stack feature set. - id: DQ-02 name: Realistic Context @@ -227,7 +233,7 @@ review: comment: Renders via export default into the harness mount, skipAnimation set, current MUI X API used. library_mastery: - score: 9 + score: 10 max: 10 items: - id: LM-01 @@ -236,14 +242,15 @@ review: max: 5 passed: true comment: Full use of xAxis/yAxis config, valueFormatter, slotProps, categoryGapRatio, - disableTicks — idiomatic community-surface usage. + disableTicks -- idiomatic community-surface usage. - id: LM-02 name: Distinctive Features - score: 4 + score: 5 max: 5 passed: true - comment: Per-series label-color mapping via slotProps.barLabel and the tickFontSize - axis-offset trick show real library familiarity. + comment: Per-series label-color mapping via slotProps.barLabel, the tickFontSize + axis-offset trick, and targeted sx overrides on internal MUI X classes (.MuiChartsAxis-line/.MuiChartsGrid-line) + show real library familiarity. verdict: APPROVED impl_tags: dependencies: []