@krainovsd/graph 0.8.3 → 0.9.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.
@@ -1,9 +1,10 @@
1
- import { isBoolean, isArray } from '@krainovsd/js-helpers';
1
+ import { isBoolean, isArray, isObject } from '@krainovsd/js-helpers';
2
2
  import { greatest } from 'd3-array';
3
3
  import { drag } from 'd3-drag';
4
4
  import { forceLink, forceSimulation, forceX, forceY, forceManyBody, forceCenter, forceCollide } from 'd3-force';
5
5
  import { create, select } from 'd3-selection';
6
6
  import { zoomIdentity, zoom, ZoomTransform } from 'd3-zoom';
7
+ import { checkType } from '../../lib/check-type.js';
7
8
  import { colorToRgb } from '../../lib/color-to-rgb.js';
8
9
  import { extractRgb } from '../../lib/extract-rgb.js';
9
10
  import { fadeRgb } from '../../lib/fade-rgb.js';
@@ -22,6 +23,7 @@ import { calculateLinkPositionByRadius } from './lib/utils/calculate-link-positi
22
23
  import { animationByProgress } from './lib/utils/animation-by-progress.js';
23
24
  import { isNodeVisible } from './lib/utils/is-node-visible.js';
24
25
  import { getParticlePosition } from './lib/utils/get-particle-position.js';
26
+ import { linkByPointerGetter } from './lib/utils/link-by-pointer-getter.js';
25
27
  import { getDrawTime, setDrawTime } from '../../lib/draw-time.js';
26
28
 
