@unovis/ts 1.6.0-beta.0 → 1.6.0-bigip.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/axis/config.d.ts +1 -1
- package/components/axis/config.js.map +1 -1
- package/components/axis/index.d.ts +0 -1
- package/components/axis/index.js +2 -10
- package/components/axis/index.js.map +1 -1
- package/components/brush/config.d.ts +1 -1
- package/components/brush/config.js.map +1 -1
- package/components/crosshair/config.d.ts +6 -0
- package/components/crosshair/config.js +1 -1
- package/components/crosshair/config.js.map +1 -1
- package/components/crosshair/index.d.ts +7 -0
- package/components/crosshair/index.js +192 -45
- package/components/crosshair/index.js.map +1 -1
- package/components/graph/config.d.ts +8 -0
- package/components/graph/config.js +1 -1
- package/components/graph/config.js.map +1 -1
- package/components/graph/index.d.ts +1 -0
- package/components/graph/index.js +14 -9
- package/components/graph/index.js.map +1 -1
- package/components/graph/modules/layout.js +33 -31
- package/components/graph/modules/layout.js.map +1 -1
- package/components/graph/modules/link/index.js +1 -1
- package/components/graph/modules/link/index.js.map +1 -1
- package/components/graph/types.d.ts +2 -1
- package/components/graph/types.js.map +1 -1
- package/components/plotband/config.d.ts +59 -0
- package/components/plotband/config.js +9 -0
- package/components/plotband/config.js.map +1 -0
- package/components/plotband/constants.d.ts +5 -0
- package/components/plotband/constants.js +413 -0
- package/components/plotband/constants.js.map +1 -0
- package/components/plotband/index.d.ts +15 -0
- package/components/plotband/index.js +92 -0
- package/components/plotband/index.js.map +1 -0
- package/components/plotband/style.d.ts +4 -0
- package/components/plotband/style.js +38 -0
- package/components/plotband/style.js.map +1 -0
- package/components/plotband/types.d.ts +51 -0
- package/components/plotband/types.js +27 -0
- package/components/plotband/types.js.map +1 -0
- package/components/scatter/index.d.ts +1 -0
- package/components/scatter/index.js +11 -1
- package/components/scatter/index.js.map +1 -1
- package/components/timeline/config.d.ts +65 -14
- package/components/timeline/config.js +15 -1
- package/components/timeline/config.js.map +1 -1
- package/components/timeline/constants.d.ts +3 -0
- package/components/timeline/constants.js +6 -0
- package/components/timeline/constants.js.map +1 -0
- package/components/timeline/index.d.ts +21 -10
- package/components/timeline/index.js +380 -95
- package/components/timeline/index.js.map +1 -1
- package/components/timeline/style.d.ts +7 -0
- package/components/timeline/style.js +40 -1
- package/components/timeline/style.js.map +1 -1
- package/components/timeline/types.d.ts +62 -0
- package/components/timeline/types.js +2 -0
- package/components/timeline/types.js.map +1 -0
- package/components/timeline/utils.d.ts +2 -0
- package/components/timeline/utils.js +16 -0
- package/components/timeline/utils.js.map +1 -0
- package/components/xy-labels/index.js +1 -1
- package/components/xy-labels/index.js.map +1 -1
- package/components.d.ts +4 -2
- package/components.js +1 -0
- package/components.js.map +1 -1
- package/containers/xy-container/config.d.ts +2 -0
- package/containers/xy-container/config.js +1 -1
- package/containers/xy-container/config.js.map +1 -1
- package/containers/xy-container/index.js +2 -2
- package/containers/xy-container/index.js.map +1 -1
- package/data-models/graph.js +7 -1
- package/data-models/graph.js.map +1 -1
- package/index.js +4 -2
- package/index.js.map +1 -1
- package/package.json +4 -3
- package/styles/index.js +1 -0
- package/styles/index.js.map +1 -1
- package/types/position.d.ts +2 -1
- package/types/position.js +1 -0
- package/types/position.js.map +1 -1
- package/types/text.d.ts +1 -1
- package/types/text.js.map +1 -1
- package/types.d.ts +2 -0
- package/types.js +2 -0
- package/types.js.map +1 -1
- package/utils/data.d.ts +1 -1
- package/utils/data.js +2 -2
- package/utils/data.js.map +1 -1
- package/utils/index.js +2 -2
- package/utils/path.d.ts +8 -0
- package/utils/path.js +109 -1
- package/utils/path.js.map +1 -1
- package/utils/text.d.ts +3 -2
- package/utils/text.js +21 -9
- package/utils/text.js.map +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pointer } from 'd3-selection';
|
|
2
2
|
import { easeLinear } from 'd3-ease';
|
|
3
3
|
import { XYComponentCore } from '../../core/xy-component/index.js';
|
|
4
|
-
import { isArray, isNumber, getNearest,
|
|
4
|
+
import { isArray, isNumber, getNearest, getNumber, clamp, isFunction, getStackedValues } from '../../utils/data.js';
|
|
5
5
|
import { smartTransition } from '../../utils/d3.js';
|
|
6
6
|
import { getColor } from '../../utils/color.js';
|
|
7
7
|
import { Position } from '../../types/position.js';
|
|
@@ -18,6 +18,8 @@ class Crosshair extends XYComponentCore {
|
|
|
18
18
|
this.x = 0;
|
|
19
19
|
this.show = false;
|
|
20
20
|
this._animFrameId = null;
|
|
21
|
+
this._dataX = undefined;
|
|
22
|
+
this._isMouseOver = false;
|
|
21
23
|
/** Accessors passed externally (e.g. from XYContainer) */
|
|
22
24
|
this._accessors = {
|
|
23
25
|
x: undefined,
|
|
@@ -26,7 +28,7 @@ class Crosshair extends XYComponentCore {
|
|
|
26
28
|
baseline: undefined,
|
|
27
29
|
};
|
|
28
30
|
if (config)
|
|
29
|
-
this.
|
|
31
|
+
this.config = Object.assign(Object.assign({}, this.config), config);
|
|
30
32
|
this.g.style('opacity', this.show ? 1 : 0);
|
|
31
33
|
this.line = this.g.append('line')
|
|
32
34
|
.attr('class', line);
|
|
@@ -35,30 +37,40 @@ class Crosshair extends XYComponentCore {
|
|
|
35
37
|
get accessors() {
|
|
36
38
|
var _a;
|
|
37
39
|
const { config } = this;
|
|
38
|
-
|
|
39
|
-
const x =
|
|
40
|
-
const yAcc =
|
|
40
|
+
// If x or y are explicitly set in config, use those; otherwise use container accessors
|
|
41
|
+
const x = config.x || this._accessors.x;
|
|
42
|
+
const yAcc = config.y || this._accessors.y;
|
|
41
43
|
const y = yAcc ? (isArray(yAcc) ? yAcc : [yAcc]) : undefined;
|
|
42
|
-
const yStacked =
|
|
44
|
+
const yStacked = config.yStacked || this._accessors.yStacked;
|
|
43
45
|
const baseline = (_a = config.baseline) !== null && _a !== void 0 ? _a : this._accessors.baseline;
|
|
44
46
|
return { x, y, yStacked, baseline };
|
|
45
47
|
}
|
|
46
48
|
setContainer(containerSvg) {
|
|
47
|
-
// Set up mousemove event for Crosshair
|
|
48
49
|
this.container = containerSvg;
|
|
49
50
|
this.container.on('mousemove.crosshair', this._onMouseMove.bind(this));
|
|
50
51
|
this.container.on('mouseout.crosshair', this._onMouseOut.bind(this));
|
|
52
|
+
this._render();
|
|
53
|
+
}
|
|
54
|
+
setConfig(config) {
|
|
55
|
+
super.setConfig(config);
|
|
56
|
+
// For synchronized charts, update from sync when config changes
|
|
57
|
+
const { isActive, enableSync } = this._getSyncState();
|
|
58
|
+
if (enableSync && !isActive && (isNumber(config.xPosition) || config.xPosition instanceof Date)) {
|
|
59
|
+
this._updateFromSync(config.xPosition);
|
|
60
|
+
}
|
|
51
61
|
}
|
|
52
62
|
_render(customDuration) {
|
|
53
63
|
const { config } = this;
|
|
54
|
-
if (config.snapToData && !this.datum)
|
|
55
|
-
return;
|
|
56
64
|
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
const { isActive, enableSync } = this._getSyncState();
|
|
66
|
+
// Handle synchronized charts with xPosition prop
|
|
67
|
+
if (enableSync && !isActive && (isNumber(config.xPosition) || config.xPosition instanceof Date)) {
|
|
68
|
+
this._updateFromSync(config.xPosition);
|
|
69
|
+
}
|
|
70
|
+
smartTransition(this.g, duration).style('opacity', this.show ? 1 : 0);
|
|
59
71
|
this.line
|
|
60
72
|
.attr('y1', 0)
|
|
61
|
-
.attr('
|
|
73
|
+
.attr('y2', this._height);
|
|
62
74
|
smartTransition(this.line, duration, easeLinear)
|
|
63
75
|
.attr('x1', this.x)
|
|
64
76
|
.attr('x2', this.x);
|
|
@@ -88,17 +100,52 @@ class Crosshair extends XYComponentCore {
|
|
|
88
100
|
hide() {
|
|
89
101
|
this._onMouseOut();
|
|
90
102
|
}
|
|
103
|
+
destroy() {
|
|
104
|
+
if (this._animFrameId) {
|
|
105
|
+
window.cancelAnimationFrame(this._animFrameId);
|
|
106
|
+
this._animFrameId = null;
|
|
107
|
+
}
|
|
108
|
+
this._hideTooltip();
|
|
109
|
+
}
|
|
91
110
|
_onMouseMove(event) {
|
|
111
|
+
// Throttle the entire mouse move processing
|
|
112
|
+
if (this._animFrameId)
|
|
113
|
+
return;
|
|
114
|
+
this._animFrameId = window.requestAnimationFrame(() => {
|
|
115
|
+
this._processMouseMove(event);
|
|
116
|
+
this._animFrameId = null;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
_processMouseMove(event) {
|
|
92
120
|
var _a, _b;
|
|
121
|
+
this._isMouseOver = true;
|
|
93
122
|
const { config, datamodel, element } = this;
|
|
123
|
+
const { isActive, enableSync } = this._getSyncState();
|
|
124
|
+
// Early return for synchronized non-active charts, but allow tooltip display
|
|
125
|
+
if (enableSync && !isActive) {
|
|
126
|
+
if (this.show && this.datum) {
|
|
127
|
+
this._showTooltip(event);
|
|
128
|
+
}
|
|
129
|
+
else if (this.show && this._dataX !== undefined && isNumber(this._dataX)) {
|
|
130
|
+
// For synchronized charts, find the datum if it doesn't exist
|
|
131
|
+
this.datum = getNearest(this.datamodel.data, this._dataX, this.accessors.x);
|
|
132
|
+
if (this.datum) {
|
|
133
|
+
this._showTooltip(event);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Check if we have the necessary accessors
|
|
94
139
|
if (!this.accessors.x && ((_a = datamodel.data) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
95
140
|
console.warn('Unovis | Crosshair: X accessor function has not been configured. Please check if it\'s present in the configuration object');
|
|
141
|
+
return;
|
|
96
142
|
}
|
|
97
143
|
const [x] = pointer(event, element);
|
|
98
144
|
const xRange = this.xScale.range();
|
|
99
145
|
if (config.snapToData) {
|
|
100
146
|
if (!this.accessors.y && !this.accessors.yStacked && ((_b = datamodel.data) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
101
147
|
console.warn('Unovis | Crosshair: Y accessors have not been configured. Please check if they\'re present in the configuration object');
|
|
148
|
+
return;
|
|
102
149
|
}
|
|
103
150
|
const scaleX = this.xScale;
|
|
104
151
|
const valueX = scaleX.invert(x);
|
|
@@ -106,42 +153,55 @@ class Crosshair extends XYComponentCore {
|
|
|
106
153
|
this.datumIndex = datamodel.data.indexOf(this.datum);
|
|
107
154
|
if (!this.datum)
|
|
108
155
|
return;
|
|
109
|
-
|
|
156
|
+
const dataX = getNumber(this.datum, this.accessors.x, this.datumIndex);
|
|
157
|
+
this.x = clamp(Math.round(scaleX(dataX)), 0, this._width);
|
|
158
|
+
this._dataX = dataX;
|
|
110
159
|
// Show the crosshair only if it's in the chart range and not far from mouse pointer (if configured)
|
|
111
160
|
this.show = (this.x >= 0) && (this.x <= this._width) && (!config.hideWhenFarFromPointer || (Math.abs(this.x - x) < config.hideWhenFarFromPointerDistance));
|
|
112
161
|
}
|
|
113
162
|
else {
|
|
114
163
|
const tolerance = 2; // Show the crosshair when it is at least 2 pixels close to the chart area
|
|
115
164
|
this.x = clamp(x, xRange[0], xRange[1]);
|
|
165
|
+
this._dataX = this.xScale.invert(this.x);
|
|
116
166
|
this.show = (x >= (xRange[0] - tolerance)) && (x <= (xRange[1] + tolerance));
|
|
117
167
|
}
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
121
|
-
}
|
|
168
|
+
// Call onCrosshairMove callback if provided
|
|
169
|
+
if (this.show && config.onCrosshairMove && this._dataX !== undefined) {
|
|
170
|
+
config.onCrosshairMove(this._dataX);
|
|
171
|
+
}
|
|
172
|
+
// Render immediately since we're already in a throttled context
|
|
173
|
+
this._render();
|
|
122
174
|
if (this.show)
|
|
123
175
|
this._showTooltip(event);
|
|
124
176
|
else
|
|
125
177
|
this._hideTooltip();
|
|
126
178
|
}
|
|
127
179
|
_onMouseOut() {
|
|
180
|
+
this._isMouseOver = false;
|
|
181
|
+
const { config } = this;
|
|
182
|
+
// Always hide on mouse out
|
|
128
183
|
this.show = false;
|
|
129
|
-
|
|
184
|
+
this._hideTooltip();
|
|
185
|
+
// Throttle rendering using requestAnimationFrame
|
|
186
|
+
if (this._animFrameId)
|
|
187
|
+
return;
|
|
130
188
|
this._animFrameId = window.requestAnimationFrame(() => {
|
|
131
189
|
this._render();
|
|
190
|
+
this._animFrameId = null;
|
|
132
191
|
});
|
|
133
|
-
this
|
|
192
|
+
// If this is the active chart, notify parent to clear sync state
|
|
193
|
+
if (config.onCrosshairMove) {
|
|
194
|
+
config.onCrosshairMove(undefined);
|
|
195
|
+
}
|
|
134
196
|
}
|
|
135
197
|
_showTooltip(event) {
|
|
136
198
|
var _a;
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
if (!tooltip)
|
|
199
|
+
const tooltip = (_a = this.config.tooltip) !== null && _a !== void 0 ? _a : this.tooltip;
|
|
200
|
+
if (!tooltip || !this.datum)
|
|
140
201
|
return;
|
|
141
202
|
const container = tooltip.getContainer() || this.container.node();
|
|
142
203
|
const [x, y] = tooltip.isContainerBody() ? [event.clientX, event.clientY] : pointer(event, container);
|
|
143
|
-
const content = config.template(this.datum, this.xScale.invert(this.x));
|
|
144
|
-
// Force set `followCursor` to `true` because we don't want Crosshair's tooltip to be hoverable
|
|
204
|
+
const content = this.config.template(this.datum, this._dataX || this.xScale.invert(this.x));
|
|
145
205
|
tooltip.config.followCursor = true;
|
|
146
206
|
// Set tooltip placement based on Crosshair's position (left / right)
|
|
147
207
|
if (!tooltip.config.horizontalPlacement || tooltip.config.horizontalPlacement === Position.Auto) {
|
|
@@ -153,46 +213,133 @@ class Crosshair extends XYComponentCore {
|
|
|
153
213
|
}
|
|
154
214
|
_hideTooltip() {
|
|
155
215
|
var _a;
|
|
156
|
-
const
|
|
157
|
-
const tooltip = (_a = config.tooltip) !== null && _a !== void 0 ? _a : this.tooltip;
|
|
216
|
+
const tooltip = (_a = this.config.tooltip) !== null && _a !== void 0 ? _a : this.tooltip;
|
|
158
217
|
tooltip === null || tooltip === void 0 ? void 0 : tooltip.hide();
|
|
159
218
|
}
|
|
160
|
-
// We don't want Crosshair to be
|
|
219
|
+
// We don't want Crosshair to be taken into account in domain calculations
|
|
161
220
|
getYDataExtent() {
|
|
162
221
|
return [undefined, undefined];
|
|
163
222
|
}
|
|
164
223
|
getCircleData() {
|
|
165
224
|
var _a, _b;
|
|
166
|
-
const {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
const { datamodel: { data } } = this;
|
|
226
|
+
const { isActive, enableSync } = this._getSyncState();
|
|
227
|
+
if (isFunction(this.config.getCircles)) {
|
|
228
|
+
return this.config.getCircles(this._dataX || this.xScale.invert(this.x), data, this.yScale);
|
|
229
|
+
}
|
|
230
|
+
// Get the datum - either from active mode or from synchronized mode
|
|
231
|
+
let datum = this.datum;
|
|
232
|
+
let datumIndex = this.datumIndex;
|
|
233
|
+
if (!datum && enableSync && !isActive && this._dataX !== undefined) {
|
|
234
|
+
if (isNumber(this._dataX)) {
|
|
235
|
+
datum = getNearest(this.datamodel.data, this._dataX, this.accessors.x);
|
|
236
|
+
datumIndex = this.datamodel.data.indexOf(datum);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (this.config.snapToData && datum) {
|
|
170
240
|
const yAccessors = (_a = this.accessors.y) !== null && _a !== void 0 ? _a : [];
|
|
171
241
|
const yStackedAccessors = (_b = this.accessors.yStacked) !== null && _b !== void 0 ? _b : [];
|
|
172
|
-
const baselineValue = getNumber(
|
|
173
|
-
const stackedValues = getStackedValues(
|
|
174
|
-
.map((value, index
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
242
|
+
const baselineValue = getNumber(datum, this.accessors.baseline, datumIndex) || 0;
|
|
243
|
+
const stackedValues = getStackedValues(datum, datumIndex, ...yStackedAccessors)
|
|
244
|
+
.map((value, index) => {
|
|
245
|
+
const yValue = value + baselineValue;
|
|
246
|
+
const yPixel = this.yScale(yValue);
|
|
247
|
+
return {
|
|
248
|
+
y: yPixel,
|
|
249
|
+
opacity: isNumber(getNumber(datum, yStackedAccessors[index])) ? 1 : 1,
|
|
250
|
+
color: getColor(datum, this.config.color, index),
|
|
251
|
+
strokeColor: this.config.strokeColor ? getColor(datum, this.config.strokeColor, index) : undefined,
|
|
252
|
+
strokeWidth: this.config.strokeWidth ? getNumber(datum, this.config.strokeWidth, index) : undefined,
|
|
253
|
+
};
|
|
254
|
+
});
|
|
181
255
|
const regularValues = yAccessors
|
|
182
256
|
.map((a, index) => {
|
|
183
|
-
const value = getNumber(
|
|
257
|
+
const value = getNumber(datum, a);
|
|
258
|
+
const yPixel = isNumber(value) ? this.yScale(value) : 0;
|
|
184
259
|
return {
|
|
185
|
-
y:
|
|
260
|
+
y: yPixel,
|
|
186
261
|
opacity: isNumber(value) ? 1 : 0,
|
|
187
|
-
color: getColor(
|
|
188
|
-
strokeColor: config.strokeColor ? getColor(
|
|
189
|
-
strokeWidth: config.strokeWidth ? getNumber(
|
|
262
|
+
color: getColor(datum, this.config.color, stackedValues.length + index),
|
|
263
|
+
strokeColor: this.config.strokeColor ? getColor(datum, this.config.strokeColor, index) : undefined,
|
|
264
|
+
strokeWidth: this.config.strokeWidth ? getNumber(datum, this.config.strokeWidth, index) : undefined,
|
|
190
265
|
};
|
|
191
266
|
});
|
|
192
267
|
return stackedValues.concat(regularValues);
|
|
193
268
|
}
|
|
269
|
+
// Return empty array if no data or no datum - crosshair line will still show
|
|
194
270
|
return [];
|
|
195
271
|
}
|
|
272
|
+
_updateFromSync(xData) {
|
|
273
|
+
var _a;
|
|
274
|
+
const { isActive, enableSync } = this._getSyncState();
|
|
275
|
+
if (!enableSync || isActive)
|
|
276
|
+
return;
|
|
277
|
+
// Handle mouse out signal
|
|
278
|
+
if (xData === undefined) {
|
|
279
|
+
this.show = false;
|
|
280
|
+
this._hideTooltip();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (!this.accessors.x || !((_a = this.datamodel.data) === null || _a === void 0 ? void 0 : _a.length))
|
|
284
|
+
return;
|
|
285
|
+
// Check if xPosition is within the chart's x domain
|
|
286
|
+
const xDomain = this.xScale.domain();
|
|
287
|
+
let xValue;
|
|
288
|
+
if (typeof xData === 'number') {
|
|
289
|
+
xValue = xData;
|
|
290
|
+
}
|
|
291
|
+
else if (xData instanceof Date) {
|
|
292
|
+
xValue = xData.getTime();
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
this.show = false;
|
|
296
|
+
this._hideTooltip();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
// If xPosition is outside the chart's domain, hide the crosshair
|
|
300
|
+
const domainMin = typeof xDomain[0] === 'number' ? xDomain[0] : (xDomain[0] instanceof Date ? xDomain[0].getTime() : 0);
|
|
301
|
+
const domainMax = typeof xDomain[1] === 'number' ? xDomain[1] : (xDomain[1] instanceof Date ? xDomain[1].getTime() : 0);
|
|
302
|
+
if (xValue < domainMin || xValue > domainMax) {
|
|
303
|
+
this.show = false;
|
|
304
|
+
this._hideTooltip();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
// Find the datum at this x position
|
|
308
|
+
if (typeof xData === 'number') {
|
|
309
|
+
this.datum = getNearest(this.datamodel.data, xData, this.accessors.x);
|
|
310
|
+
}
|
|
311
|
+
else if (xData instanceof Date) {
|
|
312
|
+
this.datum = getNearest(this.datamodel.data, xData.getTime(), this.accessors.x);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
this.datum = undefined;
|
|
316
|
+
}
|
|
317
|
+
this.datumIndex = this.datamodel.data.indexOf(this.datum);
|
|
318
|
+
// If no datum found, hide the crosshair
|
|
319
|
+
if (!this.datum) {
|
|
320
|
+
this.show = false;
|
|
321
|
+
this._hideTooltip();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const dataX = getNumber(this.datum, this.accessors.x, this.datumIndex);
|
|
325
|
+
this.x = clamp(Math.round(this.xScale(dataX)), 0, this._width);
|
|
326
|
+
this._dataX = dataX;
|
|
327
|
+
// Show the crosshair
|
|
328
|
+
this.show = true;
|
|
329
|
+
// Show tooltip for synchronized chart using the same logic as active charts
|
|
330
|
+
const syntheticEvent = {
|
|
331
|
+
clientX: this.container.node().getBoundingClientRect().left + this.x,
|
|
332
|
+
clientY: this.container.node().getBoundingClientRect().top + this._height / 2,
|
|
333
|
+
};
|
|
334
|
+
this._showTooltip(syntheticEvent);
|
|
335
|
+
}
|
|
336
|
+
_getSyncState() {
|
|
337
|
+
// A chart is active if it's being hovered and doesn't have external sync props
|
|
338
|
+
const isActive = this._isMouseOver && !isNumber(this.config.xPosition) && !this.config.forceShow;
|
|
339
|
+
// A chart is in sync mode if it has external sync props (regardless of mouse state)
|
|
340
|
+
const enableSync = isNumber(this.config.xPosition) || !!this.config.forceShow;
|
|
341
|
+
return { isActive, enableSync };
|
|
342
|
+
}
|
|
196
343
|
}
|
|
197
344
|
Crosshair.selectors = style;
|
|
198
345
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/crosshair/index.ts"],"sourcesContent":["import { Selection, pointer } from 'd3-selection'\nimport { easeLinear } from 'd3-ease'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { Tooltip } from 'components/tooltip'\n\n// Utils\nimport { isNumber, isArray, getNumber, clamp, getStackedValues, getNearest, isFunction } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Types\nimport { Position } from 'types/position'\n\n// Local Types\nimport { CrosshairAccessors, CrosshairCircle } from './types'\n\n// Config\nimport { CrosshairDefaultConfig, CrosshairConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Crosshair<Datum> extends XYComponentCore<Datum, CrosshairConfigInterface<Datum>> {\n static selectors = s\n clippable = true // Don't apply clipping path to this component. See XYContainer\n protected _defaultConfig = CrosshairDefaultConfig as CrosshairConfigInterface<Datum>\n public config: CrosshairConfigInterface<Datum> = this._defaultConfig\n container: Selection<SVGSVGElement, any, SVGSVGElement, any>\n line: Selection<SVGLineElement, any, SVGElement, any>\n x = 0\n datum: Datum\n datumIndex: number\n show = false\n private _animFrameId: number = null\n\n /** Tooltip component to be used by Crosshair if not provided by the config.\n * This property is supposed to be set externally by a container component like XYContainer. */\n public tooltip: Tooltip\n\n /** Accessors passed externally (e.g. from XYContainer) */\n private _accessors: CrosshairAccessors<Datum> = {\n x: undefined,\n y: undefined,\n yStacked: undefined,\n baseline: undefined,\n }\n\n public set accessors (accessors: CrosshairAccessors<Datum>) { this._accessors = accessors }\n public get accessors (): CrosshairAccessors<Datum> {\n const { config } = this\n\n const hasConfig = !!(config.x || config.y || config.yStacked)\n const x = hasConfig ? config.x : this._accessors.x\n const yAcc = hasConfig ? config.y : this._accessors.y\n const y = yAcc ? (isArray(yAcc) ? yAcc : [yAcc]) : undefined\n const yStacked = hasConfig ? config.yStacked : this._accessors.yStacked\n const baseline = config.baseline ?? this._accessors.baseline\n\n return { x, y, yStacked, baseline }\n }\n\n constructor (config?: CrosshairConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n\n this.g.style('opacity', this.show ? 1 : 0)\n this.line = this.g.append('line')\n .attr('class', s.line)\n }\n\n setContainer (containerSvg: Selection<SVGSVGElement, unknown, SVGSVGElement, unknown>): void {\n // Set up mousemove event for Crosshair\n this.container = containerSvg\n this.container.on('mousemove.crosshair', this._onMouseMove.bind(this))\n this.container.on('mouseout.crosshair', this._onMouseOut.bind(this))\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n if (config.snapToData && !this.datum) return\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n smartTransition(this.g, duration)\n .style('opacity', this.show ? 1 : 0)\n\n this.line\n .attr('y1', 0)\n .attr('y1', this._height)\n\n smartTransition(this.line, duration, easeLinear)\n .attr('x1', this.x)\n .attr('x2', this.x)\n\n const circleData = this.getCircleData()\n const circles = this.g\n .selectAll<SVGCircleElement, CrosshairCircle>('circle')\n .data(circleData, (d, i) => d.id ?? i)\n\n const circlesEnter = circles.enter()\n .append('circle')\n .attr('class', s.circle)\n .attr('r', 0)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n smartTransition(circlesEnter.merge(circles), duration, easeLinear)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .attr('r', 4)\n .style('opacity', d => d.opacity)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n circles.exit().remove()\n }\n\n hide (): void {\n this._onMouseOut()\n }\n\n _onMouseMove (event: MouseEvent): void {\n const { config, datamodel, element } = this\n if (!this.accessors.x && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: X accessor function has not been configured. Please check if it\\'s present in the configuration object')\n }\n const [x] = pointer(event, element)\n const xRange = this.xScale.range()\n\n if (config.snapToData) {\n if (!this.accessors.y && !this.accessors.yStacked && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: Y accessors have not been configured. Please check if they\\'re present in the configuration object')\n }\n const scaleX = this.xScale\n const valueX = scaleX.invert(x) as number\n\n this.datum = getNearest(datamodel.data, valueX, this.accessors.x)\n this.datumIndex = datamodel.data.indexOf(this.datum)\n if (!this.datum) return\n\n this.x = clamp(Math.round(scaleX(getNumber(this.datum, this.accessors.x, this.datumIndex))), 0, this._width)\n\n // Show the crosshair only if it's in the chart range and not far from mouse pointer (if configured)\n this.show = (this.x >= 0) && (this.x <= this._width) && (!config.hideWhenFarFromPointer || (Math.abs(this.x - x) < config.hideWhenFarFromPointerDistance))\n } else {\n const tolerance = 2 // Show the crosshair when it is at least 2 pixels close to the chart area\n this.x = clamp(x, xRange[0], xRange[1])\n this.show = (x >= (xRange[0] - tolerance)) && (x <= (xRange[1] + tolerance))\n }\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n\n if (this.show) this._showTooltip(event)\n else this._hideTooltip()\n }\n\n _onMouseOut (): void {\n this.show = false\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n this._hideTooltip()\n }\n\n _showTooltip (event: MouseEvent): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n if (!tooltip) return\n\n const container = tooltip.getContainer() || this.container.node()\n const [x, y] = tooltip.isContainerBody() ? [event.clientX, event.clientY] : pointer(event, container)\n const content = config.template(this.datum, this.xScale.invert(this.x))\n // Force set `followCursor` to `true` because we don't want Crosshair's tooltip to be hoverable\n tooltip.config.followCursor = true\n\n // Set tooltip placement based on Crosshair's position (left / right)\n if (!tooltip.config.horizontalPlacement || tooltip.config.horizontalPlacement === Position.Auto) {\n const xRelative = tooltip.isContainerBody() ? x - this.container.node().getBoundingClientRect().left : x\n tooltip.overrideHorizontalPlacement(xRelative > this._containerWidth / 2 ? Position.Left : Position.Right)\n }\n\n if (content) tooltip.show(content, { x, y })\n }\n\n _hideTooltip (): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n tooltip?.hide()\n }\n\n // We don't want Crosshair to be be taken in to account in domain calculations\n getYDataExtent (): number[] {\n return [undefined, undefined]\n }\n\n private getCircleData (): CrosshairCircle[] {\n const { config, datamodel: { data } } = this\n\n if (isFunction(config.getCircles)) return config.getCircles(this.xScale.invert(this.x), data, this.yScale)\n\n if (config.snapToData && this.datum) {\n const yAccessors = this.accessors.y ?? []\n const yStackedAccessors = this.accessors.yStacked ?? []\n const baselineValue = getNumber(this.datum, this.accessors.baseline, this.datumIndex) || 0\n const stackedValues: CrosshairCircle[] = getStackedValues(this.datum, this.datumIndex, ...yStackedAccessors)\n .map((value, index, arr) => ({\n y: this.yScale(value + baselineValue),\n opacity: isNumber(getNumber(this.datum, yStackedAccessors[index])) ? 1 : 0,\n color: getColor(this.datum, config.color, index),\n strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,\n strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,\n }))\n\n const regularValues: CrosshairCircle[] = yAccessors\n .map((a, index) => {\n const value = getNumber(this.datum, a)\n return {\n y: this.yScale(value),\n opacity: isNumber(value) ? 1 : 0,\n color: getColor(this.datum, config.color, stackedValues.length + index),\n strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,\n strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,\n }\n })\n\n return stackedValues.concat(regularValues)\n }\n\n return []\n }\n}\n"],"names":["s.line","s.circle","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/crosshair/index.ts"],"sourcesContent":["import { Selection, pointer } from 'd3-selection'\nimport { easeLinear } from 'd3-ease'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { Tooltip } from 'components/tooltip'\n\n// Utils\nimport { isNumber, isArray, getNumber, clamp, getStackedValues, getNearest, isFunction } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Types\nimport { Position } from 'types/position'\n\n// Local Types\nimport { CrosshairAccessors, CrosshairCircle } from './types'\n\n// Config\nimport { CrosshairDefaultConfig, CrosshairConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Crosshair<Datum> extends XYComponentCore<Datum, CrosshairConfigInterface<Datum>> {\n static selectors = s\n clippable = true // Don't apply clipping path to this component. See XYContainer\n protected _defaultConfig = CrosshairDefaultConfig as CrosshairConfigInterface<Datum>\n public config: CrosshairConfigInterface<Datum> = this._defaultConfig\n container: Selection<SVGSVGElement, any, SVGSVGElement, any>\n line: Selection<SVGLineElement, any, SVGElement, any>\n x = 0\n datum: Datum\n datumIndex: number\n show = false\n private _animFrameId: number = null\n private _dataX: number | Date | undefined = undefined\n private _isMouseOver = false\n\n /** Tooltip component to be used by Crosshair if not provided by the config.\n * This property is supposed to be set externally by a container component like XYContainer. */\n public tooltip: Tooltip\n\n /** Accessors passed externally (e.g. from XYContainer) */\n private _accessors: CrosshairAccessors<Datum> = {\n x: undefined,\n y: undefined,\n yStacked: undefined,\n baseline: undefined,\n }\n\n public set accessors (accessors: CrosshairAccessors<Datum>) { this._accessors = accessors }\n public get accessors (): CrosshairAccessors<Datum> {\n const { config } = this\n // If x or y are explicitly set in config, use those; otherwise use container accessors\n const x = config.x || this._accessors.x\n const yAcc = config.y || this._accessors.y\n const y = yAcc ? (isArray(yAcc) ? yAcc : [yAcc]) : undefined\n const yStacked = config.yStacked || this._accessors.yStacked\n const baseline = config.baseline ?? this._accessors.baseline\n\n return { x, y, yStacked, baseline }\n }\n\n constructor (config?: CrosshairConfigInterface<Datum>) {\n super()\n if (config) this.config = { ...this.config, ...config }\n\n this.g.style('opacity', this.show ? 1 : 0)\n this.line = this.g.append('line')\n .attr('class', s.line)\n }\n\n setContainer (containerSvg: Selection<SVGSVGElement, unknown, SVGSVGElement, unknown>): void {\n this.container = containerSvg\n this.container.on('mousemove.crosshair', this._onMouseMove.bind(this))\n this.container.on('mouseout.crosshair', this._onMouseOut.bind(this))\n this._render()\n }\n\n setConfig (config: CrosshairConfigInterface<Datum>): void {\n super.setConfig(config)\n // For synchronized charts, update from sync when config changes\n const { isActive, enableSync } = this._getSyncState()\n if (enableSync && !isActive && (isNumber(config.xPosition) || config.xPosition instanceof Date)) {\n this._updateFromSync(config.xPosition)\n }\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n const { isActive, enableSync } = this._getSyncState()\n // Handle synchronized charts with xPosition prop\n if (enableSync && !isActive && (isNumber(config.xPosition) || config.xPosition instanceof Date)) {\n this._updateFromSync(config.xPosition)\n }\n\n smartTransition(this.g, duration).style('opacity', this.show ? 1 : 0)\n\n this.line\n .attr('y1', 0)\n .attr('y2', this._height)\n\n smartTransition(this.line, duration, easeLinear)\n .attr('x1', this.x)\n .attr('x2', this.x)\n\n const circleData = this.getCircleData()\n const circles = this.g\n .selectAll<SVGCircleElement, CrosshairCircle>('circle')\n .data(circleData, (d, i) => d.id ?? i)\n\n const circlesEnter = circles.enter()\n .append('circle')\n .attr('class', s.circle)\n .attr('r', 0)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n smartTransition(circlesEnter.merge(circles), duration, easeLinear)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .attr('r', 4)\n .style('opacity', d => d.opacity)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n circles.exit().remove()\n }\n\n hide (): void {\n this._onMouseOut()\n }\n\n destroy (): void {\n if (this._animFrameId) {\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = null\n }\n this._hideTooltip()\n }\n\n _onMouseMove (event: MouseEvent): void {\n // Throttle the entire mouse move processing\n if (this._animFrameId) return\n this._animFrameId = window.requestAnimationFrame(() => {\n this._processMouseMove(event)\n this._animFrameId = null\n })\n }\n\n private _processMouseMove (event: MouseEvent): void {\n this._isMouseOver = true\n const { config, datamodel, element } = this\n const { isActive, enableSync } = this._getSyncState()\n\n // Early return for synchronized non-active charts, but allow tooltip display\n if (enableSync && !isActive) {\n if (this.show && this.datum) {\n this._showTooltip(event)\n } else if (this.show && this._dataX !== undefined && isNumber(this._dataX)) {\n // For synchronized charts, find the datum if it doesn't exist\n this.datum = getNearest(this.datamodel.data, this._dataX, this.accessors.x)\n if (this.datum) {\n this._showTooltip(event)\n }\n }\n return\n }\n\n // Check if we have the necessary accessors\n if (!this.accessors.x && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: X accessor function has not been configured. Please check if it\\'s present in the configuration object')\n return\n }\n\n const [x] = pointer(event, element)\n const xRange = this.xScale.range()\n\n if (config.snapToData) {\n if (!this.accessors.y && !this.accessors.yStacked && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: Y accessors have not been configured. Please check if they\\'re present in the configuration object')\n return\n }\n const scaleX = this.xScale\n const valueX = scaleX.invert(x) as number\n\n this.datum = getNearest(datamodel.data, valueX, this.accessors.x)\n this.datumIndex = datamodel.data.indexOf(this.datum)\n if (!this.datum) return\n\n const dataX = getNumber(this.datum, this.accessors.x, this.datumIndex)\n this.x = clamp(Math.round(scaleX(dataX)), 0, this._width)\n this._dataX = dataX\n\n // Show the crosshair only if it's in the chart range and not far from mouse pointer (if configured)\n this.show = (this.x >= 0) && (this.x <= this._width) && (!config.hideWhenFarFromPointer || (Math.abs(this.x - x) < config.hideWhenFarFromPointerDistance))\n } else {\n const tolerance = 2 // Show the crosshair when it is at least 2 pixels close to the chart area\n this.x = clamp(x, xRange[0], xRange[1])\n this._dataX = this.xScale.invert(this.x)\n this.show = (x >= (xRange[0] - tolerance)) && (x <= (xRange[1] + tolerance))\n }\n\n // Call onCrosshairMove callback if provided\n if (this.show && config.onCrosshairMove && this._dataX !== undefined) {\n config.onCrosshairMove(this._dataX)\n }\n\n // Render immediately since we're already in a throttled context\n this._render()\n\n if (this.show) this._showTooltip(event)\n else this._hideTooltip()\n }\n\n _onMouseOut (): void {\n this._isMouseOver = false\n const { config } = this\n\n // Always hide on mouse out\n this.show = false\n this._hideTooltip()\n\n // Throttle rendering using requestAnimationFrame\n if (this._animFrameId) return\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n this._animFrameId = null\n })\n\n // If this is the active chart, notify parent to clear sync state\n if (config.onCrosshairMove) {\n config.onCrosshairMove(undefined)\n }\n }\n\n _showTooltip (event: MouseEvent): void {\n const tooltip = this.config.tooltip ?? this.tooltip\n\n if (!tooltip || !this.datum) return\n\n const container = tooltip.getContainer() || this.container.node()\n const [x, y] = tooltip.isContainerBody() ? [event.clientX, event.clientY] : pointer(event, container)\n const content = this.config.template(this.datum, this._dataX || this.xScale.invert(this.x))\n\n tooltip.config.followCursor = true\n\n // Set tooltip placement based on Crosshair's position (left / right)\n if (!tooltip.config.horizontalPlacement || tooltip.config.horizontalPlacement === Position.Auto) {\n const xRelative = tooltip.isContainerBody() ? x - this.container.node().getBoundingClientRect().left : x\n tooltip.overrideHorizontalPlacement(xRelative > this._containerWidth / 2 ? Position.Left : Position.Right)\n }\n\n if (content) tooltip.show(content, { x, y })\n }\n\n _hideTooltip (): void {\n const tooltip = this.config.tooltip ?? this.tooltip\n tooltip?.hide()\n }\n\n // We don't want Crosshair to be taken into account in domain calculations\n getYDataExtent (): number[] {\n return [undefined, undefined]\n }\n\n private getCircleData (): CrosshairCircle[] {\n const { datamodel: { data } } = this\n const { isActive, enableSync } = this._getSyncState()\n if (isFunction(this.config.getCircles)) {\n return this.config.getCircles(this._dataX || this.xScale.invert(this.x), data, this.yScale)\n }\n // Get the datum - either from active mode or from synchronized mode\n let datum = this.datum\n let datumIndex = this.datumIndex\n if (!datum && enableSync && !isActive && this._dataX !== undefined) {\n if (isNumber(this._dataX)) {\n datum = getNearest(this.datamodel.data, this._dataX, this.accessors.x)\n datumIndex = this.datamodel.data.indexOf(datum)\n }\n }\n\n if (this.config.snapToData && datum) {\n const yAccessors = this.accessors.y ?? []\n const yStackedAccessors = this.accessors.yStacked ?? []\n const baselineValue = getNumber(datum, this.accessors.baseline, datumIndex) || 0\n\n const stackedValues: CrosshairCircle[] = getStackedValues(datum, datumIndex, ...yStackedAccessors)\n .map((value, index) => {\n const yValue = value + baselineValue\n const yPixel = this.yScale(yValue)\n return {\n y: yPixel,\n opacity: isNumber(getNumber(datum, yStackedAccessors[index])) ? 1 : 1,\n color: getColor(datum, this.config.color, index),\n strokeColor: this.config.strokeColor ? getColor(datum, this.config.strokeColor, index) : undefined,\n strokeWidth: this.config.strokeWidth ? getNumber(datum, this.config.strokeWidth, index) : undefined,\n }\n })\n\n const regularValues: CrosshairCircle[] = yAccessors\n .map((a, index) => {\n const value = getNumber(datum, a)\n const yPixel = isNumber(value) ? this.yScale(value) : 0\n return {\n y: yPixel,\n opacity: isNumber(value) ? 1 : 0, // Hide circles with invalid values\n color: getColor(datum, this.config.color, stackedValues.length + index),\n strokeColor: this.config.strokeColor ? getColor(datum, this.config.strokeColor, index) : undefined,\n strokeWidth: this.config.strokeWidth ? getNumber(datum, this.config.strokeWidth, index) : undefined,\n }\n })\n\n return stackedValues.concat(regularValues)\n }\n\n // Return empty array if no data or no datum - crosshair line will still show\n return []\n }\n\n _updateFromSync (xData: number | Date | undefined): void {\n const { isActive, enableSync } = this._getSyncState()\n if (!enableSync || isActive) return\n\n // Handle mouse out signal\n if (xData === undefined) {\n this.show = false\n this._hideTooltip()\n return\n }\n\n if (!this.accessors.x || !this.datamodel.data?.length) return\n\n // Check if xPosition is within the chart's x domain\n const xDomain = this.xScale.domain()\n let xValue: number\n if (typeof xData === 'number') {\n xValue = xData\n } else if (xData instanceof Date) {\n xValue = xData.getTime()\n } else {\n this.show = false\n this._hideTooltip()\n return\n }\n\n // If xPosition is outside the chart's domain, hide the crosshair\n const domainMin = typeof xDomain[0] === 'number' ? xDomain[0] : (xDomain[0] instanceof Date ? xDomain[0].getTime() : 0)\n const domainMax = typeof xDomain[1] === 'number' ? xDomain[1] : (xDomain[1] instanceof Date ? xDomain[1].getTime() : 0)\n if (xValue < domainMin || xValue > domainMax) {\n this.show = false\n this._hideTooltip()\n return\n }\n\n // Find the datum at this x position\n if (typeof xData === 'number') {\n this.datum = getNearest(this.datamodel.data, xData, this.accessors.x)\n } else if (xData instanceof Date) {\n this.datum = getNearest(this.datamodel.data, xData.getTime(), this.accessors.x)\n } else {\n this.datum = undefined\n }\n this.datumIndex = this.datamodel.data.indexOf(this.datum)\n\n // If no datum found, hide the crosshair\n if (!this.datum) {\n this.show = false\n this._hideTooltip()\n return\n }\n\n const dataX = getNumber(this.datum, this.accessors.x, this.datumIndex)\n this.x = clamp(Math.round(this.xScale(dataX)), 0, this._width)\n this._dataX = dataX\n\n // Show the crosshair\n this.show = true\n\n // Show tooltip for synchronized chart using the same logic as active charts\n const syntheticEvent = {\n clientX: this.container.node().getBoundingClientRect().left + this.x,\n clientY: this.container.node().getBoundingClientRect().top + this._height / 2,\n } as MouseEvent\n this._showTooltip(syntheticEvent)\n }\n\n private _getSyncState (): { isActive: boolean; enableSync: boolean } {\n // A chart is active if it's being hovered and doesn't have external sync props\n const isActive = this._isMouseOver && !isNumber(this.config.xPosition) && !this.config.forceShow\n // A chart is in sync mode if it has external sync props (regardless of mouse state)\n const enableSync = isNumber(this.config.xPosition) || !!this.config.forceShow\n return { isActive, enableSync }\n }\n}\n"],"names":["s.line","s.circle","s"],"mappings":"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"}
|
|
@@ -62,6 +62,14 @@ export interface GraphConfigInterface<N extends GraphInputNode, L extends GraphI
|
|
|
62
62
|
* Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.
|
|
63
63
|
* Default: `1` */
|
|
64
64
|
layoutParallelSubGroupsPerRow?: number;
|
|
65
|
+
/** Spacing between nodes, dynamic by default.
|
|
66
|
+
* Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.
|
|
67
|
+
* Default: `undefined` */
|
|
68
|
+
layoutParallelNodeSpacing?: number | [number, number];
|
|
69
|
+
/** Spacing between sub-groups.
|
|
70
|
+
* Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.
|
|
71
|
+
* Default: `40` */
|
|
72
|
+
layoutParallelSubGroupSpacing?: number;
|
|
65
73
|
/** Spacing between groups.
|
|
66
74
|
* Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.
|
|
67
75
|
* Default: `undefined` */
|
|
@@ -4,7 +4,7 @@ import { TrimMode } from '../../types/text.js';
|
|
|
4
4
|
import { GraphLayoutType, GraphFitViewAlignment, GraphLinkStyle, GraphNodeShape, GraphNodeSelectionHighlightMode } from './types.js';
|
|
5
5
|
|
|
6
6
|
// Utils
|
|
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, fitViewPadding: 50, fitViewAlign: GraphFitViewAlignment.Center, layoutGroupOrder: [], layoutParallelSubGroupsPerRow: 1, layoutParallelNodesPerColumn: 6, layoutParallelGroupSpacing: undefined, layoutParallelSortConnectionsByGroup: undefined, layoutNodeGroup: (n) => n.group, layoutParallelNodeSubGroup: (n) => n.subgroup, forceLayoutSettings: {
|
|
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, fitViewPadding: 50, fitViewAlign: GraphFitViewAlignment.Center, layoutGroupOrder: [], layoutParallelNodeSpacing: undefined, layoutParallelSubGroupsPerRow: 1, layoutParallelNodesPerColumn: 6, layoutParallelGroupSpacing: undefined, layoutParallelSubGroupSpacing: 40, layoutParallelSortConnectionsByGroup: undefined, layoutNodeGroup: (n) => n.group, layoutParallelNodeSubGroup: (n) => n.subgroup, forceLayoutSettings: {
|
|
8
8
|
linkDistance: 60,
|
|
9
9
|
linkStrength: 0.45,
|
|
10
10
|
charge: -500,
|
|
@@ -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'\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 { Spacing } from 'types/spacing'\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 GraphFitViewAlignment,\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 /** Padding for the graph when fitting to container. Default: `50` */\n fitViewPadding?: Spacing | number;\n /** Default alignment when fitting the graph view. Default: `GraphFitViewAlignment.Center` */\n fitViewAlign?: GraphFitViewAlignment;\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 fitViewPadding: 50,\n fitViewAlign: GraphFitViewAlignment.Center,\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
|
+
{"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 { Spacing } from 'types/spacing'\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 GraphFitViewAlignment,\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 /** Padding for the graph when fitting to container. Default: `50` */\n fitViewPadding?: Spacing | number;\n /** Default alignment when fitting the graph view. Default: `GraphFitViewAlignment.Center` */\n fitViewAlign?: GraphFitViewAlignment;\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 nodes, dynamic by default.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `undefined` */\n layoutParallelNodeSpacing?: number | [number, number];\n /** Spacing between sub-groups.\n * Only for `GraphLayoutType.Parallel` and `GraphLayoutType.ParallelHorizontal` layouts.\n * Default: `40` */\n layoutParallelSubGroupSpacing?: 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 fitViewPadding: 50,\n fitViewAlign: GraphFitViewAlignment.Center,\n\n layoutGroupOrder: [],\n layoutParallelNodeSpacing: undefined,\n layoutParallelSubGroupsPerRow: 1,\n layoutParallelNodesPerColumn: 6,\n layoutParallelGroupSpacing: undefined,\n layoutParallelSubGroupSpacing: 40,\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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"}
|