Skip to content

feat(chartjs): implement errorbar-basic#9526

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/errorbar-basic/chartjs
Jun 30, 2026
Merged

feat(chartjs): implement errorbar-basic#9526
MarkusNeusinger merged 6 commits into
mainfrom
implementation/errorbar-basic/chartjs

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Implementation: errorbar-basic - javascript/chartjs

Implements the javascript/chartjs version of errorbar-basic.

File: plots/errorbar-basic/implementations/javascript/chartjs.js

Parent Issue: #973


🤖 impl-generate workflow

@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white #FAF8F1 background (correct, not pure white). Title "errorbar-basic · javascript · chartjs · anyplot.ai" in dark ink at 22px, centered, spanning ~55% of canvas width — readable. X-axis title "Growth Temperature" and Y-axis title "Stem Length (cm)" in dark ink at 15px — balanced and descriptive. Tick labels in muted dark at 14px. Legend "Mean stem length (cm)" with green swatch at top-center. Five bars in brand green #009E73 at 60% opacity with solid border; I-shaped error bars in dark ink with horizontal caps at both ends, magnitudes varying from ±1.8 to ±3.4 cm. Bars form a natural inverted-U pattern peaking at 25 °C. All text is clearly readable against the light background — no legibility failures.

Dark render (plot-dark.png): Warm near-black #1A1A17 background (correct, not pure black). Title and all axis labels render in light cream/light-gray tokens — all readable. Legend text is light-colored. No dark-on-dark failures detected. Bar colors are identical to the light render (#009E73 at 60% opacity with solid border) — Imprint palette constant across themes. Error bars now render in white/light ink (t.ink flips to #F0EFE8 in dark mode) — highly visible against the teal bars. All text readable against the dark background.

Both paragraphs are required. A review that only describes one render is invalid.

Score: 83/100

Category Score Max
Visual Quality 29 30
Design Excellence 8 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 10 10
Library Mastery 7 10
Total 83 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — All sizes explicitly set (title 22px, axis titles 15px, ticks 14px, legend 16px); balanced axes; no overflow; readable in both themes
  • VQ-02: No Overlap (6/6) — No text or element collisions; error bars clear of axis labels
  • VQ-03: Element Visibility (6/6) — Bars clearly visible with opacity+border combination; I-caps clearly visible in both themes
  • VQ-04: Color Accessibility (2/2) — Single-series brand green; CVD-safe; error bar ink adapts per theme
  • VQ-05: Layout & Canvas (4/4) — Canvas gate passed; balanced margins; good layout padding
  • VQ-06: Axis Labels & Title (2/2) — Title in correct format; axis labels descriptive with units
  • VQ-07: Palette Compliance (2/2) — First series #009E73; bgPlugin sets t.pageBg; data colors identical across themes; chrome correctly adaptive

Design Excellence (8/20)

  • DE-01: Aesthetic Sophistication (4/8) — Well-configured default: alpha bars, rounded corners (borderRadius: 3), bgPlugin — but all four spines visible, grid on both axes; doesn't rise above a polished default
  • DE-02: Visual Refinement (2/6) — Library defaults with minimal customization; top/right spines not removed; grid showing on both X and Y axes (style guide: Y-axis only for bar charts)
  • DE-03: Data Storytelling (2/6) — Natural inverted-U shape is visible but no visual hierarchy guides the viewer; all bars identically styled; the 25 °C peak is not emphasized

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct error bar plot: bar chart base + I-bar whiskers with caps
  • SC-02: Required Features (4/4) — Visible caps, consistent cap widths (18 CSS px), symmetric errors, 5 groups (within 3–20 range)
  • SC-03: Data Mapping (3/3) — X: temperature categories; Y: stem length; error magnitudes correctly mapped
  • SC-04: Title & Legend (3/3) — Title matches exact format; legend label "Mean stem length (cm)" appropriate

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — Covers symmetric error bars with caps and varying error magnitudes; single series only — no multi-series or asymmetric error demonstration
  • DQ-02: Realistic Context (5/5) — Plant growth under temperature gradient: neutral scientific scenario, plausible values
  • DQ-03: Appropriate Scale (4/4) — Stem lengths 12–24 cm plausible; temperatures 15–35 °C appropriate; SDs 1.8–3.4 cm realistic

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear: data → plugins → mount → chart; no functions/classes
  • CQ-02: Reproducibility (2/2) — Fully hardcoded deterministic data; no RNG
  • CQ-03: Clean Imports (2/2) — No imports; all via globals (Chart, window.ANYPLOT_TOKENS)
  • CQ-04: Code Elegance (2/2) — Clean idiomatic JS; plugin objects well-structured; no over-engineering
  • CQ-05: Output & API (1/1) — Harness writes plot-{theme}.png + plot-{theme}.html; current Chart.js 4.4.7 API

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Plugin lifecycle hooks (afterDatasetsDraw), getPixelForValue(), getDatasetMeta() — genuine Chart.js API depth
  • LM-02: Distinctive Features (3/5) — Chart.js plugin system for custom canvas drawing is library-specific; hardcoded 18 px cap constant rather than using bar.width for proportional sizing is a minor missed opportunity

Score Caps Applied

  • None applied — DE-01 = 4 (> 2), so the "correct but boring" cap does not trigger

Strengths

  • Correct error bar type with I-bar caps and symmetric ±1 SD; varies error magnitude across groups
  • Custom Chart.js plugin using afterDatasetsDraw + getPixelForValue() + getDatasetMeta() — real Chart.js API depth
  • Both themes render correctly; bgPlugin fills canvas with t.pageBg; error bars adapt via t.ink token
  • All font sizes explicitly set and balanced; Imprint palette compliant; canvas gate passed
  • Realistic plant-growth dataset with a natural, story-ready inverted-U pattern

Weaknesses

  • Top/right spines not removed — add scales.x.border.display: false and scales.y.border.display: false, or use Chart.js's plugins.chartArea workaround
  • Grid on X axisscales.x.grid.display: false to restrict to Y-axis only (style guide: Y-only grid for bar charts)
  • No visual hierarchy on the peak — highlight the 25 °C bar (the story) with full opacity instead of the 60% applied uniformly, or a reference line at the optimal value
  • Cap width hardcoded at 18 CSS px — replace with bar.width * 0.4 so caps scale proportionally with bar width at any canvas size

Issues Found

  1. DE-02 LOW: All four spines visible; grid on both axes — both are Chart.js defaults not overridden
    • Fix: scales.x.grid.display: false; remove top/right border via Chart.js border options
  2. DE-03 LOW: No visual hierarchy; inverted-U pattern is data-implicit but not design-emphasized
    • Fix: Highlight the peak bar (i === 2) with full opacity or a distinct border color in the dataset config (use a backgroundColor array where means.map((_, i) => i === 2 ? t.palette[0] : t.palette[0] + '99'))
  3. LM-02 PARTIAL: Hardcoded 18 px cap width ignores bar geometry
    • Fix: Replace const CAP = 18 with const CAP = meta.data[i].width * 0.35

AI Feedback for Next Attempt

Remove top/right spines and restrict grid to Y-axis only (scales.x.grid.display: false). Add visual hierarchy by highlighting the peak bar at index 2 with full opacity while keeping other bars at 60% — this guides the viewer to the key insight (optimal growth temperature). Replace the hardcoded CAP = 18 with meta.data[i].width * 0.35 for proportional, canvas-size-aware caps.

Verdict: REJECTED

@github-actions github-actions Bot added quality:83 Quality score 83/100 ai-rejected Quality not OK, triggers update labels Jun 30, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 30, 2026
Attempt 1/3 - fixes based on AI review:
- Remove top/right spines via border.display:false + spinePlugin drawing L-shape
- Suppress x-axis grid (Y-only grid for bar charts per style guide)
- Highlight peak bar at 25°C with full opacity vs 60% for others (DE-03)
- Use bar.width * 0.35 for proportional error bar cap sizing (LM-02)
@github-actions

Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white #FAF8F1 background — correct. Title "errorbar-basic · javascript · chartjs · anyplot.ai" centered, dark ink, occupies ~55% of plot width, well-proportioned. Y-axis label "Stem Length (cm)" (with units) and X-axis label "Growth Temperature" are balanced in size and clearly readable. Tick labels are dark on light, no issues. L-shaped spine (left + bottom only) via custom spinePlugin replaces the default four-sided box. Y-axis horizontal gridlines only, subtle. Five bars in brand green #009E73 — peak bar (25 °C) at full opacity, remaining four at ~60% opacity, creating a visible inverted-U focal point. I-bar error bars drawn in dark ink with horizontal caps at top and bottom; cap width is proportional to bar width. Legend shows a green swatch labeled "Mean stem length (cm)". All text is readable against the light background — PASS.

Dark render (plot-dark.png): Warm near-black #1A1A17 background — correct. Title and axis labels flip to light off-white; tick labels similarly light. Error bar whiskers and caps render in white/light (t.ink = #F0EFE8 on dark theme), cleanly visible against the near-black surface. L-spine and gridlines use light-toned adaptive tokens. No dark-on-dark failures. Data bar colors are identical to the light render — same #009E73 green at the same opacity levels; peak emphasis is preserved. All chrome correctly adapts; both renders fully pass the readability check.

Score: 90/100

Category Score Max
Visual Quality 28 30
Design Excellence 13 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 9 10
Total 90 100

