← Back to Graph
AgentGraph

Skill · Version 1.0.0

Custom D3 visualizations

Builds tailored visual explanations with D3 geometry and clear rendering ownership inside an existing frontend.

d3-custom-visualization

See how it helps

When is it useful?

Use when ordinary chart types cannot express relationships, flows or custom linked interactions.

What does it help you do?

  • Separates data-to-coordinate calculations from framework-managed visual elements.
  • Handles empty containers, constant domains and other scale edge cases.
  • Isolates imperative interactions and cleans up simulations or listeners.

Try asking this

Create a responsive flow diagram for customer journeys with linked selection and stable rendering for empty or identical-value datasets.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

D3 & Custom Visualization

Use this skill when standard chart types are insufficient and custom visual encodings (e.g., Sankey diagrams, hierarchical treemaps/sunbursts, chord/network graphs, horizon charts, beeswarm/force layouts, or custom linked brushes) are needed.

Clean Architecture: D3 for Math, Framework for DOM (or Scoped Hybrid)

  1. Separate Pure Data-to-Geometry Math from Rendering (Bostock):
    • Use modular D3 packages (d3-scale, d3-array, d3-shape, d3-hierarchy, d3-sankey, d3-geo, d3-time) as pure mathematical functions that transform domain data into screen coordinates, paths, and ticks.
    • In React, Vue, or Angular, let the UI framework own the declarative SVG/HTML elements whenever mark counts are moderate—avoid having both D3 .enter().append() and React/Vue mutate the same DOM subtree simultaneously.
    • Reserve imperative D3 DOM/Canvas bindings (d3-selection, d3-brush, d3-zoom, d3-force tick loops) for isolated <g ref={...}> or <canvas ref={...}> subtrees with strict cleanup on unmount.

Scales, Margins & Edge-Case Guards

  • Margin Convention & Bounded Inner Dimensions:
    • Compute innerWidth = Math.max(0, width - margin.left - margin.right) and innerHeight = Math.max(0, height - margin.top - margin.bottom) so zero or initializing container sizes never produce negative SVG dimensions or NaN paths.
  • Degenerate Domain Protection:
    • When all data values are identical (domainMin === domainMax), expand or pad the scale domain deterministically so linear/log scales do not collapse to a single pixel or divide by zero.
    • Use .clamp(true) or explicit out-of-bounds indicators when external values can exceed fixed scale domains.
  • Avoid Misleading Curve Interpolations:
    • Do not use curveBasis (which fails to pass through actual data points and shaves off peaks) or curveCardinal / curveCatmullRom (which can overshoot below zero on non-negative data). Use curveLinear, curveMonotoneX (which preserves monotonicity without false overshoots), or curveStepAfter for discrete state changes.

Checklist

  • Are D3 math modules (d3-scale, d3-shape, d3-array) used cleanly without conflicting with the UI framework's virtual DOM?
  • Do scales guard against empty arrays, min === max degenerate domains, and zero/negative container sizes?
  • Is curveMonotoneX, curveLinear, or curveStep* used instead of peak-clipping curveBasis or overshooting splines?
  • Are d3-zoom, d3-brush, and d3-force timers/listeners properly cleaned up on component unmount?

Included files 1

  • SKILL.md