semiotic 3.0.1 → 3.1.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 (122) hide show
  1. package/CLAUDE.md +227 -27
  2. package/README.md +43 -11
  3. package/ai/examples.md +358 -18
  4. package/ai/schema.json +64 -2
  5. package/ai/system-prompt.md +50 -12
  6. package/dist/components/Legend.d.ts +7 -1
  7. package/dist/components/charts/geo/ChoroplethMap.d.ts +53 -0
  8. package/dist/components/charts/geo/DistanceCartogram.d.ts +90 -0
  9. package/dist/components/charts/geo/FlowMap.d.ts +83 -0
  10. package/dist/components/charts/geo/ProportionalSymbolMap.d.ts +67 -0
  11. package/dist/components/charts/geo/index.d.ts +8 -0
  12. package/dist/components/charts/index.d.ts +2 -0
  13. package/dist/components/charts/network/ChordDiagram.d.ts +6 -5
  14. package/dist/components/charts/network/CirclePack.d.ts +2 -2
  15. package/dist/components/charts/network/ForceDirectedGraph.d.ts +9 -7
  16. package/dist/components/charts/network/OrbitDiagram.d.ts +21 -20
  17. package/dist/components/charts/network/SankeyDiagram.d.ts +6 -5
  18. package/dist/components/charts/network/TreeDiagram.d.ts +2 -2
  19. package/dist/components/charts/network/Treemap.d.ts +2 -2
  20. package/dist/components/charts/ordinal/BarChart.d.ts +7 -5
  21. package/dist/components/charts/ordinal/BoxPlot.d.ts +8 -6
  22. package/dist/components/charts/ordinal/DonutChart.d.ts +8 -6
  23. package/dist/components/charts/ordinal/DotPlot.d.ts +8 -6
  24. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +7 -5
  25. package/dist/components/charts/ordinal/Histogram.d.ts +8 -5
  26. package/dist/components/charts/ordinal/PieChart.d.ts +8 -6
  27. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +2 -0
  28. package/dist/components/charts/ordinal/StackedBarChart.d.ts +7 -5
  29. package/dist/components/charts/ordinal/SwarmPlot.d.ts +8 -6
  30. package/dist/components/charts/ordinal/ViolinPlot.d.ts +8 -5
  31. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +24 -6
  32. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +28 -7
  33. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +23 -5
  34. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +24 -6
  35. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +23 -5
  36. package/dist/components/charts/shared/colorUtils.d.ts +5 -0
  37. package/dist/components/charts/shared/hooks.d.ts +13 -1
  38. package/dist/components/charts/shared/legendUtils.d.ts +2 -3
  39. package/dist/components/charts/shared/statisticalOverlays.d.ts +1 -2
  40. package/dist/components/charts/shared/statisticalOverlaysLazy.d.ts +10 -0
  41. package/dist/components/charts/shared/tooltipUtils.d.ts +1 -1
  42. package/dist/components/charts/shared/types.d.ts +10 -4
  43. package/dist/components/charts/shared/useChartSetup.d.ts +112 -0
  44. package/dist/components/charts/shared/useStreamingLegend.d.ts +65 -0
  45. package/dist/components/charts/xy/AreaChart.d.ts +11 -6
  46. package/dist/components/charts/xy/BubbleChart.d.ts +11 -6
  47. package/dist/components/charts/xy/ConnectedScatterplot.d.ts +7 -6
  48. package/dist/components/charts/xy/Heatmap.d.ts +16 -5
  49. package/dist/components/charts/xy/LineChart.d.ts +21 -5
  50. package/dist/components/charts/xy/MinimapChart.d.ts +3 -0
  51. package/dist/components/charts/xy/QuadrantChart.d.ts +120 -0
  52. package/dist/components/charts/xy/Scatterplot.d.ts +9 -6
  53. package/dist/components/charts/xy/StackedAreaChart.d.ts +11 -6
  54. package/dist/components/geo/mergeData.d.ts +18 -0
  55. package/dist/components/geo/referenceGeography.d.ts +10 -0
  56. package/dist/components/geo/useReferenceAreas.d.ts +13 -0
  57. package/dist/components/realtime/RingBuffer.d.ts +1 -0
  58. package/dist/components/realtime/types.d.ts +17 -0
  59. package/dist/components/semiotic-data.d.ts +1 -0
  60. package/dist/components/semiotic-geo.d.ts +16 -0
  61. package/dist/components/semiotic-server.d.ts +1 -1
  62. package/dist/components/semiotic-xy.d.ts +1 -0
  63. package/dist/components/semiotic.d.ts +4 -4
  64. package/dist/components/server/renderToStaticSVG.d.ts +4 -2
  65. package/dist/components/stream/AccessibleDataTable.d.ts +50 -0
  66. package/dist/components/stream/CanvasHitTester.d.ts +8 -2
  67. package/dist/components/stream/DataSourceAdapter.d.ts +33 -4
  68. package/dist/components/stream/GeoCanvasHitTester.d.ts +19 -0
  69. package/dist/components/stream/GeoParticlePool.d.ts +46 -0
  70. package/dist/components/stream/GeoPipelineStore.d.ts +81 -0
  71. package/dist/components/stream/GeoTileRenderer.d.ts +31 -0
  72. package/dist/components/stream/NetworkPipelineStore.d.ts +16 -4
  73. package/dist/components/stream/NetworkSVGOverlay.d.ts +4 -1
  74. package/dist/components/stream/OrdinalPipelineStore.d.ts +8 -4
  75. package/dist/components/stream/OrdinalSVGOverlay.d.ts +23 -1
  76. package/dist/components/stream/PipelineStore.d.ts +57 -5
  77. package/dist/components/stream/SVGOverlay.d.ts +28 -1
  78. package/dist/components/stream/SceneGraph.d.ts +7 -3
  79. package/dist/components/stream/SceneToSVG.d.ts +2 -0
  80. package/dist/components/stream/StreamGeoFrame.d.ts +4 -0
  81. package/dist/components/stream/accessorUtils.d.ts +1 -0
  82. package/dist/components/stream/canvasSetup.d.ts +26 -0
  83. package/dist/components/stream/geoTypes.d.ts +186 -0
  84. package/dist/components/stream/layouts/forceLayoutPlugin.d.ts +0 -7
  85. package/dist/components/stream/layouts/index.d.ts +2 -1
  86. package/dist/components/stream/layouts/orbitLayoutPlugin.d.ts +2 -0
  87. package/dist/components/stream/legendRenderer.d.ts +33 -0
  88. package/dist/components/stream/networkTypes.d.ts +49 -1
  89. package/dist/components/stream/ordinalTypes.d.ts +10 -0
  90. package/dist/components/stream/pipelineTransitionUtils.d.ts +42 -0
  91. package/dist/components/stream/renderers/geoCanvasRenderer.d.ts +9 -0
  92. package/dist/components/stream/renderers/heatmapCanvasRenderer.d.ts +2 -1
  93. package/dist/components/stream/renderers/lineCanvasRenderer.d.ts +1 -0
  94. package/dist/components/stream/renderers/renderPulse.d.ts +50 -0
  95. package/dist/components/stream/types.d.ts +77 -3
  96. package/dist/components/types/legendTypes.d.ts +27 -3
  97. package/dist/geo.min.js +1 -0
  98. package/dist/geo.module.min.js +1 -0
  99. package/dist/network.min.js +1 -1
  100. package/dist/network.module.min.js +1 -1
  101. package/dist/ordinal.min.js +1 -1
  102. package/dist/ordinal.module.min.js +1 -1
  103. package/dist/realtime.min.js +1 -1
  104. package/dist/realtime.module.min.js +1 -1
  105. package/dist/semiotic-ai.min.js +1 -1
  106. package/dist/semiotic-ai.module.min.js +1 -1
  107. package/dist/semiotic-data.d.ts +1 -0
  108. package/dist/semiotic-data.min.js +1 -1
  109. package/dist/semiotic-data.module.min.js +1 -1
  110. package/dist/semiotic-geo.d.ts +16 -0
  111. package/dist/semiotic-server.d.ts +1 -1
  112. package/dist/semiotic-xy.d.ts +1 -0
  113. package/dist/semiotic.d.ts +4 -4
  114. package/dist/semiotic.min.js +1 -1
  115. package/dist/semiotic.module.min.js +1 -1
  116. package/dist/server.min.js +1 -1
  117. package/dist/server.module.min.js +1 -1
  118. package/dist/test-utils/canvasMock.d.ts +3 -0
  119. package/dist/xy.min.js +1 -1
  120. package/dist/xy.module.min.js +1 -1
  121. package/package.json +29 -7
  122. package/dist/test/canvasMock.d.ts +0 -2
@@ -8,6 +8,16 @@ export interface LineStyle {
8
8
  strokeWidth?: number;
9
9
  strokeDasharray?: string;
10
10
  }
11
+ /**
12
+ * Anchoring mode for streaming annotations.
13
+ * - `"fixed"` (default): anchored to specific datum coordinates; disappears when out of view.
14
+ * - `"latest"`: annotation attaches to the most recent datum in the buffer.
15
+ * On each frame, the annotation's position is re-resolved to the latest data point.
16
+ * Useful for "current value" labels.
17
+ * - `"sticky"`: annotation stays at its last known pixel position after the target datum
18
+ * is evicted from the window. It freezes in place rather than disappearing.
19
+ */
20
+ export type AnnotationAnchorMode = "fixed" | "latest" | "sticky";
11
21
  export interface AnnotationContext {
12
22
  scales?: {
13
23
  x?: ScaleLinear<number, number>;
@@ -30,6 +40,13 @@ export interface AnnotationContext {
30
40
  y: number;
31
41
  r: number;
32
42
  }[];
43
+ /** Curve interpolation type from the parent chart */
44
+ curve?: string;
45
+ /** Cache of last known pixel positions for sticky annotations, keyed by annotation index */
46
+ stickyPositionCache?: Map<number, {
47
+ x: number;
48
+ y: number;
49
+ }>;
33
50
  }
34
51
  export interface CrosshairStyle {
35
52
  stroke?: string;
@@ -5,3 +5,4 @@
5
5
  export { bin, rollup, groupBy, pivot } from "./data/transforms";
6
6
  export { fromVegaLite } from "./data/fromVegaLite";
7
7
  export type { VegaLiteSpec, VegaLiteEncoding } from "./data/fromVegaLite";
8
+ export { mergeData } from "./geo/mergeData";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Geo entry point — geographic visualization: choropleth, proportional symbol, flow maps.
3
+ * Import from "semiotic/geo" instead of the full bundle to reduce bundle size.
4
+ */
5
+ import StreamGeoFrame from "./stream/StreamGeoFrame";
6
+ export { StreamGeoFrame };
7
+ export { ChoroplethMap } from "./charts/geo/ChoroplethMap";
8
+ export { ProportionalSymbolMap } from "./charts/geo/ProportionalSymbolMap";
9
+ export { FlowMap } from "./charts/geo/FlowMap";
10
+ export { DistanceCartogram } from "./charts/geo/DistanceCartogram";
11
+ export type { StreamGeoFrameProps, StreamGeoFrameHandle, GeoAreaSceneNode, GeoSceneNode, GeoScales, ProjectionProp, ProjectionName, GraticuleConfig, DistanceCartogramConfig, GeoPipelineConfig } from "./stream/geoTypes";
12
+ export type { GeoParticleStyle } from "./stream/GeoParticlePool";
13
+ export { mergeData } from "./geo/mergeData";
14
+ export { resolveReferenceGeography } from "./geo/referenceGeography";
15
+ export type { ReferenceGeography } from "./geo/referenceGeography";
16
+ export type { AreasProp } from "./geo/useReferenceAreas";
@@ -1 +1 @@
1
- export { renderToStaticSVG, renderXYToStaticSVG, renderOrdinalToStaticSVG, renderNetworkToStaticSVG } from "./server/renderToStaticSVG";
1
+ export { renderToStaticSVG, renderXYToStaticSVG, renderOrdinalToStaticSVG, renderNetworkToStaticSVG, renderGeoToStaticSVG } from "./server/renderToStaticSVG";
@@ -13,4 +13,5 @@ export { BubbleChart } from "./charts/xy/BubbleChart";
13
13
  export { Heatmap } from "./charts/xy/Heatmap";
14
14
  export { ScatterplotMatrix } from "./charts/xy/ScatterplotMatrix";
15
15
  export { MinimapChart } from "./charts/xy/MinimapChart";
16
+ export { QuadrantChart } from "./charts/xy/QuadrantChart";
16
17
  export type { StreamXYFrameProps, StreamXYFrameHandle } from "./stream/types";
@@ -1,7 +1,7 @@
1
1
  import StreamXYFrame from "./stream/StreamXYFrame";
2
2
  import StreamOrdinalFrame from "./stream/StreamOrdinalFrame";
3
3
  import StreamNetworkFrame from "./stream/StreamNetworkFrame";
4
- import { Scatterplot, ConnectedScatterplot, LineChart, AreaChart, StackedAreaChart, Heatmap, BubbleChart, BarChart, StackedBarChart, SwarmPlot, BoxPlot, Histogram, ViolinPlot, RidgelinePlot, DotPlot, PieChart, DonutChart, GroupedBarChart, ForceDirectedGraph, ChordDiagram, SankeyDiagram, TreeDiagram, Treemap, CirclePack, OrbitDiagram, ScatterplotMatrix, MinimapChart } from "./charts";
4
+ import { Scatterplot, ConnectedScatterplot, LineChart, AreaChart, StackedAreaChart, Heatmap, BubbleChart, BarChart, StackedBarChart, SwarmPlot, BoxPlot, Histogram, ViolinPlot, RidgelinePlot, DotPlot, PieChart, DonutChart, GroupedBarChart, ForceDirectedGraph, ChordDiagram, SankeyDiagram, TreeDiagram, Treemap, CirclePack, OrbitDiagram, ScatterplotMatrix, MinimapChart, QuadrantChart } from "./charts";
5
5
  import { LinkedCharts } from "./LinkedCharts";
6
6
  import { ThemeProvider, useTheme } from "./ThemeProvider";
7
7
  import { exportChart } from "./export/exportChart";
@@ -22,8 +22,8 @@ import { RealtimeTemporalHistogram, RealtimeHistogram } from "./charts/realtime/
22
22
  import { RealtimeSwarmChart } from "./charts/realtime/RealtimeSwarmChart";
23
23
  import { RealtimeWaterfallChart } from "./charts/realtime/RealtimeWaterfallChart";
24
24
  import { RealtimeHeatmap } from "./charts/realtime/RealtimeHeatmap";
25
- export { StreamXYFrame, StreamOrdinalFrame, StreamNetworkFrame, Scatterplot, ConnectedScatterplot, LineChart, AreaChart, StackedAreaChart, Heatmap, BubbleChart, BarChart, StackedBarChart, SwarmPlot, BoxPlot, Histogram, ViolinPlot, RidgelinePlot, DotPlot, ForceDirectedGraph, ChordDiagram, SankeyDiagram, TreeDiagram, PieChart, DonutChart, GroupedBarChart, Treemap, CirclePack, OrbitDiagram, ScatterplotMatrix, MinimapChart, LinkedCharts, ThemeProvider, useTheme, exportChart, toConfig, fromConfig, toURL, fromURL, copyConfig, configToJSX, serializeSelections, deserializeSelections, fromVegaLite, ChartErrorBoundary, ChartContainer, ChartGrid, CategoryColorProvider, useCategoryColors, ContextLayout, DetailsPanel, Tooltip, MultiLineTooltip, normalizeTooltip, RingBuffer, IncrementalExtent, RealtimeLineChart, RealtimeTemporalHistogram, RealtimeHistogram, RealtimeSwarmChart, RealtimeWaterfallChart, RealtimeHeatmap };
26
- export { ScatterplotProps, ConnectedScatterplotProps, LineChartProps, AreaChartProps, StackedAreaChartProps, HeatmapProps, BubbleChartProps, BarChartProps, StackedBarChartProps, SwarmPlotProps, BoxPlotProps, HistogramProps, ViolinPlotProps, DotPlotProps, PieChartProps, DonutChartProps, GroupedBarChartProps, RidgelinePlotProps, OrbitDiagramProps, OrbitNode, ForceDirectedGraphProps, ChordDiagramProps, SankeyDiagramProps, TreeDiagramProps, TreemapProps, CirclePackProps, ScatterplotMatrixProps, MinimapChartProps, MinimapConfig, BaseChartProps, AxisConfig, Accessor, ChartAccessor, ChartMode } from "./charts";
25
+ export { StreamXYFrame, StreamOrdinalFrame, StreamNetworkFrame, Scatterplot, ConnectedScatterplot, LineChart, AreaChart, StackedAreaChart, Heatmap, BubbleChart, BarChart, StackedBarChart, SwarmPlot, BoxPlot, Histogram, ViolinPlot, RidgelinePlot, DotPlot, ForceDirectedGraph, ChordDiagram, SankeyDiagram, TreeDiagram, PieChart, DonutChart, GroupedBarChart, Treemap, CirclePack, OrbitDiagram, ScatterplotMatrix, MinimapChart, QuadrantChart, LinkedCharts, ThemeProvider, useTheme, exportChart, toConfig, fromConfig, toURL, fromURL, copyConfig, configToJSX, serializeSelections, deserializeSelections, fromVegaLite, ChartErrorBoundary, ChartContainer, ChartGrid, CategoryColorProvider, useCategoryColors, ContextLayout, DetailsPanel, Tooltip, MultiLineTooltip, normalizeTooltip, RingBuffer, IncrementalExtent, RealtimeLineChart, RealtimeTemporalHistogram, RealtimeHistogram, RealtimeSwarmChart, RealtimeWaterfallChart, RealtimeHeatmap };
26
+ export { ScatterplotProps, ConnectedScatterplotProps, LineChartProps, AreaChartProps, StackedAreaChartProps, HeatmapProps, BubbleChartProps, BarChartProps, StackedBarChartProps, SwarmPlotProps, BoxPlotProps, HistogramProps, ViolinPlotProps, DotPlotProps, PieChartProps, DonutChartProps, GroupedBarChartProps, RidgelinePlotProps, OrbitDiagramProps, OrbitNode, ForceDirectedGraphProps, ChordDiagramProps, SankeyDiagramProps, TreeDiagramProps, TreemapProps, CirclePackProps, ScatterplotMatrixProps, MinimapChartProps, MinimapConfig, QuadrantChartProps, QuadrantsConfig, QuadrantConfig, CenterlineStyle, BaseChartProps, AxisConfig, Accessor, ChartAccessor, ChartMode } from "./charts";
27
27
  export type { StreamXYFrameProps, StreamXYFrameHandle, StreamChartType, RuntimeMode, SceneNode, Changeset, StreamScales, StreamLayout, CurveType, CanvasRendererFn } from "./stream/types";
28
28
  export type { StreamRendererFn } from "./stream/renderers/types";
29
29
  export type { StreamOrdinalFrameProps, StreamOrdinalFrameHandle, OrdinalChartType, OrdinalScales, OrdinalSceneNode } from "./stream/ordinalTypes";
@@ -49,7 +49,7 @@ export type { VegaLiteSpec, VegaLiteEncoding } from "./data/fromVegaLite";
49
49
  export type { SerializedSelections, SerializedSelection, SerializedFieldSelection } from "./export/selectionSerializer";
50
50
  export { smartTickFormat } from "./charts/shared/formatUtils";
51
51
  export type { TooltipProp, TooltipConfig, TooltipField, MultiLineTooltipConfig } from "./Tooltip/Tooltip";
52
- export type { ArrowOfTime, WindowMode, ThresholdType, LineStyle, BarStyle, WaterfallStyle, SwarmStyle, AnnotationContext, CrosshairStyle, HoverAnnotationConfig, HoverData } from "./realtime/types";
52
+ export type { ArrowOfTime, WindowMode, ThresholdType, LineStyle, BarStyle, WaterfallStyle, SwarmStyle, AnnotationContext, AnnotationAnchorMode, CrosshairStyle, HoverAnnotationConfig, HoverData } from "./realtime/types";
53
53
  export type { RealtimeLineChartProps } from "./charts/realtime/RealtimeLineChart";
54
54
  export type { RealtimeTemporalHistogramProps, RealtimeHistogramProps } from "./charts/realtime/RealtimeHistogram";
55
55
  export type { RealtimeSwarmChartProps } from "./charts/realtime/RealtimeSwarmChart";
@@ -8,9 +8,11 @@
8
8
  import type { StreamXYFrameProps } from "../stream/types";
9
9
  import type { StreamNetworkFrameProps } from "../stream/networkTypes";
10
10
  import type { StreamOrdinalFrameProps } from "../stream/ordinalTypes";
11
- type FrameType = "xy" | "ordinal" | "network";
12
- export declare function renderToStaticSVG(frameType: FrameType, props: StreamXYFrameProps | StreamNetworkFrameProps | StreamOrdinalFrameProps): string;
11
+ import type { StreamGeoFrameProps } from "../stream/geoTypes";
12
+ type FrameType = "xy" | "ordinal" | "network" | "geo";
13
+ export declare function renderToStaticSVG(frameType: FrameType, props: StreamXYFrameProps | StreamNetworkFrameProps | StreamOrdinalFrameProps | StreamGeoFrameProps): string;
13
14
  export declare function renderXYToStaticSVG(props: StreamXYFrameProps): string;
14
15
  export declare function renderOrdinalToStaticSVG(props: StreamOrdinalFrameProps): string;
15
16
  export declare function renderNetworkToStaticSVG(props: StreamNetworkFrameProps): string;
17
+ export declare function renderGeoToStaticSVG(props: StreamGeoFrameProps): string;
16
18
  export {};
@@ -0,0 +1,50 @@
1
+ import * as React from "react";
2
+ /** Scene node type used by the accessible data table — accepts any frame's scene nodes */
3
+ type AnySceneNode = {
4
+ type: string;
5
+ [key: string]: any;
6
+ };
7
+ /**
8
+ * Compute an aria-label describing the chart type and data shape from the scene graph.
9
+ */
10
+ export declare function computeCanvasAriaLabel(scene: AnySceneNode[], chartType: string): string;
11
+ /**
12
+ * Compute an aria-label for network charts from scene nodes and edges.
13
+ */
14
+ export declare function computeNetworkAriaLabel(nodeCount: number, edgeCount: number, chartType: string): string;
15
+ interface AccessibleDataTableProps {
16
+ scene: AnySceneNode[];
17
+ chartType: string;
18
+ }
19
+ /**
20
+ * Visually-hidden data table for screen readers, generated from the scene graph.
21
+ * Renders up to 50 rows with a truncation note.
22
+ */
23
+ export declare function AccessibleDataTable({ scene, chartType }: AccessibleDataTableProps): React.JSX.Element | null;
24
+ interface NetworkAccessibleDataTableProps {
25
+ nodes: Array<{
26
+ datum?: any;
27
+ id?: string;
28
+ cx?: number;
29
+ cy?: number;
30
+ x?: number;
31
+ y?: number;
32
+ }>;
33
+ edges: Array<{
34
+ datum?: any;
35
+ source?: string;
36
+ target?: string;
37
+ }>;
38
+ chartType: string;
39
+ }
40
+ /**
41
+ * Visually-hidden data table for network charts.
42
+ */
43
+ export declare function NetworkAccessibleDataTable({ nodes, edges, chartType }: NetworkAccessibleDataTableProps): React.JSX.Element | null;
44
+ /**
45
+ * Visually-hidden aria-live region that mirrors tooltip text for screen readers.
46
+ */
47
+ export declare function AriaLiveTooltip({ hoverPoint }: {
48
+ hoverPoint: any;
49
+ }): React.JSX.Element;
50
+ export {};
@@ -1,5 +1,6 @@
1
- import type { SceneNode } from "./types";
1
+ import type { SceneNode, PointSceneNode } from "./types";
2
2
  import type { RingBuffer } from "../realtime/RingBuffer";
3
+ import type { Quadtree } from "d3-quadtree";
3
4
  export interface HitResult {
4
5
  node: SceneNode;
5
6
  datum: any;
@@ -10,8 +11,13 @@ export interface HitResult {
10
11
  /**
11
12
  * Find the nearest scene node to the given pixel coordinates.
12
13
  * Dispatches to type-specific hit testers for optimal performance.
14
+ *
15
+ * When a quadtree spatial index is provided (for scatter/bubble charts with
16
+ * many points), point hit testing uses O(log n) quadtree.find() instead of
17
+ * iterating all nodes. Non-point node types (line, rect, area, etc.) still
18
+ * use the linear scan.
13
19
  */
14
- export declare function findNearestNode(scene: SceneNode[], px: number, py: number, maxDistance?: number): HitResult | null;
20
+ export declare function findNearestNode(scene: SceneNode[], px: number, py: number, maxDistance?: number, pointQuadtree?: Quadtree<PointSceneNode> | null): HitResult | null;
15
21
  /**
16
22
  * Binary search for nearest point by time value in a RingBuffer.
17
23
  */
@@ -4,9 +4,23 @@ export declare class DataSourceAdapter<T = Record<string, any>> {
4
4
  private callback;
5
5
  private lastBoundedData;
6
6
  private chunkTimer;
7
- constructor(callback: ChangesetCallback<T>);
7
+ private chunkThreshold;
8
+ private chunkSize;
9
+ /** Buffer for batching high-frequency push() calls */
10
+ private pushBuffer;
11
+ /** Whether a microtask flush is already scheduled */
12
+ private flushScheduled;
13
+ constructor(callback: ChangesetCallback<T>, options?: {
14
+ chunkThreshold?: number;
15
+ chunkSize?: number;
16
+ });
17
+ /** Update chunking options without recreating the adapter. */
18
+ updateChunkOptions(options: {
19
+ chunkThreshold?: number;
20
+ chunkSize?: number;
21
+ }): void;
8
22
  /** Clear the dedup cache so the next setBoundedData call re-ingests even the same reference.
9
- * Also cancels any in-flight progressive chunking. */
23
+ * Also cancels any in-flight progressive chunking and discards buffered pushes. */
10
24
  clearLastData(): void;
11
25
  /**
12
26
  * Ingest a bounded data array (from props).
@@ -18,16 +32,31 @@ export declare class DataSourceAdapter<T = Record<string, any>> {
18
32
  * animation frames (bounded: false so they append without clearing).
19
33
  */
20
34
  setBoundedData(data: T[]): void;
35
+ /**
36
+ * Flush all buffered push data as a single changeset.
37
+ * Called automatically via microtask after push()/pushMany().
38
+ */
39
+ private flushPushBuffer;
40
+ /** Schedule a microtask flush if one isn't already pending. */
41
+ private scheduleFlush;
21
42
  /**
22
43
  * Push a single datum (streaming mode).
23
- * Emits a micro-changeset with `bounded: false`.
44
+ * Data is buffered and flushed as a single changeset via microtask,
45
+ * so rapid sequential push() calls within the same task are batched
46
+ * into one callback invocation.
24
47
  */
25
48
  push(datum: T): void;
26
49
  /**
27
50
  * Push multiple data (streaming batch).
28
- * Emits a single changeset with `bounded: false`.
51
+ * Like push(), data is buffered and flushed via microtask. Multiple
52
+ * pushMany() calls within the same task are coalesced.
29
53
  */
30
54
  pushMany(data: T[]): void;
55
+ /**
56
+ * Immediately flush any buffered push data without waiting for the microtask.
57
+ * Useful when you need the data to be processed synchronously (e.g., in tests).
58
+ */
59
+ flush(): void;
31
60
  /**
32
61
  * Reset the adapter state.
33
62
  */
@@ -0,0 +1,19 @@
1
+ import type { GeoSceneNode } from "./geoTypes";
2
+ import type { PointSceneNode } from "./types";
3
+ import type { Quadtree } from "d3-quadtree";
4
+ export interface GeoHitResult {
5
+ node: GeoSceneNode;
6
+ distance: number;
7
+ }
8
+ /**
9
+ * Hit test geo scene nodes.
10
+ *
11
+ * Strategy:
12
+ * 1. Points first (topmost visual layer) — quadtree if available, else linear scan
13
+ * 2. Geo areas via ctx.isPointInPath(Path2D) — reverse order for top-layer-wins
14
+ * 3. Lines via closest-segment distance
15
+ *
16
+ * The `hitCtx` parameter is a shared offscreen canvas context used for
17
+ * isPointInPath checks without polluting the visible canvas.
18
+ */
19
+ export declare function findNearestGeoNode(nodes: GeoSceneNode[], mouseX: number, mouseY: number, maxDistance: number, hitCtx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, pointQuadtree?: Quadtree<PointSceneNode>): GeoHitResult | null;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * GeoParticlePool — particle system for geo line paths.
3
+ *
4
+ * Unlike the network ParticlePool (which uses bezier curves), this
5
+ * travels particles along polyline paths (arrays of screen-space points).
6
+ * Used by StreamGeoFrame to animate flow lines on maps.
7
+ */
8
+ export interface GeoParticle {
9
+ /** Progress along the polyline [0, 1] */
10
+ t: number;
11
+ /** Perpendicular offset from path centerline [-0.5, 0.5] */
12
+ offset: number;
13
+ /** Which line index this particle travels */
14
+ lineIndex: number;
15
+ active: boolean;
16
+ x: number;
17
+ y: number;
18
+ }
19
+ export interface GeoParticleStyle {
20
+ /** Particle radius @default 2 */
21
+ radius?: number;
22
+ /** Particle color: a CSS color string, "source" to inherit from line stroke, or a function `(datum) => string` */
23
+ color?: string | ((datum: any) => string);
24
+ /** Particle opacity @default 0.7 */
25
+ opacity?: number;
26
+ /** Speed multiplier @default 1 */
27
+ speedMultiplier?: number;
28
+ /** Max particles per line @default 30 */
29
+ maxPerLine?: number;
30
+ /** Spawn rate (probability per frame per line) @default 0.15 */
31
+ spawnRate?: number;
32
+ }
33
+ export declare class GeoParticlePool {
34
+ particles: GeoParticle[];
35
+ private capacity;
36
+ constructor(capacity: number);
37
+ spawn(lineIndex: number): GeoParticle | null;
38
+ /**
39
+ * Advance all active particles.
40
+ * @param paths - array of polyline paths, one per line index
41
+ * @param lineWidths - strokeWidth per line (for perpendicular offset scaling)
42
+ */
43
+ step(deltaTime: number, speed: number, paths: [number, number][][], lineWidths: number[]): void;
44
+ countForLine(lineIndex: number): number;
45
+ clear(): void;
46
+ }
@@ -0,0 +1,81 @@
1
+ import type { ZoomTransform } from "d3-zoom";
2
+ import type { GeoPipelineConfig, GeoScales, GeoSceneNode } from "./geoTypes";
3
+ import type { StreamLayout } from "./types";
4
+ import type { ActiveTransition } from "./pipelineTransitionUtils";
5
+ export declare class GeoPipelineStore {
6
+ config: GeoPipelineConfig;
7
+ scene: GeoSceneNode[];
8
+ scales: GeoScales | null;
9
+ version: number;
10
+ private projection;
11
+ private geoPath;
12
+ private baseScale;
13
+ private baseTranslate;
14
+ private baseRotation;
15
+ currentZoom: number;
16
+ cartogramLayout: {
17
+ cx: number;
18
+ cy: number;
19
+ maxCost: number;
20
+ availableRadius: number;
21
+ } | null;
22
+ private areas;
23
+ private pointData;
24
+ private lineData;
25
+ private pointBuffer;
26
+ private streaming;
27
+ lastIngestTime: number;
28
+ private timestampBuffer;
29
+ activeTransition: ActiveTransition | null;
30
+ private prevPositions;
31
+ constructor(config: GeoPipelineConfig);
32
+ updateConfig(config: Partial<GeoPipelineConfig>): void;
33
+ setAreas(features: GeoJSON.Feature[]): void;
34
+ setPoints(data: Record<string, any>[]): void;
35
+ setLines(data: Record<string, any>[]): void;
36
+ /** Initialize streaming mode with a ring buffer */
37
+ initStreaming(windowSize?: number): void;
38
+ /** Push a single streaming point */
39
+ pushPoint(datum: Record<string, any>): void;
40
+ /** Push multiple streaming points */
41
+ pushMany(data: Record<string, any>[]): void;
42
+ clear(): void;
43
+ computeScene(layout: StreamLayout): void;
44
+ private fitProjection;
45
+ /**
46
+ * Apply a d3-zoom transform to the projection.
47
+ * Called on zoom end — updates projection scale/translate and rebuilds scene.
48
+ */
49
+ applyZoomTransform(transform: ZoomTransform, layout: StreamLayout): void;
50
+ /**
51
+ * Apply zoom as scale-only (no translate shift).
52
+ * Used in drag-rotate mode to prevent globe drift on zoom.
53
+ */
54
+ applyZoomScale(k: number, layout: StreamLayout): void;
55
+ /**
56
+ * Apply a rotation to the projection and rebuild the scene.
57
+ * Called during drag-rotate gestures (orthographic globe spinning).
58
+ */
59
+ applyRotation(rotation: [number, number, number], layout: StreamLayout): void;
60
+ /**
61
+ * Set the projection rotation without rebuilding the scene.
62
+ * Use when rotation will be followed by another operation that rebuilds
63
+ * (e.g., applyZoomScale), to avoid redundant scene builds.
64
+ */
65
+ setRotation(rotation: [number, number, number]): void;
66
+ /** Get current rotation (for external tracking) */
67
+ getRotation(): [number, number, number];
68
+ /** Get the current base projection state (for zoom reset) */
69
+ getBaseProjectionState(): {
70
+ scale: number;
71
+ translate: [number, number];
72
+ };
73
+ private getPoints;
74
+ private buildSceneNodes;
75
+ private applyCartogramTransform;
76
+ private applyDecay;
77
+ private applyPulse;
78
+ get hasActivePulses(): boolean;
79
+ private startTransition;
80
+ advanceTransition(now: number): boolean;
81
+ }
@@ -0,0 +1,31 @@
1
+ import type { GeoProjection } from "d3-geo";
2
+ export type TileURLTemplate = string | ((z: number, x: number, y: number, dpr: number) => string);
3
+ interface CachedTile {
4
+ img: HTMLImageElement;
5
+ loaded: boolean;
6
+ key: string;
7
+ lastUsed: number;
8
+ }
9
+ export declare class TileCache {
10
+ private cache;
11
+ private limit;
12
+ constructor(limit?: number);
13
+ get(key: string): CachedTile | undefined;
14
+ set(key: string, entry: CachedTile): void;
15
+ private evict;
16
+ clear(): void;
17
+ }
18
+ export interface TileRenderOptions {
19
+ tileURL: TileURLTemplate;
20
+ projection: GeoProjection;
21
+ width: number;
22
+ height: number;
23
+ tileCache: TileCache;
24
+ onTileLoad?: () => void;
25
+ }
26
+ /**
27
+ * Render visible tiles onto a canvas context.
28
+ * Returns true if all visible tiles are loaded (no pending fetches).
29
+ */
30
+ export declare function renderTiles(ctx: CanvasRenderingContext2D, options: TileRenderOptions): boolean;
31
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { ParticlePool } from "./ParticlePool";
2
+ import type { ActiveTransition } from "./pipelineTransitionUtils";
2
3
  import type { NetworkPipelineConfig, NetworkSceneNode, NetworkSceneEdge, NetworkLabel, RealtimeNode, RealtimeEdge, EdgePush } from "./networkTypes";
3
4
  /**
4
5
  * NetworkPipelineStore — stateful store for the StreamNetworkFrame.
@@ -20,13 +21,12 @@ export declare class NetworkPipelineStore {
20
21
  particlePool: ParticlePool | null;
21
22
  private config;
22
23
  private tensionConfig;
23
- transition: {
24
- startTime: number;
25
- duration: number;
26
- } | null;
24
+ transition: ActiveTransition | null;
27
25
  lastIngestTime: number;
28
26
  private nodeTimestamps;
29
27
  private edgeTimestamps;
28
+ /** Cached sorted node-timestamp entries for applyDecay(); null = needs rebuild */
29
+ private _decaySortedNodes;
30
30
  /** Node IDs added in the most recent layout */
31
31
  addedNodes: Set<string>;
32
32
  /** Node IDs removed in the most recent layout */
@@ -39,6 +39,11 @@ export declare class NetworkPipelineStore {
39
39
  lastTopologyChangeTime: number;
40
40
  private previousNodeIds;
41
41
  private previousEdgeKeys;
42
+ /** Snapshot of node positions from the last layout — used for force warm-start */
43
+ _lastPositionSnapshot: Map<string, {
44
+ x: number;
45
+ y: number;
46
+ }> | null;
42
47
  constructor(config: NetworkPipelineConfig);
43
48
  updateConfig(config: NetworkPipelineConfig): void;
44
49
  /**
@@ -68,6 +73,13 @@ export declare class NetworkPipelineStore {
68
73
  * Build the scene graph from current layout positions.
69
74
  */
70
75
  buildScene(size: [number, number]): void;
76
+ /** Whether the current layout plugin drives continuous animation (respects orbitAnimated config) */
77
+ get isAnimating(): boolean;
78
+ /**
79
+ * Advance the layout animation by one frame (e.g. orbit rotation).
80
+ * Returns true if the scene should be rebuilt.
81
+ */
82
+ tickAnimation(size: [number, number], deltaTime: number): boolean;
71
83
  /**
72
84
  * Advance the transition animation. Returns true if still animating.
73
85
  */
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import type { ReactNode } from "react";
3
3
  import type { NetworkLabel } from "./networkTypes";
4
- import type { LegendGroup } from "../types/legendTypes";
4
+ import type { LegendGroup, GradientLegendConfig } from "../types/legendTypes";
5
5
  export interface NetworkSVGOverlayProps {
6
6
  width: number;
7
7
  height: number;
@@ -20,6 +20,8 @@ export interface NetworkSVGOverlayProps {
20
20
  /** Legend configuration */
21
21
  legend?: ReactNode | {
22
22
  legendGroups: LegendGroup[];
23
+ } | {
24
+ gradient: GradientLegendConfig;
23
25
  };
24
26
  legendHoverBehavior?: (item: {
25
27
  label: string;
@@ -29,6 +31,7 @@ export interface NetworkSVGOverlayProps {
29
31
  }) => void;
30
32
  legendHighlightedCategory?: string | null;
31
33
  legendIsolatedCategories?: Set<string>;
34
+ legendPosition?: "right" | "left" | "top" | "bottom";
32
35
  /** User-provided SVG elements on top */
33
36
  foregroundGraphics?: ReactNode;
34
37
  /** Scene nodes for annotation positioning */
@@ -1,6 +1,7 @@
1
1
  import { type ScaleLinear } from "d3-scale";
2
2
  import type { OrdinalPipelineConfig, OrdinalScales, OrdinalSceneNode, OrdinalColumn, OrdinalLayout } from "./ordinalTypes";
3
3
  import type { Changeset } from "./types";
4
+ import type { ActiveTransition } from "./pipelineTransitionUtils";
4
5
  export declare class OrdinalPipelineStore {
5
6
  private buffer;
6
7
  private rExtent;
@@ -17,15 +18,16 @@ export declare class OrdinalPipelineStore {
17
18
  private getConnector;
18
19
  /** Discovered categories in insertion order */
19
20
  private categories;
21
+ /** True once a non-bounded (push) changeset has been ingested */
22
+ private _hasStreamingData;
20
23
  /** Lazy color map built from colorScheme for resolvePieceStyle */
21
24
  private _colorSchemeMap;
22
25
  private _colorSchemeIndex;
23
26
  private timestampBuffer;
24
- activeTransition: {
25
- startTime: number;
26
- duration: number;
27
- } | null;
27
+ activeTransition: ActiveTransition | null;
28
28
  private prevPositionMap;
29
+ /** Exit nodes awaiting fade-out removal */
30
+ exitNodes: import("./ordinalTypes").OrdinalSceneNode[];
29
31
  lastIngestTime: number;
30
32
  scales: OrdinalScales | null;
31
33
  /** Per-accessor scales for multiAxis */
@@ -53,6 +55,8 @@ export declare class OrdinalPipelineStore {
53
55
  private applyDecay;
54
56
  private applyPulse;
55
57
  get hasActivePulses(): boolean;
58
+ /** Build a stable identity key for a scene node based on its content, not array index */
59
+ private getNodeKey;
56
60
  private snapshotPositions;
57
61
  private startTransition;
58
62
  advanceTransition(now: number): boolean;
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import type { OrdinalScales } from "./ordinalTypes";
3
3
  import type { AnnotationContext } from "../realtime/types";
4
4
  import type { ReactNode } from "react";
5
- import type { LegendGroup } from "../types/legendTypes";
5
+ import type { LegendGroup, GradientLegendConfig } from "../types/legendTypes";
6
6
  interface OrdinalSVGOverlayProps {
7
7
  width: number;
8
8
  height: number;
@@ -24,6 +24,8 @@ interface OrdinalSVGOverlayProps {
24
24
  title?: string | ReactNode;
25
25
  legend?: ReactNode | {
26
26
  legendGroups: LegendGroup[];
27
+ } | {
28
+ gradient: GradientLegendConfig;
27
29
  };
28
30
  legendHoverBehavior?: (item: {
29
31
  label: string;
@@ -33,6 +35,7 @@ interface OrdinalSVGOverlayProps {
33
35
  }) => void;
34
36
  legendHighlightedCategory?: string | null;
35
37
  legendIsolatedCategories?: Set<string>;
38
+ legendPosition?: "right" | "left" | "top" | "bottom";
36
39
  foregroundGraphics?: ReactNode;
37
40
  annotations?: Record<string, any>[];
38
41
  svgAnnotationRules?: (annotation: Record<string, any>, index: number, context: AnnotationContext) => ReactNode;
@@ -40,7 +43,26 @@ interface OrdinalSVGOverlayProps {
40
43
  xAccessor?: string;
41
44
  yAccessor?: string;
42
45
  annotationData?: Record<string, any>[];
46
+ /** When true, grid lines and axis baselines are skipped (rendered by OrdinalSVGUnderlay instead) */
47
+ underlayRendered?: boolean;
43
48
  children?: ReactNode;
44
49
  }
50
+ interface OrdinalSVGUnderlayProps {
51
+ width: number;
52
+ height: number;
53
+ totalWidth: number;
54
+ totalHeight: number;
55
+ margin: {
56
+ top: number;
57
+ right: number;
58
+ bottom: number;
59
+ left: number;
60
+ };
61
+ scales: OrdinalScales | null;
62
+ showAxes?: boolean;
63
+ showGrid?: boolean;
64
+ rFormat?: (d: number) => string;
65
+ }
66
+ export declare function OrdinalSVGUnderlay(props: OrdinalSVGUnderlayProps): React.JSX.Element | null;
45
67
  export declare function OrdinalSVGOverlay(props: OrdinalSVGOverlayProps): React.JSX.Element | null;
46
68
  export {};