Skip to content

Commit aeb08a7

Browse files
feat(muix): implement errorbar-basic (#9530)
## Implementation: `errorbar-basic` - javascript/muix Implements the **javascript/muix** version of `errorbar-basic`. **File:** `plots/errorbar-basic/implementations/javascript/muix.tsx` **Parent Issue:** #973 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/28474424869)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
1 parent 98ce8ff commit aeb08a7

2 files changed

Lines changed: 397 additions & 0 deletions

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// anyplot.ai
2+
// errorbar-basic: Basic Error Bar Plot
3+
// Library: muix 7.29.1 | JavaScript 22.23.0
4+
// Quality: 88/100 | Created: 2026-06-30
5+
//# anyplot-orientation: landscape
6+
// anyplot.ai
7+
// errorbar-basic: Basic Error Bar Plot
8+
// Library: MUI X Charts | React | Node 22
9+
// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope.
10+
// Quality: pending | Created: 2026-06-30
11+
12+
import { ChartContainer } from "@mui/x-charts/ChartContainer";
13+
import { BarPlot } from "@mui/x-charts/BarChart";
14+
import { ChartsXAxis } from "@mui/x-charts/ChartsXAxis";
15+
import { ChartsYAxis } from "@mui/x-charts/ChartsYAxis";
16+
import { ChartsGrid } from "@mui/x-charts/ChartsGrid";
17+
import { ChartsReferenceLine } from "@mui/x-charts/ChartsReferenceLine";
18+
import { useXScale, useYScale } from "@mui/x-charts/hooks";
19+
20+
const t = window.ANYPLOT_TOKENS;
21+
22+
// Plant stress experiment: mean stem elongation (cm/week) ± 1 SD across 7 growth conditions
23+
const CONDITIONS = ["Control", "Low Temp", "High Temp", "Low pH", "High pH", "Drought", "Flood"];
24+
const MEANS = [4.2, 2.8, 3.1, 2.4, 3.6, 1.9, 2.2];
25+
const ERRORS = [0.5, 0.7, 0.6, 0.8, 0.5, 0.6, 0.9];
26+
27+
// Visual hierarchy: Control=full brand green (benchmark), Drought=amber (stress/caution),
28+
// intermediate conditions=muted brand green to draw the eye to the key contrast
29+
const BAR_COLORS = CONDITIONS.map((c) => {
30+
if (c === "Control") return t.palette[0]; // #009E73 — optimal/reference
31+
if (c === "Drought") return t.amber; // #DDCC77 — peak stress (caution anchor)
32+
return t.palette[0] + "99"; // ~60% opacity — intermediate conditions
33+
});
34+
35+
// ErrorBars renders ±1 SD whiskers using the CartesianContext scale functions
36+
function ErrorBars() {
37+
const xScale = useXScale("x");
38+
const yScale = useYScale("y");
39+
if (!xScale || !yScale) return null;
40+
41+
const bw = (xScale as any).bandwidth();
42+
const cap = Math.round(bw * 0.19); // 19% of bandwidth for readable caps
43+
44+
return (
45+
<g>
46+
{CONDITIONS.map((cond, i) => {
47+
const cx = (xScale as any)(cond) + bw / 2;
48+
const yTop = (yScale as any)(MEANS[i] + ERRORS[i]);
49+
const yBot = (yScale as any)(MEANS[i] - ERRORS[i]);
50+
return (
51+
<g key={cond}>
52+
{/* Vertical whisker */}
53+
<line x1={cx} y1={yTop} x2={cx} y2={yBot}
54+
stroke={t.ink} strokeWidth={3} strokeOpacity={0.7} strokeLinecap="round" />
55+
{/* Top cap */}
56+
<line x1={cx - cap} y1={yTop} x2={cx + cap} y2={yTop}
57+
stroke={t.ink} strokeWidth={3} strokeOpacity={0.7} strokeLinecap="round" />
58+
{/* Bottom cap */}
59+
<line x1={cx - cap} y1={yBot} x2={cx + cap} y2={yBot}
60+
stroke={t.ink} strokeWidth={3} strokeOpacity={0.7} strokeLinecap="round" />
61+
</g>
62+
);
63+
})}
64+
</g>
65+
);
66+
}
67+
68+
export default function Chart() {
69+
const W = window.ANYPLOT_SIZE.width;
70+
const H = window.ANYPLOT_SIZE.height;
71+
72+
const title = "Seedling Growth Under Stress · errorbar-basic · javascript · muix · anyplot.ai";
73+
const titleSize = title.length > 67 ? Math.round(22 * 67 / title.length) : 22;
74+
75+
return (
76+
<ChartContainer
77+
width={W}
78+
height={H}
79+
series={[{
80+
type: "bar",
81+
data: MEANS,
82+
id: "growth",
83+
label: "Mean Stem Elongation (cm/week)",
84+
xAxisId: "x",
85+
yAxisId: "y",
86+
}]}
87+
xAxis={[{
88+
id: "x",
89+
scaleType: "band",
90+
data: CONDITIONS,
91+
colorMap: {
92+
type: "ordinal",
93+
values: CONDITIONS,
94+
colors: BAR_COLORS,
95+
},
96+
}]}
97+
yAxis={[{
98+
id: "y",
99+
min: 0,
100+
max: 6,
101+
}]}
102+
margin={{ top: 72, bottom: 92, left: 100, right: 100 }}
103+
>
104+
<ChartsGrid horizontal />
105+
<BarPlot skipAnimation borderRadius={4} />
106+
<ErrorBars />
107+
<ChartsReferenceLine
108+
y={MEANS[0]}
109+
axisId="y"
110+
label="Control baseline"
111+
labelAlign="end"
112+
lineStyle={{ stroke: t.inkSoft, strokeDasharray: "6 4", strokeWidth: 1.5 }}
113+
labelStyle={{ fontSize: 13, fill: t.inkSoft, fontStyle: "italic" }}
114+
/>
115+
<ChartsXAxis
116+
axisId="x"
117+
label="Growth Condition"
118+
labelStyle={{ fontSize: 16 }}
119+
tickLabelStyle={{ fontSize: 14 }}
120+
/>
121+
<ChartsYAxis
122+
axisId="y"
123+
label="Mean Stem Elongation (cm / week)"
124+
labelStyle={{ fontSize: 16 }}
125+
tickLabelStyle={{ fontSize: 14 }}
126+
/>
127+
<text
128+
x={W / 2}
129+
y={36}
130+
textAnchor="middle"
131+
dominantBaseline="middle"
132+
fontSize={titleSize}
133+
fontWeight={600}
134+
fill={t.ink}
135+
fontFamily="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
136+
>
137+
{title}
138+
</text>
139+
</ChartContainer>
140+
);
141+
}
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
library: muix
2+
language: javascript
3+
specification_id: errorbar-basic
4+
created: '2026-06-30T20:49:39Z'
5+
updated: '2026-06-30T21:09:46Z'
6+
generated_by: claude-sonnet
7+
workflow_run: 28474424869
8+
issue: 973
9+
language_version: 22.23.0
10+
library_version: 7.29.1
11+
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/javascript/muix/plot-light.png
12+
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/javascript/muix/plot-dark.png
13+
preview_html_light: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/javascript/muix/plot-light.html
14+
preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/javascript/muix/plot-dark.html
15+
quality_score: 88
16+
review:
17+
strengths:
18+
- Semantic color hierarchy (full green = optimal/reference, amber = caution/peak
19+
stress, muted green = intermediate) creates an immediate self-explaining narrative
20+
about plant stress severity
21+
- Custom SVG ErrorBars component correctly uses CartesianContext hooks (useXScale/useYScale)
22+
— the idiomatic MUI X approach for custom SVG overlays inside ChartContainer
23+
- ChartsReferenceLine baseline at y=4.2 anchors all comparisons visually with minimal
24+
code and an inline label
25+
- Both themes render correctly with fully readable text; ThemeProvider chrome adaptation
26+
is seamless — no dark-on-dark failures
27+
- 'Perfect spec compliance: error bars with visible caps, consistent widths, color-coded
28+
groups, and all data correctly mapped'
29+
weaknesses:
30+
- Duplicate header comment block at top of file (lines 1-4 contain old muix 7.29.1
31+
header, followed by correct MUI X Charts header at lines 7-10) — remove the first
32+
block
33+
- Axis label font size (16px) is slightly on the larger side for a 3200x1800 landscape
34+
canvas; 14px would be more proportional while maintaining readability
35+
- MUI X default axis chrome still visible — no explicit spine suppression; adding
36+
slotProps or sx overrides to remove top/right axis lines would improve DE-02 refinement
37+
image_description: |-
38+
Light render (plot-light.png):
39+
Background: Warm off-white (#FAF8F1) — correct theme surface, not pure white
40+
Chrome: Title "Seedling Growth Under Stress · errorbar-basic · javascript · muix · anyplot.ai" in dark ink, readable; Y-axis label "Mean Stem Elongation (cm / week)" vertical, readable; X-axis label "Growth Condition" readable; tick labels 0.0-6.0 (Y) and 7 condition names (X) all clearly visible; "Control baseline" reference label at right edge readable in italic style
41+
Data: Control bar = full brand green #009E73; Drought bar = amber #DDCC77 (semantic caution anchor); Low Temp/High Temp/Low pH/High pH/Flood = brand green at ~60% opacity; all bars have black-ink error bars with visible end caps; dashed baseline reference line at y=4.2 spans full plot width
42+
Legibility verdict: PASS — all text clearly readable against warm off-white background; no light-on-light issues
43+
44+
Dark render (plot-dark.png):
45+
Background: Warm near-black (#1A1A17) — correct dark theme surface, not pure black
46+
Chrome: Title, axis labels, tick labels, and "Control baseline" label all render in warm near-white (ThemeProvider ink token flipped to F0EFE8); all clearly legible against dark background; error bar strokes appear white/light; no dark-on-dark failures detected
47+
Data: Colors identical to light render — Control = #009E73, Drought = #DDCC77, intermediates = muted brand green; data visual identity preserved across both themes
48+
Legibility verdict: PASS — all text clearly readable against dark background; ThemeProvider chrome adaptation is seamless
49+
criteria_checklist:
50+
visual_quality:
51+
score: 29
52+
max: 30
53+
items:
54+
- id: VQ-01
55+
name: Text Legibility
56+
score: 7
57+
max: 8
58+
passed: true
59+
comment: All text readable in both themes. Title scaled via formula for 74-char
60+
title (~20px). Axis labels 16px, tick labels 14px — slightly larger than
61+
needed for landscape canvas but within acceptable range.
62+
- id: VQ-02
63+
name: No Overlap
64+
score: 6
65+
max: 6
66+
passed: true
67+
comment: No text/data collisions in either render; error bars clear of all
68+
labels.
69+
- id: VQ-03
70+
name: Element Visibility
71+
score: 6
72+
max: 6
73+
passed: true
74+
comment: Error bar whiskers and caps clearly visible in both renders; bar
75+
fills clearly distinguishable; baseline reference line visible.
76+
- id: VQ-04
77+
name: Color Accessibility
78+
score: 2
79+
max: 2
80+
passed: true
81+
comment: Imprint palette + amber anchor; CVD-safe.
82+
- id: VQ-05
83+
name: Layout & Canvas
84+
score: 4
85+
max: 4
86+
passed: true
87+
comment: Canvas gate passed (landscape 3200x1800); generous margins (top:72,
88+
bottom:92, left:100, right:100); no clipping detected.
89+
- id: VQ-06
90+
name: Axis Labels & Title
91+
score: 2
92+
max: 2
93+
passed: true
94+
comment: Y-axis has units (cm / week); X-axis descriptive; title correctly
95+
formatted with spec-id, language, library, anyplot.ai.
96+
- id: VQ-07
97+
name: Palette Compliance
98+
score: 2
99+
max: 2
100+
passed: true
101+
comment: 'Control = #009E73 (first series); Drought = #DDCC77 (amber semantic
102+
anchor for caution); intermediates = brand green with alpha (single-series
103+
design choice). Backgrounds correct: #FAF8F1 / #1A1A17. Data colors identical
104+
across themes.'
105+
design_excellence:
106+
score: 12
107+
max: 20
108+
items:
109+
- id: DE-01
110+
name: Aesthetic Sophistication
111+
score: 5
112+
max: 8
113+
passed: true
114+
comment: Semantic color hierarchy (full green = optimal, amber = peak stress,
115+
muted green = intermediate) is deliberate and effective. Reference baseline
116+
line adds contextual sophistication. Above default floor of 4.
117+
- id: DE-02
118+
name: Visual Refinement
119+
score: 3
120+
max: 6
121+
passed: true
122+
comment: Border radius on bars, horizontal-only subtle grid, no visible top/right
123+
spines, generous margins. Solid refinement above default floor of 2, but
124+
overall chrome is still MUI X default.
125+
- id: DE-03
126+
name: Data Storytelling
127+
score: 4
128+
max: 6
129+
passed: true
130+
comment: 'Clear focal narrative: Control as reference, Drought as worst stressor,
131+
intermediate conditions semantically grouped. Baseline dashed line anchors
132+
the comparison. Visual hierarchy guides reader''s eye.'
133+
spec_compliance:
134+
score: 15
135+
max: 15
136+
items:
137+
- id: SC-01
138+
name: Plot Type
139+
score: 5
140+
max: 5
141+
passed: true
142+
comment: Correct bar+error-bar chart type; custom SVG error bars overlaid
143+
on MUI X BarPlot.
144+
- id: SC-02
145+
name: Required Features
146+
score: 4
147+
max: 4
148+
passed: true
149+
comment: Visible caps on all error bars; consistent widths; color variation
150+
across groups; symmetric +/-1 SD errors.
151+
- id: SC-03
152+
name: Data Mapping
153+
score: 3
154+
max: 3
155+
passed: true
156+
comment: X = categorical conditions; Y = mean stem elongation; error = +/-1
157+
SD; full data range shown.
158+
- id: SC-04
159+
name: Title & Legend
160+
score: 3
161+
max: 3
162+
passed: true
163+
comment: Title matches {Descriptive Title} · {spec-id} · {language} · {library}
164+
· anyplot.ai format. Single-series chart; legend omitted correctly.
165+
data_quality:
166+
score: 15
167+
max: 15
168+
items:
169+
- id: DQ-01
170+
name: Feature Coverage
171+
score: 6
172+
max: 6
173+
passed: true
174+
comment: 'All error bar features present: central values, +/-1 SD whiskers
175+
with caps, reference baseline, color-coded groups.'
176+
- id: DQ-02
177+
name: Realistic Context
178+
score: 5
179+
max: 5
180+
passed: true
181+
comment: Plant stress experiment is scientifically plausible; cm/week growth
182+
rates and SD magnitudes are realistic; neutral subject matter.
183+
- id: DQ-03
184+
name: Appropriate Scale
185+
score: 4
186+
max: 4
187+
passed: true
188+
comment: Y 0-6 cm/week is appropriate; 7 conditions within spec's 3-20 range;
189+
error magnitudes (0.5-0.9) proportionate to means.
190+
code_quality:
191+
score: 9
192+
max: 10
193+
items:
194+
- id: CQ-01
195+
name: KISS Structure
196+
score: 2
197+
max: 3
198+
passed: true
199+
comment: One necessary sub-component (ErrorBars) required to access CartesianContext
200+
hooks — unavoidable in MUI X. Minor complexity trade-off.
201+
- id: CQ-02
202+
name: Reproducibility
203+
score: 2
204+
max: 2
205+
passed: true
206+
comment: All data hardcoded; no RNG.
207+
- id: CQ-03
208+
name: Clean Imports
209+
score: 2
210+
max: 2
211+
passed: true
212+
comment: All 8 imports are used; no dead imports.
213+
- id: CQ-04
214+
name: Code Elegance
215+
score: 2
216+
max: 2
217+
passed: true
218+
comment: Semantic color comments explain design intent clearly; as any casts
219+
scoped appropriately; no fake interactivity.
220+
- id: CQ-05
221+
name: Output & API
222+
score: 1
223+
max: 1
224+
passed: true
225+
comment: Default-export component; harness handles screenshots; community
226+
@mui/x-charts only.
227+
library_mastery:
228+
score: 8
229+
max: 10
230+
items:
231+
- id: LM-01
232+
name: Idiomatic Usage
233+
score: 4
234+
max: 5
235+
passed: true
236+
comment: Uses ChartContainer composition pattern (more idiomatic than top-level
237+
BarChart for mixed content); proper hook-based scale access.
238+
- id: LM-02
239+
name: Distinctive Features
240+
score: 4
241+
max: 5
242+
passed: true
243+
comment: useXScale/useYScale CartesianContext hooks for custom SVG overlay;
244+
colorMap.type:ordinal per-bar coloring on xAxis; ChartsReferenceLine with
245+
inline label — three distinctly MUI X features.
246+
verdict: APPROVED
247+
impl_tags:
248+
dependencies: []
249+
techniques:
250+
- layer-composition
251+
- annotations
252+
patterns:
253+
- iteration-over-groups
254+
dataprep: []
255+
styling:
256+
- alpha-blending

0 commit comments

Comments
 (0)