semiotic 3.7.4 → 3.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CLAUDE.md +10 -7
  2. package/README.md +36 -19
  3. package/ai/schema.json +221 -1
  4. package/ai/system-prompt.md +2 -1
  5. package/dist/components/Annotation.d.ts +4 -0
  6. package/dist/components/DataSummaryContext.d.ts +1 -0
  7. package/dist/components/ai/chartCapabilityTypes.d.ts +16 -0
  8. package/dist/components/ai/dataPitfallsBridge.d.ts +101 -0
  9. package/dist/components/ai/dataQualityBridge.d.ts +201 -0
  10. package/dist/components/ai/describeChart.d.ts +2 -0
  11. package/dist/components/ai/generativeChart.d.ts +145 -0
  12. package/dist/components/charts/custom/NetworkCustomChart.d.ts +14 -1
  13. package/dist/components/charts/ordinal/SwarmPlot.d.ts +7 -0
  14. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +21 -0
  15. package/dist/components/charts/realtime/aggregate.d.ts +51 -0
  16. package/dist/components/charts/realtime/eventTime.d.ts +26 -0
  17. package/dist/components/charts/shared/colorPalettes.d.ts +2 -0
  18. package/dist/components/charts/shared/colorUtils.d.ts +1 -12
  19. package/dist/components/charts/shared/minMax.d.ts +3 -0
  20. package/dist/components/charts/shared/radialGeometry.d.ts +0 -18
  21. package/dist/components/charts/shared/smartTooltip.d.ts +27 -0
  22. package/dist/components/charts/shared/statisticalOverlays.d.ts +35 -0
  23. package/dist/components/charts/shared/tooltipUtils.d.ts +2 -0
  24. package/dist/components/charts/shared/useChartSetup.d.ts +1 -1
  25. package/dist/components/charts/shared/useCustomChartSetup.d.ts +1 -1
  26. package/dist/components/charts/shared/validateChartData.d.ts +1 -1
  27. package/dist/components/charts/xy/Scatterplot.d.ts +9 -0
  28. package/dist/components/data/fromArrow.d.ts +54 -0
  29. package/dist/components/data/fromMermaid.d.ts +47 -0
  30. package/dist/components/data/fromObservablePlot.d.ts +69 -0
  31. package/dist/components/data/portability/index.d.ts +14 -0
  32. package/dist/components/data/portability/spec.d.ts +129 -0
  33. package/dist/components/data/portability/vegaLite.d.ts +62 -0
  34. package/dist/components/realtime/ReorderBuffer.d.ts +54 -0
  35. package/dist/components/realtime/RunningStats.d.ts +66 -0
  36. package/dist/components/realtime/WindowAccumulator.d.ts +105 -0
  37. package/dist/components/realtime/parseWindowDuration.d.ts +12 -0
  38. package/dist/components/recipes/customTooltip.d.ts +31 -0
  39. package/dist/components/recipes/gofish.d.ts +207 -0
  40. package/dist/components/recipes/gofishBoba.d.ts +23 -0
  41. package/dist/components/recipes/gofishIR.d.ts +169 -0
  42. package/dist/components/recipes/gofishIRExamples.d.ts +89 -0
  43. package/dist/components/recipes/gofishInterpreter.d.ts +52 -0
  44. package/dist/components/recipes/gofishLambdas.d.ts +145 -0
  45. package/dist/components/recipes/mermaidDag.d.ts +44 -0
  46. package/dist/components/recipes/packedClusterMatrix.d.ts +166 -0
  47. package/dist/components/recipes/recipeChrome.d.ts +100 -0
  48. package/dist/components/recipes/recipeLegend.d.ts +57 -0
  49. package/dist/components/recipes/recipeUtils.d.ts +105 -0
  50. package/dist/components/semiotic-ai.d.ts +6 -0
  51. package/dist/components/semiotic-data.d.ts +2 -0
  52. package/dist/components/semiotic-experimental.d.ts +20 -0
  53. package/dist/components/semiotic-network.d.ts +3 -1
  54. package/dist/components/semiotic-ordinal.d.ts +2 -0
  55. package/dist/components/semiotic-realtime.d.ts +9 -1
  56. package/dist/components/semiotic-recipes.d.ts +18 -1
  57. package/dist/components/semiotic-themes.d.ts +2 -0
  58. package/dist/components/semiotic-xy.d.ts +2 -0
  59. package/dist/components/semiotic.d.ts +4 -0
  60. package/dist/components/store/ObservationStore.d.ts +21 -2
  61. package/dist/components/store/SelectionStore.d.ts +1 -1
  62. package/dist/components/store/ThemeStore.d.ts +1 -1
  63. package/dist/components/store/TooltipStore.d.ts +1 -1
  64. package/dist/components/store/createStore.d.ts +1 -1
  65. package/dist/components/store/designTokens.d.ts +15 -0
  66. package/dist/components/stream/NetworkHtmlMarksLayer.d.ts +44 -0
  67. package/dist/components/stream/NetworkPipelineStore.d.ts +32 -0
  68. package/dist/components/stream/NetworkSVGOverlay.d.ts +12 -0
  69. package/dist/components/stream/OrdinalPipelineStore.d.ts +18 -0
  70. package/dist/components/stream/PipelineStore.d.ts +27 -0
  71. package/dist/components/stream/SceneGraph.d.ts +5 -1
  72. package/dist/components/stream/customLayout.d.ts +20 -0
  73. package/dist/components/stream/customLayoutDiagnostics.d.ts +11 -0
  74. package/dist/components/stream/customLayoutSelection.d.ts +52 -0
  75. package/dist/components/stream/networkCustomLayout.d.ts +66 -1
  76. package/dist/components/stream/networkTypes.d.ts +29 -1
  77. package/dist/components/stream/ordinalCustomLayout.d.ts +17 -1
  78. package/dist/components/stream/ordinalSceneBuilders/types.d.ts +2 -0
  79. package/dist/components/stream/ordinalTypes.d.ts +19 -3
  80. package/dist/components/stream/renderers/networkSymbolRenderer.d.ts +2 -0
  81. package/dist/components/stream/renderers/symbolCanvasRenderer.d.ts +2 -0
  82. package/dist/components/stream/stalenessBands.d.ts +28 -0
  83. package/dist/components/stream/symbolPath.d.ts +24 -0
  84. package/dist/components/stream/types.d.ts +72 -3
  85. package/dist/components/stream/useStalenessCheck.d.ts +6 -1
  86. package/dist/components/stream/xySceneBuilders/pointScene.d.ts +2 -2
  87. package/dist/components/stream/xySceneBuilders/types.d.ts +5 -0
  88. package/dist/geo.min.js +1 -1
  89. package/dist/geo.module.min.js +1 -1
  90. package/dist/network.min.js +1 -1
  91. package/dist/network.module.min.js +1 -1
  92. package/dist/ordinal.min.js +1 -1
  93. package/dist/ordinal.module.min.js +1 -1
  94. package/dist/realtime.min.js +1 -1
  95. package/dist/realtime.module.min.js +1 -1
  96. package/dist/semiotic-ai-semiotic-ai-u954ylUn.js +2 -0
  97. package/dist/semiotic-ai-statisticalOverlays-CU7jW05Q.js +1 -0
  98. package/dist/semiotic-ai.d.ts +6 -0
  99. package/dist/semiotic-ai.min.js +1 -1
  100. package/dist/semiotic-ai.module.min.js +1 -1
  101. package/dist/semiotic-data.d.ts +2 -0
  102. package/dist/semiotic-data.min.js +1 -1
  103. package/dist/semiotic-data.module.min.js +1 -1
  104. package/dist/semiotic-experimental.d.ts +20 -0
  105. package/dist/semiotic-experimental.min.js +1 -0
  106. package/dist/semiotic-experimental.module.min.js +1 -0
  107. package/dist/semiotic-network.d.ts +3 -1
  108. package/dist/semiotic-ordinal.d.ts +2 -0
  109. package/dist/semiotic-realtime.d.ts +9 -1
  110. package/dist/semiotic-recipes.d.ts +18 -1
  111. package/dist/semiotic-recipes.min.js +1 -1
  112. package/dist/semiotic-recipes.module.min.js +1 -1
  113. package/dist/semiotic-semiotic-BmrYbi99.js +2 -0
  114. package/dist/semiotic-statisticalOverlays-IjZw8Lsu.js +1 -0
  115. package/dist/semiotic-themes.d.ts +2 -0
  116. package/dist/semiotic-themes.min.js +1 -1
  117. package/dist/semiotic-themes.module.min.js +1 -1
  118. package/dist/semiotic-utils.min.js +1 -1
  119. package/dist/semiotic-utils.module.min.js +1 -1
  120. package/dist/semiotic-value.min.js +1 -1
  121. package/dist/semiotic-value.module.min.js +1 -1
  122. package/dist/semiotic-xy.d.ts +2 -0
  123. package/dist/semiotic.d.ts +4 -0
  124. package/dist/semiotic.min.js +1 -1
  125. package/dist/semiotic.module.min.js +1 -1
  126. package/dist/server.min.js +1 -1
  127. package/dist/server.module.min.js +1 -1
  128. package/dist/xy-semiotic-xy-Dufu3D0-.js +2 -0
  129. package/dist/xy-statisticalOverlays-3Ni9bRph.js +1 -0
  130. package/dist/xy.min.js +1 -1
  131. package/dist/xy.module.min.js +1 -1
  132. package/package.json +11 -3
  133. package/dist/semiotic-ai-statisticalOverlays-C2PPlmXv.js +0 -1
  134. package/dist/semiotic-statisticalOverlays-C3DsOgr_.js +0 -1
  135. package/dist/xy-statisticalOverlays-C2PPlmXv.js +0 -1
