What problem are you trying to solve?
DAC's chart widget is currently limited to the chart types Recharts can render cleanly (line, bar, area, pie, scatter, combo, funnel, sankey) plus a handful of bespoke React components. There is no way to express visualizations that go beyond this fixed list without forking the frontend.
- Common analytics visualizations such as treemaps, sunbursts, chord diagrams, force-directed networks, radial charts, and choropleth maps are not available.
- Power users who need a custom encoding (e.g. a scatter with size + color + faceting, a layered chart, or a domain-specific viz) have no declarative escape hatch in YAML or TSX.
- Recharts is built on D3, but D3's full capability is not exposed — users cannot opt into richer chart types without writing a new widget component upstream.
- TSX dashboards run server-side via Goja, so authors cannot drop in client-side D3 code either.
- The only current workaround is to fork DAC and add a new chart component, which creates maintenance and upgrade drift.
Proposed solution
Add D3 capability to DAC in two complementary phases, both fully declarative and version-controllable.
Phase 1 — Expand the chart widget with D3-backed chart types
Add new chart: values that render via D3 primitives (d3-hierarchy, d3-force, d3-geo, d3-chord) while keeping the existing {columns, rows} data contract. No new widget type, no user JS — just more chart types behind the same YAML/TSX surface.
- name: Revenue by Product Hierarchy
type: chart
chart: treemap
sql: |
SELECT category, product, revenue
FROM product_revenue
group: [category, product]
value: revenue
- name: Account Relationships
type: chart
chart: force
sql: |
SELECT source_account, target_account, weight
FROM account_links
source: source_account
target: target_account
weight: weight
- name: Revenue by Region
type: chart
chart: geo
sql: |
SELECT country_code, revenue
FROM revenue_by_country
region: country_code
value: revenue
Initial chart types to support:
treemap
sunburst
chord
force (network / node-link)
radial (radial bar / polar)
geo (choropleth)
Phase 2 — New vega widget type for custom visualizations
Add a 7th widget type that accepts a Vega-Lite spec as JSON/YAML. DAC injects the query result as data.values before render. This unlocks the long tail of custom visualizations without exposing arbitrary client-side JS.
- name: Deal Size vs Close Rate
type: vega
sql: |
SELECT segment, deal_size, close_rate, deal_count
FROM segment_performance
spec:
mark: circle
encoding:
x: { field: deal_size, type: quantitative }
y: { field: close_rate, type: quantitative }
size: { field: deal_count, type: quantitative }
color: { field: segment, type: nominal }
Support should include:
- new D3-backed chart types behind the existing
chart widget (Phase 1)
- a new
vega widget type wrapping Vega-Lite via react-vega (Phase 2)
- per-chart-type field mappings (
group, value, source, target, region, etc.) in YAML and TSX
- correct rendering in legends, tooltips, and the existing template system
- documentation and skill updates in
.claude/skills/create-dashboard/SKILL.md
Alternatives considered
- Stick with Recharts only — keeps the surface small but blocks every visualization Recharts cannot express, and users have already hit these limits.
- Allow custom widget bundles (
.widget.tsx compiled at dac build) — most flexible, but introduces a client-side JS execution model, sandboxing/CSP questions, viewer trust, and a build pipeline. Better deferred until Phases 1 and 2 prove insufficient.
- Recommend embedding external dashboards via iframe — breaks the single-binary, dashboard-as-code model and removes version control of the visualization.
- Fork DAC locally to add chart types — works, but creates maintenance and upgrade drift, and every team ends up reinventing the same set of charts.
Additional context
D3 is the de facto foundation for advanced data visualization on the web, and Vega-Lite is the established declarative grammar built on top of it (used by Streamlit, Apache Superset, Observable, and others). Both options preserve DAC's core principles: declarative authoring, version-controlled dashboards, no user JS in the browser at render time, and a single embedded binary.
Phase 1 is low risk and immediately unlocks the most-requested chart types; Phase 2 gives power users a declarative escape hatch for everything else. Phase 1 alone is likely to resolve the majority of "we need D3" requests, with Phase 2 as a follow-up if demand persists.
What problem are you trying to solve?
DAC's
chartwidget is currently limited to the chart types Recharts can render cleanly (line, bar, area, pie, scatter, combo, funnel, sankey) plus a handful of bespoke React components. There is no way to express visualizations that go beyond this fixed list without forking the frontend.Proposed solution
Add D3 capability to DAC in two complementary phases, both fully declarative and version-controllable.
Phase 1 — Expand the
chartwidget with D3-backed chart typesAdd new
chart:values that render via D3 primitives (d3-hierarchy,d3-force,d3-geo,d3-chord) while keeping the existing{columns, rows}data contract. No new widget type, no user JS — just more chart types behind the same YAML/TSX surface.Initial chart types to support:
treemapsunburstchordforce(network / node-link)radial(radial bar / polar)geo(choropleth)Phase 2 — New
vegawidget type for custom visualizationsAdd a 7th widget type that accepts a Vega-Lite spec as JSON/YAML. DAC injects the query result as
data.valuesbefore render. This unlocks the long tail of custom visualizations without exposing arbitrary client-side JS.Support should include:
chartwidget (Phase 1)vegawidget type wrapping Vega-Lite viareact-vega(Phase 2)group,value,source,target,region, etc.) in YAML and TSX.claude/skills/create-dashboard/SKILL.mdAlternatives considered
.widget.tsxcompiled atdac build) — most flexible, but introduces a client-side JS execution model, sandboxing/CSP questions, viewer trust, and a build pipeline. Better deferred until Phases 1 and 2 prove insufficient.Additional context
D3 is the de facto foundation for advanced data visualization on the web, and Vega-Lite is the established declarative grammar built on top of it (used by Streamlit, Apache Superset, Observable, and others). Both options preserve DAC's core principles: declarative authoring, version-controlled dashboards, no user JS in the browser at render time, and a single embedded binary.
Phase 1 is low risk and immediately unlocks the most-requested chart types; Phase 2 gives power users a declarative escape hatch for everything else. Phase 1 alone is likely to resolve the majority of "we need D3" requests, with Phase 2 as a follow-up if demand persists.