@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.
Files changed (113) hide show
  1. package/README.md +20 -16
  2. package/dist/core/categories.d.ts +18 -6
  3. package/dist/core/categories.d.ts.map +1 -1
  4. package/dist/core/categories.js +41 -10
  5. package/dist/core/categories.js.map +1 -1
  6. package/dist/core/channels.d.ts +10 -5
  7. package/dist/core/channels.d.ts.map +1 -1
  8. package/dist/core/channels.js +11 -13
  9. package/dist/core/channels.js.map +1 -1
  10. package/dist/core/detail.d.ts +14 -8
  11. package/dist/core/detail.d.ts.map +1 -1
  12. package/dist/core/detail.js +33 -15
  13. package/dist/core/detail.js.map +1 -1
  14. package/dist/core/filter.d.ts +3 -1
  15. package/dist/core/filter.d.ts.map +1 -1
  16. package/dist/core/filter.js +54 -50
  17. package/dist/core/filter.js.map +1 -1
  18. package/dist/core/load.d.ts +58 -0
  19. package/dist/core/load.d.ts.map +1 -0
  20. package/dist/core/load.js +115 -0
  21. package/dist/core/load.js.map +1 -0
  22. package/dist/core/state.d.ts +27 -55
  23. package/dist/core/state.d.ts.map +1 -1
  24. package/dist/core/store.d.ts +1 -3
  25. package/dist/core/store.d.ts.map +1 -1
  26. package/dist/core/store.js +159 -174
  27. package/dist/core/store.js.map +1 -1
  28. package/dist/core/types.d.ts +21 -17
  29. package/dist/core/types.d.ts.map +1 -1
  30. package/dist/index.d.ts +5 -7
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +19 -25
  33. package/dist/index.js.map +1 -1
  34. package/dist/parts/gesture.d.ts +1 -10
  35. package/dist/parts/gesture.d.ts.map +1 -1
  36. package/dist/parts/gesture.js +28 -28
  37. package/dist/parts/gesture.js.map +1 -1
  38. package/dist/parts/graph-canvas.d.ts.map +1 -1
  39. package/dist/parts/graph-canvas.js +119 -108
  40. package/dist/parts/graph-canvas.js.map +1 -1
  41. package/dist/parts/graph-inspector.d.ts +4 -4
  42. package/dist/parts/graph-inspector.d.ts.map +1 -1
  43. package/dist/parts/graph-inspector.js +55 -57
  44. package/dist/parts/graph-inspector.js.map +1 -1
  45. package/dist/parts/graph-legend.d.ts +4 -4
  46. package/dist/parts/graph-legend.d.ts.map +1 -1
  47. package/dist/parts/graph-legend.js +21 -21
  48. package/dist/parts/graph-legend.js.map +1 -1
  49. package/dist/parts/overlays.d.ts +2 -4
  50. package/dist/parts/overlays.d.ts.map +1 -1
  51. package/dist/parts/overlays.js +45 -45
  52. package/dist/parts/overlays.js.map +1 -1
  53. package/dist/react/use-graph-state.d.ts +4 -2
  54. package/dist/react/use-graph-state.d.ts.map +1 -1
  55. package/dist/react/use-graph-state.js +10 -6
  56. package/dist/react/use-graph-state.js.map +1 -1
  57. package/dist/react/use-graph.d.ts +1 -4
  58. package/dist/react/use-graph.d.ts.map +1 -1
  59. package/dist/react/use-graph.js +38 -49
  60. package/dist/react/use-graph.js.map +1 -1
  61. package/dist/render/graph-looks.d.ts.map +1 -1
  62. package/dist/render/graph-looks.js.map +1 -1
  63. package/dist/render/graph-model.d.ts +6 -8
  64. package/dist/render/graph-model.d.ts.map +1 -1
  65. package/dist/render/graph-model.js +51 -57
  66. package/dist/render/graph-model.js.map +1 -1
  67. package/dist/render/graph-sim.d.ts +2 -3
  68. package/dist/render/graph-sim.d.ts.map +1 -1
  69. package/dist/render/graph-sim.js.map +1 -1
  70. package/dist/render/renderer.d.ts +6 -11
  71. package/dist/render/renderer.d.ts.map +1 -1
  72. package/dist/render/renderer.js +120 -173
  73. package/dist/render/renderer.js.map +1 -1
  74. package/dist/section.d.ts.map +1 -1
  75. package/dist/section.js +3 -7
  76. package/dist/section.js.map +1 -1
  77. package/package.json +11 -11
  78. package/dist/core/refine.d.ts +0 -14
  79. package/dist/core/refine.d.ts.map +0 -1
  80. package/dist/core/refine.js +0 -20
  81. package/dist/core/refine.js.map +0 -1
  82. package/dist/core/resident.d.ts +0 -79
  83. package/dist/core/resident.d.ts.map +0 -1
  84. package/dist/core/resident.js +0 -44
  85. package/dist/core/resident.js.map +0 -1
  86. package/dist/core/scheduler.d.ts +0 -42
  87. package/dist/core/scheduler.d.ts.map +0 -1
  88. package/dist/core/scheduler.js +0 -77
  89. package/dist/core/scheduler.js.map +0 -1
  90. package/dist/core/tile-matrix.d.ts +0 -37
  91. package/dist/core/tile-matrix.d.ts.map +0 -1
  92. package/dist/core/tile-matrix.js +0 -49
  93. package/dist/core/tile-matrix.js.map +0 -1
  94. package/dist/core/tile.d.ts +0 -54
  95. package/dist/core/tile.d.ts.map +0 -1
  96. package/dist/core/tile.js +0 -76
  97. package/dist/core/tile.js.map +0 -1
  98. package/dist/core/tileset.d.ts +0 -59
  99. package/dist/core/tileset.d.ts.map +0 -1
  100. package/dist/core/tileset.js +0 -177
  101. package/dist/core/tileset.js.map +0 -1
  102. package/dist/render/adaptive.d.ts +0 -27
  103. package/dist/render/adaptive.d.ts.map +0 -1
  104. package/dist/render/adaptive.js +0 -25
  105. package/dist/render/adaptive.js.map +0 -1
  106. package/dist/render/compose.d.ts +0 -51
  107. package/dist/render/compose.d.ts.map +0 -1
  108. package/dist/render/compose.js +0 -107
  109. package/dist/render/compose.js.map +0 -1
  110. package/dist/render/encode.d.ts +0 -42
  111. package/dist/render/encode.d.ts.map +0 -1
  112. package/dist/render/encode.js +0 -68
  113. 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 f } from "./react/use-graph.js";
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 d } from "./parts/graph-canvas.js";
6
- import { GraphLegend as l } from "./parts/graph-legend.js";
7
- import { GraphToolbar as v } from "./parts/graph-toolbar.js";
8
- import { GraphInspector as O } from "./parts/graph-inspector.js";
9
- import { ShapeGlyph as y } from "./parts/shape-glyph.js";
10
- import { lookFrom as F } from "./render/graph-looks.js";
11
- import { simFrom as P } from "./render/graph-sim.js";
12
- import { adaptive as S } from "./render/adaptive.js";
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
- d as GraphCanvas,
17
- O as GraphInspector,
18
- l as GraphLegend,
14
+ l as GraphCanvas,
15
+ v as GraphInspector,
16
+ u as GraphLegend,
19
17
  e as GraphRoot,
