semiotic 3.0.0 → 3.0.1

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 (181) hide show
  1. package/CLAUDE.md +23 -10
  2. package/README.md +66 -63
  3. package/ai/cli.js +34 -21
  4. package/ai/dist/componentRegistry.js +2 -0
  5. package/ai/dist/mcp-server.js +54 -0
  6. package/ai/examples.md +75 -0
  7. package/ai/schema.json +71 -0
  8. package/ai/system-prompt.md +3 -0
  9. package/dist/{ChartGrid.d.ts → components/ChartGrid.d.ts} +9 -7
  10. package/dist/{LinkedCharts.d.ts → components/LinkedCharts.d.ts} +34 -1
  11. package/dist/{Tooltip → components/Tooltip}/Tooltip.d.ts +9 -2
  12. package/dist/{charts → components/charts}/index.d.ts +2 -0
  13. package/dist/{charts → components/charts}/network/ChordDiagram.d.ts +2 -0
  14. package/dist/{charts → components/charts}/network/CirclePack.d.ts +2 -0
  15. package/dist/{charts → components/charts}/network/ForceDirectedGraph.d.ts +2 -0
  16. package/dist/components/charts/network/OrbitDiagram.d.ts +78 -0
  17. package/dist/{charts → components/charts}/network/SankeyDiagram.d.ts +2 -0
  18. package/dist/{charts → components/charts}/network/TreeDiagram.d.ts +2 -0
  19. package/dist/{charts → components/charts}/network/Treemap.d.ts +2 -0
  20. package/dist/{charts → components/charts}/ordinal/BarChart.d.ts +2 -0
  21. package/dist/{charts → components/charts}/ordinal/BoxPlot.d.ts +2 -0
  22. package/dist/{charts → components/charts}/ordinal/DonutChart.d.ts +2 -0
  23. package/dist/{charts → components/charts}/ordinal/DotPlot.d.ts +2 -0
  24. package/dist/{charts → components/charts}/ordinal/GroupedBarChart.d.ts +2 -0
  25. package/dist/{charts → components/charts}/ordinal/PieChart.d.ts +2 -0
  26. package/dist/{charts → components/charts}/ordinal/StackedBarChart.d.ts +2 -0
  27. package/dist/{charts → components/charts}/ordinal/SwarmPlot.d.ts +2 -0
  28. package/dist/components/charts/shared/diagnoseConfig.d.ts +23 -0
  29. package/dist/{charts → components/charts}/shared/hooks.d.ts +23 -1
  30. package/dist/components/charts/shared/stringDistance.d.ts +11 -0
  31. package/dist/{charts → components/charts}/shared/tooltipUtils.d.ts +1 -1
  32. package/dist/{charts → components/charts}/shared/types.d.ts +6 -0
  33. package/dist/{charts → components/charts}/shared/withChartWrapper.d.ts +10 -0
  34. package/dist/{charts → components/charts}/xy/AreaChart.d.ts +8 -0
  35. package/dist/{charts → components/charts}/xy/BubbleChart.d.ts +8 -0
  36. package/dist/{charts → components/charts}/xy/ConnectedScatterplot.d.ts +3 -0
  37. package/dist/{charts → components/charts}/xy/Heatmap.d.ts +8 -0
  38. package/dist/{charts → components/charts}/xy/LineChart.d.ts +26 -0
  39. package/dist/{charts → components/charts}/xy/Scatterplot.d.ts +3 -0
  40. package/dist/{charts → components/charts}/xy/StackedAreaChart.d.ts +8 -0
  41. package/dist/{export → components/export}/exportChart.d.ts +6 -1
  42. package/dist/components/semiotic-ai.d.ts +61 -0
  43. package/dist/components/semiotic-data.d.ts +7 -0
  44. package/dist/components/semiotic-network.d.ts +14 -0
  45. package/dist/components/semiotic-ordinal.d.ts +18 -0
  46. package/dist/components/semiotic-realtime.d.ts +22 -0
  47. package/dist/components/semiotic-server.d.ts +1 -0
  48. package/dist/components/semiotic-xy.d.ts +16 -0
  49. package/dist/components/semiotic.d.ts +57 -0
  50. package/dist/{server → components/server}/renderToStaticSVG.d.ts +7 -0
  51. package/dist/{stream → components/stream}/NetworkSVGOverlay.d.ts +20 -0
  52. package/dist/{stream → components/stream}/OrdinalSVGOverlay.d.ts +8 -0
  53. package/dist/{stream → components/stream}/PipelineStore.d.ts +7 -0
  54. package/dist/{stream → components/stream}/SVGOverlay.d.ts +15 -0
  55. package/dist/components/stream/SceneToSVG.d.ts +20 -0
  56. package/dist/components/stream/hitTestUtils.d.ts +23 -0
  57. package/dist/{stream → components/stream}/networkTypes.d.ts +10 -2
  58. package/dist/{stream → components/stream}/ordinalTypes.d.ts +16 -10
  59. package/dist/components/stream/renderers/areaCanvasRenderer.d.ts +2 -0
  60. package/dist/{stream → components/stream}/types.d.ts +12 -0
  61. package/dist/components/stream/useStalenessCheck.d.ts +16 -0
  62. package/dist/{types → components/types}/legendTypes.d.ts +5 -0
  63. package/dist/network.min.js +1 -1
  64. package/dist/network.module.min.js +1 -1
  65. package/dist/ordinal.min.js +1 -1
  66. package/dist/ordinal.module.min.js +1 -1
  67. package/dist/realtime.min.js +1 -1
  68. package/dist/realtime.module.min.js +1 -1
  69. package/dist/semiotic-ai.d.ts +3 -0
  70. package/dist/semiotic-ai.min.js +1 -1
  71. package/dist/semiotic-ai.module.min.js +1 -1
  72. package/dist/semiotic-network.d.ts +1 -0
  73. package/dist/semiotic-ordinal.d.ts +1 -0
  74. package/dist/semiotic.d.ts +3 -3
  75. package/dist/semiotic.min.js +1 -1
  76. package/dist/semiotic.module.min.js +1 -1
  77. package/dist/server.min.js +1 -1
  78. package/dist/server.module.min.js +1 -1
  79. package/dist/test/canvasMock.d.ts +2 -0
  80. package/dist/test-utils/canvasMock.d.ts +20 -0
  81. package/dist/test-utils/frameMock.d.ts +78 -0
  82. package/dist/xy.min.js +1 -1
  83. package/dist/xy.module.min.js +1 -1
  84. package/package.json +7 -15
  85. package/dist/stream/renderers/areaCanvasRenderer.d.ts +0 -7
  86. /package/dist/{Annotation.d.ts → components/Annotation.d.ts} +0 -0
  87. /package/dist/{CategoryColors.d.ts → components/CategoryColors.d.ts} +0 -0
  88. /package/dist/{ChartContainer.d.ts → components/ChartContainer.d.ts} +0 -0
  89. /package/dist/{ChartErrorBoundary.d.ts → components/ChartErrorBoundary.d.ts} +0 -0
  90. /package/dist/{ContextLayout.d.ts → components/ContextLayout.d.ts} +0 -0
  91. /package/dist/{DetailsPanel.d.ts → components/DetailsPanel.d.ts} +0 -0
  92. /package/dist/{Legend.d.ts → components/Legend.d.ts} +0 -0
  93. /package/dist/{ThemeProvider.d.ts → components/ThemeProvider.d.ts} +0 -0
  94. /package/dist/{charts → components/charts}/ordinal/Histogram.d.ts +0 -0
  95. /package/dist/{charts → components/charts}/ordinal/RidgelinePlot.d.ts +0 -0
  96. /package/dist/{charts → components/charts}/ordinal/ViolinPlot.d.ts +0 -0
  97. /package/dist/{charts → components/charts}/realtime/RealtimeHeatmap.d.ts +0 -0
  98. /package/dist/{charts → components/charts}/realtime/RealtimeHistogram.d.ts +0 -0
  99. /package/dist/{charts → components/charts}/realtime/RealtimeLineChart.d.ts +0 -0
  100. /package/dist/{charts → components/charts}/realtime/RealtimeSwarmChart.d.ts +0 -0
  101. /package/dist/{charts → components/charts}/realtime/RealtimeWaterfallChart.d.ts +0 -0
  102. /package/dist/{charts → components/charts}/shared/ChartError.d.ts +0 -0
  103. /package/dist/{charts → components/charts}/shared/annotationRules.d.ts +0 -0
  104. /package/dist/{charts → components/charts}/shared/colorUtils.d.ts +0 -0
  105. /package/dist/{charts → components/charts}/shared/formatUtils.d.ts +0 -0
  106. /package/dist/{charts → components/charts}/shared/legendUtils.d.ts +0 -0
  107. /package/dist/{charts → components/charts}/shared/loess.d.ts +0 -0
  108. /package/dist/{charts → components/charts}/shared/networkUtils.d.ts +0 -0
  109. /package/dist/{charts → components/charts}/shared/selectionUtils.d.ts +0 -0
  110. /package/dist/{charts → components/charts}/shared/statisticalOverlays.d.ts +0 -0
  111. /package/dist/{charts → components/charts}/shared/validateChartData.d.ts +0 -0
  112. /package/dist/{charts → components/charts}/shared/validateProps.d.ts +0 -0
  113. /package/dist/{charts → components/charts}/xy/MinimapChart.d.ts +0 -0
  114. /package/dist/{charts → components/charts}/xy/ScatterplotMatrix.d.ts +0 -0
  115. /package/dist/{data → components/data}/fromVegaLite.d.ts +0 -0
  116. /package/dist/{data → components/data}/transforms.d.ts +0 -0
  117. /package/dist/{export → components/export}/chartConfig.d.ts +0 -0
  118. /package/dist/{export → components/export}/selectionSerializer.d.ts +0 -0
  119. /package/dist/{geometry → components/geometry}/sankeyLinks.d.ts +0 -0
  120. /package/dist/{realtime → components/realtime}/BinAccumulator.d.ts +0 -0
  121. /package/dist/{realtime → components/realtime}/IncrementalExtent.d.ts +0 -0
  122. /package/dist/{realtime → components/realtime}/RingBuffer.d.ts +0 -0
  123. /package/dist/{realtime → components/realtime}/renderers/types.d.ts +0 -0
  124. /package/dist/{realtime → components/realtime}/renderers/waterfallRenderer.d.ts +0 -0
  125. /package/dist/{realtime → components/realtime}/types.d.ts +0 -0
  126. /package/dist/{store → components/store}/ObservationStore.d.ts +0 -0
  127. /package/dist/{store → components/store}/SelectionStore.d.ts +0 -0
  128. /package/dist/{store → components/store}/ThemeStore.d.ts +0 -0
  129. /package/dist/{store → components/store}/TooltipStore.d.ts +0 -0
  130. /package/dist/{store → components/store}/createStore.d.ts +0 -0
  131. /package/dist/{store → components/store}/useObservation.d.ts +0 -0
  132. /package/dist/{store → components/store}/useSelection.d.ts +0 -0
  133. /package/dist/{stream → components/stream}/CanvasHitTester.d.ts +0 -0
  134. /package/dist/{stream → components/stream}/DataSourceAdapter.d.ts +0 -0
  135. /package/dist/{stream → components/stream}/MarginalGraphics.d.ts +0 -0
  136. /package/dist/{stream → components/stream}/NetworkCanvasHitTester.d.ts +0 -0
  137. /package/dist/{stream → components/stream}/NetworkPipelineStore.d.ts +0 -0
  138. /package/dist/{stream → components/stream}/OrdinalCanvasHitTester.d.ts +0 -0
  139. /package/dist/{stream → components/stream}/OrdinalPipelineStore.d.ts +0 -0
  140. /package/dist/{stream → components/stream}/ParticlePool.d.ts +0 -0
  141. /package/dist/{stream → components/stream}/SceneGraph.d.ts +0 -0
  142. /package/dist/{stream → components/stream}/StreamNetworkFrame.d.ts +0 -0
  143. /package/dist/{stream → components/stream}/StreamOrdinalFrame.d.ts +0 -0
  144. /package/dist/{stream → components/stream}/StreamXYFrame.d.ts +0 -0
  145. /package/dist/{stream → components/stream}/accessorUtils.d.ts +0 -0
  146. /package/dist/{stream → components/stream}/keyboardNav.d.ts +0 -0
  147. /package/dist/{stream → components/stream}/layouts/chordLayoutPlugin.d.ts +0 -0
  148. /package/dist/{stream → components/stream}/layouts/forceLayoutPlugin.d.ts +0 -0
  149. /package/dist/{stream → components/stream}/layouts/hierarchyLayoutPlugin.d.ts +0 -0
  150. /package/dist/{stream → components/stream}/layouts/index.d.ts +0 -0
  151. /package/dist/{stream → components/stream}/layouts/sankeyLayoutPlugin.d.ts +0 -0
  152. /package/dist/{stream → components/stream}/ordinalSceneBuilders/barScene.d.ts +0 -0
  153. /package/dist/{stream → components/stream}/ordinalSceneBuilders/connectorScene.d.ts +0 -0
  154. /package/dist/{stream → components/stream}/ordinalSceneBuilders/pieScene.d.ts +0 -0
  155. /package/dist/{stream → components/stream}/ordinalSceneBuilders/pointScene.d.ts +0 -0
  156. /package/dist/{stream → components/stream}/ordinalSceneBuilders/statisticalScene.d.ts +0 -0
  157. /package/dist/{stream → components/stream}/ordinalSceneBuilders/timelineScene.d.ts +0 -0
  158. /package/dist/{stream → components/stream}/ordinalSceneBuilders/types.d.ts +0 -0
  159. /package/dist/{stream → components/stream}/renderers/barCanvasRenderer.d.ts +0 -0
  160. /package/dist/{stream → components/stream}/renderers/boxplotCanvasRenderer.d.ts +0 -0
  161. /package/dist/{stream → components/stream}/renderers/candlestickCanvasRenderer.d.ts +0 -0
  162. /package/dist/{stream → components/stream}/renderers/connectorCanvasRenderer.d.ts +0 -0
  163. /package/dist/{stream → components/stream}/renderers/heatmapCanvasRenderer.d.ts +0 -0
  164. /package/dist/{stream → components/stream}/renderers/lineCanvasRenderer.d.ts +0 -0
  165. /package/dist/{stream → components/stream}/renderers/networkArcRenderer.d.ts +0 -0
  166. /package/dist/{stream → components/stream}/renderers/networkCircleRenderer.d.ts +0 -0
  167. /package/dist/{stream → components/stream}/renderers/networkEdgeRenderer.d.ts +0 -0
  168. /package/dist/{stream → components/stream}/renderers/networkParticleRenderer.d.ts +0 -0
  169. /package/dist/{stream → components/stream}/renderers/networkRectRenderer.d.ts +0 -0
  170. /package/dist/{stream → components/stream}/renderers/pointCanvasRenderer.d.ts +0 -0
  171. /package/dist/{stream → components/stream}/renderers/swarmCanvasRenderer.d.ts +0 -0
  172. /package/dist/{stream → components/stream}/renderers/types.d.ts +0 -0
  173. /package/dist/{stream → components/stream}/renderers/violinCanvasRenderer.d.ts +0 -0
  174. /package/dist/{stream → components/stream}/renderers/waterfallCanvasRenderer.d.ts +0 -0
  175. /package/dist/{stream → components/stream}/renderers/wedgeCanvasRenderer.d.ts +0 -0
  176. /package/dist/{stream → components/stream}/useResponsiveSize.d.ts +0 -0
  177. /package/dist/{types → components/types}/annotationTypes.d.ts +0 -0
  178. /package/dist/{types → components/types}/generalTypes.d.ts +0 -0
  179. /package/dist/{types → components/types}/interactionTypes.d.ts +0 -0
  180. /package/dist/{types → components/types}/networkTypes.d.ts +0 -0
  181. /package/dist/{types → components/types}/ordinalTypes.d.ts +0 -0
package/CLAUDE.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Quick Start
4
4
  - Install: `npm install semiotic`
5
- - Import: `semiotic`, `semiotic/xy`, `semiotic/ordinal`, `semiotic/network`, `semiotic/realtime`, `semiotic/ai`, `semiotic/data`
5
+ - Import: `semiotic`, `semiotic/xy`, `semiotic/ordinal`, `semiotic/network`, `semiotic/realtime`, `semiotic/ai`, `semiotic/data`, `semiotic/server`
6
6
  - CLI: `npx semiotic-ai [--schema|--compact|--examples|--doctor]`
7
7
  - MCP: `npx semiotic-mcp`
8
8
  - Every HOC has a built-in error boundary (never blanks the page) and dev-mode validation warnings
@@ -12,11 +12,11 @@
12
12
  - Every HOC accepts `frameProps` to pass through. TypeScript `strict: true`.
13
13
 
14
14
  ## Common Props (all HOCs)
15
- `title`, `width` (600), `height` (400), `responsiveWidth`, `responsiveHeight`, `margin`, `className`, `enableHover` (true), `tooltip`, `showLegend`, `showGrid` (false), `frameProps`, `onObservation`, `chartId`
15
+ `title`, `width` (600), `height` (400), `responsiveWidth`, `responsiveHeight`, `margin`, `className`, `enableHover` (true), `tooltip`, `showLegend`, `showGrid` (false), `frameProps`, `onObservation`, `chartId`, `loading` (false), `emptyContent`, `legendInteraction` ("none"|"highlight"|"isolate"), `emphasis` ("primary"|"secondary")
16
16
 
