Skip to content

feat(d3): implement scatter-connected-temporal#8544

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/scatter-connected-temporal/d3
Jun 10, 2026
Merged

feat(d3): implement scatter-connected-temporal#8544
MarkusNeusinger merged 6 commits into
mainfrom
implementation/scatter-connected-temporal/d3

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Implementation: scatter-connected-temporal - javascript/d3

Implements the javascript/d3 version of scatter-connected-temporal.

File: plots/scatter-connected-temporal/implementations/javascript/d3.js

Parent Issue: #4675


🤖 impl-generate workflow

@claude

claude Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white #FAF8F1 background. It shows a connected scatter path from a large green dot in the lower-left (1992, GDP ~$23k, LE ~75.3 yrs) to a large blue dot in the upper-right (2021, GDP ~$52k, LE ~79.5 yrs), with intermediate smaller dots (r=5). The path is colored by a green→blue Imprint sequential gradient encoding temporal direction. Year labels appear at 1992 (bold), 2000, 2007, 2009, 2015, 2020, and 2021 (bold). A gradient legend bar sits in the upper-right plot area with "Temporal direction →" above it and "1992"/"2021" labels below. Axis labels read "GDP per Capita (USD thousands, 2015 prices)" (X) and "Life Expectancy (years)" (Y). Both axis labels and all tick labels are clearly readable against the light background. The title "GDP & Life Expectancy · scatter-connected-temporal · javascript · d3 · anyplot.ai" is bold, centered, and fully visible. Legibility verdict: PASS.

Dark render (plot-dark.png): Identical structure on a warm near-black #1A1A17 background. Data colors (green→blue gradient, endpoint circles) are exactly identical to the light render — only chrome flips: title, axis labels, tick labels, and year annotations are all rendered in light text (t.ink/t.inkSoft tokens), clearly readable against the dark background. No dark-on-dark failures observed. Grid lines remain subtle. The brand green #009E73 at the 1992 start marker is clearly visible. Legibility verdict: PASS.

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

Score: 86/100

Category Score Max
Visual Quality 26 30
Design Excellence 13 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 7 10
Total 86 100

Visual Quality (26/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (14px ticks, 16px axis labels, 12–13px year annotations, 11–12px legend text, dynamic title scaling). All text readable in both themes. Minor: 11px legend year labels are slightly small but readable.
  • VQ-02: No Overlap (4/6) — The temporal legend gradient bar is positioned inside the plot area (upper right). The bar itself, the "1992"/"2021" legend labels, and the "Temporal direction →" text crowd the same region as the data path and end-point markers. The "1992" legend label sits visually on top of the data path lines connecting toward 2021. Text remains legible but the overlap is distracting.
  • VQ-03: Element Visibility (5/6) — Larger markers (r=9) at endpoints emphasize start/end well. Intermediate markers (r=5) are small but visible at 3200px. Connecting lines at stroke-width 2.5 with opacity 0.85 are clear.
  • VQ-04: Color Accessibility (2/2) — Imprint sequential (green→blue) is CVD-safe. pageBg stroke on circles provides definition.
  • VQ-05: Layout & Canvas (4/4) — Generous margins (top 90, right 140, bottom 90, left 110), good canvas utilization, balanced layout.
  • VQ-06: Axis Labels & Title (2/2) — Both axes have descriptive labels with units.
  • VQ-07: Palette Compliance (2/2) — Uses t.seq[0] (#009E73) → t.seq[1] (#4467A3) via d3.interpolateRgb — correct Imprint sequential cmap for single-polarity temporal data. Start color is brand green. Backgrounds are #FAF8F1 / #1A1A17. Chrome is fully theme-adaptive via ANYPLOT_TOKENS.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above a generic default: temporal gradient through the path, larger endpoint markers, year annotations at economically meaningful events (2009 financial crisis, 2020 COVID dip). The gradient legend bar adds polish. Not yet at FiveThirtyEight level — missing narrative text annotations that would elevate this to editorial quality.
  • DE-02: Visual Refinement (4/6) — Only bottom and left axes (no top/right spines) ✓. Subtle both-axis grid appropriate for scatter ✓. Clean gradient legend without a box frame ✓. Domain lines styled with inkSoft ✓. Good whitespace throughout.
  • DE-03: Data Storytelling (4/6) — Visual hierarchy is present: green→blue gradient encodes time direction, larger endpoint circles anchor the narrative, annotated dips at 2007/2009 and 2020/2021 reveal the financial crisis and COVID disruption. The viewer can trace the story. Could be stronger with a brief annotation ("2008 Financial Crisis" or "COVID-19") to make the key events immediately legible without domain knowledge.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Connected scatter with temporal path, correct.
  • SC-02: Required Features (4/4) — Chronological connection ✓, key year annotations ✓, temporal color gradient ✓, visible markers at every point ✓.
  • SC-03: Data Mapping (3/3) — X = GDP per capita, Y = life expectancy, time = year ✓.
  • SC-04: Title & Legend (3/3) — Title follows {Descriptive Title} · {spec-id} · {language} · {library} · anyplot.ai format ✓. Gradient legend bar with start/end year labels is appropriate for single-series temporal encoding ✓.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows full feature set: monotonic overall trend, visible economic-cycle dips (2001–02, 2008–09), COVID disruption (2020), temporal encoding via gradient, start/end emphasis.
  • DQ-02: Realistic Context (5/5) — GDP per capita vs. life expectancy for a developed economy 1992–2021 is a real-world, neutral, comprehensible scenario popularized in data journalism.
  • DQ-03: Appropriate Scale (4/4) — Values ($23k–$52k GDP, 75.3–80.0 yrs LE) are factually plausible for a developed country in 2015 USD. COVID dip magnitudes (GDP -$3k, LE -0.8 yrs) are realistic.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear flow: data → SVG → scales → grid → segments → circles → labels → axes → legend → title. No functions or classes.
  • CQ-02: Reproducibility (2/2) — Hard-coded deterministic data array, no randomness.
  • CQ-03: Clean Imports (2/2) — No imports needed; d3 is a global per harness contract.
  • CQ-04: Code Elegance (2/2) — Clean idiomatic code. The labelConfig array pattern for manual annotation offsets is tidy. Loop for per-segment coloring is clear.
  • CQ-05: Output & API (1/1) — Current D3 7.9.0 API. Harness handles output files.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Correct use of d3.scaleLinear, d3.extent, d3.axisBottom/Left, d3.format, selection API for axis styling. Data-driven .join() pattern for circles. Good.
  • LM-02: Distinctive Features (3/5) — Uses d3.interpolateRgb for per-segment temporal coloring (each segment colored by its midpoint fraction), SVG <defs> + <linearGradient> for the legend gradient bar, and manual .tick text / .tick line / .domain selection styling — all distinctly D3/SVG patterns. Somewhat generic for a full D3 implementation; a d3.line() generator with a path gradient approach or SVG marker arrows for direction would leverage D3 more distinctively.

Score Caps Applied

  • None applied — all category scores above cap thresholds.

Strengths

  • Perfect spec compliance: all four required features (chronological connection, year annotations, temporal color gradient, visible markers) implemented correctly.
  • Excellent data quality: real-world GDP/life-expectancy scenario with genuine economic events visible in the path shape, making the chart immediately meaningful.
  • Proper Imprint sequential palette (t.seq[0]→t.seq[1]) for temporal encoding; fully theme-adaptive chrome via ANYPLOT_TOKENS in both renders.
  • Clean, deterministic, idiomatic D3 code with no over-engineering; per-segment temporal coloring loop is elegant.
  • Dynamic title font scaling (Math.max(13, Math.round(22 * 67 / title.length))) prevents title overflow on the long mandated title.

Weaknesses

  • Temporal legend (gradient bar + labels) is placed inside the inner plot area in the upper right, overlapping the data path and endpoint markers. The "1992"/"2021" legend labels sit directly on or adjacent to data path lines near the 2021 endpoint, creating visual crowding. Move the legend outside the inner plot area — e.g., into the right margin (between iw and iw + margin.right) or just below the title.
  • Design storytelling stops at year labels; brief event annotations ("2008–09 Financial Crisis", "COVID-19 2020") near the visible dips would immediately communicate the narrative to readers without domain expertise, lifting DE-01 and DE-03.
  • LM-02 could be stronger: consider using a D3 d3.line() generator with gradient via stroke: url(#path-grad) on the path element, or SVG arrowhead <marker> elements to add directional arrows along the path — techniques that are distinctly D3/SVG and not replicable in other libraries.

Issues Found

  1. VQ-02 MODERATE (4/6): Temporal legend positioned inside the plot area overlaps data path in the upper right. The gradient bar and its "1992"/"2021" labels compete with data path lines and the 2021 endpoint cluster.
    • Fix: Move the legend block into the right margin. Set lgX = iw + 12 and lgY = ih / 2 - lgH / 2 (centered vertically in the right margin). Adjust margin.right to ~180 to accommodate.
  2. DE-01/DE-03 MODERATE (5/8, 4/6): Good temporal storytelling but lacks event-level annotations that would make the narrative self-explanatory.
    • Fix: Add two small text callouts: one near the 2009 dip ("Financial Crisis") and one near the 2020 dip ("COVID-19"), styled in t.inkSoft at 11–12px, offset to avoid overlap with path lines.
  3. LM-02 LOW (3/5): Temporal gradient uses simple d3.interpolateRgb on individual segments rather than D3's native path + gradient approach.
    • Fix (optional, for higher LM-02): Use a <linearGradient> applied to the actual path stroke via gradientUnits="userSpaceOnUse", or add SVG <marker> arrowheads at midpoints of the path to encode direction.

AI Feedback for Next Attempt

Move the temporal legend gradient bar to the right margin (outside iw) to eliminate the overlap with the data path and endpoint labels — adjust margin.right to ~180 and set lgX = iw + 12. Add concise event annotations near the 2009 and 2020 dips ("Financial Crisis" and "COVID-19") to make the chart self-explanatory. Optionally strengthen D3 distinctiveness by using a <linearGradient> on the path stroke itself with gradientUnits="userSpaceOnUse", which would remove the need for per-segment line coloring and is a more idiomatic SVG/D3 technique for this effect.

Verdict: REJECTED

@github-actions github-actions Bot added quality:86 Quality score 86/100 ai-rejected Quality not OK, triggers update labels Jun 9, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

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 10, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white (#FAF8F1) background. A connected scatter path traces the co-evolution of GDP per capita (X-axis, $20k–$55k) and life expectancy (Y-axis, 75–80 yrs) from 1992 to 2021, with the path stroke rendered via an SVG linearGradient transitioning from Imprint brand green (#009E73) at 1992 to Imprint blue (#4467A3) at 2021. Intermediate data markers are r=5 circles color-interpolated along the same gradient; the 1992 and 2021 endpoints are larger (r=9) with bold ink labels. Key years (1992, 2000, 2007, 2009, 2015, 2020, 2021) are annotated beside their respective points. Dashed leader lines connect to italic "Financial Crisis" (2009 dip) and "COVID-19" (2020 drop) annotations. A compact gradient legend bar sits in the right margin with "Temporal direction →" and "1992" / "2021" labels. Grid lines are subtle on both axes. Title "GDP & Life Expectancy · scatter-connected-temporal · javascript · d3 · anyplot.ai" is bold and clearly readable. All text is dark-on-warm-white — legibility PASS.

Dark render (plot-dark.png): The same plot on a warm near-black (#1A1A17) background. Title, axis labels, tick labels, year annotations, event text, and legend labels all render in light ink (inkSoft/ink tokens) — clearly readable against the dark surface. No dark-on-dark failure observed. Data colors (green→blue gradient) are identical to the light render; only the chrome (backgrounds, text, grid) flips. The gradient legend bar and its surrounding text are correctly visible on the dark surface. Legibility PASS.

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

Score: 93/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — Title, axis labels, ticks all clear in both themes. Annotation and legend text at 11px CSS is borderline at mobile/thumbnail scale.
  • VQ-02: No Overlap (6/6) — Year labels positioned with dx/dy offsets; dashed leader lines cleanly separate annotations from data. No collisions.
  • VQ-03: Element Visibility (6/6) — 30 sparse points: r=5 intermediate + r=9 endpoints with pageBg stroke for definition. Path at 2.5px stroke-width is prominent.
  • VQ-04: Color Accessibility (2/2) — imprint_seq (green→blue) is CVD-safe. Year labels provide redundant temporal encoding.
  • VQ-05: Layout & Canvas (4/4) — Canvas gate passed. Generous margins; no clipping; title at ~75% width is expected for this title length.
  • VQ-06: Axis Labels & Title (2/2) — X: "GDP per Capita (USD thousands, 2015 prices)", Y: "Life Expectancy (years)" — descriptive with units. Title format correct.
  • VQ-07: Palette Compliance (2/2) — t.seq (imprint_seq: #009E73→#4467A3) correctly used for continuous temporal encoding. Backgrounds #FAF8F1/#1A1A17. Colors identical across themes.

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) — SVG linearGradient with gradientUnits="userSpaceOnUse" on the path stroke is a genuinely sophisticated technique. Gradient marker interpolation and endpoint differentiation show intentional design hierarchy. Above default (4).
  • DE-02: Visual Refinement (4/6) — L-shaped frame (axisBottom+axisLeft only), subtle t.grid gridlines, pageBg stroke on markers for definition, rounded legend corners. Above default (2).
  • DE-03: Data Storytelling (5/6) — Gradient guides the eye from green-1992 to blue-2021; larger endpoints create clear focal points; Financial Crisis and COVID-19 annotations contextualize economic dips. Title anchors the narrative. Above default (2).

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct connected scatter plot with temporal path; points connected chronologically.
  • SC-02: Required Features (4/4) — Chronological connection ✓, key time-point labels ✓, color gradient for temporal direction ✓, visible markers at each position ✓.
  • SC-03: Data Mapping (3/3) — GDP per capita on X, life expectancy on Y, year as temporal ordering. Full 1992–2021 range.
  • SC-04: Title & Legend (3/3) — Title matches {Descriptive Title} · {spec-id} · javascript · d3 · anyplot.ai format. Gradient legend with direction indicator present.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Demonstrates temporal path through 2D space, cyclical patterns (2001–2003 and 2009–2010 dips), regime changes (COVID 2020 drop), and a 30-year directional trend.
  • DQ-02: Realistic Context (5/5) — GDP $23k–$52k and life expectancy 75–80 yrs are realistic for an advanced economy 1992–2021. Neutral, factual historical events.
  • DQ-03: Appropriate Scale (4/4) — 30 points across 30 years fits spec's 10–100 range perfectly.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat procedural D3 script, no functions or classes.
  • CQ-02: Reproducibility (2/2) — All data hardcoded; no randomness; fully deterministic.
  • CQ-03: Clean Imports (2/2) — No imports needed; d3 is a global; all tokens from window.ANYPLOT_TOKENS.
  • CQ-04: Code Elegance (2/2) — Well-organized sections with informative inline comment explaining userSpaceOnUse gradient technique.
  • CQ-05: Output & API (1/1) — Correctly appends single SVG to #container; sized from window.ANYPLOT_SIZE; harness writes plot-{theme}.png + plot-{theme}.html.

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — d3.scaleLinear().nice(), d3.axisBottom/Left, d3.line(), d3.extent(), .datum() for single path, d3.interpolateRgb — all idiomatic D3 patterns.
  • LM-02: Distinctive Features (4/5) — SVG defs linearGradient with gradientUnits="userSpaceOnUse" applied as a path stroke is a genuinely distinctive D3/SVG capability. One point left: adding a terminal arrowhead marker (SVG <marker> element) on the path end would complete the spec's "arrow or gradient" suggestion and fully demonstrate D3's marker API.

Score Caps Applied

  • None

Strengths

  • SVG linearGradient with gradientUnits="userSpaceOnUse" applied as path stroke is a sophisticated technique that correctly encodes temporal direction along the actual 2D trajectory
  • Color interpolation on markers via d3.interpolateRgb mirrors the path gradient, creating a unified and cohesive temporal metaphor
  • Endpoint circles (r=9 with bold ink labels) vs. intermediate circles (r=5) provide clear visual hierarchy for 1992 and 2021
  • Key economic events (Financial Crisis, COVID-19) annotated with dashed leader lines add narrative value aligned with the spec's storytelling intent
  • Full Imprint token usage: pageBg, ink, inkSoft, grid, and t.seq all correctly applied; both themes pass readability checks without any dark-on-dark failures
  • Gradient legend in right margin is compact, informative, and positioned without overlapping the data path

Weaknesses

  • Annotation and legend text at 11px CSS (22px native) is borderline at mobile/thumbnail scale — consider raising to 12–13px for "Financial Crisis", "COVID-19", and "Temporal direction →" labels
  • LM-02 near-miss: the gradient path is strong but no arrowhead is drawn on the path end to reinforce direction — spec suggests "arrow or color gradient"; adding a terminal <marker> arrowhead would complete the suggestion and earn full LM-02

Issues Found

  1. VQ-01 MINOR: Annotation and legend text at 11px CSS borderline at mobile scale
    • Fix: Raise "Financial Crisis", "COVID-19", and "Temporal direction →" text from 11px to 12–13px CSS
  2. LM-02 MINOR: No arrowhead on path end despite spec's "arrow or gradient" suggestion
    • Fix: Add SVG <marker> arrowhead to the path end using D3's marker API

AI Feedback for Next Attempt

This is a high-quality implementation. Two minor improvements: (1) raise annotation/legend text from 11px to 12–13px CSS for mobile readability; (2) add a terminal arrowhead SVG marker on the path end using d3's marker-end attribute to fully satisfy the spec's "arrow or color gradient" direction cue suggestion. These are refinements, not blockers.

Verdict: APPROVED

@github-actions github-actions Bot added quality:93 Quality score 93/100 ai-approved Quality OK, ready for merge and removed quality:86 Quality score 86/100 labels Jun 10, 2026
@MarkusNeusinger MarkusNeusinger merged commit 1b30c23 into main Jun 10, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/scatter-connected-temporal/d3 branch June 10, 2026 00:02
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:93 Quality score 93/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant