semiotic 3.8.3 → 3.8.4
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 +9 -9
- package/README.md +40 -39
- package/ai/examples.md +1 -1
- package/ai/schema.json +2726 -300
- package/ai/surface-manifest.json +1 -1
- package/ai/system-prompt.md +1 -1
- package/dist/chunk-chunk-2JGJ5GUG.module.min.js +0 -1
- package/dist/chunk-chunk-3ILKBVVQ.module.min.js +1 -0
- package/dist/{chunk-chunk-XQYVEKEJ.module.min.js → chunk-chunk-6TPGFL7M.module.min.js} +1 -1
- package/dist/{chunk-chunk-VVCA3DB7.module.min.js → chunk-chunk-7ALTGHK6.module.min.js} +1 -1
- package/dist/chunk-chunk-7KZJUTKP.module.min.js +2 -0
- package/dist/chunk-chunk-7RYBCTK5.module.min.js +1 -0
- package/dist/chunk-chunk-ACLDBMRH.module.min.js +2 -0
- package/dist/{chunk-chunk-AZJUDQRM.module.min.js → chunk-chunk-AQPQN2HH.module.min.js} +1 -1
- package/dist/chunk-chunk-ASKSE5F5.module.min.js +1 -0
- package/dist/chunk-chunk-AVBI6GDT.module.min.js +1 -0
- package/dist/chunk-chunk-B3DRZPBK.module.min.js +2 -0
- package/dist/chunk-chunk-BFHUYEOS.module.min.js +2 -0
- package/dist/chunk-chunk-C4YA6TDR.module.min.js +1 -0
- package/dist/chunk-chunk-C57LR3YG.module.min.js +1 -0
- package/dist/chunk-chunk-F5V4UIE6.module.min.js +2 -0
- package/dist/chunk-chunk-F7WFPD4O.module.min.js +2 -0
- package/dist/{chunk-chunk-SANERMIZ.module.min.js → chunk-chunk-FBGHXL72.module.min.js} +1 -1
- package/dist/chunk-chunk-FP44FHFO.module.min.js +2 -0
- package/dist/chunk-chunk-HKXUAEPJ.module.min.js +2 -0
- package/dist/chunk-chunk-ICEXPNDC.module.min.js +2 -0
- package/dist/chunk-chunk-IY7RYD4S.module.min.js +1 -0
- package/dist/{chunk-chunk-7FW6EGLP.module.min.js → chunk-chunk-JDXT6ORT.module.min.js} +1 -1
- package/dist/chunk-chunk-JMVEIZXP.module.min.js +1 -0
- package/dist/chunk-chunk-KHCOJMGK.module.min.js +1 -0
- package/dist/{chunk-chunk-OQTLSTGI.module.min.js → chunk-chunk-KQ546MKE.module.min.js} +1 -1
- package/dist/chunk-chunk-LQBSXO7K.module.min.js +2 -0
- package/dist/chunk-chunk-LRIFN2HK.module.min.js +1 -0
- package/dist/chunk-chunk-MFHF4J2Z.module.min.js +1 -0
- package/dist/{chunk-chunk-JNCHKRIR.module.min.js → chunk-chunk-N6VKKF3A.module.min.js} +1 -1
- package/dist/chunk-chunk-NEVE562N.module.min.js +1 -0
- package/dist/chunk-chunk-NKZ75IM5.module.min.js +2 -0
- package/dist/chunk-chunk-PLIDPQNG.module.min.js +2 -0
- package/dist/{chunk-chunk-FYY2ACNJ.module.min.js → chunk-chunk-PRDGLMJT.module.min.js} +1 -1
- package/dist/chunk-chunk-QGZGZI4X.module.min.js +1 -0
- package/dist/chunk-chunk-RP7WTID5.module.min.js +1 -0
- package/dist/chunk-chunk-S7KLNUO6.module.min.js +1 -0
- package/dist/chunk-chunk-SR4ZXOWR.module.min.js +2 -0
- package/dist/chunk-chunk-ZOAQDIJO.module.min.js +1 -0
- package/dist/chunk-minimapBrushOverlay-JU57U7NM.module.min.js +2 -0
- package/dist/chunk-scatterplotMatrixBrushOverlay-SDIZSN66.module.min.js +2 -0
- package/dist/chunk-statisticalOverlays-QGDLRUHX.module.min.js +1 -0
- package/dist/chunk-statisticalOverlays-T77OKLDY.module.min.js +1 -0
- package/dist/components/ChartContainer.d.ts +2 -2
- package/dist/components/ai/chartCapabilityTypes.d.ts +5 -0
- package/dist/components/charts/geo/ChoroplethMap.d.ts +2 -0
- package/dist/components/charts/geo/DistanceCartogram.d.ts +7 -3
- package/dist/components/charts/geo/FlowMap.d.ts +4 -0
- package/dist/components/charts/geo/ProportionalSymbolMap.d.ts +3 -1
- package/dist/components/charts/physics/CollisionSwarmChart.d.ts +6 -1
- package/dist/components/charts/physics/GaltonBoardChart.d.ts +6 -1
- package/dist/components/charts/physics/gauntletChartProps.d.ts +7 -1
- package/dist/components/charts/physics/gauntletChrome.d.ts +2 -1
- package/dist/components/charts/physics/gauntletPhysics.d.ts +19 -4
- package/dist/components/charts/physics/gauntletRuntime.d.ts +3 -0
- package/dist/components/charts/physics/physicsHocUtils.d.ts +12 -0
- package/dist/components/charts/shared/chartMode.d.ts +8 -0
- package/dist/components/charts/shared/chartSpecCore.d.ts +2 -2
- package/dist/components/charts/shared/hatchPattern.d.ts +8 -3
- package/dist/components/charts/shared/lineSeriesSsr.d.ts +55 -0
- package/dist/components/charts/shared/types.d.ts +2 -2
- package/dist/components/charts/shared/validateProps.d.ts +1 -1
- package/dist/components/charts/xy/AreaChart.d.ts +10 -0
- package/dist/components/charts/xy/minimapBrushOverlay.d.ts +17 -0
- package/dist/components/charts/xy/minimapBrushOverlayLazy.d.ts +4 -0
- package/dist/components/charts/xy/scatterplotMatrixBrushOverlay.d.ts +8 -0
- package/dist/components/charts/xy/scatterplotMatrixBrushOverlayLazy.d.ts +3 -0
- package/dist/components/realtime/types.d.ts +5 -0
- package/dist/components/recipes/gridObservatory.d.ts +176 -0
- package/dist/components/recipes/recipeChrome.d.ts +24 -0
- package/dist/components/recipes/sequenceLayout.d.ts +139 -0
- package/dist/components/semiotic-recipes-core.d.ts +6 -2
- package/dist/components/server/staticAnnotations.d.ts +3 -1
- package/dist/components/stream/SceneToSVG.d.ts +6 -6
- package/dist/components/stream/SceneToSVGOrdinal.d.ts +12 -0
- package/dist/components/stream/networkFramePaint.d.ts +2 -0
- package/dist/components/stream/physics/PhysicsPipelineStore.d.ts +18 -2
- package/dist/components/stream/physics/physicsBodyCanvas.d.ts +7 -0
- package/dist/components/stream/physics/physicsPipelineEviction.d.ts +15 -0
- package/dist/components/stream/physics/physicsPipelineObservations.d.ts +1 -1
- package/dist/components/stream/physics/physicsPipelineQuiescence.d.ts +20 -0
- package/dist/components/stream/sceneToSVGShared.d.ts +30 -1
- package/dist/components/stream/types.d.ts +4 -0
- package/dist/components/stream/useHydration.d.ts +7 -1
- package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +1 -1
- package/dist/forceLayoutWorker.js +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/physics.min.js +1 -1
- package/dist/physics.module.min.js +1 -1
- package/dist/physicsWorker.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/rough.min.js +1 -1
- package/dist/rough.module.min.js +1 -1
- package/dist/semiotic-ai-core.min.js +1 -1
- package/dist/semiotic-ai-core.module.min.js +1 -1
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-experimental.min.js +1 -1
- package/dist/semiotic-experimental.module.min.js +1 -1
- package/dist/semiotic-realtime-core.min.js +1 -1
- package/dist/semiotic-realtime-core.module.min.js +1 -1
- package/dist/semiotic-recipes-core.d.ts +6 -2
- package/dist/semiotic-recipes-core.min.js +1 -1
- package/dist/semiotic-recipes-core.module.min.js +1 -1
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-server-edge.min.js +1 -1
- package/dist/semiotic-server-edge.module.min.js +1 -1
- package/dist/semiotic-server-node.min.js +1 -1
- package/dist/semiotic-server-node.module.min.js +1 -1
- package/dist/semiotic-utils-core.min.js +1 -1
- package/dist/semiotic-utils-core.module.min.js +1 -1
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- package/dist/semiotic-value.module.min.js +1 -1
- 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 +3 -2
- package/dist/chunk-chunk-255KDHW5.module.min.js +0 -1
- package/dist/chunk-chunk-2CCFBTQC.module.min.js +0 -2
- package/dist/chunk-chunk-2RXP3FS3.module.min.js +0 -1
- package/dist/chunk-chunk-2WVCH4PL.module.min.js +0 -1
- package/dist/chunk-chunk-4TMZXLCR.module.min.js +0 -1
- package/dist/chunk-chunk-5APBQXZA.module.min.js +0 -1
- package/dist/chunk-chunk-6HSGDMTA.module.min.js +0 -2
- package/dist/chunk-chunk-7OEOSCBP.module.min.js +0 -1
- package/dist/chunk-chunk-A63CTACR.module.min.js +0 -2
- package/dist/chunk-chunk-B6V35LMY.module.min.js +0 -2
- package/dist/chunk-chunk-BOSVL645.module.min.js +0 -2
- package/dist/chunk-chunk-CP3EN6KZ.module.min.js +0 -1
- package/dist/chunk-chunk-F25UA5HT.module.min.js +0 -1
- package/dist/chunk-chunk-FRIO6MCV.module.min.js +0 -1
- package/dist/chunk-chunk-GWSWSPXN.module.min.js +0 -1
- package/dist/chunk-chunk-I6C3KR5H.module.min.js +0 -2
- package/dist/chunk-chunk-IP2UE74X.module.min.js +0 -1
- package/dist/chunk-chunk-J3ELI22J.module.min.js +0 -1
- package/dist/chunk-chunk-J5RL6GXU.module.min.js +0 -2
- package/dist/chunk-chunk-L3H6DQCR.module.min.js +0 -2
- package/dist/chunk-chunk-M337NY6L.module.min.js +0 -1
- package/dist/chunk-chunk-M7VYYHCE.module.min.js +0 -2
- package/dist/chunk-chunk-MC35ILYP.module.min.js +0 -2
- package/dist/chunk-chunk-N72SWNBV.module.min.js +0 -1
- package/dist/chunk-chunk-OBQRFTIL.module.min.js +0 -2
- package/dist/chunk-chunk-QRIBHZYW.module.min.js +0 -1
- package/dist/chunk-chunk-SA3D43RA.module.min.js +0 -2
- package/dist/chunk-chunk-UHSZEB74.module.min.js +0 -1
- package/dist/chunk-chunk-Y6AXCRVO.module.min.js +0 -1
- package/dist/chunk-chunk-ZCNBUZPL.module.min.js +0 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequence diagram kit — linear spines, span-arc packing, and shared-edge
|
|
3
|
+
* partition helpers for custom charts that treat a row of marks as a baseline
|
|
4
|
+
* (dependency arcs, co-reference, genomic links, alternate-hypothesis overlays).
|
|
5
|
+
*
|
|
6
|
+
* Pure / SSR-safe. Complements {@link packIntervals} (time tracks) and the
|
|
7
|
+
* edge-router kit (network S-curves): here the domain is an ordered index on a
|
|
8
|
+
* baseline and the mark is a vertical-band arc between two anchors.
|
|
9
|
+
*/
|
|
10
|
+
export interface SequenceItem {
|
|
11
|
+
/** Stable identity used as the position map key. */
|
|
12
|
+
id: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SequencePosition {
|
|
15
|
+
id: string;
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
/** Zero-based order on the baseline. */
|
|
19
|
+
index: number;
|
|
20
|
+
}
|
|
21
|
+
export interface LayoutSequenceOptions {
|
|
22
|
+
width: number;
|
|
23
|
+
y: number;
|
|
24
|
+
/** @default min(74, max(34, width * 0.08)) */
|
|
25
|
+
paddingLeft?: number;
|
|
26
|
+
/** @default min(74, max(34, width * 0.08)) */
|
|
27
|
+
paddingRight?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Place ordered items evenly along a horizontal baseline. Returns a Map keyed
|
|
31
|
+
* by `id` so callers can look up either end of a span arc in O(1).
|
|
32
|
+
*/
|
|
33
|
+
export declare function layoutSequence(items: readonly SequenceItem[], options: LayoutSequenceOptions): Map<string, SequencePosition>;
|
|
34
|
+
export interface ChipStripItem extends SequenceItem {
|
|
35
|
+
/** Optional label used by the default width estimator. */
|
|
36
|
+
label?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface LayoutChipStripOptions extends LayoutSequenceOptions {
|
|
39
|
+
/** Gap between chips when packing by content width. @default 8 */
|
|
40
|
+
gap?: number;
|
|
41
|
+
/**
|
|
42
|
+
* When true (default), distribute free horizontal space evenly between chips
|
|
43
|
+
* so the strip still spans the baseline. When false, pack left-to-right.
|
|
44
|
+
*/
|
|
45
|
+
distribute?: boolean;
|
|
46
|
+
/** Override per-chip width. Defaults to {@link estimateLabelWidth} of `label`/`id`. */
|
|
47
|
+
estimateWidth?: (item: ChipStripItem, index: number) => number;
|
|
48
|
+
}
|
|
49
|
+
export interface ChipStripPosition extends SequencePosition {
|
|
50
|
+
/** Chip width in px (for hulls / hit targets). */
|
|
51
|
+
width: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Place ordered chips along a baseline, sizing each by estimated label width.
|
|
55
|
+
* Prefer {@link layoutSequence} when marks are equal-spaced points rather than
|
|
56
|
+
* variable-width chips.
|
|
57
|
+
*/
|
|
58
|
+
export declare function layoutChipStrip(items: readonly ChipStripItem[], options: LayoutChipStripOptions): Map<string, ChipStripPosition>;
|
|
59
|
+
/**
|
|
60
|
+
* Rough text width for chip / arc labels. Matches the heuristic used by the
|
|
61
|
+
* sentence-structure stage and is good enough for layout before paint.
|
|
62
|
+
*/
|
|
63
|
+
export declare function estimateLabelWidth(text: unknown, minimum?: number, charWidth?: number, pad?: number): number;
|
|
64
|
+
export interface SpanInterval {
|
|
65
|
+
/** Stable identity for the packed result. */
|
|
66
|
+
id: string;
|
|
67
|
+
/** Inclusive left index on the sequence baseline. */
|
|
68
|
+
a: number;
|
|
69
|
+
/** Inclusive right index on the sequence baseline. */
|
|
70
|
+
b: number;
|
|
71
|
+
}
|
|
72
|
+
export interface PackedSpanLevel<T extends SpanInterval = SpanInterval> {
|
|
73
|
+
span: T;
|
|
74
|
+
/** Zero-based height level (0 = closest to the baseline). */
|
|
75
|
+
level: number;
|
|
76
|
+
}
|
|
77
|
+
export interface PackSpanLevelsResult<T extends SpanInterval = SpanInterval> {
|
|
78
|
+
packed: PackedSpanLevel<T>[];
|
|
79
|
+
/** Number of distinct levels used (`maxLevel + 1`, at least 1). */
|
|
80
|
+
levelCount: number;
|
|
81
|
+
maxLevel: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Greedy span packing: assign each interval to the lowest level whose last
|
|
85
|
+
* right edge is already left of this span's left edge. Short spans are packed
|
|
86
|
+
* first so long arcs stack above them — the classic dependency-arc layout.
|
|
87
|
+
*
|
|
88
|
+
* Indices are treated as inclusive; a span with `a === b` is a zero-width hop.
|
|
89
|
+
*/
|
|
90
|
+
export declare function packSpanLevels<T extends SpanInterval>(spans: readonly T[]): PackSpanLevelsResult<T>;
|
|
91
|
+
export interface ScaleArcBandOptions {
|
|
92
|
+
/** Y of the sequence baseline (token line). */
|
|
93
|
+
baselineY: number;
|
|
94
|
+
/** Top of the free vertical band arcs may occupy. */
|
|
95
|
+
ceilingY: number;
|
|
96
|
+
/** From {@link packSpanLevels}. */
|
|
97
|
+
levelCount: number;
|
|
98
|
+
/** Vertical room reserved under each peak for a mid-arc label. @default 18 */
|
|
99
|
+
labelRoom?: number;
|
|
100
|
+
}
|
|
101
|
+
export interface ScaleArcBandResult {
|
|
102
|
+
/** Height of the shortest (level 0) arc above the baseline foot. */
|
|
103
|
+
arcLift: number;
|
|
104
|
+
/** Vertical spacing between successive levels. */
|
|
105
|
+
levelStep: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Stretch packed arc levels across the free band between `ceilingY` and the
|
|
109
|
+
* baseline so short plots are not a cramped nest under a blank canvas.
|
|
110
|
+
*/
|
|
111
|
+
export declare function scaleArcBand(options: ScaleArcBandOptions): ScaleArcBandResult;
|
|
112
|
+
export interface SpanArcPathOptions {
|
|
113
|
+
/**
|
|
114
|
+
* How far above `baselineY` the arc feet attach (keeps arcs off token chips).
|
|
115
|
+
* @default 26
|
|
116
|
+
*/
|
|
117
|
+
footLift?: number;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Quadratic span arc between two x-positions on a baseline. Pure path `d`
|
|
121
|
+
* string for SVG overlays / scene edge emission.
|
|
122
|
+
*/
|
|
123
|
+
export declare function spanArcPath(x0: number, x1: number, baselineY: number, peakY: number, options?: SpanArcPathOptions): string;
|
|
124
|
+
/**
|
|
125
|
+
* Peak y for a packed span level given band metrics from {@link scaleArcBand}.
|
|
126
|
+
*/
|
|
127
|
+
export declare function spanArcPeakY(baselineY: number, level: number, metrics: ScaleArcBandResult): number;
|
|
128
|
+
export type EdgeKeyFn<T> = (edge: T) => string;
|
|
129
|
+
/**
|
|
130
|
+
* Partition several edge lists into the shared intersection (present in every
|
|
131
|
+
* set under `keyOf`) and the per-set exclusive remainder. Used by compare views
|
|
132
|
+
* that paint common topology once and disputed links per hypothesis.
|
|
133
|
+
*
|
|
134
|
+
* Shared edges are taken from the first set (stable identity for paint keys).
|
|
135
|
+
*/
|
|
136
|
+
export declare function partitionSharedEdges<T>(edgeSets: readonly (readonly T[])[], keyOf?: EdgeKeyFn<T>): {
|
|
137
|
+
shared: T[];
|
|
138
|
+
exclusive: T[][];
|
|
139
|
+
};
|
|
@@ -39,6 +39,8 @@ export { annotationLayout } from "./recipes/annotationLayout";
|
|
|
39
39
|
export type { AnnotationLayoutConfig, AnnotationLayoutOptions, AutoPlaceAnnotations, AutoPlaceAnnotationsConfig, AnnotationCohesion, AnnotationAudience, AnnotationMobileConfig, } from "./recipes/annotationLayout";
|
|
40
40
|
export { annotationDensity, annotationBudget, DEFAULT_AREA_PER_ANNOTATION } from "./recipes/annotationDensity";
|
|
41
41
|
export type { AnnotationDensityConfig, AnnotationDensityOptions, AnnotationDensityResult, } from "./recipes/annotationDensity";
|
|
42
|
+
export { GRID_FUEL_KEYS, GRID_FUEL_LABELS, stackFuelSeries, demandForecastRows, reserveMarginPct, reserveSeries, thresholdBandsForReserve, reserveAnnotationBands, summarizeOperatingPoint, gridEventAnnotations, tightestHours, formatMw, formatReservePct, } from "./recipes/gridObservatory";
|
|
43
|
+
export type { GridFuelKey, GridHour, ReserveSnapshot, ReserveLevels, FuelStackRow, DemandForecastRow, OperatingPointSummary, GridEventWindow, } from "./recipes/gridObservatory";
|
|
42
44
|
export { intervalLanesLayout } from "./recipes/intervalLanes";
|
|
43
45
|
export type { IntervalLanesConfig } from "./recipes/intervalLanes";
|
|
44
46
|
export { axisFixedForceLayout, axisFixedForcePositions, rectCollide } from "./recipes/axisFixedForce";
|
|
@@ -50,6 +52,8 @@ export type { Run, RunOptions } from "./recipes/runs";
|
|
|
50
52
|
export { wrapValue, shortestArcDelta, cyclicRangeContains, selectCyclicRange } from "./recipes/cyclical";
|
|
51
53
|
export { packIntervals, activeCountOverDomain } from "./recipes/intervals";
|
|
52
54
|
export type { PackedInterval, PackIntervalsResult, PackIntervalsOptions, ActiveCount, ActiveCountOptions, } from "./recipes/intervals";
|
|
55
|
+
export { layoutSequence, layoutChipStrip, estimateLabelWidth, packSpanLevels, scaleArcBand, spanArcPath, spanArcPeakY, partitionSharedEdges, } from "./recipes/sequenceLayout";
|
|
56
|
+
export type { SequenceItem, SequencePosition, LayoutSequenceOptions, ChipStripItem, LayoutChipStripOptions, ChipStripPosition, SpanInterval, PackedSpanLevel, PackSpanLevelsResult, ScaleArcBandOptions, ScaleArcBandResult, SpanArcPathOptions, EdgeKeyFn, } from "./recipes/sequenceLayout";
|
|
53
57
|
export { polarToXY, xyToAngle, angleScale, radiusScale, ringArcPath, TAU } from "./recipes/radialCoords";
|
|
54
58
|
export type { Point, PolarOptions, AngleScaleOptions, RingArcOptions } from "./recipes/radialCoords";
|
|
55
59
|
export { curvedEdgePath, orthogonalEdgePath, boxEdgeAnchors, fanOutBend, cubicPoint, cubicTangent, cubicPath, } from "./recipes/edgeRouter";
|
|
@@ -69,8 +73,8 @@ export type { NetworkSymbolName } from "./stream/symbolPath";
|
|
|
69
73
|
export { glyphPlacement, glyphExtent, glyphFractionClipRect, DEFAULT_GLYPH_VIEWBOX, DEFAULT_GLYPH_ANCHOR, } from "./stream/glyphDef";
|
|
70
74
|
export type { GlyphDef, GlyphPart, GlyphPlacement } from "./stream/glyphDef";
|
|
71
75
|
export { isotypeInk, isotypePaper, isotypeGhost, isotypeServerGlyph, isotypeChipGlyph, isotypeBoltGlyph, isotypeBusGlyph, isotypePersonPath, isotypePersonGlyph, isotypeNetworkGlyphs, } from "./recipes/isotypeGlyphs";
|
|
72
|
-
export { roundedEnclosure, boundsOf, bandLabel, markCallout, linearAxis, hatchFill } from "./recipes/recipeChrome";
|
|
73
|
-
export type { RoundedEnclosureProps, BandLabelProps, MarkCalloutProps, CalloutConnector, LinearAxisProps, AxisOrient, HatchFillOptions, } from "./recipes/recipeChrome";
|
|
76
|
+
export { roundedEnclosure, boundsOf, hullFromBoxes, bandLabel, markCallout, linearAxis, hatchFill, } from "./recipes/recipeChrome";
|
|
77
|
+
export type { RoundedEnclosureProps, HullBox, HullPadding, BandLabelProps, MarkCalloutProps, CalloutConnector, LinearAxisProps, AxisOrient, HatchFillOptions, } from "./recipes/recipeChrome";
|
|
74
78
|
export { legendGroupsFrom, legendSwatches } from "./recipes/recipeLegend";
|
|
75
79
|
export type { LegendGroupsInput, LegendSwatch, LegendSwatchesProps } from "./recipes/recipeLegend";
|
|
76
80
|
export { buildTooltipEntries, extractTooltipDatum, formatTooltipValue, } from "./recipes/customTooltip";
|
|
@@ -27,7 +27,9 @@ interface AnnotationScales {
|
|
|
27
27
|
}
|
|
28
28
|
type AnnotationScale = {
|
|
29
29
|
bivarianceHack(value: DatumValue): number;
|
|
30
|
-
}["bivarianceHack"]
|
|
30
|
+
}["bivarianceHack"] & {
|
|
31
|
+
domain?: () => DatumValue[];
|
|
32
|
+
};
|
|
31
33
|
interface AnnotationLayout {
|
|
32
34
|
width: number;
|
|
33
35
|
height: number;
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
* Shared module used by Stream Frames for SSR rendering and
|
|
5
5
|
* by semiotic/server for static SVG export.
|
|
6
6
|
*
|
|
7
|
-
* Network and
|
|
8
|
-
* (SceneToSVGNetwork.tsx / SceneToSVGGeo.tsx) and are
|
|
9
|
-
* keep this file under the file-size ratchet ceiling;
|
|
10
|
-
* shared across
|
|
7
|
+
* Network, geo, and ordinal serializers live in sibling modules
|
|
8
|
+
* (SceneToSVGNetwork.tsx / SceneToSVGGeo.tsx / SceneToSVGOrdinal.tsx) and are
|
|
9
|
+
* re-exported below to keep this file under the file-size ratchet ceiling;
|
|
10
|
+
* low-level helpers shared across them (svgFill, safeSvgId, glyphNodeToSVG,
|
|
11
|
+
* buildRectSVGGradient, perCornerSvgPath, symbolSceneNodeToSVG, ARC_NOOP)
|
|
11
12
|
* live in sceneToSVGShared.tsx.
|
|
12
13
|
*/
|
|
13
14
|
import * as React from "react";
|
|
14
15
|
import type { SceneNode } from "./types";
|
|
15
|
-
import type { OrdinalSceneNode } from "./ordinalTypes";
|
|
16
16
|
export { networkSceneNodeToSVG, networkSceneEdgeToSVG, networkLabelToSVG } from "./SceneToSVGNetwork";
|
|
17
17
|
export { geoSceneNodeToSVG } from "./SceneToSVGGeo";
|
|
18
|
+
export { ordinalSceneNodeToSVG } from "./SceneToSVGOrdinal";
|
|
18
19
|
export declare function xySceneNodeToSVG(node: SceneNode, i: number, idPrefix?: string): React.ReactNode;
|
|
19
|
-
export declare function ordinalSceneNodeToSVG(node: OrdinalSceneNode, i: number, idPrefix?: string): React.ReactNode;
|
|
20
20
|
/**
|
|
21
21
|
* Returns true when running in a true server/Node.js context where
|
|
22
22
|
* window and document are not available.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordinal scene graph → SVG element converter.
|
|
3
|
+
*
|
|
4
|
+
* Split out of SceneToSVG.tsx (which re-exports `ordinalSceneNodeToSVG`) to
|
|
5
|
+
* keep that file under the file-size ratchet ceiling. Shared helpers
|
|
6
|
+
* (svgFill, safeSvgId, glyphNodeToSVG, buildRectSVGGradient,
|
|
7
|
+
* perCornerSvgPath, symbolSceneNodeToSVG, ARC_NOOP) live in
|
|
8
|
+
* sceneToSVGShared.tsx so the XY and ordinal serializers agree on geometry.
|
|
9
|
+
*/
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import type { OrdinalSceneNode } from "./ordinalTypes";
|
|
12
|
+
export declare function ordinalSceneNodeToSVG(node: OrdinalSceneNode, i: number, idPrefix?: string): React.ReactNode;
|
|
@@ -44,6 +44,8 @@ export interface NetworkFramePaintContext {
|
|
|
44
44
|
};
|
|
45
45
|
setAnnotationFrame: (updater: (f: number) => number) => void;
|
|
46
46
|
scheduleNextFrame: () => void;
|
|
47
|
+
/** Resync color caches from scene fills after an invalidating rebuild. */
|
|
48
|
+
syncColorMap?: () => void;
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
49
51
|
* Run one paint tick. Returns whether another rAF should be scheduled
|
|
@@ -28,6 +28,7 @@ export declare class PhysicsPipelineStore {
|
|
|
28
28
|
private simulationState;
|
|
29
29
|
private visible;
|
|
30
30
|
private world;
|
|
31
|
+
private quiescence;
|
|
31
32
|
constructor(config?: PhysicsPipelineConfig);
|
|
32
33
|
updateConfig(config: PhysicsPipelineConfig): void;
|
|
33
34
|
/** Additive explicit-result form of {@link updateConfig}. */
|
|
@@ -37,6 +38,15 @@ export declare class PhysicsPipelineStore {
|
|
|
37
38
|
/** Additive explicit-result form of {@link enqueue}. */
|
|
38
39
|
enqueueWithResult(spawn: PhysicsQueuedSpawn | PhysicsQueuedSpawn[], pacing?: PhysicsSpawnPacingOptions): UpdateResult;
|
|
39
40
|
spawnNow(spawn: PhysicsQueuedSpawn): void;
|
|
41
|
+
/**
|
|
42
|
+
* Materialize already-due queued spawns without advancing simulation time.
|
|
43
|
+
*
|
|
44
|
+
* Unlike {@link tick} / {@link settleWithObservations}, this runs while
|
|
45
|
+
* paused or hidden so seed bodies (`initialSpawns` with `spawnAt <= elapsed`)
|
|
46
|
+
* appear on the first paint of a paused snapshot frame. Future-paced queue
|
|
47
|
+
* items stay queued. Does not step the kernel.
|
|
48
|
+
*/
|
|
49
|
+
materializeDueSpawns(): string[];
|
|
40
50
|
clear(): void;
|
|
41
51
|
tick(deltaSeconds: number): PhysicsPipelineTickResult;
|
|
42
52
|
settle(maxSteps?: number): number;
|
|
@@ -49,6 +59,14 @@ export declare class PhysicsPipelineStore {
|
|
|
49
59
|
hitTest(x: number, y: number, radius?: number): PhysicsBodyState | null;
|
|
50
60
|
events(): PhysicsKernelEvent[];
|
|
51
61
|
allSleeping(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* True when the world is done moving — either every body has formally slept,
|
|
64
|
+
* or the whole system has stayed quiescent long enough that never-sleeping
|
|
65
|
+
* stragglers (mutually-leaning bodies, force-equilibrium tethers) should still
|
|
66
|
+
* count as settled. This is the gate for `shouldContinue` and the "settled"
|
|
67
|
+
* simulation state, so it decides when `rerunMS` re-arms.
|
|
68
|
+
*/
|
|
69
|
+
atRest(): boolean;
|
|
52
70
|
hasPendingWork(): boolean;
|
|
53
71
|
queueSize(): number;
|
|
54
72
|
liveBodyCount(): number;
|
|
@@ -81,6 +99,4 @@ export declare class PhysicsPipelineStore {
|
|
|
81
99
|
private observeBodyBudget;
|
|
82
100
|
private syncSimulationState;
|
|
83
101
|
private evictOverflow;
|
|
84
|
-
private absorbSediment;
|
|
85
|
-
private sleepingFirstEvictionOrder;
|
|
86
102
|
}
|
|
@@ -13,12 +13,19 @@ export interface StreamPhysicsPopOptions {
|
|
|
13
13
|
color?: string;
|
|
14
14
|
durationMs?: number;
|
|
15
15
|
radius?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Uniform multiplier on the whole burst geometry (ring + sparks). Defaults to
|
|
18
|
+
* 1. Shrink it for small charts — a sparkline can't hold a context-scale
|
|
19
|
+
* burst — without changing the removed body's `radius`.
|
|
20
|
+
*/
|
|
21
|
+
scale?: number;
|
|
16
22
|
}
|
|
17
23
|
export interface StreamPhysicsPopAnimation {
|
|
18
24
|
body: PhysicsBodyState;
|
|
19
25
|
color: string;
|
|
20
26
|
durationMs: number;
|
|
21
27
|
radius: number;
|
|
28
|
+
scale: number;
|
|
22
29
|
startedAt: number;
|
|
23
30
|
}
|
|
24
31
|
export declare function resolveBodyMark(body: PhysicsBodyState, style: Style): PhysicsBodyMark;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PhysicsEngineAdapter } from "./PhysicsEngineAdapter";
|
|
2
|
+
import type { PhysicsSedimentAccumulator } from "./PhysicsSediment";
|
|
3
|
+
import type { PhysicsPipelineConfig } from "./PhysicsPipelineTypes";
|
|
4
|
+
import type { PhysicsPipelineEvictionResult } from "./physicsPipelineHelpers";
|
|
5
|
+
import type { PhysicsObservationContext } from "./physicsPipelineObservations";
|
|
6
|
+
export declare function selectEvictionCandidates(world: PhysicsEngineAdapter, eviction: PhysicsPipelineConfig["eviction"], liveBodyOrder: string[]): string[];
|
|
7
|
+
export declare function absorbPhysicsSediment(world: PhysicsEngineAdapter, sediment: PhysicsSedimentAccumulator, ids: string[], context: PhysicsObservationContext): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Selects and removes overflow bodies past `bodyLimit`, absorbing them into
|
|
10
|
+
* sediment where applicable. Returns the surviving `liveBodyOrder` alongside
|
|
11
|
+
* the eviction result so the caller can commit both atomically.
|
|
12
|
+
*/
|
|
13
|
+
export declare function evictPhysicsOverflow(world: PhysicsEngineAdapter, sediment: PhysicsSedimentAccumulator, eviction: PhysicsPipelineConfig["eviction"], bodyLimit: number, liveBodyOrder: string[], context: PhysicsObservationContext): PhysicsPipelineEvictionResult & {
|
|
14
|
+
liveBodyOrder: string[];
|
|
15
|
+
};
|
|
@@ -10,5 +10,5 @@ export interface PhysicsObservationContext {
|
|
|
10
10
|
export declare function observePhysicsKernelEvents(world: PhysicsEngineAdapter, events: PhysicsKernelEvent[], context: PhysicsObservationContext): void;
|
|
11
11
|
export declare function observePhysicsSensorTransitions(world: PhysicsEngineAdapter, previousPairs: ReadonlySet<string>, context: PhysicsObservationContext): Set<string>;
|
|
12
12
|
export declare function removePhysicsSensorPairsForBodies(pairs: Set<string>, bodyIds: ReadonlySet<string>): void;
|
|
13
|
-
export declare function resolvePhysicsSimulationState(paused: boolean, visible: boolean, hasQueuedBodies: boolean,
|
|
13
|
+
export declare function resolvePhysicsSimulationState(paused: boolean, visible: boolean, hasQueuedBodies: boolean, atRest: boolean): PhysicsSimulationState;
|
|
14
14
|
export declare function emitPhysicsSimulationStateTransition(previous: PhysicsSimulationState, next: PhysicsSimulationState, context: PhysicsObservationContext): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PhysicsKernelOptions } from "./PhysicsKernel";
|
|
2
|
+
import type { PhysicsEngineAdapter } from "./PhysicsEngineAdapter";
|
|
3
|
+
/**
|
|
4
|
+
* Tracks sustained-quiescence as an "at rest" fallback for bodies that never
|
|
5
|
+
* formally sleep (see {@link QUIESCENT_AFTER_SECONDS}).
|
|
6
|
+
*/
|
|
7
|
+
export declare class PhysicsQuiescenceTracker {
|
|
8
|
+
private seconds;
|
|
9
|
+
private speed;
|
|
10
|
+
private scratch;
|
|
11
|
+
setKernelOptions(kernel: PhysicsKernelOptions | undefined): void;
|
|
12
|
+
reset(): void;
|
|
13
|
+
isAtRest(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Advance (or reset) the sustained-quiescence timer from the bodies' current
|
|
16
|
+
* speeds. A fresh spawn or any body moving faster than the quiescent speed
|
|
17
|
+
* resets it; otherwise it accrues the simulated delta.
|
|
18
|
+
*/
|
|
19
|
+
refresh(world: PhysicsEngineAdapter, deltaSeconds: number, spawnedCount: number): void;
|
|
20
|
+
}
|
|
@@ -8,7 +8,7 @@ import * as React from "react";
|
|
|
8
8
|
import type { DefaultArcObject } from "d3-shape";
|
|
9
9
|
import { type HatchFill } from "../charts/shared/hatchFill";
|
|
10
10
|
import type { GlyphDef } from "./glyphDef";
|
|
11
|
-
import type { Style } from "./types";
|
|
11
|
+
import type { RectSceneNode, Style, SymbolSceneNode } from "./types";
|
|
12
12
|
/**
|
|
13
13
|
* Sentinel arg for d3-shape arc generators that have all four
|
|
14
14
|
* accessors set to constants. The generator's call signature requires
|
|
@@ -49,3 +49,32 @@ export declare function glyphNodeToSVG(g: {
|
|
|
49
49
|
pointId?: string;
|
|
50
50
|
_decayOpacity?: number;
|
|
51
51
|
}, x: number, y: number, key: string): React.ReactNode;
|
|
52
|
+
export declare function colorStopElements(colorStops: Array<{
|
|
53
|
+
offset: number;
|
|
54
|
+
color: string;
|
|
55
|
+
}>): React.ReactElement[] | null;
|
|
56
|
+
/**
|
|
57
|
+
* Build `<defs><linearGradient>` for a bar's fillGradient, mirroring the
|
|
58
|
+
* tip→base direction the canvas renderer uses (inferred from roundedEdge).
|
|
59
|
+
* Returns null when the config can't resolve (e.g. colorStops < 2), so the
|
|
60
|
+
* caller falls back to a solid fill — same parity with the canvas path.
|
|
61
|
+
*
|
|
62
|
+
* Using `gradientUnits="userSpaceOnUse"` with absolute coords keeps each bar's
|
|
63
|
+
* gradient aligned to its own rect independent of the parent viewBox.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildRectSVGGradient(n: RectSceneNode, id: string): React.ReactElement | null;
|
|
66
|
+
/**
|
|
67
|
+
* Emit an SVG path string for a rect with per-corner radii. Same trace
|
|
68
|
+
* order as the canvas helper (CCW from top-left); shared shape utilities
|
|
69
|
+
* (`hasAnyCornerRadius`, `clampCornerRadii`) live in
|
|
70
|
+
* `./renderers/cornerRadii.ts` so both paint paths agree on geometry.
|
|
71
|
+
*/
|
|
72
|
+
export declare function perCornerSvgPath(n: RectSceneNode): string;
|
|
73
|
+
/**
|
|
74
|
+
* Shared SVG serializer for the XY/ordinal `SymbolSceneNode` (x/y-based) — the
|
|
75
|
+
* sibling of the network symbol case in `networkSceneNodeToSVG` (cx/cy). Both
|
|
76
|
+
* delegate glyph-path generation to `symbolPathString`, matching the canvas
|
|
77
|
+
* renderer exactly (fill only when a fill is set, so stroke-only glyphs stay
|
|
78
|
+
* unfilled in SSR too).
|
|
79
|
+
*/
|
|
80
|
+
export declare function symbolSceneNodeToSVG(n: SymbolSceneNode, i: number, idPrefix?: string): React.ReactNode;
|
|
@@ -457,6 +457,10 @@ export interface CandlestickSceneNode {
|
|
|
457
457
|
isUp: boolean;
|
|
458
458
|
/** Range/dumbbell mode — no body, endpoint dots instead */
|
|
459
459
|
isRange?: boolean;
|
|
460
|
+
/** Endpoint dot radius for range/dumbbell mode. Computed in the scene
|
|
461
|
+
* builder (which owns the layout height) so the canvas and SVG renderers
|
|
462
|
+
* paint identical bulbs. */
|
|
463
|
+
dotRadius?: number;
|
|
460
464
|
datum: SceneDatum;
|
|
461
465
|
accessibleDatum?: SceneAccessibilityMetadata["accessibleDatum"];
|
|
462
466
|
accessibility?: SceneAccessibilityMetadata["accessibility"];
|
|
@@ -60,10 +60,16 @@ export interface HydrationLifecycleOptions {
|
|
|
60
60
|
* `cancelIntroAnimation()`; the hook calls it when the SVG → canvas
|
|
61
61
|
* swap fires after SSR rehydration. (Currently every shipped store
|
|
62
62
|
* implements the method, but the optional shape lets a custom store
|
|
63
|
-
* opt out.)
|
|
63
|
+
* opt out.) `sceneNodes` + `markStylePaintPending()` let the hook
|
|
64
|
+
* repaint an already-built scene instead of forcing a rebuild (see the
|
|
65
|
+
* effect body); both are optional so a minimal custom store still works.
|
|
64
66
|
*/
|
|
65
67
|
storeRef: RefObject<{
|
|
66
68
|
cancelIntroAnimation?: () => void;
|
|
69
|
+
sceneNodes?: {
|
|
70
|
+
length: number;
|
|
71
|
+
};
|
|
72
|
+
markStylePaintPending?: () => void;
|
|
67
73
|
} | null>;
|
|
68
74
|
/**
|
|
69
75
|
* Mutable dirty flag the renderer reads on its next paint. The hook
|
|
@@ -8,4 +8,4 @@ import type { Datum } from "../../charts/shared/datumTypes";
|
|
|
8
8
|
*/
|
|
9
9
|
import type { CandlestickSceneNode, StreamLayout } from "../types";
|
|
10
10
|
import type { XYSceneContext } from "./types";
|
|
11
|
-
export declare function buildCandlestickScene(ctx: XYSceneContext, data: Datum[],
|
|
11
|
+
export declare function buildCandlestickScene(ctx: XYSceneContext, data: Datum[], layout: StreamLayout): CandlestickSceneNode[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{forceCenter as e,forceCollide as t,forceLink as o,forceManyBody as n,forceSimulation as r,forceX as a,forceY as f}from"d3-force";function c(c,s,i={}){const d=i.seed??1,u=i.iterations??260,l=i.repulsion??5200,g=i.linkDistance??165,h=i.linkStrength??.045,b=i.centerStrength??.018,y=i.damping??.84,p=i.nodeRadius??12,m=i.nodePadding??3,M=i.inset??.06,x=function(e){let t=e>>>0;return function(){t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}(d),S=new Map;for(const e of c)S.set(e.id,0);for(const e of s)S.set(e.source,(S.get(e.source)??0)+1),S.set(e.target,(S.get(e.target)??0)+1);const k=500,w=c.map(e=>({id:e.id,data:e,x:200+600*x(),y:200+600*x()})),q=new Set(c.map(e=>e.id)),v=s.filter(e=>q.has(e.source)&&q.has(e.target)).map(e=>({source:e.source,target:e.target}));if(u>0){const c=r(w).randomSource(x).alphaDecay(1-Math.pow(.001,1/u)).velocityDecay(Math.max(0,Math.min(1,1-y))).force("charge",n().strength(e=>{const t=S.get(e.id)??0;return 2.5*-Math.sqrt(l)*Math.sqrt(t+1)})).force("collide",t(e=>(e=>"function"==typeof p?p(e.data):p)(e)+m).strength(.9).iterations(2)).force("center",e(k,k).strength(.8)).force("x",a(k).strength(b)).force("y",f(k).strength(b));v.length>0&&c.force("link",o(v).id(e=>e.id).distance(g).strength(e=>{const t="string"==typeof e.source?e.source:e.source.id,o="string"==typeof e.target?e.target:e.target.id,n=Math.max(1,Math.min(S.get(t)??1,S.get(o)??1));return h/.045/n})),c.stop();for(let e=0;e<u;e+=1)c.tick()}let I=1/0,R=1/0,z=-1/0,$=-1/0;for(const e of w){const t=e.x??k,o=e.y??k;t<I&&(I=t),o<R&&(R=o),t>z&&(z=t),o>$&&($=o)}const E=z-I,_=$-R,C={};for(const e of w)C[e.id]={x:0===E?.5:M+((e.x??k)-I)/E*(1-2*M),y:0===_?.5:M+((e.y??k)-R)/_*(1-2*M)};return C}import{forceSimulation as s,forceCenter as i,forceX as d,forceY as u,forceLink as l,forceManyBody as g,forceCollide as h}from"d3-force";import{scaleLinear as b}from"d3-scale";function y(e){return[parseInt(e.slice(1,3),16),parseInt(e.slice(3,5),16),parseInt(e.slice(5,7),16)]}function p(e,t,o){const n=e=>e.toString(16).padStart(2,"0");return`#${n(e)}${n(t)}${n(o)}`}function m(e){const t=e.map(y),o=t.length-1;return e=>{if(e<=0){const[e,o,n]=t[0];return p(e,o,n)}if(e>=1){const[e,n,r]=t[o];return p(e,n,r)}const n=e*o,r=Math.floor(n),a=n-r,[f,c,s]=t[r],[i,d,u]=t[r+1];return p(Math.round(f+(i-f)*a),Math.round(c+(d-c)*a),Math.round(s+(u-s)*a))}}var M=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"];m(["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"]),m(["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"]),m(["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"]),m(["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"]),m(["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"]),m(["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"]),m(["#440154","#482878","#3e4989","#31688e","#26828e","#1f9e89","#35b779","#6ece58","#b5de2b","#fde725"]),m(["#0d0887","#41049d","#6a00a8","#8f0da4","#b12a90","#cb4679","#e16462","#f1844b","#fca636","#fcce25","#f0f921"]),m(["#000004","#160b39","#420a68","#6a176e","#932667","#bc3754","#dd513a","#f3771a","#fca50a","#f6d746","#fcffa4"]),m(["#000004","#140e36","#3b0f70","#641a80","#8c2981","#b73779","#de4968","#f7705c","#fe9f6d","#fecf92","#fcfdbf"]),m(["#00224e","#123570","#3b496c","#575d6d","#707173","#8a8678","#a59c74","#c3b369","#e1cc55","#fee838","#ffea46"]),m(["#23171b","#4a58dd","#3f9ee9","#46c7af","#7eed5a","#cdf134","#fbb91f","#f56918","#c52f06","#7a0403"]),m(["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"]),m(["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"]),m(["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"]),m(["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"]),m(["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"]),m(["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"]),m(["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"]);var x=new Set,S=new WeakMap;function k(e,t){if(!e||!e.data||"object"!=typeof e.data)return e;let o=S.get(e);if(o){const e=o.get(t);if(e)return e}else o=new Map,S.set(e,o);const n=new Proxy(e,{get(e,o,n){if("string"==typeof o&&!(o in e)&&e.data&&o in e.data){const e=`${t}:${o}`;x.has(e)||(x.add(e),console.warn(`[Semiotic] "${t}" callback accessed "${o}" on the wrapper object, but it only exists on ".data". Use d.data.${o} (or d.data?.${o}) instead. Frame callbacks receive RealtimeNode/RealtimeEdge wrappers, not your raw data.`))}return Reflect.get(e,o,n)}});return o.set(t,n),n}var w={supportsStreaming:!0,hierarchical:!1,computeLayout(e,t,o,n){if(0===e.length)return;const r=o.forceStrength??.1,a=n[0]/2,f=n[1]/2,c=o.__previousPositions;let b=0;const y=[];for(const t of e){const e=null!=t.x&&null!=t.y&&(0!==t.x||0!==t.y),o=c?.get(t.id);e?b++:o?(t.x=o.x,t.y=o.y,b++):y.push(t)}const p=e.length>0?y.length/e.length:1,m=b>0&&p<=.3;if(m){const o=new Map;for(const t of e)o.set(t.id,t);for(const e of y){const n=q(e.id,t,o);if(n.length>0){let t=0,o=0;for(const e of n)t+=e.x,o+=e.y;const r=v(e.id),a=r%360*(Math.PI/180),f=10+r%20;e.x=t/n.length+f*Math.cos(a),e.y=o/n.length+f*Math.sin(a)}else{const t=v(e.id),o=t%360*(Math.PI/180),n=15+t%30;e.x=a+n*Math.cos(o),e.y=f+n*Math.sin(o)}}}else{const t=Math.PI*(3-Math.sqrt(5));for(let o=0;o<e.length;o++){const n=e[o];if(null==n.x||null==n.y||0===n.x&&0===n.y){const e=10*Math.sqrt(o+.5),r=o*t;n.x=a+e*Math.cos(r),n.y=f+e*Math.sin(r)}}}const M=e.length,x=o.iterations??Math.max(50,Math.min(300,Math.floor(300-2*(M-30)))),S=o.__skipForceSimulation||0===o.iterations?0:m?40:x,k=I(o.nodeSize,o.nodeSizeRange,e),w=e=>k(e);if(S>0){const n=new Map,c=new Map;for(const t of e)n.set(t.id,0),c.set(t.id,t);for(const e of t){const t="string"==typeof e.source?e.source:e.source.id,o="string"==typeof e.target?e.target:e.target.id;n.set(t,(n.get(t)??0)+1),n.set(o,(n.get(o)??0)+1)}const b=l().strength(e=>{const t=e.weight,o="string"==typeof e.source?e.source:e.source.id,a="string"==typeof e.target?e.target:e.target.id,f=Math.max(1,Math.min(n.get(o)??1,n.get(a)??1)),c=t&&t>0?Math.sqrt(t):1;return Math.min(2.5,c*r/(.1*f))}).distance(e=>{const t="string"==typeof e.source?c.get(e.source):e.source,o="string"==typeof e.target?c.get(e.target):e.target,n=(t?w(t):0)+(o?w(o):0)+12;return Math.max(40,n)}).id(e=>e.id),y=s();if(void 0===o.random&&void 0===o.seed||y.randomSource(o.random??function(e){let t=e>>>0;return()=>{t+=1831565813;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(o.seed)),y.force("charge",g().strength(e=>{const t=n.get(e.id)??0;return-15*w(e)*Math.sqrt(t+1)})).force("collide",h(e=>w(e)+3).strength(.9).iterations(2)).force("center",i(a,f).strength(.8)).force("x",d(a).strength(.06)).force("y",u(f).strength(.06)),y.nodes(e),t.length>0){const e=t.map(e=>({...e,source:"string"==typeof e.source?e.source:e.source.id,target:"string"==typeof e.target?e.target:e.target.id}));b.links(e),y.force("link",b)}m?y.alpha(.3):y.alpha()<.1&&y.alpha(1),y.stop();for(let e=0;e<S;++e)y.tick()}for(const t of e){if(null==t.x||null==t.y)continue;const e=w(t);t.x=Math.max(e,Math.min(n[0]-e,t.x)),t.y=Math.max(e,Math.min(n[1]-e,t.y)),t.x0=0,t.x1=0,t.y0=0,t.y1=0}const R=new Map;for(const t of e)R.set(t.id,t);for(const e of t){if("string"==typeof e.source){const t=R.get(e.source);t&&(e.source=t)}if("string"==typeof e.target){const t=R.get(e.target);t&&(e.target=t)}}},buildScene(e,t,o,n){const r=o.nodeStyle,a=o.edgeStyle,f=I(o.nodeSize,o.nodeSizeRange,e),c=Array.isArray(o.colorScheme)?o.colorScheme:o.themeCategorical&&o.themeCategorical.length>0?o.themeCategorical:M,s=new Map;e.forEach((e,t)=>{s.set(e.id,c[t%c.length])});const i=[],d=[],u=[];for(const t of e){if(null==t.x||null==t.y)continue;const e=f(k(t,"nodeSize")),n=r?r(k(t,"nodeStyle")):{},a={fill:n.fill||s.get(t.id)||o.themeSemantic?.primary||"#007bff",stroke:n.stroke||o.themeSemantic?.surface||"#fff",strokeWidth:n.strokeWidth??2,opacity:n.opacity};i.push({type:"circle",cx:t.x,cy:t.y,r:e,style:a,datum:t,id:t.id,label:t.id})}const l=new Map;for(const t of e)l.set(t.id,t);for(const e of t){const t="object"==typeof e.source?e.source:l.get(e.source),n="object"==typeof e.target?e.target:l.get(e.target);if(!t||!n)continue;if(null==t.x||null==t.y)continue;if(null==n.x||null==n.y)continue;const r=a?a(k(e,"edgeStyle")):{},f={stroke:r.stroke||o.themeSemantic?.border||o.themeSemantic?.secondary||"#999",strokeWidth:r.strokeWidth??1,opacity:r.opacity??.6};d.push({type:"line",x1:t.x,y1:t.y,x2:n.x,y2:n.y,style:f,datum:e})}if(!1!==o.showLabels){const t=(g=o.nodeLabel)?"function"==typeof g?g:e=>e[g]||e.id:null;for(const o of e){if(null==o.x||null==o.y)continue;const e=t?t(o):o.id;if(!e)continue;const n=f(k(o,"nodeSize"));u.push({x:o.x,y:o.y-n-4,text:String(e),anchor:"middle",baseline:"auto",fontSize:11})}}var g;return{sceneNodes:i,sceneEdges:d,labels:u}}};function q(e,t,o){const n=[];for(const r of t){const t="string"==typeof r.source?r.source:r.source.id,a="string"==typeof r.target?r.target:r.target.id;let f=null;if(t===e?f=a:a===e&&(f=t),f){const e=o.get(f);!e||0===e.x&&0===e.y||n.push({x:e.x,y:e.y})}}return n}function v(e){let t=0;for(let o=0;o<e.length;o++)t=(t<<5)-t+e.charCodeAt(o)|0;return Math.abs(t)}function I(e,t,o){if(o.some(e=>null!=e.__forceRadius))return e=>e.__forceRadius??8;if(null==e)return()=>8;if("number"==typeof e)return()=>e;if("function"==typeof e)return t=>e(t)||8;const n=t||[5,20],r=[];for(const t of o){const o=t.data?.[e];"number"==typeof o&&r.push(o)}if(0===r.length)return()=>n[0];const[a,f]=function(e){let t=1/0,o=-1/0;for(const n of e)n<t&&(t=n),n>o&&(o=n);return[t,o]}(r);if(a===f)return()=>(n[0]+n[1])/2;const c=b().domain([a,f]).range(n).clamp(!0);return t=>{const o=t.data?.[e];return null==o||"number"!=typeof o?n[0]:c(o)}}self.onmessage=e=>{const t=e.data,o=t?.requestId,n=t?.request??t;try{if("normalized"===n.kind){const e=n.nodeRadii,t=e?{...n.options,nodeRadius:t=>e[t.id]??12}:n.options;return void self.postMessage({requestId:o,positions:c(n.nodes,n.edges,t)})}const e=n.nodes,t=n.edges;w.computeLayout(e,t,n.config,n.size),self.postMessage({requestId:o,positions:Object.fromEntries(e.map(e=>[e.id,{x:e.x,y:e.y}]))})}catch(e){self.postMessage({requestId:o,error:{message:e instanceof Error?e.message:String(e),name:e instanceof Error?e.name:"Error",stack:e instanceof Error?e.stack:void 0}})}};
|
|
1
|
+
import{forceCenter as e,forceCollide as t,forceLink as o,forceManyBody as n,forceSimulation as r,forceX as a,forceY as f}from"d3-force";function c(c,s,i={}){const d=i.seed??1,u=i.iterations??260,l=i.repulsion??5200,g=i.linkDistance??165,h=i.linkStrength??.045,y=i.centerStrength??.018,b=i.damping??.84,m=i.nodeRadius??12,p=i.nodePadding??3,M=i.inset??.06,x=function(e){let t=e>>>0;return function(){t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}(d),S=new Map;for(const e of c)S.set(e.id,0);for(const e of s)S.set(e.source,(S.get(e.source)??0)+1),S.set(e.target,(S.get(e.target)??0)+1);const k=500,w=c.map(e=>({id:e.id,data:e,x:200+600*x(),y:200+600*x()})),v=new Set(c.map(e=>e.id)),q=s.filter(e=>v.has(e.source)&&v.has(e.target)).map(e=>({source:e.source,target:e.target}));if(u>0){const c=r(w).randomSource(x).alphaDecay(1-Math.pow(.001,1/u)).velocityDecay(Math.max(0,Math.min(1,1-b))).force("charge",n().strength(e=>{const t=S.get(e.id)??0;return 2.5*-Math.sqrt(l)*Math.sqrt(t+1)})).force("collide",t(e=>(e=>"function"==typeof m?m(e.data):m)(e)+p).strength(.9).iterations(2)).force("center",e(k,k).strength(.8)).force("x",a(k).strength(y)).force("y",f(k).strength(y));q.length>0&&c.force("link",o(q).id(e=>e.id).distance(g).strength(e=>{const t="string"==typeof e.source?e.source:e.source.id,o="string"==typeof e.target?e.target:e.target.id,n=Math.max(1,Math.min(S.get(t)??1,S.get(o)??1));return h/.045/n})),c.stop();for(let e=0;e<u;e+=1)c.tick()}let z=1/0,I=1/0,R=-1/0,$=-1/0;for(const e of w){const t=e.x??k,o=e.y??k;t<z&&(z=t),o<I&&(I=o),t>R&&(R=t),o>$&&($=o)}const E=R-z,_=$-I,C={};for(const e of w)C[e.id]={x:0===E?.5:M+((e.x??k)-z)/E*(1-2*M),y:0===_?.5:M+((e.y??k)-I)/_*(1-2*M)};return C}import{forceSimulation as s,forceCenter as i,forceX as d,forceY as u,forceLink as l,forceManyBody as g,forceCollide as h}from"d3-force";import{scaleLinear as y}from"d3-scale";function b(e){return[parseInt(e.slice(1,3),16),parseInt(e.slice(3,5),16),parseInt(e.slice(5,7),16)]}function m(e,t,o){const n=e=>e.toString(16).padStart(2,"0");return`#${n(e)}${n(t)}${n(o)}`}function p(e){const t=e.map(b),o=t.length-1;return e=>{if(e<=0){const[e,o,n]=t[0];return m(e,o,n)}if(e>=1){const[e,n,r]=t[o];return m(e,n,r)}const n=e*o,r=Math.floor(n),a=n-r,[f,c,s]=t[r],[i,d,u]=t[r+1];return m(Math.round(f+(i-f)*a),Math.round(c+(d-c)*a),Math.round(s+(u-s)*a))}}var M=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"];p(["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"]),p(["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"]),p(["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"]),p(["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"]),p(["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"]),p(["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"]),p(["#440154","#482878","#3e4989","#31688e","#26828e","#1f9e89","#35b779","#6ece58","#b5de2b","#fde725"]),p(["#0d0887","#41049d","#6a00a8","#8f0da4","#b12a90","#cb4679","#e16462","#f1844b","#fca636","#fcce25","#f0f921"]),p(["#000004","#160b39","#420a68","#6a176e","#932667","#bc3754","#dd513a","#f3771a","#fca50a","#f6d746","#fcffa4"]),p(["#000004","#140e36","#3b0f70","#641a80","#8c2981","#b73779","#de4968","#f7705c","#fe9f6d","#fecf92","#fcfdbf"]),p(["#00224e","#123570","#3b496c","#575d6d","#707173","#8a8678","#a59c74","#c3b369","#e1cc55","#fee838","#ffea46"]),p(["#23171b","#4a58dd","#3f9ee9","#46c7af","#7eed5a","#cdf134","#fbb91f","#f56918","#c52f06","#7a0403"]),p(["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"]),p(["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"]),p(["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"]),p(["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"]),p(["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"]),p(["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"]),p(["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"]);var x=new Set,S=new WeakMap;function k(e,t){if(!e||!e.data||"object"!=typeof e.data)return e;let o=S.get(e);if(o){const e=o.get(t);if(e)return e}else o=new Map,S.set(e,o);const n=new Proxy(e,{get(e,o,n){if("string"==typeof o&&!(o in e)&&e.data&&o in e.data){const e=`${t}:${o}`;x.has(e)||(x.add(e),console.warn(`[Semiotic] "${t}" callback accessed "${o}" on the wrapper object, but it only exists on ".data". Use d.data.${o} (or d.data?.${o}) instead. Frame callbacks receive RealtimeNode/RealtimeEdge wrappers, not your raw data.`))}return Reflect.get(e,o,n)}});return o.set(t,n),n}var w={supportsStreaming:!0,hierarchical:!1,computeLayout(e,t,o,n){if(0===e.length)return;const r=o.forceStrength??.1,a=n[0]/2,f=n[1]/2,c=Math.max(.1,Math.min(1,Math.min(n[0],n[1])/200)),y=Math.min(.5,.06+1.8*(1-c)),b=o.__previousPositions;let m=0;const p=[];for(const t of e){const e=null!=t.x&&null!=t.y&&(0!==t.x||0!==t.y),o=b?.get(t.id);e?m++:o?(t.x=o.x,t.y=o.y,m++):p.push(t)}const M=e.length>0?p.length/e.length:1,x=m>0&&M<=.3;if(x){const o=new Map;for(const t of e)o.set(t.id,t);for(const e of p){const n=v(e.id,t,o);if(n.length>0){let t=0,o=0;for(const e of n)t+=e.x,o+=e.y;const r=q(e.id),a=r%360*(Math.PI/180),f=(10+r%20)*c;e.x=t/n.length+f*Math.cos(a),e.y=o/n.length+f*Math.sin(a)}else{const t=q(e.id),o=t%360*(Math.PI/180),n=(15+t%30)*c;e.x=a+n*Math.cos(o),e.y=f+n*Math.sin(o)}}}else{const t=Math.PI*(3-Math.sqrt(5));for(let o=0;o<e.length;o++){const n=e[o];if(null==n.x||null==n.y||0===n.x&&0===n.y){const e=10*Math.sqrt(o+.5)*c,r=o*t;n.x=a+e*Math.cos(r),n.y=f+e*Math.sin(r)}}}const S=e.length,k=o.iterations??Math.max(50,Math.min(300,Math.floor(300-2*(S-30)))),w=o.__skipForceSimulation||0===o.iterations?0:x?40:k,I=z(o.nodeSize,o.nodeSizeRange,e),R=e=>I(e);if(w>0){const b=new Map,m=new Map;for(const t of e)b.set(t.id,0),m.set(t.id,t);for(const e of t){const t="string"==typeof e.source?e.source:e.source.id,o="string"==typeof e.target?e.target:e.target.id;b.set(t,(b.get(t)??0)+1),b.set(o,(b.get(o)??0)+1)}const p=l().strength(e=>{const t=e.weight,o="string"==typeof e.source?e.source:e.source.id,n="string"==typeof e.target?e.target:e.target.id,a=Math.max(1,Math.min(b.get(o)??1,b.get(n)??1)),f=t&&t>0?Math.sqrt(t):1;return Math.min(2.5,f*r/(.1*a))}).distance(e=>{const t="string"==typeof e.source?m.get(e.source):e.source,o="string"==typeof e.target?m.get(e.target):e.target,n=(t?R(t):0)+(o?R(o):0)+Math.max(6,12*c);return Math.max(16,40*c,n)}).id(e=>e.id),M=s();if(void 0===o.random&&void 0===o.seed||M.randomSource(o.random??function(e){let t=e>>>0;return()=>{t+=1831565813;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(o.seed)),M.force("charge",g().strength(e=>{const t=b.get(e.id)??0;return-15*c*R(e)*Math.sqrt(t+1)})).force("collide",h(e=>R(e)+3*c).strength(.9).iterations(2)).force("center",i(a,f).strength(.8)).force("x",d(a).strength(y)).force("y",u(f).strength(y)).force("bounds",function(e,t,o=2,n=.6){let r=[];const a=a=>{const f=n*Math.max(a,.2);for(const n of r){const r=n.x??e[0]/2,a=n.y??e[1]/2,c=n.vx??0,s=n.vy??0,i=t(n)+o,d=Math.min(e[0]/2,i),u=Math.max(e[0]/2,e[0]-i),l=Math.min(e[1]/2,i),g=Math.max(e[1]/2,e[1]-i),h=r+c,y=a+s;h<d?n.vx=c+(d-h)*f:h>u&&(n.vx=c+(u-h)*f),y<l?n.vy=s+(l-y)*f:y>g&&(n.vy=s+(g-y)*f)}};return a.initialize=e=>{r=e},a}(n,R)),M.nodes(e),t.length>0){const e=t.map(e=>({...e,source:"string"==typeof e.source?e.source:e.source.id,target:"string"==typeof e.target?e.target:e.target.id}));p.links(e),M.force("link",p)}x?M.alpha(.3):M.alpha()<.1&&M.alpha(1),M.stop();for(let e=0;e<w;++e)M.tick()}for(const t of e){if(null==t.x||null==t.y)continue;const e=R(t),o=w>0?2:0,r=Math.min(n[0]/2,e+o),a=Math.min(n[1]/2,e+o);t.x=Math.max(r,Math.min(n[0]-r,t.x)),t.y=Math.max(a,Math.min(n[1]-a,t.y)),t.x0=0,t.x1=0,t.y0=0,t.y1=0}const $=new Map;for(const t of e)$.set(t.id,t);for(const e of t){if("string"==typeof e.source){const t=$.get(e.source);t&&(e.source=t)}if("string"==typeof e.target){const t=$.get(e.target);t&&(e.target=t)}}},buildScene(e,t,o,n){const r=o.nodeStyle,a=o.edgeStyle,f=z(o.nodeSize,o.nodeSizeRange,e),c=Array.isArray(o.colorScheme)?o.colorScheme:o.themeCategorical&&o.themeCategorical.length>0?o.themeCategorical:M,s=new Map;e.forEach((e,t)=>{s.set(e.id,c[t%c.length])});const i=[],d=[],u=[];for(const t of e){if(null==t.x||null==t.y)continue;const e=f(k(t,"nodeSize")),n=r?r(k(t,"nodeStyle")):{},a={fill:n.fill||s.get(t.id)||o.themeSemantic?.primary||"#007bff",stroke:n.stroke||o.themeSemantic?.surface||"#fff",strokeWidth:n.strokeWidth??2,opacity:n.opacity};i.push({type:"circle",cx:t.x,cy:t.y,r:e,style:a,datum:t,id:t.id,label:t.id})}const l=new Map;for(const t of e)l.set(t.id,t);for(const e of t){const t="object"==typeof e.source?e.source:l.get(e.source),n="object"==typeof e.target?e.target:l.get(e.target);if(!t||!n)continue;if(null==t.x||null==t.y)continue;if(null==n.x||null==n.y)continue;const r=a?a(k(e,"edgeStyle")):{},f={stroke:r.stroke||o.themeSemantic?.border||o.themeSemantic?.secondary||"#999",strokeWidth:r.strokeWidth??1,opacity:r.opacity??.6};d.push({type:"line",x1:t.x,y1:t.y,x2:n.x,y2:n.y,style:f,datum:e})}if(!1!==o.showLabels){const t=(g=o.nodeLabel)?"function"==typeof g?g:e=>e[g]||e.id:null;for(const o of e){if(null==o.x||null==o.y)continue;const e=t?t(o):o.id;if(!e)continue;const n=f(k(o,"nodeSize"));u.push({x:o.x,y:o.y-n-4,text:String(e),anchor:"middle",baseline:"auto",fontSize:11})}}var g;return{sceneNodes:i,sceneEdges:d,labels:u}}};function v(e,t,o){const n=[];for(const r of t){const t="string"==typeof r.source?r.source:r.source.id,a="string"==typeof r.target?r.target:r.target.id;let f=null;if(t===e?f=a:a===e&&(f=t),f){const e=o.get(f);!e||0===e.x&&0===e.y||n.push({x:e.x,y:e.y})}}return n}function q(e){let t=0;for(let o=0;o<e.length;o++)t=(t<<5)-t+e.charCodeAt(o)|0;return Math.abs(t)}function z(e,t,o){if(o.some(e=>null!=e.__forceRadius))return e=>e.__forceRadius??8;if(null==e)return()=>8;if("number"==typeof e)return()=>e;if("function"==typeof e)return t=>e(t)||8;const n=t||[5,20],r=[];for(const t of o){const o=t.data?.[e];"number"==typeof o&&r.push(o)}if(0===r.length)return()=>n[0];const[a,f]=function(e){let t=1/0,o=-1/0;for(const n of e)n<t&&(t=n),n>o&&(o=n);return[t,o]}(r);if(a===f)return()=>(n[0]+n[1])/2;const c=y().domain([a,f]).range(n).clamp(!0);return t=>{const o=t.data?.[e];return null==o||"number"!=typeof o?n[0]:c(o)}}self.onmessage=e=>{const t=e.data,o=t?.requestId,n=t?.request??t;try{if("normalized"===n.kind){const e=n.nodeRadii,t=e?{...n.options,nodeRadius:t=>e[t.id]??12}:n.options;return void self.postMessage({requestId:o,positions:c(n.nodes,n.edges,t)})}const e=n.nodes,t=n.edges;w.computeLayout(e,t,n.config,n.size),self.postMessage({requestId:o,positions:Object.fromEntries(e.map(e=>[e.id,{x:e.x,y:e.y}]))})}catch(e){self.postMessage({requestId:o,error:{message:e instanceof Error?e.message:String(e),name:e instanceof Error?e.name:"Error",stack:e instanceof Error?e.stack:void 0}})}};
|