semiotic 3.5.0 → 3.5.2

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 (105) hide show
  1. package/CLAUDE.md +21 -19
  2. package/README.md +22 -16
  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 +900 -1
  8. package/ai/system-prompt.md +4 -1
  9. package/dist/components/Tooltip/FlippingTooltip.d.ts +16 -1
  10. package/dist/components/charts/geo/FlowMap.d.ts +13 -4
  11. package/dist/components/charts/index.d.ts +6 -0
  12. package/dist/components/charts/network/OrbitDiagram.d.ts +5 -5
  13. package/dist/components/charts/network/ProcessSankey.d.ts +141 -0
  14. package/dist/components/charts/network/processSankey/algorithm.d.ts +136 -0
  15. package/dist/components/charts/network/processSankey/buildScenes.d.ts +45 -0
  16. package/dist/components/charts/network/processSankey/ribbonInputs.d.ts +32 -0
  17. package/dist/components/charts/network/processSankey/streamingLayout.d.ts +58 -0
  18. package/dist/components/charts/network/processSankey/tooltipUtils.d.ts +41 -0
  19. package/dist/components/charts/ordinal/BarChart.d.ts +14 -0
  20. package/dist/components/charts/ordinal/BoxPlot.d.ts +2 -0
  21. package/dist/components/charts/ordinal/DotPlot.d.ts +11 -0
  22. package/dist/components/charts/ordinal/GaugeChart.d.ts +20 -0
  23. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +2 -0
  24. package/dist/components/charts/ordinal/Histogram.d.ts +2 -0
  25. package/dist/components/charts/ordinal/LikertChart.d.ts +2 -0
  26. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +2 -0
  27. package/dist/components/charts/ordinal/StackedBarChart.d.ts +2 -0
  28. package/dist/components/charts/ordinal/SwarmPlot.d.ts +2 -0
  29. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +7 -0
  30. package/dist/components/charts/ordinal/ViolinPlot.d.ts +2 -0
  31. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +14 -11
  32. package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +43 -0
  33. package/dist/components/charts/shared/axisExtent.d.ts +59 -0
  34. package/dist/components/charts/shared/chartSpecs.d.ts +75 -0
  35. package/dist/components/charts/shared/colorUtils.d.ts +8 -2
  36. package/dist/components/charts/shared/networkUtils.d.ts +3 -5
  37. package/dist/components/charts/shared/radialGeometry.d.ts +99 -0
  38. package/dist/components/charts/shared/regressionUtils.d.ts +59 -0
  39. package/dist/components/charts/shared/selectionUtils.d.ts +8 -1
  40. package/dist/components/charts/shared/streamPropsHelpers.d.ts +5 -0
  41. package/dist/components/charts/shared/types.d.ts +13 -0
  42. package/dist/components/charts/shared/useAreaSeriesSetup.d.ts +75 -0
  43. package/dist/components/charts/shared/useEncodingDomain.d.ts +48 -0
  44. package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +1 -1
  45. package/dist/components/charts/shared/useNetworkChartSetup.d.ts +148 -0
  46. package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +87 -0
  47. package/dist/components/charts/shared/useSeriesFeatures.d.ts +57 -0
  48. package/dist/components/charts/shared/useStreamStatus.d.ts +33 -0
  49. package/dist/components/charts/shared/useXYLineStyle.d.ts +69 -0
  50. package/dist/components/charts/shared/useXYPointStyle.d.ts +87 -0
  51. package/dist/components/charts/xy/AreaChart.d.ts +38 -0
  52. package/dist/components/charts/xy/BubbleChart.d.ts +13 -0
  53. package/dist/components/charts/xy/CandlestickChart.d.ts +4 -0
  54. package/dist/components/charts/xy/ConnectedScatterplot.d.ts +20 -0
  55. package/dist/components/charts/xy/DifferenceChart.d.ts +172 -0
  56. package/dist/components/charts/xy/Heatmap.d.ts +4 -0
  57. package/dist/components/charts/xy/LineChart.d.ts +12 -0
  58. package/dist/components/charts/xy/MinimapChart.d.ts +7 -0
  59. package/dist/components/charts/xy/Scatterplot.d.ts +38 -0
  60. package/dist/components/charts/xy/StackedAreaChart.d.ts +12 -0
  61. package/dist/components/geometry/ribbonGeometry.d.ts +76 -0
  62. package/dist/components/semiotic-ai.d.ts +2 -0
  63. package/dist/components/semiotic-network.d.ts +4 -0
  64. package/dist/components/semiotic-realtime.d.ts +2 -0
  65. package/dist/components/semiotic-utils.d.ts +4 -0
  66. package/dist/components/semiotic-xy.d.ts +2 -0
  67. package/dist/components/semiotic.d.ts +3 -3
  68. package/dist/components/server/serverChartConfigs.d.ts +2 -0
  69. package/dist/components/stream/GeoPipelineStore.d.ts +21 -0
  70. package/dist/components/stream/OrdinalSVGOverlay.d.ts +8 -0
  71. package/dist/components/stream/PipelineStore.d.ts +5 -0
  72. package/dist/components/stream/SVGOverlay.d.ts +18 -0
  73. package/dist/components/stream/annotationAccessorResolver.d.ts +39 -0
  74. package/dist/components/stream/geoTypes.d.ts +12 -0
  75. package/dist/components/stream/ordinalTypes.d.ts +12 -0
  76. package/dist/components/stream/renderers/cornerRadii.d.ts +33 -0
  77. package/dist/components/stream/types.d.ts +23 -0
  78. package/dist/components/types/legendTypes.d.ts +1 -1
  79. package/dist/geo.min.js +1 -1
  80. package/dist/geo.module.min.js +1 -1
  81. package/dist/network.min.js +1 -1
  82. package/dist/network.module.min.js +1 -1
  83. package/dist/ordinal.min.js +1 -1
  84. package/dist/ordinal.module.min.js +1 -1
  85. package/dist/realtime.min.js +1 -1
  86. package/dist/realtime.module.min.js +1 -1
  87. package/dist/semiotic-ai.d.ts +2 -0
  88. package/dist/semiotic-ai.min.js +1 -1
  89. package/dist/semiotic-ai.module.min.js +1 -1
  90. package/dist/semiotic-network.d.ts +4 -0
  91. package/dist/semiotic-realtime.d.ts +2 -0
  92. package/dist/semiotic-recipes.min.js +1 -1
  93. package/dist/semiotic-recipes.module.min.js +1 -1
  94. package/dist/semiotic-utils.d.ts +4 -0
  95. package/dist/semiotic-utils.min.js +1 -1
  96. package/dist/semiotic-utils.module.min.js +1 -1
  97. package/dist/semiotic-xy.d.ts +2 -0
  98. package/dist/semiotic.d.ts +3 -3
  99. package/dist/semiotic.min.js +1 -1
  100. package/dist/semiotic.module.min.js +1 -1
  101. package/dist/server.min.js +1 -1
  102. package/dist/server.module.min.js +1 -1
  103. package/dist/xy.min.js +1 -1
  104. package/dist/xy.module.min.js +1 -1
  105. package/package.json +10 -5
@@ -27,6 +27,11 @@ export interface GaugeChartProps extends BaseChartProps {
27
27
  backgroundColor?: string;
28
28
  /** Arc thickness as fraction of radius (0–1, default 0.3) */
29
29
  arcWidth?: number;
30
+ /** Pixel radius for the rounded ends of each arc segment, same prop
31
+ * semantics as `DonutChart.cornerRadius`. Default `undefined`
32
+ * (sharp corners). Useful for the "pill" aesthetic where each
33
+ * threshold zone reads as a discrete capsule. */
34
+ cornerRadius?: number;
30
35
  /** Show needle indicator (default true) */
31
36
  showNeedle?: boolean;
32
37
  /** Needle color (default: var(--semiotic-text, #333)) */
@@ -94,6 +99,21 @@ export interface GaugeChartProps extends BaseChartProps {
94
99
  * fillZones
95
100
  * />
96
101
  * ```
102
+ *
103
+ * @example
104
+ * ```tsx
105
+ * // Rounded segment ends — same `cornerRadius` semantics as DonutChart.
106
+ * // Each threshold zone reads as a capsule with the others.
107
+ * <GaugeChart
108
+ * value={65}
109
+ * thresholds={[
110
+ * { value: 60, color: "#22c55e" },
111
+ * { value: 80, color: "#f59e0b" },
112
+ * { value: 100, color: "#ef4444" },
113
+ * ]}
114
+ * cornerRadius={6}
115
+ * />
116
+ * ```
97
117
  */
98
118
  export declare const GaugeChart: {
99
119
  (props: GaugeChartProps & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -32,6 +32,8 @@ export interface GroupedBarChartProps<TDatum extends Datum = Datum> extends Base
32
32
  annotations?: Datum[];
33
33
  /** Custom formatter for category tick labels */
34
34
  categoryFormat?: CategoryFormatFn;
35
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. */
36
+ valueExtent?: [number | undefined, number | undefined] | [number];
35
37
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
36
38
  }
37
39
  /**
@@ -72,6 +72,8 @@ export interface HistogramProps<TDatum extends Datum = Datum> extends BaseChartP
72
72
  };
73
73
  /** Custom formatter for category tick labels */
74
74
  categoryFormat?: CategoryFormatFn;
75
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. Wins over Histogram's auto-computed shared bin extent — useful for pinning the axis to a known range so streamed updates don't shift the bins as min/max drift. */
76
+ valueExtent?: [number | undefined, number | undefined] | [number];
75
77
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
76
78
  }
77
79
  /**
@@ -87,6 +87,8 @@ export interface LikertChartProps<TDatum extends Datum = Datum> extends BaseChar
87
87
  annotations?: Datum[];
88
88
  /** Custom formatter for category tick labels */
89
89
  categoryFormat?: CategoryFormatFn;
90
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. Likert is normally pinned to symmetric proportions; pass `valueExtent` to override. */
91
+ valueExtent?: [number | undefined, number | undefined] | [number];
90
92
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
91
93
  }
92
94
  export interface LikertChartHandle extends RealtimeFrameHandle {
@@ -29,6 +29,8 @@ export interface RidgelinePlotProps<TDatum extends Datum = Datum> extends BaseCh
29
29
  annotations?: Datum[];
30
30
  /** Custom formatter for category tick labels */
31
31
  categoryFormat?: CategoryFormatFn;
32
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. */
33
+ valueExtent?: [number | undefined, number | undefined] | [number];
32
34
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
33
35
  }
34
36
  /**
@@ -33,6 +33,8 @@ export interface StackedBarChartProps<TDatum extends Datum = Datum> extends Base
33
33
  annotations?: Datum[];
34
34
  /** Custom formatter for category tick labels */
35
35
  categoryFormat?: CategoryFormatFn;
36
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. Stacked bars auto-extend the value domain to cover the cumulative stack unless `valueExtent` is fully specified. */
37
+ valueExtent?: [number | undefined, number | undefined] | [number];
36
38
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
37
39
  }
38
40
  /**
@@ -41,6 +41,8 @@ export interface SwarmPlotProps<TDatum extends Datum = Datum> extends BaseChartP
41
41
  };
42
42
  /** Custom formatter for category tick labels */
43
43
  categoryFormat?: CategoryFormatFn;
44
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. */
45
+ valueExtent?: [number | undefined, number | undefined] | [number];
44
46
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
45
47
  }
46
48
  /**
@@ -83,6 +83,13 @@ export interface SwimlaneChartProps<TDatum extends Datum = Datum> extends BaseCh
83
83
  color: string;
84
84
  opacity?: number;
85
85
  };
86
+ /** Rounded corner radius (in pixels) for the outermost ends of each
87
+ * lane. Both ends round: left+right in horizontal orientation, top+bottom
88
+ * in vertical. Middle segments of multi-segment lanes stay square so
89
+ * pieces visually butt against each other. */
90
+ roundedTop?: number;
91
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. */
92
+ valueExtent?: [number | undefined, number | undefined] | [number];
86
93
  /** Pass-through props to StreamOrdinalFrame */
87
94
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
88
95
  }
@@ -40,6 +40,8 @@ export interface ViolinPlotProps<TDatum extends Datum = Datum> extends BaseChart
40
40
  };
41
41
  /** Custom formatter for category tick labels */
42
42
  categoryFormat?: CategoryFormatFn;
43
+ /** Fixed value-axis domain `[min, max]`. Either bound may be `undefined` to leave that side data-derived. */
44
+ valueExtent?: [number | undefined, number | undefined] | [number];
43
45
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
44
46
  }
45
47
  /**
@@ -6,7 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
6
6
  import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
7
7
  import type { OnObservationCallback } from "../../store/ObservationStore";
8
8
  import type { Datum } from "../shared/datumTypes";
9
- export interface RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> {
9
+ export interface RealtimeHistogramProps<TDatum extends Datum = Datum> {
10
10
  /** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
11
11
  mode?: ChartMode;
12
12
  /** Time interval for binning */
@@ -137,7 +137,7 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> {
137
137
  pointIdAccessor?: string | ((d: Datum) => string);
138
138
  }
139
139
  /**
140
- * RealtimeTemporalHistogram - Streaming temporal histogram.
140
+ * RealtimeHistogram - Streaming temporal histogram.
141
141
  *
142
142
  * Wraps StreamXYFrame with `chartType="bar"` and `runtimeMode="streaming"`,
143
143
  * binning pushed data points into time-windowed bars. Supports both simple
@@ -149,7 +149,7 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> {
149
149
  * @example
150
150
  * ```tsx
151
151
  * // Simple temporal histogram — push each event, the chart bins by time
152
- * <RealtimeTemporalHistogram
152
+ * <RealtimeHistogram
153
153
  * ref={ref}
154
154
  * binSize={20}
155
155
  * fill="#007bff"
@@ -160,7 +160,7 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> {
160
160
  * @example
161
161
  * ```tsx
162
162
  * // Stacked by category — same push API, color by status field
163
- * <RealtimeTemporalHistogram
163
+ * <RealtimeHistogram
164
164
  * ref={ref}
165
165
  * binSize={25}
166
166
  * categoryAccessor="category"
@@ -169,14 +169,17 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> {
169
169
  * />
170
170
  * ```
171
171
  */
172
- export declare const RealtimeTemporalHistogram: {
173
- <TDatum extends Datum = Datum>(props: RealtimeTemporalHistogramProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
172
+ export declare const RealtimeHistogram: {
173
+ <TDatum extends Datum = Datum>(props: RealtimeHistogramProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
174
174
  displayName?: string;
175
175
  };
176
- /** @deprecated Use RealtimeTemporalHistogram instead */
177
- export declare const RealtimeHistogram: {
178
- <TDatum extends Datum = Datum>(props: RealtimeTemporalHistogramProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
176
+ /** @deprecated Use `RealtimeHistogram` (the canonical public name) instead. The
177
+ * `RealtimeTemporalHistogram` alias is preserved for back-compat with code
178
+ * written before the rename and will be removed in a future major version. */
179
+ export declare const RealtimeTemporalHistogram: {
180
+ <TDatum extends Datum = Datum>(props: RealtimeHistogramProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
179
181
  displayName?: string;
180
182
  };
181
- /** @deprecated Use RealtimeTemporalHistogramProps instead */
182
- export type RealtimeHistogramProps = RealtimeTemporalHistogramProps;
183
+ /** @deprecated Use `RealtimeHistogramProps` instead. Same component, just the
184
+ * pre-rename type alias. */
185
+ export type RealtimeTemporalHistogramProps<TDatum extends Datum = Datum> = RealtimeHistogramProps<TDatum>;
@@ -40,4 +40,47 @@ export declare function buildDefaultRealtimeTooltip<TDatum extends Datum = Datum
40
40
  * scene builder).
41
41
  */
42
42
  export declare function buildWaterfallTooltip<TDatum extends Datum = Datum>(options?: DefaultRealtimeTooltipOptions<TDatum>): (d: HoverData) => ReactNode;
43
+ /**
44
+ * Histogram-specific default tooltip.
45
+ *
46
+ * The barScene's histogram path enriches each rect's datum with
47
+ * `{ binStart, binEnd, total, category?, categoryValue? }`. The generic
48
+ * `x: <time>, y: <value>` shape produces empty strings on those bins
49
+ * because neither `time` nor `value` exists on the aggregated payload.
50
+ * This builder surfaces the fields that actually carry meaning for a
51
+ * histogram bin:
52
+ *
53
+ * range: <binStart>–<binEnd>
54
+ * count: <total>
55
+ * category: <category> (only when categoryAccessor is set)
56
+ *
57
+ * Falls back to the canonical x/y shape if a bin's enriched fields are
58
+ * absent — guards against a non-streaming render path or a static frame
59
+ * that bypasses the bin scene.
60
+ */
61
+ export declare function buildHistogramTooltip<TDatum extends Datum = Datum>(options?: DefaultRealtimeTooltipOptions<TDatum>): (d: HoverData) => ReactNode;
62
+ /**
63
+ * Heatmap-specific default tooltip.
64
+ *
65
+ * The streaming heatmap aggregates raw points into 2D bins; each cell's
66
+ * datum is `{ xi, yi, value, count, sum, xCenter, yCenter, agg }`. The
67
+ * generic `x: <time>, y: <value>` shape is meaningless because the cell
68
+ * doesn't carry the user's original fields — it carries bin indices and
69
+ * aggregated counts.
70
+ *
71
+ * This tooltip surfaces the user-relevant info:
72
+ * x: <data-space x-center of the bin>
73
+ * y: <data-space y-center of the bin>
74
+ * count: 12 (when datum.count is present — streaming path)
75
+ * sum: 142 (when agg === "sum")
76
+ * mean: 11.83 (when agg === "mean")
77
+ *
78
+ * For `agg === "sum"` we always surface the sum (it's the metric the
79
+ * heatmap is colored by, even when sum happens to equal count).
80
+ *
81
+ * Falls back to the canonical x/y shape if the enriched fields are
82
+ * absent (e.g. a non-streaming render path); the count/sum/mean rows
83
+ * only appear when the matching field is present on the datum.
84
+ */
85
+ export declare function buildHeatmapTooltip<TDatum extends Datum = Datum>(options?: DefaultRealtimeTooltipOptions<TDatum>): (d: HoverData) => ReactNode;
43
86
  export {};
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Equidistant tick generation for the `axisExtent="exact"` axis mode.
3
+ *
4
+ * The default "nice" mode (d3 scale's `.ticks(count)` algorithm)
5
+ * returns aesthetically-rounded tick values WITHIN the data domain —
6
+ * the first tick may sit above the data min and the last tick may
7
+ * sit below the data max. That's the standard reading: round labels
8
+ * win, exact data bounds lose.
9
+ *
10
+ * "exact" mode reverses that tradeoff. The first tick sits exactly at
11
+ * `dataMin`, the last tick sits exactly at `dataMax`, and the
12
+ * intermediate ticks are equidistant within the domain. Labels are
13
+ * whatever the value formatter produces — often not round.
14
+ *
15
+ * Works on `scaleLinear` and `scaleTime` (operates on millisecond
16
+ * timestamps, returns Date objects so downstream formatters receive
17
+ * the same shape they get from `scale.ticks()`).
18
+ *
19
+ * `scaleLog` is supported but the ticks come out evenly spaced in
20
+ * VALUE space, not pixel space — `[1, 250.75, 500.5, 750.25, 1000]`
21
+ * instead of `[1, 10, 100, 1000]`. That's intentional for the
22
+ * "endpoints must read as the actual data bounds" use case the
23
+ * feature was added for, but it's not "equidistant on the rendered
24
+ * axis". Users that want log-space-equidistant ticks should pass
25
+ * explicit `tickValues` (e.g. `[1, 10, 100, 1000]`) — those bypass
26
+ * `axisExtent` entirely.
27
+ */
28
+ export type AxisExtentMode = "nice" | "exact";
29
+ /** A d3-style continuous scale (linear, time, log) — the bit we use.
30
+ * The `domain()` return type stays as `number[]` / `Date[]` rather
31
+ * than a strict 2-tuple because that's what d3-scale's own types
32
+ * declare (the runtime contract is "first and last elements are the
33
+ * bounds" — d3 never returns a single-element domain in practice). */
34
+ type TickableScale<T = number | Date> = {
35
+ domain(): T[];
36
+ ticks(count?: number): T[];
37
+ };
38
+ /**
39
+ * Generate `count` ticks evenly spaced across the scale's domain,
40
+ * inclusive of both endpoints. For a domain of `[lo, hi]` and a
41
+ * count of `n`, returns `[lo, lo + step, ..., hi]` where
42
+ * `step = (hi - lo) / (n - 1)`.
43
+ *
44
+ * Edge cases:
45
+ * - `count < 2` returns just the two endpoints.
46
+ * - Empty/zero-width domain returns the endpoints unchanged.
47
+ * - Date-valued domain returns Date objects (preserving the shape
48
+ * d3-scale-time's `.ticks()` returns).
49
+ */
50
+ export declare function equidistantTicks<T extends number | Date>(scale: TickableScale<T>, count: number): T[];
51
+ /**
52
+ * Return either equidistant ticks (when `mode === "exact"`) or the
53
+ * scale's own d3-generated ticks (default "nice" behavior).
54
+ *
55
+ * Centralized so XY and ordinal overlay code paths can both call
56
+ * one function instead of branching at every `.ticks()` site.
57
+ */
58
+ export declare function ticksForMode<T extends number | Date>(scale: TickableScale<T>, count: number, mode: AxisExtentMode | undefined): T[];
59
+ export {};
@@ -35,6 +35,73 @@
35
35
  export type PropType = "string" | "number" | "boolean" | "array" | "object" | "function";
36
36
  export type DataShape = "array" | "object" | "network" | "realtime" | "none";
37
37
  export type ChartCategory = "xy" | "ordinal" | "network" | "geo" | "realtime";
38
+ /**
39
+ * Capability tags for runtime behavior. Driven by the
40
+ * `hoc-frame-architecture-audit` Phase 1: each chart declares which
41
+ * features it actually supports so docs, AI/MCP tools, and CI gates
42
+ * can read structured truth instead of inferring it from the source.
43
+ *
44
+ * All fields are required so a new chart entry can't omit them
45
+ * silently — the audit's anti-goal "Do not make registry metadata
46
+ * aspirational. It should describe real runtime behavior and be
47
+ * checked." applies here.
48
+ */
49
+ export interface ChartCapabilities {
50
+ /**
51
+ * Render pipeline. `canvas` for Stream-Frame-driven charts that
52
+ * paint to canvas with SVG overlays for chrome (the common case).
53
+ * `svg` for charts that are pure SVG (none today, but reserved).
54
+ * `hybrid` for charts that use both — currently every Stream-Frame
55
+ * HOC qualifies as hybrid; reserve `canvas` for any future
56
+ * canvas-only fallback.
57
+ */
58
+ renderModes: Array<"canvas" | "svg" | "hybrid">;
59
+ /** Renders a legend swatch column when `colorBy` (or equivalent)
60
+ * resolves to non-empty categories. */
61
+ supportsLegend: boolean;
62
+ /** Reads from a `selection` prop and dims/highlights matching
63
+ * marks via `wrapStyleWithSelection` or equivalent. */
64
+ supportsSelection: boolean;
65
+ /** Produces a hover-driven selection (used by linked crosshair /
66
+ * cross-filter patterns) via `linkedHover`. */
67
+ supportsLinkedHover: boolean;
68
+ /** Exposes a ref handle (`push`, `pushMany`, etc.) so consumers
69
+ * can mutate the data list without re-rendering. Hierarchy
70
+ * charts (Treemap/CirclePack/TreeDiagram/OrbitDiagram) and
71
+ * pure-synthetic charts (GaugeChart) declare false. */
72
+ supportsPush: boolean;
73
+ /** Renders to a static SVG via `renderChart()` from `semiotic/server`
74
+ * through a registered entry in `serverChartConfigs.ts`. SSR-only
75
+ * charts (none yet) and HOC-SSR exclusions also declare false. */
76
+ supportsSSR: boolean;
77
+ /**
78
+ * How color is consumed by the chart's data marks.
79
+ * - `categorical`: discrete buckets, paired with a `colorBy` accessor.
80
+ * - `sequential`: continuous scale (heatmap intensity, choropleth value).
81
+ * - `threshold`: stepped scale with explicit breakpoints (gauge zones).
82
+ * - `continuous`: smooth interpolation along a 1-D path (gradient fill).
83
+ * - `none`: chart doesn't use color encoding (sparkline, pure layout).
84
+ */
85
+ colorModel: "categorical" | "sequential" | "threshold" | "continuous" | "none";
86
+ /**
87
+ * Where the geometry comes from.
88
+ * - `plugin`: a built-in plugin in the frame (sankey/force/chord/tree
89
+ * for network; bar/pie/swarm/etc. for ordinal; line/area/etc. for XY).
90
+ * - `custom`: emitted via the frame's customLayout escape hatch
91
+ * (ProcessSankey via `customNetworkLayout`, NetworkCustomChart,
92
+ * XYCustomChart, OrdinalCustomChart).
93
+ * - `synthetic`: no layout — the chart constructs its scene from
94
+ * the input value(s) directly (GaugeChart computes arc geometry).
95
+ */
96
+ layoutMode: "plugin" | "custom" | "synthetic";
97
+ /**
98
+ * Free-form tag list for opt-in features that don't fit the
99
+ * boolean shape — e.g. "particles", "forecast", "anomaly", "brush",
100
+ * "streamgraph", "minimap". Used by docs feature tables and
101
+ * potential capability-driven AI suggestions.
102
+ */
103
+ specialFeatures: string[];
104
+ }
38
105
  export interface ChartPropSpec {
39
106
  /** Allowed runtime types. May be a single value or a union. */
40
107
  type: PropType | PropType[];
@@ -71,6 +138,14 @@ export interface ChartSpec {
71
138
  propBags: ReadonlyArray<keyof typeof PROP_BAGS>;
72
139
  /** Chart-specific prop spec, overlaid on top of the composed bags. */
73
140
  ownProps: Record<string, ChartPropSpec>;
141
+ /**
142
+ * Capability matrix — declarative facts about runtime behavior.
143
+ * Drives docs feature tables, capability-aware AI/MCP tools, and
144
+ * the `check:capabilities` drift gate (which verifies, e.g., that
145
+ * a chart claiming `supportsSSR: true` has a matching entry in
146
+ * `serverChartConfigs.ts`).
147
+ */
148
+ capabilities: ChartCapabilities;
74
149
  }
75
150
  export declare const PROP_BAGS: {
76
151
  readonly common: Record<string, ChartPropSpec>;
@@ -62,12 +62,18 @@ export declare function getColor(dataPoint: Datum, colorBy: string | ((d: Datum)
62
62
  */
63
63
  export declare function createColorScale(data: Array<Datum>, colorBy: string, scheme?: string | string[]): (v: string) => string;
64
64
  /**
65
- * Generates a size function based on sizeBy configuration
65
+ * Generates a size function based on sizeBy configuration.
66
+ *
67
+ * Output is clamped to `sizeRange`. A pushed point whose `sizeBy`
68
+ * value falls outside the currently-known domain (which can happen
69
+ * in push mode before the running min/max catches up) renders at
70
+ * the boundary radius rather than producing an arbitrarily large
71
+ * (or negative) pixel value.
66
72
  *
67
73
  * @param dataPoint - The data point
68
74
  * @param sizeBy - Field name or function to determine size
69
75
  * @param sizeRange - Min and max size range [min, max]
70
76
  * @param domain - Optional domain for scaling [minValue, maxValue]
71
- * @returns Size value
77
+ * @returns Size value, clamped to `sizeRange` when a domain is given
72
78
  */
73
79
  export declare function getSize(dataPoint: Datum, sizeBy: string | ((d: Datum) => number), sizeRange?: [number, number], domain?: [number, number]): number;
@@ -4,15 +4,13 @@ import type { Accessor } from "./types";
4
4
  * Flatten a hierarchical data structure into an array of all nodes
5
5
  * by recursively traversing children.
6
6
  */
7
- export declare function flattenHierarchy(data: Datum | null, childrenAccessor: string | ((d: Datum) => any[])): Array<Datum>;
7
+ export declare function flattenHierarchy(data: Datum | null, childrenAccessor: string | ((d: Datum) => Datum[])): Array<Datum>;
8
8
  /**
9
9
  * Infer nodes from edges when a nodes array is not provided.
10
10
  * Extracts unique source/target IDs and returns `{ id }` objects.
11
11
  * Returns the provided nodes array if it's non-empty.
12
12
  */
13
- export declare function inferNodesFromEdges(nodes: any[] | undefined, edges: any[], sourceAccessor: string | ((d: Datum) => string), targetAccessor: string | ((d: Datum) => string)): Array<{
14
- id: string;
15
- }>;
13
+ export declare function inferNodesFromEdges(nodes: Datum[] | undefined, edges: Datum[], sourceAccessor: string | ((d: Datum) => string), targetAccessor: string | ((d: Datum) => string)): Datum[];
16
14
  /**
17
15
  * Convert a valueAccessor prop into a hierarchy sum function.
18
16
  * Used by TreeDiagram, Treemap, and CirclePack for d3-hierarchy's `.sum()`.
@@ -26,7 +24,7 @@ export declare function createEdgeStyleFn({ edgeColorBy, colorBy, colorScale, no
26
24
  edgeColorBy: "source" | "target" | "gradient" | ((d: Datum) => string);
27
25
  colorBy: Accessor<string> | undefined;
28
26
  colorScale: ((v: string) => string) | undefined;
29
- nodeStyleFn: (d: any, index?: number) => Datum;
27
+ nodeStyleFn: (d: Datum, index?: number) => Datum;
30
28
  edgeOpacity: number;
31
29
  baseStyle?: Record<string, string | number>;
32
30
  }): (d: Datum) => Datum;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * radialGeometry — pure math helpers for radial chart authoring.
3
+ *
4
+ * The original consumer is `GaugeChart`, which needs to:
5
+ * - Convert a sweep angle (degrees) into start-angle + radian
6
+ * forms that align with the convention pieScene.ts uses
7
+ * (0° = 12 o'clock, positive = clockwise, gap centered at the
8
+ * 6 o'clock position).
9
+ * - Map a value in `[min, max]` to its angle along the arc.
10
+ * - Compute the arc's visible bounding box in unit-circle coords
11
+ * so a container can fit the arc and pick a maximum radius.
12
+ *
13
+ * Custom radial chart authors using `XYCustomChart` or building a
14
+ * bespoke radial layout can reach for the same primitives without
15
+ * reimplementing the trigonometry. Surface intentionally tight —
16
+ * each function is a few lines of math with a documented input
17
+ * convention.
18
+ */
19
+ /** Result of `sweepToAngles`. All angles are in the
20
+ * 12-o'clock-zero, clockwise-positive convention used by pieScene
21
+ * and the underlying gauge implementation. */
22
+ export interface SweepAngles {
23
+ /** Full sweep angle in radians. */
24
+ sweepRad: number;
25
+ /** Gap angle (the unfilled portion) in degrees. */
26
+ gapDeg: number;
27
+ /** Starting angle of the arc, measured in degrees clockwise from
28
+ * 12 o'clock. The gap is centered at 6 o'clock (180°), so the
29
+ * arc starts at `180° + gapDeg / 2`. */
30
+ startAngleDeg: number;
31
+ /** Same as `startAngleDeg`, in radians (12 o'clock = 0). */
32
+ startAngleRad: number;
33
+ /** Offset angle in radians measured from +X (3 o'clock, the
34
+ * trigonometric convention). Useful for direct `Math.cos` /
35
+ * `Math.sin` calls when projecting points onto the arc. */
36
+ offsetRad: number;
37
+ }
38
+ /**
39
+ * Convert a sweep angle (degrees) into the four angle forms a
40
+ * radial chart layout typically needs. Defaults to a 240° sweep
41
+ * (gauge-style: gap of 120° centered at the bottom).
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const { sweepRad, startAngleRad } = sweepToAngles(180) // half-circle
46
+ * ```
47
+ */
48
+ export declare function sweepToAngles(sweepDegrees?: number): SweepAngles;
49
+ /**
50
+ * Map a numeric value in `[min, max]` to its angle along the arc.
51
+ * Returned angles are in trig-convention radians (suitable for
52
+ * `Math.cos` / `Math.sin` to project to unit-circle x/y).
53
+ *
54
+ * Values outside `[min, max]` are clamped.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const { offsetRad, sweepRad } = sweepToAngles(240)
59
+ * const θ = valueToAngle(75, 0, 100, sweepRad, offsetRad)
60
+ * // x = Math.cos(θ), y = Math.sin(θ)
61
+ * ```
62
+ */
63
+ export declare function valueToAngle(value: number, min: number, max: number, sweepRad: number, offsetRad: number): number;
64
+ /** Bounding box of the visible arc in unit-circle coordinates
65
+ * (radius = 1 around the origin). Multiply by the chosen radius
66
+ * to get pixel-space extents. */
67
+ export interface ArcBoundingBox {
68
+ minX: number;
69
+ maxX: number;
70
+ minY: number;
71
+ maxY: number;
72
+ /** `maxX - minX`. Multiply by radius for pixel width. */
73
+ width: number;
74
+ /** `maxY - minY`. Multiply by radius for pixel height. */
75
+ height: number;
76
+ /** Center of the bbox in unit-circle coords. */
77
+ cx: number;
78
+ cy: number;
79
+ }
80
+ /**
81
+ * Compute the bounding box of an arc with the given sweep, in
82
+ * unit-circle coordinates. Useful for centering the arc within a
83
+ * container and picking a maximum radius that keeps the arc inside
84
+ * the available width/height.
85
+ *
86
+ * The bbox includes:
87
+ * - The two arc endpoints.
88
+ * - The arc's center point `(0, 0)`.
89
+ * - Any of the cardinal points `(±1, 0)`, `(0, ±1)` that fall
90
+ * within the swept range.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const bbox = computeArcBoundingBox(240)
95
+ * // Maximize radius so the arc fits in a (W × H) container:
96
+ * const radius = Math.min((W - 2 * pad) / bbox.width, (H - 2 * pad) / bbox.height)
97
+ * ```
98
+ */
99
+ export declare function computeArcBoundingBox(sweepDegrees?: number): ArcBoundingBox;
@@ -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
  /**
@@ -117,6 +117,19 @@ export interface BaseChartProps {
117
117
  * `true` uses defaults (300ms ease-out, intro enabled). Object form allows customization.
118
118
  * Set `{ intro: false }` to disable the animated intro on first render. */
119
119
  animate?: AnimateProp;
120
+ /** Axis extent mode. `"nice"` (default) uses d3-scale's rounded
121
+ * tick generator — labels stay round but ticks may sit inside the
122
+ * data domain. `"exact"` pins the first and last tick to the
123
+ * actual data min and max with equidistant intermediate ticks.
124
+ * Useful when a fixed scale (gauge, score band, KPI dial) needs
125
+ * endpoints to read as the actual boundaries.
126
+ *
127
+ * Applies to:
128
+ * - XY charts: both x and y axes (linear, time, log).
129
+ * - Ordinal charts: the value (r) axis only — the categorical
130
+ * axis is a band scale and doesn't have a numeric tick set.
131
+ * - Network / geo / hierarchy charts: no-op (no continuous axis). */
132
+ axisExtent?: import("./axisExtent").AxisExtentMode;
120
133
  }
121
134
  /**
122
135
  * Axis configuration props