Skip to content

feat(echarts): implement errorbar-asymmetric - #11295

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/errorbar-asymmetric/echarts
Sep 5, 2026
Merged

feat(echarts): implement errorbar-asymmetric#11295
MarkusNeusinger merged 6 commits into
mainfrom
implementation/errorbar-asymmetric/echarts

Conversation

@github-actions

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

Copy link
Copy Markdown
Contributor

Implementation: errorbar-asymmetric - javascript/echarts

Implements the javascript/echarts version of errorbar-asymmetric.

File: plots/errorbar-asymmetric/implementations/javascript/echarts.js

Parent Issue: #2781


🤖 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 (#FAF8F1) background. Bold dark title "errorbar-asymmetric · javascript · echarts · anyplot.ai" centered at top, with a legend below showing two entries ("10th-90th percentile range" swatch, "Point forecast" dot). Y-axis title "Revenue growth (%)" is rotated on the left, x-axis title "Forecast quarter" centered below. All six quarters (Q1-Q6) show brand-green (#009E73) error bars with visible caps and a distinct point-forecast marker, each with clearly different upper/lower magnitudes (e.g. Q3's bar extends much further below its point than above, dipping under 0%). All text — title, axis titles, tick labels, legend — is clearly readable against the light background; no light-on-light issues, no clipping at any canvas edge.

Dark render (plot-dark.png): Same layout and data on a warm near-black (#1A1A17) background. Title, legend, and axis labels now render in light text, fully legible with no dark-on-dark failures. The data colors (error bars, caps, markers) are identical brand green (#009E73) to the light render — only the chrome (background, text, gridlines) flipped, exactly as required.

Both renders pass the theme-readability check.

Score: 86/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) - Explicit sizes throughout, readable in both themes; title comfortably fits but occupies only ~35% of canvas width, below the 50-70% target for this title format
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6) - Markers/lines well-sized for the sparse 6-point dataset
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4) - Plot fills the canvas well, balanced margins, nothing clipped
  • VQ-06: Axis Labels & Title (2/2) - Units present on both axes
  • VQ-07: Palette Compliance (2/2) - Brand green consistent across themes, correct backgrounds/chrome

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) - Well-configured but monotone single-color look, no extra design flourish
  • DE-02: Visual Refinement (4/6) - Clean chrome (hidden axis line, subtle grid) but not exceptional
  • DE-03: Data Storytelling (2/6) - Data displayed accurately with no emphasis/annotation on the widening-uncertainty trend

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct asymmetric error-bar chart via custom renderItem
  • SC-02: Required Features (4/4) - Visible caps, legend explains percentile-range meaning, genuinely asymmetric bounds
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - Distinct asymmetric magnitudes per quarter incl. one bound crossing zero; minor mismatch between code comment narrative and actual errorLower trend
  • DQ-02: Realistic Context (5/5) - Neutral business revenue-forecast scenario
  • DQ-03: Appropriate Scale (4/4)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3)
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) - Custom series renderItem is the correct idiomatic solution since ECharts has no native error-bar series type
  • LM-02: Distinctive Features (3/5) - Leverages ECharts' custom renderItem/api.coord coordinate-transform API

Score Caps Applied

  • None

Strengths

  • Correct, idiomatic use of ECharts' custom series renderItem API to build genuine asymmetric error bars (vertical line + two end caps) via api.coord/api.size — the right approach since ECharts has no native error-bar series type
  • Clean theme-adaptive chrome: hidden y-axis line, subtle horizontal-only gridlines, correctly mapped ANYPLOT_TOKENS for both light and dark renders, with identical brand-green data color across themes
  • Marker and line sizing well-matched to the sparse 6-point dataset (20px markers, 3px lines with caps) — clearly visible without overplotting
  • Legend explicitly explains what the bounds represent ("10th-90th percentile range"), directly satisfying the spec's note to clarify asymmetric bound meaning
  • Realistic, neutral business-forecast scenario with genuinely varying (non-uniform) asymmetric error magnitudes per quarter, including one bound crossing zero

