semiotic 3.5.1 → 3.5.3

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 (127) hide show
  1. package/CLAUDE.md +26 -23
  2. package/README.md +27 -21
  3. package/ai/chartSuggestions.cjs +191 -3
  4. package/ai/componentMetadata.cjs +3 -3
  5. package/ai/dist/mcp-server.js +266 -48
  6. package/ai/examples.md +68 -0
  7. package/ai/schema.json +914 -1
  8. package/ai/system-prompt.md +4 -1
  9. package/dist/components/ThemeProvider.d.ts +2 -2
  10. package/dist/components/Tooltip/FlippingTooltip.d.ts +16 -1
  11. package/dist/components/charts/geo/FlowMap.d.ts +13 -4
  12. package/dist/components/charts/index.d.ts +6 -0
  13. package/dist/components/charts/network/OrbitDiagram.d.ts +5 -5
  14. package/dist/components/charts/network/ProcessSankey.d.ts +163 -0
  15. package/dist/components/charts/network/SankeyDiagram.d.ts +5 -1
  16. package/dist/components/charts/network/processSankey/algorithm.d.ts +193 -0
  17. package/dist/components/charts/network/processSankey/buildScenes.d.ts +51 -0
  18. package/dist/components/charts/network/processSankey/ribbonInputs.d.ts +32 -0
  19. package/dist/components/charts/network/processSankey/streamingLayout.d.ts +71 -0
  20. package/dist/components/charts/network/processSankey/tooltipUtils.d.ts +41 -0
  21. package/dist/components/charts/ordinal/BarChart.d.ts +12 -0
  22. package/dist/components/charts/ordinal/DotPlot.d.ts +9 -0
  23. package/dist/components/charts/ordinal/GaugeChart.d.ts +20 -0
  24. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +5 -0
  25. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +2 -0
  26. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +16 -11
  27. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +2 -0
  28. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +2 -0
  29. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +2 -0
  30. package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +19 -0
  31. package/dist/components/charts/shared/axisExtent.d.ts +59 -0
  32. package/dist/components/charts/shared/chartSpecs.d.ts +75 -0
  33. package/dist/components/charts/shared/colorUtils.d.ts +8 -2
  34. package/dist/components/charts/shared/networkUtils.d.ts +3 -5
  35. package/dist/components/charts/shared/radialGeometry.d.ts +99 -0
  36. package/dist/components/charts/shared/regressionUtils.d.ts +59 -0
  37. package/dist/components/charts/shared/selectionUtils.d.ts +8 -1
  38. package/dist/components/charts/shared/streamPropsHelpers.d.ts +5 -0
  39. package/dist/components/charts/shared/tooltipUtils.d.ts +11 -0
  40. package/dist/components/charts/shared/types.d.ts +19 -0
  41. package/dist/components/charts/shared/useAreaSeriesSetup.d.ts +78 -0
  42. package/dist/components/charts/shared/useChartSetup.d.ts +2 -0
  43. package/dist/components/charts/shared/useCustomChartSetup.d.ts +1 -0
  44. package/dist/components/charts/shared/useEncodingDomain.d.ts +48 -0
  45. package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +1 -1
  46. package/dist/components/charts/shared/useNetworkChartSetup.d.ts +150 -0
  47. package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +87 -0
  48. package/dist/components/charts/shared/useSeriesFeatures.d.ts +57 -0
  49. package/dist/components/charts/shared/useStreamStatus.d.ts +33 -0
  50. package/dist/components/charts/shared/useXYLineStyle.d.ts +69 -0
  51. package/dist/components/charts/shared/useXYPointStyle.d.ts +87 -0
  52. package/dist/components/charts/shared/withChartWrapper.d.ts +10 -3
  53. package/dist/components/charts/xy/AreaChart.d.ts +36 -2
  54. package/dist/components/charts/xy/BubbleChart.d.ts +9 -0
  55. package/dist/components/charts/xy/ConnectedScatterplot.d.ts +16 -0
  56. package/dist/components/charts/xy/DifferenceChart.d.ts +172 -0
  57. package/dist/components/charts/xy/LineChart.d.ts +26 -2
  58. package/dist/components/charts/xy/Scatterplot.d.ts +39 -1
  59. package/dist/components/geometry/ribbonGeometry.d.ts +76 -0
  60. package/dist/components/semiotic-ai.d.ts +2 -0
  61. package/dist/components/semiotic-network.d.ts +4 -0
  62. package/dist/components/semiotic-realtime.d.ts +2 -0
  63. package/dist/components/semiotic-utils.d.ts +4 -0
  64. package/dist/components/semiotic-xy.d.ts +2 -0
  65. package/dist/components/semiotic.d.ts +4 -4
  66. package/dist/components/server/renderToStaticSVG.d.ts +2 -1
  67. package/dist/components/server/serverChartConfigs.d.ts +3 -0
  68. package/dist/components/server/staticAnnotations.d.ts +1 -1
  69. package/dist/components/server/themeResolver.d.ts +7 -1
  70. package/dist/components/store/ThemeStore.d.ts +7 -1
  71. package/dist/components/stream/AccessibleDataTable.d.ts +2 -2
  72. package/dist/components/stream/GeoPipelineStore.d.ts +21 -0
  73. package/dist/components/stream/OrdinalSVGOverlay.d.ts +8 -0
  74. package/dist/components/stream/PipelineStore.d.ts +25 -13
  75. package/dist/components/stream/SVGOverlay.d.ts +9 -18
  76. package/dist/components/stream/accessorUtils.d.ts +2 -1
  77. package/dist/components/stream/annotationAccessorResolver.d.ts +39 -0
  78. package/dist/components/stream/geoTypes.d.ts +12 -0
  79. package/dist/components/stream/layouts/hierarchyLayoutPlugin.d.ts +1 -1
  80. package/dist/components/stream/networkTypes.d.ts +11 -0
  81. package/dist/components/stream/ordinalTypes.d.ts +27 -1
  82. package/dist/components/stream/renderers/cornerRadii.d.ts +33 -0
  83. package/dist/components/stream/renderers/wedgePathBuilder.d.ts +56 -0
  84. package/dist/components/stream/types.d.ts +127 -11
  85. package/dist/components/stream/xySceneBuilders/areaGradient.d.ts +20 -0
  86. package/dist/components/stream/xySceneBuilders/barScene.d.ts +2 -2
  87. package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +2 -2
  88. package/dist/components/stream/xySceneBuilders/heatmapScene.d.ts +2 -2
  89. package/dist/components/stream/xySceneBuilders/lineScene.d.ts +4 -3
  90. package/dist/components/stream/xySceneBuilders/pointScene.d.ts +2 -2
  91. package/dist/components/stream/xySceneBuilders/ribbonScene.d.ts +107 -0
  92. package/dist/components/stream/xySceneBuilders/swarmScene.d.ts +2 -2
  93. package/dist/components/stream/xySceneBuilders/types.d.ts +9 -12
  94. package/dist/components/stream/xySceneBuilders/waterfallScene.d.ts +2 -2
  95. package/dist/components/types/legendTypes.d.ts +1 -1
  96. package/dist/geo.min.js +1 -1
  97. package/dist/geo.module.min.js +1 -1
  98. package/dist/network.min.js +1 -1
  99. package/dist/network.module.min.js +1 -1
  100. package/dist/ordinal.min.js +1 -1
  101. package/dist/ordinal.module.min.js +1 -1
  102. package/dist/realtime.min.js +1 -1
  103. package/dist/realtime.module.min.js +1 -1
  104. package/dist/semiotic-ai.d.ts +2 -0
  105. package/dist/semiotic-ai.min.js +1 -1
  106. package/dist/semiotic-ai.module.min.js +1 -1
  107. package/dist/semiotic-data.min.js +1 -1
  108. package/dist/semiotic-data.module.min.js +1 -1
  109. package/dist/semiotic-network.d.ts +4 -0
  110. package/dist/semiotic-realtime.d.ts +2 -0
  111. package/dist/semiotic-recipes.min.js +1 -1
  112. package/dist/semiotic-recipes.module.min.js +1 -1
  113. package/dist/semiotic-themes.min.js +1 -1
  114. package/dist/semiotic-themes.module.min.js +1 -1
  115. package/dist/semiotic-utils.d.ts +4 -0
  116. package/dist/semiotic-utils.min.js +1 -1
  117. package/dist/semiotic-utils.module.min.js +1 -1
  118. package/dist/semiotic-xy.d.ts +2 -0
  119. package/dist/semiotic.d.ts +4 -4
  120. package/dist/semiotic.min.js +1 -1
  121. package/dist/semiotic.module.min.js +1 -1
  122. package/dist/server.min.js +1 -1
  123. package/dist/server.module.min.js +1 -1
  124. package/dist/xy.min.js +1 -1
  125. package/dist/xy.module.min.js +1 -1
  126. package/package.json +23 -10
  127. package/dist/components/stream/xySceneBuilders/boundsScene.d.ts +0 -9
@@ -0,0 +1,59 @@
1
+ /**
2
+ * regressionUtils — sugar for the `trend` annotation.
3
+ *
4
+ * The `trend` annotation type (see annotationRules.tsx) already
5
+ * computes and renders linear / polynomial / LOESS regression lines
6
+ * for any chart that exposes x/y scales. This module wraps that into
7
+ * a chart-prop ergonomic — `regression={true}`, `regression="loess"`,
8
+ * or a full config object — so users don't have to author an
9
+ * annotation object by hand for the most common cases.
10
+ *
11
+ * Mirrors the shape of LineChart's `forecast` and `anomaly` props,
12
+ * which are likewise sugar over annotation-side work.
13
+ */
14
+ import type { Datum } from "./datumTypes";
15
+ /** Regression methods supported by the trend annotation. */
16
+ export type RegressionMethod = "linear" | "polynomial" | "loess";
17
+ /**
18
+ * Full regression configuration. All visual props mirror the
19
+ * underlying `trend` annotation; users dropping into the `annotations`
20
+ * array directly can pass the same shape.
21
+ */
22
+ export interface RegressionConfig {
23
+ /** Regression method. @default "linear" */
24
+ method?: RegressionMethod;
25
+ /** LOESS bandwidth (0–1). Lower = more local detail. @default 0.3 */
26
+ bandwidth?: number;
27
+ /** Polynomial order (only for `method: "polynomial"`). @default 2 */
28
+ order?: number;
29
+ /** Stroke color for the regression line. @default "#6366f1" */
30
+ color?: string;
31
+ /** Stroke width. @default 2 */
32
+ strokeWidth?: number;
33
+ /** Dash pattern. @default "6,3" */
34
+ strokeDasharray?: string;
35
+ /** Optional label rendered at the line's right end. */
36
+ label?: string;
37
+ }
38
+ /**
39
+ * Prop shape on chart HOCs. The boolean form gives users a
40
+ * "just draw a regression line" toggle; the string form picks the
41
+ * method with default styling; the object form opens up the full
42
+ * configuration. Mirrors `forecast` / `anomaly` on LineChart.
43
+ */
44
+ export type RegressionProp = boolean | RegressionMethod | RegressionConfig;
45
+ /**
46
+ * Convert a `regression` prop value into the trend-annotation object
47
+ * to splice into the chart's annotations array. Returns `undefined`
48
+ * when the prop is falsy so callers can skip the spread.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const trendAnn = buildRegressionAnnotation(regression)
53
+ * const annotations = [
54
+ * ...(trendAnn ? [trendAnn] : []),
55
+ * ...(userAnnotations || []),
56
+ * ]
57
+ * ```
58
+ */
59
+ export declare function buildRegressionAnnotation(regression: RegressionProp | undefined): Datum | undefined;
@@ -65,5 +65,12 @@ export declare const DEFAULT_SELECTION_OPACITY = 0.5;
65
65
  * Dimming opacity is resolved in this order:
66
66
  * 1. `config.unselectedOpacity` (explicit, usually per-chart or theme-merged)
67
67
  * 2. `DEFAULT_SELECTION_OPACITY`
68
+ *
69
+ * Variadic in the trailing args so callers can pass `(datum, group)` —
70
+ * the `group` argument that `PipelineStore.resolveLineStyle` threads
71
+ * through for line/area styles must reach the wrapped base function,
72
+ * or group-dependent styling (`fillArea: string[]`, `resolveStroke(d,
73
+ * group)` in `useXYLineStyle`'s MultiAxisLineChart path) silently
74
+ * drops to its no-group branch whenever a selection is active.
68
75
  */
69
- export declare function wrapStyleWithSelection(baseStyleFn: (d: Datum) => Datum, selectionHook: SelectionHookResult | null, config?: SelectionStyleConfig): (d: Datum) => Datum;
76
+ export declare function wrapStyleWithSelection<TArgs extends unknown[]>(baseStyleFn: (d: Datum, ...args: TArgs) => Datum, selectionHook: SelectionHookResult | null, config?: SelectionStyleConfig): (d: Datum, ...args: TArgs) => Datum;
@@ -43,6 +43,11 @@ export interface BaseMetadataProps {
43
43
  accessibleTable?: boolean;
44
44
  className?: string;
45
45
  animate?: AnimateProp;
46
+ /** Strictly speaking not "metadata" — but the spread-when-defined
47
+ * pattern is identical, and every XY/ordinal HOC needs to forward
48
+ * this to the frame. Bundling it here avoids a parallel helper
49
+ * + 22 separate adoption edits. */
50
+ axisExtent?: import("./axisExtent").AxisExtentMode;
46
51
  }
47
52
  export declare function buildBaseMetadataProps(input: BaseMetadataProps): BaseMetadataProps;
48
53
  /**
@@ -21,6 +21,17 @@ export interface TooltipFieldConfig {
21
21
  export declare function accessorName(acc: string | ((...args: any[]) => any)): string;
22
22
  export declare function formatVal(v: unknown): string;
23
23
  export declare function resolveValue(d: Datum, acc: string | ((d: Datum) => any)): unknown;
24
+ /**
25
+ * Build TooltipFieldConfig rows for a `band` prop config so the default
26
+ * tooltip surfaces envelope values automatically. Reads from the
27
+ * `bands` array the hover handler synthesizes onto the datum — one
28
+ * row pair per configured band (low + high). String accessors are
29
+ * used verbatim as labels; function accessors fall back to "low"/"high".
30
+ *
31
+ * Returns an empty array when band is not configured, so the spread at
32
+ * the call site is a no-op for the common case.
33
+ */
34
+ export declare function bandTooltipFields(band: unknown, valueFormat?: (v: any, ...rest: any[]) => React.ReactNode): TooltipFieldConfig[];
24
35
  /**
25
36
  * Build a default tooltipContent function for StreamXYFrame HOCs.
26
37
  * Receives HoverData ({ data, time, value, x, y }) and renders
@@ -78,6 +78,12 @@ export interface BaseChartProps {
78
78
  chartId?: string;
79
79
  /** Show a loading skeleton placeholder */
80
80
  loading?: boolean;
81
+ /** Custom content to render in place of the default skeleton when `loading` is `true`.
82
+ * Sibling to `emptyContent` — use for branded loading states or progress UI.
83
+ * When omitted, the built-in shimmer-bar skeleton renders.
84
+ * Pass `false` to suppress the loading UI entirely (an outer wrapper's
85
+ * loading state takes over). */
86
+ loadingContent?: React.ReactNode | false;
81
87
  /** Custom content to render when data is empty. Set to `false` to disable empty state. */
82
88
  emptyContent?: React.ReactNode | false;
83
89
  /** Uniform fill color for all data marks. Overrides colorScheme and theme categorical.
@@ -117,6 +123,19 @@ export interface BaseChartProps {
117
123
  * `true` uses defaults (300ms ease-out, intro enabled). Object form allows customization.
118
124
  * Set `{ intro: false }` to disable the animated intro on first render. */
119
125
  animate?: AnimateProp;
126
+ /** Axis extent mode. `"nice"` (default) uses d3-scale's rounded
127
+ * tick generator — labels stay round but ticks may sit inside the
128
+ * data domain. `"exact"` pins the first and last tick to the
129
+ * actual data min and max with equidistant intermediate ticks.
130
+ * Useful when a fixed scale (gauge, score band, KPI dial) needs
131
+ * endpoints to read as the actual boundaries.
132
+ *
133
+ * Applies to:
134
+ * - XY charts: both x and y axes (linear, time, log).
135
+ * - Ordinal charts: the value (r) axis only — the categorical
136
+ * axis is a band scale and doesn't have a numeric tick set.
137
+ * - Network / geo / hierarchy charts: no-op (no continuous axis). */
138
+ axisExtent?: import("./axisExtent").AxisExtentMode;
120
139
  }
121
140
  /**
122
141
  * Axis configuration props
@@ -0,0 +1,78 @@
1
+ import type { ReactNode } from "react";
2
+ import type { Datum } from "./datumTypes";
3
+ import type { Accessor, ChartAccessor } from "./types";
4
+ import type { SelectionHookResult } from "./selectionUtils";
5
+ import type { HoverData } from "../../stream/types";
6
+ export interface AreaSeriesSetupOptions<TDatum extends Datum = Datum> {
7
+ /** Sparse-filtered data array (the HOC's `safeData`). */
8
+ safeData: TDatum[];
9
+ /** Original `data` prop — used to short-circuit to push-mode flatten. */
10
+ data: TDatum[] | undefined;
11
+ /** Group accessor (`areaBy` on the HOC). When set, flat data is
12
+ * grouped into one series per distinct value. */
13
+ areaBy?: ChartAccessor<TDatum, string>;
14
+ /** Field on grouped objects that contains the coordinate array.
15
+ * Convention: `"coordinates"`. Pre-grouped input is detected by
16
+ * presence of this field on the first row. */
17
+ lineDataAccessor: string;
18
+ /** Effective color accessor (already resolved by HOC: AreaChart =
19
+ * `colorBy`; StackedAreaChart = `colorBy || areaBy`). */
20
+ colorBy?: Accessor<string> | ChartAccessor<TDatum, string>;
21
+ /** Resolved categorical color scale from `useChartSetup`. */
22
+ colorScale: ((v: string) => string) | undefined;
23
+ /** Top-level uniform `color` prop. */
24
+ color?: string;
25
+ /** Top-level primitive props — applied last so they win over
26
+ * HOC base + (future) user style. */
27
+ stroke?: string;
28
+ strokeWidth?: number;
29
+ opacity?: number;
30
+ /** Selection hook output (`setup.effectiveSelectionHook`). */
31
+ effectiveSelectionHook: SelectionHookResult | null | undefined;
32
+ /** Resolved selection config (`setup.resolvedSelection`). */
33
+ resolvedSelection: import("./types").SelectionConfig | undefined;
34
+ /** Area fillOpacity. @default 0.7 */
35
+ areaOpacity: number;
36
+ /** Render line on top of fill. @default true */
37
+ showLine: boolean;
38
+ /** Line stroke width. @default 2 */
39
+ lineWidth: number;
40
+ /** Render points along the line. @default false */
41
+ showPoints: boolean;
42
+ /** Point radius when `showPoints`. @default 3 */
43
+ pointRadius: number;
44
+ xAccessor: ChartAccessor<TDatum, number | Date | string>;
45
+ yAccessor: ChartAccessor<TDatum, number>;
46
+ xLabel?: string;
47
+ yLabel?: string;
48
+ /** Tooltip-side x formatter — same signature as `AxisConfig.xFormat`
49
+ * so the HOC can forward the prop verbatim. ReactNode return is OK. */
50
+ xFormat?: (d: number | Date | string, index?: number, allTicks?: number[]) => string | ReactNode;
51
+ yFormat?: (d: number | Date | string) => string | ReactNode;
52
+ /** Field used to label the series row in the default tooltip.
53
+ * Typically `areaBy ?? colorBy`. */
54
+ groupField?: Accessor<string> | ChartAccessor<TDatum, string>;
55
+ /** Optional band prop — when set, the default tooltip surfaces a
56
+ * pair of rows per band (low + high). Threaded through verbatim. */
57
+ band?: unknown;
58
+ }
59
+ export interface AreaSeriesSetupResult<TDatum extends Datum = Datum> {
60
+ /** Flat data array ready for `<StreamXYFrame data={…} />`. Empty
61
+ * when the HOC is in push mode (no `data` prop). */
62
+ flattenedData: TDatum[];
63
+ /** Selection-aware line/area style fn. */
64
+ lineStyle: (d: Datum) => Record<string, string | number>;
65
+ /** Selection-aware point style fn — `undefined` when `showPoints`
66
+ * is false so the HOC can spread it conditionally. */
67
+ pointStyle: ((d: Datum) => Record<string, string | number>) | undefined;
68
+ /** Default tooltip content fn for the chart. */
69
+ defaultTooltipContent: (hover: HoverData) => ReactNode;
70
+ }
71
+ /**
72
+ * Build the area-series pieces for an area-shaped XY HOC.
73
+ * The HOC still owns chart-specific frame props (chartType,
74
+ * gradientFill, normalize, baseline, stackOrder) and all the
75
+ * passthrough wiring; this hook covers the part both shared
76
+ * verbatim before extraction.
77
+ */
78
+ export declare function useAreaSeriesSetup<TDatum extends Datum = Datum>(options: AreaSeriesSetupOptions<TDatum>): AreaSeriesSetupResult<TDatum>;
@@ -60,6 +60,8 @@ export interface ChartSetupInput {
60
60
  hoverHighlight?: boolean;
61
61
  /** Loading state */
62
62
  loading: boolean | undefined;
63
+ /** Custom content rendered in place of the default skeleton while `loading` is true. */
64
+ loadingContent?: ReactNode | false;
63
65
  /** Empty content override */
64
66
  emptyContent?: ReactNode;
65
67
  /** Resolved width from useChartMode */
@@ -64,6 +64,7 @@ interface DataSetupOptions extends ScaffoldOptions {
64
64
  }) => void;
65
65
  chartId?: string;
66
66
  loading?: boolean;
67
+ loadingContent?: ReactNode | false;
67
68
  emptyContent?: ReactNode;
68
69
  }
69
70
  interface DataSetupResult<TFrameHandle> extends ScaffoldResult<TFrameHandle> {
@@ -0,0 +1,48 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor } from "./types";
3
+ export interface EncodingDomainOptions<TDatum extends Datum = Datum> {
4
+ /** Encoding accessor (string field name or function). */
5
+ accessor: Accessor<number> | undefined;
6
+ /** Bounded chart data. Ignored when `isPushMode` is true. */
7
+ data: TDatum[];
8
+ /** When true, the hook tracks pushed values via the returned
9
+ * `trackPushed` helper instead of reading `data`. */
10
+ isPushMode: boolean;
11
+ }
12
+ export interface EncodingDomainResult<TDatum extends Datum = Datum> {
13
+ /** `[min, max]` tuple over seen values. Undefined when no data has
14
+ * been seen yet (push mode initial state, or bounded mode with
15
+ * empty data + no accessor). */
16
+ domain: [number, number] | undefined;
17
+ /** Walk `items` and update the running domain. Bumps the version
18
+ * counter when any min/max actually moves. No-op in bounded mode
19
+ * — the hook reads from `data` directly there. */
20
+ trackPushed: (items: TDatum[]) => void;
21
+ /** Reset the running domain to empty. Paired with the HOC's
22
+ * `clear()` override. No-op in bounded mode. */
23
+ reset: () => void;
24
+ }
25
+ /**
26
+ * Track a numeric encoding's `[min, max]` domain across bounded and
27
+ * push data sources.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * // BubbleChart-style usage:
32
+ * const { domain: sizeDomain, trackPushed, reset } = useEncodingDomain({
33
+ * accessor: sizeBy,
34
+ * data: safeData,
35
+ * isPushMode: data === undefined,
36
+ * })
37
+ *
38
+ * useFrameImperativeHandle(ref, {
39
+ * variant: "xy", frameRef,
40
+ * overrides: {
41
+ * push: (d) => { trackPushed([d]); frameRef.current?.push(d) },
42
+ * pushMany: (ds) => { trackPushed(ds); frameRef.current?.pushMany(ds) },
43
+ * clear: () => { reset(); frameRef.current?.clear() },
44
+ * },
45
+ * })
46
+ * ```
47
+ */
48
+ export declare function useEncodingDomain<TDatum extends Datum = Datum>(options: EncodingDomainOptions<TDatum>): EncodingDomainResult<TDatum>;
@@ -1,6 +1,6 @@
1
1
  import type { Ref, RefObject, DependencyList } from "react";
2
2
  import type { RealtimeFrameHandle } from "../../realtime/types";
3
- type FrameVariant = "xy" | "network" | "geo-points";
3
+ type FrameVariant = "xy" | "network" | "geo-points" | "geo-lines";
4
4
  interface Options {
5
5
  /**
6
6
  * Variant decides which default method bodies are emitted. The
@@ -0,0 +1,150 @@
1
+ import type { ReactNode, ReactElement } from "react";
2
+ import type { Datum } from "./datumTypes";
3
+ import type { Accessor, ChartAccessor, SelectionConfig, LinkedHoverProp } from "./types";
4
+ import type { OnObservationCallback } from "../../store/ObservationStore";
5
+ import type { PartialMargin, MarginType } from "../../types/marginType";
6
+ import { useChartSelection, useChartLegendAndMargin } from "./hooks";
7
+ import type { LegendInteractionMode, LegendPosition, LegendInteractionState } from "./hooks";
8
+ export interface NetworkChartSetupInput<TNode extends Datum = Datum, TEdge extends Datum = Datum> {
9
+ /** Raw `nodes` prop (may be undefined). */
10
+ nodes: TNode[] | undefined;
11
+ /** Raw `edges` prop (may be undefined). */
12
+ edges: TEdge[] | undefined;
13
+ /**
14
+ * When `true`, missing nodes are inferred from edge endpoints via
15
+ * `inferNodesFromEdges`. Sankey/Chord set this; ForceDirected leaves
16
+ * it `false` and treats both as required. Default: `true`.
17
+ */
18
+ inferNodes?: boolean;
19
+ /** Node id accessor for inference + tooltip identity. */
20
+ nodeIdAccessor?: ChartAccessor<TNode, string>;
21
+ /** Edge source accessor (used by `inferNodesFromEdges`). */
22
+ sourceAccessor?: ChartAccessor<TEdge, string>;
23
+ /** Edge target accessor (used by `inferNodesFromEdges`). */
24
+ targetAccessor?: ChartAccessor<TEdge, string>;
25
+ colorBy?: Accessor<string>;
26
+ colorScheme?: string | string[];
27
+ /** `undefined` defaults to "auto" (on when colorBy is set). */
28
+ showLegend?: boolean;
29
+ legendPosition?: LegendPosition;
30
+ legendInteraction?: LegendInteractionMode;
31
+ selection?: SelectionConfig;
32
+ linkedHover?: LinkedHoverProp;
33
+ onObservation?: OnObservationCallback;
34
+ onClick?: (datum: Datum, event: {
35
+ x: number;
36
+ y: number;
37
+ }) => void;
38
+ /** Used by useChartSelection for chart-type-stamped observation events. */
39
+ chartType: string;
40
+ chartId?: string;
41
+ /** Mode-resolved margin defaults from useChartMode. */
42
+ marginDefaults: MarginType;
43
+ /** User-provided margin override. */
44
+ userMargin?: PartialMargin;
45
+ width: number;
46
+ height: number;
47
+ loading?: boolean;
48
+ /** Custom content rendered in place of the default skeleton while `loading` is true. */
49
+ loadingContent?: ReactNode | false;
50
+ emptyContent?: ReactNode | false;
51
+ /**
52
+ * Which array drives the empty-state check. `"edges"` (default)
53
+ * fits Sankey/Chord/ProcessSankey where edges are the primary
54
+ * data shape and nodes are optional/inferred. `"nodes"` fits
55
+ * ForceDirectedGraph where both nodes and edges are required and
56
+ * empty-state should fire when the user supplied a sparse-only
57
+ * node list. The undefined-vs-empty distinction is preserved
58
+ * either way: undefined = push mode (don't show empty UI);
59
+ * present-but-empty = user supplied empty data (show empty UI).
60
+ */
61
+ emptyDataKey?: "edges" | "nodes";
62
+ }
63
+ export interface NetworkChartSetupResult {
64
+ /**
65
+ * Sparse-filtered nodes. When `inferNodes` was `true` and the
66
+ * caller didn't supply nodes, this is the inferred `[{id}]` array
67
+ * derived from edge endpoints. Otherwise it's just the input
68
+ * `nodes` with sparse holes removed.
69
+ */
70
+ safeNodes: Datum[];
71
+ /** Sparse-filtered edges. Identity-equal to input when nothing was dropped. */
72
+ safeEdges: Datum[];
73
+ /**
74
+ * Color scale built from `(safeNodes, colorBy, colorScheme)`.
75
+ * `undefined` when colorBy is unset.
76
+ */
77
+ colorScale: ((v: string) => string) | undefined;
78
+ /**
79
+ * Effective palette array. Resolved as:
80
+ * 1. `colorScheme` if it's an array.
81
+ * 2. ThemeProvider categorical if non-empty.
82
+ * 3. Named scheme lookup in `COLOR_SCHEMES`.
83
+ * 4. `DEFAULT_COLORS` fallback.
84
+ *
85
+ * Pass this to the frame's `colorScheme` prop so its internal
86
+ * `getNodeColor` (used for particles, hover, interactions) matches
87
+ * what the HOC's nodeStyle resolves.
88
+ */
89
+ effectivePalette: string[];
90
+ themeCategorical: string[] | undefined;
91
+ /** Distinct category values from `(safeNodes, colorBy)`, for legend interaction. */
92
+ allCategories: string[];
93
+ legendState: LegendInteractionState;
94
+ legend: ReturnType<typeof useChartLegendAndMargin>["legend"];
95
+ margin: MarginType;
96
+ legendPosition: LegendPosition;
97
+ customHoverBehavior: ReturnType<typeof useChartSelection>["customHoverBehavior"];
98
+ customClickBehavior: ReturnType<typeof useChartSelection>["customClickBehavior"];
99
+ /**
100
+ * The full selection-hook output. Most network HOCs only need the
101
+ * resolved hover/click behaviors above, but hierarchy charts
102
+ * (Treemap, CirclePack, TreeDiagram, OrbitDiagram) wrap node styles
103
+ * with selection state via `activeSelectionHook.isActive` /
104
+ * `.predicate`. Passed through verbatim so those charts don't need
105
+ * a parallel `useChartSelection` call.
106
+ */
107
+ activeSelectionHook: ReturnType<typeof useChartSelection>["activeSelectionHook"];
108
+ hoverSelectionHook: ReturnType<typeof useChartSelection>["hoverSelectionHook"];
109
+ crosshairSourceId: ReturnType<typeof useChartSelection>["crosshairSourceId"];
110
+ /** When non-null, render this element instead of the chart. */
111
+ loadingEl: ReactElement | null;
112
+ /** When non-null, render this element instead of the chart. */
113
+ emptyEl: ReactElement | null;
114
+ }
115
+ /**
116
+ * Run the consolidated network-HOC setup pipeline. Call this once
117
+ * after `useChartMode` and before any chart-specific logic. The
118
+ * returned `loadingEl`/`emptyEl` are early-exit slots — when either
119
+ * is non-null, return it before the frame.
120
+ *
121
+ * @example
122
+ * ```tsx
123
+ * const setup = useNetworkChartSetup({
124
+ * nodes, edges,
125
+ * inferNodes: true,
126
+ * nodeIdAccessor, sourceAccessor, targetAccessor,
127
+ * colorBy, colorScheme, showLegend, legendPosition, legendInteraction,
128
+ * selection, linkedHover, onObservation, onClick,
129
+ * chartType: "SankeyDiagram", chartId,
130
+ * marginDefaults, userMargin, width, height,
131
+ * loading, emptyContent,
132
+ * })
133
+ * if (setup.loadingEl) return setup.loadingEl
134
+ * if (setup.emptyEl) return setup.emptyEl
135
+ * return (
136
+ * <StreamNetworkFrame
137
+ * nodes={setup.safeNodes}
138
+ * edges={setup.safeEdges}
139
+ * colorScheme={setup.effectivePalette}
140
+ * legend={setup.legend}
141
+ * legendPosition={setup.legendPosition}
142
+ * margin={setup.margin}
143
+ * customHoverBehavior={setup.customHoverBehavior}
144
+ * customClickBehavior={setup.customClickBehavior}
145
+ * ...
146
+ * />
147
+ * )
148
+ * ```
149
+ */
150
+ export declare function useNetworkChartSetup<TNode extends Datum = Datum, TEdge extends Datum = Datum>(input: NetworkChartSetupInput<TNode, TEdge>): NetworkChartSetupResult;
@@ -0,0 +1,87 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor, ChartAccessor } from "./types";
3
+ import type { SelectionHookResult } from "./selectionUtils";
4
+ export interface OrdinalPieceStyleOptions {
5
+ /** colorBy accessor — string field name or function */
6
+ colorBy?: Accessor<string> | ChartAccessor<Datum, string>;
7
+ /** Resolved categorical color scale (typically from useChartSetup). */
8
+ colorScale: ((v: string) => string) | undefined;
9
+ /** Top-level uniform `color` prop (BaseChartProps). Applied as a
10
+ * default-fill primitive when `colorBy` is unset. */
11
+ color?: string;
12
+ /** Theme categorical palette (from useThemeCategorical). */
13
+ themeCategorical: string[] | undefined;
14
+ /** colorScheme prop — array or string scheme name. */
15
+ colorScheme?: string | string[];
16
+ /** Stable category-index map for default-fill cycling. */
17
+ categoryIndexMap: Map<string, number>;
18
+ /** User-supplied `frameProps.pieceStyle`. Accepts the looser
19
+ * Frame-side `Style` type (typed fields like `fill: string`) or a
20
+ * function returning the same shape; we don't pin a stricter
21
+ * contract here because every ordinal HOC re-types pieceStyle
22
+ * via its own props interface. */
23
+ userPieceStyle?: ((d: Datum, category?: string) => Record<string, unknown>) | Record<string, unknown> | unknown;
24
+ /** Top-level primitive props — applied last so they win over HOC base + user overlay. */
25
+ stroke?: string;
26
+ strokeWidth?: number;
27
+ opacity?: number;
28
+ /**
29
+ * Chart-shape defaults applied BEFORE the color resolution and
30
+ * user overlay. Use for properties that are intrinsic to the
31
+ * chart's mark shape (point radius `r`, fillOpacity for swarms /
32
+ * dots, etc.). User-supplied `frameProps.pieceStyle` and top-level
33
+ * primitive props can still override them.
34
+ *
35
+ * Static object form for shape-constant defaults
36
+ * (`{ r: dotRadius, fillOpacity: 0.8 }` — DotPlot). Function form
37
+ * for per-datum derivation (`(d) => ({ r: sizeBy ? getSize(d, ...) :
38
+ * pointRadius })` — SwarmPlot's size-encoded points). The function
39
+ * receives the same `(d, category)` args as user pieceStyle.
40
+ */
41
+ baseStyleExtras?: Record<string, string | number | undefined> | ((d: Datum, category?: string) => Record<string, string | number | undefined>);
42
+ /**
43
+ * After the base fill is resolved, also write it to `stroke`.
44
+ * Used by statistical-summary charts (BoxPlot / ViolinPlot /
45
+ * RidgelinePlot / Histogram) where the box outline should match
46
+ * the box fill rather than be a separate stroke. Top-level
47
+ * primitive `stroke` still wins via `mergeShapeStyle` if supplied.
48
+ */
49
+ linkStrokeToFill?: boolean;
50
+ /**
51
+ * When `colorBy` is unset, pass the per-piece `category` to
52
+ * `resolveDefaultFill` so each piece cycles through the
53
+ * colorScheme's palette (Pie / Donut / Funnel / radial charts —
54
+ * each slice/wedge wants its own color).
55
+ *
56
+ * When `false` (default), the category arg is omitted and
57
+ * `resolveDefaultFill` returns the first scheme color uniformly
58
+ * (BarChart / StackedBarChart / GroupedBarChart — bars without
59
+ * `colorBy` should be one color, since the user picked
60
+ * `categoryAccessor` but explicitly didn't ask for category-driven
61
+ * coloring). Locked by `bugRepros.test.tsx` BR-2.
62
+ */
63
+ cycleByCategory?: boolean;
64
+ /** Selection hook output (typically `setup.effectiveSelectionHook`). */
65
+ effectiveSelectionHook: SelectionHookResult | null | undefined;
66
+ /** Resolved selection config (typically `setup.resolvedSelection`). */
67
+ resolvedSelection: import("./types").SelectionConfig | undefined;
68
+ }
69
+ /**
70
+ * Build a memoized `pieceStyle` function that the chart can pass
71
+ * straight to `<StreamOrdinalFrame pieceStyle={…} />`. Composes the
72
+ * standard base-fill / user-overlay / primitive-prop / selection
73
+ * pipeline so each HOC doesn't re-derive it.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * const pieceStyle = useOrdinalPieceStyle({
78
+ * colorBy, colorScale: setup.colorScale,
79
+ * color, themeCategorical, colorScheme, categoryIndexMap,
80
+ * userPieceStyle: frameProps?.pieceStyle,
81
+ * stroke, strokeWidth, opacity,
82
+ * effectiveSelectionHook: setup.effectiveSelectionHook,
83
+ * resolvedSelection: setup.resolvedSelection,
84
+ * })
85
+ * ```
86
+ */
87
+ export declare function useOrdinalPieceStyle(options: OrdinalPieceStyleOptions): (d: Datum, category?: string) => Record<string, string | number | undefined>;
@@ -0,0 +1,57 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor } from "./types";
3
+ import type { ForecastConfig, AnomalyConfig } from "./statisticalOverlays";
4
+ export interface SeriesFeaturesOptions {
5
+ /** Sparse-filtered chart data (the HOC's `safeData`). */
6
+ data: Datum[];
7
+ /** x accessor — string or function. */
8
+ xAccessor: Accessor<number | Date | string>;
9
+ /** y accessor — string or function. */
10
+ yAccessor: Accessor<number>;
11
+ /** Optional forecast configuration. When set, the hook adds
12
+ * segment-tagged future points to `effectiveData` and appends
13
+ * envelope/forecast-line annotations. */
14
+ forecast?: ForecastConfig | undefined;
15
+ /** Optional anomaly configuration (band + dot overlay). */
16
+ anomaly?: AnomalyConfig | undefined;
17
+ /** When the consuming HOC supports grouped series (e.g. LineChart's
18
+ * `lineBy`), pass the grouping field name so the overlay pipeline
19
+ * can do group-aware boundary duplication. Required when the same
20
+ * data array carries multiple metric series interleaved by x. */
21
+ groupBy?: Accessor<string> | undefined;
22
+ }
23
+ export interface SeriesFeaturesResult {
24
+ /** Data to forward to the frame. When forecast adds future points,
25
+ * this is the augmented set; otherwise the original `data`. */
26
+ effectiveData: Datum[];
27
+ /** Annotations the chart should merge into its own annotations
28
+ * array (envelope, anomaly band, anomaly dots). Empty when
29
+ * forecast/anomaly are unset or still loading. */
30
+ statisticalAnnotations: Datum[];
31
+ /** True when forecast is active and processedData differs from
32
+ * the input data. Useful for HOC-side branches (e.g. LineChart's
33
+ * compound-group accessor). */
34
+ hasForecast: boolean;
35
+ /** Resolved string key for the x axis — either the user's string
36
+ * accessor or a synthetic key written by the bake step. The
37
+ * forecast/anomaly pipeline reads through this key. */
38
+ xAccessorKey: string;
39
+ /** Resolved string key for the y axis (mirror of xAccessorKey). */
40
+ yAccessorKey: string;
41
+ }
42
+ /**
43
+ * Build series feature overlays (forecast + anomaly) for a chart.
44
+ * Returns the effective data + annotations to merge into the
45
+ * chart's stream-frame props. Returns the input data unchanged when
46
+ * neither prop is set.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const { effectiveData, statisticalAnnotations } = useSeriesFeatures({
51
+ * data: safeData, xAccessor, yAccessor, forecast, anomaly,
52
+ * })
53
+ * const mergedAnnotations = [...(annotations || []), ...statisticalAnnotations]
54
+ * // forward effectiveData + mergedAnnotations to the frame
55
+ * ```
56
+ */
57
+ export declare function useSeriesFeatures(options: SeriesFeaturesOptions): SeriesFeaturesResult;
@@ -0,0 +1,33 @@
1
+ import type { RealtimeFrameHandle } from "../../realtime/types";
2
+ /**
3
+ * Status enum exposed by the hook.
4
+ *
5
+ * - `"idle"` — no pushes have happened yet since mount.
6
+ * - `"active"` — at least one push has happened within the
7
+ * threshold window.
8
+ * - `"stale"` — pushes have stopped or slowed; last push is older
9
+ * than `staleThresholdMs`.
10
+ */
11
+ export type StreamStatus = "idle" | "active" | "stale";
12
+ export interface StreamStatusOptions {
13
+ /** Time in ms since the last push before status flips to `"stale"`.
14
+ * @default 5000 */
15
+ staleThresholdMs?: number;
16
+ /** Polling interval for status transitions. Smaller = more
17
+ * responsive but higher cost. @default 1000 */
18
+ pollIntervalMs?: number;
19
+ }
20
+ export interface StreamStatusResult<THandle extends RealtimeFrameHandle = RealtimeFrameHandle> {
21
+ /** Ref to pass to the chart's `ref` prop. The hook intercepts
22
+ * push/pushMany calls on this ref so it can timestamp them. */
23
+ ref: React.MutableRefObject<THandle | null>;
24
+ /** Current status. Re-renders the consumer on transition. */
25
+ status: StreamStatus;
26
+ /** Timestamp (from `performance.now()`) of the most recent push,
27
+ * or null when no push has happened yet. */
28
+ lastPushTime: number | null;
29
+ }
30
+ /**
31
+ * Track ingest activity on a push-API chart and expose status.
32
+ */
33
+ export declare function useStreamStatus<THandle extends RealtimeFrameHandle = RealtimeFrameHandle>(options?: StreamStatusOptions): StreamStatusResult<THandle>;