@kgdiff/g6 0.0.0-stage → 0.2.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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -2
  3. package/dist/color.d.ts +24 -0
  4. package/dist/color.d.ts.map +1 -0
  5. package/dist/color.js +95 -0
  6. package/dist/color.js.map +1 -0
  7. package/dist/constants.d.ts +81 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +81 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/controller.d.ts +126 -0
  12. package/dist/controller.d.ts.map +1 -0
  13. package/dist/controller.js +422 -0
  14. package/dist/controller.js.map +1 -0
  15. package/dist/geometry.d.ts +19 -0
  16. package/dist/geometry.d.ts.map +1 -0
  17. package/dist/geometry.js +43 -0
  18. package/dist/geometry.js.map +1 -0
  19. package/dist/index.d.ts +101 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +99 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/locator.d.ts +24 -0
  24. package/dist/locator.d.ts.map +1 -0
  25. package/dist/locator.js +69 -0
  26. package/dist/locator.js.map +1 -0
  27. package/dist/map-context.d.ts +70 -0
  28. package/dist/map-context.d.ts.map +1 -0
  29. package/dist/map-context.js +44 -0
  30. package/dist/map-context.js.map +1 -0
  31. package/dist/map-edge.d.ts +19 -0
  32. package/dist/map-edge.d.ts.map +1 -0
  33. package/dist/map-edge.js +399 -0
  34. package/dist/map-edge.js.map +1 -0
  35. package/dist/map-node.d.ts +10 -0
  36. package/dist/map-node.d.ts.map +1 -0
  37. package/dist/map-node.js +243 -0
  38. package/dist/map-node.js.map +1 -0
  39. package/dist/map.d.ts +47 -0
  40. package/dist/map.d.ts.map +1 -0
  41. package/dist/map.js +92 -0
  42. package/dist/map.js.map +1 -0
  43. package/dist/node.d.ts +68 -0
  44. package/dist/node.d.ts.map +1 -0
  45. package/dist/node.js +189 -0
  46. package/dist/node.js.map +1 -0
  47. package/dist/options.d.ts +33 -0
  48. package/dist/options.d.ts.map +1 -0
  49. package/dist/options.js +172 -0
  50. package/dist/options.js.map +1 -0
  51. package/dist/patch.d.ts +45 -0
  52. package/dist/patch.d.ts.map +1 -0
  53. package/dist/patch.js +120 -0
  54. package/dist/patch.js.map +1 -0
  55. package/dist/replay.d.ts +20 -0
  56. package/dist/replay.d.ts.map +1 -0
  57. package/dist/replay.js +36 -0
  58. package/dist/replay.js.map +1 -0
  59. package/package.json +54 -3
  60. package/src/color.ts +101 -0
  61. package/src/constants.ts +96 -0
  62. package/src/controller.ts +517 -0
  63. package/src/geometry.ts +44 -0
  64. package/src/index.ts +140 -0
  65. package/src/locator.ts +72 -0
  66. package/src/map-context.ts +119 -0
  67. package/src/map-edge.ts +481 -0
  68. package/src/map-node.ts +272 -0
  69. package/src/map.ts +130 -0
  70. package/src/node.ts +240 -0
  71. package/src/options.ts +215 -0
  72. package/src/patch.ts +133 -0
  73. package/src/replay.ts +59 -0
@@ -0,0 +1,422 @@
1
+ import { KgdiffError } from '@kgdiff/core';
2
+ import { createViewState, createVisualResolver, } from '@kgdiff/scene';
3
+ import { BACKGROUND_PLUGIN_KEY, DRAW_GRACE_MS, FOLLOW_VISIBLE_SHARE, MIN_STEP_MS, } from './constants.js';
4
+ import { crossesLod, kgdiffData, mapFrame } from './map.js';
5
+ import { generatedOptions, mergeG6Options } from './options.js';
6
+ import { diffData } from './patch.js';
7
+ import { planReplay } from './replay.js';
8
+ const EDITABLE_LAYERS = new Set(['union', 'before', 'after']);
9
+ function invalid(message) {
10
+ return new KgdiffError('invalid-input', message);
11
+ }
12
+ function targetId(event) {
13
+ const target = event.target;
14
+ return typeof target?.id === 'string' ? target.id : null;
15
+ }
16
+ function destroyedError() {
17
+ return invalid('This diff graph has been destroyed.');
18
+ }
19
+ class ReplayRun {
20
+ cancelled = false;
21
+ stopped;
22
+ release;
23
+ constructor() {
24
+ this.stopped = new Promise((resolve) => {
25
+ this.release = resolve;
26
+ });
27
+ }
28
+ cancel() {
29
+ this.cancelled = true;
30
+ this.release();
31
+ }
32
+ }
33
+ export class DiffGraphControllerImpl {
34
+ options;
35
+ deps;
36
+ graphRef = null;
37
+ scene;
38
+ resolver;
39
+ view;
40
+ frame;
41
+ data = new Map();
42
+ meta = new Map();
43
+ lod = [];
44
+ lodZoom = 1;
45
+ job = null;
46
+ queue = Promise.resolve();
47
+ replay = null;
48
+ destroyed = false;
49
+ dead;
50
+ kill;
51
+ handlers = [];
52
+ constructor(scene, options, deps) {
53
+ this.options = options;
54
+ this.deps = deps;
55
+ this.scene = scene;
56
+ this.resolver = createVisualResolver(scene);
57
+ this.view = createViewState(options.view ?? {});
58
+ this.dead = new Promise((resolve) => {
59
+ this.kill = resolve;
60
+ });
61
+ }
62
+ get graph() {
63
+ if (this.graphRef === null)
64
+ throw invalid('The G6 graph is not created yet.');
65
+ return this.graphRef;
66
+ }
67
+ /** Create, render and fit the graph. */
68
+ async start(container) {
69
+ const interactive = this.options.interactive !== false;
70
+ const initial = this.map(1);
71
+ const generated = generatedOptions({
72
+ container,
73
+ data: initial,
74
+ theme: () => this.scene.theme,
75
+ interactive,
76
+ hoverable: (event) => {
77
+ const id = targetId(event);
78
+ const d = id === null ? undefined : this.meta.get(id);
79
+ return d !== undefined && d.kgdiff !== 'collapsed' && d.kgdiff !== 'anchor';
80
+ },
81
+ });
82
+ const graph = this.deps.createGraph(mergeG6Options({ ...generated, animation: this.timing(false) }, this.options.g6));
83
+ this.graphRef = graph;
84
+ if (interactive) {
85
+ this.listen('node:click', (event) => this.onElementClick(event));
86
+ this.listen('edge:click', (event) => this.onElementClick(event));
87
+ this.listen('canvas:click', () => this.onCanvasClick());
88
+ }
89
+ await graph.render();
90
+ // Only now: G6 emits transforms while it sets up its viewport, before `getZoom` works.
91
+ this.listen('aftertransform', () => this.onTransform());
92
+ await graph.fitView(undefined, false);
93
+ }
94
+ // ─── Public API ───────────────────────────────────────────────────────────
95
+ setLayer(layer) {
96
+ if (!EDITABLE_LAYERS.has(layer)) {
97
+ return Promise.reject(invalid(`setLayer expects 'union', 'before' or 'after', got ${JSON.stringify(layer)}.`));
98
+ }
99
+ if (this.destroyed)
100
+ return Promise.reject(destroyedError());
101
+ this.stop();
102
+ this.view = createViewState({ ...this.view, layer });
103
+ return this.request(this.scene.theme.motion.base);
104
+ }
105
+ selectHunk(index) {
106
+ const H = this.scene.hunks.length;
107
+ if (!Number.isInteger(index) || index < -1 || index >= H) {
108
+ return Promise.reject(invalid(`Hunk index must be an integer in [-1, ${H - 1}], got ${String(index)}.`));
109
+ }
110
+ return this.select(index, -1);
111
+ }
112
+ async playReplay(options = {}) {
113
+ const speed = options.speed ?? 1;
114
+ if (!(typeof speed === 'number' && Number.isFinite(speed) && speed > 0)) {
115
+ throw invalid(`Replay speed must be a positive number, got ${String(speed)}.`);
116
+ }
117
+ this.assertAlive();
118
+ this.stop();
119
+ const run = new ReplayRun();
120
+ this.replay = run;
121
+ try {
122
+ await Promise.race([this.runReplay(run, speed), run.stopped, this.dead]);
123
+ }
124
+ finally {
125
+ if (this.replay === run)
126
+ this.replay = null;
127
+ }
128
+ }
129
+ /** Stop a running replay (its promise resolves at once); no-op otherwise. */
130
+ stop() {
131
+ const run = this.replay;
132
+ this.replay = null;
133
+ run?.cancel();
134
+ }
135
+ setTheme(theme) {
136
+ if (theme === null ||
137
+ typeof theme !== 'object' ||
138
+ typeof theme.canvas?.background !== 'string') {
139
+ return Promise.reject(invalid('setTheme expects a Theme (see getTheme in @kgdiff/scene).'));
140
+ }
141
+ return this.request(theme.motion.base, undefined, theme);
142
+ }
143
+ destroy() {
144
+ if (this.destroyed)
145
+ return;
146
+ this.stop();
147
+ this.destroyed = true;
148
+ this.kill();
149
+ const graph = this.graphRef;
150
+ if (graph === null)
151
+ return;
152
+ for (const [name, handler] of this.handlers)
153
+ graph.off(name, handler);
154
+ this.handlers.length = 0;
155
+ if (!graph.destroyed)
156
+ graph.destroy();
157
+ }
158
+ // ─── Internals ────────────────────────────────────────────────────────────
159
+ assertAlive() {
160
+ if (this.destroyed)
161
+ throw invalid('This diff graph has been destroyed.');
162
+ }
163
+ listen(name, handler) {
164
+ this.graph.on(name, handler);
165
+ this.handlers.push([name, handler]);
166
+ }
167
+ /**
168
+ * Run `task` after the queued ones. Rejects at once after `destroy()`; a task still queued or
169
+ * running when the graph is destroyed settles (resolves) instead of waiting on G6.
170
+ */
171
+ enqueue(task) {
172
+ if (this.destroyed)
173
+ return Promise.reject(destroyedError());
174
+ const run = this.queue.then(() => this.destroyed ? undefined : Promise.race([task(), this.dead]));
175
+ this.queue = run.catch(() => undefined);
176
+ return run;
177
+ }
178
+ /**
179
+ * Schedule one view update: resolve the current view, patch the graph, optionally switch the
180
+ * theme and pan. Requests made while an update is waiting in the queue join it (latest wins),
181
+ * so a burst of clicks costs one G6 draw.
182
+ */
183
+ request(duration, focus, theme) {
184
+ if (this.destroyed)
185
+ return Promise.reject(destroyedError());
186
+ let job = this.job;
187
+ if (job === null) {
188
+ const created = { duration, focus: undefined, theme: null, promise: Promise.resolve() };
189
+ created.promise = this.enqueue(() => this.runJob(created));
190
+ this.job = created;
191
+ job = created;
192
+ }
193
+ job.duration = duration;
194
+ if (focus !== undefined)
195
+ job.focus = focus;
196
+ if (theme !== undefined)
197
+ job.theme = theme;
198
+ return job.promise;
199
+ }
200
+ async runJob(job) {
201
+ if (this.job === job)
202
+ this.job = null;
203
+ if (job.theme !== null) {
204
+ this.scene = { ...this.scene, theme: job.theme };
205
+ this.resolver = createVisualResolver(this.scene);
206
+ this.frame = undefined;
207
+ this.graph.updatePlugin({
208
+ key: BACKGROUND_PLUGIN_KEY,
209
+ background: job.theme.canvas.background,
210
+ });
211
+ }
212
+ const camera = job.focus !== undefined && job.focus !== null
213
+ ? this.focus(job.focus, this.scene.theme.motion.slow)
214
+ : null;
215
+ await Promise.all([this.apply(this.timing(job.duration)), camera]);
216
+ }
217
+ /** Failures of fire-and-forget work (event handlers): surfaced, unless the graph is gone. */
218
+ report = (error) => {
219
+ if (this.destroyed)
220
+ return;
221
+ queueMicrotask(() => {
222
+ throw error;
223
+ });
224
+ };
225
+ /** G6's global animation option for one draw: false, or the theme easing over `duration`. */
226
+ timing(duration) {
227
+ if (duration === false || this.options.g6?.animation === false)
228
+ return false;
229
+ const [x1, y1, x2, y2] = this.scene.theme.motion.easing;
230
+ return { duration: Math.max(0, duration), easing: `cubic-bezier(${x1}, ${y1}, ${x2}, ${y2})` };
231
+ }
232
+ viewportTiming(duration) {
233
+ const t = this.timing(duration);
234
+ if (t === false || this.view.reducedMotion)
235
+ return false;
236
+ return { duration: t.duration ?? duration, easing: t.easing ?? 'ease' };
237
+ }
238
+ /** Resolve the current view and map it for `zoom`; records what was mapped. */
239
+ map(zoom) {
240
+ this.frame = this.resolver.resolve(this.view, this.frame);
241
+ const mapped = mapFrame(this.scene, this.frame, { idPrefix: '', keepHidden: false, zoom });
242
+ const all = [...mapped.data.nodes, ...mapped.data.edges];
243
+ this.data = new Map();
244
+ this.meta = new Map();
245
+ for (const datum of all) {
246
+ if (datum.id === undefined)
247
+ continue;
248
+ this.data.set(datum.id, datum);
249
+ const d = kgdiffData(datum.data);
250
+ if (d !== null)
251
+ this.meta.set(datum.id, d);
252
+ }
253
+ this.lod = mapped.lod;
254
+ this.lodZoom = zoom;
255
+ return mapped.data;
256
+ }
257
+ /** Map the current view and hand G6 only the difference to what it shows. */
258
+ async apply(animation) {
259
+ if (this.destroyed)
260
+ return;
261
+ const graph = this.graph;
262
+ const prev = this.data;
263
+ const next = this.map(graph.getZoom());
264
+ const patch = diffData(prev, next);
265
+ if (patch.size === 0)
266
+ return;
267
+ graph.setOptions({ animation });
268
+ // G6's own order: add, update (edges may move to added nodes), then remove.
269
+ if (patch.add.nodes.length + patch.add.edges.length > 0)
270
+ graph.addData(patch.add);
271
+ if (patch.update.nodes.length + patch.update.edges.length > 0)
272
+ graph.updateData(patch.update);
273
+ if (patch.remove.nodes.length + patch.remove.edges.length > 0)
274
+ graph.removeData(patch.remove);
275
+ if (patch.readd.nodes.length + patch.readd.edges.length > 0)
276
+ graph.addData(patch.readd);
277
+ const duration = animation === false ? 0 : (animation.duration ?? 0);
278
+ await Promise.race([graph.draw(), this.dead, this.deps.deadline(duration + DRAW_GRACE_MS)]);
279
+ }
280
+ select(hunk, node) {
281
+ if (this.destroyed)
282
+ return Promise.reject(destroyedError());
283
+ this.stop();
284
+ let view = { ...this.view, selectedHunk: hunk, selectedNode: node };
285
+ if (this.view.layer === 'replay' && hunk >= 0) {
286
+ // In the replay layer a selection seeks to the end of the hunk's window.
287
+ const w = this.scene.timeline.windows.find((x) => x.hunk === hunk);
288
+ if (w !== undefined)
289
+ view = { ...view, t: w.end };
290
+ }
291
+ this.view = createViewState(view);
292
+ return this.request(this.scene.theme.motion.base, hunk >= 0 ? [hunk] : null);
293
+ }
294
+ /** Ids of the hunks' nodes that are currently drawn. */
295
+ hunkNodeIds(hunks) {
296
+ const ids = [];
297
+ for (const h of hunks) {
298
+ const hunk = this.scene.hunks[h];
299
+ if (hunk === undefined)
300
+ continue;
301
+ for (const i of hunk.nodes) {
302
+ const id = this.scene.nodes[i]?.id;
303
+ if (id !== undefined && this.meta.get(id)?.kgdiff === 'node')
304
+ ids.push(id);
305
+ }
306
+ }
307
+ return ids;
308
+ }
309
+ /**
310
+ * Pan to the hunks' nodes. Called before the next patch, so G6 measures elements that still
311
+ * exist; resolves when the camera has arrived — or when the graph is destroyed, since G6 then
312
+ * cancels the camera animation without ever settling its promise.
313
+ */
314
+ focus(hunks, duration) {
315
+ const ids = this.hunkNodeIds(hunks);
316
+ if (ids.length === 0)
317
+ return null;
318
+ const moving = this.graph.focusElement(ids, this.viewportTiming(duration)).catch(this.report);
319
+ return Promise.race([moving, this.dead]);
320
+ }
321
+ /** Share of the hunks' bounds inside the viewport, in [0, 1]. */
322
+ visibleShare(hunks) {
323
+ let x0 = Number.POSITIVE_INFINITY;
324
+ let y0 = Number.POSITIVE_INFINITY;
325
+ let x1 = Number.NEGATIVE_INFINITY;
326
+ let y1 = Number.NEGATIVE_INFINITY;
327
+ for (const h of hunks) {
328
+ const b = this.scene.hunks[h]?.bounds;
329
+ if (b === undefined)
330
+ continue;
331
+ x0 = Math.min(x0, b.x);
332
+ y0 = Math.min(y0, b.y);
333
+ x1 = Math.max(x1, b.x + b.width);
334
+ y1 = Math.max(y1, b.y + b.height);
335
+ }
336
+ const area = (x1 - x0) * (y1 - y0);
337
+ if (!(area > 0))
338
+ return 1;
339
+ const graph = this.graph;
340
+ const [w, h] = graph.getSize();
341
+ const a = graph.getCanvasByViewport([0, 0]);
342
+ const b = graph.getCanvasByViewport([w, h]);
343
+ const vx0 = Math.min(a[0], b[0]);
344
+ const vx1 = Math.max(a[0], b[0]);
345
+ const vy0 = Math.min(a[1], b[1]);
346
+ const vy1 = Math.max(a[1], b[1]);
347
+ const ix = Math.max(0, Math.min(x1, vx1) - Math.max(x0, vx0));
348
+ const iy = Math.max(0, Math.min(y1, vy1) - Math.max(y0, vy0));
349
+ return (ix * iy) / area;
350
+ }
351
+ async runReplay(run, speed) {
352
+ const steps = planReplay(this.scene.timeline);
353
+ const base = this.scene.theme.motion.base;
354
+ // Morph from whatever is shown into the before state at t = 0.
355
+ await this.enqueue(async () => {
356
+ if (run.cancelled)
357
+ return;
358
+ this.view = createViewState({
359
+ ...this.view,
360
+ layer: 'replay',
361
+ t: 0,
362
+ selectedHunk: -1,
363
+ selectedNode: -1,
364
+ });
365
+ await this.apply(this.timing(base));
366
+ });
367
+ let pending = 0;
368
+ let focus = null;
369
+ for (let k = 0; k < steps.length; k++) {
370
+ if (run.cancelled)
371
+ return;
372
+ const step = steps[k];
373
+ pending += step.dt / speed;
374
+ focus = step.focus ?? focus;
375
+ // Steps too short to see are folded into the next one.
376
+ if (pending < MIN_STEP_MS && k < steps.length - 1)
377
+ continue;
378
+ const duration = pending;
379
+ const hunks = focus;
380
+ pending = 0;
381
+ focus = null;
382
+ await this.enqueue(async () => {
383
+ if (run.cancelled)
384
+ return;
385
+ const camera = hunks !== null && this.visibleShare(hunks) < FOLLOW_VISIBLE_SHARE
386
+ ? this.focus(hunks, Math.min(Math.max(duration, 350), 1100))
387
+ : null;
388
+ this.view = createViewState({ ...this.view, t: step.t });
389
+ await Promise.all([
390
+ this.apply(this.timing(duration)),
391
+ Promise.race([this.deps.wait(duration), this.dead]),
392
+ camera,
393
+ ]);
394
+ });
395
+ }
396
+ }
397
+ onTransform() {
398
+ // A queued update and a running replay both re-map at the current zoom anyway.
399
+ if (this.destroyed || this.graphRef === null || this.job !== null || this.replay !== null) {
400
+ return;
401
+ }
402
+ if (!crossesLod(this.lod, this.lodZoom, this.graph.getZoom()))
403
+ return;
404
+ this.request(false).catch(this.report);
405
+ }
406
+ onElementClick(event) {
407
+ const id = targetId(event);
408
+ const d = id === null ? undefined : this.meta.get(id);
409
+ if (d === undefined || d.kgdiff === 'collapsed' || d.kgdiff === 'anchor')
410
+ return;
411
+ if (d.hunk >= 0)
412
+ this.select(d.hunk, -1).catch(this.report);
413
+ else if (d.kgdiff === 'node')
414
+ this.select(-1, d.index).catch(this.report);
415
+ }
416
+ onCanvasClick() {
417
+ if (this.view.selectedHunk < 0 && this.view.selectedNode < 0)
418
+ return;
419
+ this.select(-1, -1).catch(this.report);
420
+ }
421
+ }
422
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** Small numeric helpers for the mapping (pure, allocation-light). */
2
+ /** `v` clamped to [0, 1]; NaN → 0. */
3
+ export declare function unit(v: number): number;
4
+ /** `v` when finite, else `fallback`. */
5
+ export declare function finite(v: number, fallback: number): number;
6
+ /** zIndex inside a band: the scene's `z` clamped to [0, span) and added to `base`. */
7
+ export declare function band(base: number, z: number, span: number): number;
8
+ /**
9
+ * `dash` scaled so a whole number of periods tiles a circle of radius `r` (no seam where the
10
+ * outline closes), exactly like the native renderer's ghost outlines.
11
+ */
12
+ export declare function evenCircleDash(dash: readonly number[], r: number): number[];
13
+ /**
14
+ * Approximate length of the quadratic link between two points `len` apart with curvature `c`
15
+ * (scene curve convention: the control point sits `|c|·len` off the chord midpoint). Uses the
16
+ * mean of the chord and the control polygon, within a few percent for |c| ≤ 0.5.
17
+ */
18
+ export declare function linkLength(len: number, c: number): number;
19
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,sCAAsC;AACtC,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AAED,wCAAwC;AACxC,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,sFAAsF;AACtF,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMzD"}
@@ -0,0 +1,43 @@
1
+ /** Small numeric helpers for the mapping (pure, allocation-light). */
2
+ /** `v` clamped to [0, 1]; NaN → 0. */
3
+ export function unit(v) {
4
+ return v > 0 ? Math.min(v, 1) : 0;
5
+ }
6
+ /** `v` when finite, else `fallback`. */
7
+ export function finite(v, fallback) {
8
+ return Number.isFinite(v) ? v : fallback;
9
+ }
10
+ /** zIndex inside a band: the scene's `z` clamped to [0, span) and added to `base`. */
11
+ export function band(base, z, span) {
12
+ const k = Number.isFinite(z) ? Math.round(z) : 0;
13
+ return base + Math.min(span - 1, Math.max(0, k));
14
+ }
15
+ /**
16
+ * `dash` scaled so a whole number of periods tiles a circle of radius `r` (no seam where the
17
+ * outline closes), exactly like the native renderer's ghost outlines.
18
+ */
19
+ export function evenCircleDash(dash, r) {
20
+ let period = 0;
21
+ for (const d of dash)
22
+ period += d;
23
+ if (dash.length % 2 === 1)
24
+ period *= 2;
25
+ const circumference = 2 * Math.PI * r;
26
+ const count = Math.max(1, Math.round(circumference / period));
27
+ const s = period > 0 ? circumference / (count * period) : 1;
28
+ return dash.map((d) => d * s);
29
+ }
30
+ /**
31
+ * Approximate length of the quadratic link between two points `len` apart with curvature `c`
32
+ * (scene curve convention: the control point sits `|c|·len` off the chord midpoint). Uses the
33
+ * mean of the chord and the control polygon, within a few percent for |c| ≤ 0.5.
34
+ */
35
+ export function linkLength(len, c) {
36
+ if (c === 0)
37
+ return len;
38
+ const half = len / 2;
39
+ const off = Math.abs(c) * len;
40
+ const polygon = 2 * Math.sqrt(half * half + off * off);
41
+ return (len + polygon) / 2;
42
+ }
43
+ //# sourceMappingURL=geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,sCAAsC;AACtC,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,QAAgB;IAChD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3C,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,CAAS,EAAE,IAAY;IACxD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAuB,EAAE,CAAS;IAC/D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,MAAM,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,CAAS;IAC/C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxB,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC9B,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @kgdiff/g6: render kgdiff scenes with AntV G6 v5.
3
+ *
4
+ * For teams whose product already uses G6: the same visual language as the
5
+ * kgdiff viewer (docs/visual-language.md), driven by the same `VisualResolver`,
6
+ * expressed as G6 data, styles and animations.
7
+ *
8
+ * map.ts frame → GraphData (pure)
9
+ * node.ts `kgdiff-node`: circle + ring, glow / offset-ring halo, pulse, struck old name
10
+ * options.ts generated G6 options (no G6 theme, hover states, animations)
11
+ * controller.ts view state → frames → setData / draw; replay; LOD; interaction
12
+ * replay.ts replay sampling plan
13
+ */
14
+ import { Graph, type GraphData } from '@antv/g6';
15
+ import type { FrameVisuals, Layer, Scene, Theme, ViewState } from '@kgdiff/scene';
16
+ export type { KgdiffDatumData } from './map.js';
17
+ export interface ToG6DataOptions {
18
+ /** Prefix for generated G6 element ids (default ''). */
19
+ readonly idPrefix?: string;
20
+ /** Include invisible elements with `visibility: 'hidden'` instead of omitting them. Default false. */
21
+ readonly keepHidden?: boolean;
22
+ }
23
+ /**
24
+ * Convert a resolved frame into G6 v5 `GraphData`: one node per scene node, one edge per
25
+ * scene edge (+ glyph edges for merge/move arcs), with positions and fully resolved styles.
26
+ * Pure; no G6 runtime needed.
27
+ *
28
+ * - Ids: `idPrefix + union id` for scene nodes and edges; glyphs
29
+ * `idPrefix + 'kgdiff-glyph-' + kind + ':' + JSON([source key, target key])` (keys are union
30
+ * ids, or anchor keys; stable across frames, so G6 animates them); anchors
31
+ * `idPrefix + 'kgdiff-anchor-' + JSON(key)`; collapsed pills
32
+ * `idPrefix + 'kgdiff-collapsed-' + group id`. A collision gets a `#2`, `#3`… suffix.
33
+ * - `datum.data` is a `KgdiffDatumData`: kind, scene index, hunk, family (flat primitives).
34
+ * - Edges are `line` or `quadratic` (`curveOffset` from the scene curvature) between the
35
+ * frame's endpoint nodes. Glyph arcs become extra edges between the visible nodes whose discs
36
+ * hold their endpoints; an end with no drawn node there (a split target before it emerges)
37
+ * attaches to an anchor: an invisible, non-interactive point node (`data.kgdiff: 'anchor'`),
38
+ * shared by the arcs of a frame. Arcs with both ends on one node are omitted. Pivot dots become
39
+ * small non-interactive nodes on their node's outline.
40
+ * - Sizes the scene gives in px are world units here (exact at zoom 1). Level of detail is
41
+ * evaluated at zoom 1: labels / badges / arrowheads whose `minZoom` is above 1 are switched
42
+ * off (`createDiffGraph` re-evaluates it at the live zoom).
43
+ * - Ring, glow, pulse and the struck old name use extra style keys drawn by the `kgdiff-node`
44
+ * type that `createDiffGraph` registers; on G6's plain `circle` they are ignored and the halo
45
+ * falls back to G6's built-in band.
46
+ *
47
+ * Deterministic; O(N + E + glyphs). Does not mutate its inputs.
48
+ *
49
+ * @throws KgdiffError(`invalid-input`) when `frame` was not resolved for `scene`.
50
+ */
51
+ export declare function toG6Data(scene: Scene, frame: FrameVisuals, options?: ToG6DataOptions): GraphData;
52
+ export interface CreateDiffGraphOptions {
53
+ /** Initial view state. */
54
+ readonly view?: Partial<ViewState>;
55
+ /** Extra G6 options merged into the generated ones (behaviors, plugins…). */
56
+ readonly g6?: Record<string, unknown>;
57
+ /** Default true: zoom-canvas, drag-canvas, hover highlight, click to select a hunk. */
58
+ readonly interactive?: boolean;
59
+ }
60
+ export interface DiffGraphController {
61
+ readonly graph: Graph;
62
+ setLayer(layer: Exclude<Layer, 'replay'>): Promise<void>;
63
+ /** Select a hunk by index (-1 clears) and focus it. */
64
+ selectHunk(index: number): Promise<void>;
65
+ /** Play the replay hunk by hunk with G6 animations; resolves when finished or stopped. */
66
+ playReplay(options?: {
67
+ readonly speed?: number;
68
+ }): Promise<void>;
69
+ stop(): void;
70
+ setTheme(theme: Theme): Promise<void>;
71
+ destroy(): void;
72
+ }
73
+ /**
74
+ * Create a G6 graph in `container` that renders `scene`.
75
+ *
76
+ * The graph uses no G6 theme (`theme: false`): kgdiff's own encodings, a background plugin in
77
+ * `theme.canvas.background`, the `kgdiff-node` node type and a private hover state. Each view
78
+ * change resolves one frame and sends G6 only the difference to the previous one (`addData`,
79
+ * `updateData` with just the changed style keys, `removeData`) before `graph.draw()`; G6
80
+ * animates it over `theme.motion.base` (layers, selection, themes) or the timeline (replay).
81
+ * Calls made while a draw is still running are merged into one update (latest wins). Elements
82
+ * the caller adds to `graph` are left alone; do not `setData` / `clear` the graph yourself.
83
+ *
84
+ * - `options.g6` is merged over the generated options: `behaviors` / `plugins` / `transforms`
85
+ * are appended, plain objects merge recursively, other values replace. `animation: false`
86
+ * disables every animation (replay still keeps its pace).
87
+ * - Interaction (`interactive`, default true): zoom-canvas, drag-canvas, hover (stroke + label
88
+ * like the native viewer), click a changed element → select its hunk, click an unchanged node
89
+ * → select it, click the canvas → clear.
90
+ * - Level of detail follows the camera: crossing a label / badge / arrow threshold re-maps.
91
+ * - `selectHunk(i)` spotlights the hunk and pans to its nodes; in the replay layer it seeks to the
92
+ * end of the hunk's window. `playReplay({ speed })` (default 1×) resolves every window (every
93
+ * chapter in chapter mode) at the end of its spotlight, mid-transform, settle start and end,
94
+ * and lets G6 animate between them; the camera pans to units less than 70% in view. It
95
+ * resolves when finished or `stop()`ped; `setLayer` / `selectHunk` stop it.
96
+ *
97
+ * @throws KgdiffError(`invalid-input`) for invalid arguments (also from the controller's methods,
98
+ * which reject at once after `destroy()`; calls still pending at `destroy()` resolve).
99
+ */
100
+ export declare function createDiffGraph(container: HTMLElement | string, scene: Scene, options?: CreateDiffGraphOptions): Promise<DiffGraphController>;
101
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAKlF,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sGAAsG;IACtG,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,eAAoB,GAC5B,SAAS,CAMX;AAED,MAAM,WAAW,sBAAsB;IACrC,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,uFAAuF;IACvF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,uDAAuD;IACvD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,0FAA0F;IAC1F,UAAU,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,IAAI,CAAC;CACjB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,WAAW,GAAG,MAAM,EAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAc9B"}