Visual Quality (28/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (title 22, legend 16, ticks 14, axis labels 15); well-proportioned in both themes, no overflow
  • VQ-02: No Overlap (6/6) — No overlapping text or data elements
  • VQ-03: Element Visibility (6/6) — Bars and I-bar error bars clearly visible; cap width proportional to bar width (35%)
  • VQ-04: Color Accessibility (2/2) — Single series in colorblind-safe brand green; error bars in high-contrast ink
  • VQ-05: Layout & Canvas (4/4) — Good proportions, balanced margins, no cut-off elements
  • VQ-06: Axis Labels & Title (2/2) — "Stem Length (cm)" with units; "Growth Temperature" descriptive
  • VQ-07: Palette Compliance (2/2) — First series #009E73; backgrounds #FAF8F1 / #1A1A17; data colors identical across themes; chrome fully theme-adaptive

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above well-configured defaults: custom spine plugin, L-frame, peak opacity emphasis; not quite FiveThirtyEight level
  • DE-02: Visual Refinement (4/6) — L-shaped spine via plugin, Y-only grid, rounded bar corners (borderRadius: 3), proportional caps; redundant single-series legend not removed
  • DE-03: Data Storytelling (4/6) — Clear inverted-U narrative; opacity variation at 25 °C peak guides viewer to the focal point

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct error bar chart using bar type with custom I-bar plugin
  • SC-02: Required Features (4/4) — Error bars with visible caps, consistent widths, symmetric errors, 5 groups within spec range
  • SC-03: Data Mapping (3/3) — Temperature on X (categorical), stem length on Y (numeric), ±error correctly mapped
  • SC-04: Title & Legend (3/3) — Title "errorbar-basic · javascript · chartjs · anyplot.ai" correct; legend label descriptive

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Varied error magnitudes (1.8–3.4 cm), inverted-U trend, visible caps on all bars
  • DQ-02: Realistic Context (5/5) — Plant growth × temperature study; real-world biology, neutral, comprehensible
  • DQ-03: Appropriate Scale (4/4) — Temperatures 15–35 °C and stem lengths 12–24 cm biologically plausible; peak at 25 °C realistic

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Header → data → plugins → mount → chart; clean linear structure
  • CQ-02: Reproducibility (2/2) — All data hardcoded; fully deterministic
  • CQ-03: Clean Imports (2/2) — No imports; Chart is global per harness contract; no extraneous globals
  • CQ-04: Code Elegance (2/2) — Clean, readable plugins; proportional cap calculation is concise
  • CQ-05: Output & API (1/1) — responsive:true, maintainAspectRatio:false, animation:false all set; harness handles file output

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — Correct use of Chart.js plugin system, lifecycle hooks, and scales.getPixelForValue() API
  • LM-02: Distinctive Features (4/5) — afterDatasetsDraw, afterDraw, beforeDraw hooks and getPixelForValue() are Chart.js-specific; not easily replicated in other libraries

Score Caps Applied

  • None

Strengths

  • Custom Chart.js plugin system (bgPlugin, spinePlugin, errorBarPlugin) demonstrates idiomatic use of Chart.js lifecycle hooks
  • Data storytelling via opacity emphasis — peak bar at 25 °C at full opacity, remaining bars at 60%, creating a clear inverted-U focal point
  • Proportional cap width (35% of bar width) and custom L-shaped spine show polished attention to detail
  • Fully theme-adaptive chrome: error bars use t.ink, backgrounds use t.pageBg, both renders correctly switch chrome without touching data colors
  • Realistic plant-growth scenario with plausible temperatures and biologically sensible inverted-U peak

Weaknesses

  • Single-series legend is redundant — the y-axis label already carries the same information; removing it would reduce visual noise and save vertical space
  • DE-01 ceiling: the composition is clean and intentional but stops short of publication-ready sophistication — a subtle annotation marking the 25 °C apex or a thin average reference line would elevate the storytelling
  • Error bar color uses t.ink (full primary text color) — a slightly softer t.inkSoft tone would let the data bars breathe more while keeping whiskers readable

Issues Found

  1. DE-01 MODERATE: Composition is polished but doesn't reach the highest tier — annotating the peak or adding a mean reference line would push it to FiveThirtyEight-level storytelling
  2. DE-02 MINOR: Single-series legend not removed despite style guide recommending removal to reduce chrome clutter

AI Feedback for Next Attempt

The implementation is strong. For the next attempt: (1) remove the legend (single-series — redundant with y-axis label); (2) optionally add a thin horizontal reference line at the overall mean or a small text annotation at the 25 °C peak bar to make the inverted-U narrative explicit; (3) consider using t.inkSoft instead of t.ink for error bar stroke color to soften the whiskers slightly. These changes would push DE-01 from 5 to 6-7 and DE-02 from 4 to 5.

Verdict: APPROVED

@github-actions github-actions Bot added quality:90 Quality score 90/100 ai-approved Quality OK, ready for merge and removed quality:83 Quality score 83/100 labels Jun 30, 2026
@MarkusNeusinger MarkusNeusinger merged commit 08d7118 into main Jun 30, 2026
1 check passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/errorbar-basic/chartjs branch June 30, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:90 Quality score 90/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant