Skip to content

feat(chartjs): implement pyramid-basic - #11585

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/pyramid-basic/chartjs
Sep 5, 2026
Merged

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

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Implementation: pyramid-basic - javascript/chartjs

Implements the javascript/chartjs version of pyramid-basic.

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

Parent Issue: #1000


🤖 impl-generate workflow

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1-consistent, not pure white). Bold dark title "pyramid-basic · javascript · chartjs · anyplot.ai" at top, with a "Male"/"Female" legend (green/lavender swatches) below it. Nine horizontal diverging bars, one per age group (0-9 through 80+): Male extends left in brand green (#009E73), Female extends right in lavender (#C475FD). Bars widen through the middle age groups and narrow at the extremes, with Female visibly longer than Male in the 70-79 and 80+ rows — a realistic gender-longevity gap. X-axis title "Population (thousands)" (with units) and Y-axis title "Age Group" are both present, tick labels mirror correctly (abs values) on both sides of center. All text — title, legend, axis titles, tick labels, category labels — is clearly readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17-consistent, not pure black). Identical layout to the light render, with chrome (title, legend text, axis titles, tick labels) flipped to light/off-white ink for contrast. Data bars are unchanged: Male in #009E73, Female in #C475FD — confirming the data colors are identical between themes and only chrome flipped. No dark-on-dark issues: every text element is clearly legible against the dark surface.

Both renders pass the theme-readability check.

Score: 85/100

Category Score Max
Visual Quality 30 30
Design Excellence 10 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 5 10
Total 85 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — all font sizes explicitly set (title 22px, axis titles 18px, legend 16px, ticks 14px), readable in both themes
  • VQ-02: No Overlap (6/6) — no overlap between any elements
  • VQ-03: Element Visibility (6/6) — bar thickness well-adapted to 9 categories
  • VQ-04: Color Accessibility (2/2) — green/lavender pairing plus redundant left/right positional encoding
  • VQ-05: Layout & Canvas (4/4) — chart fills a large, balanced portion of the canvas
  • VQ-06: Axis Labels & Title (2/2) — X-axis has units ("Population (thousands)"), Y-axis descriptive
  • VQ-07: Palette Compliance (2/2) — first series #009E73, second series canonical Imprint position 2 (#C475FD); theme-correct chrome in both renders

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) - Well-configured Chart.js default, no custom typography or distinctive polish
  • DE-02: Visual Refinement (4/6) - Y-axis gridlines hidden and x-grid uses theme token, but otherwise standard defaults
  • DE-03: Data Storytelling (2/6) - The widening older-age gender gap exists in the data but isn't visually emphasized

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — correct diverging stacked-bar pyramid
  • SC-02: Required Features (4/4) — symmetric axis, distinct colors per side, legend, centered category axis all present
  • SC-03: Data Mapping (3/3) — X = population (diverging), Y = age group categories
  • SC-04: Title & Legend (3/3) — title matches mandated format exactly; legend labels match dataset labels

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — full age range with realistic older-age gender divergence
  • DQ-02: Realistic Context (5/5) — population pyramid by age/gender is the canonical neutral demographic example named in the spec
  • DQ-03: Appropriate Scale (4/4) — values and the gender gap at older ages are factually plausible

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — flat script, no functions/classes
  • CQ-02: Reproducibility (2/2) — hard-coded deterministic arrays
  • CQ-03: Clean Imports (2/2) — no unused imports
  • CQ-04: Code Elegance (2/2) — appropriately simple, no fake functionality
  • CQ-05: Output & API (1/1) — correct mount-node contract, animation: false set, current Chart.js v4 API

Library Mastery (5/10)

  • LM-01: Idiomatic Usage (4/5) - Solid use of stacked scales, plugins, and tick callbacks
  • LM-02: Distinctive Features (1/5) - Stacked-negative-value pyramid + tooltip callback is a generic cross-library pattern, not Chart.js-distinctive

Score Caps Applied

  • None

Strengths

  • Correct Imprint palette usage in canonical order (brand green #009E73 for Male, lavender #C475FD for Female), fully theme-correct chrome in both renders — data colors identical across themes
  • Full spec compliance: symmetric axis scale (-50 to 50), distinct colors per side, legend, centered category labels, tooltip callback correctly reports absolute values
  • Realistic, neutral demographic data forming a genuine population-pyramid shape, including a plausible widening female/male gap in the older cohorts (70-79, 80+)
  • Clean, deterministic, KISS code with the correct mount-node contract and animation: false

Weaknesses

  • Design Excellence is generic/default: standard Chart.js bar styling with no distinctive typography or visual hierarchy — nothing draws the eye to the chart's own insight (the widening gender gap in older age groups); consider a subtle emphasis technique (e.g., a bolder outline or callout on the 70-79/80+ rows)
  • Library Mastery is generic: the stacked-bar-with-negated-values pyramid technique plus a tooltip callback is a common cross-library pattern — consider a Chart.js-specific touch (e.g., a small custom plugin drawing a center divider line, or the annotation plugin) to better showcase the library's extensibility
  • Layout could be tightened slightly: there is a visible gap between the legend and the first data row (0-9) that could be trimmed for a more compact composition

Issues Found

  1. DE-01/DE-02/DE-03 LOW: Design Excellence sits at well-configured-default level with no storytelling emphasis
    • Fix: Add a subtle visual-hierarchy technique (color/opacity emphasis, callout, or annotation) to highlight the widening older-age gender gap; refine typography beyond the library defaults
  2. LM-02 LOW: Generic cross-library technique, no Chart.js-distinctive feature
    • Fix: Leverage a Chart.js-specific capability (custom plugin, annotation plugin, or similar) that wouldn't be trivially replicated in another library

AI Feedback for Next Attempt

Keep the palette, spec compliance, and data quality exactly as-is — they are all correct. Focus the repair on Design Excellence: add a deliberate visual-hierarchy element that calls out the widening gender gap in the oldest cohorts (e.g., subtle color/opacity emphasis, callout annotation, or thicker bar row highlight), and consider a small Chart.js-specific plugin (like a center divider line) to raise Library Mastery beyond generic usage.

Verdict: REJECTED

@github-actions github-actions Bot added quality:85 Quality score 85/100 ai-rejected Quality not OK, triggers update labels Sep 5, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Sep 5, 2026
Attempt 1/4 - fixes based on AI review
@github-actions

github-actions Bot commented Sep 5, 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 Sep 5, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background, consistent with #FAF8F1 — not pure white, not dark. Bold dark title "pyramid-basic · javascript · chartjs · anyplot.ai" at top, italic dark-gray subtitle "Female population increasingly exceeds male past age 70" beneath it, green/lavender "Male"/"Female" legend swatches below that. X-axis title "Population (thousands)" and Y-axis title "Age Group" both present with units. A new dashed vertical line marks the center axis, and an amber bracket + "gap widens" label sit to the right of the 70-79/80+ rows, which also carry a thin amber accent border on their bars. All text — title, subtitle, legend, axis titles, tick labels, category labels, "gap widens" annotation — is clearly readable against the light background, with no clipping at the canvas edges.

Dark render (plot-dark.png): Warm near-black background, consistent with #1A1A17 — not pure black, not light. Identical layout to the light render, with chrome (title, subtitle, legend text, axis titles, tick labels) flipped to light/off-white ink for contrast. The dashed center line, amber bracket, and "gap widens" label remain amber and clearly visible against the dark surface. No dark-on-dark issues found. Data bars are unchanged — Male #009E73, Female #C475FD — confirming data colors are identical between themes and only chrome flipped.

Both renders pass the theme-readability check.

Score: 94/100

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

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — all font sizes explicitly set, readable in both themes including the new annotation text
  • VQ-02: No Overlap (6/6) — no collisions; bracket/annotation sit cleanly in the reserved right-side padding
  • VQ-03: Element Visibility (6/6) — bar thickness well-adapted to 9 categories, accent borders don't obscure data
  • VQ-04: Color Accessibility (2/2) — green/lavender pairing plus redundant left/right positional encoding
  • VQ-05: Layout & Canvas (4/4) — chart fills a large, balanced portion of the canvas; right padding correctly reserved for the bracket, nothing cut off
  • VQ-06: Axis Labels & Title (2/2) — X-axis has units, Y-axis descriptive
  • VQ-07: Palette Compliance (2/2) — first series #009E73, second series canonical Imprint position 2 (#C475FD); theme-correct chrome in both renders

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) - Custom plugin (center line, bracket, annotation) and new subtitle add deliberate polish and hierarchy beyond library defaults
  • DE-02: Visual Refinement (4/6) - Spines/grid/whitespace unchanged from attempt 1, still fairly default aside from the new plugin
  • DE-03: Data Storytelling (5/6) - Bracket + "gap widens" annotation + accent borders directly emphasize the widening older-age gender gap

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — correct diverging stacked-bar pyramid
  • SC-02: Required Features (4/4) — symmetric axis, distinct colors per side, legend, centered category axis all present
  • SC-03: Data Mapping (3/3) — X = population (diverging), Y = age group categories
  • SC-04: Title & Legend (3/3) — title matches mandated format exactly; legend labels match dataset labels

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — full age range with realistic older-age gender divergence
  • DQ-02: Realistic Context (5/5) — population pyramid by age/gender is the canonical neutral demographic example named in the spec
  • DQ-03: Appropriate Scale (4/4) — values and the gender gap at older ages are factually plausible

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — flat script; the plugin object and small helper arrow functions are idiomatic Chart.js extensibility, not gratuitous abstraction
  • CQ-02: Reproducibility (2/2) — hard-coded deterministic arrays
  • CQ-03: Clean Imports (2/2) — no unused imports
  • CQ-04: Code Elegance (2/2) — appropriately complex, no fake functionality — highlighted rows are computed from an explicit, data-driven set
  • CQ-05: Output & API (1/1) — correct mount-node contract, animation: false set, current Chart.js v4 API

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) - Solid use of stacked scales, plugin system, and tick callbacks
  • LM-02: Distinctive Features (4/5) - Custom afterDraw plugin is a genuinely Chart.js-specific extensibility hook, directly addressing the prior generic-usage weakness

Score Caps Applied

  • None

Strengths

  • Custom Chart.js plugin (afterDraw hook) draws a dashed center axis, a bracket, and a "gap widens" annotation that directly calls out the widening 70-79/80+ gender gap — a genuinely library-distinctive technique that resolves the prior LM-02 and DE-03 weaknesses
  • Accent border highlighting on the two oldest rows reinforces the same insight without breaking Imprint palette compliance
  • New subtitle ("Female population increasingly exceeds male past age 70") adds narrative context and visual hierarchy above the chart
  • Full spec compliance retained: canonical Imprint palette order, symmetric -50..50 axis, tooltip callback, correct mount-node contract with animation: false
  • Clean, deterministic, KISS code

Weaknesses

  • Visual refinement (spines/grid/whitespace) is largely unchanged from attempt 1 — aside from the new plugin, the chart still relies on fairly default Chart.js chrome; further subtle grid/typography polish would raise DE-02
  • Minor: noticeable whitespace gap remains between the legend row and the first data bar (age 0-9) — could be trimmed for a tighter composition

Issues Found

  1. DE-02 LOW: Grid/whitespace refinement is unchanged from the rejected attempt
    • Fix (optional, non-blocking): trim the legend-to-first-row whitespace and consider further subtle grid styling

AI Feedback for Next Attempt

No further repair needed — this attempt resolves the prior Design Excellence and Library Mastery weaknesses with a genuine Chart.js-specific plugin technique. If iterating further purely for polish, tighten the legend-to-first-row whitespace and consider additional grid/typography refinement.

Verdict: APPROVED

@github-actions github-actions Bot added quality:94 Quality score 94/100 ai-approved Quality OK, ready for merge and removed quality:85 Quality score 85/100 labels Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger merged commit dedcf49 into main Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger deleted the implementation/pyramid-basic/chartjs branch September 5, 2026 12:28
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:94 Quality score 94/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant