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.
- package/CLAUDE.md +23 -10
- package/README.md +66 -63
- package/ai/cli.js +34 -21
- package/ai/dist/componentRegistry.js +2 -0
- package/ai/dist/mcp-server.js +54 -0
- package/ai/examples.md +75 -0
- package/ai/schema.json +71 -0
- package/ai/system-prompt.md +3 -0
- package/dist/{ChartGrid.d.ts → components/ChartGrid.d.ts} +9 -7
- package/dist/{LinkedCharts.d.ts → components/LinkedCharts.d.ts} +34 -1
- package/dist/{Tooltip → components/Tooltip}/Tooltip.d.ts +9 -2
- package/dist/{charts → components/charts}/index.d.ts +2 -0
- package/dist/{charts → components/charts}/network/ChordDiagram.d.ts +2 -0
- package/dist/{charts → components/charts}/network/CirclePack.d.ts +2 -0
- package/dist/{charts → components/charts}/network/ForceDirectedGraph.d.ts +2 -0
- package/dist/components/charts/network/OrbitDiagram.d.ts +78 -0
- package/dist/{charts → components/charts}/network/SankeyDiagram.d.ts +2 -0
- package/dist/{charts → components/charts}/network/TreeDiagram.d.ts +2 -0
- package/dist/{charts → components/charts}/network/Treemap.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/BarChart.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/BoxPlot.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/DonutChart.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/DotPlot.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/GroupedBarChart.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/PieChart.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/StackedBarChart.d.ts +2 -0
- package/dist/{charts → components/charts}/ordinal/SwarmPlot.d.ts +2 -0
- package/dist/components/charts/shared/diagnoseConfig.d.ts +23 -0
- package/dist/{charts → components/charts}/shared/hooks.d.ts +23 -1
- package/dist/components/charts/shared/stringDistance.d.ts +11 -0
- package/dist/{charts → components/charts}/shared/tooltipUtils.d.ts +1 -1
- package/dist/{charts → components/charts}/shared/types.d.ts +6 -0
- package/dist/{charts → components/charts}/shared/withChartWrapper.d.ts +10 -0
- package/dist/{charts → components/charts}/xy/AreaChart.d.ts +8 -0
- package/dist/{charts → components/charts}/xy/BubbleChart.d.ts +8 -0
- package/dist/{charts → components/charts}/xy/ConnectedScatterplot.d.ts +3 -0
- package/dist/{charts → components/charts}/xy/Heatmap.d.ts +8 -0
- package/dist/{charts → components/charts}/xy/LineChart.d.ts +26 -0
- package/dist/{charts → components/charts}/xy/Scatterplot.d.ts +3 -0
- package/dist/{charts → components/charts}/xy/StackedAreaChart.d.ts +8 -0
- package/dist/{export → components/export}/exportChart.d.ts +6 -1
- package/dist/components/semiotic-ai.d.ts +61 -0
- package/dist/components/semiotic-data.d.ts +7 -0
- package/dist/components/semiotic-network.d.ts +14 -0
- package/dist/components/semiotic-ordinal.d.ts +18 -0
- package/dist/components/semiotic-realtime.d.ts +22 -0
- package/dist/components/semiotic-server.d.ts +1 -0
- package/dist/components/semiotic-xy.d.ts +16 -0
- package/dist/components/semiotic.d.ts +57 -0
- package/dist/{server → components/server}/renderToStaticSVG.d.ts +7 -0
- package/dist/{stream → components/stream}/NetworkSVGOverlay.d.ts +20 -0
- package/dist/{stream → components/stream}/OrdinalSVGOverlay.d.ts +8 -0
- package/dist/{stream → components/stream}/PipelineStore.d.ts +7 -0
- package/dist/{stream → components/stream}/SVGOverlay.d.ts +15 -0
- package/dist/components/stream/SceneToSVG.d.ts +20 -0
- package/dist/components/stream/hitTestUtils.d.ts +23 -0
- package/dist/{stream → components/stream}/networkTypes.d.ts +10 -2
- package/dist/{stream → components/stream}/ordinalTypes.d.ts +16 -10
- package/dist/components/stream/renderers/areaCanvasRenderer.d.ts +2 -0
- package/dist/{stream → components/stream}/types.d.ts +12 -0
- package/dist/components/stream/useStalenessCheck.d.ts +16 -0
- package/dist/{types → components/types}/legendTypes.d.ts +5 -0
- package/dist/network.min.js +1 -1
- package/dist/network.module.min.js +1 -1
- package/dist/ordinal.min.js +1 -1
- package/dist/ordinal.module.min.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai.d.ts +3 -0
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-network.d.ts +1 -0
- package/dist/semiotic-ordinal.d.ts +1 -0
- package/dist/semiotic.d.ts +3 -3
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/dist/server.min.js +1 -1
- package/dist/server.module.min.js +1 -1
- package/dist/test/canvasMock.d.ts +2 -0
- package/dist/test-utils/canvasMock.d.ts +20 -0
- package/dist/test-utils/frameMock.d.ts +78 -0
- package/dist/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +7 -15
- package/dist/stream/renderers/areaCanvasRenderer.d.ts +0 -7
- /package/dist/{Annotation.d.ts → components/Annotation.d.ts} +0 -0
- /package/dist/{CategoryColors.d.ts → components/CategoryColors.d.ts} +0 -0
- /package/dist/{ChartContainer.d.ts → components/ChartContainer.d.ts} +0 -0
- /package/dist/{ChartErrorBoundary.d.ts → components/ChartErrorBoundary.d.ts} +0 -0
- /package/dist/{ContextLayout.d.ts → components/ContextLayout.d.ts} +0 -0
- /package/dist/{DetailsPanel.d.ts → components/DetailsPanel.d.ts} +0 -0
- /package/dist/{Legend.d.ts → components/Legend.d.ts} +0 -0
- /package/dist/{ThemeProvider.d.ts → components/ThemeProvider.d.ts} +0 -0
- /package/dist/{charts → components/charts}/ordinal/Histogram.d.ts +0 -0
- /package/dist/{charts → components/charts}/ordinal/RidgelinePlot.d.ts +0 -0
- /package/dist/{charts → components/charts}/ordinal/ViolinPlot.d.ts +0 -0
- /package/dist/{charts → components/charts}/realtime/RealtimeHeatmap.d.ts +0 -0
- /package/dist/{charts → components/charts}/realtime/RealtimeHistogram.d.ts +0 -0
- /package/dist/{charts → components/charts}/realtime/RealtimeLineChart.d.ts +0 -0
- /package/dist/{charts → components/charts}/realtime/RealtimeSwarmChart.d.ts +0 -0
- /package/dist/{charts → components/charts}/realtime/RealtimeWaterfallChart.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/ChartError.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/annotationRules.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/colorUtils.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/formatUtils.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/legendUtils.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/loess.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/networkUtils.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/selectionUtils.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/statisticalOverlays.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/validateChartData.d.ts +0 -0
- /package/dist/{charts → components/charts}/shared/validateProps.d.ts +0 -0
- /package/dist/{charts → components/charts}/xy/MinimapChart.d.ts +0 -0
- /package/dist/{charts → components/charts}/xy/ScatterplotMatrix.d.ts +0 -0
- /package/dist/{data → components/data}/fromVegaLite.d.ts +0 -0
- /package/dist/{data → components/data}/transforms.d.ts +0 -0
- /package/dist/{export → components/export}/chartConfig.d.ts +0 -0
- /package/dist/{export → components/export}/selectionSerializer.d.ts +0 -0
- /package/dist/{geometry → components/geometry}/sankeyLinks.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/BinAccumulator.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/IncrementalExtent.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/RingBuffer.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/renderers/types.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/renderers/waterfallRenderer.d.ts +0 -0
- /package/dist/{realtime → components/realtime}/types.d.ts +0 -0
- /package/dist/{store → components/store}/ObservationStore.d.ts +0 -0
- /package/dist/{store → components/store}/SelectionStore.d.ts +0 -0
- /package/dist/{store → components/store}/ThemeStore.d.ts +0 -0
- /package/dist/{store → components/store}/TooltipStore.d.ts +0 -0
- /package/dist/{store → components/store}/createStore.d.ts +0 -0
- /package/dist/{store → components/store}/useObservation.d.ts +0 -0
- /package/dist/{store → components/store}/useSelection.d.ts +0 -0
- /package/dist/{stream → components/stream}/CanvasHitTester.d.ts +0 -0
- /package/dist/{stream → components/stream}/DataSourceAdapter.d.ts +0 -0
- /package/dist/{stream → components/stream}/MarginalGraphics.d.ts +0 -0
- /package/dist/{stream → components/stream}/NetworkCanvasHitTester.d.ts +0 -0
- /package/dist/{stream → components/stream}/NetworkPipelineStore.d.ts +0 -0
- /package/dist/{stream → components/stream}/OrdinalCanvasHitTester.d.ts +0 -0
- /package/dist/{stream → components/stream}/OrdinalPipelineStore.d.ts +0 -0
- /package/dist/{stream → components/stream}/ParticlePool.d.ts +0 -0
- /package/dist/{stream → components/stream}/SceneGraph.d.ts +0 -0
- /package/dist/{stream → components/stream}/StreamNetworkFrame.d.ts +0 -0
- /package/dist/{stream → components/stream}/StreamOrdinalFrame.d.ts +0 -0
- /package/dist/{stream → components/stream}/StreamXYFrame.d.ts +0 -0
- /package/dist/{stream → components/stream}/accessorUtils.d.ts +0 -0
- /package/dist/{stream → components/stream}/keyboardNav.d.ts +0 -0
- /package/dist/{stream → components/stream}/layouts/chordLayoutPlugin.d.ts +0 -0
- /package/dist/{stream → components/stream}/layouts/forceLayoutPlugin.d.ts +0 -0
- /package/dist/{stream → components/stream}/layouts/hierarchyLayoutPlugin.d.ts +0 -0
- /package/dist/{stream → components/stream}/layouts/index.d.ts +0 -0
- /package/dist/{stream → components/stream}/layouts/sankeyLayoutPlugin.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/barScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/connectorScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/pieScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/pointScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/statisticalScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/timelineScene.d.ts +0 -0
- /package/dist/{stream → components/stream}/ordinalSceneBuilders/types.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/barCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/boxplotCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/candlestickCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/connectorCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/heatmapCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/lineCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/networkArcRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/networkCircleRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/networkEdgeRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/networkParticleRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/networkRectRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/pointCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/swarmCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/types.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/violinCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/waterfallCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/renderers/wedgeCanvasRenderer.d.ts +0 -0
- /package/dist/{stream → components/stream}/useResponsiveSize.d.ts +0 -0
- /package/dist/{types → components/types}/annotationTypes.d.ts +0 -0
- /package/dist/{types → components/types}/generalTypes.d.ts +0 -0
- /package/dist/{types → components/types}/interactionTypes.d.ts +0 -0
- /package/dist/{types → components/types}/networkTypes.d.ts +0 -0
- /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
|
-
- `
|
|
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
|
[](https://www.npmjs.com/package/semiotic)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
A React data visualization library for
|
|
7
|
+
A React data visualization library designed for AI-assisted development.
|
|
8
8
|
|
|
9
|
-
Simple charts in 5 lines.
|
|
10
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
###
|
|
31
|
+
### Built for AI-assisted development
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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" //
|
|
261
|
-
import { BarChart } from "semiotic/ordinal" //
|
|
262
|
-
import { ForceDirectedGraph } from "semiotic/network" //
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
console.log(` ⚠
|
|
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
|
-
|
|
90
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
};
|
package/ai/dist/mcp-server.js
CHANGED
|
@@ -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": {
|
package/ai/system-prompt.md
CHANGED
|
@@ -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)
|