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

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.
@@ -8,6 +8,7 @@ import removeClass from './remove-class';
8
8
 
9
9
  var KICON = 'k-icon';
10
10
  var KI_PREFFIX = 'k-i-';
11
+ var KFONTICON = 'k-font-icon';
11
12
  var KSVGICON = 'k-svg-icon';
12
13
  var KSVG_PREFFIX = 'k-svg-i-';
13
14
 
@@ -55,6 +56,7 @@ var HTMLFontIcon = (function (HTMLBaseIcon) {
55
56
  this._className = className;
56
57
 
57
58
  addClass(this.element, KICON);
59
+ addClass(this.element, KFONTICON);
58
60
  removeClass(this.element, currentIconClass); // Remove any existing icons.
59
61
  addClass(this.element, className);
60
62
  addClass(this.element, this.options.iconClass || '');
@@ -3,24 +3,40 @@ import { deepExtend } from '../common';
3
3
  var max = function (array, mapFn) { return Math.max.apply(null, array.map(mapFn)); };
4
4
  var min = function (array, mapFn) { return Math.min.apply(null, array.map(mapFn)); };
5
5
  var sum = function (array, mapFn) { return array.map(mapFn).reduce(function (acc, curr) { return (acc + curr); }, 0); };
6
- var sortAsc = function (a, b) { return a.y0 - b.y0; };
6
+ var sortAsc = function (a, b) { return (a.y0 === b.y0 ? a.index - b.index : a.y0 + a.y1 - b.y0 - b.y1); };
7
7
  var sortSource = function (a, b) { return sortAsc(a.source, b.source); };
8
8
  var sortTarget = function (a, b) { return sortAsc(a.target, b.target); };
9
9
  var value = function (node) { return node.value; };
10
10
 
11
11
  function sortLinks(nodes) {
12
12
  nodes.forEach(function (node) {
13
- var sourceLinks = node.sourceLinks;
14
- var targetLinks = node.targetLinks;
15
- sourceLinks.sort(sortTarget);
16
- targetLinks.sort(sortSource);
13
+ node.targetLinks.forEach(function (link) {
14
+ link.source.sourceLinks.sort(sortTarget);
15
+ });
16
+ node.sourceLinks.forEach(function (link) {
17
+ link.target.targetLinks.sort(sortSource);
18
+ });
17
19
  });
18
20
  }
19
21
 
22
+ var calcLayer = function (node, maxDepth) {
23
+ if (node.align === 'left') {
24
+ return node.depth;
25
+ }
26
+
27
+ if (node.align === 'right') {
28
+ return maxDepth - node.height;
29
+ }
30
+
31
+ return node.sourceLinks.length ? node.depth : maxDepth;
32
+ };
33
+
20
34
  var Sankey = function Sankey(options) {
21
- var offset = options.nodesOptions.offset || {};
35
+ var ref = options.nodesOptions;
36
+ var offset = ref.offset; if ( offset === void 0 ) offset = {};
37
+ var align = ref.align;
22
38
  this.data = {
23
- nodes: options.nodes.map(function (node) { return deepExtend({}, { offset: offset }, node); }),
39
+ nodes: options.nodes.map(function (node) { return deepExtend({}, { offset: offset, align: align }, node); }),
24
40
  links: options.links.map(function (link) { return deepExtend({}, link); })
25
41
  };
26
42
 
@@ -30,6 +46,10 @@ var Sankey = function Sankey(options) {
30
46
  this.offsetY = options.offsetY || 0;
31
47
  this.nodeWidth = options.nodesOptions.width;
32
48
  this.nodePadding = options.nodesOptions.padding;
49
+ this.reverse = options.reverse;
50
+ this.targetColumnIndex = options.targetColumnIndex;
51
+ this.loops = options.loops;
52
+ this.autoLayout = options.autoLayout;
33
53
  };
34
54
 
35
55
  Sankey.prototype.calculate = function calculate () {
@@ -39,19 +59,21 @@ Sankey.prototype.calculate = function calculate () {
39
59
  this.connectLinksToNodes(nodes, links);
40
60
  this.calculateNodeValues(nodes);
41
61
  this.calculateNodeDepths(nodes);
62
+ this.calculateNodeHeights(nodes);
42
63
 
43
64
  var columns = this.calculateNodeColumns(nodes);
44
65
  this.calculateNodeBreadths(columns);
45
66
  this.applyNodesOffset(nodes);
46
67
  this.calculateLinkBreadths(nodes);
47
68
 
48
- return this.data;
69
+ return Object.assign({}, this.data, {columns: columns});
49
70
  };
50
71
 
51
72
  Sankey.prototype.connectLinksToNodes = function connectLinksToNodes (nodes, links) {
52
73
  var nodesMap = new Map();
53
74
 
54
- nodes.forEach(function (node) {
75
+ nodes.forEach(function (node, i) {
76
+ node.index = i;
55
77
  node.sourceLinks = [];
56
78
  node.targetLinks = [];
57
79
  node.id = node.id !== undefined ? node.id : node.label.text;
@@ -95,6 +117,24 @@ Sankey.prototype.calculateNodeDepths = function calculateNodeDepths (nodes) {
95
117
  }
96
118
  };
97
119
 
120
+ Sankey.prototype.calculateNodeHeights = function calculateNodeHeights (nodes) {
121
+ var current = new Set(nodes);
122
+ var next = new Set;
123
+ var x = 0;
124
+ var eachNode = function (node) {
125
+ node.height = x;
126
+ node.targetLinks.forEach(function (link) {
127
+ next.add(link.source);
128
+ });
129
+ };
130
+ while (current.size) {
131
+ current.forEach(eachNode);
132
+ x++;
133
+ current = next;
134
+ next = new Set;
135
+ }
136
+ };
137
+
98
138
  Sankey.prototype.calculateNodeColumns = function calculateNodeColumns (nodes) {
99
139
  var this$1 = this;
100
140
 
@@ -103,11 +143,12 @@ Sankey.prototype.calculateNodeColumns = function calculateNodeColumns (nodes) {
103
143
  var columns = new Array(maxDepth + 1);
104
144
  for (var i = 0; i < nodes.length; i++) {
105
145
  var node = nodes[i];
106
- var depth = Math.max(0, Math.min(maxDepth, node.sourceLinks.length ? node.depth : maxDepth));
107
- node.x0 = this$1.offsetX + depth * columnWidth;
146
+ var layer = Math.max(0, Math.min(maxDepth, calcLayer(node, maxDepth)));
147
+ node.x0 = this$1.offsetX + layer * columnWidth;
108
148
  node.x1 = node.x0 + this$1.nodeWidth;
109
- columns[depth] = columns[depth] || [];
110
- columns[depth].push(node);
149
+ node.layer = layer;
150
+ columns[layer] = columns[layer] || [];
151
+ columns[layer].push(node);
111
152
  }
112
153
 
113
154
  return columns;
@@ -118,31 +159,39 @@ Sankey.prototype.calculateNodeBreadths = function calculateNodeBreadths (columns
118
159
 
119
160
  var kSize = min(columns, function (c) { return (this$1.height - this$1.offsetY - (c.length - 1) * this$1.nodePadding) / sum(c, value); });
120
161
 
121
- for (var c = 0; c < columns.length; c++) {
122
- var nodes = columns[c];
162
+ columns.forEach(function (nodes) {
123
163
  var y = this$1.offsetY;
124
- for (var i = 0; i < nodes.length; i++) {
125
- var node = nodes[i];
164
+ nodes.forEach(function (node) {
126
165
  node.y0 = y;
127
166
  node.y1 = y + node.value * kSize;
128
167
  y = node.y1 + this$1.nodePadding;
129
- for (var l = 0; l < node.sourceLinks.length; l++) {
130
- var link = node.sourceLinks[l];
168
+ node.sourceLinks.forEach(function (link) {
131
169
  link.width = link.value * kSize;
132
- }
133
- }
134
-
170
+ });
171
+ });
135
172
  y = (this$1.height - y + this$1.nodePadding) / (nodes.length + 1);
136
- for (var i$1 = 0; i$1 < nodes.length; ++i$1) {
137
- var node$1 = nodes[i$1];
138
- node$1.y0 += y * (i$1 + 1);
139
- node$1.y1 += y * (i$1 + 1);
173
+ nodes.forEach(function (node, i) {
174
+ node.y0 += y * (i + 1);
175
+ node.y1 += y * (i + 1);
176
+ });
177
+ });
178
+
179
+ if (this.autoLayout !== false) {
180
+ var loops = this.loops !== undefined ? this.loops : columns.length - 1;
181
+ var targetColumnIndex = this.targetColumnIndex || 1;
182
+
183
+ for (var i = 0; i < loops; i++) {
184
+ if (!this$1.reverse) {
185
+ this$1.uncurlLinksToLeft(columns, targetColumnIndex);
186
+ this$1.uncurlLinksToRight(columns, targetColumnIndex);
187
+ } else {
188
+ this$1.uncurlLinksToRight(columns, targetColumnIndex);
189
+ this$1.uncurlLinksToLeft(columns, targetColumnIndex);
190
+ }
140
191
  }
141
192
  }
142
193
 
143
- for (var c$1 = 0; c$1 < columns.length; c$1++) {
144
- sortLinks(columns[c$1]);
145
- }
194
+ columns.forEach(sortLinks);
146
195
  };
147
196
 
148
197
  Sankey.prototype.applyNodesOffset = function applyNodesOffset (nodes) {
@@ -163,14 +212,188 @@ Sankey.prototype.calculateLinkBreadths = function calculateLinkBreadths (nodes)
163
212
  var y = node.y0;
164
213
  var y1 = y;
165
214
  sourceLinks.forEach(function (link) {
215
+ link.x0 = link.source.x1;
166
216
  link.y0 = y + link.width / 2;
167
217
  y += link.width;
168
218
  });
169
219
  targetLinks.forEach(function (link) {
220
+ link.x1 = link.target.x0;
170
221
  link.y1 = y1 + link.width / 2;
171
222
  y1 += link.width;
172
223
  });
173
224
  });
174
225
  };
175
226
 
227
+ Sankey.prototype.uncurlLinksToRight = function uncurlLinksToRight (columns, targetColumnIndex) {
228
+ var this$1 = this;
229
+
230
+ var n = columns.length;
231
+ for (var i = targetColumnIndex; i < n; i++) {
232
+ var column = columns[i];
233
+ column.forEach(function (target) {
234
+ var y = 0;
235
+ var sum = 0;
236
+ target.targetLinks.forEach(function (link) {
237
+ var kValue = link.value * (target.layer - link.source.layer);
238
+ y += this$1.targetTopPos(link.source, target) * kValue;
239
+ sum += kValue;
240
+ });
241
+
242
+ var dy = y === 0 ? 0 : (y / sum - target.y0);
243
+ target.y0 += dy;
244
+ target.y1 += dy;
245
+ sortLinks([target]);
246
+ });
247
+ column.sort(sortAsc);
248
+ this$1.arrangeNodesVertically(column);
249
+ }
250
+ };
251
+
252
+ Sankey.prototype.uncurlLinksToLeft = function uncurlLinksToLeft (columns, targetColumnIndex) {
253
+ var this$1 = this;
254
+
255
+ var l = columns.length;
256
+ var startIndex = l - 1 - targetColumnIndex;
257
+ for (var i = startIndex; i >= 0; i--) {
258
+ var column = columns[i];
259
+ var loop = function ( j ) {
260
+ var source = column[j];
261
+ var y = 0;
262
+ var sum = 0;
263
+ source.sourceLinks.forEach(function (link) {
264
+ var kValue = link.value * (link.target.layer - source.layer);
265
+ y += this$1.sourceTopPos(source, link.target) * kValue;
266
+ sum += kValue;
267
+ });
268
+ var dy = y === 0 ? 0 : (y / sum - source.y0);
269
+ source.y0 += dy;
270
+ source.y1 += dy;
271
+ sortLinks([source]);
272
+ };
273
+
274
+ for (var j = 0; j < column.length; j++) loop( j );
275
+
276
+ column.sort(sortAsc);
277
+ this$1.arrangeNodesVertically(column);
278
+ }
279
+ };
280
+
281
+ Sankey.prototype.arrangeNodesVertically = function arrangeNodesVertically (nodes) {
282
+ var startIndex = 0;
283
+ var endIndex = nodes.length - 1;
284
+
285
+ this.arrangeUp(nodes, this.height, endIndex);
286
+ this.arrangeDown(nodes, this.offsetY, startIndex);
287
+ };
288
+
289
+ Sankey.prototype.arrangeDown = function arrangeDown (nodes, yPos, index) {
290
+ var this$1 = this;
291
+
292
+ var currentY = yPos;
293
+
294
+ for (var i = index; i < nodes.length; i++) {
295
+ var node = nodes[i];
296
+ var dy = Math.max(0, currentY - node.y0);
297
+ node.y0 += dy;
298
+ node.y1 += dy;
299
+ currentY = node.y1 + this$1.nodePadding;
300
+ }
301
+ };
302
+
303
+ Sankey.prototype.arrangeUp = function arrangeUp (nodes, yPos, index) {
304
+ var this$1 = this;
305
+
306
+ var currentY = yPos;
307
+ for (var i = index; i >= 0; --i) {
308
+ var node = nodes[i];
309
+ var dy = Math.max(0, node.y1 - currentY);
310
+ node.y0 -= dy;
311
+ node.y1 -= dy;
312
+ currentY = node.y0 - this$1.nodePadding;
313
+ }
314
+ };
315
+
316
+ Sankey.prototype.sourceTopPos = function sourceTopPos (source, target) {
317
+ var this$1 = this;
318
+
319
+ var y = target.y0 - ((target.targetLinks.length - 1) * this.nodePadding) / 2;
320
+ for (var i = 0; i < target.targetLinks.length; i++) {
321
+ var link = target.targetLinks[i];
322
+ if (link.source === source) {
323
+ break;
324
+ }
325
+ y += link.width + this$1.nodePadding;
326
+ }
327
+ for (var i$1 = 0; i$1 < source.sourceLinks.length; i$1++) {
328
+ var link$1 = source.sourceLinks[i$1];
329
+ if (link$1.target === target) {
330
+ break;
331
+ }
332
+ y -= link$1.width;
333
+ }
334
+ return y;
335
+ };
336
+
337
+ Sankey.prototype.targetTopPos = function targetTopPos (source, target) {
338
+ var this$1 = this;
339
+
340
+ var y = source.y0 - ((source.sourceLinks.length - 1) * this.nodePadding) / 2;
341
+ for (var i = 0; i < source.sourceLinks.length; i++) {
342
+ var link = source.sourceLinks[i];
343
+ if (link.target === target) {
344
+ break;
345
+ }
346
+ y += link.width + this$1.nodePadding;
347
+ }
348
+ for (var i$1 = 0; i$1 < target.targetLinks.length; i$1++) {
349
+ var link$1 = target.targetLinks[i$1];
350
+ if (link$1.source === source) {
351
+ break;
352
+ }
353
+ y -= link$1.width;
354
+ }
355
+ return y;
356
+ };
357
+
176
358
  export var calculateSankey = function (options) { return new Sankey(options).calculate(); };
359
+
360
+ export var crossesValue = function (links) {
361
+ var value = 0;
362
+ var linksLength = links.length;
363
+
364
+ for (var i = 0; i < linksLength; i++) {
365
+ var link = links[i];
366
+
367
+ for (var lNext = i + 1; lNext < linksLength; lNext++) {
368
+ var nextLink = links[lNext];
369
+
370
+ if (intersect(link, nextLink)) {
371
+ value += Math.min(link.value, nextLink.value);
372
+ }
373
+ }
374
+ }
375
+
376
+ return value;
377
+ };
378
+
379
+ function rotationDirection(p1x, p1y, p2x, p2y, p3x, p3y) {
380
+ var expression1 = (p3y - p1y) * (p2x - p1x);
381
+ var expression2 = (p2y - p1y) * (p3x - p1x);
382
+
383
+ if (expression1 > expression2) {
384
+ return 1;
385
+ } else if (expression1 === expression2) {
386
+ return 0;
387
+ }
388
+
389
+ return -1;
390
+ }
391
+
392
+ function intersect(link1, link2) {
393
+ var f1 = rotationDirection(link1.x0, link1.y0, link1.x1, link1.y1, link2.x1, link2.y1);
394
+ var f2 = rotationDirection(link1.x0, link1.y0, link1.x1, link1.y1, link2.x0, link2.y0);
395
+ var f3 = rotationDirection(link1.x0, link1.y0, link2.x0, link2.y0, link2.x1, link2.y1);
396
+ var f4 = rotationDirection(link1.x1, link1.y1, link2.x0, link2.y0, link2.x1, link2.y1);
397
+
398
+ return f1 !== f2 && f3 !== f4;
399
+ }
@@ -14,14 +14,14 @@ export var Link = (function (SankeyElement) {
14
14
 
15
15
  Link.prototype.getElement = function getElement () {
16
16
  var link = this.options.link;
17
- var source = link.source;
18
- var target = link.target;
17
+ var x0 = link.x0;
18
+ var x1 = link.x1;
19
19
  var y0 = link.y0;
20
20
  var y1 = link.y1;
21
- var xC = (source.x0 + target.x1) / 2;
21
+ var xC = (x0 + x1) / 2;
22
22
 
23
23
  return new drawing.Path(this.visualOptions())
24
- .moveTo(source.x1, y0).curveTo([xC, y0], [xC, y1], [target.x0, y1]);
24
+ .moveTo(x0, y0).curveTo([xC, y0], [xC, y1], [x1, y1]);
25
25
  };
26
26
 
27
27
  Link.prototype.visualOptions = function visualOptions () {
@@ -1,6 +1,6 @@
1
1
  import { geometry, drawing } from '@progress/kendo-drawing';
2
2
  import { deepExtend, addClass, setDefaultOptions } from '../common';
3
- import { calculateSankey } from './calculation';
3
+ import { calculateSankey, crossesValue } from './calculation';
4
4
  import { Node, resolveNodeOptions } from './node';
5
5
  import { Link, resolveLinkOptions } from './link';
6
6
  import { Label, resolveLabelOptions } from './label';
@@ -68,6 +68,7 @@ export var Sankey = (function (Observable) {
68
68
  }
69
69
  this$1.size = { width: width, height: height };
70
70
  this$1.surface.setSize(this$1.size);
71
+ this$1.resize = true;
71
72
  this$1._redraw();
72
73
  });
73
74
  });
@@ -265,6 +266,8 @@ export var Sankey = (function (Observable) {
265
266
  var nodes = sankeyOptions.nodes;
266
267
  var labels = sankeyOptions.labels;
267
268
  var nodesColors = sankeyOptions.nodesColors;
269
+ var disableAutoLayout = sankeyOptions.disableAutoLayout;
270
+ var autoLayout = !disableAutoLayout;
268
271
 
269
272
  var sankeyBox = new Box(0, 0, calcOptions.width, calcOptions.height);
270
273
  var titleBox = this.titleBox(title, sankeyBox);
@@ -283,26 +286,27 @@ export var Sankey = (function (Observable) {
283
286
  }
284
287
 
285
288
  var legendBox = this.legendBox(legend, data.nodes, legendArea);
289
+ var legendPosition = (legend && legend.position) || Legend.prototype.options.position;
286
290
 
287
291
  if (legendBox) {
288
- if (legend.position === LEFT) {
292
+ if (legendPosition === LEFT) {
289
293
  sankeyBox.unpad({ left: legendBox.width() });
290
294
  }
291
295
 
292
- if (legend.position === RIGHT) {
296
+ if (legendPosition === RIGHT) {
293
297
  sankeyBox.shrink(legendBox.width(), 0);
294
298
  }
295
299
 
296
- if (legend.position === TOP) {
300
+ if (legendPosition === TOP) {
297
301
  sankeyBox.unpad({ top: legendBox.height() });
298
302
  }
299
303
 
300
- if (legend.position === BOTTOM) {
304
+ if (legendPosition === BOTTOM) {
301
305
  sankeyBox.shrink(0, legendBox.height());
302
306
  }
303
307
  }
304
308
 
305
- var calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: sankeyBox.x1, offsetY: sankeyBox.y1, width: sankeyBox.x2, height: sankeyBox.y2})).nodes;
309
+ var calculatedNodes = calculateSankey(Object.assign({}, calcOptions, {offsetX: 0, offsetY: 0, width: sankeyBox.width(), height: sankeyBox.height()})).nodes;
306
310
  var box = new Box();
307
311
 
308
312
  calculatedNodes.forEach(function (nodeEl, i) {
@@ -310,21 +314,71 @@ export var Sankey = (function (Observable) {
310
314
  var nodeInstance = new Node(nodeOps);
311
315
  box.wrap(rectToBox(nodeInstance.exportVisual().rawBBox()));
312
316
 
313
- var labelInstance = new Label(deepExtend({ node: nodeEl, totalWidth: calcOptions.width }, labels));
317
+ var labelInstance = new Label(resolveLabelOptions(nodeEl, labels, sankeyBox.width()));
314
318
  var labelVisual = labelInstance.exportVisual();
315
319
  if (labelVisual) {
316
320
  box.wrap(rectToBox(labelVisual.rawBBox()));
317
321
  }
318
322
  });
319
323
 
320
- var offsetX = (box.x1 < 0 ? -box.x1 : 0) + sankeyBox.x1;
321
- var offsetY = (box.y1 < 0 ? -box.y1 : 0) + sankeyBox.y1;
324
+ var offsetX = sankeyBox.x1;
325
+ var offsetY = sankeyBox.y1;
322
326
 
323
- var width = box.width() > sankeyBox.x2 ? offsetX + sankeyBox.x2 - (box.width() - sankeyBox.x2) : sankeyBox.x2;
324
- var height = box.height() > sankeyBox.y2 ? offsetY + sankeyBox.y2 - (box.height() - sankeyBox.y2) : sankeyBox.y2;
327
+ var width = sankeyBox.width() + offsetX;
328
+ var height = sankeyBox.height() + offsetY;
329
+
330
+ width -= box.x2 > sankeyBox.width() ? box.x2 - sankeyBox.width() : 0;
331
+ height -= box.y2 > sankeyBox.height() ? box.y2 - sankeyBox.height() : 0;
332
+
333
+ offsetX += box.x1 < 0 ? -box.x1 : 0;
334
+ offsetY += box.y1 < 0 ? -box.y1 : 0;
335
+
336
+ if (autoLayout === false) {
337
+ return {
338
+ sankey: calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height, autoLayout: false})),
339
+ legendBox: legendBox,
340
+ titleBox: titleBox
341
+ };
342
+ }
343
+
344
+ if (this.resize && autoLayout && this.permutation) {
345
+ this.resize = false;
346
+ return {
347
+ sankey: calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height}, this.permutation)),
348
+ legendBox: legendBox,
349
+ titleBox: titleBox
350
+ };
351
+ }
352
+
353
+ var startColumn = 1;
354
+ var loops = 2;
355
+ var columnsLength = calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height, autoLayout: false})).columns.length;
356
+ var results = [];
357
+
358
+ var permutation = function (targetColumnIndex, reverse) {
359
+ var currPerm = calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height, loops: loops, targetColumnIndex: targetColumnIndex, reverse: reverse}));
360
+ var crosses = crossesValue(currPerm.links);
361
+ results.push({
362
+ crosses: crosses,
363
+ reverse: reverse,
364
+ targetColumnIndex: targetColumnIndex
365
+ });
366
+ return crosses === 0;
367
+ };
368
+
369
+ for (var index = startColumn; index <= columnsLength - 1; index++) {
370
+ if (permutation(index, false) || permutation(index, true)) {
371
+ break;
372
+ }
373
+ }
374
+
375
+ var minCrosses = Math.min.apply(null, results.map(function (r) { return r.crosses; }));
376
+ var bestResult = results.find(function (r) { return r.crosses === minCrosses; });
377
+ this.permutation = { targetColumnIndex: bestResult.targetColumnIndex, reverse: bestResult.reverse };
378
+ var result = calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height}, this.permutation));
325
379
 
326
380
  return {
327
- sankey: calculateSankey(Object.assign({}, calcOptions, {offsetX: offsetX, offsetY: offsetY, width: width, height: height})),
381
+ sankey: result,
328
382
  legendBox: legendBox,
329
383
  titleBox: titleBox
330
384
  };
@@ -418,8 +472,9 @@ export var Sankey = (function (Observable) {
418
472
  visual.append(linkVisual);
419
473
  });
420
474
 
475
+ var diagramWidth = nodes.reduce(function (acc, node) { return Math.max(acc, node.x1); }, 0);
421
476
  nodes.forEach(function (node) {
422
- var textOps = resolveLabelOptions(node, labelOptions, width);
477
+ var textOps = resolveLabelOptions(node, labelOptions, diagramWidth);
423
478
  var labelInstance = new Label(textOps);
424
479
  var labelVisual = labelInstance.exportVisual();
425
480
 
@@ -453,6 +508,9 @@ export var Sankey = (function (Observable) {
453
508
  }(Observable));
454
509
 
455
510
  setDefaultOptions(Sankey, {
511
+ title: {
512
+ position: TOP, // 'top', 'bottom'
513
+ },
456
514
  labels: {
457
515
  visible: true,
458
516
  margin: {
@@ -471,6 +529,7 @@ setDefaultOptions(Sankey, {
471
529
  width: 24,
472
530
  padding: 16,
473
531
  opacity: 1,
532
+ align: 'stretch', // 'left', 'right', 'stretch'
474
533
  offset: { left: 0, top: 0 }
475
534
  },
476
535
  links: {
@@ -37,7 +37,6 @@ export var Title = (function (SankeyElement) {
37
37
  }(SankeyElement));
38
38
 
39
39
  setDefaultOptions(Title, {
40
- position: TOP, // 'top', 'bottom'
41
40
  align: CENTER, // 'left', 'right', 'center'
42
41
  opacity: 1,
43
42
  border: {
@@ -8,6 +8,7 @@ import removeClass from './remove-class';
8
8
 
9
9
  const KICON = 'k-icon';
10
10
  const KI_PREFFIX = 'k-i-';
11
+ const KFONTICON = 'k-font-icon';
11
12
  const KSVGICON = 'k-svg-icon';
12
13
  const KSVG_PREFFIX = 'k-svg-i-';
13
14
 
@@ -53,6 +54,7 @@ class HTMLFontIcon extends HTMLBaseIcon {
53
54
  this._className = className;
54
55
 
55
56
  addClass(this.element, KICON);
57
+ addClass(this.element, KFONTICON);
56
58
  removeClass(this.element, currentIconClass); // Remove any existing icons.
57
59
  addClass(this.element, className);
58
60
  addClass(this.element, this.options.iconClass || '');