Weaknesses

  • The chart relies on a single flat green across bars, caps, markers, and legend swatch — correct per palette rules but visually plain; consider emphasizing the widening-uncertainty trend to add data storytelling
  • Visual refinement is clean but generic beyond the hidden axis line and horizontal gridlines — a touch more polish (e.g. a subtitle stating the percentile convention) would lift DE-02
  • Title occupies only ~35% of canvas width at fontsize 22 — comfortably readable but well under the style guide's 50-70% target; a modestly larger fontsize (~26-28) would improve visual balance without risking overflow
  • Code comment claims "downside risk shrinks while upside potential grows" but errorLower is non-monotonic (1.5, 2.0, 3.2, 1.8, 2.5, 3.0 across Q1-Q6) — tighten the comment or the data trend for consistency

Issues Found

  1. DE-03 LOW: No visual hierarchy or emphasis beyond the raw data
    • Fix: Consider a subtle callout/annotation on the highest-uncertainty quarter (e.g. Q6) or a slightly bolder treatment of the point-forecast marker to guide the viewer toward the widening-uncertainty story
  2. DE-01/DE-02 MODERATE: Single-hue, minimally-refined presentation
    • Fix: Increase fontsize on the title slightly (~26-28px) to better fill the canvas width, and consider a small subtitle noting the percentile convention for added polish

AI Feedback for Next Attempt

Solid, correct implementation of a genuinely tricky ECharts chart type (idiomatic use of the custom-series renderItem API). To push higher, add visual hierarchy/storytelling — e.g. a subtle annotation calling out the widening uncertainty over the forecast horizon — and refine the title sizing so it better fills the mandated title's expected width band.

Verdict: REJECTED

@github-actions github-actions Bot added quality:86 Quality score 86/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
@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 (#FAF8F1, not pure white). Bold dark title "errorbar-asymmetric · javascript · echarts · anyplot.ai" centered at top (measured ~43% of canvas width, no clipping), with a new subtitle below explaining the percentile convention. Legend sits cleanly below with two entries ("10th-90th percentile range", "Point forecast"), no overlap with title or plot area. Y-axis "Revenue growth (%)" and x-axis "Forecast quarter" are both descriptive with units where relevant; tick labels in soft dark gray; a slightly bolder line marks the 0% baseline. All error bars, caps, and point markers render in brand green (#009E73). Six quarters (Q1-Q6) show distinct, genuinely asymmetric upper/lower error magnitudes (Q3 dips below 0%). New in this attempt: error-bar stroke weight visibly thickens from Q1 (~4px measured) to Q6 (~9px measured), tracking the growing total interval width. All text is clearly readable against the light background — no light-on-light issues.

Dark render (plot-dark.png): Same layout on a warm near-black background (#1A1A17, not pure black). Title, subtitle, legend, and axis labels render in light text against the dark background; gridlines are faint but visible; the 0% baseline stays light-colored. No dark-on-dark failures — every text element remains legible. Data colors are identical to the light render (#009E73) — only chrome flipped, per the theme-adaptive rule. The stroke-weight encoding is pixel-identical to the light render.

Both renders pass the theme-readability check.

Score: 89/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) - Explicit sizes throughout, readable in both themes; title now ~43% of canvas width (up from ~35% last review), still under the 50-70% guideline but no overflow/clipping so not a hard fault
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6) - 20px markers, variable-weight (2-4.5px) capped error bars well-sized for the sparse 6-point dataset
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4) - Plot area ~60-65% of canvas, balanced margins, nothing cut off
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (4/8) - Still a single-hue monochrome look; bold title/subtitle add polish but no further palette/typographic sophistication
  • DE-02: Visual Refinement (4/6) - Hidden y-axis line, subtle horizontal grid, subtitle, refined legend icon — good, not exceptional
  • DE-03: Data Storytelling (4/6) - New variable stroke-weight encoding (measured 4px→9px) creates a real, visible size-based hierarchy showing the widening-uncertainty trend — fixes the prior review's flagged weakness

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (4/4)
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Data comment now matches the actual non-monotonic errorLower trend (Q3 supply-chain spike)
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3)
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5)
  • LM-02: Distinctive Features (3/5) - Uses ECharts' custom renderItem/api.coord coordinate-transform, fairly distinctive to this library

Score Caps Applied

  • None

Strengths

  • Correct, idiomatic use of ECharts' custom series renderItem API to build genuine asymmetric error bars (vertical line + two end caps) via api.coord/api.size — the right approach since ECharts has no native error-bar series type
  • New variable stroke-weight encoding (2-4.5px, scaled by total interval width per quarter) is a real, visually-perceptible redundant encoding — measured ~4px on Q1 vs ~9px on Q6 in the rendered PNG — that lets the widening-uncertainty trend read at a glance
  • Bold title + new subtitle reinforces the spec's requirement to explain what the asymmetric bounds represent
  • Data narrative comment now accurately matches the generated data (Q3 supply-chain risk spike), fixing the prior mismatch with the actual non-monotonic errorLower array
  • Clean theme-adaptive chrome, identical brand-green data color across themes
  • Realistic, neutral business-forecast scenario with genuinely varying asymmetric error magnitudes, including one bound (Q3) dipping below 0%

Weaknesses

  • The chart still relies on a single flat green across bars, caps, markers, and legend swatch — correct per palette rules but visually plain; DE-01 remains at "well-configured default" level
  • Title occupies ~43% of canvas width — up from ~35% last review, but still on the smaller side of the 50-70% guideline; a further fontSize bump (~30-32) would improve visual balance further, though this is not a hard fault since there's no overflow/clipping
  • Legend swatches are both the identical brand green, distinguishing entries only by icon/label text rather than color — acceptable for a single-series-family chart, but slightly reduces scan-ability

Issues Found

None blocking — see weaknesses above for optional polish for a future pass.

AI Feedback for Next Attempt

This attempt successfully addressed all four weaknesses flagged in review 1: title size increased, data-storytelling encoding added (variable stroke weight), visual refinement details added (subtitle, legend icon), and the data-comment mismatch fixed. If revisited again, the main remaining lever is Design Excellence: consider adding one more deliberate design touch (e.g., a subtle callout/annotation on the highest-uncertainty quarter, or nudging the title fontSize a bit larger) to push DE-01/DE-02 beyond "well-configured default."

Verdict: APPROVED

@github-actions github-actions Bot added quality:89 Quality score 89/100 ai-approved Quality OK, ready for merge and removed quality:86 Quality score 86/100 labels Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger merged commit 590464c into main Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger deleted the implementation/errorbar-asymmetric/echarts branch September 5, 2026 01:24
MarkusNeusinger added a commit that referenced this pull request Sep 5, 2026
## Summary
- `impl-merge.yml`'s completeness check fetched the PR branch, which `gh
pr merge --delete-branch` removes at the merge, so a re-dispatch for an
already-merged PR died on `couldn't find remote ref` before it could
reach the post-merge steps that "already merged → continue" exists for.
The check now validates against `origin/main` when the PR is merged
(where the squash put the files) and no longer tries to close a merged
PR when they are missing.
- Trigger: #11295 (2026-09-05 01:24 UTC) merged and then failed at
`Authenticate to GCP` 5 s later — images left in staging, metadata on
main pointing at production URLs, no `impl:echarts:done` label, no
Postgres sync. The manual re-dispatch failed with exactly this error.
- The `babysit-pipeline` skill gets the gotcha: how to recognise a
post-merge crash in the step list, re-dispatch instead of promoting by
hand, and compare landed pairs against production images every status
cycle.

## Plan
N/A

## Test plan
- [ ] Workflow YAML parses; the edited `run` block passes `bash -n`
- [ ] After merge: `gh workflow run impl-merge.yml -f pr_number=11295`
reaches "already merged — validating against origin/main", then
promotion, labels and sync succeed;
`gs://anyplot-images/plots/errorbar-asymmetric/javascript/echarts/plot-light.png`
exists and staging is empty
- [ ] `uv run python -m tools.changelog check --base origin/main` passes
- [ ] Unmerged path unchanged: a normal `ai-approved` merge still
validates against the PR branch

Known gap: `.github/workflows/` changes have no local verification loop;
the re-dispatch for #11295 after merge is the real test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01LfPAdJKa4JWzvsEUQZUuhs

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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:89 Quality score 89/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant