Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions plots/bar-stacked-labeled/implementations/javascript/muix.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// anyplot.ai
// bar-stacked-labeled: Stacked Bar Chart with Total Labels
// Library: muix 7.29.1 | JavaScript 22.23.2
// Quality: 88/100 | Created: 2026-08-26
import { BarChart } from "@mui/x-charts/BarChart";
import { useXScale, useYScale } from "@mui/x-charts/hooks";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";

const t = window.ANYPLOT_TOKENS;

// --- Data (in-memory, deterministic) ----------------------------------------
// Project budget breakdown by phase, three stacked cost types (Imprint palette 1-3).
const phases = ["Planning", "Design", "Development", "Testing", "Deployment"];
const costTypes = ["Labor", "Materials", "Equipment"];
const labor = [18, 32, 58, 34, 22];
const materials = [6, 14, 20, 10, 8];
const equipment = [4, 10, 16, 6, 12];
const totals = phases.map((_, i) => labor[i] + materials[i] + equipment[i]);
const maxTotal = Math.max(...totals);

const TITLE = "bar-stacked-labeled · javascript · muix · anyplot.ai";
const TITLE_H = 56;

// --- Total labels (custom overlay, positioned via chart scales) -------------
function TotalLabels() {
const xScale = useXScale();
const yScale = useYScale();
return (
<g>
{phases.map((phase, i) => (
<text
key={phase}
x={xScale(phase) + xScale.bandwidth() / 2}
y={yScale(totals[i]) - 16}
textAnchor="middle"
fontSize={20}
fontWeight={700}
fill={t.ink}
>
{`$${totals[i]}k`}
</text>
))}
</g>
);
}