17
17
  ## XY Charts (`semiotic/xy`)
18
18
 
19
- **LineChart** — `data`, `xAccessor` ("x"), `yAccessor` ("y"), `lineBy`, `lineDataAccessor` ("coordinates"), `colorBy`, `colorScheme`, `curve`, `lineWidth` (2), `showPoints`, `pointRadius` (3), `fillArea`, `areaOpacity` (0.3), `anomaly` (AnomalyConfig), `forecast` (ForecastConfig)
19
+ **LineChart** — `data`, `xAccessor` ("x"), `yAccessor` ("y"), `lineBy`, `lineDataAccessor` ("coordinates"), `colorBy`, `colorScheme`, `curve`, `lineWidth` (2), `showPoints`, `pointRadius` (3), `fillArea`, `areaOpacity` (0.3), `anomaly` (AnomalyConfig), `forecast` (ForecastConfig), `directLabel` (boolean|{position,fontSize}), `gapStrategy` ("break"|"interpolate"|"zero")
20
20
 
21
21
  **AreaChart** — LineChart props + `areaBy`, `y0Accessor` (band/ribbon), `gradientFill` (boolean|{topOpacity,bottomOpacity}), `areaOpacity` (0.7), `showLine` (true)
22
22
 
@@ -51,6 +51,7 @@
51
51
  **TreeDiagram** — `data` (root), `layout`, `orientation`, `childrenAccessor`, `colorBy`, `colorByDepth`, `edgeStyle`
52
52
  **Treemap** — `data` (root), `childrenAccessor`, `valueAccessor`, `colorBy`, `colorByDepth`, `showLabels`, `labelMode`
53
53
  **CirclePack** — `data` (root), `childrenAccessor`, `valueAccessor`, `colorBy`, `colorByDepth`, `circleOpacity`
54
+ **OrbitDiagram** — `data` (root), `childrenAccessor`, `nodeIdAccessor`, `orbitMode` ("flat"|"solar"|"atomic"|number[]), `speed` (0.25), `revolution`, `eccentricity`, `orbitSize`, `nodeRadius`, `showRings`, `showLabels`, `animated` (true), `colorBy`, `colorByDepth`, `annotations` (widget annotations anchor by nodeId)
54
55
 
55
56
  ## Realtime Charts (`semiotic/realtime`)
56
57
 
@@ -67,14 +68,14 @@ Realtime encoding: `decay`, `pulse`, `transition`, `staleness` — compose freel
67
68
 
68
69
  ## Coordinated Views
69
70
 
70
- **LinkedCharts** — wraps charts. Props: `selections` (resolution: "union"|"intersect"|"crossfilter")
71
+ **LinkedCharts** — wraps charts. Props: `selections` (resolution: "union"|"intersect"|"crossfilter"), `showLegend` (auto when CategoryColorProvider present), `legendPosition` ("top"|"bottom"), `legendInteraction` ("highlight"|"isolate"|"none"), `legendSelectionName` (selection name for legend-driven cross-highlighting), `legendField` (data field for legend selections)
71
72
  **CategoryColorProvider** — stable category→color mapping. Props: `colors` (map) or `categories` + `colorScheme`
72
73
  Chart props: `selection`, `linkedHover`, `linkedBrush`. Hooks: `useSelection`, `useLinkedHover`, `useBrushSelection`, `useFilteredData`
73
74
  **ScatterplotMatrix** — `data`, `fields`, `colorBy`, `cellSize`, `hoverMode`, `brushMode`
74
75
 
75
76
  ## Layout & Composition
76
77
 
77
- **ChartGrid** — CSS Grid layout. `columns` (number|"auto"), `minCellWidth` (300), `gap` (16)
78
+ **ChartGrid** — CSS Grid layout. `columns` (number|"auto"), `minCellWidth` (300), `gap` (16). Children with `emphasis="primary"` span two columns.
78
79
  **ContextLayout** — primary + context panel. `context` (ReactNode), `position`, `contextSize` (250)
79
80
 
80
81
  ## Key Patterns
@@ -108,16 +109,28 @@ ref.current.push({ time: Date.now(), value: 42 })
108
109
  <RealtimeLineChart ref={ref} timeAccessor="time" valueAccessor="value" />
109
110
  ```
110
111
 
112
+ ## Annotations
113
+ - `type: "widget"` — place any React element at data coordinates. Works on all frame types. XY/ordinal use data coordinates (`x`/`y` or field names). Network/orbit use `nodeId`. Default: info emoji. Renders as HTML overlay (not SVG) so popups/threads overflow freely.
114
+ ```jsx
115
+ annotations={[{ type: "widget", month: 4, revenue: 32, dy: -4, content: <MyAlertButton /> }]}
116
+ // OrbitDiagram: annotations={[{ type: "widget", nodeId: "Pipeline", content: <Alert /> }]}
117
+ ```
118
+
119
+ ## Server-Side Rendering
120
+ - All HOC charts and Stream Frames render SVG automatically in server environments (no window/document)
121
+ - `renderToStaticSVG()`, `renderXYToStaticSVG()`, `renderOrdinalToStaticSVG()`, `renderNetworkToStaticSVG()` — standalone SVG generation from `semiotic/server`
122
+ - Works with Next.js App Router, Remix, Astro — same component on server and client
123
+
111
124
  ## AI Features
112
125
  - `onObservation` — structured events (hover, click, brush, selection) on all HOCs
113
126
  - `useChartObserver` — aggregates observations across LinkedCharts
114
127
  - `toConfig`/`fromConfig`/`toURL`/`fromURL`/`copyConfig`/`configToJSX` — chart state serialization
115
128
  - `DetailsPanel` — click-driven detail panel inside `ChartContainer`
116
- - `validateProps(componentName, props)` — prop validation
129
+ - `validateProps(componentName, props)` — prop validation with Levenshtein typo suggestions
130
+ - `diagnoseConfig(componentName, props)` — anti-pattern detector (12 checks: empty data, bad dimensions, missing accessors, margin overflow, etc.)
117
131
  - `ChartErrorBoundary` — error boundary
118
- - `exportChart(el, { format: "png"|"svg" })` — browser export
119
- - `renderToStaticSVG()` — server-side SVG (from `semiotic/server`)
120
- - `npx semiotic-ai --doctor` — validate component + props JSON from CLI
132
+ - `exportChart(el, { format: "png"|"svg" })` — browser export (default: PNG, composites canvas + SVG layers)
133
+ - `npx semiotic-ai --doctor` — validate component + props JSON from CLI (uses both validateProps and diagnoseConfig)
121
134
 
122
135
  ## Differentiators
123
- Network viz, streaming canvas, realtime encoding, coordinated views, statistical summaries, AI hooks, chart serialization, global theming, keyboard navigation
136
+ Network viz, streaming canvas, realtime encoding, coordinated views, statistical summaries, AI hooks, chart serialization, global theming, keyboard navigation, interactive legends (highlight/isolate), direct labeling, gap handling, empty/loading states, landmark tick labels, LinkedCharts unified legend
package/README.md CHANGED
@@ -4,10 +4,11 @@
4
4
  [![npm version](https://img.shields.io/npm/v/semiotic.svg)](https://www.npmjs.com/package/semiotic)
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-built--in-blue.svg)](https://www.typescriptlang.org/)
6
6
 
7
- A React data visualization library for charts, networks, and beyond.
7
+ A React data visualization library designed for AI-assisted development.
8
8
 
9
- Simple charts in 5 lines. Force-directed graphs, Sankey diagrams, treemaps,
10
- and chord diagrams when you need them. Full D3-level control when you want it.
9
+ Simple charts in 5 lines. Network graphs, streaming data, and coordinated
10
+ dashboards when you need them. Structured schemas and an MCP server so
11
+ AI coding assistants generate correct chart code on the first try.
11
12
 
12
13
  ```jsx
13
14
  import { LineChart } from "semiotic"
@@ -21,31 +22,46 @@ import { LineChart } from "semiotic"
21
22
 
22
23
  ## Why Semiotic
23
24
 
24
- Most React charting libraries give you bar charts, line charts, and pie charts.
25
- Semiotic gives you those too but it's built for the projects where those
26
- aren't enough.
25
+ Semiotic is a data visualization library for React that combines broad chart
26
+ coverage with first-class AI tooling. It handles the chart types that most
27
+ libraries skip — network graphs, streaming data, statistical distributions,
28
+ coordinated views — and ships with machine-readable schemas so LLMs can
29
+ generate correct code without examples.
27
30
 
28
- ### When you need more than standard charts
31
+ ### Built for AI-assisted development
29
32
 
30
- **Network visualization.** Show how things connect org charts,
31
- dependency graphs, budget flows, taxonomies. Semiotic has force-directed
32
- graphs, Sankey diagrams, chord diagrams, tree layouts, treemaps, and circle
33
- packing as React components with the same prop API as LineChart.
33
+ Semiotic ships with everything an AI coding assistant needs to generate
34
+ correct visualizations without trial and error:
34
35
 
35
- **Streaming data.** Monitor live systems server metrics, sensor feeds,
36
- financial tickers. Semiotic's realtime charts render on canvas at 60fps with
37
- a ref-based push API. Old data fades out (decay), new data flashes in
38
- (pulse), and stale feeds are flagged automatically.
36
+ - **`semiotic/ai`** a single import with all 28 chart components, optimized for LLM code generation
37
+ - **`ai/schema.json`** machine-readable prop schemas for every component
38
+ - **`npx semiotic-mcp`** an MCP server for tool-based chart rendering in any MCP client
39
+ - **`npx semiotic-ai --doctor`** validate component + props JSON from the command line with typo suggestions and anti-pattern detection
40
+ - **`diagnoseConfig(component, props)`** — programmatic anti-pattern detector with 12 checks and actionable fixes
41
+ - **`CLAUDE.md`** — instruction files auto-synced for Claude, Cursor, Copilot, Windsurf, and Cline
42
+ - **`llms.txt`** — machine-readable documentation following the emerging standard
39
43
 
40
- **Coordinated dashboards.** Hover one chart, highlight matching data in
41
- others. Brush a scatterplot, filter a bar chart. Semiotic's `LinkedCharts`
42
- and `ScatterplotMatrix` provide crossfilter coordination that other libraries
43
- leave you to build from scratch.
44
+ Every chart includes a built-in error boundary and dev-mode validation
45
+ warnings with typo suggestions, so AI-generated code fails gracefully with
46
+ actionable diagnostics instead of a blank screen.
44
47
 
45
- **Statistical summaries.** Box plots, violin plots, swarm plots, ridgeline
46
- plots, histograms — the distribution charts that data scientists need and
47
- most charting libraries skip. Add marginal distribution graphics (histogram,
48
- violin, ridgeline, boxplot) to scatterplot margins with a single prop.
48
+ ### Beyond standard charts
49
+
50
+ **Network visualization.** Force-directed graphs, Sankey diagrams, chord
51
+ diagrams, tree layouts, treemaps, circle packing, and orbit diagrams all
52
+ as React components with the same prop API as LineChart.
53
+
54
+ **Streaming data.** Realtime charts render on canvas at 60fps with a
55
+ ref-based push API. Built-in decay, pulse, and staleness encoding for
56
+ monitoring dashboards.
57
+
58
+ **Coordinated views.** `LinkedCharts` provides hover cross-highlighting,
59
+ brush cross-filtering, and selection synchronization across any combination
60
+ of chart types — zero wiring.
61
+
62
+ **Statistical summaries.** Box plots, violin plots, swarm plots, histograms,
63
+ LOESS smoothing, forecast with confidence envelopes, and anomaly detection.
64
+ Marginal distribution graphics on scatterplot axes with a single prop.
49
65
 
50
66
  ### Start simple, go deep
51
67
 
@@ -57,6 +73,13 @@ violin, ridgeline, boxplot) to scatterplot margins with a single prop.
57
73
  Every Chart component accepts a `frameProps` prop to access the underlying
58
74
  Frame API without leaving the simpler interface.
59
75
 
76
+ ### Serialization and interop
77
+
78
+ Charts serialize to JSON and back: `toConfig`, `fromConfig`, `toURL`,
79
+ `copyConfig`, `configToJSX`. Have Vega-Lite specs? `fromVegaLite(spec)`
80
+ translates them to Semiotic configs — works with `configToJSX()` for
81
+ full round-trip from notebooks and AI-generated specs.
82
+
60
83
  ### When to use something else
61
84
 
62
85
  Need a standard bar or line chart for a dashboard you'll never need to
@@ -69,40 +92,10 @@ Semiotic is for projects that outgrow those libraries — when you need
69
92
  network graphs alongside time series, streaming data alongside static
70
93
  snapshots, or coordinated views across chart types.
71
94
 
72
- ### Bundle size comparison
73
-
74
- | Library | Packed | Unpacked | What you get |
75
- |---|---|---|---|
76
- | Victory | 393 KB | 2.3 MB | Charts only |
77
- | Lightweight Charts | 586 KB | 3.0 MB | Financial charts only |
78
- | **Semiotic** | **668 KB** | **2.5 MB** | **Charts + networks + streaming + coordination** |
79
- | Recharts | 1.4 MB | 6.4 MB | Charts only |
80
- | Chart.js | 1.6 MB | 6.2 MB | Charts only, no React |
81
- | ApexCharts | 1.8 MB | 8.4 MB | Charts only |
82
- | ECharts | 11.4 MB | 57.6 MB | Everything, no React |
83
-
84
- **AI-ready.** Semiotic ships with structured schemas (`ai/schema.json`), an
85
- `import from "semiotic/ai"` entry point, and an MCP server — all designed for
86
- LLM code generation. AI coding assistants can generate correct Semiotic code on
87
- the first try. Run `npx semiotic-ai --help` for CLI options, `npx semiotic-ai --doctor`
88
- to validate props from the command line, or add `semiotic-mcp` to your MCP client
89
- config for tool-based chart rendering. Every HOC chart includes a built-in error
90
- boundary and dev-mode validation warnings with actionable fix suggestions.
91
-
92
- **Vega-Lite compatible.** Have existing Vega-Lite specs? `fromVegaLite(spec)`
93
- translates them to Semiotic chart configs — instant onboarding from notebooks,
94
- dashboards, or AI-generated specs. Composes with `configToJSX()`,
95
- `copyConfig()`, and `toURL()` for full round-trip interop.
96
-
97
- **Streaming system models.** Turn a streaming Sankey into a live system monitor:
98
- click-to-inspect `DetailsPanel`, particle speed proportional to edge throughput,
99
- threshold alerting with animated glow, and automatic topology diffing that
100
- highlights new services as they appear. Visualization as product navigation.
101
-
102
95
  ## Install
103
96
 
104
97
  ```bash
105
- npm install semiotic@3.0.0
98
+ npm install semiotic
106
99
  ```
107
100
 
108
101
  Requires React 18.1+ or React 19.
@@ -215,9 +208,9 @@ import { LineChart, BarChart } from "semiotic"
215
208
 
216
209
  | Category | Components |
217
210
  |---|---|
218
- | **XY** | `LineChart` `AreaChart` `StackedAreaChart` `Scatterplot` `BubbleChart` `Heatmap` |
211
+ | **XY** | `LineChart` `AreaChart` `StackedAreaChart` `Scatterplot` `ConnectedScatterplot` `BubbleChart` `Heatmap` |
219
212
  | **Categorical** | `BarChart` `StackedBarChart` `GroupedBarChart` `SwarmPlot` `BoxPlot` `Histogram` `ViolinPlot` `DotPlot` `PieChart` `DonutChart` |
220
- | **Network** | `ForceDirectedGraph` `ChordDiagram` `SankeyDiagram` `TreeDiagram` `Treemap` `CirclePack` |
213
+ | **Network** | `ForceDirectedGraph` `ChordDiagram` `SankeyDiagram` `TreeDiagram` `Treemap` `CirclePack` `OrbitDiagram` |
221
214
  | **Realtime** | `RealtimeLineChart` `RealtimeHistogram` `RealtimeSwarmChart` `RealtimeWaterfallChart` `RealtimeHeatmap` |
222
215
  | **Coordination** | `LinkedCharts` `ScatterplotMatrix` |
223
216
  | **Layout** | `ChartGrid` `ContextLayout` `CategoryColorProvider` |
@@ -257,9 +250,9 @@ for color, size, aggregation, and binning.
257
250
  Import only what you need:
258
251
 
259
252
  ```jsx
260
- import { LineChart } from "semiotic/xy" // 123 KB
261
- import { BarChart } from "semiotic/ordinal" // 118 KB
262
- import { ForceDirectedGraph } from "semiotic/network" // 127 KB
253
+ import { LineChart } from "semiotic/xy" // 124 KB
254
+ import { BarChart } from "semiotic/ordinal" // 100 KB
255
+ import { ForceDirectedGraph } from "semiotic/network" // 104 KB
263
256
  import { LineChart } from "semiotic/ai" // HOC-only surface for AI generation
264
257
  ```
265
258
 
@@ -283,7 +276,19 @@ interface Sale { month: number; revenue: number }
283
276
 
284
277
  ## Server-Side Rendering
285
278
 
286
- Static SVG generation for Node.js (email, OG images, PDF):
279
+ All chart components render SVG automatically in server environments no
280
+ special imports or configuration needed:
281
+
282
+ ```jsx
283
+ // Works in Next.js App Router, Remix, Astro — same component, same props
284
+ import { LineChart } from "semiotic"
285
+
286
+ // Server: renders <svg> with path/circle/rect elements
287
+ // Client: renders <canvas> with SVG overlay for axes
288
+ <LineChart data={data} xAccessor="date" yAccessor="value" />
289
+ ```
290
+
291
+ For standalone SVG generation (email, OG images, PDF), use the server entry point:
287
292
 
288
293
  ```js
289
294
  import { renderToStaticSVG } from "semiotic/server"
@@ -296,14 +301,12 @@ const svg = renderToStaticSVG("xy", {
296
301
  })
297
302
  ```
298
303
 
299
- Works with Next.js App Router, Remix, and Astro via `"use client"` directives.
300
-
301
304
  ## Documentation
302
305
 
303
306
  [Interactive docs and examples](https://semiotic.nteract.io)
304
307
 
305
308
  - [Getting Started](https://semiotic.nteract.io/getting-started)
306
- - [Charts](https://semiotic.nteract.io/charts) — all 27 chart types with live examples
309
+ - [Charts](https://semiotic.nteract.io/charts) — all 28 chart types with live examples
307
310
  - [Frames](https://semiotic.nteract.io/frames) — full Frame API reference
308
311
  - [Features](https://semiotic.nteract.io/features) — axes, annotations, tooltips, styling, Vega-Lite translator
309
312
  - [Cookbook](https://semiotic.nteract.io/cookbook) — advanced patterns and recipes
package/ai/cli.js CHANGED
@@ -54,46 +54,59 @@ if (flag === "--doctor") {
54
54
  process.exit(1)
55
55
  }
56
56
 
57
- // Load validateProps from dist
57
+ // Load diagnoseConfig from dist (falls back to validateProps)
58
58
  const distPath = path.join(pkgRoot, "dist", "semiotic-ai.min.js")
59
- let validateProps
59
+ let diagnoseConfig, validateProps
60
60
  try {
61
61
  const mod = require(distPath)
62
+ diagnoseConfig = mod.diagnoseConfig
62
63
  validateProps = mod.validateProps
63
64
  } catch (e) {
64
65
  console.error("Could not load semiotic/ai dist. Run 'npm run dist' first.")
65
66
  process.exit(1)
66
67
  }
67
68
 
68
- if (!validateProps) {
69
- console.error("validateProps not found in semiotic/ai exports.")
69
+ if (!diagnoseConfig && !validateProps) {
70
+ console.error("diagnoseConfig/validateProps not found in semiotic/ai exports.")
70
71
  process.exit(1)
71
72
  }
72
73
 
73
- const result = validateProps(component, props)
74
- if (result.valid) {
75
- console.log(`✓ ${component}: props are valid.`)
76
- // Additional data shape checks
74
+ if (diagnoseConfig) {
75
+ // Use the full anti-pattern detector
76
+ const result = diagnoseConfig(component, props)
77
+
78
+ // Show data shape summary
77
79
  if (props.data && Array.isArray(props.data) && props.data.length > 0) {
78
80
  const sample = props.data[0]
79
81
  console.log(` Data shape: ${props.data.length} items, keys: [${Object.keys(sample).join(", ")}]`)
80
- if (props.xAccessor && typeof props.xAccessor === "string" && !(props.xAccessor in sample)) {
81
- console.log(` ⚠ xAccessor "${props.xAccessor}" not in data keys. Available: ${Object.keys(sample).join(", ")}`)
82
- }
83
- if (props.yAccessor && typeof props.yAccessor === "string" && !(props.yAccessor in sample)) {
84
- console.log(` ⚠ yAccessor "${props.yAccessor}" not in data keys. Available: ${Object.keys(sample).join(", ")}`)
85
- }
86
- if (props.categoryAccessor && typeof props.categoryAccessor === "string" && !(props.categoryAccessor in sample)) {
87
- console.log(` ⚠ categoryAccessor "${props.categoryAccessor}" not in data keys. Available: ${Object.keys(sample).join(", ")}`)
82
+ }
83
+
84
+ if (result.ok && result.diagnoses.length === 0) {
85
+ console.log(`✓ ${component}: configuration looks good.`)
86
+ } else if (result.ok) {
87
+ console.log(`✓ ${component}: configuration OK with warnings:`)
88
+ for (const d of result.diagnoses) {
89
+ console.log(` ⚠ [${d.code}] ${d.message}`)
90
+ if (d.fix) console.log(` Fix: ${d.fix}`)
88
91
  }
89
- if (props.valueAccessor && typeof props.valueAccessor === "string" && !(props.valueAccessor in sample)) {
90
- console.log(` ⚠ valueAccessor "${props.valueAccessor}" not in data keys. Available: ${Object.keys(sample).join(", ")}`)
92
+ } else {
93
+ console.log(`✗ ${component}: issues detected.`)
94
+ for (const d of result.diagnoses) {
95
+ const icon = d.severity === "error" ? "✗" : "⚠"
96
+ console.log(` ${icon} [${d.code}] ${d.message}`)
97
+ if (d.fix) console.log(` Fix: ${d.fix}`)
91
98
  }
92
99
  }
93
100
  } else {
94
- console.log(`✗ ${component}: validation failed.`)
95
- for (const err of result.errors) {
96
- console.log(` • ${err}`)
101
+ // Fallback to validateProps only
102
+ const result = validateProps(component, props)
103
+ if (result.valid) {
104
+ console.log(`✓ ${component}: props are valid.`)
105
+ } else {
106
+ console.log(`✗ ${component}: validation failed.`)
107
+ for (const err of result.errors) {
108
+ console.log(` • ${err}`)
109
+ }
97
110
  }
98
111
  }
99
112
  } catch (err) {
@@ -9,6 +9,7 @@ exports.COMPONENT_REGISTRY = {
9
9
  Scatterplot: { component: ai_1.Scatterplot, category: "xy" },
10
10
  BubbleChart: { component: ai_1.BubbleChart, category: "xy" },
11
11
  Heatmap: { component: ai_1.Heatmap, category: "xy" },
12
+ ConnectedScatterplot: { component: ai_1.ConnectedScatterplot, category: "xy" },
12
13
  BarChart: { component: ai_1.BarChart, category: "ordinal" },
13
14
  StackedBarChart: { component: ai_1.StackedBarChart, category: "ordinal" },
14
15
  GroupedBarChart: { component: ai_1.GroupedBarChart, category: "ordinal" },
@@ -23,4 +24,5 @@ exports.COMPONENT_REGISTRY = {
23
24
  TreeDiagram: { component: ai_1.TreeDiagram, category: "network" },
24
25
  Treemap: { component: ai_1.Treemap, category: "network" },
25
26
  CirclePack: { component: ai_1.CirclePack, category: "network" },
27
+ OrbitDiagram: { component: ai_1.OrbitDiagram, category: "network" },
26
28
  };
@@ -57,6 +57,7 @@ const fs = __importStar(require("fs"));
57
57
  const path = __importStar(require("path"));
58
58
  const renderHOCToSVG_1 = require("./renderHOCToSVG");
59
59
  const componentRegistry_1 = require("./componentRegistry");
60
+ const ai_1 = require("semiotic/ai");
60
61
  // Load schema.json for tool definitions
61
62
  const schemaPath = path.resolve(__dirname, "../schema.json");
62
63
  const schema = JSON.parse(fs.readFileSync(schemaPath, "utf-8"));
@@ -88,6 +89,59 @@ for (const toolDef of schema.tools) {
88
89
  };
89
90
  });
90
91
  }
92
+ // ── Generic renderChart tool ─────────────────────────────────────────────
93
+ // Accepts { component, props } — closes the agent feedback loop by letting
94
+ // an LLM render any chart type in a single tool call.
95
+ server.tool("renderChart", "Render any Semiotic chart to static SVG. Pass { component: 'LineChart', props: { data: [...], ... } }. Returns SVG string or validation errors.", {}, async (args) => {
96
+ const component = args.component;
97
+ const props = (args.props || args);
98
+ if (!component) {
99
+ return {
100
+ content: [{ type: "text", text: "Missing 'component' field. Provide { component: 'LineChart', props: { ... } }." }],
101
+ isError: true,
102
+ };
103
+ }
104
+ const result = (0, renderHOCToSVG_1.renderHOCToSVG)(component, props);
105
+ if (result.error) {
106
+ return {
107
+ content: [{ type: "text", text: result.error }],
108
+ isError: true,
109
+ };
110
+ }
111
+ return {
112
+ content: [{ type: "text", text: result.svg }],
113
+ };
114
+ });
115
+ // ── diagnoseConfig tool ──────────────────────────────────────────────────
116
+ // Anti-pattern detector: checks for common failure modes and returns
117
+ // actionable fix instructions.
118
+ server.tool("diagnoseConfig", "Diagnose a Semiotic chart configuration for common problems (empty data, bad dimensions, missing accessors, wrong data shape, etc). Pass { component: 'LineChart', props: { ... } }. Returns structured diagnoses with fix instructions.", {}, async (args) => {
119
+ const component = args.component;
120
+ const props = (args.props || args);
121
+ if (!component) {
122
+ return {
123
+ content: [{ type: "text", text: "Missing 'component' field. Provide { component: 'LineChart', props: { ... } }." }],
124
+ isError: true,
125
+ };
126
+ }
127
+ const result = (0, ai_1.diagnoseConfig)(component, props);
128
+ if (result.ok) {
129
+ const warnings = result.diagnoses.filter(d => d.severity === "warning");
130
+ const msg = warnings.length > 0
131
+ ? `Configuration looks good with ${warnings.length} warning(s):\n${warnings.map(w => `⚠ [${w.code}] ${w.message}\n Fix: ${w.fix}`).join("\n")}`
132
+ : `✓ Configuration looks good — no issues detected.`;
133
+ return { content: [{ type: "text", text: msg }] };
134
+ }
135
+ const lines = result.diagnoses.map(d => {
136
+ const icon = d.severity === "error" ? "✗" : "⚠";
137
+ const fixLine = d.fix ? `\n Fix: ${d.fix}` : "";
138
+ return `${icon} [${d.code}] ${d.message}${fixLine}`;
139
+ });
140
+ return {
141
+ content: [{ type: "text", text: lines.join("\n") }],
142
+ isError: true,
143
+ };
144
+ });
91
145
  // Start the server
92
146
  async function main() {
93
147
  const transport = new stdio_js_1.StdioServerTransport();
package/ai/examples.md CHANGED
@@ -111,6 +111,32 @@ const data = [
111
111
 
112
112
  Key props: `valueAccessor`, `colorScheme` ("blues"|"reds"|"greens"|"viridis"), `showValues`
113
113
 
114
+ ### ConnectedScatterplot
115
+
116
+ ```jsx
117
+ import { ConnectedScatterplot } from "semiotic/ai"
118
+
119
+ const data = [
120
+ { year: 2018, unemployment: 3.9, inflation: 2.4 },
121
+ { year: 2019, unemployment: 3.7, inflation: 1.8 },
122
+ { year: 2020, unemployment: 8.1, inflation: 1.2 },
123
+ { year: 2021, unemployment: 5.4, inflation: 4.7 },
124
+ { year: 2022, unemployment: 3.6, inflation: 8.0 },
125
+ { year: 2023, unemployment: 3.6, inflation: 4.1 }
126
+ ]
127
+
128
+ <ConnectedScatterplot
129
+ data={data}
130
+ xAccessor="unemployment"
131
+ yAccessor="inflation"
132
+ orderAccessor="year"
133
+ xLabel="Unemployment Rate (%)"
134
+ yLabel="Inflation Rate (%)"
135
+ />
136
+ ```
137
+
138
+ Key props: `orderAccessor` sequences points along the path, Viridis gradient from start→end
139
+
114
140
  ---
115
141
 
116
142
  ## Flat Array — Ordinal Charts
@@ -369,6 +395,55 @@ Key props: `valueAccessor` controls circle size, nested circles for hierarchy
369
395
 
370
396
  ---
371
397
 
398
+ ### OrbitDiagram
399
+
400
+ ```jsx
401
+ import { OrbitDiagram } from "semiotic/ai"
402
+
403
+ const pipeline = {
404
+ name: "ML Pipeline",
405
+ children: [
406
+ {
407
+ name: "Data Ingestion",
408
+ children: [
409
+ { name: "API Feed" },
410
+ { name: "CSV Upload" },
411
+ { name: "DB Connector" }
412
+ ]
413
+ },
414
+ {
415
+ name: "Processing",
416
+ children: [
417
+ { name: "Clean" },
418
+ { name: "Feature Eng" },
419
+ { name: "Normalize" }
420
+ ]
421
+ },
422
+ {
423
+ name: "Model",
424
+ children: [
425
+ { name: "Train" },
426
+ { name: "Evaluate" },
427
+ { name: "Deploy" }
428
+ ]
429
+ }
430
+ ]
431
+ }
432
+
433
+ <OrbitDiagram
434
+ data={pipeline}
435
+ childrenAccessor="children"
436
+ nodeIdAccessor="name"
437
+ orbitMode="solar"
438
+ showLabels
439
+ colorByDepth
440
+ />
441
+ ```
442
+
443
+ Key props: `orbitMode` ("flat"|"solar"|"atomic"|number[]), `speed`, `animated`, `showRings`
444
+
445
+ ---
446
+
372
447
  ## Network Data — Nodes + Edges Arrays
373
448
 
374
449
  ### ForceDirectedGraph
package/ai/schema.json CHANGED
@@ -383,6 +383,40 @@
383
383
  }
384
384
  }
385
385
  },
386
+ {
387
+ "type": "function",
388
+ "function": {
389
+ "name": "ConnectedScatterplot",
390
+ "description": "Scatterplot where points are connected in order, showing trajectories through 2D space. Viridis-colored start→end, white halo under lines.",
391
+ "parameters": {
392
+ "type": "object",
393
+ "properties": {
394
+ "data": {
395
+ "type": "array",
396
+ "items": { "type": "object" },
397
+ "description": "Array of data objects"
398
+ },
399
+ "xAccessor": { "type": "string", "description": "Key for x-axis values", "default": "x" },
400
+ "yAccessor": { "type": "string", "description": "Key for y-axis values", "default": "y" },
401
+ "orderAccessor": { "type": "string", "description": "Key for point ordering (number or Date field)" },
402
+ "orderLabel": { "type": "string", "description": "Label for the ordering metric in tooltips" },
403
+ "pointRadius": { "type": "number", "description": "Point radius", "default": 4 },
404
+ "pointIdAccessor": { "type": "string", "description": "Accessor for unique point IDs, used by point-anchored annotations" },
405
+ "annotations": { "type": "array", "description": "Annotation objects to render on the chart" },
406
+ "colorBy": { "type": "string", "description": "Key to determine color encoding" },
407
+ "colorScheme": { "type": ["string", "array"], "description": "Named d3 color scheme or array of color strings" },
408
+ "title": { "type": "string" },
409
+ "width": { "type": "number", "default": 600 },
410
+ "height": { "type": "number", "default": 400 },
411
+ "enableHover": { "type": "boolean", "default": true },
412
+ "showGrid": { "type": "boolean", "default": false },
413
+ "margin": { "type": "object" },
414
+ "className": { "type": "string" }
415
+ },
416
+ "required": ["data"]
417
+ }
418
+ }
419
+ },
386
420
  {
387
421
  "type": "function",
388
422
  "function": {
@@ -1126,6 +1160,43 @@
1126
1160
  }
1127
1161
  }
1128
1162
  },
1163
+ {
1164
+ "type": "function",
1165
+ "function": {
1166
+ "name": "OrbitDiagram",
1167
+ "description": "Animated orbital diagram showing hierarchical data as nodes orbiting a center. Supports flat, solar, atomic, and custom ring arrangements.",
1168
+ "parameters": {
1169
+ "type": "object",
1170
+ "properties": {
1171
+ "data": {
1172
+ "type": "object",
1173
+ "description": "Hierarchical root object with children: { name: 'root', children: [...] }"
1174
+ },
1175
+ "childrenAccessor": { "type": "string", "description": "Key to access children from each datum", "default": "children" },
1176
+ "nodeIdAccessor": { "type": "string", "description": "Key to identify each node", "default": "name" },
1177
+ "colorBy": { "type": "string", "description": "Field or function for node color" },
1178
+ "colorScheme": { "type": ["string", "array"], "description": "Color scheme", "default": "category10" },
1179
+ "colorByDepth": { "type": "boolean", "description": "Color by hierarchy depth", "default": false },
1180
+ "orbitMode": { "type": ["string", "array"], "description": "Ring arrangement: 'flat', 'solar', 'atomic', or number[]", "default": "flat" },
1181
+ "orbitSize": { "type": "number", "description": "Ring size divisor per depth", "default": 2.95 },
1182
+ "speed": { "type": "number", "description": "Orbit speed in degrees per frame", "default": 0.25 },
1183
+ "eccentricity": { "type": "number", "description": "Vertical squash for elliptical orbits (1 = circle)", "default": 1 },
1184
+ "showRings": { "type": "boolean", "description": "Show orbital ring paths", "default": true },
1185
+ "nodeRadius": { "type": "number", "description": "Node radius", "default": 6 },
1186
+ "showLabels": { "type": "boolean", "description": "Show node labels", "default": false },
1187
+ "animated": { "type": "boolean", "description": "Enable animation", "default": true },
1188
+ "annotations": { "type": "array", "description": "Annotations anchored by nodeId" },
1189
+ "title": { "type": "string" },
1190
+ "width": { "type": "number", "default": 600 },
1191
+ "height": { "type": "number", "default": 600 },
1192
+ "enableHover": { "type": "boolean", "default": true },
1193
+ "margin": { "type": "object" },
1194
+ "className": { "type": "string" }
1195
+ },
1196
+ "required": ["data"]
1197
+ }
1198
+ }
1199
+ },
1129
1200
  {
1130
1201
  "type": "function",
1131
1202
  "function": {
@@ -8,6 +8,7 @@ Use `import { ComponentName } from "semiotic/ai"` for all components below.
8
8
  - **StackedAreaChart** — `xAccessor`, `yAccessor`, `areaBy` (required), `normalize`
9
9
  - **Scatterplot** — `xAccessor`, `yAccessor`, `colorBy`, `sizeBy`
10
10
  - **BubbleChart** — `xAccessor`, `yAccessor`, **`sizeBy`** (required), `sizeRange`
11
+ - **ConnectedScatterplot** — `xAccessor`, `yAccessor`, `orderAccessor` (sequencing field), `pointRadius`
11
12
  - **Heatmap** — `xAccessor`, `yAccessor`, `valueAccessor`, `colorScheme` ("blues"|"reds"|"greens"|"viridis")
12
13
  - **BarChart** — `categoryAccessor`, `valueAccessor`, `orientation`, `sort`
13
14
  - **StackedBarChart** — `categoryAccessor`, `valueAccessor`, **`stackBy`** (required), `normalize`
@@ -24,6 +25,7 @@ Use `import { ComponentName } from "semiotic/ai"` for all components below.
24
25
  - **TreeDiagram** — `childrenAccessor`, `nodeIdAccessor`, `layout` ("tree"|"cluster"|"partition"), `orientation`
25
26
  - **Treemap** — `childrenAccessor`, `valueAccessor`, `nodeIdAccessor`, `colorByDepth`
26
27
  - **CirclePack** — `childrenAccessor`, `valueAccessor`, `nodeIdAccessor`, `colorByDepth`
28
+ - **OrbitDiagram** — `childrenAccessor`, `nodeIdAccessor`, `orbitMode` ("flat"|"solar"|"atomic"|number[]), `speed`, `animated`
27
29
 
28
30
  ## Network Data (`nodes: object[]`, `edges: object[]`)
29
31
  - **ForceDirectedGraph** — **`nodes`**, **`edges`** (both required), `nodeIDAccessor`, `sourceAccessor`, `targetAccessor`
@@ -35,6 +37,7 @@ Use `import { ComponentName } from "semiotic/ai"` for all components below.
35
37
  - **RealtimeHistogram** — **`binSize`** (required), `timeAccessor`, `valueAccessor`
36
38
  - **RealtimeSwarmChart** — `timeAccessor`, `valueAccessor`, `categoryAccessor`
37
39
  - **RealtimeWaterfallChart** — `timeAccessor`, `valueAccessor`, `positiveColor`, `negativeColor`
40
+ - **RealtimeHeatmap** — `timeAccessor`, `valueAccessor`, `heatmapXBins`, `heatmapYBins`, `aggregation`
38
41
  - **StreamNetworkFrame** (`chartType="sankey"`) — `ref.current.push({ source, target, value })`, `sourceAccessor`, `targetAccessor`, `valueAccessor` (import from `semiotic`)
39
42
 
40
43
  ## Common Props (all components)