@progress/kendo-charts 2.2.0 → 2.3.0-dev.202402161315

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.
@@ -1,4 +1,4 @@
1
- import { drawing } from '@progress/kendo-drawing';
1
+ import { geometry, drawing } from '@progress/kendo-drawing';
2
2
  import { deepExtend, addClass, setDefaultOptions } from '../common';
3
3
  import { calculateSankey } from './calculation';
4
4
  import { Node, resolveNodeOptions } from './node';
@@ -10,6 +10,7 @@ import Box from '../core/box';
10
10
  import rectToBox from '../core/utils/rect-to-box';
11
11
  import { Observable } from '../common/observable';
12
12
  import { Legend } from './legend';
13
+ import { defined } from '../drawing-utils';
13
14
 
14
15
  var LINK = 'link';
15
16
  var NODE = 'node';
@@ -77,7 +78,8 @@ export var Sankey = (function (Observable) {
77
78
  Sankey.prototype._createSurface = function _createSurface () {
78
79
  return drawing.Surface.create(this.surfaceElement, {
79
80
  mouseenter: this._mouseenter.bind(this),
80
- mouseleave: this._mouseleave.bind(this)
81
+ mouseleave: this._mouseleave.bind(this),
82
+ mousemove: this._mousemove.bind(this),
81
83
  });
82
84
  };
83
85
 
@@ -100,8 +102,11 @@ export var Sankey = (function (Observable) {
100
102
  };
101
103
 
102
104
  Sankey.prototype.trigger = function trigger (name, ev) {
103
- ev.type = name;
104
- return Observable.prototype.trigger.call(this, name, ev);
105
+ var event = Object.assign({}, ev,
106
+ {type: name,
107
+ dataItem: ev.element.dataItem});
108
+
109
+ return Observable.prototype.trigger.call(this, name, event);
105
110
  };
106
111
 
107
112
  Sankey.prototype._mouseenter = function _mouseenter (ev) {
@@ -139,6 +144,10 @@ export var Sankey = (function (Observable) {
139
144
  return;
140
145
  }
141
146
 
147
+ if (isLink || isNode) {
148
+ this.trigger('hideTooltip', ev);
149
+ }
150
+
142
151
  if ((isLink && this.trigger('linkLeave', ev)) ||
143
152
  (isNode && this.trigger('nodeLeave', ev))) {
144
153
  return;
@@ -149,6 +158,16 @@ export var Sankey = (function (Observable) {
149
158
  }
150
159
  };
151
160
 
161
+ Sankey.prototype._mousemove = function _mousemove (ev) {
162
+ var element = ev.element;
163
+
164
+ if (element.type === NODE) {
165
+ this.trigger('nodeTooltip', ev);
166
+ } else if (element.type === LINK) {
167
+ this.trigger('linkTooltip', ev);
168
+ }
169
+ };
170
+
152
171
  Sankey.prototype.highlightLinks = function highlightLinks (node, highlight) {
153
172
  var this$1 = this;
154
173
 
@@ -239,17 +258,15 @@ export var Sankey = (function (Observable) {
239
258
  return legendVisual.chartElement.box;
240
259
  };
241
260
 
242
- Sankey.prototype.calculateSankey = function calculateSankey$1 (options) {
243
- var ref = this.options;
244
- var title = ref.title;
245
- var legend = ref.legend;
246
- var data = ref.data;
247
- var ref$1 = this.options;
248
- var nodes = ref$1.nodes;
249
- var labels = ref$1.labels;
250
- var nodesColors = ref$1.nodesColors;
251
-
252
- var sankeyBox = new Box(0, 0, options.width, options.height);
261
+ Sankey.prototype.calculateSankey = function calculateSankey$1 (calcOptions, sankeyOptions) {
262
+ var title = sankeyOptions.title;
263
+ var legend = sankeyOptions.legend;
264
+ var data = sankeyOptions.data;
265
+ var nodes = sankeyOptions.nodes;
266
+ var labels = sankeyOptions.labels;
267
+ var nodesColors = sankeyOptions.nodesColors;
268
+
269
+ var sankeyBox = new Box(0, 0, calcOptions.width, calcOptions.height);
253
270
  var titleBox = this.titleBox(title, sankeyBox);
254
271
 
255
272
  var legendArea = sankeyBox.clone();
@@ -258,10 +275,10 @@ export var Sankey = (function (Observable) {
258
275
  var titleHeight = titleBox.height();
259
276
  if (title.position === TOP) {
260
277
  sankeyBox.unpad({ top: titleHeight });
261
- legendArea = new Box(0, titleHeight, options.width, options.height);
278
+ legendArea = new Box(0, titleHeight, calcOptions.width, calcOptions.height);
262
279
  } else {
263
280
  sankeyBox.shrink(0, titleHeight);
264
- legendArea = new Box(0, 0, options.width, options.height - titleHeight);
281
+ legendArea = new Box(0, 0, calcOptions.width, calcOptions.height - titleHeight);
265
282
  }
266
283
  }
267
284
 
@@ -285,7 +302,7 @@ export var Sankey = (function (Observable) {
285
302
  }
286
303
  }
287
304
 
288
- var calculatedNodes = calculateSankey(Object.assign({}, options, {offsetX: sankeyBox.x1, offsetY: sankeyBox.y1, width: sankeyBox.x2, height: sankeyBox.y2})).nodes;
305
+ var calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: sankeyBox.x1, offsetY: sankeyBox.y1, width: sankeyBox.x2, height: sankeyBox.y2})).nodes;
289
306
  var box = new Box();
290
307
 
291
308
  calculatedNodes.forEach(function (nodeEl, i) {
@@ -293,7 +310,7 @@ export var Sankey = (function (Observable) {
293
310
  var nodeInstance = new Node(nodeOps);
294
311
  box.wrap(rectToBox(nodeInstance.exportVisual().rawBBox()));
295
312
 
296
- var labelInstance = new Label(deepExtend({ node: nodeEl, totalWidth: options.width }, labels));
313
+ var labelInstance = new Label(deepExtend({ node: nodeEl, totalWidth: calcOptions.width }, labels));
297
314
  var labelVisual = labelInstance.exportVisual();
298
315
  if (labelVisual) {
299
316
  box.wrap(rectToBox(labelVisual.rawBBox()));
@@ -307,33 +324,38 @@ export var Sankey = (function (Observable) {
307
324
  var height = box.height() > sankeyBox.y2 ? offsetY + sankeyBox.y2 - (box.height() - sankeyBox.y2) : sankeyBox.y2;
308
325
 
309
326
  return {
310
- sankey: calculateSankey(Object.assign({}, options, {offsetX: offsetX, offsetY: offsetY, width: width, height: height})),
327
+ sankey: calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height})),
311
328
  legendBox: legendBox,
312
329
  titleBox: titleBox
313
330
  };
314
331
  };
315
332
 
316
- Sankey.prototype._render = function _render () {
317
- var ref = this.options;
318
- var data = ref.data;
319
- var labelOptions = ref.labels;
320
- var nodesOptions = ref.nodes;
321
- var linkOptions = ref.links;
322
- var nodesColors = ref.nodesColors;
323
- var title = ref.title;
324
- var legend = ref.legend;
325
- var ref$1 = this.size;
326
- var width = ref$1.width;
327
- var height = ref$1.height;
333
+ Sankey.prototype._render = function _render (options, context) {
334
+ var sankeyOptions = options || this.options;
335
+ var sankeyContext = context || this;
336
+
337
+ var data = sankeyOptions.data;
338
+ var labelOptions = sankeyOptions.labels;
339
+ var nodesOptions = sankeyOptions.nodes;
340
+ var linkOptions = sankeyOptions.links;
341
+ var nodesColors = sankeyOptions.nodesColors;
342
+ var title = sankeyOptions.title;
343
+ var legend = sankeyOptions.legend;
344
+ var ref = sankeyContext.size;
345
+ var width = ref.width;
346
+ var height = ref.height;
347
+
328
348
  var calcOptions = Object.assign({}, data, {width: width, height: height, nodesOptions: nodesOptions, title: title, legend: legend});
329
- var ref$2 = this.calculateSankey(calcOptions);
330
- var sankey = ref$2.sankey;
331
- var titleBox = ref$2.titleBox;
332
- var legendBox = ref$2.legendBox;
349
+ var ref$1 = this.calculateSankey(calcOptions, sankeyOptions);
350
+ var sankey = ref$1.sankey;
351
+ var titleBox = ref$1.titleBox;
352
+ var legendBox = ref$1.legendBox;
333
353
  var nodes = sankey.nodes;
334
354
  var links = sankey.links;
335
355
 
336
- var visual = new drawing.Group();
356
+ var visual = new drawing.Group({
357
+ clip: drawing.Path.fromRect(new geometry.Rect([0, 0], [width, height]))
358
+ });
337
359
 
338
360
  if (titleBox) {
339
361
  var titleElement = new Title(Object.assign({}, title, {drawingRect: titleBox}));
@@ -348,6 +370,7 @@ export var Sankey = (function (Observable) {
348
370
  }
349
371
 
350
372
  var visualNodes = new Map();
373
+ sankeyContext.nodesVisuals = visualNodes;
351
374
 
352
375
  nodes.forEach(function (node, i) {
353
376
  var nodeOps = resolveNodeOptions(node, nodesOptions, nodesColors, i);
@@ -356,6 +379,12 @@ export var Sankey = (function (Observable) {
356
379
  var nodeVisual = nodeInstance.exportVisual();
357
380
  nodeVisual.links = [];
358
381
  nodeVisual.type = NODE;
382
+
383
+ nodeVisual.dataItem = Object.assign({}, data.nodes[i],
384
+ {color: nodeOps.color,
385
+ opacity: nodeOps.opacity,
386
+ sourceLinks: node.sourceLinks.map(function (link) { return ({ sourceId: link.sourceId, targetId: link.targetId, value: link.value }); }),
387
+ targetLinks: node.targetLinks.map(function (link) { return ({ sourceId: link.sourceId, targetId: link.targetId, value: link.value }); })});
359
388
  visualNodes.set(node.id, nodeVisual);
360
389
 
361
390
  visual.append(nodeVisual);
@@ -364,6 +393,7 @@ export var Sankey = (function (Observable) {
364
393
  var sortedLinks = links.slice().sort(function (a, b) { return b.value - a.value; });
365
394
 
366
395
  var linksVisuals = [];
396
+ sankeyContext.linksVisuals = linksVisuals;
367
397
 
368
398
  sortedLinks.forEach(function (link) {
369
399
  var source = link.source;
@@ -375,6 +405,11 @@ export var Sankey = (function (Observable) {
375
405
  var linkVisual = linkInstance.exportVisual();
376
406
 
377
407
  linkVisual.type = LINK;
408
+ linkVisual.dataItem = {
409
+ source: Object.assign({}, sourceNode.dataItem),
410
+ target: Object.assign({}, targetNode.dataItem),
411
+ value: link.value
412
+ };
378
413
  linksVisuals.push(linkVisual);
379
414
 
380
415
  sourceNode.links.push(linkVisual);
@@ -383,9 +418,6 @@ export var Sankey = (function (Observable) {
383
418
  visual.append(linkVisual);
384
419
  });
385
420
 
386
- this.linksVisuals = linksVisuals;
387
- this.nodesVisuals = visualNodes;
388
-
389
421
  nodes.forEach(function (node) {
390
422
  var textOps = resolveLabelOptions(node, labelOptions, width);
391
423
  var labelInstance = new Label(textOps);
@@ -399,8 +431,18 @@ export var Sankey = (function (Observable) {
399
431
  return visual;
400
432
  };
401
433
 
402
- Sankey.prototype.exportVisual = function exportVisual () {
403
- return this._render();
434
+ Sankey.prototype.exportVisual = function exportVisual (exportOptions) {
435
+ var options = (exportOptions && exportOptions.options) ?
436
+ deepExtend({}, this.options, exportOptions.options) : this.options;
437
+
438
+ var context = {
439
+ size: {
440
+ width: defined(exportOptions && exportOptions.width) ? exportOptions.width : this.size.width,
441
+ height: defined(exportOptions && exportOptions.height) ? exportOptions.height : this.size.height
442
+ }
443
+ };
444
+
445
+ return this._render(options, context);
404
446
  };
405
447
 
406
448
  Sankey.prototype._setOptions = function _setOptions (options) {
@@ -1,4 +1,4 @@
1
- import { drawing } from '@progress/kendo-drawing';
1
+ import { geometry, drawing } from '@progress/kendo-drawing';
2
2
  import { deepExtend, addClass, setDefaultOptions } from '../common';
3
3
  import { calculateSankey } from './calculation';
4
4
  import { Node, resolveNodeOptions } from './node';
@@ -10,6 +10,7 @@ import Box from '../core/box';
10
10
  import rectToBox from '../core/utils/rect-to-box';
11
11
  import { Observable } from '../common/observable';
12
12
  import { Legend } from './legend';
13
+ import { defined } from '../drawing-utils';
13
14
 
14
15
  const LINK = 'link';
15
16
  const NODE = 'node';
@@ -69,7 +70,8 @@ export class Sankey extends Observable {
69
70
  _createSurface() {
70
71
  return drawing.Surface.create(this.surfaceElement, {
71
72
  mouseenter: this._mouseenter.bind(this),
72
- mouseleave: this._mouseleave.bind(this)
73
+ mouseleave: this._mouseleave.bind(this),
74
+ mousemove: this._mousemove.bind(this),
73
75
  });
74
76
  }
75
77
 
@@ -90,8 +92,11 @@ export class Sankey extends Observable {
90
92
  }
91
93
 
92
94
  trigger(name, ev) {
93
- ev.type = name;
94
- return super.trigger(name, ev);
95
+ const event = Object.assign({}, ev,
96
+ {type: name,
97
+ dataItem: ev.element.dataItem});
98
+
99
+ return super.trigger(name, event);
95
100
  }
96
101
 
97
102
  _mouseenter(ev) {
@@ -128,6 +133,10 @@ export class Sankey extends Observable {
128
133
  return;
129
134
  }
130
135
 
136
+ if (isLink || isNode) {
137
+ this.trigger('hideTooltip', ev);
138
+ }
139
+
131
140
  if ((isLink && this.trigger('linkLeave', ev)) ||
132
141
  (isNode && this.trigger('nodeLeave', ev))) {
133
142
  return;
@@ -138,6 +147,16 @@ export class Sankey extends Observable {
138
147
  }
139
148
  }
140
149
 
150
+ _mousemove(ev) {
151
+ const element = ev.element;
152
+
153
+ if (element.type === NODE) {
154
+ this.trigger('nodeTooltip', ev);
155
+ } else if (element.type === LINK) {
156
+ this.trigger('linkTooltip', ev);
157
+ }
158
+ }
159
+
141
160
  highlightLinks(node, highlight) {
142
161
  if (node) {
143
162
  this.setLinksOpacity(highlight.inactiveOpacity);
@@ -224,11 +243,10 @@ export class Sankey extends Observable {
224
243
  return legendVisual.chartElement.box;
225
244
  }
226
245
 
227
- calculateSankey(options) {
228
- const { title, legend, data } = this.options;
229
- const { nodes, labels, nodesColors } = this.options;
246
+ calculateSankey(calcOptions, sankeyOptions) {
247
+ const { title, legend, data, nodes, labels, nodesColors } = sankeyOptions;
230
248
 
231
- const sankeyBox = new Box(0, 0, options.width, options.height);
249
+ const sankeyBox = new Box(0, 0, calcOptions.width, calcOptions.height);
232
250
  const titleBox = this.titleBox(title, sankeyBox);
233
251
 
234
252
  let legendArea = sankeyBox.clone();
@@ -237,10 +255,10 @@ export class Sankey extends Observable {
237
255
  const titleHeight = titleBox.height();
238
256
  if (title.position === TOP) {
239
257
  sankeyBox.unpad({ top: titleHeight });
240
- legendArea = new Box(0, titleHeight, options.width, options.height);
258
+ legendArea = new Box(0, titleHeight, calcOptions.width, calcOptions.height);
241
259
  } else {
242
260
  sankeyBox.shrink(0, titleHeight);
243
- legendArea = new Box(0, 0, options.width, options.height - titleHeight);
261
+ legendArea = new Box(0, 0, calcOptions.width, calcOptions.height - titleHeight);
244
262
  }
245
263
  }
246
264
 
@@ -264,7 +282,7 @@ export class Sankey extends Observable {
264
282
  }
265
283
  }
266
284
 
267
- const calculatedNodes = calculateSankey(Object.assign({}, options, {offsetX: sankeyBox.x1, offsetY: sankeyBox.y1, width: sankeyBox.x2, height: sankeyBox.y2})).nodes;
285
+ const calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: sankeyBox.x1, offsetY: sankeyBox.y1, width: sankeyBox.x2, height: sankeyBox.y2})).nodes;
268
286
  const box = new Box();
269
287
 
270
288
  calculatedNodes.forEach((nodeEl, i) => {
@@ -272,7 +290,7 @@ export class Sankey extends Observable {
272
290
  const nodeInstance = new Node(nodeOps);
273
291
  box.wrap(rectToBox(nodeInstance.exportVisual().rawBBox()));
274
292
 
275
- const labelInstance = new Label(deepExtend({ node: nodeEl, totalWidth: options.width }, labels));
293
+ const labelInstance = new Label(deepExtend({ node: nodeEl, totalWidth: calcOptions.width }, labels));
276
294
  const labelVisual = labelInstance.exportVisual();
277
295
  if (labelVisual) {
278
296
  box.wrap(rectToBox(labelVisual.rawBBox()));
@@ -286,20 +304,26 @@ export class Sankey extends Observable {
286
304
  let height = box.height() > sankeyBox.y2 ? offsetY + sankeyBox.y2 - (box.height() - sankeyBox.y2) : sankeyBox.y2;
287
305
 
288
306
  return {
289
- sankey: calculateSankey(Object.assign({}, options, {offsetX, offsetY, width, height})),
307
+ sankey: calculateSankey(Object.assign({}, calcOptions, {offsetX, offsetY, width, height})),
290
308
  legendBox,
291
309
  titleBox
292
310
  };
293
311
  }
294
312
 
295
- _render() {
296
- const { data, labels: labelOptions, nodes: nodesOptions, links: linkOptions, nodesColors, title, legend } = this.options;
297
- const { width, height } = this.size;
313
+ _render(options, context) {
314
+ const sankeyOptions = options || this.options;
315
+ const sankeyContext = context || this;
316
+
317
+ const { data, labels: labelOptions, nodes: nodesOptions, links: linkOptions, nodesColors, title, legend } = sankeyOptions;
318
+ const { width, height } = sankeyContext.size;
319
+
298
320
  const calcOptions = Object.assign({}, data, {width, height, nodesOptions, title, legend});
299
- const { sankey, titleBox, legendBox } = this.calculateSankey(calcOptions);
321
+ const { sankey, titleBox, legendBox } = this.calculateSankey(calcOptions, sankeyOptions);
300
322
  const { nodes, links } = sankey;
301
323
 
302
- const visual = new drawing.Group();
324
+ const visual = new drawing.Group({
325
+ clip: drawing.Path.fromRect(new geometry.Rect([0, 0], [width, height]))
326
+ });
303
327
 
304
328
  if (titleBox) {
305
329
  const titleElement = new Title(Object.assign({}, title, {drawingRect: titleBox}));
@@ -314,6 +338,7 @@ export class Sankey extends Observable {
314
338
  }
315
339
 
316
340
  const visualNodes = new Map();
341
+ sankeyContext.nodesVisuals = visualNodes;
317
342
 
318
343
  nodes.forEach((node, i) => {
319
344
  const nodeOps = resolveNodeOptions(node, nodesOptions, nodesColors, i);
@@ -322,6 +347,12 @@ export class Sankey extends Observable {
322
347
  const nodeVisual = nodeInstance.exportVisual();
323
348
  nodeVisual.links = [];
324
349
  nodeVisual.type = NODE;
350
+
351
+ nodeVisual.dataItem = Object.assign({}, data.nodes[i],
352
+ {color: nodeOps.color,
353
+ opacity: nodeOps.opacity,
354
+ sourceLinks: node.sourceLinks.map(link => ({ sourceId: link.sourceId, targetId: link.targetId, value: link.value })),
355
+ targetLinks: node.targetLinks.map(link => ({ sourceId: link.sourceId, targetId: link.targetId, value: link.value }))});
325
356
  visualNodes.set(node.id, nodeVisual);
326
357
 
327
358
  visual.append(nodeVisual);
@@ -330,6 +361,7 @@ export class Sankey extends Observable {
330
361
  const sortedLinks = links.slice().sort((a, b) => b.value - a.value);
331
362
 
332
363
  const linksVisuals = [];
364
+ sankeyContext.linksVisuals = linksVisuals;
333
365
 
334
366
  sortedLinks.forEach(link => {
335
367
  const { source, target } = link;
@@ -340,6 +372,11 @@ export class Sankey extends Observable {
340
372
  const linkVisual = linkInstance.exportVisual();
341
373
 
342
374
  linkVisual.type = LINK;
375
+ linkVisual.dataItem = {
376
+ source: Object.assign({}, sourceNode.dataItem),
377
+ target: Object.assign({}, targetNode.dataItem),
378
+ value: link.value
379
+ };
343
380
  linksVisuals.push(linkVisual);
344
381
 
345
382
  sourceNode.links.push(linkVisual);
@@ -348,9 +385,6 @@ export class Sankey extends Observable {
348
385
  visual.append(linkVisual);
349
386
  });
350
387
 
351
- this.linksVisuals = linksVisuals;
352
- this.nodesVisuals = visualNodes;
353
-
354
388
  nodes.forEach((node) => {
355
389
  const textOps = resolveLabelOptions(node, labelOptions, width);
356
390
  const labelInstance = new Label(textOps);
@@ -364,8 +398,18 @@ export class Sankey extends Observable {
364
398
  return visual;
365
399
  }
366
400
 
367
- exportVisual() {
368
- return this._render();
401
+ exportVisual(exportOptions) {
402
+ const options = (exportOptions && exportOptions.options) ?
403
+ deepExtend({}, this.options, exportOptions.options) : this.options;
404
+
405
+ const context = {
406
+ size: {
407
+ width: defined(exportOptions && exportOptions.width) ? exportOptions.width : this.size.width,
408
+ height: defined(exportOptions && exportOptions.height) ? exportOptions.height : this.size.height
409
+ }
410
+ };
411
+
412
+ return this._render(options, context);
369
413
  }
370
414
 
371
415
  _setOptions(options) {