@krainovsd/graph 0.7.0 → 0.8.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 (30) hide show
  1. package/lib/cjs/index.cjs +945 -165
  2. package/lib/cjs/index.cjs.map +1 -1
  3. package/lib/esm/index.js +3 -0
  4. package/lib/esm/index.js.map +1 -1
  5. package/lib/esm/lib/draw-time.js +25 -0
  6. package/lib/esm/lib/draw-time.js.map +1 -0
  7. package/lib/esm/lib/get-controls-info.js +541 -0
  8. package/lib/esm/lib/get-controls-info.js.map +1 -0
  9. package/lib/esm/module/GraphCanvas/GraphCanvas.js +218 -67
  10. package/lib/esm/module/GraphCanvas/GraphCanvas.js.map +1 -1
  11. package/lib/esm/module/GraphCanvas/constants/settings.js +26 -7
  12. package/lib/esm/module/GraphCanvas/constants/settings.js.map +1 -1
  13. package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js +7 -4
  14. package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js.map +1 -1
  15. package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js +6 -5
  16. package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js.map +1 -1
  17. package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js +12 -0
  18. package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js.map +1 -0
  19. package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js +2 -2
  20. package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js.map +1 -1
  21. package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js +24 -0
  22. package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js.map +1 -0
  23. package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js +14 -0
  24. package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js.map +1 -0
  25. package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js +1 -0
  26. package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js.map +1 -1
  27. package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js +1 -0
  28. package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js.map +1 -1
  29. package/lib/index.d.ts +72 -3
  30. 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
- if (options.forceSettings)
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
- if (options.linkSettings)
123
- this.linkSettings = linkSettingsGetter(options.linkSettings);
124
- if (options.nodeSettings)
125
- this.nodeSettings = nodeSettingsGetter(options.nodeSettings);
126
- if (options.forceSettings)
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
- else if (!this.simulation.force("collide"))
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
- return;
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
- return;
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
- const textRenders = [];
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,52 +410,151 @@ class GraphCanvas {
374
410
  !link.target.x ||
375
411
  !link.target.y)
376
412
  return;
377
- const linkOptions = linkIterationExtractor(link, index, this.links, state, this.linkSettings.options ?? {}, linkOptionsGetter);
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
- alpha =
389
- this.graphSettings.highlightLinkFadingMin +
390
- (alpha - this.graphSettings.highlightLinkFadingMin) * (1 - this.highlightProgress);
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 { x1, x2, y1, y2 } = calculateLinkPositionByRadius(link) ?? {
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
- this.context.moveTo(x1, y1);
405
- this.context.lineTo(x2, y2);
476
+ xStart = x1;
477
+ xEnd = x2;
478
+ yStart = y1;
479
+ yEnd = y2;
406
480
  }
407
- else {
408
- this.context.moveTo(link.source.x, link.source.y);
409
- this.context.lineTo(link.target.x, link.target.y);
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
- if (this.highlightedNeighbors && this.highlightedNode)
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
- const nodeOptions = nodeIterationExtractor(node, index, this.nodes, state, this.nodeSettings.options ?? {}, nodeOptionsGetter);
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
  nodeOptions.nodeDraw(node, nodeOptions, state);
425
560
  return;
@@ -437,15 +572,16 @@ class GraphCanvas {
437
572
  /** Not highlighted */
438
573
  if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
439
574
  if (nodeOptions.highlightFading) {
440
- alpha =
441
- this.graphSettings.highlightFadingMin +
442
- (alpha - this.graphSettings.highlightFadingMin) * (1 - this.highlightProgress);
575
+ const min = this.graphSettings.highlightFadingMin < alpha
576
+ ? this.graphSettings.highlightFadingMin
577
+ : alpha;
578
+ alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
443
579
  }
444
580
  if (nodeOptions.highlightTextFading) {
445
- textAlpha =
446
- this.graphSettings.highlightTextFadingMin +
447
- (textAlpha - this.graphSettings.highlightTextFadingMin) *
448
- (1 - this.highlightProgress);
581
+ const min = this.graphSettings.highlightTextFadingMin < textAlpha
582
+ ? this.graphSettings.highlightTextFadingMin
583
+ : textAlpha;
584
+ textAlpha = animationByProgress(min, textAlpha - min, 1 - this.highlightProgress);
449
585
  }
450
586
  if (nodeOptions.highlightColor) {
451
587
  const colorRgb = extractRgb(colorToRgb(color));
@@ -460,20 +596,14 @@ class GraphCanvas {
460
596
  (this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
461
597
  /** Highlighted */
462
598
  if (nodeOptions.highlightSizing) {
463
- const radiusMax = radiusInitial + this.graphSettings.highlightSizingAdditional;
464
- radiusInitial += ((radiusMax - radiusInitial) / 100) * (this.highlightProgress * 100);
599
+ radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightSizingAdditional, this.highlightProgress);
465
600
  }
466
601
  if (nodeOptions.highlightTextSizing) {
467
- const textSizeMax = textSize + this.graphSettings.highlightTextSizingAdditional;
468
- const textShiftXMax = textShiftX + this.graphSettings.highlightTextShiftXAdditional;
469
- const textShiftYMax = textShiftY + this.graphSettings.highlightTextShiftYAdditional;
470
- const textWeightMax = textWeight + this.graphSettings.highlightTextWeightAdditional;
471
- const textWidthMax = textWidth + this.graphSettings.highlightTextWidthAdditional;
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);
602
+ textSize = animationByProgress(textSize, this.graphSettings.highlightTextSizingAdditional, this.highlightProgress);
603
+ textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightTextShiftXAdditional, this.highlightProgress);
604
+ textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightTextShiftYAdditional, this.highlightProgress);
605
+ textWeight = animationByProgress(textWeight, this.graphSettings.highlightTextWeightAdditional, this.highlightProgress);
606
+ textWidth = animationByProgress(textWidth, this.graphSettings.highlightTextWidthAdditional, this.highlightProgress);
477
607
  }
478
608
  }
479
609
  }
@@ -485,8 +615,31 @@ class GraphCanvas {
485
615
  linkCount: node.linkCount,
486
616
  });
487
617
  node._radius = radius;
488
- this.context.beginPath();
489
- this.context.globalAlpha = alpha;
618
+ if (!isNodeVisible({
619
+ height: this.height,
620
+ width: this.width,
621
+ x: node.x,
622
+ y: node.y,
623
+ radius,
624
+ transform: this.areaTransform,
625
+ })) {
626
+ node._visible = false;
627
+ return;
628
+ }
629
+ node._visible = true;
630
+ nodeRenders.push(() => {
631
+ if (!this.context || !node.x || !node.y)
632
+ return;
633
+ this.context.beginPath();
634
+ this.context.globalAlpha = alpha;
635
+ /** circle */
636
+ this.context.lineWidth = nodeOptions.borderWidth;
637
+ this.context.strokeStyle = nodeOptions.borderColor;
638
+ this.context.fillStyle = color;
639
+ this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
640
+ this.context.fill();
641
+ this.context.stroke();
642
+ });
490
643
  /** text */
491
644
  if (nodeOptions.textVisible && nodeOptions.text) {
492
645
  textRenders.push(() => {
@@ -541,13 +694,6 @@ class GraphCanvas {
541
694
  }
542
695
  });
543
696
  }
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
697
  if (nodeOptions.nodeExtraDraw) {
552
698
  nodeOptions.nodeExtraDraw(node, {
553
699
  ...nodeOptions,
@@ -564,6 +710,9 @@ class GraphCanvas {
564
710
  }
565
711
  };
566
712
  }
713
+ if (this.graphSettings.showDrawTime) {
714
+ return setDrawTime(draw.bind(this), this.graphSettings.showDrawTimeEveryTick);
715
+ }
567
716
  return draw;
568
717
  }
569
718
  initResize() {
@@ -757,7 +906,7 @@ class GraphCanvas {
757
906
  this.listeners.onEndDragFinished?.(event, this.state);
758
907
  }));
759
908
  }
760
- initZoom() {
909
+ initZoom(currentZoom) {
761
910
  if (!this.area)
762
911
  throw new Error("bad init data");
763
912
  const zoomInstance = zoom()
@@ -765,7 +914,9 @@ class GraphCanvas {
765
914
  .on("zoom", (event) => {
766
915
  this.listeners.onZoom?.(event);
767
916
  this.areaTransform = event.transform;
768
- if (!this.simulationWorking)
917
+ this.linkOptionsCache = {};
918
+ this.nodeOptionsCache = {};
919
+ if (!this.simulationWorking && !this.highlightWorking)
769
920
  requestAnimationFrame(() => this.draw());
770
921
  });
771
922
  if (this.graphSettings.translateExtentEnable) {
@@ -780,7 +931,7 @@ class GraphCanvas {
780
931
  ]);
781
932
  }
782
933
  select(this.area).call(zoomInstance).on("dblclick.zoom", null);
783
- const zoomInitial = this.graphSettings.zoomInitial;
934
+ const zoomInitial = currentZoom ?? this.graphSettings.zoomInitial;
784
935
  this.areaTransform = new ZoomTransform(zoomInitial?.k ?? 1, zoomInitial?.x ?? this.width / 2, zoomInitial?.y ?? this.height / 2);
785
936
  zoom().transform(select(this.area), this.areaTransform);
786
937
  }