@krainovsd/graph 0.6.0 → 0.7.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.
package/lib/cjs/index.cjs CHANGED
@@ -196,6 +196,8 @@ function linkSettingsGetter(settings) {
196
196
  function linkOptionsGetter(_, __, ___, state) {
197
197
  return {
198
198
  ...LINK_SETTINGS,
199
+ drawExtraLink: null,
200
+ drawLink: null,
199
201
  color: state?.areaTransform && state?.areaTransform.k > COMMON_SETTINGS.linkColorZoomBorder
200
202
  ? COMMON_SETTINGS.linkColorZoomNear
201
203
  : COMMON_SETTINGS.linkColorZoomFar,
@@ -220,6 +222,10 @@ function nodeOptionsGetter(node, _, __, state) {
220
222
  const { textShiftY, textSize } = nodeTextSizeGetter(state?.areaTransform);
221
223
  return {
222
224
  ...NODE_SETTINGS,
225
+ nodeDraw: null,
226
+ nodeExtraDraw: null,
227
+ textDraw: null,
228
+ textExtraDraw: null,
223
229
  color: color(String(node.group ?? "_DEFAULT")),
224
230
  textVisible: Boolean(state?.areaTransform && state.areaTransform.k > COMMON_SETTINGS.nodeTextScaleMin),
225
231
  text: node.name ?? node.id.toString(),
@@ -738,8 +744,9 @@ class GraphCanvas {
738
744
  function draw() {
739
745
  if (!this.context)
740
746
  return;
747
+ const state = this.state;
741
748
  if (this.listeners.onDraw) {
742
- this.listeners.onDraw(this.state, (status) => {
749
+ this.listeners.onDraw(state, (status) => {
743
750
  this.highlightDrawing = status;
744
751
  }, () => {
745
752
  if (this.highlightedNeighbors)
@@ -755,158 +762,216 @@ class GraphCanvas {
755
762
  this.context.scale(this.areaTransform.k, this.areaTransform.k);
756
763
  /** links */
757
764
  this.context.beginPath();
758
- this.links.forEach(drawLink.bind(this));
765
+ this.links.forEach(getDrawLink(state).bind(this));
759
766
  this.context.stroke();
760
767
  /** nodes */
761
768
  const textRenders = [];
762
- this.nodes.forEach(drawNode(textRenders).bind(this));
769
+ this.nodes.forEach(getDrawNode(textRenders, state).bind(this));
763
770
  textRenders.forEach((render) => render());
764
771
  this.context.restore();
765
- this.listeners.onDrawFinished?.(this.state);
772
+ this.listeners.onDrawFinished?.(state);
766
773
  calculateHighlightFading.bind(this)();
767
774
  }
768
- function drawLink(link, index) {
769
- if (!this.context ||
770
- typeof link.source !== "object" ||
771
- typeof link.target !== "object" ||
772
- !link.source.x ||
773
- !link.source.y ||
774
- !link.target.x ||
775
- !link.target.y)
776
- return;
777
- const linkOptions = linkIterationExtractor(link, index, this.links, this.state, this.linkSettings.options ?? {}, linkOptionsGetter);
778
- let alpha = linkOptions.alpha;
779
- if (this.highlightedNeighbors && this.highlightedNode) {
780
- /** Not highlighted */
781
- if (this.highlightedNode.id != link.source.id &&
782
- this.highlightedNode.id != link.target.id) {
783
- if (linkOptions.highlightFading)
784
- alpha =
785
- this.graphSettings.highlightLinkFadingMin +
786
- (alpha - this.graphSettings.highlightLinkFadingMin) * (1 - this.highlightProgress);
775
+ function getDrawLink(state) {
776
+ return function drawLink(link, index) {
777
+ if (!this.context ||
778
+ typeof link.source !== "object" ||
779
+ typeof link.target !== "object" ||
780
+ !link.source.x ||
781
+ !link.source.y ||
782
+ !link.target.x ||
783
+ !link.target.y)
784
+ return;
785
+ const linkOptions = linkIterationExtractor(link, index, this.links, state, this.linkSettings.options ?? {}, linkOptionsGetter);
786
+ if (linkOptions.drawLink) {
787
+ linkOptions.drawLink(link, linkOptions, state);
788
+ return;
787
789
  }
788
- this.context.beginPath();
789
- }
790
- this.context.globalAlpha = alpha;
791
- this.context.strokeStyle = linkOptions.color;
792
- this.context.lineWidth = linkOptions.width;
793
- if (linkOptions.pretty) {
794
- const { x1, x2, y1, y2 } = calculateLinkPositionByRadius(link) ?? {
795
- x1: 0,
796
- x2: 0,
797
- y1: 0,
798
- y2: 0,
799
- };
800
- this.context.moveTo(x1, y1);
801
- this.context.lineTo(x2, y2);
802
- }
803
- else {
804
- this.context.moveTo(link.source.x, link.source.y);
805
- this.context.lineTo(link.target.x, link.target.y);
806
- }
807
- if (this.highlightedNeighbors && this.highlightedNode)
808
- this.context.stroke();
809
- }
810
- const drawNode = (textRenders) => function drawNode(node, index) {
811
- if (!this.context || !node.x || !node.y)
812
- return;
813
- const nodeOptions = nodeIterationExtractor(node, index, this.nodes, this.state, this.nodeSettings.options ?? {}, nodeOptionsGetter);
814
- let alpha = nodeOptions.alpha;
815
- let color = nodeOptions.color;
816
- let radiusInitial = nodeOptions.radius ?? this.graphSettings.nodeRadiusInitial;
817
- let textAlpha = nodeOptions.textAlpha;
818
- let textSize = nodeOptions.textSize;
819
- let textShiftX = nodeOptions.textShiftX;
820
- let textShiftY = nodeOptions.textShiftY;
821
- let textWeight = nodeOptions.textWeight;
822
- let textWidth = nodeOptions.textWidth;
823
- if (this.highlightedNeighbors && this.highlightedNode) {
824
- /** Not highlighted */
825
- if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
826
- if (nodeOptions.highlightFading) {
827
- alpha =
828
- this.graphSettings.highlightFadingMin +
829
- (alpha - this.graphSettings.highlightFadingMin) * (1 - this.highlightProgress);
790
+ let alpha = linkOptions.alpha;
791
+ if (this.highlightedNeighbors && this.highlightedNode) {
792
+ /** Not highlighted */
793
+ if (this.highlightedNode.id != link.source.id &&
794
+ this.highlightedNode.id != link.target.id) {
795
+ if (linkOptions.highlightFading)
796
+ alpha =
797
+ this.graphSettings.highlightLinkFadingMin +
798
+ (alpha - this.graphSettings.highlightLinkFadingMin) * (1 - this.highlightProgress);
830
799
  }
831
- if (nodeOptions.highlightTextFading) {
832
- textAlpha =
833
- this.graphSettings.highlightTextFadingMin +
834
- (textAlpha - this.graphSettings.highlightTextFadingMin) *
835
- (1 - this.highlightProgress);
800
+ this.context.beginPath();
801
+ }
802
+ this.context.globalAlpha = alpha;
803
+ this.context.strokeStyle = linkOptions.color;
804
+ this.context.lineWidth = linkOptions.width;
805
+ if (linkOptions.pretty) {
806
+ const { x1, x2, y1, y2 } = calculateLinkPositionByRadius(link) ?? {
807
+ x1: 0,
808
+ x2: 0,
809
+ y1: 0,
810
+ y2: 0,
811
+ };
812
+ this.context.moveTo(x1, y1);
813
+ this.context.lineTo(x2, y2);
814
+ }
815
+ else {
816
+ this.context.moveTo(link.source.x, link.source.y);
817
+ this.context.lineTo(link.target.x, link.target.y);
818
+ }
819
+ if (this.highlightedNeighbors && this.highlightedNode)
820
+ this.context.stroke();
821
+ if (linkOptions.drawExtraLink) {
822
+ linkOptions.drawExtraLink(link, { ...linkOptions, alpha }, state);
823
+ }
824
+ };
825
+ }
826
+ function getDrawNode(textRenders, state) {
827
+ return function drawNode(node, index) {
828
+ if (!this.context || !node.x || !node.y)
829
+ return;
830
+ const nodeOptions = nodeIterationExtractor(node, index, this.nodes, state, this.nodeSettings.options ?? {}, nodeOptionsGetter);
831
+ if (nodeOptions.nodeDraw) {
832
+ nodeOptions.nodeDraw(node, nodeOptions, state);
833
+ return;
834
+ }
835
+ let alpha = nodeOptions.alpha;
836
+ let color = nodeOptions.color;
837
+ let radiusInitial = nodeOptions.radius ?? this.graphSettings.nodeRadiusInitial;
838
+ let textAlpha = nodeOptions.textAlpha;
839
+ let textSize = nodeOptions.textSize;
840
+ let textShiftX = nodeOptions.textShiftX;
841
+ let textShiftY = nodeOptions.textShiftY;
842
+ let textWeight = nodeOptions.textWeight;
843
+ let textWidth = nodeOptions.textWidth;
844
+ if (this.highlightedNeighbors && this.highlightedNode) {
845
+ /** Not highlighted */
846
+ if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
847
+ if (nodeOptions.highlightFading) {
848
+ alpha =
849
+ this.graphSettings.highlightFadingMin +
850
+ (alpha - this.graphSettings.highlightFadingMin) * (1 - this.highlightProgress);
851
+ }
852
+ if (nodeOptions.highlightTextFading) {
853
+ textAlpha =
854
+ this.graphSettings.highlightTextFadingMin +
855
+ (textAlpha - this.graphSettings.highlightTextFadingMin) *
856
+ (1 - this.highlightProgress);
857
+ }
858
+ if (nodeOptions.highlightColor) {
859
+ const colorRgb = extractRgb(colorToRgb(color));
860
+ if (colorRgb) {
861
+ const colorRgbFade = fadeRgb(colorRgb, this.graphSettings.highlightColorFadingMin);
862
+ const colorFadeAnimation = rgbAnimationByProgress(colorRgb, colorRgbFade, this.highlightProgress);
863
+ color = `rgb(${colorFadeAnimation.r}, ${colorFadeAnimation.g}, ${colorFadeAnimation.b})`;
864
+ }
865
+ }
836
866
  }
837
- if (nodeOptions.highlightColor) {
838
- const colorRgb = extractRgb(colorToRgb(color));
839
- if (colorRgb) {
840
- const colorRgbFade = fadeRgb(colorRgb, this.graphSettings.highlightColorFadingMin);
841
- const colorFadeAnimation = rgbAnimationByProgress(colorRgb, colorRgbFade, this.highlightProgress);
842
- color = `rgb(${colorFadeAnimation.r}, ${colorFadeAnimation.g}, ${colorFadeAnimation.b})`;
867
+ else if (!this.graphSettings.highlightOnlyRoot ||
868
+ (this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
869
+ /** Highlighted */
870
+ if (nodeOptions.highlightSizing) {
871
+ const radiusMax = radiusInitial + this.graphSettings.highlightSizingAdditional;
872
+ radiusInitial += ((radiusMax - radiusInitial) / 100) * (this.highlightProgress * 100);
873
+ }
874
+ if (nodeOptions.highlightTextSizing) {
875
+ const textSizeMax = textSize + this.graphSettings.highlightTextSizingAdditional;
876
+ const textShiftXMax = textShiftX + this.graphSettings.highlightTextShiftXAdditional;
877
+ const textShiftYMax = textShiftY + this.graphSettings.highlightTextShiftYAdditional;
878
+ const textWeightMax = textWeight + this.graphSettings.highlightTextWeightAdditional;
879
+ const textWidthMax = textWidth + this.graphSettings.highlightTextWidthAdditional;
880
+ textSize += ((textSizeMax - textSize) / 100) * (this.highlightProgress * 100);
881
+ textShiftX += ((textShiftXMax - textShiftX) / 100) * (this.highlightProgress * 100);
882
+ textShiftY += ((textShiftYMax - textShiftY) / 100) * (this.highlightProgress * 100);
883
+ textWeight += ((textWeightMax - textWeight) / 100) * (this.highlightProgress * 100);
884
+ textWidth += ((textWidthMax - textWidth) / 100) * (this.highlightProgress * 100);
843
885
  }
844
886
  }
845
887
  }
846
- else if (!this.graphSettings.highlightOnlyRoot ||
847
- (this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
848
- /** Highlighted */
849
- if (nodeOptions.highlightSizing) {
850
- const radiusMax = radiusInitial + this.graphSettings.highlightSizingAdditional;
851
- radiusInitial += ((radiusMax - radiusInitial) / 100) * (this.highlightProgress * 100);
852
- }
853
- if (nodeOptions.highlightTextSizing) {
854
- const textSizeMax = textSize + this.graphSettings.highlightTextSizingAdditional;
855
- const textShiftXMax = textShiftX + this.graphSettings.highlightTextShiftXAdditional;
856
- const textShiftYMax = textShiftY + this.graphSettings.highlightTextShiftYAdditional;
857
- const textWeightMax = textWeight + this.graphSettings.highlightTextWeightAdditional;
858
- const textWidthMax = textWidth + this.graphSettings.highlightTextWidthAdditional;
859
- textSize += ((textSizeMax - textSize) / 100) * (this.highlightProgress * 100);
860
- textShiftX += ((textShiftXMax - textShiftX) / 100) * (this.highlightProgress * 100);
861
- textShiftY += ((textShiftYMax - textShiftY) / 100) * (this.highlightProgress * 100);
862
- textWeight += ((textWeightMax - textWeight) / 100) * (this.highlightProgress * 100);
863
- textWidth += ((textWidthMax - textWidth) / 100) * (this.highlightProgress * 100);
864
- }
888
+ const radius = nodeRadiusGetter({
889
+ radiusFlexible: this.graphSettings.nodeRadiusFlexible,
890
+ radiusInitial,
891
+ radiusCoefficient: this.graphSettings.nodeRadiusCoefficient,
892
+ radiusFactor: this.graphSettings.nodeRadiusFactor,
893
+ linkCount: node.linkCount,
894
+ });
895
+ node._radius = radius;
896
+ this.context.beginPath();
897
+ this.context.globalAlpha = alpha;
898
+ /** text */
899
+ if (nodeOptions.textVisible && nodeOptions.text) {
900
+ textRenders.push(() => {
901
+ if (nodeOptions.textDraw) {
902
+ nodeOptions.textDraw(node, {
903
+ ...nodeOptions,
904
+ radius,
905
+ alpha,
906
+ color,
907
+ textAlpha,
908
+ textSize,
909
+ textShiftX,
910
+ textShiftY,
911
+ textWeight,
912
+ textWidth,
913
+ }, state);
914
+ return;
915
+ }
916
+ if (!this.context || !node.x || !node.y || !nodeOptions.text)
917
+ return;
918
+ this.context.beginPath();
919
+ this.context.globalAlpha = textAlpha;
920
+ drawText({
921
+ id: node.id,
922
+ cachedNodeText: this.cachedNodeText,
923
+ context: this.context,
924
+ text: nodeOptions.text,
925
+ textAlign: nodeOptions.textAlign,
926
+ textColor: nodeOptions.textColor,
927
+ textFont: nodeOptions.textFont,
928
+ textSize,
929
+ x: node.x + textShiftX,
930
+ y: node.y + radius + textShiftY,
931
+ maxWidth: textWidth,
932
+ textStyle: nodeOptions.textStyle,
933
+ textWeight,
934
+ textGap: nodeOptions.textGap,
935
+ });
936
+ if (nodeOptions.textExtraDraw) {
937
+ nodeOptions.textExtraDraw(node, {
938
+ ...nodeOptions,
939
+ radius,
940
+ alpha,
941
+ color,
942
+ textAlpha,
943
+ textSize,
944
+ textShiftX,
945
+ textShiftY,
946
+ textWeight,
947
+ textWidth,
948
+ }, state);
949
+ }
950
+ });
865
951
  }
866
- }
867
- const radius = nodeRadiusGetter({
868
- radiusFlexible: this.graphSettings.nodeRadiusFlexible,
869
- radiusInitial,
870
- radiusCoefficient: this.graphSettings.nodeRadiusCoefficient,
871
- radiusFactor: this.graphSettings.nodeRadiusFactor,
872
- linkCount: node.linkCount,
873
- });
874
- node._radius = radius;
875
- this.context.beginPath();
876
- this.context.globalAlpha = alpha;
877
- /** text */
878
- if (nodeOptions.textVisible && nodeOptions.text) {
879
- textRenders.push(() => {
880
- if (!this.context || !node.x || !node.y || !nodeOptions.text)
881
- return;
882
- this.context.beginPath();
883
- this.context.globalAlpha = textAlpha;
884
- drawText({
885
- id: node.id,
886
- cachedNodeText: this.cachedNodeText,
887
- context: this.context,
888
- text: nodeOptions.text,
889
- textAlign: nodeOptions.textAlign,
890
- textColor: nodeOptions.textColor,
891
- textFont: nodeOptions.textFont,
952
+ /** circle */
953
+ this.context.lineWidth = nodeOptions.borderWidth;
954
+ this.context.strokeStyle = nodeOptions.borderColor;
955
+ this.context.fillStyle = color;
956
+ this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
957
+ this.context.fill();
958
+ this.context.stroke();
959
+ if (nodeOptions.nodeExtraDraw) {
960
+ nodeOptions.nodeExtraDraw(node, {
961
+ ...nodeOptions,
962
+ radius,
963
+ alpha,
964
+ color,
965
+ textAlpha,
892
966
  textSize,
893
- x: node.x + textShiftX,
894
- y: node.y + radius + textShiftY,
895
- maxWidth: textWidth,
896
- textStyle: nodeOptions.textStyle,
967
+ textShiftX,
968
+ textShiftY,
897
969
  textWeight,
898
- textGap: nodeOptions.textGap,
899
- });
900
- });
901
- }
902
- /** circle */
903
- this.context.lineWidth = nodeOptions.borderWidth;
904
- this.context.strokeStyle = nodeOptions.borderColor;
905
- this.context.fillStyle = color;
906
- this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
907
- this.context.fill();
908
- this.context.stroke();
909
- };
970
+ textWidth,
971
+ }, state);
972
+ }
973
+ };
974
+ }
910
975
  return draw;
911
976
  }
912
977
  initResize() {
@@ -1116,7 +1181,7 @@ class GraphCanvas {
1116
1181
  const [coefficientX, coefficientY] = jsHelpers.isArray(coefficient)
1117
1182
  ? coefficient
1118
1183
  : [coefficient, coefficient];
1119
- const [[minX = -this.width * coefficientX, minY = -this.height * coefficientX], [maxX = this.width * coefficientY, maxY = this.height * coefficientY],] = this.graphSettings.translateExtent;
1184
+ const [[minX = -this.width * coefficientX, minY = -this.height * coefficientY], [maxX = this.width * coefficientX, maxY = this.height * coefficientY],] = this.graphSettings.translateExtent;
1120
1185
  zoomInstance.translateExtent([
1121
1186
  [minX, minY],
1122
1187
  [maxX, maxY],