20
18
  p as GraphRootProvider,
21
- v as GraphToolbar,
22
- y as ShapeGlyph,
23
- S as adaptive,
24
- L as denseOf,
25
- F as lookFrom,
26
- g as scaleOf,
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":";;;;;;;;;;;;"}
@@ -1,7 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Graph } from '@cosmos.gl/graph';
3
- import { Resident, VertexId } from '../core/resident';
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,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEtE;;;;;;;;;;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;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,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,CA0IhF"}
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"}
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { useState as m, useRef as R, useCallback as S, useEffect as I } from "react";
3
- const x = 3, K = 4, _ = 60;
4
- function D(l) {
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 q = {
9
+ const _ = {
10
10
  rect: { source: "marquee", label: "Marquee" },
11
11
  lasso: { source: "lasso", label: "Lasso" }
12
12
  };
13
- function G(l) {
14
- const { commit: i, getGraph: a, getResident: k, getSelection: v, setTool: y, tool: h } = l, [s, c] = m(null), [L, f] = m(null), [T, d] = m(!1), b = R(0), p = S(
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 = S(
30
+ ), E = g(
31
31
  (t) => {
32
32
  const e = performance.now();
33
- e - b.current < _ || (b.current = e, f(p(t).length));
33
+ e - b.current < K || (b.current = e, f(w(t).length));
34
34
  },
35
- [p]
35
+ [w]
36
36
  );
37
- I(() => {
37
+ R(() => {
38
38
  const t = (n) => {
39
- n.key === "Shift" && d(!0), n.key === "Escape" && (c((r) => (r || (h ? y(null) : i(null, "node", "")), null)), f(null));
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" && d(!1);
42
- }, o = () => d(!1);
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
- }, A = (t, e) => {
51
- var P;
50
+ }, T = (t, e) => {
51
+ var S;
52
52
  if (c(null), f(null), !t) return;
53
- const o = new Set(k().verticesAt(p(t)));
53
+ const o = new Set(w(t));
54
54
  if (o.size === 0 && !e.altKey) return;
55
- const { label: n, source: r } = q[t.tool], u = ((P = v()) == null ? void 0 : P.vertices) ?? [];
55
+ const { label: n, source: r } = _[t.tool], u = ((S = k()) == null ? void 0 : S.vertices) ?? [];
56
56
  if (e.altKey) {
57
- const w = new Set(u);
58
- for (const C of o) w.delete(C);
59
- i(w.size > 0 ? w : null, r, n);
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
- }, g = h ?? (T ? "rect" : null);
61
+ }, P = h ?? (L ? "rect" : null);
62
62
  return {
63
63
  drag: s,
64
- preview: L,
65
- active: g,
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
- g === "rect" ? { tool: "rect", from: e, to: e } : { tool: "lasso", path: [e] }
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]) < K) return;
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) => A(s, 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
- D as cursorChip,
97
- G as useGesture
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 { Resident, VertexId } from \"../core/resident\";\nimport type { Selection, SelectionSource, Tool } 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 /**\n * Who is drawn right now — the only thing that can turn a hit-test index into an identity.\n *\n * A gesture selects positions on screen, and a position is a buffer index, which the next\n * residency reuses for a different vertex. So the gesture resolves to identities here and now,\n * while the answer that produced them is still the one on screen.\n */\n getResident: () => Resident;\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, getResident, 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 one line the whole gesture turns on: the hit test answers in buffer indices, and they stop\n // meaning anything the moment the resident set changes.\n const vertices = new Set(getResident().verticesAt(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":";;AAyBA;AAOO;AACL;AACA;AACA;AACF;AAkCA;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;AAGA;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
+ {"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;AAc1F,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACnE,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA+BD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BA0InF"}
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 y, jsx as t } from "react/jsx-runtime";
3
- import { useThemeTick as K, categoricalCapacity as P, Show as h, cn as Q } from "@kanzo-tech/ui";
4
- import { useMemo as S, useCallback as W, useRef as U, useState as V, useEffect as N } from "react";
5
- import { nameOf as X } from "../core/categories.js";
6
- import { denseOf as Y } from "../core/resident.js";
7
- import { useGraphContext as Z } from "../react/graph-root.js";
8
- import { internalsOf as ee } from "../react/use-graph.js";
9
- import { useGraphState as g } from "../react/use-graph-state.js";
10
- import { resolveLook as te } from "../render/graph-looks.js";
11
- import { scaleOf as re } from "../render/graph-model.js";
12
- import { useGesture as ne, cursorChip as ae } from "./gesture.js";
13
- import { useOverlays as oe } from "./overlays.js";
14
- import { ShapeGlyph as se } from "./shape-glyph.js";
15
- const j = "var(--brand-a5)";
16
- function le(c, s, m) {
17
- const u = c.titles;
18
- if (!u || s <= 0) return [];
19
- const n = Array.from({ length: c.vertices }, (i, r) => r), d = c.sizes;
20
- d && n.sort((i, r) => (d[r] ?? 0) - (d[i] ?? 0));
21
- const l = n.slice(0, s), a = m === null ? void 0 : c.resident.indexOf(m);
22
- return a !== void 0 && !l.includes(a) && l.unshift(a), l.flatMap((i) => {
23
- const r = c.resident.at(i), v = u[i];
24
- return r === void 0 || !v ? [] : [{ vertex: r, text: v }];
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 ie = {
39
+ const ue = {
28
40
  opening: "Opening the corpus…",
29
- reading: "Reading the corpus…"
41
+ loading: "Loading the graph…"
30
42
  };
31
- function Ne({ children: c, className: s, slot: m, ...u }) {
32
- const n = Z(), { attach: d, renderer: l } = ee(n), a = g((e) => e.focus), i = g((e) => e.tool), r = g((e) => e.options), v = g((e) => {
33
- var f;
34
- return ((f = e.drawn) == null ? void 0 : f.domain) ?? e.domain;
35
- }), x = g((e) => e.drawn === null ? ie[e.status] : void 0), p = S(() => te(r.look), [r.look]), k = W(() => {
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 = l()) == null ? void 0 : e.graph) ?? null;
38
- }, [l]), H = oe({ getGraph: k, getResident: n.getResident }), { cardRef: I, gridRef: $, hostRef: R, hoverAt: G, labelRef: L, schedule: b, setHovered: D, setLabelOrder: _, track: M } = H, T = U(null), [w, E] = V(null);
39
- N(() => {
40
- const e = T.current;
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 d(e, { onFrame: b, onComposed: E, onHover: G });
43
- }, [d, G, b]);
44
- const F = K();
45
- N(() => {
54
+ return c(e, { onFrame: v, onHover: _ });
55
+ }, [c, _, v]);
56
+ const Q = Y();
57
+ y(() => {
46
58
  var e;
47
- (e = l()) == null || e.repaint();
48
- }, [l, F]);
49
- const O = S(
50
- () => w ? le(w, p.labels, a) : [],
51
- [w, a, p.labels]
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
- N(() => {
54
- _(O.map((e) => e.vertex)), M(), b();
55
- }, [O, b, _, M, p.grid]);
56
- const z = ne({
57
- getGraph: k,
58
- getResident: n.getResident,
59
- getSelection: W(() => n.getState().selection, [n]),
60
- commit: (e, f, J) => n.select(e ? [...e] : null, f, J),
61
- setTool: n.setTool,
62
- tool: i
63
- }), { active: q, drag: o, preview: C } = z, A = R.current ? P(R.current) : void 0, B = S(() => re(r, A), [r, A]);
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
- ...u,
68
- className: Q("relative isolate size-full overflow-hidden bg-background", s),
69
- "data-slot": m ?? "graph-canvas",
70
- ref: R,
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__ */ t("div", { className: "size-full", "data-slot": "graph-canvas-surface", ref: T }),
73
- /* @__PURE__ */ t(h, { when: p.grid, children: /* @__PURE__ */ t(
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__ */ t(h, { when: p.vignette, children: /* @__PURE__ */ t(
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__ */ y("div", { className: "pointer-events-none absolute inset-0 overflow-hidden", children: [
89
- O.map((e) => /* @__PURE__ */ t(
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: L(e.vertex),
107
+ ref: K(e.vertex),
94
108
  children: e.text
95
109
  },
96
110
  String(e.vertex)
97
111
  )),
98
- /* @__PURE__ */ t(
99
- ce,
112
+ /* @__PURE__ */ a(
113
+ he,
100
114
  {
101
- cardRef: I,
102
- composition: w,
103
- domain: v,
104
- options: r,
105
- scale: B,
106
- schedule: b,
107
- setHovered: D
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__ */ t(h, { when: q !== null, children: /* @__PURE__ */ y("div", { className: "absolute inset-0 cursor-crosshair", "data-slot": "graph-canvas-gesture", ...z.handlers, children: [
112
- o && /* @__PURE__ */ t("svg", { className: "pointer-events-none size-full", children: o.tool === "rect" ? /* @__PURE__ */ t(
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(o.to[1] - o.from[1]),
130
+ height: Math.abs(l.to[1] - l.from[1]),
117
131
  strokeDasharray: "4 3",
118
132
  strokeWidth: 1,
119
- style: { fill: j },
120
- width: Math.abs(o.to[0] - o.from[0]),
121
- x: Math.min(o.from[0], o.to[0]),
122
- y: Math.min(o.from[1], o.to[1])
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
- ) : o.path.length > 1 && /* @__PURE__ */ t(
138
+ ) : l.path.length > 1 && /* @__PURE__ */ a(
125
139
  "polygon",
126
140
  {
127
141
  className: "stroke-primary",
128
- points: o.path.map(([e, f]) => `${e},${f}`).join(" "),
142
+ points: l.path.map(([e, h]) => `${e},${h}`).join(" "),
129
143
  strokeWidth: 1,
130
- style: { fill: j }
144
+ style: { fill: E }
131
145
  }
132
146
  ) }),
133
- /* @__PURE__ */ t(h, { when: C !== null, children: /* @__PURE__ */ y(
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: ae(o),
151
+ style: ce(l),
138
152
  children: [
139
- C,
153
+ O,
140
154
  " node",
141
- C === 1 ? "" : "s"
155
+ O === 1 ? "" : "s"
142
156
  ]
143
157
  }
144
158
  ) })
145
159
  ] }) }),
146
- /* @__PURE__ */ t(h, { when: x !== void 0, children: /* @__PURE__ */ t(
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: x
165
+ children: w
152
166
  }
153
167
  ) }),
154
- c
168
+ u
155
169
  ]
156
170
  }
157
171
  );
158
172
  }
159
- function ce({ cardRef: c, composition: s, domain: m, options: u, scale: n, schedule: d, setHovered: l }) {
160
- var p;
161
- const a = g((k) => k.hovered);
162
- N(() => {
163
- l(a), d();
164
- }, [a, d, l]);
165
- const i = a === null || s == null ? void 0 : s.resident.indexOf(a);
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: c,
184
+ ref: u,
174
185
  children: [
175
- /* @__PURE__ */ t(se, { className: "size-2.5 shrink-0", color: n.color(r), shape: n.shape(r) }),
176
- /* @__PURE__ */ t("span", { className: "truncate font-medium text-popover-foreground text-sm leading-none", children: ((p = s.titles) == null ? void 0 : p[i]) || `#${Y(a)}` }),
177
- /* @__PURE__ */ t(h, { when: x !== null, children: /* @__PURE__ */ t("span", { className: "text-muted-foreground text-xs", children: x }) })
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
- Ne as GraphCanvas
194
+ Me as GraphCanvas
184
195
  };
185
196
  //# sourceMappingURL=graph-canvas.js.map