semiotic 3.8.6 → 3.8.7
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 +33 -7
- package/README.md +82 -55
- package/ai/behaviorContracts.cjs +86 -1
- package/ai/componentMetadata.cjs +4 -9
- package/ai/dist/mcp-server.js +97 -10
- package/ai/examples.md +154 -7
- package/ai/schema.json +1611 -145
- package/ai/surface-manifest.json +12 -10
- package/ai/system-prompt.md +9 -3
- package/dist/{chunk-chartContainerDataAudit-FEOD5GTQ.module.min.js → chunk-chartContainerDataAudit-JDSVSKGM.module.min.js} +1 -1
- package/dist/chunk-chunk-2YAZHXL4.module.min.js +2 -0
- package/dist/{chunk-chunk-G7WFWHAD.module.min.js → chunk-chunk-4ITOQRXM.module.min.js} +1 -1
- package/dist/chunk-chunk-5SD6BHVW.module.min.js +2 -0
- package/dist/chunk-chunk-6V5VQVCT.module.min.js +2 -0
- package/dist/chunk-chunk-7TTBHSAG.module.min.js +2 -0
- package/dist/chunk-chunk-7ZDJSYKI.module.min.js +2 -0
- package/dist/chunk-chunk-BGHPD3RA.module.min.js +1 -0
- package/dist/chunk-chunk-BMRZ2SPU.module.min.js +2 -0
- package/dist/chunk-chunk-BNGBEY7N.module.min.js +2 -0
- package/dist/chunk-chunk-C7APLVQD.module.min.js +2 -0
- package/dist/chunk-chunk-DGWFBOGB.module.min.js +1 -0
- package/dist/{chunk-chunk-Q2BS46W2.module.min.js → chunk-chunk-DIVE2DRA.module.min.js} +1 -1
- package/dist/chunk-chunk-FBUNUIPV.module.min.js +2 -0
- package/dist/chunk-chunk-FQPKOAIH.module.min.js +2 -0
- package/dist/chunk-chunk-FRO4TRXK.module.min.js +2 -0
- package/dist/chunk-chunk-G7QVPZUD.module.min.js +2 -0
- package/dist/chunk-chunk-GBPYV4FP.module.min.js +2 -0
- package/dist/chunk-chunk-GU2EJIDJ.module.min.js +2 -0
- package/dist/chunk-chunk-J5QD4RAM.module.min.js +2 -0
- package/dist/{chunk-chunk-RA7JCG7D.module.min.js → chunk-chunk-JWXLNZSM.module.min.js} +1 -1
- package/dist/chunk-chunk-KXAFCCDB.module.min.js +2 -0
- package/dist/chunk-chunk-LG7YKJAK.module.min.js +2 -0
- package/dist/{chunk-chunk-XP3OHHFX.module.min.js → chunk-chunk-LVHDZAT3.module.min.js} +1 -1
- package/dist/chunk-chunk-LWITSR2O.module.min.js +2 -0
- package/dist/{chunk-chunk-SMVD3EQJ.module.min.js → chunk-chunk-MX35T6RX.module.min.js} +1 -1
- package/dist/chunk-chunk-NH4MEAKP.module.min.js +2 -0
- package/dist/chunk-chunk-NJETWX42.module.min.js +2 -0
- package/dist/chunk-chunk-NW25WGLS.module.min.js +2 -0
- package/dist/{chunk-chunk-GFTVACTO.module.min.js → chunk-chunk-OI7R7EJB.module.min.js} +1 -1
- package/dist/{chunk-chunk-OM6NWS4H.module.min.js → chunk-chunk-ONMLEXHR.module.min.js} +1 -1
- package/dist/chunk-chunk-OY66GCE6.module.min.js +1 -0
- package/dist/chunk-chunk-PZFT457G.module.min.js +1 -0
- package/dist/chunk-chunk-Q3WW6JGR.module.min.js +1 -0
- package/dist/chunk-chunk-Q6XKQTOQ.module.min.js +1 -0
- package/dist/chunk-chunk-RJRM2E6P.module.min.js +1 -0
- package/dist/chunk-chunk-RPL7WYXI.module.min.js +1 -0
- package/dist/chunk-chunk-SV4XAZ3Q.module.min.js +1 -0
- package/dist/chunk-chunk-TSCFL235.module.min.js +1 -0
- package/dist/chunk-chunk-UOQRPGPK.module.min.js +2 -0
- package/dist/chunk-chunk-V3OAKG32.module.min.js +1 -0
- package/dist/chunk-chunk-WLOIUMWG.module.min.js +2 -0
- package/dist/chunk-chunk-XEGXX4F7.module.min.js +1 -0
- package/dist/chunk-chunk-XFRBLXYM.module.min.js +1 -0
- package/dist/chunk-chunk-Z2AJERX5.module.min.js +2 -0
- package/dist/chunk-chunk-ZXYDYAB7.module.min.js +2 -0
- package/dist/components/ai/SemioticVACPBridge.d.ts +22 -0
- package/dist/components/ai/chartCapabilities.d.ts +4 -3
- package/dist/components/ai/conversationArc.d.ts +2 -176
- package/dist/components/ai/conversationArcTypes.d.ts +202 -0
- package/dist/components/ai/readerGrounding.d.ts +12 -0
- package/dist/components/ai/vacpAdapter.d.ts +13 -0
- package/dist/components/ai/vacpAdapterActions.d.ts +2 -0
- package/dist/components/ai/vacpAdapterModel.d.ts +7 -0
- package/dist/components/ai/vacpAdapterRuntime.d.ts +26 -0
- package/dist/components/ai/vacpAdapterState.d.ts +3 -0
- package/dist/components/ai/vacpAdapterTypes.d.ts +169 -0
- package/dist/components/ai/vacpTypes.d.ts +160 -0
- package/dist/components/charts/index.d.ts +4 -4
- package/dist/components/charts/physics/ChainReactionChart.capability.d.ts +9 -0
- package/dist/components/charts/physics/ChainReactionChart.d.ts +29 -0
- package/dist/components/charts/physics/CollisionSwarmChart.d.ts +1 -1
- package/dist/components/charts/physics/EventDropChart.d.ts +7 -2
- package/dist/components/charts/physics/GaltonBoardChart.d.ts +1 -1
- package/dist/components/charts/physics/{PhysicsPileChart.capability.d.ts → PacketFlowChart.capability.d.ts} +1 -1
- package/dist/components/charts/physics/{PhysicalFlowChart.d.ts → PacketFlowChart.d.ts} +22 -6
- package/dist/components/charts/physics/PhysicsCustomChart.d.ts +1 -1
- package/dist/components/charts/physics/ProcessFlowChart.d.ts +7 -4
- package/dist/components/charts/physics/{PhysicalFlowChart.capability.d.ts → UnitPileChart.capability.d.ts} +1 -1
- package/dist/components/charts/physics/{PhysicsPileChart.d.ts → UnitPileChart.d.ts} +19 -6
- package/dist/components/charts/physics/crucibleChartProps.d.ts +1 -1
- package/dist/components/charts/physics/crucibleChartUtils.d.ts +9 -0
- package/dist/components/charts/physics/gauntletChartProps.d.ts +6 -1
- package/dist/components/charts/physics/gauntletTerminal.d.ts +61 -0
- package/dist/components/charts/physics/packetFlowSemantics.d.ts +6 -0
- package/dist/components/charts/physics/physicsHocUtils.d.ts +45 -2
- package/dist/components/charts/shared/auditAccessibilityStyles.d.ts +9 -0
- package/dist/components/charts/shared/knownChartComponents.d.ts +1 -1
- package/dist/components/charts/shared/useChartLegend.d.ts +8 -1
- package/dist/components/charts/shared/useChartSetup.d.ts +7 -0
- package/dist/components/data/portability/capabilityBinding.d.ts +41 -0
- package/dist/components/data/portability/index.d.ts +2 -0
- package/dist/components/legendLayout.d.ts +56 -0
- package/dist/components/recipes/geographicDotGrid.d.ts +82 -0
- package/dist/components/recipes/geographicGrid.d.ts +100 -0
- package/dist/components/recipes/physics.d.ts +2 -0
- package/dist/components/recipes/physicsStageGeography.d.ts +137 -0
- package/dist/components/semiotic-ai.d.ts +4 -3
- package/dist/components/semiotic-experimental-vacp.d.ts +11 -0
- package/dist/components/semiotic-experimental.d.ts +6 -3
- package/dist/components/semiotic-geo.d.ts +4 -0
- package/dist/components/semiotic-physics.d.ts +9 -6
- package/dist/components/semiotic-recipes-core.d.ts +6 -1
- package/dist/components/server/renderEvidence.d.ts +1 -1
- package/dist/components/server/renderToStaticSVG.d.ts +2 -1
- package/dist/components/server/serverChartConfigHeatmap.d.ts +6 -0
- package/dist/components/server/serverChartConfigNetworkStyles.d.ts +12 -0
- package/dist/components/server/serverChartConfigShared.d.ts +16 -0
- package/dist/components/server/serverChartConfigs.d.ts +2 -2
- package/dist/components/server/serverChartConfigsPhysics.d.ts +2 -2
- package/dist/components/server/serverChartConfigsXY.d.ts +0 -1
- package/dist/components/server/staticLegend.d.ts +6 -0
- package/dist/components/server/staticSVGChrome.d.ts +10 -2
- package/dist/components/server/staticValue.d.ts +8 -0
- package/dist/components/stream/geoPipelineConfig.d.ts +10 -0
- package/dist/components/stream/legendRenderer.d.ts +8 -0
- package/dist/components/stream/physics/PhysicsEvidence.d.ts +37 -0
- package/dist/components/stream/physics/PhysicsPipelineStore.d.ts +9 -0
- package/dist/components/stream/physics/PhysicsSettledScene.d.ts +5 -0
- package/dist/components/stream/physics/physicsFramePipelineConfig.d.ts +19 -0
- package/dist/components/stream/physics/physicsPipelineSettle.d.ts +52 -0
- package/dist/components/stream/physics/physicsRegionRuntime.d.ts +23 -0
- package/dist/components/stream/types.d.ts +2 -0
- package/dist/components/types/legendTypes.d.ts +17 -1
- package/dist/controls.min.js +1 -1
- package/dist/controls.module.min.js +1 -1
- package/dist/geo.min.js +1 -1
- package/dist/geo.module.min.js +1 -1
- 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/physics.min.js +1 -1
- package/dist/physics.module.min.js +1 -1
- package/dist/physicsWorker.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai-core.min.js +1 -1
- package/dist/semiotic-ai-core.module.min.js +1 -1
- package/dist/semiotic-ai.d.ts +4 -3
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-data.module.min.js +1 -1
- package/dist/semiotic-experimental-vacp.d.ts +11 -0
- package/dist/semiotic-experimental-vacp.min.js +1 -0
- package/dist/semiotic-experimental-vacp.module.min.js +1 -0
- package/dist/semiotic-experimental.d.ts +6 -3
- package/dist/semiotic-experimental.min.js +2 -1
- package/dist/semiotic-experimental.module.min.js +2 -1
- package/dist/semiotic-geo.d.ts +4 -0
- package/dist/semiotic-physics.d.ts +9 -6
- package/dist/semiotic-realtime-core.min.js +1 -1
- package/dist/semiotic-realtime-core.module.min.js +1 -1
- package/dist/semiotic-recipes-core.d.ts +6 -1
- package/dist/semiotic-recipes-core.min.js +1 -1
- package/dist/semiotic-recipes-core.module.min.js +1 -1
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-server-edge.min.js +1 -1
- package/dist/semiotic-server-edge.module.min.js +1 -1
- package/dist/semiotic-server-node.min.js +1 -1
- package/dist/semiotic-server-node.module.min.js +1 -1
- package/dist/semiotic-utils-core.min.js +1 -1
- package/dist/semiotic-utils-core.module.min.js +1 -1
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- 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/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +18 -2
- package/spec/README.md +94 -2
- package/spec/bindings/README.md +14 -3
- package/spec/v0.1/examples/annotation-provenance-reviewed-revision.json +27 -0
- package/spec/v0.1/examples/annotation-provenance-watcher-threshold.json +21 -0
- package/spec/v0.1/examples/audience-profile-executive-review.json +24 -0
- package/spec/v0.1/examples/audience-profile-incident-operators.json +42 -0
- package/spec/v0.1/examples/chart-capability-bar-comparison.json +48 -0
- package/spec/v0.1/examples/chart-capability-service-flow.json +54 -0
- package/dist/chunk-chunk-2CHN2TA3.module.min.js +0 -1
- package/dist/chunk-chunk-3SHB24AG.module.min.js +0 -1
- package/dist/chunk-chunk-4MMOOYTX.module.min.js +0 -2
- package/dist/chunk-chunk-5RKXZQ2P.module.min.js +0 -1
- package/dist/chunk-chunk-75OTQSXS.module.min.js +0 -1
- package/dist/chunk-chunk-7ALTGHK6.module.min.js +0 -1
- package/dist/chunk-chunk-A5GRQUOF.module.min.js +0 -1
- package/dist/chunk-chunk-AAF5LZAU.module.min.js +0 -2
- package/dist/chunk-chunk-ARZGA4LJ.module.min.js +0 -2
- package/dist/chunk-chunk-C4YA6TDR.module.min.js +0 -1
- package/dist/chunk-chunk-CAFLML4L.module.min.js +0 -2
- package/dist/chunk-chunk-CO5KQMGH.module.min.js +0 -1
- package/dist/chunk-chunk-FHBN7OEB.module.min.js +0 -2
- package/dist/chunk-chunk-GMQ5AYTD.module.min.js +0 -1
- package/dist/chunk-chunk-IP2UE74X.module.min.js +0 -1
- package/dist/chunk-chunk-ITDWLZXV.module.min.js +0 -2
- package/dist/chunk-chunk-JCG72SGW.module.min.js +0 -2
- package/dist/chunk-chunk-LPSPATPC.module.min.js +0 -1
- package/dist/chunk-chunk-PX5YQGDP.module.min.js +0 -2
- package/dist/chunk-chunk-QSQVBIJA.module.min.js +0 -1
- package/dist/chunk-chunk-RCF52Z42.module.min.js +0 -2
- package/dist/chunk-chunk-RNUHEXZA.module.min.js +0 -2
- package/dist/chunk-chunk-ROZWKEUG.module.min.js +0 -1
- package/dist/chunk-chunk-T2FKJD4O.module.min.js +0 -2
- package/dist/chunk-chunk-UDREYOLV.module.min.js +0 -1
- package/dist/chunk-chunk-VOWE3SAP.module.min.js +0 -2
- package/dist/chunk-chunk-VQPNBUSW.module.min.js +0 -2
- package/dist/chunk-chunk-WAWCIHFJ.module.min.js +0 -1
- package/dist/chunk-chunk-WYARAXHR.module.min.js +0 -2
- package/dist/chunk-chunk-XV3KGYTR.module.min.js +0 -2
- package/dist/chunk-chunk-YC2IVEPX.module.min.js +0 -1
- package/dist/chunk-chunk-ZOAQDIJO.module.min.js +0 -1
- package/dist/chunk-chunk-ZXIXAPRE.module.min.js +0 -2
package/CLAUDE.md
CHANGED
|
@@ -4,16 +4,20 @@
|
|
|
4
4
|
- Install: `npm install semiotic`
|
|
5
5
|
<!-- semiotic-bundle-sizes:start -->
|
|
6
6
|
<!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
|
|
7
|
-
- **Use sub-path imports** — `semiotic/xy` (
|
|
7
|
+
- **Use sub-path imports** — `semiotic/xy` (145KB gz), `semiotic/ordinal` (120KB gz), `semiotic/network` (126KB gz), `semiotic/geo` (103KB gz), `semiotic/realtime` (153KB gz), `semiotic/realtime/core` (144KB gz), `semiotic/realtime/react` (1KB gz), `semiotic/server` (210KB gz), `semiotic/server/node` (210KB gz), `semiotic/server/edge` (224KB gz), `semiotic/utils` (83KB gz), `semiotic/utils/core` (82KB gz), `semiotic/utils/react` (6KB gz), `semiotic/recipes` (88KB gz), `semiotic/recipes/core` (87KB gz), `semiotic/recipes/react` (2KB gz), `semiotic/themes` (7KB gz), `semiotic/themes/core` (7KB gz), `semiotic/themes/react` (6KB gz), `semiotic/data` (4KB gz), `semiotic/value` (8KB gz), `semiotic/physics` (160KB gz), `semiotic/physics/matter` (1KB gz), `semiotic/physics/rapier` (1KB gz), `semiotic/ai` (486KB gz), `semiotic/ai/core` (80KB gz), `semiotic/controls` (12KB gz), `semiotic/rough` (4KB gz). Full `semiotic` is 389KB gz.
|
|
8
8
|
<!-- semiotic-bundle-sizes:end -->
|
|
9
9
|
- CLI: `npx semiotic-ai [--schema|--compact|--examples|--doctor|--audit-a11y]` · MCP: `npx semiotic-mcp`
|
|
10
10
|
|
|
11
11
|
## Architecture
|
|
12
12
|
HOC Charts (simple, default) → Stream Frames (full control). Use HOCs unless you need control they don't expose. Stream Frames pass `RealtimeNode`/`RealtimeEdge` wrappers in callbacks, not your data. Every HOC accepts `frameProps`, has an error boundary + dev-mode validation. TypeScript `strict: true`.
|
|
13
13
|
|
|
14
|
-
## Common Props (
|
|
14
|
+
## Common Props (chart HOCs only)
|
|
15
15
|
`title`, `description` (aria-label), `summary` (sr-only), `width` (600), `height` (400), `responsiveWidth`, `responsiveHeight`, `margin`, `className`, `color` (uniform fill), `stroke`, `strokeWidth`, `opacity`, `enableHover` (true), `tooltip` (boolean | "multi" | function | config), `showLegend`, `showGrid` (false), `frameProps`, `onObservation`, `onClick`, `chartId`, `loading`, `loadingContent` (ReactNode; `false` suppresses), `emptyContent`, `legendInteraction` ("none"|"highlight"|"isolate"), `legendPosition` ("right"|"left"|"top"|"bottom"), `emphasis` ("primary"|"secondary"), `annotations`, `accessibleTable` (true), `hoverHighlight` (requires `colorBy`), `hoverRadius` (30), `animate` (boolean | {duration?, easing?, intro?}), `axisExtent` ("nice"|"exact" — pins first/last tick to data min/max; XY x/y + ordinal value axis only).
|
|
16
16
|
|
|
17
|
+
This list is not global. Plain value components do not inherit chart-HOC props and must be
|
|
18
|
+
validated against their own schema. In particular, `BigNumber` uses `label`, `description`, and
|
|
19
|
+
`summary`; it does not accept `title` or `accessibleTable`.
|
|
20
|
+
|
|
17
21
|
**Primitive styling** (`color`/`stroke`/`strokeWidth`/`opacity`): apply to any shape the chart draws. Precedence: top-level prop > `frameProps.*Style` fn return > HOC base > theme. Use CSS vars (`stroke="var(--semiotic-border)"`) for cascade-overridable theming. Per-datum: use `frameProps.pieceStyle`/`pointStyle`/`lineStyle` fn form.
|
|
18
22
|
|
|
19
23
|
`onClick` receives `(datum, { x, y })`. `onObservation` receives `{ type, datum?, x?, y?, timestamp, chartType, chartId }`.
|
|
@@ -55,7 +59,7 @@ HOC Charts (simple, default) → Stream Frames (full control). Use HOCs unless y
|
|
|
55
59
|
|
|
56
60
|
All ordinal: `colorBy`, `colorScheme`, `categoryFormat` (string|ReactNode), `showCategoryTicks` (true).
|
|
57
61
|
|
|
58
|
-
**`styleRules`** (declarative threshold-aware styling — **every chart family**) — an ordered `StyleRule[]` where each `{ when, style }` matching a mark contributes its style, merged in list order so **the last applicable rule wins per property** (CSS-cascade model). Wired on: **ordinal** BarChart/StackedBarChart/GroupedBarChart (bars/segments); **XY** LineChart/AreaChart/StackedAreaChart (per-series) + Scatterplot/BubbleChart/QuadrantChart/ConnectedScatterplot (per-point); **network** ForceDirectedGraph/SankeyDiagram/ChordDiagram (nodes); **geo** ChoroplethMap (features) + ProportionalSymbolMap/DistanceCartogram (symbols); **physics** GaltonBoardChart/
|
|
62
|
+
**`styleRules`** (declarative threshold-aware styling — **every chart family**) — an ordered `StyleRule[]` where each `{ when, style }` matching a mark contributes its style, merged in list order so **the last applicable rule wins per property** (CSS-cascade model). Wired on: **ordinal** BarChart/StackedBarChart/GroupedBarChart (bars/segments); **XY** LineChart/AreaChart/StackedAreaChart (per-series) + Scatterplot/BubbleChart/QuadrantChart/ConnectedScatterplot (per-point); **network** ForceDirectedGraph/SankeyDiagram/ChordDiagram (nodes); **geo** ChoroplethMap (features) + ProportionalSymbolMap/DistanceCartogram (symbols); **physics** GaltonBoardChart/UnitPileChart/CollisionSwarmChart/EventDropChart (particles). `when` = predicate `(datum, ctx) => boolean`, a declarative threshold (`{ axis?: "x"|"y"|"value", field?, gt, gte, lt, lte, eq, ne, within:[min,max], outside, in:[...] }`), or `true`/omitted (always). `ctx` channels by family: bars `{ value, category }`; XY `{ value(=y), x, y }` (use `axis:"x"`/`"y"` to target either axis regardless of accessor field name); network/geo/physics `{ value, category }` (category = the colorBy/group). A rule's `style.fill` may be a color string or a **`HatchFill`** descriptor (`{ type:"hatch", background?, stroke?, spacing?, angle?, lineWidth?, lineOpacity? }`) resolving to a `CanvasPattern` on canvas and an SVG `<pattern>` in SSR — one declaration, both backends. Precedence: top-level primitives > per-mark style fn (`pieceStyle`/`pointStyle`/`nodeStyle`) > `styleRules` > base `colorBy`/`color`/theme. Works through `renderChart`/MCP for all wired families (use the declarative-threshold form, not predicates, when the config must serialize). `HatchFill` is also a `band`/`x-band` annotation `fill` and any scene `style.fill`. Caveats: line/area rules resolve per-series (sample datum, not per-vertex); network hierarchy charts (Tree/Treemap/CirclePack/Orbit) are NOT wired (their `colorByDepth` owns fill); MultiAxisLineChart/MinimapChart/CandlestickChart not wired. Exported from `semiotic` + each family entry + `semiotic/utils`: `StyleRule`, `resolveStyleRules`, `matchesThreshold`, `makeRuleValueResolver`, `makeXYRuleContext`, `makeNodeRuleContext`, `composeStyleRules`, `HatchFill`, `isHatchFill`. See `/features/style-rules`.
|
|
59
63
|
|
|
60
64
|
## Network Charts (`semiotic/network`)
|
|
61
65
|
|
|
@@ -87,13 +91,17 @@ Process/arrival/distribution charts backed by `StreamPhysicsFrame`. The settled
|
|
|
87
91
|
|
|
88
92
|
**GaltonBoardChart** — `data`, `valueAccessor` ("value"), `bins` (21), `mode` ("sample"|"mechanical"), `pegRows`, `mechanicalCount`, `branchProbability`, `ballRadius`, `colorBy`, `styleRules` (per-particle; `ctx.category` = colorBy group), `seed`, `size`/`width`/`height`, `paused`, `frameProps`. Renders a deterministic Galton/Plinko-style distribution that settles into bins; mechanical mode can generate a seeded no-data demonstration.
|
|
89
93
|
**EventDropChart** — `data`, `timeAccessor` ("time"), `arrivalAccessor` ("arrivalTime"), `windows` ({size}), `watermark` ({delay}|fn), `timeScale`, `ballRadius`, `colorBy`, `seed`, `size`, `paused`, `frameProps`. Use for event-time arrival, lateness, and watermark-window stories.
|
|
90
|
-
**
|
|
94
|
+
**UnitPileChart** (was `PhysicsPileChart`; alias kept) — `data`, `categoryAccessor` ("category"), `valueAccessor` ("value"), `mode` ("sample"|"mechanical"), `mechanicalCount`, `mechanicalCategories`, `unitValue` (1), `ballRadius`, `colorBy`, `seed`, `showProjection`, `size`, `paused`, `frameProps`. Unitizes values into repeated bodies that settle into category piles; mechanical mode can generate a seeded no-data capacity sketch; the default projection overlay keeps exact totals readable.
|
|
91
95
|
**CollisionSwarmChart** — `data`, `xAccessor` ("x"), optional `groupAccessor`, `radiusAccessor`, `pointRadius`, `xExtent`, `collisionIterations`, `settle`, `showProjection`, `colorBy`, `seed`, `size`, `paused`, `frameProps`. Uses springs plus collisions to separate overlapping dots while preserving the quantitative axis and optional group lanes.
|
|
92
|
-
**
|
|
96
|
+
**PacketFlowChart** (was `PhysicalFlowChart`; alias kept) — `nodes`, `links`/`edges`/`data`, `nodeIdAccessor` ("id"), `nodeXAccessor` ("x"), `nodeYAccessor` ("y"), `sourceAccessor` ("source"), `targetAccessor` ("target"), `throughputAccessor` ("value"), `pathAccessor` ("path"), `coordinateMode` ("auto"|"normalized"|"pixels"), `particleRate`, `maxParticles`, `particleRadius`, `flowSpeed`, `pathConstraint` ("path"|"none"), `reducedMotion`, `showStaticFlow`, `showNodeLabels`, `showSensors`, `paused`, `seed`, `size`. Experimental physics-backed flow chart where packets move along authored node coordinates or link paths while a static throughput layer keeps route quantities readable.
|
|
93
97
|
**ProcessFlowChart** — multi-body workflow lane. `data`, `stages` (required: `[{id, label?, force?, damping?, capacity?, pressure?, portal?, absorb?, share?}]`), `stageAccessor` ("stage"), `idAccessor`, `groupBy` (optional feature key; completion when all members hit an absorb stage), `groupLabelAccessor`, `workAccessor`, `radiusAccessor`, `ballRadius` (6), `colorBy`, `groupCompletion` ("allAbsorbed"|"none"), `groupAnchorAlong` (0.55), `showProjection` (true), `showChrome` (true — processChrome kit), `liveCapacity` (true — FIFO queues at `unitsPerSecond`), `onCapacityChange` (queue depth / processed), `bodyLimit` (soft stream budget + oldest eviction), `bodyMark` ("circle"|"halo"|"faceted"|"pill"|"diamond"|"square" or per-row `datum.__physicsMark`), `selection`, `settle`, `seed`, `size`, `paused`, `frameProps`. Settled projection is stage occupancy + capacity badges; use for review queues / triage / merge pipelines. Prefer **GauntletChart** for one compound plan with timed gate effects.
|
|
98
|
+
**Stage geography kit** (`semiotic/physics` + `semiotic/recipes`) — `physicsStageGeography({size, flow ("down"|"right"), destinations (count | [{id,label}]), padding, chargeExtent, destinationExtent, projectionExtent, channelRatio})` → `{charge, apparatus, destinations: [{id,label,order,centerX,centerY,…}], projection}`. The shared **charge → apparatus → destinations** vocabulary every physics chart re-invented locally (Gauntlet `startX`/`socketX`/`graveyardX`, Crucible `chamber`/`mouth`/`outlets`, Galton bins and Pile tubes writing the *same* lane formula). Companions: `physicsStageColliders` (floor + one divider per interior boundary, so bodies land in the bin the data says), `physicsChargePoint` (spread a burst across the entry zone instead of co-locating it), `physicsDestination(geo, id)`, `describePhysicsStageGeography` (one-sentence reading protocol for a11y/agent grounding). Authoring vocabulary for a **new** chart or `PhysicsCustomChart` layout — shipped charts keep their own layouts; a test pins the builder to their lane math.
|
|
99
|
+
**Terminal state (event-tape charts)** — a tape-driven physics chart's end state must be computable from authored inputs with no simulation, because that pure result is what reduced motion, SSR, snapshot export, and `describeChart` receive. `CrucibleChart`: `compileCruciblePlan(...)` → `plan.initialState`/`plan.terminalState`/`plan.terminalSpawns`. `ChainReactionChart`: `initialRuntime(machine, mode, currentTime, true)`. `GauntletChart`: **`resolveGauntletTerminalStates({projects, events, layout, positiveProperties, negativeProperties, viability?, outcome?})`** (also `resolveGauntletTerminalState` for one project) — folds the authored tape, mirroring the live tick's effect order. Caveat: with Gauntlet's `crashDetection` armed (default), physics can still override the outcome to `bad_design_crash`, which no pure fold can predict; the pure result is "what the plan earns on paper". Pass `crashDetection={false}` for a fully authored reading. **Design test for a new physics metaphor:** can you state its ledger in one sentence (else it's an animation), does its terminal state exist without simulating (else it's a movie), would a naive reader guess the reading protocol from the apparatus (else the name is wrong)?
|
|
100
|
+
**Physics family contracts** (every physics HOC) — `seed` (deterministic; an explicit `frameProps.config.kernel.seed` still wins), `rerunMS` (settle → delay → deterministic replay; `null`/omitted = single run), `showProjection`, `paused`, and `selection` + `linkedHover`. `selection` accepts **either** a `{ name }` `SelectionConfig` — joining the shared selection store so physics bodies cross-highlight inside `LinkedCharts` like every other family — **or** a resolved `{ isActive, predicate }` `PhysicsBodySelection` body predicate as the escape hatch. The store's datum predicate is lifted over `body.datum`, so chrome bodies (walls, pegs, tubes) never match a data selection. Under `prefers-reduced-motion` the frame settles to the true end state in one pass: paced arrivals (`initialSpawnPacing`, per-datum `spawnAt`) are all admitted and elapsed-time event tapes run to completion, so the settled projection reports the outcome rather than the authored start.
|
|
94
101
|
**Physics controllers** (`createCapacityQueueController`, `createPortalController`, `composePhysicsControllers`) — process plugins via `controllers`. Capacity `getSnapshot()` → queueDepth/processedCount; emit `physics-capacity-processed`. **processChrome** (`semiotic/physics` / `semiotic/recipes`) — stage bays, capacity badges, feature sockets (theme: `--semiotic-process-*`). `PhysicsCustomChart`: `layout()` may return `regionEffects`, `controllers`, `bodyForces`; `layoutConfig` hot path without re-enqueue. Guide: `/features/physics-process-guide`. Contracts: `PhysicsContracts.test.tsx`.
|
|
95
102
|
**GauntletChart** — compound project core + tethered positive/negative property bodies + timed gate events. `positiveProperties`/`negativeProperties` (req), `gates`, `events`, `showChrome` (true), `showProjection` (true — viability/outcome strip), `showTethers` (true), `onStateChange`, `frameProps`. Bodies clamp inside walls (`clampGauntletPoint`). Not for multi-item factory floors (use ProcessFlowChart).
|
|
96
103
|
**CrucibleChart** — bounded peer components undergo authored `phases` and `events`, form declared `products`, and settle into reason-labelled `outlets` with source lineage. The ledger/projection is authoritative; motion never infers classification, timing, membership, loss, or routing. `buildCrucibleProductEvents({productId, form, contributions?, complete})` is pure authoring sugar for `combine → contribute* → complete-product`; every source/relation id, event position, reason, and outlet remains caller-supplied. The ref handle's `replay()` atomically restarts the deterministic tape even mid-run (`reset()` restores-and-pauses; `rerunMS` repeats after settlement). `playbackRate` changes presentation only. No push/live-event API.
|
|
104
|
+
**ChainReactionChart** — dependency chain reaction. `data`, `taskIDAccessor`, `labelAccessor`, `laneAccessor`, `dependencyAccessor` (all required — edges are never inferred), plus optional `startAccessor`/`endAccessor`/`progressAccessor`/`statusAccessor`/`completionTimeAccessor`/`blockerAccessor`/`milestoneAccessor`. Tasks place by workstream lane × dependency depth; a completed task releases one delivery ball per outgoing edge and a downstream task arms only once every prerequisite ball arrives, so a blocked task's *reach* is the reading. `mode` ("snapshot" derives the settled state at `currentTime` with no simulation | "replay" animates deliveries over that same derived state | "mechanical"), `insight` ("blocker-amplification" reports unfinished downstream tasks + affected lanes), `controls` (play/pause/step/reset/settle), `selectedTaskIDs`/`onSelectionChange`, `reducedMotion: "settle"`, `seed`. Ref handle: `play`/`pause`/`step`/`reset`/`settle`, `previewResolve(taskID)`/`clearPreview` (ask "what would resolving this blocker unlock?" without editing data), `completeTask`/`blockTask`/`unblockTask`, `getAmplification`, `getMachineState`. Task completion is always an explicit data event — the simulation delivers prerequisites, it never decides done. Documented `serverChartConfigs` exclusion: the settled reading is an authored overlay over zero bodies, so the HOC SSR path is the supported static snapshot.
|
|
97
105
|
**Pop (body-removal burst)** — every physics HOC ref is a `PhysicsFrameHandle` (extends the shared push handle) exposing **`popBodies(ids, options?)`** (`StreamPhysicsPopOptions` = `{ color?, durationMs?, radius? }`): removes the bodies and plays a burst — expanding ring + inner glow + radial sparks fading over `durationMs` (`drawPopAnimations`) — returning the removed ids. It reads as a *departure*, the physics/exit-emphasis counterpart to realtime **`pulse`**'s data-*arrival* glow (the same transient-emphasis metaphor on opposite ends of a datum's life). GauntletChart also fires it internally on gate-driven property removal; `/examples/nimby` (civic-value balloons) and `/examples/merge-pressure` (merge-risk traits) drive it that way.
|
|
98
106
|
|
|
99
107
|
## Value Charts (`semiotic/value`)
|
|
@@ -351,13 +359,31 @@ These rules are generated from `ai/behaviorContracts.cjs` and are consumed by `s
|
|
|
351
359
|
Agent action: Use colorBy for categorical encodings. Use CategoryColorProvider or LinkedCharts for cross-chart consistency, colorScheme for per-chart fallback palettes, and avoid frameProps style functions unless intentionally bypassing HOC color resolution.
|
|
352
360
|
- **Required prop combinations** (`props.required-combinations`): Some chart families need semantic props beyond data. These combinations are enforced by validation/schema for static configs and remain required in push mode unless explicitly noted.
|
|
353
361
|
Agent action: Before returning code, check the selected component against the required combinations list. For push mode, omit data but keep semantic props such as areaBy, sizeBy, stackBy, and groupBy.
|
|
354
|
-
Required combinations: StackedAreaChart: static data + areaBy; push areaBy. Stacked areas need a flat data array plus areaBy to identify the stacked series. BubbleChart: static data + sizeBy; push sizeBy. Bubbles need sizeBy in addition to x/y accessors so radius encodes data rather than a constant point size. StackedBarChart: static data + stackBy; push stackBy. Stacked bars need stackBy to split each category into stack segments. GroupedBarChart: static data + groupBy; push groupBy. Grouped bars need groupBy to split each category into side-by-side bars. SwimlaneChart: static data + subcategoryAccessor; push subcategoryAccessor. Swimlanes need subcategoryAccessor; colorBy defaults to the same field when not provided. GaugeChart: static value; push not supported. GaugeChart is value-only. thresholds,
|
|
362
|
+
Required combinations: StackedAreaChart: static data + areaBy; push areaBy. Stacked areas need a flat data array plus areaBy to identify the stacked series. BubbleChart: static data + sizeBy; push sizeBy. Bubbles need sizeBy in addition to x/y accessors so radius encodes data rather than a constant point size. StackedBarChart: static data + stackBy; push stackBy. Stacked bars need stackBy to split each category into stack segments. GroupedBarChart: static data + groupBy; push groupBy. Grouped bars need groupBy to split each category into side-by-side bars. SwimlaneChart: static data + subcategoryAccessor; push subcategoryAccessor. Swimlanes need subcategoryAccessor; colorBy defaults to the same field when not provided. GaugeChart: static value; push not supported. GaugeChart is value-only. Its thresholds use { value, color, label? }; BigNumber thresholds use the distinct { at, level, color?, label? } vocabulary. ForceDirectedGraph: static nodes + edges; push nodes + edges. ForceDirectedGraph schema/rendering requires nodes and edges. If an agent infers nodes from edge endpoints, it must materialize a nodes array before returning code.
|
|
355
363
|
- **Push mode omits data** (`streaming.push-mode-data`): HOC push mode is selected by omitting the data prop entirely. Passing data={[]} is static empty data and can clear/reinitialize the frame on render.
|
|
356
364
|
Agent action: For live charts, create a ref, omit data, then call ref.current.push() or pushMany(). For static renderChart/MCP snapshots, provide data because renderChart cannot push later.
|
|
365
|
+
- **Serialized proposals keep the initial snapshot** (`streaming.serialized-proposal-snapshot`): A JSON component/props proposal for MCP, SSR, or evaluation is a static snapshot even when the request mentions future pushes. Keep the supplied initial rows in the component's real data prop and do not invent pushRows, pushRequirement, ref, or method props.
|
|
366
|
+
Agent action: Return renderable initial props in JSON. If the requested deliverable is React push code, separately omit the controlled data prop in JSX, attach a ref, and call the documented imperative method from an effect or event handler.
|
|
367
|
+
Example: `JSON snapshot: { "component": "LineChart", "props": { "data": [{"week":1,"users":120}], "xAccessor":"week", "yAccessor":"users" } }. React push code instead omits data and calls ref.current?.push(row).`
|
|
357
368
|
- **Ref mutations need stable IDs** (`streaming.ref-mutations-require-id-accessors`): push() and pushMany() can append without IDs, but remove(id) and update(id, updater) require a stable ID accessor: pointIdAccessor for XY/realtime charts, dataIdAccessor for ordinal charts, and nodeIDAccessor/edgeIdAccessor for network operations.
|
|
358
369
|
Agent action: When generating code that calls remove() or update(), include the matching ID accessor and make sure pushed rows carry that ID field.
|
|
359
370
|
- **renderChart uses static props only** (`rendering.renderchart-static-props`): MCP renderChart and semiotic/server renderChart render a single static SVG/PNG snapshot. Browser-only realtime components and future ref pushes are not renderable through that path.
|
|
360
371
|
Agent action: Use renderChart only with renderable HOC components and complete static data. For live behavior, return React code with a ref and do not promise MCP-rendered output.
|
|
372
|
+
- **Axis formatters are React callbacks** (`serialization.formatters-are-react-callbacks`): xFormat, yFormat, categoryFormat, and valueFormat are callback props, not d3 format strings or axis-title strings. They are intentionally absent from JSON/MCP schemas and string values fail validation.
|
|
373
|
+
Agent action: In serialized props, omit formatter callbacks and use xLabel, yLabel, categoryLabel, or valueLabel for axis titles. In React JSX, pass a function such as xFormat={value => formatAxis(value)}.
|
|
374
|
+
Example: `JSON: { "xLabel": "Payload (KB)", "yLabel": "Response time (ms)" }. React-only: xFormat={value => formatNumber(value, { maximumFractionDigits: 0 })}.`
|
|
375
|
+
- **Value components do not inherit chart-HOC props** (`value.bignumber-wire-contract`): BigNumber is a value component, not a chart HOC, so it does not inherit the common chart-HOC prop list. It uses label as its visible heading and supports description and summary; title and accessibleTable are invalid. Its percent format expects a ratio such as 0.97 and renders it as 97%.
|
|
376
|
+
Agent action: Validate BigNumber against its own prop schema and remove inherited chart-HOC props such as title and accessibleTable before returning a proposal. Use label, description, and summary for text. For a 97-of-100 KPI, either pass value={0.97} with format="percent" or pass value={97} with format="number" and suffix="%"; do not combine value={97} with format="percent".
|
|
377
|
+
Example: `{ "component": "BigNumber", "props": { "value": 97, "label": "SLA attainment", "format": "number", "suffix": "%", "target": { "value": 99, "label": "target", "format": "number" } } }`
|
|
378
|
+
- **Proportional symbol maps use geographic props** (`geo.proportional-symbol-wire-shape`): ProportionalSymbolMap reads point rows from points, longitude from xAccessor (default lon), latitude from yAccessor (default lat), and radius from sizeBy. sizeRange is the two-number pixel-radius range.
|
|
379
|
+
Agent action: Use points, xAccessor, yAccessor, and sizeBy. Do not rename points to data or sizeBy to valueAccessor merely because the map renders circles.
|
|
380
|
+
Example: `{ "points": [{"city":"A","longitude":-122.4,"latitude":37.8,"incidents":18}], "xAccessor":"longitude", "yAccessor":"latitude", "sizeBy":"incidents", "sizeRange":[5,40] }`
|
|
381
|
+
- **Physics charts separate chart mode from simulation input** (`physics.sample-and-mechanical-inputs`): Sample simulations use data plus the chart's accessors. Seeded no-data demonstrations use simulationMode="mechanical" (legacy mode="mechanical" remains accepted); mode otherwise carries chart display modes such as primary or sparkline.
|
|
382
|
+
Agent action: For observed Galton values pass data + valueAccessor. For unit piles pass data + categoryAccessor + valueAccessor. Use seed for reproducibility, bins for Galton columns, and unitValue for the amount represented by one UnitPile body.
|
|
383
|
+
Example: `{ "component": "GaltonBoardChart", "props": { "data": [{"id":"a","value":1}], "valueAccessor":"value", "bins":4, "seed":42 } }`
|
|
384
|
+
- **Physics push methods ingest source records** (`physics.push-uses-source-records`): Physics HOC refs push source records through the chart's accessors. pushRows and dataIdAccessor are not component props; stable source id fields are retained on spawned bodies without an invented accessor.
|
|
385
|
+
Agent action: For React live code, call ref.current?.push(row) or pushMany(rows). For serialized snapshots, append the rows to data. Keep category/value/time accessors, but omit pushRows and dataIdAccessor.
|
|
386
|
+
Example: `ref.current?.push({ id: "c", team: "Blue", value: 2 }); <UnitPileChart ref={ref} categoryAccessor="team" valueAccessor="value" unitValue={1} />`
|
|
361
387
|
|
|
362
388
|
<!-- semiotic-behavior-contracts:end -->
|
|
363
389
|
|
|
@@ -380,7 +406,7 @@ These rules are generated from `ai/behaviorContracts.cjs` and are consumed by `s
|
|
|
380
406
|
- **Tooltip datum shape**: HOC tooltips get raw data. Frame `tooltipContent` gets wrapped — use `d.data`.
|
|
381
407
|
- **Tooltip format cascade**: `valueFormat`/`xFormat`/`yFormat` flow to default tooltip (axis + tooltip read identically). Custom `tooltip` fully overrides — re-pass via `Tooltip({format})` / `MultiLineTooltip({fields:[{format}]})`. Bespoke-tooltip charts (Histogram, FunnelChart, LikertChart, GaugeChart) don't participate; customize via `tooltip`.
|
|
382
408
|
- **`tooltip="multi"`**: shows all series at hovered X for LineChart, AreaChart, StackedAreaChart. Custom fn receives `datum.allSeries`.
|
|
383
|
-
- **Legend**: "bottom" expands margin ~80px. MultiAxisLineChart: use `legendPosition="bottom"`.
|
|
409
|
+
- **Legend**: "bottom" expands margin ~80px. MultiAxisLineChart: use `legendPosition="bottom"`. A **bottom** legend is placed *outside* the bottom axis chrome (tick labels, axis title) so it doesn't overdraw it; the band is auto-measured. Top axes are opt-in, so a **top** legend reserves nothing by default — set `frameProps.legendLayout.axisGutter` for one. `axisGutter` also overrides the measured bottom band (`0` anchors to the plot edge); `sideGutter` is the left/right counterpart.
|
|
384
410
|
- **Horizontal bars**: need wider left margin (`margin={{ left: 120 }}`).
|
|
385
411
|
- **Log scale**: domain min clamped to 1e-6. **`xScaleType: "time"`**: creates `scaleTime`; required for landmark ticks with timestamps.
|
|
386
412
|
- **`barPadding`**: pixel value (40/60 default). Reduce for small charts.
|
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
[](https://mcptoplist.com/server/io.github.nteract%2Fsemiotic)
|
|
2
|
+
|
|
1
3
|
[](https://semiotic.nteract.io)
|
|
2
4
|
|
|
3
5
|
[](https://github.com/nteract/semiotic/actions/workflows/node.js.yml)
|
|
4
6
|
[](https://www.npmjs.com/package/semiotic)
|
|
5
7
|
[](https://www.typescriptlang.org/)
|
|
6
|
-
[](https://glama.ai/mcp/servers/nteract/semiotic)
|
|
7
8
|
[](https://mseep.ai/app/nteract-semiotic)
|
|
8
9
|
|
|
9
10
|
A React data visualization library designed for AI-assisted development.
|
|
@@ -16,21 +17,22 @@ AI coding assistants generate correct chart code on the first try.
|
|
|
16
17
|
<img src="./docs/public/assets/img/semiotic-release-dashboard.svg" alt="Semiotic release dashboard showing chart count, bundle sizes, capability coverage, chart families, and documentation growth" width="100%">
|
|
17
18
|
<!-- semiotic-readme-dashboard:end -->
|
|
18
19
|
|
|
19
|
-
## What's New in 3.8.
|
|
20
|
+
## What's New in 3.8.7
|
|
20
21
|
|
|
21
|
-
3.8.
|
|
22
|
-
|
|
22
|
+
3.8.7 hardens the physics, server-rendering, and agent-evaluation paths exercised after the 3.8.6
|
|
23
|
+
release:
|
|
23
24
|
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
- Physics reduced-motion settling now admits paced spawns and completes time-driven event tapes;
|
|
26
|
+
runtime preference changes no longer accumulate a giant animation delta. Chain-reaction tiles
|
|
27
|
+
and lane labels no longer overlap, and physics chrome follows the active theme.
|
|
28
|
+
- BigNumber now has native static render evidence, exact source facts flow through reader
|
|
29
|
+
grounding, and agent guidance keeps value-component props separate from chart-HOC props.
|
|
30
|
+
- Static SVG preserves chart-level primitive styling and heatmap cell borders, while
|
|
31
|
+
horizontal legends clear axis ticks and titles consistently in browser and server renders.
|
|
32
|
+
- Physics charts participate in shared linked hover, while the clearer `UnitPileChart` and
|
|
33
|
+
`PacketFlowChart` names ship with permanent aliases for their previous names.
|
|
34
|
+
- The public model-evaluation reading room preserves the complete baseline and three targeted
|
|
35
|
+
follow-up trials, including the unresolved Luna gauge result rather than smoothing it away.
|
|
34
36
|
|
|
35
37
|
```jsx
|
|
36
38
|
import { LineChart } from "semiotic/xy"
|
|
@@ -70,6 +72,19 @@ warnings with typo suggestions, and accessibility features (canvas
|
|
|
70
72
|
`<title>`/`<desc>`) so AI-generated code fails gracefully with
|
|
71
73
|
actionable diagnostics instead of a blank screen.
|
|
72
74
|
|
|
75
|
+
### Accessibility is a release surface
|
|
76
|
+
|
|
77
|
+
The [European Accessibility Act](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=legissum%3A4403933)
|
|
78
|
+
has applied to covered products and services since 28 June 2025. A chart
|
|
79
|
+
library cannot certify an application's legal compliance: scope, content,
|
|
80
|
+
surrounding controls, testing, and national enforcement remain the
|
|
81
|
+
application owner's responsibility. Semiotic supplies testable infrastructure
|
|
82
|
+
for that work: keyboard interaction, accessible data tables, layered
|
|
83
|
+
descriptions, structured navigation, reduced-motion and forced-colors paths,
|
|
84
|
+
and WCAG-derived contrast tests for shipped theme presets. See the
|
|
85
|
+
[Accessibility docs](https://semiotic.nteract.io/accessibility/overview) and
|
|
86
|
+
run the application's own assistive-technology and user testing.
|
|
87
|
+
|
|
73
88
|
### Beyond standard charts
|
|
74
89
|
|
|
75
90
|
**Network visualization.** Force-directed graphs, Sankey diagrams, chord
|
|
@@ -83,7 +98,7 @@ semantics. Built-in decay, pulse, and staleness encoding for monitoring dashboar
|
|
|
83
98
|
|
|
84
99
|
**Coordinated views.** `LinkedCharts` provides hover cross-highlighting,
|
|
85
100
|
brush cross-filtering, coordinate-based linked crosshairs, and selection
|
|
86
|
-
synchronization across any combination of chart types
|
|
101
|
+
synchronization across any combination of chart types through shared selection state.
|
|
87
102
|
|
|
88
103
|
**Geographic visualization.** Choropleth maps, proportional symbol maps, flow
|
|
89
104
|
maps with animated particles, and distance cartograms — all canvas-rendered
|
|
@@ -100,11 +115,11 @@ paths. Opt into placement, hierarchy, density, progressive disclosure,
|
|
|
100
115
|
audience-aware amount, provenance, and editorial lifecycle when the chart
|
|
101
116
|
needs to communicate more than its encoding alone.
|
|
102
117
|
|
|
103
|
-
###
|
|
118
|
+
### Choose the API layer
|
|
104
119
|
|
|
105
120
|
| Layer | For | Example |
|
|
106
121
|
|---|---|---|
|
|
107
|
-
| **Charts** | Common
|
|
122
|
+
| **Charts** | Common chart forms with chart-level props | `<LineChart data={d} xAccessor="x" yAccessor="y" />` |
|
|
108
123
|
| **Frames** | Full control over rendering, interaction, and layout | `<StreamXYFrame chartType="line" lineStyle={...} />` |
|
|
109
124
|
|
|
110
125
|
Every Chart component accepts a `frameProps` prop to access the underlying
|
|
@@ -181,7 +196,7 @@ Requires React 18.1+ or React 19.
|
|
|
181
196
|
|
|
182
197
|
### Coordinated Dashboard
|
|
183
198
|
|
|
184
|
-
Hover one chart
|
|
199
|
+
Hover one chart and highlight the same data in another through a shared selection:
|
|
185
200
|
|
|
186
201
|
```jsx
|
|
187
202
|
import { LinkedCharts, Scatterplot, BarChart } from "semiotic"
|
|
@@ -287,7 +302,7 @@ chartRef.current.push({ source: "API", target: "Orders", value: 15 })
|
|
|
287
302
|
|
|
288
303
|
### Standard Charts
|
|
289
304
|
|
|
290
|
-
Line, bar, scatter, area
|
|
305
|
+
Line, bar, scatter, and area charts share the same accessor-driven API:
|
|
291
306
|
|
|
292
307
|
```jsx
|
|
293
308
|
import { LineChart, BarChart } from "semiotic"
|
|
@@ -379,35 +394,35 @@ The numbers below are **first-party artifact cost**: the gzip size of Semiotic's
|
|
|
379
394
|
|
|
380
395
|
| Entry Point | gzip | What's inside |
|
|
381
396
|
|---|---|---|
|
|
382
|
-
| `semiotic/xy` | **
|
|
383
|
-
| `semiotic/ordinal` | **
|
|
384
|
-
| `semiotic/network` | **
|
|
385
|
-
| `semiotic/geo` | **
|
|
386
|
-
| `semiotic/realtime` | **
|
|
387
|
-
| `semiotic/realtime/core` | **
|
|
397
|
+
| `semiotic/xy` | **145 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
|
|
398
|
+
| `semiotic/ordinal` | **120 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
|
|
399
|
+
| `semiotic/network` | **126 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
|
|
400
|
+
| `semiotic/geo` | **103 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
|
|
401
|
+
| `semiotic/realtime` | **153 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
|
|
402
|
+
| `semiotic/realtime/core` | **144 KB** | Streaming chart types, HOCs, and buffer helpers |
|
|
388
403
|
| `semiotic/realtime/react` | **1 KB** | Stream status and synced push hooks |
|
|
389
|
-
| `semiotic/server` | **
|
|
390
|
-
| `semiotic/server/node` | **
|
|
391
|
-
| `semiotic/server/edge` | **
|
|
404
|
+
| `semiotic/server` | **210 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
|
|
405
|
+
| `semiotic/server/node` | **210 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
|
|
406
|
+
| `semiotic/server/edge` | **224 KB** | renderChart, renderChartWithEvidence, renderToStaticSVG, renderDashboard |
|
|
392
407
|
| `semiotic/utils` | **83 KB** | ThemeProvider, numeric/accessibility audits, serialization — no chart components |
|
|
393
|
-
| `semiotic/utils/core` | **
|
|
408
|
+
| `semiotic/utils/core` | **82 KB** | Pure theme helpers, numeric/accessibility audits, and serialization |
|
|
394
409
|
| `semiotic/utils/react` | **6 KB** | ThemeProvider, useTheme, useReducedMotion, useHighContrast, useStreamStatus |
|
|
395
|
-
| `semiotic/recipes` | **
|
|
396
|
-
| `semiotic/recipes/core` | **
|
|
410
|
+
| `semiotic/recipes` | **88 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
|
|
411
|
+
| `semiotic/recipes/core` | **87 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
|
|
397
412
|
| `semiotic/recipes/react` | **2 KB** | Glyph and React layout-selection helpers |
|
|
398
413
|
| `semiotic/themes` | **7 KB** | Theme presets only (tufte, carbon, etc.) |
|
|
399
414
|
| `semiotic/themes/core` | **7 KB** | Theme presets and token helpers |
|
|
400
415
|
| `semiotic/themes/react` | **6 KB** | ThemeProvider/useTheme and hooks |
|
|
401
416
|
| `semiotic/data` | **4 KB** | bin, rollup, groupBy, pivot, fromVegaLite |
|
|
402
417
|
| `semiotic/value` | **8 KB** | BigNumber — focal-value KPI / scorecard (SingleValueFrame POC) |
|
|
403
|
-
| `semiotic/physics` | **
|
|
418
|
+
| `semiotic/physics` | **160 KB** | GaltonBoardChart, EventDropChart, UnitPileChart, CollisionSwarmChart, PacketFlowChart, PhysicsCustomChart |
|
|
404
419
|
| `semiotic/physics/matter` | **1 KB** | Matter.js migration helpers + optional peer guard (no chart components) |
|
|
405
420
|
| `semiotic/physics/rapier` | **1 KB** | Rapier peer guard + adapter decision metadata (no chart components) |
|
|
406
|
-
| `semiotic/ai` | **
|
|
407
|
-
| `semiotic/ai/core` | **
|
|
421
|
+
| `semiotic/ai` | **486 KB** | All schema-backed charts + validation — optimized for LLM code generation |
|
|
422
|
+
| `semiotic/ai/core` | **80 KB** | suggestCharts, auditData, describeChart, repairChartConfig, tool adapters — no chart components |
|
|
408
423
|
| `semiotic/controls` | **12 KB** | DirectManipulationControl, CircularBrush, MobileStandardControls, auditVisualizationControls — no frame renderer |
|
|
409
424
|
| `semiotic/rough` | **4 KB** | Optional deterministic Rough.js paint backend — exact Semiotic geometry remains authoritative |
|
|
410
|
-
| `semiotic` | **
|
|
425
|
+
| `semiotic` | **389 KB** | Everything below (full bundle) |
|
|
411
426
|
|
|
412
427
|
<!-- semiotic-bundle-sizes:end -->
|
|
413
428
|
|
|
@@ -428,29 +443,29 @@ Method: fresh `npm pack --ignore-scripts` tarball → temporary consumer → min
|
|
|
428
443
|
|
|
429
444
|
| Public named import | Runtime | gzip cold-consumer bundle |
|
|
430
445
|
|---|---:|---:|
|
|
431
|
-
| `import { LineChart } from "semiotic"` | browser | **
|
|
432
|
-
| `import { LineChart } from "semiotic/xy"` | browser | **
|
|
433
|
-
| `import { BarChart } from "semiotic/ordinal"` | browser | **
|
|
434
|
-
| `import { SankeyDiagram } from "semiotic/network"` | browser | **
|
|
435
|
-
| `import { RealtimeLineChart } from "semiotic/realtime"` | browser | **122.
|
|
436
|
-
| `import { RingBuffer } from "semiotic/realtime/core"` | browser | **170.
|
|
446
|
+
| `import { LineChart } from "semiotic"` | browser | **153.1 KiB** |
|
|
447
|
+
| `import { LineChart } from "semiotic/xy"` | browser | **153.3 KiB** |
|
|
448
|
+
| `import { BarChart } from "semiotic/ordinal"` | browser | **123.5 KiB** |
|
|
449
|
+
| `import { SankeyDiagram } from "semiotic/network"` | browser | **128.1 KiB** |
|
|
450
|
+
| `import { RealtimeLineChart } from "semiotic/realtime"` | browser | **122.8 KiB** |
|
|
451
|
+
| `import { RingBuffer } from "semiotic/realtime/core"` | browser | **170.6 KiB** |
|
|
437
452
|
| `import { useStreamStatus } from "semiotic/realtime/react"` | browser | **0.6 KiB** |
|
|
438
|
-
| `import { GaltonBoardChart } from "semiotic/physics"` | browser | **
|
|
453
|
+
| `import { GaltonBoardChart } from "semiotic/physics"` | browser | **134.2 KiB** |
|
|
439
454
|
| `import { MATTER_PHYSICS_CAPABILITIES } from "semiotic/physics/matter"` | browser | **0.2 KiB** |
|
|
440
455
|
| `import { RAPIER_PHYSICS_CAPABILITIES } from "semiotic/physics/rapier"` | browser | **0.2 KiB** |
|
|
441
|
-
| `import { renderChart } from "semiotic/server"` | node | **
|
|
442
|
-
| `import { generateFrameSVGs } from "semiotic/server/edge"` | node | **
|
|
443
|
-
| `import { renderToImage } from "semiotic/server/node"` | node | **
|
|
444
|
-
| `import { suggestCharts } from "semiotic/ai"` | browser | **
|
|
445
|
-
| `import { suggestCharts } from "semiotic/ai/core"` | browser | **
|
|
456
|
+
| `import { renderChart } from "semiotic/server"` | node | **269.8 KiB** |
|
|
457
|
+
| `import { generateFrameSVGs } from "semiotic/server/edge"` | node | **164.5 KiB** |
|
|
458
|
+
| `import { renderToImage } from "semiotic/server/node"` | node | **270.2 KiB** |
|
|
459
|
+
| `import { suggestCharts } from "semiotic/ai"` | browser | **193.1 KiB** |
|
|
460
|
+
| `import { suggestCharts } from "semiotic/ai/core"` | browser | **36.3 KiB** |
|
|
446
461
|
| `import { bin } from "semiotic/data"` | browser | **0.4 KiB** |
|
|
447
|
-
| `import { ChoroplethMap } from "semiotic/geo"` | browser | **108.
|
|
462
|
+
| `import { ChoroplethMap } from "semiotic/geo"` | browser | **108.5 KiB** |
|
|
448
463
|
| `import { createRoughRenderMode } from "semiotic/rough"` | browser | **3.4 KiB** |
|
|
449
464
|
| `import { resolveThemePreset } from "semiotic/themes"` | browser | **3.4 KiB** |
|
|
450
465
|
| `import { resolveThemePreset } from "semiotic/themes/core"` | browser | **3.4 KiB** |
|
|
451
466
|
| `import { ThemeProvider } from "semiotic/themes/react"` | browser | **4.4 KiB** |
|
|
452
|
-
| `import { validateProps } from "semiotic/utils"` | browser | **
|
|
453
|
-
| `import { smartTickFormat } from "semiotic/utils/core"` | browser | **0.
|
|
467
|
+
| `import { validateProps } from "semiotic/utils"` | browser | **8.2 KiB** |
|
|
468
|
+
| `import { smartTickFormat } from "semiotic/utils/core"` | browser | **0.7 KiB** |
|
|
454
469
|
| `import { useReducedMotion } from "semiotic/utils/react"` | browser | **0.3 KiB** |
|
|
455
470
|
| `import { waffleLayout } from "semiotic/recipes"` | browser | **2.5 KiB** |
|
|
456
471
|
| `import { waffleLayout } from "semiotic/recipes/core"` | browser | **2.5 KiB** |
|
|
@@ -490,15 +505,23 @@ interface Sale { month: number; revenue: number }
|
|
|
490
505
|
## Server-Side Rendering
|
|
491
506
|
|
|
492
507
|
All chart components render SVG automatically in server environments — no
|
|
493
|
-
special imports or configuration needed
|
|
508
|
+
special imports or configuration needed. Non-streaming chart HOCs can be
|
|
509
|
+
imported and rendered directly from a Next.js Server Component: Semiotic's
|
|
510
|
+
`"use client"` directive defines the package boundary, so the importing page
|
|
511
|
+
does not need its own wrapper or directive. Props crossing that boundary must
|
|
512
|
+
remain serializable; add an app-owned client wrapper only when you introduce
|
|
513
|
+
hooks, callback props, browser state, or a push-driven streaming chart.
|
|
494
514
|
|
|
495
515
|
```jsx
|
|
496
|
-
//
|
|
497
|
-
import { LineChart } from "semiotic"
|
|
516
|
+
// app/dashboard/page.tsx — a Next.js Server Component
|
|
517
|
+
import { LineChart } from "semiotic/xy"
|
|
498
518
|
|
|
499
519
|
// Server: renders <svg> with path/circle/rect elements
|
|
500
520
|
// Client: renders <canvas> with SVG overlay for axes
|
|
501
|
-
|
|
521
|
+
export default async function DashboardPage() {
|
|
522
|
+
const data = await fetchMetrics()
|
|
523
|
+
return <LineChart data={data} xAccessor="date" yAccessor="value" />
|
|
524
|
+
}
|
|
502
525
|
```
|
|
503
526
|
|
|
504
527
|
For standalone SVG/PNG/GIF generation (email, OG images, PDF, Slack), use the server entry point:
|
|
@@ -693,7 +716,11 @@ Semiotic is indexed by AI-coding-agent documentation tools so your assistant (Cl
|
|
|
693
716
|
- **DeepWiki** — [deepwiki.com/nteract/semiotic](https://deepwiki.com/nteract/semiotic)
|
|
694
717
|
- **GitMCP** — [gitmcp.io/nteract/semiotic](https://gitmcp.io/nteract/semiotic) (exposes the repo as an MCP endpoint directly)
|
|
695
718
|
- **Official MCP Registry** — search "semiotic" at [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io)
|
|
696
|
-
|
|
719
|
+
|
|
720
|
+
The Official MCP Registry is the canonical MCP directory record; it is distinct
|
|
721
|
+
from acceptance into any assistant vendor's curated connector directory.
|
|
722
|
+
Secondary-directory freshness and release ownership are tracked in
|
|
723
|
+
[MCP_DISTRIBUTION.md](https://github.com/nteract/semiotic/blob/main/MCP_DISTRIBUTION.md).
|
|
697
724
|
|
|
698
725
|
Agent-facing API surface:
|
|
699
726
|
|
package/ai/behaviorContracts.cjs
CHANGED
|
@@ -102,7 +102,7 @@ const REQUIRED_COMBINATIONS = [
|
|
|
102
102
|
required: ["value"],
|
|
103
103
|
staticRequired: ["value"],
|
|
104
104
|
pushRequired: [],
|
|
105
|
-
summary: "GaugeChart is value-only. thresholds,
|
|
105
|
+
summary: "GaugeChart is value-only. Its thresholds use { value, color, label? }; BigNumber thresholds use the distinct { at, level, color?, label? } vocabulary.",
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
component: "ForceDirectedGraph",
|
|
@@ -142,6 +142,15 @@ const PUSH_MODE_COMPONENTS = [
|
|
|
142
142
|
"ChordDiagram",
|
|
143
143
|
"ProportionalSymbolMap",
|
|
144
144
|
"DistanceCartogram",
|
|
145
|
+
"GaltonBoardChart",
|
|
146
|
+
"EventDropChart",
|
|
147
|
+
"UnitPileChart",
|
|
148
|
+
"CollisionSwarmChart",
|
|
149
|
+
"PacketFlowChart",
|
|
150
|
+
"ProcessFlowChart",
|
|
151
|
+
"GauntletChart",
|
|
152
|
+
"CrucibleChart",
|
|
153
|
+
"ChainReactionChart",
|
|
145
154
|
]
|
|
146
155
|
|
|
147
156
|
const STATIC_DATA_COMPONENTS = loadStaticDataComponentsFromSchema()
|
|
@@ -201,6 +210,18 @@ const BEHAVIOR_CONTRACTS = [
|
|
|
201
210
|
summary: "HOC push mode is selected by omitting the data prop entirely. Passing data={[]} is static empty data and can clear/reinitialize the frame on render.",
|
|
202
211
|
agentAction: "For live charts, create a ref, omit data, then call ref.current.push() or pushMany(). For static renderChart/MCP snapshots, provide data because renderChart cannot push later.",
|
|
203
212
|
},
|
|
213
|
+
{
|
|
214
|
+
id: "streaming.serialized-proposal-snapshot",
|
|
215
|
+
category: "streaming",
|
|
216
|
+
title: "Serialized proposals keep the initial snapshot",
|
|
217
|
+
severity: "warning",
|
|
218
|
+
appliesTo: {
|
|
219
|
+
components: PUSH_MODE_COMPONENTS,
|
|
220
|
+
},
|
|
221
|
+
summary: "A JSON component/props proposal for MCP, SSR, or evaluation is a static snapshot even when the request mentions future pushes. Keep the supplied initial rows in the component's real data prop and do not invent pushRows, pushRequirement, ref, or method props.",
|
|
222
|
+
agentAction: "Return renderable initial props in JSON. If the requested deliverable is React push code, separately omit the controlled data prop in JSX, attach a ref, and call the documented imperative method from an effect or event handler.",
|
|
223
|
+
example: 'JSON snapshot: { "component": "LineChart", "props": { "data": [{"week":1,"users":120}], "xAccessor":"week", "yAccessor":"users" } }. React push code instead omits data and calls ref.current?.push(row).',
|
|
224
|
+
},
|
|
204
225
|
{
|
|
205
226
|
id: "streaming.ref-mutations-require-id-accessors",
|
|
206
227
|
category: "streaming",
|
|
@@ -221,6 +242,66 @@ const BEHAVIOR_CONTRACTS = [
|
|
|
221
242
|
summary: "MCP renderChart and semiotic/server renderChart render a single static SVG/PNG snapshot. Browser-only realtime components and future ref pushes are not renderable through that path.",
|
|
222
243
|
agentAction: "Use renderChart only with renderable HOC components and complete static data. For live behavior, return React code with a ref and do not promise MCP-rendered output.",
|
|
223
244
|
},
|
|
245
|
+
{
|
|
246
|
+
id: "serialization.formatters-are-react-callbacks",
|
|
247
|
+
category: "serialization",
|
|
248
|
+
title: "Axis formatters are React callbacks",
|
|
249
|
+
severity: "error",
|
|
250
|
+
appliesTo: {
|
|
251
|
+
propsAny: ["xFormat", "yFormat", "categoryFormat", "valueFormat"],
|
|
252
|
+
},
|
|
253
|
+
summary: "xFormat, yFormat, categoryFormat, and valueFormat are callback props, not d3 format strings or axis-title strings. They are intentionally absent from JSON/MCP schemas and string values fail validation.",
|
|
254
|
+
agentAction: "In serialized props, omit formatter callbacks and use xLabel, yLabel, categoryLabel, or valueLabel for axis titles. In React JSX, pass a function such as xFormat={value => formatAxis(value)}.",
|
|
255
|
+
example: 'JSON: { "xLabel": "Payload (KB)", "yLabel": "Response time (ms)" }. React-only: xFormat={value => formatNumber(value, { maximumFractionDigits: 0 })}.',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: "value.bignumber-wire-contract",
|
|
259
|
+
category: "value",
|
|
260
|
+
title: "Value components do not inherit chart-HOC props",
|
|
261
|
+
severity: "error",
|
|
262
|
+
appliesTo: {
|
|
263
|
+
components: ["BigNumber"],
|
|
264
|
+
},
|
|
265
|
+
summary: "BigNumber is a value component, not a chart HOC, so it does not inherit the common chart-HOC prop list. It uses label as its visible heading and supports description and summary; title and accessibleTable are invalid. Its percent format expects a ratio such as 0.97 and renders it as 97%.",
|
|
266
|
+
agentAction: "Validate BigNumber against its own prop schema and remove inherited chart-HOC props such as title and accessibleTable before returning a proposal. Use label, description, and summary for text. For a 97-of-100 KPI, either pass value={0.97} with format=\"percent\" or pass value={97} with format=\"number\" and suffix=\"%\"; do not combine value={97} with format=\"percent\".",
|
|
267
|
+
example: '{ "component": "BigNumber", "props": { "value": 97, "label": "SLA attainment", "format": "number", "suffix": "%", "target": { "value": 99, "label": "target", "format": "number" } } }',
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
id: "geo.proportional-symbol-wire-shape",
|
|
271
|
+
category: "geo",
|
|
272
|
+
title: "Proportional symbol maps use geographic props",
|
|
273
|
+
severity: "error",
|
|
274
|
+
appliesTo: {
|
|
275
|
+
components: ["ProportionalSymbolMap"],
|
|
276
|
+
},
|
|
277
|
+
summary: "ProportionalSymbolMap reads point rows from points, longitude from xAccessor (default lon), latitude from yAccessor (default lat), and radius from sizeBy. sizeRange is the two-number pixel-radius range.",
|
|
278
|
+
agentAction: "Use points, xAccessor, yAccessor, and sizeBy. Do not rename points to data or sizeBy to valueAccessor merely because the map renders circles.",
|
|
279
|
+
example: '{ "points": [{"city":"A","longitude":-122.4,"latitude":37.8,"incidents":18}], "xAccessor":"longitude", "yAccessor":"latitude", "sizeBy":"incidents", "sizeRange":[5,40] }',
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: "physics.sample-and-mechanical-inputs",
|
|
283
|
+
category: "physics",
|
|
284
|
+
title: "Physics charts separate chart mode from simulation input",
|
|
285
|
+
severity: "warning",
|
|
286
|
+
appliesTo: {
|
|
287
|
+
components: ["GaltonBoardChart", "UnitPileChart", "CollisionSwarmChart"],
|
|
288
|
+
},
|
|
289
|
+
summary: "Sample simulations use data plus the chart's accessors. Seeded no-data demonstrations use simulationMode=\"mechanical\" (legacy mode=\"mechanical\" remains accepted); mode otherwise carries chart display modes such as primary or sparkline.",
|
|
290
|
+
agentAction: "For observed Galton values pass data + valueAccessor. For unit piles pass data + categoryAccessor + valueAccessor. Use seed for reproducibility, bins for Galton columns, and unitValue for the amount represented by one UnitPile body.",
|
|
291
|
+
example: '{ "component": "GaltonBoardChart", "props": { "data": [{"id":"a","value":1}], "valueAccessor":"value", "bins":4, "seed":42 } }',
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: "physics.push-uses-source-records",
|
|
295
|
+
category: "physics",
|
|
296
|
+
title: "Physics push methods ingest source records",
|
|
297
|
+
severity: "error",
|
|
298
|
+
appliesTo: {
|
|
299
|
+
components: ["GaltonBoardChart", "EventDropChart", "UnitPileChart", "CollisionSwarmChart"],
|
|
300
|
+
},
|
|
301
|
+
summary: "Physics HOC refs push source records through the chart's accessors. pushRows and dataIdAccessor are not component props; stable source id fields are retained on spawned bodies without an invented accessor.",
|
|
302
|
+
agentAction: "For React live code, call ref.current?.push(row) or pushMany(rows). For serialized snapshots, append the rows to data. Keep category/value/time accessors, but omit pushRows and dataIdAccessor.",
|
|
303
|
+
example: 'ref.current?.push({ id: "c", team: "Blue", value: 2 }); <UnitPileChart ref={ref} categoryAccessor="team" valueAccessor="value" unitValue={1} />',
|
|
304
|
+
},
|
|
224
305
|
]
|
|
225
306
|
|
|
226
307
|
function hasOwn(value, key) {
|
|
@@ -284,6 +365,7 @@ function formatDoctorBehaviorContracts(contracts) {
|
|
|
284
365
|
lines.push(` ${formatRequiredCombination(combo)}`)
|
|
285
366
|
}
|
|
286
367
|
}
|
|
368
|
+
if (contract.example) lines.push(` Example: ${contract.example}`)
|
|
287
369
|
lines.push(` Action: ${contract.agentAction}`)
|
|
288
370
|
}
|
|
289
371
|
return lines.join("\n")
|
|
@@ -308,6 +390,9 @@ function formatBehaviorContractsMarkdown({ compact = false } = {}) {
|
|
|
308
390
|
const combos = contract.combinations.map(formatRequiredCombination).join(" ")
|
|
309
391
|
lines.push(` Required combinations: ${combos}`)
|
|
310
392
|
}
|
|
393
|
+
if (!compact && contract.example) {
|
|
394
|
+
lines.push(` Example: \`${contract.example}\``)
|
|
395
|
+
}
|
|
311
396
|
}
|
|
312
397
|
|
|
313
398
|
lines.push("", DOC_MARKER_END)
|
package/ai/componentMetadata.cjs
CHANGED
|
@@ -25,8 +25,9 @@ const COMPONENTS_BY_CATEGORY = {
|
|
|
25
25
|
"RealtimeWaterfallChart", "RealtimeHeatmap",
|
|
26
26
|
],
|
|
27
27
|
physics: [
|
|
28
|
-
"GaltonBoardChart", "EventDropChart", "
|
|
29
|
-
"
|
|
28
|
+
"GaltonBoardChart", "EventDropChart", "UnitPileChart", "CollisionSwarmChart",
|
|
29
|
+
"PacketFlowChart", "ProcessFlowChart", "GauntletChart", "CrucibleChart",
|
|
30
|
+
"ChainReactionChart",
|
|
30
31
|
],
|
|
31
32
|
value: [
|
|
32
33
|
"BigNumber",
|
|
@@ -67,17 +68,11 @@ function metadataForComponent(entryOrName) {
|
|
|
67
68
|
// any other static HOC. Matches the name-prefix exclusion the
|
|
68
69
|
// check-surface-parity script applies.
|
|
69
70
|
const isPushOnly = category === "realtime" && name.startsWith("Realtime")
|
|
70
|
-
// Value-family charts (BigNumber, future SingleValueFrame HOCs)
|
|
71
|
-
// render via react-dom/server in a normal React tree, but they do
|
|
72
|
-
// not route through the frame-driven `renderChart` path in
|
|
73
|
-
// serverChartConfigs.ts — so they are not MCP-renderable. Mirrors
|
|
74
|
-
// the `hoc-ssr-only` special feature documented in chartSpecs.ts.
|
|
75
|
-
const isValueCategory = category === "value"
|
|
76
71
|
return {
|
|
77
72
|
name,
|
|
78
73
|
category,
|
|
79
74
|
importPath: importPathForCategory(category),
|
|
80
|
-
renderable: !isPushOnly
|
|
75
|
+
renderable: !isPushOnly,
|
|
81
76
|
description: typeof entryOrName === "string" ? undefined : entryOrName.description,
|
|
82
77
|
}
|
|
83
78
|
}
|