Skip to content

feat(echarts): implement network-force-directed#9590

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/network-force-directed/echarts
Jul 1, 2026
Merged

feat(echarts): implement network-force-directed#9590
MarkusNeusinger merged 6 commits into
mainfrom
implementation/network-force-directed/echarts

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Implementation: network-force-directed - javascript/echarts

Implements the javascript/echarts version of network-force-directed.

File: plots/network-force-directed/implementations/javascript/echarts.js

Parent Issue: #990


🤖 impl-generate workflow

@github-actions

github-actions Bot commented Jul 1, 2026

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

@github-actions github-actions Bot added the ai-review-failed AI review action failed or timed out label Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

❌ AI Review Failed (auto-retry exhausted)

The AI review action completed but did not produce valid output files. Auto-retry already tried once.

What happened:

  • The Claude Code Action ran
  • No quality_score.txt file was created

Manual rerun:

gh workflow run impl-review.yml -f pr_number=9590

🤖 impl-review

@github-actions github-actions Bot added ai-review-rescued Review re-dispatched once after ai-review-failed and removed ai-review-failed AI review action failed or timed out labels Jul 1, 2026
@claude

claude Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1) — correct. Bold title "network-force-directed · javascript · echarts · anyplot.ai" in dark ink at top center, clearly readable. Legend below title shows 4 circle icons (Frontend, Backend, Data Layer, Infrastructure) with inkSoft text — readable. Force-directed graph with 30 nodes: Frontend = #009E73 (brand green, correct first palette slot), Backend = lavender/purple, Data Layer = blue, Infrastructure = ochre. Node sizes vary by degree — API node is clearly the largest hub. Edges are semi-transparent (opacity 0.55), straight, colored by source node. Labels placed right of nodes with hideOverlap suppressing collisions. Canvas utilization issue: graph cluster occupies the center-left region spanning ~41% of width and ~36% of height, leaving ~35% of canvas height empty below the graph and ~30% empty on the right. All visible text is readable against the light background.