package/CLAUDE.md CHANGED
@@ -4,7 +4,7 @@
4
4
  - Install: `npm install semiotic`
5
5
  <!-- semiotic-bundle-sizes:start -->
6
6
  <!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
7
- - **Use sub-path imports** — `semiotic/xy` (90KB gz), `semiotic/ordinal` (74KB gz), `semiotic/network` (68KB gz), `semiotic/geo` (55KB gz), `semiotic/realtime` (95KB gz), `semiotic/server` (128KB gz), `semiotic/utils` (38KB gz), `semiotic/recipes` (9KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (250KB gz). Full `semiotic` is 203KB gz.
7
+ - **Use sub-path imports** — `semiotic/xy` (96KB gz), `semiotic/ordinal` (78KB gz), `semiotic/network` (73KB gz), `semiotic/geo` (57KB gz), `semiotic/realtime` (104KB gz), `semiotic/server` (132KB gz), `semiotic/utils` (39KB gz), `semiotic/recipes` (19KB gz), `semiotic/themes` (6KB gz), `semiotic/data` (4KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (269KB gz). Full `semiotic` is 216KB gz.
8
8
  <!-- semiotic-bundle-sizes:end -->
9
9
  - CLI: `npx semiotic-ai [--schema|--compact|--examples|--doctor|--audit-a11y]` · MCP: `npx semiotic-mcp`
10
10
 
@@ -24,7 +24,7 @@ HOC Charts (simple, default) → Stream Frames (full control). Use HOCs unless y
24
24
  **AreaChart** — LineChart props + `areaBy`, `y0Accessor`, `gradientFill`, `areaOpacity` (0.7), `showLine` (true), `band`, `tooltip="multi"`
25
25
  **DifferenceChart** — Two-series A/B. Fills between with `seriesAColor` where A>B, `seriesBColor` where B>A; crossovers interpolated. `data`, `xAccessor`, `seriesAAccessor` ("a"), `seriesBAccessor` ("b"), `seriesALabel`/`seriesBLabel`, `seriesAColor` (var(--semiotic-danger))/`seriesBColor` (var(--semiotic-info)), `showLines` (true), `lineWidth` (1.5), `showPoints` (false), `pointRadius` (3), `curve` ("linear"), `areaOpacity` (0.6), `gradientFill`, `xExtent`/`yExtent`, `pointIdAccessor`, `windowSize`. Push via `ref.push({x,a,b})`. Accessor outputs coerce through `toNumber`.
26
26
  **StackedAreaChart** — flat array + `areaBy` (required), `colorBy`, `normalize`, `baseline` ("zero"|"wiggle" streamgraph|"silhouette" centered), `stackOrder` ("key"|"insideOut"|"asc"|"desc"). Streamgraph: `baseline="wiggle"` + `stackOrder="insideOut"`. `baseline` ⊥ `normalize`. No `lineBy`. `tooltip="multi"` interpolates between samples.
27
- **Scatterplot** — `xAccessor`, `yAccessor`, `colorBy`, `sizeBy`, `sizeRange`, `pointRadius` (5), `pointOpacity` (0.8), `marginalGraphics`, `regression` (boolean | "linear"|"polynomial"|"loess" | RegressionConfig — sugar for trend overlay)
27
+ **Scatterplot** — `xAccessor`, `yAccessor`, `colorBy`, `sizeBy`, `sizeRange`, `symbolBy` (categorical field → glyph **shape**: each mark becomes a d3-shape glyph; size still tracks `sizeBy`/`pointRadius`), `symbolMap` ({category → shape}; unmapped auto-assign — pass it for legend-matchable shapes), `pointRadius` (5), `pointOpacity` (0.8), `marginalGraphics`, `regression` (boolean | "linear"|"polynomial"|"loess" | RegressionConfig — sugar for trend overlay)
28
28
  **BubbleChart** — Scatterplot + `sizeBy` (required), `sizeRange` ([5,40]), `regression`
29
29
  **ConnectedScatterplot** — + `orderAccessor`, `regression`
30
30
  **QuadrantChart** — Scatterplot + `quadrants`, `xCenter`, `yCenter`
@@ -39,7 +39,7 @@ HOC Charts (simple, default) → Stream Frames (full control). Use HOCs unless y
39
39
  **BarChart** — `categoryAccessor`, `valueAccessor`, `orientation`, `colorBy`, `sort`, `barPadding` (40), `roundedTop`, `gradientFill` (true | {topOpacity, bottomOpacity} | {colorStops}; tip→base), `regression`
40
40
  **StackedBarChart** — + `stackBy` (required), `normalize`, `sort` (false default — insertion order)
41
41
  **GroupedBarChart** — + `groupBy` (required), `barPadding` (60), `sort` (false default)
42
- **SwarmPlot** — `colorBy`, `sizeBy`, `pointRadius`, `pointOpacity`
42
+ **SwarmPlot** — `colorBy`, `sizeBy`, `symbolBy` (categorical field → glyph shape, like Scatterplot), `symbolMap`, `pointRadius`, `pointOpacity`
43
43
  **BoxPlot** — + `showOutliers`, `outlierRadius`
44
44
  **Histogram** — + `bins` (25), `relative`. Always horizontal.
45
45
  **ViolinPlot** — + `bins`, `curve`, `showIQR`
@@ -127,13 +127,14 @@ When the catalog doesn't fit, three HOCs take a layout function emitting scene p
127
127
 
128
128
  - **`XYCustomChart`** (`semiotic/xy`) — waffle, calendar heatmap, custom point/line/area
129
129
  - **`OrdinalCustomChart`** (`semiotic/ordinal`) — marimekko, parallel coords, bullet, fan, slope
130
- - **`NetworkCustomChart`** (`semiotic/network`) — flextree, dagre, custom force/radial
130
+ - **`NetworkCustomChart`** (`semiotic/network`) — flextree, dagre, custom force/radial, packed-cluster beeswarm matrix
131
131
 
132
132
  Layout signature differs by family:
133
133
  - **XY/Ordinal**: `layout: (ctx) => { nodes, overlays? }`. `ctx`: `data`, `scales` ({x,y} XY | {o,r,projection} ordinal), `dimensions` (plot rect — center-anchored for radial ordinal, top-left otherwise), `theme`, `resolveColor(key)`, `config`.
134
- - **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection` (shared-selection predicate `{ isActive, predicate(datum) }` from `LinkedCharts`, `null` when unwired — dim/highlight by it). Run external positioners (`d3-flextree`, `dagre`) then emit network scene primitives (circle/rect/arc nodes; line/bezier/curved edges).
134
+ - **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays?, htmlMarks? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection` (shared-selection predicate `{ isActive, predicate(datum) }` from `LinkedCharts`, `null` when unwired — dim/highlight by it). Run external positioners (`d3-flextree`, `dagre`) then emit network scene primitives (circle/rect/arc/**symbol** nodes; line/bezier/curved edges). The `symbol` node is the per-datum **shape** channel — a `d3-shape` glyph (`circle`/`square`/`triangle`/`diamond`/`star`/`cross`/`wye`/`chevron`, or a custom `path`) sized by `size` (area), rendered on canvas + SVG/SSR and hit-tested + keyboard-navigated as a unit. **The `symbol` mark is cross-pipeline**: XY and ordinal custom layouts emit it too (`{type:"symbol", x, y, size, symbolType}` — note `x`/`y`, vs the network variant's `cx`/`cy`), and Scatterplot/SwarmPlot expose it as the `symbolBy` encoding. One shared `symbolPath` implementation backs canvas/SVG/hit-test across all three families.
135
+ - **`htmlMarks`** (network only): `NetworkHtmlMark[]` = `{ id, x, y, width, height, content: ReactNode }`, positioned in the **same plot space as `sceneNodes`** and rendered into one real-DOM layer the framework places **above the canvas and SVG `overlays`** (stack: canvas → `overlays` → `htmlMarks`). Reach for it over an SVG `<foreignObject>` when a mark is **text-heavy/rich and dims or animates on hover** — a real `<div>` composites `opacity`/`transform`/`visibility` changes instead of re-rasterizing text (the `foreignObject` stall on large graphs). Framework owns the margin (and future zoom/pan) transform so marks stay pixel-aligned; each mark is its own element, keyed by `id` (position-only re-runs reposition without remounting). `pointer-events: none` by default — keep a transparent hit-rect `sceneNode` per mark so canvas hit-testing/`onObservation` stays authoritative. Mark `content` can read `useCustomLayoutSelection()` to dim on shared selection without a relayout. Additive: omit it and no extra DOM renders. Class hooks: `.semiotic-network-html-marks` (layer) / `.semiotic-network-html-mark` (each).
135
136
 
136
- `semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `flextreeLayout`, `dagreLayout`, `lineageDagLayout`). BYO heavy deps (`d3-flextree`, `dagre`) in user code. `lineageDagLayout` renders a pre-positioned **layered lineage/DAG** (reads logical layer/row coords, no re-layout) with composite node glyphs (one hit-rect per node + icon/label/store-chip chrome in `overlays`), level-of-detail collapse (full→compact→icon→dot), distinct dashed back-edges, and host-driven reach-dimming (`layoutConfig.reachableIds`) + selection (`layoutConfig.selectedId` / shared `ctx.selection`).
137
+ `semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `flextreeLayout`, `dagreLayout`, `lineageDagLayout`, `packedClusterMatrix`). BYO heavy deps (`d3-flextree`, `dagre`) in user code. `packedClusterMatrix` (network) bins records into a column×row matrix of **densely-packed beeswarm clusters** (deterministic self-contained packing, geometry cached) and emits **multi-channel glyphs** — hue (`colorAccessor`/`colorMap`), size (`sizeAccessor`, area), shade (`shadeAccessor`, CIELAB lightness), plus EITHER shape-encoding (`symbolAccessor`/`symbolMap` — the base mark becomes that shape) OR the **composite-glyph** model (`iconAccessor`/`iconMap` — base is a filled circle, only mapped values get a stroked inner icon). `rowMode:"banded"` (default) gives aligned global orbit-bands (row labels align, one enclosure spans the columns per band, columns vary in height) vs `"stacked"` (per-column cell heights ∝ count). `callouts:[{field,value,label}]` draws leader lines to named marks. `cellSizing:"proportional"` makes area ∝ count. **Recipe chrome kit** (exported from `semiotic/recipes`, for any custom-layout's `overlays`): `roundedEnclosure`/`boundsOf` (group/band borders), `bandLabel` (overflow-aware axis/band labels), `markCallout` (leader-line callout to a mark), `readField` (`node.data`-wrapper reader), `groupBy`, `dimFor` (the highlight/dim opacity rule — `{predicate?, highlight?, baseOpacity?, dimOpacity?, brighten?}`; `matchesHighlight` is its `{field,value}[]` matcher), `signatureKey`/`LayoutCache` (content-signature geometry cache so re-styling never re-runs an expensive layout — key by *content*, never by `ctx.nodes` identity), `legendGroupsFrom` (`{colorMap|keys, symbolMap?, sizeStops?}` → `LegendGroup[]` for `frameProps.legend`), `shade`/`makeShade`, `symbolPathString`/`symbolRadius`/`symbolExtent`/`SYMBOL_SEQUENCE`. (`bandLabel`/`dimFor` are adopted by marimekko/bullet/parallelCoordinates/packedClusterMatrix.) `lineageDagLayout` renders a pre-positioned **layered lineage/DAG** (reads logical layer/row coords, no re-layout) with composite node glyphs (one hit-rect per node + icon/label/store-chip chrome in `overlays`), level-of-detail collapse (full→compact→icon→dot), distinct dashed back-edges, and host-driven reach-dimming (`layoutConfig.reachableIds`) + selection (`layoutConfig.selectedId` / shared `ctx.selection`).
137
138
 
138
139
  **Chrome (labels/axes/legends): the recipe owns it.** Recipes emit own chrome via `overlays` return field (ReactNode painted on top). Built-in axes via `showAxes` on the HOC work for layouts respecting the standard scale. Recipe convention: `showXxx` boolean toggles, `xxxFormat` callbacks. Shipped recipes' toggles: marimekko `showCategoryLabels`, bullet `showLabels`+`showTicks`, parallelCoordinates `showAxes`, flextree/dagre `showLabels`, waffle/calendar none.
139
140
 
@@ -145,7 +146,9 @@ Layout signature differs by family:
145
146
  - Streaming layouts: ingest via ref (`push`/`pushMany`); layout re-runs on each ingest. Overlays update on data-change paths, NOT per-frame.
146
147
  - **On `NetworkCustomChart`, a `layoutConfig` change re-runs the layout (`buildScene`) WITHOUT re-ingesting the node/edge topology** — so drive interaction state, styling, or animation progress through `layoutConfig` for cheap per-frame updates; swapping `nodes`/`edges` (or the chart `width`/`height`) is the heavier path that re-ingests. Custom overlays are read straight from the store at render time (the frame's repaint re-reads them), so a recipe returning fresh JSX every layout call needs no per-frame `setState`.
147
148
  - Custom layouts own their colors — always prefer `ctx.resolveColor(key)` over hardcoded literals. `CategoryColorProvider` integration is XY-only; for cross-chart sync on network/ordinal customLayouts, pass matching `colorScheme` to each.
148
- - `NetworkCustomChart` accepts `selection` / `linkedHover` / `chartId` like the built-in network HOCs: hover/click emit into the shared selection store, and the resolved predicate arrives as `ctx.selection` so the layout can dim/highlight by a cross-chart selection. Host-owned per-render dimming (e.g. a graph-reachability set) is orthogonal — pass it through `layoutConfig` and read `ctx.config`.
149
+ - All three custom HOCs accept `selection` / `linkedHover` / `chartId` like the built-in HOCs: hover/click emit into the shared selection store, and the resolved predicate arrives as `ctx.selection` so the layout can dim/highlight by a cross-chart selection. Host-owned per-render dimming (e.g. a graph-reachability set) is orthogonal — pass it through `layoutConfig` and read `ctx.config`.
150
+ - **Selection restyle without a relayout** (the cheap hover path): by default a `ctx.selection` change re-runs the layout (rebuilds sceneNodes + repaints + rebuilds the quadtree). To restyle on hover/selection *without* re-positioning, opt in two ways: (1) return a **`restyle(node, selection)`** (network also `restyleEdge`) from the layout result — its presence makes a selection change re-apply styles to the existing scene **off each mark's base style** and just repaint (no relayout, no quadtree rebuild); compute geometry once in the layout body, express dimming in `restyle`. (2) For the React **`overlays`**, call **`useCustomLayoutSelection()`** (from `semiotic`/`semiotic/recipes` or the family entry) → `{ isActive, predicate }`; the frame swaps only the context value on selection change, so subscribing overlay components re-render while the canvas/quadtree stay untouched. Express selection/highlight through the selection store (not `layoutConfig`) to ride this path.
151
+ - **Annotation-to-mark anchoring**: all three custom HOCs accept `annotations`. A custom layout's marks anchor by id — emit a scene node with `id: "<foo>"` and an annotation `{ pointId: "<foo>", … }` resolves to that mark's center (XY/ordinal point+symbol nodes and every network node are harvested as anchor points). Data-coordinate anchoring still works for XY/ordinal; network has no data scales, so anchor by `pointId` (or draw a `markCallout` directly).
149
152
  - Tooltips: emit datum keys matching user-visible accessor names. Avoid underscored synthetic keys (default tooltip filters those out).
150
153
 
151
154
  ## Coordinated Views
package/README.md CHANGED
@@ -12,15 +12,15 @@ Simple charts in 5 lines. Network graphs, streaming data, and coordinated
12
12
  dashboards when you need them. Structured schemas and an MCP server so
13
13
  AI coding assistants generate correct chart code on the first try.
14
14
 
15
- ## What's New in 3.7.4
15
+ ## What's New in 3.7.5
16
16
 
17
- 3.7.4 is a network-chart and maintenance patch release:
17
+ 3.7.5 is a chart-correctness and responsive-layout patch release:
18
18
 
19
- - `semiotic/recipes` adds lineage DAG helpers for laying out data-flow and KStreams-style network
20
- diagrams.
21
- - Network custom layouts now preserve selection metadata through streaming layout and render paths.
22
- - Docs add the KStreams DAG recipe and expand custom network chart guidance, alongside
23
- dependency updates for Prettier, TypeScript ESLint, Rollup, and Sharp.
19
+ - ForceDirectedGraph string `edgeWidth` accessors now read the underlying edge data, and server
20
+ rendering handles `edgeWidth`, `edgeColor`, and `edgeOpacity` for SSR parity.
21
+ - Crowded ordinal category axes now thin tick labels to avoid overlapping temporal-histogram bins.
22
+ - XY custom-layout overlays now re-run on responsive size changes, keeping SVG chrome aligned with
23
+ canvas scene nodes after first measurement.
24
24
 
25
25
  ```jsx
26
26
  import { LineChart } from "semiotic/xy"
@@ -105,6 +105,23 @@ Charts serialize to JSON and back: `toConfig`, `fromConfig`, `toURL`,
105
105
  translates them to Semiotic configs — works with `configToJSX()` for
106
106
  full round-trip from notebooks and AI-generated specs.
107
107
 
108
+ Need an external pitfall review? `toDataPitfallsChain()` builds a
109
+ dependency-free chain input for [`datapitfalls`](https://github.com/bjonesdataliteracy/datapitfalls),
110
+ combining the Semiotic config, JSX, reader grounding, diagnostics,
111
+ accessibility audit, and optional rendered SVG/image evidence:
112
+
113
+ ```ts
114
+ import { toDataPitfallsChain } from "semiotic/ai"
115
+ import { detectPitfalls } from "datapitfalls"
116
+
117
+ const input = toDataPitfallsChain("LineChart", props, {
118
+ narrative: "Monthly sales are accelerating.",
119
+ rendered: { svg, evidence },
120
+ })
121
+
122
+ const report = await detectPitfalls(input, { apiKey: process.env.ANTHROPIC_API_KEY })
123
+ ```
124
+
108
125
  ### When to use something else
109
126
 
110
127
  Need a standard bar or line chart for a dashboard you'll never need to
@@ -325,19 +342,19 @@ Semiotic ships 12 entry points. **Don't import from `"semiotic"` unless you need
325
342
 
326
343
  | Entry Point | gzip | What's inside |
327
344
  |---|---|---|
328
- | `semiotic/xy` | **90 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
329
- | `semiotic/ordinal` | **74 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
330
- | `semiotic/network` | **68 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
331
- | `semiotic/geo` | **55 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
332
- | `semiotic/realtime` | **95 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
333
- | `semiotic/server` | **128 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
334
- | `semiotic/utils` | **38 KB** | ThemeProvider, validators, serialization — no chart components |
335
- | `semiotic/recipes` | **9 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
336
- | `semiotic/themes` | **4 KB** | Theme presets only (tufte, carbon, etc.) |
337
- | `semiotic/data` | **3 KB** | bin, rollup, groupBy, pivot, fromVegaLite |
345
+ | `semiotic/xy` | **96 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
346
+ | `semiotic/ordinal` | **78 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
347
+ | `semiotic/network` | **73 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
348
+ | `semiotic/geo` | **57 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
349
+ | `semiotic/realtime` | **104 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
350
+ | `semiotic/server` | **132 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
351
+ | `semiotic/utils` | **39 KB** | ThemeProvider, validators, serialization — no chart components |
352
+ | `semiotic/recipes` | **19 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
353
+ | `semiotic/themes` | **6 KB** | Theme presets only (tufte, carbon, etc.) |
354
+ | `semiotic/data` | **4 KB** | bin, rollup, groupBy, pivot, fromVegaLite |
338
355
  | `semiotic/value` | **6 KB** | BigNumber — focal-value KPI / scorecard (SingleValueFrame POC) |
339
- | `semiotic/ai` | **250 KB** | All 47 schema-backed charts + validation — optimized for LLM code generation |
340
- | `semiotic` | **203 KB** | Everything below (full bundle) |
356
+ | `semiotic/ai` | **269 KB** | All 47 schema-backed charts + validation — optimized for LLM code generation |
357
+ | `semiotic` | **216 KB** | Everything below (full bundle) |
341
358
 
342
359
  <!-- semiotic-bundle-sizes:end -->
343
360
 
package/ai/schema.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "name": "semiotic",
4
- "version": "3.7.4",
4
+ "version": "3.7.5",
5
5
  "description": "React data visualization library for charts, networks, and beyond",
6
6
  "tools": [
7
7
  {
@@ -117,6 +117,24 @@
117
117
  "yLabel": {
118
118
  "type": "string"
119
119
  },
120
+ "xScaleType": {
121
+ "type": "string",
122
+ "enum": [
123
+ "linear",
124
+ "log",
125
+ "time"
126
+ ],
127
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
128
+ },
129
+ "yScaleType": {
130
+ "type": "string",
131
+ "enum": [
132
+ "linear",
133
+ "log",
134
+ "time"
135
+ ],
136
+ "description": "y scale type."
137
+ },
120
138
  "data": {
121
139
  "type": "array",
122
140
  "description": "Array of data objects"
@@ -325,6 +343,24 @@
325
343
  "yLabel": {
326
344
  "type": "string"
327
345
  },
346
+ "xScaleType": {
347
+ "type": "string",
348
+ "enum": [
349
+ "linear",
350
+ "log",
351
+ "time"
352
+ ],
353
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
354
+ },
355
+ "yScaleType": {
356
+ "type": "string",
357
+ "enum": [
358
+ "linear",
359
+ "log",
360
+ "time"
361
+ ],
362
+ "description": "y scale type."
363
+ },
328
364
  "data": {
329
365
  "type": "array",
330
366
  "description": "Array of data objects"
@@ -532,6 +568,24 @@
532
568
  "yLabel": {
533
569
  "type": "string"
534
570
  },
571
+ "xScaleType": {
572
+ "type": "string",
573
+ "enum": [
574
+ "linear",
575
+ "log",
576
+ "time"
577
+ ],
578
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
579
+ },
580
+ "yScaleType": {
581
+ "type": "string",
582
+ "enum": [
583
+ "linear",
584
+ "log",
585
+ "time"
586
+ ],
587
+ "description": "y scale type."
588
+ },
535
589
  "data": {
536
590
  "type": "array",
537
591
  "description": "Array of data objects"
@@ -714,6 +768,24 @@
714
768
  "yLabel": {
715
769
  "type": "string"
716
770
  },
771
+ "xScaleType": {
772
+ "type": "string",
773
+ "enum": [
774
+ "linear",
775
+ "log",
776
+ "time"
777
+ ],
778
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
779
+ },
780
+ "yScaleType": {
781
+ "type": "string",
782
+ "enum": [
783
+ "linear",
784
+ "log",
785
+ "time"
786
+ ],
787
+ "description": "y scale type."
788
+ },
717
789
  "data": {
718
790
  "type": "array",
719
791
  "description": "Array of data objects"
@@ -747,6 +819,17 @@
747
819
  15
748
820
  ]
749
821
  },
822
+ "symbolBy": {
823
+ "type": [
824
+ "string",
825
+ "function"
826
+ ],
827
+ "description": "Categorical field → glyph shape; each mark renders as a d3-shape glyph (circle/square/triangle/diamond/star/cross/wye/chevron) instead of a circle."
828
+ },
829
+ "symbolMap": {
830
+ "type": "object",
831
+ "description": "Explicit {category → shape} map for symbolBy; unmapped categories auto-assign."
832
+ },
750
833
  "pointRadius": {
751
834
  "type": "number",
752
835
  "description": "Fixed point radius",
@@ -892,6 +975,24 @@
892
975
  "yLabel": {
893
976
  "type": "string"
894
977
  },
978
+ "xScaleType": {
979
+ "type": "string",
980
+ "enum": [
981
+ "linear",
982
+ "log",
983
+ "time"
984
+ ],
985
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
986
+ },
987
+ "yScaleType": {
988
+ "type": "string",
989
+ "enum": [
990
+ "linear",
991
+ "log",
992
+ "time"
993
+ ],
994
+ "description": "y scale type."
995
+ },
895
996
  "data": {
896
997
  "type": "array",
897
998
  "description": "Array of data objects"
@@ -1091,6 +1192,24 @@
1091
1192
  "yLabel": {
1092
1193
  "type": "string"
1093
1194
  },
1195
+ "xScaleType": {
1196
+ "type": "string",
1197
+ "enum": [
1198
+ "linear",
1199
+ "log",
1200
+ "time"
1201
+ ],
1202
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
1203
+ },
1204
+ "yScaleType": {
1205
+ "type": "string",
1206
+ "enum": [
1207
+ "linear",
1208
+ "log",
1209
+ "time"
1210
+ ],
1211
+ "description": "y scale type."
1212
+ },
1094
1213
  "data": {
1095
1214
  "type": "array",
1096
1215
  "description": "Array of data objects shared by both series"
@@ -1235,6 +1354,24 @@
1235
1354
  "yLabel": {
1236
1355
  "type": "string"
1237
1356
  },
1357
+ "xScaleType": {
1358
+ "type": "string",
1359
+ "enum": [
1360
+ "linear",
1361
+ "log",
1362
+ "time"
1363
+ ],
1364
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
1365
+ },
1366
+ "yScaleType": {
1367
+ "type": "string",
1368
+ "enum": [
1369
+ "linear",
1370
+ "log",
1371
+ "time"
1372
+ ],
1373
+ "description": "y scale type."
1374
+ },
1238
1375
  "data": {
1239
1376
  "type": "array"
1240
1377
  },
@@ -1408,6 +1545,24 @@
1408
1545
  "yLabel": {
1409
1546
  "type": "string"
1410
1547
  },
1548
+ "xScaleType": {
1549
+ "type": "string",
1550
+ "enum": [
1551
+ "linear",
1552
+ "log",
1553
+ "time"
1554
+ ],
1555
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
1556
+ },
1557
+ "yScaleType": {
1558
+ "type": "string",
1559
+ "enum": [
1560
+ "linear",
1561
+ "log",
1562
+ "time"
1563
+ ],
1564
+ "description": "y scale type."
1565
+ },
1411
1566
  "data": {
1412
1567
  "type": "array",
1413
1568
  "description": "Array of data objects"
@@ -1584,6 +1739,24 @@
1584
1739
  "yLabel": {
1585
1740
  "type": "string"
1586
1741
  },
1742
+ "xScaleType": {
1743
+ "type": "string",
1744
+ "enum": [
1745
+ "linear",
1746
+ "log",
1747
+ "time"
1748
+ ],
1749
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
1750
+ },
1751
+ "yScaleType": {
1752
+ "type": "string",
1753
+ "enum": [
1754
+ "linear",
1755
+ "log",
1756
+ "time"
1757
+ ],
1758
+ "description": "y scale type."
1759
+ },
1587
1760
  "data": {
1588
1761
  "type": "array",
1589
1762
  "description": "Array of data objects with x, y, and value"
@@ -1757,6 +1930,24 @@
1757
1930
  "yLabel": {
1758
1931
  "type": "string"
1759
1932
  },
1933
+ "xScaleType": {
1934
+ "type": "string",
1935
+ "enum": [
1936
+ "linear",
1937
+ "log",
1938
+ "time"
1939
+ ],
1940
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
1941
+ },
1942
+ "yScaleType": {
1943
+ "type": "string",
1944
+ "enum": [
1945
+ "linear",
1946
+ "log",
1947
+ "time"
1948
+ ],
1949
+ "description": "y scale type."
1950
+ },
1760
1951
  "data": {
1761
1952
  "type": "array",
1762
1953
  "description": "Array of data objects"
@@ -2659,6 +2850,17 @@
2659
2850
  8
2660
2851
  ]
2661
2852
  },
2853
+ "symbolBy": {
2854
+ "type": [
2855
+ "string",
2856
+ "function"
2857
+ ],
2858
+ "description": "Categorical field → glyph shape; each point renders as a d3-shape glyph instead of a circle."
2859
+ },
2860
+ "symbolMap": {
2861
+ "type": "object",
2862
+ "description": "Explicit {category → shape} map for symbolBy; unmapped categories auto-assign."
2863
+ },
2662
2864
  "pointRadius": {
2663
2865
  "type": "number",
2664
2866
  "default": 4
@@ -7599,6 +7801,24 @@
7599
7801
  "yLabel": {
7600
7802
  "type": "string"
7601
7803
  },
7804
+ "xScaleType": {
7805
+ "type": "string",
7806
+ "enum": [
7807
+ "linear",
7808
+ "log",
7809
+ "time"
7810
+ ],
7811
+ "description": "x scale type. \"time\" builds a scaleTime (required for landmark ticks on timestamps)."
7812
+ },
7813
+ "yScaleType": {
7814
+ "type": "string",
7815
+ "enum": [
7816
+ "linear",
7817
+ "log",
7818
+ "time"
7819
+ ],
7820
+ "description": "y scale type."
7821
+ },
7602
7822
  "data": {
7603
7823
  "type": "array",
7604
7824
  "description": "Array of `{x, a, b}` objects. Omit for push API mode."
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- semiotic-bundle-sizes:start -->
4
4
  <!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
5
- **Use sub-path imports** — `semiotic/xy` (90KB gz), `semiotic/ordinal` (74KB gz), `semiotic/network` (68KB gz), `semiotic/geo` (55KB gz), `semiotic/realtime` (95KB gz), `semiotic/server` (128KB gz), `semiotic/utils` (38KB gz), `semiotic/recipes` (9KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (250KB gz). Full `semiotic` is 203KB gz.
5
+ **Use sub-path imports** — `semiotic/xy` (96KB gz), `semiotic/ordinal` (78KB gz), `semiotic/network` (73KB gz), `semiotic/geo` (57KB gz), `semiotic/realtime` (104KB gz), `semiotic/server` (132KB gz), `semiotic/utils` (39KB gz), `semiotic/recipes` (19KB gz), `semiotic/themes` (6KB gz), `semiotic/data` (4KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (269KB gz). Full `semiotic` is 216KB gz.
6
6
  <!-- semiotic-bundle-sizes:end -->
7
7
 
8
8
  ## Flat Array Data (`data: object[]`)
@@ -143,4 +143,5 @@ These rules are generated from `ai/behaviorContracts.cjs` and are consumed by `s
143
143
  - **SSR**: `renderChart("BarChart", props)` from `semiotic/server` — uses HOC names. Also `"Sparkline"` (no axes, 2px margins). `renderChartWithEvidence()` returns `{ svg, evidence }` (mark counts by scene type, axis domains, empty flag, annotation count, accessible name) so agents can verify the render drew data marks. `renderToImage()` (PNG), `renderToAnimatedGif()` (GIF), `renderDashboard()` (multi-chart). All accept `theme`. Required props: StackedBarChart needs `stackBy`, GroupedBarChart needs `groupBy`, StackedAreaChart needs `areaBy`, BubbleChart needs `sizeBy`, FunnelChart uses `stepAccessor`, GaugeChart needs `value` (`thresholds` optional).
144
144
  - **CLI**: `npx semiotic-ai --list` shows components/import paths/renderability; `npx semiotic-ai --schema GaugeChart` prints one component schema with metadata; `--doctor` validates props JSON and behavior contracts.
145
145
  - **MCP**: `npx semiotic-mcp` exposes schema, suggestion, diagnosis, accessibility, grounding, issue, theme, static render (`renderChart`), and ChatGPT Apps render (`renderInteractiveChart`) tools. Resources include `semiotic://schema`, `semiotic://components`, `semiotic://behavior-contracts`, `semiotic://system-prompt`, `semiotic://examples`, and the widget template `ui://semiotic/chart-widget.html`. Prompts: `build-semiotic-chart`, `debug-semiotic-chart`.
146
+ - **Data Pitfalls bridge**: `toDataPitfallsChain(component, props, { rendered, context, narrative })` from `semiotic/ai` returns a dependency-free `datapitfalls` chain input containing config, JSX, reader grounding, diagnostics, accessibility audit, and optional render evidence/image.
146
147
  - **exportChart**: Pass the wrapper div, not the SVG element: `exportChart(wrapperDiv, { format: "png" })`. It finds canvas+SVG internally.
@@ -7,6 +7,10 @@ type AnnotationNote = {
7
7
  orientation?: string;
8
8
  align?: string;
9
9
  noWrap?: boolean;
10
+ /** Render note text in a foreignObject for browser-native HTML wrapping. */
11
+ useHTML?: boolean;
12
+ /** Alias for useHTML. */
13
+ html?: boolean;
10
14
  };
11
15
  type AnnotationConnector = {
12
16
  end?: "arrow";
@@ -3,6 +3,7 @@ interface DataSummaryState {
3
3
  /** When true, AccessibleDataTable renders visibly instead of sr-only */
4
4
  visible: boolean;
5
5
  setVisible: React.Dispatch<React.SetStateAction<boolean>>;
6
+ toggle: () => void;
6
7
  }
7
8
  export declare function DataSummaryProvider({ children }: {
8
9
  children: React.ReactNode;
@@ -73,6 +73,22 @@ export interface ChartDataProfile extends DataSummary {
73
73
  hasRepeatedX: boolean;
74
74
  /** True when the primary x candidate is monotonic. */
75
75
  monotonicX: boolean;
76
+ /**
77
+ * How amenable the (x × series) grid is to stacking. Only populated when both
78
+ * a primary x and series field exist. A stacked area/bar reads as bands only
79
+ * when series share x columns; when most columns hold a single series, the
80
+ * renderer zero-fills the gaps and every layer collapses into an isolated
81
+ * triangular spike instead of a continuous band. Capabilities gate on this to
82
+ * decline stacking on near-unique x (flat record lists, scatter-shaped data).
83
+ */
84
+ stackability?: {
85
+ /** Mean distinct series present per x value. ~1 → spiky; ~seriesCount → dense. */
86
+ seriesPerX: number;
87
+ /** Fraction of x columns where 2+ series coexist (where stacking is visible). */
88
+ multiSeriesFraction: number;
89
+ /** Number of distinct x columns considered. */
90
+ xColumns: number;
91
+ };
76
92
  /** True when there is at least one date-typed candidate. */
77
93
  hasTimeAxis: boolean;
78
94
  /**
@@ -0,0 +1,101 @@
1
+ import type { Datum } from "../charts/shared/datumTypes";
2
+ import { type AccessibilityAuditResult, type AuditAccessibilityOptions } from "../charts/shared/auditAccessibility";
3
+ import { type DiagnosisResult } from "../charts/shared/diagnoseConfig";
4
+ import { type ChartConfig, type ToConfigOptions } from "../export/chartConfig";
5
+ import { type ChartReaderGrounding, type ChartReaderGroundingOptions } from "./readerGrounding";
6
+ export type DataPitfallsImageMediaType = "image/png" | "image/jpeg" | "image/gif" | "image/webp";
7
+ export interface DataPitfallsImageSource {
8
+ content: string;
9
+ mediaType: DataPitfallsImageMediaType;
10
+ filename?: string;
11
+ }
12
+ export interface DataPitfallsTextInput {
13
+ kind: "code" | "text";
14
+ content: string;
15
+ language?: string;
16
+ filename?: string;
17
+ }
18
+ export interface DataPitfallsImageInput {
19
+ kind: "image";
20
+ images: DataPitfallsImageSource[];
21
+ }
22
+ export interface DataPitfallsDocumentInput {
23
+ kind: "document";
24
+ content: string;
25
+ mediaType: "application/pdf";
26
+ filename?: string;
27
+ }
28
+ export interface DataPitfallsSlideContent {
29
+ text: string;
30
+ images: DataPitfallsImageSource[];
31
+ }
32
+ export interface DataPitfallsSlidesInput {
33
+ kind: "slides";
34
+ slides: DataPitfallsSlideContent[];
35
+ filename?: string;
36
+ }
37
+ export type DataPitfallsSingleArtifactInput = DataPitfallsTextInput | DataPitfallsImageInput | DataPitfallsDocumentInput | DataPitfallsSlidesInput;
38
+ export interface DataPitfallsChainStage {
39
+ role: string;
40
+ artifact: DataPitfallsSingleArtifactInput;
41
+ }
42
+ export interface DataPitfallsChainInput {
43
+ kind: "chain";
44
+ stages: DataPitfallsChainStage[];
45
+ }
46
+ export interface DataPitfallsRenderedChart {
47
+ /** SVG markup from `semiotic/server` renderChart/renderChartWithEvidence or MCP renderChart. */
48
+ svg?: string;
49
+ /** Render evidence from `renderChartWithEvidence` or MCP renderChart. */
50
+ evidence?: unknown;
51
+ /** Optional rendered chart image for Data Pitfalls' Vision path. */
52
+ image?: DataPitfallsImageSource | DataPitfallsImageSource[];
53
+ }
54
+ export interface DataPitfallsBridgeOptions {
55
+ /** Default true. Include the serializable Semiotic chart config as JSON. */
56
+ includeConfig?: boolean;
57
+ /** Default true. Include JSX reconstructed from the serializable chart config. */
58
+ includeJSX?: boolean;
59
+ /** Default true. Include describeChart/buildReaderGrounding text and structure. */
60
+ includeGrounding?: boolean;
61
+ /** Default true. Include diagnoseConfig output. */
62
+ includeDiagnostics?: boolean;
63
+ /** Default true. Include auditAccessibility output. */
64
+ includeAccessibility?: boolean;
65
+ /** Optional author or app context, such as the analytical question or intended claim. */
66
+ context?: string;
67
+ /** Optional narrative/caption/claim that will be reviewed alongside the chart. */
68
+ narrative?: string;
69
+ /** Optional output from a render path. */
70
+ rendered?: DataPitfallsRenderedChart;
71
+ /** Forwarded to toConfig. Use includeData: false to omit raw rows from config/JSX stages; other stages may still summarize data. */
72
+ config?: ToConfigOptions;
73
+ /** Forwarded to buildReaderGrounding. */
74
+ grounding?: ChartReaderGroundingOptions;
75
+ /** Forwarded to auditAccessibility. */
76
+ accessibility?: AuditAccessibilityOptions;
77
+ /** Prefix used for generated filenames. Default: component name. */
78
+ filenamePrefix?: string;
79
+ /** Extra caller-supplied chain stages, appended last. */
80
+ additionalStages?: DataPitfallsChainStage[];
81
+ }
82
+ export interface DataPitfallsBridgeResult {
83
+ input: DataPitfallsChainInput;
84
+ config: ChartConfig;
85
+ grounding?: ChartReaderGrounding;
86
+ diagnosis?: DiagnosisResult;
87
+ accessibility?: AccessibilityAuditResult;
88
+ }
89
+ /**
90
+ * Build a Data Pitfalls-compatible chain input from a Semiotic chart config.
91
+ *
92
+ * The returned `input` is intentionally dependency-free: pass it to
93
+ * `detectPitfalls(input, options)` from the `datapitfalls` package in your app,
94
+ * CI job, or research harness. Semiotic contributes the chart config,
95
+ * reader-grounding payload, config diagnostics, accessibility audit, and
96
+ * optional rendered output; Data Pitfalls remains responsible for model-backed
97
+ * pitfall detection.
98
+ */
99
+ export declare function buildDataPitfallsBridge(component: string, props: Datum, options?: DataPitfallsBridgeOptions): DataPitfallsBridgeResult;
100
+ /** Convenience wrapper when you only need the Data Pitfalls input object. */
101
+ export declare function toDataPitfallsChain(component: string, props: Datum, options?: DataPitfallsBridgeOptions): DataPitfallsChainInput;