@kanzo-tech/graph 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -16
- package/dist/core/categories.d.ts +18 -6
- package/dist/core/categories.d.ts.map +1 -1
- package/dist/core/categories.js +41 -10
- package/dist/core/categories.js.map +1 -1
- package/dist/core/channels.d.ts +10 -5
- package/dist/core/channels.d.ts.map +1 -1
- package/dist/core/channels.js +11 -13
- package/dist/core/channels.js.map +1 -1
- package/dist/core/detail.d.ts +14 -8
- package/dist/core/detail.d.ts.map +1 -1
- package/dist/core/detail.js +33 -15
- package/dist/core/detail.js.map +1 -1
- package/dist/core/filter.d.ts +3 -1
- package/dist/core/filter.d.ts.map +1 -1
- package/dist/core/filter.js +54 -50
- package/dist/core/filter.js.map +1 -1
- package/dist/core/load.d.ts +58 -0
- package/dist/core/load.d.ts.map +1 -0
- package/dist/core/load.js +115 -0
- package/dist/core/load.js.map +1 -0
- package/dist/core/state.d.ts +27 -55
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts +1 -3
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +159 -174
- package/dist/core/store.js.map +1 -1
- package/dist/core/types.d.ts +21 -17
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -25
- package/dist/index.js.map +1 -1
- package/dist/parts/gesture.d.ts +1 -10
- package/dist/parts/gesture.d.ts.map +1 -1
- package/dist/parts/gesture.js +28 -28
- package/dist/parts/gesture.js.map +1 -1
- package/dist/parts/graph-canvas.d.ts.map +1 -1
- package/dist/parts/graph-canvas.js +119 -108
- package/dist/parts/graph-canvas.js.map +1 -1
- package/dist/parts/graph-inspector.d.ts +4 -4
- package/dist/parts/graph-inspector.d.ts.map +1 -1
- package/dist/parts/graph-inspector.js +55 -57
- package/dist/parts/graph-inspector.js.map +1 -1
- package/dist/parts/graph-legend.d.ts +4 -4
- package/dist/parts/graph-legend.d.ts.map +1 -1
- package/dist/parts/graph-legend.js +21 -21
- package/dist/parts/graph-legend.js.map +1 -1
- package/dist/parts/overlays.d.ts +2 -4
- package/dist/parts/overlays.d.ts.map +1 -1
- package/dist/parts/overlays.js +45 -45
- package/dist/parts/overlays.js.map +1 -1
- package/dist/react/use-graph-state.d.ts +4 -2
- package/dist/react/use-graph-state.d.ts.map +1 -1
- package/dist/react/use-graph-state.js +10 -6
- package/dist/react/use-graph-state.js.map +1 -1
- package/dist/react/use-graph.d.ts +1 -4
- package/dist/react/use-graph.d.ts.map +1 -1
- package/dist/react/use-graph.js +38 -49
- package/dist/react/use-graph.js.map +1 -1
- package/dist/render/graph-looks.d.ts.map +1 -1
- package/dist/render/graph-looks.js.map +1 -1
- package/dist/render/graph-model.d.ts +6 -8
- package/dist/render/graph-model.d.ts.map +1 -1
- package/dist/render/graph-model.js +51 -57
- package/dist/render/graph-model.js.map +1 -1
- package/dist/render/graph-sim.d.ts +2 -3
- package/dist/render/graph-sim.d.ts.map +1 -1
- package/dist/render/graph-sim.js.map +1 -1
- package/dist/render/renderer.d.ts +6 -11
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +120 -173
- package/dist/render/renderer.js.map +1 -1
- package/dist/section.d.ts.map +1 -1
- package/dist/section.js +3 -7
- package/dist/section.js.map +1 -1
- package/package.json +11 -11
- package/dist/core/refine.d.ts +0 -14
- package/dist/core/refine.d.ts.map +0 -1
- package/dist/core/refine.js +0 -20
- package/dist/core/refine.js.map +0 -1
- package/dist/core/resident.d.ts +0 -79
- package/dist/core/resident.d.ts.map +0 -1
- package/dist/core/resident.js +0 -44
- package/dist/core/resident.js.map +0 -1
- package/dist/core/scheduler.d.ts +0 -42
- package/dist/core/scheduler.d.ts.map +0 -1
- package/dist/core/scheduler.js +0 -77
- package/dist/core/scheduler.js.map +0 -1
- package/dist/core/tile-matrix.d.ts +0 -37
- package/dist/core/tile-matrix.d.ts.map +0 -1
- package/dist/core/tile-matrix.js +0 -49
- package/dist/core/tile-matrix.js.map +0 -1
- package/dist/core/tile.d.ts +0 -54
- package/dist/core/tile.d.ts.map +0 -1
- package/dist/core/tile.js +0 -76
- package/dist/core/tile.js.map +0 -1
- package/dist/core/tileset.d.ts +0 -59
- package/dist/core/tileset.d.ts.map +0 -1
- package/dist/core/tileset.js +0 -177
- package/dist/core/tileset.js.map +0 -1
- package/dist/render/adaptive.d.ts +0 -27
- package/dist/render/adaptive.d.ts.map +0 -1
- package/dist/render/adaptive.js +0 -25
- package/dist/render/adaptive.js.map +0 -1
- package/dist/render/compose.d.ts +0 -51
- package/dist/render/compose.d.ts.map +0 -1
- package/dist/render/compose.js +0 -107
- package/dist/render/compose.js.map +0 -1
- package/dist/render/encode.d.ts +0 -42
- package/dist/render/encode.d.ts.map +0 -1
- package/dist/render/encode.js +0 -68
- package/dist/render/encode.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,35 +1,29 @@
|
|
|
1
1
|
import { GraphRoot as e, GraphRootProvider as p, useGraphContext as t } from "./react/graph-root.js";
|
|
2
|
-
import { useGraph as
|
|
2
|
+
import { useGraph as m } from "./react/use-graph.js";
|
|
3
3
|
import { useGraphState as x } from "./react/use-graph-state.js";
|
|
4
4
|
import { useGraphPrefs as G } from "./react/use-graph-prefs.js";
|
|
5
|
-
import { GraphCanvas as
|
|
6
|
-
import { GraphLegend as
|
|
7
|
-
import { GraphToolbar as
|
|
8
|
-
import { GraphInspector as
|
|
9
|
-
import { ShapeGlyph as
|
|
10
|
-
import { lookFrom as
|
|
11
|
-
import { simFrom as
|
|
12
|
-
import {
|
|
13
|
-
import { scaleOf as g } from "./render/graph-model.js";
|
|
14
|
-
import { denseOf as L, typeOf as T, vertexId as j } from "./core/resident.js";
|
|
5
|
+
import { GraphCanvas as l } from "./parts/graph-canvas.js";
|
|
6
|
+
import { GraphLegend as u } from "./parts/graph-legend.js";
|
|
7
|
+
import { GraphToolbar as d } from "./parts/graph-toolbar.js";
|
|
8
|
+
import { GraphInspector as v } from "./parts/graph-inspector.js";
|
|
9
|
+
import { ShapeGlyph as F } from "./parts/shape-glyph.js";
|
|
10
|
+
import { lookFrom as R } from "./render/graph-looks.js";
|
|
11
|
+
import { simFrom as b } from "./render/graph-sim.js";
|
|
12
|
+
import { scaleOf as k } from "./render/graph-model.js";
|
|
15
13
|
export {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
l as GraphCanvas,
|
|
15
|
+
v as GraphInspector,
|
|
16
|
+
u as GraphLegend,
|
|
19
17
|
e as GraphRoot,
|
|
20
18
|
p as GraphRootProvider,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
P as simFrom,
|
|
28
|
-
T as typeOf,
|
|
29
|
-
f as useGraph,
|
|
19
|
+
d as GraphToolbar,
|
|
20
|
+
F as ShapeGlyph,
|
|
21
|
+
R as lookFrom,
|
|
22
|
+
k as scaleOf,
|
|
23
|
+
b as simFrom,
|
|
24
|
+
m as useGraph,
|
|
30
25
|
t as useGraphContext,
|
|
31
26
|
G as useGraphPrefs,
|
|
32
|
-
x as useGraphState
|
|
33
|
-
j as vertexId
|
|
27
|
+
x as useGraphState
|
|
34
28
|
};
|
|
35
29
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
|
package/dist/parts/gesture.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { Graph } from '@cosmos.gl/graph';
|
|
3
|
-
import {
|
|
4
|
-
import { Selection, SelectionSource, Tool } from '../core/types';
|
|
3
|
+
import { Selection, SelectionSource, Tool, VertexId } from '../core/types';
|
|
5
4
|
/**
|
|
6
5
|
* Drawing a selection on the canvas: the marquee, the lasso, and the keys that modify them.
|
|
7
6
|
*
|
|
@@ -41,14 +40,6 @@ export interface GraphSelectionGesture {
|
|
|
41
40
|
}
|
|
42
41
|
export interface GraphSelectionOptions {
|
|
43
42
|
getGraph: () => Graph | null;
|
|
44
|
-
/**
|
|
45
|
-
* Who is drawn right now — the only thing that can turn a hit-test index into an identity.
|
|
46
|
-
*
|
|
47
|
-
* A gesture selects positions on screen, and a position is a buffer index, which the next
|
|
48
|
-
* residency reuses for a different vertex. So the gesture resolves to identities here and now,
|
|
49
|
-
* while the answer that produced them is still the one on screen.
|
|
50
|
-
*/
|
|
51
|
-
getResident: () => Resident;
|
|
52
43
|
/** The live selection, for the modifiers to add to or subtract from. */
|
|
53
44
|
getSelection: () => Selection | null;
|
|
54
45
|
commit: (vertices: Set<VertexId> | null, source: SelectionSource, label: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gesture.d.ts","sourceRoot":"","sources":["../../src/parts/gesture.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"gesture.d.ts","sourceRoot":"","sources":["../../src/parts/gesture.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEhF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErC,wFAAwF;AACxF,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,KAAK,EAAE,CAAA;CAAE,CAAC;AAS/F,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,aAAa,CAIjE;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,oFAAoF;IACpF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,mFAAmF;IACnF,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE;QACR,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACnD,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACnD,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACjD,eAAe,EAAE,MAAM,IAAI,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC;IAC7B,wEAAwE;IACxE,YAAY,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzF,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/B;AAOD,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,qBAAqB,CAyIhF"}
|
package/dist/parts/gesture.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useState as m, useRef as
|
|
3
|
-
const x = 3,
|
|
4
|
-
function
|
|
2
|
+
import { useState as m, useRef as A, useCallback as g, useEffect as R } from "react";
|
|
3
|
+
const x = 3, I = 4, K = 60;
|
|
4
|
+
function z(l) {
|
|
5
5
|
if (!l) return { display: "none" };
|
|
6
6
|
const [i = 0, a = 0] = l.tool === "rect" ? l.to : l.path[l.path.length - 1] ?? [];
|
|
7
7
|
return { left: i + 14, top: a + 14 };
|
|
8
8
|
}
|
|
9
|
-
const
|
|
9
|
+
const _ = {
|
|
10
10
|
rect: { source: "marquee", label: "Marquee" },
|
|
11
11
|
lasso: { source: "lasso", label: "Lasso" }
|
|
12
12
|
};
|
|
13
|
-
function
|
|
14
|
-
const { commit: i, getGraph: a,
|
|
13
|
+
function D(l) {
|
|
14
|
+
const { commit: i, getGraph: a, getSelection: k, setTool: y, tool: h } = l, [s, c] = m(null), [v, f] = m(null), [L, p] = m(!1), b = A(0), w = g(
|
|
15
15
|
(t) => {
|
|
16
16
|
const e = a();
|
|
17
17
|
if (!e) return [];
|
|
@@ -27,19 +27,19 @@ function G(l) {
|
|
|
27
27
|
return t.path.length < 3 ? [] : Array.from(e.findPointsInPolygon(t.path));
|
|
28
28
|
},
|
|
29
29
|
[a]
|
|
30
|
-
), E =
|
|
30
|
+
), E = g(
|
|
31
31
|
(t) => {
|
|
32
32
|
const e = performance.now();
|
|
33
|
-
e - b.current <
|
|
33
|
+
e - b.current < K || (b.current = e, f(w(t).length));
|
|
34
34
|
},
|
|
35
|
-
[
|
|
35
|
+
[w]
|
|
36
36
|
);
|
|
37
|
-
|
|
37
|
+
R(() => {
|
|
38
38
|
const t = (n) => {
|
|
39
|
-
n.key === "Shift" &&
|
|
39
|
+
n.key === "Shift" && p(!0), n.key === "Escape" && (c((r) => (r || (h ? y(null) : i(null, "node", "")), null)), f(null));
|
|
40
40
|
}, e = (n) => {
|
|
41
|
-
n.key === "Shift" &&
|
|
42
|
-
}, o = () =>
|
|
41
|
+
n.key === "Shift" && p(!1);
|
|
42
|
+
}, o = () => p(!1);
|
|
43
43
|
return window.addEventListener("keydown", t), window.addEventListener("keyup", e), window.addEventListener("blur", o), () => {
|
|
44
44
|
window.removeEventListener("keydown", t), window.removeEventListener("keyup", e), window.removeEventListener("blur", o);
|
|
45
45
|
};
|
|
@@ -47,29 +47,29 @@ function G(l) {
|
|
|
47
47
|
const M = (t) => {
|
|
48
48
|
const e = t.currentTarget.getBoundingClientRect();
|
|
49
49
|
return [t.clientX - e.left, t.clientY - e.top];
|
|
50
|
-
},
|
|
51
|
-
var
|
|
50
|
+
}, T = (t, e) => {
|
|
51
|
+
var S;
|
|
52
52
|
if (c(null), f(null), !t) return;
|
|
53
|
-
const o = new Set(
|
|
53
|
+
const o = new Set(w(t));
|
|
54
54
|
if (o.size === 0 && !e.altKey) return;
|
|
55
|
-
const { label: n, source: r } =
|
|
55
|
+
const { label: n, source: r } = _[t.tool], u = ((S = k()) == null ? void 0 : S.vertices) ?? [];
|
|
56
56
|
if (e.altKey) {
|
|
57
|
-
const
|
|
58
|
-
for (const C of o)
|
|
59
|
-
i(
|
|
57
|
+
const d = new Set(u);
|
|
58
|
+
for (const C of o) d.delete(C);
|
|
59
|
+
i(d.size > 0 ? d : null, r, n);
|
|
60
60
|
} else e.metaKey || e.ctrlKey ? i(/* @__PURE__ */ new Set([...u, ...o]), r, n) : i(o, r, n);
|
|
61
|
-
},
|
|
61
|
+
}, P = h ?? (L ? "rect" : null);
|
|
62
62
|
return {
|
|
63
63
|
drag: s,
|
|
64
|
-
preview:
|
|
65
|
-
active:
|
|
64
|
+
preview: v,
|
|
65
|
+
active: P,
|
|
66
66
|
handlers: {
|
|
67
67
|
onPointerDown: (t) => {
|
|
68
68
|
if (t.button !== 0) return;
|
|
69
69
|
t.currentTarget.setPointerCapture(t.pointerId);
|
|
70
70
|
const e = M(t);
|
|
71
71
|
c(
|
|
72
|
-
|
|
72
|
+
P === "rect" ? { tool: "rect", from: e, to: e } : { tool: "lasso", path: [e] }
|
|
73
73
|
);
|
|
74
74
|
},
|
|
75
75
|
onPointerMove: (t) => {
|
|
@@ -81,11 +81,11 @@ function G(l) {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
const o = s.path[s.path.length - 1];
|
|
84
|
-
if (Math.hypot(e[0] - o[0], e[1] - o[1]) <
|
|
84
|
+
if (Math.hypot(e[0] - o[0], e[1] - o[1]) < I) return;
|
|
85
85
|
const n = { tool: "lasso", path: [...s.path, e] };
|
|
86
86
|
c(n), E(n);
|
|
87
87
|
},
|
|
88
|
-
onPointerUp: (t) =>
|
|
88
|
+
onPointerUp: (t) => T(s, t),
|
|
89
89
|
onPointerCancel: () => {
|
|
90
90
|
c(null), f(null);
|
|
91
91
|
}
|
|
@@ -93,7 +93,7 @@ function G(l) {
|
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
export {
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
z as cursorChip,
|
|
97
|
+
D as useGesture
|
|
98
98
|
};
|
|
99
99
|
//# sourceMappingURL=gesture.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gesture.js","sources":["../../src/parts/gesture.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type React from \"react\";\nimport type { Graph } from \"@cosmos.gl/graph\";\nimport type {
|
|
1
|
+
{"version":3,"file":"gesture.js","sources":["../../src/parts/gesture.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type React from \"react\";\nimport type { Graph } from \"@cosmos.gl/graph\";\nimport type { Selection, SelectionSource, Tool, VertexId } from \"../core/types\";\n\n/**\n * Drawing a selection on the canvas: the marquee, the lasso, and the keys that modify them.\n *\n * The whole gesture lives here — what is being drawn, how many nodes it currently holds, and what\n * happens when the pointer comes up. The component gets handlers to spread onto an overlay and the\n * state to draw it with; it does not need to know that Shift borrows the marquee or that a hit test\n * costs a GPU readback.\n *\n * Modifiers are read at *release*, not at press, because that is when the reader has decided:\n * `Alt` removes what was drawn from the selection, `⌘`/`Ctrl` adds it, and neither replaces.\n */\nexport type Point = [number, number];\n\n/** A selection gesture in flight. The two tools differ only in what they accumulate. */\nexport type Drag = { tool: \"rect\"; from: Point; to: Point } | { tool: \"lasso\"; path: Point[] };\n\n/** Below this the hit test would be answering about a click, not a box. */\nconst MIN_RECT = 3;\n/** A raw pointer stream makes a polygon of near-duplicate vertices; the hit test walks every one. */\nconst PATH_STEP = 4;\n/** Slower than the hand, faster than the eye — and one GPU readback per gesture frame is plenty. */\nconst MEASURE_MS = 60;\n\n/** The running count rides just off the cursor, at the edge the gesture is growing from. */\nexport function cursorChip(drag: Drag | null): React.CSSProperties {\n if (!drag) return { display: \"none\" };\n const [x = 0, y = 0] = drag.tool === \"rect\" ? drag.to : (drag.path[drag.path.length - 1] ?? []);\n return { left: x + 14, top: y + 14 };\n}\n\nexport interface GraphSelectionGesture {\n /** The gesture being drawn, for the overlay to render. */\n drag: Drag | null;\n /** How many nodes it holds right now, so the number lands before the mouse does. */\n preview: number | null;\n /** The tool actually in force: the chosen one, or the marquee Shift is lending. */\n active: Tool;\n handlers: {\n onPointerDown: (event: React.PointerEvent) => void;\n onPointerMove: (event: React.PointerEvent) => void;\n onPointerUp: (event: React.PointerEvent) => void;\n onPointerCancel: () => void;\n };\n}\n\nexport interface GraphSelectionOptions {\n getGraph: () => Graph | null;\n /** The live selection, for the modifiers to add to or subtract from. */\n getSelection: () => Selection | null;\n commit: (vertices: Set<VertexId> | null, source: SelectionSource, label: string) => void;\n tool: Tool;\n setTool: (tool: Tool) => void;\n}\n\nconst NAME: Record<\"rect\" | \"lasso\", { source: SelectionSource; label: string }> = {\n rect: { source: \"marquee\", label: \"Marquee\" },\n lasso: { source: \"lasso\", label: \"Lasso\" },\n};\n\nexport function useGesture(options: GraphSelectionOptions): GraphSelectionGesture {\n const { commit, getGraph, getSelection, setTool, tool } = options;\n const [drag, setDrag] = useState<Drag | null>(null);\n const [preview, setPreview] = useState<number | null>(null);\n const [shift, setShift] = useState(false);\n const measured = useRef(0);\n\n const hitTest = useCallback(\n (shape: Drag): number[] => {\n const graph = getGraph();\n if (!graph) return [];\n // Before its device cosmos.gl answers `[]` here: a gesture over a graph that has not drawn\n // selects nothing, which is what it looks like.\n if (shape.tool === \"rect\") {\n const [[ax, ay], [bx, by]] = [shape.from, shape.to];\n if (Math.abs(bx - ax) < MIN_RECT || Math.abs(by - ay) < MIN_RECT) return [];\n return Array.from(\n graph.findPointsInRect([\n [Math.min(ax, bx), Math.min(ay, by)],\n [Math.max(ax, bx), Math.max(ay, by)],\n ]),\n );\n }\n if (shape.path.length < 3) return [];\n return Array.from(graph.findPointsInPolygon(shape.path));\n },\n [getGraph],\n );\n\n // Both hit tests are a GPU pass followed by a synchronous `readPixels`, so running one per\n // pointer event would stall the frame the gesture is being drawn into.\n const measure = useCallback(\n (shape: Drag) => {\n const now = performance.now();\n if (now - measured.current < MEASURE_MS) return;\n measured.current = now;\n setPreview(hitTest(shape).length);\n },\n [hitTest],\n );\n\n // Escape is the way out of everything, in layers: it abandons a drag in progress, then drops the\n // tool, then clears what is held. And a window that loses focus never delivers the Shift keyup,\n // which would leave the canvas unable to pan.\n useEffect(() => {\n const down = (event: KeyboardEvent) => {\n if (event.key === \"Shift\") setShift(true);\n if (event.key !== \"Escape\") return;\n setDrag((current) => {\n if (current) return null;\n if (tool) setTool(null);\n else commit(null, \"node\", \"\");\n return null;\n });\n setPreview(null);\n };\n const up = (event: KeyboardEvent) => {\n if (event.key === \"Shift\") setShift(false);\n };\n const blur = () => setShift(false);\n window.addEventListener(\"keydown\", down);\n window.addEventListener(\"keyup\", up);\n window.addEventListener(\"blur\", blur);\n return () => {\n window.removeEventListener(\"keydown\", down);\n window.removeEventListener(\"keyup\", up);\n window.removeEventListener(\"blur\", blur);\n };\n }, [commit, setTool, tool]);\n\n /** Screen coordinates inside the canvas — the space every cosmos.gl hit test speaks. */\n const at = (event: React.PointerEvent): Point => {\n const box = event.currentTarget.getBoundingClientRect();\n return [event.clientX - box.left, event.clientY - box.top];\n };\n\n const finish = (shape: Drag | null, event: React.PointerEvent) => {\n setDrag(null);\n setPreview(null);\n if (!shape) return;\n // The hit test answers in buffer indices, and a drawn vertex's index is its id.\n const vertices = new Set<VertexId>(hitTest(shape));\n // A gesture that caught nothing and asked for nothing is a misfire, not a request to clear —\n // clearing is what the corner's own button and Escape are for.\n if (vertices.size === 0 && !event.altKey) return;\n const { label, source } = NAME[shape.tool];\n const held = getSelection()?.vertices ?? [];\n if (event.altKey) {\n const next = new Set(held);\n for (const vertex of vertices) next.delete(vertex);\n commit(next.size > 0 ? next : null, source, label);\n } else if (event.metaKey || event.ctrlKey) {\n commit(new Set([...held, ...vertices]), source, label);\n } else {\n commit(vertices, source, label);\n }\n };\n\n const active: Tool = tool ?? (shift ? \"rect\" : null);\n\n return {\n drag,\n preview,\n active,\n handlers: {\n onPointerDown: (event) => {\n if (event.button !== 0) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n const start = at(event);\n setDrag(\n active === \"rect\"\n ? { tool: \"rect\", from: start, to: start }\n : { tool: \"lasso\", path: [start] },\n );\n },\n onPointerMove: (event) => {\n if (!drag) return;\n const next = at(event);\n if (drag.tool === \"rect\") {\n const shape: Drag = { ...drag, to: next };\n setDrag(shape);\n measure(shape);\n return;\n }\n const last = drag.path[drag.path.length - 1] as Point;\n if (Math.hypot(next[0] - last[0], next[1] - last[1]) < PATH_STEP) return;\n const shape: Drag = { tool: \"lasso\", path: [...drag.path, next] };\n setDrag(shape);\n measure(shape);\n },\n onPointerUp: (event) => finish(drag, event),\n onPointerCancel: () => {\n setDrag(null);\n setPreview(null);\n },\n },\n };\n}\n"],"names":[],"mappings":";;AAwBA;AAOO;AACL;AACA;AACA;AACF;AA0BA;AAAmF;AAC/C;AAEpC;AAEO;AACL;AAMgB;AAEZ;AACA;AAGA;AACE;AACA;AACa;AACY;AACc;AACA;AACpC;AAAA;AAGL;AACuD;AACzD;AACS;AAKK;AAEZ;AACA;AAEgC;AAClC;AACQ;AAMV;AACE;AAEE;AAOe;AAGf;AAAyC;AAG3C;AAIE;AAEuC;AACzC;AAIF;AACE;AACA;AAAyD;;AAMzD;AAEA;AAGA;AACA;AAEA;AACE;AACA;AACA;AAAiD;AAInB;AAMlC;AAAO;AACL;AACA;AACA;AACU;AAEN;AACA;AACA;AACA;AAAA;AAGmC;AAAE;AAEvC;AAEE;AACA;AACA;AACE;AACA;AAEA;AAAA;AAEF;AACA;AACA;AACA;AACa;AACf;AAC0C;AAExC;AACe;AACjB;AAAA;AAGN;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-canvas.d.ts","sourceRoot":"","sources":["../../src/parts/graph-canvas.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-canvas.d.ts","sourceRoot":"","sources":["../../src/parts/graph-canvas.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAe1F,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACnE,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAkDD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BAgJnF"}
|
|
@@ -1,185 +1,196 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import { useThemeTick as
|
|
4
|
-
import { useMemo as
|
|
5
|
-
import { nameOf as
|
|
6
|
-
import {
|
|
7
|
-
import { useGraphContext as
|
|
8
|
-
import { internalsOf as
|
|
9
|
-
import { useGraphState as
|
|
10
|
-
import { resolveLook as
|
|
11
|
-
import { scaleOf as
|
|
12
|
-
import { useGesture as
|
|
13
|
-
import { useOverlays as
|
|
14
|
-
import { ShapeGlyph as
|
|
15
|
-
const
|
|
16
|
-
function
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
import { jsxs as b, jsx as a } from "react/jsx-runtime";
|
|
3
|
+
import { useThemeTick as Y, categoricalCapacity as Z, Show as g, cn as ee } from "@kanzo-tech/ui";
|
|
4
|
+
import { useMemo as x, useCallback as $, useRef as te, useEffect as y, useState as oe } from "react";
|
|
5
|
+
import { nameOf as ne } from "../core/categories.js";
|
|
6
|
+
import { readTitles as re } from "../core/detail.js";
|
|
7
|
+
import { useGraphContext as F } from "../react/graph-root.js";
|
|
8
|
+
import { internalsOf as ae } from "../react/use-graph.js";
|
|
9
|
+
import { useGraphState as m, useGraphSnapshot as S } from "../react/use-graph-state.js";
|
|
10
|
+
import { resolveLook as se } from "../render/graph-looks.js";
|
|
11
|
+
import { scaleOf as le } from "../render/graph-model.js";
|
|
12
|
+
import { useGesture as ie, cursorChip as ce } from "./gesture.js";
|
|
13
|
+
import { useOverlays as pe } from "./overlays.js";
|
|
14
|
+
import { ShapeGlyph as de } from "./shape-glyph.js";
|
|
15
|
+
const E = "color-mix(in oklab, var(--primary) 17%, transparent)";
|
|
16
|
+
function me(u, d, i, p, s) {
|
|
17
|
+
const c = d.sizes, n = [];
|
|
18
|
+
if (c && p > 0)
|
|
19
|
+
for (let t = 0; t < u.size; t++) {
|
|
20
|
+
const r = c[t];
|
|
21
|
+
if (i && !i[t] || Number.isNaN(r) || n.length === p && r <= c[n[p - 1]]) continue;
|
|
22
|
+
let o = n.length;
|
|
23
|
+
for (; o > 0 && c[n[o - 1]] < r; ) o--;
|
|
24
|
+
n.splice(o, 0, t), n.length > p && n.pop();
|
|
25
|
+
}
|
|
26
|
+
return s === null || n.includes(s) ? n : [s, ...n];
|
|
27
|
+
}
|
|
28
|
+
function D(u) {
|
|
29
|
+
const d = F(), i = m((r) => r.corpus), p = m((r) => r.options.title), s = S((r) => r.geometry), [c, n] = oe(() => /* @__PURE__ */ new Map()), t = u.join(",");
|
|
30
|
+
return y(() => {
|
|
31
|
+
if (!i || !s || t === "") return;
|
|
32
|
+
const r = new AbortController();
|
|
33
|
+
return re(i, s, t.split(",").map(Number), p, r.signal).then(
|
|
34
|
+
(o) => !r.signal.aborted && n(o),
|
|
35
|
+
(o) => !r.signal.aborted && d.getState().options.onFailure(o instanceof Error ? o.message : String(o))
|
|
36
|
+
), () => r.abort();
|
|
37
|
+
}, [d, i, s, t, p]), c;
|
|
26
38
|
}
|
|
27
|
-
const
|
|
39
|
+
const ue = {
|
|
28
40
|
opening: "Opening the corpus…",
|
|
29
|
-
|
|
41
|
+
loading: "Loading the graph…"
|
|
30
42
|
};
|
|
31
|
-
function
|
|
32
|
-
const
|
|
33
|
-
var
|
|
34
|
-
return ((
|
|
35
|
-
}),
|
|
43
|
+
function Me({ children: u, className: d, slot: i, ...p }) {
|
|
44
|
+
const s = F(), { attach: c, renderer: n } = ae(s), t = m((e) => e.focus), r = m((e) => e.tool), o = m((e) => e.options), k = m((e) => {
|
|
45
|
+
var h;
|
|
46
|
+
return ((h = e.drawn) == null ? void 0 : h.domain) ?? e.domain;
|
|
47
|
+
}), w = m((e) => e.drawn === null ? ue[e.status] : void 0), f = x(() => se(o.look), [o.look]), R = $(() => {
|
|
36
48
|
var e;
|
|
37
|
-
return ((e =
|
|
38
|
-
}, [
|
|
39
|
-
|
|
40
|
-
const e =
|
|
49
|
+
return ((e = n()) == null ? void 0 : e.graph) ?? null;
|
|
50
|
+
}, [n]), q = pe({ getGraph: R }), { cardRef: B, gridRef: J, hostRef: T, hoverAt: _, labelRef: K, schedule: v, setHovered: P, setLabelOrder: j, track: A } = q, I = te(null), G = S((e) => e.geometry), N = S((e) => e.encoding), W = S((e) => e.mask);
|
|
51
|
+
y(() => {
|
|
52
|
+
const e = I.current;
|
|
41
53
|
if (e)
|
|
42
|
-
return
|
|
43
|
-
}, [
|
|
44
|
-
const
|
|
45
|
-
|
|
54
|
+
return c(e, { onFrame: v, onHover: _ });
|
|
55
|
+
}, [c, _, v]);
|
|
56
|
+
const Q = Y();
|
|
57
|
+
y(() => {
|
|
46
58
|
var e;
|
|
47
|
-
(e =
|
|
48
|
-
}, [
|
|
49
|
-
const
|
|
50
|
-
() =>
|
|
51
|
-
[
|
|
59
|
+
(e = n()) == null || e.repaint();
|
|
60
|
+
}, [n, Q]);
|
|
61
|
+
const C = x(
|
|
62
|
+
() => G && N ? me(G, N, W, f.labels, t) : [],
|
|
63
|
+
[G, N, W, t, f.labels]
|
|
64
|
+
), M = D(C), z = x(
|
|
65
|
+
() => C.flatMap((e) => M.get(e) ? [{ vertex: e, text: M.get(e) }] : []),
|
|
66
|
+
[C, M]
|
|
52
67
|
);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}, [
|
|
56
|
-
const
|
|
57
|
-
getGraph:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return /* @__PURE__ */ y(
|
|
68
|
+
y(() => {
|
|
69
|
+
j(z.map((e) => e.vertex)), A(), v();
|
|
70
|
+
}, [z, v, j, A, f.grid]);
|
|
71
|
+
const H = ie({
|
|
72
|
+
getGraph: R,
|
|
73
|
+
getSelection: $(() => s.getState().selection, [s]),
|
|
74
|
+
commit: (e, h, X) => s.select(e ? [...e] : null, h, X),
|
|
75
|
+
setTool: s.setTool,
|
|
76
|
+
tool: r
|
|
77
|
+
}), { active: U, drag: l, preview: O } = H, L = T.current ? Z(T.current) : void 0, V = x(() => le(o, L), [o, L]);
|
|
78
|
+
return /* @__PURE__ */ b(
|
|
65
79
|
"div",
|
|
66
80
|
{
|
|
67
|
-
...
|
|
68
|
-
className:
|
|
69
|
-
"data-slot":
|
|
70
|
-
ref:
|
|
81
|
+
...p,
|
|
82
|
+
className: ee("relative isolate size-full overflow-hidden bg-background", d),
|
|
83
|
+
"data-slot": i ?? "graph-canvas",
|
|
84
|
+
ref: T,
|
|
71
85
|
children: [
|
|
72
|
-
/* @__PURE__ */
|
|
73
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ a("div", { className: "size-full", "data-slot": "graph-canvas-surface", ref: I }),
|
|
87
|
+
/* @__PURE__ */ a(g, { when: f.grid, children: /* @__PURE__ */ a(
|
|
74
88
|
"div",
|
|
75
89
|
{
|
|
76
90
|
className: "pointer-events-none absolute inset-0",
|
|
77
|
-
ref:
|
|
91
|
+
ref: J,
|
|
78
92
|
style: { backgroundImage: "radial-gradient(var(--border) 1px, transparent 1px)" }
|
|
79
93
|
}
|
|
80
94
|
) }),
|
|
81
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ a(g, { when: f.vignette, children: /* @__PURE__ */ a(
|
|
82
96
|
"div",
|
|
83
97
|
{
|
|
84
98
|
className: "pointer-events-none absolute inset-0",
|
|
85
99
|
style: { background: "radial-gradient(ellipse 75% 65% at 50% 45%, transparent 30%, var(--background) 100%)" }
|
|
86
100
|
}
|
|
87
101
|
) }),
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
|
|
102
|
+
/* @__PURE__ */ b("div", { className: "pointer-events-none absolute inset-0 overflow-hidden", children: [
|
|
103
|
+
z.map((e) => /* @__PURE__ */ a(
|
|
90
104
|
"span",
|
|
91
105
|
{
|
|
92
106
|
className: "absolute top-0 left-0 whitespace-nowrap font-medium text-[10px] text-foreground leading-none opacity-0 transition-opacity [text-shadow:0_0_3px_var(--background),0_0_6px_var(--background)]",
|
|
93
|
-
ref:
|
|
107
|
+
ref: K(e.vertex),
|
|
94
108
|
children: e.text
|
|
95
109
|
},
|
|
96
110
|
String(e.vertex)
|
|
97
111
|
)),
|
|
98
|
-
/* @__PURE__ */
|
|
99
|
-
|
|
112
|
+
/* @__PURE__ */ a(
|
|
113
|
+
he,
|
|
100
114
|
{
|
|
101
|
-
cardRef:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
options:
|
|
105
|
-
scale:
|
|
106
|
-
schedule:
|
|
107
|
-
setHovered:
|
|
115
|
+
cardRef: B,
|
|
116
|
+
domain: k,
|
|
117
|
+
encoding: N,
|
|
118
|
+
options: o,
|
|
119
|
+
scale: V,
|
|
120
|
+
schedule: v,
|
|
121
|
+
setHovered: P
|
|
108
122
|
}
|
|
109
123
|
)
|
|
110
124
|
] }),
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
-
|
|
125
|
+
/* @__PURE__ */ a(g, { when: U !== null, children: /* @__PURE__ */ b("div", { className: "absolute inset-0 cursor-crosshair", "data-slot": "graph-canvas-gesture", ...H.handlers, children: [
|
|
126
|
+
l && /* @__PURE__ */ a("svg", { className: "pointer-events-none size-full", children: l.tool === "rect" ? /* @__PURE__ */ a(
|
|
113
127
|
"rect",
|
|
114
128
|
{
|
|
115
129
|
className: "stroke-primary",
|
|
116
|
-
height: Math.abs(
|
|
130
|
+
height: Math.abs(l.to[1] - l.from[1]),
|
|
117
131
|
strokeDasharray: "4 3",
|
|
118
132
|
strokeWidth: 1,
|
|
119
|
-
style: { fill:
|
|
120
|
-
width: Math.abs(
|
|
121
|
-
x: Math.min(
|
|
122
|
-
y: Math.min(
|
|
133
|
+
style: { fill: E },
|
|
134
|
+
width: Math.abs(l.to[0] - l.from[0]),
|
|
135
|
+
x: Math.min(l.from[0], l.to[0]),
|
|
136
|
+
y: Math.min(l.from[1], l.to[1])
|
|
123
137
|
}
|
|
124
|
-
) :
|
|
138
|
+
) : l.path.length > 1 && /* @__PURE__ */ a(
|
|
125
139
|
"polygon",
|
|
126
140
|
{
|
|
127
141
|
className: "stroke-primary",
|
|
128
|
-
points:
|
|
142
|
+
points: l.path.map(([e, h]) => `${e},${h}`).join(" "),
|
|
129
143
|
strokeWidth: 1,
|
|
130
|
-
style: { fill:
|
|
144
|
+
style: { fill: E }
|
|
131
145
|
}
|
|
132
146
|
) }),
|
|
133
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ a(g, { when: O !== null, children: /* @__PURE__ */ b(
|
|
134
148
|
"span",
|
|
135
149
|
{
|
|
136
150
|
className: "pointer-events-none absolute rounded-sm bg-primary px-1.5 py-0.5 font-medium text-[10px] text-primary-foreground tabular-nums",
|
|
137
|
-
style:
|
|
151
|
+
style: ce(l),
|
|
138
152
|
children: [
|
|
139
|
-
|
|
153
|
+
O,
|
|
140
154
|
" node",
|
|
141
|
-
|
|
155
|
+
O === 1 ? "" : "s"
|
|
142
156
|
]
|
|
143
157
|
}
|
|
144
158
|
) })
|
|
145
159
|
] }) }),
|
|
146
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ a(g, { when: w !== void 0, children: /* @__PURE__ */ a(
|
|
147
161
|
"p",
|
|
148
162
|
{
|
|
149
163
|
className: "pointer-events-none absolute inset-0 grid place-items-center text-muted-foreground text-xs",
|
|
150
164
|
"data-slot": "graph-canvas-waiting",
|
|
151
|
-
children:
|
|
165
|
+
children: w
|
|
152
166
|
}
|
|
153
167
|
) }),
|
|
154
|
-
|
|
168
|
+
u
|
|
155
169
|
]
|
|
156
170
|
}
|
|
157
171
|
);
|
|
158
172
|
}
|
|
159
|
-
function
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (a === null || !s || i === void 0) return null;
|
|
167
|
-
const r = s.categories[i] ?? 0, x = (u.fill !== void 0 || u.symbol !== void 0) && r < m.length ? X(m[r], u.categories) : null;
|
|
168
|
-
return /* @__PURE__ */ y(
|
|
173
|
+
function he({ cardRef: u, domain: d, encoding: i, options: p, scale: s, schedule: c, setHovered: n }) {
|
|
174
|
+
const t = m((w) => w.hovered), r = D(x(() => t === null ? [] : [t], [t]));
|
|
175
|
+
if (y(() => {
|
|
176
|
+
n(t), c();
|
|
177
|
+
}, [t, c, n, r]), t === null || !i || t >= i.ranks.length) return null;
|
|
178
|
+
const o = i.ranks[t] ?? 0, k = o < d.length ? ne(d[o], p.categories) : null;
|
|
179
|
+
return /* @__PURE__ */ b(
|
|
169
180
|
"div",
|
|
170
181
|
{
|
|
171
182
|
className: "absolute top-0 left-0 flex w-max max-w-60 items-center gap-2 rounded-lg border bg-popover px-2.5 py-2 opacity-0 shadow-lg",
|
|
172
183
|
"data-slot": "graph-canvas-card",
|
|
173
|
-
ref:
|
|
184
|
+
ref: u,
|
|
174
185
|
children: [
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
/* @__PURE__ */
|
|
177
|
-
/* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ a(de, { className: "size-2.5 shrink-0", color: s.color(o), shape: s.shape(o) }),
|
|
187
|
+
/* @__PURE__ */ a("span", { className: "truncate font-medium text-popover-foreground text-sm leading-none", children: r.get(t) || `#${t}` }),
|
|
188
|
+
/* @__PURE__ */ a(g, { when: k !== null, children: /* @__PURE__ */ a("span", { className: "text-muted-foreground text-xs", children: k }) })
|
|
178
189
|
]
|
|
179
190
|
}
|
|
180
191
|
);
|
|
181
192
|
}
|
|
182
193
|
export {
|
|
183
|
-
|
|
194
|
+
Me as GraphCanvas
|
|
184
195
|
};
|
|
185
196
|
//# sourceMappingURL=graph-canvas.js.map
|