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.
- package/CLAUDE.md +26 -23
- package/README.md +27 -21
- package/ai/chartSuggestions.cjs +191 -3
- package/ai/componentMetadata.cjs +3 -3
- package/ai/dist/mcp-server.js +266 -48
- package/ai/examples.md +68 -0
- package/ai/schema.json +914 -1
- package/ai/system-prompt.md +4 -1
- package/dist/components/ThemeProvider.d.ts +2 -2
- package/dist/components/Tooltip/FlippingTooltip.d.ts +16 -1
- package/dist/components/charts/geo/FlowMap.d.ts +13 -4
- package/dist/components/charts/index.d.ts +6 -0
- package/dist/components/charts/network/OrbitDiagram.d.ts +5 -5
- package/dist/components/charts/network/ProcessSankey.d.ts +163 -0
- package/dist/components/charts/network/SankeyDiagram.d.ts +5 -1
- package/dist/components/charts/network/processSankey/algorithm.d.ts +193 -0
- package/dist/components/charts/network/processSankey/buildScenes.d.ts +51 -0
- package/dist/components/charts/network/processSankey/ribbonInputs.d.ts +32 -0
- package/dist/components/charts/network/processSankey/streamingLayout.d.ts +71 -0
- package/dist/components/charts/network/processSankey/tooltipUtils.d.ts +41 -0
- package/dist/components/charts/ordinal/BarChart.d.ts +12 -0
- package/dist/components/charts/ordinal/DotPlot.d.ts +9 -0
- package/dist/components/charts/ordinal/GaugeChart.d.ts +20 -0
- package/dist/components/charts/ordinal/SwimlaneChart.d.ts +5 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +16 -11
- package/dist/components/charts/realtime/RealtimeLineChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +2 -0
- package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +19 -0
- package/dist/components/charts/shared/axisExtent.d.ts +59 -0
- package/dist/components/charts/shared/chartSpecs.d.ts +75 -0
- package/dist/components/charts/shared/colorUtils.d.ts +8 -2
- package/dist/components/charts/shared/networkUtils.d.ts +3 -5
- package/dist/components/charts/shared/radialGeometry.d.ts +99 -0
- package/dist/components/charts/shared/regressionUtils.d.ts +59 -0
- package/dist/components/charts/shared/selectionUtils.d.ts +8 -1
- package/dist/components/charts/shared/streamPropsHelpers.d.ts +5 -0
- package/dist/components/charts/shared/tooltipUtils.d.ts +11 -0
- package/dist/components/charts/shared/types.d.ts +19 -0
- package/dist/components/charts/shared/useAreaSeriesSetup.d.ts +78 -0
- package/dist/components/charts/shared/useChartSetup.d.ts +2 -0
- package/dist/components/charts/shared/useCustomChartSetup.d.ts +1 -0
- package/dist/components/charts/shared/useEncodingDomain.d.ts +48 -0
- package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +1 -1
- package/dist/components/charts/shared/useNetworkChartSetup.d.ts +150 -0
- package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +87 -0
- package/dist/components/charts/shared/useSeriesFeatures.d.ts +57 -0
- package/dist/components/charts/shared/useStreamStatus.d.ts +33 -0
- package/dist/components/charts/shared/useXYLineStyle.d.ts +69 -0
- package/dist/components/charts/shared/useXYPointStyle.d.ts +87 -0
- package/dist/components/charts/shared/withChartWrapper.d.ts +10 -3
- package/dist/components/charts/xy/AreaChart.d.ts +36 -2
- package/dist/components/charts/xy/BubbleChart.d.ts +9 -0
- package/dist/components/charts/xy/ConnectedScatterplot.d.ts +16 -0
- package/dist/components/charts/xy/DifferenceChart.d.ts +172 -0
- package/dist/components/charts/xy/LineChart.d.ts +26 -2
- package/dist/components/charts/xy/Scatterplot.d.ts +39 -1
- package/dist/components/geometry/ribbonGeometry.d.ts +76 -0
- package/dist/components/semiotic-ai.d.ts +2 -0
- package/dist/components/semiotic-network.d.ts +4 -0
- package/dist/components/semiotic-realtime.d.ts +2 -0
- package/dist/components/semiotic-utils.d.ts +4 -0
- package/dist/components/semiotic-xy.d.ts +2 -0
- package/dist/components/semiotic.d.ts +4 -4
- package/dist/components/server/renderToStaticSVG.d.ts +2 -1
- package/dist/components/server/serverChartConfigs.d.ts +3 -0
- package/dist/components/server/staticAnnotations.d.ts +1 -1
- package/dist/components/server/themeResolver.d.ts +7 -1
- package/dist/components/store/ThemeStore.d.ts +7 -1
- package/dist/components/stream/AccessibleDataTable.d.ts +2 -2
- package/dist/components/stream/GeoPipelineStore.d.ts +21 -0
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +8 -0
- package/dist/components/stream/PipelineStore.d.ts +25 -13
- package/dist/components/stream/SVGOverlay.d.ts +9 -18
- package/dist/components/stream/accessorUtils.d.ts +2 -1
- package/dist/components/stream/annotationAccessorResolver.d.ts +39 -0
- package/dist/components/stream/geoTypes.d.ts +12 -0
- package/dist/components/stream/layouts/hierarchyLayoutPlugin.d.ts +1 -1
- package/dist/components/stream/networkTypes.d.ts +11 -0
- package/dist/components/stream/ordinalTypes.d.ts +27 -1
- package/dist/components/stream/renderers/cornerRadii.d.ts +33 -0
- package/dist/components/stream/renderers/wedgePathBuilder.d.ts +56 -0
- package/dist/components/stream/types.d.ts +127 -11
- package/dist/components/stream/xySceneBuilders/areaGradient.d.ts +20 -0
- package/dist/components/stream/xySceneBuilders/barScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/heatmapScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/lineScene.d.ts +4 -3
- package/dist/components/stream/xySceneBuilders/pointScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/ribbonScene.d.ts +107 -0
- package/dist/components/stream/xySceneBuilders/swarmScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/types.d.ts +9 -12
- package/dist/components/stream/xySceneBuilders/waterfallScene.d.ts +2 -2
- package/dist/components/types/legendTypes.d.ts +1 -1
- package/dist/geo.min.js +1 -1
- package/dist/geo.module.min.js +1 -1
- package/dist/network.min.js +1 -1
- package/dist/network.module.min.js +1 -1
- package/dist/ordinal.min.js +1 -1
- package/dist/ordinal.module.min.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai.d.ts +2 -0
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-data.min.js +1 -1
- package/dist/semiotic-data.module.min.js +1 -1
- package/dist/semiotic-network.d.ts +4 -0
- package/dist/semiotic-realtime.d.ts +2 -0
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-themes.min.js +1 -1
- package/dist/semiotic-themes.module.min.js +1 -1
- package/dist/semiotic-utils.d.ts +4 -0
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- package/dist/semiotic-xy.d.ts +2 -0
- package/dist/semiotic.d.ts +4 -4
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/dist/server.min.js +1 -1
- package/dist/server.module.min.js +1 -1
- package/dist/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +23 -10
- package/dist/components/stream/xySceneBuilders/boundsScene.d.ts +0 -9
package/ai/system-prompt.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Semiotic — React Data Visualization
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- semiotic-bundle-sizes:start -->
|
|
4
|
+
<!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
|
|
5
|
+
**Use sub-path imports** — `semiotic/xy` (85KB gz), `semiotic/ordinal` (68KB gz), `semiotic/network` (63KB gz), `semiotic/geo` (51KB gz), `semiotic/realtime` (90KB gz), `semiotic/server` (117KB gz), `semiotic/utils` (22KB gz), `semiotic/recipes` (5KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/ai` (188KB gz). Full `semiotic` is 186KB gz.
|
|
6
|
+
<!-- semiotic-bundle-sizes:end -->
|
|
4
7
|
|
|
5
8
|
## Flat Array Data (`data: object[]`)
|
|
6
9
|
- **LineChart** — `xAccessor`, `yAccessor`, `lineBy` (multi-line), `curve`
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { LIGHT_THEME, DARK_THEME, HIGH_CONTRAST_THEME } from "./store/ThemeStore";
|
|
3
|
-
import type { SemioticTheme } from "./store/ThemeStore";
|
|
3
|
+
import type { SemioticTheme, SemioticThemeUpdate } from "./store/ThemeStore";
|
|
4
4
|
import type { ThemePresetName } from "./semiotic-themes";
|
|
5
5
|
interface ThemeProviderProps {
|
|
6
6
|
/** Theme preset name (e.g. "tufte", "pastels-dark", "bi-tool") or a partial SemioticTheme object. */
|
|
7
|
-
theme?: ThemePresetName |
|
|
7
|
+
theme?: ThemePresetName | SemioticThemeUpdate;
|
|
8
8
|
children: React.ReactNode;
|
|
9
9
|
}
|
|
10
10
|
declare function ThemeProviderWrapper({ theme, children }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -29,6 +29,21 @@ interface FlippingTooltipProps {
|
|
|
29
29
|
* On first render, uses a heuristic (similar to the old 70%/30% thresholds).
|
|
30
30
|
* After measuring the actual tooltip size via ref, repositions precisely to
|
|
31
31
|
* prevent clipping against container edges.
|
|
32
|
+
*
|
|
33
|
+
* Two defensive behaviors:
|
|
34
|
+
*
|
|
35
|
+
* - **Chrome guarantee.** If the rendered tooltip content lacks the
|
|
36
|
+
* `semiotic-tooltip` className on its root, the wrapper applies
|
|
37
|
+
* `defaultTooltipStyle` to itself so the tooltip always has a
|
|
38
|
+
* visible background, padding, and shadow. Shared tooltip helpers
|
|
39
|
+
* keep working unchanged (their `semiotic-tooltip` class causes the
|
|
40
|
+
* wrapper to stay transparent).
|
|
41
|
+
* - **Non-finite position guard.** Returns `null` when `x` or `y` is
|
|
42
|
+
* `NaN` / `Infinity`. The frame's hover plumbing can occasionally
|
|
43
|
+
* produce a non-finite hit-test result during a scale rebuild or
|
|
44
|
+
* when a custom layout emits a degenerate vertex; without the
|
|
45
|
+
* guard, React throws `'NaN' is an invalid value for the 'top' css
|
|
46
|
+
* style property` and the entire frame stops rendering.
|
|
32
47
|
*/
|
|
33
|
-
export declare function FlippingTooltip({ x, y, containerWidth, containerHeight, margin, children, className, zIndex }: FlippingTooltipProps): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export declare function FlippingTooltip({ x, y, containerWidth, containerHeight, margin, children, className, zIndex }: FlippingTooltipProps): import("react/jsx-runtime").JSX.Element | null;
|
|
34
49
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Datum } from "../shared/datumTypes";
|
|
2
|
+
import * as React from "react";
|
|
2
3
|
import type { StreamGeoFrameProps, ProjectionProp } from "../../stream/geoTypes";
|
|
4
|
+
import type { RealtimeFrameHandle } from "../../realtime/types";
|
|
3
5
|
import type { BaseChartProps, ChartAccessor } from "../shared/types";
|
|
4
6
|
import { type TooltipProp } from "../../Tooltip/Tooltip";
|
|
5
7
|
import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
@@ -79,6 +81,13 @@ export interface FlowMapProps<TDatum extends Datum = Datum> extends BaseChartPro
|
|
|
79
81
|
tileCacheSize?: number;
|
|
80
82
|
/** Annotations */
|
|
81
83
|
annotations?: Datum[];
|
|
84
|
+
/**
|
|
85
|
+
* ID accessor on flow records — required for `ref.current.remove(id)`
|
|
86
|
+
* and `ref.current.update(id, …)`. The accessor reads the same field
|
|
87
|
+
* the user supplies on each flow; the field is preserved on the
|
|
88
|
+
* resolved line entry so the frame's `removeLine` can match by id.
|
|
89
|
+
*/
|
|
90
|
+
lineIdAccessor?: string | ((d: Datum) => string);
|
|
82
91
|
/** Passthrough */
|
|
83
92
|
frameProps?: Partial<Omit<StreamGeoFrameProps, "projection">>;
|
|
84
93
|
}
|
|
@@ -132,7 +141,7 @@ export interface FlowMapProps<TDatum extends Datum = Datum> extends BaseChartPro
|
|
|
132
141
|
* />
|
|
133
142
|
* ```
|
|
134
143
|
*/
|
|
135
|
-
export declare
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
144
|
+
export declare const FlowMap: {
|
|
145
|
+
<TDatum extends Datum = Datum>(props: FlowMapProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
|
|
146
|
+
displayName?: string;
|
|
147
|
+
};
|
|
@@ -14,6 +14,8 @@ export { LineChart } from "./xy/LineChart";
|
|
|
14
14
|
export type { LineChartProps } from "./xy/LineChart";
|
|
15
15
|
export { AreaChart } from "./xy/AreaChart";
|
|
16
16
|
export type { AreaChartProps } from "./xy/AreaChart";
|
|
17
|
+
export { DifferenceChart } from "./xy/DifferenceChart";
|
|
18
|
+
export type { DifferenceChartProps } from "./xy/DifferenceChart";
|
|
17
19
|
export { StackedAreaChart } from "./xy/StackedAreaChart";
|
|
18
20
|
export type { StackedAreaChartProps } from "./xy/StackedAreaChart";
|
|
19
21
|
export { Heatmap } from "./xy/Heatmap";
|
|
@@ -72,6 +74,10 @@ export { ChordDiagram } from "./network/ChordDiagram";
|
|
|
72
74
|
export type { ChordDiagramProps } from "./network/ChordDiagram";
|
|
73
75
|
export { SankeyDiagram } from "./network/SankeyDiagram";
|
|
74
76
|
export type { SankeyDiagramProps } from "./network/SankeyDiagram";
|
|
77
|
+
export { ProcessSankey } from "./network/ProcessSankey";
|
|
78
|
+
export type { ProcessSankeyProps, ProcessSankeyTick } from "./network/ProcessSankey";
|
|
79
|
+
export { validateProcessSankey, formatProcessSankeyIssue, } from "./network/processSankey/algorithm";
|
|
80
|
+
export type { ProcessSankeyNode as ProcessSankeyValidatorNode, ProcessSankeyEdge as ProcessSankeyValidatorEdge, ProcessSankeyIssue, } from "./network/processSankey/algorithm";
|
|
75
81
|
export { TreeDiagram } from "./network/TreeDiagram";
|
|
76
82
|
export type { TreeDiagramProps } from "./network/TreeDiagram";
|
|
77
83
|
export { Treemap } from "./network/Treemap";
|
|
@@ -4,7 +4,7 @@ import type { StreamNetworkFrameProps } from "../../stream/networkTypes";
|
|
|
4
4
|
import type { BaseChartProps } from "../shared/types";
|
|
5
5
|
import { type TooltipProp } from "../../Tooltip/Tooltip";
|
|
6
6
|
export interface OrbitNode {
|
|
7
|
-
datum:
|
|
7
|
+
datum: Datum;
|
|
8
8
|
x: number;
|
|
9
9
|
y: number;
|
|
10
10
|
ring: number;
|
|
@@ -38,11 +38,11 @@ export interface OrbitDiagramProps<TDatum extends Datum = Datum> extends BaseCha
|
|
|
38
38
|
*/
|
|
39
39
|
orbitMode?: OrbitMode;
|
|
40
40
|
/** Ring size divisor per depth. Larger = tighter orbits. @default 2.95 */
|
|
41
|
-
orbitSize?: number | ((node:
|
|
41
|
+
orbitSize?: number | ((node: Datum) => number);
|
|
42
42
|
/** Orbit speed in degrees per frame @default 0.25 */
|
|
43
43
|
speed?: number;
|
|
44
44
|
/** Per-node speed modifier @default (node) => 1 / (node.depth + 1) */
|
|
45
|
-
revolution?: (node:
|
|
45
|
+
revolution?: (node: Datum) => number;
|
|
46
46
|
/**
|
|
47
47
|
* Built-in revolution style presets:
|
|
48
48
|
* - "locked": children rotate with parent at decreasing speed (default)
|
|
@@ -53,11 +53,11 @@ export interface OrbitDiagramProps<TDatum extends Datum = Datum> extends BaseCha
|
|
|
53
53
|
*/
|
|
54
54
|
revolutionStyle?: "locked" | "decay" | "alternate";
|
|
55
55
|
/** Vertical squash for elliptical orbits. 1 = circle, 0.5 = ellipse @default 1 */
|
|
56
|
-
eccentricity?: number | ((node:
|
|
56
|
+
eccentricity?: number | ((node: Datum) => number);
|
|
57
57
|
/** Show orbital ring paths @default true */
|
|
58
58
|
showRings?: boolean;
|
|
59
59
|
/** Node radius. Number or function of node. @default 6 */
|
|
60
|
-
nodeRadius?: number | ((node:
|
|
60
|
+
nodeRadius?: number | ((node: Datum) => number);
|
|
61
61
|
/** Show node labels @default false */
|
|
62
62
|
showLabels?: boolean;
|
|
63
63
|
/** Enable animation @default true */
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Datum } from "../shared/datumTypes";
|
|
3
|
+
import type { BaseChartProps, ChartAccessor } from "../shared/types";
|
|
4
|
+
import type { RealtimeFrameHandle } from "../../realtime/types";
|
|
5
|
+
import type { StreamNetworkFrameProps, ParticleStyle } from "../../stream/networkTypes";
|
|
6
|
+
import { type TooltipProp } from "../../Tooltip/Tooltip";
|
|
7
|
+
type TimeLike = number | Date | string;
|
|
8
|
+
export interface ProcessSankeyTick {
|
|
9
|
+
date: TimeLike;
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ProcessSankeyProps<TNode extends Datum = Datum, TEdge extends Datum = Datum> extends BaseChartProps {
|
|
13
|
+
nodes?: TNode[];
|
|
14
|
+
edges?: TEdge[];
|
|
15
|
+
/** [tStart, tEnd] of the chart's x-axis. Required. */
|
|
16
|
+
domain: [TimeLike, TimeLike];
|
|
17
|
+
/** Optional axis ticks. Each tick: { date, label }. */
|
|
18
|
+
axisTicks?: ProcessSankeyTick[];
|
|
19
|
+
nodeIdAccessor?: ChartAccessor<TNode, string>;
|
|
20
|
+
sourceAccessor?: ChartAccessor<TEdge, string>;
|
|
21
|
+
targetAccessor?: ChartAccessor<TEdge, string>;
|
|
22
|
+
valueAccessor?: ChartAccessor<TEdge, number>;
|
|
23
|
+
startTimeAccessor?: ChartAccessor<TEdge, TimeLike>;
|
|
24
|
+
endTimeAccessor?: ChartAccessor<TEdge, TimeLike>;
|
|
25
|
+
/**
|
|
26
|
+
* Optional accessor for the per-edge "system in" time — when
|
|
27
|
+
* `value` is added to the SOURCE node's mass. Use when the
|
|
28
|
+
* source node has an intake event distinct from when this edge
|
|
29
|
+
* departs (e.g. a patient is admitted to the ER at 7pm and
|
|
30
|
+
* transferred out at 9pm — the ER node carries the patient's
|
|
31
|
+
* weight between 7pm and 9pm). Without this, the source node's
|
|
32
|
+
* mass is synthesized as a flat baseline and the band reads as
|
|
33
|
+
* "always there." Set it and the node band climbs / falls as
|
|
34
|
+
* units arrive and depart — a true staircase profile.
|
|
35
|
+
*/
|
|
36
|
+
systemInTimeAccessor?: ChartAccessor<TEdge, TimeLike>;
|
|
37
|
+
/**
|
|
38
|
+
* Optional accessor for the per-edge "system out" time — when
|
|
39
|
+
* `value` is removed from the TARGET node's mass. Mirror of
|
|
40
|
+
* `systemInTimeAccessor` for the inbound side.
|
|
41
|
+
*/
|
|
42
|
+
systemOutTimeAccessor?: ChartAccessor<TEdge, TimeLike>;
|
|
43
|
+
/**
|
|
44
|
+
* Accessor for a node's explicit lifetime extent — a `[start, end]`
|
|
45
|
+
* tuple of time-likes. Lane spans
|
|
46
|
+
* `min(xExtent[0], earliestEdge)` to `max(xExtent[1], latestEdge)`.
|
|
47
|
+
*/
|
|
48
|
+
xExtentAccessor?: ChartAccessor<TNode, [TimeLike, TimeLike]>;
|
|
49
|
+
edgeIdAccessor?: ChartAccessor<TEdge, string>;
|
|
50
|
+
colorBy?: ChartAccessor<TNode, string>;
|
|
51
|
+
colorScheme?: string | string[];
|
|
52
|
+
/** Show a swatch + label legend. Defaults to `true` when `colorBy` is set. */
|
|
53
|
+
showLegend?: boolean;
|
|
54
|
+
/** Legend position. Default `"right"`. */
|
|
55
|
+
legendPosition?: "right" | "left" | "top" | "bottom";
|
|
56
|
+
/**
|
|
57
|
+
* Format function for time values — applied to axis tick labels and
|
|
58
|
+
* to time fields in the default tooltip. Same convention as
|
|
59
|
+
* `xFormat` on XY charts.
|
|
60
|
+
*/
|
|
61
|
+
timeFormat?: (d: number | Date) => string | React.ReactNode;
|
|
62
|
+
/** Format function for the `value` field. Mirrors `yFormat` on XY charts. */
|
|
63
|
+
valueFormat?: (d: number) => string | React.ReactNode;
|
|
64
|
+
pairing?: "value" | "temporal";
|
|
65
|
+
packing?: "off" | "reuse";
|
|
66
|
+
laneOrder?: "insertion" | "crossing-min" | "inside-out" | "crossing-min+inside-out";
|
|
67
|
+
ribbonLane?: "source" | "target" | "both";
|
|
68
|
+
lifetimeMode?: "full" | "half";
|
|
69
|
+
showLaneRails?: boolean;
|
|
70
|
+
showQualityReadout?: boolean;
|
|
71
|
+
/** Render the per-band node id label at the band's left edge.
|
|
72
|
+
* Default `true`. Set `false` for dense layouts where labels
|
|
73
|
+
* would overlap, or when the legend already names every band. */
|
|
74
|
+
showLabels?: boolean;
|
|
75
|
+
edgeOpacity?: number;
|
|
76
|
+
/** Tooltip content. `false` disables, `true` uses the default,
|
|
77
|
+
* or pass a `Tooltip(...)` / custom function for full control. */
|
|
78
|
+
tooltip?: TooltipProp;
|
|
79
|
+
enableHover?: boolean;
|
|
80
|
+
onClick?: (datum: Datum, position?: {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
}) => void;
|
|
84
|
+
showParticles?: boolean;
|
|
85
|
+
/** Style config for the particle overlay — same shape
|
|
86
|
+
* StreamNetworkFrame consumes from SankeyDiagram. Defaults
|
|
87
|
+
* (radius 3, opacity 0.7, spawnRate 0.1, maxPerEdge 50) live in
|
|
88
|
+
* `DEFAULT_PARTICLE_STYLE`. */
|
|
89
|
+
particleStyle?: ParticleStyle;
|
|
90
|
+
/** Pass-through to the underlying StreamNetworkFrame. */
|
|
91
|
+
frameProps?: Partial<Omit<StreamNetworkFrameProps, "nodes" | "edges" | "chartType" | "size" | "customNetworkLayout" | "layoutConfig">>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* ProcessSankey — temporal flow between nodes with an actual time x-axis.
|
|
95
|
+
*
|
|
96
|
+
* Built on top of `StreamNetworkFrame` via the `customNetworkLayout`
|
|
97
|
+
* escape hatch. Bands and ribbons emit as `bezier` scene-edges; the
|
|
98
|
+
* Frame handles canvas painting, hit testing, accessibility, theme
|
|
99
|
+
* cascade, and the push API.
|
|
100
|
+
*
|
|
101
|
+
* **Differs from SankeyDiagram in three ways:**
|
|
102
|
+
*
|
|
103
|
+
* 1. **Edges carry time.** Each edge has `startTime` / `endTime`.
|
|
104
|
+
* 2. **Nodes have lifetimes, not ranks.** A node's vertical lane spans
|
|
105
|
+
* `min(xExtent[0], earliestEdge)` to `max(xExtent[1], latestEdge)`.
|
|
106
|
+
* 3. **Static-graph cycles are valid** as long as edges move forward in time.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```tsx
|
|
110
|
+
* // Static fixture: pre-built nodes + timed edges, categorical colors.
|
|
111
|
+
* <ProcessSankey
|
|
112
|
+
* nodes={[
|
|
113
|
+
* { id: "Alice", category: "Person", xExtent: ["2026-01-06", "2026-01-06"] },
|
|
114
|
+
* { id: "Bob", category: "Person", xExtent: ["2026-02-01", "2026-02-01"] },
|
|
115
|
+
* { id: "Eng", category: "Team" },
|
|
116
|
+
* { id: "Release", category: "Milestone", xExtent: ["2026-04-15", "2026-05-30"] },
|
|
117
|
+
* ]}
|
|
118
|
+
* edges={[
|
|
119
|
+
* { id: "alice-eng", source: "Alice", target: "Eng", value: 8,
|
|
120
|
+
* startTime: "2026-01-20", endTime: "2026-02-10" },
|
|
121
|
+
* { id: "bob-eng", source: "Bob", target: "Eng", value: 5,
|
|
122
|
+
* startTime: "2026-02-15", endTime: "2026-03-15" },
|
|
123
|
+
* { id: "eng-rel", source: "Eng", target: "Release", value: 13,
|
|
124
|
+
* startTime: "2026-04-15", endTime: "2026-05-15" },
|
|
125
|
+
* ]}
|
|
126
|
+
* domain={["2026-01-01", "2026-05-31"]}
|
|
127
|
+
* colorBy="category"
|
|
128
|
+
* showLegend
|
|
129
|
+
* />
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* // Push mode: omit `edges`, mutate via the ref. Same chart shape, but
|
|
135
|
+
* // edges arrive over time. Particles depict throughput.
|
|
136
|
+
* const ref = useRef<RealtimeFrameHandle>(null)
|
|
137
|
+
*
|
|
138
|
+
* useEffect(() => {
|
|
139
|
+
* const id = setInterval(() => {
|
|
140
|
+
* ref.current?.push({
|
|
141
|
+
* source: "API", target: "DB", value: Math.random() * 10,
|
|
142
|
+
* startTime: Date.now(), endTime: Date.now() + 1500,
|
|
143
|
+
* })
|
|
144
|
+
* }, 800)
|
|
145
|
+
* return () => clearInterval(id)
|
|
146
|
+
* }, [])
|
|
147
|
+
*
|
|
148
|
+
* return (
|
|
149
|
+
* <ProcessSankey
|
|
150
|
+
* ref={ref}
|
|
151
|
+
* domain={[t0, t0 + 60_000]}
|
|
152
|
+
* showParticles
|
|
153
|
+
* colorBy="category"
|
|
154
|
+
* showLegend
|
|
155
|
+
* />
|
|
156
|
+
* )
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
export declare const ProcessSankey: {
|
|
160
|
+
<TNode extends Datum = Datum, TEdge extends Datum = Datum>(props: ProcessSankeyProps<TNode, TEdge> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
|
|
161
|
+
displayName?: string;
|
|
162
|
+
};
|
|
163
|
+
export default ProcessSankey;
|
|
@@ -4,7 +4,7 @@ import type { StreamNetworkFrameProps } from "../../stream/networkTypes";
|
|
|
4
4
|
import type { RealtimeFrameHandle } from "../../realtime/types";
|
|
5
5
|
import type { BaseChartProps, ChartAccessor } from "../shared/types";
|
|
6
6
|
import { type TooltipProp } from "../../Tooltip/Tooltip";
|
|
7
|
-
import type { LegendInteractionMode } from "../shared/hooks";
|
|
7
|
+
import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
8
8
|
/**
|
|
9
9
|
* SankeyDiagram component props
|
|
10
10
|
*/
|
|
@@ -25,6 +25,10 @@ export interface SankeyDiagramProps<TNode extends Datum = Datum, TEdge extends D
|
|
|
25
25
|
nodeLabel?: ChartAccessor<TNode, string>;
|
|
26
26
|
showLabels?: boolean;
|
|
27
27
|
enableHover?: boolean;
|
|
28
|
+
/** Show a swatch + label legend. Defaults to `true` when `colorBy` is set. */
|
|
29
|
+
showLegend?: boolean;
|
|
30
|
+
/** Legend position. Default `"right"`. */
|
|
31
|
+
legendPosition?: LegendPosition;
|
|
28
32
|
legendInteraction?: LegendInteractionMode;
|
|
29
33
|
edgeOpacity?: number;
|
|
30
34
|
edgeSort?: (a: any, b: any) => number;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export interface ProcessSankeyNode {
|
|
2
|
+
id: string;
|
|
3
|
+
/** Optional explicit lifetime bound [start, end]. Lifetime is
|
|
4
|
+
* `min(xExtent[0], earliestEdge)` to `max(xExtent[1], latestEdge)`. */
|
|
5
|
+
xExtent?: [number, number];
|
|
6
|
+
}
|
|
7
|
+
export interface ProcessSankeyEdge {
|
|
8
|
+
id: string;
|
|
9
|
+
source: string;
|
|
10
|
+
target: string;
|
|
11
|
+
value: number;
|
|
12
|
+
startTime: number;
|
|
13
|
+
endTime: number;
|
|
14
|
+
/** Optional: time at which this unit of mass actually "arrived" at
|
|
15
|
+
* the SOURCE node (e.g., the hospital admit time for an ER patient
|
|
16
|
+
* whose transfer to ICU happens later at `startTime`). Purely a
|
|
17
|
+
* rendering hint — the layout/mass profile is unchanged. The
|
|
18
|
+
* renderer cuts a rectangular slot out of the source node's band
|
|
19
|
+
* from the node's left edge up to the scaled `systemInTime`, with
|
|
20
|
+
* height equal to this edge's ribbon thickness. Edges without
|
|
21
|
+
* `systemInTime` are drawn as-is. Result: a staircase profile on
|
|
22
|
+
* the source side as units enter the system one by one.
|
|
23
|
+
* Default: undefined. */
|
|
24
|
+
systemInTime?: number;
|
|
25
|
+
/** Optional: time at which this unit of mass leaves the TARGET node
|
|
26
|
+
* (e.g., the discharge time for a patient who arrived at the ward
|
|
27
|
+
* at `endTime`). Symmetric to `systemInTime`: the renderer cuts a
|
|
28
|
+
* rectangular slot out of the target node's band from the scaled
|
|
29
|
+
* `systemOutTime` to the node's right edge, with height equal to
|
|
30
|
+
* this edge's ribbon thickness. Layout/mass profile unchanged.
|
|
31
|
+
* Default: undefined. */
|
|
32
|
+
systemOutTime?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ProcessSankeyIssue {
|
|
35
|
+
kind: string;
|
|
36
|
+
id?: string;
|
|
37
|
+
source?: string;
|
|
38
|
+
target?: string;
|
|
39
|
+
endpoint?: string;
|
|
40
|
+
nodeId?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ProcessSankeySample {
|
|
43
|
+
t: number;
|
|
44
|
+
topMass: number;
|
|
45
|
+
botMass: number;
|
|
46
|
+
}
|
|
47
|
+
export type AttachmentSide = "top" | "bot";
|
|
48
|
+
export type AttachmentKind = "in" | "out";
|
|
49
|
+
export interface ProcessSankeyAttachment {
|
|
50
|
+
side: AttachmentSide;
|
|
51
|
+
time: number;
|
|
52
|
+
sideMassBefore: number;
|
|
53
|
+
sideMassAfter: number;
|
|
54
|
+
kind: AttachmentKind;
|
|
55
|
+
value: number;
|
|
56
|
+
}
|
|
57
|
+
export interface ProcessSankeyNodeData {
|
|
58
|
+
samples: ProcessSankeySample[];
|
|
59
|
+
peak: number;
|
|
60
|
+
topPeak: number;
|
|
61
|
+
botPeak: number;
|
|
62
|
+
localAttachments: Map<string, ProcessSankeyAttachment>;
|
|
63
|
+
}
|
|
64
|
+
export interface ProcessSankeySlotPeak {
|
|
65
|
+
topPeak: number;
|
|
66
|
+
botPeak: number;
|
|
67
|
+
}
|
|
68
|
+
export interface ProcessSankeySlotOccupant {
|
|
69
|
+
id: string;
|
|
70
|
+
end: number;
|
|
71
|
+
}
|
|
72
|
+
export interface ProcessSankeySlot {
|
|
73
|
+
peak: ProcessSankeySlotPeak;
|
|
74
|
+
occupants: ProcessSankeySlotOccupant[];
|
|
75
|
+
}
|
|
76
|
+
export interface ProcessSankeyLaneLifetime {
|
|
77
|
+
start: number | null;
|
|
78
|
+
end: number | null;
|
|
79
|
+
}
|
|
80
|
+
export interface ProcessSankeySideRecord {
|
|
81
|
+
sourceSide?: AttachmentSide;
|
|
82
|
+
targetSide?: AttachmentSide;
|
|
83
|
+
}
|
|
84
|
+
export interface ProcessSankeyLayout {
|
|
85
|
+
nodeData: Record<string, ProcessSankeyNodeData>;
|
|
86
|
+
sides: Map<string, ProcessSankeySideRecord>;
|
|
87
|
+
valueScale: number;
|
|
88
|
+
padding: number;
|
|
89
|
+
compressedPadding: boolean;
|
|
90
|
+
centerlines: Record<string, number>;
|
|
91
|
+
laneLifetime: Record<string, ProcessSankeyLaneLifetime>;
|
|
92
|
+
slots: ProcessSankeySlot[];
|
|
93
|
+
slotByNode: Record<string, number>;
|
|
94
|
+
crossingsBefore: number | null;
|
|
95
|
+
crossingsAfter: number | null;
|
|
96
|
+
lengthBefore: number | null;
|
|
97
|
+
lengthAfter: number | null;
|
|
98
|
+
}
|
|
99
|
+
export interface ProcessSankeyOptions {
|
|
100
|
+
plotH: number;
|
|
101
|
+
pairing?: "value" | "temporal";
|
|
102
|
+
packing?: "off" | "reuse";
|
|
103
|
+
laneOrder?: "insertion" | "crossing-min" | "inside-out" | "crossing-min+inside-out";
|
|
104
|
+
lifetimeMode?: "full" | "half";
|
|
105
|
+
}
|
|
106
|
+
export interface ProcessSankeyEdgeIndex {
|
|
107
|
+
incoming: Record<string, ProcessSankeyEdge[]>;
|
|
108
|
+
outgoing: Record<string, ProcessSankeyEdge[]>;
|
|
109
|
+
}
|
|
110
|
+
type Domain = [number, number] | null | undefined;
|
|
111
|
+
export declare function validateProcessSankey(nodes: ProcessSankeyNode[], edges: ProcessSankeyEdge[], domain: [number, number]): ProcessSankeyIssue[];
|
|
112
|
+
export declare function formatProcessSankeyIssue(issue: ProcessSankeyIssue): string;
|
|
113
|
+
export declare function buildEdgeIndex(nodes: ProcessSankeyNode[], edges: ProcessSankeyEdge[]): ProcessSankeyEdgeIndex;
|
|
114
|
+
export declare function assignSides(nodes: ProcessSankeyNode[], edges: ProcessSankeyEdge[], edgeIndex: ProcessSankeyEdgeIndex, pairing?: "value" | "temporal"): Map<string, ProcessSankeySideRecord>;
|
|
115
|
+
export declare function computeNode(node: ProcessSankeyNode, edgeIndex: ProcessSankeyEdgeIndex, sides: Map<string, ProcessSankeySideRecord>): ProcessSankeyNodeData;
|
|
116
|
+
export declare function clampTime(t: number, domain: Domain): number;
|
|
117
|
+
export declare function clampSamples(samples: ProcessSankeySample[], domain: Domain): ProcessSankeySample[];
|
|
118
|
+
export declare function attachmentYRange(att: ProcessSankeyAttachment, cl: number, S: number): [number, number];
|
|
119
|
+
export declare function buildBandPath(samples: ProcessSankeySample[], cl: number, S: number, xScale: (t: number) => number, domain: Domain): string | null;
|
|
120
|
+
/**
|
|
121
|
+
* One 20-px gradient stub at an attachment with `systemInTime` /
|
|
122
|
+
* `systemOutTime`. Rendered as its own bezier scene-edge with a
|
|
123
|
+
* horizontal gradient, painted underneath the band. The band
|
|
124
|
+
* paints with `fill: none` whenever any stubs are present, so the
|
|
125
|
+
* stub gradients are the only colored regions inside the band's
|
|
126
|
+
* outline.
|
|
127
|
+
*/
|
|
128
|
+
export interface BandGradientStub {
|
|
129
|
+
/** Rect path (M-L-L-L-Z). */
|
|
130
|
+
pathD: string;
|
|
131
|
+
/** Gradient extent in screen pixels. */
|
|
132
|
+
x0: number;
|
|
133
|
+
x1: number;
|
|
134
|
+
/** Color stops — 0 = transparent end, 1 = band-color end. */
|
|
135
|
+
from: 0 | 1;
|
|
136
|
+
to: 0 | 1;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Build the per-edge 20-px gradient stubs that visualize
|
|
140
|
+
* `systemInTime` / `systemOutTime` on a node band. Each stub is
|
|
141
|
+
* a rect on the edge's attachment slot, painted with a horizontal
|
|
142
|
+
* gradient that fades the band color in (or out) over 20 screen
|
|
143
|
+
* pixels and saturates through the rest of the rect.
|
|
144
|
+
*
|
|
145
|
+
* The rect is clipped to the band's outline bounds (so cutouts don't
|
|
146
|
+
* spill outside the node shape), but the gradient extent stays at
|
|
147
|
+
* its natural `[xSysIn - FADE_PX, xSysIn]` / `[xSysOut, xSysOut + FADE_PX]`
|
|
148
|
+
* range. The canvas renderer uses pad-mode clamping for color stops
|
|
149
|
+
* outside the rect, so a stub whose fade region falls past the band's
|
|
150
|
+
* edge still paints solid band-color where it's visible — instead of
|
|
151
|
+
* collapsing to a degenerate gradient that the renderer would clamp
|
|
152
|
+
* to transparent.
|
|
153
|
+
*
|
|
154
|
+
* Pure rendering hint — layout/mass-profile unchanged. Returns an
|
|
155
|
+
* empty array when the node has no qualifying edges.
|
|
156
|
+
*/
|
|
157
|
+
export declare function buildBandCutoutsForNode(nodeId: string, edges: ProcessSankeyEdge[], layout: ProcessSankeyLayout, xScale: (t: number) => number, domain: Domain): BandGradientStub[];
|
|
158
|
+
type SlotByNode = Record<string, number>;
|
|
159
|
+
export declare function countCrossings(slotByNode: SlotByNode, edges: ProcessSankeyEdge[]): number;
|
|
160
|
+
export declare function totalEdgeLength(slotByNode: SlotByNode, edges: ProcessSankeyEdge[]): number;
|
|
161
|
+
interface LaneLayoutOptions {
|
|
162
|
+
plotH: number;
|
|
163
|
+
padding: number;
|
|
164
|
+
valueScale: number;
|
|
165
|
+
packing?: "off" | "reuse";
|
|
166
|
+
laneOrder?: "insertion" | "crossing-min" | "inside-out" | "crossing-min+inside-out";
|
|
167
|
+
lifetimeMode?: "full" | "half";
|
|
168
|
+
}
|
|
169
|
+
interface LaneLayoutResult {
|
|
170
|
+
effectiveSlotsHeight: number;
|
|
171
|
+
centerlines: Record<string, number>;
|
|
172
|
+
laneLifetime: Record<string, ProcessSankeyLaneLifetime>;
|
|
173
|
+
slots: ProcessSankeySlot[];
|
|
174
|
+
slotByNode: SlotByNode;
|
|
175
|
+
slotCenter: number[];
|
|
176
|
+
crossingsBefore: number | null;
|
|
177
|
+
crossingsAfter: number | null;
|
|
178
|
+
lengthBefore: number | null;
|
|
179
|
+
lengthAfter: number | null;
|
|
180
|
+
}
|
|
181
|
+
export declare function computeLaneLayout(nodes: ProcessSankeyNode[], edges: ProcessSankeyEdge[], nodeData: Record<string, ProcessSankeyNodeData>, edgeIndex: ProcessSankeyEdgeIndex, opts: LaneLayoutOptions): LaneLayoutResult;
|
|
182
|
+
/**
|
|
183
|
+
* Compute the full Process Sankey layout for a given dataset and
|
|
184
|
+
* configuration. Pure function, no side effects.
|
|
185
|
+
*
|
|
186
|
+
* The chart's time domain isn't a layout opt — domain handling lives
|
|
187
|
+
* in the geometry helpers (`buildBandPath`, `buildRibbonGeometry`,
|
|
188
|
+
* `clampSamples`) which receive an `xScale` and a domain pair from
|
|
189
|
+
* the caller. The layout itself is timeless apart from the per-node
|
|
190
|
+
* sample/event timestamps.
|
|
191
|
+
*/
|
|
192
|
+
export declare function computeProcessSankeyLayout(nodes: ProcessSankeyNode[], edges: ProcessSankeyEdge[], opts: ProcessSankeyOptions): ProcessSankeyLayout;
|
|
193
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { scaleTime } from "d3-scale";
|
|
2
|
+
import { type ProcessSankeyOptions, type ProcessSankeyLayout, type ProcessSankeyIssue } from "./algorithm";
|
|
3
|
+
import type { ProcessSankeyLayoutConfig } from "./streamingLayout";
|
|
4
|
+
import type { Datum } from "../../shared/datumTypes";
|
|
5
|
+
export interface ProcessSankeyNormalizedNode {
|
|
6
|
+
id: string;
|
|
7
|
+
xExtent?: [number, number];
|
|
8
|
+
__raw?: Datum;
|
|
9
|
+
}
|
|
10
|
+
export interface ProcessSankeyNormalizedEdge {
|
|
11
|
+
id: string;
|
|
12
|
+
source: string;
|
|
13
|
+
target: string;
|
|
14
|
+
value: number;
|
|
15
|
+
startTime: number;
|
|
16
|
+
endTime: number;
|
|
17
|
+
/** Optional render-only hint: when this unit of mass actually
|
|
18
|
+
* entered the source node. Triggers a cutout in the source band. */
|
|
19
|
+
systemInTime?: number;
|
|
20
|
+
/** Optional render-only hint: when this unit of mass left the
|
|
21
|
+
* target node. Triggers a cutout in the target band. */
|
|
22
|
+
systemOutTime?: number;
|
|
23
|
+
__raw?: Datum;
|
|
24
|
+
}
|
|
25
|
+
export interface BuildScenesInput {
|
|
26
|
+
nodes: ProcessSankeyNormalizedNode[];
|
|
27
|
+
edges: ProcessSankeyNormalizedEdge[];
|
|
28
|
+
domain: [number, number];
|
|
29
|
+
plotW: number;
|
|
30
|
+
plotH: number;
|
|
31
|
+
ribbonLane: "source" | "target" | "both";
|
|
32
|
+
edgeOpacity: number;
|
|
33
|
+
/** Resolves a node's color by id+index (lets the caller plug in
|
|
34
|
+
* the same theme/colorScheme/colorBy resolution the HOC uses). */
|
|
35
|
+
colorOf: (id: string, idx: number) => string;
|
|
36
|
+
layoutOpts: Pick<ProcessSankeyOptions, "pairing" | "packing" | "laneOrder" | "lifetimeMode">;
|
|
37
|
+
}
|
|
38
|
+
export interface BuildScenesResult {
|
|
39
|
+
layout: ProcessSankeyLayout | null;
|
|
40
|
+
layoutConfig: ProcessSankeyLayoutConfig;
|
|
41
|
+
issues: ProcessSankeyIssue[];
|
|
42
|
+
/** Used downstream for tooltips (mass-history) and overlays. */
|
|
43
|
+
xScale: ReturnType<typeof scaleTime>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run the full ProcessSankey layout pipeline. Returns the algorithm
|
|
47
|
+
* output, the bands/ribbons specs ready for `customNetworkLayout`, and
|
|
48
|
+
* the validation issues (caller decides whether to render an error
|
|
49
|
+
* gate or fall through). Pure: no DOM, no React, no rAF.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildProcessSankeyScenes(input: BuildScenesInput): BuildScenesResult;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the `RibbonGeometryInput` shape for a ProcessSankey ribbon
|
|
3
|
+
* from its source/target attachment data. Both the HOC (CSR) and the
|
|
4
|
+
* pure scene builder (SSR) call this so the coords feeding into the
|
|
5
|
+
* shared `buildRibbonGeometry` helper match between the two paths.
|
|
6
|
+
*
|
|
7
|
+
* Replaces `algorithm.js`'s `buildRibbonPath` — the path-D formula
|
|
8
|
+
* itself moved into `buildRibbonGeometry` so SankeyDiagram and
|
|
9
|
+
* ProcessSankey emit identical M-C-L-C-Z shapes.
|
|
10
|
+
*/
|
|
11
|
+
import type { RibbonGeometryInput } from "../../../geometry/ribbonGeometry";
|
|
12
|
+
type Side = "top" | "bot";
|
|
13
|
+
type Kind = "in" | "out";
|
|
14
|
+
interface AttachmentLike {
|
|
15
|
+
side: Side;
|
|
16
|
+
time: number;
|
|
17
|
+
sideMassBefore: number;
|
|
18
|
+
sideMassAfter: number;
|
|
19
|
+
kind: Kind;
|
|
20
|
+
value: number;
|
|
21
|
+
}
|
|
22
|
+
type RibbonLane = "source" | "target" | "both";
|
|
23
|
+
type XScale = (t: number) => number;
|
|
24
|
+
/**
|
|
25
|
+
* Build the geometry inputs for a single ProcessSankey ribbon. The
|
|
26
|
+
* source attachment is assumed to be `kind: "out"` (the value leaves
|
|
27
|
+
* the source on its outgoing side); the target attachment is
|
|
28
|
+
* `kind: "in"`. attachmentYRange's formula is inlined here to keep
|
|
29
|
+
* this module pure TS (the `algorithm.js` version is JS-only).
|
|
30
|
+
*/
|
|
31
|
+
export declare function computeProcessSankeyRibbonInputs(srcAtt: AttachmentLike, srcCenterline: number, tgtAtt: AttachmentLike, tgtCenterline: number, valueScale: number, xScale: XScale, lane: RibbonLane, domain: [number, number] | null): RibbonGeometryInput;
|
|
32
|
+
export {};
|