@pibbl/core 0.0.2 → 0.0.3-alpha.90.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.
- package/THIRD_PARTY_NOTICES.txt +81 -0
- package/dist/features/textures/index.d.ts +12 -2
- package/dist/features/textures/index.js +33 -1
- package/dist/features/textures/index.js.map +2 -2
- package/dist/features/textures/lib/chemical-field.d.ts +56 -0
- package/dist/features/textures/lib/chemical-field.js +154 -0
- package/dist/features/textures/lib/chemical-field.js.map +7 -0
- package/dist/features/textures/lib/chemical-recipes.d.ts +119 -0
- package/dist/features/textures/lib/chemical-recipes.js +275 -0
- package/dist/features/textures/lib/chemical-recipes.js.map +7 -0
- package/dist/features/textures/lib/definitions.d.ts +3 -18
- package/dist/features/textures/lib/definitions.js +15 -20
- package/dist/features/textures/lib/definitions.js.map +2 -2
- package/dist/features/textures/lib/geometric-patterns.d.ts +149 -0
- package/dist/features/textures/lib/geometric-patterns.js +305 -0
- package/dist/features/textures/lib/geometric-patterns.js.map +7 -0
- package/dist/features/textures/lib/gray-scott.d.ts +55 -0
- package/dist/features/textures/lib/gray-scott.js +39 -0
- package/dist/features/textures/lib/gray-scott.js.map +7 -0
- package/dist/features/textures/lib/patterns.d.ts +123 -0
- package/dist/features/textures/lib/patterns.js +344 -0
- package/dist/features/textures/lib/patterns.js.map +7 -0
- package/dist/features/textures/lib/reaction-diffusion.d.ts +3 -2
- package/dist/features/textures/lib/reaction-diffusion.js +9 -20
- package/dist/features/textures/lib/reaction-diffusion.js.map +2 -2
- package/dist/features/textures/lib/simulation.d.ts +10 -4
- package/dist/features/textures/lib/simulation.js +23 -13
- package/dist/features/textures/lib/simulation.js.map +2 -2
- package/dist/features/viz/index.d.ts +68 -6
- package/dist/features/viz/index.js +164 -2
- package/dist/features/viz/index.js.map +2 -2
- package/dist/features/viz/inspection/bar.d.ts +79 -0
- package/dist/features/viz/inspection/bar.js +49 -0
- package/dist/features/viz/inspection/bar.js.map +7 -0
- package/dist/features/viz/inspection/candle.d.ts +156 -0
- package/dist/features/viz/inspection/candle.js +120 -0
- package/dist/features/viz/inspection/candle.js.map +7 -0
- package/dist/features/viz/inspection/capture-types.d.ts +65 -0
- package/dist/features/viz/inspection/capture.d.ts +16 -0
- package/dist/features/viz/inspection/capture.js +49 -0
- package/dist/features/viz/inspection/capture.js.map +7 -0
- package/dist/features/viz/inspection/handler.d.ts +36 -0
- package/dist/features/viz/inspection/handler.js +91 -0
- package/dist/features/viz/inspection/handler.js.map +7 -0
- package/dist/features/viz/inspection/ohlc-bar.d.ts +132 -0
- package/dist/features/viz/inspection/ohlc-bar.js +118 -0
- package/dist/features/viz/inspection/ohlc-bar.js.map +7 -0
- package/dist/features/viz/inspection/owned-ref.d.ts +16 -0
- package/dist/features/viz/inspection/owned-ref.js +99 -0
- package/dist/features/viz/inspection/owned-ref.js.map +7 -0
- package/dist/features/viz/inspection/painted-point.d.ts +22 -0
- package/dist/features/viz/inspection/painted-point.js +29 -0
- package/dist/features/viz/inspection/painted-point.js.map +7 -0
- package/dist/features/viz/inspection/queries.d.ts +100 -0
- package/dist/features/viz/inspection/queries.js +192 -0
- package/dist/features/viz/inspection/queries.js.map +7 -0
- package/dist/features/viz/inspection/query-types.d.ts +177 -0
- package/dist/features/viz/inspection/volume.d.ts +104 -0
- package/dist/features/viz/inspection/volume.js +95 -0
- package/dist/features/viz/inspection/volume.js.map +7 -0
- package/dist/features/viz/inspection.d.ts +19 -0
- package/dist/features/viz/inspection.js +54 -0
- package/dist/features/viz/inspection.js.map +7 -0
- package/dist/features/viz/inspection.mjs +1 -0
- package/dist/features/viz/lib/area-series.d.ts +62 -0
- package/dist/features/viz/lib/area-series.js +120 -0
- package/dist/features/viz/lib/area-series.js.map +7 -0
- package/dist/features/viz/lib/axis.js +1 -1
- package/dist/features/viz/lib/axis.js.map +2 -2
- package/dist/features/viz/lib/bar-series.d.ts +3 -1
- package/dist/features/viz/lib/bar-series.js +16 -1
- package/dist/features/viz/lib/bar-series.js.map +2 -2
- package/dist/features/viz/lib/baseline-series.d.ts +55 -0
- package/dist/features/viz/lib/baseline-series.js +136 -0
- package/dist/features/viz/lib/baseline-series.js.map +7 -0
- package/dist/features/viz/lib/candlestick-series.d.ts +62 -0
- package/dist/features/viz/lib/candlestick-series.js +150 -0
- package/dist/features/viz/lib/candlestick-series.js.map +7 -0
- package/dist/features/viz/lib/censored-point-series.d.ts +71 -0
- package/dist/features/viz/lib/censored-point-series.js +129 -0
- package/dist/features/viz/lib/censored-point-series.js.map +7 -0
- package/dist/features/viz/lib/color-context.d.ts +4 -0
- package/dist/features/viz/lib/color-context.js +41 -0
- package/dist/features/viz/lib/color-context.js.map +7 -0
- package/dist/features/viz/lib/color-math.d.ts +4 -0
- package/dist/features/viz/lib/color-math.js +31 -0
- package/dist/features/viz/lib/color-math.js.map +7 -0
- package/dist/features/viz/lib/color-types.d.ts +53 -0
- package/dist/features/viz/lib/curve-definition.d.ts +49 -0
- package/dist/features/viz/lib/curve-definition.js +148 -0
- package/dist/features/viz/lib/curve-definition.js.map +7 -0
- package/dist/features/viz/lib/diverging-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/diverging-color-scale.js +51 -0
- package/dist/features/viz/lib/diverging-color-scale.js.map +7 -0
- package/dist/features/viz/lib/domain-navigation.d.ts +40 -0
- package/dist/features/viz/lib/domain-navigation.js +77 -0
- package/dist/features/viz/lib/domain-navigation.js.map +7 -0
- package/dist/features/viz/lib/editable-chart-elements.d.ts +178 -0
- package/dist/features/viz/lib/editable-chart-elements.js +733 -0
- package/dist/features/viz/lib/editable-chart-elements.js.map +7 -0
- package/dist/features/viz/lib/financial-aggregation.d.ts +127 -0
- package/dist/features/viz/lib/financial-aggregation.js +116 -0
- package/dist/features/viz/lib/financial-aggregation.js.map +7 -0
- package/dist/features/viz/lib/financial-autoscale.d.ts +64 -0
- package/dist/features/viz/lib/financial-autoscale.js +61 -0
- package/dist/features/viz/lib/financial-autoscale.js.map +7 -0
- package/dist/features/viz/lib/financial-comparison.d.ts +62 -0
- package/dist/features/viz/lib/financial-comparison.js +98 -0
- package/dist/features/viz/lib/financial-comparison.js.map +7 -0
- package/dist/features/viz/lib/financial-geometry.d.ts +77 -0
- package/dist/features/viz/lib/financial-geometry.js +67 -0
- package/dist/features/viz/lib/financial-geometry.js.map +7 -0
- package/dist/features/viz/lib/financial-indicators.d.ts +114 -0
- package/dist/features/viz/lib/financial-indicators.js +135 -0
- package/dist/features/viz/lib/financial-indicators.js.map +7 -0
- package/dist/features/viz/lib/financial-oscillators.d.ts +171 -0
- package/dist/features/viz/lib/financial-oscillators.js +265 -0
- package/dist/features/viz/lib/financial-oscillators.js.map +7 -0
- package/dist/features/viz/lib/graph/bipartite.d.ts +14 -0
- package/dist/features/viz/lib/graph/bipartite.js +250 -0
- package/dist/features/viz/lib/graph/bipartite.js.map +7 -0
- package/dist/features/viz/lib/graph/chord.d.ts +44 -0
- package/dist/features/viz/lib/graph/chord.js +348 -0
- package/dist/features/viz/lib/graph/chord.js.map +7 -0
- package/dist/features/viz/lib/graph/dependency.d.ts +26 -0
- package/dist/features/viz/lib/graph/dependency.js +141 -0
- package/dist/features/viz/lib/graph/dependency.js.map +7 -0
- package/dist/features/viz/lib/graph/force.d.ts +28 -0
- package/dist/features/viz/lib/graph/force.js +580 -0
- package/dist/features/viz/lib/graph/force.js.map +7 -0
- package/dist/features/viz/lib/graph/hierarchy.d.ts +21 -0
- package/dist/features/viz/lib/graph/hierarchy.js +112 -0
- package/dist/features/viz/lib/graph/hierarchy.js.map +7 -0
- package/dist/features/viz/lib/graph/icicle.d.ts +16 -0
- package/dist/features/viz/lib/graph/icicle.js +153 -0
- package/dist/features/viz/lib/graph/icicle.js.map +7 -0
- package/dist/features/viz/lib/graph/matrix.d.ts +30 -0
- package/dist/features/viz/lib/graph/matrix.js +243 -0
- package/dist/features/viz/lib/graph/matrix.js.map +7 -0
- package/dist/features/viz/lib/graph/neighborhood.d.ts +11 -0
- package/dist/features/viz/lib/graph/neighborhood.js +281 -0
- package/dist/features/viz/lib/graph/neighborhood.js.map +7 -0
- package/dist/features/viz/lib/graph/routes.d.ts +35 -0
- package/dist/features/viz/lib/graph/routes.js +102 -0
- package/dist/features/viz/lib/graph/routes.js.map +7 -0
- package/dist/features/viz/lib/graph/sankey.d.ts +44 -0
- package/dist/features/viz/lib/graph/sankey.js +341 -0
- package/dist/features/viz/lib/graph/sankey.js.map +7 -0
- package/dist/features/viz/lib/graph/shared.d.ts +59 -0
- package/dist/features/viz/lib/graph/shared.js +296 -0
- package/dist/features/viz/lib/graph/shared.js.map +7 -0
- package/dist/features/viz/lib/graph/tree.d.ts +11 -0
- package/dist/features/viz/lib/graph/tree.js +232 -0
- package/dist/features/viz/lib/graph/tree.js.map +7 -0
- package/dist/features/viz/lib/graph/treemap.d.ts +20 -0
- package/dist/features/viz/lib/graph/treemap.js +227 -0
- package/dist/features/viz/lib/graph/treemap.js.map +7 -0
- package/dist/features/viz/lib/graph/types.d.ts +1097 -0
- package/dist/features/viz/lib/hover-data.d.ts +1 -1
- package/dist/features/viz/lib/hover-data.js +5 -2
- package/dist/features/viz/lib/hover-data.js.map +2 -2
- package/dist/features/viz/lib/interval-band-series.d.ts +49 -0
- package/dist/features/viz/lib/interval-band-series.js +136 -0
- package/dist/features/viz/lib/interval-band-series.js.map +7 -0
- package/dist/features/viz/lib/interval-diamond-series.d.ts +43 -0
- package/dist/features/viz/lib/interval-diamond-series.js +124 -0
- package/dist/features/viz/lib/interval-diamond-series.js.map +7 -0
- package/dist/features/viz/lib/interval-series.d.ts +79 -0
- package/dist/features/viz/lib/interval-series.js +158 -0
- package/dist/features/viz/lib/interval-series.js.map +7 -0
- package/dist/features/viz/lib/line-series.d.ts +1 -1
- package/dist/features/viz/lib/line-series.js +47 -28
- package/dist/features/viz/lib/line-series.js.map +2 -2
- package/dist/features/viz/lib/linear-scale.js +1 -1
- package/dist/features/viz/lib/linear-scale.js.map +2 -2
- package/dist/features/viz/lib/monotone-curve.d.ts +11 -0
- package/dist/features/viz/lib/monotone-curve.js +63 -0
- package/dist/features/viz/lib/monotone-curve.js.map +7 -0
- package/dist/features/viz/lib/numeric-range-interpolation.d.ts +15 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js +36 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js.map +7 -0
- package/dist/features/viz/lib/ohlc-bar-series.d.ts +55 -0
- package/dist/features/viz/lib/ohlc-bar-series.js +168 -0
- package/dist/features/viz/lib/ohlc-bar-series.js.map +7 -0
- package/dist/features/viz/lib/paired-series.d.ts +44 -0
- package/dist/features/viz/lib/paired-series.js +93 -0
- package/dist/features/viz/lib/paired-series.js.map +7 -0
- package/dist/features/viz/lib/plot-series.js +11 -6
- package/dist/features/viz/lib/plot-series.js.map +2 -2
- package/dist/features/viz/lib/plot-types.d.ts +4 -3
- package/dist/features/viz/lib/point-series.d.ts +1 -1
- package/dist/features/viz/lib/point-series.js +36 -9
- package/dist/features/viz/lib/point-series.js.map +2 -2
- package/dist/features/viz/lib/point-types.d.ts +5 -2
- package/dist/features/viz/lib/scale-context.d.ts +1 -1
- package/dist/features/viz/lib/scale-ticks.js +21 -6
- package/dist/features/viz/lib/scale-ticks.js.map +2 -2
- package/dist/features/viz/lib/sequential-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/sequential-color-scale.js +49 -0
- package/dist/features/viz/lib/sequential-color-scale.js.map +7 -0
- package/dist/features/viz/lib/series-position.d.ts +12 -0
- package/dist/features/viz/lib/series-position.js +44 -0
- package/dist/features/viz/lib/series-position.js.map +7 -0
- package/dist/features/viz/lib/step-curves.d.ts +19 -0
- package/dist/features/viz/lib/step-curves.js +53 -0
- package/dist/features/viz/lib/step-curves.js.map +7 -0
- package/dist/features/viz/lib/threshold-color-scale.d.ts +43 -0
- package/dist/features/viz/lib/threshold-color-scale.js +59 -0
- package/dist/features/viz/lib/threshold-color-scale.js.map +7 -0
- package/dist/features/viz/lib/trading-time-mapping.d.ts +32 -0
- package/dist/features/viz/lib/trading-time-mapping.js +89 -0
- package/dist/features/viz/lib/trading-time-mapping.js.map +7 -0
- package/dist/features/viz/lib/trading-time-scale.d.ts +83 -0
- package/dist/features/viz/lib/trading-time-scale.js +96 -0
- package/dist/features/viz/lib/trading-time-scale.js.map +7 -0
- package/dist/features/viz/lib/trajectory-series.d.ts +71 -0
- package/dist/features/viz/lib/trajectory-series.js +111 -0
- package/dist/features/viz/lib/trajectory-series.js.map +7 -0
- package/dist/features/viz/lib/types.d.ts +20 -4
- package/dist/features/viz/lib/use-continuous-scale.js +6 -1
- package/dist/features/viz/lib/use-continuous-scale.js.map +2 -2
- package/dist/features/viz/lib/volume-series.d.ts +59 -0
- package/dist/features/viz/lib/volume-series.js +117 -0
- package/dist/features/viz/lib/volume-series.js.map +7 -0
- package/dist/features/viz/lib/weighted-point-series.d.ts +71 -0
- package/dist/features/viz/lib/weighted-point-series.js +169 -0
- package/dist/features/viz/lib/weighted-point-series.js.map +7 -0
- package/dist/filters/backdrop-contrast-gpu.d.ts +5 -0
- package/dist/filters/backdrop-contrast-gpu.js +33 -0
- package/dist/filters/backdrop-contrast-gpu.js.map +7 -0
- package/dist/filters/backdrop-contrast.d.ts +21 -0
- package/dist/filters/backdrop-contrast.js +61 -0
- package/dist/filters/backdrop-contrast.js.map +7 -0
- package/dist/filters/emboss-gpu.d.ts +4 -0
- package/dist/filters/emboss-gpu.js +39 -0
- package/dist/filters/emboss-gpu.js.map +7 -0
- package/dist/filters/emboss.d.ts +32 -0
- package/dist/filters/emboss.js +106 -0
- package/dist/filters/emboss.js.map +7 -0
- package/dist/filters/filter-executor.d.ts +11 -4
- package/dist/filters/filter-executor.js +104 -49
- package/dist/filters/filter-executor.js.map +2 -2
- package/dist/filters/reflection-gpu.d.ts +3 -1
- package/dist/filters/reflection-gpu.js +5 -2
- package/dist/filters/reflection-gpu.js.map +2 -2
- package/dist/filters/render-backdrop-contrast-boundary.d.ts +31 -0
- package/dist/filters/render-backdrop-contrast-boundary.js +116 -0
- package/dist/filters/render-backdrop-contrast-boundary.js.map +7 -0
- package/dist/filters/render-emboss-boundary.d.ts +13 -0
- package/dist/filters/render-emboss-boundary.js +131 -0
- package/dist/filters/render-emboss-boundary.js.map +7 -0
- package/dist/filters.d.ts +9 -5
- package/dist/filters.js +4 -0
- package/dist/filters.js.map +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +2 -2
- package/dist/lib/events/event-facade.d.ts +13 -0
- package/dist/lib/events/event-facade.js +23 -0
- package/dist/lib/events/event-facade.js.map +2 -2
- package/dist/lib/events/propagation.js +19 -14
- package/dist/lib/events/propagation.js.map +2 -2
- package/dist/lib/execute-render.js +13 -0
- package/dist/lib/execute-render.js.map +2 -2
- package/dist/lib/recording/recording.d.ts +43 -0
- package/dist/lib/recording/recording.js +555 -0
- package/dist/lib/recording/recording.js.map +7 -0
- package/dist/lib/recording/types.d.ts +118 -0
- package/dist/lib/recording/wasm-bytes.d.ts +1 -0
- package/dist/lib/recording/wasm-bytes.js +5 -0
- package/dist/lib/recording/wasm-bytes.js.map +7 -0
- package/dist/lib/recording/worker-source.d.ts +1 -0
- package/dist/lib/recording/worker-source.js +5 -0
- package/dist/lib/recording/worker-source.js.map +7 -0
- package/dist/lib/render-transaction.d.ts +5 -2
- package/dist/lib/render-transaction.js +23 -1
- package/dist/lib/render-transaction.js.map +2 -2
- package/dist/lib/series-inspection-frame.d.ts +18 -0
- package/dist/lib/series-inspection-frame.js +70 -0
- package/dist/lib/series-inspection-frame.js.map +7 -0
- package/dist/lib/types.d.ts +6 -0
- package/package.json +10 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { jsx, jsxs } from "@pibbl/core/jsx-runtime";
|
|
2
|
+
import { Group, SvgPath, resolveSignalValue } from "@pibbl/core";
|
|
3
|
+
import {
|
|
4
|
+
defaultGraphEdgeStyle,
|
|
5
|
+
defaultGraphLabelStyle,
|
|
6
|
+
defaultGraphNodeStyle,
|
|
7
|
+
GraphLabel,
|
|
8
|
+
GraphNode,
|
|
9
|
+
resolveMarkStyle,
|
|
10
|
+
useGraphFrame
|
|
11
|
+
} from "./shared.js";
|
|
12
|
+
function access(input, datum) {
|
|
13
|
+
return typeof input === "function" ? input(datum) : datum[input];
|
|
14
|
+
}
|
|
15
|
+
function finite(value, name, zero = false) {
|
|
16
|
+
if (!Number.isFinite(value) || zero && value < 0)
|
|
17
|
+
throw new RangeError(
|
|
18
|
+
`layoutBipartite: ${name} must be finite${zero ? " and nonnegative" : ""}.`
|
|
19
|
+
);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function label(text, bounds) {
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
text,
|
|
25
|
+
bounds: Object.freeze(bounds),
|
|
26
|
+
rotationDegrees: 0
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function route(a, b) {
|
|
30
|
+
const middle = (a.x + b.x) / 2;
|
|
31
|
+
const segments = Object.freeze([
|
|
32
|
+
{ type: "move", x: a.x, y: a.y },
|
|
33
|
+
{
|
|
34
|
+
type: "cubic",
|
|
35
|
+
cp1x: middle,
|
|
36
|
+
cp1y: a.y,
|
|
37
|
+
cp2x: middle,
|
|
38
|
+
cp2y: b.y,
|
|
39
|
+
x: b.x,
|
|
40
|
+
y: b.y
|
|
41
|
+
}
|
|
42
|
+
]);
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
sourceAnchor: Object.freeze(a),
|
|
45
|
+
targetAnchor: Object.freeze(b),
|
|
46
|
+
segments,
|
|
47
|
+
arrowSegments: null
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function path(route2) {
|
|
51
|
+
return route2.segments.map(
|
|
52
|
+
(segment) => segment.type === "move" ? `M ${segment.x} ${segment.y}` : segment.type === "cubic" ? `C ${segment.cp1x} ${segment.cp1y} ${segment.cp2x} ${segment.cp2y} ${segment.x} ${segment.y}` : ""
|
|
53
|
+
).join(" ");
|
|
54
|
+
}
|
|
55
|
+
function placed(data, keyBy, labelBy, atX, bounds, size, gap) {
|
|
56
|
+
const total = data.reduce((sum, datum) => sum + (size?.(datum).height ?? 34), 0) + Math.max(0, data.length - 1) * gap;
|
|
57
|
+
let y = bounds.y + Math.max(0, (bounds.height - total) / 2);
|
|
58
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59
|
+
return Object.freeze(
|
|
60
|
+
data.map((datum) => {
|
|
61
|
+
const key = access(keyBy, datum);
|
|
62
|
+
if (seen.has(key))
|
|
63
|
+
throw new Error(
|
|
64
|
+
`layoutBipartite: duplicate node key ${String(key)} on one side.`
|
|
65
|
+
);
|
|
66
|
+
seen.add(key);
|
|
67
|
+
const dimensions = size?.(datum) ?? { width: 150, height: 34 };
|
|
68
|
+
const box = {
|
|
69
|
+
x: atX,
|
|
70
|
+
y,
|
|
71
|
+
width: dimensions.width,
|
|
72
|
+
height: dimensions.height
|
|
73
|
+
};
|
|
74
|
+
y += dimensions.height + gap;
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
key,
|
|
77
|
+
datum,
|
|
78
|
+
bounds: Object.freeze(box),
|
|
79
|
+
label: label(labelBy ? access(labelBy, datum) : String(key), box),
|
|
80
|
+
detail: null
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
function layoutBipartite(graph, options) {
|
|
86
|
+
const b = options.bounds;
|
|
87
|
+
finite(b.x, "bounds.x");
|
|
88
|
+
finite(b.y, "bounds.y");
|
|
89
|
+
finite(b.width, "bounds.width", true);
|
|
90
|
+
finite(b.height, "bounds.height", true);
|
|
91
|
+
const gap = finite(options.nodeGap ?? 12, "nodeGap", true), columnGap = finite(options.columnGap ?? 120, "columnGap", true);
|
|
92
|
+
const leftSize = options.leftSize, leftResolver = typeof leftSize === "function" ? leftSize : leftSize === void 0 ? void 0 : () => leftSize;
|
|
93
|
+
const rightSize = options.rightSize, rightResolver = typeof rightSize === "function" ? rightSize : rightSize === void 0 ? void 0 : () => rightSize;
|
|
94
|
+
const left = placed(
|
|
95
|
+
graph.left,
|
|
96
|
+
options.leftKey,
|
|
97
|
+
options.leftLabel,
|
|
98
|
+
b.x,
|
|
99
|
+
b,
|
|
100
|
+
leftResolver,
|
|
101
|
+
gap
|
|
102
|
+
);
|
|
103
|
+
const rightWidth = typeof rightSize === "function" ? 150 : rightSize?.width ?? 150;
|
|
104
|
+
const right = placed(
|
|
105
|
+
graph.right,
|
|
106
|
+
options.rightKey,
|
|
107
|
+
options.rightLabel,
|
|
108
|
+
Math.max(b.x, b.x + b.width - rightWidth),
|
|
109
|
+
b,
|
|
110
|
+
rightResolver,
|
|
111
|
+
gap
|
|
112
|
+
);
|
|
113
|
+
const leftByKey = new Map(left.map((node) => [node.key, node])), rightByKey = new Map(right.map((node) => [node.key, node]));
|
|
114
|
+
const edgeKeys = /* @__PURE__ */ new Set();
|
|
115
|
+
const edges = graph.edges.map((edge) => {
|
|
116
|
+
const key = access(options.edgeKey, edge);
|
|
117
|
+
if (edgeKeys.has(key))
|
|
118
|
+
throw new Error(`layoutBipartite: duplicate edge key ${String(key)}.`);
|
|
119
|
+
edgeKeys.add(key);
|
|
120
|
+
const source = access(options.source, edge), target = access(options.target, edge), leftNode = leftByKey.get(source), rightNode = rightByKey.get(target);
|
|
121
|
+
if (!leftNode || !rightNode)
|
|
122
|
+
throw new RangeError(
|
|
123
|
+
"layoutBipartite: every edge must point from a known left key to a known right key."
|
|
124
|
+
);
|
|
125
|
+
const r = route(
|
|
126
|
+
{
|
|
127
|
+
x: leftNode.bounds.x + leftNode.bounds.width,
|
|
128
|
+
y: leftNode.bounds.y + leftNode.bounds.height / 2
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
x: rightNode.bounds.x,
|
|
132
|
+
y: rightNode.bounds.y + rightNode.bounds.height / 2
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
return Object.freeze({
|
|
136
|
+
key,
|
|
137
|
+
datum: edge,
|
|
138
|
+
sourceKey: source,
|
|
139
|
+
targetKey: target,
|
|
140
|
+
left: leftNode,
|
|
141
|
+
right: rightNode,
|
|
142
|
+
route: r,
|
|
143
|
+
path: path(r),
|
|
144
|
+
arrowPath: null
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
if (left.length && right.length && right[0].bounds.x - (left[0].bounds.x + left[0].bounds.width) < columnGap)
|
|
148
|
+
throw new RangeError(
|
|
149
|
+
"layoutBipartite: bounds are too narrow for node sizes and columnGap."
|
|
150
|
+
);
|
|
151
|
+
return Object.freeze({
|
|
152
|
+
bounds: Object.freeze({ ...b }),
|
|
153
|
+
left,
|
|
154
|
+
right,
|
|
155
|
+
edges: Object.freeze(edges)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function BipartiteGraph(props) {
|
|
159
|
+
const frame = useGraphFrame(props.style), style = frame.style;
|
|
160
|
+
if (!frame.bounds.width || !frame.bounds.height)
|
|
161
|
+
return /* @__PURE__ */ jsx(Group, { style: frame.groupStyle, children: null });
|
|
162
|
+
const layout = layoutBipartite(resolveSignalValue(props.graph), {
|
|
163
|
+
...props,
|
|
164
|
+
bounds: frame.bounds,
|
|
165
|
+
columnGap: style.columnGap,
|
|
166
|
+
nodeGap: style.nodeGap
|
|
167
|
+
});
|
|
168
|
+
return /* @__PURE__ */ jsxs(Group, { style: frame.groupStyle, children: [
|
|
169
|
+
layout.edges.map((edge) => /* @__PURE__ */ jsx(
|
|
170
|
+
Group,
|
|
171
|
+
{
|
|
172
|
+
onClick: (event) => props.onEdgeClick?.(edge, event),
|
|
173
|
+
children: props.renderEdge ? props.renderEdge(edge) : /* @__PURE__ */ jsx(
|
|
174
|
+
SvgPath,
|
|
175
|
+
{
|
|
176
|
+
style: {
|
|
177
|
+
...defaultGraphEdgeStyle(edge),
|
|
178
|
+
...resolveMarkStyle(edge, props.edgeStyle),
|
|
179
|
+
d: edge.path
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
},
|
|
184
|
+
String(edge.key)
|
|
185
|
+
)),
|
|
186
|
+
layout.left.map((node) => /* @__PURE__ */ jsx(
|
|
187
|
+
Group,
|
|
188
|
+
{
|
|
189
|
+
onClick: (event) => props.onLeftNodeClick?.(node, event),
|
|
190
|
+
children: props.renderLeftNode ? props.renderLeftNode(node) : /* @__PURE__ */ jsxs(Group, { children: [
|
|
191
|
+
/* @__PURE__ */ jsx(
|
|
192
|
+
GraphNode,
|
|
193
|
+
{
|
|
194
|
+
node,
|
|
195
|
+
style: {
|
|
196
|
+
...defaultGraphNodeStyle(node),
|
|
197
|
+
...resolveMarkStyle(node, props.leftNodeStyle)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
),
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
GraphLabel,
|
|
203
|
+
{
|
|
204
|
+
label: node.label,
|
|
205
|
+
style: {
|
|
206
|
+
...defaultGraphLabelStyle(node.label),
|
|
207
|
+
...resolveSignalValue(props.labelStyle)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
] })
|
|
212
|
+
},
|
|
213
|
+
`left-${String(node.key)}`
|
|
214
|
+
)),
|
|
215
|
+
layout.right.map((node) => /* @__PURE__ */ jsx(
|
|
216
|
+
Group,
|
|
217
|
+
{
|
|
218
|
+
onClick: (event) => props.onRightNodeClick?.(node, event),
|
|
219
|
+
children: props.renderRightNode ? props.renderRightNode(node) : /* @__PURE__ */ jsxs(Group, { children: [
|
|
220
|
+
/* @__PURE__ */ jsx(
|
|
221
|
+
GraphNode,
|
|
222
|
+
{
|
|
223
|
+
node,
|
|
224
|
+
style: {
|
|
225
|
+
...defaultGraphNodeStyle(node),
|
|
226
|
+
...resolveMarkStyle(node, props.rightNodeStyle)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
),
|
|
230
|
+
/* @__PURE__ */ jsx(
|
|
231
|
+
GraphLabel,
|
|
232
|
+
{
|
|
233
|
+
label: node.label,
|
|
234
|
+
style: {
|
|
235
|
+
...defaultGraphLabelStyle(node.label),
|
|
236
|
+
...resolveSignalValue(props.labelStyle)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
] })
|
|
241
|
+
},
|
|
242
|
+
`right-${String(node.key)}`
|
|
243
|
+
))
|
|
244
|
+
] });
|
|
245
|
+
}
|
|
246
|
+
export {
|
|
247
|
+
BipartiteGraph,
|
|
248
|
+
layoutBipartite
|
|
249
|
+
};
|
|
250
|
+
//# sourceMappingURL=bipartite.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/features/viz/lib/graph/bipartite.tsx"],
|
|
4
|
+
"sourcesContent": ["import { Group, SvgPath, resolveSignalValue } from \"@pibbl/core\";\nimport type { PathSegment, PibblNode } from \"@pibbl/core\";\nimport type {\n Accessor,\n BipartiteData,\n BipartiteGraphProps,\n BipartiteLayout,\n BipartiteOptions,\n GraphNodeGeometry,\n Size,\n VizKey,\n} from \"./types.js\";\nimport {\n defaultGraphEdgeStyle,\n defaultGraphLabelStyle,\n defaultGraphNodeStyle,\n GraphLabel,\n GraphNode,\n resolveMarkStyle,\n useGraphFrame,\n} from \"./shared.js\";\n\nfunction access<D, V>(input: Accessor<D, V>, datum: D): V {\n return typeof input === \"function\"\n ? input(datum)\n : (datum as Record<PropertyKey, V>)[input];\n}\nfunction finite(value: number, name: string, zero = false) {\n if (!Number.isFinite(value) || (zero && value < 0))\n throw new RangeError(\n `layoutBipartite: ${name} must be finite${zero ? \" and nonnegative\" : \"\"}.`,\n );\n return value;\n}\nfunction label(\n text: string,\n bounds: { x: number; y: number; width: number; height: number },\n) {\n return Object.freeze({\n text,\n bounds: Object.freeze(bounds),\n rotationDegrees: 0,\n });\n}\nfunction route(a: { x: number; y: number }, b: { x: number; y: number }) {\n const middle = (a.x + b.x) / 2;\n const segments = Object.freeze([\n { type: \"move\" as const, x: a.x, y: a.y },\n {\n type: \"cubic\" as const,\n cp1x: middle,\n cp1y: a.y,\n cp2x: middle,\n cp2y: b.y,\n x: b.x,\n y: b.y,\n },\n ]);\n return Object.freeze({\n sourceAnchor: Object.freeze(a),\n targetAnchor: Object.freeze(b),\n segments,\n arrowSegments: null,\n });\n}\nfunction path(route: { segments: readonly PathSegment[] }) {\n return route.segments\n .map((segment) =>\n segment.type === \"move\"\n ? `M ${segment.x} ${segment.y}`\n : segment.type === \"cubic\"\n ? `C ${segment.cp1x} ${segment.cp1y} ${segment.cp2x} ${segment.cp2y} ${segment.x} ${segment.y}`\n : \"\",\n )\n .join(\" \");\n}\nfunction placed<D>(\n data: readonly D[],\n keyBy: Accessor<D, VizKey>,\n labelBy: Accessor<D, string> | undefined,\n atX: number,\n bounds: { y: number; height: number },\n size: ((datum: D) => Size) | undefined,\n gap: number,\n): readonly GraphNodeGeometry<D>[] {\n const total =\n data.reduce((sum, datum) => sum + (size?.(datum).height ?? 34), 0) +\n Math.max(0, data.length - 1) * gap;\n let y = bounds.y + Math.max(0, (bounds.height - total) / 2);\n const seen = new Set<VizKey>();\n return Object.freeze(\n data.map((datum) => {\n const key = access(keyBy, datum);\n if (seen.has(key))\n throw new Error(\n `layoutBipartite: duplicate node key ${String(key)} on one side.`,\n );\n seen.add(key);\n const dimensions = size?.(datum) ?? { width: 150, height: 34 };\n const box = {\n x: atX,\n y,\n width: dimensions.width,\n height: dimensions.height,\n };\n y += dimensions.height + gap;\n return Object.freeze({\n key,\n datum,\n bounds: Object.freeze(box),\n label: label(labelBy ? access(labelBy, datum) : String(key), box),\n detail: null,\n });\n }),\n );\n}\n\n/** Arranges two explicit entity sets in columns, retaining side-qualified identity.\n * @param graph - Explicit left and right entities with cross-set edges. See {@link BipartiteData}.\n * @param options - Accessors, dimensions, and column spacing. See {@link BipartiteOptions}.\n * @returns Immutable side-aware nodes and routed edges. See {@link BipartiteLayout}.\n */\nexport function layoutBipartite<L, R, E>(\n graph: BipartiteData<L, R, E>,\n options: BipartiteOptions<L, R, E>,\n): BipartiteLayout<L, R, E> {\n const b = options.bounds;\n finite(b.x, \"bounds.x\");\n finite(b.y, \"bounds.y\");\n finite(b.width, \"bounds.width\", true);\n finite(b.height, \"bounds.height\", true);\n const gap = finite(options.nodeGap ?? 12, \"nodeGap\", true),\n columnGap = finite(options.columnGap ?? 120, \"columnGap\", true);\n const leftSize = options.leftSize,\n leftResolver: ((datum: L) => Size) | undefined =\n typeof leftSize === \"function\"\n ? leftSize\n : leftSize === undefined\n ? undefined\n : () => leftSize;\n const rightSize = options.rightSize,\n rightResolver: ((datum: R) => Size) | undefined =\n typeof rightSize === \"function\"\n ? rightSize\n : rightSize === undefined\n ? undefined\n : () => rightSize;\n const left = placed(\n graph.left,\n options.leftKey,\n options.leftLabel,\n b.x,\n b,\n leftResolver,\n gap,\n );\n const rightWidth =\n typeof rightSize === \"function\" ? 150 : (rightSize?.width ?? 150);\n const right = placed(\n graph.right,\n options.rightKey,\n options.rightLabel,\n Math.max(b.x, b.x + b.width - rightWidth),\n b,\n rightResolver,\n gap,\n );\n const leftByKey = new Map(left.map((node) => [node.key, node])),\n rightByKey = new Map(right.map((node) => [node.key, node]));\n const edgeKeys = new Set<VizKey>();\n const edges = graph.edges.map((edge) => {\n const key = access(options.edgeKey, edge);\n if (edgeKeys.has(key))\n throw new Error(`layoutBipartite: duplicate edge key ${String(key)}.`);\n edgeKeys.add(key);\n const source = access(options.source, edge),\n target = access(options.target, edge),\n leftNode = leftByKey.get(source),\n rightNode = rightByKey.get(target);\n if (!leftNode || !rightNode)\n throw new RangeError(\n \"layoutBipartite: every edge must point from a known left key to a known right key.\",\n );\n const r = route(\n {\n x: leftNode.bounds.x + leftNode.bounds.width,\n y: leftNode.bounds.y + leftNode.bounds.height / 2,\n },\n {\n x: rightNode.bounds.x,\n y: rightNode.bounds.y + rightNode.bounds.height / 2,\n },\n );\n return Object.freeze({\n key,\n datum: edge,\n sourceKey: source,\n targetKey: target,\n left: leftNode,\n right: rightNode,\n route: r,\n path: path(r),\n arrowPath: null,\n });\n });\n if (\n left.length &&\n right.length &&\n right[0].bounds.x - (left[0].bounds.x + left[0].bounds.width) < columnGap\n )\n throw new RangeError(\n \"layoutBipartite: bounds are too narrow for node sizes and columnGap.\",\n );\n return Object.freeze({\n bounds: Object.freeze({ ...b }),\n left,\n right,\n edges: Object.freeze(edges),\n });\n}\n\n/** Render left/right entity sets and their cross-set relationships.\n * @param props - Entity data and presentation.\n * @returns Canvas node.\n * @see {@link layoutBipartite}\n */\nexport function BipartiteGraph<L, R, E>(\n props: BipartiteGraphProps<L, R, E>,\n): PibblNode {\n const frame = useGraphFrame(props.style),\n style = frame.style;\n if (!frame.bounds.width || !frame.bounds.height)\n return <Group style={frame.groupStyle}>{null}</Group>;\n const layout = layoutBipartite(resolveSignalValue(props.graph), {\n ...props,\n bounds: frame.bounds,\n columnGap: style.columnGap,\n nodeGap: style.nodeGap,\n });\n return (\n <Group style={frame.groupStyle}>\n {layout.edges.map((edge) => (\n <Group\n key={String(edge.key)}\n onClick={(event) => props.onEdgeClick?.(edge, event)}\n >\n {props.renderEdge ? (\n props.renderEdge(edge)\n ) : (\n <SvgPath\n style={{\n ...defaultGraphEdgeStyle(edge),\n ...resolveMarkStyle(edge, props.edgeStyle),\n d: edge.path,\n }}\n />\n )}\n </Group>\n ))}\n {layout.left.map((node) => (\n <Group\n key={`left-${String(node.key)}`}\n onClick={(event) => props.onLeftNodeClick?.(node, event)}\n >\n {props.renderLeftNode ? (\n props.renderLeftNode(node)\n ) : (\n <Group>\n <GraphNode\n node={node}\n style={{\n ...defaultGraphNodeStyle(node),\n ...resolveMarkStyle(node, props.leftNodeStyle),\n }}\n />\n <GraphLabel\n label={node.label}\n style={{\n ...defaultGraphLabelStyle(node.label),\n ...resolveSignalValue(props.labelStyle),\n }}\n />\n </Group>\n )}\n </Group>\n ))}\n {layout.right.map((node) => (\n <Group\n key={`right-${String(node.key)}`}\n onClick={(event) => props.onRightNodeClick?.(node, event)}\n >\n {props.renderRightNode ? (\n props.renderRightNode(node)\n ) : (\n <Group>\n <GraphNode\n node={node}\n style={{\n ...defaultGraphNodeStyle(node),\n ...resolveMarkStyle(node, props.rightNodeStyle),\n }}\n />\n <GraphLabel\n label={node.label}\n style={{\n ...defaultGraphLabelStyle(node.label),\n ...resolveSignalValue(props.labelStyle),\n }}\n />\n </Group>\n )}\n </Group>\n ))}\n </Group>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["route"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PibblNode } from "@pibbl/core";
|
|
2
|
+
import type { ChordBandGeometry, ChordData, ChordDiagramProps, ChordLayout, ChordOptions, ChordRibbonGeometry, EdgeStyle, MarkInteraction, Style } from "./types.js";
|
|
3
|
+
/** Computes a directed chord layout, aggregating repeated ordered transfer pairs.
|
|
4
|
+
* @param data - Ordered category transfers. See {@link ChordData}.
|
|
5
|
+
* @param options - Accessors, bounds, angular spacing, and unit. See {@link ChordOptions}.
|
|
6
|
+
* @returns Immutable bands and directed ribbon geometry. See {@link ChordLayout}.
|
|
7
|
+
*/
|
|
8
|
+
export declare function layoutChords<C, T>(data: ChordData<C, T>, options: ChordOptions<C, T>): ChordLayout<C, T>;
|
|
9
|
+
/** Default outer-band paint for custom chord compositions.
|
|
10
|
+
* @param _band - Band geometry.
|
|
11
|
+
* @returns Resolved band paint.
|
|
12
|
+
* @see {@link ChordBand}
|
|
13
|
+
*/
|
|
14
|
+
export declare function defaultChordBandStyle<C>(_band: ChordBandGeometry<C>): EdgeStyle;
|
|
15
|
+
/** Default directed-ribbon paint for custom chord compositions.
|
|
16
|
+
* @param _ribbon - Ribbon geometry.
|
|
17
|
+
* @returns Resolved ribbon paint.
|
|
18
|
+
* @see {@link ChordRibbon}
|
|
19
|
+
*/
|
|
20
|
+
export declare function defaultChordRibbonStyle<T>(_ribbon: ChordRibbonGeometry<T>): EdgeStyle;
|
|
21
|
+
/** Draw one supplied category band.
|
|
22
|
+
* @param argument - Band props.
|
|
23
|
+
* @returns Canvas node.
|
|
24
|
+
* @see {@link ChordBandGeometry}
|
|
25
|
+
*/
|
|
26
|
+
export declare function ChordBand<C>({ band, style: input, ...events }: MarkInteraction & {
|
|
27
|
+
readonly band: ChordBandGeometry<C>;
|
|
28
|
+
readonly style?: Style<EdgeStyle>;
|
|
29
|
+
}): PibblNode;
|
|
30
|
+
/** Draw one supplied directed ribbon.
|
|
31
|
+
* @param argument - Ribbon props.
|
|
32
|
+
* @returns Canvas node.
|
|
33
|
+
* @see {@link ChordRibbonGeometry}
|
|
34
|
+
*/
|
|
35
|
+
export declare function ChordRibbon<T>({ ribbon, style: input, ...events }: MarkInteraction & {
|
|
36
|
+
readonly ribbon: ChordRibbonGeometry<T>;
|
|
37
|
+
readonly style?: Style<EdgeStyle>;
|
|
38
|
+
}): PibblNode;
|
|
39
|
+
/** Render a directed transfer chord diagram.
|
|
40
|
+
* @param props - Transfer data and presentation.
|
|
41
|
+
* @returns Canvas node.
|
|
42
|
+
* @see {@link layoutChords}
|
|
43
|
+
*/
|
|
44
|
+
export declare function ChordDiagram<C, T>(props: ChordDiagramProps<C, T>): PibblNode;
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { jsx, jsxs } from "@pibbl/core/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
Group,
|
|
4
|
+
SvgPath,
|
|
5
|
+
resolveSignalValue,
|
|
6
|
+
PathGeometry,
|
|
7
|
+
toSvgPathData
|
|
8
|
+
} from "@pibbl/core";
|
|
9
|
+
import {
|
|
10
|
+
defaultGraphLabelStyle,
|
|
11
|
+
GraphLabel,
|
|
12
|
+
resolveMarkStyle,
|
|
13
|
+
useGraphFrame
|
|
14
|
+
} from "./shared.js";
|
|
15
|
+
function access(input, datum) {
|
|
16
|
+
return typeof input === "function" ? input(datum) : datum[input];
|
|
17
|
+
}
|
|
18
|
+
function finite(value, name, zero = false) {
|
|
19
|
+
if (!Number.isFinite(value) || zero && value < 0)
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
`layoutChords: ${name} must be finite${zero ? " and nonnegative" : ""}.`
|
|
22
|
+
);
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function point(cx, cy, radius, degrees) {
|
|
26
|
+
const radians = (degrees - 90) * Math.PI / 180;
|
|
27
|
+
return {
|
|
28
|
+
x: cx + Math.cos(radians) * radius,
|
|
29
|
+
y: cy + Math.sin(radians) * radius
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function svg(segments) {
|
|
33
|
+
const geometry = new PathGeometry();
|
|
34
|
+
geometry.spliceSegments(0, 0, segments);
|
|
35
|
+
return toSvgPathData(geometry);
|
|
36
|
+
}
|
|
37
|
+
function bandSegments(cx, cy, outer, inner, start, end) {
|
|
38
|
+
const first = point(cx, cy, outer, start), last = point(cx, cy, inner, end), radians = Math.PI / 180;
|
|
39
|
+
return Object.freeze([
|
|
40
|
+
{ type: "move", ...first },
|
|
41
|
+
{
|
|
42
|
+
type: "arc",
|
|
43
|
+
cx,
|
|
44
|
+
cy,
|
|
45
|
+
ux: outer,
|
|
46
|
+
uy: 0,
|
|
47
|
+
vx: 0,
|
|
48
|
+
vy: outer,
|
|
49
|
+
startAngle: (start - 90) * radians,
|
|
50
|
+
sweep: (end - start) * radians
|
|
51
|
+
},
|
|
52
|
+
{ type: "line", ...last },
|
|
53
|
+
{
|
|
54
|
+
type: "arc",
|
|
55
|
+
cx,
|
|
56
|
+
cy,
|
|
57
|
+
ux: inner,
|
|
58
|
+
uy: 0,
|
|
59
|
+
vx: 0,
|
|
60
|
+
vy: inner,
|
|
61
|
+
startAngle: (end - 90) * radians,
|
|
62
|
+
sweep: (start - end) * radians
|
|
63
|
+
},
|
|
64
|
+
{ type: "close" }
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
function layoutChords(data, options) {
|
|
68
|
+
const b = options.bounds;
|
|
69
|
+
finite(b.x, "bounds.x");
|
|
70
|
+
finite(b.y, "bounds.y");
|
|
71
|
+
finite(b.width, "bounds.width", true);
|
|
72
|
+
finite(b.height, "bounds.height", true);
|
|
73
|
+
const width = finite(options.bandWidth ?? 20, "bandWidth", true), pad = finite(options.padAngle ?? 2, "padAngle", true), start = finite(options.startAngle ?? 0, "startAngle");
|
|
74
|
+
if (data.categories.length * pad >= 360 && data.categories.length)
|
|
75
|
+
throw new RangeError(
|
|
76
|
+
"layoutChords: total padAngle must be less than 360 degrees."
|
|
77
|
+
);
|
|
78
|
+
const categories = /* @__PURE__ */ new Map();
|
|
79
|
+
for (const category of data.categories) {
|
|
80
|
+
const key = access(options.categoryKey, category);
|
|
81
|
+
if (categories.has(key))
|
|
82
|
+
throw new Error(`layoutChords: duplicate category key ${String(key)}.`);
|
|
83
|
+
categories.set(key, category);
|
|
84
|
+
}
|
|
85
|
+
const groups = /* @__PURE__ */ new Map();
|
|
86
|
+
const incoming = /* @__PURE__ */ new Map(), outgoing = /* @__PURE__ */ new Map();
|
|
87
|
+
for (const key of categories.keys()) {
|
|
88
|
+
incoming.set(key, 0);
|
|
89
|
+
outgoing.set(key, 0);
|
|
90
|
+
}
|
|
91
|
+
for (const transfer of data.transfers) {
|
|
92
|
+
const source = access(options.source, transfer), target = access(options.target, transfer), amount = finite(access(options.value, transfer), "transfer value", true);
|
|
93
|
+
if (!categories.has(source) || !categories.has(target))
|
|
94
|
+
throw new RangeError(
|
|
95
|
+
"layoutChords: transfer endpoint is not a category key."
|
|
96
|
+
);
|
|
97
|
+
incoming.set(
|
|
98
|
+
target,
|
|
99
|
+
finite(incoming.get(target) + amount, "incoming total", true)
|
|
100
|
+
);
|
|
101
|
+
outgoing.set(
|
|
102
|
+
source,
|
|
103
|
+
finite(outgoing.get(source) + amount, "outgoing total", true)
|
|
104
|
+
);
|
|
105
|
+
const id = `chord:${typeof source}:${String(source)}\0${typeof target}:${String(target)}`;
|
|
106
|
+
const prior = groups.get(id);
|
|
107
|
+
if (prior) {
|
|
108
|
+
prior.records.push(transfer);
|
|
109
|
+
prior.value = finite(prior.value + amount, "transfer total", true);
|
|
110
|
+
} else
|
|
111
|
+
groups.set(id, { source, target, records: [transfer], value: amount });
|
|
112
|
+
}
|
|
113
|
+
const total = Array.from(groups.values()).reduce(
|
|
114
|
+
(sum2, entry) => sum2 + entry.value,
|
|
115
|
+
0
|
|
116
|
+
);
|
|
117
|
+
const cx = b.x + b.width / 2, cy = b.y + b.height / 2, radius = Math.max(0, Math.min(b.width, b.height) / 2 - 28), inner = Math.max(0, radius - width);
|
|
118
|
+
const weight = Array.from(categories.keys()).map(
|
|
119
|
+
(key) => incoming.get(key) + outgoing.get(key)
|
|
120
|
+
);
|
|
121
|
+
const sum = weight.reduce((a, n) => a + n, 0);
|
|
122
|
+
finite(total, "transfer total", true);
|
|
123
|
+
finite(sum, "incident total", true);
|
|
124
|
+
const usable = 360 - data.categories.length * pad;
|
|
125
|
+
let angle = start;
|
|
126
|
+
const bands = [];
|
|
127
|
+
const arcs = /* @__PURE__ */ new Map();
|
|
128
|
+
for (let index = 0; index < data.categories.length; index++) {
|
|
129
|
+
const datum = data.categories[index], key = access(options.categoryKey, datum), span = sum === 0 ? 0 : weight[index] / sum * usable, arc = Object.freeze({
|
|
130
|
+
center: Object.freeze({ x: cx, y: cy }),
|
|
131
|
+
radius,
|
|
132
|
+
startAngleDegrees: angle,
|
|
133
|
+
endAngleDegrees: angle + span
|
|
134
|
+
});
|
|
135
|
+
const segments = bandSegments(cx, cy, radius, inner, angle, angle + span);
|
|
136
|
+
const mid = angle + span / 2, labelPoint = point(cx, cy, radius + 18, mid);
|
|
137
|
+
const label = Object.freeze({
|
|
138
|
+
text: options.label ? access(options.label, datum) : String(key),
|
|
139
|
+
bounds: Object.freeze({
|
|
140
|
+
x: labelPoint.x - 45,
|
|
141
|
+
y: labelPoint.y - 10,
|
|
142
|
+
width: 90,
|
|
143
|
+
height: 20
|
|
144
|
+
}),
|
|
145
|
+
rotationDegrees: 0
|
|
146
|
+
});
|
|
147
|
+
bands.push(
|
|
148
|
+
Object.freeze({
|
|
149
|
+
key,
|
|
150
|
+
datum,
|
|
151
|
+
incomingValue: incoming.get(key),
|
|
152
|
+
outgoingValue: outgoing.get(key),
|
|
153
|
+
arc,
|
|
154
|
+
innerRadius: inner,
|
|
155
|
+
segments,
|
|
156
|
+
path: svg(segments),
|
|
157
|
+
label
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
arcs.set(key, { start: angle, end: angle + span, cursor: angle });
|
|
161
|
+
angle += span + pad;
|
|
162
|
+
}
|
|
163
|
+
const ribbons = [];
|
|
164
|
+
for (const entry of groups.values()) {
|
|
165
|
+
if (entry.value === 0) continue;
|
|
166
|
+
const source = arcs.get(entry.source), target = arcs.get(entry.target);
|
|
167
|
+
const sourceWeight = incoming.get(entry.source) + outgoing.get(entry.source), targetWeight = incoming.get(entry.target) + outgoing.get(entry.target);
|
|
168
|
+
const sourceSpan = sourceWeight === 0 ? 0 : (source.end - source.start) * entry.value / sourceWeight, targetSpan = targetWeight === 0 ? 0 : (target.end - target.start) * entry.value / targetWeight;
|
|
169
|
+
const sourceArc = Object.freeze({
|
|
170
|
+
center: Object.freeze({ x: cx, y: cy }),
|
|
171
|
+
radius: inner,
|
|
172
|
+
startAngleDegrees: source.cursor,
|
|
173
|
+
endAngleDegrees: source.cursor + sourceSpan
|
|
174
|
+
});
|
|
175
|
+
source.cursor += sourceSpan;
|
|
176
|
+
const targetStart = target.cursor;
|
|
177
|
+
const targetArc = Object.freeze({
|
|
178
|
+
center: Object.freeze({ x: cx, y: cy }),
|
|
179
|
+
radius: inner,
|
|
180
|
+
startAngleDegrees: targetStart,
|
|
181
|
+
endAngleDegrees: targetStart + targetSpan
|
|
182
|
+
});
|
|
183
|
+
target.cursor += targetSpan;
|
|
184
|
+
const a = point(cx, cy, inner, sourceArc.startAngleDegrees), d = point(cx, cy, inner, targetArc.startAngleDegrees);
|
|
185
|
+
const segments = Object.freeze([
|
|
186
|
+
{ type: "move", ...a },
|
|
187
|
+
{
|
|
188
|
+
type: "arc",
|
|
189
|
+
cx,
|
|
190
|
+
cy,
|
|
191
|
+
ux: inner,
|
|
192
|
+
uy: 0,
|
|
193
|
+
vx: 0,
|
|
194
|
+
vy: inner,
|
|
195
|
+
startAngle: (sourceArc.startAngleDegrees - 90) * Math.PI / 180,
|
|
196
|
+
sweep: (sourceArc.endAngleDegrees - sourceArc.startAngleDegrees) * Math.PI / 180
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
type: "quadratic",
|
|
200
|
+
cpx: cx,
|
|
201
|
+
cpy: cy,
|
|
202
|
+
x: d.x,
|
|
203
|
+
y: d.y
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
type: "arc",
|
|
207
|
+
cx,
|
|
208
|
+
cy,
|
|
209
|
+
ux: inner,
|
|
210
|
+
uy: 0,
|
|
211
|
+
vx: 0,
|
|
212
|
+
vy: inner,
|
|
213
|
+
startAngle: (targetArc.startAngleDegrees - 90) * Math.PI / 180,
|
|
214
|
+
sweep: (targetArc.endAngleDegrees - targetArc.startAngleDegrees) * Math.PI / 180
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: "quadratic",
|
|
218
|
+
cpx: cx,
|
|
219
|
+
cpy: cy,
|
|
220
|
+
x: a.x,
|
|
221
|
+
y: a.y
|
|
222
|
+
},
|
|
223
|
+
{ type: "close" }
|
|
224
|
+
]);
|
|
225
|
+
ribbons.push(
|
|
226
|
+
Object.freeze({
|
|
227
|
+
key: `${typeof entry.source}:${String(entry.source)}\0${typeof entry.target}:${String(entry.target)}`,
|
|
228
|
+
sourceKey: entry.source,
|
|
229
|
+
targetKey: entry.target,
|
|
230
|
+
records: Object.freeze(entry.records),
|
|
231
|
+
value: entry.value,
|
|
232
|
+
sourceArc,
|
|
233
|
+
targetArc,
|
|
234
|
+
segments,
|
|
235
|
+
path: svg(segments)
|
|
236
|
+
})
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
return Object.freeze({
|
|
240
|
+
bounds: Object.freeze({ ...b }),
|
|
241
|
+
unit: options.unit,
|
|
242
|
+
total,
|
|
243
|
+
bands: Object.freeze(bands),
|
|
244
|
+
ribbons: Object.freeze(ribbons)
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function defaultChordBandStyle(_band) {
|
|
248
|
+
return { fill: "#0f766e" };
|
|
249
|
+
}
|
|
250
|
+
function defaultChordRibbonStyle(_ribbon) {
|
|
251
|
+
return { fill: "rgba(15, 118, 110, 0.3)" };
|
|
252
|
+
}
|
|
253
|
+
function ChordBand({
|
|
254
|
+
band,
|
|
255
|
+
style: input,
|
|
256
|
+
...events
|
|
257
|
+
}) {
|
|
258
|
+
return /* @__PURE__ */ jsx(
|
|
259
|
+
SvgPath,
|
|
260
|
+
{
|
|
261
|
+
...events,
|
|
262
|
+
style: { ...resolveSignalValue(input) ?? {}, d: band.path }
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
function ChordRibbon({
|
|
267
|
+
ribbon,
|
|
268
|
+
style: input,
|
|
269
|
+
...events
|
|
270
|
+
}) {
|
|
271
|
+
return /* @__PURE__ */ jsx(
|
|
272
|
+
SvgPath,
|
|
273
|
+
{
|
|
274
|
+
...events,
|
|
275
|
+
style: { ...resolveSignalValue(input) ?? {}, d: ribbon.path }
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
function ChordDiagram(props) {
|
|
280
|
+
const frame = useGraphFrame(props.style), style = frame.style;
|
|
281
|
+
if (!frame.bounds.width || !frame.bounds.height)
|
|
282
|
+
return /* @__PURE__ */ jsx(Group, { style: frame.groupStyle, children: null });
|
|
283
|
+
const layout = layoutChords(resolveSignalValue(props.data), {
|
|
284
|
+
...props,
|
|
285
|
+
bounds: frame.bounds,
|
|
286
|
+
bandWidth: style.bandWidth,
|
|
287
|
+
padAngle: style.padAngle,
|
|
288
|
+
startAngle: style.startAngle
|
|
289
|
+
});
|
|
290
|
+
return /* @__PURE__ */ jsxs(Group, { style: frame.groupStyle, children: [
|
|
291
|
+
layout.ribbons.map((ribbon) => /* @__PURE__ */ jsx(
|
|
292
|
+
Group,
|
|
293
|
+
{
|
|
294
|
+
onClick: (event) => props.onRibbonClick?.(ribbon, event),
|
|
295
|
+
children: props.renderRibbon ? props.renderRibbon(ribbon) : /* @__PURE__ */ jsx(
|
|
296
|
+
ChordRibbon,
|
|
297
|
+
{
|
|
298
|
+
ribbon,
|
|
299
|
+
keyboardFocusable: Boolean(props.onRibbonClick),
|
|
300
|
+
style: {
|
|
301
|
+
...defaultChordRibbonStyle(ribbon),
|
|
302
|
+
...resolveMarkStyle(ribbon, props.ribbonStyle)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
)
|
|
306
|
+
},
|
|
307
|
+
ribbon.key
|
|
308
|
+
)),
|
|
309
|
+
layout.bands.map((band) => /* @__PURE__ */ jsx(
|
|
310
|
+
Group,
|
|
311
|
+
{
|
|
312
|
+
onClick: (event) => props.onBandClick?.(band, event),
|
|
313
|
+
children: props.renderBand ? props.renderBand(band) : /* @__PURE__ */ jsxs(Group, { children: [
|
|
314
|
+
/* @__PURE__ */ jsx(
|
|
315
|
+
ChordBand,
|
|
316
|
+
{
|
|
317
|
+
band,
|
|
318
|
+
style: {
|
|
319
|
+
...defaultChordBandStyle(band),
|
|
320
|
+
...resolveMarkStyle(band, props.bandStyle)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
),
|
|
324
|
+
/* @__PURE__ */ jsx(
|
|
325
|
+
GraphLabel,
|
|
326
|
+
{
|
|
327
|
+
label: band.label,
|
|
328
|
+
style: {
|
|
329
|
+
...defaultGraphLabelStyle(band.label),
|
|
330
|
+
...resolveSignalValue(props.labelStyle)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
] })
|
|
335
|
+
},
|
|
336
|
+
String(band.key)
|
|
337
|
+
))
|
|
338
|
+
] });
|
|
339
|
+
}
|
|
340
|
+
export {
|
|
341
|
+
ChordBand,
|
|
342
|
+
ChordDiagram,
|
|
343
|
+
ChordRibbon,
|
|
344
|
+
defaultChordBandStyle,
|
|
345
|
+
defaultChordRibbonStyle,
|
|
346
|
+
layoutChords
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=chord.js.map
|