@unovis/ts 1.5.1-ql.2 → 1.5.1-xplg.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.
Files changed (118) hide show
  1. package/components/area/index.js +1 -1
  2. package/components/area/index.js.map +1 -1
  3. package/components/axis/config.d.ts +1 -1
  4. package/components/axis/config.js.map +1 -1
  5. package/components/axis/index.d.ts +0 -1
  6. package/components/axis/index.js +2 -10
  7. package/components/axis/index.js.map +1 -1
  8. package/components/brush/config.d.ts +1 -1
  9. package/components/brush/config.js.map +1 -1
  10. package/components/donut/config.d.ts +4 -0
  11. package/components/donut/config.js +1 -1
  12. package/components/donut/config.js.map +1 -1
  13. package/components/donut/constants.d.ts +2 -0
  14. package/components/donut/constants.js +8 -0
  15. package/components/donut/constants.js.map +1 -0
  16. package/components/donut/index.js +35 -5
  17. package/components/donut/index.js.map +1 -1
  18. package/components/graph/config.d.ts +28 -4
  19. package/components/graph/config.js +5 -2
  20. package/components/graph/config.js.map +1 -1
  21. package/components/graph/index.d.ts +12 -9
  22. package/components/graph/index.js +48 -25
  23. package/components/graph/index.js.map +1 -1
  24. package/components/graph/modules/layout-helpers.js +1 -1
  25. package/components/graph/modules/layout-helpers.js.map +1 -1
  26. package/components/graph/modules/layout.js +1 -1
  27. package/components/graph/modules/layout.js.map +1 -1
  28. package/components/graph/modules/link/index.d.ts +3 -2
  29. package/components/graph/modules/link/index.js +53 -28
  30. package/components/graph/modules/link/index.js.map +1 -1
  31. package/components/graph/modules/link/style.js +4 -3
  32. package/components/graph/modules/link/style.js.map +1 -1
  33. package/components/graph/modules/node/index.d.ts +2 -0
  34. package/components/graph/modules/node/index.js +7 -4
  35. package/components/graph/modules/node/index.js.map +1 -1
  36. package/components/graph/modules/panel/index.js +2 -2
  37. package/components/graph/modules/panel/index.js.map +1 -1
  38. package/components/graph/types.d.ts +5 -0
  39. package/components/graph/types.js.map +1 -1
  40. package/components/nested-donut/config.d.ts +1 -1
  41. package/components/nested-donut/config.js.map +1 -1
  42. package/components/stacked-bar/index.js +7 -5
  43. package/components/stacked-bar/index.js.map +1 -1
  44. package/components/stacked-bar/types.d.ts +1 -1
  45. package/components/timeline/config.d.ts +65 -14
  46. package/components/timeline/config.js +15 -1
  47. package/components/timeline/config.js.map +1 -1
  48. package/components/timeline/constants.d.ts +3 -0
  49. package/components/timeline/constants.js +6 -0
  50. package/components/timeline/constants.js.map +1 -0
  51. package/components/timeline/index.d.ts +21 -10
  52. package/components/timeline/index.js +375 -93
  53. package/components/timeline/index.js.map +1 -1
  54. package/components/timeline/style.d.ts +7 -0
  55. package/components/timeline/style.js +40 -1
  56. package/components/timeline/style.js.map +1 -1
  57. package/components/timeline/types.d.ts +62 -0
  58. package/components/timeline/types.js +2 -0
  59. package/components/timeline/types.js.map +1 -0
  60. package/components/timeline/utils.d.ts +2 -0
  61. package/components/timeline/utils.js +16 -0
  62. package/components/timeline/utils.js.map +1 -0
  63. package/components/treemap/config.d.ts +44 -0
  64. package/components/treemap/config.js +6 -0
  65. package/components/treemap/config.js.map +1 -0
  66. package/components/treemap/index.d.ts +16 -0
  67. package/components/treemap/index.js +263 -0
  68. package/components/treemap/index.js.map +1 -0
  69. package/components/treemap/style.d.ts +22 -0
  70. package/components/treemap/style.js +62 -0
  71. package/components/treemap/style.js.map +1 -0
  72. package/components/treemap/types.d.ts +11 -0
  73. package/components/treemap/types.js +2 -0
  74. package/components/treemap/types.js.map +1 -0
  75. package/components.d.ts +3 -0
  76. package/components.js +2 -0
  77. package/components.js.map +1 -1
  78. package/containers/single-container/config.d.ts +3 -0
  79. package/containers/single-container/config.js.map +1 -1
  80. package/containers/single-container/index.js +2 -1
  81. package/containers/single-container/index.js.map +1 -1
  82. package/containers/xy-container/config.d.ts +5 -0
  83. package/containers/xy-container/config.js +1 -1
  84. package/containers/xy-container/config.js.map +1 -1
  85. package/containers/xy-container/index.d.ts +1 -0
  86. package/containers/xy-container/index.js +15 -11
  87. package/containers/xy-container/index.js.map +1 -1
  88. package/data-models/graph.d.ts +3 -2
  89. package/data-models/graph.js +15 -6
  90. package/data-models/graph.js.map +1 -1
  91. package/data-models/index.d.ts +4 -0
  92. package/data-models/index.js +5 -0
  93. package/data-models/index.js.map +1 -0
  94. package/index.d.ts +1 -0
  95. package/index.js +10 -3
  96. package/index.js.map +1 -1
  97. package/package.json +4 -5
  98. package/types/data.d.ts +1 -2
  99. package/types/graph.d.ts +4 -0
  100. package/types/position.d.ts +2 -1
  101. package/types/position.js +1 -0
  102. package/types/position.js.map +1 -1
  103. package/types.d.ts +2 -0
  104. package/types.js +2 -0
  105. package/types.js.map +1 -1
  106. package/utils/color.d.ts +14 -0
  107. package/utils/color.js +26 -2
  108. package/utils/color.js.map +1 -1
  109. package/utils/data.d.ts +2 -2
  110. package/utils/data.js +10 -17
  111. package/utils/data.js.map +1 -1
  112. package/utils/index.js +3 -3
  113. package/utils/path.d.ts +8 -0
  114. package/utils/path.js +109 -1
  115. package/utils/path.js.map +1 -1
  116. package/utils/text.d.ts +10 -9
  117. package/utils/text.js +26 -10
  118. package/utils/text.js.map +1 -1
@@ -2,9 +2,11 @@ import { D3BrushEvent } from 'd3-brush';
2
2
  import { D3DragEvent } from 'd3-drag';
3
3
  import { D3ZoomEvent, ZoomTransform } from 'd3-zoom';
4
4
  import { Selection } from 'd3-selection';
5
+ import { ElkShape } from 'elkjs';
6
+ import type { GraphDataModel } from "../../data-models/graph";
5
7
  import { ComponentConfigInterface } from "../../core/component/config";
6
8
  import { TrimMode } from "../../types/text";
7
- import { GraphInputLink, GraphInputNode } from "../../types/graph";
9
+ import { GraphInputLink, GraphInputNode, GraphInputData } from "../../types/graph";
8
10
  import { BooleanAccessor, ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from "../../types/accessor";
9
11
  import { GraphLayoutType, GraphCircleLabel, GraphLinkStyle, GraphLinkArrowStyle, GraphPanelConfig, GraphForceLayoutSettings, GraphElkLayoutSettings, GraphNodeShape, GraphDagreLayoutSetting, GraphNode, GraphLink, GraphNodeSelectionHighlightMode } from './types';
10
12
  export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphInputLink> extends ComponentConfigInterface {
@@ -79,6 +81,12 @@ export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphI
79
81
  * E.g.: `[n => n.group, n => n.subGroup]`.
80
82
  * Default: `undefined` */
81
83
  layoutElkNodeGroups?: StringAccessor<N>[];
84
+ /** A function to be called per graph node to get the ELK shape object.
85
+ * This enables you to provide custom node dimensions (through the `width` and `height` properties)
86
+ * and coordinates (through the `x` and `y` properties) if needed.
87
+ * Default: `undefined`
88
+ */
89
+ layoutElkGetNodeShape?: (d: GraphNode<N, L>, i: number) => ElkShape;
82
90
  /** Link width accessor function ot constant value. Default: `1` */
83
91
  linkWidth?: NumericAccessor<L>;
84
92
  /** Link style accessor function or constant value. Default: `GraphLinkStyle.Solid` */
@@ -93,10 +101,13 @@ export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphI
93
101
  linkDisabled?: BooleanAccessor<L>;
94
102
  /** Link flow animation accessor function or constant value. Default: `false` */
95
103
  linkFlow?: BooleanAccessor<L>;
96
- /** Animation duration of the flow (traffic) circles. Default: `20000` */
97
- linkFlowAnimDuration?: number;
104
+ /** Animation duration of the flow (traffic) circles in milliseconds. If `linkFlowParticleSpeed` is provided,
105
+ * this duration will be calculated based on the link length and particle speed. Default: `20000` */
106
+ linkFlowAnimDuration?: NumericAccessor<L>;
98
107
  /** Size of the moving particles that represent traffic flow. Default: `2` */
99
- linkFlowParticleSize?: number;
108
+ linkFlowParticleSize?: NumericAccessor<L>;
109
+ /** Speed of the moving particles in pixels per second. This property takes precedence over `linkFlowAnimDuration`. Default: `undefined` */
110
+ linkFlowParticleSpeed?: NumericAccessor<L>;
100
111
  /** Link label accessor function or constant value. Default: `undefined` */
101
112
  linkLabel?: GenericAccessor<GraphCircleLabel | GraphCircleLabel[], L> | undefined;
102
113
  /** Shift label along the link center a little bit to avoid overlap with the link arrow. Default: `true` */
@@ -109,6 +120,12 @@ export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphI
109
120
  * `1.5` - very curve.
110
121
  * Default: `0` */
111
122
  linkCurvature?: NumericAccessor<L>;
123
+ /** Highlight links on hover. Default: `true` */
124
+ linkHighlightOnHover?: boolean;
125
+ /** Offset [x,y] in pixels from the source node's center point where the link should start. Default: `undefined` */
126
+ linkSourcePointOffset?: GenericAccessor<[number, number], GraphLink<N, L>>;
127
+ /** Offset [x,y] in pixels from the target node's center point where the link should end. Default: `undefined` */
128
+ linkTargetPointOffset?: GenericAccessor<[number, number], GraphLink<N, L>>;
112
129
  /** Set selected link by its unique id. Default: `undefined` */
113
130
  selectedLinkId?: number | string;
114
131
  /** Node size accessor function or constant value. Default: `30` */
@@ -206,5 +223,12 @@ export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphI
206
223
  onNodeSelectionDrag?: (selectedNodes: GraphNode<N, L>[], event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void;
207
224
  /** Callback function to be called when the graph rendering is complete. Default: `undefined` */
208
225
  onRenderComplete?: (g: Selection<SVGGElement, unknown, null, undefined>, nodes: GraphNode<N, L>[], links: GraphLink<N, L>[], config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number, width: number, height: number) => void;
226
+ /** Determines whether the component should update when new data is provided.
227
+ * This function takes the previous and new data as parameters and returns a boolean
228
+ * indicating whether the update should proceed. Useful for fine-grained control over
229
+ * update behavior when your data has a complex nested structure.
230
+ * By default the `isEqual` function from Unovis will be used to do the comparison.
231
+ */
232
+ shouldDataUpdate?: (prevData: GraphInputData<N, L>, nextData: GraphInputData<N, L>, datamodel: GraphDataModel<N, L, GraphNode<N, L>, GraphLink<N, L>>) => boolean;
209
233
  }
210
234
  export declare const GraphDefaultConfig: GraphConfigInterface<GraphInputNode, GraphInputLink>;
@@ -1,8 +1,9 @@
1
+ import { isEqual } from '../../utils/data.js';
1
2
  import { ComponentDefaultConfig } from '../../core/component/config.js';
2
3
  import { TrimMode } from '../../types/text.js';
3
4
  import { GraphLayoutType, GraphLinkStyle, GraphNodeShape, GraphNodeSelectionHighlightMode } from './types.js';
4
5
 
5
- // Config
6
+ // Utils
6
7
  const GraphDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfig), { duration: 1000, zoomScaleExtent: [0.35, 1.25], disableZoom: false, zoomEventFilter: undefined, disableDrag: false, disableBrush: false, zoomThrottledUpdateNodeThreshold: 100, layoutType: GraphLayoutType.Force, layoutAutofit: true, layoutAutofitTolerance: 8.0, layoutNonConnectedAside: false, layoutGroupOrder: [], layoutParallelSubGroupsPerRow: 1, layoutParallelNodesPerColumn: 6, layoutParallelGroupSpacing: undefined, layoutParallelSortConnectionsByGroup: undefined, layoutNodeGroup: (n) => n.group, layoutParallelNodeSubGroup: (n) => n.subgroup, forceLayoutSettings: {
7
8
  linkDistance: 60,
8
9
  linkStrength: 0.45,
@@ -14,7 +15,9 @@ const GraphDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfi
14
15
  }, dagreLayoutSettings: {
15
16
  rankdir: 'BT',
16
17
  ranker: 'longest-path',
17
- }, layoutElkSettings: undefined, layoutElkNodeGroups: undefined, linkFlowAnimDuration: 20000, linkFlowParticleSize: 2, linkWidth: 1, linkStyle: GraphLinkStyle.Solid, linkBandWidth: 0, linkArrow: undefined, linkStroke: undefined, linkFlow: false, linkLabel: undefined, linkLabelShiftFromCenter: true, linkNeighborSpacing: 8, linkDisabled: false, linkCurvature: 0, selectedLinkId: undefined, nodeGaugeAnimDuration: 1500, nodeSize: 30, nodeStrokeWidth: 3, nodeShape: GraphNodeShape.Circle, nodeGaugeValue: 0, nodeIcon: (n) => n.icon, nodeIconSize: undefined, nodeLabel: (n) => n.label, nodeLabelTrim: true, nodeLabelTrimLength: 15, nodeLabelTrimMode: TrimMode.Middle, nodeSubLabel: '', nodeSubLabelTrim: true, nodeSubLabelTrimLength: 15, nodeSubLabelTrimMode: TrimMode.Middle, nodeSideLabels: undefined, nodeBottomIcon: undefined, nodeDisabled: false, nodeFill: (n) => n.fill, nodeGaugeFill: undefined, nodeStroke: (n) => n.stroke, nodeEnterPosition: undefined, nodeEnterScale: 0.75, nodeExitPosition: undefined, nodeExitScale: 0.75, nodeSort: undefined, nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected, selectedNodeId: undefined, selectedNodeIds: undefined, panels: undefined, onNodeDragStart: undefined, onNodeDrag: undefined, onNodeDragEnd: undefined, onZoom: undefined, onZoomStart: undefined, onZoomEnd: undefined, onLayoutCalculated: undefined, onNodeSelectionBrush: undefined, onNodeSelectionDrag: undefined, onRenderComplete: undefined });
18
+ }, layoutElkSettings: undefined, layoutElkNodeGroups: undefined, layoutElkGetNodeShape: undefined, linkFlowAnimDuration: 20000, linkFlowParticleSize: 2, linkFlowParticleSpeed: undefined, linkWidth: 1, linkStyle: GraphLinkStyle.Solid, linkBandWidth: 0, linkArrow: undefined, linkStroke: undefined, linkFlow: false, linkLabel: undefined, linkLabelShiftFromCenter: true, linkNeighborSpacing: 8, linkDisabled: false, linkCurvature: 0, linkHighlightOnHover: true, linkSourcePointOffset: undefined, linkTargetPointOffset: undefined, selectedLinkId: undefined, nodeSize: 30, nodeStrokeWidth: 3, nodeShape: GraphNodeShape.Circle, nodeGaugeValue: 0, nodeIcon: (n) => n.icon, nodeIconSize: undefined, nodeLabel: (n) => n.label, nodeLabelTrim: true, nodeLabelTrimLength: 15, nodeLabelTrimMode: TrimMode.Middle, nodeSubLabel: '', nodeSubLabelTrim: true, nodeSubLabelTrimLength: 15, nodeSubLabelTrimMode: TrimMode.Middle, nodeSideLabels: undefined, nodeBottomIcon: undefined, nodeDisabled: false, nodeFill: (n) => n.fill, nodeGaugeFill: undefined, nodeStroke: (n) => n.stroke, nodeEnterPosition: undefined, nodeEnterScale: 0.75, nodeExitPosition: undefined, nodeExitScale: 0.75, nodeSort: undefined, nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected, nodeGaugeAnimDuration: 1500, selectedNodeId: undefined, selectedNodeIds: undefined, panels: undefined, onNodeDragStart: undefined, onNodeDrag: undefined, onNodeDragEnd: undefined, onZoom: undefined, onZoomStart: undefined, onZoomEnd: undefined, onLayoutCalculated: undefined, onNodeSelectionBrush: undefined, onNodeSelectionDrag: undefined, onRenderComplete: undefined, shouldDataUpdate: (prevData, nextData) => {
19
+ return !isEqual(prevData, nextData);
20
+ } });
18
21
 
19
22
  export { GraphDefaultConfig };
20
23
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../../src/components/graph/config.ts"],"sourcesContent":["import { D3BrushEvent } from 'd3-brush'\nimport { D3DragEvent } from 'd3-drag'\nimport { D3ZoomEvent, ZoomTransform } from 'd3-zoom'\nimport { Selection } from 'd3-selection'\n\n// Config\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Types\nimport { TrimMode } from 'types/text'\nimport { GraphInputLink, GraphInputNode } from 'types/graph'\nimport { BooleanAccessor, ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from 'types/accessor'\n\n// Local Types\nimport {\n GraphLayoutType,\n GraphCircleLabel,\n GraphLinkStyle,\n GraphLinkArrowStyle,\n GraphPanelConfig,\n GraphForceLayoutSettings,\n GraphElkLayoutSettings,\n GraphNodeShape,\n GraphDagreLayoutSetting,\n GraphNode,\n GraphLink,\n GraphNodeSelectionHighlightMode,\n} from './types'\n\n\nexport interface GraphConfigInterface<N extends GraphInputNode, L extends GraphInputLink> extends ComponentConfigInterface {\n // Zoom and drag\n /** Zoom level constraints. Default: [0.35, 1.25] */\n zoomScaleExtent?: [number, number];\n /** Disable zooming. Default: `false` */\n disableZoom?: boolean;\n /** Custom Zoom event filter to better control which actions should trigger zooming.\n * Learn more: https://d3js.org/d3-zoom#zoom_filter.\n * Default: `undefined` */\n zoomEventFilter?: (event: PointerEvent) => boolean;\n /** Disable node dragging. Default: `false` */\n disableDrag?: boolean;\n /** Disable brush for multiple node selection. Default: `false` */\n disableBrush?: boolean;\n /** Interval to re-render the graph when zooming. Default: `100` */\n zoomThrottledUpdateNodeThreshold?: number;\n\n // Layout general settings\n /** Type of the graph layout. Default: `GraphLayoutType.Force` */\n layoutType?: GraphLayoutType | string;\n /** Fit the graph to container on data or config updates, or on container resize. Default: `true` */\n layoutAutofit?: boolean;\n /** Tolerance constant defining whether the graph should be fitted to container\n * (on data or config update, or container resize) after a zoom / pan interaction or not.\n * `0` — Stop fitting after any pan or zoom\n * `Number.POSITIVE_INFINITY` — Always fit\n * Default: `8.0` */\n layoutAutofitTolerance?: number;\n /** Place non-connected nodes at the bottom of the graph. Default: `false` */\n layoutNonConnectedAside?: boolean;\n\n // Settings for Parallel and Concentric layouts\n /** Node group accessor function.\n * Only for `GraphLayoutType.Parallel`, `GraphLayoutType.ParallelHorizontal` and `GraphLayoutType.Concentric` layouts.\n * Default: `node => node.group` */\n layoutNodeGroup?: StringAccessor<N>;\n /** Order of the layout groups.\n * Only for `GraphLayoutType.Parallel`, `GraphLayoutType.ParallelHorizontal` and `GraphLayoutType.Concentric` layouts.\n * Default: `[]` */\n layoutGroupOrder?: string[];\n\n // Setting for Parallel layouts only\n /** Sets the number of nodes in a sub-group after which they'll continue on the next column (or row if `layoutType` is\n * `GraphLayoutType.ParallelHorizontal`).\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `6` */\n layoutParallelNodesPerColumn?: number;\n /** Node sub-group accessor function.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `node => node.subgroup` */\n layoutParallelNodeSubGroup?: StringAccessor<N>;\n /** Number of sub-groups per row (or column if `layoutType` is `GraphLayoutType.ParallelHorizontal`) in a group.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `1` */\n layoutParallelSubGroupsPerRow?: number;\n /** Spacing between groups.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `undefined` */\n layoutParallelGroupSpacing?: number;\n /** Set a group by name to have priority in sorting the graph links.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `undefined` */\n layoutParallelSortConnectionsByGroup?: string;\n\n // Force layout\n /** Force Layout settings, see the `d3-force` package for more details */\n forceLayoutSettings?: GraphForceLayoutSettings<N, L>;\n\n // Dagre layout\n /** Darge Layout settings, see the `dagrejs` package\n * for more details: https://github.com/dagrejs/dagre/wiki#configuring-the-layout\n */\n dagreLayoutSettings?: GraphDagreLayoutSetting;\n\n // ELK layout\n /** ELK layout options, see the `elkjs` package for more details: https://github.com/kieler/elkjs.\n * If you want to specify custom layout option for each node group, you can provide an accessor function that\n * receives group name ('root' for the top-level configuration) as the first argument and returns an object containing\n * layout options. Default: `undefined`\n */\n layoutElkSettings?: GenericAccessor<GraphElkLayoutSettings, string> | undefined;\n /** Array of accessor functions to define nested node groups for the ELK Layered layout.\n * E.g.: `[n => n.group, n => n.subGroup]`.\n * Default: `undefined` */\n layoutElkNodeGroups?: StringAccessor<N>[];\n\n // Links\n /** Link width accessor function ot constant value. Default: `1` */\n linkWidth?: NumericAccessor<L>;\n /** Link style accessor function or constant value. Default: `GraphLinkStyle.Solid` */\n linkStyle?: GenericAccessor<GraphLinkStyle, L>;\n /** Link band width accessor function or constant value. Default: `0` */\n linkBandWidth?: NumericAccessor<L>;\n /** Link arrow accessor function or constant value. Default: `undefined` */\n linkArrow?: GenericAccessor<GraphLinkArrowStyle | string | boolean, L> | undefined;\n /** Link stroke color accessor function or constant value. Default: `undefined` */\n linkStroke?: ColorAccessor<L>;\n /** Link disabled state accessor function or constant value. Default: `false` */\n linkDisabled?: BooleanAccessor<L>;\n /** Link flow animation accessor function or constant value. Default: `false` */\n linkFlow?: BooleanAccessor<L>;\n /** Animation duration of the flow (traffic) circles. Default: `20000` */\n linkFlowAnimDuration?: number;\n /** Size of the moving particles that represent traffic flow. Default: `2` */\n linkFlowParticleSize?: number;\n /** Link label accessor function or constant value. Default: `undefined` */\n linkLabel?: GenericAccessor<GraphCircleLabel | GraphCircleLabel[], L> | undefined;\n /** Shift label along the link center a little bit to avoid overlap with the link arrow. Default: `true` */\n linkLabelShiftFromCenter?: BooleanAccessor<L>;\n /** Spacing between neighboring links. Default: `8` */\n linkNeighborSpacing?: number;\n /** Curvature of the link. Recommended value range: [0:1.5].\n * `0` - straight line,\n * `1` - nice curvature,\n * `1.5` - very curve.\n * Default: `0` */\n linkCurvature?: NumericAccessor<L>;\n /** Set selected link by its unique id. Default: `undefined` */\n selectedLinkId?: number | string;\n\n // Nodes\n /** Node size accessor function or constant value. Default: `30` */\n nodeSize?: NumericAccessor<N>;\n /** Node stroke width accessor function or constant value. Default: `3` */\n nodeStrokeWidth?: NumericAccessor<N>;\n /** Node shape accessor function or constant value. Default: `GraphNodeShape.Circle` */\n nodeShape?: GenericAccessor<GraphNodeShape | string, N>;\n /** Node gauge outline accessor function or constant value in the range [0,100]. Default: `0` */\n nodeGaugeValue?: NumericAccessor<N>;\n /** Node gauge outline fill color accessor function or constant value. Default: `undefined` */\n nodeGaugeFill?: ColorAccessor<N>;\n /** Animation duration of the node gauge outline. Default: `1500` */\n nodeGaugeAnimDuration?: number;\n /** Node central icon accessor function or constant value. Default: `node => node.icon` */\n nodeIcon?: StringAccessor<N>;\n /** Node central icon size accessor function or constant value. Default: `undefined` */\n nodeIconSize?: NumericAccessor<N>;\n /** Node label accessor function or constant value. Default: `node => node.label` */\n nodeLabel?: StringAccessor<N>;\n /** Defines whether to trim the node labels or not. Default: `true` */\n nodeLabelTrim?: BooleanAccessor<N>;\n /** Node label trimming mode. Default: `TrimMode.Middle` */\n nodeLabelTrimMode?: GenericAccessor<TrimMode | string, N>;\n /** Node label maximum allowed text length above which the label will be trimmed. Default: `15` */\n nodeLabelTrimLength?: NumericAccessor<N>;\n /** Node sub-label accessor function or constant value: Default: `''` */\n nodeSubLabel?: StringAccessor<N>;\n /** Defines whether to trim the node sub-labels or not. Default: `true` */\n nodeSubLabelTrim?: BooleanAccessor<N>;\n /** Node sub-label trimming mode. Default: `TrimMode.Middle` */\n nodeSubLabelTrimMode?: GenericAccessor<TrimMode | string, N>;\n /** Node sub-label maximum allowed text length above which the label will be trimmed. Default: `15` */\n nodeSubLabelTrimLength?: NumericAccessor<N>;\n /** Node circular side labels accessor function. The function should return an array of GraphCircleLabel objects. Default: `undefined` */\n nodeSideLabels?: GenericAccessor<GraphCircleLabel[], N>;\n /** Node bottom icon accessor function. Default: `undefined` */\n nodeBottomIcon?: StringAccessor<N>;\n /** Node disabled state accessor function or constant value. Default: `false` */\n nodeDisabled?: BooleanAccessor<N>;\n /** Node fill color accessor function or constant value. Default: `node => node.fill` */\n nodeFill?: ColorAccessor<N>;\n /** Node stroke color accessor function or constant value. Default: `node => node.stroke` */\n nodeStroke?: ColorAccessor<N>;\n /** Sorting function to determine node placement. Default: `undefined` */\n nodeSort?: ((a: N, b: N) => number);\n /** Specify the initial position for entering nodes as [x, y]. Default: `undefined` */\n nodeEnterPosition?: GenericAccessor<[number, number], N> | undefined;\n /** Specify the initial scale for entering nodes in the range [0,1]. Default: `0.75` */\n nodeEnterScale?: NumericAccessor<N> | undefined;\n /** Specify the destination position for exiting nodes as [x, y]. Default: `undefined` */\n nodeExitPosition?: GenericAccessor<[number, number], N> | undefined;\n /** Specify the destination scale for exiting nodes in the range [0,1]. Default: `0.75` */\n nodeExitScale?: NumericAccessor<N> | undefined;\n /** Custom \"enter\" function for node rendering. Default: `undefined` */\n nodeEnterCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom \"update\" function for node rendering. Default: `undefined` */\n nodeUpdateCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom partial \"update\" function for node rendering which will be triggered after the following events:\n * - Full node update (`nodeUpdateCustomRenderFunction`);\n * - Background click;\n * - Node and Link mouseover and mouseout;\n * - Node brushing,\n * Default: `undefined` */\n nodePartialUpdateCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom \"exit\" function for node rendering. Default: `undefined` */\n nodeExitCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom render function that will be called while zooming / panning the graph. Default: `undefined` */\n nodeOnZoomCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, zoomLevel: number) => void;\n /** Define the mode for highlighting selected nodes in the graph. Default: `GraphNodeSelectionHighlightMode.GreyoutNonConnected` */\n nodeSelectionHighlightMode?: GraphNodeSelectionHighlightMode;\n /** Set selected node by unique id. Default: `undefined` */\n selectedNodeId?: number | string;\n /** Set selected nodes by unique id. Default: `undefined` */\n selectedNodeIds?: number[] | string[];\n\n /** Panels configuration. An array of `GraphPanelConfig` objects. Default: `[]` */\n panels?: GraphPanelConfig[] | undefined;\n\n // Events\n /** Graph node drag start callback function. Default: `undefined` */\n onNodeDragStart?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Graph node drag callback function. Default: `undefined` */\n onNodeDrag?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Graph node drag end callback function. Default: `undefined` */\n onNodeDragEnd?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Zoom event callback. Default: `undefined` */\n onZoom?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Zoom start event callback. Default: `undefined` */\n onZoomStart?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Zoom end event callback. Default: `undefined` */\n onZoomEnd?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Callback function to be called when the graph layout is calculated. Default: `undefined` */\n onLayoutCalculated?: (nodes: GraphNode<N, L>[], links: GraphLink<N, L>[]) => void;\n /** Graph node selection brush callback function. Default: `undefined` */\n onNodeSelectionBrush?: (selectedNodes: GraphNode<N, L>[], event: D3BrushEvent<SVGGElement> | undefined) => void;\n /** Graph multiple node drag callback function. Default: `undefined` */\n onNodeSelectionDrag?: (selectedNodes: GraphNode<N, L>[], event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void;\n /** Callback function to be called when the graph rendering is complete. Default: `undefined` */\n onRenderComplete?: (\n g: Selection<SVGGElement, unknown, null, undefined>,\n nodes: GraphNode<N, L>[],\n links: GraphLink<N, L>[],\n config: GraphConfigInterface<N, L>,\n duration: number,\n zoomLevel: number,\n width: number,\n height: number\n ) => void;\n}\n\nexport const GraphDefaultConfig: GraphConfigInterface<GraphInputNode, GraphInputLink> = {\n ...ComponentDefaultConfig,\n duration: 1000,\n zoomScaleExtent: [0.35, 1.25],\n disableZoom: false,\n zoomEventFilter: undefined,\n disableDrag: false,\n disableBrush: false,\n zoomThrottledUpdateNodeThreshold: 100,\n layoutType: GraphLayoutType.Force,\n layoutAutofit: true,\n layoutAutofitTolerance: 8.0,\n layoutNonConnectedAside: false,\n\n layoutGroupOrder: [],\n layoutParallelSubGroupsPerRow: 1,\n layoutParallelNodesPerColumn: 6,\n layoutParallelGroupSpacing: undefined,\n layoutParallelSortConnectionsByGroup: undefined,\n layoutNodeGroup: (n: GraphInputNode): string => (n as { group: string }).group,\n layoutParallelNodeSubGroup: (n: GraphInputNode): string => (n as { subgroup: string }).subgroup,\n\n forceLayoutSettings: {\n linkDistance: 60,\n linkStrength: 0.45,\n charge: -500,\n forceXStrength: 0.15,\n forceYStrength: 0.25,\n numIterations: undefined,\n fixNodePositionAfterSimulation: false,\n },\n\n dagreLayoutSettings: {\n rankdir: 'BT',\n ranker: 'longest-path',\n },\n\n layoutElkSettings: undefined,\n layoutElkNodeGroups: undefined,\n\n linkFlowAnimDuration: 20000,\n linkFlowParticleSize: 2,\n linkWidth: 1,\n linkStyle: GraphLinkStyle.Solid,\n linkBandWidth: 0,\n linkArrow: undefined,\n linkStroke: undefined,\n linkFlow: false,\n linkLabel: undefined,\n linkLabelShiftFromCenter: true,\n linkNeighborSpacing: 8,\n linkDisabled: false,\n linkCurvature: 0,\n selectedLinkId: undefined,\n nodeGaugeAnimDuration: 1500,\n\n nodeSize: 30,\n nodeStrokeWidth: 3,\n nodeShape: GraphNodeShape.Circle,\n nodeGaugeValue: 0,\n nodeIcon: (n: GraphInputNode): string => (n as { icon: string }).icon,\n nodeIconSize: undefined,\n nodeLabel: (n: GraphInputNode): string => (n as { label: string }).label,\n nodeLabelTrim: true,\n nodeLabelTrimLength: 15,\n nodeLabelTrimMode: TrimMode.Middle,\n nodeSubLabel: '',\n nodeSubLabelTrim: true,\n nodeSubLabelTrimLength: 15,\n nodeSubLabelTrimMode: TrimMode.Middle,\n nodeSideLabels: undefined,\n nodeBottomIcon: undefined,\n nodeDisabled: false,\n nodeFill: (n: GraphInputNode): string => (n as { fill: string }).fill,\n nodeGaugeFill: undefined,\n nodeStroke: (n: GraphInputNode): string => (n as { stroke: string }).stroke,\n nodeEnterPosition: undefined,\n nodeEnterScale: 0.75,\n nodeExitPosition: undefined,\n nodeExitScale: 0.75,\n nodeSort: undefined,\n nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected,\n\n selectedNodeId: undefined,\n selectedNodeIds: undefined,\n\n panels: undefined,\n\n onNodeDragStart: undefined,\n onNodeDrag: undefined,\n onNodeDragEnd: undefined,\n onZoom: undefined,\n onZoomStart: undefined,\n onZoomEnd: undefined,\n onLayoutCalculated: undefined,\n onNodeSelectionBrush: undefined,\n onNodeSelectionDrag: undefined,\n onRenderComplete: undefined,\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sources":["../../../src/components/graph/config.ts"],"sourcesContent":["import { D3BrushEvent } from 'd3-brush'\nimport { D3DragEvent } from 'd3-drag'\nimport { D3ZoomEvent, ZoomTransform } from 'd3-zoom'\nimport { Selection } from 'd3-selection'\nimport { ElkShape } from 'elkjs'\n\n// Core\nimport type { GraphDataModel } from 'data-models/graph'\n\n// Utils\nimport { isEqual } from 'utils/data'\n\n// Config\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Types\nimport { TrimMode } from 'types/text'\nimport { GraphInputLink, GraphInputNode, GraphInputData } from 'types/graph'\nimport { BooleanAccessor, ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from 'types/accessor'\n\n// Local Types\nimport {\n GraphLayoutType,\n GraphCircleLabel,\n GraphLinkStyle,\n GraphLinkArrowStyle,\n GraphPanelConfig,\n GraphForceLayoutSettings,\n GraphElkLayoutSettings,\n GraphNodeShape,\n GraphDagreLayoutSetting,\n GraphNode,\n GraphLink,\n GraphNodeSelectionHighlightMode,\n} from './types'\n\nexport interface GraphConfigInterface<N extends GraphInputNode, L extends GraphInputLink> extends ComponentConfigInterface {\n // Zoom and drag\n /** Zoom level constraints. Default: [0.35, 1.25] */\n zoomScaleExtent?: [number, number];\n /** Disable zooming. Default: `false` */\n disableZoom?: boolean;\n /** Custom Zoom event filter to better control which actions should trigger zooming.\n * Learn more: https://d3js.org/d3-zoom#zoom_filter.\n * Default: `undefined` */\n zoomEventFilter?: (event: PointerEvent) => boolean;\n /** Disable node dragging. Default: `false` */\n disableDrag?: boolean;\n /** Disable brush for multiple node selection. Default: `false` */\n disableBrush?: boolean;\n /** Interval to re-render the graph when zooming. Default: `100` */\n zoomThrottledUpdateNodeThreshold?: number;\n\n // Layout general settings\n /** Type of the graph layout. Default: `GraphLayoutType.Force` */\n layoutType?: GraphLayoutType | string;\n /** Fit the graph to container on data or config updates, or on container resize. Default: `true` */\n layoutAutofit?: boolean;\n /** Tolerance constant defining whether the graph should be fitted to container\n * (on data or config update, or container resize) after a zoom / pan interaction or not.\n * `0` — Stop fitting after any pan or zoom\n * `Number.POSITIVE_INFINITY` — Always fit\n * Default: `8.0` */\n layoutAutofitTolerance?: number;\n /** Place non-connected nodes at the bottom of the graph. Default: `false` */\n layoutNonConnectedAside?: boolean;\n\n // Settings for Parallel and Concentric layouts\n /** Node group accessor function.\n * Only for `GraphLayoutType.Parallel`, `GraphLayoutType.ParallelHorizontal` and `GraphLayoutType.Concentric` layouts.\n * Default: `node => node.group` */\n layoutNodeGroup?: StringAccessor<N>;\n /** Order of the layout groups.\n * Only for `GraphLayoutType.Parallel`, `GraphLayoutType.ParallelHorizontal` and `GraphLayoutType.Concentric` layouts.\n * Default: `[]` */\n layoutGroupOrder?: string[];\n\n // Setting for Parallel layouts only\n /** Sets the number of nodes in a sub-group after which they'll continue on the next column (or row if `layoutType` is\n * `GraphLayoutType.ParallelHorizontal`).\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `6` */\n layoutParallelNodesPerColumn?: number;\n /** Node sub-group accessor function.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `node => node.subgroup` */\n layoutParallelNodeSubGroup?: StringAccessor<N>;\n /** Number of sub-groups per row (or column if `layoutType` is `GraphLayoutType.ParallelHorizontal`) in a group.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `1` */\n layoutParallelSubGroupsPerRow?: number;\n /** Spacing between groups.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `undefined` */\n layoutParallelGroupSpacing?: number;\n /** Set a group by name to have priority in sorting the graph links.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `undefined` */\n layoutParallelSortConnectionsByGroup?: string;\n\n // Force layout\n /** Force Layout settings, see the `d3-force` package for more details */\n forceLayoutSettings?: GraphForceLayoutSettings<N, L>;\n\n // Dagre layout\n /** Darge Layout settings, see the `dagrejs` package\n * for more details: https://github.com/dagrejs/dagre/wiki#configuring-the-layout\n */\n dagreLayoutSettings?: GraphDagreLayoutSetting;\n\n // ELK layout\n /** ELK layout options, see the `elkjs` package for more details: https://github.com/kieler/elkjs.\n * If you want to specify custom layout option for each node group, you can provide an accessor function that\n * receives group name ('root' for the top-level configuration) as the first argument and returns an object containing\n * layout options. Default: `undefined`\n */\n layoutElkSettings?: GenericAccessor<GraphElkLayoutSettings, string> | undefined;\n /** Array of accessor functions to define nested node groups for the ELK Layered layout.\n * E.g.: `[n => n.group, n => n.subGroup]`.\n * Default: `undefined` */\n layoutElkNodeGroups?: StringAccessor<N>[];\n /** A function to be called per graph node to get the ELK shape object.\n * This enables you to provide custom node dimensions (through the `width` and `height` properties)\n * and coordinates (through the `x` and `y` properties) if needed.\n * Default: `undefined`\n */\n layoutElkGetNodeShape?: (d: GraphNode<N, L>, i: number) => ElkShape;\n\n // Links\n /** Link width accessor function ot constant value. Default: `1` */\n linkWidth?: NumericAccessor<L>;\n /** Link style accessor function or constant value. Default: `GraphLinkStyle.Solid` */\n linkStyle?: GenericAccessor<GraphLinkStyle, L>;\n /** Link band width accessor function or constant value. Default: `0` */\n linkBandWidth?: NumericAccessor<L>;\n /** Link arrow accessor function or constant value. Default: `undefined` */\n linkArrow?: GenericAccessor<GraphLinkArrowStyle | string | boolean, L> | undefined;\n /** Link stroke color accessor function or constant value. Default: `undefined` */\n linkStroke?: ColorAccessor<L>;\n /** Link disabled state accessor function or constant value. Default: `false` */\n linkDisabled?: BooleanAccessor<L>;\n /** Link flow animation accessor function or constant value. Default: `false` */\n linkFlow?: BooleanAccessor<L>;\n /** Animation duration of the flow (traffic) circles in milliseconds. If `linkFlowParticleSpeed` is provided,\n * this duration will be calculated based on the link length and particle speed. Default: `20000` */\n linkFlowAnimDuration?: NumericAccessor<L>;\n /** Size of the moving particles that represent traffic flow. Default: `2` */\n linkFlowParticleSize?: NumericAccessor<L>;\n /** Speed of the moving particles in pixels per second. This property takes precedence over `linkFlowAnimDuration`. Default: `undefined` */\n linkFlowParticleSpeed?: NumericAccessor<L>;\n /** Link label accessor function or constant value. Default: `undefined` */\n linkLabel?: GenericAccessor<GraphCircleLabel | GraphCircleLabel[], L> | undefined;\n /** Shift label along the link center a little bit to avoid overlap with the link arrow. Default: `true` */\n linkLabelShiftFromCenter?: BooleanAccessor<L>;\n /** Spacing between neighboring links. Default: `8` */\n linkNeighborSpacing?: number;\n /** Curvature of the link. Recommended value range: [0:1.5].\n * `0` - straight line,\n * `1` - nice curvature,\n * `1.5` - very curve.\n * Default: `0` */\n linkCurvature?: NumericAccessor<L>;\n /** Highlight links on hover. Default: `true` */\n linkHighlightOnHover?: boolean;\n /** Offset [x,y] in pixels from the source node's center point where the link should start. Default: `undefined` */\n linkSourcePointOffset?: GenericAccessor<[number, number], GraphLink<N, L>>;\n /** Offset [x,y] in pixels from the target node's center point where the link should end. Default: `undefined` */\n linkTargetPointOffset?: GenericAccessor<[number, number], GraphLink<N, L>>;\n /** Set selected link by its unique id. Default: `undefined` */\n selectedLinkId?: number | string;\n\n // Nodes\n /** Node size accessor function or constant value. Default: `30` */\n nodeSize?: NumericAccessor<N>;\n /** Node stroke width accessor function or constant value. Default: `3` */\n nodeStrokeWidth?: NumericAccessor<N>;\n /** Node shape accessor function or constant value. Default: `GraphNodeShape.Circle` */\n nodeShape?: GenericAccessor<GraphNodeShape | string, N>;\n /** Node gauge outline accessor function or constant value in the range [0,100]. Default: `0` */\n nodeGaugeValue?: NumericAccessor<N>;\n /** Node gauge outline fill color accessor function or constant value. Default: `undefined` */\n nodeGaugeFill?: ColorAccessor<N>;\n /** Animation duration of the node gauge outline. Default: `1500` */\n nodeGaugeAnimDuration?: number;\n /** Node central icon accessor function or constant value. Default: `node => node.icon` */\n nodeIcon?: StringAccessor<N>;\n /** Node central icon size accessor function or constant value. Default: `undefined` */\n nodeIconSize?: NumericAccessor<N>;\n /** Node label accessor function or constant value. Default: `node => node.label` */\n nodeLabel?: StringAccessor<N>;\n /** Defines whether to trim the node labels or not. Default: `true` */\n nodeLabelTrim?: BooleanAccessor<N>;\n /** Node label trimming mode. Default: `TrimMode.Middle` */\n nodeLabelTrimMode?: GenericAccessor<TrimMode | string, N>;\n /** Node label maximum allowed text length above which the label will be trimmed. Default: `15` */\n nodeLabelTrimLength?: NumericAccessor<N>;\n /** Node sub-label accessor function or constant value: Default: `''` */\n nodeSubLabel?: StringAccessor<N>;\n /** Defines whether to trim the node sub-labels or not. Default: `true` */\n nodeSubLabelTrim?: BooleanAccessor<N>;\n /** Node sub-label trimming mode. Default: `TrimMode.Middle` */\n nodeSubLabelTrimMode?: GenericAccessor<TrimMode | string, N>;\n /** Node sub-label maximum allowed text length above which the label will be trimmed. Default: `15` */\n nodeSubLabelTrimLength?: NumericAccessor<N>;\n /** Node circular side labels accessor function. The function should return an array of GraphCircleLabel objects. Default: `undefined` */\n nodeSideLabels?: GenericAccessor<GraphCircleLabel[], N>;\n /** Node bottom icon accessor function. Default: `undefined` */\n nodeBottomIcon?: StringAccessor<N>;\n /** Node disabled state accessor function or constant value. Default: `false` */\n nodeDisabled?: BooleanAccessor<N>;\n /** Node fill color accessor function or constant value. Default: `node => node.fill` */\n nodeFill?: ColorAccessor<N>;\n /** Node stroke color accessor function or constant value. Default: `node => node.stroke` */\n nodeStroke?: ColorAccessor<N>;\n /** Sorting function to determine node placement. Default: `undefined` */\n nodeSort?: ((a: N, b: N) => number);\n /** Specify the initial position for entering nodes as [x, y]. Default: `undefined` */\n nodeEnterPosition?: GenericAccessor<[number, number], N> | undefined;\n /** Specify the initial scale for entering nodes in the range [0,1]. Default: `0.75` */\n nodeEnterScale?: NumericAccessor<N> | undefined;\n /** Specify the destination position for exiting nodes as [x, y]. Default: `undefined` */\n nodeExitPosition?: GenericAccessor<[number, number], N> | undefined;\n /** Specify the destination scale for exiting nodes in the range [0,1]. Default: `0.75` */\n nodeExitScale?: NumericAccessor<N> | undefined;\n /** Custom \"enter\" function for node rendering. Default: `undefined` */\n nodeEnterCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom \"update\" function for node rendering. Default: `undefined` */\n nodeUpdateCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom partial \"update\" function for node rendering which will be triggered after the following events:\n * - Full node update (`nodeUpdateCustomRenderFunction`);\n * - Background click;\n * - Node and Link mouseover and mouseout;\n * - Node brushing,\n * Default: `undefined` */\n nodePartialUpdateCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom \"exit\" function for node rendering. Default: `undefined` */\n nodeExitCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, duration: number, zoomLevel: number) => void;\n /** Custom render function that will be called while zooming / panning the graph. Default: `undefined` */\n nodeOnZoomCustomRenderFunction?:\n (datum: GraphNode<N, L>, nodeGroupElementSelection: Selection<SVGGElement, GraphNode<N, L>, null, unknown>, config: GraphConfigInterface<N, L>, zoomLevel: number) => void;\n /** Define the mode for highlighting selected nodes in the graph. Default: `GraphNodeSelectionHighlightMode.GreyoutNonConnected` */\n nodeSelectionHighlightMode?: GraphNodeSelectionHighlightMode;\n /** Set selected node by unique id. Default: `undefined` */\n selectedNodeId?: number | string;\n /** Set selected nodes by unique id. Default: `undefined` */\n selectedNodeIds?: number[] | string[];\n\n /** Panels configuration. An array of `GraphPanelConfig` objects. Default: `[]` */\n panels?: GraphPanelConfig[] | undefined;\n\n // Events\n /** Graph node drag start callback function. Default: `undefined` */\n onNodeDragStart?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Graph node drag callback function. Default: `undefined` */\n onNodeDrag?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Graph node drag end callback function. Default: `undefined` */\n onNodeDragEnd?: (n: GraphNode<N, L>, event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void | undefined;\n /** Zoom event callback. Default: `undefined` */\n onZoom?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Zoom start event callback. Default: `undefined` */\n onZoomStart?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Zoom end event callback. Default: `undefined` */\n onZoomEnd?: (zoomScale: number, zoomScaleExtent: [number, number], event: D3ZoomEvent<SVGGElement, unknown> | undefined, transform: ZoomTransform) => void;\n /** Callback function to be called when the graph layout is calculated. Default: `undefined` */\n onLayoutCalculated?: (nodes: GraphNode<N, L>[], links: GraphLink<N, L>[]) => void;\n /** Graph node selection brush callback function. Default: `undefined` */\n onNodeSelectionBrush?: (selectedNodes: GraphNode<N, L>[], event: D3BrushEvent<SVGGElement> | undefined) => void;\n /** Graph multiple node drag callback function. Default: `undefined` */\n onNodeSelectionDrag?: (selectedNodes: GraphNode<N, L>[], event: D3DragEvent<SVGGElement, GraphNode<N, L>, unknown>) => void;\n /** Callback function to be called when the graph rendering is complete. Default: `undefined` */\n onRenderComplete?: (\n g: Selection<SVGGElement, unknown, null, undefined>,\n nodes: GraphNode<N, L>[],\n links: GraphLink<N, L>[],\n config: GraphConfigInterface<N, L>,\n duration: number,\n zoomLevel: number,\n width: number,\n height: number\n ) => void;\n\n /** Determines whether the component should update when new data is provided.\n * This function takes the previous and new data as parameters and returns a boolean\n * indicating whether the update should proceed. Useful for fine-grained control over\n * update behavior when your data has a complex nested structure.\n * By default the `isEqual` function from Unovis will be used to do the comparison.\n */\n shouldDataUpdate?: (\n prevData: GraphInputData<N, L>,\n nextData: GraphInputData<N, L>,\n datamodel: GraphDataModel<N, L, GraphNode<N, L>, GraphLink<N, L>>\n ) => boolean;\n}\n\nexport const GraphDefaultConfig: GraphConfigInterface<GraphInputNode, GraphInputLink> = {\n ...ComponentDefaultConfig,\n duration: 1000,\n zoomScaleExtent: [0.35, 1.25],\n disableZoom: false,\n zoomEventFilter: undefined,\n disableDrag: false,\n disableBrush: false,\n zoomThrottledUpdateNodeThreshold: 100,\n layoutType: GraphLayoutType.Force,\n layoutAutofit: true,\n layoutAutofitTolerance: 8.0,\n layoutNonConnectedAside: false,\n\n layoutGroupOrder: [],\n layoutParallelSubGroupsPerRow: 1,\n layoutParallelNodesPerColumn: 6,\n layoutParallelGroupSpacing: undefined,\n layoutParallelSortConnectionsByGroup: undefined,\n layoutNodeGroup: (n: GraphInputNode): string => (n as { group: string }).group,\n layoutParallelNodeSubGroup: (n: GraphInputNode): string => (n as { subgroup: string }).subgroup,\n\n forceLayoutSettings: {\n linkDistance: 60,\n linkStrength: 0.45,\n charge: -500,\n forceXStrength: 0.15,\n forceYStrength: 0.25,\n numIterations: undefined,\n fixNodePositionAfterSimulation: false,\n },\n\n dagreLayoutSettings: {\n rankdir: 'BT',\n ranker: 'longest-path',\n },\n\n layoutElkSettings: undefined,\n layoutElkNodeGroups: undefined,\n layoutElkGetNodeShape: undefined,\n\n linkFlowAnimDuration: 20000,\n linkFlowParticleSize: 2,\n linkFlowParticleSpeed: undefined,\n linkWidth: 1,\n linkStyle: GraphLinkStyle.Solid,\n linkBandWidth: 0,\n linkArrow: undefined,\n linkStroke: undefined,\n linkFlow: false,\n linkLabel: undefined,\n linkLabelShiftFromCenter: true,\n linkNeighborSpacing: 8,\n linkDisabled: false,\n linkCurvature: 0,\n linkHighlightOnHover: true,\n linkSourcePointOffset: undefined,\n linkTargetPointOffset: undefined,\n selectedLinkId: undefined,\n\n nodeSize: 30,\n nodeStrokeWidth: 3,\n nodeShape: GraphNodeShape.Circle,\n nodeGaugeValue: 0,\n nodeIcon: (n: GraphInputNode): string => (n as { icon: string }).icon,\n nodeIconSize: undefined,\n nodeLabel: (n: GraphInputNode): string => (n as { label: string }).label,\n nodeLabelTrim: true,\n nodeLabelTrimLength: 15,\n nodeLabelTrimMode: TrimMode.Middle,\n nodeSubLabel: '',\n nodeSubLabelTrim: true,\n nodeSubLabelTrimLength: 15,\n nodeSubLabelTrimMode: TrimMode.Middle,\n nodeSideLabels: undefined,\n nodeBottomIcon: undefined,\n nodeDisabled: false,\n nodeFill: (n: GraphInputNode): string => (n as { fill: string }).fill,\n nodeGaugeFill: undefined,\n nodeStroke: (n: GraphInputNode): string => (n as { stroke: string }).stroke,\n nodeEnterPosition: undefined,\n nodeEnterScale: 0.75,\n nodeExitPosition: undefined,\n nodeExitScale: 0.75,\n nodeSort: undefined,\n nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected,\n nodeGaugeAnimDuration: 1500,\n\n selectedNodeId: undefined,\n selectedNodeIds: undefined,\n\n panels: undefined,\n\n onNodeDragStart: undefined,\n onNodeDrag: undefined,\n onNodeDragEnd: undefined,\n onZoom: undefined,\n onZoomStart: undefined,\n onZoomEnd: undefined,\n onLayoutCalculated: undefined,\n onNodeSelectionBrush: undefined,\n onNodeSelectionDrag: undefined,\n onRenderComplete: undefined,\n\n shouldDataUpdate: (prevData: GraphInputData<GraphInputNode, GraphInputLink>, nextData: GraphInputData<GraphInputNode, GraphInputLink>): boolean => {\n return !isEqual(prevData, nextData)\n },\n}\n"],"names":[],"mappings":"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"}
@@ -1,15 +1,12 @@
1
1
  import { Selection } from 'd3-selection';
2
2
  import { ComponentCore } from "../../core/component";
3
3
  import { GraphDataModel } from "../../data-models/graph";
4
- import { GraphInputLink, GraphInputNode } from "../../types/graph";
4
+ import { GraphInputLink, GraphInputNode, GraphInputData } from "../../types/graph";
5
5
  import { Spacing } from "../../types/spacing";
6
6
  import { GraphNode, GraphLink } from './types';
7
7
  import { GraphConfigInterface } from './config';
8
8
  import * as nodeSelectors from './modules/node/style';
9
- export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> extends ComponentCore<{
10
- nodes: N[];
11
- links?: L[];
12
- }, GraphConfigInterface<N, L>> {
9
+ export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> extends ComponentCore<GraphInputData<N, L>, GraphConfigInterface<N, L>> {
13
10
  static selectors: {
14
11
  root: string;
15
12
  graphGroup: string;
@@ -22,6 +19,7 @@ export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> e
22
19
  dimmedNode: string;
23
20
  link: string;
24
21
  linkLine: string;
22
+ linkLabel: string;
25
23
  dimmedLink: string;
26
24
  panel: string;
27
25
  panelRect: string;
@@ -63,6 +61,7 @@ export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> e
63
61
  private _isDragging;
64
62
  private _brushBehavior;
65
63
  private _groupDragInit;
64
+ private _linkPathLengthMap;
66
65
  events: {
67
66
  [x: string]: {
68
67
  click: () => void;
@@ -82,10 +81,7 @@ export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> e
82
81
  get selectedNodes(): GraphNode<N, L>[];
83
82
  get selectedLink(): GraphLink<N, L>;
84
83
  constructor(config?: GraphConfigInterface<N, L>);
85
- setData(data: {
86
- nodes: N[];
87
- links?: L[];
88
- }): void;
84
+ setData(data: GraphInputData<N, L>): void;
89
85
  setConfig(config: GraphConfigInterface<N, L>): void;
90
86
  get bleed(): Spacing;
91
87
  _render(customDuration?: number): void;
@@ -143,4 +139,11 @@ export declare class Graph<N extends GraphInputNode, L extends GraphInputLink> e
143
139
  x: number;
144
140
  y: number;
145
141
  } | undefined;
142
+ /** Set the node state by id */
143
+ setNodeStateById(nodeId: string, state: GraphNode<N, L>['_state']): void;
144
+ /** Call a partial render to update the positions of the nodes and their links.
145
+ * This can be useful when you've changed the node positions manually outside
146
+ * of the component and want to update the graph.
147
+ */
148
+ updateNodePositions(duration?: number): void;
146
149
  }
@@ -7,18 +7,18 @@ import { drag } from 'd3-drag';
7
7
  import { interval } from 'd3-timer';
8
8
  import { ComponentCore } from '../../core/component/index.js';
9
9
  import { GraphDataModel } from '../../data-models/graph.js';
10
- import { isEqual, isNumber, isFunction, clamp, getBoolean, shallowDiff, isPlainObject } from '../../utils/data.js';
10
+ import { isNumber, isFunction, clamp, getBoolean, getNumber, shallowDiff, isPlainObject, isEqual } from '../../utils/data.js';
11
11
  import { smartTransition } from '../../utils/d3.js';
12
12
  import { GraphLayoutType, GraphNodeSelectionHighlightMode, GraphLinkArrowStyle } from './types.js';
13
13
  import { GraphDefaultConfig } from './config.js';
14
14
  import { background, graphGroup, brush, root } from './style.js';
15
15
  import * as style from './modules/node/style.js';
16
16
  import { nodes, gNode, gNodeExit, brushed, brushable, node, nodeGauge, sideLabelGroup, label, greyedOutNode } from './modules/node/style.js';
17
- import { links, gLink, gLinkExit, link, greyedOutLink } from './modules/link/style.js';
17
+ import { links, gLink, gLinkExit, linkSupport, link, linkLabelGroup, greyedOutLink } from './modules/link/style.js';
18
18
  import { panels, gPanel, panel, panelSelection, label as label$1, labelText, sideIconGroup, sideIconShape, sideIconSymbol } from './modules/panel/style.js';
19
- import { createNodes, updateNodes, removeNodes, updateNodesPartial, zoomNodesThrottled, zoomNodes } from './modules/node/index.js';
19
+ import { createNodes, updateNodes, removeNodes, updateNodesPartial, zoomNodesThrottled, zoomNodes, updateNodePositions } from './modules/node/index.js';
20
20
  import { getMaxNodeSize, getX, getY, getNodeSize } from './modules/node/helper.js';
21
- import { createLinks, updateLinks, removeLinks, updateLinksPartial, animateLinkFlow, zoomLinksThrottled, zoomLinks } from './modules/link/index.js';
21
+ import { createLinks, updateLinks, removeLinks, updateLinksPartial, animateLinkFlow, zoomLinksThrottled, zoomLinks, updateLinkLines } from './modules/link/index.js';
22
22
  import { getArrowPath, getDoubleArrowPath } from './modules/link/helper.js';
23
23
  import { removePanels, createPanels, updatePanels } from './modules/panel/index.js';
24
24
  import { updatePanelNumNodes, updatePanelBBoxSize, initPanels, setPanelForNodes } from './modules/panel/helper.js';
@@ -35,6 +35,8 @@ class Graph extends ComponentCore {
35
35
  this._shouldSetPanels = false;
36
36
  this._isAutoFitDisabled = false;
37
37
  this._isDragging = false;
38
+ // A map for storing link total path lengths to optimize rendering performance
39
+ this._linkPathLengthMap = new Map();
38
40
  this.events = {
39
41
  [Graph.selectors.background]: {
40
42
  click: this._onBackgroundClick.bind(this),
@@ -82,7 +84,7 @@ class Graph extends ComponentCore {
82
84
  }
83
85
  setData(data) {
84
86
  const { config } = this;
85
- if (isEqual(this.datamodel.data, data))
87
+ if (!config.shouldDataUpdate(this.datamodel.data, data, this.datamodel))
86
88
  return;
87
89
  this.datamodel.nodeSort = config.nodeSort;
88
90
  this.datamodel.data = data;
@@ -178,7 +180,7 @@ class Graph extends ComponentCore {
178
180
  this._resetSelectionGreyoutState();
179
181
  if (this.config.selectedNodeId || this.config.selectedNodeIds) {
180
182
  const selectedIds = (_a = this.config.selectedNodeIds) !== null && _a !== void 0 ? _a : [this.config.selectedNodeId];
181
- const selectedNodes = selectedIds.map(id => datamodel.getNodeFromId(id));
183
+ const selectedNodes = selectedIds.map(id => datamodel.getNodeById(id));
182
184
  this._setNodeSelectionState(selectedNodes);
183
185
  }
184
186
  if (this.config.selectedLinkId) {
@@ -198,14 +200,6 @@ class Graph extends ComponentCore {
198
200
  this.g.on('.zoom', null);
199
201
  else
200
202
  this.g.call(this._zoomBehavior).on('dblclick.zoom', null);
201
- // While the graph is animating we disable pointer events on the graph group
202
- if (animDuration) {
203
- this._graphGroup.attr('pointer-events', 'none');
204
- }
205
- smartTransition(this._graphGroup, animDuration)
206
- .on('end interrupt', () => {
207
- this._graphGroup.attr('pointer-events', null);
208
- });
209
203
  // We need to set up events and attributes again because the rendering might have been delayed by the layout
210
204
  // calculation and they were not set up properly (see the render function of `ComponentCore`)
211
205
  this._setUpComponentEventsThrottled();
@@ -247,13 +241,13 @@ class Graph extends ComponentCore {
247
241
  _drawLinks(duration) {
248
242
  const { config, datamodel: { links } } = this;
249
243
  const linkGroups = this._linksGroup
250
- .selectAll(`.${gLink}`)
244
+ .selectAll(`.${gLink}:not(.${gLinkExit}`)
251
245
  .data(links, (d) => String(d._id));
252
246
  const linkGroupsEnter = linkGroups.enter().append('g')
253
247
  .attr('class', gLink)
254
248
  .call(createLinks, config, duration);
255
249
  const linkGroupsMerged = linkGroups.merge(linkGroupsEnter);
256
- linkGroupsMerged.call(updateLinks, config, duration, this._scale, this._getLinkArrowDefId);
250
+ linkGroupsMerged.call(updateLinks, config, duration, this._scale, this._getLinkArrowDefId, this._linkPathLengthMap);
257
251
  const linkGroupsExit = linkGroups.exit();
258
252
  linkGroupsExit
259
253
  .attr('class', gLinkExit)
@@ -489,7 +483,8 @@ class Graph extends ComponentCore {
489
483
  _onLinkMouseOver(d) {
490
484
  if (this._isDragging)
491
485
  return;
492
- d._state.hovered = true;
486
+ if (this.config.linkHighlightOnHover)
487
+ d._state.hovered = true;
493
488
  this._updateNodesLinksPartial();
494
489
  }
495
490
  _onLinkMouseOut(d) {
@@ -499,15 +494,26 @@ class Graph extends ComponentCore {
499
494
  this._updateNodesLinksPartial();
500
495
  }
501
496
  _onLinkFlowTimerFrame(elapsed = 0) {
502
- const { config: { linkFlow, linkFlowAnimDuration }, datamodel: { links } } = this;
503
- const hasLinksWithFlow = links.some((d, i) => getBoolean(d, linkFlow, i));
497
+ const { config, datamodel: { links } } = this;
498
+ const hasLinksWithFlow = links.some((d, i) => getBoolean(d, config.linkFlow, i));
504
499
  if (!hasLinksWithFlow)
505
500
  return;
506
- const t = (elapsed % linkFlowAnimDuration) / linkFlowAnimDuration;
507
501
  const linkElements = this._linksGroup.selectAll(`.${gLink}`);
508
502
  const linksToAnimate = linkElements.filter(d => !d._state.greyout);
509
- linksToAnimate.each(d => { d._state.flowAnimTime = t; });
510
- animateLinkFlow(linksToAnimate, this.config, this._scale);
503
+ linksToAnimate.each((l, i, els) => {
504
+ var _a;
505
+ let linkFlowAnimDuration = getNumber(l, config.linkFlowAnimDuration, l._indexGlobal);
506
+ const linkFlowParticleSpeed = getNumber(l, config.linkFlowParticleSpeed, l._indexGlobal);
507
+ // If particle speed is provided, calculate duration based on link length and speed
508
+ if (linkFlowParticleSpeed) {
509
+ const linkPathElement = els[i].querySelector(`.${linkSupport}`);
510
+ const pathLength = linkPathElement ? ((_a = this._linkPathLengthMap.get(linkPathElement.getAttribute('d'))) !== null && _a !== void 0 ? _a : linkPathElement.getTotalLength()) : 0;
511
+ if (pathLength > 0)
512
+ linkFlowAnimDuration = (pathLength / linkFlowParticleSpeed) * 1000; // Convert to milliseconds
513
+ }
514
+ l._state.flowAnimTime = (elapsed % linkFlowAnimDuration) / linkFlowAnimDuration;
515
+ });
516
+ animateLinkFlow(linksToAnimate, this.config, this._scale, this._linkPathLengthMap);
511
517
  }
512
518
  _onZoom(t, event) {
513
519
  const { config, datamodel: { nodes } } = this;
@@ -651,10 +657,10 @@ class Graph extends ComponentCore {
651
657
  const target = l.target;
652
658
  return source._id === d._id || target._id === d._id;
653
659
  });
654
- linksToUpdate.call(updateLinks, config, 0, scale, this._getLinkArrowDefId);
660
+ linksToUpdate.call(updateLinks, config, 0, scale, this._getLinkArrowDefId, this._linkPathLengthMap);
655
661
  const linksToAnimate = linksToUpdate.filter(d => d._state.greyout);
656
662
  if (linksToAnimate.size())
657
- animateLinkFlow(linksToAnimate, config, this._scale);
663
+ animateLinkFlow(linksToAnimate, config, this._scale, this._linkPathLengthMap);
658
664
  (_a = config.onNodeDrag) === null || _a === void 0 ? void 0 : _a.call(config, d, event);
659
665
  }
660
666
  _onDragEnded(d, event, nodeSelection) {
@@ -685,7 +691,7 @@ class Graph extends ComponentCore {
685
691
  selectedNodes.each(n => this._updateNodePosition(n, n.x + dx, n.y + dy));
686
692
  const connectedLinks = smartTransition(this._linksGroup.selectAll(`.${gLink}`)
687
693
  .filter(l => { var _a, _b, _c, _d; return ((_b = (_a = l.source) === null || _a === void 0 ? void 0 : _a._state) === null || _b === void 0 ? void 0 : _b.isDragged) || ((_d = (_c = l.target) === null || _c === void 0 ? void 0 : _c._state) === null || _d === void 0 ? void 0 : _d.isDragged); }));
688
- connectedLinks.call(updateLinks, this.config, 0, this._scale, this._getLinkArrowDefId);
694
+ connectedLinks.call(updateLinks, this.config, 0, this._scale, this._getLinkArrowDefId, this._linkPathLengthMap);
689
695
  }
690
696
  else {
691
697
  this._isDragging = false;
@@ -812,6 +818,22 @@ class Graph extends ComponentCore {
812
818
  };
813
819
  }
814
820
  }
821
+ /** Set the node state by id */
822
+ setNodeStateById(nodeId, state) {
823
+ this.datamodel.setNodeStateById(nodeId, state);
824
+ }
825
+ /** Call a partial render to update the positions of the nodes and their links.
826
+ * This can be useful when you've changed the node positions manually outside
827
+ * of the component and want to update the graph.
828
+ */
829
+ updateNodePositions(duration) {
830
+ const { config } = this;
831
+ const animDuration = isNumber(duration) ? duration : config.duration;
832
+ const linkElements = this._linksGroup.selectAll(`.${gLink}:not(.${gLinkExit}`);
833
+ updateLinkLines(linkElements, config, animDuration, this._scale, this._getLinkArrowDefId, this._linkPathLengthMap);
834
+ const nodeElements = this._nodesGroup.selectAll(`.${gNode}:not(.${gNodeExit})`);
835
+ updateNodePositions(nodeElements, animDuration);
836
+ }
815
837
  }
816
838
  Graph.selectors = {
817
839
  root: root,
@@ -825,6 +847,7 @@ Graph.selectors = {
825
847
  dimmedNode: greyedOutNode,
826
848
  link: gLink,
827
849
  linkLine: link,
850
+ linkLabel: linkLabelGroup,
828
851
  dimmedLink: greyedOutLink,
829
852
  panel: gPanel,
830
853
  panelRect: panel,