Skip to content

feat(chartjs): implement acf-pacf#8576

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/acf-pacf/chartjs
Jun 10, 2026
Merged

feat(chartjs): implement acf-pacf#8576
MarkusNeusinger merged 6 commits into
mainfrom
implementation/acf-pacf/chartjs

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Implementation: acf-pacf - javascript/chartjs

Implements the javascript/chartjs version of acf-pacf.

File: plots/acf-pacf/implementations/javascript/chartjs.js

Parent Issue: #4663


🤖 impl-generate workflow

@claude

claude Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Two vertically stacked bar/stem subplots on a warm off-white (#FAF8F1) background. The top subplot shows the ACF for lags 0–30, with lag 0 anchored at 1.0 and an exponentially decaying pattern typical of an AR(2) process. Positive bars are rendered in brand green (#009E73); one or two small near-zero lags near the right edge briefly go negative (matte red #AE3030). The bottom subplot shows the PACF for lags 1–30, with a prominent bar at lag 1 (~0.78) and a smaller bar at lag 2 (~0.1), then mostly near-zero values — the expected AR(2) cutoff. Negative PACF values are correctly rendered in matte red. Horizontal dashed CI lines (±1.96/√240 ≈ ±0.127) are present in both subplots. The overall title 'acf-pacf · javascript · chartjs · anyplot.ai' is bold and centered. Y-axes are labeled 'ACF' and 'PACF'; 'Lag' appears only on the bottom x-axis (shared-axis convention). A '95% CI' dashed-line legend entry appears above each subplot. All text is clearly readable against the light background.

Dark render (plot-dark.png): Identical layout and data on a warm near-black (#1A1A17) background. The title, axis labels, and tick labels flip to light-colored text, all clearly readable against the dark surface. Data colors are unchanged — brand green and matte red are identical to the light render, consistent with Imprint palette rules. CI dashed lines remain visible. Grid lines are subtle. No dark-on-dark failures; the implementation correctly threads theme tokens to all chrome elements. Both renders pass the legibility check.

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

Score: 88/100

Category Score Max
Visual Quality 28 30
Design Excellence 12 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 8 10
Total 88 100

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (13px ticks, 14px axis titles, 22px overall title). Readable in both themes. Minor: tick size at 13px CSS (26 source px) is fractionally below the recommended 14px; title proportion ~70% of width is well within expected range for the mandated format.
  • VQ-02: No Overlap (6/6) — No overlapping text or data elements in either render.
  • VQ-03: Element Visibility (5/6) — Significant correlation bars clearly visible. Near-zero PACF bars (values <0.05) resolve to ~5 source px tall at barThickness:4, data-accurate but extremely thin; a slightly larger barThickness (6–8) would improve visibility without distorting scale.
  • VQ-04: Color Accessibility (2/2) — Brand green (#009E73) positive / matte red (#AE3030) negative is a well-justified semantic exception; both are CVD-safe Imprint members.
  • VQ-05: Layout & Canvas (4/4) — Landscape orientation correct for dual-panel layout. Generous padding (30px top/bottom, 64px sides). Two equal-height panes fill the canvas well.
  • VQ-06: Axis Labels & Title (2/2) — 'ACF', 'PACF', and 'Lag' labels correctly placed. X-axis title shown only on the bottom chart (shared-axis convention).
  • VQ-07: Palette Compliance (2/2) — Brand green first, matte red for negative (semantic exception). Backgrounds are #FAF8F1 (light) / #1A1A17 (dark). Data colors identical across themes; chrome flips correctly.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above the well-configured-default baseline (4): the semantic positive/negative color encoding adds insight beyond generic single-color bars, and the overall composition is intentional. Not yet near publication-ready (6+); removing the chart frame spines would noticeably lift the polish level.
  • DE-02: Visual Refinement (3/6) — Above minimal (2): filtered legend showing only '95% CI' (not the ACF/PACF dataset labels), highlighted zero-baseline via zeroGridColor callback, and explicit whitespace in the container. Gap: no spine removal — top and right chart borders remain, which is the single most impactful refinement step available.
  • DE-03: Data Storytelling (4/6) — Smart AR(2) data choice that clearly demonstrates both key diagnostic patterns (exponential ACF decay, PACF cutoff after lag 2). The semantic color coding further highlights which bars are significant vs. noise. The reader immediately sees the ARIMA order identification story.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Two vertically stacked ACF/PACF panels with vertical stem-style bars from the zero baseline.
  • SC-02: Required Features (4/4) — ACF top / PACF bottom ✓, lag 0 in ACF ✓, PACF starts at lag 1 ✓, 95% CI dashed lines ✓, 30 lags ✓, y-axes labeled ✓.
  • SC-03: Data Mapping (3/3) — X-axis shows lag numbers; ACF values include lag 0 = 1.0; PACF lags start at 1. All data visible.
  • SC-04: Title & Legend (3/3) — Title is exactly 'acf-pacf · javascript · chartjs · anyplot.ai'. Legend filtered to '95% CI' only.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Demonstrates both ACF and PACF with full Levinson-Durbin PACF computation, CI bounds, zero baseline, positive/negative distinction, and lag 0 handling. All aspects of the plot type covered.
  • DQ-02: Realistic Context (5/5) — AR(2) process (x_t = 0.7·x_{t-1} + 0.2·x_{t-2} + ε_t) is a canonical, neutral time series example from statistics textbooks. No controversial content.
  • DQ-03: Appropriate Scale (4/4) — N=240 observations, 30 lags, correlation values in [-1,1], CI at ±0.127 — all statistically correct for the chosen AR(2) specification.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Helper functions (lcgRand, stdNormal, computeACF, computePACF, ciLine, yAxis, makePane) are lean and directly used. No classes or over-abstraction.
  • CQ-02: Reproducibility (2/2) — LCG with fixed seed 42; completely deterministic.
  • CQ-03: Clean Imports (2/2) — No imports; all globals (Chart, window.ANYPLOT_TOKENS) are used.
  • CQ-04: Code Elegance (2/2) — Clean, idiomatic JS. No fake interactivity. Per-bar backgroundColor function is elegant.
  • CQ-05: Output & API (1/1) — Harness handles file output; no filesystem calls needed or present.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — Expertly uses Chart.js mixed-chart approach (bar datasets + line overlay datasets), per-bar backgroundColor callback, responsive + maintainAspectRatio:false + animation:false pattern, and the legend filter function.
  • LM-02: Distinctive Features (3/5) — Uses Chart.js-specific callback patterns: per-datum backgroundColor function (stemColor), legend item filter, zero-baseline color callback (zeroGridColor). Multi-chart approach on a single container page demonstrates Chart.js canvas management.

Score Caps Applied

  • None — all caps avoided (DE-01=5 > 2, DE-02=3 > 2, VQ-02=6, VQ-03=5, SC-01=5, DQ-02=5, CQ-04=2)

Strengths

  • Semantic positive/negative color encoding (green/positive, red/negative) adds analytical value beyond a single-color implementation
  • AR(2) data choice is pedagogically perfect: demonstrates both the characteristic ACF decay and the PACF lag-2 cutoff simultaneously
  • Levinson-Durbin PACF recursion computed from scratch — statistically correct and reproducible
  • Legend correctly filtered to show only the CI entry, reducing visual noise
  • Highlighted zero baseline via zeroGridColor callback is a thoughtful refinement
  • Perfect spec compliance: lag 0 in ACF, PACF starts at lag 1, x-axis title on bottom panel only

Weaknesses

  • Chart borders (top and right spines) are visible in both renders; removing them (set border: { display: false } or similar on each scale) would significantly lift the visual refinement score
  • Duplicate '95% CI' legend blocks appear above each subplot — consider suppressing the legend on the ACF chart and showing only one shared legend; alternatively a single styled header can convey the CI information without repeating the legend widget
  • Bar thickness of 4px means near-zero PACF bars (~5–6 source px tall) are barely visible; increasing barThickness to 6–8 would improve low-value visibility without distorting the scale
  • Tick font size at 13px CSS is fractionally below the recommended 14px; bump to 14px for consistency

Issues Found

  1. DE-02 LOW: No spine removal — top and right chart borders remain visible in both renders, the single biggest gap between the current visual polish and the next level
    • Fix: Add to the scale configs for both charts, or suppress specific axes using Chart.js border options
  2. DE-01 GAP: No design refinements beyond semantic coloring — could benefit from removing the chart grid on the x-axis and keeping only y-axis grid lines
    • Fix: Set on both charts to reduce visual noise

AI Feedback for Next Attempt

Remove top/right chart frame borders (spine removal) on both the ACF and PACF chart instances — this single change will noticeably lift visual refinement. Additionally, consider suppressing the x-axis grid lines (keeping only y-axis) and consolidating the duplicate '95% CI' legends into a single entry. Bump tick font from 13px to 14px. These targeted changes should lift the score to ≥90 without touching the data logic or chart structure, which are already excellent.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-rejected Quality not OK, triggers update labels Jun 10, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 10, 2026
Attempt 1/3 - fixes based on AI review
@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

@github-actions

Copy link
Copy Markdown
Contributor Author

🔧 AI Review Produced No Score — Auto-Retrying

The Claude Code Action ran but didn't write quality_score.txt. Auto-retrying review once...


🤖 impl-review

@claude

claude Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Two-panel layout arranged vertically in a flex column: ACF on top, PACF on bottom, with the mandated title "acf-pacf · javascript · chartjs · anyplot.ai" centred above in bold 22px. ACF panel shows exponential decay from lag 0 (= 1.0) to lag 30 using brand green (#009E73) bars. PACF panel shows the classic AR(2) cutoff pattern — tall green bars at lags 1–2 (~0.78 and ~0.20), then bars that are mostly noise around zero, with small red (#AE3030) bars for slightly negative values. Horizontal dashed CI lines at ±1.96/√240 ≈ ±0.127 are clearly visible in both panels. The 95% CI legend entry sits between the two panels. Y-axis labels "ACF" and "PACF" are readable; "Lag" x-axis label appears only on the bottom chart. ACF x-axis shows even lags (0, 2, 4… 30); PACF shows all lags (1–30). All text is clearly readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17). Identical layout and data colors — the green and red bars are exactly the same hex values as in the light render, confirming Imprint palette data-color invariance. All chrome flips correctly: title, tick labels, axis labels, and legend text are light-colored against the dark surface. Grid lines remain subtle. No dark-on-dark failures observed anywhere. Brand green #009E73 reads clearly on the dark surface. Both renders pass all theme-readability checks.

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

Score: 84/100

Category Score Max
Visual Quality 27 30
Design Excellence 12 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 9 10
Library Mastery 7 10
Total 84 100

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title 22px DOM, axis labels 14px/600, tick labels 14px, legend 13px). Minor: ACF x-axis uses maxTicksLimit:16 (every-other lag) while PACF shows all 30 ticks — slight density inconsistency between panels.
  • VQ-02: No Overlap (6/6) — No text or element overlaps in either render.
  • VQ-03: Element Visibility (5/6) — ACF and significant PACF bars are well-sized (barThickness:7). Very small negative PACF bars at higher lags (lags 10–30) are statistically correct but barely visible; not a code defect.
  • VQ-04: Color Accessibility (2/2) — Semantic green/red is CVD-safe here: bar position (above/below zero) provides redundant encoding so color is not the sole signal.
  • VQ-05: Layout & Canvas (3/4) — Good two-panel flex layout with generous padding (30px/64px). Minor: suggestedMin/Max of ±1.1 to ±1.15 still results in y-axis rendering to ±1.5 (library headroom), creating moderate unused vertical space since ACF data is all positive and PACF values cluster near zero.
  • VQ-06: Axis Labels & Title (2/2) — "ACF", "PACF", "Lag" are descriptive and correctly placed.
  • VQ-07: Palette Compliance (2/2) — First series #009E73 ✓; red #AE3030 for negative correlations is a legitimate semantic exception (positive/negative sign); light background #FAF8F1 ✓; dark background #1A1A17 ✓; theme-adaptive chrome in both renders ✓.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Thoughtful semantic coloring (green/red for positive/negative), custom DOM title element for better layout control, clean axis styling. Above a well-configured default, but not FiveThirtyEight publication-ready.
  • DE-02: Visual Refinement (4/6) — X-axis grid removed, chart border set to display:false (equivalent spine removal), generous padding, custom zero-line gridline highlight via scriptable callback. Solid refinements above library defaults.
  • DE-03: Data Storytelling (3/6) — The AR(2) data choice perfectly demonstrates the diagnostic insight (exponential ACF decay + PACF cutoff at lag 2). Green/red adds visual emphasis. However, no annotations pointing the viewer to the key lag-2 cutoff insight; a reader unfamiliar with ARIMA theory must find it themselves.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Bar-based stem plot in two vertically stacked panels matches the spec exactly.
  • SC-02: Required Features (4/4) — ACF top/PACF bottom ✓, 95% CI dashed lines ✓, lag 0 in ACF ✓, PACF starts at lag 1 ✓, 30 lags ✓, axes correctly labeled ✓.
  • SC-03: Data Mapping (3/3) — X = lag number, Y = correlation value, both charts correctly mapped.
  • SC-04: Title & Legend (3/3) — Title "acf-pacf · javascript · chartjs · anyplot.ai" is exact format ✓; "95% CI" legend entry correct ✓.

Data Quality (14/15)

  • DQ-01: Feature Coverage (6/6) — AR(2) process demonstrates all diagnostic features: exponential ACF decay, PACF cutoff at model order, lag-0 autocorrelation = 1.0, both positive and negative correlation values, significance testing via CI bands.
  • DQ-02: Realistic Context (4/5) — Plausible and neutral statistical time series; the AR(2) model is the standard example for ACF/PACF education. Slightly abstract (no explicit real-world domain label like "monthly temperature" or "stock returns").
  • DQ-03: Appropriate Scale (4/4) — AR(2) with phi1=0.7, phi2=0.2 produces statistically correct correlations; N=240 gives realistic CI width; all values within [-1, 1].

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — Helper functions (lcgRand, stdNormal, computeACF, computePACF, makePane, ciLine, yAxis) deviate from the flat-script KISS ideal, but each is justified: no seeded RNG in the browser requires a custom LCG, and the ACF/PACF math is non-trivial. Functions reduce duplication between the two charts.
  • CQ-02: Reproducibility (2/2) — Fixed LCG seed (_seed=42) ensures deterministic data generation.
  • CQ-03: Clean Imports (2/2) — No imports in JavaScript; all globals (Chart, window.ANYPLOT_TOKENS) are used.
  • CQ-04: Code Elegance (2/2) — Clean, well-commented code. No fake UI elements. Appropriate complexity for the mathematical requirements.
  • CQ-05: Output & API (1/1) — Correct orientation directive, harness-compatible, current Chart.js 4.4.7 API.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Good use of Chart.js: mixed dataset types (bar + line in same chart), responsive/maintainAspectRatio/animation:false pattern, token-based color mapping. Scriptable options (zeroGridColor callback) is idiomatic Chart.js. Two-canvas approach is a valid workaround for missing subplot support.
  • LM-02: Distinctive Features (3/5) — Uses Chart.js-distinctive scriptable options API for grid color (zeroGridColor callback), legend filter callback, and mixed chart type (bar + line datasets). These features are Chart.js-specific but the overall chart is a bar chart that could be replicated with minor effort in other libraries.

Score Caps Applied

  • None — all caps thresholds are cleared.

Strengths

  • Textbook AR(2) dataset choice that demonstrates all key ACF/PACF diagnostic properties in one plot
  • Semantic green/red color coding for positive/negative correlations is both correct statistically and visually clear
  • Correct Levinson-Durbin recursion for PACF computation (mathematically sound implementation)
  • Dual-canvas flex layout cleanly solves Chart.js's lack of native subplot support
  • All theme tokens correctly applied; both renders pass light and dark theme checks
  • Scriptable grid color callback (zero-line highlight) is an elegant Chart.js-idiomatic touch
  • Fixed LCG seed ensures fully deterministic output across renders

Weaknesses

  • ACF x-axis uses maxTicksLimit:16 (even lags only: 0, 2, 4…) while PACF shows all 30 lags — inconsistent tick density between panels makes the shared x-axis harder to read as a unified scale
  • Y-axis range renders to approximately ±1.5 in practice (Chart.js padding beyond suggestedMin/Max), creating more unused vertical space than needed since ACF is all-positive and most PACF values cluster within ±0.15 for lags > 2; consider reducing suggestedMin to ~-0.4 and suggestedMax to ~1.1 for better use of panel height
  • DQ-02: No real-world domain context — adding a comment or subtitle indicating what the time series represents (e.g. monthly temperature anomalies) would make the data more concrete
  • DE-03: No annotation pointing the viewer to the key insight (the PACF cutoff at lag 2 identifies this as an AR(2) process)

Issues Found

  1. VQ-01 MINOR: Inconsistent x-axis tick density between ACF (every 2 lags) and PACF (every lag).
    • Fix: Apply the same maxTicksLimit to both x-axes for visual consistency.
  2. VQ-05 MINOR: Y-axis range too wide for the actual data range in the PACF panel.
    • Fix: Set tighter suggestedMin/Max values so the PACF panel uses its vertical space more efficiently.

AI Feedback for Next Attempt

The implementation is solid and well above the 80-point threshold. If repaired: (1) make x-axis tick density consistent across both panels by applying the same maxTicksLimit, (2) tighten the PACF y-axis range to better show the near-zero high-lag values, (3) optionally add a small annotation at lag 2 pointing to the PACF cutoff to elevate DE-03 storytelling.

Verdict: APPROVED

@github-actions github-actions Bot added quality:84 Quality score 84/100 ai-approved Quality OK, ready for merge and removed quality:88 Quality score: 88/100 labels Jun 10, 2026
@MarkusNeusinger MarkusNeusinger merged commit c39f838 into main Jun 10, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/acf-pacf/chartjs branch June 10, 2026 02:27
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:84 Quality score 84/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant