semiotic 3.4.2 → 3.5.1

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 (163) hide show
  1. package/CLAUDE.md +114 -9
  2. package/README.md +45 -4
  3. package/ai/behaviorContracts.cjs +311 -0
  4. package/ai/chartSuggestions.cjs +291 -0
  5. package/ai/cli.js +255 -30
  6. package/ai/componentMetadata.cjs +107 -0
  7. package/ai/dist/mcp-server.js +907 -227
  8. package/ai/schema.json +3954 -2537
  9. package/ai/system-prompt.md +23 -4
  10. package/dist/components/LinkedCharts.d.ts +5 -1
  11. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  12. package/dist/components/charts/custom/NetworkCustomChart.d.ts +64 -0
  13. package/dist/components/charts/custom/OrdinalCustomChart.d.ts +71 -0
  14. package/dist/components/charts/custom/XYCustomChart.d.ts +59 -0
  15. package/dist/components/charts/geo/ChoroplethMap.d.ts +93 -2
  16. package/dist/components/charts/geo/DistanceCartogram.d.ts +51 -4
  17. package/dist/components/charts/geo/FlowMap.d.ts +55 -0
  18. package/dist/components/charts/geo/ProportionalSymbolMap.d.ts +53 -0
  19. package/dist/components/charts/index.d.ts +6 -0
  20. package/dist/components/charts/network/ChordDiagram.d.ts +34 -2
  21. package/dist/components/charts/network/CirclePack.d.ts +36 -1
  22. package/dist/components/charts/network/ForceDirectedGraph.d.ts +130 -2
  23. package/dist/components/charts/network/OrbitDiagram.d.ts +37 -0
  24. package/dist/components/charts/network/SankeyDiagram.d.ts +51 -2
  25. package/dist/components/charts/network/TreeDiagram.d.ts +37 -2
  26. package/dist/components/charts/network/Treemap.d.ts +36 -2
  27. package/dist/components/charts/ordinal/BarChart.d.ts +113 -1
  28. package/dist/components/charts/ordinal/BoxPlot.d.ts +33 -0
  29. package/dist/components/charts/ordinal/DonutChart.d.ts +36 -0
  30. package/dist/components/charts/ordinal/DotPlot.d.ts +33 -0
  31. package/dist/components/charts/ordinal/FunnelChart.d.ts +40 -0
  32. package/dist/components/charts/ordinal/GaugeChart.d.ts +45 -0
  33. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +40 -0
  34. package/dist/components/charts/ordinal/Histogram.d.ts +97 -0
  35. package/dist/components/charts/ordinal/LikertChart.d.ts +44 -0
  36. package/dist/components/charts/ordinal/PieChart.d.ts +90 -1
  37. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +29 -0
  38. package/dist/components/charts/ordinal/StackedBarChart.d.ts +40 -0
  39. package/dist/components/charts/ordinal/SwarmPlot.d.ts +38 -0
  40. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +62 -0
  41. package/dist/components/charts/ordinal/ViolinPlot.d.ts +34 -0
  42. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +22 -4
  43. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +5 -2
  44. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +24 -3
  45. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +12 -0
  46. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +14 -0
  47. package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +67 -0
  48. package/dist/components/charts/realtime/resolveWindowSize.d.ts +26 -0
  49. package/dist/components/charts/shared/chartSpecs.d.ts +91 -0
  50. package/dist/components/charts/shared/colorPalettes.d.ts +62 -0
  51. package/dist/components/charts/shared/colorUtils.d.ts +9 -10
  52. package/dist/components/charts/shared/numberFormat.d.ts +58 -0
  53. package/dist/components/charts/shared/sparseArray.d.ts +27 -0
  54. package/dist/components/charts/shared/streamPropsHelpers.d.ts +113 -0
  55. package/dist/components/charts/shared/timeFormat.d.ts +60 -0
  56. package/dist/components/charts/shared/useChartSetup.d.ts +8 -0
  57. package/dist/components/charts/shared/useCustomChartSetup.d.ts +84 -0
  58. package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +28 -0
  59. package/dist/components/charts/shared/useOrdinalStreaming.d.ts +6 -19
  60. package/dist/components/charts/shared/useStreamingLegend.d.ts +27 -11
  61. package/dist/components/charts/shared/validateProps.d.ts +2 -2
  62. package/dist/components/charts/shared/validationMap.d.ts +2 -1
  63. package/dist/components/charts/shared/withChartWrapper.d.ts +13 -4
  64. package/dist/components/charts/xy/AreaChart.d.ts +44 -1
  65. package/dist/components/charts/xy/BubbleChart.d.ts +4 -0
  66. package/dist/components/charts/xy/CandlestickChart.d.ts +37 -6
  67. package/dist/components/charts/xy/ConnectedScatterplot.d.ts +28 -0
  68. package/dist/components/charts/xy/Heatmap.d.ts +4 -0
  69. package/dist/components/charts/xy/LineChart.d.ts +12 -0
  70. package/dist/components/charts/xy/MinimapChart.d.ts +58 -0
  71. package/dist/components/charts/xy/MultiAxisLineChart.d.ts +27 -0
  72. package/dist/components/charts/xy/QuadrantChart.d.ts +21 -0
  73. package/dist/components/charts/xy/Scatterplot.d.ts +38 -2
  74. package/dist/components/charts/xy/ScatterplotMatrix.d.ts +16 -0
  75. package/dist/components/charts/xy/StackedAreaChart.d.ts +61 -1
  76. package/dist/components/realtime/types.d.ts +2 -4
  77. package/dist/components/recipes/bullet.d.ts +86 -0
  78. package/dist/components/recipes/calendar.d.ts +43 -0
  79. package/dist/components/recipes/dagre.d.ts +56 -0
  80. package/dist/components/recipes/flextree.d.ts +55 -0
  81. package/dist/components/recipes/marimekko.d.ts +55 -0
  82. package/dist/components/recipes/parallelCoordinates.d.ts +97 -0
  83. package/dist/components/recipes/recipeUtils.d.ts +27 -0
  84. package/dist/components/recipes/waffle.d.ts +46 -0
  85. package/dist/components/semiotic-ai.d.ts +4 -0
  86. package/dist/components/semiotic-network.d.ts +3 -0
  87. package/dist/components/semiotic-ordinal.d.ts +3 -0
  88. package/dist/components/semiotic-recipes.d.ts +24 -0
  89. package/dist/components/semiotic-xy.d.ts +3 -0
  90. package/dist/components/semiotic.d.ts +2 -2
  91. package/dist/components/server/renderToStaticSVG.d.ts +8 -2
  92. package/dist/components/server/serverChartConfigs.d.ts +47 -1
  93. package/dist/components/server/staticAnnotations.d.ts +6 -0
  94. package/dist/components/store/ObservationStore.d.ts +1 -3
  95. package/dist/components/store/SelectionStore.d.ts +1 -3
  96. package/dist/components/store/ThemeStore.d.ts +4 -4
  97. package/dist/components/store/TooltipStore.d.ts +1 -3
  98. package/dist/components/store/createStore.d.ts +4 -2
  99. package/dist/components/stream/CanvasHitTester.d.ts +10 -8
  100. package/dist/components/stream/DataSourceAdapter.d.ts +9 -0
  101. package/dist/components/stream/GeoPipelineStore.d.ts +9 -0
  102. package/dist/components/stream/GeoTileRenderer.d.ts +14 -0
  103. package/dist/components/stream/NetworkPipelineStore.d.ts +25 -0
  104. package/dist/components/stream/OrdinalPipelineStore.d.ts +12 -0
  105. package/dist/components/stream/PipelineStore.d.ts +51 -0
  106. package/dist/components/stream/SVGOverlay.d.ts +12 -0
  107. package/dist/components/stream/SceneGraph.d.ts +15 -1
  108. package/dist/components/stream/SceneToSVG.d.ts +1 -1
  109. package/dist/components/stream/categoryDomain.d.ts +4 -0
  110. package/dist/components/stream/composeOverlays.d.ts +15 -0
  111. package/dist/components/stream/customLayout.d.ts +76 -0
  112. package/dist/components/stream/customLayoutPalette.d.ts +29 -0
  113. package/dist/components/stream/geoTypes.d.ts +13 -0
  114. package/dist/components/stream/hoverUtils.d.ts +4 -10
  115. package/dist/components/stream/networkCustomLayout.d.ts +67 -0
  116. package/dist/components/stream/networkTypes.d.ts +45 -0
  117. package/dist/components/stream/ordinalCustomLayout.d.ts +84 -0
  118. package/dist/components/stream/ordinalTypes.d.ts +35 -1
  119. package/dist/components/stream/renderers/barFunnelCanvasRenderer.d.ts +9 -1
  120. package/dist/components/stream/renderers/canvasRenderHelpers.d.ts +92 -0
  121. package/dist/components/stream/sampleCurvePath.d.ts +9 -0
  122. package/dist/components/stream/types.d.ts +44 -1
  123. package/dist/components/stream/useHydration.d.ts +89 -0
  124. package/dist/components/stream/useStableShallow.d.ts +1 -0
  125. package/dist/components/stream/xySceneBuilders/types.d.ts +4 -0
  126. package/dist/geo.min.js +2 -1
  127. package/dist/geo.module.min.js +2 -1
  128. package/dist/network.min.js +2 -1
  129. package/dist/network.module.min.js +2 -1
  130. package/dist/ordinal.min.js +2 -1
  131. package/dist/ordinal.module.min.js +2 -1
  132. package/dist/realtime.min.js +2 -1
  133. package/dist/realtime.module.min.js +2 -1
  134. package/dist/semiotic-ai.d.ts +69 -65
  135. package/dist/semiotic-ai.min.js +2 -1
  136. package/dist/semiotic-ai.module.min.js +2 -1
  137. package/dist/semiotic-data.d.ts +4 -4
  138. package/dist/semiotic-geo.d.ts +15 -15
  139. package/dist/semiotic-network.d.ts +19 -16
  140. package/dist/semiotic-ordinal.d.ts +31 -28
  141. package/dist/semiotic-realtime.d.ts +17 -17
  142. package/dist/semiotic-recipes.d.ts +24 -0
  143. package/dist/semiotic-recipes.min.js +1 -0
  144. package/dist/semiotic-recipes.module.min.js +1 -0
  145. package/dist/semiotic-server.d.ts +6 -6
  146. package/dist/semiotic-statisticalOverlays-C3DsOgr_.js +1 -0
  147. package/dist/semiotic-themes.d.ts +3 -3
  148. package/dist/semiotic-themes.min.js +2 -1
  149. package/dist/semiotic-themes.module.min.js +2 -1
  150. package/dist/semiotic-utils.d.ts +23 -23
  151. package/dist/semiotic-utils.min.js +2 -1
  152. package/dist/semiotic-utils.module.min.js +2 -1
  153. package/dist/semiotic-xy.d.ts +27 -24
  154. package/dist/semiotic.d.ts +63 -63
  155. package/dist/semiotic.min.js +2 -1
  156. package/dist/semiotic.module.min.js +2 -1
  157. package/dist/server.min.js +1 -1
  158. package/dist/server.module.min.js +1 -1
  159. package/dist/test-utils/canvasMock.d.ts +34 -5
  160. package/dist/xy.min.js +2 -1
  161. package/dist/xy.module.min.js +2 -1
  162. package/package.json +38 -17
  163. package/dist/semiotic-statisticalOverlays-Ckd_jM8z.js +0 -1
@@ -65,6 +65,33 @@ export interface MultiAxisLineChartProps<TDatum extends Datum = Datum> extends B
65
65
  *
66
66
  * If `series` does not contain exactly 2 entries, renders as a standard
67
67
  * multi-line chart with a dev-mode console warning.
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * // Revenue (left axis, $) vs. signups (right axis, count)
72
+ * <MultiAxisLineChart
73
+ * data={metrics}
74
+ * xAccessor="month"
75
+ * series={[
76
+ * { yAccessor: "revenue", label: "Revenue", color: "#3b82f6", format: (v) => `$${v}` },
77
+ * { yAccessor: "signups", label: "Signups", color: "#22c55e" },
78
+ * ]}
79
+ * legendPosition="bottom"
80
+ * />
81
+ * ```
82
+ *
83
+ * @example
84
+ * ```tsx
85
+ * // Pinning each axis extent independently
86
+ * <MultiAxisLineChart
87
+ * data={metrics}
88
+ * xAccessor="t"
89
+ * series={[
90
+ * { yAccessor: "tempC", label: "°C", color: "#ef4444", extent: [-10, 40] },
91
+ * { yAccessor: "humidity", label: "%", color: "#06b6d4", extent: [0, 100] },
92
+ * ]}
93
+ * />
94
+ * ```
68
95
  */
69
96
  export declare const MultiAxisLineChart: {
70
97
  <TDatum extends Datum = Datum>(props: MultiAxisLineChartProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -114,6 +114,27 @@ export interface QuadrantChartProps<TDatum extends Datum = Datum> extends BaseCh
114
114
  * }}
115
115
  * />
116
116
  * ```
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * // Effort vs. impact prioritization with a fixed 5×5 split.
121
+ * // Omit `xCenter`/`yCenter` to let the chart center on the domain midpoint.
122
+ * <QuadrantChart
123
+ * data={features}
124
+ * xAccessor="impact"
125
+ * yAccessor="effort"
126
+ * xCenter={5}
127
+ * yCenter={5}
128
+ * quadrants={{
129
+ * topRight: { label: "Quick wins", color: "#22c55e" },
130
+ * topLeft: { label: "Maybe later", color: "#94a3b8" },
131
+ * bottomRight: { label: "Big bets", color: "#3b82f6" },
132
+ * bottomLeft: { label: "Skip", color: "#ef4444" },
133
+ * }}
134
+ * colorBy="team"
135
+ * sizeBy="estimate"
136
+ * />
137
+ * ```
117
138
  */
118
139
  export declare const QuadrantChart: {
119
140
  <TDatum extends Datum = Datum>(props: QuadrantChartProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -45,20 +45,56 @@ export interface ScatterplotProps<TDatum extends Datum = Datum> extends BaseChar
45
45
  legendPosition?: LegendPosition;
46
46
  /** Annotation objects to render on the chart */
47
47
  annotations?: Datum[];
48
+ /** Fixed x domain `[min, max]` (either bound may be undefined to leave that side data-derived). */
49
+ xExtent?: [number | undefined, number | undefined] | [number];
50
+ /** Fixed y domain `[min, max]` (either bound may be undefined to leave that side data-derived). */
51
+ yExtent?: [number | undefined, number | undefined] | [number];
48
52
  /** Additional StreamXYFrame props for advanced customization */
49
53
  frameProps?: Partial<Omit<StreamXYFrameProps, "chartType" | "data" | "size">>;
50
54
  }
51
55
  /**
52
- * Scatterplot - Visualize relationships between two continuous variables
56
+ * Scatterplot - Visualize relationships between two continuous variables.
57
+ *
58
+ * Each row becomes a circle at `(xAccessor, yAccessor)`. Add a third
59
+ * dimension via {@link BubbleChart} (size encoding) or
60
+ * {@link ConnectedScatterplot} (point ordering). For matrix views of every
61
+ * pairwise combination, use {@link ScatterplotMatrix}.
53
62
  *
54
63
  * @example
55
64
  * ```tsx
65
+ * // Simple scatter
56
66
  * <Scatterplot
57
- * data={[{x: 1, y: 10}, {x: 2, y: 20}]}
67
+ * data={[{ x: 1, y: 10 }, { x: 2, y: 20 }]}
58
68
  * xLabel="Time"
59
69
  * yLabel="Value"
60
70
  * />
61
71
  * ```
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * // Color by category, marginal histograms in axis margins
76
+ * <Scatterplot
77
+ * data={observations}
78
+ * xAccessor="age"
79
+ * yAccessor="income"
80
+ * colorBy="region"
81
+ * showLegend
82
+ * marginalGraphics={{ x: "histogram", y: "histogram" }}
83
+ * />
84
+ * ```
85
+ *
86
+ * @example
87
+ * ```tsx
88
+ * // Hover-highlight non-hovered series + click handler
89
+ * <Scatterplot
90
+ * data={observations}
91
+ * xAccessor="x"
92
+ * yAccessor="y"
93
+ * colorBy="cluster"
94
+ * hoverHighlight
95
+ * onClick={(d) => console.log(d)}
96
+ * />
97
+ * ```
62
98
  */
63
99
  export declare const Scatterplot: {
64
100
  <TDatum extends Datum = Datum>(props: ScatterplotProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -56,6 +56,7 @@ export interface ScatterplotMatrixProps<TDatum extends Datum = Datum> extends Ba
56
56
  *
57
57
  * @example
58
58
  * ```tsx
59
+ * // Iris dataset — every pairwise field combination
59
60
  * <ScatterplotMatrix
60
61
  * data={iris}
61
62
  * fields={["sepalLength", "sepalWidth", "petalLength", "petalWidth"]}
@@ -64,6 +65,21 @@ export interface ScatterplotMatrixProps<TDatum extends Datum = Datum> extends Ba
64
65
  * diagonal="histogram"
65
66
  * />
66
67
  * ```
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * // Brush mode: drag in any cell to highlight matching points across the
72
+ * // matrix. The `crossfilter` mode excludes the brushed cell from its own
73
+ * // filter so it stays fully visible while the others dim non-matches.
74
+ * // Brush selections live in the matrix's internal selection store and do
75
+ * // not propagate to charts rendered outside the component.
76
+ * <ScatterplotMatrix
77
+ * data={observations}
78
+ * fields={["x", "y", "z"]}
79
+ * hoverMode={false}
80
+ * brushMode="crossfilter"
81
+ * />
82
+ * ```
67
83
  */
68
84
  export declare function ScatterplotMatrix<TDatum extends Datum = Datum>(props: ScatterplotMatrixProps<TDatum>): import("react/jsx-runtime").JSX.Element;
69
85
  export declare namespace ScatterplotMatrix {
@@ -92,6 +92,33 @@ export interface StackedAreaChartProps<TDatum extends Datum = Datum> extends Bas
92
92
  * @default false
93
93
  */
94
94
  normalize?: boolean;
95
+ /**
96
+ * Stacked baseline mode — controls where the stack origin sits.
97
+ * - `"zero"` (default): standard stacked area, baseline at y=0.
98
+ * - `"wiggle"`: streamgraph offset (Byron–Wattenberg). Minimizes visual
99
+ * wiggle across series — best for high-cardinality series where
100
+ * relative shape matters more than absolute values.
101
+ * - `"silhouette"`: center the stack symmetrically around y=0.
102
+ *
103
+ * Mutually exclusive with `normalize` — when `normalize` is true,
104
+ * baseline is forced to `"zero"`.
105
+ *
106
+ * @default "zero"
107
+ */
108
+ baseline?: "zero" | "wiggle" | "silhouette";
109
+ /**
110
+ * Stack order — controls which series sits at the top, middle, or
111
+ * bottom of the stack. Pair with `baseline: "wiggle"` or
112
+ * `"silhouette"` for the canonical streamgraph look:
113
+ *
114
+ * - `"key"` (default): alphabetical by series key. Stable under
115
+ * streaming (no re-shuffling on data eviction).
116
+ * - `"insideOut"`: largest-total series in the middle, smaller series
117
+ * wrapping outward. The classic d3 streamgraph aesthetic — gives
118
+ * you a "central anchor" layer with everything else built off of it.
119
+ * - `"asc"` / `"desc"`: by total ascending / descending.
120
+ */
121
+ stackOrder?: "key" | "insideOut" | "asc" | "desc";
95
122
  /**
96
123
  * Enable hover annotations
97
124
  * @default true
@@ -119,13 +146,31 @@ export interface StackedAreaChartProps<TDatum extends Datum = Datum> extends Bas
119
146
  */
120
147
  legendPosition?: LegendPosition;
121
148
  /**
122
- * Tooltip configuration
149
+ * Tooltip configuration.
150
+ *
151
+ * Pass `"multi"` to enable hover-anywhere mode: hovering at any x along the
152
+ * chart surfaces a single tooltip listing every stacked series at that x,
153
+ * with values interpolated between rendered path samples. Stacked series
154
+ * report band height rather than the cumulative stack top. Without `"multi"`,
155
+ * the tooltip only appears within `hoverRadius` of an explicit data point.
123
156
  */
124
157
  tooltip?: TooltipProp;
125
158
  /**
126
159
  * Annotation objects to render on the chart
127
160
  */
128
161
  annotations?: Datum[];
162
+ /**
163
+ * Fixed x domain `[min, max]`. Either bound may be `undefined` to leave
164
+ * that side data-derived.
165
+ */
166
+ xExtent?: [number | undefined, number | undefined] | [number];
167
+ /**
168
+ * Fixed y domain `[min, max]`. Either bound may be `undefined` to leave
169
+ * that side data-derived. Stacked areas auto-extend the y domain to
170
+ * cover the cumulative sum unless `yExtent` is fully specified —
171
+ * passing `yExtent={[0, 200]}` pins both bounds.
172
+ */
173
+ yExtent?: [number | undefined, number | undefined] | [number];
129
174
  /**
130
175
  * Additional StreamXYFrame props for advanced customization
131
176
  * For full control, consider using StreamXYFrame directly
@@ -143,6 +188,7 @@ export interface StackedAreaChartProps<TDatum extends Datum = Datum> extends Bas
143
188
  *
144
189
  * @example
145
190
  * ```tsx
191
+ * // Stacked series — each category contributes a band of height
146
192
  * <StackedAreaChart
147
193
  * data={[
148
194
  * {x: 1, y: 10, category: 'A'},
@@ -156,6 +202,20 @@ export interface StackedAreaChartProps<TDatum extends Datum = Datum> extends Bas
156
202
  * yLabel="Value"
157
203
  * />
158
204
  * ```
205
+ *
206
+ * @example
207
+ * ```tsx
208
+ * // 100% normalized stack — y axis becomes share of total
209
+ * <StackedAreaChart
210
+ * data={data}
211
+ * xAccessor="t"
212
+ * yAccessor="value"
213
+ * areaBy="category"
214
+ * colorBy="category"
215
+ * normalize
216
+ * yFormat={(v) => `${(v * 100).toFixed(0)}%`}
217
+ * />
218
+ * ```
159
219
  */
160
220
  export declare const StackedAreaChart: {
161
221
  <TDatum extends Datum = Datum>(props: StackedAreaChartProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -72,10 +72,8 @@ export interface HoverData {
72
72
  x: number;
73
73
  /** Pixel Y coordinate of the hovered element */
74
74
  y: number;
75
- /** Pixel X coordinate, aliased as "time" for backwards compatibility with realtime charts */
76
- time: number;
77
- /** Pixel Y coordinate, aliased as "value" for backwards compatibility with realtime charts */
78
- value: number;
75
+ /** @internal Explicit marker used to distinguish Semiotic hover wrappers from raw user data. */
76
+ __semioticHoverData?: true;
79
77
  /** All series values at hovered X (multi-point tooltip mode) */
80
78
  allSeries?: Array<{
81
79
  group: string;
@@ -0,0 +1,86 @@
1
+ import type { OrdinalCustomLayout } from "../stream/ordinalCustomLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface BulletConfig {
4
+ /** Field (or function) yielding the row label per datum. Each row is one bullet. */
5
+ categoryAccessor: string | ((d: Datum) => string);
6
+ /** Field (or function) yielding the actual measured value (the dark bar). */
7
+ valueAccessor: string | ((d: Datum) => number);
8
+ /** Field (or function) yielding the target marker value (the perpendicular tick). */
9
+ targetAccessor: string | ((d: Datum) => number);
10
+ /**
11
+ * Field (or function) yielding the qualitative range thresholds — an
12
+ * ascending array of cutoffs ([poor, satisfactory, good]) per datum.
13
+ * The ranges paint as background bars in successively darker shades.
14
+ */
15
+ rangesAccessor: string | ((d: Datum) => number[]);
16
+ /** Pixel height of each row's bullet. @default 28 */
17
+ rowHeight?: number;
18
+ /** Pixel gap between rows. @default 12 */
19
+ rowGap?: number;
20
+ /** Color for the actual-value bar. Defaults to theme primary. */
21
+ actualColor?: string;
22
+ /** Color for the target tick. Defaults to theme text. */
23
+ targetColor?: string;
24
+ /**
25
+ * Render the metric name to the left of each row. Reserves
26
+ * `labelWidth` from the bullet area. @default true
27
+ */
28
+ showLabels?: boolean;
29
+ /**
30
+ * Pixel width reserved on the left for row labels. Only used when
31
+ * `showLabels` is true. @default 120
32
+ */
33
+ labelWidth?: number;
34
+ /**
35
+ * Render value-axis tick marks below each bullet (since each row is
36
+ * independently scaled, ticks are per-row). @default true
37
+ */
38
+ showTicks?: boolean;
39
+ /**
40
+ * Format function for the per-row tick labels rendered below each
41
+ * bullet. @default v => v.toLocaleString()
42
+ */
43
+ tickFormat?: (v: number) => string;
44
+ }
45
+ /**
46
+ * Bullet chart (Stephen Few, 2005) — a compact replacement for KPI gauges.
47
+ * Each row stacks three layers along the value axis:
48
+ *
49
+ * 1. Three background bars in successively darker shades (poor →
50
+ * satisfactory → good zones) sized by `rangesAccessor` values.
51
+ * 2. The actual measured value as a thinner dark bar.
52
+ * 3. A perpendicular tick at the target.
53
+ *
54
+ * Reads from low to high left-to-right. Far better than a half-circle
55
+ * gauge for dashboards — same information, ~5× the data density, no
56
+ * pie-shaped overhead.
57
+ *
58
+ * All inputs (`actual`, `target`, range thresholds) are treated as
59
+ * non-negative — values < 0 or non-finite are clamped to 0. Range
60
+ * thresholds are also sorted ascending so band order is always
61
+ * deterministic regardless of input order.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * import { OrdinalCustomChart } from "semiotic/ordinal"
66
+ * import { bulletLayout } from "semiotic/recipes"
67
+ *
68
+ * <OrdinalCustomChart
69
+ * data={[
70
+ * { metric: "Revenue", actual: 270, target: 250, ranges: [150, 225, 300] },
71
+ * { metric: "Profit", actual: 23, target: 27, ranges: [ 20, 25, 30] },
72
+ * { metric: "Order Size", actual: 102, target: 120, ranges: [ 80, 110, 140] },
73
+ * ]}
74
+ * layout={bulletLayout}
75
+ * layoutConfig={{
76
+ * categoryAccessor: "metric",
77
+ * valueAccessor: "actual",
78
+ * targetAccessor: "target",
79
+ * rangesAccessor: "ranges",
80
+ * }}
81
+ * width={500}
82
+ * height={180}
83
+ * />
84
+ * ```
85
+ */
86
+ export declare const bulletLayout: OrdinalCustomLayout<BulletConfig>;
@@ -0,0 +1,43 @@
1
+ import type { CustomLayout } from "../stream/customLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface CalendarConfig {
4
+ /** Field name (or function) yielding a Date or epoch ms per datum. */
5
+ dateAccessor: string | ((d: Datum) => Date | number);
6
+ /** Field name (or function) yielding the value used to color each day. */
7
+ valueAccessor: string | ((d: Datum) => number);
8
+ /**
9
+ * Two-stop color ramp: [low, high]. By default, this uses the active
10
+ * theme's semantic colors from `surface` to `primary` — pass explicit
11
+ * colors here for non-default ramps.
12
+ */
13
+ colorRamp?: [string, string];
14
+ /**
15
+ * Calendar year to render. If omitted, infers the year from the first datum.
16
+ * For multi-year series, render one XYCustomChart per year.
17
+ */
18
+ year?: number;
19
+ /** Pixel gap between cells. @default 2 */
20
+ gutter?: number;
21
+ /** Inset on the left to leave room for weekday labels. @default 0 */
22
+ labelInset?: number;
23
+ }
24
+ /**
25
+ * GitHub-style calendar heatmap — 53 columns (ISO weeks) × 7 rows (days of
26
+ * week), color-encoded by daily value. One year per layout.
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * <XYCustomChart
31
+ * data={dailyEvents}
32
+ * layout={calendarLayout}
33
+ * layoutConfig={{
34
+ * dateAccessor: "date",
35
+ * valueAccessor: "count",
36
+ * year: 2025,
37
+ * }}
38
+ * width={900}
39
+ * height={140}
40
+ * />
41
+ * ```
42
+ */
43
+ export declare const calendarLayout: CustomLayout<CalendarConfig>;
@@ -0,0 +1,56 @@
1
+ import type { NetworkCustomLayout } from "../stream/networkCustomLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface DagreConfig {
4
+ /** Default node width when nodes don't carry a `width` field. @default 100 */
5
+ nodeWidth?: number;
6
+ /** Default node height when nodes don't carry a `height` field. @default 36 */
7
+ nodeHeight?: number;
8
+ /** Edge style — straight polyline through waypoints, or smoothed bezier. @default "polyline" */
9
+ edgeStyle?: "polyline" | "smooth";
10
+ /** Render text labels at node centers. @default true */
11
+ showLabels?: boolean;
12
+ /** Field name (or function) yielding the label string per node. @default "label" */
13
+ labelAccessor?: string | ((d: Datum) => string);
14
+ /** Per-node fill style override. */
15
+ nodeFill?: string;
16
+ /** Stroke for edges. */
17
+ edgeStroke?: string;
18
+ }
19
+ /**
20
+ * Dagre layout recipe — renders a pre-positioned directed acyclic graph
21
+ * (e.g. output of `dagre`).
22
+ *
23
+ * The user runs `dagre.layout(g)` themselves and flattens the result into
24
+ * `nodes` (each with `x`, `y`, `width`, `height`, `label`) and `edges`
25
+ * (each with `source`, `target`, optional `points` waypoint array). The
26
+ * recipe handles scene emission only.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import dagre from "dagre"
31
+ * import { dagreLayout } from "semiotic/recipes"
32
+ *
33
+ * const g = new dagre.graphlib.Graph()
34
+ * g.setGraph({ rankdir: "TB" })
35
+ * g.setDefaultEdgeLabel(() => ({}))
36
+ * for (const n of myNodes) g.setNode(n.id, { width: 120, height: 40, label: n.label })
37
+ * for (const e of myEdges) g.setEdge(e.source, e.target)
38
+ * dagre.layout(g)
39
+ *
40
+ * const nodes = g.nodes().map((id) => {
41
+ * const n = g.node(id)
42
+ * return { id, x: n.x, y: n.y, width: n.width, height: n.height, label: n.label }
43
+ * })
44
+ * const edges = g.edges().map((e) => {
45
+ * const ed = g.edge(e)
46
+ * return { source: e.v, target: e.w, points: ed.points }
47
+ * })
48
+ *
49
+ * <StreamNetworkFrame
50
+ * chartType="force"
51
+ * nodes={nodes} edges={edges}
52
+ * customNetworkLayout={dagreLayout}
53
+ * />
54
+ * ```
55
+ */
56
+ export declare const dagreLayout: NetworkCustomLayout<DagreConfig>;
@@ -0,0 +1,55 @@
1
+ import type { NetworkCustomLayout } from "../stream/networkCustomLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface FlextreeConfig {
4
+ /** Default node width when nodes don't carry a `width` field. @default 80 */
5
+ nodeWidth?: number;
6
+ /** Default node height when nodes don't carry a `height` field. @default 30 */
7
+ nodeHeight?: number;
8
+ /** Edge style — curved (cubic-bezier path) or straight lines. @default "curved" */
9
+ edgeCurve?: "line" | "curved";
10
+ /** Tree orientation. Affects bezier control-point placement. @default "vertical" */
11
+ orientation?: "vertical" | "horizontal";
12
+ /** Render text labels at node centers. @default true */
13
+ showLabels?: boolean;
14
+ /** Field name (or function) yielding the label string per node. @default "id" */
15
+ labelAccessor?: string | ((d: Datum) => string);
16
+ /** Per-node fill style override. */
17
+ nodeFill?: string;
18
+ }
19
+ /**
20
+ * Flextree layout recipe — renders a pre-positioned variable-width tree
21
+ * (e.g. output of `d3-flextree`).
22
+ *
23
+ * The user runs `d3-flextree` themselves and passes the laid-out nodes
24
+ * as data. Each node should carry `x`, `y`, optional `width`/`height`.
25
+ * Edges should be parent → child links (no waypoints needed).
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import flextree from "d3-flextree"
30
+ * import { flextreeLayout } from "semiotic/recipes"
31
+ *
32
+ * const layout = flextree({ nodeSize: (n) => [n.data.size, 40] })
33
+ * const tree = layout.hierarchy(rootData)
34
+ * layout(tree)
35
+ *
36
+ * const nodes = tree.descendants().map((n) => ({
37
+ * id: n.data.id,
38
+ * x: n.x, y: n.y,
39
+ * width: n.size[0], height: n.size[1],
40
+ * label: n.data.name,
41
+ * }))
42
+ * const edges = tree.links().map((l) => ({
43
+ * source: l.source.data.id,
44
+ * target: l.target.data.id,
45
+ * }))
46
+ *
47
+ * <StreamNetworkFrame
48
+ * chartType="force"
49
+ * nodes={nodes} edges={edges}
50
+ * customNetworkLayout={flextreeLayout}
51
+ * layoutConfig={{ orientation: "vertical" }}
52
+ * />
53
+ * ```
54
+ */
55
+ export declare const flextreeLayout: NetworkCustomLayout<FlextreeConfig>;
@@ -0,0 +1,55 @@
1
+ import type { OrdinalCustomLayout } from "../stream/ordinalCustomLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface MarimekkoConfig {
4
+ /** Field (or function) yielding the category for each datum. Categories become x-axis bars. */
5
+ categoryAccessor: string | ((d: Datum) => string);
6
+ /** Field (or function) yielding the value (segment height contribution). */
7
+ valueAccessor: string | ((d: Datum) => number);
8
+ /** Field (or function) yielding the stack key — segments inside each bar. */
9
+ stackBy: string | ((d: Datum) => string);
10
+ /** Pixel gap between adjacent category bars. @default 2 */
11
+ gutter?: number;
12
+ /** Optional explicit category order. If omitted, uses data insertion order. */
13
+ categoryOrder?: string[];
14
+ /** Optional explicit stack order. If omitted, uses insertion order. */
15
+ stackOrder?: string[];
16
+ /**
17
+ * Render category labels under each bar via SVG overlays. The default
18
+ * ordinal axis can't position labels under variable-width bars (it
19
+ * assumes a uniform band scale), so the recipe handles label
20
+ * placement itself. @default true
21
+ */
22
+ showCategoryLabels?: boolean;
23
+ /**
24
+ * Pixel-padding reserved beneath the bars for labels. Subtracted from
25
+ * the plot height when laying out the bars. @default 22 when labels
26
+ * are shown, 0 otherwise.
27
+ */
28
+ labelPadding?: number;
29
+ }
30
+ /**
31
+ * Marimekko (mosaic) chart — variable-width stacked bars where each bar's
32
+ * width encodes its category's contribution to the grand total, and the
33
+ * inner stacked segments encode the within-category breakdown by
34
+ * `stackBy`. Both dimensions are proportional, making it the natural pick
35
+ * for cohort revenue analysis, market share by segment × product, etc.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * import { OrdinalCustomChart } from "semiotic/ordinal"
40
+ * import { marimekkoLayout } from "semiotic/recipes"
41
+ *
42
+ * <OrdinalCustomChart
43
+ * data={salesByRegionAndProduct}
44
+ * layout={marimekkoLayout}
45
+ * layoutConfig={{
46
+ * categoryAccessor: "region",
47
+ * stackBy: "product",
48
+ * valueAccessor: "revenue",
49
+ * }}
50
+ * width={700}
51
+ * height={400}
52
+ * />
53
+ * ```
54
+ */
55
+ export declare const marimekkoLayout: OrdinalCustomLayout<MarimekkoConfig>;
@@ -0,0 +1,97 @@
1
+ import type { OrdinalCustomLayout } from "../stream/ordinalCustomLayout";
2
+ import type { Datum } from "../charts/shared/datumTypes";
3
+ export interface ParallelCoordinatesConfig {
4
+ /**
5
+ * Field names (in order) defining the axes. Each field must yield a
6
+ * numeric value per datum. The leftmost field is axis 0.
7
+ */
8
+ fields: string[];
9
+ /**
10
+ * Field (or function) yielding a category per datum used for line
11
+ * coloring. If omitted, all lines render in the theme primary color.
12
+ */
13
+ colorBy?: string | ((d: Datum) => string);
14
+ /**
15
+ * Optional per-field [min, max] domains. If omitted, computed from
16
+ * data per field. Useful for locking axes when streaming.
17
+ */
18
+ domains?: Record<string, [number, number]>;
19
+ /** Line opacity. Lower for many overlapping rows. @default 0.45 */
20
+ opacity?: number;
21
+ /** Line stroke width in px. @default 1.25 */
22
+ strokeWidth?: number;
23
+ /**
24
+ * Render small dots at each row's value on each axis. @default false
25
+ * (recommended for low-cardinality data only — gets noisy with 100+ rows).
26
+ */
27
+ showPoints?: boolean;
28
+ /**
29
+ * Render axis chrome — vertical axis lines, top labels (the field
30
+ * name), and 5 tick marks per axis showing the domain range. Each
31
+ * axis is independently scaled, so each gets its own ticks. @default
32
+ * true
33
+ */
34
+ showAxes?: boolean;
35
+ /**
36
+ * Pixel padding reserved at the **top** of the plot for axis field-name
37
+ * labels. Used only when `showAxes` is `true`. Subtracted from the line
38
+ * drawing area along with bottom padding. @default 24
39
+ *
40
+ * The recipe also reserves bottom padding for tick numbers — 18px when
41
+ * `showAxes` is true, 8px when it's false. That bottom value is fixed;
42
+ * use a smaller chart `margin.bottom` if you need tighter packing.
43
+ * Top padding when `showAxes` is false is also a fixed 8px (so polyline
44
+ * endpoints don't hug the chart edge).
45
+ */
46
+ axisLabelPadding?: number;
47
+ /**
48
+ * Optional per-field tick formatter map. Falls back to
49
+ * `v.toLocaleString()` for fields without explicit formatters.
50
+ */
51
+ tickFormat?: Record<string, (v: number) => string>;
52
+ /**
53
+ * Predicate that decides which rows render at full opacity. Rows where
54
+ * `highlightFn(d) === false` render at `dimmedOpacity` instead, with
55
+ * the matching rows z-ordered on top so they don't get covered by
56
+ * neighbors. Recipes are pure functions so they can't own brush state
57
+ * themselves — wire this from a parent component that manages the
58
+ * selection (hover, brush, search query, etc.). Leave undefined for
59
+ * uniform opacity.
60
+ *
61
+ * Roadmap: a future `<ParallelCoordinatesBrushes>` overlay component
62
+ * will manage drag-to-brush state and feed this hook automatically;
63
+ * `useBrushSelection` will carry per-field range constraints across
64
+ * linked charts. This prop is the integration point both will use.
65
+ */
66
+ highlightFn?: (d: Datum) => boolean;
67
+ /** Stroke opacity for non-matching rows when `highlightFn` is set. @default 0.08 */
68
+ dimmedOpacity?: number;
69
+ }
70
+ /**
71
+ * Parallel coordinates — one polyline per row, traced across N parallel
72
+ * vertical axes. Each axis represents a numeric field with its own
73
+ * independent linear scale, so columns in different units can sit
74
+ * side-by-side without normalizing.
75
+ *
76
+ * Useful for high-dimensional pattern hunting: clusters of similar rows,
77
+ * outliers that "swing wildly" between axes, and inverse correlations
78
+ * (lines crossing).
79
+ *
80
+ * @example
81
+ * ```tsx
82
+ * import { OrdinalCustomChart } from "semiotic/ordinal"
83
+ * import { parallelCoordinatesLayout } from "semiotic/recipes"
84
+ *
85
+ * <OrdinalCustomChart
86
+ * data={cars}
87
+ * layout={parallelCoordinatesLayout}
88
+ * layoutConfig={{
89
+ * fields: ["mpg", "displacement", "horsepower", "weight", "acceleration"],
90
+ * colorBy: "origin",
91
+ * }}
92
+ * width={800}
93
+ * height={400}
94
+ * />
95
+ * ```
96
+ */
97
+ export declare const parallelCoordinatesLayout: OrdinalCustomLayout<ParallelCoordinatesConfig>;