27
29
  class GraphCanvas {
@@ -52,6 +54,7 @@ class GraphCanvas {
52
54
  nodeOptionsCache = {};
53
55
  isDragging = false;
54
56
  highlightedNode = null;
57
+ highlightedLink = null;
55
58
  highlightedNeighbors = null;
56
59
  highlightProgress = 1;
57
60
  highlightWorking = false;
@@ -73,6 +76,7 @@ class GraphCanvas {
73
76
  highlightDrawing: this.highlightDrawing,
74
77
  highlightedNeighbors: this.highlightedNeighbors,
75
78
  highlightedNode: this.highlightedNode,
79
+ highlightedLink: this.highlightedLink,
76
80
  highlightWorking: this.highlightWorking,
77
81
  isDragging: this.isDragging,
78
82
  simulation: this.simulation,
@@ -144,6 +148,10 @@ class GraphCanvas {
144
148
  }
145
149
  this.tick();
146
150
  }
151
+ updateRect() {
152
+ if (this.area)
153
+ this.areaRect = this.area.getBoundingClientRect();
154
+ }
147
155
  clearCache() {
148
156
  this.nodeOptionsCache = {};
149
157
  this.linkOptionsCache = {};
@@ -199,6 +207,7 @@ class GraphCanvas {
199
207
  clearState() {
200
208
  this.isDragging = false;
201
209
  this.highlightedNode = null;
210
+ this.highlightedLink = null;
202
211
  this.highlightedNeighbors = null;
203
212
  this.highlightProgress = 0;
204
213
  this.highlightWorking = false;
@@ -359,9 +368,10 @@ class GraphCanvas {
359
368
  return void requestAnimationFrame(() => this.draw());
360
369
  }
361
370
  if (!this.highlightWorking && this.highlightProgress <= 0) {
362
- if (this.highlightedNeighbors || this.highlightedNode) {
371
+ if (this.highlightedNeighbors || this.highlightedNode || this.highlightedLink) {
363
372
  this.highlightedNeighbors = null;
364
373
  this.highlightedNode = null;
374
+ this.highlightedLink = null;
365
375
  this.particles = {};
366
376
  if (!this.simulationWorking)
367
377
  return void requestAnimationFrame(() => this.draw());
@@ -381,6 +391,8 @@ class GraphCanvas {
381
391
  this.highlightedNeighbors = null;
382
392
  if (this.highlightedNode)
383
393
  this.highlightedNode = null;
394
+ if (this.highlightedLink)
395
+ this.highlightedLink = null;
384
396
  });
385
397
  return;
386
398
  }
@@ -429,21 +441,49 @@ class GraphCanvas {
429
441
  }
430
442
  let alpha = linkOptions.alpha;
431
443
  let arrowAlpha = linkOptions.arrowReverseAppear ? 0 : linkOptions.arrowAlpha;
444
+ /** NODE HIGHLIGHT */
432
445
  if (this.highlightedNeighbors && this.highlightedNode) {
433
446
  /** Not highlighted */
434
447
  if (this.highlightedNode.id != link.source.id &&
435
448
  this.highlightedNode.id != link.target.id) {
436
- if (linkOptions.highlightFading) {
437
- const min = this.graphSettings.highlightLinkFadingMin < alpha
438
- ? this.graphSettings.highlightLinkFadingMin
449
+ if (linkOptions.highlightByNodeLinkFading) {
450
+ const min = this.graphSettings.highlightByNodeLinkFadingMin < alpha
451
+ ? this.graphSettings.highlightByNodeLinkFadingMin
439
452
  : alpha;
440
453
  alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
441
454
  }
442
455
  if (linkOptions.arrow &&
443
- linkOptions.arrowHighlightFading &&
456
+ linkOptions.highlightByNodeArrowFading &&
444
457
  !linkOptions.arrowReverseAppear) {
445
- const min = this.graphSettings.highlightArrowFadingMin < arrowAlpha
446
- ? this.graphSettings.highlightArrowFadingMin
458
+ const min = this.graphSettings.highlightByNodeArrowFadingMin < arrowAlpha
459
+ ? this.graphSettings.highlightByNodeArrowFadingMin
460
+ : arrowAlpha;
461
+ arrowAlpha = animationByProgress(min, arrowAlpha - min, 1 - this.highlightProgress);
462
+ }
463
+ }
464
+ else {
465
+ // eslint-disable-next-line no-lonely-if
466
+ if (linkOptions.arrow && linkOptions.arrowReverseAppear) {
467
+ /** Highlighted */
468
+ arrowAlpha = animationByProgress(0, linkOptions.arrowAlpha, this.highlightProgress);
469
+ }
470
+ }
471
+ }
472
+ /** LINK HIGHLIGHT */
473
+ if (this.highlightedNeighbors && this.highlightedLink) {
474
+ /** Not highlighted */
475
+ if (this.highlightedLink !== link) {
476
+ if (linkOptions.highlightByLinkLinkFading) {
477
+ const min = this.graphSettings.highlightByLinkLinkFadingMin < alpha
478
+ ? this.graphSettings.highlightByLinkLinkFadingMin
479
+ : alpha;
480
+ alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
481
+ }
482
+ if (linkOptions.arrow &&
483
+ linkOptions.highlightByLinkArrowFading &&
484
+ !linkOptions.arrowReverseAppear) {
485
+ const min = this.graphSettings.highlightByLinkArrowFadingMin < arrowAlpha
486
+ ? this.graphSettings.highlightByLinkArrowFadingMin
447
487
  : arrowAlpha;
448
488
  arrowAlpha = animationByProgress(min, arrowAlpha - min, 1 - this.highlightProgress);
449
489
  }
@@ -483,8 +523,10 @@ class GraphCanvas {
483
523
  this.context.stroke();
484
524
  /** Particle */
485
525
  if (this.linkSettings.particles &&
486
- this.highlightedNode &&
487
- (this.highlightedNode.id === link.source.id || this.highlightedNode.id === link.target.id)) {
526
+ ((this.highlightedNode &&
527
+ (this.highlightedNode.id === link.source.id ||
528
+ this.highlightedNode.id === link.target.id)) ||
529
+ (this.highlightedLink && this.highlightedLink === link))) {
488
530
  if (!this.particles[id]) {
489
531
  const sourceId = link.source.id;
490
532
  const targetId = link.target.id;
@@ -573,42 +615,84 @@ class GraphCanvas {
573
615
  let textShiftY = nodeOptions.textShiftY;
574
616
  let textWeight = nodeOptions.textWeight;
575
617
  let textWidth = nodeOptions.textWidth;
618
+ /** Node Highlight */
576
619
  if (this.highlightedNeighbors && this.highlightedNode) {
577
620
  /** Not highlighted */
578
621
  if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
579
- if (nodeOptions.highlightFading) {
580
- const min = this.graphSettings.highlightFadingMin < alpha
581
- ? this.graphSettings.highlightFadingMin
622
+ if (nodeOptions.highlightByNodeNodeFading) {
623
+ const min = this.graphSettings.highlightByNodeNodeFadingMin < alpha
624
+ ? this.graphSettings.highlightByNodeNodeFadingMin
582
625
  : alpha;
583
626
  alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
584
627
  }
585
- if (nodeOptions.highlightTextFading) {
586
- const min = this.graphSettings.highlightTextFadingMin < textAlpha
587
- ? this.graphSettings.highlightTextFadingMin
628
+ if (nodeOptions.highlightByNodeTextFading) {
629
+ const min = this.graphSettings.highlightByNodeTextFadingMin < textAlpha
630
+ ? this.graphSettings.highlightByNodeTextFadingMin
588
631
  : textAlpha;
589
632
  textAlpha = animationByProgress(min, textAlpha - min, 1 - this.highlightProgress);
590
633
  }
591
- if (nodeOptions.highlightColor) {
634
+ if (nodeOptions.highlightByNodeNodeColor) {
592
635
  const colorRgb = extractRgb(colorToRgb(color));
593
636
  if (colorRgb) {
594
- const colorRgbFade = fadeRgb(colorRgb, this.graphSettings.highlightColorFadingMin);
637
+ const colorRgbFade = fadeRgb(colorRgb, this.graphSettings.highlightByNodeNodeColorFadingMin);
595
638
  const colorFadeAnimation = rgbAnimationByProgress(colorRgb, colorRgbFade, this.highlightProgress);
596
639
  color = `rgb(${colorFadeAnimation.r}, ${colorFadeAnimation.g}, ${colorFadeAnimation.b})`;
597
640
  }
598
641
  }
599
642
  }
600
- else if (!this.graphSettings.highlightOnlyRoot ||
601
- (this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
643
+ else if (!this.graphSettings.highlightByNodeOnlyRoot ||
644
+ (this.graphSettings.highlightByNodeOnlyRoot && this.highlightedNode.id === node.id)) {
602
645
  /** Highlighted */
603
- if (nodeOptions.highlightSizing) {
604
- radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightSizingAdditional, this.highlightProgress);
646
+ if (nodeOptions.highlightByNodeNodeSizing) {
647
+ radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightByNodeNodeSizingAdditional, this.highlightProgress);
605
648
  }
606
- if (nodeOptions.highlightTextSizing) {
607
- textSize = animationByProgress(textSize, this.graphSettings.highlightTextSizingAdditional, this.highlightProgress);
608
- textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightTextShiftXAdditional, this.highlightProgress);
609
- textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightTextShiftYAdditional, this.highlightProgress);
610
- textWeight = animationByProgress(textWeight, this.graphSettings.highlightTextWeightAdditional, this.highlightProgress);
611
- textWidth = animationByProgress(textWidth, this.graphSettings.highlightTextWidthAdditional, this.highlightProgress);
649
+ if (nodeOptions.highlightByNodeTextSizing) {
650
+ textSize = animationByProgress(textSize, this.graphSettings.highlightByNodeTextSizingAdditional, this.highlightProgress);
651
+ textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightByNodeTextShiftXAdditional, this.highlightProgress);
652
+ textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightByNodeTextShiftYAdditional, this.highlightProgress);
653
+ textWeight = animationByProgress(textWeight, this.graphSettings.highlightByNodeTextWeightAdditional, this.highlightProgress);
654
+ textWidth = animationByProgress(textWidth, this.graphSettings.highlightByNodeTextWidthAdditional, this.highlightProgress);
655
+ }
656
+ }
657
+ }
658
+ /** LinkHighlight */
659
+ if (this.highlightedNeighbors && this.highlightedLink) {
660
+ /** Not highlighted */
661
+ if (!this.highlightedNeighbors.has(node.id) &&
662
+ this.highlightedLink.source !== node &&
663
+ this.highlightedLink.target !== node) {
664
+ if (nodeOptions.highlightByLinkNodeFading) {
665
+ const min = this.graphSettings.highlightByLinkNodeFadingMin < alpha
666
+ ? this.graphSettings.highlightByLinkNodeFadingMin
667
+ : alpha;
668
+ alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
669
+ }
670
+ if (nodeOptions.highlightByLinkTextFading) {
671
+ const min = this.graphSettings.highlightByLinkTextFadingMin < textAlpha
672
+ ? this.graphSettings.highlightByLinkTextFadingMin
673
+ : textAlpha;
674
+ textAlpha = animationByProgress(min, textAlpha - min, 1 - this.highlightProgress);
675
+ }
676
+ if (nodeOptions.highlightByLinkNodeColor) {
677
+ const colorRgb = extractRgb(colorToRgb(color));
678
+ if (colorRgb) {
679
+ const colorRgbFade = fadeRgb(colorRgb, this.graphSettings.highlightByLinkNodeColorFadingMin);
680
+ const colorFadeAnimation = rgbAnimationByProgress(colorRgb, colorRgbFade, this.highlightProgress);
681
+ color = `rgb(${colorFadeAnimation.r}, ${colorFadeAnimation.g}, ${colorFadeAnimation.b})`;
682
+ }
683
+ }
684
+ }
685
+ else {
686
+ /** Highlighted */
687
+ if (nodeOptions.highlightByLinkNodeSizing) {
688
+ radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightByLinkNodeSizingAdditional, this.highlightProgress);
689
+ }
690
+ if (nodeOptions.highlightByLinkTextSizing) {
691
+ textSize = animationByProgress(textSize, this.graphSettings.highlightByLinkTextSizingAdditional, this.highlightProgress);
692
+ textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightByLinkTextShiftXAdditional, this.highlightProgress);
693
+ textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightByLinkTextShiftYAdditional, this.highlightProgress);
694
+ textWeight = animationByProgress(textWeight, this.graphSettings.highlightByLinkTextWeightAdditional, this.highlightProgress);
695
+ textWidth = animationByProgress(textWidth, this.graphSettings.highlightByLinkTextWidthAdditional, this.highlightProgress);
612
696
  }
613
697
  }
614
698
  }
@@ -740,11 +824,7 @@ class GraphCanvas {
740
824
  this.updateSize();
741
825
  });
742
826
  });
743
- function updateRect() {
744
- if (this.area)
745
- this.areaRect = this.area.getBoundingClientRect();
746
- }
747
- document.addEventListener("scroll", updateRect.bind(this), {
827
+ document.addEventListener("scroll", this.updateRect.bind(this), {
748
828
  capture: true,
749
829
  passive: true,
750
830
  signal: abortController.signal,
@@ -754,10 +834,14 @@ class GraphCanvas {
754
834
  initPointer() {
755
835
  if (!this.area || !this.nodes || !this.simulation)
756
836
  throw new Error("bad init data");
757
- /** hover */
758
- this.area.addEventListener("pointermove", (event) => {
837
+ function onHover(event) {
838
+ if (!this.area)
839
+ return;
759
840
  let currentNode;
760
- if (this.graphSettings.highlightByHover && !this.isDragging) {
841
+ let currentLink;
842
+ const checkHighlightNode = this.graphSettings.highlightByHoverNode && !this.isDragging;
843
+ const checkHighlightLink = this.graphSettings.highlightByHoverLink && !this.isDragging;
844
+ if (checkHighlightNode) {
761
845
  currentNode = nodeByPointerGetter({
762
846
  graphSettings: this.graphSettings,
763
847
  areaRect: this.areaRect,
@@ -765,26 +849,61 @@ class GraphCanvas {
765
849
  mouseEvent: event,
766
850
  nodes: this.nodes,
767
851
  });
768
- if (currentNode && this.highlightedNode !== currentNode) {
769
- this.highlightedNode = currentNode;
770
- this.highlightedNeighbors = new Set(this.highlightedNode?.neighbors ?? []);
771
- this.highlightWorking = true;
772
- if (!this.simulationWorking && !this.highlightDrawing)
773
- requestAnimationFrame(() => {
774
- this.draw();
775
- });
852
+ }
853
+ if (currentNode) {
854
+ this.area.style.cursor = "pointer";
855
+ }
856
+ else if (checkHighlightLink) {
857
+ currentLink = linkByPointerGetter({
858
+ graphSettings: this.graphSettings,
859
+ areaRect: this.areaRect,
860
+ areaTransform: this.areaTransform,
861
+ mouseEvent: event,
862
+ links: this.links,
863
+ });
864
+ if (currentLink) {
865
+ this.area.style.cursor = "pointer";
776
866
  }
777
- else if (!currentNode && this.highlightedNode) {
778
- this.highlightWorking = false;
779
- if (!this.simulationWorking && !this.highlightDrawing)
780
- requestAnimationFrame(() => {
781
- this.draw();
782
- });
867
+ else {
868
+ this.area.style.cursor = "default";
783
869
  }
784
870
  }
871
+ else {
872
+ this.area.style.cursor = "default";
873
+ }
874
+ if (currentNode && this.highlightedNode !== currentNode) {
875
+ this.highlightedNode = currentNode;
876
+ this.highlightedLink = null;
877
+ this.highlightedNeighbors = new Set(this.highlightedNode?.neighbors ?? []);
878
+ this.highlightWorking = true;
879
+ if (!this.simulationWorking && !this.highlightDrawing)
880
+ requestAnimationFrame(() => {
881
+ this.draw();
882
+ });
883
+ }
884
+ else if (currentLink &&
885
+ checkType(currentLink.source, isObject(currentLink.source)) &&
886
+ checkType(currentLink.target, isObject(currentLink.target)) &&
887
+ this.highlightedLink !== currentLink) {
888
+ this.highlightedLink = currentLink;
889
+ this.highlightedNode = null;
890
+ this.highlightedNeighbors = new Set([currentLink.source.id, currentLink.target.id]);
891
+ this.highlightWorking = true;
892
+ if (!this.simulationWorking && !this.highlightDrawing)
893
+ requestAnimationFrame(() => {
894
+ this.draw();
895
+ });
896
+ }
897
+ else if (!currentNode && !currentLink && (this.highlightedNode || this.highlightedLink)) {
898
+ this.highlightWorking = false;
899
+ if (!this.simulationWorking && !this.highlightDrawing)
900
+ requestAnimationFrame(() => {
901
+ this.draw();
902
+ });
903
+ }
785
904
  if (!this.listeners.onMove)
786
905
  return;
787
- if (!currentNode)
906
+ if (!currentNode && !checkHighlightNode)
788
907
  currentNode = nodeByPointerGetter({
789
908
  graphSettings: this.graphSettings,
790
909
  areaRect: this.areaRect,
@@ -792,13 +911,23 @@ class GraphCanvas {
792
911
  mouseEvent: event,
793
912
  nodes: this.nodes,
794
913
  });
795
- return void this.listeners.onMove(event, currentNode);
796
- }, {
797
- signal: this.eventAbortController.signal,
798
- });
799
- /** dblclick */
800
- this.area.addEventListener("dblclick", (event) => {
801
- if (!this.listeners.onDoubleClick)
914
+ if (!currentNode && (!checkHighlightNode || (!checkHighlightLink && !currentLink))) {
915
+ currentLink = linkByPointerGetter({
916
+ graphSettings: this.graphSettings,
917
+ areaRect: this.areaRect,
918
+ areaTransform: this.areaTransform,
919
+ mouseEvent: event,
920
+ links: this.links,
921
+ });
922
+ }
923
+ if (!currentNode)
924
+ return void this.listeners.onMove(event, currentNode, currentLink);
925
+ }
926
+ function onWheelClick(event) {
927
+ if (this.isDragging ||
928
+ !this.listeners.onWheelClick ||
929
+ !("button" in event) ||
930
+ event.button !== 1)
802
931
  return;
803
932
  const currentNode = nodeByPointerGetter({
804
933
  graphSettings: this.graphSettings,
@@ -807,11 +936,20 @@ class GraphCanvas {
807
936
  mouseEvent: event,
808
937
  nodes: this.nodes,
809
938
  });
810
- return void this.listeners.onDoubleClick(event, currentNode);
811
- });
812
- /** wheel click */
813
- this.area.addEventListener("mousedown", (event) => {
814
- if (this.isDragging || !this.listeners.onWheelClick || event.button !== 1)
939
+ if (!currentNode) {
940
+ const currentLink = linkByPointerGetter({
941
+ graphSettings: this.graphSettings,
942
+ areaRect: this.areaRect,
943
+ areaTransform: this.areaTransform,
944
+ mouseEvent: event,
945
+ links: this.links,
946
+ });
947
+ return void this.listeners.onWheelClick(event, undefined, currentLink);
948
+ }
949
+ return void this.listeners.onWheelClick(event, currentNode, undefined);
950
+ }
951
+ function onRightClick(event) {
952
+ if (!this.listeners.onContextMenu)
815
953
  return;
816
954
  const currentNode = nodeByPointerGetter({
817
955
  graphSettings: this.graphSettings,
@@ -820,13 +958,20 @@ class GraphCanvas {
820
958
  mouseEvent: event,
821
959
  nodes: this.nodes,
822
960
  });
823
- return void this.listeners.onWheelClick(event, currentNode);
824
- }, {
825
- signal: this.eventAbortController.signal,
826
- });
827
- /** click */
828
- this.area.addEventListener("click", (event) => {
829
- if (this.isDragging || !this.listeners.onClick || event.button !== 0)
961
+ if (!currentNode) {
962
+ const currentLink = linkByPointerGetter({
963
+ graphSettings: this.graphSettings,
964
+ areaRect: this.areaRect,
965
+ areaTransform: this.areaTransform,
966
+ mouseEvent: event,
967
+ links: this.links,
968
+ });
969
+ return void this.listeners.onContextMenu(event, undefined, currentLink);
970
+ }
971
+ return void this.listeners.onContextMenu(event, currentNode, undefined);
972
+ }
973
+ function onDoubleClick(event) {
974
+ if (!this.listeners.onDoubleClick)
830
975
  return;
831
976
  const currentNode = nodeByPointerGetter({
832
977
  graphSettings: this.graphSettings,
@@ -835,13 +980,20 @@ class GraphCanvas {
835
980
  mouseEvent: event,
836
981
  nodes: this.nodes,
837
982
  });
838
- return void this.listeners.onClick(event, currentNode);
839
- }, {
840
- signal: this.eventAbortController.signal,
841
- });
842
- /** right click */
843
- this.area.addEventListener("contextmenu", (event) => {
844
- if (!this.listeners.onContextMenu)
983
+ if (!currentNode) {
984
+ const currentLink = linkByPointerGetter({
985
+ graphSettings: this.graphSettings,
986
+ areaRect: this.areaRect,
987
+ areaTransform: this.areaTransform,
988
+ mouseEvent: event,
989
+ links: this.links,
990
+ });
991
+ return void this.listeners.onDoubleClick(event, undefined, currentLink);
992
+ }
993
+ return void this.listeners.onDoubleClick(event, currentNode, undefined);
994
+ }
995
+ function onClick(event) {
996
+ if (this.isDragging || !this.listeners.onClick || ("button" in event && event.button !== 0))
845
997
  return;
846
998
  const currentNode = nodeByPointerGetter({
847
999
  graphSettings: this.graphSettings,
@@ -850,15 +1002,46 @@ class GraphCanvas {
850
1002
  mouseEvent: event,
851
1003
  nodes: this.nodes,
852
1004
  });
853
- return void this.listeners.onContextMenu(event, currentNode);
854
- }, {
1005
+ if (!currentNode) {
1006
+ const currentLink = linkByPointerGetter({
1007
+ graphSettings: this.graphSettings,
1008
+ areaRect: this.areaRect,
1009
+ areaTransform: this.areaTransform,
1010
+ mouseEvent: event,
1011
+ links: this.links,
1012
+ });
1013
+ return void this.listeners.onClick(event, undefined, currentLink);
1014
+ }
1015
+ return void this.listeners.onClick(event, currentNode, undefined);
1016
+ }
1017
+ /** hover */
1018
+ this.area.addEventListener("mousemove", onHover.bind(this), {
1019
+ signal: this.eventAbortController.signal,
1020
+ });
1021
+ this.area.addEventListener("touchmove", onHover.bind(this), {
1022
+ signal: this.eventAbortController.signal,
1023
+ });
1024
+ /** dblclick */
1025
+ this.area.addEventListener("dblclick", onDoubleClick.bind(this), {
1026
+ signal: this.eventAbortController.signal,
1027
+ });
1028
+ /** wheel click */
1029
+ this.area.addEventListener("mousedown", onWheelClick.bind(this), {
1030
+ signal: this.eventAbortController.signal,
1031
+ });
1032
+ /** click */
1033
+ this.area.addEventListener("click", onClick.bind(this), {
1034
+ signal: this.eventAbortController.signal,
1035
+ });
1036
+ /** right click */
1037
+ this.area.addEventListener("contextmenu", onRightClick.bind(this), {
855
1038
  signal: this.eventAbortController.signal,
856
1039
  });
857
1040
  }
858
1041
  initDnd() {
859
1042
  if (!this.area || !this.nodes || !this.simulation)
860
1043
  throw new Error("bad init data");
861
- select(this.area).call(drag()
1044
+ const dragHandler = drag()
862
1045
  .subject((event) => {
863
1046
  if (this.listeners.onDragSubject) {
864
1047
  return this.listeners.onDragSubject(event, this.state);
@@ -920,7 +1103,8 @@ class GraphCanvas {
920
1103
  event.subject.fy = null;
921
1104
  }
922
1105
  this.listeners.onEndDragFinished?.(event, this.state);
923
- }));
1106
+ });
1107
+ select(this.area).call(dragHandler);
924
1108
  }
925
1109
  initZoom(currentZoom) {
926
1110
  if (!this.area)