chartjs-chart-treemap 2.1.2 → 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 +125 -161
- package/dist/chartjs-chart-treemap.js +124 -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,20 +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,
|
|
259
237
|
active: rect.active,
|
|
260
238
|
radius
|
|
261
|
-
}
|
|
239
|
+
};
|
|
262
240
|
|
|
263
241
|
return {
|
|
264
242
|
outer,
|
|
@@ -318,7 +296,7 @@ function drawText(ctx, rect, options, item, levels) {
|
|
|
318
296
|
ctx.beginPath();
|
|
319
297
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
320
298
|
ctx.clip();
|
|
321
|
-
const isLeaf = (!(
|
|
299
|
+
const isLeaf = item && (!defined(item.l) || item.l === levels);
|
|
322
300
|
if (isLeaf && labels.display) {
|
|
323
301
|
drawLabel(ctx, rect, options);
|
|
324
302
|
} else if (!isLeaf && shouldDrawCaption(rect, captions)) {
|
|
@@ -472,12 +450,12 @@ class TreemapElement extends Element {
|
|
|
472
450
|
}
|
|
473
451
|
}
|
|
474
452
|
|
|
475
|
-
draw(ctx, data, levels = 0
|
|
453
|
+
draw(ctx, data, levels = 0) {
|
|
476
454
|
if (!data) {
|
|
477
455
|
return;
|
|
478
456
|
}
|
|
479
457
|
const options = this.options;
|
|
480
|
-
const {inner, outer} = boundingRects(this
|
|
458
|
+
const {inner, outer} = boundingRects(this);
|
|
481
459
|
|
|
482
460
|
const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
|
|
483
461
|
|
|
@@ -591,11 +569,11 @@ TreemapElement.defaultRoutes = {
|
|
|
591
569
|
borderColor: 'borderColor'
|
|
592
570
|
};
|
|
593
571
|
|
|
594
|
-
function getDims(itm, w2, s2, key
|
|
572
|
+
function getDims(itm, w2, s2, key) {
|
|
595
573
|
const a = itm._normalized;
|
|
596
574
|
const ar = w2 * a / s2;
|
|
597
|
-
const d1 =
|
|
598
|
-
const d2 =
|
|
575
|
+
const d1 = Math.sqrt(a * ar);
|
|
576
|
+
const d2 = a / d1;
|
|
599
577
|
const w = key === '_ix' ? d1 : d2;
|
|
600
578
|
const h = key === '_ix' ? d2 : d1;
|
|
601
579
|
|
|
@@ -604,8 +582,8 @@ function getDims(itm, w2, s2, key, dpr, maxd2) {
|
|
|
604
582
|
|
|
605
583
|
const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
606
584
|
|
|
607
|
-
function buildRow(rect, itm, dims, sum
|
|
608
|
-
const r =
|
|
585
|
+
function buildRow(rect, itm, dims, sum) {
|
|
586
|
+
const r = {
|
|
609
587
|
x: getX(rect, dims.w),
|
|
610
588
|
y: rect.y + rect._iy,
|
|
611
589
|
w: dims.w,
|
|
@@ -614,7 +592,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
614
592
|
v: itm.value,
|
|
615
593
|
s: sum,
|
|
616
594
|
_data: itm._data
|
|
617
|
-
}
|
|
595
|
+
};
|
|
618
596
|
if (itm.group) {
|
|
619
597
|
r.g = itm.group;
|
|
620
598
|
r.l = itm.level;
|
|
@@ -624,8 +602,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
624
602
|
}
|
|
625
603
|
|
|
626
604
|
class Rect {
|
|
627
|
-
constructor(r
|
|
628
|
-
this.dpr = dpr;
|
|
605
|
+
constructor(r) {
|
|
629
606
|
r = r || {w: 1, h: 1};
|
|
630
607
|
this.rtl = !!r.rtl;
|
|
631
608
|
this.x = r.x || r.left || 0;
|
|
@@ -654,61 +631,33 @@ class Rect {
|
|
|
654
631
|
}
|
|
655
632
|
|
|
656
633
|
get side() {
|
|
657
|
-
return
|
|
634
|
+
return this.dir === 'x' ? this.iw : this.ih;
|
|
658
635
|
}
|
|
659
636
|
|
|
660
637
|
map(arr) {
|
|
661
|
-
const {dir, side
|
|
662
|
-
const
|
|
638
|
+
const {dir, side} = this;
|
|
639
|
+
const key = dir === 'x' ? '_ix' : '_iy';
|
|
663
640
|
const sum = arr.nsum;
|
|
664
641
|
const row = arr.get();
|
|
665
642
|
const w2 = side * side;
|
|
666
|
-
const availd2 = rasterize(this[id2prop], dpr);
|
|
667
643
|
const s2 = sum * sum;
|
|
668
644
|
const ret = [];
|
|
669
645
|
let maxd2 = 0;
|
|
670
646
|
let totd1 = 0;
|
|
671
647
|
for (const itm of row) {
|
|
672
|
-
const dims = getDims(itm, w2, s2, key
|
|
648
|
+
const dims = getDims(itm, w2, s2, key);
|
|
673
649
|
totd1 += dims.d1;
|
|
674
|
-
maxd2 = Math.
|
|
675
|
-
ret.push(buildRow(this, itm, dims, arr.sum
|
|
650
|
+
maxd2 = Math.max(maxd2, dims.d2);
|
|
651
|
+
ret.push(buildRow(this, itm, dims, arr.sum));
|
|
676
652
|
this[key] += dims.d1;
|
|
677
653
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const d2 = r[d2prop];
|
|
681
|
-
if (d2 !== maxd2) {
|
|
682
|
-
if (this.rtl && dir === 'y') {
|
|
683
|
-
// for RTL, x-coordinate needs to be adjusted too
|
|
684
|
-
r.x -= maxd2 - d2;
|
|
685
|
-
}
|
|
686
|
-
r[d2prop] = maxd2;
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
this[d2key] += maxd2;
|
|
654
|
+
|
|
655
|
+
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
690
656
|
this[key] -= totd1;
|
|
691
657
|
return ret;
|
|
692
658
|
}
|
|
693
659
|
}
|
|
694
660
|
|
|
695
|
-
function getPropNames(dir) {
|
|
696
|
-
if (dir === 'x') {
|
|
697
|
-
return {
|
|
698
|
-
key: '_ix',
|
|
699
|
-
d2prop: 'h',
|
|
700
|
-
id2prop: 'ih',
|
|
701
|
-
d2key: '_iy'
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
return {
|
|
705
|
-
key: '_iy',
|
|
706
|
-
d2prop: 'w',
|
|
707
|
-
id2prop: 'iw',
|
|
708
|
-
d2key: '_ix'
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
|
|
712
661
|
const min = Math.min;
|
|
713
662
|
const max = Math.max;
|
|
714
663
|
|
|
@@ -807,15 +756,14 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
807
756
|
* @param {number[]|object[]} values
|
|
808
757
|
* @param {object} rectangle
|
|
809
758
|
* @param {string} [key]
|
|
810
|
-
* @param {
|
|
811
|
-
* @param {
|
|
812
|
-
* @param {
|
|
813
|
-
* @param {*} [gsum]
|
|
759
|
+
* @param {string} [grp]
|
|
760
|
+
* @param {number} [lvl]
|
|
761
|
+
* @param {number} [gsum]
|
|
814
762
|
*/
|
|
815
|
-
function squarify(values, rectangle, key,
|
|
763
|
+
function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
816
764
|
values = values || [];
|
|
817
765
|
const rows = [];
|
|
818
|
-
const rect = new Rect(rectangle
|
|
766
|
+
const rect = new Rect(rectangle);
|
|
819
767
|
const row = new StatArray('value', rect.area / sum(values, key));
|
|
820
768
|
let length = rect.side;
|
|
821
769
|
const n = values.length;
|
|
@@ -852,35 +800,58 @@ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
|
|
|
852
800
|
return flatten(rows);
|
|
853
801
|
}
|
|
854
802
|
|
|
855
|
-
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
|
+
}
|
|
856
819
|
|
|
857
820
|
function rectNotEqual(r1, r2) {
|
|
858
821
|
return !r1 || !r2
|
|
859
822
|
|| r1.x !== r2.x
|
|
860
823
|
|| r1.y !== r2.y
|
|
861
824
|
|| r1.w !== r2.w
|
|
862
|
-
|| r1.h !== r2.h
|
|
825
|
+
|| r1.h !== r2.h
|
|
826
|
+
|| r1.rtl !== r2.rtl;
|
|
863
827
|
}
|
|
864
828
|
|
|
865
|
-
function arrayNotEqual(
|
|
829
|
+
function arrayNotEqual(a, b) {
|
|
866
830
|
let i, n;
|
|
867
831
|
|
|
868
|
-
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) {
|
|
869
841
|
return true;
|
|
870
842
|
}
|
|
871
843
|
|
|
872
|
-
for (i = 0, n =
|
|
873
|
-
if (
|
|
844
|
+
for (i = 0, n = a.length; i < n; ++i) {
|
|
845
|
+
if (a[i] !== b[i]) {
|
|
874
846
|
return true;
|
|
875
847
|
}
|
|
876
848
|
}
|
|
877
849
|
return false;
|
|
878
850
|
}
|
|
879
851
|
|
|
880
|
-
function buildData(dataset, mainRect
|
|
852
|
+
function buildData(tree, dataset, mainRect) {
|
|
881
853
|
const key = dataset.key || '';
|
|
882
854
|
const treeLeafKey = dataset.treeLeafKey || '_leaf';
|
|
883
|
-
let tree = dataset.tree || [];
|
|
884
855
|
if (isObject(tree)) {
|
|
885
856
|
tree = normalizeTreeToArray(key, treeLeafKey, tree);
|
|
886
857
|
}
|
|
@@ -895,7 +866,7 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
895
866
|
const g = getGroupKey(groups[gidx]);
|
|
896
867
|
const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
|
|
897
868
|
const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
|
|
898
|
-
const gsq = squarify(gdata, rect, key,
|
|
869
|
+
const gsq = squarify(gdata, rect, key, g, gidx, gs);
|
|
899
870
|
const ret = gsq.slice();
|
|
900
871
|
if (gidx < glen - 1) {
|
|
901
872
|
gsq.forEach((sq) => {
|
|
@@ -911,44 +882,25 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
911
882
|
subRect.y += font.lineHeight + padding * 2;
|
|
912
883
|
subRect.h -= font.lineHeight + padding * 2;
|
|
913
884
|
}
|
|
914
|
-
ret.push(...recur(gidx + 1,
|
|
885
|
+
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
915
886
|
});
|
|
916
887
|
}
|
|
917
888
|
return ret;
|
|
918
889
|
}
|
|
919
890
|
|
|
920
|
-
if (!tree.length && dataset.data.length) {
|
|
921
|
-
tree = dataset.tree = dataset.data;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
891
|
return glen
|
|
925
892
|
? recur(0, mainRect)
|
|
926
|
-
: squarify(tree, mainRect, key
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
function getMinMax(data, useTree) {
|
|
930
|
-
const vMax = useTree ? 1 : maxValue(data);
|
|
931
|
-
const vMin = useTree ? 0 : minValue(data, vMax);
|
|
932
|
-
return {vMin, vMax};
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
function getArea({xScale, yScale}, data, rtl, useTree) {
|
|
936
|
-
const {vMin, vMax} = getMinMax(data, useTree);
|
|
937
|
-
const xMin = xScale.getPixelForValue(0);
|
|
938
|
-
const xMax = xScale.getPixelForValue(1);
|
|
939
|
-
const yMin = yScale.getPixelForValue(vMin);
|
|
940
|
-
const yMax = yScale.getPixelForValue(vMax);
|
|
941
|
-
return {x: xMin, y: yMax, w: xMax - xMin, h: yMin - yMax, rtl};
|
|
893
|
+
: squarify(tree, mainRect, key);
|
|
942
894
|
}
|
|
943
895
|
|
|
944
896
|
class TreemapController extends DatasetController {
|
|
945
897
|
constructor(chart, datasetIndex) {
|
|
946
898
|
super(chart, datasetIndex);
|
|
947
899
|
|
|
948
|
-
this._rect = undefined;
|
|
949
|
-
this._key = undefined;
|
|
950
900
|
this._groups = undefined;
|
|
951
|
-
this.
|
|
901
|
+
this._key = undefined;
|
|
902
|
+
this._rect = undefined;
|
|
903
|
+
this._rectChanged = true;
|
|
952
904
|
}
|
|
953
905
|
|
|
954
906
|
initialize() {
|
|
@@ -956,86 +908,93 @@ class TreemapController extends DatasetController {
|
|
|
956
908
|
super.initialize();
|
|
957
909
|
}
|
|
958
910
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
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
|
|
964
923
|
return;
|
|
965
924
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
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();
|
|
971
940
|
}
|
|
972
|
-
const dataset = this.getDataset();
|
|
973
|
-
const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
|
|
974
|
-
range.min = vMin;
|
|
975
|
-
range.max = vMax;
|
|
976
941
|
}
|
|
977
942
|
|
|
978
943
|
update(mode) {
|
|
979
|
-
const meta = this.getMeta();
|
|
980
944
|
const dataset = this.getDataset();
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
if (!defined(this._useTree)) {
|
|
984
|
-
this._useTree = !!dataset.tree;
|
|
985
|
-
}
|
|
945
|
+
const {data} = this.getMeta();
|
|
986
946
|
const groups = dataset.groups || (dataset.groups = []);
|
|
987
|
-
const key = dataset.key
|
|
988
|
-
const
|
|
947
|
+
const key = dataset.key;
|
|
948
|
+
const tree = dataset.tree = dataset.tree || dataset.data || [];
|
|
989
949
|
|
|
990
|
-
|
|
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
|
+
}
|
|
991
954
|
|
|
992
|
-
if (
|
|
993
|
-
this._rect = mainRect;
|
|
955
|
+
if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
|
|
994
956
|
this._groups = groups.slice();
|
|
995
957
|
this._key = key;
|
|
958
|
+
this._prevTree = tree;
|
|
959
|
+
this._rectChanged = false;
|
|
996
960
|
|
|
997
|
-
dataset.data = buildData(
|
|
961
|
+
dataset.data = buildData(tree, dataset, this._rect);
|
|
998
962
|
// @ts-ignore using private stuff
|
|
999
963
|
this._dataCheck();
|
|
1000
964
|
// @ts-ignore using private stuff
|
|
1001
965
|
this._resyncElements();
|
|
1002
966
|
}
|
|
1003
967
|
|
|
1004
|
-
this.updateElements(
|
|
968
|
+
this.updateElements(data, 0, data.length, mode);
|
|
1005
969
|
}
|
|
1006
970
|
|
|
1007
971
|
updateElements(rects, start, count, mode) {
|
|
1008
|
-
const me = this;
|
|
1009
972
|
const reset = mode === 'reset';
|
|
1010
|
-
const dataset =
|
|
1011
|
-
const firstOpts =
|
|
1012
|
-
const sharedOptions =
|
|
1013
|
-
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);
|
|
1014
978
|
|
|
1015
979
|
for (let i = start; i < start + count; i++) {
|
|
1016
|
-
const
|
|
1017
|
-
const
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
y: sq.y + sp,
|
|
1023
|
-
width: reset ? 0 : sq.w - sp2,
|
|
1024
|
-
height: reset ? 0 : sq.h - sp2,
|
|
1025
|
-
hidden: sp2 > sq.w || sp2 > sq.h,
|
|
1026
|
-
};
|
|
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
|
+
}
|
|
1027
986
|
|
|
1028
987
|
if (includeOptions) {
|
|
1029
988
|
properties.options = options;
|
|
1030
989
|
}
|
|
1031
|
-
|
|
990
|
+
this.updateElement(rects[i], i, properties, mode);
|
|
1032
991
|
}
|
|
1033
992
|
|
|
1034
|
-
|
|
993
|
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
|
1035
994
|
}
|
|
1036
995
|
|
|
1037
996
|
draw() {
|
|
1038
|
-
const {ctx, chartArea
|
|
997
|
+
const {ctx, chartArea} = this.chart;
|
|
1039
998
|
const metadata = this.getMeta().data || [];
|
|
1040
999
|
const dataset = this.getDataset();
|
|
1041
1000
|
const levels = (dataset.groups || []).length - 1;
|
|
@@ -1045,7 +1004,7 @@ class TreemapController extends DatasetController {
|
|
|
1045
1004
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
1046
1005
|
const rect = metadata[i];
|
|
1047
1006
|
if (!rect.hidden) {
|
|
1048
|
-
rect.draw(ctx, data[i], levels
|
|
1007
|
+
rect.draw(ctx, data[i], levels);
|
|
1049
1008
|
}
|
|
1050
1009
|
}
|
|
1051
1010
|
unclipArea(ctx);
|
|
@@ -1106,11 +1065,16 @@ TreemapController.overrides = {
|
|
|
1106
1065
|
scales: {
|
|
1107
1066
|
x: {
|
|
1108
1067
|
type: 'linear',
|
|
1068
|
+
alignToPixels: true,
|
|
1069
|
+
bounds: 'data',
|
|
1109
1070
|
display: false
|
|
1110
1071
|
},
|
|
1111
1072
|
y: {
|
|
1112
1073
|
type: 'linear',
|
|
1113
|
-
|
|
1074
|
+
alignToPixels: true,
|
|
1075
|
+
bounds: 'data',
|
|
1076
|
+
display: false,
|
|
1077
|
+
reverse: true
|
|
1114
1078
|
}
|
|
1115
1079
|
},
|
|
1116
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,20 +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,
|
|
262
240
|
active: rect.active,
|
|
263
241
|
radius
|
|
264
|
-
}
|
|
242
|
+
};
|
|
265
243
|
|
|
266
244
|
return {
|
|
267
245
|
outer,
|
|
@@ -321,7 +299,7 @@ function drawText(ctx, rect, options, item, levels) {
|
|
|
321
299
|
ctx.beginPath();
|
|
322
300
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
323
301
|
ctx.clip();
|
|
324
|
-
const isLeaf = (!(
|
|
302
|
+
const isLeaf = item && (!helpers.defined(item.l) || item.l === levels);
|
|
325
303
|
if (isLeaf && labels.display) {
|
|
326
304
|
drawLabel(ctx, rect, options);
|
|
327
305
|
} else if (!isLeaf && shouldDrawCaption(rect, captions)) {
|
|
@@ -475,12 +453,12 @@ class TreemapElement extends chart_js.Element {
|
|
|
475
453
|
}
|
|
476
454
|
}
|
|
477
455
|
|
|
478
|
-
draw(ctx, data, levels = 0
|
|
456
|
+
draw(ctx, data, levels = 0) {
|
|
479
457
|
if (!data) {
|
|
480
458
|
return;
|
|
481
459
|
}
|
|
482
460
|
const options = this.options;
|
|
483
|
-
const {inner, outer} = boundingRects(this
|
|
461
|
+
const {inner, outer} = boundingRects(this);
|
|
484
462
|
|
|
485
463
|
const addRectPath = hasRadius(outer.radius) ? helpers.addRoundedRectPath : addNormalRectPath;
|
|
486
464
|
|
|
@@ -594,11 +572,11 @@ TreemapElement.defaultRoutes = {
|
|
|
594
572
|
borderColor: 'borderColor'
|
|
595
573
|
};
|
|
596
574
|
|
|
597
|
-
function getDims(itm, w2, s2, key
|
|
575
|
+
function getDims(itm, w2, s2, key) {
|
|
598
576
|
const a = itm._normalized;
|
|
599
577
|
const ar = w2 * a / s2;
|
|
600
|
-
const d1 =
|
|
601
|
-
const d2 =
|
|
578
|
+
const d1 = Math.sqrt(a * ar);
|
|
579
|
+
const d2 = a / d1;
|
|
602
580
|
const w = key === '_ix' ? d1 : d2;
|
|
603
581
|
const h = key === '_ix' ? d2 : d1;
|
|
604
582
|
|
|
@@ -607,8 +585,8 @@ function getDims(itm, w2, s2, key, dpr, maxd2) {
|
|
|
607
585
|
|
|
608
586
|
const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
|
|
609
587
|
|
|
610
|
-
function buildRow(rect, itm, dims, sum
|
|
611
|
-
const r =
|
|
588
|
+
function buildRow(rect, itm, dims, sum) {
|
|
589
|
+
const r = {
|
|
612
590
|
x: getX(rect, dims.w),
|
|
613
591
|
y: rect.y + rect._iy,
|
|
614
592
|
w: dims.w,
|
|
@@ -617,7 +595,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
617
595
|
v: itm.value,
|
|
618
596
|
s: sum,
|
|
619
597
|
_data: itm._data
|
|
620
|
-
}
|
|
598
|
+
};
|
|
621
599
|
if (itm.group) {
|
|
622
600
|
r.g = itm.group;
|
|
623
601
|
r.l = itm.level;
|
|
@@ -627,8 +605,7 @@ function buildRow(rect, itm, dims, sum, dpr) {
|
|
|
627
605
|
}
|
|
628
606
|
|
|
629
607
|
class Rect {
|
|
630
|
-
constructor(r
|
|
631
|
-
this.dpr = dpr;
|
|
608
|
+
constructor(r) {
|
|
632
609
|
r = r || {w: 1, h: 1};
|
|
633
610
|
this.rtl = !!r.rtl;
|
|
634
611
|
this.x = r.x || r.left || 0;
|
|
@@ -657,61 +634,33 @@ class Rect {
|
|
|
657
634
|
}
|
|
658
635
|
|
|
659
636
|
get side() {
|
|
660
|
-
return
|
|
637
|
+
return this.dir === 'x' ? this.iw : this.ih;
|
|
661
638
|
}
|
|
662
639
|
|
|
663
640
|
map(arr) {
|
|
664
|
-
const {dir, side
|
|
665
|
-
const
|
|
641
|
+
const {dir, side} = this;
|
|
642
|
+
const key = dir === 'x' ? '_ix' : '_iy';
|
|
666
643
|
const sum = arr.nsum;
|
|
667
644
|
const row = arr.get();
|
|
668
645
|
const w2 = side * side;
|
|
669
|
-
const availd2 = rasterize(this[id2prop], dpr);
|
|
670
646
|
const s2 = sum * sum;
|
|
671
647
|
const ret = [];
|
|
672
648
|
let maxd2 = 0;
|
|
673
649
|
let totd1 = 0;
|
|
674
650
|
for (const itm of row) {
|
|
675
|
-
const dims = getDims(itm, w2, s2, key
|
|
651
|
+
const dims = getDims(itm, w2, s2, key);
|
|
676
652
|
totd1 += dims.d1;
|
|
677
|
-
maxd2 = Math.
|
|
678
|
-
ret.push(buildRow(this, itm, dims, arr.sum
|
|
653
|
+
maxd2 = Math.max(maxd2, dims.d2);
|
|
654
|
+
ret.push(buildRow(this, itm, dims, arr.sum));
|
|
679
655
|
this[key] += dims.d1;
|
|
680
656
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
const d2 = r[d2prop];
|
|
684
|
-
if (d2 !== maxd2) {
|
|
685
|
-
if (this.rtl && dir === 'y') {
|
|
686
|
-
// for RTL, x-coordinate needs to be adjusted too
|
|
687
|
-
r.x -= maxd2 - d2;
|
|
688
|
-
}
|
|
689
|
-
r[d2prop] = maxd2;
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
this[d2key] += maxd2;
|
|
657
|
+
|
|
658
|
+
this[dir === 'x' ? '_iy' : '_ix'] += maxd2;
|
|
693
659
|
this[key] -= totd1;
|
|
694
660
|
return ret;
|
|
695
661
|
}
|
|
696
662
|
}
|
|
697
663
|
|
|
698
|
-
function getPropNames(dir) {
|
|
699
|
-
if (dir === 'x') {
|
|
700
|
-
return {
|
|
701
|
-
key: '_ix',
|
|
702
|
-
d2prop: 'h',
|
|
703
|
-
id2prop: 'ih',
|
|
704
|
-
d2key: '_iy'
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
return {
|
|
708
|
-
key: '_iy',
|
|
709
|
-
d2prop: 'w',
|
|
710
|
-
id2prop: 'iw',
|
|
711
|
-
d2key: '_ix'
|
|
712
|
-
};
|
|
713
|
-
}
|
|
714
|
-
|
|
715
664
|
const min = Math.min;
|
|
716
665
|
const max = Math.max;
|
|
717
666
|
|
|
@@ -810,15 +759,14 @@ function compareAspectRatio(oldStat, newStat, args) {
|
|
|
810
759
|
* @param {number[]|object[]} values
|
|
811
760
|
* @param {object} rectangle
|
|
812
761
|
* @param {string} [key]
|
|
813
|
-
* @param {
|
|
814
|
-
* @param {
|
|
815
|
-
* @param {
|
|
816
|
-
* @param {*} [gsum]
|
|
762
|
+
* @param {string} [grp]
|
|
763
|
+
* @param {number} [lvl]
|
|
764
|
+
* @param {number} [gsum]
|
|
817
765
|
*/
|
|
818
|
-
function squarify(values, rectangle, key,
|
|
766
|
+
function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
819
767
|
values = values || [];
|
|
820
768
|
const rows = [];
|
|
821
|
-
const rect = new Rect(rectangle
|
|
769
|
+
const rect = new Rect(rectangle);
|
|
822
770
|
const row = new StatArray('value', rect.area / sum(values, key));
|
|
823
771
|
let length = rect.side;
|
|
824
772
|
const n = values.length;
|
|
@@ -855,35 +803,58 @@ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
|
|
|
855
803
|
return flatten(rows);
|
|
856
804
|
}
|
|
857
805
|
|
|
858
|
-
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
|
+
}
|
|
859
822
|
|
|
860
823
|
function rectNotEqual(r1, r2) {
|
|
861
824
|
return !r1 || !r2
|
|
862
825
|
|| r1.x !== r2.x
|
|
863
826
|
|| r1.y !== r2.y
|
|
864
827
|
|| r1.w !== r2.w
|
|
865
|
-
|| r1.h !== r2.h
|
|
828
|
+
|| r1.h !== r2.h
|
|
829
|
+
|| r1.rtl !== r2.rtl;
|
|
866
830
|
}
|
|
867
831
|
|
|
868
|
-
function arrayNotEqual(
|
|
832
|
+
function arrayNotEqual(a, b) {
|
|
869
833
|
let i, n;
|
|
870
834
|
|
|
871
|
-
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) {
|
|
872
844
|
return true;
|
|
873
845
|
}
|
|
874
846
|
|
|
875
|
-
for (i = 0, n =
|
|
876
|
-
if (
|
|
847
|
+
for (i = 0, n = a.length; i < n; ++i) {
|
|
848
|
+
if (a[i] !== b[i]) {
|
|
877
849
|
return true;
|
|
878
850
|
}
|
|
879
851
|
}
|
|
880
852
|
return false;
|
|
881
853
|
}
|
|
882
854
|
|
|
883
|
-
function buildData(dataset, mainRect
|
|
855
|
+
function buildData(tree, dataset, mainRect) {
|
|
884
856
|
const key = dataset.key || '';
|
|
885
857
|
const treeLeafKey = dataset.treeLeafKey || '_leaf';
|
|
886
|
-
let tree = dataset.tree || [];
|
|
887
858
|
if (helpers.isObject(tree)) {
|
|
888
859
|
tree = normalizeTreeToArray(key, treeLeafKey, tree);
|
|
889
860
|
}
|
|
@@ -898,7 +869,7 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
898
869
|
const g = getGroupKey(groups[gidx]);
|
|
899
870
|
const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
|
|
900
871
|
const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
|
|
901
|
-
const gsq = squarify(gdata, rect, key,
|
|
872
|
+
const gsq = squarify(gdata, rect, key, g, gidx, gs);
|
|
902
873
|
const ret = gsq.slice();
|
|
903
874
|
if (gidx < glen - 1) {
|
|
904
875
|
gsq.forEach((sq) => {
|
|
@@ -914,44 +885,25 @@ function buildData(dataset, mainRect, dpr) {
|
|
|
914
885
|
subRect.y += font.lineHeight + padding * 2;
|
|
915
886
|
subRect.h -= font.lineHeight + padding * 2;
|
|
916
887
|
}
|
|
917
|
-
ret.push(...recur(gidx + 1,
|
|
888
|
+
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
918
889
|
});
|
|
919
890
|
}
|
|
920
891
|
return ret;
|
|
921
892
|
}
|
|
922
893
|
|
|
923
|
-
if (!tree.length && dataset.data.length) {
|
|
924
|
-
tree = dataset.tree = dataset.data;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
894
|
return glen
|
|
928
895
|
? recur(0, mainRect)
|
|
929
|
-
: squarify(tree, mainRect, key
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
function getMinMax(data, useTree) {
|
|
933
|
-
const vMax = useTree ? 1 : maxValue(data);
|
|
934
|
-
const vMin = useTree ? 0 : minValue(data, vMax);
|
|
935
|
-
return {vMin, vMax};
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
function getArea({xScale, yScale}, data, rtl, useTree) {
|
|
939
|
-
const {vMin, vMax} = getMinMax(data, useTree);
|
|
940
|
-
const xMin = xScale.getPixelForValue(0);
|
|
941
|
-
const xMax = xScale.getPixelForValue(1);
|
|
942
|
-
const yMin = yScale.getPixelForValue(vMin);
|
|
943
|
-
const yMax = yScale.getPixelForValue(vMax);
|
|
944
|
-
return {x: xMin, y: yMax, w: xMax - xMin, h: yMin - yMax, rtl};
|
|
896
|
+
: squarify(tree, mainRect, key);
|
|
945
897
|
}
|
|
946
898
|
|
|
947
899
|
class TreemapController extends chart_js.DatasetController {
|
|
948
900
|
constructor(chart, datasetIndex) {
|
|
949
901
|
super(chart, datasetIndex);
|
|
950
902
|
|
|
951
|
-
this._rect = undefined;
|
|
952
|
-
this._key = undefined;
|
|
953
903
|
this._groups = undefined;
|
|
954
|
-
this.
|
|
904
|
+
this._key = undefined;
|
|
905
|
+
this._rect = undefined;
|
|
906
|
+
this._rectChanged = true;
|
|
955
907
|
}
|
|
956
908
|
|
|
957
909
|
initialize() {
|
|
@@ -959,86 +911,93 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
959
911
|
super.initialize();
|
|
960
912
|
}
|
|
961
913
|
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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
|
|
967
926
|
return;
|
|
968
927
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
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();
|
|
974
943
|
}
|
|
975
|
-
const dataset = this.getDataset();
|
|
976
|
-
const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
|
|
977
|
-
range.min = vMin;
|
|
978
|
-
range.max = vMax;
|
|
979
944
|
}
|
|
980
945
|
|
|
981
946
|
update(mode) {
|
|
982
|
-
const meta = this.getMeta();
|
|
983
947
|
const dataset = this.getDataset();
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
if (!helpers.defined(this._useTree)) {
|
|
987
|
-
this._useTree = !!dataset.tree;
|
|
988
|
-
}
|
|
948
|
+
const {data} = this.getMeta();
|
|
989
949
|
const groups = dataset.groups || (dataset.groups = []);
|
|
990
|
-
const key = dataset.key
|
|
991
|
-
const
|
|
950
|
+
const key = dataset.key;
|
|
951
|
+
const tree = dataset.tree = dataset.tree || dataset.data || [];
|
|
992
952
|
|
|
993
|
-
|
|
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
|
+
}
|
|
994
957
|
|
|
995
|
-
if (
|
|
996
|
-
this._rect = mainRect;
|
|
958
|
+
if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
|
|
997
959
|
this._groups = groups.slice();
|
|
998
960
|
this._key = key;
|
|
961
|
+
this._prevTree = tree;
|
|
962
|
+
this._rectChanged = false;
|
|
999
963
|
|
|
1000
|
-
dataset.data = buildData(
|
|
964
|
+
dataset.data = buildData(tree, dataset, this._rect);
|
|
1001
965
|
// @ts-ignore using private stuff
|
|
1002
966
|
this._dataCheck();
|
|
1003
967
|
// @ts-ignore using private stuff
|
|
1004
968
|
this._resyncElements();
|
|
1005
969
|
}
|
|
1006
970
|
|
|
1007
|
-
this.updateElements(
|
|
971
|
+
this.updateElements(data, 0, data.length, mode);
|
|
1008
972
|
}
|
|
1009
973
|
|
|
1010
974
|
updateElements(rects, start, count, mode) {
|
|
1011
|
-
const me = this;
|
|
1012
975
|
const reset = mode === 'reset';
|
|
1013
|
-
const dataset =
|
|
1014
|
-
const firstOpts =
|
|
1015
|
-
const sharedOptions =
|
|
1016
|
-
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);
|
|
1017
981
|
|
|
1018
982
|
for (let i = start; i < start + count; i++) {
|
|
1019
|
-
const
|
|
1020
|
-
const
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
y: sq.y + sp,
|
|
1026
|
-
width: reset ? 0 : sq.w - sp2,
|
|
1027
|
-
height: reset ? 0 : sq.h - sp2,
|
|
1028
|
-
hidden: sp2 > sq.w || sp2 > sq.h,
|
|
1029
|
-
};
|
|
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
|
+
}
|
|
1030
989
|
|
|
1031
990
|
if (includeOptions) {
|
|
1032
991
|
properties.options = options;
|
|
1033
992
|
}
|
|
1034
|
-
|
|
993
|
+
this.updateElement(rects[i], i, properties, mode);
|
|
1035
994
|
}
|
|
1036
995
|
|
|
1037
|
-
|
|
996
|
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
|
1038
997
|
}
|
|
1039
998
|
|
|
1040
999
|
draw() {
|
|
1041
|
-
const {ctx, chartArea
|
|
1000
|
+
const {ctx, chartArea} = this.chart;
|
|
1042
1001
|
const metadata = this.getMeta().data || [];
|
|
1043
1002
|
const dataset = this.getDataset();
|
|
1044
1003
|
const levels = (dataset.groups || []).length - 1;
|
|
@@ -1048,7 +1007,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
1048
1007
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
1049
1008
|
const rect = metadata[i];
|
|
1050
1009
|
if (!rect.hidden) {
|
|
1051
|
-
rect.draw(ctx, data[i], levels
|
|
1010
|
+
rect.draw(ctx, data[i], levels);
|
|
1052
1011
|
}
|
|
1053
1012
|
}
|
|
1054
1013
|
helpers.unclipArea(ctx);
|
|
@@ -1109,11 +1068,16 @@ TreemapController.overrides = {
|
|
|
1109
1068
|
scales: {
|
|
1110
1069
|
x: {
|
|
1111
1070
|
type: 'linear',
|
|
1071
|
+
alignToPixels: true,
|
|
1072
|
+
bounds: 'data',
|
|
1112
1073
|
display: false
|
|
1113
1074
|
},
|
|
1114
1075
|
y: {
|
|
1115
1076
|
type: 'linear',
|
|
1116
|
-
|
|
1077
|
+
alignToPixels: true,
|
|
1078
|
+
bounds: 'data',
|
|
1079
|
+
display: false,
|
|
1080
|
+
reverse: true
|
|
1117
1081
|
}
|
|
1118
1082
|
},
|
|
1119
1083
|
};
|
|
@@ -1153,8 +1117,6 @@ exports.flatten = flatten;
|
|
|
1153
1117
|
exports.getGroupKey = getGroupKey;
|
|
1154
1118
|
exports.group = group;
|
|
1155
1119
|
exports.index = index;
|
|
1156
|
-
exports.maxValue = maxValue;
|
|
1157
|
-
exports.minValue = minValue;
|
|
1158
1120
|
exports.normalizeTreeToArray = normalizeTreeToArray;
|
|
1159
1121
|
exports.requireVersion = requireVersion;
|
|
1160
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,active:t.active,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,active:t.active,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.2",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",
|