chartjs-chart-treemap 2.1.1 → 2.1.3
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.esm.js +127 -161
- package/dist/chartjs-chart-treemap.js +126 -162
- package/dist/chartjs-chart-treemap.min.js +2 -2
- package/package.json +1 -1
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap v2.1.
|
|
2
|
+
* chartjs-chart-treemap v2.1.3
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2022 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
6
6
|
*/
|
|
7
7
|
import { Element, Chart, registry, DatasetController } from 'chart.js';
|
|
8
|
-
import { isObject, addRoundedRectPath, toFont, isArray, toTRBL, toTRBLCorners, valueOrDefault,
|
|
9
|
-
|
|
10
|
-
const getValue = (item) => isObject(item) ? item.v : item;
|
|
11
|
-
|
|
12
|
-
const maxValue = (data) => data.reduce(function(m, v) {
|
|
13
|
-
return (m > getValue(v) ? m : getValue(v));
|
|
14
|
-
}, 0);
|
|
15
|
-
|
|
16
|
-
const minValue = (data, mx) => data.reduce(function(m, v) {
|
|
17
|
-
return (m < getValue(v) ? m : getValue(v));
|
|
18
|
-
}, mx);
|
|
8
|
+
import { isObject, addRoundedRectPath, defined, toFont, isArray, toTRBL, toTRBLCorners, valueOrDefault, clipArea, unclipArea } from 'chart.js/helpers';
|
|
19
9
|
|
|
20
10
|
const getGroupKey = (lvl) => '' + lvl;
|
|
21
11
|
|
|
@@ -192,18 +182,6 @@ function requireVersion(min, ver) {
|
|
|
192
182
|
}
|
|
193
183
|
}
|
|
194
184
|
|
|
195
|
-
const rasterize = (v, dpr) => Math.round(v * dpr) / dpr;
|
|
196
|
-
|
|
197
|
-
function rasterizeRect(rect, dpr) {
|
|
198
|
-
return {
|
|
199
|
-
...rect,
|
|
200
|
-
x: rasterize(rect.x, dpr),
|
|
201
|
-
y: rasterize(rect.y, dpr),
|
|
202
|
-
w: rasterize(rect.w, dpr),
|
|
203
|
-
h: rasterize(rect.h, dpr),
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
185
|
const widthCache = new Map();
|
|
208
186
|
|
|
209
187
|
/**
|
|
@@ -245,19 +223,20 @@ function parseBorderRadius(value, maxW, maxH) {
|
|
|
245
223
|
};
|
|
246
224
|
}
|
|
247
225
|
|
|
248
|
-
function boundingRects(rect
|
|
226
|
+
function boundingRects(rect) {
|
|
249
227
|
const bounds = getBounds(rect);
|
|
250
228
|
const width = bounds.right - bounds.left;
|
|
251
229
|
const height = bounds.bottom - bounds.top;
|
|
252
230
|
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
|
|
253
231
|
const radius = parseBorderRadius(rect.options.borderRadius, width / 2, height / 2);
|
|
254
|
-
const outer =
|
|
232
|
+
const outer = {
|
|
255
233
|
x: bounds.left,
|
|
256
234
|
y: bounds.top,
|
|
257
235
|
w: width,
|
|
258
236
|
h: height,
|
|
237
|
+
active: rect.active,
|
|
259
238
|
radius
|
|
260
|
-
}
|
|
239
|
+
};
|
|
261
240
|
|
|
262
241
|
return {
|
|
263
242
|
outer,
|
|
@@ -266,6 +245,7 @@ function boundingRects(rect, dpr) {
|
|
|
266
245
|
y: outer.y + border.t,
|
|
267
246
|
w: outer.w - border.l - border.r,
|
|
268
247
|
h: outer.h - border.t - border.b,
|
|
248
|
+
active: rect.active,
|
|
269
249
|
radius: {
|
|
270
250
|
topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
|
|
271
251
|
topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
|
|
@@ -316,7 +296,7 @@ function drawText(ctx, rect, options, item, levels) {
|
|
|
316
296
|
ctx.beginPath();
|
|
317
297
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
318
298
|
ctx.clip();
|
|
319
|
-
const isLeaf = (!(
|
|
299
|
+
const isLeaf = item && (!defined(item.l) || item.l === levels);
|
|
320
300
|
if (isLeaf && labels.display) {
|
|
321
301
|
drawLabel(ctx, rect, options);
|
|
322
302
|
} else if (!isLeaf && shouldDrawCaption(rect, captions)) {
|
|
@@ -470,12 +450,12 @@ class TreemapElement extends Element {
|
|
|
470
450
|
}
|
|
471
451
|
}
|
|
472
452
|
|
|
473
|
-
draw(ctx, data, levels = 0
|
|
453
|
+
draw(ctx, data, levels = 0) {
|
|
474
454
|
if (!data) {
|
|
475
455
|
return;
|
|
476
456
|
}
|
|
477
457
|
const options = this.options;
|
|
478
|
-
const {inner, outer} = boundingRects(this
|
|
458
|
+
const {inner, outer} = boundingRects(this);
|
|
479
459
|
|
|
480
460
|
const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
|
|
481
461
|
|
|
@@ -589,11 +569,11 @@ TreemapElement.defaultRoutes = {
|
|
|
589
569
|
borderColor: 'borderColor'
|
|
590
570
|
};
|
|
591
571
|
|
|
592
|
-
function getDims(itm, w2, s2, key
|
|
572
|
+
function getDims(itm, w2, s2, key) {
|
|
593
573
|
const a = itm._normalized;
|
|
594
574
|
const ar = w2 * a / s2;
|
|
595
|
-
const d1 =
|
|
596
|
-
const d2 =
|
|
575
|
+
const d1 = Math.sqrt(a * ar);
|
|
576
|
+
const d2 = a / d1;
|
|
597
577
|
const w = key === '_ix' ? d1 : d2;
|
|
598
578
|
const h = key === '_ix' ? d2 : d1;
|
|
599
579
|
|
|
@@ -602,8 +582,8 @@ function getDims(itm, w2, s2, key, dpr, maxd2) {
|
|
|
602
582
|
|
|
603
583
|
const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
604
584
|
|
|
605
|
-
function buildRow(rect, itm, dims, sum
|
|
606
|
-
const r =
|
|
585
|
+
function buildRow(rect, itm, dims, sum) {
|
|
586
|
+
const r = {
|
|
607
587
|
x: getX(rect, dims.w),
|
|
608
588
|
y: rect.y + rect._iy,
|
|
609
589
|
w: dims.w,
|
|
@@ -612,7 +592,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
612
592
|
v: itm.value,
|
|
613
593
|
s: sum,
|
|
614
594
|
_data: itm._data
|
|
615
|
-
}
|
|
595
|
+
};
|
|
616
596
|
if (itm.group) {
|
|
617
597
|
r.g = itm.group;
|
|
618
598
|
r.l = itm.level;
|
|
@@ -622,8 +602,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
622
602
|
}
|
|
623
603
|
|
|
624
604
|
class Rect {
|
|
625
|
-
constructor(r
|
|
626
|
-
this.dpr = dpr;
|
|
605
|
+
constructor(r) {
|
|
627
606
|
r = r || {w: 1, h: 1};
|
|
628
607
|
this.rtl = !!r.rtl;
|
|
629
608
|
this.x = r.x || r.left || 0;
|
|
@@ -652,61 +631,33 @@ class Rect {
|
|
|
652
631
|
}
|
|
653
632
|
|
|
654
633
|
get side() {
|
|
655
|
-
return
|
|
634
|
+
return this.dir === 'x' ? this.iw : this.ih;
|
|
656
635
|
}
|
|
657
636
|
|
|
658
637
|
map(arr) {
|
|
659
|
-
const {dir, side
|
|
660
|
-
const
|
|
638
|
+
const {dir, side} = this;
|
|
639
|
+
const key = dir === 'x' ? '_ix' : '_iy';
|
|
661
640
|
const sum = arr.nsum;
|
|
662
641
|
const row = arr.get();
|
|
663
642
|
const w2 = side * side;
|
|
664
|
-
const availd2 = rasterize(this[id2prop], dpr);
|
|
665
643
|
const s2 = sum * sum;
|
|
666
644
|
const ret = [];
|
|
667
645
|
let maxd2 = 0;
|
|
668
646
|
let totd1 = 0;
|
|
669
647
|
for (const itm of row) {
|
|
670
|
-
const dims = getDims(itm, w2, s2, key
|
|
648
|
+
const dims = getDims(itm, w2, s2, key);
|
|
671
649
|
totd1 += dims.d1;
|
|
672
|
-
maxd2 = Math.
|
|
673
|
-
ret.push(buildRow(this, itm, dims, arr.sum
|
|
650
|
+
maxd2 = Math.max(maxd2, dims.d2);
|
|
651
|
+
ret.push(buildRow(this, itm, dims, arr.sum));
|
|
674
652
|
this[key] += dims.d1;
|
|
675
653
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const d2 = r[d2prop];
|
|
679
|
-
if (d2 !== maxd2) {
|
|
680
|
-
if (this.rtl && dir === 'y') {
|
|
681
|
-
// for RTL, x-coordinate needs to be adjusted too
|
|
682
|
-
r.x -= maxd2 - d2;
|
|
683
|
-
}
|
|
684
|
-
r[d2prop] = maxd2;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
this[d2key] += maxd2;
|
|
654
|
+
|
|
655
|
+
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
688
656
|
this[key] -= totd1;
|
|
689
657
|
return ret;
|
|
690
658
|
}
|
|
691
659
|
}
|
|
692
660
|
|
|
693
|
-
function getPropNames(dir) {
|
|
694
|
-
if (dir === 'x') {
|
|
695
|
-
return {
|
|
696
|
-
key: '_ix',
|
|
697
|
-
d2prop: 'h',
|
|
698
|
-
id2prop: 'ih',
|
|
699
|
-
d2key: '_iy'
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
return {
|
|
703
|
-
key: '_iy',
|
|
704
|
-
d2prop: 'w',
|
|
705
|
-
id2prop: 'iw',
|
|
706
|
-
d2key: '_ix'
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
|
|
710
661
|
const min = Math.min;
|
|
711
662
|
const max = Math.max;
|
|
712
663
|
|
|
@@ -805,15 +756,14 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
805
756
|
* @param {number[]|object[]} values
|
|
806
757
|
* @param {object} rectangle
|
|
807
758
|
* @param {string} [key]
|
|
808
|
-
* @param {
|
|
809
|
-
* @param {
|
|
810
|
-
* @param {
|
|
811
|
-
* @param {*} [gsum]
|
|
759
|
+
* @param {string} [grp]
|
|
760
|
+
* @param {number} [lvl]
|
|
761
|
+
* @param {number} [gsum]
|
|
812
762
|
*/
|
|
813
|
-
function squarify(values, rectangle, key,
|
|
763
|
+
function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
814
764
|
values = values || [];
|
|
815
765
|
const rows = [];
|
|
816
|
-
const rect = new Rect(rectangle
|
|
766
|
+
const rect = new Rect(rectangle);
|
|
817
767
|
const row = new StatArray('value', rect.area / sum(values, key));
|
|
818
768
|
let length = rect.side;
|
|
819
769
|
const n = values.length;
|
|
@@ -850,35 +800,58 @@ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
|
|
|
850
800
|
return flatten(rows);
|
|
851
801
|
}
|
|
852
802
|
|
|
853
|
-
var version = "2.1.
|
|
803
|
+
var version = "2.1.3";
|
|
804
|
+
|
|
805
|
+
function scaleRect(sq, xScale, yScale, sp) {
|
|
806
|
+
const sp2 = sp * 2;
|
|
807
|
+
const x = xScale.getPixelForValue(sq.x);
|
|
808
|
+
const y = yScale.getPixelForValue(sq.y);
|
|
809
|
+
const w = xScale.getPixelForValue(sq.x + sq.w) - x;
|
|
810
|
+
const h = yScale.getPixelForValue(sq.y + sq.h) - y;
|
|
811
|
+
return {
|
|
812
|
+
x: x + sp,
|
|
813
|
+
y: y + sp,
|
|
814
|
+
width: w - sp2,
|
|
815
|
+
height: h - sp2,
|
|
816
|
+
hidden: sp2 > w || sp2 > h,
|
|
817
|
+
};
|
|
818
|
+
}
|
|
854
819
|
|
|
855
820
|
function rectNotEqual(r1, r2) {
|
|
856
821
|
return !r1 || !r2
|
|
857
822
|
|| r1.x !== r2.x
|
|
858
823
|
|| r1.y !== r2.y
|
|
859
824
|
|| r1.w !== r2.w
|
|
860
|
-
|| r1.h !== r2.h
|
|
825
|
+
|| r1.h !== r2.h
|
|
826
|
+
|| r1.rtl !== r2.rtl;
|
|
861
827
|
}
|
|
862
828
|
|
|
863
|
-
function arrayNotEqual(
|
|
829
|
+
function arrayNotEqual(a, b) {
|
|
864
830
|
let i, n;
|
|
865
831
|
|
|
866
|
-
if (
|
|
832
|
+
if (!a || !b) {
|
|
833
|
+
return true;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (a === b) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (a.length !== b.length) {
|
|
867
841
|
return true;
|
|
868
842
|
}
|
|
869
843
|
|
|
870
|
-
for (i = 0, n =
|
|
871
|
-
if (
|
|
844
|
+
for (i = 0, n = a.length; i < n; ++i) {
|
|
845
|
+
if (a[i] !== b[i]) {
|
|
872
846
|
return true;
|
|
873
847
|
}
|
|
874
848
|
}
|
|
875
849
|
return false;
|
|
876
850
|
}
|
|
877
851
|
|
|
878
|
-
function buildData(dataset, mainRect
|
|
852
|
+
function buildData(tree, dataset, mainRect) {
|
|
879
853
|
const key = dataset.key || '';
|
|
880
854
|
const treeLeafKey = dataset.treeLeafKey || '_leaf';
|
|
881
|
-
let tree = dataset.tree || [];
|
|
882
855
|
if (isObject(tree)) {
|
|
883
856
|
tree = normalizeTreeToArray(key, treeLeafKey, tree);
|
|
884
857
|
}
|
|
@@ -893,7 +866,7 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
893
866
|
const g = getGroupKey(groups[gidx]);
|
|
894
867
|
const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
|
|
895
868
|
const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
|
|
896
|
-
const gsq = squarify(gdata, rect, key,
|
|
869
|
+
const gsq = squarify(gdata, rect, key, g, gidx, gs);
|
|
897
870
|
const ret = gsq.slice();
|
|
898
871
|
if (gidx < glen - 1) {
|
|
899
872
|
gsq.forEach((sq) => {
|
|
@@ -909,44 +882,25 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
909
882
|
subRect.y += font.lineHeight + padding * 2;
|
|
910
883
|
subRect.h -= font.lineHeight + padding * 2;
|
|
911
884
|
}
|
|
912
|
-
ret.push(...recur(gidx + 1,
|
|
885
|
+
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
913
886
|
});
|
|
914
887
|
}
|
|
915
888
|
return ret;
|
|
916
889
|
}
|
|
917
890
|
|
|
918
|
-
if (!tree.length && dataset.data.length) {
|
|
919
|
-
tree = dataset.tree = dataset.data;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
891
|
return glen
|
|
923
892
|
? recur(0, mainRect)
|
|
924
|
-
: squarify(tree, mainRect, key
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
function getMinMax(data, useTree) {
|
|
928
|
-
const vMax = useTree ? 1 : maxValue(data);
|
|
929
|
-
const vMin = useTree ? 0 : minValue(data, vMax);
|
|
930
|
-
return {vMin, vMax};
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
function getArea({xScale, yScale}, data, rtl, useTree) {
|
|
934
|
-
const {vMin, vMax} = getMinMax(data, useTree);
|
|
935
|
-
const xMin = xScale.getPixelForValue(0);
|
|
936
|
-
const xMax = xScale.getPixelForValue(1);
|
|
937
|
-
const yMin = yScale.getPixelForValue(vMin);
|
|
938
|
-
const yMax = yScale.getPixelForValue(vMax);
|
|
939
|
-
return {x: xMin, y: yMax, w: xMax - xMin, h: yMin - yMax, rtl};
|
|
893
|
+
: squarify(tree, mainRect, key);
|
|
940
894
|
}
|
|
941
895
|
|
|
942
896
|
class TreemapController extends DatasetController {
|
|
943
897
|
constructor(chart, datasetIndex) {
|
|
944
898
|
super(chart, datasetIndex);
|
|
945
899
|
|
|
946
|
-
this._rect = undefined;
|
|
947
|
-
this._key = undefined;
|
|
948
900
|
this._groups = undefined;
|
|
949
|
-
this.
|
|
901
|
+
this._key = undefined;
|
|
902
|
+
this._rect = undefined;
|
|
903
|
+
this._rectChanged = true;
|
|
950
904
|
}
|
|
951
905
|
|
|
952
906
|
initialize() {
|
|
@@ -954,86 +908,93 @@ class TreemapController extends DatasetController {
|
|
|
954
908
|
super.initialize();
|
|
955
909
|
}
|
|
956
910
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
911
|
+
getMinMax(scale) {
|
|
912
|
+
return {
|
|
913
|
+
min: 0,
|
|
914
|
+
max: scale.axis === 'x' ? scale.right - scale.left : scale.bottom - scale.top
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
configure() {
|
|
919
|
+
super.configure();
|
|
920
|
+
const {xScale, yScale} = this.getMeta();
|
|
921
|
+
if (!xScale || !yScale) {
|
|
922
|
+
// configure is called once before `linkScales`, and at that call we don't have any scales linked yet
|
|
962
923
|
return;
|
|
963
924
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
925
|
+
|
|
926
|
+
const w = xScale.right - xScale.left;
|
|
927
|
+
const h = yScale.bottom - yScale.top;
|
|
928
|
+
const rect = {x: 0, y: 0, w, h, rtl: !!this.options.rtl};
|
|
929
|
+
|
|
930
|
+
if (rectNotEqual(this._rect, rect)) {
|
|
931
|
+
this._rect = rect;
|
|
932
|
+
this._rectChanged = true;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
if (this._rectChanged) {
|
|
936
|
+
xScale.max = w;
|
|
937
|
+
xScale.configure();
|
|
938
|
+
yScale.max = h;
|
|
939
|
+
yScale.configure();
|
|
969
940
|
}
|
|
970
|
-
const dataset = this.getDataset();
|
|
971
|
-
const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
|
|
972
|
-
range.min = vMin;
|
|
973
|
-
range.max = vMax;
|
|
974
941
|
}
|
|
975
942
|
|
|
976
943
|
update(mode) {
|
|
977
|
-
const meta = this.getMeta();
|
|
978
944
|
const dataset = this.getDataset();
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
if (!defined(this._useTree)) {
|
|
982
|
-
this._useTree = !!dataset.tree;
|
|
983
|
-
}
|
|
945
|
+
const {data} = this.getMeta();
|
|
984
946
|
const groups = dataset.groups || (dataset.groups = []);
|
|
985
|
-
const key = dataset.key
|
|
986
|
-
const
|
|
947
|
+
const key = dataset.key;
|
|
948
|
+
const tree = dataset.tree = dataset.tree || dataset.data || [];
|
|
987
949
|
|
|
988
|
-
|
|
950
|
+
if (mode === 'reset') {
|
|
951
|
+
// reset is called before 2nd configure and is only called if animations are enabled. So wen need an extra configure call here.
|
|
952
|
+
this.configure();
|
|
953
|
+
}
|
|
989
954
|
|
|
990
|
-
if (
|
|
991
|
-
this._rect = mainRect;
|
|
955
|
+
if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
|
|
992
956
|
this._groups = groups.slice();
|
|
993
957
|
this._key = key;
|
|
958
|
+
this._prevTree = tree;
|
|
959
|
+
this._rectChanged = false;
|
|
994
960
|
|
|
995
|
-
dataset.data = buildData(
|
|
961
|
+
dataset.data = buildData(tree, dataset, this._rect);
|
|
996
962
|
// @ts-ignore using private stuff
|
|
997
963
|
this._dataCheck();
|
|
998
964
|
// @ts-ignore using private stuff
|
|
999
965
|
this._resyncElements();
|
|
1000
966
|
}
|
|
1001
967
|
|
|
1002
|
-
this.updateElements(
|
|
968
|
+
this.updateElements(data, 0, data.length, mode);
|
|
1003
969
|
}
|
|
1004
970
|
|
|
1005
971
|
updateElements(rects, start, count, mode) {
|
|
1006
|
-
const me = this;
|
|
1007
972
|
const reset = mode === 'reset';
|
|
1008
|
-
const dataset =
|
|
1009
|
-
const firstOpts =
|
|
1010
|
-
const sharedOptions =
|
|
1011
|
-
const includeOptions =
|
|
973
|
+
const dataset = this.getDataset();
|
|
974
|
+
const firstOpts = this._rect.options = this.resolveDataElementOptions(start, mode);
|
|
975
|
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
|
976
|
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
|
977
|
+
const {xScale, yScale} = this.getMeta(this.index);
|
|
1012
978
|
|
|
1013
979
|
for (let i = start; i < start + count; i++) {
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
y: sq.y + sp,
|
|
1021
|
-
width: reset ? 0 : sq.w - sp2,
|
|
1022
|
-
height: reset ? 0 : sq.h - sp2,
|
|
1023
|
-
hidden: sp2 > sq.w || sp2 > sq.h,
|
|
1024
|
-
};
|
|
980
|
+
const options = sharedOptions || this.resolveDataElementOptions(i, mode);
|
|
981
|
+
const properties = scaleRect(dataset.data[i], xScale, yScale, options.spacing);
|
|
982
|
+
if (reset) {
|
|
983
|
+
properties.width = 0;
|
|
984
|
+
properties.height = 0;
|
|
985
|
+
}
|
|
1025
986
|
|
|
1026
987
|
if (includeOptions) {
|
|
1027
988
|
properties.options = options;
|
|
1028
989
|
}
|
|
1029
|
-
|
|
990
|
+
this.updateElement(rects[i], i, properties, mode);
|
|
1030
991
|
}
|
|
1031
992
|
|
|
1032
|
-
|
|
993
|
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
|
1033
994
|
}
|
|
1034
995
|
|
|
1035
996
|
draw() {
|
|
1036
|
-
const {ctx, chartArea
|
|
997
|
+
const {ctx, chartArea} = this.chart;
|
|
1037
998
|
const metadata = this.getMeta().data || [];
|
|
1038
999
|
const dataset = this.getDataset();
|
|
1039
1000
|
const levels = (dataset.groups || []).length - 1;
|
|
@@ -1043,7 +1004,7 @@ class TreemapController extends DatasetController {
|
|
|
1043
1004
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
1044
1005
|
const rect = metadata[i];
|
|
1045
1006
|
if (!rect.hidden) {
|
|
1046
|
-
rect.draw(ctx, data[i], levels
|
|
1007
|
+
rect.draw(ctx, data[i], levels);
|
|
1047
1008
|
}
|
|
1048
1009
|
}
|
|
1049
1010
|
unclipArea(ctx);
|
|
@@ -1104,11 +1065,16 @@ TreemapController.overrides = {
|
|
|
1104
1065
|
scales: {
|
|
1105
1066
|
x: {
|
|
1106
1067
|
type: 'linear',
|
|
1068
|
+
alignToPixels: true,
|
|
1069
|
+
bounds: 'data',
|
|
1107
1070
|
display: false
|
|
1108
1071
|
},
|
|
1109
1072
|
y: {
|
|
1110
1073
|
type: 'linear',
|
|
1111
|
-
|
|
1074
|
+
alignToPixels: true,
|
|
1075
|
+
bounds: 'data',
|
|
1076
|
+
display: false,
|
|
1077
|
+
reverse: true
|
|
1112
1078
|
}
|
|
1113
1079
|
},
|
|
1114
1080
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap v2.1.
|
|
2
|
+
* chartjs-chart-treemap v2.1.3
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2022 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
@@ -10,16 +10,6 @@ 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
|
-
const getValue = (item) => helpers.isObject(item) ? item.v : item;
|
|
14
|
-
|
|
15
|
-
const maxValue = (data) => data.reduce(function(m, v) {
|
|
16
|
-
return (m > getValue(v) ? m : getValue(v));
|
|
17
|
-
}, 0);
|
|
18
|
-
|
|
19
|
-
const minValue = (data, mx) => data.reduce(function(m, v) {
|
|
20
|
-
return (m < getValue(v) ? m : getValue(v));
|
|
21
|
-
}, mx);
|
|
22
|
-
|
|
23
13
|
const getGroupKey = (lvl) => '' + lvl;
|
|
24
14
|
|
|
25
15
|
function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
|
|
@@ -195,18 +185,6 @@ function requireVersion(min, ver) {
|
|
|
195
185
|
}
|
|
196
186
|
}
|
|
197
187
|
|
|
198
|
-
const rasterize = (v, dpr) => Math.round(v * dpr) / dpr;
|
|
199
|
-
|
|
200
|
-
function rasterizeRect(rect, dpr) {
|
|
201
|
-
return {
|
|
202
|
-
...rect,
|
|
203
|
-
x: rasterize(rect.x, dpr),
|
|
204
|
-
y: rasterize(rect.y, dpr),
|
|
205
|
-
w: rasterize(rect.w, dpr),
|
|
206
|
-
h: rasterize(rect.h, dpr),
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
188
|
const widthCache = new Map();
|
|
211
189
|
|
|
212
190
|
/**
|
|
@@ -248,19 +226,20 @@ function parseBorderRadius(value, maxW, maxH) {
|
|
|
248
226
|
};
|
|
249
227
|
}
|
|
250
228
|
|
|
251
|
-
function boundingRects(rect
|
|
229
|
+
function boundingRects(rect) {
|
|
252
230
|
const bounds = getBounds(rect);
|
|
253
231
|
const width = bounds.right - bounds.left;
|
|
254
232
|
const height = bounds.bottom - bounds.top;
|
|
255
233
|
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
|
|
256
234
|
const radius = parseBorderRadius(rect.options.borderRadius, width / 2, height / 2);
|
|
257
|
-
const outer =
|
|
235
|
+
const outer = {
|
|
258
236
|
x: bounds.left,
|
|
259
237
|
y: bounds.top,
|
|
260
238
|
w: width,
|
|
261
239
|
h: height,
|
|
240
|
+
active: rect.active,
|
|
262
241
|
radius
|
|
263
|
-
}
|
|
242
|
+
};
|
|
264
243
|
|
|
265
244
|
return {
|
|
266
245
|
outer,
|
|
@@ -269,6 +248,7 @@ function boundingRects(rect, dpr) {
|
|
|
269
248
|
y: outer.y + border.t,
|
|
270
249
|
w: outer.w - border.l - border.r,
|
|
271
250
|
h: outer.h - border.t - border.b,
|
|
251
|
+
active: rect.active,
|
|
272
252
|
radius: {
|
|
273
253
|
topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
|
|
274
254
|
topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
|
|
@@ -319,7 +299,7 @@ function drawText(ctx, rect, options, item, levels) {
|
|
|
319
299
|
ctx.beginPath();
|
|
320
300
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
321
301
|
ctx.clip();
|
|
322
|
-
const isLeaf = (!(
|
|
302
|
+
const isLeaf = item && (!helpers.defined(item.l) || item.l === levels);
|
|
323
303
|
if (isLeaf && labels.display) {
|
|
324
304
|
drawLabel(ctx, rect, options);
|
|
325
305
|
} else if (!isLeaf && shouldDrawCaption(rect, captions)) {
|
|
@@ -473,12 +453,12 @@ class TreemapElement extends chart_js.Element {
|
|
|
473
453
|
}
|
|
474
454
|
}
|
|
475
455
|
|
|
476
|
-
draw(ctx, data, levels = 0
|
|
456
|
+
draw(ctx, data, levels = 0) {
|
|
477
457
|
if (!data) {
|
|
478
458
|
return;
|
|
479
459
|
}
|
|
480
460
|
const options = this.options;
|
|
481
|
-
const {inner, outer} = boundingRects(this
|
|
461
|
+
const {inner, outer} = boundingRects(this);
|
|
482
462
|
|
|
483
463
|
const addRectPath = hasRadius(outer.radius) ? helpers.addRoundedRectPath : addNormalRectPath;
|
|
484
464
|
|
|
@@ -592,11 +572,11 @@ TreemapElement.defaultRoutes = {
|
|
|
592
572
|
borderColor: 'borderColor'
|
|
593
573
|
};
|
|
594
574
|
|
|
595
|
-
function getDims(itm, w2, s2, key
|
|
575
|
+
function getDims(itm, w2, s2, key) {
|
|
596
576
|
const a = itm._normalized;
|
|
597
577
|
const ar = w2 * a / s2;
|
|
598
|
-
const d1 =
|
|
599
|
-
const d2 =
|
|
578
|
+
const d1 = Math.sqrt(a * ar);
|
|
579
|
+
const d2 = a / d1;
|
|
600
580
|
const w = key === '_ix' ? d1 : d2;
|
|
601
581
|
const h = key === '_ix' ? d2 : d1;
|
|
602
582
|
|
|
@@ -605,8 +585,8 @@ function getDims(itm, w2, s2, key, dpr, maxd2) {
|
|
|
605
585
|
|
|
606
586
|
const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
607
587
|
|
|
608
|
-
function buildRow(rect, itm, dims, sum
|
|
609
|
-
const r =
|
|
588
|
+
function buildRow(rect, itm, dims, sum) {
|
|
589
|
+
const r = {
|
|
610
590
|
x: getX(rect, dims.w),
|
|
611
591
|
y: rect.y + rect._iy,
|
|
612
592
|
w: dims.w,
|
|
@@ -615,7 +595,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
615
595
|
v: itm.value,
|
|
616
596
|
s: sum,
|
|
617
597
|
_data: itm._data
|
|
618
|
-
}
|
|
598
|
+
};
|
|
619
599
|
if (itm.group) {
|
|
620
600
|
r.g = itm.group;
|
|
621
601
|
r.l = itm.level;
|
|
@@ -625,8 +605,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
625
605
|
}
|
|
626
606
|
|
|
627
607
|
class Rect {
|
|
628
|
-
constructor(r
|
|
629
|
-
this.dpr = dpr;
|
|
608
|
+
constructor(r) {
|
|
630
609
|
r = r || {w: 1, h: 1};
|
|
631
610
|
this.rtl = !!r.rtl;
|
|
632
611
|
this.x = r.x || r.left || 0;
|
|
@@ -655,61 +634,33 @@ class Rect {
|
|
|
655
634
|
}
|
|
656
635
|
|
|
657
636
|
get side() {
|
|
658
|
-
return
|
|
637
|
+
return this.dir === 'x' ? this.iw : this.ih;
|
|
659
638
|
}
|
|
660
639
|
|
|
661
640
|
map(arr) {
|
|
662
|
-
const {dir, side
|
|
663
|
-
const
|
|
641
|
+
const {dir, side} = this;
|
|
642
|
+
const key = dir === 'x' ? '_ix' : '_iy';
|
|
664
643
|
const sum = arr.nsum;
|
|
665
644
|
const row = arr.get();
|
|
666
645
|
const w2 = side * side;
|
|
667
|
-
const availd2 = rasterize(this[id2prop], dpr);
|
|
668
646
|
const s2 = sum * sum;
|
|
669
647
|
const ret = [];
|
|
670
648
|
let maxd2 = 0;
|
|
671
649
|
let totd1 = 0;
|
|
672
650
|
for (const itm of row) {
|
|
673
|
-
const dims = getDims(itm, w2, s2, key
|
|
651
|
+
const dims = getDims(itm, w2, s2, key);
|
|
674
652
|
totd1 += dims.d1;
|
|
675
|
-
maxd2 = Math.
|
|
676
|
-
ret.push(buildRow(this, itm, dims, arr.sum
|
|
653
|
+
maxd2 = Math.max(maxd2, dims.d2);
|
|
654
|
+
ret.push(buildRow(this, itm, dims, arr.sum));
|
|
677
655
|
this[key] += dims.d1;
|
|
678
656
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
const d2 = r[d2prop];
|
|
682
|
-
if (d2 !== maxd2) {
|
|
683
|
-
if (this.rtl && dir === 'y') {
|
|
684
|
-
// for RTL, x-coordinate needs to be adjusted too
|
|
685
|
-
r.x -= maxd2 - d2;
|
|
686
|
-
}
|
|
687
|
-
r[d2prop] = maxd2;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
this[d2key] += maxd2;
|
|
657
|
+
|
|
658
|
+
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
691
659
|
this[key] -= totd1;
|
|
692
660
|
return ret;
|
|
693
661
|
}
|
|
694
662
|
}
|
|
695
663
|
|
|
696
|
-
function getPropNames(dir) {
|
|
697
|
-
if (dir === 'x') {
|
|
698
|
-
return {
|
|
699
|
-
key: '_ix',
|
|
700
|
-
d2prop: 'h',
|
|
701
|
-
id2prop: 'ih',
|
|
702
|
-
d2key: '_iy'
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
return {
|
|
706
|
-
key: '_iy',
|
|
707
|
-
d2prop: 'w',
|
|
708
|
-
id2prop: 'iw',
|
|
709
|
-
d2key: '_ix'
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
|
|
713
664
|
const min = Math.min;
|
|
714
665
|
const max = Math.max;
|
|
715
666
|
|
|
@@ -808,15 +759,14 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
808
759
|
* @param {number[]|object[]} values
|
|
809
760
|
* @param {object} rectangle
|
|
810
761
|
* @param {string} [key]
|
|
811
|
-
* @param {
|
|
812
|
-
* @param {
|
|
813
|
-
* @param {
|
|
814
|
-
* @param {*} [gsum]
|
|
762
|
+
* @param {string} [grp]
|
|
763
|
+
* @param {number} [lvl]
|
|
764
|
+
* @param {number} [gsum]
|
|
815
765
|
*/
|
|
816
|
-
function squarify(values, rectangle, key,
|
|
766
|
+
function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
817
767
|
values = values || [];
|
|
818
768
|
const rows = [];
|
|
819
|
-
const rect = new Rect(rectangle
|
|
769
|
+
const rect = new Rect(rectangle);
|
|
820
770
|
const row = new StatArray('value', rect.area / sum(values, key));
|
|
821
771
|
let length = rect.side;
|
|
822
772
|
const n = values.length;
|
|
@@ -853,35 +803,58 @@ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
|
|
|
853
803
|
return flatten(rows);
|
|
854
804
|
}
|
|
855
805
|
|
|
856
|
-
var version = "2.1.
|
|
806
|
+
var version = "2.1.3";
|
|
807
|
+
|
|
808
|
+
function scaleRect(sq, xScale, yScale, sp) {
|
|
809
|
+
const sp2 = sp * 2;
|
|
810
|
+
const x = xScale.getPixelForValue(sq.x);
|
|
811
|
+
const y = yScale.getPixelForValue(sq.y);
|
|
812
|
+
const w = xScale.getPixelForValue(sq.x + sq.w) - x;
|
|
813
|
+
const h = yScale.getPixelForValue(sq.y + sq.h) - y;
|
|
814
|
+
return {
|
|
815
|
+
x: x + sp,
|
|
816
|
+
y: y + sp,
|
|
817
|
+
width: w - sp2,
|
|
818
|
+
height: h - sp2,
|
|
819
|
+
hidden: sp2 > w || sp2 > h,
|
|
820
|
+
};
|
|
821
|
+
}
|
|
857
822
|
|
|
858
823
|
function rectNotEqual(r1, r2) {
|
|
859
824
|
return !r1 || !r2
|
|
860
825
|
|| r1.x !== r2.x
|
|
861
826
|
|| r1.y !== r2.y
|
|
862
827
|
|| r1.w !== r2.w
|
|
863
|
-
|| r1.h !== r2.h
|
|
828
|
+
|| r1.h !== r2.h
|
|
829
|
+
|| r1.rtl !== r2.rtl;
|
|
864
830
|
}
|
|
865
831
|
|
|
866
|
-
function arrayNotEqual(
|
|
832
|
+
function arrayNotEqual(a, b) {
|
|
867
833
|
let i, n;
|
|
868
834
|
|
|
869
|
-
if (
|
|
835
|
+
if (!a || !b) {
|
|
836
|
+
return true;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (a === b) {
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
if (a.length !== b.length) {
|
|
870
844
|
return true;
|
|
871
845
|
}
|
|
872
846
|
|
|
873
|
-
for (i = 0, n =
|
|
874
|
-
if (
|
|
847
|
+
for (i = 0, n = a.length; i < n; ++i) {
|
|
848
|
+
if (a[i] !== b[i]) {
|
|
875
849
|
return true;
|
|
876
850
|
}
|
|
877
851
|
}
|
|
878
852
|
return false;
|
|
879
853
|
}
|
|
880
854
|
|
|
881
|
-
function buildData(dataset, mainRect
|
|
855
|
+
function buildData(tree, dataset, mainRect) {
|
|
882
856
|
const key = dataset.key || '';
|
|
883
857
|
const treeLeafKey = dataset.treeLeafKey || '_leaf';
|
|
884
|
-
let tree = dataset.tree || [];
|
|
885
858
|
if (helpers.isObject(tree)) {
|
|
886
859
|
tree = normalizeTreeToArray(key, treeLeafKey, tree);
|
|
887
860
|
}
|
|
@@ -896,7 +869,7 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
896
869
|
const g = getGroupKey(groups[gidx]);
|
|
897
870
|
const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
|
|
898
871
|
const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
|
|
899
|
-
const gsq = squarify(gdata, rect, key,
|
|
872
|
+
const gsq = squarify(gdata, rect, key, g, gidx, gs);
|
|
900
873
|
const ret = gsq.slice();
|
|
901
874
|
if (gidx < glen - 1) {
|
|
902
875
|
gsq.forEach((sq) => {
|
|
@@ -912,44 +885,25 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
912
885
|
subRect.y += font.lineHeight + padding * 2;
|
|
913
886
|
subRect.h -= font.lineHeight + padding * 2;
|
|
914
887
|
}
|
|
915
|
-
ret.push(...recur(gidx + 1,
|
|
888
|
+
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
916
889
|
});
|
|
917
890
|
}
|
|
918
891
|
return ret;
|
|
919
892
|
}
|
|
920
893
|
|
|
921
|
-
if (!tree.length && dataset.data.length) {
|
|
922
|
-
tree = dataset.tree = dataset.data;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
894
|
return glen
|
|
926
895
|
? recur(0, mainRect)
|
|
927
|
-
: squarify(tree, mainRect, key
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
function getMinMax(data, useTree) {
|
|
931
|
-
const vMax = useTree ? 1 : maxValue(data);
|
|
932
|
-
const vMin = useTree ? 0 : minValue(data, vMax);
|
|
933
|
-
return {vMin, vMax};
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
function getArea({xScale, yScale}, data, rtl, useTree) {
|
|
937
|
-
const {vMin, vMax} = getMinMax(data, useTree);
|
|
938
|
-
const xMin = xScale.getPixelForValue(0);
|
|
939
|
-
const xMax = xScale.getPixelForValue(1);
|
|
940
|
-
const yMin = yScale.getPixelForValue(vMin);
|
|
941
|
-
const yMax = yScale.getPixelForValue(vMax);
|
|
942
|
-
return {x: xMin, y: yMax, w: xMax - xMin, h: yMin - yMax, rtl};
|
|
896
|
+
: squarify(tree, mainRect, key);
|
|
943
897
|
}
|
|
944
898
|
|
|
945
899
|
class TreemapController extends chart_js.DatasetController {
|
|
946
900
|
constructor(chart, datasetIndex) {
|
|
947
901
|
super(chart, datasetIndex);
|
|
948
902
|
|
|
949
|
-
this._rect = undefined;
|
|
950
|
-
this._key = undefined;
|
|
951
903
|
this._groups = undefined;
|
|
952
|
-
this.
|
|
904
|
+
this._key = undefined;
|
|
905
|
+
this._rect = undefined;
|
|
906
|
+
this._rectChanged = true;
|
|
953
907
|
}
|
|
954
908
|
|
|
955
909
|
initialize() {
|
|
@@ -957,86 +911,93 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
957
911
|
super.initialize();
|
|
958
912
|
}
|
|
959
913
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
914
|
+
getMinMax(scale) {
|
|
915
|
+
return {
|
|
916
|
+
min: 0,
|
|
917
|
+
max: scale.axis === 'x' ? scale.right - scale.left : scale.bottom - scale.top
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
configure() {
|
|
922
|
+
super.configure();
|
|
923
|
+
const {xScale, yScale} = this.getMeta();
|
|
924
|
+
if (!xScale || !yScale) {
|
|
925
|
+
// configure is called once before `linkScales`, and at that call we don't have any scales linked yet
|
|
965
926
|
return;
|
|
966
927
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
928
|
+
|
|
929
|
+
const w = xScale.right - xScale.left;
|
|
930
|
+
const h = yScale.bottom - yScale.top;
|
|
931
|
+
const rect = {x: 0, y: 0, w, h, rtl: !!this.options.rtl};
|
|
932
|
+
|
|
933
|
+
if (rectNotEqual(this._rect, rect)) {
|
|
934
|
+
this._rect = rect;
|
|
935
|
+
this._rectChanged = true;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
if (this._rectChanged) {
|
|
939
|
+
xScale.max = w;
|
|
940
|
+
xScale.configure();
|
|
941
|
+
yScale.max = h;
|
|
942
|
+
yScale.configure();
|
|
972
943
|
}
|
|
973
|
-
const dataset = this.getDataset();
|
|
974
|
-
const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
|
|
975
|
-
range.min = vMin;
|
|
976
|
-
range.max = vMax;
|
|
977
944
|
}
|
|
978
945
|
|
|
979
946
|
update(mode) {
|
|
980
|
-
const meta = this.getMeta();
|
|
981
947
|
const dataset = this.getDataset();
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
if (!helpers.defined(this._useTree)) {
|
|
985
|
-
this._useTree = !!dataset.tree;
|
|
986
|
-
}
|
|
948
|
+
const {data} = this.getMeta();
|
|
987
949
|
const groups = dataset.groups || (dataset.groups = []);
|
|
988
|
-
const key = dataset.key
|
|
989
|
-
const
|
|
950
|
+
const key = dataset.key;
|
|
951
|
+
const tree = dataset.tree = dataset.tree || dataset.data || [];
|
|
990
952
|
|
|
991
|
-
|
|
953
|
+
if (mode === 'reset') {
|
|
954
|
+
// reset is called before 2nd configure and is only called if animations are enabled. So wen need an extra configure call here.
|
|
955
|
+
this.configure();
|
|
956
|
+
}
|
|
992
957
|
|
|
993
|
-
if (
|
|
994
|
-
this._rect = mainRect;
|
|
958
|
+
if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
|
|
995
959
|
this._groups = groups.slice();
|
|
996
960
|
this._key = key;
|
|
961
|
+
this._prevTree = tree;
|
|
962
|
+
this._rectChanged = false;
|
|
997
963
|
|
|
998
|
-
dataset.data = buildData(
|
|
964
|
+
dataset.data = buildData(tree, dataset, this._rect);
|
|
999
965
|
// @ts-ignore using private stuff
|
|
1000
966
|
this._dataCheck();
|
|
1001
967
|
// @ts-ignore using private stuff
|
|
1002
968
|
this._resyncElements();
|
|
1003
969
|
}
|
|
1004
970
|
|
|
1005
|
-
this.updateElements(
|
|
971
|
+
this.updateElements(data, 0, data.length, mode);
|
|
1006
972
|
}
|
|
1007
973
|
|
|
1008
974
|
updateElements(rects, start, count, mode) {
|
|
1009
|
-
const me = this;
|
|
1010
975
|
const reset = mode === 'reset';
|
|
1011
|
-
const dataset =
|
|
1012
|
-
const firstOpts =
|
|
1013
|
-
const sharedOptions =
|
|
1014
|
-
const includeOptions =
|
|
976
|
+
const dataset = this.getDataset();
|
|
977
|
+
const firstOpts = this._rect.options = this.resolveDataElementOptions(start, mode);
|
|
978
|
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
|
979
|
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
|
980
|
+
const {xScale, yScale} = this.getMeta(this.index);
|
|
1015
981
|
|
|
1016
982
|
for (let i = start; i < start + count; i++) {
|
|
1017
|
-
const
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
y: sq.y + sp,
|
|
1024
|
-
width: reset ? 0 : sq.w - sp2,
|
|
1025
|
-
height: reset ? 0 : sq.h - sp2,
|
|
1026
|
-
hidden: sp2 > sq.w || sp2 > sq.h,
|
|
1027
|
-
};
|
|
983
|
+
const options = sharedOptions || this.resolveDataElementOptions(i, mode);
|
|
984
|
+
const properties = scaleRect(dataset.data[i], xScale, yScale, options.spacing);
|
|
985
|
+
if (reset) {
|
|
986
|
+
properties.width = 0;
|
|
987
|
+
properties.height = 0;
|
|
988
|
+
}
|
|
1028
989
|
|
|
1029
990
|
if (includeOptions) {
|
|
1030
991
|
properties.options = options;
|
|
1031
992
|
}
|
|
1032
|
-
|
|
993
|
+
this.updateElement(rects[i], i, properties, mode);
|
|
1033
994
|
}
|
|
1034
995
|
|
|
1035
|
-
|
|
996
|
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
|
1036
997
|
}
|
|
1037
998
|
|
|
1038
999
|
draw() {
|
|
1039
|
-
const {ctx, chartArea
|
|
1000
|
+
const {ctx, chartArea} = this.chart;
|
|
1040
1001
|
const metadata = this.getMeta().data || [];
|
|
1041
1002
|
const dataset = this.getDataset();
|
|
1042
1003
|
const levels = (dataset.groups || []).length - 1;
|
|
@@ -1046,7 +1007,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
1046
1007
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
1047
1008
|
const rect = metadata[i];
|
|
1048
1009
|
if (!rect.hidden) {
|
|
1049
|
-
rect.draw(ctx, data[i], levels
|
|
1010
|
+
rect.draw(ctx, data[i], levels);
|
|
1050
1011
|
}
|
|
1051
1012
|
}
|
|
1052
1013
|
helpers.unclipArea(ctx);
|
|
@@ -1107,11 +1068,16 @@ TreemapController.overrides = {
|
|
|
1107
1068
|
scales: {
|
|
1108
1069
|
x: {
|
|
1109
1070
|
type: 'linear',
|
|
1071
|
+
alignToPixels: true,
|
|
1072
|
+
bounds: 'data',
|
|
1110
1073
|
display: false
|
|
1111
1074
|
},
|
|
1112
1075
|
y: {
|
|
1113
1076
|
type: 'linear',
|
|
1114
|
-
|
|
1077
|
+
alignToPixels: true,
|
|
1078
|
+
bounds: 'data',
|
|
1079
|
+
display: false,
|
|
1080
|
+
reverse: true
|
|
1115
1081
|
}
|
|
1116
1082
|
},
|
|
1117
1083
|
};
|
|
@@ -1151,8 +1117,6 @@ exports.flatten = flatten;
|
|
|
1151
1117
|
exports.getGroupKey = getGroupKey;
|
|
1152
1118
|
exports.group = group;
|
|
1153
1119
|
exports.index = index;
|
|
1154
|
-
exports.maxValue = maxValue;
|
|
1155
|
-
exports.minValue = minValue;
|
|
1156
1120
|
exports.normalizeTreeToArray = normalizeTreeToArray;
|
|
1157
1121
|
exports.requireVersion = requireVersion;
|
|
1158
1122
|
exports.sort = sort;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap v2.1.
|
|
2
|
+
* chartjs-chart-treemap v2.1.3
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2022 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
6
6
|
*/
|
|
7
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["exports","chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-chart-treemap"]={},t.Chart,t.Chart.helpers)}(this,(function(t,e,n){"use strict";const i=t=>n.isObject(t)?t.v:t,r=t=>t.reduce((function(t,e){return t>i(e)?t:i(e)}),0),o=(t,e)=>t.reduce((function(t,e){return t<i(e)?t:i(e)}),e),s=t=>""+t;function a(t,e,i,r=[],o=0,l=[]){const h=o-1;if(t in i&&o>0){const n=r.reduce((function(t,e,n){return n!==h&&(t[s(n)]=e),t}),{});n[e]=r[h],n[t]=i[t],l.push(n)}else for(const s of Object.keys(i)){const h=i[s];n.isObject(h)&&(r.push(s),a(t,e,h,r,o+1,l))}return r.splice(h,1),l}function l(t,e,n){const i=a(t,e,n);if(!i.length)return i;const r=i.reduce((function(t,e){const n=Object.keys(e).length-2;return t>n?t:n}));return i.forEach((function(t){for(let e=0;e<r;e++){const n=s(e);t[n]||(t[n]="")}})),i}function h(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function u(t,e,n){if(!t.length)return;const i=[];for(const r of t){const t=e[r];if(""===t){i.push(n);break}i.push(t)}return i.length?i.join("."):n}function c(t,e,n,i,r,o,s=[]){const a=Object.create(null),l=Object.create(null),h=[];let c,d,p;for(d=0,p=t.length;d<p;++d){const h=t[d];r&&h[r]!==o||(c=h[e]||h[i]||"",c in a||(a[c]={value:0},l[c]=[]),a[c].value+=+h[n],a[c].label=h[e]||"",a[c].path=u(s,h,c),l[c].push(h))}return Object.keys(a).forEach((t=>{const i={children:l[t]};i[n]=+a[t].value,i[e]=a[t].label,i.label=t,i.path=a[t].path,r&&(i[r]=o),h.push(i)})),h}function d(t,e){let i,r=t.length;if(!r)return e;const o=n.isObject(t[0]);for(e=o?e:"v",i=0,r=t.length;i<r;++i)o?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}function p(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function f(t,e){let n,i,r;for(n=0,i=0,r=t.length;i<r;++i)n+=e?+t[i][e]:+t[i];return n}function g(t,e){const n=e.split(".");if(!t.split(".").reduce(((t,e,i)=>t&&e<=n[i]),!0))throw new Error(`Chart.js v${e} is not supported. v${t} or newer is required.`)}const m=(t,e)=>Math.round(t*e)/e;function x(t,e){return{...t,x:m(t.x,e),y:m(t.y,e),w:m(t.w,e),h:m(t.h,e)}}const y=new Map;function b(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function v(t,e,n){return Math.max(Math.min(t,n),e)}function w(t,e,i){const r=n.toTRBL(t);return{t:v(r.top,0,i),r:v(r.right,0,e),b:v(r.bottom,0,i),l:v(r.left,0,e)}}function _(t,e){const i=b(t),r=i.right-i.left,o=i.bottom-i.top,s=w(t.options.borderWidth,r/2,o/2),a=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:v(r.topLeft,0,o),topRight:v(r.topRight,0,o),bottomLeft:v(r.bottomLeft,0,o),bottomRight:v(r.bottomRight,0,o)}}(t.options.borderRadius,r/2,o/2),l=x({x:i.left,y:i.top,w:r,h:o,radius:a},e);return{outer:l,inner:{x:l.x+s.l,y:l.y+s.t,w:l.w-s.l-s.r,h:l.h-s.t-s.b,radius:{topLeft:Math.max(0,a.topLeft-Math.max(s.t,s.l)),topRight:Math.max(0,a.topRight-Math.max(s.t,s.r)),bottomLeft:Math.max(0,a.bottomLeft-Math.max(s.b,s.l)),bottomRight:Math.max(0,a.bottomRight-Math.max(s.b,s.r))}}}}function M(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&b(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function k(t,e){t.rect(e.x,e.y,e.w,e.h)}function R(t,e){if(!e||!1===e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=v(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function O(t,e,i,r,o){const{captions:s,labels:a}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const l=!("l"in r)||r.l===o;l&&a.display?function(t,e,i){const r=i.labels,o=r.formatter;if(!o)return;const s=n.isArray(o)?o:[o],{font:a,hoverFont:l}=r,h=(e.active?l:a)||a,u=n.isArray(h)?h.map((t=>n.toFont(t))):[n.toFont(h)],c=function(t,e,n){const i=n.reduce((function(t,e){return t+=e.string}),""),r=e.join()+i+(t._measureText?"-spriting":"");if(!y.has(r)){t.save();const i=e.length;let o=0,s=0;for(let r=0;r<i;r++){const i=n[Math.min(r,n.length-1)];t.font=i.string;const a=e[r];o=Math.max(o,t.measureText(a).width),s+=i.lineHeight}t.restore(),y.set(r,{width:o,height:s})}return y.get(r)}(t,s,u);if(!function(t,e,n,i){const{overflow:r,padding:o}=n,{width:s,height:a}=i;if("hidden"===r)return!(s+2*o>e.w||a+2*o>e.h);return!0}(0,e,r,c))return;const{color:d,hoverColor:p,align:f}=r,g=(e.active?p:d)||d,m=n.isArray(g)?g:[g],x=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=C(t,i,o),a="top"===r?t.y+o:"bottom"===r?t.y+t.h-o-n.height:t.y+(t.h-n.height)/2+o;return{x:s,y:a}}(e,r,c);t.textAlign=f,t.textBaseline="middle";let b=0;s.forEach((function(e,n){const i=m[Math.min(n,m.length-1)],r=u[Math.min(n,u.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,x.x,x.y+o/2+b),b+=o}))}(t,e,i):!l&&R(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:l,hoverColor:h,font:u,hoverFont:c,padding:d,align:p,formatter:f}=o,g=(e.active?h:l)||l,m=p||(a?"right":"left"),x=(e.active?c:u)||u,y=n.toFont(x),b=y.lineHeight/2,v=C(e,m,d);t.fillStyle=g,t.font=y.string,t.textAlign=m,t.textBaseline="middle",t.fillText(f||r.g,v,e.y+d+s+b)}(t,e,i,r),t.restore()}function C(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class j extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t,e,i=0,r){if(!e)return;const o=this.options,{inner:s,outer:a}=_(this,r),l=(h=a.radius).topLeft||h.topRight||h.bottomLeft||h.bottomRight?n.addRoundedRectPath:k;var h;t.save(),a.w===s.w&&a.h===s.h||(t.beginPath(),l(t,a),t.clip(),l(t,s),t.fillStyle=o.borderColor,t.fill("evenodd")),t.beginPath(),l(t,s),t.fillStyle=o.backgroundColor,t.fill(),function(t,e,n,i){const r=n.dividers;if(!r.display||!i._data.children.length)return;const{x:o,y:s,w:a,h:l}=e,{lineColor:h,lineCapStyle:u,lineDash:c,lineDashOffset:d,lineWidth:p}=r;if(t.save(),t.strokeStyle=h,t.lineCap=u,t.setLineDash(c),t.lineDashOffset=d,t.lineWidth=p,t.beginPath(),a>l){const e=a/2;t.moveTo(o+e,s),t.lineTo(o+e,s+l)}else{const e=l/2;t.moveTo(o,s+e),t.lineTo(o+a,s+e)}t.stroke(),t.restore()}(t,s,o,e),O(t,s,o,e,i),t.restore()}inRange(t,e,n){return M(this,t,e,n)}inXRange(t,e){return M(this,t,null,e)}inYRange(t,e){return M(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}function T(t,e,n,i,r,o){const s=t._normalized,a=e*s/n,l=m(Math.sqrt(s*a),r),h=Math.min(m(s/l,r),o);return{d1:l,d2:h,w:"_ix"===i?l:h,h:"_ix"===i?h:l}}j.id="treemap",j.defaults={label:void 0,borderRadius:0,borderWidth:0,captions:{align:void 0,color:"black",display:!0,font:{},formatter:t=>t.raw.g||t.raw._data.label||"",padding:3},dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:[],lineDashOffset:0,lineWidth:1},labels:{align:"center",color:"black",display:!1,font:{},formatter:t=>t.raw.g?[t.raw.g,t.raw.v+""]:t.raw._data.label?[t.raw._data.label,t.raw.v+""]:t.raw.v+"",overflow:"cut",position:"middle",padding:3},rtl:!1,spacing:.5},j.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},j.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const P=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function D(t,e,n,i,r){const o=x({x:P(t,n.w),y:t.y+t._iy,w:n.w,h:n.h,a:e._normalized,v:e.value,s:i,_data:e._data},r);return e.group&&(o.g=e.group,o.l=e.level,o.gs=e.groupSum),o}class L{constructor(t,e){this.dpr=e,t=t||{w:1,h:1},this.rtl=!!t.rtl,this.x=t.x||t.left||0,this.y=t.y||t.top||0,this._ix=0,this._iy=0,this.w=t.w||t.width||t.right-t.left,this.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return m("x"===this.dir?this.iw:this.ih,this.dpr)}map(t){const{dir:e,side:n,dpr:i}=this,{key:r,d2prop:o,id2prop:s,d2key:a}=function(t){if("x"===t)return{key:"_ix",d2prop:"h",id2prop:"ih",d2key:"_iy"};return{key:"_iy",d2prop:"w",id2prop:"iw",d2key:"_ix"}}(e),l=t.nsum,h=t.get(),u=n*n,c=m(this[s],i),d=l*l,p=[];let f=0,g=0;for(const e of h){const n=T(e,u,d,r,i,c);g+=n.d1,f=Math.min(Math.max(f,n.d2),c),p.push(D(this,e,n,t.sum,i)),this[r]+=n.d1}for(const t of p){const n=t[o];n!==f&&(this.rtl&&"y"===e&&(t.x-=f-n),t[o]=f)}return this[a]+=f,this[r]-=g,p}}const S=Math.min,E=Math.max;function F(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:S(t.min,n),max:E(t.max,n),sum:t.sum+n,nmin:S(t.nmin,i),nmax:E(t.nmax,i),nsum:t.nsum+i}}function A(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class V{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){A(this,t,F(this,t))}pushIf(t,e,...n){const i=F(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;A(this,t,i)}get(){return this._arr}}function z(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function H(t,e,n,i=1,r,o,s){t=t||[];const a=[],l=new L(e,i),u=new V("value",l.area/f(t,n));let c=l.side;const g=t.length;let m,x;if(!g)return a;const y=t.slice();n=d(y,n),p(y,n);const b=t=>r&&y[t][r];for(m=0;m<g;++m)x={value:(v=m,n?+y[v][n]:+y[v]),groupSum:s,_data:t[y[m]._idx],level:void 0,group:void 0},r&&(x.level=o,x.group=b(m)),x=u.pushIf(x,z,c),x&&(a.push(l.map(u)),c=l.side,u.reset(),u.push(x));var v;return u.length&&a.push(l.map(u)),h(a)}function W(t,e){const n=e?1:r(t);return{vMin:e?0:o(t,n),vMax:n}}class q extends e.DatasetController{constructor(t,e){super(t,e),this._rect=void 0,this._key=void 0,this._groups=void 0,this._useTree=void 0}initialize(){this.enableOptionSharing=!0,super.initialize()}updateRangeFromParsed(t,e){if(t.updated)return;if(t.updated=!0,"x"===e.axis)return t.min=0,void(t.max=1);const n=this.getDataset(),{vMin:i,vMax:r}=W(n.data,this._useTree);t.min=i,t.max=r}update(t){const e=this.getMeta(),i=this.getDataset(),r=this.chart.currentDevicePixelRatio;n.defined(this._useTree)||(this._useTree=!!i.tree);const o=i.groups||(i.groups=[]),a=i.key||"",h=!!i.rtl,u=x(function({xScale:t,yScale:e},n,i,r){const{vMin:o,vMax:s}=W(n,r),a=t.getPixelForValue(0),l=t.getPixelForValue(1),h=e.getPixelForValue(o),u=e.getPixelForValue(s);return{x:a,y:u,w:l-a,h:h-u,rtl:i}}(e,i.data,h,this._useTree),r);var d,p;"reset"!==t&&(d=this._rect,p=u,d&&p&&d.x===p.x&&d.y===p.y&&d.w===p.w&&d.h===p.h)&&this._key===a&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(this._groups,o)||(this._rect=u,this._groups=o.slice(),this._key=a,i.data=function(t,e,i){const r=t.key||"",o=t.treeLeafKey||"_leaf";let a=t.tree||[];n.isObject(a)&&(a=l(r,o,a));const h=t.groups||[],u=h.length,d=n.valueOrDefault(t.spacing,0),p=t.captions||{},f=n.toFont(p.font),g=n.valueOrDefault(p.padding,3);return!a.length&&t.data.length&&(a=t.tree=t.data),u?function e(n,l,m,y){const b=s(h[n]),v=n>0&&s(h[n-1]),_=c(a,b,r,o,v,m,h.filter(((t,e)=>e<=n))),M=H(_,l,r,i,b,n,y),k=M.slice();return n<u-1&&M.forEach((r=>{const o=w(t.borderWidth,r.w/2,r.h/2),s={...l,x:r.x+d+o.l,y:r.y+d+o.t,w:r.w-2*d-o.l-o.r,h:r.h-2*d-o.t-o.b};R(s,p)&&(s.y+=f.lineHeight+2*g,s.h-=f.lineHeight+2*g),k.push(...e(n+1,x(s,i),r.g,r.s))})),k}(0,e):H(a,e,r,i)}(i,u,r),this._dataCheck(),this._resyncElements()),this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),l=r.getSharedOptions(a),h=r.includeOptions(i,l);for(let a=e;a<e+n;a++){const e=s.data[a],n=l||r.resolveDataElementOptions(a,i),u=n.spacing,c=2*u,d={x:e.x+u,y:e.y+u,width:o?0:e.w-c,height:o?0:e.h-c,hidden:c>e.w||c>e.h};h&&(d.options=n),r.updateElement(t[a],a,d,i)}r.updateSharedOptions(l,i,a)}draw(){const{ctx:t,chartArea:e,currentDevicePixelRatio:i}=this.chart,r=this.getMeta().data||[],o=this.getDataset(),s=(o.groups||[]).length-1,a=o.data;n.clipArea(t,e);for(let e=0,n=r.length;e<n;++e){const n=r[e];n.hidden||n.draw(t,a[e],s,i)}n.unclipArea(t)}}q.id="treemap",q.version="2.1.1",q.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},q.descriptors={_scriptable:!0,_indexable:!1},q.overrides={interaction:{mode:"point",includeInvisible:!0,intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}},q.beforeRegister=function(){g("3.8",e.Chart.version)},q.afterRegister=function(){const t=e.registry.plugins.get("tooltip");t?t.positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()}:console.warn("Unable to register the treemap positioner because tooltip plugin is not registered")},q.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(q,j),t.flatten=h,t.getGroupKey=s,t.group=c,t.index=d,t.maxValue=r,t.minValue=o,t.normalizeTreeToArray=l,t.requireVersion=g,t.sort=p,t.sum=f,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
7
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["exports","chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-chart-treemap"]={},t.Chart,t.Chart.helpers)}(this,(function(t,e,n){"use strict";const i=t=>""+t;function r(t,e,o,s=[],a=0,h=[]){const l=a-1;if(t in o&&a>0){const n=s.reduce((function(t,e,n){return n!==l&&(t[i(n)]=e),t}),{});n[e]=s[l],n[t]=o[t],h.push(n)}else for(const i of Object.keys(o)){const l=o[i];n.isObject(l)&&(s.push(i),r(t,e,l,s,a+1,h))}return s.splice(l,1),h}function o(t,e,n){const o=r(t,e,n);if(!o.length)return o;const s=o.reduce((function(t,e){const n=Object.keys(e).length-2;return t>n?t:n}));return o.forEach((function(t){for(let e=0;e<s;e++){const n=i(e);t[n]||(t[n]="")}})),o}function s(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function a(t,e,n){if(!t.length)return;const i=[];for(const r of t){const t=e[r];if(""===t){i.push(n);break}i.push(t)}return i.length?i.join("."):n}function h(t,e,n,i,r,o,s=[]){const h=Object.create(null),l=Object.create(null),u=[];let c,d,g;for(d=0,g=t.length;d<g;++d){const u=t[d];r&&u[r]!==o||(c=u[e]||u[i]||"",c in h||(h[c]={value:0},l[c]=[]),h[c].value+=+u[n],h[c].label=u[e]||"",h[c].path=a(s,u,c),l[c].push(u))}return Object.keys(h).forEach((t=>{const i={children:l[t]};i[n]=+h[t].value,i[e]=h[t].label,i.label=t,i.path=h[t].path,r&&(i[r]=o),u.push(i)})),u}function l(t,e){let i,r=t.length;if(!r)return e;const o=n.isObject(t[0]);for(e=o?e:"v",i=0,r=t.length;i<r;++i)o?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}function u(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function c(t,e){let n,i,r;for(n=0,i=0,r=t.length;i<r;++i)n+=e?+t[i][e]:+t[i];return n}function d(t,e){const n=e.split(".");if(!t.split(".").reduce(((t,e,i)=>t&&e<=n[i]),!0))throw new Error(`Chart.js v${e} is not supported. v${t} or newer is required.`)}const g=new Map;function f(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function p(t,e,n){return Math.max(Math.min(t,n),e)}function m(t,e,i){const r=n.toTRBL(t);return{t:p(r.top,0,i),r:p(r.right,0,e),b:p(r.bottom,0,i),l:p(r.left,0,e)}}function x(t){const e=f(t),i=e.right-e.left,r=e.bottom-e.top,o=m(t.options.borderWidth,i/2,r/2),s=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:p(r.topLeft,0,o),topRight:p(r.topRight,0,o),bottomLeft:p(r.bottomLeft,0,o),bottomRight:p(r.bottomRight,0,o)}}(t.options.borderRadius,i/2,r/2),a={x:e.left,y:e.top,w:i,h:r,active:t.active,radius:s};return{outer:a,inner:{x:a.x+o.l,y:a.y+o.t,w:a.w-o.l-o.r,h:a.h-o.t-o.b,active:t.active,radius:{topLeft:Math.max(0,s.topLeft-Math.max(o.t,o.l)),topRight:Math.max(0,s.topRight-Math.max(o.t,o.r)),bottomLeft:Math.max(0,s.bottomLeft-Math.max(o.b,o.l)),bottomRight:Math.max(0,s.bottomRight-Math.max(o.b,o.r))}}}}function b(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&f(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function y(t,e){t.rect(e.x,e.y,e.w,e.h)}function v(t,e){if(!e||!1===e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=p(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function w(t,e,i,r,o){const{captions:s,labels:a}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const h=r&&(!n.defined(r.l)||r.l===o);h&&a.display?function(t,e,i){const r=i.labels,o=r.formatter;if(!o)return;const s=n.isArray(o)?o:[o],{font:a,hoverFont:h}=r,l=(e.active?h:a)||a,u=n.isArray(l)?l.map((t=>n.toFont(t))):[n.toFont(l)],c=function(t,e,n){const i=n.reduce((function(t,e){return t+=e.string}),""),r=e.join()+i+(t._measureText?"-spriting":"");if(!g.has(r)){t.save();const i=e.length;let o=0,s=0;for(let r=0;r<i;r++){const i=n[Math.min(r,n.length-1)];t.font=i.string;const a=e[r];o=Math.max(o,t.measureText(a).width),s+=i.lineHeight}t.restore(),g.set(r,{width:o,height:s})}return g.get(r)}(t,s,u);if(!function(t,e,n,i){const{overflow:r,padding:o}=n,{width:s,height:a}=i;if("hidden"===r)return!(s+2*o>e.w||a+2*o>e.h);return!0}(0,e,r,c))return;const{color:d,hoverColor:f,align:p}=r,m=(e.active?f:d)||d,x=n.isArray(m)?m:[m],b=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=_(t,i,o),a="top"===r?t.y+o:"bottom"===r?t.y+t.h-o-n.height:t.y+(t.h-n.height)/2+o;return{x:s,y:a}}(e,r,c);t.textAlign=p,t.textBaseline="middle";let y=0;s.forEach((function(e,n){const i=x[Math.min(n,x.length-1)],r=u[Math.min(n,u.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,b.x,b.y+o/2+y),y+=o}))}(t,e,i):!h&&v(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:h,hoverColor:l,font:u,hoverFont:c,padding:d,align:g,formatter:f}=o,p=(e.active?l:h)||h,m=g||(a?"right":"left"),x=(e.active?c:u)||u,b=n.toFont(x),y=b.lineHeight/2,v=_(e,m,d);t.fillStyle=p,t.font=b.string,t.textAlign=m,t.textBaseline="middle",t.fillText(f||r.g,v,e.y+d+s+y)}(t,e,i,r),t.restore()}function _(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class M extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t,e,i=0){if(!e)return;const r=this.options,{inner:o,outer:s}=x(this),a=(h=s.radius).topLeft||h.topRight||h.bottomLeft||h.bottomRight?n.addRoundedRectPath:y;var h;t.save(),s.w===o.w&&s.h===o.h||(t.beginPath(),a(t,s),t.clip(),a(t,o),t.fillStyle=r.borderColor,t.fill("evenodd")),t.beginPath(),a(t,o),t.fillStyle=r.backgroundColor,t.fill(),function(t,e,n,i){const r=n.dividers;if(!r.display||!i._data.children.length)return;const{x:o,y:s,w:a,h:h}=e,{lineColor:l,lineCapStyle:u,lineDash:c,lineDashOffset:d,lineWidth:g}=r;if(t.save(),t.strokeStyle=l,t.lineCap=u,t.setLineDash(c),t.lineDashOffset=d,t.lineWidth=g,t.beginPath(),a>h){const e=a/2;t.moveTo(o+e,s),t.lineTo(o+e,s+h)}else{const e=h/2;t.moveTo(o,s+e),t.lineTo(o+a,s+e)}t.stroke(),t.restore()}(t,o,r,e),w(t,o,r,e,i),t.restore()}inRange(t,e,n){return b(this,t,e,n)}inXRange(t,e){return b(this,t,null,e)}inYRange(t,e){return b(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}function C(t,e,n,i){const r=t._normalized,o=e*r/n,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===i?s:a,h:"_ix"===i?a:s}}M.id="treemap",M.defaults={label:void 0,borderRadius:0,borderWidth:0,captions:{align:void 0,color:"black",display:!0,font:{},formatter:t=>t.raw.g||t.raw._data.label||"",padding:3},dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:[],lineDashOffset:0,lineWidth:1},labels:{align:"center",color:"black",display:!1,font:{},formatter:t=>t.raw.g?[t.raw.g,t.raw.v+""]:t.raw._data.label?[t.raw._data.label,t.raw.v+""]:t.raw.v+"",overflow:"cut",position:"middle",padding:3},rtl:!1,spacing:.5},M.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},M.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const k=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function O(t,e,n,i){const r={x:k(t,n.w),y:t.y+t._iy,w:n.w,h:n.h,a:e._normalized,v:e.value,s:i,_data:e._data};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class R{constructor(t){t=t||{w:1,h:1},this.rtl=!!t.rtl,this.x=t.x||t.left||0,this.y=t.y||t.top||0,this._ix=0,this._iy=0,this.w=t.w||t.width||t.right-t.left,this.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return"x"===this.dir?this.iw:this.ih}map(t){const{dir:e,side:n}=this,i="x"===e?"_ix":"_iy",r=t.nsum,o=t.get(),s=n*n,a=r*r,h=[];let l=0,u=0;for(const e of o){const n=C(e,s,a,i);u+=n.d1,l=Math.max(l,n.d2),h.push(O(this,e,n,t.sum)),this[i]+=n.d1}return this["x"===e?"_iy":"_ix"]+=l,this[i]-=u,h}}const j=Math.min,T=Math.max;function P(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:j(t.min,n),max:T(t.max,n),sum:t.sum+n,nmin:j(t.nmin,i),nmax:T(t.nmax,i),nsum:t.nsum+i}}function S(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class D{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){S(this,t,P(this,t))}pushIf(t,e,...n){const i=P(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;S(this,t,i)}get(){return this._arr}}function L(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function E(t,e,n,i,r,o){t=t||[];const a=[],h=new R(e),d=new D("value",h.area/c(t,n));let g=h.side;const f=t.length;let p,m;if(!f)return a;const x=t.slice();n=l(x,n),u(x,n);const b=t=>i&&x[t][i];for(p=0;p<f;++p)m={value:(y=p,n?+x[y][n]:+x[y]),groupSum:o,_data:t[x[p]._idx],level:void 0,group:void 0},i&&(m.level=r,m.group=b(p)),m=d.pushIf(m,L,g),m&&(a.push(h.map(d)),g=h.side,d.reset(),d.push(m));var y;return d.length&&a.push(h.map(d)),s(a)}function A(t,e,n,i){const r=2*i,o=e.getPixelForValue(t.x),s=n.getPixelForValue(t.y),a=e.getPixelForValue(t.x+t.w)-o,h=n.getPixelForValue(t.y+t.h)-s;return{x:o+i,y:s+i,width:a-r,height:h-r,hidden:r>a||r>h}}class F extends e.DatasetController{constructor(t,e){super(t,e),this._groups=void 0,this._key=void 0,this._rect=void 0,this._rectChanged=!0}initialize(){this.enableOptionSharing=!0,super.initialize()}getMinMax(t){return{min:0,max:"x"===t.axis?t.right-t.left:t.bottom-t.top}}configure(){super.configure();const{xScale:t,yScale:e}=this.getMeta();if(!t||!e)return;const n=t.right-t.left,i=e.bottom-e.top,r={x:0,y:0,w:n,h:i,rtl:!!this.options.rtl};var o,s;o=this._rect,s=r,o&&s&&o.x===s.x&&o.y===s.y&&o.w===s.w&&o.h===s.h&&o.rtl===s.rtl||(this._rect=r,this._rectChanged=!0),this._rectChanged&&(t.max=n,t.configure(),e.max=i,e.configure())}update(t){const e=this.getDataset(),{data:r}=this.getMeta(),s=e.groups||(e.groups=[]),a=e.key,l=e.tree=e.tree||e.data||[];"reset"===t&&this.configure(),(this._rectChanged||this._key!==a||function(t,e){let n,i;if(!t||!e)return!0;if(t===e)return!1;if(t.length!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(this._groups,s)||this._prevTree!==l)&&(this._groups=s.slice(),this._key=a,this._prevTree=l,this._rectChanged=!1,e.data=function(t,e,r){const s=e.key||"",a=e.treeLeafKey||"_leaf";n.isObject(t)&&(t=o(s,a,t));const l=e.groups||[],u=l.length,c=n.valueOrDefault(e.spacing,0),d=e.captions||{},g=n.toFont(d.font),f=n.valueOrDefault(d.padding,3);return u?function n(r,o,p,x){const b=i(l[r]),y=r>0&&i(l[r-1]),w=h(t,b,s,a,y,p,l.filter(((t,e)=>e<=r))),_=E(w,o,s,b,r,x),M=_.slice();return r<u-1&&_.forEach((t=>{const i=m(e.borderWidth,t.w/2,t.h/2),s={...o,x:t.x+c+i.l,y:t.y+c+i.t,w:t.w-2*c-i.l-i.r,h:t.h-2*c-i.t-i.b};v(s,d)&&(s.y+=g.lineHeight+2*f,s.h-=g.lineHeight+2*f),M.push(...n(r+1,s,t.g,t.s))})),M}(0,r):E(t,r,s)}(l,e,this._rect),this._dataCheck(),this._resyncElements()),this.updateElements(r,0,r.length,t)}updateElements(t,e,n,i){const r="reset"===i,o=this.getDataset(),s=this._rect.options=this.resolveDataElementOptions(e,i),a=this.getSharedOptions(s),h=this.includeOptions(i,a),{xScale:l,yScale:u}=this.getMeta(this.index);for(let s=e;s<e+n;s++){const e=a||this.resolveDataElementOptions(s,i),n=A(o.data[s],l,u,e.spacing);r&&(n.width=0,n.height=0),h&&(n.options=e),this.updateElement(t[s],s,n,i)}this.updateSharedOptions(a,i,s)}draw(){const{ctx:t,chartArea:e}=this.chart,i=this.getMeta().data||[],r=this.getDataset(),o=(r.groups||[]).length-1,s=r.data;n.clipArea(t,e);for(let e=0,n=i.length;e<n;++e){const n=i[e];n.hidden||n.draw(t,s[e],o)}n.unclipArea(t)}}F.id="treemap",F.version="2.1.3",F.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},F.descriptors={_scriptable:!0,_indexable:!1},F.overrides={interaction:{mode:"point",includeInvisible:!0,intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",alignToPixels:!0,bounds:"data",display:!1},y:{type:"linear",alignToPixels:!0,bounds:"data",display:!1,reverse:!0}}},F.beforeRegister=function(){d("3.8",e.Chart.version)},F.afterRegister=function(){const t=e.registry.plugins.get("tooltip");t?t.positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()}:console.warn("Unable to register the treemap positioner because tooltip plugin is not registered")},F.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(F,M),t.flatten=s,t.getGroupKey=i,t.group=h,t.index=l,t.normalizeTreeToArray=o,t.requireVersion=d,t.sort=u,t.sum=c,Object.defineProperty(t,"__esModule",{value:!0})}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs-chart-treemap",
|
|
3
3
|
"homepage": "https://chartjs-chart-treemap.pages.dev/",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.3",
|
|
5
5
|
"description": "Chart.js module for creating treemap charts",
|
|
6
6
|
"main": "dist/chartjs-chart-treemap.js",
|
|
7
7
|
"module": "dist/chartjs-chart-treemap.esm.js",
|