@kanzo-tech/graph 0.26.0 → 0.28.0
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/README.md +7 -4
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +16 -16
- package/dist/core/client.js.map +1 -1
- package/dist/core/error.d.ts +3 -3
- package/dist/core/error.d.ts.map +1 -1
- package/dist/core/error.js.map +1 -1
- package/dist/core/state.d.ts +8 -3
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts +1 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +84 -76
- package/dist/core/store.js.map +1 -1
- package/dist/core/types.d.ts +5 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -24
- package/dist/index.js.map +1 -1
- package/dist/parts/graph-counts.d.ts +9 -11
- package/dist/parts/graph-counts.d.ts.map +1 -1
- package/dist/parts/graph-counts.js +28 -27
- package/dist/parts/graph-counts.js.map +1 -1
- package/dist/parts/graph-select.d.ts +27 -0
- package/dist/parts/graph-select.d.ts.map +1 -0
- package/dist/parts/graph-select.js +53 -0
- package/dist/parts/graph-select.js.map +1 -0
- package/dist/parts/graph-status.d.ts +13 -0
- package/dist/parts/graph-status.d.ts.map +1 -0
- package/dist/parts/graph-status.js +28 -0
- package/dist/parts/graph-status.js.map +1 -0
- package/dist/react/use-graph-prefs.d.ts +1 -1
- package/dist/react/use-graph-prefs.js.map +1 -1
- package/dist/render/camera.d.ts +12 -1
- package/dist/render/camera.d.ts.map +1 -1
- package/dist/render/camera.js +33 -21
- package/dist/render/camera.js.map +1 -1
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +85 -84
- package/dist/render/renderer.js.map +1 -1
- package/package.json +8 -8
package/dist/render/renderer.js
CHANGED
|
@@ -1,158 +1,159 @@
|
|
|
1
|
-
import { Graph as
|
|
1
|
+
import { Graph as an } from "@cosmos.gl/graph";
|
|
2
2
|
import { GraphError as L } from "../core/error.js";
|
|
3
|
-
import { resolveLook as
|
|
4
|
-
import { forces as z, appearance as
|
|
5
|
-
import { resolveSim as
|
|
6
|
-
import { createCamera as
|
|
7
|
-
import { simulating as F, highlighted as
|
|
8
|
-
import { placementOf as
|
|
9
|
-
import { webglBox as
|
|
10
|
-
const T = 0.35,
|
|
11
|
-
function
|
|
3
|
+
import { resolveLook as Y } from "./graph-looks.js";
|
|
4
|
+
import { forces as z, appearance as J, paint as ln } from "./graph-model.js";
|
|
5
|
+
import { resolveSim as Q } from "./graph-sim.js";
|
|
6
|
+
import { createCamera as sn, FIT_DURATION as un } from "./camera.js";
|
|
7
|
+
import { simulating as F, highlighted as cn, decayFor as fn, LINKS_WHILE_RUNNING as pn } from "./motion.js";
|
|
8
|
+
import { placementOf as dn, cornersOf as mn, placed as gn } from "./placement.js";
|
|
9
|
+
import { webglBox as hn, releaseContext as Sn } from "./webgl.js";
|
|
10
|
+
const T = 0.35, Pn = 1200, X = 20, $ = 1e4;
|
|
11
|
+
function xn(f, i, e = {}) {
|
|
12
12
|
let C = !1;
|
|
13
|
-
const
|
|
14
|
-
C ||
|
|
15
|
-
}, N =
|
|
13
|
+
const h = (n) => {
|
|
14
|
+
C || i.unrenderable(n);
|
|
15
|
+
}, N = hn();
|
|
16
16
|
if (N === null)
|
|
17
|
-
return
|
|
18
|
-
let b =
|
|
17
|
+
return h(new L("graph/no-webgl", "This browser offers no WebGL context to draw with.")), null;
|
|
18
|
+
let b = Q(i.getOptions().sim), p = !1, E = !1, O = null, x = null, w = 0, A = -1;
|
|
19
19
|
const _ = (n) => {
|
|
20
|
-
const o = Math.round(n *
|
|
21
|
-
o !== A && (A = o,
|
|
20
|
+
const o = Math.round(n * X);
|
|
21
|
+
o !== A && (A = o, i.reportProgress(o / X));
|
|
22
22
|
};
|
|
23
|
-
let
|
|
23
|
+
let S = Y(i.getOptions().look), B = i.getOptions().look;
|
|
24
24
|
const a = { positions: !0, paint: !0, state: !0, pinned: !0 };
|
|
25
|
-
let
|
|
25
|
+
let P = 0, d = null, s = i.getSnapshot(), m = i.getOptions();
|
|
26
26
|
const G = () => {
|
|
27
27
|
var n;
|
|
28
|
-
return ((n =
|
|
28
|
+
return ((n = i.getSnapshot().geometry) == null ? void 0 : n.size) ?? 0;
|
|
29
29
|
};
|
|
30
30
|
let t;
|
|
31
31
|
try {
|
|
32
|
-
t = new
|
|
32
|
+
t = new an(f, {
|
|
33
33
|
// No `spaceSize` here: it is the geometry's, set when the graph has loaded.
|
|
34
34
|
// `rescalePositions: false` because the placement below is ours.
|
|
35
35
|
rescalePositions: !1,
|
|
36
36
|
fitViewOnInit: !1,
|
|
37
37
|
transitionDuration: 0,
|
|
38
|
-
enableSimulation:
|
|
38
|
+
enableSimulation: p,
|
|
39
39
|
...z(b),
|
|
40
40
|
randomSeed: "kanzo-discovery",
|
|
41
41
|
pixelRatio: window.devicePixelRatio || 1,
|
|
42
42
|
enableDrag: !0,
|
|
43
43
|
hoveredPointCursor: "pointer",
|
|
44
44
|
attribution: "",
|
|
45
|
-
onSimulationStart: () =>
|
|
45
|
+
onSimulationStart: () => i.report("running"),
|
|
46
46
|
onSimulationEnd: () => {
|
|
47
47
|
var n;
|
|
48
|
-
I("settled"), _(1),
|
|
48
|
+
I("settled"), _(1), u.settle(), (n = e.onFrame) == null || n.call(e);
|
|
49
49
|
},
|
|
50
50
|
onSimulationPause: () => I("paused"),
|
|
51
51
|
onSimulationUnpause: () => I("running"),
|
|
52
52
|
onSimulationTick: (n, o, r) => {
|
|
53
|
-
var
|
|
54
|
-
_(t.progress),
|
|
53
|
+
var c, l;
|
|
54
|
+
_(t.progress), u.tick(), o !== void 0 && r && ((c = e.onHover) == null || c.call(e, r)), (l = e.onFrame) == null || l.call(e);
|
|
55
55
|
},
|
|
56
|
-
onZoomStart: (n, o) =>
|
|
56
|
+
onZoomStart: (n, o) => v(o),
|
|
57
57
|
onZoom: () => {
|
|
58
58
|
var n;
|
|
59
|
-
return (n =
|
|
59
|
+
return (n = e.onFrame) == null ? void 0 : n.call(e);
|
|
60
60
|
},
|
|
61
61
|
onPointMouseOver: (n, o) => {
|
|
62
62
|
var r;
|
|
63
|
-
O = n, (r =
|
|
63
|
+
O = n, (r = e.onHover) == null || r.call(e, o), i.hover(n);
|
|
64
64
|
},
|
|
65
65
|
onPointMouseOut: () => {
|
|
66
66
|
var n;
|
|
67
|
-
O = null, (n =
|
|
67
|
+
O = null, (n = e.onHover) == null || n.call(e, null), i.hover(null);
|
|
68
68
|
},
|
|
69
69
|
onDragStart: () => {
|
|
70
70
|
x = O;
|
|
71
71
|
},
|
|
72
72
|
onDrag: (n) => {
|
|
73
73
|
var o, r;
|
|
74
|
-
(o =
|
|
74
|
+
(o = e.onHover) == null || o.call(e, t.screenToSpacePosition([n.x, n.y])), (r = e.onFrame) == null || r.call(e);
|
|
75
75
|
},
|
|
76
76
|
// d3-force's drag-to-fix, and only while a layout can move the point back: cosmos.gl moves a
|
|
77
77
|
// dragged point with the simulation off too, and a pin nothing pulls against means nothing.
|
|
78
78
|
onDragEnd: () => {
|
|
79
79
|
const n = x;
|
|
80
80
|
x = null;
|
|
81
|
-
const { motion: o, pinned: r } =
|
|
82
|
-
n !== null && o !== "settled" && !r.includes(n) &&
|
|
81
|
+
const { motion: o, pinned: r } = i.getSnapshot();
|
|
82
|
+
n !== null && o !== "settled" && !r.includes(n) && i.pin([...r, n]);
|
|
83
83
|
},
|
|
84
84
|
onPointClick: (n) => Z(n),
|
|
85
85
|
onBackgroundClick: () => q()
|
|
86
86
|
});
|
|
87
87
|
} catch (n) {
|
|
88
|
-
return
|
|
88
|
+
return h(new L("graph/no-webgl", "The renderer failed to start.", {}, { cause: n })), null;
|
|
89
89
|
}
|
|
90
|
-
const { camera:
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
const { camera: u, taken: v } = sn(t, f, h), D = () => {
|
|
91
|
+
P || (P = requestAnimationFrame(() => {
|
|
92
|
+
P = 0, nn();
|
|
93
93
|
}));
|
|
94
94
|
};
|
|
95
|
-
function
|
|
96
|
-
var
|
|
97
|
-
const n =
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
function nn() {
|
|
96
|
+
var j, K;
|
|
97
|
+
const n = i.getSnapshot(), { geometry: o, encoding: r } = n, c = i.getOptions(), l = a.positions && r ? o : null;
|
|
98
|
+
l && (a.positions = !1, t.setPointPositions(on(l), !0), l.links !== d && (d = l.links, t.setLinks(d), a.paint = a.state = a.pinned = !0));
|
|
99
|
+
const V = a.paint && o && r;
|
|
100
|
+
if (V) {
|
|
100
101
|
a.paint = !1;
|
|
101
|
-
const y =
|
|
102
|
-
t.setPointColors(y.colors), t.setPointSizes(y.sizes), t.setPointShapes(y.shapes), t.setLinkColors(y.linkColors), t.setPointClusters(r.clusters ?? []), t.setConfigPartial({ ...
|
|
102
|
+
const y = ln(o, r, S, f, c);
|
|
103
|
+
t.setPointColors(y.colors), t.setPointSizes(y.sizes), t.setPointShapes(y.shapes), t.setLinkColors(y.linkColors), t.setPointClusters(r.clusters ?? []), t.setConfigPartial({ ...J(S, f), renderLinks: H() });
|
|
103
104
|
}
|
|
104
105
|
a.state && o && (a.state = !1, t.setConfigPartial({
|
|
105
|
-
...
|
|
106
|
+
...cn(o, n.mask, ((j = n.selection) == null ? void 0 : j.vertices) ?? null),
|
|
106
107
|
focusedPointIndex: n.focus === null || n.focus >= o.size ? void 0 : n.focus
|
|
107
|
-
})), a.pinned && o && (a.pinned = !1, t.setPinnedPoints(n.pinned.length > 0 ? [...n.pinned] : null)),
|
|
108
|
+
})), a.pinned && o && (a.pinned = !1, t.setPinnedPoints(n.pinned.length > 0 ? [...n.pinned] : null)), (V || l) && t.render(), l && tn(l, F(c, l)), o && r && !a.paint && i.reportDrawn(n), (K = e.onFrame) == null || K.call(e);
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
-
const o = n.bound && n.extent ?
|
|
111
|
-
return t.setConfigPartial({ spaceSize: (o == null ? void 0 : o.side) ?? n.space, simulationDecay:
|
|
110
|
+
function on(n) {
|
|
111
|
+
const o = n.bound && n.extent ? dn(n.extent, N) : null;
|
|
112
|
+
return t.setConfigPartial({ spaceSize: (o == null ? void 0 : o.side) ?? n.space, simulationDecay: fn(n.size) }), !o || !n.extent ? n.positions : (u.frame(mn(n.extent, o)), gn(n.positions, o));
|
|
112
113
|
}
|
|
113
|
-
function
|
|
114
|
-
if (o) return
|
|
115
|
-
|
|
114
|
+
function tn(n, o) {
|
|
115
|
+
if (u.drawn(), o) return k(1);
|
|
116
|
+
p && t.pause(), n.bound || u.fit();
|
|
116
117
|
}
|
|
117
|
-
const H = () =>
|
|
118
|
+
const H = () => S.link.render && !(E && ((d == null ? void 0 : d.length) ?? 0) / 2 > pn), U = () => t.setConfigPartial({ renderLinks: H() });
|
|
118
119
|
function I(n) {
|
|
119
|
-
E = n === "running", U(),
|
|
120
|
+
E = n === "running", U(), i.report(n);
|
|
120
121
|
}
|
|
121
|
-
function
|
|
122
|
-
const o =
|
|
123
|
-
b = o,
|
|
122
|
+
function en(n) {
|
|
123
|
+
const o = Q(n), r = Object.keys(o).some((c) => o[c] !== b[c]);
|
|
124
|
+
b = o, p && (t.setConfigPartial(z(o)), r && i.getSnapshot().motion !== "paused" && t.start(T));
|
|
124
125
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
126
|
+
function k(n) {
|
|
127
|
+
p || (p = !0, t.setConfigPartial({ enableSimulation: !0, ...z(b) })), u.run(), E = !0, t.start(n), U();
|
|
127
128
|
}
|
|
128
|
-
function
|
|
129
|
+
function g() {
|
|
129
130
|
clearTimeout(w), w = 0;
|
|
130
131
|
}
|
|
131
132
|
function Z(n) {
|
|
132
133
|
const o = t.getNeighboringPointIndices(n) ?? [];
|
|
133
|
-
|
|
134
|
+
i.select([n, ...o], "node", "Node"), i.focus(n);
|
|
134
135
|
}
|
|
135
136
|
function q() {
|
|
136
|
-
|
|
137
|
+
i.select(null), i.focus(null);
|
|
137
138
|
}
|
|
138
|
-
t.setConfigPartial(
|
|
139
|
+
t.setConfigPartial(J(S, f)), t.render();
|
|
139
140
|
const M = (n) => {
|
|
140
|
-
n.preventDefault(),
|
|
141
|
-
}, W = (n, o) =>
|
|
141
|
+
n.preventDefault(), h(new L("graph/context-lost", "The browser took back the WebGL context; reload to get one."));
|
|
142
|
+
}, W = (n, o) => h(new L("graph/no-webgl", "No GPU device came up to draw with.", n, { cause: o })), R = setTimeout(() => W({ after: $ }), $);
|
|
142
143
|
t.ready.then(
|
|
143
144
|
() => {
|
|
144
145
|
var n;
|
|
145
|
-
clearTimeout(R), C || (n =
|
|
146
|
+
clearTimeout(R), C || (n = f.querySelector("canvas")) == null || n.addEventListener("webglcontextlost", M), u.ready();
|
|
146
147
|
},
|
|
147
148
|
(n) => {
|
|
148
149
|
clearTimeout(R), W({}, n);
|
|
149
150
|
}
|
|
150
|
-
),
|
|
151
|
-
const
|
|
152
|
-
const n =
|
|
153
|
-
n.geometry !==
|
|
151
|
+
), i.report(p && t.isSimulationRunning ? "running" : "settled"), D();
|
|
152
|
+
const rn = i.subscribe(() => {
|
|
153
|
+
const n = i.getSnapshot(), o = i.getOptions();
|
|
154
|
+
n.geometry !== s.geometry && (a.positions = !0), n.encoding !== s.encoding && (a.paint = !0), o.look !== B && (B = o.look, S = Y(o.look), a.paint = !0), (o.fill !== m.fill || o.symbol !== m.symbol || o.stroke !== m.stroke) && (a.paint = !0), (n.selection !== s.selection || n.focus !== s.focus || n.mask !== s.mask) && (a.state = !0), n.pinned !== s.pinned && (a.pinned = !0), o.sim !== m.sim && en(o.sim);
|
|
154
155
|
const r = F(o, n.geometry);
|
|
155
|
-
n.geometry ===
|
|
156
|
+
n.geometry === s.geometry && r !== F(m, s.geometry) && (g(), r ? k(T) : t.pause()), s = n, m = o, (a.positions || a.paint || a.state || a.pinned) && D();
|
|
156
157
|
});
|
|
157
158
|
return {
|
|
158
159
|
graph: t,
|
|
@@ -166,15 +167,15 @@ function On(u, e, i = {}) {
|
|
|
166
167
|
zoomBy(n) {
|
|
167
168
|
t.setZoomLevel(t.getZoomLevel() * n, 220);
|
|
168
169
|
},
|
|
169
|
-
fit: () =>
|
|
170
|
+
fit: () => u.fit(),
|
|
170
171
|
pause() {
|
|
171
|
-
|
|
172
|
+
g(), t.pause();
|
|
172
173
|
},
|
|
173
174
|
resume() {
|
|
174
|
-
|
|
175
|
+
g(), i.getSnapshot().motion === "settled" || !p ? k(T) : t.unpause();
|
|
175
176
|
},
|
|
176
177
|
restart() {
|
|
177
|
-
|
|
178
|
+
g(), i.pin([]), k(1);
|
|
178
179
|
},
|
|
179
180
|
/**
|
|
180
181
|
* d3's release: unfix, then reheat, so the released points visibly flow back. A running layout
|
|
@@ -182,28 +183,28 @@ function On(u, e, i = {}) {
|
|
|
182
183
|
* bounded burst and is paused again, because the reader paused it.
|
|
183
184
|
*/
|
|
184
185
|
unpin() {
|
|
185
|
-
const { motion: n, pinned: o } =
|
|
186
|
-
o.length !== 0 && (
|
|
186
|
+
const { motion: n, pinned: o } = i.getSnapshot();
|
|
187
|
+
o.length !== 0 && (g(), i.pin([]), k(T), n === "paused" && (w = window.setTimeout(() => {
|
|
187
188
|
w = 0, t.pause();
|
|
188
|
-
},
|
|
189
|
+
}, Pn)));
|
|
189
190
|
},
|
|
190
191
|
reveal(n) {
|
|
191
192
|
n >= G() || (Z(n), t.zoomToPointByIndex(n, 500, 5, !0));
|
|
192
193
|
},
|
|
193
194
|
frameSelection() {
|
|
194
195
|
var o;
|
|
195
|
-
const n = (((o =
|
|
196
|
-
n.length > 0 && t.fitViewByPointIndices(n,
|
|
196
|
+
const n = (((o = i.getSnapshot().selection) == null ? void 0 : o.vertices) ?? []).filter((r) => r < G());
|
|
197
|
+
n.length > 0 && t.fitViewByPointIndices(n, un, 0.25);
|
|
197
198
|
},
|
|
198
199
|
clear: q,
|
|
199
200
|
destroy() {
|
|
200
|
-
|
|
201
|
-
const n =
|
|
202
|
-
n == null || n.removeEventListener("webglcontextlost", M), t.destroy(),
|
|
201
|
+
rn(), g(), P && cancelAnimationFrame(P), clearTimeout(R), u.destroy(), C = !0;
|
|
202
|
+
const n = f.querySelector("canvas");
|
|
203
|
+
n == null || n.removeEventListener("webglcontextlost", M), t.destroy(), Sn(n);
|
|
203
204
|
}
|
|
204
205
|
};
|
|
205
206
|
}
|
|
206
207
|
export {
|
|
207
|
-
|
|
208
|
+
xn as createRenderer
|
|
208
209
|
};
|
|
209
210
|
//# sourceMappingURL=renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","sources":["../../src/render/renderer.ts"],"sourcesContent":["import { Graph } from \"@cosmos.gl/graph\";\nimport { GraphError } from \"../core/error\";\nimport type { Geometry } from \"../core/load\";\nimport type { GraphStore } from \"../core/store\";\nimport type { GraphCommands, Motion, VertexId } from \"../core/types\";\nimport { resolveLook, type Look } from \"./graph-looks\";\nimport { appearance, forces, paint } from \"./graph-model\";\nimport { resolveSim, type Sim } from \"./graph-sim\";\nimport { createCamera, FIT_DURATION } from \"./camera\";\nimport { decayFor, highlighted, LINKS_WHILE_RUNNING, simulating } from \"./motion\";\nimport { cornersOf, placed, placementOf } from \"./placement\";\nimport { releaseContext, webglBox } from \"./webgl\";\n\nexport interface RendererEvents {\n /** After every frame and every camera move — where the overlays repaint. */\n onFrame?: () => void;\n /** Where the hovered point is in space, as cosmos.gl reports it: no GPU readback per hover. */\n onHover?: (position: [number, number] | null) => void;\n}\n\nexport interface Renderer extends GraphCommands {\n readonly graph: Graph;\n /** The theme moved under the canvas: colours are resolved again, nothing else. */\n repaint(): void;\n /** The drawn points inside a screen rectangle or polygon, once the device is ready. */\n hit(shape: { rect: [[number, number], [number, number]] } | { polygon: [number, number][] }): number[];\n destroy(): void;\n}\n\nconst REHEAT = 0.35;\n/** How long a release wakes a paused layout before pausing it again. */\nconst RELEASE_BURST = 1200;\n/** Twentieths: a settle costs twenty reports rather than one per frame. */\nconst PROGRESS_STEPS = 20;\n\n/**\n * The slowest honest answer for a GPU device: one comes up in milliseconds when it can be made at\n * all, so ten seconds is a device that will not come, not one that is slow.\n */\nconst READY_DEADLINE = 10_000;\n\n/**\n * **cosmos.gl's lifetime, and the frame that renders once.** Built once per element; it subscribes to\n * the store and discharges what changed in one `requestAnimationFrame`:\n *\n * - a new graph uploads positions and links, once per corpus and per position binding;\n * - a binding, a look or a theme change uploads colours, sizes, shapes and clusters and nothing else;\n * - a filter, a selection, a focus or a pin sets config and uploads nothing, and never calls\n * `render()`: a vertex the page's filter does not keep is greyed out, Cosmograph's way, so the\n * points never move because a chart was brushed;\n * - the camera reaches nothing: cosmos.gl moves it, and the overlays follow.\n *\n * A vertex's id is its index here, so nothing is resolved between the store and the buffers.\n * `transitionDuration` is 0: the default animates every upload for 800 ms and keeps the loop awake.\n * The layout runs on its own when `x` and `y` are unbound, and from the current positions.\n * Every callback reads the store's latest options, so a host's inline `onFailure` never rebuilds it.\n * A failure to draw at all marks the store `failed` through `unrenderable`, never `onFailure` alone.\n */\nexport function createRenderer(host: HTMLDivElement, store: GraphStore, events: RendererEvents = {}): Renderer | null {\n let destroyed = false;\n const fail = (error: unknown) => {\n if (!destroyed) store.unrenderable(error);\n };\n const box = webglBox();\n if (box === null) {\n fail(new GraphError(\"graph/no-webgl\", \"This browser offers no WebGL context to draw with.\"));\n return null;\n }\n\n let sim: Sim = resolveSim(store.getOptions().sim);\n let live = false;\n /** Whether a layout is moving the points — ours, since cosmos.gl's flag waits for its device. */\n let moving = false;\n let hovering: number | null = null;\n let dragging: number | null = null;\n let burst = 0;\n let reported = -1;\n const progress = (value: number) => {\n const bucket = Math.round(value * PROGRESS_STEPS);\n if (bucket === reported) return;\n reported = bucket;\n store.reportProgress(bucket / PROGRESS_STEPS);\n };\n\n let look: Look = resolveLook(store.getOptions().look);\n let lookPatch = store.getOptions().look;\n const dirty = { positions: true, paint: true, state: true, pinned: true };\n let frame = 0;\n let links: Float32Array | null = null;\n let last = store.getSnapshot();\n let lastOptions = store.getOptions();\n\n const size = () => store.getSnapshot().geometry?.size ?? 0;\n\n let graph: Graph;\n try {\n graph = new Graph(host, {\n // No `spaceSize` here: it is the geometry's, set when the graph has loaded.\n // `rescalePositions: false` because the placement below is ours.\n rescalePositions: false,\n fitViewOnInit: false,\n transitionDuration: 0,\n enableSimulation: live,\n ...forces(sim),\n randomSeed: \"kanzo-discovery\",\n pixelRatio: window.devicePixelRatio || 1,\n enableDrag: true,\n hoveredPointCursor: \"pointer\",\n attribution: \"\",\n onSimulationStart: () => store.report(\"running\"),\n onSimulationEnd: () => {\n moved(\"settled\");\n progress(1);\n camera.settle();\n events.onFrame?.();\n },\n onSimulationPause: () => moved(\"paused\"),\n onSimulationUnpause: () => moved(\"running\"),\n onSimulationTick: (_alpha, index, position) => {\n progress(graph.progress);\n camera.tick();\n if (index !== undefined && position) events.onHover?.(position);\n events.onFrame?.();\n },\n onZoomStart: (_event, userDriven) => taken(userDriven),\n onZoom: () => events.onFrame?.(),\n onPointMouseOver: (index, position) => {\n hovering = index;\n events.onHover?.(position);\n store.hover(index);\n },\n onPointMouseOut: () => {\n hovering = null;\n events.onHover?.(null);\n store.hover(null);\n },\n onDragStart: () => {\n dragging = hovering;\n },\n onDrag: (event) => {\n events.onHover?.(graph.screenToSpacePosition([event.x, event.y]));\n events.onFrame?.();\n },\n // d3-force's drag-to-fix, and only while a layout can move the point back: cosmos.gl moves a\n // dragged point with the simulation off too, and a pin nothing pulls against means nothing.\n onDragEnd: () => {\n const vertex = dragging;\n dragging = null;\n const { motion, pinned } = store.getSnapshot();\n if (vertex !== null && motion !== \"settled\" && !pinned.includes(vertex)) store.pin([...pinned, vertex]);\n },\n onPointClick: (index) => focusOn(index),\n onBackgroundClick: () => clear(),\n });\n } catch (error) {\n fail(new GraphError(\"graph/no-webgl\", \"The renderer failed to start.\", {}, { cause: error }));\n return null;\n }\n const { camera, taken } = createCamera(graph, host);\n\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n draw();\n });\n };\n\n function draw(): void {\n const snapshot = store.getSnapshot();\n const { geometry, encoding } = snapshot;\n const options = store.getOptions();\n let changed = false;\n // Positions wait for the first colours, so a graph's first frame is the drawn one, not a grey one.\n if (dirty.positions && geometry && encoding) {\n dirty.positions = false;\n graph.setPointPositions(position(geometry), true);\n if (geometry.links !== links) {\n links = geometry.links;\n graph.setLinks(links);\n dirty.paint = dirty.state = dirty.pinned = true;\n }\n changed = true;\n layout(geometry, simulating(options, geometry));\n }\n if (dirty.paint && geometry && encoding) {\n dirty.paint = false;\n const buffers = paint(geometry, encoding, look, host, options);\n graph.setPointColors(buffers.colors);\n graph.setPointSizes(buffers.sizes);\n graph.setPointShapes(buffers.shapes);\n graph.setLinkColors(buffers.linkColors);\n graph.setPointClusters(encoding.clusters ?? []);\n graph.setConfigPartial({ ...appearance(look, host), renderLinks: linksShown() });\n changed = true;\n }\n if (dirty.state && geometry) {\n dirty.state = false;\n graph.setConfigPartial({\n ...highlighted(geometry, snapshot.mask, snapshot.selection?.vertices ?? null),\n focusedPointIndex: snapshot.focus === null || snapshot.focus >= geometry.size ? undefined : snapshot.focus,\n });\n }\n if (dirty.pinned && geometry) {\n dirty.pinned = false;\n graph.setPinnedPoints(snapshot.pinned.length > 0 ? [...snapshot.pinned] : null);\n }\n if (changed) graph.render();\n if (geometry && encoding && !dirty.paint) store.reportDrawn(snapshot);\n events.onFrame?.();\n }\n\n /** The positions cosmos.gl gets: bound, the data's extent centred in the device's box; unbound, the seeded start. */\n function position(geometry: Geometry): Float32Array {\n const placement = geometry.bound && geometry.extent ? placementOf(geometry.extent, box as number) : null;\n graph.setConfigPartial({ spaceSize: placement?.side ?? geometry.space, simulationDecay: decayFor(geometry.size) });\n if (!placement || !geometry.extent) return geometry.positions;\n camera.frame(cornersOf(geometry.extent, placement));\n return placed(geometry.positions, placement);\n }\n\n /** A new geometry lays itself out when its positions are a start, and stands still when they are data. */\n function layout(geometry: Geometry, running: boolean): void {\n if (running) return run(1);\n if (live) graph.pause();\n if (!geometry.bound) camera.fit();\n }\n\n /** Whether links are drawn now: the look's choice, unless a large layout is running. */\n const linksShown = (): boolean => look.link.render && !(moving && (links?.length ?? 0) / 2 > LINKS_WHILE_RUNNING);\n const showLinks = () => graph.setConfigPartial({ renderLinks: linksShown() });\n function moved(motion: Motion): void {\n moving = motion === \"running\";\n showLinks();\n store.report(motion);\n }\n\n function applyForces(patch: Partial<Sim> | undefined): void {\n const next = resolveSim(patch);\n const moved = Object.keys(next).some((key) => next[key as keyof Sim] !== sim[key as keyof Sim]);\n sim = next;\n if (!live) return;\n graph.setConfigPartial(forces(next));\n if (moved && store.getSnapshot().motion !== \"paused\") graph.start(REHEAT);\n }\n\n /** A layout runs from where the points are: enabling cosmos.gl's simulation keeps its positions. */\n function run(alpha: number): void {\n if (!live) {\n live = true;\n graph.setConfigPartial({ enableSimulation: true, ...forces(sim) });\n }\n camera.run();\n moving = true;\n graph.start(alpha);\n showLinks();\n }\n\n function endBurst(): void {\n clearTimeout(burst);\n burst = 0;\n }\n\n function focusOn(vertex: VertexId): void {\n const around = graph.getNeighboringPointIndices(vertex) ?? [];\n store.select([vertex, ...around], \"node\", \"Node\");\n store.focus(vertex);\n }\n\n function clear(): void {\n store.select(null);\n store.focus(null);\n }\n\n // cosmos.gl 3.4 queues every setter and command until its device exists (`ensureDevice`), and its\n // two synchronous hit tests answer `[]` until then; only the canvas element has to wait for `ready`.\n graph.setConfigPartial(appearance(look, host));\n graph.render();\n const onLost = (event: Event) => {\n event.preventDefault();\n fail(new GraphError(\"graph/context-lost\", \"The browser took back the WebGL context; reload to get one.\"));\n };\n const noDevice = (data: GraphError[\"data\"], cause?: unknown) =>\n fail(new GraphError(\"graph/no-webgl\", \"No GPU device came up to draw with.\", data, { cause }));\n // `ready` never settles when cosmos.gl cannot make a device, so the deadline is what ends the wait.\n const deadline = setTimeout(() => noDevice({ after: READY_DEADLINE }), READY_DEADLINE);\n void graph.ready.then(\n () => {\n clearTimeout(deadline);\n if (!destroyed) host.querySelector(\"canvas\")?.addEventListener(\"webglcontextlost\", onLost);\n },\n (error: unknown) => {\n clearTimeout(deadline);\n noDevice({}, error);\n },\n );\n store.report(live && graph.isSimulationRunning ? \"running\" : \"settled\");\n schedule();\n\n const unsubscribe = store.subscribe(() => {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n if (snapshot.geometry !== last.geometry) dirty.positions = true;\n if (snapshot.encoding !== last.encoding) dirty.paint = true;\n if (options.look !== lookPatch) {\n lookPatch = options.look;\n look = resolveLook(options.look);\n dirty.paint = true;\n }\n if (options.fill !== lastOptions.fill || options.symbol !== lastOptions.symbol || options.stroke !== lastOptions.stroke) {\n dirty.paint = true;\n }\n if (snapshot.selection !== last.selection || snapshot.focus !== last.focus || snapshot.mask !== last.mask) dirty.state = true;\n if (snapshot.pinned !== last.pinned) dirty.pinned = true;\n if (options.sim !== lastOptions.sim) applyForces(options.sim);\n const wants = simulating(options, snapshot.geometry);\n if (snapshot.geometry === last.geometry && wants !== simulating(lastOptions, last.geometry)) {\n endBurst();\n if (wants) run(REHEAT);\n else graph.pause();\n }\n last = snapshot;\n lastOptions = options;\n if (dirty.positions || dirty.paint || dirty.state || dirty.pinned) schedule();\n });\n\n return {\n graph,\n repaint() {\n dirty.paint = true;\n schedule();\n },\n hit(shape) {\n const found = \"rect\" in shape ? graph.findPointsInRect(shape.rect) : graph.findPointsInPolygon(shape.polygon);\n return Array.from(found);\n },\n zoomBy(factor) {\n graph.setZoomLevel(graph.getZoomLevel() * factor, 220);\n },\n fit: () => camera.fit(),\n pause() {\n endBurst();\n graph.pause();\n },\n resume() {\n endBurst();\n const settled = store.getSnapshot().motion === \"settled\";\n if (settled || !live) run(REHEAT);\n else graph.unpause();\n },\n restart() {\n endBurst();\n store.pin([]);\n run(1);\n },\n /**\n * d3's release: unfix, then reheat, so the released points visibly flow back. A running layout\n * takes the heat and goes on; a settled one cools to settled on its own; a paused one gets a\n * bounded burst and is paused again, because the reader paused it.\n */\n unpin() {\n const { motion, pinned } = store.getSnapshot();\n if (pinned.length === 0) return;\n endBurst();\n store.pin([]);\n run(REHEAT);\n if (motion === \"paused\") {\n burst = window.setTimeout(() => {\n burst = 0;\n graph.pause();\n }, RELEASE_BURST);\n }\n },\n reveal(vertex) {\n if (vertex >= size()) return;\n focusOn(vertex);\n graph.zoomToPointByIndex(vertex, 500, 5, true);\n },\n frameSelection() {\n const vertices = (store.getSnapshot().selection?.vertices ?? []).filter((id) => id < size());\n if (vertices.length > 0) graph.fitViewByPointIndices(vertices, FIT_DURATION, 0.25);\n },\n clear,\n destroy() {\n unsubscribe();\n endBurst();\n if (frame) cancelAnimationFrame(frame);\n clearTimeout(deadline);\n camera.destroy();\n destroyed = true;\n // Read here rather than remembered from construction: the element exists only with the device.\n const canvas = host.querySelector(\"canvas\");\n canvas?.removeEventListener(\"webglcontextlost\", onLost);\n graph.destroy();\n releaseContext(canvas);\n },\n };\n}\n"],"names":["REHEAT","RELEASE_BURST","PROGRESS_STEPS","READY_DEADLINE","createRenderer","host","store","events","destroyed","fail","error","box","webglBox","GraphError","sim","resolveSim","live","moving","hovering","dragging","burst","reported","progress","value","bucket","look","resolveLook","lookPatch","dirty","frame","links","last","lastOptions","size","_a","graph","Graph","forces","moved","camera","_alpha","index","position","_b","_event","userDriven","taken","event","vertex","motion","pinned","focusOn","clear","createCamera","schedule","draw","snapshot","geometry","encoding","options","changed","layout","simulating","buffers","paint","appearance","linksShown","highlighted","placement","placementOf","decayFor","cornersOf","placed","running","run","LINKS_WHILE_RUNNING","showLinks","applyForces","patch","next","key","alpha","endBurst","around","onLost","noDevice","data","cause","deadline","unsubscribe","wants","shape","found","factor","vertices","id","FIT_DURATION","canvas","releaseContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderer.js","sources":["../../src/render/renderer.ts"],"sourcesContent":["import { Graph } from \"@cosmos.gl/graph\";\nimport { GraphError } from \"../core/error\";\nimport type { Geometry } from \"../core/load\";\nimport type { GraphStore } from \"../core/store\";\nimport type { GraphCommands, Motion, VertexId } from \"../core/types\";\nimport { resolveLook, type Look } from \"./graph-looks\";\nimport { appearance, forces, paint } from \"./graph-model\";\nimport { resolveSim, type Sim } from \"./graph-sim\";\nimport { createCamera, FIT_DURATION } from \"./camera\";\nimport { decayFor, highlighted, LINKS_WHILE_RUNNING, simulating } from \"./motion\";\nimport { cornersOf, placed, placementOf } from \"./placement\";\nimport { releaseContext, webglBox } from \"./webgl\";\n\nexport interface RendererEvents {\n /** After every frame and every camera move — where the overlays repaint. */\n onFrame?: () => void;\n /** Where the hovered point is in space, as cosmos.gl reports it: no GPU readback per hover. */\n onHover?: (position: [number, number] | null) => void;\n}\n\nexport interface Renderer extends GraphCommands {\n readonly graph: Graph;\n /** The theme moved under the canvas: colours are resolved again, nothing else. */\n repaint(): void;\n /** The drawn points inside a screen rectangle or polygon, once the device is ready. */\n hit(shape: { rect: [[number, number], [number, number]] } | { polygon: [number, number][] }): number[];\n destroy(): void;\n}\n\nconst REHEAT = 0.35;\n/** How long a release wakes a paused layout before pausing it again. */\nconst RELEASE_BURST = 1200;\n/** Twentieths: a settle costs twenty reports rather than one per frame. */\nconst PROGRESS_STEPS = 20;\n\n/**\n * The slowest honest answer for a GPU device: one comes up in milliseconds when it can be made at\n * all, so ten seconds is a device that will not come, not one that is slow.\n */\nconst READY_DEADLINE = 10_000;\n\n/**\n * **cosmos.gl's lifetime, and the frame that renders once.** Built once per element; it subscribes to\n * the store and discharges what changed in one `requestAnimationFrame`:\n *\n * - a new graph uploads positions and links, once per corpus and per position binding;\n * - a binding, a look or a theme change uploads colours, sizes, shapes and clusters and nothing else;\n * - a filter, a selection, a focus or a pin sets config and uploads nothing, and never calls\n * `render()`: a vertex the page's filter does not keep is greyed out, Cosmograph's way, so the\n * points never move because a chart was brushed;\n * - the camera reaches nothing: cosmos.gl moves it, and the overlays follow.\n *\n * A vertex's id is its index here, so nothing is resolved between the store and the buffers.\n * `transitionDuration` is 0: the default animates every upload for 800 ms and keeps the loop awake.\n * The layout runs on its own when `x` and `y` are unbound, and from the current positions.\n * Every callback reads the store's latest options, so a host's inline `onFailure` never rebuilds it.\n * A failure to draw at all marks the store `failed` through `unrenderable`, never `onFailure` alone.\n */\nexport function createRenderer(host: HTMLDivElement, store: GraphStore, events: RendererEvents = {}): Renderer | null {\n let destroyed = false;\n const fail = (error: unknown) => {\n if (!destroyed) store.unrenderable(error);\n };\n const box = webglBox();\n if (box === null) {\n fail(new GraphError(\"graph/no-webgl\", \"This browser offers no WebGL context to draw with.\"));\n return null;\n }\n\n let sim: Sim = resolveSim(store.getOptions().sim);\n let live = false;\n /** Whether a layout is moving the points — ours, since cosmos.gl's flag waits for its device. */\n let moving = false;\n let hovering: number | null = null;\n let dragging: number | null = null;\n let burst = 0;\n let reported = -1;\n const progress = (value: number) => {\n const bucket = Math.round(value * PROGRESS_STEPS);\n if (bucket === reported) return;\n reported = bucket;\n store.reportProgress(bucket / PROGRESS_STEPS);\n };\n\n let look: Look = resolveLook(store.getOptions().look);\n let lookPatch = store.getOptions().look;\n const dirty = { positions: true, paint: true, state: true, pinned: true };\n let frame = 0;\n let links: Float32Array | null = null;\n let last = store.getSnapshot();\n let lastOptions = store.getOptions();\n\n const size = () => store.getSnapshot().geometry?.size ?? 0;\n\n let graph: Graph;\n try {\n graph = new Graph(host, {\n // No `spaceSize` here: it is the geometry's, set when the graph has loaded.\n // `rescalePositions: false` because the placement below is ours.\n rescalePositions: false,\n fitViewOnInit: false,\n transitionDuration: 0,\n enableSimulation: live,\n ...forces(sim),\n randomSeed: \"kanzo-discovery\",\n pixelRatio: window.devicePixelRatio || 1,\n enableDrag: true,\n hoveredPointCursor: \"pointer\",\n attribution: \"\",\n onSimulationStart: () => store.report(\"running\"),\n onSimulationEnd: () => {\n moved(\"settled\");\n progress(1);\n camera.settle();\n events.onFrame?.();\n },\n onSimulationPause: () => moved(\"paused\"),\n onSimulationUnpause: () => moved(\"running\"),\n onSimulationTick: (_alpha, index, position) => {\n progress(graph.progress);\n camera.tick();\n if (index !== undefined && position) events.onHover?.(position);\n events.onFrame?.();\n },\n onZoomStart: (_event, userDriven) => taken(userDriven),\n onZoom: () => events.onFrame?.(),\n onPointMouseOver: (index, position) => {\n hovering = index;\n events.onHover?.(position);\n store.hover(index);\n },\n onPointMouseOut: () => {\n hovering = null;\n events.onHover?.(null);\n store.hover(null);\n },\n onDragStart: () => {\n dragging = hovering;\n },\n onDrag: (event) => {\n events.onHover?.(graph.screenToSpacePosition([event.x, event.y]));\n events.onFrame?.();\n },\n // d3-force's drag-to-fix, and only while a layout can move the point back: cosmos.gl moves a\n // dragged point with the simulation off too, and a pin nothing pulls against means nothing.\n onDragEnd: () => {\n const vertex = dragging;\n dragging = null;\n const { motion, pinned } = store.getSnapshot();\n if (vertex !== null && motion !== \"settled\" && !pinned.includes(vertex)) store.pin([...pinned, vertex]);\n },\n onPointClick: (index) => focusOn(index),\n onBackgroundClick: () => clear(),\n });\n } catch (error) {\n fail(new GraphError(\"graph/no-webgl\", \"The renderer failed to start.\", {}, { cause: error }));\n return null;\n }\n const { camera, taken } = createCamera(graph, host, fail);\n\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n draw();\n });\n };\n\n function draw(): void {\n const snapshot = store.getSnapshot();\n const { geometry, encoding } = snapshot;\n const options = store.getOptions();\n // Positions wait for the first colours, so a graph's first frame is the drawn one, not a grey one.\n const placing = dirty.positions && encoding ? geometry : null;\n if (placing) {\n dirty.positions = false;\n graph.setPointPositions(position(placing), true);\n if (placing.links !== links) {\n links = placing.links;\n graph.setLinks(links);\n dirty.paint = dirty.state = dirty.pinned = true;\n }\n }\n const painting = dirty.paint && geometry && encoding;\n if (painting) {\n dirty.paint = false;\n const buffers = paint(geometry, encoding, look, host, options);\n graph.setPointColors(buffers.colors);\n graph.setPointSizes(buffers.sizes);\n graph.setPointShapes(buffers.shapes);\n graph.setLinkColors(buffers.linkColors);\n graph.setPointClusters(encoding.clusters ?? []);\n graph.setConfigPartial({ ...appearance(look, host), renderLinks: linksShown() });\n }\n if (dirty.state && geometry) {\n dirty.state = false;\n graph.setConfigPartial({\n ...highlighted(geometry, snapshot.mask, snapshot.selection?.vertices ?? null),\n focusedPointIndex: snapshot.focus === null || snapshot.focus >= geometry.size ? undefined : snapshot.focus,\n });\n }\n if (dirty.pinned && geometry) {\n dirty.pinned = false;\n graph.setPinnedPoints(snapshot.pinned.length > 0 ? [...snapshot.pinned] : null);\n }\n if (painting || placing) graph.render();\n if (placing) layout(placing, simulating(options, placing)); // after render(): cosmos.gl 3.4 turning its simulation on drops unrendered uploads\n if (geometry && encoding && !dirty.paint) store.reportDrawn(snapshot);\n events.onFrame?.();\n }\n\n /** The positions cosmos.gl gets: bound, the data's extent centred in the device's box; unbound, the seeded start. */\n function position(geometry: Geometry): Float32Array {\n const placement = geometry.bound && geometry.extent ? placementOf(geometry.extent, box as number) : null;\n graph.setConfigPartial({ spaceSize: placement?.side ?? geometry.space, simulationDecay: decayFor(geometry.size) });\n if (!placement || !geometry.extent) return geometry.positions;\n camera.frame(cornersOf(geometry.extent, placement));\n return placed(geometry.positions, placement);\n }\n\n /** A new geometry lays itself out when its positions are a start, and stands still when they are data. */\n function layout(geometry: Geometry, running: boolean): void {\n camera.drawn();\n if (running) return run(1);\n if (live) graph.pause();\n if (!geometry.bound) camera.fit();\n }\n\n /** Whether links are drawn now: the look's choice, unless a large layout is running. */\n const linksShown = (): boolean => look.link.render && !(moving && (links?.length ?? 0) / 2 > LINKS_WHILE_RUNNING);\n const showLinks = () => graph.setConfigPartial({ renderLinks: linksShown() });\n function moved(motion: Motion): void {\n moving = motion === \"running\";\n showLinks();\n store.report(motion);\n }\n\n function applyForces(patch: Partial<Sim> | undefined): void {\n const next = resolveSim(patch);\n const moved = Object.keys(next).some((key) => next[key as keyof Sim] !== sim[key as keyof Sim]);\n sim = next;\n if (!live) return;\n graph.setConfigPartial(forces(next));\n if (moved && store.getSnapshot().motion !== \"paused\") graph.start(REHEAT);\n }\n\n /** A layout runs from where the points are: enabling cosmos.gl's simulation keeps its positions. */\n function run(alpha: number): void {\n if (!live) {\n live = true;\n graph.setConfigPartial({ enableSimulation: true, ...forces(sim) });\n }\n camera.run();\n moving = true;\n graph.start(alpha);\n showLinks();\n }\n\n function endBurst(): void {\n clearTimeout(burst);\n burst = 0;\n }\n\n function focusOn(vertex: VertexId): void {\n const around = graph.getNeighboringPointIndices(vertex) ?? [];\n store.select([vertex, ...around], \"node\", \"Node\");\n store.focus(vertex);\n }\n\n function clear(): void {\n store.select(null);\n store.focus(null);\n }\n\n // cosmos.gl 3.4 queues every setter and command until its device exists (`ensureDevice`), and its\n // two synchronous hit tests answer `[]` until then; only the canvas element has to wait for `ready`.\n graph.setConfigPartial(appearance(look, host));\n graph.render();\n const onLost = (event: Event) => {\n event.preventDefault();\n fail(new GraphError(\"graph/context-lost\", \"The browser took back the WebGL context; reload to get one.\"));\n };\n const noDevice = (data: GraphError[\"data\"], cause?: unknown) =>\n fail(new GraphError(\"graph/no-webgl\", \"No GPU device came up to draw with.\", data, { cause }));\n // `ready` never settles when cosmos.gl cannot make a device, so the deadline is what ends the wait.\n const deadline = setTimeout(() => noDevice({ after: READY_DEADLINE }), READY_DEADLINE);\n void graph.ready.then(\n () => {\n clearTimeout(deadline);\n if (!destroyed) host.querySelector(\"canvas\")?.addEventListener(\"webglcontextlost\", onLost);\n camera.ready();\n },\n (error: unknown) => {\n clearTimeout(deadline);\n noDevice({}, error);\n },\n );\n store.report(live && graph.isSimulationRunning ? \"running\" : \"settled\");\n schedule();\n\n const unsubscribe = store.subscribe(() => {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n if (snapshot.geometry !== last.geometry) dirty.positions = true;\n if (snapshot.encoding !== last.encoding) dirty.paint = true;\n if (options.look !== lookPatch) {\n lookPatch = options.look;\n look = resolveLook(options.look);\n dirty.paint = true;\n }\n if (options.fill !== lastOptions.fill || options.symbol !== lastOptions.symbol || options.stroke !== lastOptions.stroke) {\n dirty.paint = true;\n }\n if (snapshot.selection !== last.selection || snapshot.focus !== last.focus || snapshot.mask !== last.mask) dirty.state = true;\n if (snapshot.pinned !== last.pinned) dirty.pinned = true;\n if (options.sim !== lastOptions.sim) applyForces(options.sim);\n const wants = simulating(options, snapshot.geometry);\n if (snapshot.geometry === last.geometry && wants !== simulating(lastOptions, last.geometry)) {\n endBurst();\n if (wants) run(REHEAT);\n else graph.pause();\n }\n last = snapshot;\n lastOptions = options;\n if (dirty.positions || dirty.paint || dirty.state || dirty.pinned) schedule();\n });\n\n return {\n graph,\n repaint() {\n dirty.paint = true;\n schedule();\n },\n hit(shape) {\n const found = \"rect\" in shape ? graph.findPointsInRect(shape.rect) : graph.findPointsInPolygon(shape.polygon);\n return Array.from(found);\n },\n zoomBy(factor) {\n graph.setZoomLevel(graph.getZoomLevel() * factor, 220);\n },\n fit: () => camera.fit(),\n pause() {\n endBurst();\n graph.pause();\n },\n resume() {\n endBurst();\n const settled = store.getSnapshot().motion === \"settled\";\n if (settled || !live) run(REHEAT);\n else graph.unpause();\n },\n restart() {\n endBurst();\n store.pin([]);\n run(1);\n },\n /**\n * d3's release: unfix, then reheat, so the released points visibly flow back. A running layout\n * takes the heat and goes on; a settled one cools to settled on its own; a paused one gets a\n * bounded burst and is paused again, because the reader paused it.\n */\n unpin() {\n const { motion, pinned } = store.getSnapshot();\n if (pinned.length === 0) return;\n endBurst();\n store.pin([]);\n run(REHEAT);\n if (motion === \"paused\") {\n burst = window.setTimeout(() => {\n burst = 0;\n graph.pause();\n }, RELEASE_BURST);\n }\n },\n reveal(vertex) {\n if (vertex >= size()) return;\n focusOn(vertex);\n graph.zoomToPointByIndex(vertex, 500, 5, true);\n },\n frameSelection() {\n const vertices = (store.getSnapshot().selection?.vertices ?? []).filter((id) => id < size());\n if (vertices.length > 0) graph.fitViewByPointIndices(vertices, FIT_DURATION, 0.25);\n },\n clear,\n destroy() {\n unsubscribe();\n endBurst();\n if (frame) cancelAnimationFrame(frame);\n clearTimeout(deadline);\n camera.destroy();\n destroyed = true;\n // Read here rather than remembered from construction: the element exists only with the device.\n const canvas = host.querySelector(\"canvas\");\n canvas?.removeEventListener(\"webglcontextlost\", onLost);\n graph.destroy();\n releaseContext(canvas);\n },\n };\n}\n"],"names":["REHEAT","RELEASE_BURST","PROGRESS_STEPS","READY_DEADLINE","createRenderer","host","store","events","destroyed","fail","error","box","webglBox","GraphError","sim","resolveSim","live","moving","hovering","dragging","burst","reported","progress","value","bucket","look","resolveLook","lookPatch","dirty","frame","links","last","lastOptions","size","_a","graph","Graph","forces","moved","camera","_alpha","index","position","_b","_event","userDriven","taken","event","vertex","motion","pinned","focusOn","clear","createCamera","schedule","draw","snapshot","geometry","encoding","options","placing","painting","buffers","paint","appearance","linksShown","highlighted","layout","simulating","placement","placementOf","decayFor","cornersOf","placed","running","run","LINKS_WHILE_RUNNING","showLinks","applyForces","patch","next","key","alpha","endBurst","around","onLost","noDevice","data","cause","deadline","unsubscribe","wants","shape","found","factor","vertices","id","FIT_DURATION","canvas","releaseContext"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanzo-tech/graph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Kanzo graph view — a fossil corpus attached to the page's DuckDB, read through the page's Mosaic coordinator as one more client, laid out and drawn with cosmos.gl on the GPU. Sibling of @kanzo-tech/ui, not part of it: the admission rules exclude graphs from the generic vocabulary by name.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"@cosmos.gl/graph": "^3.4.0",
|
|
29
29
|
"lucide-react": ">=1",
|
|
30
30
|
"react": "^19.0.0",
|
|
31
|
-
"@kanzo-tech/mosaic": "0.
|
|
32
|
-
"@kanzo-tech/ui": "0.
|
|
31
|
+
"@kanzo-tech/mosaic": "0.28.0",
|
|
32
|
+
"@kanzo-tech/ui": "0.28.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@cosmos.gl/graph": "^3.4.0",
|
|
@@ -39,21 +39,21 @@
|
|
|
39
39
|
"@testing-library/user-event": "^14.6.1",
|
|
40
40
|
"@types/react": "^19.0.0",
|
|
41
41
|
"@types/react-dom": "^19.0.0",
|
|
42
|
-
"@uwdata/mosaic-core": "^0.
|
|
43
|
-
"@uwdata/mosaic-sql": "^0.
|
|
42
|
+
"@uwdata/mosaic-core": "^0.32.0",
|
|
43
|
+
"@uwdata/mosaic-sql": "^0.32.0",
|
|
44
44
|
"jsdom": "^25.0.0",
|
|
45
45
|
"lucide-react": "^1.23.0",
|
|
46
46
|
"react": "^19.0.0",
|
|
47
47
|
"react-dom": "^19.0.0",
|
|
48
48
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
49
|
-
"@kanzo-tech/mosaic": "0.
|
|
49
|
+
"@kanzo-tech/mosaic": "0.28.0"
|
|
50
50
|
},
|
|
51
|
-
"//size-limit": "Budgets our code only: `ignore` mirrors the peers the build externalises in vite.config.ts, cosmos.gl included (about 190 kB gzipped on its own, and the consumer pays it once whatever this package does). First measured 2026-09-30 at 19.07 kB, before the lag work of `perf/phase1-lag`; 19.13 kB before the whole-corpus store deleted the tileset, 15.29 kB after it, and the budget follows it down so real growth trips the gate. Raised to 18 kB on 2026-10-01 as a decision: 17.71 kB after GraphCounts, GraphSearch and GraphLooks moved in from the workspace showcase (their code left the host, it did not appear from nowhere) and the drag-to-fix release. Raised to 18.5 kB on 2026-10-02 as a decision (Ángel): 18.01 kB once the layout's square placement and the camera that follows a running layout landed.",
|
|
51
|
+
"//size-limit": "Budgets our code only: `ignore` mirrors the peers the build externalises in vite.config.ts, cosmos.gl included (about 190 kB gzipped on its own, and the consumer pays it once whatever this package does). First measured 2026-09-30 at 19.07 kB, before the lag work of `perf/phase1-lag`; 19.13 kB before the whole-corpus store deleted the tileset, 15.29 kB after it, and the budget follows it down so real growth trips the gate. Raised to 18 kB on 2026-10-01 as a decision: 17.71 kB after GraphCounts, GraphSearch and GraphLooks moved in from the workspace showcase (their code left the host, it did not appear from nowhere) and the drag-to-fix release. Raised to 18.5 kB on 2026-10-02 as a decision (Ángel): 18.01 kB once the layout's square placement and the camera that follows a running layout landed. Raised to 19 kB on 2026-10-03 as a decision (Ángel): 18.58 kB once GraphSelect moved in from the hosts (which drop their copies) and the camera stopped reading positions cosmos.gl had not uploaded.",
|
|
52
52
|
"size-limit": [
|
|
53
53
|
{
|
|
54
54
|
"name": "root barrel (JS)",
|
|
55
55
|
"path": "dist/index.js",
|
|
56
|
-
"limit": "
|
|
56
|
+
"limit": "19 kB",
|
|
57
57
|
"ignore": [
|
|
58
58
|
"react",
|
|
59
59
|
"react-dom",
|