@krainovsd/graph 0.7.0 → 0.8.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/lib/cjs/index.cjs +962 -178
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/index.js +3 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/lib/draw-time.js +25 -0
- package/lib/esm/lib/draw-time.js.map +1 -0
- package/lib/esm/lib/get-controls-info.js +541 -0
- package/lib/esm/lib/get-controls-info.js.map +1 -0
- package/lib/esm/module/GraphCanvas/GraphCanvas.js +235 -80
- package/lib/esm/module/GraphCanvas/GraphCanvas.js.map +1 -1
- package/lib/esm/module/GraphCanvas/constants/settings.js +26 -7
- package/lib/esm/module/GraphCanvas/constants/settings.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js +7 -4
- package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js +6 -5
- package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js +12 -0
- package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js +2 -2
- package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js +24 -0
- package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js +14 -0
- package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js.map +1 -1
- package/lib/index.d.ts +72 -3
- package/package.json +4 -2
|
@@ -19,11 +19,16 @@ import { nodeByPointerGetter } from './lib/utils/node-by-pointer-getter.js';
|
|
|
19
19
|
import { nodeIterationExtractor } from './lib/utils/node-iteration-extractor.js';
|
|
20
20
|
import { drawText } from './lib/utils/draw-text.js';
|
|
21
21
|
import { calculateLinkPositionByRadius } from './lib/utils/calculate-link-position-by-radius.js';
|
|
22
|
+
import { animationByProgress } from './lib/utils/animation-by-progress.js';
|
|
23
|
+
import { isNodeVisible } from './lib/utils/is-node-visible.js';
|
|
24
|
+
import { getParticlePosition } from './lib/utils/get-particle-position.js';
|
|
25
|
+
import { getDrawTime, setDrawTime } from '../../lib/draw-time.js';
|
|
22
26
|
|
|
23
27
|
class GraphCanvas {
|
|
24
28
|
/** initial data */
|
|
25
29
|
nodes;
|
|
26
30
|
links;
|
|
31
|
+
particles = {};
|
|
27
32
|
width;
|
|
28
33
|
height;
|
|
29
34
|
root;
|
|
@@ -43,6 +48,8 @@ class GraphCanvas {
|
|
|
43
48
|
draw;
|
|
44
49
|
eventAbortController;
|
|
45
50
|
cachedNodeText = {};
|
|
51
|
+
linkOptionsCache = {};
|
|
52
|
+
nodeOptionsCache = {};
|
|
46
53
|
isDragging = false;
|
|
47
54
|
highlightedNode = null;
|
|
48
55
|
highlightedNeighbors = null;
|
|
@@ -115,20 +122,35 @@ class GraphCanvas {
|
|
|
115
122
|
this.updateData(alpha);
|
|
116
123
|
}
|
|
117
124
|
changeSettings(options) {
|
|
118
|
-
if (options.graphSettings)
|
|
125
|
+
if (options.graphSettings) {
|
|
119
126
|
this.graphSettings = graphSettingsGetter(options.graphSettings, this.graphSettings);
|
|
120
|
-
|
|
127
|
+
this.draw = this.initDraw();
|
|
128
|
+
this.initZoom(this.areaTransform);
|
|
129
|
+
}
|
|
130
|
+
if (options.forceSettings) {
|
|
121
131
|
this.forceSettings = forceSettingsGetter(options.forceSettings, this.forceSettings);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.
|
|
126
|
-
|
|
132
|
+
}
|
|
133
|
+
if (options.linkSettings) {
|
|
134
|
+
this.linkSettings = linkSettingsGetter(options.linkSettings, this.linkSettings);
|
|
135
|
+
this.linkOptionsCache = {};
|
|
136
|
+
}
|
|
137
|
+
if (options.nodeSettings) {
|
|
138
|
+
this.nodeSettings = nodeSettingsGetter(options.nodeSettings, this.nodeSettings);
|
|
139
|
+
this.cachedNodeText = {};
|
|
140
|
+
this.nodeOptionsCache = {};
|
|
141
|
+
}
|
|
142
|
+
if (options.forceSettings) {
|
|
127
143
|
return void this.updateSimulation();
|
|
144
|
+
}
|
|
128
145
|
this.tick();
|
|
129
146
|
}
|
|
147
|
+
clearCache() {
|
|
148
|
+
this.nodeOptionsCache = {};
|
|
149
|
+
this.linkOptionsCache = {};
|
|
150
|
+
this.cachedNodeText = {};
|
|
151
|
+
}
|
|
130
152
|
tick() {
|
|
131
|
-
if (!this.simulationWorking)
|
|
153
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
132
154
|
this.draw();
|
|
133
155
|
}
|
|
134
156
|
restart(alpha) {
|
|
@@ -184,6 +206,8 @@ class GraphCanvas {
|
|
|
184
206
|
}
|
|
185
207
|
clearDataDependencies() {
|
|
186
208
|
this.cachedNodeText = {};
|
|
209
|
+
this.nodeOptionsCache = {};
|
|
210
|
+
this.linkOptionsCache = {};
|
|
187
211
|
}
|
|
188
212
|
updateData(alpha) {
|
|
189
213
|
this.clearDataDependencies();
|
|
@@ -207,7 +231,7 @@ class GraphCanvas {
|
|
|
207
231
|
this.initZoom();
|
|
208
232
|
this.initResize();
|
|
209
233
|
this.initPointer();
|
|
210
|
-
if (!this.simulationWorking)
|
|
234
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
211
235
|
this.draw();
|
|
212
236
|
}
|
|
213
237
|
init() {
|
|
@@ -228,6 +252,8 @@ class GraphCanvas {
|
|
|
228
252
|
})
|
|
229
253
|
.on("end", () => {
|
|
230
254
|
this.listeners.onSimulationEnd?.(this.state);
|
|
255
|
+
if (this.graphSettings.showDrawTime)
|
|
256
|
+
getDrawTime();
|
|
231
257
|
});
|
|
232
258
|
this.initSimulationForces();
|
|
233
259
|
}
|
|
@@ -250,9 +276,9 @@ class GraphCanvas {
|
|
|
250
276
|
.distanceMax(this.forceSettings.chargeDistanceMax)
|
|
251
277
|
.distanceMin(this.forceSettings.chargeDistanceMin))
|
|
252
278
|
.force("center", forceCenter(this.forceSettings.centerPosition.x ?? 0, this.forceSettings.centerPosition.y ?? 0).strength(this.forceSettings.centerStrength));
|
|
253
|
-
this.initCollideForce();
|
|
279
|
+
this.initCollideForce(true);
|
|
254
280
|
}
|
|
255
|
-
initCollideForce() {
|
|
281
|
+
initCollideForce(forceUpdate) {
|
|
256
282
|
if (!this.simulation)
|
|
257
283
|
return;
|
|
258
284
|
if (!this.forceSettings.collideOn) {
|
|
@@ -263,9 +289,10 @@ class GraphCanvas {
|
|
|
263
289
|
const isHasMax = this.forceSettings.collideOffMax.links != 0 && this.forceSettings.collideOffMax.nodes != 0;
|
|
264
290
|
const isMaxCollideNodes = isHasMax && this.forceSettings.collideOffMax.nodes < this.nodes.length;
|
|
265
291
|
const isMaxCollideLinks = isHasMax && this.forceSettings.collideOffMax.links < this.links.length;
|
|
266
|
-
if (isMaxCollideNodes && isMaxCollideLinks)
|
|
292
|
+
if (isMaxCollideNodes && isMaxCollideLinks) {
|
|
267
293
|
this.simulation.force("collide", null);
|
|
268
|
-
|
|
294
|
+
}
|
|
295
|
+
else if (!this.simulation.force("collide") || forceUpdate) {
|
|
269
296
|
this.simulation.force("collide", forceCollide()
|
|
270
297
|
.radius((node, index) => {
|
|
271
298
|
if (this.forceSettings.collideRadius) {
|
|
@@ -283,6 +310,7 @@ class GraphCanvas {
|
|
|
283
310
|
})
|
|
284
311
|
.strength(this.forceSettings.collideStrength)
|
|
285
312
|
.iterations(this.forceSettings.collideIterations));
|
|
313
|
+
}
|
|
286
314
|
}
|
|
287
315
|
initArea() {
|
|
288
316
|
if (!this.area || !this.context || !this.container) {
|
|
@@ -317,19 +345,27 @@ class GraphCanvas {
|
|
|
317
345
|
this.highlightProgress -= this.graphSettings.highlightDownStep;
|
|
318
346
|
if (!this.simulationWorking)
|
|
319
347
|
return void requestAnimationFrame(() => this.draw());
|
|
320
|
-
|
|
348
|
+
if (!this.linkSettings.particles)
|
|
349
|
+
return;
|
|
321
350
|
}
|
|
322
351
|
if (this.highlightWorking && this.highlightProgress < 1) {
|
|
323
352
|
this.highlightProgress += this.graphSettings.highlightUpStep;
|
|
324
353
|
if (!this.simulationWorking)
|
|
325
354
|
return void requestAnimationFrame(() => this.draw());
|
|
326
|
-
|
|
355
|
+
if (!this.linkSettings.particles)
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (this.linkSettings.particles && this.highlightWorking && !this.simulationWorking) {
|
|
359
|
+
return void requestAnimationFrame(() => this.draw());
|
|
327
360
|
}
|
|
328
361
|
if (!this.highlightWorking && this.highlightProgress <= 0) {
|
|
329
|
-
if (this.highlightedNeighbors)
|
|
362
|
+
if (this.highlightedNeighbors || this.highlightedNode) {
|
|
330
363
|
this.highlightedNeighbors = null;
|
|
331
|
-
if (this.highlightedNode)
|
|
332
364
|
this.highlightedNode = null;
|
|
365
|
+
this.particles = {};
|
|
366
|
+
if (!this.simulationWorking)
|
|
367
|
+
return void requestAnimationFrame(() => this.draw());
|
|
368
|
+
}
|
|
333
369
|
}
|
|
334
370
|
this.highlightDrawing = false;
|
|
335
371
|
}
|
|
@@ -352,13 +388,13 @@ class GraphCanvas {
|
|
|
352
388
|
this.context.clearRect(0, 0, this.width, this.height);
|
|
353
389
|
this.context.translate(this.areaTransform.x, this.areaTransform.y);
|
|
354
390
|
this.context.scale(this.areaTransform.k, this.areaTransform.k);
|
|
391
|
+
const textRenders = [];
|
|
392
|
+
const nodeRenders = [];
|
|
393
|
+
this.nodes.forEach(getDrawNode(nodeRenders, textRenders, state).bind(this));
|
|
355
394
|
/** links */
|
|
356
|
-
this.context.beginPath();
|
|
357
395
|
this.links.forEach(getDrawLink(state).bind(this));
|
|
358
|
-
this.context.stroke();
|
|
359
396
|
/** nodes */
|
|
360
|
-
|
|
361
|
-
this.nodes.forEach(getDrawNode(textRenders, state).bind(this));
|
|
397
|
+
nodeRenders.forEach((render) => render());
|
|
362
398
|
textRenders.forEach((render) => render());
|
|
363
399
|
this.context.restore();
|
|
364
400
|
this.listeners.onDrawFinished?.(state);
|
|
@@ -374,54 +410,155 @@ class GraphCanvas {
|
|
|
374
410
|
!link.target.x ||
|
|
375
411
|
!link.target.y)
|
|
376
412
|
return;
|
|
377
|
-
|
|
413
|
+
if (!link.source._visible && !link.target._visible)
|
|
414
|
+
return;
|
|
415
|
+
const id = `${link.target.id}${link.source.id}`;
|
|
416
|
+
let linkOptions;
|
|
417
|
+
if (this.linkSettings.cache && this.linkOptionsCache[id]) {
|
|
418
|
+
linkOptions = this.linkOptionsCache[id];
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
linkOptions = linkIterationExtractor(link, index, this.links, state, this.linkSettings.options ?? {}, linkOptionsGetter);
|
|
422
|
+
if (this.linkSettings.cache) {
|
|
423
|
+
this.linkOptionsCache[id] = linkOptions;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
378
426
|
if (linkOptions.drawLink) {
|
|
379
427
|
linkOptions.drawLink(link, linkOptions, state);
|
|
380
428
|
return;
|
|
381
429
|
}
|
|
382
430
|
let alpha = linkOptions.alpha;
|
|
431
|
+
let arrowAlpha = linkOptions.arrowReverseAppear ? 0 : linkOptions.arrowAlpha;
|
|
383
432
|
if (this.highlightedNeighbors && this.highlightedNode) {
|
|
384
433
|
/** Not highlighted */
|
|
385
434
|
if (this.highlightedNode.id != link.source.id &&
|
|
386
435
|
this.highlightedNode.id != link.target.id) {
|
|
387
|
-
if (linkOptions.highlightFading)
|
|
388
|
-
|
|
389
|
-
this.graphSettings.highlightLinkFadingMin
|
|
390
|
-
|
|
436
|
+
if (linkOptions.highlightFading) {
|
|
437
|
+
const min = this.graphSettings.highlightLinkFadingMin < alpha
|
|
438
|
+
? this.graphSettings.highlightLinkFadingMin
|
|
439
|
+
: alpha;
|
|
440
|
+
alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
|
|
441
|
+
}
|
|
442
|
+
if (linkOptions.arrow &&
|
|
443
|
+
linkOptions.arrowHighlightFading &&
|
|
444
|
+
!linkOptions.arrowReverseAppear) {
|
|
445
|
+
const min = this.graphSettings.highlightArrowFadingMin < arrowAlpha
|
|
446
|
+
? this.graphSettings.highlightArrowFadingMin
|
|
447
|
+
: arrowAlpha;
|
|
448
|
+
arrowAlpha = animationByProgress(min, arrowAlpha - min, 1 - this.highlightProgress);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// eslint-disable-next-line no-lonely-if
|
|
453
|
+
if (linkOptions.arrow && linkOptions.arrowReverseAppear) {
|
|
454
|
+
/** Highlighted */
|
|
455
|
+
arrowAlpha = animationByProgress(0, linkOptions.arrowAlpha, this.highlightProgress);
|
|
456
|
+
}
|
|
391
457
|
}
|
|
392
|
-
this.context.beginPath();
|
|
393
458
|
}
|
|
459
|
+
/** Link */
|
|
460
|
+
this.context.beginPath();
|
|
394
461
|
this.context.globalAlpha = alpha;
|
|
395
462
|
this.context.strokeStyle = linkOptions.color;
|
|
396
463
|
this.context.lineWidth = linkOptions.width;
|
|
464
|
+
let xStart = link.source.x;
|
|
465
|
+
let yStart = link.source.y;
|
|
466
|
+
let xEnd = link.target.x;
|
|
467
|
+
let yEnd = link.target.y;
|
|
397
468
|
if (linkOptions.pretty) {
|
|
398
|
-
const
|
|
469
|
+
const isHasArrow = linkOptions.arrow && arrowAlpha > 0;
|
|
470
|
+
const { x1, x2, y1, y2 } = calculateLinkPositionByRadius(link, isHasArrow ? linkOptions.arrowSize : 0) ?? {
|
|
399
471
|
x1: 0,
|
|
400
472
|
x2: 0,
|
|
401
473
|
y1: 0,
|
|
402
474
|
y2: 0,
|
|
403
475
|
};
|
|
404
|
-
|
|
405
|
-
|
|
476
|
+
xStart = x1;
|
|
477
|
+
xEnd = x2;
|
|
478
|
+
yStart = y1;
|
|
479
|
+
yEnd = y2;
|
|
406
480
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
481
|
+
this.context.moveTo(xStart, yStart);
|
|
482
|
+
this.context.lineTo(xEnd, yEnd);
|
|
483
|
+
this.context.stroke();
|
|
484
|
+
/** Particle */
|
|
485
|
+
if (this.linkSettings.particles &&
|
|
486
|
+
this.highlightedNode &&
|
|
487
|
+
(this.highlightedNode.id === link.source.id || this.highlightedNode.id === link.target.id)) {
|
|
488
|
+
if (!this.particles[id]) {
|
|
489
|
+
const sourceId = link.source.id;
|
|
490
|
+
const targetId = link.target.id;
|
|
491
|
+
this.particles[id] = Array.from({ length: linkOptions.particleCount }, (_, index) => {
|
|
492
|
+
return {
|
|
493
|
+
step: 0,
|
|
494
|
+
wait: index * (linkOptions.particleSteps / linkOptions.particleCount),
|
|
495
|
+
sourceId,
|
|
496
|
+
targetId,
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
this.particles[id].forEach((particle) => {
|
|
501
|
+
if (!this.context)
|
|
502
|
+
return;
|
|
503
|
+
getParticlePosition({
|
|
504
|
+
particle,
|
|
505
|
+
totalSteps: linkOptions.particleSteps,
|
|
506
|
+
xEnd,
|
|
507
|
+
xStart,
|
|
508
|
+
yEnd,
|
|
509
|
+
yStart,
|
|
510
|
+
});
|
|
511
|
+
if (particle.x != undefined && particle.y != undefined) {
|
|
512
|
+
this.context.beginPath();
|
|
513
|
+
this.context.arc(particle.x, particle.y, linkOptions.particleRadius, 0, Math.PI * 2);
|
|
514
|
+
this.context.fillStyle = linkOptions.particleColor;
|
|
515
|
+
this.context.fill();
|
|
516
|
+
this.context.stroke();
|
|
517
|
+
}
|
|
518
|
+
});
|
|
410
519
|
}
|
|
411
|
-
|
|
520
|
+
/** Arrow */
|
|
521
|
+
if (linkOptions.arrow && arrowAlpha > 0) {
|
|
522
|
+
const { x1: xStart, x2: xEnd, y1: yStart, y2: yEnd, } = calculateLinkPositionByRadius(link) ?? {
|
|
523
|
+
x1: 0,
|
|
524
|
+
x2: 0,
|
|
525
|
+
y1: 0,
|
|
526
|
+
y2: 0,
|
|
527
|
+
};
|
|
528
|
+
const angle = Math.atan2(yEnd - yStart, xEnd - xStart);
|
|
529
|
+
this.context.beginPath();
|
|
530
|
+
this.context.globalAlpha = arrowAlpha;
|
|
531
|
+
this.context.moveTo(xEnd, yEnd);
|
|
532
|
+
this.context.lineTo(xEnd - linkOptions.arrowSize * Math.cos(angle - Math.PI / 6), yEnd - linkOptions.arrowSize * Math.sin(angle - Math.PI / 6));
|
|
533
|
+
this.context.lineTo(xEnd - linkOptions.arrowSize * Math.cos(angle + Math.PI / 6), yEnd - linkOptions.arrowSize * Math.sin(angle + Math.PI / 6));
|
|
534
|
+
this.context.closePath();
|
|
535
|
+
this.context.fillStyle = linkOptions.arrowColor;
|
|
536
|
+
this.context.fill();
|
|
412
537
|
this.context.stroke();
|
|
538
|
+
}
|
|
413
539
|
if (linkOptions.drawExtraLink) {
|
|
414
540
|
linkOptions.drawExtraLink(link, { ...linkOptions, alpha }, state);
|
|
415
541
|
}
|
|
416
542
|
};
|
|
417
543
|
}
|
|
418
|
-
function getDrawNode(textRenders, state) {
|
|
544
|
+
function getDrawNode(nodeRenders, textRenders, state) {
|
|
419
545
|
return function drawNode(node, index) {
|
|
420
546
|
if (!this.context || !node.x || !node.y)
|
|
421
547
|
return;
|
|
422
|
-
|
|
548
|
+
let nodeOptions;
|
|
549
|
+
if (this.nodeSettings.cache && this.nodeOptionsCache[node.id]) {
|
|
550
|
+
nodeOptions = this.nodeOptionsCache[node.id];
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
nodeOptions = nodeIterationExtractor(node, index, this.nodes, state, this.nodeSettings.options ?? {}, nodeOptionsGetter);
|
|
554
|
+
if (this.nodeSettings.cache) {
|
|
555
|
+
this.nodeOptionsCache[node.id] = nodeOptions;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
423
558
|
if (nodeOptions.nodeDraw) {
|
|
424
|
-
|
|
559
|
+
nodeRenders.push(() => {
|
|
560
|
+
nodeOptions?.nodeDraw?.(node, nodeOptions, state);
|
|
561
|
+
});
|
|
425
562
|
return;
|
|
426
563
|
}
|
|
427
564
|
let alpha = nodeOptions.alpha;
|
|
@@ -437,15 +574,16 @@ class GraphCanvas {
|
|
|
437
574
|
/** Not highlighted */
|
|
438
575
|
if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
|
|
439
576
|
if (nodeOptions.highlightFading) {
|
|
440
|
-
|
|
441
|
-
this.graphSettings.highlightFadingMin
|
|
442
|
-
|
|
577
|
+
const min = this.graphSettings.highlightFadingMin < alpha
|
|
578
|
+
? this.graphSettings.highlightFadingMin
|
|
579
|
+
: alpha;
|
|
580
|
+
alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
|
|
443
581
|
}
|
|
444
582
|
if (nodeOptions.highlightTextFading) {
|
|
445
|
-
|
|
446
|
-
this.graphSettings.highlightTextFadingMin
|
|
447
|
-
|
|
448
|
-
|
|
583
|
+
const min = this.graphSettings.highlightTextFadingMin < textAlpha
|
|
584
|
+
? this.graphSettings.highlightTextFadingMin
|
|
585
|
+
: textAlpha;
|
|
586
|
+
textAlpha = animationByProgress(min, textAlpha - min, 1 - this.highlightProgress);
|
|
449
587
|
}
|
|
450
588
|
if (nodeOptions.highlightColor) {
|
|
451
589
|
const colorRgb = extractRgb(colorToRgb(color));
|
|
@@ -460,20 +598,14 @@ class GraphCanvas {
|
|
|
460
598
|
(this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
|
|
461
599
|
/** Highlighted */
|
|
462
600
|
if (nodeOptions.highlightSizing) {
|
|
463
|
-
|
|
464
|
-
radiusInitial += ((radiusMax - radiusInitial) / 100) * (this.highlightProgress * 100);
|
|
601
|
+
radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightSizingAdditional, this.highlightProgress);
|
|
465
602
|
}
|
|
466
603
|
if (nodeOptions.highlightTextSizing) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
textSize += ((textSizeMax - textSize) / 100) * (this.highlightProgress * 100);
|
|
473
|
-
textShiftX += ((textShiftXMax - textShiftX) / 100) * (this.highlightProgress * 100);
|
|
474
|
-
textShiftY += ((textShiftYMax - textShiftY) / 100) * (this.highlightProgress * 100);
|
|
475
|
-
textWeight += ((textWeightMax - textWeight) / 100) * (this.highlightProgress * 100);
|
|
476
|
-
textWidth += ((textWidthMax - textWidth) / 100) * (this.highlightProgress * 100);
|
|
604
|
+
textSize = animationByProgress(textSize, this.graphSettings.highlightTextSizingAdditional, this.highlightProgress);
|
|
605
|
+
textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightTextShiftXAdditional, this.highlightProgress);
|
|
606
|
+
textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightTextShiftYAdditional, this.highlightProgress);
|
|
607
|
+
textWeight = animationByProgress(textWeight, this.graphSettings.highlightTextWeightAdditional, this.highlightProgress);
|
|
608
|
+
textWidth = animationByProgress(textWidth, this.graphSettings.highlightTextWidthAdditional, this.highlightProgress);
|
|
477
609
|
}
|
|
478
610
|
}
|
|
479
611
|
}
|
|
@@ -485,8 +617,31 @@ class GraphCanvas {
|
|
|
485
617
|
linkCount: node.linkCount,
|
|
486
618
|
});
|
|
487
619
|
node._radius = radius;
|
|
488
|
-
|
|
489
|
-
|
|
620
|
+
if (!isNodeVisible({
|
|
621
|
+
height: this.height,
|
|
622
|
+
width: this.width,
|
|
623
|
+
x: node.x,
|
|
624
|
+
y: node.y,
|
|
625
|
+
radius,
|
|
626
|
+
transform: this.areaTransform,
|
|
627
|
+
})) {
|
|
628
|
+
node._visible = false;
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
node._visible = true;
|
|
632
|
+
nodeRenders.push(() => {
|
|
633
|
+
if (!this.context || !node.x || !node.y)
|
|
634
|
+
return;
|
|
635
|
+
this.context.beginPath();
|
|
636
|
+
this.context.globalAlpha = alpha;
|
|
637
|
+
/** circle */
|
|
638
|
+
this.context.lineWidth = nodeOptions.borderWidth;
|
|
639
|
+
this.context.strokeStyle = nodeOptions.borderColor;
|
|
640
|
+
this.context.fillStyle = color;
|
|
641
|
+
this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
|
|
642
|
+
this.context.fill();
|
|
643
|
+
this.context.stroke();
|
|
644
|
+
});
|
|
490
645
|
/** text */
|
|
491
646
|
if (nodeOptions.textVisible && nodeOptions.text) {
|
|
492
647
|
textRenders.push(() => {
|
|
@@ -541,29 +696,27 @@ class GraphCanvas {
|
|
|
541
696
|
}
|
|
542
697
|
});
|
|
543
698
|
}
|
|
544
|
-
/** circle */
|
|
545
|
-
this.context.lineWidth = nodeOptions.borderWidth;
|
|
546
|
-
this.context.strokeStyle = nodeOptions.borderColor;
|
|
547
|
-
this.context.fillStyle = color;
|
|
548
|
-
this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
|
|
549
|
-
this.context.fill();
|
|
550
|
-
this.context.stroke();
|
|
551
699
|
if (nodeOptions.nodeExtraDraw) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
700
|
+
nodeRenders.push(() => {
|
|
701
|
+
nodeOptions?.nodeExtraDraw?.(node, {
|
|
702
|
+
...nodeOptions,
|
|
703
|
+
radius,
|
|
704
|
+
alpha,
|
|
705
|
+
color,
|
|
706
|
+
textAlpha,
|
|
707
|
+
textSize,
|
|
708
|
+
textShiftX,
|
|
709
|
+
textShiftY,
|
|
710
|
+
textWeight,
|
|
711
|
+
textWidth,
|
|
712
|
+
}, state);
|
|
713
|
+
});
|
|
564
714
|
}
|
|
565
715
|
};
|
|
566
716
|
}
|
|
717
|
+
if (this.graphSettings.showDrawTime) {
|
|
718
|
+
return setDrawTime(draw.bind(this), this.graphSettings.showDrawTimeEveryTick);
|
|
719
|
+
}
|
|
567
720
|
return draw;
|
|
568
721
|
}
|
|
569
722
|
initResize() {
|
|
@@ -757,7 +910,7 @@ class GraphCanvas {
|
|
|
757
910
|
this.listeners.onEndDragFinished?.(event, this.state);
|
|
758
911
|
}));
|
|
759
912
|
}
|
|
760
|
-
initZoom() {
|
|
913
|
+
initZoom(currentZoom) {
|
|
761
914
|
if (!this.area)
|
|
762
915
|
throw new Error("bad init data");
|
|
763
916
|
const zoomInstance = zoom()
|
|
@@ -765,7 +918,9 @@ class GraphCanvas {
|
|
|
765
918
|
.on("zoom", (event) => {
|
|
766
919
|
this.listeners.onZoom?.(event);
|
|
767
920
|
this.areaTransform = event.transform;
|
|
768
|
-
|
|
921
|
+
this.linkOptionsCache = {};
|
|
922
|
+
this.nodeOptionsCache = {};
|
|
923
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
769
924
|
requestAnimationFrame(() => this.draw());
|
|
770
925
|
});
|
|
771
926
|
if (this.graphSettings.translateExtentEnable) {
|
|
@@ -780,7 +935,7 @@ class GraphCanvas {
|
|
|
780
935
|
]);
|
|
781
936
|
}
|
|
782
937
|
select(this.area).call(zoomInstance).on("dblclick.zoom", null);
|
|
783
|
-
const zoomInitial = this.graphSettings.zoomInitial;
|
|
938
|
+
const zoomInitial = currentZoom ?? this.graphSettings.zoomInitial;
|
|
784
939
|
this.areaTransform = new ZoomTransform(zoomInitial?.k ?? 1, zoomInitial?.x ?? this.width / 2, zoomInitial?.y ?? this.height / 2);
|
|
785
940
|
zoom().transform(select(this.area), this.areaTransform);
|
|
786
941
|
}
|