diff --git a/plots/scatter-connected-temporal/implementations/javascript/muix.tsx b/plots/scatter-connected-temporal/implementations/javascript/muix.tsx new file mode 100644 index 0000000000..081166c23a --- /dev/null +++ b/plots/scatter-connected-temporal/implementations/javascript/muix.tsx @@ -0,0 +1,204 @@ +// anyplot.ai +// scatter-connected-temporal: Connected Scatter Plot with Temporal Path +// Library: muix 7.29.1 | JavaScript 22.22.3 +// Quality: 90/100 | Updated: 2026-06-10 + +import { LineChart, useXScale, useYScale } from "@mui/x-charts"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; + +const t = window.ANYPLOT_TOKENS; + +// US Phillips curve: unemployment rate (%) vs. inflation rate (%), 1970–2009 +const unemployment = [ + 4.9, 5.9, 5.6, 4.9, 5.6, 8.5, 7.7, 7.1, 6.1, 5.8, // 1970-1979 + 7.1, 7.6, 9.7, 9.6, 7.5, 7.2, 7.0, 6.2, 5.5, 5.3, // 1980-1989 + 5.6, 6.8, 7.5, 6.9, 6.1, 5.6, 5.4, 4.9, 4.5, 4.2, // 1990-1999 + 4.0, 4.7, 5.8, 6.0, 5.5, 5.1, 4.6, 4.6, 5.8, 9.3, // 2000-2009 +]; + +const inflation = [ + 5.7, 4.4, 3.2, 6.2, 11.0, 9.1, 5.8, 6.5, 7.6, 11.3, // 1970-1979 + 13.5, 10.3, 6.2, 3.2, 4.3, 3.6, 1.9, 3.6, 4.1, 4.8, // 1980-1989 + 5.4, 4.2, 3.0, 3.0, 2.6, 2.8, 3.0, 2.3, 1.6, 2.2, // 1990-1999 + 3.4, 2.8, 1.6, 2.3, 2.7, 3.4, 3.2, 2.9, 3.8, -0.4, // 2000-2009 +]; + +// Decade segments — overlap at boundary indices for seamless path connection +const s1970s = inflation.map((v, i) => (i <= 9 ? v : null)); +const s1980s = inflation.map((v, i) => (i >= 9 && i <= 19 ? v : null)); +const s1990s = inflation.map((v, i) => (i >= 19 && i <= 29 ? v : null)); +const s2000s = inflation.map((v, i) => (i >= 29 ? v : null)); + +// Decade start/end + notable event year annotations [index, label, dx, dy] +const KEY_POINTS = [ + { i: 0, label: "1970", dx: -30, dy: -10 }, + { i: 3, label: "1973", dx: 8, dy: -10 }, // oil shock + { i: 9, label: "1979", dx: 10, dy: -8 }, + { i: 10, label: "1980", dx: -30, dy: -10 }, + { i: 19, label: "1989", dx: 12, dy: 12 }, + { i: 20, label: "1990", dx: -30, dy: -8 }, + { i: 29, label: "1999", dx: 12, dy: 6 }, + { i: 30, label: "2000", dx: -30, dy: -8 }, + { i: 38, label: "2008", dx: 10, dy: -10 }, // financial crisis + { i: 39, label: "2009", dx: 10, dy: 8 }, +]; + +// One directional arrow per decade at its midpoint to show temporal flow +const ARROWS = [ + { i: 5, color: t.palette[0] }, // 1975 (1970s midpoint) + { i: 15, color: t.palette[1] }, // 1985 (1980s midpoint) + { i: 24, color: t.palette[2] }, // 1994 (1990s midpoint) + { i: 34, color: t.palette[3] }, // 2004 (2000s midpoint) +]; + +// Custom overlay rendered inside the LineChart SVG via the children prop. +// Uses useXScale/useYScale (MUI X composition hooks) to convert data coordinates +// to SVG pixel positions for year annotations and directional arrows. +function TemporalOverlay() { + const xScale = useXScale(); + const yScale = useYScale(); + if (!xScale || !yScale) return null; + + return ( + + + {ARROWS.map(({ color }, idx) => ( + + + + ))} + + + {/* Direction arrows at decade midpoints */} + {ARROWS.map(({ i, color }, idx) => { + const x1 = xScale(unemployment[i - 1]); + const y1 = yScale(inflation[i - 1]); + const x2 = xScale(unemployment[i + 1]); + const y2 = yScale(inflation[i + 1]); + if (x1 == null || y1 == null || x2 == null || y2 == null) return null; + const mx = (x1 + x2) / 2; + const my = (y1 + y2) / 2; + const dx = x2 - x1; + const dy = y2 - y1; + const len = Math.sqrt(dx * dx + dy * dy) || 1; + const s = 20 / len; + return ( + + ); + })} + + {/* Year annotations at decade boundaries and notable events */} + {KEY_POINTS.map(({ i, label, dx, dy }) => { + const x = xScale(unemployment[i]); + const y = yScale(inflation[i]); + if (x == null || y == null) return null; + return ( + + {label} + + ); + })} + + ); +} + +// Larger filled markers (r=6) with page-bg outline to distinguish connected-scatter from plain line +function CustomMark({ x, y, color }) { + return ; +} + +const TITLE_H = 52; + +export default function Chart() { + const W = window.ANYPLOT_SIZE.width; + const H = window.ANYPLOT_SIZE.height; + + return ( + + + Phillips Curve · scatter-connected-temporal · javascript · muix · anyplot.ai + + + + + + ); +} diff --git a/plots/scatter-connected-temporal/metadata/javascript/muix.yaml b/plots/scatter-connected-temporal/metadata/javascript/muix.yaml new file mode 100644 index 0000000000..d84f3cd9ed --- /dev/null +++ b/plots/scatter-connected-temporal/metadata/javascript/muix.yaml @@ -0,0 +1,262 @@ +library: muix +language: javascript +specification_id: scatter-connected-temporal +created: '2026-06-09T23:50:44Z' +updated: '2026-06-10T00:21:00Z' +generated_by: claude-sonnet +workflow_run: 27242702921 +issue: 4675 +language_version: 22.22.3 +library_version: 7.29.1 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/muix/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/muix/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/muix/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/muix/plot-dark.html +quality_score: 90 +review: + strengths: + - Historically accurate US Phillips Curve data (1970-2009) providing real economic + context and factual accuracy + - Excellent use of MUI X composition API (useXScale/useYScale) for data-coordinate + custom SVG overlay — a genuinely distinctive library feature + - Four-color decade segmentation with directional arrowheads creates clear temporal + narrative + - Null-masking for decade path segmentation is an elegant MUI X pattern for multi-series + line charts with gaps + - Year annotations at the 1973 oil shock and 2008 financial crisis provide narrative + depth without over-annotating + - Correct Imprint palette application with t.palette[0]-[3] and theme-adaptive chrome + through ANYPLOT_TOKENS + weaknesses: + - Title font size (19px CSS) is slightly below the 22px CSS guideline for JS libraries; + minor legibility reduction at small display sizes + - Annotation text (fontSize=12 SVG units) is on the smaller side for mobile readability + — increase to 13-14 + - MUI X default chart frame/border retained; removing or softening via sx override + would improve visual refinement (DE-02) + - Lower-left annotation cluster (1989/1990, 1999/2000 labels near 4-6% unemployment) + is dense, though not overlapping thanks to dx/dy offsets + image_description: |- + Light render (plot-light.png): + Background: Warm off-white approximately #FAF8F1 — correct light theme surface + Chrome: Title "Phillips Curve · scatter-connected-temporal · javascript · muix · anyplot.ai" in dark ink, centered at top (fontSize 19 CSS). X-axis label "Unemployment Rate (%)" and Y-axis label "Inflation Rate (%)" in dark ink with explicit sizes. Tick labels (fontSize 14 CSS) clearly readable. Year annotation labels (fontSize 12 SVG) visible but small. + Data: 4 decade paths — 1970s in #009E73 (first series, brand green ✓), 1980s in #C475FD (lavender), 1990s in #4467A3 (blue), 2000s in #BD8233 (ochre). Custom circle markers (r=6) with page-bg outline stroke. Directional arrowheads at decade midpoints. Year annotations at 1970, 1973, 1979, 1980, 1989, 1990, 1999, 2000, 2008, 2009. + Legibility verdict: PASS — all text readable against warm off-white background + + Dark render (plot-dark.png): + Background: Near-black approximately #1A1A17 — correct dark theme surface + Chrome: Title, axis labels, and tick labels all render in light/cream-colored text — no dark-on-dark failures detected. Year annotations use t.inkSoft which is theme-adaptive. Chart frame and grid lines adapt correctly. + Data: Colors identical to light render — 1970s green, 1980s lavender, 1990s blue, 2000s ochre. Custom markers and arrowheads at same positions with same colors. Chrome-only flip confirmed. + Legibility verdict: PASS — all text clearly readable against near-black background, no dark-on-dark failures + criteria_checklist: + visual_quality: + score: 27 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 6 + max: 8 + passed: true + comment: 'All font sizes explicitly set (title 19px CSS, axis labels 16px, + ticks 14px, annotations 12px SVG). All readable in both themes. Slight dock: + title below 22px CSS guideline and annotations small for mobile.' + - id: VQ-02 + name: No Overlap + score: 5 + max: 6 + passed: true + comment: Decade-boundary labels use opposite dx/dy offsets to minimize crowding. + Lower-left cluster is tight but readable without clear collision. + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Custom circle marks (r=6 CSS px) with page-bg stroke are perfectly + sized for 10 points per series. Line strokeWidth=2.5 appropriate for data + density. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette provides CVD-safe spacing across 4 hue families. + Directional arrows use same series colors for redundant encoding. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: No canvas gate failure. Chart fills 848/900 CSS px height. Balanced + margins, legend inside plot area top-right, no edge clipping. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Unemployment Rate (%) and Inflation Rate (%) with units. Descriptive + title prefix Phillips Curve. + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series #009E73 correct. Imprint palette canonical order for + subsequent series. Background #FAF8F1/#1A1A17. Chrome theme-correct in both + renders.' + design_excellence: + score: 15 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: 'Clearly above generic defaults: Imprint palette correctly applied, + custom SVG markers with page-bg outlines, directional arrowheads, professional + Phillips Curve narrative. Not quite publication-ready.' + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: Grid opacity reduced to 0.25 via sx override, custom circle marks, + line strokeWidth set. MUI X default chart frame retained, capping at good + not perfect. + - id: DE-03 + name: Data Storytelling + score: 5 + max: 6 + passed: true + comment: 'Clear visual hierarchy: color differentiates decades, arrows encode + direction, annotations at 1973 oil shock and 2008 financial crisis create + focal narrative moments.' + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct connected scatter with temporal path. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: 'All features present: chronological connection, key point annotations, + directional arrows, visible markers, color temporal encoding.' + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X=unemployment, Y=inflation, time as traversal order and decade hue. + All 40 years shown. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title follows Phillips Curve · scatter-connected-temporal · javascript + · muix · anyplot.ai format. Legend shows decade labels. + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: 'Shows all aspects: connected path, directional flow, multi-series + temporal segmentation, annotations at economic events.' + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: US Phillips Curve data 1970-2009 is real and well-known. Neutral + economic domain. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: 'Values historically accurate: 1980 inflation 13.5%, 2009 unemployment + 9.3%, negative 2009 inflation -0.4%.' + code_quality: + score: 9 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 2 + max: 3 + passed: true + comment: Clean structure but two helper components (TemporalOverlay, CustomMark) + add complexity. Both are architecturally necessary for React/MUI X hooks + pattern. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: All data hard-coded as constants. Fully deterministic, no RNG. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: 'All imports used: LineChart, useXScale, useYScale, Box, Typography.' + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean idiomatic React/MUI X code. Null-masking for decade segmentation + is elegant. No fake functionality. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Harness handles plot-light.png/dark.png + HTML output. + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: 'Expert use of MUI X composition pattern: useXScale/useYScale hooks + inside child component, slots.mark, slotProps.legend, skipAnimation, sx + overrides — all idiomatic.' + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: 'useXScale/useYScale composition hooks for data-coordinate SVG overlay + is distinctive MUI X feature. slots.mark custom renderer. Minor dock: arrowhead + SVG is hand-rolled rather than a native MUI X feature.' + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - annotations + - html-export + - layer-composition + patterns: + - data-generation + - iteration-over-groups + dataprep: [] + styling: + - edge-highlighting + - grid-styling