Dark render (plot-dark.png): Near-black background (#1A1A17) — correct. Title in light/white text — clearly readable. Legend text in light inkSoft — readable. No dark-on-dark failures. Data colors are identical to the light render: Frontend=#009E73, Backend=lavender, Data Layer=blue, Infrastructure=ochre (only chrome flips). Graph layout differs slightly from light render — expected for non-deterministic force simulation. Node borders use t.pageBg for visual separation. Same canvas utilization issue as light render — graph fills a compact cluster. All visible text is readable against the dark background.

Both paragraphs confirmed. No AR-09 edge clipping detected. Canvas gate file absent (gate passed).

Score: 85/100

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

Visual Quality (25/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title=22px, legend=13px, labels=12px). Readable in both themes. Minor deduction: 12px node labels approach readability floor at mobile scale.
  • VQ-02: No Overlap (6/6) — labelLayout: { hideOverlap: true } prevents all label collisions.
  • VQ-03: Element Visibility (5/6) — Degree-proportional node sizing works well. Minor deduction: edges at width=1.5 are thin.
  • VQ-04: Color Accessibility (2/2) — Imprint palette is CVD-safe. Node borders on pageBg provide separation.
  • VQ-05: Layout & Canvas (1/4) — Graph cluster occupies ~14% of the 2400×2400 canvas. In light render: x=330–780 (~41% width), y=330–720 (~36% height). Bottom ~35% of canvas height and right ~30% of canvas width are completely empty. Force repulsion (180) is too weak to spread the graph.
  • VQ-06: Axis Labels & Title (2/2) — Title correct. No axis labels needed for network graph.
  • VQ-07: Palette Compliance (2/2) — color: t.palette correct. First category (Frontend) = #009E73. Backgrounds: #FAF8F1 light / #1A1A17 dark. All chrome tokens theme-adaptive.

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (4/8) — Good choices: degree-based sizing, community colors, node borders on pageBg. Canvas utilization problem detracts from overall aesthetic. Reads as a well-configured library default.
  • DE-02: Visual Refinement (4/6) — Solid refinements: edge opacity 0.55, borderColor matching pageBg, hideOverlap, emphasis scale=false, legend icon=circle with itemGap=28.
  • DE-03: Data Storytelling (3/6) — Software architecture community structure tells a clear story. Degree-based sizing highlights the API hub. Visual hierarchy present but no cross-community edge emphasis.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct force-directed network graph via ECharts graph + force layout.
  • SC-02: Required Features (4/4) — Force simulation, node sizing by degree, 4-community color coding, overlap-managed labels.
  • SC-03: Data Mapping (3/3) — Source/target edges correct. Degree correctly computed. Categories mapped.
  • SC-04: Title & Legend (3/3) — Title: "network-force-directed · javascript · echarts · anyplot.ai" ✓. Legend shows all 4 communities.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows community structure, degree variation (leaf Assets/Styles vs hub API), intra-community edges, and cross-community bridging.
  • DQ-02: Realistic Context (5/5) — Software module dependency network is realistic, neutral, and comprehensible (Router, Auth, Database, Docker, K8s, CI/CD).
  • DQ-03: Appropriate Scale (4/4) — 30 nodes (within 20–200 spec range), 4 communities, plausible edge density.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Clean data → init → setOption structure. No functions or classes.
  • CQ-02: Reproducibility (2/2) — All data hardcoded and deterministic. No RNG.
  • CQ-03: Clean Imports (2/2) — Uses only echarts and window.ANYPLOT_TOKENS globals.
  • CQ-04: Code Elegance (2/2) — Readable, efficient degree computation via forEach, clean map for node/link arrays.
  • CQ-05: Output & API (1/1) — animation: false set. No deprecated APIs. Harness handles output.

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — Expertly uses graph/force with categories, labelLayout, emphasis, and force physics — all correct ECharts patterns.
  • LM-02: Distinctive Features (4/5) — graph+force, categories grouping, labelLayout: { hideOverlap: true }, and emphasis.scale=false are ECharts-specific features. Minor deduction: no use of markPoint, tooltip callback, or other differentiating ECharts capabilities.

Score Caps Applied

  • None applied (DE-01=4 > 2, VQ-02=6, VQ-03=5, SC-01=5, DQ-02=5, CQ-04=2)

Strengths

  • Imprint palette correctly applied across all 4 communities (Frontend=#009E73 first slot ✓)
  • Degree-proportional node sizing creates clear visual hierarchy with API as the obvious hub
  • labelLayout: { hideOverlap: true } is excellent ECharts-native label management
  • Idiomatic ECharts graph/force/categories usage with proper physics configuration
  • Realistic software dependency scenario with 30 well-chosen module nodes
  • Both themes pass readability: all chrome tokens (t.ink, t.inkSoft, t.pageBg) correctly applied
  • Node borderColor: t.pageBg / borderWidth: 2 creates polished visual separation

Weaknesses

  • Canvas utilization too low: The force-directed graph occupies ~14% of the 2400×2400 canvas area (x=330–780, y=330–720 in display coords). Increase force.repulsion from 180 to 400–600, widen force.edgeLength from [50, 120] to [100, 250], and raise force.gravity to 0.20–0.25 to spread the layout and fill 50%+ of the canvas. Alternatively, add layoutCenter / layoutSize parameters to constrain the layout region explicitly.
  • Design could be more distinguished: Consider making cross-community edges visually distinct from intra-community edges (e.g., lower opacity 0.3 for intra-community, higher 0.7 for cross-community) to tell the integration story more clearly. The API hub could also have an accent ring or subtle glow to emphasize its central role.

Issues Found

  1. VQ-05 LOW (1/4): Graph fills ~14% of canvas — force repulsion too weak to spread nodes across the 2400×2400 square canvas.
    • Fix: Increase force.repulsion to 400–600, set force.edgeLength: [100, 250], gravity to 0.2. The layout should spread to fill at least 50% of the canvas area.
  2. DE-01 MEDIUM (4/8): Aesthetically functional but not distinctive — large empty canvas space makes the plot feel unfinished.
    • Fix: After fixing canvas utilization, differentiate cross-community vs intra-community edge styling (opacity, width) to add storytelling depth.

AI Feedback for Next Attempt

The core implementation is technically excellent — spec compliance, code quality, and library mastery are near-perfect. The primary fix needed is canvas utilization: force.repulsion: 180 and edgeLength: [50, 120] are too conservative for a 2400×2400 canvas, producing a compact cluster that fills only ~14% of the available space. Increase repulsion to 400–600 and edgeLength to [100, 250] to let the graph breathe. Optionally, add layoutCenter: ['50%', '55%'] and layoutSize: '85%' to anchor and bound the layout. For design differentiation, style cross-community edges differently (e.g., width 2.0, opacity 0.7) vs intra-community edges (width 1.0, opacity 0.35) to visually emphasize the integration points.

Verdict: REJECTED

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

github-actions Bot commented Jul 1, 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 Jul 1, 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 — correct anyplot surface. Title "network-force-directed · javascript · echarts · anyplot.ai" is centered at top in bold dark text (t.ink = #1A1A17), clearly readable. A horizontal legend immediately below shows 4 community labels (Frontend, Backend, Data Layer, Infrastructure) with colored circle icons in t.inkSoft — all readable. The force-directed network has 30 nodes in 4 color-coded communities: Frontend in brand green #009E73 (correct first series ✓), Backend in lavender #C475FD, Data Layer in blue #4467A3, Infrastructure in ochre #BD8233. The API hub node is the largest (9 connections) and bears a thick dark border for emphasis. Node labels are positioned to the right of nodes in t.inkSoft, with hideOverlap preventing collisions. Edges are semi-transparent (opacity: 0.55) and inherit source-node color. Cross-community edges are slightly wider. All text is readable against the light background. The graph occupies roughly 60% of the 2400×2400 canvas, leaving visible empty whitespace in the lower portion.

Dark render (plot-dark.png): The background is warm near-black #1A1A17 — correct dark surface. Title text and legend labels use light-colored tokens (t.ink = #F0EFE8, t.inkSoft = #B8B7B0) — both clearly readable against the dark surface. No dark-on-dark text failures observed. Node labels use t.inkSoft (light gray) — readable on the dark background. The 4 community palette colors are identical to the light render: #009E73, #C475FD, #4467A3, #BD8233 — confirmed no data color drift between themes. The node border color correctly switches to pageBg (#1A1A17 in dark), making standard nodes seamless, while the API hub border flips to t.ink (#F0EFE8). Note: the force layout converged at different node positions than the light render (non-seeded), producing a different topology — both are visually reasonable but differ.

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

Score: 83/100

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

Visual Quality (25/30)

  • VQ-01: Text Legibility (6/8) — Title and legend fully readable in both themes. Node labels at fontSize: 12 CSS px are adequate but borderline for mobile; hideOverlap prevents clutter at the cost of hiding some labels.
  • VQ-02: No Overlap (5/6) — labelLayout: { hideOverlap: true } prevents collisions; some labels are hidden rather than overlapping — acceptable for a 30-node graph.
  • VQ-03: Element Visibility (5/6) — Nodes sized by degree (symbolSize 14–46), API hub visually prominent. Edge opacity 0.55 keeps edges visible without overwhelming.
  • VQ-04: Color Accessibility (2/2) — Imprint palette, CVD-safe by design. 4 categories span distinct hue families.
  • VQ-05: Layout & Canvas (3/4) — Square orientation appropriate for network graph. No overflow or clipping. Graph uses ~60% of canvas with empty whitespace in lower portions; force parameters could spread nodes further.
  • VQ-06: Axis Labels & Title (2/2) — No axes required. Title correctly formatted. Legend labels describe communities.
  • VQ-07: Palette Compliance (2/2) — First series (Frontend) = #009E73 ✓. Imprint positions 2–4 in order. Background pageBg token. Data colors identical between themes.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above-default: community coloring, hub node special styling (thick border), cross-community edge distinction, degree-based sizing, lineStyle.color: 'source' for organic edge appearance. Missing: annotations, callout boxes, or explicit focal hierarchy to elevate polish.
  • DE-02: Visual Refinement (4/6) — No spines/grid needed; clean transparent background. Label placement right of nodes. curveness: 0 keeps edges clean. borderColor: pageBg creates seamless node appearance. Solid small refinements throughout.
  • DE-03: Data Storytelling (3/6) — Community coloring reveals structure. API hub is visually large. Cross-community edges are wider. But no annotations or subtitle explicitly tells the story — reader must infer the API hub's central role.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Force-directed graph with physics simulation. Correct.
  • SC-02: Required Features (4/4) — Node labels, edges, community coloring, node size by degree, cross-community edge distinction, layoutAnimation: false for convergence, hideOverlap for clutter control.
  • SC-03: Data Mapping (3/3) — Nodes → vertices, edges → connections, categories → communities, degree → node size.
  • SC-04: Title & Legend (3/3) — Title: network-force-directed · javascript · echarts · anyplot.ai ✓. Legend shows 4 community categories with circle icons.

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — 30 nodes, 4 communities, 43 edges, cross-community connections, hub distinction. Minor: cross-edge width is a design choice rather than data-driven weight encoding.
  • DQ-02: Realistic Context (5/5) — Software module dependency network is a classic, highly realistic force-directed use case. Module names (App, Router, API, Database, K8s, etc.) are plausible real-world components. Neutral domain.
  • DQ-03: Appropriate Scale (4/4) — 30 nodes (spec's 20–200 range), 43 edges, degree range 2–9, symbolSize 14–46 — all sensible.

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes. Flat procedural code using forEach/map. Clean and direct.
  • CQ-02: Reproducibility (1/2) — Node/edge data is hardcoded (deterministic), but ECharts force layout has no seed parameter — the layout converges to a different equilibrium each render. Light and dark PNGs show different topologies, confirming non-determinism.
  • CQ-03: Clean Imports (2/2) — No imports; uses only window.ANYPLOT_TOKENS and echarts globals.
  • CQ-04: Code Elegance (2/2) — Good use of Set for cross-edge lookup, map/forEach for data transformation, isHub shorthand. Appropriate complexity.
  • CQ-05: Output & API (1/1) — animation: false set; echarts.init without explicit size or devicePixelRatio ✓.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) — graph type with layout: 'force' is idiomatic. categories array for community coloring is the ECharts pattern. Force config (repulsion, gravity, edgeLength) correctly tuned. lineStyle.color: 'source' is the idiomatic edge-from-node-color pattern.
  • LM-02: Distinctive Features (4/5) — labelLayout: { hideOverlap: true } is ECharts-specific. lineStyle.color: 'source' for organic edge coloring. categories + legend integration. Force physics parameters. Hub node emphasis via borderWidth/borderColor. Genuine ECharts-native features.

Score Caps Applied

  • None

Strengths

  • Realistic software module dependency dataset with meaningful 4-community structure — clear real-world use case for force-directed graphs
  • Degree-based node sizing clearly identifies the API hub as the central connector across all communities
  • Cross-community edges visually distinguished (wider, higher opacity) to guide the eye to inter-layer connections
  • Imprint palette correctly applied in canonical order — first series (Frontend) uses brand green #009E73
  • ECharts-idiomatic patterns: categories for community coloring, labelLayout: { hideOverlap: true }, lineStyle.color: 'source' for organic edges
  • Theme-adaptive chrome correctly uses t.ink / t.inkSoft / t.pageBg tokens — all text elements flip correctly between light and dark

Weaknesses

  • Non-deterministic force layout: ECharts force layout has no seed parameter, so light and dark renders produce different node topologies. Fix: pre-compute deterministic x/y positions using a seeded LCG before the force phase, or pass fixed x/y values on each node.
  • Canvas underutilization: the network occupies roughly 60% of the 2400×2400 canvas, leaving empty whitespace in the lower portions. Fix: increase edgeLength to [120, 280] and repulsion to 600–700 to spread nodes further.
  • Node labels at fontSize: 12 CSS px (~24 source px) are borderline small for mobile readability at ~400px width. Fix: increase to fontSize: 14.
  • Design storytelling limited to community coloring — no annotations or callouts highlight the API hub's central role. Fix: add a subtitle or text annotation near API node ("Central hub: 9 connections").

Issues Found

  1. CQ-02 NON-DETERMINISTIC: ECharts force layout has no seed — light and dark renders show different topologies. Fix: pre-compute node x/y using a seeded LCG (e.g., a tiny fixed-seed Mulberry32 function) and pass as fixed positions on each node object, bypassing the random initial placement.
  2. VQ-05 MILD: Graph uses ~60% of the 2400×2400 canvas. Fix: increase edgeLength: [120, 280] and repulsion: 650 to expand the network across the full canvas area.
  3. DE-03 LOW: No data storytelling beyond color-coding. Fix: add graphic or title.subtext to surface the API hub's role (e.g., subtext: "API module connects all four layers — 9 direct dependencies"), or annotate the top-3 hub nodes by degree.

AI Feedback for Next Attempt

The core implementation is correct, idiomatic, and well-structured. Three focused improvements: (1) Reproducibility — use a seeded LCG (e.g. Mulberry32) to pre-compute deterministic initial x/y positions for each node and pass them in the node objects; this ensures light and dark renders converge to the same layout; (2) Canvas utilization — increase edgeLength to [120, 280] and repulsion to 600–700 so the network spreads across the full 2400×2400 canvas instead of clustering in the center; (3) Storytelling — add a title.subtext like "30 modules · 4 layers · API as central hub" to help readers orient immediately.

Verdict: APPROVED

@github-actions github-actions Bot added quality:83 Quality score 83/100 ai-approved Quality OK, ready for merge and removed quality:85 Quality score 85/100 labels Jul 1, 2026
@MarkusNeusinger MarkusNeusinger merged commit 18ae9df into main Jul 1, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/network-force-directed/echarts branch July 1, 2026 07:57
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 ai-review-rescued Review re-dispatched once after ai-review-failed quality:83 Quality score 83/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant