chartjs-chart-treemap 5.0.0-next.3 → 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 +217 -168
- package/dist/chartjs-chart-treemap.esm.js +221 -190
- package/dist/chartjs-chart-treemap.min.js +2 -2
- package/dist/chartjs-chart-treemap.min.js.map +1 -1
- package/dist/controller.d.ts +19 -13
- package/dist/index.esm.d.ts +1 -0
- package/dist/layout.d.ts +27 -0
- package/dist/rect.d.ts +1 -1
- package/dist/squarify.d.ts +15 -0
- package/dist/types.d.ts +9 -5
- package/dist/utils.d.ts +9 -0
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
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
|
|
@@ -10,7 +10,7 @@ typeof define === 'function' && define.amd ? define(['exports', 'chart.js', 'cha
|
|
|
10
10
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["chartjs-chart-treemap"] = {}, global.Chart, global.Chart.helpers));
|
|
11
11
|
})(this, (function (exports, chart_js, helpers) { 'use strict';
|
|
12
12
|
|
|
13
|
-
var version = "5.0.0-next.
|
|
13
|
+
var version = "5.0.0-next.4";
|
|
14
14
|
|
|
15
15
|
function scaleRect(sq, xScale, yScale, sp) {
|
|
16
16
|
const sp2 = sp * 2;
|
|
@@ -29,25 +29,6 @@ function scaleRect(sq, xScale, yScale, sp) {
|
|
|
29
29
|
function rectNotEqual(r1, r2) {
|
|
30
30
|
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;
|
|
31
31
|
}
|
|
32
|
-
function arrayNotEqual(a, b) {
|
|
33
|
-
let i;
|
|
34
|
-
let n;
|
|
35
|
-
if (!a || !b) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
if (a === b) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
if (a.length !== b.length) {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
for(i = 0, n = a.length; i < n; ++i){
|
|
45
|
-
if (a[i] !== b[i]) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
32
|
|
|
52
33
|
const layoutDefaults = {
|
|
53
34
|
displayMode: 'containerBoxes',
|
|
@@ -92,24 +73,14 @@ function getDims(itm, w2, s2, key) {
|
|
|
92
73
|
};
|
|
93
74
|
}
|
|
94
75
|
const getX = (rect, w)=>rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
95
|
-
function
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
w: dims.w,
|
|
104
|
-
x: getX(rect, dims.w),
|
|
105
|
-
y: rect.y + rect._iy
|
|
106
|
-
};
|
|
107
|
-
if (itm.group) {
|
|
108
|
-
r.g = itm.group;
|
|
109
|
-
r.l = itm.level;
|
|
110
|
-
r.gs = itm.groupSum;
|
|
111
|
-
}
|
|
112
|
-
return r;
|
|
76
|
+
function assignRow(rect, itm, dims, sum) {
|
|
77
|
+
itm.a = itm._normalized;
|
|
78
|
+
itm.h = dims.h;
|
|
79
|
+
itm.s = sum;
|
|
80
|
+
itm.w = dims.w;
|
|
81
|
+
itm.x = getX(rect, dims.w);
|
|
82
|
+
itm.y = rect.y + rect._iy;
|
|
83
|
+
delete itm._normalized;
|
|
113
84
|
}
|
|
114
85
|
class Rect {
|
|
115
86
|
get area() {
|
|
@@ -135,19 +106,17 @@ class Rect {
|
|
|
135
106
|
const row = arr.get();
|
|
136
107
|
const w2 = side * side;
|
|
137
108
|
const s2 = sum * sum;
|
|
138
|
-
const ret = [];
|
|
139
109
|
let maxd2 = 0;
|
|
140
110
|
let totd1 = 0;
|
|
141
111
|
for (const itm of row){
|
|
142
112
|
const dims = getDims(itm, w2, s2, key);
|
|
143
113
|
totd1 += dims.d1;
|
|
144
114
|
maxd2 = Math.max(maxd2, dims.d2);
|
|
145
|
-
|
|
115
|
+
assignRow(this, itm, dims, arr.sum);
|
|
146
116
|
this[key] += dims.d1;
|
|
147
117
|
}
|
|
148
118
|
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
149
119
|
this[key] -= totd1;
|
|
150
|
-
return ret;
|
|
151
120
|
}
|
|
152
121
|
constructor(r){
|
|
153
122
|
r = r || {
|
|
@@ -267,6 +236,9 @@ function scanTreeObject(keys, leafKey, obj, tree = [], lvl = 0, result = []) {
|
|
|
267
236
|
}
|
|
268
237
|
tree.splice(objIndex, 1);
|
|
269
238
|
return result;
|
|
239
|
+
}
|
|
240
|
+
function flattenTree(tree, keys, leafKey) {
|
|
241
|
+
return normalizeTreeToArray(keys, leafKey, tree);
|
|
270
242
|
}
|
|
271
243
|
function normalizeTreeToArray(keys, leafKey, obj) {
|
|
272
244
|
const data = scanTreeObject(keys, leafKey, obj);
|
|
@@ -467,54 +439,51 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
467
439
|
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
|
|
468
440
|
return nr <= or;
|
|
469
441
|
}
|
|
470
|
-
function
|
|
471
|
-
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
let o;
|
|
479
|
-
if (!n) {
|
|
480
|
-
return rows;
|
|
481
|
-
}
|
|
482
|
-
const tmp = values.slice();
|
|
483
|
-
const key = index(tmp, keys[0]);
|
|
484
|
-
if (!rectangle?.unsorted) {
|
|
485
|
-
sort(tmp, key);
|
|
486
|
-
}
|
|
487
|
-
const val = (idx)=>key ? +tmp[idx][key] : +tmp[idx];
|
|
488
|
-
const gval = (idx)=>grp && tmp[idx][grp];
|
|
489
|
-
for(i = 0; i < n; ++i){
|
|
490
|
-
o = {
|
|
491
|
-
_data: values[tmp[i]._idx],
|
|
492
|
-
group: undefined,
|
|
493
|
-
groupSum: gsum,
|
|
494
|
-
level: undefined,
|
|
495
|
-
value: val(i)
|
|
442
|
+
function toNodes(values, keys, grp, lvl) {
|
|
443
|
+
const items = values ? values.slice() : [];
|
|
444
|
+
const key = index(items, keys[0]);
|
|
445
|
+
return items.map((item)=>{
|
|
446
|
+
const node = {
|
|
447
|
+
_data: values[item._idx],
|
|
448
|
+
v: key ? +item[key] : +item,
|
|
449
|
+
vs: undefined
|
|
496
450
|
};
|
|
497
451
|
if (grp) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
obj[k] = +
|
|
452
|
+
node.g = item[grp];
|
|
453
|
+
node.gs = undefined;
|
|
454
|
+
node.l = item.groupIndex ?? lvl;
|
|
455
|
+
node.vs = keys.reduce((obj, k)=>{
|
|
456
|
+
obj[k] = +item[k];
|
|
503
457
|
return obj;
|
|
504
458
|
}, {});
|
|
505
459
|
}
|
|
506
|
-
|
|
460
|
+
return node;
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
function sortNodes(nodes) {
|
|
464
|
+
sort(nodes, 'v');
|
|
465
|
+
}
|
|
466
|
+
function packInto(nodes, rectangle) {
|
|
467
|
+
const n = nodes.length;
|
|
468
|
+
if (!n) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const rect = new Rect(rectangle);
|
|
472
|
+
const row = new StatArray('v', rect.area / sum(nodes, 'v'));
|
|
473
|
+
let length = rect.side;
|
|
474
|
+
let o;
|
|
475
|
+
for(let i = 0; i < n; ++i){
|
|
476
|
+
o = row.pushIf(nodes[i], compareAspectRatio, length);
|
|
507
477
|
if (o) {
|
|
508
|
-
|
|
478
|
+
rect.map(row);
|
|
509
479
|
length = rect.side;
|
|
510
480
|
row.reset();
|
|
511
481
|
row.push(o);
|
|
512
482
|
}
|
|
513
483
|
}
|
|
514
484
|
if (row.length) {
|
|
515
|
-
|
|
485
|
+
rect.map(row);
|
|
516
486
|
}
|
|
517
|
-
return flatten(rows);
|
|
518
487
|
}
|
|
519
488
|
|
|
520
489
|
const widthCache = new Map();
|
|
@@ -541,10 +510,6 @@ function getCaptionHeight(displayMode, rect, font, padding) {
|
|
|
541
510
|
function drawText(ctx, rect, options, item, element, layout) {
|
|
542
511
|
const { captions, labels } = options;
|
|
543
512
|
const { displayMode } = layout;
|
|
544
|
-
ctx.save();
|
|
545
|
-
ctx.beginPath();
|
|
546
|
-
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
547
|
-
ctx.clip();
|
|
548
513
|
const isLeaf = item && (!helpers.defined(item.l) || item.isLeaf);
|
|
549
514
|
let block;
|
|
550
515
|
if (isLeaf) {
|
|
@@ -554,9 +519,14 @@ function drawText(ctx, rect, options, item, element, layout) {
|
|
|
554
519
|
} else if (shouldDrawCaption(displayMode, rect, captions)) {
|
|
555
520
|
block = captionBlock(ctx, rect, options, item, element, layout);
|
|
556
521
|
}
|
|
557
|
-
if (block) {
|
|
558
|
-
|
|
522
|
+
if (!block) {
|
|
523
|
+
return;
|
|
559
524
|
}
|
|
525
|
+
ctx.save();
|
|
526
|
+
ctx.beginPath();
|
|
527
|
+
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
528
|
+
ctx.clip();
|
|
529
|
+
drawTextBlock(ctx, rect, block);
|
|
560
530
|
ctx.restore();
|
|
561
531
|
}
|
|
562
532
|
function drawTextBlock(ctx, rect, block) {
|
|
@@ -761,74 +731,109 @@ function calculateX(rect, align, padding) {
|
|
|
761
731
|
return rect.x + rect.w / 2;
|
|
762
732
|
}
|
|
763
733
|
|
|
764
|
-
function
|
|
765
|
-
const {
|
|
766
|
-
if (helpers.isObject(tree)) {
|
|
767
|
-
tree = normalizeTreeToArray(keys, leafKey, tree);
|
|
768
|
-
}
|
|
734
|
+
function buildHierarchy(values, gidx, keys, layout, parentGroupValue) {
|
|
735
|
+
const { groups, leafKey, unsorted } = layout;
|
|
769
736
|
const glen = groups.length;
|
|
737
|
+
const g = getGroupKey(groups[gidx]);
|
|
738
|
+
const gdata = group(values, g, keys, leafKey, undefined, parentGroupValue, groups.filter((_item, index)=>index <= gidx), groups, gidx);
|
|
739
|
+
const nodes = toNodes(gdata, keys, g, gidx);
|
|
740
|
+
if (!unsorted) {
|
|
741
|
+
sortNodes(nodes);
|
|
742
|
+
}
|
|
743
|
+
for (const node of nodes){
|
|
744
|
+
const record = node._data;
|
|
745
|
+
const nextGroupIndex = record.groupIndex + 1;
|
|
746
|
+
const children = gidx < glen - 1 && nextGroupIndex < glen ? buildHierarchy(record.children, nextGroupIndex, keys, layout, node.g) : [];
|
|
747
|
+
Object.defineProperty(node, '_children', {
|
|
748
|
+
configurable: true,
|
|
749
|
+
value: children,
|
|
750
|
+
writable: true
|
|
751
|
+
});
|
|
752
|
+
node.isLeaf = !children.length;
|
|
753
|
+
}
|
|
754
|
+
return nodes;
|
|
755
|
+
}
|
|
756
|
+
function flattenNodes(nodes) {
|
|
757
|
+
const flat = nodes.slice();
|
|
758
|
+
for (const node of nodes){
|
|
759
|
+
if (node._children?.length) {
|
|
760
|
+
flat.push(...flattenNodes(node._children));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return flat;
|
|
764
|
+
}
|
|
765
|
+
function layoutLevel(nodes, rect, layout, parentSum) {
|
|
766
|
+
if (parentSum !== undefined) {
|
|
767
|
+
for (const node of nodes){
|
|
768
|
+
node.gs = parentSum;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
packInto(nodes, rect);
|
|
772
|
+
for (const node of nodes){
|
|
773
|
+
if (node._children?.length) {
|
|
774
|
+
layoutLevel(node._children, getSubRect(node, rect, layout), layout, node.s);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function layoutNodes(nodes, rect, layout) {
|
|
779
|
+
layoutLevel(nodes, rect, layout);
|
|
780
|
+
applyHeaderBoxes(flattenNodes(nodes), layout);
|
|
781
|
+
}
|
|
782
|
+
function getSubRect(sq, rect, layout) {
|
|
783
|
+
const { borderWidth, captions, displayMode } = layout;
|
|
770
784
|
const sp = displayMode === 'headerBoxes' ? 0 : layout.spacing;
|
|
785
|
+
const bw = displayMode === 'headerBoxes' ? {
|
|
786
|
+
b: 0,
|
|
787
|
+
l: 0,
|
|
788
|
+
r: 0,
|
|
789
|
+
t: 0
|
|
790
|
+
} : parseBorderWidth(borderWidth, sq.w / 2, sq.h / 2);
|
|
791
|
+
const subRect = {
|
|
792
|
+
...rect,
|
|
793
|
+
h: sq.h - 2 * sp - bw.t - bw.b,
|
|
794
|
+
w: sq.w - 2 * sp - bw.l - bw.r,
|
|
795
|
+
x: sq.x + sp + bw.l,
|
|
796
|
+
y: sq.y + sp + bw.t
|
|
797
|
+
};
|
|
798
|
+
if (shouldDrawCaption(displayMode, subRect, captions)) {
|
|
799
|
+
const captionHeight = getCaptionHeight(displayMode, subRect, helpers.toFont(captions.font), helpers.valueOrDefault(captions.padding, 3));
|
|
800
|
+
subRect.y += captionHeight;
|
|
801
|
+
subRect.h -= captionHeight;
|
|
802
|
+
}
|
|
803
|
+
return subRect;
|
|
804
|
+
}
|
|
805
|
+
function buildNodes(tree, keys, layout) {
|
|
806
|
+
const { groups, leafKey, unsorted } = layout;
|
|
807
|
+
const input = helpers.isObject(tree) ? normalizeTreeToArray(keys, leafKey, tree) : tree;
|
|
808
|
+
if (groups.length) {
|
|
809
|
+
return buildHierarchy(input, 0, keys, layout);
|
|
810
|
+
}
|
|
811
|
+
const nodes = toNodes(input || [], keys);
|
|
812
|
+
if (!unsorted) {
|
|
813
|
+
sortNodes(nodes);
|
|
814
|
+
}
|
|
815
|
+
return nodes;
|
|
816
|
+
}
|
|
817
|
+
function applyHeaderBoxes(nodes, layout) {
|
|
818
|
+
const { captions, displayMode } = layout;
|
|
819
|
+
if (displayMode !== 'headerBoxes') {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
771
822
|
const font = helpers.toFont(captions.font);
|
|
772
823
|
const padding = helpers.valueOrDefault(captions.padding, 3);
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
l: 0,
|
|
777
|
-
r: 0,
|
|
778
|
-
t: 0
|
|
779
|
-
} : parseBorderWidth(borderWidth, sq.w / 2, sq.h / 2);
|
|
780
|
-
const subRect = {
|
|
781
|
-
...rect,
|
|
782
|
-
h: sq.h - 2 * sp - bw.t - bw.b,
|
|
783
|
-
w: sq.w - 2 * sp - bw.l - bw.r,
|
|
784
|
-
x: sq.x + sp + bw.l,
|
|
785
|
-
y: sq.y + sp + bw.t
|
|
786
|
-
};
|
|
787
|
-
if (shouldDrawCaption(displayMode, subRect, captions)) {
|
|
788
|
-
const captionHeight = getCaptionHeight(displayMode, subRect, font, padding);
|
|
789
|
-
subRect.y += captionHeight;
|
|
790
|
-
subRect.h -= captionHeight;
|
|
824
|
+
for (const node of nodes){
|
|
825
|
+
if (node.isLeaf) {
|
|
826
|
+
continue;
|
|
791
827
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const g = getGroupKey(groups[gidx]);
|
|
796
|
-
const gdata = group(treeElements, g, keys, leafKey, undefined, parent, groups.filter((_item, index)=>index <= gidx), groups, gidx);
|
|
797
|
-
const gsq = squarify(gdata, rect, keys, g, gidx, gs);
|
|
798
|
-
const ret = gsq.slice();
|
|
799
|
-
if (gidx < glen - 1) {
|
|
800
|
-
gsq.forEach((sq)=>{
|
|
801
|
-
const subRect = getSubRect(sq, rect);
|
|
802
|
-
const children = [];
|
|
803
|
-
const nextGroupIndex = sq._data.groupIndex + 1;
|
|
804
|
-
if (nextGroupIndex < glen) {
|
|
805
|
-
children.push(...recur(sq._data.children, nextGroupIndex, subRect, sq.g, sq.s));
|
|
806
|
-
}
|
|
807
|
-
ret.push(...children);
|
|
808
|
-
sq.isLeaf = !children.length;
|
|
809
|
-
});
|
|
828
|
+
if (shouldDrawCaption(displayMode, node, captions)) {
|
|
829
|
+
node.h = getCaptionHeight(displayMode, node, font, padding);
|
|
830
|
+
node.hidden = false;
|
|
810
831
|
} else {
|
|
811
|
-
|
|
812
|
-
sq.isLeaf = true;
|
|
813
|
-
});
|
|
832
|
+
node.hidden = true;
|
|
814
833
|
}
|
|
815
|
-
return ret;
|
|
816
834
|
}
|
|
817
|
-
const result = glen ? recur(tree, 0, mainRect) : squarify(tree, mainRect, keys);
|
|
818
|
-
return result.map((d)=>{
|
|
819
|
-
if (displayMode !== 'headerBoxes' || d.isLeaf) {
|
|
820
|
-
return d;
|
|
821
|
-
}
|
|
822
|
-
if (!shouldDrawCaption(displayMode, d, captions)) {
|
|
823
|
-
return undefined;
|
|
824
|
-
}
|
|
825
|
-
const captionHeight = getCaptionHeight(displayMode, d, font, padding);
|
|
826
|
-
return {
|
|
827
|
-
...d,
|
|
828
|
-
h: captionHeight
|
|
829
|
-
};
|
|
830
|
-
}).filter(Boolean);
|
|
831
835
|
}
|
|
836
|
+
|
|
832
837
|
function registerTooltipPositioner() {
|
|
833
838
|
const tooltipPlugin = chart_js.registry.plugins.get('tooltip');
|
|
834
839
|
if (!tooltipPlugin || tooltipPlugin.positioners.treemap) {
|
|
@@ -890,38 +895,81 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
890
895
|
displayMode: options.displayMode,
|
|
891
896
|
groups: options.groups || [],
|
|
892
897
|
leafKey: options.leafKey,
|
|
893
|
-
spacing: helpers.valueOrDefault(dataset.spacing, 0)
|
|
898
|
+
spacing: helpers.valueOrDefault(dataset.spacing, 0),
|
|
899
|
+
unsorted: !!options.unsorted
|
|
894
900
|
};
|
|
895
901
|
}
|
|
896
|
-
|
|
902
|
+
buildOrUpdateElements(_resetNewElements) {
|
|
903
|
+
this.parse(0, 0);
|
|
904
|
+
const meta = this.getMeta();
|
|
905
|
+
const count = meta._parsed.length;
|
|
906
|
+
const elements = meta.data;
|
|
907
|
+
if (elements.length > count) {
|
|
908
|
+
elements.splice(count, elements.length - count);
|
|
909
|
+
}
|
|
910
|
+
while(elements.length < count){
|
|
911
|
+
elements.push(new this.dataElementType());
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
parse(_start, _count) {
|
|
897
915
|
const dataset = this.getDataset();
|
|
898
|
-
|
|
916
|
+
if (dataset.tree !== undefined) {
|
|
917
|
+
throw new Error('chartjs-chart-treemap v5: the "tree" option was renamed to "data". ' + 'See https://chartjs-chart-treemap.pages.dev/usage/');
|
|
918
|
+
}
|
|
899
919
|
const options = this.options;
|
|
900
|
-
const groups = options.groups || [];
|
|
901
920
|
const keys = [
|
|
902
921
|
options.key || ''
|
|
903
922
|
].concat(options.sumKeys || []);
|
|
904
|
-
|
|
905
|
-
const
|
|
906
|
-
const
|
|
923
|
+
const nodes = buildNodes(dataset.data || [], keys, this._layoutOptions());
|
|
924
|
+
const flat = flattenNodes(nodes);
|
|
925
|
+
const fingerprint = flat.map((node)=>`${node.v}\u0000${node.g}\u0000${node.l}`).join('\u0001');
|
|
926
|
+
if (this._fingerprint === fingerprint) {
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
this._fingerprint = fingerprint;
|
|
930
|
+
this._nodes = nodes;
|
|
931
|
+
this.getMeta()._parsed = flat;
|
|
932
|
+
this._layoutDirty = true;
|
|
933
|
+
}
|
|
934
|
+
getContext(index, active, mode) {
|
|
935
|
+
const base = chart_js.DatasetController.prototype.getContext;
|
|
936
|
+
const context = base.call(this, index, active, mode);
|
|
937
|
+
const parsed = typeof index === 'number' ? this.getParsed(index) : undefined;
|
|
938
|
+
if (parsed) {
|
|
939
|
+
context.raw = parsed;
|
|
940
|
+
context.parsed = parsed;
|
|
941
|
+
}
|
|
942
|
+
return context;
|
|
943
|
+
}
|
|
944
|
+
getLabelAndValue(index) {
|
|
945
|
+
const node = this.getParsed(index);
|
|
946
|
+
if (!node) {
|
|
947
|
+
return {
|
|
948
|
+
label: '',
|
|
949
|
+
value: ''
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
const dataset = this.getDataset();
|
|
953
|
+
const label = node.g ?? node._data?.label ?? dataset.label;
|
|
954
|
+
return {
|
|
955
|
+
label: label === undefined ? '' : `${label}`,
|
|
956
|
+
value: `${node.v}`
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
update(mode) {
|
|
960
|
+
const { data } = this.getMeta();
|
|
907
961
|
if (mode === 'reset') {
|
|
908
962
|
this.configure();
|
|
909
963
|
}
|
|
910
|
-
if (this.
|
|
911
|
-
this.
|
|
912
|
-
this.
|
|
913
|
-
this._prevTree = tree;
|
|
914
|
-
this._prevTreeVersion = treeVersion;
|
|
964
|
+
if (this._layoutDirty || this._rectChanged) {
|
|
965
|
+
layoutNodes(this._nodes, this._rect, this._layoutOptions());
|
|
966
|
+
this._layoutDirty = false;
|
|
915
967
|
this._rectChanged = false;
|
|
916
|
-
dataset.data = buildData(tree, this._keys, this._rect, this._layoutOptions());
|
|
917
|
-
this._dataCheck();
|
|
918
|
-
this._resyncElements();
|
|
919
968
|
}
|
|
920
969
|
this.updateElements(data, 0, data.length, mode);
|
|
921
970
|
}
|
|
922
971
|
updateElements(rects, start, count, mode) {
|
|
923
972
|
const reset = mode === 'reset';
|
|
924
|
-
const dataset = this.getDataset();
|
|
925
973
|
const firstOpts = this.resolveDataElementOptions(start, mode);
|
|
926
974
|
this._rect.options = firstOpts;
|
|
927
975
|
const sharedOptions = this.getSharedOptions(firstOpts);
|
|
@@ -930,7 +978,9 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
930
978
|
const spacing = this.options.spacing;
|
|
931
979
|
for(let i = start; i < start + count; i++){
|
|
932
980
|
const options = sharedOptions || this.resolveDataElementOptions(i, mode);
|
|
933
|
-
const
|
|
981
|
+
const node = this.getParsed(i);
|
|
982
|
+
const properties = scaleRect(node, xScale, yScale, spacing);
|
|
983
|
+
properties.hidden = properties.hidden || !!node.hidden;
|
|
934
984
|
if (reset) {
|
|
935
985
|
properties.width = 0;
|
|
936
986
|
properties.height = 0;
|
|
@@ -945,8 +995,6 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
945
995
|
draw() {
|
|
946
996
|
const { ctx, chartArea } = this.chart;
|
|
947
997
|
const metadata = this.getMeta().data || [];
|
|
948
|
-
const dataset = this.getDataset();
|
|
949
|
-
const data = dataset.data;
|
|
950
998
|
const { displayMode, rtl, spacing } = this.options;
|
|
951
999
|
const layout = {
|
|
952
1000
|
displayMode,
|
|
@@ -957,17 +1005,18 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
957
1005
|
for(let i = 0, ilen = metadata.length; i < ilen; ++i){
|
|
958
1006
|
const rect = metadata[i];
|
|
959
1007
|
if (!rect.hidden) {
|
|
960
|
-
rect.draw(ctx,
|
|
1008
|
+
rect.draw(ctx, this.getParsed(i), layout);
|
|
961
1009
|
}
|
|
962
1010
|
}
|
|
963
1011
|
helpers.unclipArea(ctx);
|
|
964
1012
|
}
|
|
965
1013
|
constructor(chart, datasetIndex){
|
|
966
1014
|
super(chart, datasetIndex);
|
|
967
|
-
this._groups = undefined;
|
|
968
|
-
this._keys = undefined;
|
|
969
1015
|
this._rect = undefined;
|
|
970
1016
|
this._rectChanged = true;
|
|
1017
|
+
this._nodes = [];
|
|
1018
|
+
this._layoutDirty = true;
|
|
1019
|
+
this._fingerprint = undefined;
|
|
971
1020
|
}
|
|
972
1021
|
}
|
|
973
1022
|
TreemapController.id = 'treemap';
|
|
@@ -1017,10 +1066,9 @@ TreemapController.overrides = {
|
|
|
1017
1066
|
tooltip: {
|
|
1018
1067
|
callbacks: {
|
|
1019
1068
|
label (item) {
|
|
1020
|
-
const
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1023
|
-
return (label ? `${label}: ` : '') + dataItem.v;
|
|
1069
|
+
const node = item.parsed;
|
|
1070
|
+
const label = node.g || node._data?.label || item.dataset.label;
|
|
1071
|
+
return (label ? `${label}: ` : '') + node.v;
|
|
1024
1072
|
},
|
|
1025
1073
|
title (items) {
|
|
1026
1074
|
if (items.length) {
|
|
@@ -1238,6 +1286,7 @@ chart_js.Chart.register(TreemapController, TreemapElement);
|
|
|
1238
1286
|
exports.TreemapController = TreemapController;
|
|
1239
1287
|
exports.TreemapElement = TreemapElement;
|
|
1240
1288
|
exports.flatten = flatten;
|
|
1289
|
+
exports.flattenTree = flattenTree;
|
|
1241
1290
|
exports.getGroupKey = getGroupKey;
|
|
1242
1291
|
exports.group = group;
|
|
1243
1292
|
exports.index = index;
|