// --- Chart (default-exported component — the harness mounts it) -------------
export default function Chart() {
const { width, height } = window.ANYPLOT_SIZE;

return (
<Box
sx={{
width,
height,
bgcolor: t.pageBg,
display: "flex",
flexDirection: "column",
}}
>
<Box
sx={{
height: TITLE_H,
display: "flex",
alignItems: "center",
px: "40px",
pt: "10px",
}}
>
<Typography
sx={{
color: t.ink,
fontSize: "22px",
fontWeight: 600,
letterSpacing: "0.02em",
lineHeight: 1,
}}
>
{TITLE}
</Typography>
</Box>

<BarChart
width={width}
height={height - TITLE_H}
colors={t.palette}
skipAnimation
borderRadius={4}
grid={{ horizontal: true }}
xAxis={[
{
scaleType: "band",
data: phases,
label: "Project Phase",
},
]}
yAxis={[
{
label: "Cost ($ thousands)",
max: Math.ceil((maxTotal * 1.18) / 10) * 10,
tickFontSize: 14,
labelFontSize: 16,
tickSize: 8,
},
]}
series={[
{ data: labor, label: costTypes[0], stack: "total" },
{ data: materials, label: costTypes[1], stack: "total" },
{ data: equipment, label: costTypes[2], stack: "total" },
]}
margin={{ top: 30, right: 32, bottom: 90, left: 90 }}
sx={{
"& .MuiChartsAxis-tickLabel": { fontSize: "14px" },
"& .MuiChartsAxis-label": { fontSize: "16px", fontWeight: 600 },
"& .MuiChartsLegend-label": { fontSize: "15px" },
"& .MuiChartsGrid-line": { stroke: t.grid, strokeWidth: 1 },
"& .MuiBarElement-root": { stroke: t.pageBg, strokeWidth: 1.5 },
}}
slotProps={{
legend: { position: { vertical: "bottom", horizontal: "middle" } },
}}
>
<TotalLabels />
</BarChart>
</Box>
);
}
244 changes: 244 additions & 0 deletions plots/bar-stacked-labeled/metadata/javascript/muix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
library: muix
language: javascript
specification_id: bar-stacked-labeled
created: '2026-08-26T19:14:45Z'
updated: '2026-08-26T19:28:32Z'
generated_by: claude-sonnet
workflow_run: 33003514982
issue: 3504
language_version: 22.23.2
library_version: 7.29.1
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-labeled/javascript/muix/plot-light.png
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-labeled/javascript/muix/plot-dark.png
preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-labeled/javascript/muix/plot-light.html
preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-stacked-labeled/javascript/muix/plot-dark.html
quality_score: 88
review:
strengths:
- Correct use of MUI X's useXScale/useYScale hooks to render dynamic, scale-accurate
total labels above each stack — an idiomatic, distinctive solution to the spec's
core requirement.
- Repair pass added a subtle 1.5px pageBg-colored edge stroke and 4px border radius
to bar segments, giving clearer segment definition without breaking the Imprint
palette.
- Imprint palette applied correctly and identically across both themes (green →
lavender → blue canonical order), with fully theme-adaptive chrome (title, axes,
legend, total labels all flip correctly).
- Y-axis max computed with deliberate headroom (Math.ceil((maxTotal * 1.18) / 10)
* 10) specifically to leave room for total labels — directly satisfies the spec's
headroom note.
- Deterministic hardcoded data, skipAnimation set, clean imports — no extraneous
dependencies or fake functionality.
weaknesses:
- Design still reads close to a well-configured MUI X BarChart default beyond the
total-label overlay and the new edge/border-radius touches — no differentiating
typographic treatment, accent, or additional polish.
- No further visual hierarchy within each stack (e.g. optional per-segment value
labels for the dominant Labor segment) to reinforce the data story beyond the
total labels.
- Element visibility is good but unremarkable — bar widths and segment proportions
rely on library defaults rather than a deliberately tuned density-aware sizing.
image_description: |-
Light render (plot-light.png):
Background: Warm off-white, matches #FAF8F1 — not pure white.
Chrome: Bold dark title "bar-stacked-labeled · javascript · muix · anyplot.ai" top-left, clearly readable. Y-axis label "Cost ($ thousands)" and X-axis label "Project Phase" both dark, legible, and similarly sized/weighted (bolded in this attempt). Tick labels dark and legible. Horizontal gridlines subtle and light. Legend ("Labor", "Materials", "Equipment") centered below the plot, dark text, readable.
Data: Stacks use brand green (Labor, #009E73), lavender (Materials), and blue (Equipment) — canonical Imprint order, first series is #009E73 as required. Bars now show a thin cream-colored (pageBg) edge stroke and slight border radius separating segments, and each bar. Bold black total labels ("$28k", "$56k", "$94k", "$50k", "$42k") sit directly above each stack with clear headroom below the y=120 axis max.
Legibility verdict: PASS

Dark render (plot-dark.png):
Background: Warm near-black, matches #1A1A17 — not pure black.
Chrome: Title, axis labels, and tick labels flip to white/light text and remain clearly legible — no dark-on-dark issues anywhere. Legend text is white and readable. Gridlines remain subtle.
Data: Colors (green/lavender/blue) are pixel-identical to the light render, confirming only chrome flipped. The bar edge stroke now reads as a thin near-black (pageBg) separator between segments, consistent with the theme. Total labels flip to white text, clearly readable above each stack.
Legibility verdict: PASS
criteria_checklist:
visual_quality:
score: 28
max: 30
items:
- id: VQ-01
name: Text Legibility
score: 7
max: 8
passed: true
comment: All font sizes explicitly set, readable in both themes; title fits
without clipping
- id: VQ-02
name: No Overlap
score: 6
max: 6
passed: true
comment: No collisions between text, data, or legend
- id: VQ-03
name: Element Visibility
score: 5
max: 6
passed: true
comment: Bars clearly visible with new edge stroke + border radius, but sizing
still relies on library defaults
- id: VQ-04
name: Color Accessibility
score: 2
max: 2
passed: true
comment: Good contrast, CVD-safe; edge strokes aid segment distinction beyond
hue alone
- id: VQ-05
name: Layout & Canvas
score: 4
max: 4
passed: true
comment: Chart fills the canvas well, balanced margins, nothing cut off
- id: VQ-06
name: Axis Labels & Title
score: 2
max: 2
passed: true
comment: Descriptive axis labels with units (Cost ($ thousands))
- id: VQ-07
name: Palette Compliance
score: 2
max: 2
passed: true
comment: 'Canonical Imprint order, first series #009E73, theme-correct chrome
in both renders'
design_excellence:
score: 12
max: 20
items:
- id: DE-01
name: Aesthetic Sophistication
score: 5
max: 8
passed: false
comment: Border radius, edge strokes, and letter-spacing add polish above
a stock default, but overall still close to a well-configured MUI X chart
- id: DE-02
name: Visual Refinement
score: 4
max: 6
passed: false
comment: New pageBg edge stroke and border radius on bars give visible refinement;
grid subtle, spines minimal
- id: DE-03
name: Data Storytelling
score: 3
max: 6
passed: false
comment: Bold total labels create a clear focal point on the Development peak,
but segments aren't further differentiated for storytelling
spec_compliance:
score: 15
max: 15
items:
- id: SC-01
name: Plot Type
score: 5
max: 5
passed: true
comment: Correct stacked bar chart
- id: SC-02
name: Required Features
score: 4
max: 4
passed: true
comment: Total labels above each stack, adequate headroom, all spec features
present
- id: SC-03
name: Data Mapping
score: 3
max: 3
passed: true
comment: Category on x-axis, value stacked by component on y-axis
- id: SC-04
name: Title & Legend
score: 3
max: 3
passed: true
comment: Title format correct; legend labels match cost-type series
data_quality:
score: 15
max: 15
items:
- id: DQ-01
name: Feature Coverage
score: 6
max: 6
passed: true
comment: Segment proportions vary meaningfully across phases (Development
dominated by Labor, Planning more balanced)
- id: DQ-02
name: Realistic Context
score: 5
max: 5
passed: true
comment: Neutral, realistic project-budget-by-phase scenario
- id: DQ-03
name: Appropriate Scale
score: 4
max: 4
passed: true
comment: Plausible cost figures and proportions for a project budget in $
thousands
code_quality:
score: 10
max: 10
items:
- id: CQ-01
name: KISS Structure
score: 3
max: 3
passed: true
comment: Straightforward data → overlay component → chart; TotalLabels component
is required for the hooks pattern, not over-engineering
- id: CQ-02
name: Reproducibility
score: 2
max: 2
passed: true
comment: Deterministic hardcoded arrays
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
comment: Only used imports (BarChart, hooks, Box, Typography)
- id: CQ-04
name: Code Elegance
score: 2
max: 2
passed: true
comment: Appropriate complexity, no fake functionality
- id: CQ-05
name: Output & API
score: 1
max: 1
passed: true
comment: Harness-mounted component, current MUI X API
library_mastery:
score: 8
max: 10
items:
- id: LM-01
name: Idiomatic Usage
score: 4
max: 5
passed: true
comment: Correct high-level BarChart API usage, stack config, sx/slotProps
overrides
- id: LM-02
name: Distinctive Features
score: 4
max: 5
passed: true
comment: useXScale/useYScale hooks drive a scale-accurate custom overlay —
distinctive to MUI X
verdict: APPROVED
impl_tags:
dependencies: []
techniques:
- annotations
patterns:
- data-generation
dataprep: []
styling:
- edge-highlighting
Loading