@unovis/ts 1.5.0-alpha.8 → 1.5.0-nikita.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/components/graph/config.d.ts +12 -1
  2. package/components/graph/config.js +3 -3
  3. package/components/graph/config.js.map +1 -1
  4. package/components/graph/index.d.ts +15 -5
  5. package/components/graph/index.js +199 -74
  6. package/components/graph/index.js.map +1 -1
  7. package/components/graph/modules/link/index.d.ts +2 -1
  8. package/components/graph/modules/link/index.js +7 -4
  9. package/components/graph/modules/link/index.js.map +1 -1
  10. package/components/graph/modules/node/index.d.ts +2 -1
  11. package/components/graph/modules/node/index.js +6 -5
  12. package/components/graph/modules/node/index.js.map +1 -1
  13. package/components/graph/modules/node/style.d.ts +2 -0
  14. package/components/graph/modules/node/style.js +34 -4
  15. package/components/graph/modules/node/style.js.map +1 -1
  16. package/components/graph/style.d.ts +1 -0
  17. package/components/graph/style.js +22 -1
  18. package/components/graph/style.js.map +1 -1
  19. package/components/graph/types.d.ts +6 -0
  20. package/components/graph/types.js +8 -2
  21. package/components/graph/types.js.map +1 -1
  22. package/components/scatter/index.d.ts +1 -0
  23. package/components/scatter/index.js +19 -12
  24. package/components/scatter/index.js.map +1 -1
  25. package/components/scatter/modules/point.js +1 -3
  26. package/components/scatter/modules/point.js.map +1 -1
  27. package/components/scatter/types.d.ts +2 -0
  28. package/data-models/graph.d.ts +2 -0
  29. package/data-models/graph.js +6 -0
  30. package/data-models/graph.js.map +1 -1
  31. package/index.js +1 -1
  32. package/package.json +1 -1
  33. package/types/graph.d.ts +2 -0
  34. package/types.js +1 -1
@@ -1,6 +1,7 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import { min, max } from 'd3-array';
3
3
  import { select, pointer } from 'd3-selection';
4
+ import { brush as brush$1 } from 'd3-brush';
4
5
  import { zoom, zoomTransform, zoomIdentity } from 'd3-zoom';
5
6
  import { drag } from 'd3-drag';
6
7
  import { interval } from 'd3-timer';
@@ -8,16 +9,16 @@ import { ComponentCore } from '../../core/component/index.js';
8
9
  import { GraphDataModel } from '../../data-models/graph.js';
9
10
  import { isNumber, isFunction, clamp, getBoolean, shallowDiff, isPlainObject, isEqual } from '../../utils/data.js';
10
11
  import { smartTransition } from '../../utils/d3.js';
11
- import { GraphLayoutType, GraphLinkArrowStyle } from './types.js';
12
+ import { GraphLayoutType, GraphNodeSelectionHighlightMode, GraphLinkArrowStyle } from './types.js';
12
13
  import { GraphDefaultConfig } from './config.js';
13
- import { background, graphGroup, root } from './style.js';
14
+ import { background, graphGroup, brush, root } from './style.js';
14
15
  import * as style from './modules/node/style.js';
15
- import { nodes, gNode, gNodeExit, node, nodeGauge, sideLabelGroup, label, greyedOutNode } from './modules/node/style.js';
16
+ import { nodes, gNode, gNodeExit, brushed, brushable, node, nodeGauge, sideLabelGroup, label, greyedOutNode } from './modules/node/style.js';
16
17
  import { links, gLink, gLinkExit, link, greyedOutLink } from './modules/link/style.js';
17
18
  import { panels, gPanel, panel, panelSelection, label as label$1, labelText, sideIconGroup, sideIconShape, sideIconSymbol } from './modules/panel/style.js';
18
- import { createNodes, updateNodes, removeNodes, updateNodeSelectedGreyout, zoomNodesThrottled, zoomNodes } from './modules/node/index.js';
19
+ import { createNodes, updateNodes, removeNodes, updateNodesPartial, zoomNodesThrottled, zoomNodes } from './modules/node/index.js';
19
20
  import { getMaxNodeSize, getX, getY, getNodeSize } from './modules/node/helper.js';
20
- import { createLinks, updateLinks, removeLinks, updateSelectedLinks, animateLinkFlow, zoomLinksThrottled, zoomLinks } from './modules/link/index.js';
21
+ import { createLinks, updateLinks, removeLinks, updateLinksPartial, animateLinkFlow, zoomLinksThrottled, zoomLinks } from './modules/link/index.js';
21
22
  import { getArrowPath, getDoubleArrowPath } from './modules/link/helper.js';
22
23
  import { removePanels, createPanels, updatePanels } from './modules/panel/index.js';
23
24
  import { updatePanelNumNodes, updatePanelBBoxSize, initPanels, setPanelForNodes } from './modules/panel/helper.js';
@@ -53,9 +54,14 @@ class Graph extends ComponentCore {
53
54
  this.setConfig(config);
54
55
  this._backgroundRect = this.g.append('rect').attr('class', background);
55
56
  this._graphGroup = this.g.append('g').attr('class', graphGroup);
57
+ this._brush = this.g.append('g').attr('class', brush);
56
58
  this._zoomBehavior = zoom()
57
59
  .scaleExtent(this.config.zoomScaleExtent)
58
60
  .on('zoom', (e) => this._onZoom(e.transform, e));
61
+ this._brushBehavior = brush$1()
62
+ .on('start brush end', this._onBrush.bind(this))
63
+ .filter(event => event.shiftKey)
64
+ .keyModifiers(false);
59
65
  this._panelsGroup = this._graphGroup.append('g').attr('class', panels);
60
66
  this._linksGroup = this._graphGroup.append('g').attr('class', links);
61
67
  this._nodesGroup = this._graphGroup.append('g').attr('class', nodes);
@@ -63,7 +69,11 @@ class Graph extends ComponentCore {
63
69
  this._getLinkArrowDefId = this._getLinkArrowDefId.bind(this);
64
70
  }
65
71
  get selectedNode() {
66
- return this._selectedNode;
72
+ var _a;
73
+ return (_a = this._selectedNodes) === null || _a === void 0 ? void 0 : _a[0];
74
+ }
75
+ get selectedNodes() {
76
+ return this._selectedNodes;
67
77
  }
68
78
  get selectedLink() {
69
79
  return this._selectedLink;
@@ -95,7 +105,7 @@ class Graph extends ComponentCore {
95
105
  return { top: extraPadding, bottom: extraPadding, left: extraPadding, right: extraPadding };
96
106
  }
97
107
  _render(customDuration) {
98
- const { config: { disableZoom, duration, layoutAutofit, zoomEventFilter }, datamodel } = this;
108
+ const { config: { disableBrush, disableZoom, duration, layoutAutofit, zoomEventFilter }, datamodel } = this;
99
109
  if (!datamodel.nodes && !datamodel.links)
100
110
  return;
101
111
  const animDuration = isNumber(customDuration) ? customDuration : duration;
@@ -109,6 +119,25 @@ class Graph extends ComponentCore {
109
119
  this._prevWidth = this._width;
110
120
  this._prevHeight = this._height;
111
121
  }
122
+ // Handle brush behavior
123
+ if (!disableBrush) {
124
+ this._brushBehavior.extent([[0, 0], [this._width, this._height]]);
125
+ this._brush.call(this._brushBehavior);
126
+ // Activate the brush when the shift key is pressed
127
+ select(window)
128
+ .on('keydown.unovis-graph', e => e.key === 'Shift' && this._activateBrush())
129
+ .on('keyup.unovis-graph', e => e.key === 'Shift' && this._clearBrush());
130
+ this._zoomBehavior.filter(event => !event.shiftKey);
131
+ }
132
+ else {
133
+ this._brush.on('.brush', null);
134
+ select(window)
135
+ .on('keydown.unovis-graph', null)
136
+ .on('keyup.unovis-graph', null);
137
+ // Clear brush in case it was disabled in an active state
138
+ if (this._brush.classed('active'))
139
+ this._clearBrush();
140
+ }
112
141
  // Apply layout and render
113
142
  if (this._shouldRecalculateLayout || !this._layoutCalculationPromise) {
114
143
  this._layoutCalculationPromise = this._calculateLayout();
@@ -119,13 +148,14 @@ class Graph extends ComponentCore {
119
148
  (_b = (_a = this.config).onLayoutCalculated) === null || _b === void 0 ? void 0 : _b.call(_a, datamodel.nodes, datamodel.links);
120
149
  });
121
150
  }
122
- // Redefine Zoom Behavior filter is specified in the config
123
- // https://d3js.org/d3-zoom#zoom_filter
151
+ // Redefining Zoom Behavior filter to the one specified in the config,
152
+ // or to the default one supporting `shiftKey` for node brushing
153
+ // See more: https://d3js.org/d3-zoom#zoom_filter
124
154
  this._zoomBehavior.filter(isFunction(zoomEventFilter)
125
155
  ? zoomEventFilter
126
- : (e) => !e.shiftKey); // Default filter
156
+ : (e) => (!e.ctrlKey || e.type === 'wheel') && !e.button && !e.shiftKey); // Default filter
127
157
  this._layoutCalculationPromise.then((isFirstRender) => {
128
- var _a, _b;
158
+ var _a, _b, _c;
129
159
  // If the component has been destroyed while the layout calculation
130
160
  // was in progress, we cancel the render
131
161
  if (this.isDestroyed())
@@ -140,19 +170,20 @@ class Graph extends ComponentCore {
140
170
  this._fit(duration);
141
171
  this._shouldFitLayout = false;
142
172
  }
143
- // Draw
144
- this._drawNodes(animDuration);
145
- this._drawLinks(animDuration);
146
- // Select Links / Nodes
147
- this._resetSelection();
148
- if (this.config.selectedNodeId) {
149
- const selectedNode = datamodel.nodes.find(node => node.id === this.config.selectedNodeId);
150
- this._selectNode(selectedNode);
173
+ // Update Nodes and Links Selection State
174
+ this._resetSelectionGreyoutState();
175
+ if (this.config.selectedNodeId || this.config.selectedNodeIds) {
176
+ const selectedIds = (_a = this.config.selectedNodeIds) !== null && _a !== void 0 ? _a : [this.config.selectedNodeId];
177
+ const selectedNodes = selectedIds.map(id => datamodel.getNodeFromId(id));
178
+ this._setNodeSelectionState(selectedNodes);
151
179
  }
152
180
  if (this.config.selectedLinkId) {
153
181
  const selectedLink = datamodel.links.find(link => link.id === this.config.selectedLinkId);
154
- this._selectLink(selectedLink);
182
+ this._setLinkSelectionState(selectedLink);
155
183
  }
184
+ // Draw
185
+ this._drawNodes(animDuration);
186
+ this._drawLinks(animDuration);
156
187
  // Link flow animation timer
157
188
  if (!this._timer) {
158
189
  const refreshRateMs = 35;
@@ -180,7 +211,7 @@ class Graph extends ComponentCore {
180
211
  this._setUpComponentEventsThrottled();
181
212
  this._setCustomAttributesThrottled();
182
213
  // On render complete callback
183
- (_b = (_a = this.config).onRenderComplete) === null || _b === void 0 ? void 0 : _b.call(_a, this.g, datamodel.nodes, datamodel.links, this.config, animDuration, this._scale, this._width, this._height);
214
+ (_c = (_b = this.config).onRenderComplete) === null || _c === void 0 ? void 0 : _c.call(_b, this.g, datamodel.nodes, datamodel.links, this.config, animDuration, this._scale, this._containerWidth, this._containerHeight);
184
215
  });
185
216
  this._isFirstRender = false;
186
217
  }
@@ -204,9 +235,9 @@ class Graph extends ComponentCore {
204
235
  const thisRef = this;
205
236
  if (!config.disableDrag) {
206
237
  const dragBehaviour = drag()
207
- .on('start', function (event, d) { thisRef._onDragStarted(d, event, select(this)); })
208
- .on('drag', function (event, d) { thisRef._onDragged(d, event, nodeGroupsMerged); })
209
- .on('end', function (event, d) { thisRef._onDragEnded(d, event, select(this)); });
238
+ .on('start drag end', function (event, d) {
239
+ thisRef._handleDrag(d, event, select(this));
240
+ });
210
241
  nodeGroupsMerged.call(dragBehaviour);
211
242
  }
212
243
  else {
@@ -348,38 +379,45 @@ class Graph extends ComponentCore {
348
379
  .scale(clampedScale);
349
380
  return transform;
350
381
  }
351
- _selectNode(node) {
352
- const { datamodel: { nodes, links } } = this;
353
- if (!node)
354
- console.warn('Unovis | Graph: Select Node: Not found');
355
- this._selectedNode = node;
356
- // Apply grey out
357
- // Grey out all nodes
358
- nodes.forEach(n => {
382
+ _setNodeSelectionState(nodesToSelect) {
383
+ const { config, datamodel } = this;
384
+ // Grey out all nodes and set us unselected
385
+ for (const n of datamodel.nodes) {
359
386
  n._state.selected = false;
360
- n._state.greyout = true;
361
- });
362
- // Grey out all links
363
- links.forEach(l => {
364
- l._state.greyout = true;
387
+ if (config.nodeSelectionHighlightMode !== GraphNodeSelectionHighlightMode.None) {
388
+ n._state.greyout = true;
389
+ }
390
+ }
391
+ // Grey out all links and set us unselected
392
+ for (const l of datamodel.links) {
365
393
  l._state.selected = false;
394
+ if (config.nodeSelectionHighlightMode !== GraphNodeSelectionHighlightMode.None) {
395
+ l._state.greyout = true;
396
+ }
397
+ }
398
+ // Filter out non-existing nodes
399
+ this._selectedNodes = nodesToSelect.filter(n => {
400
+ const doesNodeExist = Boolean(n);
401
+ if (!doesNodeExist)
402
+ console.warn('Unovis | Graph: Select Node: Not found');
403
+ return doesNodeExist;
366
404
  });
367
- // Highlight selected
368
- if (node) {
369
- node._state.selected = true;
370
- node._state.greyout = false;
371
- const connectedLinks = links.filter(l => (l.source === node) || (l.target === node));
405
+ // Set provided nodes as selected and ungreyout
406
+ for (const n of this._selectedNodes) {
407
+ n._state.selected = true;
408
+ n._state.greyout = false;
409
+ }
410
+ // Highlight connected links and nodes
411
+ if (config.nodeSelectionHighlightMode === GraphNodeSelectionHighlightMode.GreyoutNonConnected) {
412
+ const connectedLinks = datamodel.links.filter(l => this._selectedNodes.includes(l.source) || this._selectedNodes.includes(l.target));
372
413
  connectedLinks.forEach(l => {
373
- const source = l.source;
374
- const target = l.target;
375
- source._state.greyout = false;
376
- target._state.greyout = false;
414
+ l.source._state.greyout = false;
415
+ l.target._state.greyout = false;
377
416
  l._state.greyout = false;
378
417
  });
379
418
  }
380
- this._updateSelectedElements();
381
419
  }
382
- _selectLink(link) {
420
+ _setLinkSelectionState(link) {
383
421
  const { datamodel: { nodes, links } } = this;
384
422
  if (!link)
385
423
  console.warn('Unovis: Graph: Select Link: Not found');
@@ -409,13 +447,12 @@ class Graph extends ComponentCore {
409
447
  });
410
448
  if (link)
411
449
  link._state.selected = true;
412
- this._updateSelectedElements();
413
450
  }
414
- _resetSelection() {
451
+ _resetSelectionGreyoutState() {
415
452
  const { datamodel: { nodes, links } } = this;
416
- this._selectedNode = undefined;
453
+ this._selectedNodes = [];
417
454
  this._selectedLink = undefined;
418
- // Disable Grayout
455
+ // Disable Greyout
419
456
  nodes.forEach(n => {
420
457
  delete n._state.selected;
421
458
  delete n._state.greyout;
@@ -424,18 +461,17 @@ class Graph extends ComponentCore {
424
461
  delete l._state.greyout;
425
462
  delete l._state.selected;
426
463
  });
427
- this._updateSelectedElements();
428
464
  }
429
- _updateSelectedElements() {
465
+ _updateNodesLinksPartial() {
430
466
  const { config } = this;
431
467
  const linkElements = this._linksGroup.selectAll(`.${gLink}`);
432
- linkElements.call(updateSelectedLinks, config, this._scale);
468
+ linkElements.call(updateLinksPartial, config, this._scale);
433
469
  const nodeElements = this._nodesGroup.selectAll(`.${gNode}`);
434
- nodeElements.call(updateNodeSelectedGreyout, config);
435
- // this._drawPanels(nodeElements, 0)
470
+ nodeElements.call(updateNodesPartial, config);
436
471
  }
437
472
  _onBackgroundClick() {
438
- this._resetSelection();
473
+ this._resetSelectionGreyoutState();
474
+ this._updateNodesLinksPartial();
439
475
  }
440
476
  // eslint-disable-next-line @typescript-eslint/no-empty-function
441
477
  _onNodeClick(d) {
@@ -453,13 +489,13 @@ class Graph extends ComponentCore {
453
489
  if (this._isDragging)
454
490
  return;
455
491
  d._state.hovered = true;
456
- this._updateSelectedElements();
492
+ this._updateNodesLinksPartial();
457
493
  }
458
494
  _onLinkMouseOut(d) {
459
495
  if (this._isDragging)
460
496
  return;
461
497
  delete d._state.hovered;
462
- this._updateSelectedElements();
498
+ this._updateNodesLinksPartial();
463
499
  }
464
500
  _onLinkFlowTimerFrame(elapsed = 0) {
465
501
  const { config: { linkFlow, linkFlowAnimDuration }, datamodel: { links } } = this;
@@ -503,27 +539,17 @@ class Graph extends ComponentCore {
503
539
  this._linksGroup.selectAll(`.${gLink}`)
504
540
  .call((nodes.length > config.zoomThrottledUpdateNodeThreshold ? zoomLinksThrottled : zoomLinks), config, this._scale, this._getLinkArrowDefId);
505
541
  }
506
- _onDragStarted(d, event, nodeSelection) {
507
- var _a;
508
- const { config } = this;
509
- this._isDragging = true;
510
- d._state.isDragged = true;
511
- nodeSelection.call(updateNodes, config, 0, this._scale);
512
- (_a = config.onNodeDragStart) === null || _a === void 0 ? void 0 : _a.call(config, d, event);
513
- }
514
- _onDragged(d, event, allNodesSelection) {
515
- var _a, _b, _c;
516
- const { config } = this;
542
+ _updateNodePosition(d, x, y) {
543
+ var _a, _b;
517
544
  const transform = zoomTransform(this.g.node());
518
545
  const scale = transform.k;
519
546
  // Prevent the node from being dragged offscreen or outside its panel
520
547
  const panels = (_b = (_a = this._panels) === null || _a === void 0 ? void 0 : _a.filter(p => p.nodes.includes(d._id))) !== null && _b !== void 0 ? _b : [];
521
- const nodeSizeValue = getNodeSize(d, config.nodeSize, d._index);
548
+ const nodeSizeValue = getNodeSize(d, this.config.nodeSize, d._index);
522
549
  const maxY = min([(this._height - transform.y) / scale, ...panels.map(p => p._y + p._height)]) - nodeSizeValue / 2;
523
550
  const maxX = min([(this._width - transform.x) / scale, ...panels.map(p => p._x + p._width)]) - nodeSizeValue / 2;
524
551
  const minY = max([-transform.y / scale, ...panels.map(p => p._y)]) + nodeSizeValue / 2;
525
552
  const minX = max([-transform.x / scale, ...panels.map(p => p._x)]) + nodeSizeValue / 2;
526
- let [x, y] = pointer(event, this._graphGroup.node());
527
553
  if (y < minY)
528
554
  y = minY;
529
555
  else if (y > maxY)
@@ -544,6 +570,62 @@ class Graph extends ComponentCore {
544
570
  delete d._state.fx;
545
571
  if (d._state.fy === d.y)
546
572
  delete d._state.fy;
573
+ }
574
+ _onBrush(event) {
575
+ var _a;
576
+ if (!event.selection || !event.sourceEvent)
577
+ return;
578
+ const { config } = this;
579
+ const transform = zoomTransform(this._graphGroup.node());
580
+ const [xMin, yMin] = transform.invert(event.selection[0]);
581
+ const [xMax, yMax] = transform.invert(event.selection[1]);
582
+ // Update brushed nodes
583
+ this._nodesGroup.selectAll(`.${gNode}`)
584
+ .each(n => {
585
+ const x = getX(n);
586
+ const y = getY(n);
587
+ n._state.brushed = x >= xMin && x <= xMax && y >= yMin && y <= yMax;
588
+ })
589
+ .classed(brushed, n => n._state.brushed);
590
+ const brushedNodes = this._nodesGroup.selectAll(`.${brushed}`)
591
+ .call(updateNodesPartial, config, 0, this._scale);
592
+ this._brush.classed('active', event.type !== 'end');
593
+ (_a = config.onNodeSelectionBrush) === null || _a === void 0 ? void 0 : _a.call(config, brushedNodes.data(), event);
594
+ }
595
+ _handleDrag(d, event, nodeSelection) {
596
+ if (event.sourceEvent.shiftKey && d._state.brushed) {
597
+ this._dragSelectedNodes(event);
598
+ }
599
+ else if (!event.sourceEvent.shiftKey) {
600
+ switch (event.type) {
601
+ case 'start':
602
+ this._onDragStarted(d, event, nodeSelection);
603
+ break;
604
+ case 'drag':
605
+ this._onDragged(d, event);
606
+ break;
607
+ case 'end':
608
+ this._onDragEnded(d, event, nodeSelection);
609
+ break;
610
+ }
611
+ }
612
+ }
613
+ _onDragStarted(d, event, nodeSelection) {
614
+ var _a;
615
+ const { config } = this;
616
+ this._isDragging = true;
617
+ d._state.isDragged = true;
618
+ nodeSelection.call(updateNodes, config, 0, this._scale);
619
+ (_a = config.onNodeDragStart) === null || _a === void 0 ? void 0 : _a.call(config, d, event);
620
+ }
621
+ _onDragged(d, event) {
622
+ var _a;
623
+ const { config } = this;
624
+ const transform = zoomTransform(this.g.node());
625
+ const scale = transform.k;
626
+ // Update node position
627
+ const [x, y] = pointer(event, this._graphGroup.node());
628
+ this._updateNodePosition(d, x, y);
547
629
  // Update affected DOM elements
548
630
  const nodeSelection = this._nodesGroup.selectAll(`.${gNode}`);
549
631
  const nodeToUpdate = nodeSelection.filter((n) => n._id === d._id);
@@ -558,7 +640,7 @@ class Graph extends ComponentCore {
558
640
  const linksToAnimate = linksToUpdate.filter(d => d._state.greyout);
559
641
  if (linksToAnimate.size())
560
642
  animateLinkFlow(linksToAnimate, config, this._scale);
561
- (_c = config.onNodeDrag) === null || _c === void 0 ? void 0 : _c.call(config, d, event);
643
+ (_a = config.onNodeDrag) === null || _a === void 0 ? void 0 : _a.call(config, d, event);
562
644
  }
563
645
  _onDragEnded(d, event, nodeSelection) {
564
646
  var _a;
@@ -568,6 +650,49 @@ class Graph extends ComponentCore {
568
650
  nodeSelection.call(updateNodes, config, 0, this._scale);
569
651
  (_a = config.onNodeDragEnd) === null || _a === void 0 ? void 0 : _a.call(config, d, event);
570
652
  }
653
+ _dragSelectedNodes(event) {
654
+ var _a, _b;
655
+ const { config } = this;
656
+ const curr = pointer(event, this._graphGroup.node());
657
+ const selectedNodes = smartTransition(this._nodesGroup.selectAll(`.${brushed}`));
658
+ if (event.type === 'start') {
659
+ this._groupDragInit = curr;
660
+ this._isDragging = true;
661
+ selectedNodes.each(n => {
662
+ n.x = getX(n);
663
+ n.y = getY(n);
664
+ n._state.isDragged = true;
665
+ });
666
+ }
667
+ else if (event.type === 'drag') {
668
+ const dx = curr[0] - this._groupDragInit[0];
669
+ const dy = curr[1] - this._groupDragInit[1];
670
+ selectedNodes.each(n => this._updateNodePosition(n, n.x + dx, n.y + dy));
671
+ const connectedLinks = smartTransition(this._linksGroup.selectAll(`.${gLink}`)
672
+ .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); }));
673
+ connectedLinks.call(updateLinks, this.config, 0, this._scale, this._getLinkArrowDefId);
674
+ }
675
+ else {
676
+ this._isDragging = false;
677
+ selectedNodes.each(n => { n._state.isDragged = false; });
678
+ }
679
+ selectedNodes.call(updateNodes, config, 0, this._scale);
680
+ (_b = (_a = this.config).onNodeSelectionDrag) === null || _b === void 0 ? void 0 : _b.call(_a, selectedNodes.data(), event);
681
+ }
682
+ _activateBrush() {
683
+ this._brush.classed('active', true);
684
+ this._nodesGroup.selectAll(`.${gNode}`)
685
+ .classed(brushable, true);
686
+ }
687
+ _clearBrush() {
688
+ var _a;
689
+ this._brush.classed('active', false).call((_a = this._brushBehavior) === null || _a === void 0 ? void 0 : _a.clear);
690
+ this._nodesGroup.selectAll(`.${gNode}`)
691
+ .classed(brushable, false)
692
+ .classed(brushed, false)
693
+ .each(n => { n._state.brushed = false; })
694
+ .call(updateNodesPartial, this.config, 0, this._scale);
695
+ }
571
696
  _shouldLayoutRecalculate() {
572
697
  const { prevConfig, config } = this;
573
698
  if (prevConfig.layoutType !== config.layoutType)