@progress/kendo-charts 2.3.0-dev.202404081747 → 2.3.0-dev.202404121620

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.
@@ -58,9 +58,14 @@ Sankey.prototype.calculate = function calculate () {
58
58
  var links = ref.links;
59
59
  this.connectLinksToNodes(nodes, links);
60
60
  this.calculateNodeValues(nodes);
61
- this.calculateNodeDepths(nodes);
62
- this.calculateNodeHeights(nodes);
63
61
 
62
+ var circularLinks = this.calculateNodeHeights(nodes);
63
+
64
+ if (circularLinks) {
65
+ return { nodes: [], links: [], columns: [], circularLinks: circularLinks };
66
+ }
67
+
68
+ this.calculateNodeDepths(nodes);
64
69
  var columns = this.calculateNodeColumns(nodes);
65
70
  this.calculateNodeBreadths(columns);
66
71
  this.applyNodesOffset(nodes);
@@ -118,21 +123,26 @@ Sankey.prototype.calculateNodeDepths = function calculateNodeDepths (nodes) {
118
123
  };
119
124
 
120
125
  Sankey.prototype.calculateNodeHeights = function calculateNodeHeights (nodes) {
126
+ var nodesLength = nodes.length;
121
127
  var current = new Set(nodes);
122
128
  var next = new Set;
123
- var x = 0;
129
+ var currentHeight = 0;
124
130
  var eachNode = function (node) {
125
- node.height = x;
131
+ node.height = currentHeight;
126
132
  node.targetLinks.forEach(function (link) {
127
133
  next.add(link.source);
128
134
  });
129
135
  };
130
136
  while (current.size) {
131
137
  current.forEach(eachNode);
132
- x++;
138
+ currentHeight++;
139
+ if (currentHeight > nodesLength) {
140
+ return true;
141
+ }
133
142
  current = next;
134
143
  next = new Set;
135
144
  }
145
+ return false;
136
146
  };
137
147
 
138
148
  Sankey.prototype.calculateNodeColumns = function calculateNodeColumns (nodes) {
@@ -1,7 +1,6 @@
1
1
  import { default as ChartLegend } from "../chart/legend/legend";
2
2
  import { SankeyElement } from "./element";
3
3
  import { setDefaultOptions } from '../common';
4
- import { nodeColor } from "./node";
5
4
  import { BOTTOM, CENTER, POINTER } from "../common/constants";
6
5
  import { AREA } from "../chart/constants";
7
6
 
@@ -25,17 +24,16 @@ export var Legend = (function (SankeyElement) {
25
24
  var options = this.options;
26
25
  var drawingRect = options.drawingRect;
27
26
  var nodes = options.nodes; if ( nodes === void 0 ) nodes = [];
28
- var colors = options.colors; if ( colors === void 0 ) colors = [];
29
27
  var item = options.item;
30
28
 
31
29
  if (options.visible === false || !nodes.length) {
32
30
  return null;
33
31
  }
34
32
 
35
- var data = nodes.map(function (node, index) { return ({
33
+ var data = nodes.map(function (node) { return ({
36
34
  text: (node.label && node.label.text) || '',
37
35
  area: {
38
- background: item.areaBackground !== undefined ? item.areaBackground : nodeColor(node, colors, index),
36
+ background: item.areaBackground !== undefined ? item.areaBackground : node.color,
39
37
  opacity: item.areaOpacity !== undefined ? item.areaOpacity : node.opacity
40
38
  },
41
39
  node: node,
@@ -38,7 +38,7 @@ export var Node = (function (SankeyElement) {
38
38
  return Node;
39
39
  }(SankeyElement));
40
40
 
41
- export var nodeColor = function (node, nodeColors, index) { return node.color || nodeColors[index % nodeColors.length]; };
41
+ var nodeColor = function (node, nodeColors, index) { return node.color || nodeColors[index % nodeColors.length]; };
42
42
 
43
43
  export var resolveNodeOptions = function (node, options, nodeColors, index) {
44
44
  var nodeOptions = deepExtend({}, options, options.node);
@@ -105,12 +105,21 @@ export var Sankey = (function (Observable) {
105
105
  var this$1 = this;
106
106
 
107
107
  this.linksVisuals.forEach(function (link) {
108
- this$1.setOpacity(link, opacity);
108
+ this$1.setOpacity(link, opacity, link.linkOptions.opacity);
109
109
  });
110
110
  };
111
111
 
112
- Sankey.prototype.setOpacity = function setOpacity (link, opacity) {
113
- link.options.set('stroke', Object.assign({}, link.options.stroke, {opacity: opacity}));
112
+ Sankey.prototype.setLinksInactivityOpacity = function setLinksInactivityOpacity (inactiveOpacity) {
113
+ var this$1 = this;
114
+
115
+ this.linksVisuals.forEach(function (link) {
116
+ this$1.setOpacity(link, inactiveOpacity, link.linkOptions.highlight.inactiveOpacity);
117
+ });
118
+ };
119
+
120
+ Sankey.prototype.setOpacity = function setOpacity (link, opacity, linkValue) {
121
+ link.options.set('stroke', Object.assign({}, link.options.stroke,
122
+ {opacity: defined(linkValue) ? linkValue : opacity}));
114
123
  };
115
124
 
116
125
  Sankey.prototype.trigger = function trigger (name, ev) {
@@ -136,8 +145,8 @@ export var Sankey = (function (Observable) {
136
145
  var ref = this.options.links;
137
146
  var highlight = ref.highlight;
138
147
  if (isLink) {
139
- this.setLinksOpacity(highlight.inactiveOpacity);
140
- this.setOpacity(element, highlight.opacity);
148
+ this.setLinksInactivityOpacity(highlight.inactiveOpacity);
149
+ this.setOpacity(element, highlight.opacity, element.linkOptions.highlight.opacity);
141
150
  } else if (isNode) {
142
151
  this.highlightLinks(element, highlight);
143
152
  } else if (isLegendItem) {
@@ -147,6 +156,8 @@ export var Sankey = (function (Observable) {
147
156
  };
148
157
 
149
158
  Sankey.prototype._mouseleave = function _mouseleave (ev) {
159
+ var this$1 = this;
160
+
150
161
  var element = ev.element;
151
162
  var isLink = element.type === LINK;
152
163
  var isNode = element.type === NODE;
@@ -172,7 +183,9 @@ export var Sankey = (function (Observable) {
172
183
  }
173
184
 
174
185
  if (isLink || isNode || isLegendItem) {
175
- this.setLinksOpacity(this.options.links.opacity);
186
+ this.linksVisuals.forEach(function (link) {
187
+ this$1.setOpacity(link, this$1.options.links.opacity, link.linkOptions.opacity);
188
+ });
176
189
  }
177
190
  };
178
191
 
@@ -241,9 +254,9 @@ export var Sankey = (function (Observable) {
241
254
  var this$1 = this;
242
255
 
243
256
  if (node) {
244
- this.setLinksOpacity(highlight.inactiveOpacity);
257
+ this.setLinksInactivityOpacity(highlight.inactiveOpacity);
245
258
  node.links.forEach(function (link) {
246
- this$1.setOpacity(link, highlight.opacity);
259
+ this$1.setOpacity(link, highlight.opacity, link.linkOptions.highlight.opacity);
247
260
  });
248
261
  }
249
262
  };
@@ -374,7 +387,14 @@ export var Sankey = (function (Observable) {
374
387
  }
375
388
  }
376
389
 
377
- var calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: 0, offsetY: 0, width: sankeyBox.width(), height: sankeyBox.height()})).nodes;
390
+ var ref = calculateSankey(Object.assign({}, calcOptions, {offsetX: 0, offsetY: 0, width: sankeyBox.width(), height: sankeyBox.height()}));
391
+ var calculatedNodes = ref.nodes;
392
+ var circularLinks = ref.circularLinks;
393
+ if (circularLinks) {
394
+ console.warn('Circular links detected. Kendo Sankey diagram does not support circular links.');
395
+ return { sankey: { nodes: [], links: [], circularLinks: circularLinks }, legendBox: legendBox, titleBox: titleBox };
396
+ }
397
+
378
398
  var box = new Box();
379
399
 
380
400
  calculatedNodes.forEach(function (nodeEl, i) {
@@ -485,6 +505,10 @@ export var Sankey = (function (Observable) {
485
505
  visual.append(titleVisual);
486
506
  }
487
507
 
508
+ if (sankey.circularLinks) {
509
+ return visual;
510
+ }
511
+
488
512
  var visualNodes = new Map();
489
513
  sankeyContext.nodesVisuals = visualNodes;
490
514
 
@@ -496,6 +520,9 @@ export var Sankey = (function (Observable) {
496
520
  nodeVisual.links = [];
497
521
  nodeVisual.type = NODE;
498
522
 
523
+ node.color = nodeOps.color;
524
+ node.opacity = nodeOps.opacity;
525
+
499
526
  nodeVisual.dataItem = Object.assign({}, data.nodes[i],
500
527
  {color: nodeOps.color,
501
528
  opacity: nodeOps.opacity,
@@ -526,6 +553,7 @@ export var Sankey = (function (Observable) {
526
553
  target: Object.assign({}, targetNode.dataItem),
527
554
  value: link.value
528
555
  };
556
+ linkVisual.linkOptions = linkOps;
529
557
  linksVisuals.push(linkVisual);
530
558
 
531
559
  sourceNode.links.push(linkVisual);
@@ -546,7 +574,7 @@ export var Sankey = (function (Observable) {
546
574
  });
547
575
 
548
576
  if (legendBox) {
549
- var legendElement = new Legend(Object.assign({}, legend, {drawingRect: legendBox, nodes: nodes, colors: nodeColors}));
577
+ var legendElement = new Legend(Object.assign({}, legend, {drawingRect: legendBox, nodes: nodes}));
550
578
  var legendVisual = legendElement.exportVisual();
551
579
  visual.append(legendVisual);
552
580
  }
@@ -55,9 +55,14 @@ class Sankey {
55
55
  const { nodes, links } = this.data;
56
56
  this.connectLinksToNodes(nodes, links);
57
57
  this.calculateNodeValues(nodes);
58
- this.calculateNodeDepths(nodes);
59
- this.calculateNodeHeights(nodes);
60
58
 
59
+ const circularLinks = this.calculateNodeHeights(nodes);
60
+
61
+ if (circularLinks) {
62
+ return { nodes: [], links: [], columns: [], circularLinks };
63
+ }
64
+
65
+ this.calculateNodeDepths(nodes);
61
66
  const columns = this.calculateNodeColumns(nodes);
62
67
  this.calculateNodeBreadths(columns);
63
68
  this.applyNodesOffset(nodes);
@@ -115,21 +120,26 @@ class Sankey {
115
120
  }
116
121
 
117
122
  calculateNodeHeights(nodes) {
123
+ const nodesLength = nodes.length;
118
124
  let current = new Set(nodes);
119
125
  let next = new Set;
120
- let x = 0;
126
+ let currentHeight = 0;
121
127
  const eachNode = (node) => {
122
- node.height = x;
128
+ node.height = currentHeight;
123
129
  node.targetLinks.forEach((link) => {
124
130
  next.add(link.source);
125
131
  });
126
132
  };
127
133
  while (current.size) {
128
134
  current.forEach(eachNode);
129
- x++;
135
+ currentHeight++;
136
+ if (currentHeight > nodesLength) {
137
+ return true;
138
+ }
130
139
  current = next;
131
140
  next = new Set;
132
141
  }
142
+ return false;
133
143
  }
134
144
 
135
145
  calculateNodeColumns(nodes) {
@@ -1,7 +1,6 @@
1
1
  import { default as ChartLegend } from "../chart/legend/legend";
2
2
  import { SankeyElement } from "./element";
3
3
  import { setDefaultOptions } from '../common';
4
- import { nodeColor } from "./node";
5
4
  import { BOTTOM, CENTER, POINTER } from "../common/constants";
6
5
  import { AREA } from "../chart/constants";
7
6
 
@@ -15,16 +14,16 @@ const sortData = (a, b) => {
15
14
  export class Legend extends SankeyElement {
16
15
  getElement() {
17
16
  const options = this.options;
18
- const { drawingRect, nodes = [], colors = [], item } = options;
17
+ const { drawingRect, nodes = [], item } = options;
19
18
 
20
19
  if (options.visible === false || !nodes.length) {
21
20
  return null;
22
21
  }
23
22
 
24
- const data = nodes.map((node, index) => ({
23
+ const data = nodes.map((node) => ({
25
24
  text: (node.label && node.label.text) || '',
26
25
  area: {
27
- background: item.areaBackground !== undefined ? item.areaBackground : nodeColor(node, colors, index),
26
+ background: item.areaBackground !== undefined ? item.areaBackground : node.color,
28
27
  opacity: item.areaOpacity !== undefined ? item.areaOpacity : node.opacity
29
28
  },
30
29
  node: node,
@@ -28,7 +28,7 @@ export class Node extends SankeyElement {
28
28
  }
29
29
  }
30
30
 
31
- export const nodeColor = (node, nodeColors, index) => node.color || nodeColors[index % nodeColors.length];
31
+ const nodeColor = (node, nodeColors, index) => node.color || nodeColors[index % nodeColors.length];
32
32
 
33
33
  export const resolveNodeOptions = (node, options, nodeColors, index) => {
34
34
  const nodeOptions = deepExtend({}, options, options.node);
@@ -94,12 +94,19 @@ export class Sankey extends Observable {
94
94
 
95
95
  setLinksOpacity(opacity) {
96
96
  this.linksVisuals.forEach(link => {
97
- this.setOpacity(link, opacity);
97
+ this.setOpacity(link, opacity, link.linkOptions.opacity);
98
98
  });
99
99
  }
100
100
 
101
- setOpacity(link, opacity) {
102
- link.options.set('stroke', Object.assign({}, link.options.stroke, {opacity}));
101
+ setLinksInactivityOpacity(inactiveOpacity) {
102
+ this.linksVisuals.forEach(link => {
103
+ this.setOpacity(link, inactiveOpacity, link.linkOptions.highlight.inactiveOpacity);
104
+ });
105
+ }
106
+
107
+ setOpacity(link, opacity, linkValue) {
108
+ link.options.set('stroke', Object.assign({}, link.options.stroke,
109
+ {opacity: defined(linkValue) ? linkValue : opacity}));
103
110
  }
104
111
 
105
112
  trigger(name, ev) {
@@ -124,8 +131,8 @@ export class Sankey extends Observable {
124
131
 
125
132
  const { highlight } = this.options.links;
126
133
  if (isLink) {
127
- this.setLinksOpacity(highlight.inactiveOpacity);
128
- this.setOpacity(element, highlight.opacity);
134
+ this.setLinksInactivityOpacity(highlight.inactiveOpacity);
135
+ this.setOpacity(element, highlight.opacity, element.linkOptions.highlight.opacity);
129
136
  } else if (isNode) {
130
137
  this.highlightLinks(element, highlight);
131
138
  } else if (isLegendItem) {
@@ -160,7 +167,9 @@ export class Sankey extends Observable {
160
167
  }
161
168
 
162
169
  if (isLink || isNode || isLegendItem) {
163
- this.setLinksOpacity(this.options.links.opacity);
170
+ this.linksVisuals.forEach(link => {
171
+ this.setOpacity(link, this.options.links.opacity, link.linkOptions.opacity);
172
+ });
164
173
  }
165
174
  }
166
175
 
@@ -221,9 +230,9 @@ export class Sankey extends Observable {
221
230
 
222
231
  highlightLinks(node, highlight) {
223
232
  if (node) {
224
- this.setLinksOpacity(highlight.inactiveOpacity);
233
+ this.setLinksInactivityOpacity(highlight.inactiveOpacity);
225
234
  node.links.forEach(link => {
226
- this.setOpacity(link, highlight.opacity);
235
+ this.setOpacity(link, highlight.opacity, link.linkOptions.highlight.opacity);
227
236
  });
228
237
  }
229
238
  }
@@ -346,7 +355,12 @@ export class Sankey extends Observable {
346
355
  }
347
356
  }
348
357
 
349
- const calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: 0, offsetY: 0, width: sankeyBox.width(), height: sankeyBox.height()})).nodes;
358
+ const { nodes: calculatedNodes, circularLinks } = calculateSankey(Object.assign({}, calcOptions, {offsetX: 0, offsetY: 0, width: sankeyBox.width(), height: sankeyBox.height()}));
359
+ if (circularLinks) {
360
+ console.warn('Circular links detected. Kendo Sankey diagram does not support circular links.');
361
+ return { sankey: { nodes: [], links: [], circularLinks }, legendBox, titleBox };
362
+ }
363
+
350
364
  const box = new Box();
351
365
 
352
366
  calculatedNodes.forEach((nodeEl, i) => {
@@ -445,6 +459,10 @@ export class Sankey extends Observable {
445
459
  visual.append(titleVisual);
446
460
  }
447
461
 
462
+ if (sankey.circularLinks) {
463
+ return visual;
464
+ }
465
+
448
466
  const visualNodes = new Map();
449
467
  sankeyContext.nodesVisuals = visualNodes;
450
468
 
@@ -456,6 +474,9 @@ export class Sankey extends Observable {
456
474
  nodeVisual.links = [];
457
475
  nodeVisual.type = NODE;
458
476
 
477
+ node.color = nodeOps.color;
478
+ node.opacity = nodeOps.opacity;
479
+
459
480
  nodeVisual.dataItem = Object.assign({}, data.nodes[i],
460
481
  {color: nodeOps.color,
461
482
  opacity: nodeOps.opacity,
@@ -485,6 +506,7 @@ export class Sankey extends Observable {
485
506
  target: Object.assign({}, targetNode.dataItem),
486
507
  value: link.value
487
508
  };
509
+ linkVisual.linkOptions = linkOps;
488
510
  linksVisuals.push(linkVisual);
489
511
 
490
512
  sourceNode.links.push(linkVisual);
@@ -505,7 +527,7 @@ export class Sankey extends Observable {
505
527
  });
506
528
 
507
529
  if (legendBox) {
508
- const legendElement = new Legend(Object.assign({}, legend, {drawingRect: legendBox, nodes, colors: nodeColors}));
530
+ const legendElement = new Legend(Object.assign({}, legend, {drawingRect: legendBox, nodes}));
509
531
  const legendVisual = legendElement.exportVisual();
510
532
  visual.append(legendVisual);
511
533
  }