chartjs-chart-treemap 5.0.0-next.2 → 5.0.0-next.4
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/dist/chartjs-chart-treemap.cjs +354 -267
- package/dist/chartjs-chart-treemap.esm.js +358 -289
- package/dist/chartjs-chart-treemap.min.js +2 -2
- package/dist/chartjs-chart-treemap.min.js.map +1 -1
- package/dist/controller.d.ts +25 -4
- package/dist/element.d.ts +2 -7
- package/dist/index.esm.d.ts +1 -0
- package/dist/layout.d.ts +27 -0
- package/dist/options.d.ts +7 -1
- package/dist/rect.d.ts +1 -1
- package/dist/squarify.d.ts +15 -0
- package/dist/text.d.ts +2 -2
- package/dist/types.d.ts +18 -9
- package/dist/utils.d.ts +11 -2
- package/package.json +2 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap v5.0.0-next.
|
|
2
|
+
* chartjs-chart-treemap v5.0.0-next.4
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2026 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
6
6
|
*/
|
|
7
|
-
import { DatasetController,
|
|
8
|
-
import { toTRBL, toTRBLCorners, isObject, defined,
|
|
7
|
+
import { DatasetController, registry, Chart, Element } from 'chart.js';
|
|
8
|
+
import { toTRBL, toTRBLCorners, isObject, defined, isArray, isNumber, toFont, valueOrDefault, clipArea, unclipArea, addRoundedRectPath } from 'chart.js/helpers';
|
|
9
9
|
|
|
10
|
-
var version = "5.0.0-next.
|
|
10
|
+
var version = "5.0.0-next.4";
|
|
11
11
|
|
|
12
12
|
function scaleRect(sq, xScale, yScale, sp) {
|
|
13
13
|
const sp2 = sp * 2;
|
|
@@ -26,26 +26,12 @@ function scaleRect(sq, xScale, yScale, sp) {
|
|
|
26
26
|
function rectNotEqual(r1, r2) {
|
|
27
27
|
return !r1 || !r2 || r1.x !== r2.x || r1.y !== r2.y || r1.w !== r2.w || r1.h !== r2.h || r1.rtl !== r2.rtl || r1.unsorted !== r2.unsorted;
|
|
28
28
|
}
|
|
29
|
-
function arrayNotEqual(a, b) {
|
|
30
|
-
let i;
|
|
31
|
-
let n;
|
|
32
|
-
if (!a || !b) {
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (a === b) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
if (a.length !== b.length) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
for(i = 0, n = a.length; i < n; ++i){
|
|
42
|
-
if (a[i] !== b[i]) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
29
|
|
|
30
|
+
const layoutDefaults = {
|
|
31
|
+
displayMode: 'containerBoxes',
|
|
32
|
+
rtl: false,
|
|
33
|
+
spacing: 0.5
|
|
34
|
+
};
|
|
49
35
|
function limit(value, min, max) {
|
|
50
36
|
return Math.max(Math.min(value, max), min);
|
|
51
37
|
}
|
|
@@ -84,24 +70,14 @@ function getDims(itm, w2, s2, key) {
|
|
|
84
70
|
};
|
|
85
71
|
}
|
|
86
72
|
const getX = (rect, w)=>rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
w: dims.w,
|
|
96
|
-
x: getX(rect, dims.w),
|
|
97
|
-
y: rect.y + rect._iy
|
|
98
|
-
};
|
|
99
|
-
if (itm.group) {
|
|
100
|
-
r.g = itm.group;
|
|
101
|
-
r.l = itm.level;
|
|
102
|
-
r.gs = itm.groupSum;
|
|
103
|
-
}
|
|
104
|
-
return r;
|
|
73
|
+
function assignRow(rect, itm, dims, sum) {
|
|
74
|
+
itm.a = itm._normalized;
|
|
75
|
+
itm.h = dims.h;
|
|
76
|
+
itm.s = sum;
|
|
77
|
+
itm.w = dims.w;
|
|
78
|
+
itm.x = getX(rect, dims.w);
|
|
79
|
+
itm.y = rect.y + rect._iy;
|
|
80
|
+
delete itm._normalized;
|
|
105
81
|
}
|
|
106
82
|
class Rect {
|
|
107
83
|
get area() {
|
|
@@ -127,19 +103,17 @@ class Rect {
|
|
|
127
103
|
const row = arr.get();
|
|
128
104
|
const w2 = side * side;
|
|
129
105
|
const s2 = sum * sum;
|
|
130
|
-
const ret = [];
|
|
131
106
|
let maxd2 = 0;
|
|
132
107
|
let totd1 = 0;
|
|
133
108
|
for (const itm of row){
|
|
134
109
|
const dims = getDims(itm, w2, s2, key);
|
|
135
110
|
totd1 += dims.d1;
|
|
136
111
|
maxd2 = Math.max(maxd2, dims.d2);
|
|
137
|
-
|
|
112
|
+
assignRow(this, itm, dims, arr.sum);
|
|
138
113
|
this[key] += dims.d1;
|
|
139
114
|
}
|
|
140
115
|
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
141
116
|
this[key] -= totd1;
|
|
142
|
-
return ret;
|
|
143
117
|
}
|
|
144
118
|
constructor(r){
|
|
145
119
|
r = r || {
|
|
@@ -234,7 +208,7 @@ class StatArray {
|
|
|
234
208
|
const isOlderPart = (act, req)=>req > act || act.length > req.length && act.startsWith(req);
|
|
235
209
|
const getGroupKey = (lvl)=>String(lvl);
|
|
236
210
|
const hasGroupValue = (value)=>value !== undefined && value !== null && value !== '';
|
|
237
|
-
function scanTreeObject(keys,
|
|
211
|
+
function scanTreeObject(keys, leafKey, obj, tree = [], lvl = 0, result = []) {
|
|
238
212
|
const objIndex = lvl - 1;
|
|
239
213
|
if (keys[0] in obj && lvl > 0) {
|
|
240
214
|
const record = tree.reduce((reduced, item, i)=>{
|
|
@@ -243,7 +217,7 @@ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = [])
|
|
|
243
217
|
}
|
|
244
218
|
return reduced;
|
|
245
219
|
}, {});
|
|
246
|
-
record[
|
|
220
|
+
record[leafKey] = tree[objIndex];
|
|
247
221
|
keys.forEach((k)=>{
|
|
248
222
|
record[k] = obj[k];
|
|
249
223
|
});
|
|
@@ -253,15 +227,18 @@ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = [])
|
|
|
253
227
|
const child = obj[childKey];
|
|
254
228
|
if (isObject(child)) {
|
|
255
229
|
tree.push(childKey);
|
|
256
|
-
scanTreeObject(keys,
|
|
230
|
+
scanTreeObject(keys, leafKey, child, tree, lvl + 1, result);
|
|
257
231
|
}
|
|
258
232
|
}
|
|
259
233
|
}
|
|
260
234
|
tree.splice(objIndex, 1);
|
|
261
235
|
return result;
|
|
262
236
|
}
|
|
263
|
-
function
|
|
264
|
-
|
|
237
|
+
function flattenTree(tree, keys, leafKey) {
|
|
238
|
+
return normalizeTreeToArray(keys, leafKey, tree);
|
|
239
|
+
}
|
|
240
|
+
function normalizeTreeToArray(keys, leafKey, obj) {
|
|
241
|
+
const data = scanTreeObject(keys, leafKey, obj);
|
|
265
242
|
if (!data.length) {
|
|
266
243
|
return data;
|
|
267
244
|
}
|
|
@@ -279,21 +256,6 @@ function normalizeTreeToArray(keys, treeLeafKey, obj) {
|
|
|
279
256
|
});
|
|
280
257
|
return data;
|
|
281
258
|
}
|
|
282
|
-
function flatten(input) {
|
|
283
|
-
const stack = [
|
|
284
|
-
...input
|
|
285
|
-
];
|
|
286
|
-
const res = [];
|
|
287
|
-
while(stack.length){
|
|
288
|
-
const next = stack.pop();
|
|
289
|
-
if (Array.isArray(next)) {
|
|
290
|
-
stack.push(...next);
|
|
291
|
-
} else {
|
|
292
|
-
res.push(next);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return res.reverse();
|
|
296
|
-
}
|
|
297
259
|
function getPath(groups, value, defaultValue) {
|
|
298
260
|
const path = [];
|
|
299
261
|
for (const grp of groups){
|
|
@@ -305,7 +267,7 @@ function getPath(groups, value, defaultValue) {
|
|
|
305
267
|
}
|
|
306
268
|
return path.length ? path.join('.') : defaultValue;
|
|
307
269
|
}
|
|
308
|
-
function resolveGroup(value,
|
|
270
|
+
function resolveGroup(value, leafKey, allGroups, groupIndex) {
|
|
309
271
|
for(let idx = groupIndex; idx < allGroups.length; idx++){
|
|
310
272
|
const groupKey = getGroupKey(allGroups[idx]);
|
|
311
273
|
if (hasGroupValue(value[groupKey])) {
|
|
@@ -316,11 +278,11 @@ function resolveGroup(value, treeLeafKey, allGroups, groupIndex) {
|
|
|
316
278
|
};
|
|
317
279
|
}
|
|
318
280
|
}
|
|
319
|
-
if (hasGroupValue(value[
|
|
281
|
+
if (hasGroupValue(value[leafKey])) {
|
|
320
282
|
return {
|
|
321
|
-
group:
|
|
283
|
+
group: leafKey,
|
|
322
284
|
groupIndex,
|
|
323
|
-
value: value[
|
|
285
|
+
value: value[leafKey]
|
|
324
286
|
};
|
|
325
287
|
}
|
|
326
288
|
return undefined;
|
|
@@ -338,7 +300,7 @@ function ensureGroup(tmp, data, groupValue, addKeys) {
|
|
|
338
300
|
});
|
|
339
301
|
data[groupValue] = [];
|
|
340
302
|
}
|
|
341
|
-
function group(values, grp, keys,
|
|
303
|
+
function group(values, grp, keys, leafKey, mainGrp, mainValue, groups = [], allGroups = groups, groupIndex = groups.length - 1) {
|
|
342
304
|
const key = keys[0];
|
|
343
305
|
const addKeys = keys.slice(1);
|
|
344
306
|
const tmp = Object.create(null);
|
|
@@ -352,7 +314,7 @@ function group(values, grp, keys, treeLeafKey, mainGrp, mainValue, groups = [],
|
|
|
352
314
|
let n;
|
|
353
315
|
for(i = 0, n = values.length; i < n; ++i){
|
|
354
316
|
const v = values[i];
|
|
355
|
-
const itemGroup = resolveGroup(v,
|
|
317
|
+
const itemGroup = resolveGroup(v, leafKey, resolvedAllGroups, resolvedGroupIndex);
|
|
356
318
|
if (!itemGroup) {
|
|
357
319
|
return [];
|
|
358
320
|
}
|
|
@@ -407,10 +369,8 @@ function index(values, key) {
|
|
|
407
369
|
return key;
|
|
408
370
|
}
|
|
409
371
|
function sort(values, key) {
|
|
410
|
-
|
|
372
|
+
{
|
|
411
373
|
values.sort((a, b)=>+b[key] - +a[key]);
|
|
412
|
-
} else {
|
|
413
|
-
values.sort((a, b)=>+b - +a);
|
|
414
374
|
}
|
|
415
375
|
}
|
|
416
376
|
function sum(values, key) {
|
|
@@ -418,7 +378,7 @@ function sum(values, key) {
|
|
|
418
378
|
let i;
|
|
419
379
|
let n;
|
|
420
380
|
for(s = 0, i = 0, n = values.length; i < n; ++i){
|
|
421
|
-
s +=
|
|
381
|
+
s += +values[i][key] ;
|
|
422
382
|
}
|
|
423
383
|
return s;
|
|
424
384
|
}
|
|
@@ -453,54 +413,51 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
453
413
|
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
|
|
454
414
|
return nr <= or;
|
|
455
415
|
}
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
let o;
|
|
465
|
-
if (!n) {
|
|
466
|
-
return rows;
|
|
467
|
-
}
|
|
468
|
-
const tmp = values.slice();
|
|
469
|
-
const key = index(tmp, keys[0]);
|
|
470
|
-
if (!rectangle?.unsorted) {
|
|
471
|
-
sort(tmp, key);
|
|
472
|
-
}
|
|
473
|
-
const val = (idx)=>key ? +tmp[idx][key] : +tmp[idx];
|
|
474
|
-
const gval = (idx)=>grp && tmp[idx][grp];
|
|
475
|
-
for(i = 0; i < n; ++i){
|
|
476
|
-
o = {
|
|
477
|
-
_data: values[tmp[i]._idx],
|
|
478
|
-
group: undefined,
|
|
479
|
-
groupSum: gsum,
|
|
480
|
-
level: undefined,
|
|
481
|
-
value: val(i)
|
|
416
|
+
function toNodes(values, keys, grp, lvl) {
|
|
417
|
+
const items = values ? values.slice() : [];
|
|
418
|
+
const key = index(items, keys[0]);
|
|
419
|
+
return items.map((item)=>{
|
|
420
|
+
const node = {
|
|
421
|
+
_data: values[item._idx],
|
|
422
|
+
v: key ? +item[key] : +item,
|
|
423
|
+
vs: undefined
|
|
482
424
|
};
|
|
483
425
|
if (grp) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
obj[k] = +
|
|
426
|
+
node.g = item[grp];
|
|
427
|
+
node.gs = undefined;
|
|
428
|
+
node.l = item.groupIndex ?? lvl;
|
|
429
|
+
node.vs = keys.reduce((obj, k)=>{
|
|
430
|
+
obj[k] = +item[k];
|
|
489
431
|
return obj;
|
|
490
432
|
}, {});
|
|
491
433
|
}
|
|
492
|
-
|
|
434
|
+
return node;
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
function sortNodes(nodes) {
|
|
438
|
+
sort(nodes, 'v');
|
|
439
|
+
}
|
|
440
|
+
function packInto(nodes, rectangle) {
|
|
441
|
+
const n = nodes.length;
|
|
442
|
+
if (!n) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const rect = new Rect(rectangle);
|
|
446
|
+
const row = new StatArray('v', rect.area / sum(nodes, 'v'));
|
|
447
|
+
let length = rect.side;
|
|
448
|
+
let o;
|
|
449
|
+
for(let i = 0; i < n; ++i){
|
|
450
|
+
o = row.pushIf(nodes[i], compareAspectRatio, length);
|
|
493
451
|
if (o) {
|
|
494
|
-
|
|
452
|
+
rect.map(row);
|
|
495
453
|
length = rect.side;
|
|
496
454
|
row.reset();
|
|
497
455
|
row.push(o);
|
|
498
456
|
}
|
|
499
457
|
}
|
|
500
458
|
if (row.length) {
|
|
501
|
-
|
|
459
|
+
rect.map(row);
|
|
502
460
|
}
|
|
503
|
-
return flatten(rows);
|
|
504
461
|
}
|
|
505
462
|
|
|
506
463
|
const widthCache = new Map();
|
|
@@ -524,20 +481,42 @@ function getCaptionHeight(displayMode, rect, font, padding) {
|
|
|
524
481
|
const captionHeight = font.lineHeight + padding * 2;
|
|
525
482
|
return rect.h < 2 * captionHeight ? rect.h / 3 : captionHeight;
|
|
526
483
|
}
|
|
527
|
-
function drawText(ctx, rect, options, item, element) {
|
|
528
|
-
const { captions, labels
|
|
484
|
+
function drawText(ctx, rect, options, item, element, layout) {
|
|
485
|
+
const { captions, labels } = options;
|
|
486
|
+
const { displayMode } = layout;
|
|
487
|
+
const isLeaf = item && (!defined(item.l) || item.isLeaf);
|
|
488
|
+
let block;
|
|
489
|
+
if (isLeaf) {
|
|
490
|
+
if (labels.display) {
|
|
491
|
+
block = labelBlock(ctx, rect, options, item, element);
|
|
492
|
+
}
|
|
493
|
+
} else if (shouldDrawCaption(displayMode, rect, captions)) {
|
|
494
|
+
block = captionBlock(ctx, rect, options, item, element, layout);
|
|
495
|
+
}
|
|
496
|
+
if (!block) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
529
499
|
ctx.save();
|
|
530
500
|
ctx.beginPath();
|
|
531
501
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
532
502
|
ctx.clip();
|
|
533
|
-
|
|
534
|
-
if (isLeaf && labels.display) {
|
|
535
|
-
drawLabel(ctx, rect, options, item, element);
|
|
536
|
-
} else if (!isLeaf && shouldDrawCaption(displayMode, rect, captions)) {
|
|
537
|
-
drawCaption(ctx, rect, options, item, element);
|
|
538
|
-
}
|
|
503
|
+
drawTextBlock(ctx, rect, block);
|
|
539
504
|
ctx.restore();
|
|
540
505
|
}
|
|
506
|
+
function drawTextBlock(ctx, rect, block) {
|
|
507
|
+
const { align, colors, fonts, lines, padding, top } = block;
|
|
508
|
+
const x = calculateX(rect, align, padding);
|
|
509
|
+
ctx.textAlign = align;
|
|
510
|
+
ctx.textBaseline = 'middle';
|
|
511
|
+
let offset = 0;
|
|
512
|
+
lines.forEach((line, i)=>{
|
|
513
|
+
const font = fonts[Math.min(i, fonts.length - 1)];
|
|
514
|
+
ctx.font = font.string;
|
|
515
|
+
ctx.fillStyle = colors[Math.min(i, colors.length - 1)];
|
|
516
|
+
ctx.fillText(line, x, top + offset + font.lineHeight / 2);
|
|
517
|
+
offset += font.lineHeight;
|
|
518
|
+
});
|
|
519
|
+
}
|
|
541
520
|
function callbackContext(element, item) {
|
|
542
521
|
const context = element.$context || {
|
|
543
522
|
active: !!element.active,
|
|
@@ -554,16 +533,12 @@ function resolveOption(option, context) {
|
|
|
554
533
|
function resolveCaptionText(captions, element, item) {
|
|
555
534
|
return resolveOption(captions.formatter, callbackContext(element, item)) || item.g || '';
|
|
556
535
|
}
|
|
557
|
-
function
|
|
558
|
-
const {
|
|
536
|
+
function captionBlock(ctx, rect, options, item, element, layout) {
|
|
537
|
+
const { displayMode, rtl, spacing } = layout;
|
|
538
|
+
const { captions } = options;
|
|
559
539
|
const { color, hoverColor, font, hoverFont, padding, align } = captions;
|
|
560
|
-
const oColor = (rect.active ? hoverColor : color) || color;
|
|
561
|
-
const oAlign = align || (rtl ? 'right' : 'left');
|
|
562
540
|
const optFont = (rect.active ? hoverFont : font) || font;
|
|
563
541
|
const oFont = toFont(optFont);
|
|
564
|
-
const fonts = [
|
|
565
|
-
oFont
|
|
566
|
-
];
|
|
567
542
|
if (oFont.lineHeight > rect.h) {
|
|
568
543
|
return;
|
|
569
544
|
}
|
|
@@ -571,20 +546,62 @@ function drawCaption(ctx, rect, options, item, element) {
|
|
|
571
546
|
if (!text) {
|
|
572
547
|
return;
|
|
573
548
|
}
|
|
574
|
-
const
|
|
549
|
+
const fonts = [
|
|
550
|
+
oFont
|
|
551
|
+
];
|
|
552
|
+
if (measureLabelSize(ctx, [
|
|
575
553
|
text
|
|
576
|
-
], fonts)
|
|
577
|
-
if (captionSize.width + 2 * padding > rect.w) {
|
|
554
|
+
], fonts).width + 2 * padding > rect.w) {
|
|
578
555
|
text = sliceTextToFitWidth(ctx, text, rect.w - 2 * padding, fonts);
|
|
579
556
|
}
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
557
|
+
const top = displayMode === 'headerBoxes' ? rect.y + (rect.h - oFont.lineHeight) / 2 : rect.y + padding + spacing;
|
|
558
|
+
return {
|
|
559
|
+
align: align || (rtl ? 'right' : 'left'),
|
|
560
|
+
colors: [
|
|
561
|
+
(rect.active ? hoverColor : color) || color
|
|
562
|
+
],
|
|
563
|
+
fonts,
|
|
564
|
+
lines: [
|
|
565
|
+
text
|
|
566
|
+
],
|
|
567
|
+
padding,
|
|
568
|
+
top
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function labelBlock(ctx, rect, options, item, element) {
|
|
572
|
+
const labels = options.labels;
|
|
573
|
+
const content = resolveOption(labels.formatter, callbackContext(element, item));
|
|
574
|
+
if (!content) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const lines = isArray(content) ? content : [
|
|
578
|
+
content
|
|
579
|
+
];
|
|
580
|
+
let fonts = getFontFromOptions(rect, labels);
|
|
581
|
+
let labelSize = measureLabelSize(ctx, lines, fonts);
|
|
582
|
+
const lblToDraw = labelToDraw(rect, labels, labelSize);
|
|
583
|
+
if (!lblToDraw) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
if (isNumber(lblToDraw)) {
|
|
587
|
+
labelSize = {
|
|
588
|
+
height: labelSize.height * lblToDraw,
|
|
589
|
+
width: labelSize.width * lblToDraw
|
|
590
|
+
};
|
|
591
|
+
fonts = toFonts(fonts, lblToDraw);
|
|
592
|
+
}
|
|
593
|
+
const { color, hoverColor, align, padding } = labels;
|
|
594
|
+
const optColor = (rect.active ? hoverColor : color) || color;
|
|
595
|
+
return {
|
|
596
|
+
align,
|
|
597
|
+
colors: isArray(optColor) ? optColor : [
|
|
598
|
+
optColor
|
|
599
|
+
],
|
|
600
|
+
fonts,
|
|
601
|
+
lines,
|
|
602
|
+
padding,
|
|
603
|
+
top: calculateBlockTop(rect, labels, labelSize)
|
|
604
|
+
};
|
|
588
605
|
}
|
|
589
606
|
function sliceTextToFitWidth(ctx, text, width, fonts) {
|
|
590
607
|
const ellipsis = '...';
|
|
@@ -649,7 +666,7 @@ function toFonts(fonts, fitRatio) {
|
|
|
649
666
|
});
|
|
650
667
|
});
|
|
651
668
|
}
|
|
652
|
-
function labelToDraw(
|
|
669
|
+
function labelToDraw(rect, options, labelSize) {
|
|
653
670
|
const { overflow, padding } = options;
|
|
654
671
|
const { width, height } = labelSize;
|
|
655
672
|
if (overflow === 'hidden') {
|
|
@@ -669,62 +686,15 @@ function getFontFromOptions(rect, labels) {
|
|
|
669
686
|
toFont(optFont)
|
|
670
687
|
];
|
|
671
688
|
}
|
|
672
|
-
function
|
|
673
|
-
const
|
|
674
|
-
const content = resolveOption(labels.formatter, callbackContext(element, item));
|
|
675
|
-
if (!content) {
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
const contents = isArray(content) ? content : [
|
|
679
|
-
content
|
|
680
|
-
];
|
|
681
|
-
let fonts = getFontFromOptions(rect, labels);
|
|
682
|
-
let labelSize = measureLabelSize(ctx, contents, fonts);
|
|
683
|
-
const lblToDraw = labelToDraw(ctx, rect, labels, labelSize);
|
|
684
|
-
if (!lblToDraw) {
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
if (isNumber(lblToDraw)) {
|
|
688
|
-
labelSize = {
|
|
689
|
-
height: labelSize.height * lblToDraw,
|
|
690
|
-
width: labelSize.width * lblToDraw
|
|
691
|
-
};
|
|
692
|
-
fonts = toFonts(fonts, lblToDraw);
|
|
693
|
-
}
|
|
694
|
-
const { color, hoverColor, align } = labels;
|
|
695
|
-
const optColor = (rect.active ? hoverColor : color) || color;
|
|
696
|
-
const colors = isArray(optColor) ? optColor : [
|
|
697
|
-
optColor
|
|
698
|
-
];
|
|
699
|
-
const xyPoint = calculateXYLabel(rect, labels, labelSize);
|
|
700
|
-
ctx.textAlign = align;
|
|
701
|
-
ctx.textBaseline = 'middle';
|
|
702
|
-
let lhs = 0;
|
|
703
|
-
contents.forEach((l, i)=>{
|
|
704
|
-
const c = colors[Math.min(i, colors.length - 1)];
|
|
705
|
-
const f = fonts[Math.min(i, fonts.length - 1)];
|
|
706
|
-
const lh = f.lineHeight;
|
|
707
|
-
ctx.font = f.string;
|
|
708
|
-
ctx.fillStyle = c;
|
|
709
|
-
ctx.fillText(l, xyPoint.x, xyPoint.y + lh / 2 + lhs);
|
|
710
|
-
lhs += lh;
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
function calculateXYLabel(rect, options, labelSize) {
|
|
714
|
-
const { align, position, padding } = options;
|
|
715
|
-
const x = calculateX(rect, align, padding);
|
|
716
|
-
let y;
|
|
689
|
+
function calculateBlockTop(rect, options, labelSize) {
|
|
690
|
+
const { position, padding } = options;
|
|
717
691
|
if (position === 'top') {
|
|
718
|
-
|
|
719
|
-
} else if (position === 'bottom') {
|
|
720
|
-
y = rect.y + rect.h - padding - labelSize.height;
|
|
721
|
-
} else {
|
|
722
|
-
y = rect.y + (rect.h - labelSize.height) / 2 + padding;
|
|
692
|
+
return rect.y + padding;
|
|
723
693
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
694
|
+
if (position === 'bottom') {
|
|
695
|
+
return rect.y + rect.h - padding - labelSize.height;
|
|
696
|
+
}
|
|
697
|
+
return rect.y + (rect.h - labelSize.height) / 2 + padding;
|
|
728
698
|
}
|
|
729
699
|
function calculateX(rect, align, padding) {
|
|
730
700
|
if (align === 'left') {
|
|
@@ -735,76 +705,109 @@ function calculateX(rect, align, padding) {
|
|
|
735
705
|
return rect.x + rect.w / 2;
|
|
736
706
|
}
|
|
737
707
|
|
|
738
|
-
function
|
|
739
|
-
const
|
|
740
|
-
if (isObject(tree)) {
|
|
741
|
-
tree = normalizeTreeToArray(keys, treeLeafKey, tree);
|
|
742
|
-
}
|
|
743
|
-
const groups = dataset.groups || [];
|
|
708
|
+
function buildHierarchy(values, gidx, keys, layout, parentGroupValue) {
|
|
709
|
+
const { groups, leafKey, unsorted } = layout;
|
|
744
710
|
const glen = groups.length;
|
|
745
|
-
const
|
|
746
|
-
const
|
|
711
|
+
const g = getGroupKey(groups[gidx]);
|
|
712
|
+
const gdata = group(values, g, keys, leafKey, undefined, parentGroupValue, groups.filter((_item, index)=>index <= gidx), groups, gidx);
|
|
713
|
+
const nodes = toNodes(gdata, keys, g, gidx);
|
|
714
|
+
if (!unsorted) {
|
|
715
|
+
sortNodes(nodes);
|
|
716
|
+
}
|
|
717
|
+
for (const node of nodes){
|
|
718
|
+
const record = node._data;
|
|
719
|
+
const nextGroupIndex = record.groupIndex + 1;
|
|
720
|
+
const children = gidx < glen - 1 && nextGroupIndex < glen ? buildHierarchy(record.children, nextGroupIndex, keys, layout, node.g) : [];
|
|
721
|
+
Object.defineProperty(node, '_children', {
|
|
722
|
+
configurable: true,
|
|
723
|
+
value: children,
|
|
724
|
+
writable: true
|
|
725
|
+
});
|
|
726
|
+
node.isLeaf = !children.length;
|
|
727
|
+
}
|
|
728
|
+
return nodes;
|
|
729
|
+
}
|
|
730
|
+
function flattenNodes(nodes) {
|
|
731
|
+
const flat = nodes.slice();
|
|
732
|
+
for (const node of nodes){
|
|
733
|
+
if (node._children?.length) {
|
|
734
|
+
flat.push(...flattenNodes(node._children));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return flat;
|
|
738
|
+
}
|
|
739
|
+
function layoutLevel(nodes, rect, layout, parentSum) {
|
|
740
|
+
if (parentSum !== undefined) {
|
|
741
|
+
for (const node of nodes){
|
|
742
|
+
node.gs = parentSum;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
packInto(nodes, rect);
|
|
746
|
+
for (const node of nodes){
|
|
747
|
+
if (node._children?.length) {
|
|
748
|
+
layoutLevel(node._children, getSubRect(node, rect, layout), layout, node.s);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function layoutNodes(nodes, rect, layout) {
|
|
753
|
+
layoutLevel(nodes, rect, layout);
|
|
754
|
+
applyHeaderBoxes(flattenNodes(nodes), layout);
|
|
755
|
+
}
|
|
756
|
+
function getSubRect(sq, rect, layout) {
|
|
757
|
+
const { borderWidth, captions, displayMode } = layout;
|
|
758
|
+
const sp = displayMode === 'headerBoxes' ? 0 : layout.spacing;
|
|
759
|
+
const bw = displayMode === 'headerBoxes' ? {
|
|
760
|
+
b: 0,
|
|
761
|
+
l: 0,
|
|
762
|
+
r: 0,
|
|
763
|
+
t: 0
|
|
764
|
+
} : parseBorderWidth(borderWidth, sq.w / 2, sq.h / 2);
|
|
765
|
+
const subRect = {
|
|
766
|
+
...rect,
|
|
767
|
+
h: sq.h - 2 * sp - bw.t - bw.b,
|
|
768
|
+
w: sq.w - 2 * sp - bw.l - bw.r,
|
|
769
|
+
x: sq.x + sp + bw.l,
|
|
770
|
+
y: sq.y + sp + bw.t
|
|
771
|
+
};
|
|
772
|
+
if (shouldDrawCaption(displayMode, subRect, captions)) {
|
|
773
|
+
const captionHeight = getCaptionHeight(displayMode, subRect, toFont(captions.font), valueOrDefault(captions.padding, 3));
|
|
774
|
+
subRect.y += captionHeight;
|
|
775
|
+
subRect.h -= captionHeight;
|
|
776
|
+
}
|
|
777
|
+
return subRect;
|
|
778
|
+
}
|
|
779
|
+
function buildNodes(tree, keys, layout) {
|
|
780
|
+
const { groups, leafKey, unsorted } = layout;
|
|
781
|
+
const input = isObject(tree) ? normalizeTreeToArray(keys, leafKey, tree) : tree;
|
|
782
|
+
if (groups.length) {
|
|
783
|
+
return buildHierarchy(input, 0, keys, layout);
|
|
784
|
+
}
|
|
785
|
+
const nodes = toNodes(input || [], keys);
|
|
786
|
+
if (!unsorted) {
|
|
787
|
+
sortNodes(nodes);
|
|
788
|
+
}
|
|
789
|
+
return nodes;
|
|
790
|
+
}
|
|
791
|
+
function applyHeaderBoxes(nodes, layout) {
|
|
792
|
+
const { captions, displayMode } = layout;
|
|
793
|
+
if (displayMode !== 'headerBoxes') {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
747
796
|
const font = toFont(captions.font);
|
|
748
797
|
const padding = valueOrDefault(captions.padding, 3);
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
l: 0,
|
|
753
|
-
r: 0,
|
|
754
|
-
t: 0
|
|
755
|
-
} : parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2);
|
|
756
|
-
const subRect = {
|
|
757
|
-
...rect,
|
|
758
|
-
h: sq.h - 2 * sp - bw.t - bw.b,
|
|
759
|
-
w: sq.w - 2 * sp - bw.l - bw.r,
|
|
760
|
-
x: sq.x + sp + bw.l,
|
|
761
|
-
y: sq.y + sp + bw.t
|
|
762
|
-
};
|
|
763
|
-
if (shouldDrawCaption(dataset.displayMode, subRect, captions)) {
|
|
764
|
-
const captionHeight = getCaptionHeight(dataset.displayMode, subRect, font, padding);
|
|
765
|
-
subRect.y += captionHeight;
|
|
766
|
-
subRect.h -= captionHeight;
|
|
798
|
+
for (const node of nodes){
|
|
799
|
+
if (node.isLeaf) {
|
|
800
|
+
continue;
|
|
767
801
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const g = getGroupKey(groups[gidx]);
|
|
772
|
-
const gdata = group(treeElements, g, keys, treeLeafKey, undefined, parent, groups.filter((_item, index)=>index <= gidx), groups, gidx);
|
|
773
|
-
const gsq = squarify(gdata, rect, keys, g, gidx, gs);
|
|
774
|
-
const ret = gsq.slice();
|
|
775
|
-
if (gidx < glen - 1) {
|
|
776
|
-
gsq.forEach((sq)=>{
|
|
777
|
-
const subRect = getSubRect(sq, rect);
|
|
778
|
-
const children = [];
|
|
779
|
-
const nextGroupIndex = sq._data.groupIndex + 1;
|
|
780
|
-
if (nextGroupIndex < glen) {
|
|
781
|
-
children.push(...recur(sq._data.children, nextGroupIndex, subRect, sq.g, sq.s));
|
|
782
|
-
}
|
|
783
|
-
ret.push(...children);
|
|
784
|
-
sq.isLeaf = !children.length;
|
|
785
|
-
});
|
|
802
|
+
if (shouldDrawCaption(displayMode, node, captions)) {
|
|
803
|
+
node.h = getCaptionHeight(displayMode, node, font, padding);
|
|
804
|
+
node.hidden = false;
|
|
786
805
|
} else {
|
|
787
|
-
|
|
788
|
-
sq.isLeaf = true;
|
|
789
|
-
});
|
|
806
|
+
node.hidden = true;
|
|
790
807
|
}
|
|
791
|
-
return ret;
|
|
792
808
|
}
|
|
793
|
-
const result = glen ? recur(tree, 0, mainRect) : squarify(tree, mainRect, keys);
|
|
794
|
-
return result.map((d)=>{
|
|
795
|
-
if (dataset.displayMode !== 'headerBoxes' || d.isLeaf) {
|
|
796
|
-
return d;
|
|
797
|
-
}
|
|
798
|
-
if (!shouldDrawCaption(dataset.displayMode, d, captions)) {
|
|
799
|
-
return undefined;
|
|
800
|
-
}
|
|
801
|
-
const captionHeight = getCaptionHeight(dataset.displayMode, d, font, padding);
|
|
802
|
-
return {
|
|
803
|
-
...d,
|
|
804
|
-
h: captionHeight
|
|
805
|
-
};
|
|
806
|
-
}).filter(Boolean);
|
|
807
809
|
}
|
|
810
|
+
|
|
808
811
|
function registerTooltipPositioner() {
|
|
809
812
|
const tooltipPlugin = registry.plugins.get('tooltip');
|
|
810
813
|
if (!tooltipPlugin || tooltipPlugin.positioners.treemap) {
|
|
@@ -857,42 +860,101 @@ class TreemapController extends DatasetController {
|
|
|
857
860
|
yScale.configure();
|
|
858
861
|
}
|
|
859
862
|
}
|
|
860
|
-
|
|
863
|
+
_layoutOptions() {
|
|
861
864
|
const dataset = this.getDataset();
|
|
862
|
-
const
|
|
863
|
-
|
|
865
|
+
const options = this.options;
|
|
866
|
+
return {
|
|
867
|
+
borderWidth: dataset.borderWidth,
|
|
868
|
+
captions: dataset.captions || {},
|
|
869
|
+
displayMode: options.displayMode,
|
|
870
|
+
groups: options.groups || [],
|
|
871
|
+
leafKey: options.leafKey,
|
|
872
|
+
spacing: valueOrDefault(dataset.spacing, 0),
|
|
873
|
+
unsorted: !!options.unsorted
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
buildOrUpdateElements(_resetNewElements) {
|
|
877
|
+
this.parse(0, 0);
|
|
878
|
+
const meta = this.getMeta();
|
|
879
|
+
const count = meta._parsed.length;
|
|
880
|
+
const elements = meta.data;
|
|
881
|
+
if (elements.length > count) {
|
|
882
|
+
elements.splice(count, elements.length - count);
|
|
883
|
+
}
|
|
884
|
+
while(elements.length < count){
|
|
885
|
+
elements.push(new this.dataElementType());
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
parse(_start, _count) {
|
|
889
|
+
const dataset = this.getDataset();
|
|
890
|
+
if (dataset.tree !== undefined) {
|
|
891
|
+
throw new Error('chartjs-chart-treemap v5: the "tree" option was renamed to "data". ' + 'See https://chartjs-chart-treemap.pages.dev/usage/');
|
|
892
|
+
}
|
|
893
|
+
const options = this.options;
|
|
864
894
|
const keys = [
|
|
865
|
-
|
|
866
|
-
].concat(
|
|
867
|
-
|
|
868
|
-
const
|
|
869
|
-
const
|
|
895
|
+
options.key || ''
|
|
896
|
+
].concat(options.sumKeys || []);
|
|
897
|
+
const nodes = buildNodes(dataset.data || [], keys, this._layoutOptions());
|
|
898
|
+
const flat = flattenNodes(nodes);
|
|
899
|
+
const fingerprint = flat.map((node)=>`${node.v}\u0000${node.g}\u0000${node.l}`).join('\u0001');
|
|
900
|
+
if (this._fingerprint === fingerprint) {
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
this._fingerprint = fingerprint;
|
|
904
|
+
this._nodes = nodes;
|
|
905
|
+
this.getMeta()._parsed = flat;
|
|
906
|
+
this._layoutDirty = true;
|
|
907
|
+
}
|
|
908
|
+
getContext(index, active, mode) {
|
|
909
|
+
const base = DatasetController.prototype.getContext;
|
|
910
|
+
const context = base.call(this, index, active, mode);
|
|
911
|
+
const parsed = typeof index === 'number' ? this.getParsed(index) : undefined;
|
|
912
|
+
if (parsed) {
|
|
913
|
+
context.raw = parsed;
|
|
914
|
+
context.parsed = parsed;
|
|
915
|
+
}
|
|
916
|
+
return context;
|
|
917
|
+
}
|
|
918
|
+
getLabelAndValue(index) {
|
|
919
|
+
const node = this.getParsed(index);
|
|
920
|
+
if (!node) {
|
|
921
|
+
return {
|
|
922
|
+
label: '',
|
|
923
|
+
value: ''
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
const dataset = this.getDataset();
|
|
927
|
+
const label = node.g ?? node._data?.label ?? dataset.label;
|
|
928
|
+
return {
|
|
929
|
+
label: label === undefined ? '' : `${label}`,
|
|
930
|
+
value: `${node.v}`
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
update(mode) {
|
|
934
|
+
const { data } = this.getMeta();
|
|
870
935
|
if (mode === 'reset') {
|
|
871
936
|
this.configure();
|
|
872
937
|
}
|
|
873
|
-
if (this.
|
|
874
|
-
this.
|
|
875
|
-
this.
|
|
876
|
-
this._prevTree = tree;
|
|
877
|
-
this._prevTreeVersion = treeVersion;
|
|
938
|
+
if (this._layoutDirty || this._rectChanged) {
|
|
939
|
+
layoutNodes(this._nodes, this._rect, this._layoutOptions());
|
|
940
|
+
this._layoutDirty = false;
|
|
878
941
|
this._rectChanged = false;
|
|
879
|
-
dataset.data = buildData(tree, dataset, this._keys, this._rect);
|
|
880
|
-
this._dataCheck();
|
|
881
|
-
this._resyncElements();
|
|
882
942
|
}
|
|
883
943
|
this.updateElements(data, 0, data.length, mode);
|
|
884
944
|
}
|
|
885
945
|
updateElements(rects, start, count, mode) {
|
|
886
946
|
const reset = mode === 'reset';
|
|
887
|
-
const dataset = this.getDataset();
|
|
888
947
|
const firstOpts = this.resolveDataElementOptions(start, mode);
|
|
889
948
|
this._rect.options = firstOpts;
|
|
890
949
|
const sharedOptions = this.getSharedOptions(firstOpts);
|
|
891
950
|
const includeOptions = this.includeOptions(mode, sharedOptions || {});
|
|
892
951
|
const { xScale, yScale } = this.getMeta();
|
|
952
|
+
const spacing = this.options.spacing;
|
|
893
953
|
for(let i = start; i < start + count; i++){
|
|
894
954
|
const options = sharedOptions || this.resolveDataElementOptions(i, mode);
|
|
895
|
-
const
|
|
955
|
+
const node = this.getParsed(i);
|
|
956
|
+
const properties = scaleRect(node, xScale, yScale, spacing);
|
|
957
|
+
properties.hidden = properties.hidden || !!node.hidden;
|
|
896
958
|
if (reset) {
|
|
897
959
|
properties.width = 0;
|
|
898
960
|
properties.height = 0;
|
|
@@ -907,23 +969,28 @@ class TreemapController extends DatasetController {
|
|
|
907
969
|
draw() {
|
|
908
970
|
const { ctx, chartArea } = this.chart;
|
|
909
971
|
const metadata = this.getMeta().data || [];
|
|
910
|
-
const
|
|
911
|
-
const
|
|
972
|
+
const { displayMode, rtl, spacing } = this.options;
|
|
973
|
+
const layout = {
|
|
974
|
+
displayMode,
|
|
975
|
+
rtl,
|
|
976
|
+
spacing
|
|
977
|
+
};
|
|
912
978
|
clipArea(ctx, chartArea);
|
|
913
979
|
for(let i = 0, ilen = metadata.length; i < ilen; ++i){
|
|
914
980
|
const rect = metadata[i];
|
|
915
981
|
if (!rect.hidden) {
|
|
916
|
-
rect.draw(ctx,
|
|
982
|
+
rect.draw(ctx, this.getParsed(i), layout);
|
|
917
983
|
}
|
|
918
984
|
}
|
|
919
985
|
unclipArea(ctx);
|
|
920
986
|
}
|
|
921
987
|
constructor(chart, datasetIndex){
|
|
922
988
|
super(chart, datasetIndex);
|
|
923
|
-
this._groups = undefined;
|
|
924
|
-
this._keys = undefined;
|
|
925
989
|
this._rect = undefined;
|
|
926
990
|
this._rectChanged = true;
|
|
991
|
+
this._nodes = [];
|
|
992
|
+
this._layoutDirty = true;
|
|
993
|
+
this._fingerprint = undefined;
|
|
927
994
|
}
|
|
928
995
|
}
|
|
929
996
|
TreemapController.id = 'treemap';
|
|
@@ -940,7 +1007,15 @@ TreemapController.defaults = {
|
|
|
940
1007
|
type: 'number'
|
|
941
1008
|
}
|
|
942
1009
|
},
|
|
943
|
-
dataElementType: 'treemap'
|
|
1010
|
+
dataElementType: 'treemap',
|
|
1011
|
+
displayMode: layoutDefaults.displayMode,
|
|
1012
|
+
groups: [],
|
|
1013
|
+
key: '',
|
|
1014
|
+
leafKey: '_leaf',
|
|
1015
|
+
rtl: layoutDefaults.rtl,
|
|
1016
|
+
spacing: layoutDefaults.spacing,
|
|
1017
|
+
sumKeys: [],
|
|
1018
|
+
unsorted: false
|
|
944
1019
|
};
|
|
945
1020
|
TreemapController.descriptors = {
|
|
946
1021
|
_indexable: false,
|
|
@@ -965,10 +1040,9 @@ TreemapController.overrides = {
|
|
|
965
1040
|
tooltip: {
|
|
966
1041
|
callbacks: {
|
|
967
1042
|
label (item) {
|
|
968
|
-
const
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
return (label ? `${label}: ` : '') + dataItem.v;
|
|
1043
|
+
const node = item.parsed;
|
|
1044
|
+
const label = node.g || node._data?.label || item.dataset.label;
|
|
1045
|
+
return (label ? `${label}: ` : '') + node.v;
|
|
972
1046
|
},
|
|
973
1047
|
title (items) {
|
|
974
1048
|
if (items.length) {
|
|
@@ -1070,7 +1144,7 @@ function addNormalRectPath(ctx, rect) {
|
|
|
1070
1144
|
}
|
|
1071
1145
|
|
|
1072
1146
|
class TreemapElement extends Element {
|
|
1073
|
-
draw(ctx, data) {
|
|
1147
|
+
draw(ctx, data, layout = layoutDefaults) {
|
|
1074
1148
|
if (!data) {
|
|
1075
1149
|
return;
|
|
1076
1150
|
}
|
|
@@ -1090,7 +1164,7 @@ class TreemapElement extends Element {
|
|
|
1090
1164
|
addRectPath(ctx, inner);
|
|
1091
1165
|
ctx.fillStyle = options.backgroundColor;
|
|
1092
1166
|
ctx.fill();
|
|
1093
|
-
drawText(ctx, inner, options, data, this);
|
|
1167
|
+
drawText(ctx, inner, options, data, this, layout);
|
|
1094
1168
|
ctx.restore();
|
|
1095
1169
|
}
|
|
1096
1170
|
inRange(mouseX, mouseY, useFinalPosition) {
|
|
@@ -1141,8 +1215,6 @@ TreemapElement.defaults = {
|
|
|
1141
1215
|
},
|
|
1142
1216
|
padding: 3
|
|
1143
1217
|
},
|
|
1144
|
-
displayMode: 'containerBoxes',
|
|
1145
|
-
label: undefined,
|
|
1146
1218
|
labels: {
|
|
1147
1219
|
align: 'center',
|
|
1148
1220
|
color: 'black',
|
|
@@ -1164,10 +1236,7 @@ TreemapElement.defaults = {
|
|
|
1164
1236
|
overflow: 'cut',
|
|
1165
1237
|
padding: 3,
|
|
1166
1238
|
position: 'middle'
|
|
1167
|
-
}
|
|
1168
|
-
rtl: false,
|
|
1169
|
-
spacing: 0.5,
|
|
1170
|
-
unsorted: false
|
|
1239
|
+
}
|
|
1171
1240
|
};
|
|
1172
1241
|
TreemapElement.descriptors = {
|
|
1173
1242
|
_indexable: false,
|
|
@@ -1186,4 +1255,4 @@ TreemapElement.defaultRoutes = {
|
|
|
1186
1255
|
borderColor: 'borderColor'
|
|
1187
1256
|
};
|
|
1188
1257
|
|
|
1189
|
-
export { TreemapController, TreemapElement };
|
|
1258
|
+
export { TreemapController, TreemapElement, flattenTree };
|