semiotic 3.7.5 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/CLAUDE.md +54 -12
  2. package/README.md +121 -27
  3. package/agent-skill/semiotic-charts/SKILL.md +146 -0
  4. package/ai/cli.js +133 -45
  5. package/ai/componentMetadata.cjs +6 -1
  6. package/ai/dist/mcp-server.js +1651 -154
  7. package/ai/examples.md +174 -0
  8. package/ai/schema.json +2733 -536
  9. package/ai/surface-manifest.json +200 -0
  10. package/ai/system-prompt.md +18 -3
  11. package/dist/components/CategoryColors.d.ts +1 -1
  12. package/dist/components/ChartContainer.d.ts +91 -0
  13. package/dist/components/ChartGrid.d.ts +11 -1
  14. package/dist/components/CircularBrush.d.ts +61 -0
  15. package/dist/components/ContextLayout.d.ts +5 -1
  16. package/dist/components/DirectManipulationControl.d.ts +63 -0
  17. package/dist/components/LinkedCharts.d.ts +3 -1
  18. package/dist/components/MobileAnnotationCalloutList.d.ts +13 -0
  19. package/dist/components/MobileChartContainer.d.ts +51 -0
  20. package/dist/components/MobileStandardControls.d.ts +68 -0
  21. package/dist/components/SmallMultipleChart.d.ts +84 -0
  22. package/dist/components/Tooltip/FlippingTooltip.d.ts +21 -0
  23. package/dist/components/ai/ChartRecipe.d.ts +16 -0
  24. package/dist/components/ai/IntentMark.d.ts +15 -0
  25. package/dist/components/ai/chartCapabilities.d.ts +8 -1
  26. package/dist/components/ai/chartCapabilityTypes.d.ts +26 -1
  27. package/dist/components/ai/chartClinic.d.ts +91 -0
  28. package/dist/components/ai/chartRecipeRegistry.d.ts +14 -0
  29. package/dist/components/ai/chartRecipes.d.ts +278 -0
  30. package/dist/components/ai/dataPitfallsBridge.d.ts +102 -0
  31. package/dist/components/ai/describeChart.d.ts +7 -0
  32. package/dist/components/ai/describeRecipeChart.d.ts +16 -0
  33. package/dist/components/ai/generativeChart.d.ts +28 -3
  34. package/dist/components/ai/intentManifest.d.ts +62 -0
  35. package/dist/components/ai/navigationTree.d.ts +3 -0
  36. package/dist/components/ai/observedSceneAudit.d.ts +72 -0
  37. package/dist/components/ai/readerGrounding.d.ts +83 -0
  38. package/dist/components/ai/recipeCapability.d.ts +8 -0
  39. package/dist/components/ai/recipeNavigation.d.ts +13 -0
  40. package/dist/components/ai/recipeSemantics.d.ts +11 -0
  41. package/dist/components/ai/repairChartConfig.d.ts +9 -0
  42. package/dist/components/ai/suggestCharts.d.ts +11 -1
  43. package/dist/components/charts/custom/GeoCustomChart.d.ts +48 -0
  44. package/dist/components/charts/custom/NetworkCustomChart.d.ts +8 -2
  45. package/dist/components/charts/custom/OrdinalCustomChart.d.ts +8 -2
  46. package/dist/components/charts/custom/XYCustomChart.d.ts +11 -2
  47. package/dist/components/charts/geo/DistanceCartogram.d.ts +1 -1
  48. package/dist/components/charts/geo/FlowMap.d.ts +1 -1
  49. package/dist/components/charts/geo/ProportionalSymbolMap.d.ts +1 -1
  50. package/dist/components/charts/geo/index.d.ts +2 -0
  51. package/dist/components/charts/index.d.ts +29 -1
  52. package/dist/components/charts/network/ChordDiagram.d.ts +1 -1
  53. package/dist/components/charts/network/CirclePack.d.ts +1 -1
  54. package/dist/components/charts/network/ForceDirectedGraph.d.ts +15 -5
  55. package/dist/components/charts/network/OrbitDiagram.d.ts +1 -1
  56. package/dist/components/charts/network/ProcessSankey.d.ts +1 -1
  57. package/dist/components/charts/network/SankeyDiagram.d.ts +1 -1
  58. package/dist/components/charts/network/TreeDiagram.d.ts +1 -1
  59. package/dist/components/charts/network/Treemap.d.ts +1 -1
  60. package/dist/components/charts/network/useForceLayout.d.ts +17 -0
  61. package/dist/components/charts/ordinal/BarChart.d.ts +1 -1
  62. package/dist/components/charts/ordinal/BoxPlot.d.ts +1 -1
  63. package/dist/components/charts/ordinal/DonutChart.d.ts +1 -1
  64. package/dist/components/charts/ordinal/DotPlot.d.ts +1 -1
  65. package/dist/components/charts/ordinal/FunnelChart.d.ts +1 -1
  66. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +1 -1
  67. package/dist/components/charts/ordinal/Histogram.d.ts +1 -1
  68. package/dist/components/charts/ordinal/PieChart.d.ts +1 -1
  69. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +1 -1
  70. package/dist/components/charts/ordinal/StackedBarChart.d.ts +1 -1
  71. package/dist/components/charts/ordinal/SwarmPlot.d.ts +1 -1
  72. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +1 -1
  73. package/dist/components/charts/ordinal/ViolinPlot.d.ts +1 -1
  74. package/dist/components/charts/physics/ChainReactionChart.d.ts +9 -0
  75. package/dist/components/charts/physics/CollisionSwarmChart.capability.d.ts +2 -0
  76. package/dist/components/charts/physics/CollisionSwarmChart.d.ts +47 -0
  77. package/dist/components/charts/physics/EventDropChart.capability.d.ts +2 -0
  78. package/dist/components/charts/physics/EventDropChart.d.ts +53 -0
  79. package/dist/components/charts/physics/GaltonBoardChart.capability.d.ts +2 -0
  80. package/dist/components/charts/physics/GaltonBoardChart.d.ts +66 -0
  81. package/dist/components/charts/physics/GauntletChart.capability.d.ts +2 -0
  82. package/dist/components/charts/physics/GauntletChart.d.ts +73 -0
  83. package/dist/components/charts/physics/PhysicalFlowChart.capability.d.ts +2 -0
  84. package/dist/components/charts/physics/PhysicalFlowChart.d.ts +63 -0
  85. package/dist/components/charts/physics/PhysicsCustomChart.d.ts +120 -0
  86. package/dist/components/charts/physics/PhysicsPileChart.capability.d.ts +2 -0
  87. package/dist/components/charts/physics/PhysicsPileChart.d.ts +53 -0
  88. package/dist/components/charts/physics/ProcessFlowChart.capability.d.ts +2 -0
  89. package/dist/components/charts/physics/ProcessFlowChart.d.ts +96 -0
  90. package/dist/components/charts/physics/chainReactionOverlay.d.ts +22 -0
  91. package/dist/components/charts/physics/chainReactionRuntime.d.ts +37 -0
  92. package/dist/components/charts/physics/chainReactionTypes.d.ts +97 -0
  93. package/dist/components/charts/physics/collisionSwarmPhysics.d.ts +27 -0
  94. package/dist/components/charts/physics/dependencyMachine.d.ts +188 -0
  95. package/dist/components/charts/physics/eventDropPhysics.d.ts +64 -0
  96. package/dist/components/charts/physics/galtonBoardPhysics.d.ts +28 -0
  97. package/dist/components/charts/physics/gauntletChartProps.d.ts +67 -0
  98. package/dist/components/charts/physics/gauntletChrome.d.ts +33 -0
  99. package/dist/components/charts/physics/gauntletController.d.ts +73 -0
  100. package/dist/components/charts/physics/gauntletEffects.d.ts +36 -0
  101. package/dist/components/charts/physics/gauntletPhysics.d.ts +71 -0
  102. package/dist/components/charts/physics/gauntletRuntime.d.ts +42 -0
  103. package/dist/components/charts/physics/gauntletTypes.d.ts +213 -0
  104. package/dist/components/charts/physics/physicalFlowPhysics.d.ts +57 -0
  105. package/dist/components/charts/physics/physicsChartShared.d.ts +41 -0
  106. package/dist/components/charts/physics/physicsChartUtils.d.ts +18 -0
  107. package/dist/components/charts/physics/physicsEncoding.d.ts +142 -0
  108. package/dist/components/charts/physics/physicsHocHandle.d.ts +53 -0
  109. package/dist/components/charts/physics/physicsHocUtils.d.ts +128 -0
  110. package/dist/components/charts/physics/physicsPilePhysics.d.ts +41 -0
  111. package/dist/components/charts/physics/physicsProcessPrimitives.d.ts +38 -0
  112. package/dist/components/charts/physics/processFlowPhysics.d.ts +97 -0
  113. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +9 -1
  114. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +9 -1
  115. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +9 -1
  116. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +16 -2
  117. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +9 -1
  118. package/dist/components/charts/shared/auditMobileVisualization.d.ts +91 -0
  119. package/dist/components/charts/shared/chartDefinitionPilot.d.ts +145 -0
  120. package/dist/components/charts/shared/chartFamilySets.d.ts +20 -0
  121. package/dist/components/charts/shared/chartSpecCore.d.ts +165 -0
  122. package/dist/components/charts/shared/chartSpecs.d.ts +8 -127
  123. package/dist/components/charts/shared/chartSpecsGeo.d.ts +2 -0
  124. package/dist/components/charts/shared/chartSpecsNetwork.d.ts +2 -0
  125. package/dist/components/charts/shared/chartSpecsOrdinal.d.ts +2 -0
  126. package/dist/components/charts/shared/chartSpecsPhysics.d.ts +2 -0
  127. package/dist/components/charts/shared/chartSpecsRealtime.d.ts +2 -0
  128. package/dist/components/charts/shared/chartSpecsValue.d.ts +2 -0
  129. package/dist/components/charts/shared/chartSpecsXY.d.ts +2 -0
  130. package/dist/components/charts/shared/colorContrast.d.ts +3 -0
  131. package/dist/components/charts/shared/colorUtils.d.ts +16 -1
  132. package/dist/components/charts/shared/diagnoseAnnotationChecks.d.ts +4 -0
  133. package/dist/components/charts/shared/diagnoseConfig.d.ts +9 -14
  134. package/dist/components/charts/shared/diagnoseMisleadingChecks.d.ts +9 -0
  135. package/dist/components/charts/shared/diagnosePhysicsChecks.d.ts +3 -0
  136. package/dist/components/charts/shared/diagnoseTypes.d.ts +10 -0
  137. package/dist/components/charts/shared/hooks.d.ts +28 -5
  138. package/dist/components/charts/shared/motionEncoding.d.ts +145 -0
  139. package/dist/components/charts/shared/responsiveRules.d.ts +56 -0
  140. package/dist/components/charts/shared/streamPropsHelpers.d.ts +12 -2
  141. package/dist/components/charts/shared/temporalStrings.d.ts +7 -0
  142. package/dist/components/charts/shared/types.d.ts +49 -1
  143. package/dist/components/charts/shared/useChartSetup.d.ts +9 -2
  144. package/dist/components/charts/shared/useCustomChartSetup.d.ts +14 -5
  145. package/dist/components/charts/shared/useNetworkChartSetup.d.ts +6 -2
  146. package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +1 -1
  147. package/dist/components/charts/shared/useStreamingLegend.d.ts +1 -1
  148. package/dist/components/charts/shared/useSyncedPushData.d.ts +49 -0
  149. package/dist/components/charts/shared/validationMap.d.ts +0 -11
  150. package/dist/components/charts/xy/AreaChart.d.ts +1 -1
  151. package/dist/components/charts/xy/BubbleChart.d.ts +1 -1
  152. package/dist/components/charts/xy/LineChart.d.ts +1 -1
  153. package/dist/components/charts/xy/MinimapChart.d.ts +1 -1
  154. package/dist/components/charts/xy/MultiAxisLineChart.d.ts +2 -2
  155. package/dist/components/charts/xy/QuadrantChart.d.ts +1 -1
  156. package/dist/components/charts/xy/Scatterplot.d.ts +1 -1
  157. package/dist/components/charts/xy/ScatterplotMatrix.d.ts +11 -1
  158. package/dist/components/charts/xy/StackedAreaChart.d.ts +9 -4
  159. package/dist/components/controls/controlAudit.d.ts +24 -0
  160. package/dist/components/controls/controlContract.d.ts +57 -0
  161. package/dist/components/data/fromFlintChart.d.ts +74 -0
  162. package/dist/components/data/fromVegaLite.d.ts +27 -0
  163. package/dist/components/data/portability/index.d.ts +6 -3
  164. package/dist/components/data/portability/result.d.ts +52 -0
  165. package/dist/components/data/portability/spec.d.ts +31 -0
  166. package/dist/components/data/portability/vegaLite.d.ts +24 -6
  167. package/dist/components/export/chartConfig.d.ts +11 -0
  168. package/dist/components/realtime/types.d.ts +11 -0
  169. package/dist/components/recipes/annotationLayout.d.ts +29 -0
  170. package/dist/components/recipes/axisFixedForce.d.ts +119 -0
  171. package/dist/components/recipes/{gofishBoba.d.ts → boba.d.ts} +2 -2
  172. package/dist/components/recipes/cyclical.d.ts +39 -0
  173. package/dist/components/recipes/edgeRouter.d.ts +103 -0
  174. package/dist/components/recipes/forceLayout.d.ts +48 -0
  175. package/dist/components/recipes/forceLayoutAsync.d.ts +17 -0
  176. package/dist/components/recipes/gofishBobaHandwritten.d.ts +3 -0
  177. package/dist/components/recipes/gofishDisplayListFixtures.generated.d.ts +37 -0
  178. package/dist/components/recipes/gofishIR.d.ts +178 -132
  179. package/dist/components/recipes/gofishIRExamples.d.ts +30 -81
  180. package/dist/components/recipes/intervalLanes.d.ts +87 -0
  181. package/dist/components/recipes/intervals.d.ts +80 -0
  182. package/dist/components/recipes/isometricLandmarks.d.ts +88 -0
  183. package/dist/components/recipes/isotypeGlyphs.d.ts +17 -0
  184. package/dist/components/recipes/mobileAnnotationStrategy.d.ts +48 -0
  185. package/dist/components/recipes/mobileChartFamilyRecipes.d.ts +59 -0
  186. package/dist/components/recipes/networkAnalysis.d.ts +102 -0
  187. package/dist/components/recipes/networkLayouts.d.ts +83 -0
  188. package/dist/components/recipes/physics.d.ts +122 -0
  189. package/dist/components/recipes/physicsReference.d.ts +102 -0
  190. package/dist/components/recipes/processAggregates.d.ts +32 -0
  191. package/dist/components/recipes/processChrome.d.ts +67 -0
  192. package/dist/components/recipes/processJourney.d.ts +54 -0
  193. package/dist/components/recipes/processPhysics.d.ts +300 -0
  194. package/dist/components/recipes/processVolumeGeometry.d.ts +28 -0
  195. package/dist/components/recipes/radialCoords.d.ts +69 -0
  196. package/dist/components/recipes/random.d.ts +2 -0
  197. package/dist/components/recipes/recipeChrome.d.ts +91 -0
  198. package/dist/components/recipes/recipeGlyph.d.ts +42 -0
  199. package/dist/components/recipes/recipeLegend.d.ts +53 -1
  200. package/dist/components/recipes/recipeUtils.d.ts +52 -0
  201. package/dist/components/recipes/runs.d.ts +59 -0
  202. package/dist/components/recipes/tokenEncoding.d.ts +157 -0
  203. package/dist/components/recipes/tokenLayer.d.ts +79 -0
  204. package/dist/components/recipes/unitize.d.ts +108 -0
  205. package/dist/components/recipes/vector.d.ts +28 -0
  206. package/dist/components/recipes/waffle.d.ts +43 -0
  207. package/dist/components/semiotic-ai-core.d.ts +47 -0
  208. package/dist/components/semiotic-ai.d.ts +50 -8
  209. package/dist/components/semiotic-controls.d.ts +18 -0
  210. package/dist/components/semiotic-experimental.d.ts +38 -9
  211. package/dist/components/semiotic-geo.d.ts +11 -0
  212. package/dist/components/semiotic-network.d.ts +11 -0
  213. package/dist/components/semiotic-ordinal.d.ts +8 -0
  214. package/dist/components/semiotic-physics-matter.d.ts +10 -0
  215. package/dist/components/semiotic-physics-rapier.d.ts +9 -0
  216. package/dist/components/semiotic-physics.d.ts +56 -0
  217. package/dist/components/semiotic-realtime-core.d.ts +34 -0
  218. package/dist/components/semiotic-realtime-react.d.ts +10 -0
  219. package/dist/components/semiotic-realtime.d.ts +4 -30
  220. package/dist/components/semiotic-recipes-core.d.ts +92 -0
  221. package/dist/components/semiotic-recipes-react.d.ts +7 -0
  222. package/dist/components/semiotic-recipes.d.ts +4 -43
  223. package/dist/components/semiotic-server-edge.d.ts +8 -0
  224. package/dist/components/semiotic-server-node.d.ts +5 -0
  225. package/dist/components/semiotic-server.d.ts +2 -2
  226. package/dist/components/semiotic-themes-core.d.ts +53 -0
  227. package/dist/components/semiotic-themes-react.d.ts +4 -0
  228. package/dist/components/semiotic-themes.d.ts +6 -76
  229. package/dist/components/semiotic-utils-core.d.ts +46 -0
  230. package/dist/components/semiotic-utils-react.d.ts +5 -0
  231. package/dist/components/semiotic-utils.d.ts +3 -39
  232. package/dist/components/semiotic-xy.d.ts +8 -0
  233. package/dist/components/semiotic.d.ts +35 -7
  234. package/dist/components/server/animatedGif.d.ts +36 -0
  235. package/dist/components/server/renderEvidence.d.ts +1 -1
  236. package/dist/components/server/renderToStaticSVG.d.ts +3 -35
  237. package/dist/components/server/serverChartConfigShared.d.ts +17 -0
  238. package/dist/components/server/serverChartConfigs.d.ts +19 -9
  239. package/dist/components/server/serverChartConfigsCustom.d.ts +5 -0
  240. package/dist/components/server/serverChartConfigsGeo.d.ts +9 -0
  241. package/dist/components/server/serverChartConfigsNetwork.d.ts +8 -0
  242. package/dist/components/server/serverChartConfigsOrdinal.d.ts +16 -0
  243. package/dist/components/server/serverChartConfigsPhysics.d.ts +9 -0
  244. package/dist/components/server/serverChartConfigsXY.d.ts +11 -0
  245. package/dist/components/server/staticGeo.d.ts +4 -0
  246. package/dist/components/server/staticLegend.d.ts +1 -1
  247. package/dist/components/server/staticNetwork.d.ts +8 -0
  248. package/dist/components/server/staticOrdinal.d.ts +11 -0
  249. package/dist/components/server/staticPhysics.d.ts +3 -0
  250. package/dist/components/server/staticSVGChrome.d.ts +110 -0
  251. package/dist/components/server/staticXY.d.ts +4 -0
  252. package/dist/components/store/ObservationStore.d.ts +3 -2
  253. package/dist/components/store/themeSerialization.d.ts +32 -0
  254. package/dist/components/store/useChartInterrogation.d.ts +9 -0
  255. package/dist/components/stream/AccessibleDataTable.d.ts +3 -13
  256. package/dist/components/stream/FocusRing.d.ts +4 -2
  257. package/dist/components/stream/GeoCanvasHitTester.d.ts +1 -1
  258. package/dist/components/stream/GeoPipelineStore.d.ts +28 -0
  259. package/dist/components/stream/NetworkPipelineStore.d.ts +31 -26
  260. package/dist/components/stream/NetworkSVGOverlay.d.ts +4 -1
  261. package/dist/components/stream/OrdinalPipelineStore.d.ts +46 -2
  262. package/dist/components/stream/PipelineStore.d.ts +81 -170
  263. package/dist/components/stream/SceneGraph.d.ts +9 -1
  264. package/dist/components/stream/StreamGeoFrame.d.ts +1 -1
  265. package/dist/components/stream/StreamNetworkFrame.d.ts +1 -1
  266. package/dist/components/stream/StreamOrdinalFrame.d.ts +1 -1
  267. package/dist/components/stream/StreamXYFrame.d.ts +2 -18
  268. package/dist/components/stream/accessibleDataRows.d.ts +33 -0
  269. package/dist/components/stream/accessorUtils.d.ts +23 -10
  270. package/dist/components/stream/brushAccessibility.d.ts +25 -0
  271. package/dist/components/stream/canvasBackground.d.ts +24 -0
  272. package/dist/components/stream/canvasSetup.d.ts +4 -1
  273. package/dist/components/stream/customLayoutFailure.d.ts +33 -0
  274. package/dist/components/stream/customLayoutPalette.d.ts +19 -9
  275. package/dist/components/stream/frameThemeColors.d.ts +24 -0
  276. package/dist/components/stream/geoAnnotationAnchors.d.ts +14 -0
  277. package/dist/components/stream/geoCartogram.d.ts +17 -0
  278. package/dist/components/stream/geoCustomLayout.d.ts +59 -0
  279. package/dist/components/stream/geoDefaultTooltip.d.ts +11 -0
  280. package/dist/components/stream/geoFrameHelpers.d.ts +34 -0
  281. package/dist/components/stream/geoPipelineHelpers.d.ts +46 -0
  282. package/dist/components/stream/geoTypes.d.ts +56 -7
  283. package/dist/components/stream/glyphDef.d.ts +98 -0
  284. package/dist/components/stream/hitTarget.d.ts +170 -0
  285. package/dist/components/stream/hoverUtils.d.ts +3 -0
  286. package/dist/components/stream/keyboardNav.d.ts +4 -1
  287. package/dist/components/stream/layouts/forceLayoutPlugin.d.ts +9 -1
  288. package/dist/components/stream/layouts/forceLayoutWorkerClient.d.ts +57 -0
  289. package/dist/components/stream/networkBezier.d.ts +10 -0
  290. package/dist/components/stream/networkColorAccessors.d.ts +49 -0
  291. package/dist/components/stream/networkDefaultTooltip.d.ts +10 -0
  292. package/dist/components/stream/networkFrameInteraction.d.ts +37 -0
  293. package/dist/components/stream/networkFramePaint.d.ts +43 -0
  294. package/dist/components/stream/networkPipelineConfig.d.ts +22 -0
  295. package/dist/components/stream/networkPipelineHelpers.d.ts +12 -0
  296. package/dist/components/stream/networkRealtimeEncoding.d.ts +41 -0
  297. package/dist/components/stream/networkTypes.d.ts +76 -5
  298. package/dist/components/stream/ordinalCanvasRenderers.d.ts +7 -0
  299. package/dist/components/stream/ordinalDataIndex.d.ts +5 -0
  300. package/dist/components/stream/ordinalDefaultTooltip.d.ts +10 -0
  301. package/dist/components/stream/ordinalDomain.d.ts +38 -0
  302. package/dist/components/stream/ordinalPipelineUpdateResults.d.ts +12 -0
  303. package/dist/components/stream/ordinalPulse.d.ts +10 -0
  304. package/dist/components/stream/ordinalPulseResources.d.ts +3 -0
  305. package/dist/components/stream/ordinalSceneBuilders/sceneBuilderMap.d.ts +5 -0
  306. package/dist/components/stream/ordinalSpatialIndex.d.ts +9 -0
  307. package/dist/components/stream/ordinalTypes.d.ts +40 -8
  308. package/dist/components/stream/paintNeeds.d.ts +31 -0
  309. package/dist/components/stream/physics/CapacityQueueController.d.ts +5 -0
  310. package/dist/components/stream/physics/CapacityQueueTypes.d.ts +134 -0
  311. package/dist/components/stream/physics/MatterPhysicsEngineAdapter.d.ts +42 -0
  312. package/dist/components/stream/physics/PhysicsAccessibility.d.ts +48 -0
  313. package/dist/components/stream/physics/PhysicsAnnotations.d.ts +58 -0
  314. package/dist/components/stream/physics/PhysicsBodyBudget.d.ts +26 -0
  315. package/dist/components/stream/physics/PhysicsBodySpatialIndex.d.ts +10 -0
  316. package/dist/components/stream/physics/PhysicsCanvasTheme.d.ts +26 -0
  317. package/dist/components/stream/physics/PhysicsControllers.d.ts +75 -0
  318. package/dist/components/stream/physics/PhysicsEngineAdapter.d.ts +59 -0
  319. package/dist/components/stream/physics/PhysicsEngineConformance.d.ts +23 -0
  320. package/dist/components/stream/physics/PhysicsEvidence.d.ts +25 -0
  321. package/dist/components/stream/physics/PhysicsKernel.d.ts +207 -0
  322. package/dist/components/stream/physics/PhysicsOptionalEngineAdapters.d.ts +12 -0
  323. package/dist/components/stream/physics/PhysicsPipelineStore.d.ts +84 -0
  324. package/dist/components/stream/physics/PhysicsPipelineTypes.d.ts +181 -0
  325. package/dist/components/stream/physics/PhysicsSVGOverlay.d.ts +72 -0
  326. package/dist/components/stream/physics/PhysicsSediment.d.ts +69 -0
  327. package/dist/components/stream/physics/PhysicsSettledSVG.d.ts +18 -0
  328. package/dist/components/stream/physics/PhysicsSettledScene.d.ts +21 -0
  329. package/dist/components/stream/physics/PhysicsWorkerClient.d.ts +24 -0
  330. package/dist/components/stream/physics/PhysicsWorkerProtocol.d.ts +101 -0
  331. package/dist/components/stream/physics/PhysicsWorkerRuntime.d.ts +5 -0
  332. package/dist/components/stream/physics/RapierPhysicsEngineAdapter.d.ts +18 -0
  333. package/dist/components/stream/physics/ServiceOperationsControllers.d.ts +27 -0
  334. package/dist/components/stream/physics/ServiceOperationsTypes.d.ts +89 -0
  335. package/dist/components/stream/physics/StreamPhysicsFrame.d.ts +6 -0
  336. package/dist/components/stream/physics/StreamPhysicsTypes.d.ts +302 -0
  337. package/dist/components/stream/physics/physicsBodyCanvas.d.ts +27 -0
  338. package/dist/components/stream/physics/physicsPipelineControls.d.ts +4 -0
  339. package/dist/components/stream/physics/physicsPipelineHelpers.d.ts +41 -0
  340. package/dist/components/stream/physics/physicsPipelineObservations.d.ts +14 -0
  341. package/dist/components/stream/physics/physicsPipelineUpdateResults.d.ts +9 -0
  342. package/dist/components/stream/physics/physicsRegionRuntime.d.ts +54 -0
  343. package/dist/components/stream/physics/physicsSemanticUI.d.ts +20 -0
  344. package/dist/components/stream/physics/usePhysicsFrameLifecyclePolicy.d.ts +16 -0
  345. package/dist/components/stream/pipelineBufferUtils.d.ts +26 -0
  346. package/dist/components/stream/pipelineConfig.d.ts +177 -0
  347. package/dist/components/stream/pipelineDecay.d.ts +20 -2
  348. package/dist/components/stream/pipelineDomainResolution.d.ts +62 -0
  349. package/dist/components/stream/pipelineIdentityOps.d.ts +26 -0
  350. package/dist/components/stream/pipelinePulse.d.ts +16 -2
  351. package/dist/components/stream/pipelineRibbons.d.ts +41 -0
  352. package/dist/components/stream/pipelineSpatialIndex.d.ts +12 -0
  353. package/dist/components/stream/pipelineStoreUpdateResults.d.ts +12 -0
  354. package/dist/components/stream/pipelineStyleResolvers.d.ts +46 -0
  355. package/dist/components/stream/pipelineTransitions.d.ts +2 -0
  356. package/dist/components/stream/pipelineUpdateContract.d.ts +62 -0
  357. package/dist/components/stream/pulseFrameRefresh.d.ts +22 -0
  358. package/dist/components/stream/renderers/glyphCanvasRenderer.d.ts +6 -0
  359. package/dist/components/stream/renderers/resolveCSSColor.d.ts +6 -0
  360. package/dist/components/stream/sceneRevisionDiagnostics.d.ts +18 -0
  361. package/dist/components/stream/streamStoreSync.d.ts +37 -0
  362. package/dist/components/stream/types.d.ts +135 -7
  363. package/dist/components/stream/useFrame.d.ts +21 -2
  364. package/dist/components/stream/useHydration.d.ts +6 -0
  365. package/dist/components/stream/useLegendCategoryEmission.d.ts +5 -0
  366. package/dist/components/stream/workerModuleUrl.d.ts +10 -0
  367. package/dist/components/stream/xyAnnotationAnchors.d.ts +13 -0
  368. package/dist/components/stream/xyCanvasRenderers.d.ts +7 -0
  369. package/dist/components/stream/xyCrosshair.d.ts +11 -0
  370. package/dist/components/stream/xyDateTicks.d.ts +9 -0
  371. package/dist/components/stream/xyDefaultTooltip.d.ts +10 -0
  372. package/dist/components/stream/xySceneBuilders/types.d.ts +4 -4
  373. package/dist/controls.min.js +2 -0
  374. package/dist/controls.module.min.js +2 -0
  375. package/dist/forceLayoutWorker.js +1 -0
  376. package/dist/geo.min.js +1 -1
  377. package/dist/geo.module.min.js +1 -1
  378. package/dist/network.min.js +1 -1
  379. package/dist/network.module.min.js +1 -1
  380. package/dist/ordinal.min.js +1 -1
  381. package/dist/ordinal.module.min.js +1 -1
  382. package/dist/physics-matter.min.js +1 -0
  383. package/dist/physics-matter.module.min.js +1 -0
  384. package/dist/physics-rapier.min.js +1 -0
  385. package/dist/physics-rapier.module.min.js +1 -0
  386. package/dist/physics.min.js +2 -0
  387. package/dist/physics.module.min.js +2 -0
  388. package/dist/physicsWorker.js +1 -0
  389. package/dist/realtime.min.js +1 -1
  390. package/dist/realtime.module.min.js +1 -1
  391. package/dist/semiotic-ai-chunk-OG7BQUUW.module.min.js +2 -0
  392. package/dist/semiotic-ai-core.d.ts +47 -0
  393. package/dist/semiotic-ai-core.min.js +1 -0
  394. package/dist/semiotic-ai-core.module.min.js +1 -0
  395. package/dist/semiotic-ai-statisticalOverlays-CY4WKR4A.module.min.js +2 -0
  396. package/dist/semiotic-ai.d.ts +50 -8
  397. package/dist/semiotic-ai.min.js +1 -1
  398. package/dist/semiotic-ai.module.min.js +1 -1
  399. package/dist/semiotic-chunk-3FSVZ46U.module.min.js +2 -0
  400. package/dist/semiotic-controls.d.ts +18 -0
  401. package/dist/semiotic-data.min.js +1 -1
  402. package/dist/semiotic-data.module.min.js +1 -1
  403. package/dist/semiotic-experimental.d.ts +38 -9
  404. package/dist/semiotic-experimental.min.js +1 -1
  405. package/dist/semiotic-experimental.module.min.js +1 -1
  406. package/dist/semiotic-geo.d.ts +11 -0
  407. package/dist/semiotic-network.d.ts +11 -0
  408. package/dist/semiotic-ordinal.d.ts +8 -0
  409. package/dist/semiotic-physics-matter.d.ts +10 -0
  410. package/dist/semiotic-physics-rapier.d.ts +9 -0
  411. package/dist/semiotic-physics.d.ts +56 -0
  412. package/dist/semiotic-realtime-core.d.ts +34 -0
  413. package/dist/semiotic-realtime-core.min.js +1 -0
  414. package/dist/semiotic-realtime-core.module.min.js +1 -0
  415. package/dist/semiotic-realtime-react.d.ts +10 -0
  416. package/dist/semiotic-realtime-react.min.js +2 -0
  417. package/dist/semiotic-realtime-react.module.min.js +2 -0
  418. package/dist/semiotic-realtime.d.ts +4 -30
  419. package/dist/semiotic-recipes-core.d.ts +92 -0
  420. package/dist/semiotic-recipes-core.min.js +1 -0
  421. package/dist/semiotic-recipes-core.module.min.js +1 -0
  422. package/dist/semiotic-recipes-react.d.ts +7 -0
  423. package/dist/semiotic-recipes-react.min.js +2 -0
  424. package/dist/semiotic-recipes-react.module.min.js +2 -0
  425. package/dist/semiotic-recipes.d.ts +4 -43
  426. package/dist/semiotic-recipes.min.js +1 -1
  427. package/dist/semiotic-recipes.module.min.js +1 -1
  428. package/dist/semiotic-server-edge.d.ts +8 -0
  429. package/dist/semiotic-server-edge.min.js +1 -0
  430. package/dist/semiotic-server-edge.module.min.js +1 -0
  431. package/dist/semiotic-server-node.d.ts +5 -0
  432. package/dist/semiotic-server-node.min.js +1 -0
  433. package/dist/semiotic-server-node.module.min.js +1 -0
  434. package/dist/semiotic-server.d.ts +2 -2
  435. package/dist/semiotic-statisticalOverlays-UOMSFKVJ.module.min.js +2 -0
  436. package/dist/semiotic-themes-core.d.ts +53 -0
  437. package/dist/semiotic-themes-core.min.js +1 -0
  438. package/dist/semiotic-themes-core.module.min.js +1 -0
  439. package/dist/semiotic-themes-react.d.ts +4 -0
  440. package/dist/semiotic-themes-react.min.js +2 -0
  441. package/dist/semiotic-themes-react.module.min.js +2 -0
  442. package/dist/semiotic-themes.d.ts +6 -76
  443. package/dist/semiotic-themes.min.js +1 -2
  444. package/dist/semiotic-themes.module.min.js +1 -2
  445. package/dist/semiotic-utils-core.d.ts +46 -0
  446. package/dist/semiotic-utils-core.min.js +1 -0
  447. package/dist/semiotic-utils-core.module.min.js +1 -0
  448. package/dist/semiotic-utils-react.d.ts +5 -0
  449. package/dist/semiotic-utils-react.min.js +2 -0
  450. package/dist/semiotic-utils-react.module.min.js +2 -0
  451. package/dist/semiotic-utils.d.ts +3 -39
  452. package/dist/semiotic-utils.min.js +1 -2
  453. package/dist/semiotic-utils.module.min.js +1 -2
  454. package/dist/semiotic-value.min.js +1 -1
  455. package/dist/semiotic-value.module.min.js +1 -1
  456. package/dist/semiotic-xy.d.ts +8 -0
  457. package/dist/semiotic.d.ts +35 -7
  458. package/dist/semiotic.min.js +1 -1
  459. package/dist/semiotic.module.min.js +1 -1
  460. package/dist/server.min.js +1 -1
  461. package/dist/server.module.min.js +1 -1
  462. package/dist/xy-chunk-IWD6IB6V.module.min.js +2 -0
  463. package/dist/xy-statisticalOverlays-7RWG6LJT.module.min.js +2 -0
  464. package/dist/xy.min.js +1 -1
  465. package/dist/xy.module.min.js +1 -1
  466. package/package.json +239 -87
  467. package/spec/README.md +152 -0
  468. package/spec/bindings/README.md +35 -0
  469. package/spec/bindings/vega-lite.mjs +112 -0
  470. package/spec/v0.1/annotation-provenance.schema.json +127 -0
  471. package/spec/v0.1/audience-profile.schema.json +67 -0
  472. package/spec/v0.1/chart-capability.schema.json +186 -0
  473. package/dist/components/recipes/gofish.d.ts +0 -207
  474. package/dist/components/recipes/gofishInterpreter.d.ts +0 -52
  475. package/dist/components/recipes/gofishLambdas.d.ts +0 -145
  476. package/dist/semiotic-ai-semiotic-ai-u954ylUn.js +0 -2
  477. package/dist/semiotic-ai-statisticalOverlays-CU7jW05Q.js +0 -1
  478. package/dist/semiotic-semiotic-BmrYbi99.js +0 -2
  479. package/dist/semiotic-statisticalOverlays-IjZw8Lsu.js +0 -1
  480. package/dist/xy-semiotic-xy-Dufu3D0-.js +0 -2
  481. package/dist/xy-statisticalOverlays-3Ni9bRph.js +0 -1
package/CLAUDE.md CHANGED
@@ -4,7 +4,7 @@
4
4
  - Install: `npm install semiotic`
5
5
  <!-- semiotic-bundle-sizes:start -->
6
6
  <!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
7
- - **Use sub-path imports** — `semiotic/xy` (96KB gz), `semiotic/ordinal` (78KB gz), `semiotic/network` (73KB gz), `semiotic/geo` (57KB gz), `semiotic/realtime` (104KB gz), `semiotic/server` (132KB gz), `semiotic/utils` (39KB gz), `semiotic/recipes` (19KB gz), `semiotic/themes` (6KB gz), `semiotic/data` (4KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (269KB gz). Full `semiotic` is 216KB gz.
7
+ - **Use sub-path imports** — `semiotic/xy` (101KB gz), `semiotic/ordinal` (82KB gz), `semiotic/network` (85KB gz), `semiotic/geo` (62KB gz), `semiotic/realtime` (111KB gz), `semiotic/realtime/core` (110KB gz), `semiotic/realtime/react` (1KB gz), `semiotic/server` (189KB gz), `semiotic/server/node` (189KB gz), `semiotic/server/edge` (188KB gz), `semiotic/utils` (71KB gz), `semiotic/utils/core` (70KB gz), `semiotic/utils/react` (4KB gz), `semiotic/recipes` (53KB gz), `semiotic/recipes/core` (52KB gz), `semiotic/recipes/react` (1KB gz), `semiotic/themes` (6KB gz), `semiotic/themes/core` (6KB gz), `semiotic/themes/react` (4KB gz), `semiotic/data` (3KB gz), `semiotic/value` (6KB gz), `semiotic/physics` (98KB gz), `semiotic/physics/matter` (1KB gz), `semiotic/physics/rapier` (1KB gz), `semiotic/ai` (394KB gz), `semiotic/ai/core` (79KB gz), `semiotic/controls` (5KB gz). Full `semiotic` is 258KB 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
 
@@ -56,7 +56,7 @@ All ordinal: `colorBy`, `colorScheme`, `categoryFormat` (string|ReactNode), `sho
56
56
 
57
57
  ## Network Charts (`semiotic/network`)
58
58
 
59
- **ForceDirectedGraph** — `nodes`, `edges`, `nodeIDAccessor`, `sourceAccessor`, `targetAccessor`, `colorBy`, `nodeSize`, `nodeSizeRange`, `edgeWidth`, `iterations` (300), `forceStrength` (0.1), `showLabels`, `nodeLabel`
59
+ **ForceDirectedGraph** — `nodes`, `edges`, `nodeIDAccessor`, `sourceAccessor`, `targetAccessor`, `colorBy`, `nodeSize`, `nodeSizeRange`, `edgeWidth`, `iterations` (300), `forceStrength` (0.1 — link-attraction multiplier), `layoutExecution` ("auto" default | "worker" | "sync" — auto runs big layouts in a Web Worker by estimated cost, sync fallback everywhere), `layoutLoadingContent` (ReactNode while worker layout pends; `false` suppresses), `onLayoutStateChange` (`"pending"|"ready"|"error"`), `showLabels`, `nodeLabel`
60
60
  **SankeyDiagram** — `edges`, `nodes`, `valueAccessor`, `nodeIdAccessor`, `colorBy`, `edgeColorBy`, `orientation`, `nodeAlign`, `nodeWidth`, `nodePaddingRatio`, `showLabels`
61
61
  **ProcessSankey** — temporal sankey with real time x-axis. `nodes`, `edges` (each with `startTime`/`endTime`), `domain` (req `[t0, t1]`), `axisTicks?`, `xExtentAccessor` (optional `[start, end]` lifetime per node), `colorBy`/`colorScheme`/`showLegend`/`legendPosition`, `pairing` ("value"|"temporal"), `packing` ("off"|"reuse"), `laneOrder` ("crossing-min"|"inside-out"|"crossing-min+inside-out"|"insertion"), `lifetimeMode` ("full"|"half"), `ribbonLane` ("source"|"target"|"both"), `showLaneRails`, `showLabels` (true), `showQualityReadout`, `showParticles` + `particleStyle`, `timeFormat`/`valueFormat`, push API via ref. Static-graph cycles OK as long as edges move forward in time. Use ProcessSankey for time-stamped events; SankeyDiagram for static snapshots.
62
62
  **ChordDiagram** — `edges`, `nodes`, `valueAccessor`, `edgeColorBy`, `padAngle`, `showLabels`
@@ -76,6 +76,22 @@ Import from `semiotic/geo` only — avoids d3-geo in non-geo bundles.
76
76
 
77
77
  All geo: `fitPadding`, `zoomable`, `zoomExtent`, `onZoom`, `dragRotate`, `graticule`, `tileURL`, `tileAttribution`. Helpers: `resolveReferenceGeography("world-110m"|"world-50m")`, `mergeData(features, data, {featureKey, dataKey})`.
78
78
 
79
+ ## Physics Charts (`semiotic/physics`)
80
+
81
+ Import from `semiotic/physics` only — not re-exported from the root `semiotic` entry (keeps the physics kernel out of default dashboards).
82
+
83
+ Process/arrival/distribution charts backed by `StreamPhysicsFrame`. The settled projection is the chart; motion is explanatory context. Use when the movement has data semantics, not as decoration.
84
+
85
+ **GaltonBoardChart** — `data`, `valueAccessor` ("value"), `bins` (21), `mode` ("sample"|"mechanical"), `pegRows`, `mechanicalCount`, `branchProbability`, `ballRadius`, `colorBy`, `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.
86
+ **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.
87
+ **PhysicsPileChart** — `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.
88
+ **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.
89
+ **PhysicalFlowChart** — `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.
90
+ **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.
91
+ **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`.
92
+ **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).
93
+ **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.
94
+
79
95
  ## Value Charts (`semiotic/value`)
80
96
 
81
97
  Single-focal-value displays — when one number is the answer, a chart is the wrong abstraction. Plain React (no Stream Frame); SSR-clean; ~7KB gz. **Ships no chart-family dependency** — embed your own Semiotic chart via two slots picked by aspect ratio.
@@ -100,7 +116,7 @@ Helpers exported: `buildFormatter`, `formatSignedDelta`, `formatDeltaPercent`, `
100
116
 
101
117
  Push API: `ref.current.push({time, value})`. All pushed data must include a time field.
102
118
 
103
- **RealtimeLineChart**, **RealtimeHistogram** (+ `brush`, `onBrush`, `linkedBrush`, `direction`), **TemporalHistogram** (static sibling — same props minus `windowSize`/`windowMode`), **RealtimeSwarmChart**, **RealtimeWaterfallChart**, **RealtimeHeatmap**, **Streaming Sankey** (StreamNetworkFrame + `showParticles`).
119
+ **RealtimeLineChart**, **RealtimeHistogram** (+ `brush`, `onBrush`, `linkedBrush`, `direction`; **stacked** via `categoryAccessor` + `colors` — bars sum by category within each bin; **mirrored/diverging** via `direction="down"` flipping the value domain — pair two halves with a shared `timeExtent`/`valueExtent` for an up/down detail view, and overlay extra instances on the same extent for layered envelopes), **TemporalHistogram** (static sibling — same props minus `windowSize`/`windowMode`), **RealtimeSwarmChart**, **RealtimeWaterfallChart**, **RealtimeHeatmap**, **Streaming Sankey** (StreamNetworkFrame + `showParticles`).
104
120
 
105
121
  Encoding: `decay`, `pulse`, `transition`, `staleness` — compose freely.
106
122
 
@@ -116,25 +132,44 @@ ref.current.update("p1", d => ({ ...d, y: 99 })) // requires ID accessor
116
132
  ref.current.clear()
117
133
  ref.current.getData()
118
134
  ref.current.getScales() // {o, r, projection} (ordinal) | {x, y} (XY) — null if unmounted
135
+ ref.current.getCustomLayout() // custom charts: the most recent layout(ctx) result (readback — don't re-run the layout host-side); null before first layout / on built-ins
119
136
  <Scatterplot ref={ref} xAccessor="x" yAccessor="y" pointIdAccessor="id" />
120
137
  ```
121
138
  ID accessor: `pointIdAccessor` (XY/realtime), `dataIdAccessor` (ordinal), `nodeIDAccessor`/`edgeIdAccessor` (network). `replace()` is ordinal-only — used by aggregator HOCs like LikertChart. Network HOC refs operate on nodes; for edges use `StreamNetworkFrameHandle` directly: `removeNode(id)`, `removeEdge(sourceId, targetId)` or `removeEdge(edgeId)`, `updateNode(id, updater)`, `updateEdge(sourceId, targetId, updater)`.
139
+ **Controlled→push bridge**: `useSyncedPushData(ref, rows, { id, resetKey })` (from `semiotic` / `semiotic/realtime`) reconciles a controlled React array into the push buffer — diffs by id, issues the minimal push/update/remove, and clears + rebuilds on `resetKey` change. Reach for it instead of hand-rolling the mirror when rows live in React state; pass rows to the hook, not `data`. Pairs with `useStreamStatus` (live/stale badge). Pure core `syncPushBuffer` is exported for testing.
122
140
  Not supported: Tree, Treemap, CirclePack, Orbit, ChoroplethMap, FlowMap, ScatterplotMatrix.
123
141
 
124
142
  ## Custom Charts (escape hatch)
125
143
 
126
- When the catalog doesn't fit, three HOCs take a layout function emitting scene primitives. Frame still owns hit testing, transitions, decay, theme, SSR.
144
+ When the catalog doesn't fit, four HOCs take a layout function emitting scene primitives. Frame still owns hit testing, transitions, decay, theme, SSR.
127
145
 
128
146
  - **`XYCustomChart`** (`semiotic/xy`) — waffle, calendar heatmap, custom point/line/area
129
147
  - **`OrdinalCustomChart`** (`semiotic/ordinal`) — marimekko, parallel coords, bullet, fan, slope
130
148
  - **`NetworkCustomChart`** (`semiotic/network`) — flextree, dagre, custom force/radial, packed-cluster beeswarm matrix
149
+ - **`GeoCustomChart`** (`semiotic/geo`) — isometric landmark boards, custom geographic tessellations
131
150
 
132
151
  Layout signature differs by family:
133
152
  - **XY/Ordinal**: `layout: (ctx) => { nodes, overlays? }`. `ctx`: `data`, `scales` ({x,y} XY | {o,r,projection} ordinal), `dimensions` (plot rect — center-anchored for radial ordinal, top-left otherwise), `theme`, `resolveColor(key)`, `config`.
134
- - **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays?, htmlMarks? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection` (shared-selection predicate `{ isActive, predicate(datum) }` from `LinkedCharts`, `null` when unwired — dim/highlight by it). Run external positioners (`d3-flextree`, `dagre`) then emit network scene primitives (circle/rect/arc/**symbol** nodes; line/bezier/curved edges). The `symbol` node is the per-datum **shape** channel — a `d3-shape` glyph (`circle`/`square`/`triangle`/`diamond`/`star`/`cross`/`wye`/`chevron`, or a custom `path`) sized by `size` (area), rendered on canvas + SVG/SSR and hit-tested + keyboard-navigated as a unit. **The `symbol` mark is cross-pipeline**: XY and ordinal custom layouts emit it too (`{type:"symbol", x, y, size, symbolType}` — note `x`/`y`, vs the network variant's `cx`/`cy`), and Scatterplot/SwarmPlot expose it as the `symbolBy` encoding. One shared `symbolPath` implementation backs canvas/SVG/hit-test across all three families.
153
+ - **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays?, htmlMarks? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection` (shared-selection predicate `{ isActive, predicate(datum) }` from `LinkedCharts`, `null` when unwired — dim/highlight by it). Run external positioners (`d3-flextree`, `dagre`) then emit network scene primitives (circle/rect/arc/**symbol**/**glyph** nodes; line/bezier/curved edges). The `symbol` node is the per-datum **shape** channel — a `d3-shape` glyph (`circle`/`square`/`triangle`/`diamond`/`star`/`cross`/`wye`/`chevron`, or a custom `path`) sized by `size` (area), rendered on canvas + SVG/SSR and hit-tested + keyboard-navigated as a unit. **The `symbol` mark is cross-pipeline**: XY and ordinal custom layouts emit it too (`{type:"symbol", x, y, size, symbolType}` — note `x`/`y`, vs the network variant's `cx`/`cy`), and Scatterplot/SwarmPlot expose it as the `symbolBy` encoding. One shared `symbolPath` implementation backs canvas/SVG/hit-test across all three families.
154
+ - **The `glyph` node — composite pictograms (ALL FOUR families incl. geo)**: where `symbol` is one path, `glyph` stamps a multi-part vector pictogram — a `GlyphDef` (`{viewBox?, anchor?, parts: [{d, fill?, stroke?, strokeWidth?, opacity?}]}`) whose parts declare **role paints** (`"color"`/`"accent"`/literal) resolved per node (`color`/`accent` props), so one definition recolors per category like a pictogram plate reused in many inks. `{type:"glyph", x, y, size, glyph, color?, accent?, fraction?, fractionStart?, fractionDirection?, ghostColor?, rotation?, style, datum, pointId?}` (network variant uses `cx`/`cy` + `id`/`label`). `size` = rendered **height** px (width follows viewBox aspect); `anchor: [0.5, 1]` stands a sign's feet on a baseline/terrain. **Partial fills**: `fraction`/`fractionStart` clip a `[start, end]` window (horizontal or bottom-up vertical) with an optional full-extent `ghostColor` silhouette — the ISOTYPE partial-symbol convention, fed directly by `unitize`. Full pipeline citizen: canvas + SVG/SSR, hit-test + keyboard nav over the drawn bounds, `pointId`/`id` annotation anchoring, and enter/move/exit transition identity (which `symbol` lacks). Datum-less glyph nodes (`datum: null`) paint but don't hit-test/navigate — use one `hitTarget` per logical mark under a multi-sign tally. `<Glyph def size color …/>` (from `semiotic/recipes`) renders the same definition as React SVG for overlays/legends/chrome; `glyphPlacement`/`glyphExtent` expose its geometry for layout math.
155
+ - **Geo**: `layout: (ctx) => { nodes?, overlays? }`. `ctx`: `areas`, `points`, `lines`, fitted `GeoScales`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection`. Emit `geoarea`/`point`/`line`/`glyph` nodes; use overlays for labels and sprites.
135
156
  - **`htmlMarks`** (network only): `NetworkHtmlMark[]` = `{ id, x, y, width, height, content: ReactNode }`, positioned in the **same plot space as `sceneNodes`** and rendered into one real-DOM layer the framework places **above the canvas and SVG `overlays`** (stack: canvas → `overlays` → `htmlMarks`). Reach for it over an SVG `<foreignObject>` when a mark is **text-heavy/rich and dims or animates on hover** — a real `<div>` composites `opacity`/`transform`/`visibility` changes instead of re-rasterizing text (the `foreignObject` stall on large graphs). Framework owns the margin (and future zoom/pan) transform so marks stay pixel-aligned; each mark is its own element, keyed by `id` (position-only re-runs reposition without remounting). `pointer-events: none` by default — keep a transparent hit-rect `sceneNode` per mark so canvas hit-testing/`onObservation` stays authoritative. Mark `content` can read `useCustomLayoutSelection()` to dim on shared selection without a relayout. Additive: omit it and no extra DOM renders. Class hooks: `.semiotic-network-html-marks` (layer) / `.semiotic-network-html-mark` (each).
136
157
 
137
- `semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `flextreeLayout`, `dagreLayout`, `lineageDagLayout`, `packedClusterMatrix`). BYO heavy deps (`d3-flextree`, `dagre`) in user code. `packedClusterMatrix` (network) bins records into a column×row matrix of **densely-packed beeswarm clusters** (deterministic self-contained packing, geometry cached) and emits **multi-channel glyphs** — hue (`colorAccessor`/`colorMap`), size (`sizeAccessor`, area), shade (`shadeAccessor`, CIELAB lightness), plus EITHER shape-encoding (`symbolAccessor`/`symbolMap` — the base mark becomes that shape) OR the **composite-glyph** model (`iconAccessor`/`iconMap` — base is a filled circle, only mapped values get a stroked inner icon). `rowMode:"banded"` (default) gives aligned global orbit-bands (row labels align, one enclosure spans the columns per band, columns vary in height) vs `"stacked"` (per-column cell heights ∝ count). `callouts:[{field,value,label}]` draws leader lines to named marks. `cellSizing:"proportional"` makes area ∝ count. **Recipe chrome kit** (exported from `semiotic/recipes`, for any custom-layout's `overlays`): `roundedEnclosure`/`boundsOf` (group/band borders), `bandLabel` (overflow-aware axis/band labels), `markCallout` (leader-line callout to a mark), `readField` (`node.data`-wrapper reader), `groupBy`, `dimFor` (the highlight/dim opacity rule — `{predicate?, highlight?, baseOpacity?, dimOpacity?, brighten?}`; `matchesHighlight` is its `{field,value}[]` matcher), `signatureKey`/`LayoutCache` (content-signature geometry cache so re-styling never re-runs an expensive layout key by *content*, never by `ctx.nodes` identity), `legendGroupsFrom` (`{colorMap|keys, symbolMap?, sizeStops?}` → `LegendGroup[]` for `frameProps.legend`), `shade`/`makeShade`, `symbolPathString`/`symbolRadius`/`symbolExtent`/`SYMBOL_SEQUENCE`. (`bandLabel`/`dimFor` are adopted by marimekko/bullet/parallelCoordinates/packedClusterMatrix.) `lineageDagLayout` renders a pre-positioned **layered lineage/DAG** (reads logical layer/row coords, no re-layout) with composite node glyphs (one hit-rect per node + icon/label/store-chip chrome in `overlays`), level-of-detail collapse (full→compact→icon→dot), distinct dashed back-edges, and host-driven reach-dimming (`layoutConfig.reachableIds`) + selection (`layoutConfig.selectedId` / shared `ctx.selection`).
158
+ **Custom-chart authoring kit** (`semiotic/recipes`; `hitTarget*` also from `semiotic/xy`/`ordinal`/`network`). The shape every hand-built custom chart converges ondraw real marks in `overlays`, emit a **transparent scene node per mark** for interaction is first-class:
159
+ - **`hitTargetPoint`/`hitTargetRect`** (XY/ordinal) + **`networkHitTarget`** (circle or rect) + **`geoHitTarget`** (geo — same transparent `PointSceneNode`; project lon/lat via `ctx.scales.projectedPoint` first): a zero-opacity, fully-transparent, hit-tested node from `{x, y, (r|width,height), datum, id}`. The `id` becomes the node's `pointId`/`id` (annotation anchor + nav-tree leaf) **and** its transition key. This is how a custom chart inherits **accessibility** (keyboard nav, focus ring, data table), **annotation** anchoring, **AI**/`onObservation` + shared selection, and **chart-mode** transitions for free — replaces the `rgba(0,0,0,0)`+`opacity:0`+`pointId`+`_transitionKey` boilerplate. The visible glyph lives in `overlays`; the focus ring still draws on the invisible target. A keyboard-focused **geoarea** outlines its polygon (a shape focus ring) rather than a centroid dot.
160
+ - **Radial coordinate kit**: `polarToXY`/`xyToAngle` (0 = up, clockwise), `angleScale`/`radiusScale`, `ringArcPath` (annular-sector / wedge / full-ring path), `TAU` — angle ⟂ radius for two-continuous-channel radial charts (the radial analogue of the chrome kit).
161
+ - **Edge-router kit** (custom network edges): `curvedEdgePath` (S-curve + near-level side-bow), `orthogonalEdgePath`, `boxEdgeAnchors` (box exit/entry by direction), `fanOutBend` (fan parallel edges apart). Plus cubic-Bézier evaluation — `cubicPoint`/`cubicTangent` (sample a point/tangent along a `CubicCurve` to *seat a mark on the curve* — a node mid-edge, an arrowhead at the end) and `cubicPath` (serialize to SVG).
162
+ - **2D vector kit**: `addPoints`/`subtractPoints`/`scalePoint`/`pointMagnitude`/`normalizePoint` — the point math any hand-built radial or network layout re-derives (an edge offset normal to its tangent, a spoke, a leader line). Operates on the shared `Point`, composes with the radial + edge kits.
163
+ - **Interval/timeline**: `packIntervals` (greedy Gantt sub-track packer), `activeCountOverDomain` (concurrency step series).
164
+ - **`runs`/`runLengthEncode`**: collapse a per-step categorical/boolean series into drawable runs (condition strips, status timelines, calendar ribbons).
165
+ - **Cyclical math** (day-of-year, hour, compass bearing): `wrapValue`, `shortestArcDelta`, `cyclicRangeContains`, `selectCyclicRange`.
166
+ - **`axisFixedForcePositions`** (+ shared **`rectCollide`** positioner): pin one axis from a data field, relax the other with edge attraction + an anchor spring + **rectangular** (label-box) collision — the "time is structural, the graph settles the cross-axis" family that hierarchical recipes don't cover. `axisFixedForceLayout` wraps it as a ready `NetworkCustomLayout`.
167
+ - **Chrome**: `linearAxis` (tick axis + gridlines from *any* scale — the bespoke-scale escape hatch `showAxes` can't cover), `legendSwatches` (portable SVG legend for `overlays` — fill/line/shape/hatch swatches; sibling to `legendGroupsFrom` which feeds `frameProps.legend`), `hatchFill` (`{def, fill}` SVG `<pattern>` for percentile/uncertainty bands — the SVG analogue of `createHatchPattern`).
168
+ - **`unwrapDatum`** (`semiotic/recipes` + `semiotic/utils`): collapse the wrapped-vs-raw datum split — always the raw user object (handles both `.data` wrappers and `.datum` nesting). **The** unwrap path for `onObservation` handlers AND `frameProps.tooltipContent` renderers: call it once on the incoming value; never pre-unwrap the argument (`unwrapDatum(x?.data ?? x)` double-unwraps).
169
+
170
+ `semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `intervalLanesLayout`, `flextreeLayout`, `dagreLayout`, `lineageDagLayout`, `axisFixedForceLayout`, `packedClusterMatrix`, `isometricLandmarkLayout`, `forceLayout`, `arcLayout`, `adjacencyMatrix`, `circularLayout`). **Network-analysis kit** (`semiotic/recipes`, pure graph algorithms): `buildAdjacency`, `bfsDistances`, `shortestPath`, `egoNetwork`, `degree`/`betweenness`(Brandes)/`closeness`/`clustering` (+ `normalizeScores`), and `proximityProblem` — the "spatial problem" layout diagnostic that flags nodes drawn closer than their graph distance warrants. Pair with network charts to size by centrality, highlight an ego network on hover, trace a shortest path, or diagnose a misleading layout. `forceLayout(nodes, edges, {seed})` is a **seeded, deterministic** positioner returning normalized `{id:{x,y}}` for `NetworkCustomChart` (same seed ⇒ same layout; re-seed for a "re-run the layout" interaction); `forceLayoutAsync(nodes, edges, {execution?, workerThreshold?, signal?})` is its Promise sibling that runs large layouts in a short-lived module Web Worker (identical deterministic output; graceful sync fallback), and `useForceLayout(nodes, edges, options)` → `{positions, status, error}` is the React wrapper — SSR and first hydration stay synchronous for markup parity, client graph changes go async while previous positions stay visible, and settled positions are memoized by node/edge array identity + options so remounting the same module-constant graph is "ready" immediately (no loading flash). `arcLayout`/`adjacencyMatrix`/`circularLayout` (+ `orderByGroupDegree`, `arcPath`) are the classic physics-free network forms. `allocateCells` is the largest-remainder grid allocator behind `waffleLayout` (turn `{key, weight}[]` + a cell count into integer cells with no rounding drift; `minPerCategory` keeps small categories visible) — reusable for any feature-mix / proportional waffle. **`unitize(value, {unit, maxUnits?, minFraction?})` / `unitizeRange(value, rangeValue, opts)`** is the counting sibling: the pictogram/tally allocator (value → repeated unit signs with a fractional final sign — ISOTYPE: symbols repeat, they never grow). Returns `{units: [{index, fraction, start, end, value}], total, shown, overflow}` — `maxUnits` caps with an `overflow` flag, `minFraction` drops trailing slivers while `total` vs `shown` keeps the ledger honest; `unitizeRange` extends the tally to a projected/scenario endpoint (`rangeUnits` drawn hatched), sharing a mid-sign boundary exactly via `startFraction`. Feeds `glyph`-node `fraction`s directly (unit charts, sign stacks, arrow bundles; `allocateCells` divides fixed cells, `unitize` counts). **Tokenized reasoning helpers**: `generateTokens(input, tokenEncoding)` wraps `unitize` plus `actual`, `fixed-denominator`, `quantile`, `posterior-sample`/`sample`, and seeded `random-sample` strategies with explicit `tokenType` (`dot`/`icon`/`glyph`), `tokenSemantics` (`observed-unit`, `unitized-measure`, `risk-case`, `possible-outcome`, etc.), and `countStrategy`; `{ value, rangeValue }` yields `rangeTokens` for scenario/projection tallies. `layoutTokenGrid` places the resulting tokens for icon/glyph arrays; `normalizeTokenEncoding` keeps legacy `token`/`unit` aliases working while canonical configs use `icon`/`unitValue`; `diagnoseTokenEncoding`, `suggestTokenEncoding`, and `tokenTaskIntentToCapabilityIntents` expose IDID-style warnings, task-aware defaults, and a bridge to `suggestCharts` intents. Built-in token glyph names include `person`, `server`, `chip`, `bolt`, and `bus`. `intervalLanesLayout` (ordinal) packs concurrent `{start,end,lane}` records into stacked Gantt sub-tracks per lane with period bands + lane labels + a time axis — packing runs in rendered-pixel space and honors `minBarWidth` (2) so zero/short-duration events stay visible without overlapping same-track neighbors; `axisFixedForceLayout` (network) pins one axis from a field and settles the other (rect-aware collision). BYO heavy deps (`d3-flextree`, `dagre`) in user code. `packedClusterMatrix` (network) bins records into a column×row matrix of **densely-packed beeswarm clusters** (deterministic self-contained packing, geometry cached) and emits **multi-channel glyphs** — hue (`colorAccessor`/`colorMap`), size (`sizeAccessor`, area), shade (`shadeAccessor`, CIELAB lightness), plus EITHER shape-encoding (`symbolAccessor`/`symbolMap` — the base mark becomes that shape) OR the **composite-glyph** model (`iconAccessor`/`iconMap` — base is a filled circle, only mapped values get a stroked inner icon). `rowMode:"banded"` (default) gives aligned global orbit-bands (row labels align, one enclosure spans the columns per band, columns vary in height) vs `"stacked"` (per-column cell heights ∝ count). `callouts:[{field,value,label}]` draws leader lines to named marks. `cellSizing:"proportional"` makes area ∝ count. **Recipe chrome kit** (exported from `semiotic/recipes`, for any custom-layout's `overlays`): `roundedEnclosure`/`boundsOf` (group/band borders), `bandLabel` (overflow-aware axis/band labels), `markCallout` (leader-line callout to a mark), `readField` (`node.data`-wrapper reader), `groupBy`, `dimFor` (the highlight/dim opacity rule — `{predicate?, highlight?, baseOpacity?, dimOpacity?, brighten?}`; `matchesHighlight` is its `{field,value}[]` matcher), `signatureKey`/`LayoutCache` (content-signature geometry cache so re-styling never re-runs an expensive layout — key by *content*, never by `ctx.nodes` identity), `legendGroupsFrom` (`{colorMap|keys, symbolMap?, sizeStops?}` → `LegendGroup[]` for `frameProps.legend`), `shade`/`makeShade`, `symbolPathString`/`symbolRadius`/`symbolExtent`/`SYMBOL_SEQUENCE`, and the small numeric/color one-liners every layout re-declares — `clamp`, `mean`, `withAlpha`, `nonNegativeFinite` (hex→`rgba()` so a hover-dim can ride a recipe's `resolveColor` callback). (`bandLabel`/`dimFor` are adopted by marimekko/bullet/parallelCoordinates/packedClusterMatrix.) `lineageDagLayout` renders a pre-positioned **layered lineage/DAG** (reads logical layer/row coords, no re-layout) with composite node glyphs (one hit-rect per node + icon/label/store-chip chrome in `overlays`), level-of-detail collapse (full→compact→icon→dot), distinct dashed back-edges, and host-driven reach-dimming (`layoutConfig.reachableIds`) + selection (`layoutConfig.selectedId` / shared `ctx.selection`).
171
+
172
+ `tokenLayer({input, encoding, options})` is the high-level tokenized-rendering helper for custom layouts: it runs `generateTokens`, applies row/column/grid/waffle/dotplot/bar-segment/quantile-strip placement (or `positionToken` for scale/map-driven placement), and returns ordinary dot/symbol/glyph scene nodes with `pointId`/transition identity. Use it for ISOTYPE, icon arrays, risk grids, quantile dotplots, strips, and hybrid token overlays; pass `includeRange` to render `rangeTokens`; drop down to `generateTokens` when a bespoke layout only needs records.
138
173
 
139
174
  **Chrome (labels/axes/legends): the recipe owns it.** Recipes emit own chrome via `overlays` return field (ReactNode painted on top). Built-in axes via `showAxes` on the HOC work for layouts respecting the standard scale. Recipe convention: `showXxx` boolean toggles, `xxxFormat` callbacks. Shipped recipes' toggles: marimekko `showCategoryLabels`, bullet `showLabels`+`showTicks`, parallelCoordinates `showAxes`, flextree/dagre `showLabels`, waffle/calendar none.
140
175
 
@@ -146,9 +181,9 @@ Layout signature differs by family:
146
181
  - Streaming layouts: ingest via ref (`push`/`pushMany`); layout re-runs on each ingest. Overlays update on data-change paths, NOT per-frame.
147
182
  - **On `NetworkCustomChart`, a `layoutConfig` change re-runs the layout (`buildScene`) WITHOUT re-ingesting the node/edge topology** — so drive interaction state, styling, or animation progress through `layoutConfig` for cheap per-frame updates; swapping `nodes`/`edges` (or the chart `width`/`height`) is the heavier path that re-ingests. Custom overlays are read straight from the store at render time (the frame's repaint re-reads them), so a recipe returning fresh JSX every layout call needs no per-frame `setState`.
148
183
  - Custom layouts own their colors — always prefer `ctx.resolveColor(key)` over hardcoded literals. `CategoryColorProvider` integration is XY-only; for cross-chart sync on network/ordinal customLayouts, pass matching `colorScheme` to each.
149
- - All three custom HOCs accept `selection` / `linkedHover` / `chartId` like the built-in HOCs: hover/click emit into the shared selection store, and the resolved predicate arrives as `ctx.selection` so the layout can dim/highlight by a cross-chart selection. Host-owned per-render dimming (e.g. a graph-reachability set) is orthogonal — pass it through `layoutConfig` and read `ctx.config`.
184
+ - All four custom HOCs accept `selection` / `linkedHover` / `chartId` like the built-in HOCs: hover/click emit into the shared selection store, and the resolved predicate arrives as `ctx.selection` so the layout can dim/highlight by a cross-chart selection. Host-owned per-render dimming (e.g. a graph-reachability set) is orthogonal — pass it through `layoutConfig` and read `ctx.config`.
150
185
  - **Selection restyle without a relayout** (the cheap hover path): by default a `ctx.selection` change re-runs the layout (rebuilds sceneNodes + repaints + rebuilds the quadtree). To restyle on hover/selection *without* re-positioning, opt in two ways: (1) return a **`restyle(node, selection)`** (network also `restyleEdge`) from the layout result — its presence makes a selection change re-apply styles to the existing scene **off each mark's base style** and just repaint (no relayout, no quadtree rebuild); compute geometry once in the layout body, express dimming in `restyle`. (2) For the React **`overlays`**, call **`useCustomLayoutSelection()`** (from `semiotic`/`semiotic/recipes` or the family entry) → `{ isActive, predicate }`; the frame swaps only the context value on selection change, so subscribing overlay components re-render while the canvas/quadtree stay untouched. Express selection/highlight through the selection store (not `layoutConfig`) to ride this path.
151
- - **Annotation-to-mark anchoring**: all three custom HOCs accept `annotations`. A custom layout's marks anchor by id — emit a scene node with `id: "<foo>"` and an annotation `{ pointId: "<foo>", }` resolves to that mark's center (XY/ordinal point+symbol nodes and every network node are harvested as anchor points). Data-coordinate anchoring still works for XY/ordinal; network has no data scales, so anchor by `pointId` (or draw a `markCallout` directly).
186
+ - **Annotations**: all four custom HOCs accept `annotations`. XY/ordinal/network custom marks can anchor by `pointId`; Geo annotations use geographic coordinates, while sprite- or tile-specific callouts can be emitted directly in the layout overlay.
152
187
  - Tooltips: emit datum keys matching user-visible accessor names. Avoid underscored synthetic keys (default tooltip filters those out).
153
188
 
154
189
  ## Coordinated Views
@@ -159,7 +194,8 @@ Chart props: `selection`, `linkedHover`, `linkedBrush`. Hooks: `useSelection`, `
159
194
  **Shared categories inside LinkedCharts → wrap in `CategoryColorProvider`.** Gives identical per-category colors AND makes LinkedCharts render one unified legend (suppressing individual chart legends). Without it, mismatched colors and duplicate legends.
160
195
  **Linked crosshair**: `linkedHover={{ name: "sync", mode: "x-position", xField: "time" }}`. Click locks crosshair (dashed white); click/Escape unlocks.
161
196
  **Linked series highlight** (series↔bar cross-highlight): `linkedHover={{ name: "sync", mode: "series" }}` auto-resolves the chart's series-identity field (colorBy/lineBy/areaBy/stackBy/groupBy) and keys the linked selection off it — no hand-wired `fields`. Add `seriesField: "region"` to override (align charts whose series live under different prop names). Modes are exclusive: `mode` is `"field"` (default) | `"x-position"` (crosshair) | `"series"`.
162
- Also: **ScatterplotMatrix**, **ChartContainer** (`title`, `subtitle`, `actions`), **ChartGrid** (`columns`, `gap`), **ContextLayout**.
197
+ **CircularBrush** — accessible range brush over a **cyclical** domain (day-of-year, hour, compass): `value` ({start,end}) / `onChange` (value | updater) / `period` (365) / `radius` / `step`+`largeStep` / `formatValue` / `arcFill`/`stroke`. Wrap-around ranges, pointer-capture drag, and full keyboard control (each handle + the range is a `role="slider"`, ←/→ nudges, Shift = `largeStep`). The radial counterpart to the linear `RealtimeHistogram` brush. **Control-surface contract**: it takes value/domain/geometry/`onChange` and never reaches into a chart — layer it over a chart sharing its coordinate space and feed `onChange` into your state (or the selection store). Built on the cyclical + radial kit.
198
+ Also: **ScatterplotMatrix**, **ChartContainer** (`title`, `subtitle`, `actions`, `notifications` — `ChartNotification[]` chart-level notices with no mark to anchor to, e.g. audit/data-pitfall findings or user-authored notes; `{ id?, level? ("info"|"success"|"warning"|"error"|"neutral" → semantic role colors), title?, message, source?, dismissible? }`, collapsed into a severity-colored toolbar bell + count badge (bell adopts the most severe visible level's icon/color) that opens a popover of dismissible cards — an overlay, so notices never reflow the plot; sr-only aria-live region announces count + severity, + `onNotificationDismiss`), **ChartGrid** (`columns`, `gap`), **ContextLayout**.
163
199
 
164
200
  ## Server-Side Rendering (`semiotic/server`)
165
201
 
@@ -188,7 +224,7 @@ All components also accept: `width`, `height`, `theme`, `title`, `description`,
188
224
  All HOCs accept `annotations`. Coordinates use data field names.
189
225
 
190
226
  **Positioning**: `widget`, `label`, `callout`, `callout-circle`, `callout-rect`, `text`, `bracket`
191
- **Reference lines**: `y-threshold` (`value`, `label`, `color`, `labelPosition`), `x-threshold`, `band` (`y0`, `y1`)
227
+ **Reference lines**: `y-threshold` (`value`, `label`, `color`, `labelPosition`), `x-threshold`, `band` (`y0`, `y1`), `x-band` (`x0`, `x1`, `fill`, `fillOpacity` — full-height vertical region for eras/phases; skipped when either bound is missing)
192
228
  **Ordinal**: `category-highlight`
193
229
  **Enclosures**: `enclose`, `rect-enclose`, `highlight`
194
230
  **Statistical**: `trend`, `envelope`, `anomaly-band`, `forecast`
@@ -211,7 +247,7 @@ CSS custom properties: `--semiotic-{bg, text, text-secondary, border, grid, prim
211
247
  <ThemeProvider theme={{ mode: "dark", colors: { categorical: [...] } }}> {/* merge onto dark base */}
212
248
  ```
213
249
 
214
- **Color priority** (with `colorBy`): CategoryColorProvider/LinkedCharts map > `colorScheme` > ThemeProvider `colors.categorical` > `"category10"`.
250
+ **Color priority** (with `colorBy`): CategoryColorProvider/LinkedCharts map > `colorScheme` > ThemeProvider `colors.categorical` > `"category10"`. `colorScheme` accepts a named scheme (`"tableau10"`), an array, or a `{category: color}` **object map** for exact per-category colors (no array ordering to keep in sync).
215
251
  Presets: `light`, `dark`, `high-contrast`, `pastels`(-dark), `bi-tool`(-dark), `italian`(-dark), `tufte`(-dark), `journalist`(-dark), `playful`(-dark), `carbon`(-dark).
216
252
  Serialization: `themeToCSS(theme, selector)`, `themeToTokens(theme)`, `resolveThemePreset(name)`.
217
253
 
@@ -219,9 +255,13 @@ Serialization: `themeToCSS(theme, selector)`, `themeToTokens(theme)`, `resolveTh
219
255
 
220
256
  **Scoped CSS cascade override** (per-subtree, no ThemeProvider needed): wrap a subtree in `<div style={{ "--semiotic-danger": "#4b0082" }}>` — canvas scene builders read CSS vars via `getComputedStyle` on the canvas DOM ancestor, so cascade rules apply even though rendering is canvas. CSS vars for single-role overrides; nested `ThemeProvider` for array/scale overrides (categorical palette, sequential/diverging scheme).
221
257
 
258
+ ## AI Design Guidance
259
+
260
+ - **ISOTYPE/icon arrays**: Repeated pictograms, semantic icons, and glyph tokens should be legible in the final rendered layout. Treat 16px as the minimum intended rendered icon dimension for ISOTYPE/icon-array designs. This is design guidance, not a Semiotic-enforced minimum: low-level helpers may default smaller for dense/sparkline contexts, so set `tokenSize`, glyph `size`, SVG slots, or wrapping explicitly. If available width would shrink icons below that visual floor, wrap tokens into multiple rows/columns, reduce visible token count, change the unit value, or choose a non-icon encoding.
261
+
222
262
  ## AI Features
223
263
 
224
- Surface APIs: `onObservation`/`useChartObserver`, `toConfig`/`fromConfig`/`toURL`/`fromURL`/`copyConfig`/`configToJSX`, `validateProps`, `diagnoseConfig`, `auditAccessibility`/`accessibilityCaveats` + `describeChart` + `buildNavigationTree`/`AccessibleNavTree`/`useNavigationSync` + `buildReaderGrounding` (a11y audit + descriptions + structured navigation + bidirectional sync + agent-reader grounding — see Accessibility), `exportChart(div, { format })`, `npx semiotic-ai --doctor`/`--audit-a11y`.
264
+ Surface APIs: `onObservation`/`useChartObserver`, `toConfig`/`fromConfig`/`toURL`/`fromURL`/`copyConfig`/`configToJSX`, `validateProps`, `diagnoseConfig` (includes `tokenEncoding` warnings when present), `suggestTokenEncoding`/`diagnoseTokenEncoding`, `auditAccessibility`/`accessibilityCaveats` + `describeChart` + `buildNavigationTree`/`AccessibleNavTree`/`useNavigationSync` + `buildReaderGrounding` (a11y audit + descriptions + structured navigation + bidirectional sync + agent-reader grounding — see Accessibility), `exportChart(div, { format })`, `npx semiotic-ai --doctor`/`--audit-a11y`.
225
265
 
226
266
  ### Conversational Interrogation (`semiotic/ai`)
227
267
  Headless "chat with the chart" hook. Library ships no UI — BYO chat surface.
@@ -345,6 +385,8 @@ These rules are generated from `ai/behaviorContracts.cjs` and are consumed by `s
345
385
  - **`scalePadding`**: pixel inset on scale ranges (via `frameProps={{ scalePadding: 12 }}`).
346
386
  - **`categoryFormat`/`xFormat`/`yFormat`**: can return ReactNode (renders in `<foreignObject>`). Tick deduplication: adjacent identical labels auto-removed.
347
387
  - **Composing overlays**: XY/Ordinal paint `--semiotic-bg` across the canvas; stack with `frameProps={{ background: "transparent" }}` on the overlay. Network/Geo don't paint bg by default.
388
+ - **`foregroundGraphics`/`backgroundGraphics` resolved scales**: the function form receives `{ size, margin, scales }` — `scales` is the frame's **resolved** scales (`{x, y}` for XY, `{o, r, projection}` for ordinal; `null` before first layout). Anchor a bespoke SVG overlay to `scales.x(...)`/`scales.y(...)` so it can't drift from the axes the chart drew (the HOC analogue of a custom layout's `ctx.scales`). Fall back to your own mapping while `scales` is null.
389
+ - **Theming a custom chart**: prefer `--semiotic-*` tokens for chrome (`stroke="var(--semiotic-text-secondary)"`) and `ctx.resolveColor(key)` / semantic role vars (`var(--semiotic-danger)`) for data, so the chart tracks `ThemeProvider`/dark mode — *or* deliberately paint fixed editorial colors on a `background: "transparent"` frame for art direction. Both are first-class; the kit's chrome helpers default to `--semiotic-*` tokens either way.
348
390
 
349
391
  ## Performance
350
392
  Prefer string accessors (`xAccessor="value"`) — always referentially stable. Memoize function accessors with `useCallback`.
package/README.md CHANGED
@@ -12,15 +12,20 @@ Simple charts in 5 lines. Network graphs, streaming data, and coordinated
12
12
  dashboards when you need them. Structured schemas and an MCP server so
13
13
  AI coding assistants generate correct chart code on the first try.
14
14
 
15
- ## What's New in 3.7.5
15
+ <!-- semiotic-readme-dashboard:start -->
16
+ <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
+ <!-- semiotic-readme-dashboard:end -->
16
18
 
17
- 3.7.5 is a chart-correctness and responsive-layout patch release:
19
+ ## What's New in 3.8.0
18
20
 
19
- - ForceDirectedGraph string `edgeWidth` accessors now read the underlying edge data, and server
20
- rendering handles `edgeWidth`, `edgeColor`, and `edgeOpacity` for SSR parity.
21
- - Crowded ordinal category axes now thin tick labels to avoid overlapping temporal-histogram bins.
22
- - XY custom-layout overlays now re-run on responsive size changes, keeping SVG chrome aligned with
23
- canvas scene nodes after first measurement.
21
+ 3.8.0 makes chart status, layout, and review workflows more explicit:
22
+
23
+ - `ChartContainer` notifications add a non-intrusive bell/popover for chart-level findings.
24
+ - ForceDirectedGraph can run expensive layouts in a Web Worker with synchronous SSR/hydration parity.
25
+ - `x-band` annotations, minimum-width interval lanes, and custom-layout readback make dense,
26
+ time-oriented charts easier to inspect.
27
+ - The DataPitfalls bridge and GoFish DisplayList adapter remain experimental and are exposed from
28
+ `semiotic/experimental` with `unstable_` names.
24
29
 
25
30
  ```jsx
26
31
  import { LineChart } from "semiotic/xy"
@@ -45,7 +50,7 @@ generate correct code without examples.
45
50
  Semiotic ships with everything an AI coding assistant needs to generate
46
51
  correct visualizations without trial and error:
47
52
 
48
- - **`semiotic/ai`** — a single import with the 47-chart capability catalog (XY, ordinal, network, realtime, geo, value), optimized for LLM code generation. Note: the published entry files are pre-bundled, so importing one chart from `semiotic/ai` still ships most of the bundle — treat it as a codegen/tooling surface and use family subpaths (`semiotic/xy`, `semiotic/geo`, `semiotic/value`, …) in production code, at roughly half the single-chart cost.
53
+ - **`semiotic/ai`** — a single import with the schema-backed chart capability catalog (XY, ordinal, network, realtime, geo, value), optimized for LLM code generation. See `ai/surface-manifest.json` for the generated current inventory. Note: the published entry files are pre-bundled, so importing one chart from `semiotic/ai` still ships most of the bundle — treat it as a codegen/tooling surface and use family subpaths (`semiotic/xy`, `semiotic/geo`, `semiotic/value`, …) in production code, at roughly half the single-chart cost.
49
54
  - **`ai/schema.json`** — machine-readable prop schemas for every component
50
55
  - **`npx semiotic-mcp`** — an MCP server for tool-based chart rendering in any MCP client
51
56
  - **`npx semiotic-ai --doctor`** — validate component + props JSON from the command line with typo suggestions and anti-pattern detection
@@ -105,16 +110,16 @@ Charts serialize to JSON and back: `toConfig`, `fromConfig`, `toURL`,
105
110
  translates them to Semiotic configs — works with `configToJSX()` for
106
111
  full round-trip from notebooks and AI-generated specs.
107
112
 
108
- Need an external pitfall review? `toDataPitfallsChain()` builds a
113
+ Need an external pitfall review? The experimental `unstable_toDataPitfallsChain()` builds a
109
114
  dependency-free chain input for [`datapitfalls`](https://github.com/bjonesdataliteracy/datapitfalls),
110
115
  combining the Semiotic config, JSX, reader grounding, diagnostics,
111
116
  accessibility audit, and optional rendered SVG/image evidence:
112
117
 
113
118
  ```ts
114
- import { toDataPitfallsChain } from "semiotic/ai"
119
+ import { unstable_toDataPitfallsChain } from "semiotic/experimental"
115
120
  import { detectPitfalls } from "datapitfalls"
116
121
 
117
- const input = toDataPitfallsChain("LineChart", props, {
122
+ const input = unstable_toDataPitfallsChain("LineChart", props, {
118
123
  narrative: "Monthly sales are accelerating.",
119
124
  rendered: { svg, evidence },
120
125
  })
@@ -122,6 +127,29 @@ const input = toDataPitfallsChain("LineChart", props, {
122
127
  const report = await detectPitfalls(input, { apiKey: process.env.ANTHROPIC_API_KEY })
123
128
  ```
124
129
 
130
+ The return path stays dependency-free too. Use whole-chart findings as
131
+ `ChartContainer` notifications, and only turn findings into annotations after
132
+ your app can anchor them to marks or semantic positions:
133
+
134
+ ```tsx
135
+ import { ChartContainer } from "semiotic"
136
+ import { LineChart } from "semiotic/xy"
137
+ import {
138
+ unstable_toDataPitfallsAnnotations,
139
+ unstable_toDataPitfallsNotifications,
140
+ } from "semiotic/experimental"
141
+
142
+ const notifications = unstable_toDataPitfallsNotifications(report)
143
+ const annotations = unstable_toDataPitfallsAnnotations(report, {
144
+ anchorFor: (finding) =>
145
+ finding.ruleId === "truncated-axis" ? { x: 9, y: 9000 } : null,
146
+ })
147
+
148
+ <ChartContainer notifications={notifications}>
149
+ <LineChart {...props} annotations={annotations} />
150
+ </ChartContainer>
151
+ ```
152
+
125
153
  ### When to use something else
126
154
 
127
155
  Need a standard bar or line chart for a dashboard you'll never need to
@@ -335,29 +363,94 @@ loadConversationArc(sink.load(), { enabled: false })
335
363
 
336
364
  ## Bundle Sizes
337
365
 
338
- Semiotic ships 12 entry points. **Don't import from `"semiotic"` unless you need everything** — use the sub-path that matches your chart type:
366
+ Semiotic ships 17 stable module entry points. **Don't import from `"semiotic"` unless you need everything** — use the sub-path that matches your chart type.
367
+
368
+ The numbers below are **first-party artifact cost**: the gzip size of Semiotic's own code for each sub-path. They exclude React and other runtime dependencies, so they are not a prediction of a cold application bundle. Do not add artifact rows to estimate an app: dependency resolution and cross-import deduplication happen in the consumer bundler and are measured separately below.
339
369
 
340
370
  <!-- semiotic-bundle-sizes:start -->
341
371
  <!-- Auto-generated by `scripts/sync-bundle-sizes.mjs`. Edit dist/*, not this block. -->
342
372
 
343
373
  | Entry Point | gzip | What's inside |
344
374
  |---|---|---|
345
- | `semiotic/xy` | **96 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
346
- | `semiotic/ordinal` | **78 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
347
- | `semiotic/network` | **73 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
348
- | `semiotic/geo` | **57 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
349
- | `semiotic/realtime` | **104 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
350
- | `semiotic/server` | **132 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
351
- | `semiotic/utils` | **39 KB** | ThemeProvider, validators, serialization no chart components |
352
- | `semiotic/recipes` | **19 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
375
+ | `semiotic/xy` | **101 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
376
+ | `semiotic/ordinal` | **82 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
377
+ | `semiotic/network` | **85 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
378
+ | `semiotic/geo` | **62 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
379
+ | `semiotic/realtime` | **111 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
380
+ | `semiotic/realtime/core` | **110 KB** | Streaming chart types, HOCs, and buffer helpers |
381
+ | `semiotic/realtime/react` | **1 KB** | Stream status and synced push hooks |
382
+ | `semiotic/server` | **189 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
383
+ | `semiotic/server/node` | **189 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
384
+ | `semiotic/server/edge` | **188 KB** | renderChart, renderChartWithEvidence, renderToStaticSVG, renderDashboard |
385
+ | `semiotic/utils` | **71 KB** | ThemeProvider, validators, serialization — no chart components |
386
+ | `semiotic/utils/core` | **70 KB** | Theme helpers and serialization utilities |
387
+ | `semiotic/utils/react` | **4 KB** | ThemeProvider, useTheme, useReducedMotion, useHighContrast, useStreamStatus |
388
+ | `semiotic/recipes` | **53 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
389
+ | `semiotic/recipes/core` | **52 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
390
+ | `semiotic/recipes/react` | **1 KB** | Glyph and React layout-selection helpers |
353
391
  | `semiotic/themes` | **6 KB** | Theme presets only (tufte, carbon, etc.) |
354
- | `semiotic/data` | **4 KB** | bin, rollup, groupBy, pivot, fromVegaLite |
392
+ | `semiotic/themes/core` | **6 KB** | Theme presets and token helpers |
393
+ | `semiotic/themes/react` | **4 KB** | ThemeProvider/useTheme and hooks |
394
+ | `semiotic/data` | **3 KB** | bin, rollup, groupBy, pivot, fromVegaLite |
355
395
  | `semiotic/value` | **6 KB** | BigNumber — focal-value KPI / scorecard (SingleValueFrame POC) |
356
- | `semiotic/ai` | **269 KB** | All 47 schema-backed charts + validation — optimized for LLM code generation |
357
- | `semiotic` | **216 KB** | Everything below (full bundle) |
396
+ | `semiotic/physics` | **98 KB** | GaltonBoardChart, EventDropChart, PhysicsPileChart, CollisionSwarmChart, PhysicalFlowChart, PhysicsCustomChart |
397
+ | `semiotic/physics/matter` | **1 KB** | Matter.js migration helpers + optional peer guard (no chart components) |
398
+ | `semiotic/physics/rapier` | **1 KB** | Rapier peer guard + adapter decision metadata (no chart components) |
399
+ | `semiotic/ai` | **394 KB** | All schema-backed charts + validation — optimized for LLM code generation |
400
+ | `semiotic/ai/core` | **79 KB** | suggestCharts, validateProps, describeChart, repairChartConfig, tool adapters — no chart components |
401
+ | `semiotic/controls` | **5 KB** | DirectManipulationControl, CircularBrush, MobileStandardControls, auditVisualizationControls — no frame renderer |
402
+ | `semiotic` | **258 KB** | Everything below (full bundle) |
358
403
 
359
404
  <!-- semiotic-bundle-sizes:end -->
360
405
 
406
+ ### Cold-consumer named imports
407
+
408
+ The table above is **first-party artifact cost**, not an application bundle. The generated table
409
+ below measures a different thing: a fresh consumer bundles one retained named import from a packed
410
+ `semiotic` tarball through the public export path. It includes Semiotic and its resolved runtime dependencies,
411
+ but externalizes React/React DOM and optional adapter peers that the host application owns. Each row
412
+ starts cold, so use it to compare one public import choice—not to add together an application's rows.
413
+ The checked machine-readable baseline is `benchmarks/setup/cold-consumer-imports.json`; refresh it
414
+ after a production build with `npm run docs:cold-consumer`.
415
+
416
+ <!-- semiotic-cold-consumer:start -->
417
+ <!-- Auto-generated by `scripts/measure-cold-consumer.mjs`. Do not edit by hand. -->
418
+
419
+ Method: fresh `npm pack --ignore-scripts` tarball → temporary consumer → minified/tree-shaken esbuild ESM bundle → gzip -9. React/React DOM and optional adapter peers are external; Semiotic and its resolved runtime dependencies are included.
420
+
421
+ | Public named import | Runtime | gzip cold-consumer bundle |
422
+ |---|---:|---:|
423
+ | `import { LineChart } from "semiotic"` | browser | **290.2 KiB** |
424
+ | `import { LineChart } from "semiotic/xy"` | browser | **138.9 KiB** |
425
+ | `import { BarChart } from "semiotic/ordinal"` | browser | **114.3 KiB** |
426
+ | `import { SankeyDiagram } from "semiotic/network"` | browser | **118.2 KiB** |
427
+ | `import { RealtimeLineChart } from "semiotic/realtime"` | browser | **157.2 KiB** |
428
+ | `import { RingBuffer } from "semiotic/realtime/core"` | browser | **157.2 KiB** |
429
+ | `import { useStreamStatus } from "semiotic/realtime/react"` | browser | **0.6 KiB** |
430
+ | `import { GaltonBoardChart } from "semiotic/physics"` | browser | **109.5 KiB** |
431
+ | `import { MATTER_PHYSICS_CAPABILITIES } from "semiotic/physics/matter"` | browser | **0.2 KiB** |
432
+ | `import { RAPIER_PHYSICS_CAPABILITIES } from "semiotic/physics/rapier"` | browser | **0.2 KiB** |
433
+ | `import { renderChart } from "semiotic/server"` | node | **249.5 KiB** |
434
+ | `import { generateFrameSVGs } from "semiotic/server/edge"` | node | **190.7 KiB** |
435
+ | `import { renderToImage } from "semiotic/server/node"` | node | **249.9 KiB** |
436
+ | `import { suggestCharts } from "semiotic/ai"` | browser | **414.4 KiB** |
437
+ | `import { suggestCharts } from "semiotic/ai/core"` | browser | **44.0 KiB** |
438
+ | `import { bin } from "semiotic/data"` | browser | **0.4 KiB** |
439
+ | `import { ChoroplethMap } from "semiotic/geo"` | browser | **102.8 KiB** |
440
+ | `import { resolveThemePreset } from "semiotic/themes"` | browser | **3.4 KiB** |
441
+ | `import { resolveThemePreset } from "semiotic/themes/core"` | browser | **3.4 KiB** |
442
+ | `import { ThemeProvider } from "semiotic/themes/react"` | browser | **4.4 KiB** |
443
+ | `import { validateProps } from "semiotic/utils"` | browser | **20.4 KiB** |
444
+ | `import { smartTickFormat } from "semiotic/utils/core"` | browser | **18.9 KiB** |
445
+ | `import { useReducedMotion } from "semiotic/utils/react"` | browser | **1.8 KiB** |
446
+ | `import { waffleLayout } from "semiotic/recipes"` | browser | **1.3 KiB** |
447
+ | `import { waffleLayout } from "semiotic/recipes/core"` | browser | **1.3 KiB** |
448
+ | `import { Glyph } from "semiotic/recipes/react"` | browser | **0.9 KiB** |
449
+ | `import { BigNumber } from "semiotic/value"` | browser | **5.6 KiB** |
450
+ | `import { DirectManipulationControl } from "semiotic/controls"` | browser | **1.3 KiB** |
451
+
452
+ <!-- semiotic-cold-consumer:end -->
453
+
361
454
  ```jsx
362
455
  // Import from the sub-path, not from "semiotic"
363
456
  import { LineChart } from "semiotic/xy"
@@ -366,7 +459,7 @@ import { SankeyDiagram } from "semiotic/network"
366
459
  import { ChoroplethMap } from "semiotic/geo"
367
460
  ```
368
461
 
369
- **Tree-shaking**: Each sub-path is a self-contained bundle with `"sideEffects": false`. Bundlers (webpack, Rollup, Vite, esbuild) will tree-shake unused exports. If you only use `LineChart` from `semiotic/xy`, the bar/pie/network code is never included.
462
+ **Tree-shaking**: Each sub-path is a separate, pre-bundled artifact marked `"sideEffects": false`, so importing from `semiotic/xy` never pulls in `semiotic/ordinal` or `semiotic/network`. Note the boundary: within a family artifact the charts are **already combined into one module**, so importing only `LineChart` from `semiotic/xy` still loads the whole XY family artifact (≈98 KB gz) — bundlers cannot tree-shake individual charts back out of a pre-bundled family. Cross-family separation is real; per-chart separation within a family is not (granular per-chart entries are planned). Pick the narrowest sub-path for your charts.
370
463
 
371
464
  **When to use `"semiotic"`**: Only if your app uses charts from 3+ categories (XY + ordinal + network) and you'd rather have one import than three. The full bundle is roughly the sum of every sub-path bundle above — see the `semiotic` row of the table for the current number.
372
465
 
@@ -438,7 +531,7 @@ Add to your MCP client config (e.g. `claude_desktop_config.json` for Claude Desk
438
531
  }
439
532
  ```
440
533
 
441
- No API keys or authentication required. The server runs locally via stdio. HTTP mode is also available for inspectors, web clients, and ChatGPT Apps SDK experiments: `npx semiotic-mcp --http --port 3001`. Since 3.7.2, HTTP mode is stateless: each request gets a fresh read-only MCP server + transport, so it can autoscale on serverless hosts without sticky sessions.
534
+ No API keys or authentication required. The server runs locally via stdio. HTTP mode is also available for inspectors, web clients, and ChatGPT Apps SDK experiments: `npx semiotic-mcp --http --port 3001`. It binds to `127.0.0.1` by default; intentionally expose another interface with `--host 0.0.0.0` or `MCP_HOST=0.0.0.0`. Since 3.7.2, HTTP mode is stateless: each request gets a fresh read-only MCP server + transport, so it can autoscale on serverless hosts without sticky sessions.
442
535
 
443
536
  For ChatGPT developer mode, expose the HTTP endpoint over HTTPS with a tunnel and create a connector that points at `https://<your-tunnel>/mcp`. The experimental Apps SDK surface is `renderInteractiveChart`, which returns a `text/html;profile=mcp-app` widget template plus a hidden SVG payload rendered by Semiotic on the MCP server.
444
537
 
@@ -454,7 +547,7 @@ host-header allowlisting. For ChatGPT Apps domain verification, set
454
547
  |------|-------------|
455
548
  | **`renderChart`** | Render a Semiotic chart to static SVG. Supports the components returned by `getSchema` that are marked `[renderable]`. Pass `{ component: "LineChart", props: { data: [...], xAccessor: "x", yAccessor: "y" } }`. Returns SVG string plus a "Render evidence" JSON block (mark counts by scene type, resolved axis domains, empty flag, annotation count, accessible name) so agents can verify the chart drew data marks, or validation errors with fix suggestions. |
456
549
  | **`renderInteractiveChart`** | Render a static-data chart as a ChatGPT Apps widget. Uses the same Semiotic server render path as `renderChart`, then hydrates an iframe UI with fit, zoom, data, hover, and render-evidence controls. |
457
- | **`getSchema`** | Return the prop schema for a specific component. Pass `{ component: "LineChart" }` to get its props, or omit `component` to list all 47 chart schemas. Components marked `[renderable]` are available through `renderChart`; realtime charts require a browser/live environment. |
550
+ | **`getSchema`** | Return the prop schema for a specific component. Pass `{ component: "LineChart" }` to get its props, or omit `component` to list the complete schema-backed catalog. Components marked `[renderable]` are available through `renderChart`; realtime charts require a browser/live environment. |
458
551
  | **`suggestChart`** | Legacy sample-row recommender. Pass `{ data: [{...}, ...] }` with 1–5 sample objects plus optional broad intent/capability filters. |
459
552
  | **`suggestCharts`** | Capability-based recommender for bounded row data. Returns ranked chart suggestions with scores, reasons, caveats, import paths, and ready-to-use props. |
460
553
  | **`suggestStreamCharts`** | Recommend realtime charts from a stream schema, throughput, and retention hints. |
@@ -472,6 +565,7 @@ host-header allowlisting. For ChatGPT Apps domain verification, set
472
565
  |----------|-------------|
473
566
  | **`semiotic://schema`** | Full machine-readable component schema JSON. |
474
567
  | **`semiotic://components`** | Component index showing renderable/browser-only status and MCP categories. |
568
+ | **`semiotic://surface-manifest`** | Generated inventory of the current AI schema, exports, renderability, tools, resources, and prompts. |
475
569
  | **`semiotic://behavior-contracts`** | Agent-visible semantic rules for color precedence, required prop combinations, push refs, and renderability. |
476
570
  | **`semiotic://system-prompt`** | Compact AI instructions with import rules, chart props, SSR guidance, and pitfalls. |
477
571
  | **`semiotic://examples`** | Copy-paste chart examples by data shape. |
@@ -594,7 +688,7 @@ Semiotic is indexed by AI-coding-agent documentation tools so your assistant (Cl
594
688
 
595
689
  Agent-facing API surface:
596
690
 
597
- - **`CLAUDE.md`**, **`ai/schema.json`**, **`ai/behaviorContracts.cjs`** — bundled in the npm tarball (see `package.json#files`); agents that install Semiotic locally read these directly. `CLAUDE.md` is the quick-start cheat sheet (HOC props, push API, theming, usage notes); `ai/schema.json` is the JSON Schema for every chart's prop surface (47 charts); `ai/behaviorContracts.cjs` carries the agent-visible semantic rules (color precedence, push-mode requirements, ID-accessor contracts).
691
+ - **`CLAUDE.md`**, **`ai/schema.json`**, **`ai/surface-manifest.json`**, **`ai/behaviorContracts.cjs`** — bundled in the npm tarball (see `package.json#files`); agents that install Semiotic locally read these directly. `CLAUDE.md` is the quick-start cheat sheet (HOC props, push API, theming, usage notes); `ai/schema.json` is the JSON Schema for every chart's prop surface; `ai/surface-manifest.json` is the generated inventory; `ai/behaviorContracts.cjs` carries the agent-visible semantic rules (color precedence, push-mode requirements, ID-accessor contracts).
598
692
  - [**`semiotic.nteract.io/llms.txt`**](https://semiotic.nteract.io/llms.txt) + [**`/llms-full.txt`**](https://semiotic.nteract.io/llms-full.txt) — deployed at the docs site per the [llms.txt standard](https://llmstxt.org). Agents fetch the navigation map (`llms.txt`) or the full inlined docs (`llms-full.txt`) over HTTP; they're not part of the npm package itself.
599
693
 
600
694
  ## Documentation