chartjs-chart-treemap 2.2.0 → 2.3.1

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # chartjs-chart-treemap
2
2
 
3
- [Chart.js](https://www.chartjs.org/) **v3.8.0** module for creating treemap charts. Implementation for Chart.js v2 is in [2.x branch](https://github.com/kurkle/chartjs-chart-treemap/tree/2.x)
3
+ [Chart.js](https://www.chartjs.org/) **v3.8+, v4+** module for creating treemap charts. Implementation for Chart.js v2 is in [2.x branch](https://github.com/kurkle/chartjs-chart-treemap/tree/2.x)
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/chartjs-chart-treemap.svg)](https://www.npmjs.com/package/chartjs-chart-treemap)
6
6
  [![release](https://img.shields.io/github/release/kurkle/chartjs-chart-treemap.svg?style=flat-square)](https://github.com/kurkle/chartjs-chart-treemap/releases/latest)
@@ -1,19 +1,19 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.2.0
2
+ * chartjs-chart-treemap v2.3.1
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2024 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, defined, toFont, isArray, toTRBL, toTRBLCorners, valueOrDefault, clipArea, unclipArea } from 'chart.js/helpers';
8
+ import { isObject, addRoundedRectPath, defined, toFont, isArray, isNumber, toTRBL, toTRBLCorners, valueOrDefault, clipArea, unclipArea } from 'chart.js/helpers';
9
9
 
10
10
  const isOlderPart = (act, req) => req > act || (act.length > req.length && act.slice(0, req.length) === req);
11
11
 
12
12
  const getGroupKey = (lvl) => '' + lvl;
13
13
 
14
- function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
14
+ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
15
15
  const objIndex = lvl - 1;
16
- if (key in obj && lvl > 0) {
16
+ if (keys[0] in obj && lvl > 0) {
17
17
  const record = tree.reduce(function(reduced, item, i) {
18
18
  if (i !== objIndex) {
19
19
  reduced[getGroupKey(i)] = item;
@@ -21,14 +21,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
21
21
  return reduced;
22
22
  }, {});
23
23
  record[treeLeafKey] = tree[objIndex];
24
- record[key] = obj[key];
24
+ keys.forEach(function(k) {
25
+ record[k] = obj[k];
26
+ });
25
27
  result.push(record);
26
28
  } else {
27
29
  for (const childKey of Object.keys(obj)) {
28
30
  const child = obj[childKey];
29
31
  if (isObject(child)) {
30
32
  tree.push(childKey);
31
- scanTreeObject(key, treeLeafKey, child, tree, lvl + 1, result);
33
+ scanTreeObject(keys, treeLeafKey, child, tree, lvl + 1, result);
32
34
  }
33
35
  }
34
36
  }
@@ -36,16 +38,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
36
38
  return result;
37
39
  }
38
40
 
39
- function normalizeTreeToArray(key, treeLeafKey, obj) {
40
- const data = scanTreeObject(key, treeLeafKey, obj);
41
+ function normalizeTreeToArray(keys, treeLeafKey, obj) {
42
+ const data = scanTreeObject(keys, treeLeafKey, obj);
41
43
  if (!data.length) {
42
44
  return data;
43
45
  }
44
46
  const max = data.reduce(function(maxVal, element) {
45
47
  // minus 2 because _leaf and value properties are added
46
48
  // on top to groups ones
47
- const keys = Object.keys(element).length - 2;
48
- return maxVal > keys ? maxVal : keys;
49
+ const ikeys = Object.keys(element).length - 2;
50
+ return maxVal > ikeys ? maxVal : ikeys;
49
51
  });
50
52
  data.forEach(function(element) {
51
53
  for (let i = 0; i < max; i++) {
@@ -95,13 +97,15 @@ function getPath(groups, value, defaultValue) {
95
97
  /**
96
98
  * @param {[]} values
97
99
  * @param {string} grp
98
- * @param {string} key
100
+ * @param {[string]} keys
99
101
  * @param {string} treeeLeafKey
100
102
  * @param {string} [mainGrp]
101
103
  * @param {*} [mainValue]
102
104
  * @param {[]} groups
103
105
  */
104
- function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
106
+ function group(values, grp, keys, treeLeafKey, mainGrp, mainValue, groups = []) {
107
+ const key = keys[0];
108
+ const addKeys = keys.slice(1);
105
109
  const tmp = Object.create(null);
106
110
  const data = Object.create(null);
107
111
  const ret = [];
@@ -113,11 +117,18 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
113
117
  }
114
118
  g = v[grp] || v[treeLeafKey] || '';
115
119
  if (!(g in tmp)) {
116
- tmp[g] = {value: 0};
120
+ const tmpRef = tmp[g] = {value: 0};
121
+ addKeys.forEach(function(k) {
122
+ tmpRef[k] = 0;
123
+ });
117
124
  data[g] = [];
118
125
  }
119
126
  tmp[g].value += +v[key];
120
127
  tmp[g].label = v[grp] || '';
128
+ const tmpRef = tmp[g];
129
+ addKeys.forEach(function(k) {
130
+ tmpRef[k] += v[k];
131
+ });
121
132
  tmp[g].path = getPath(groups, v, g);
122
133
  data[g].push(v);
123
134
  }
@@ -125,6 +136,9 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
125
136
  Object.keys(tmp).forEach((k) => {
126
137
  const v = {children: data[k]};
127
138
  v[key] = +tmp[k].value;
139
+ addKeys.forEach(function(ak) {
140
+ v[ak] = +tmp[k][ak];
141
+ });
128
142
  v[grp] = tmp[k].label;
129
143
  v.label = k;
130
144
  v.path = tmp[k].path;
@@ -366,15 +380,34 @@ function measureLabelSize(ctx, lines, fonts) {
366
380
  return widthCache.get(mapKey);
367
381
  }
368
382
 
383
+ function toFonts(fonts, fitRatio) {
384
+ return fonts.map(function(f) {
385
+ f.size = Math.floor(f.size * fitRatio);
386
+ f.lineHeight = undefined;
387
+ return toFont(f);
388
+ });
389
+ }
390
+
369
391
  function labelToDraw(ctx, rect, options, labelSize) {
370
392
  const {overflow, padding} = options;
371
393
  const {width, height} = labelSize;
372
394
  if (overflow === 'hidden') {
373
395
  return !((width + padding * 2) > rect.w || (height + padding * 2) > rect.h);
396
+ } else if (overflow === 'fit') {
397
+ const ratio = Math.min(rect.w / (width + padding * 2), rect.h / (height + padding * 2));
398
+ if (ratio < 1) {
399
+ return ratio;
400
+ }
374
401
  }
375
402
  return true;
376
403
  }
377
404
 
405
+ function getFontFromOptions(rect, labels) {
406
+ const {font, hoverFont} = labels;
407
+ const optFont = (rect.active ? hoverFont : font) || font;
408
+ return isArray(optFont) ? optFont.map(f => toFont(f)) : [toFont(optFont)];
409
+ }
410
+
378
411
  function drawLabel(ctx, rect, options) {
379
412
  const labels = options.labels;
380
413
  const content = labels.formatter;
@@ -382,13 +415,16 @@ function drawLabel(ctx, rect, options) {
382
415
  return;
383
416
  }
384
417
  const contents = isArray(content) ? content : [content];
385
- const {font, hoverFont} = labels;
386
- const optFont = (rect.active ? hoverFont : font) || font;
387
- const fonts = isArray(optFont) ? optFont.map(f => toFont(f)) : [toFont(optFont)];
388
- const labelSize = measureLabelSize(ctx, contents, fonts);
389
- if (!labelToDraw(ctx, rect, labels, labelSize)) {
418
+ let fonts = getFontFromOptions(rect, labels);
419
+ let labelSize = measureLabelSize(ctx, contents, fonts);
420
+ const lblToDraw = labelToDraw(ctx, rect, labels, labelSize);
421
+ if (!lblToDraw) {
390
422
  return;
391
423
  }
424
+ if (isNumber(lblToDraw)) {
425
+ labelSize = {width: labelSize.width * lblToDraw, height: labelSize.height * lblToDraw};
426
+ fonts = toFonts(fonts, lblToDraw);
427
+ }
392
428
  const {color, hoverColor, align} = labels;
393
429
  const optColor = (rect.active ? hoverColor : color) || color;
394
430
  const colors = isArray(optColor) ? optColor : [optColor];
@@ -611,6 +647,7 @@ function buildRow(rect, itm, dims, sum) {
611
647
  h: dims.h,
612
648
  a: itm._normalized,
613
649
  v: itm.value,
650
+ vs: itm.values,
614
651
  s: sum,
615
652
  _data: itm._data
616
653
  };
@@ -781,11 +818,11 @@ function compareAspectRatio(oldStat, newStat, args) {
781
818
  * @param {number} [lvl]
782
819
  * @param {number} [gsum]
783
820
  */
784
- function squarify(values, rectangle, key, grp, lvl, gsum) {
821
+ function squarify(values, rectangle, keys = [], grp, lvl, gsum) {
785
822
  values = values || [];
786
823
  const rows = [];
787
824
  const rect = new Rect(rectangle);
788
- const row = new StatArray('value', rect.area / sum(values, key));
825
+ const row = new StatArray('value', rect.area / sum(values, keys[0]));
789
826
  let length = rect.side;
790
827
  const n = values.length;
791
828
  let i, o;
@@ -795,7 +832,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
795
832
  }
796
833
 
797
834
  const tmp = values.slice();
798
- key = index(tmp, key);
835
+ let key = index(tmp, keys[0]);
799
836
  sort(tmp, key);
800
837
 
801
838
  const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
@@ -806,6 +843,11 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
806
843
  if (grp) {
807
844
  o.level = lvl;
808
845
  o.group = gval(i);
846
+ const tmpRef = tmp[i];
847
+ o.values = keys.reduce(function(obj, k) {
848
+ obj[k] = +tmpRef[k];
849
+ return obj;
850
+ }, {});
809
851
  }
810
852
  o = row.pushIf(o, compareAspectRatio, length);
811
853
  if (o) {
@@ -821,7 +863,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
821
863
  return flatten(rows);
822
864
  }
823
865
 
824
- var version = "2.2.0";
866
+ var version = "2.3.1";
825
867
 
826
868
  function scaleRect(sq, xScale, yScale, sp) {
827
869
  const sp2 = sp * 2;
@@ -870,11 +912,10 @@ function arrayNotEqual(a, b) {
870
912
  return false;
871
913
  }
872
914
 
873
- function buildData(tree, dataset, mainRect) {
874
- const key = dataset.key || '';
915
+ function buildData(tree, dataset, keys, mainRect) {
875
916
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
876
917
  if (isObject(tree)) {
877
- tree = normalizeTreeToArray(key, treeLeafKey, tree);
918
+ tree = normalizeTreeToArray(keys, treeLeafKey, tree);
878
919
  }
879
920
  const groups = dataset.groups || [];
880
921
  const glen = groups.length;
@@ -883,11 +924,11 @@ function buildData(tree, dataset, mainRect) {
883
924
  const font = toFont(captions.font);
884
925
  const padding = valueOrDefault(captions.padding, 3);
885
926
 
886
- function recur(gidx, rect, parent, gs) {
927
+ function recur(treeElements, gidx, rect, parent, gs) {
887
928
  const g = getGroupKey(groups[gidx]);
888
929
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
889
- const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
890
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
930
+ const gdata = group(treeElements, g, keys, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
931
+ const gsq = squarify(gdata, rect, keys, g, gidx, gs);
891
932
  const ret = gsq.slice();
892
933
  if (gidx < glen - 1) {
893
934
  gsq.forEach((sq) => {
@@ -903,15 +944,17 @@ function buildData(tree, dataset, mainRect) {
903
944
  subRect.y += font.lineHeight + padding * 2;
904
945
  subRect.h -= font.lineHeight + padding * 2;
905
946
  }
906
- ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
947
+ gdata.forEach((gEl) => {
948
+ ret.push(...recur(gEl.children, gidx + 1, subRect, sq.g, sq.s));
949
+ });
907
950
  });
908
951
  }
909
952
  return ret;
910
953
  }
911
954
 
912
955
  return glen
913
- ? recur(0, mainRect)
914
- : squarify(tree, mainRect, key);
956
+ ? recur(tree, 0, mainRect)
957
+ : squarify(tree, mainRect, keys);
915
958
  }
916
959
 
917
960
  class TreemapController extends DatasetController {
@@ -919,7 +962,7 @@ class TreemapController extends DatasetController {
919
962
  super(chart, datasetIndex);
920
963
 
921
964
  this._groups = undefined;
922
- this._key = undefined;
965
+ this._keys = undefined;
923
966
  this._rect = undefined;
924
967
  this._rectChanged = true;
925
968
  }
@@ -964,8 +1007,8 @@ class TreemapController extends DatasetController {
964
1007
  update(mode) {
965
1008
  const dataset = this.getDataset();
966
1009
  const {data} = this.getMeta();
967
- const groups = dataset.groups || (dataset.groups = []);
968
- const key = dataset.key;
1010
+ const groups = dataset.groups || [];
1011
+ const keys = [dataset.key || ''].concat(dataset.sumKeys || []);
969
1012
  const tree = dataset.tree = dataset.tree || dataset.data || [];
970
1013
 
971
1014
  if (mode === 'reset') {
@@ -973,13 +1016,13 @@ class TreemapController extends DatasetController {
973
1016
  this.configure();
974
1017
  }
975
1018
 
976
- if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
1019
+ if (this._rectChanged || arrayNotEqual(this._keys, keys) || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
977
1020
  this._groups = groups.slice();
978
- this._key = key;
1021
+ this._keys = keys.slice();
979
1022
  this._prevTree = tree;
980
1023
  this._rectChanged = false;
981
1024
 
982
- dataset.data = buildData(tree, dataset, this._rect);
1025
+ dataset.data = buildData(tree, dataset, this._keys, this._rect);
983
1026
  // @ts-ignore using private stuff
984
1027
  this._dataCheck();
985
1028
  // @ts-ignore using private stuff
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.2.0
2
+ * chartjs-chart-treemap v2.3.1
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2024 Jukka Kurkela
5
5
  * Released under the MIT license
6
6
  */
7
7
  (function (global, factory) {
@@ -14,9 +14,9 @@ const isOlderPart = (act, req) => req > act || (act.length > req.length && act.s
14
14
 
15
15
  const getGroupKey = (lvl) => '' + lvl;
16
16
 
17
- function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
17
+ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
18
18
  const objIndex = lvl - 1;
19
- if (key in obj && lvl > 0) {
19
+ if (keys[0] in obj && lvl > 0) {
20
20
  const record = tree.reduce(function(reduced, item, i) {
21
21
  if (i !== objIndex) {
22
22
  reduced[getGroupKey(i)] = item;
@@ -24,14 +24,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
24
24
  return reduced;
25
25
  }, {});
26
26
  record[treeLeafKey] = tree[objIndex];
27
- record[key] = obj[key];
27
+ keys.forEach(function(k) {
28
+ record[k] = obj[k];
29
+ });
28
30
  result.push(record);
29
31
  } else {
30
32
  for (const childKey of Object.keys(obj)) {
31
33
  const child = obj[childKey];
32
34
  if (helpers.isObject(child)) {
33
35
  tree.push(childKey);
34
- scanTreeObject(key, treeLeafKey, child, tree, lvl + 1, result);
36
+ scanTreeObject(keys, treeLeafKey, child, tree, lvl + 1, result);
35
37
  }
36
38
  }
37
39
  }
@@ -39,16 +41,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
39
41
  return result;
40
42
  }
41
43
 
42
- function normalizeTreeToArray(key, treeLeafKey, obj) {
43
- const data = scanTreeObject(key, treeLeafKey, obj);
44
+ function normalizeTreeToArray(keys, treeLeafKey, obj) {
45
+ const data = scanTreeObject(keys, treeLeafKey, obj);
44
46
  if (!data.length) {
45
47
  return data;
46
48
  }
47
49
  const max = data.reduce(function(maxVal, element) {
48
50
  // minus 2 because _leaf and value properties are added
49
51
  // on top to groups ones
50
- const keys = Object.keys(element).length - 2;
51
- return maxVal > keys ? maxVal : keys;
52
+ const ikeys = Object.keys(element).length - 2;
53
+ return maxVal > ikeys ? maxVal : ikeys;
52
54
  });
53
55
  data.forEach(function(element) {
54
56
  for (let i = 0; i < max; i++) {
@@ -98,13 +100,15 @@ function getPath(groups, value, defaultValue) {
98
100
  /**
99
101
  * @param {[]} values
100
102
  * @param {string} grp
101
- * @param {string} key
103
+ * @param {[string]} keys
102
104
  * @param {string} treeeLeafKey
103
105
  * @param {string} [mainGrp]
104
106
  * @param {*} [mainValue]
105
107
  * @param {[]} groups
106
108
  */
107
- function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
109
+ function group(values, grp, keys, treeLeafKey, mainGrp, mainValue, groups = []) {
110
+ const key = keys[0];
111
+ const addKeys = keys.slice(1);
108
112
  const tmp = Object.create(null);
109
113
  const data = Object.create(null);
110
114
  const ret = [];
@@ -116,11 +120,18 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
116
120
  }
117
121
  g = v[grp] || v[treeLeafKey] || '';
118
122
  if (!(g in tmp)) {
119
- tmp[g] = {value: 0};
123
+ const tmpRef = tmp[g] = {value: 0};
124
+ addKeys.forEach(function(k) {
125
+ tmpRef[k] = 0;
126
+ });
120
127
  data[g] = [];
121
128
  }
122
129
  tmp[g].value += +v[key];
123
130
  tmp[g].label = v[grp] || '';
131
+ const tmpRef = tmp[g];
132
+ addKeys.forEach(function(k) {
133
+ tmpRef[k] += v[k];
134
+ });
124
135
  tmp[g].path = getPath(groups, v, g);
125
136
  data[g].push(v);
126
137
  }
@@ -128,6 +139,9 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
128
139
  Object.keys(tmp).forEach((k) => {
129
140
  const v = {children: data[k]};
130
141
  v[key] = +tmp[k].value;
142
+ addKeys.forEach(function(ak) {
143
+ v[ak] = +tmp[k][ak];
144
+ });
131
145
  v[grp] = tmp[k].label;
132
146
  v.label = k;
133
147
  v.path = tmp[k].path;
@@ -369,15 +383,34 @@ function measureLabelSize(ctx, lines, fonts) {
369
383
  return widthCache.get(mapKey);
370
384
  }
371
385
 
386
+ function toFonts(fonts, fitRatio) {
387
+ return fonts.map(function(f) {
388
+ f.size = Math.floor(f.size * fitRatio);
389
+ f.lineHeight = undefined;
390
+ return helpers.toFont(f);
391
+ });
392
+ }
393
+
372
394
  function labelToDraw(ctx, rect, options, labelSize) {
373
395
  const {overflow, padding} = options;
374
396
  const {width, height} = labelSize;
375
397
  if (overflow === 'hidden') {
376
398
  return !((width + padding * 2) > rect.w || (height + padding * 2) > rect.h);
399
+ } else if (overflow === 'fit') {
400
+ const ratio = Math.min(rect.w / (width + padding * 2), rect.h / (height + padding * 2));
401
+ if (ratio < 1) {
402
+ return ratio;
403
+ }
377
404
  }
378
405
  return true;
379
406
  }
380
407
 
408
+ function getFontFromOptions(rect, labels) {
409
+ const {font, hoverFont} = labels;
410
+ const optFont = (rect.active ? hoverFont : font) || font;
411
+ return helpers.isArray(optFont) ? optFont.map(f => helpers.toFont(f)) : [helpers.toFont(optFont)];
412
+ }
413
+
381
414
  function drawLabel(ctx, rect, options) {
382
415
  const labels = options.labels;
383
416
  const content = labels.formatter;
@@ -385,13 +418,16 @@ function drawLabel(ctx, rect, options) {
385
418
  return;
386
419
  }
387
420
  const contents = helpers.isArray(content) ? content : [content];
388
- const {font, hoverFont} = labels;
389
- const optFont = (rect.active ? hoverFont : font) || font;
390
- const fonts = helpers.isArray(optFont) ? optFont.map(f => helpers.toFont(f)) : [helpers.toFont(optFont)];
391
- const labelSize = measureLabelSize(ctx, contents, fonts);
392
- if (!labelToDraw(ctx, rect, labels, labelSize)) {
421
+ let fonts = getFontFromOptions(rect, labels);
422
+ let labelSize = measureLabelSize(ctx, contents, fonts);
423
+ const lblToDraw = labelToDraw(ctx, rect, labels, labelSize);
424
+ if (!lblToDraw) {
393
425
  return;
394
426
  }
427
+ if (helpers.isNumber(lblToDraw)) {
428
+ labelSize = {width: labelSize.width * lblToDraw, height: labelSize.height * lblToDraw};
429
+ fonts = toFonts(fonts, lblToDraw);
430
+ }
395
431
  const {color, hoverColor, align} = labels;
396
432
  const optColor = (rect.active ? hoverColor : color) || color;
397
433
  const colors = helpers.isArray(optColor) ? optColor : [optColor];
@@ -614,6 +650,7 @@ function buildRow(rect, itm, dims, sum) {
614
650
  h: dims.h,
615
651
  a: itm._normalized,
616
652
  v: itm.value,
653
+ vs: itm.values,
617
654
  s: sum,
618
655
  _data: itm._data
619
656
  };
@@ -784,11 +821,11 @@ function compareAspectRatio(oldStat, newStat, args) {
784
821
  * @param {number} [lvl]
785
822
  * @param {number} [gsum]
786
823
  */
787
- function squarify(values, rectangle, key, grp, lvl, gsum) {
824
+ function squarify(values, rectangle, keys = [], grp, lvl, gsum) {
788
825
  values = values || [];
789
826
  const rows = [];
790
827
  const rect = new Rect(rectangle);
791
- const row = new StatArray('value', rect.area / sum(values, key));
828
+ const row = new StatArray('value', rect.area / sum(values, keys[0]));
792
829
  let length = rect.side;
793
830
  const n = values.length;
794
831
  let i, o;
@@ -798,7 +835,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
798
835
  }
799
836
 
800
837
  const tmp = values.slice();
801
- key = index(tmp, key);
838
+ let key = index(tmp, keys[0]);
802
839
  sort(tmp, key);
803
840
 
804
841
  const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
@@ -809,6 +846,11 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
809
846
  if (grp) {
810
847
  o.level = lvl;
811
848
  o.group = gval(i);
849
+ const tmpRef = tmp[i];
850
+ o.values = keys.reduce(function(obj, k) {
851
+ obj[k] = +tmpRef[k];
852
+ return obj;
853
+ }, {});
812
854
  }
813
855
  o = row.pushIf(o, compareAspectRatio, length);
814
856
  if (o) {
@@ -824,7 +866,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
824
866
  return flatten(rows);
825
867
  }
826
868
 
827
- var version = "2.2.0";
869
+ var version = "2.3.1";
828
870
 
829
871
  function scaleRect(sq, xScale, yScale, sp) {
830
872
  const sp2 = sp * 2;
@@ -873,11 +915,10 @@ function arrayNotEqual(a, b) {
873
915
  return false;
874
916
  }
875
917
 
876
- function buildData(tree, dataset, mainRect) {
877
- const key = dataset.key || '';
918
+ function buildData(tree, dataset, keys, mainRect) {
878
919
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
879
920
  if (helpers.isObject(tree)) {
880
- tree = normalizeTreeToArray(key, treeLeafKey, tree);
921
+ tree = normalizeTreeToArray(keys, treeLeafKey, tree);
881
922
  }
882
923
  const groups = dataset.groups || [];
883
924
  const glen = groups.length;
@@ -886,11 +927,11 @@ function buildData(tree, dataset, mainRect) {
886
927
  const font = helpers.toFont(captions.font);
887
928
  const padding = helpers.valueOrDefault(captions.padding, 3);
888
929
 
889
- function recur(gidx, rect, parent, gs) {
930
+ function recur(treeElements, gidx, rect, parent, gs) {
890
931
  const g = getGroupKey(groups[gidx]);
891
932
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
892
- const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
893
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
933
+ const gdata = group(treeElements, g, keys, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
934
+ const gsq = squarify(gdata, rect, keys, g, gidx, gs);
894
935
  const ret = gsq.slice();
895
936
  if (gidx < glen - 1) {
896
937
  gsq.forEach((sq) => {
@@ -906,15 +947,17 @@ function buildData(tree, dataset, mainRect) {
906
947
  subRect.y += font.lineHeight + padding * 2;
907
948
  subRect.h -= font.lineHeight + padding * 2;
908
949
  }
909
- ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
950
+ gdata.forEach((gEl) => {
951
+ ret.push(...recur(gEl.children, gidx + 1, subRect, sq.g, sq.s));
952
+ });
910
953
  });
911
954
  }
912
955
  return ret;
913
956
  }
914
957
 
915
958
  return glen
916
- ? recur(0, mainRect)
917
- : squarify(tree, mainRect, key);
959
+ ? recur(tree, 0, mainRect)
960
+ : squarify(tree, mainRect, keys);
918
961
  }
919
962
 
920
963
  class TreemapController extends chart_js.DatasetController {
@@ -922,7 +965,7 @@ class TreemapController extends chart_js.DatasetController {
922
965
  super(chart, datasetIndex);
923
966
 
924
967
  this._groups = undefined;
925
- this._key = undefined;
968
+ this._keys = undefined;
926
969
  this._rect = undefined;
927
970
  this._rectChanged = true;
928
971
  }
@@ -967,8 +1010,8 @@ class TreemapController extends chart_js.DatasetController {
967
1010
  update(mode) {
968
1011
  const dataset = this.getDataset();
969
1012
  const {data} = this.getMeta();
970
- const groups = dataset.groups || (dataset.groups = []);
971
- const key = dataset.key;
1013
+ const groups = dataset.groups || [];
1014
+ const keys = [dataset.key || ''].concat(dataset.sumKeys || []);
972
1015
  const tree = dataset.tree = dataset.tree || dataset.data || [];
973
1016
 
974
1017
  if (mode === 'reset') {
@@ -976,13 +1019,13 @@ class TreemapController extends chart_js.DatasetController {
976
1019
  this.configure();
977
1020
  }
978
1021
 
979
- if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
1022
+ if (this._rectChanged || arrayNotEqual(this._keys, keys) || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
980
1023
  this._groups = groups.slice();
981
- this._key = key;
1024
+ this._keys = keys.slice();
982
1025
  this._prevTree = tree;
983
1026
  this._rectChanged = false;
984
1027
 
985
- dataset.data = buildData(tree, dataset, this._rect);
1028
+ dataset.data = buildData(tree, dataset, this._keys, this._rect);
986
1029
  // @ts-ignore using private stuff
987
1030
  this._dataCheck();
988
1031
  // @ts-ignore using private stuff
@@ -1,7 +1,8 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.2.0
2
+ * chartjs-chart-treemap v2.3.1
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2024 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,e)=>e>t||t.length>e.length&&t.slice(0,e.length)===e,r=t=>""+t;function o(t,e,i,s=[],a=0,h=[]){const l=a-1;if(t in i&&a>0){const n=s.reduce((function(t,e,n){return n!==l&&(t[r(n)]=e),t}),{});n[e]=s[l],n[t]=i[t],h.push(n)}else for(const r of Object.keys(i)){const l=i[r];n.isObject(l)&&(s.push(r),o(t,e,l,s,a+1,h))}return s.splice(l,1),h}function s(t,e,n){const i=o(t,e,n);if(!i.length)return i;const s=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<s;e++){const n=r(e);t[n]||(t[n]="")}})),i}function a(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 h(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 l(t,e,n,i,r,o,s=[]){const a=Object.create(null),l=Object.create(null),u=[];let c,g,d;for(g=0,d=t.length;g<d;++g){const u=t[g];r&&u[r]!==o||(c=u[e]||u[i]||"",c in a||(a[c]={value:0},l[c]=[]),a[c].value+=+u[n],a[c].label=u[e]||"",a[c].path=h(s,u,c),l[c].push(u))}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),u.push(i)})),u}function u(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 c(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function g(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,n,r=!0){const o=n.split(".");let s=0;for(const a of e.split(".")){const h=o[s++];if(parseInt(a,10)<parseInt(h,10))break;if(i(h,a)){if(r)throw new Error(`${t} v${n} is not supported. v${e} or newer is required.`);return!1}}return!0}const f=new Map;function p(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 m(t,e,n){return Math.max(Math.min(t,n),e)}function x(t,e,i){const r=n.toTRBL(t);return{t:m(r.top,0,i),r:m(r.right,0,e),b:m(r.bottom,0,i),l:m(r.left,0,e)}}function b(t){const e=p(t),i=e.right-e.left,r=e.bottom-e.top,o=x(t.options.borderWidth,i/2,r/2),s=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:m(r.topLeft,0,o),topRight:m(r.topRight,0,o),bottomLeft:m(r.bottomLeft,0,o),bottomRight:m(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 y(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&p(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function v(t,e){t.rect(e.x,e.y,e.w,e.h)}function w(t,e){if(!e||!1===e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=m(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function _(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(!f.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(),f.set(r,{width:o,height:s})}return f.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:g,hoverColor:d,align:p}=r,m=(e.active?d:g)||g,x=n.isArray(m)?m:[m],b=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=M(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&&w(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:h,hoverColor:l,font:u,hoverFont:c,padding:g,align:d,formatter:f}=o,p=(e.active?l:h)||h,m=d||(a?"right":"left"),x=(e.active?c:u)||u,b=n.toFont(x),y=b.lineHeight/2,v=M(e,m,g);t.fillStyle=p,t.font=b.string,t.textAlign=m,t.textBaseline="middle",t.fillText(f||r.g,v,e.y+g+s+y)}(t,e,i,r),t.restore()}function M(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class C 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}=b(this),a=(h=s.radius).topLeft||h.topRight||h.bottomLeft||h.bottomRight?n.addRoundedRectPath:v;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:g,lineWidth:d}=r;if(t.save(),t.strokeStyle=l,t.lineCap=u,t.setLineDash(c),t.lineDashOffset=g,t.lineWidth=d,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),_(t,o,r,e,i),t.restore()}inRange(t,e,n){return y(this,t,e,n)}inXRange(t,e){return y(this,t,null,e)}inYRange(t,e){return y(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 k(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}}C.id="treemap",C.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},C.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},C.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const R=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function O(t,e,n,i){const r={x:R(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 j{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=k(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 T=Math.min,P=Math.max;function S(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:T(t.min,n),max:P(t.max,n),sum:t.sum+n,nmin:T(t.nmin,i),nmax:P(t.nmax,i),nsum:t.nsum+i}}function D(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class L{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){D(this,t,S(this,t))}pushIf(t,e,...n){const i=S(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;D(this,t,i)}get(){return this._arr}}function E(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 A(t,e,n,i,r,o){t=t||[];const s=[],h=new j(e),l=new L("value",h.area/g(t,n));let d=h.side;const f=t.length;let p,m;if(!f)return s;const x=t.slice();n=u(x,n),c(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=l.pushIf(m,E,d),m&&(s.push(h.map(l)),d=h.side,l.reset(),l.push(m));var y;return l.length&&s.push(h.map(l)),a(s)}function F(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 z 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:i}=this.getMeta(),o=e.groups||(e.groups=[]),a=e.key,h=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,o)||this._prevTree!==h)&&(this._groups=o.slice(),this._key=a,this._prevTree=h,this._rectChanged=!1,e.data=function(t,e,i){const o=e.key||"",a=e.treeLeafKey||"_leaf";n.isObject(t)&&(t=s(o,a,t));const h=e.groups||[],u=h.length,c=n.valueOrDefault(e.spacing,0),g=e.captions||{},d=n.toFont(g.font),f=n.valueOrDefault(g.padding,3);return u?function n(i,s,p,m){const b=r(h[i]),y=i>0&&r(h[i-1]),v=l(t,b,o,a,y,p,h.filter(((t,e)=>e<=i))),_=A(v,s,o,b,i,m),M=_.slice();return i<u-1&&_.forEach((t=>{const r=x(e.borderWidth,t.w/2,t.h/2),o={...s,x:t.x+c+r.l,y:t.y+c+r.t,w:t.w-2*c-r.l-r.r,h:t.h-2*c-r.t-r.b};w(o,g)&&(o.y+=d.lineHeight+2*f,o.h-=d.lineHeight+2*f),M.push(...n(i+1,o,t.g,t.s))})),M}(0,i):A(t,i,o)}(h,e,this._rect),this._dataCheck(),this._resyncElements()),this.updateElements(i,0,i.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=F(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)}}z.id="treemap",z.version="2.2.0",z.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},z.descriptors={_scriptable:!0,_indexable:!1},z.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}}},z.beforeRegister=function(){d("chart.js","3.8",e.Chart.version)},z.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")},z.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(z,C),t.flatten=a,t.getGroupKey=r,t.group=l,t.index=u,t.normalizeTreeToArray=s,t.requireVersion=d,t.sort=c,t.sum=g}));
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,e)=>e>t||t.length>e.length&&t.slice(0,e.length)===e,r=t=>""+t;function o(t,e,i,s=[],a=0,h=[]){const l=a-1;if(t[0]in i&&a>0){const n=s.reduce((function(t,e,n){return n!==l&&(t[r(n)]=e),t}),{});n[e]=s[l],t.forEach((function(t){n[t]=i[t]})),h.push(n)}else for(const r of Object.keys(i)){const l=i[r];n.isObject(l)&&(s.push(r),o(t,e,l,s,a+1,h))}return s.splice(l,1),h}function s(t,e,n){const i=o(t,e,n);if(!i.length)return i;const s=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<s;e++){const n=r(e);t[n]||(t[n]="")}})),i}function a(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 h(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 l(t,e,n,i,r,o,s=[]){const a=n[0],l=n.slice(1),c=Object.create(null),u=Object.create(null),f=[];let d,g,p;for(g=0,p=t.length;g<p;++g){const n=t[g];if(r&&n[r]!==o)continue;if(d=n[e]||n[i]||"",!(d in c)){const t=c[d]={value:0};l.forEach((function(e){t[e]=0})),u[d]=[]}c[d].value+=+n[a],c[d].label=n[e]||"";const f=c[d];l.forEach((function(t){f[t]+=n[t]})),c[d].path=h(s,n,d),u[d].push(n)}return Object.keys(c).forEach((t=>{const n={children:u[t]};n[a]=+c[t].value,l.forEach((function(e){n[e]=+c[t][e]})),n[e]=c[t].label,n.label=t,n.path=c[t].path,r&&(n[r]=o),f.push(n)})),f}function c(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 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 d(t,e,n,r=!0){const o=n.split(".");let s=0;for(const a of e.split(".")){const h=o[s++];if(parseInt(a,10)<parseInt(h,10))break;if(i(h,a)){if(r)throw new Error(`${t} v${n} is not supported. v${e} or newer is required.`);return!1}}return!0}const g=new Map;function p(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 m(t,e,n){return Math.max(Math.min(t,n),e)}function x(t,e,i){const r=n.toTRBL(t);return{t:m(r.top,0,i),r:m(r.right,0,e),b:m(r.bottom,0,i),l:m(r.left,0,e)}}function b(t){const e=p(t),i=e.right-e.left,r=e.bottom-e.top,o=x(t.options.borderWidth,i/2,r/2),s=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:m(r.topLeft,0,o),topRight:m(r.topRight,0,o),bottomLeft:m(r.bottomLeft,0,o),bottomRight:m(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 y(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&p(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function v(t,e){t.rect(e.x,e.y,e.w,e.h)}function w(t,e){if(!e||!1===e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=m(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function _(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];let a=function(t,e){const{font:i,hoverFont:r}=e,o=(t.active?r:i)||i;return n.isArray(o)?o.map((t=>n.toFont(t))):[n.toFont(o)]}(e,r),h=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,a);const l=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);if("fit"===r){const t=Math.min(e.w/(s+2*o),e.h/(a+2*o));if(t<1)return t}return!0}(0,e,r,h);if(!l)return;n.isNumber(l)&&(h={width:h.width*l,height:h.height*l},a=function(t,e){return t.map((function(t){return t.size=Math.floor(t.size*e),t.lineHeight=void 0,n.toFont(t)}))}(a,l));const{color:c,hoverColor:u,align:f}=r,d=(e.active?u:c)||c,p=n.isArray(d)?d:[d],m=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=M(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,h);t.textAlign=f,t.textBaseline="middle";let x=0;s.forEach((function(e,n){const i=p[Math.min(n,p.length-1)],r=a[Math.min(n,a.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,m.x,m.y+o/2+x),x+=o}))}(t,e,i):!h&&w(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:h,hoverColor:l,font:c,hoverFont:u,padding:f,align:d,formatter:g}=o,p=(e.active?l:h)||h,m=d||(a?"right":"left"),x=(e.active?u:c)||c,b=n.toFont(x),y=b.lineHeight/2,v=M(e,m,f);t.fillStyle=p,t.font=b.string,t.textAlign=m,t.textBaseline="middle",t.fillText(g||r.g,v,e.y+f+s+y)}(t,e,i,r),t.restore()}function M(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class C 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}=b(this),a=(h=s.radius).topLeft||h.topRight||h.bottomLeft||h.bottomRight?n.addRoundedRectPath:v;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:c,lineDash:u,lineDashOffset:f,lineWidth:d}=r;if(t.save(),t.strokeStyle=l,t.lineCap=c,t.setLineDash(u),t.lineDashOffset=f,t.lineWidth=d,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),_(t,o,r,e,i),t.restore()}inRange(t,e,n){return y(this,t,e,n)}inXRange(t,e){return y(this,t,null,e)}inYRange(t,e){return y(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 k(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}}C.id="treemap",C.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},C.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},C.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const R=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function O(t,e,n,i){const r={x:R(t,n.w),y:t.y+t._iy,w:n.w,h:n.h,a:e._normalized,v:e.value,vs:e.values,s:i,_data:e._data};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class j{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,c=0;for(const e of o){const n=k(e,s,a,i);c+=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]-=c,h}}const T=Math.min,E=Math.max;function P(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:T(t.min,n),max:E(t.max,n),sum:t.sum+n,nmin:T(t.nmin,i),nmax:E(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 F(t,e,n=[],i,r,o){t=t||[];const s=[],h=new j(e),l=new D("value",h.area/f(t,n[0]));let d=h.side;const g=t.length;let p,m;if(!g)return s;const x=t.slice();let b=c(x,n[0]);u(x,b);const y=t=>i&&x[t][i];for(p=0;p<g;++p){if(m={value:(v=p,b?+x[v][b]:+x[v]),groupSum:o,_data:t[x[p]._idx],level:void 0,group:void 0},i){m.level=r,m.group=y(p);const t=x[p];m.values=n.reduce((function(e,n){return e[n]=+t[n],e}),{})}m=l.pushIf(m,L,d),m&&(s.push(h.map(l)),d=h.side,l.reset(),l.push(m))}var v;return l.length&&s.push(h.map(l)),a(s)}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}}function z(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}class H extends e.DatasetController{constructor(t,e){super(t,e),this._groups=void 0,this._keys=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:i}=this.getMeta(),o=e.groups||[],a=[e.key||""].concat(e.sumKeys||[]),h=e.tree=e.tree||e.data||[];"reset"===t&&this.configure(),(this._rectChanged||z(this._keys,a)||z(this._groups,o)||this._prevTree!==h)&&(this._groups=o.slice(),this._keys=a.slice(),this._prevTree=h,this._rectChanged=!1,e.data=function(t,e,i,o){const a=e.treeLeafKey||"_leaf";n.isObject(t)&&(t=s(i,a,t));const h=e.groups||[],c=h.length,u=n.valueOrDefault(e.spacing,0),f=e.captions||{},d=n.toFont(f.font),g=n.valueOrDefault(f.padding,3);return c?function t(n,o,s,p,m){const b=r(h[o]),y=o>0&&r(h[o-1]),v=l(n,b,i,a,y,p,h.filter(((t,e)=>e<=o))),_=F(v,s,i,b,o,m),M=_.slice();return o<c-1&&_.forEach((n=>{const i=x(e.borderWidth,n.w/2,n.h/2),r={...s,x:n.x+u+i.l,y:n.y+u+i.t,w:n.w-2*u-i.l-i.r,h:n.h-2*u-i.t-i.b};w(r,f)&&(r.y+=d.lineHeight+2*g,r.h-=d.lineHeight+2*g),v.forEach((e=>{M.push(...t(e.children,o+1,r,n.g,n.s))}))})),M}(t,0,o):F(t,o,i)}(h,e,this._keys,this._rect),this._dataCheck(),this._resyncElements()),this.updateElements(i,0,i.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:c}=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,c,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)}}H.id="treemap",H.version="2.3.1",H.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},H.descriptors={_scriptable:!0,_indexable:!1},H.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}}},H.beforeRegister=function(){d("chart.js","3.8",e.Chart.version)},H.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")},H.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(H,C),t.flatten=a,t.getGroupKey=r,t.group=l,t.index=c,t.normalizeTreeToArray=s,t.requireVersion=d,t.sort=u,t.sum=f}));
8
+ //# sourceMappingURL=chartjs-chart-treemap.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chartjs-chart-treemap.min.js","sources":["../src/utils.js","../src/element.js","../src/rect.js","../src/statArray.js","../src/squarify.js","../src/helpers/index.js","../src/controller.js","../src/index.js"],"sourcesContent":["import {isObject} from 'chart.js/helpers';\n\nconst isOlderPart = (act, req) => req > act || (act.length > req.length && act.slice(0, req.length) === req);\n\nexport const getGroupKey = (lvl) => '' + lvl;\n\nfunction scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = []) {\n const objIndex = lvl - 1;\n if (keys[0] in obj && lvl > 0) {\n const record = tree.reduce(function(reduced, item, i) {\n if (i !== objIndex) {\n reduced[getGroupKey(i)] = item;\n }\n return reduced;\n }, {});\n record[treeLeafKey] = tree[objIndex];\n keys.forEach(function(k) {\n record[k] = obj[k];\n });\n result.push(record);\n } else {\n for (const childKey of Object.keys(obj)) {\n const child = obj[childKey];\n if (isObject(child)) {\n tree.push(childKey);\n scanTreeObject(keys, treeLeafKey, child, tree, lvl + 1, result);\n }\n }\n }\n tree.splice(objIndex, 1);\n return result;\n}\n\nexport function normalizeTreeToArray(keys, treeLeafKey, obj) {\n const data = scanTreeObject(keys, treeLeafKey, obj);\n if (!data.length) {\n return data;\n }\n const max = data.reduce(function(maxVal, element) {\n // minus 2 because _leaf and value properties are added\n // on top to groups ones\n const ikeys = Object.keys(element).length - 2;\n return maxVal > ikeys ? maxVal : ikeys;\n });\n data.forEach(function(element) {\n for (let i = 0; i < max; i++) {\n const groupKey = getGroupKey(i);\n if (!element[groupKey]) {\n element[groupKey] = '';\n }\n }\n });\n return data;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat\nexport function flatten(input) {\n const stack = [...input];\n const res = [];\n while (stack.length) {\n // pop value from stack\n const next = stack.pop();\n if (Array.isArray(next)) {\n // push back array items, won't modify the original input\n stack.push(...next);\n } else {\n res.push(next);\n }\n }\n // reverse to restore input order\n return res.reverse();\n}\n\nfunction getPath(groups, value, defaultValue) {\n if (!groups.length) {\n return;\n }\n const path = [];\n for (const grp of groups) {\n const item = value[grp];\n if (item === '') {\n path.push(defaultValue);\n break;\n }\n path.push(item);\n }\n return path.length ? path.join('.') : defaultValue;\n}\n\n/**\n * @param {[]} values\n * @param {string} grp\n * @param {[string]} keys\n * @param {string} treeeLeafKey\n * @param {string} [mainGrp]\n * @param {*} [mainValue]\n * @param {[]} groups\n */\nexport function group(values, grp, keys, treeLeafKey, mainGrp, mainValue, groups = []) {\n const key = keys[0];\n const addKeys = keys.slice(1);\n const tmp = Object.create(null);\n const data = Object.create(null);\n const ret = [];\n let g, i, n;\n for (i = 0, n = values.length; i < n; ++i) {\n const v = values[i];\n if (mainGrp && v[mainGrp] !== mainValue) {\n continue;\n }\n g = v[grp] || v[treeLeafKey] || '';\n if (!(g in tmp)) {\n const tmpRef = tmp[g] = {value: 0};\n addKeys.forEach(function(k) {\n tmpRef[k] = 0;\n });\n data[g] = [];\n }\n tmp[g].value += +v[key];\n tmp[g].label = v[grp] || '';\n const tmpRef = tmp[g];\n addKeys.forEach(function(k) {\n tmpRef[k] += v[k];\n });\n tmp[g].path = getPath(groups, v, g);\n data[g].push(v);\n }\n\n Object.keys(tmp).forEach((k) => {\n const v = {children: data[k]};\n v[key] = +tmp[k].value;\n addKeys.forEach(function(ak) {\n v[ak] = +tmp[k][ak];\n });\n v[grp] = tmp[k].label;\n v.label = k;\n v.path = tmp[k].path;\n\n if (mainGrp) {\n v[mainGrp] = mainValue;\n }\n ret.push(v);\n });\n\n return ret;\n}\n\nexport function index(values, key) {\n let n = values.length;\n let i;\n\n if (!n) {\n return key;\n }\n\n const obj = isObject(values[0]);\n key = obj ? key : 'v';\n\n for (i = 0, n = values.length; i < n; ++i) {\n if (obj) {\n values[i]._idx = i;\n } else {\n values[i] = {v: values[i], _idx: i};\n }\n }\n return key;\n}\n\nexport function sort(values, key) {\n if (key) {\n values.sort((a, b) => +b[key] - +a[key]);\n } else {\n values.sort((a, b) => +b - +a);\n }\n}\n\nexport function sum(values, key) {\n let s, i, n;\n\n for (s = 0, i = 0, n = values.length; i < n; ++i) {\n s += key ? +values[i][key] : +values[i];\n }\n\n return s;\n}\n\n/**\n * @param {string} pkg\n * @param {string} min\n * @param {string} ver\n * @param {boolean} [strict=true]\n * @returns {boolean}\n */\nexport function requireVersion(pkg, min, ver, strict = true) {\n const parts = ver.split('.');\n let i = 0;\n for (const req of min.split('.')) {\n const act = parts[i++];\n if (parseInt(req, 10) < parseInt(act, 10)) {\n break;\n }\n if (isOlderPart(act, req)) {\n if (strict) {\n throw new Error(`${pkg} v${ver} is not supported. v${min} or newer is required.`);\n } else {\n return false;\n }\n }\n }\n return true;\n}\n","import {Element} from 'chart.js';\nimport {toFont, isArray, toTRBL, toTRBLCorners, addRoundedRectPath, valueOrDefault, defined, isNumber} from 'chart.js/helpers';\n\nconst widthCache = new Map();\n\n/**\n * Helper function to get the bounds of the rect\n * @param {TreemapElement} rect the rect\n * @param {boolean} [useFinalPosition]\n * @return {object} bounds of the rect\n * @private\n */\nfunction getBounds(rect, useFinalPosition) {\n const {x, y, width, height} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);\n return {left: x, top: y, right: x + width, bottom: y + height};\n}\n\nfunction limit(value, min, max) {\n return Math.max(Math.min(value, max), min);\n}\n\nexport function parseBorderWidth(value, maxW, maxH) {\n const o = toTRBL(value);\n\n return {\n t: limit(o.top, 0, maxH),\n r: limit(o.right, 0, maxW),\n b: limit(o.bottom, 0, maxH),\n l: limit(o.left, 0, maxW)\n };\n}\n\nfunction parseBorderRadius(value, maxW, maxH) {\n const o = toTRBLCorners(value);\n const maxR = Math.min(maxW, maxH);\n\n return {\n topLeft: limit(o.topLeft, 0, maxR),\n topRight: limit(o.topRight, 0, maxR),\n bottomLeft: limit(o.bottomLeft, 0, maxR),\n bottomRight: limit(o.bottomRight, 0, maxR)\n };\n}\n\nfunction boundingRects(rect) {\n const bounds = getBounds(rect);\n const width = bounds.right - bounds.left;\n const height = bounds.bottom - bounds.top;\n const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);\n const radius = parseBorderRadius(rect.options.borderRadius, width / 2, height / 2);\n const outer = {\n x: bounds.left,\n y: bounds.top,\n w: width,\n h: height,\n active: rect.active,\n radius\n };\n\n return {\n outer,\n inner: {\n x: outer.x + border.l,\n y: outer.y + border.t,\n w: outer.w - border.l - border.r,\n h: outer.h - border.t - border.b,\n active: rect.active,\n radius: {\n topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),\n topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),\n bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)),\n bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)),\n }\n }\n };\n}\n\nfunction inRange(rect, x, y, useFinalPosition) {\n const skipX = x === null;\n const skipY = y === null;\n const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);\n\n return bounds\n\t\t&& (skipX || x >= bounds.left && x <= bounds.right)\n\t\t&& (skipY || y >= bounds.top && y <= bounds.bottom);\n}\n\nfunction hasRadius(radius) {\n return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;\n}\n\n/**\n * Add a path of a rectangle to the current sub-path\n * @param {CanvasRenderingContext2D} ctx Context\n * @param {*} rect Bounding rect\n */\nfunction addNormalRectPath(ctx, rect) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h);\n}\n\nexport function shouldDrawCaption(rect, options) {\n if (!options || options.display === false) {\n return false;\n }\n const {w, h} = rect;\n const font = toFont(options.font);\n const min = font.lineHeight;\n const padding = limit(valueOrDefault(options.padding, 3) * 2, 0, Math.min(w, h));\n return (w - padding) > min && (h - padding) > min;\n}\n\nfunction drawText(ctx, rect, options, item, levels) {\n const {captions, labels} = options;\n ctx.save();\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.w, rect.h);\n ctx.clip();\n const isLeaf = item && (!defined(item.l) || item.l === levels);\n if (isLeaf && labels.display) {\n drawLabel(ctx, rect, options);\n } else if (!isLeaf && shouldDrawCaption(rect, captions)) {\n drawCaption(ctx, rect, options, item);\n }\n ctx.restore();\n}\n\nfunction drawCaption(ctx, rect, options, item) {\n const {captions, spacing, rtl} = options;\n const {color, hoverColor, font, hoverFont, padding, align, formatter} = captions;\n const oColor = (rect.active ? hoverColor : color) || color;\n const oAlign = align || (rtl ? 'right' : 'left');\n const optFont = (rect.active ? hoverFont : font) || font;\n const oFont = toFont(optFont);\n const lh = oFont.lineHeight / 2;\n const x = calculateX(rect, oAlign, padding);\n ctx.fillStyle = oColor;\n ctx.font = oFont.string;\n ctx.textAlign = oAlign;\n ctx.textBaseline = 'middle';\n ctx.fillText(formatter || item.g, x, rect.y + padding + spacing + lh);\n}\n\nfunction measureLabelSize(ctx, lines, fonts) {\n const fontsKey = fonts.reduce(function(prev, item) {\n prev += item.string;\n return prev;\n }, '');\n const mapKey = lines.join() + fontsKey + (ctx._measureText ? '-spriting' : '');\n if (!widthCache.has(mapKey)) {\n ctx.save();\n const count = lines.length;\n let width = 0;\n let height = 0;\n for (let i = 0; i < count; i++) {\n const font = fonts[Math.min(i, fonts.length - 1)];\n ctx.font = font.string;\n const text = lines[i];\n width = Math.max(width, ctx.measureText(text).width);\n height += font.lineHeight;\n }\n ctx.restore();\n widthCache.set(mapKey, {width, height});\n }\n return widthCache.get(mapKey);\n}\n\nfunction toFonts(fonts, fitRatio) {\n return fonts.map(function(f) {\n f.size = Math.floor(f.size * fitRatio);\n f.lineHeight = undefined;\n return toFont(f);\n });\n}\n\nfunction labelToDraw(ctx, rect, options, labelSize) {\n const {overflow, padding} = options;\n const {width, height} = labelSize;\n if (overflow === 'hidden') {\n return !((width + padding * 2) > rect.w || (height + padding * 2) > rect.h);\n } else if (overflow === 'fit') {\n const ratio = Math.min(rect.w / (width + padding * 2), rect.h / (height + padding * 2));\n if (ratio < 1) {\n return ratio;\n }\n }\n return true;\n}\n\nfunction getFontFromOptions(rect, labels) {\n const {font, hoverFont} = labels;\n const optFont = (rect.active ? hoverFont : font) || font;\n return isArray(optFont) ? optFont.map(f => toFont(f)) : [toFont(optFont)];\n}\n\nfunction drawLabel(ctx, rect, options) {\n const labels = options.labels;\n const content = labels.formatter;\n if (!content) {\n return;\n }\n const contents = isArray(content) ? content : [content];\n let fonts = getFontFromOptions(rect, labels);\n let labelSize = measureLabelSize(ctx, contents, fonts);\n const lblToDraw = labelToDraw(ctx, rect, labels, labelSize);\n if (!lblToDraw) {\n return;\n }\n if (isNumber(lblToDraw)) {\n labelSize = {width: labelSize.width * lblToDraw, height: labelSize.height * lblToDraw};\n fonts = toFonts(fonts, lblToDraw);\n }\n const {color, hoverColor, align} = labels;\n const optColor = (rect.active ? hoverColor : color) || color;\n const colors = isArray(optColor) ? optColor : [optColor];\n const xyPoint = calculateXYLabel(rect, labels, labelSize);\n ctx.textAlign = align;\n ctx.textBaseline = 'middle';\n let lhs = 0;\n contents.forEach(function(l, i) {\n const c = colors[Math.min(i, colors.length - 1)];\n const f = fonts[Math.min(i, fonts.length - 1)];\n const lh = f.lineHeight;\n ctx.font = f.string;\n ctx.fillStyle = c;\n ctx.fillText(l, xyPoint.x, xyPoint.y + lh / 2 + lhs);\n lhs += lh;\n });\n}\n\nfunction drawDivider(ctx, rect, options, item) {\n const dividers = options.dividers;\n if (!dividers.display || !item._data.children.length) {\n return;\n }\n const {x, y, w, h} = rect;\n const {lineColor, lineCapStyle, lineDash, lineDashOffset, lineWidth} = dividers;\n ctx.save();\n ctx.strokeStyle = lineColor;\n ctx.lineCap = lineCapStyle;\n ctx.setLineDash(lineDash);\n ctx.lineDashOffset = lineDashOffset;\n ctx.lineWidth = lineWidth;\n ctx.beginPath();\n if (w > h) {\n const w2 = w / 2;\n ctx.moveTo(x + w2, y);\n ctx.lineTo(x + w2, y + h);\n } else {\n const h2 = h / 2;\n ctx.moveTo(x, y + h2);\n ctx.lineTo(x + w, y + h2);\n }\n ctx.stroke();\n ctx.restore();\n}\n\nfunction calculateXYLabel(rect, options, labelSize) {\n const {align, position, padding} = options;\n let x, y;\n x = calculateX(rect, align, padding);\n if (position === 'top') {\n y = rect.y + padding;\n } else if (position === 'bottom') {\n y = rect.y + rect.h - padding - labelSize.height;\n } else {\n y = rect.y + (rect.h - labelSize.height) / 2 + padding;\n }\n return {x, y};\n}\n\nfunction calculateX(rect, align, padding) {\n if (align === 'left') {\n return rect.x + padding;\n } else if (align === 'right') {\n return rect.x + rect.w - padding;\n }\n return rect.x + rect.w / 2;\n}\n\nexport default class TreemapElement extends Element {\n\n constructor(cfg) {\n super();\n\n this.options = undefined;\n this.width = undefined;\n this.height = undefined;\n\n if (cfg) {\n Object.assign(this, cfg);\n }\n }\n\n draw(ctx, data, levels = 0) {\n if (!data) {\n return;\n }\n const options = this.options;\n const {inner, outer} = boundingRects(this);\n\n const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;\n\n ctx.save();\n\n if (outer.w !== inner.w || outer.h !== inner.h) {\n ctx.beginPath();\n addRectPath(ctx, outer);\n ctx.clip();\n addRectPath(ctx, inner);\n ctx.fillStyle = options.borderColor;\n ctx.fill('evenodd');\n }\n\n ctx.beginPath();\n addRectPath(ctx, inner);\n ctx.fillStyle = options.backgroundColor;\n ctx.fill();\n\n drawDivider(ctx, inner, options, data);\n drawText(ctx, inner, options, data, levels);\n ctx.restore();\n }\n\n inRange(mouseX, mouseY, useFinalPosition) {\n return inRange(this, mouseX, mouseY, useFinalPosition);\n }\n\n inXRange(mouseX, useFinalPosition) {\n return inRange(this, mouseX, null, useFinalPosition);\n }\n\n inYRange(mouseY, useFinalPosition) {\n return inRange(this, null, mouseY, useFinalPosition);\n }\n\n getCenterPoint(useFinalPosition) {\n const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);\n return {\n x: x + width / 2,\n y: y + height / 2\n };\n }\n\n tooltipPosition() {\n return this.getCenterPoint();\n }\n\n /**\n * @todo: remove this unused function in v3\n */\n getRange(axis) {\n return axis === 'x' ? this.width / 2 : this.height / 2;\n }\n}\n\nTreemapElement.id = 'treemap';\n\nTreemapElement.defaults = {\n label: undefined,\n borderRadius: 0,\n borderWidth: 0,\n captions: {\n align: undefined,\n color: 'black',\n display: true,\n font: {},\n formatter: (ctx) => ctx.raw.g || ctx.raw._data.label || '',\n padding: 3\n },\n dividers: {\n display: false,\n lineCapStyle: 'butt',\n lineColor: 'black',\n lineDash: [],\n lineDashOffset: 0,\n lineWidth: 1,\n },\n labels: {\n align: 'center',\n color: 'black',\n display: false,\n font: {},\n formatter(ctx) {\n if (ctx.raw.g) {\n return [ctx.raw.g, ctx.raw.v + ''];\n }\n return ctx.raw._data.label ? [ctx.raw._data.label, ctx.raw.v + ''] : ctx.raw.v + '';\n },\n overflow: 'cut',\n position: 'middle',\n padding: 3\n },\n rtl: false,\n spacing: 0.5\n};\n\nTreemapElement.descriptors = {\n labels: {\n _fallback: true\n },\n captions: {\n _fallback: true\n },\n _scriptable: true,\n _indexable: false\n};\n\nTreemapElement.defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor'\n};\n","function getDims(itm, w2, s2, key) {\n const a = itm._normalized;\n const ar = w2 * a / s2;\n const d1 = Math.sqrt(a * ar);\n const d2 = a / d1;\n const w = key === '_ix' ? d1 : d2;\n const h = key === '_ix' ? d2 : d1;\n\n return {d1, d2, w, h};\n}\n\nconst getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;\n\nfunction buildRow(rect, itm, dims, sum) {\n const r = {\n x: getX(rect, dims.w),\n y: rect.y + rect._iy,\n w: dims.w,\n h: dims.h,\n a: itm._normalized,\n v: itm.value,\n vs: itm.values,\n s: sum,\n _data: itm._data\n };\n if (itm.group) {\n r.g = itm.group;\n r.l = itm.level;\n r.gs = itm.groupSum;\n }\n return r;\n}\n\nexport default class Rect {\n constructor(r) {\n r = r || {w: 1, h: 1};\n this.rtl = !!r.rtl;\n this.x = r.x || r.left || 0;\n this.y = r.y || r.top || 0;\n this._ix = 0;\n this._iy = 0;\n this.w = r.w || r.width || (r.right - r.left);\n this.h = r.h || r.height || (r.bottom - r.top);\n }\n\n get area() {\n return this.w * this.h;\n }\n\n get iw() {\n return this.w - this._ix;\n }\n\n get ih() {\n return this.h - this._iy;\n }\n\n get dir() {\n const ih = this.ih;\n return ih <= this.iw && ih > 0 ? 'y' : 'x';\n }\n\n get side() {\n return this.dir === 'x' ? this.iw : this.ih;\n }\n\n map(arr) {\n const {dir, side} = this;\n const key = dir === 'x' ? '_ix' : '_iy';\n const sum = arr.nsum;\n const row = arr.get();\n const w2 = side * side;\n const s2 = sum * sum;\n const ret = [];\n let maxd2 = 0;\n let totd1 = 0;\n for (const itm of row) {\n const dims = getDims(itm, w2, s2, key);\n totd1 += dims.d1;\n maxd2 = Math.max(maxd2, dims.d2);\n ret.push(buildRow(this, itm, dims, arr.sum));\n this[key] += dims.d1;\n }\n\n this[dir === 'x' ? '_iy' : '_ix'] += maxd2;\n this[key] -= totd1;\n return ret;\n }\n}\n","const min = Math.min;\nconst max = Math.max;\n\nfunction getStat(sa) {\n return {\n min: sa.min,\n max: sa.max,\n sum: sa.sum,\n nmin: sa.nmin,\n nmax: sa.nmax,\n nsum: sa.nsum\n };\n}\n\nfunction getNewStat(sa, o) {\n const v = +o[sa.key];\n const n = v * sa.ratio;\n o._normalized = n;\n\n return {\n min: min(sa.min, v),\n max: max(sa.max, v),\n sum: sa.sum + v,\n nmin: min(sa.nmin, n),\n nmax: max(sa.nmax, n),\n nsum: sa.nsum + n\n };\n}\n\nfunction setStat(sa, stat) {\n Object.assign(sa, stat);\n}\n\nfunction push(sa, o, stat) {\n sa._arr.push(o);\n setStat(sa, stat);\n}\n\nexport default class StatArray {\n constructor(key, ratio) {\n const me = this;\n me.key = key;\n me.ratio = ratio;\n me.reset();\n }\n\n get length() {\n return this._arr.length;\n }\n\n reset() {\n const me = this;\n me._arr = [];\n me._hist = [];\n me.sum = 0;\n me.nsum = 0;\n me.min = Infinity;\n me.max = -Infinity;\n me.nmin = Infinity;\n me.nmax = -Infinity;\n }\n\n push(o) {\n push(this, o, getNewStat(this, o));\n }\n\n pushIf(o, fn, ...args) {\n const nstat = getNewStat(this, o);\n if (!fn(getStat(this), nstat, args)) {\n return o;\n }\n push(this, o, nstat);\n }\n\n get() {\n return this._arr;\n }\n}\n","import {sum, index, sort, flatten} from './utils';\nimport Rect from './rect';\nimport StatArray from './statArray';\n\nfunction compareAspectRatio(oldStat, newStat, args) {\n if (oldStat.sum === 0) {\n return true;\n }\n\n const [length] = args;\n const os2 = oldStat.nsum * oldStat.nsum;\n const ns2 = newStat.nsum * newStat.nsum;\n const l2 = length * length;\n const or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));\n const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));\n return nr <= or;\n}\n\n/**\n *\n * @param {number[]|object[]} values\n * @param {object} rectangle\n * @param {string} [key]\n * @param {string} [grp]\n * @param {number} [lvl]\n * @param {number} [gsum]\n */\nexport default function squarify(values, rectangle, keys = [], grp, lvl, gsum) {\n values = values || [];\n const rows = [];\n const rect = new Rect(rectangle);\n const row = new StatArray('value', rect.area / sum(values, keys[0]));\n let length = rect.side;\n const n = values.length;\n let i, o;\n\n if (!n) {\n return rows;\n }\n\n const tmp = values.slice();\n let key = index(tmp, keys[0]);\n sort(tmp, key);\n\n const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];\n const gval = (idx) => grp && tmp[idx][grp];\n\n for (i = 0; i < n; ++i) {\n o = {value: val(i), groupSum: gsum, _data: values[tmp[i]._idx], level: undefined, group: undefined};\n if (grp) {\n o.level = lvl;\n o.group = gval(i);\n const tmpRef = tmp[i];\n o.values = keys.reduce(function(obj, k) {\n obj[k] = +tmpRef[k];\n return obj;\n }, {});\n }\n o = row.pushIf(o, compareAspectRatio, length);\n if (o) {\n rows.push(rect.map(row));\n length = rect.side;\n row.reset();\n row.push(o);\n }\n }\n if (row.length) {\n rows.push(rect.map(row));\n }\n return flatten(rows);\n}\n","export function scaleRect(sq, xScale, yScale, sp) {\n const sp2 = sp * 2;\n const x = xScale.getPixelForValue(sq.x);\n const y = yScale.getPixelForValue(sq.y);\n const w = xScale.getPixelForValue(sq.x + sq.w) - x;\n const h = yScale.getPixelForValue(sq.y + sq.h) - y;\n return {\n x: x + sp,\n y: y + sp,\n width: w - sp2,\n height: h - sp2,\n hidden: sp2 > w || sp2 > h,\n };\n}\n\nexport function rectNotEqual(r1, r2) {\n return !r1 || !r2\n\t\t|| r1.x !== r2.x\n\t\t|| r1.y !== r2.y\n\t\t|| r1.w !== r2.w\n\t\t|| r1.h !== r2.h\n || r1.rtl !== r2.rtl;\n}\n\nexport function arrayNotEqual(a, b) {\n let i, n;\n\n if (!a || !b) {\n return true;\n }\n\n if (a === b) {\n return false;\n }\n\n if (a.length !== b.length) {\n return true;\n }\n\n for (i = 0, n = a.length; i < n; ++i) {\n if (a[i] !== b[i]) {\n return true;\n }\n }\n return false;\n}\n","import {Chart, DatasetController, registry} from 'chart.js';\nimport {toFont, valueOrDefault, isObject, clipArea, unclipArea} from 'chart.js/helpers';\nimport {group, requireVersion, normalizeTreeToArray, getGroupKey} from './utils';\nimport {shouldDrawCaption, parseBorderWidth} from './element';\nimport squarify from './squarify';\nimport {version} from '../package.json';\nimport {arrayNotEqual, rectNotEqual, scaleRect} from './helpers/index';\n\nfunction buildData(tree, dataset, keys, mainRect) {\n const treeLeafKey = dataset.treeLeafKey || '_leaf';\n if (isObject(tree)) {\n tree = normalizeTreeToArray(keys, treeLeafKey, tree);\n }\n const groups = dataset.groups || [];\n const glen = groups.length;\n const sp = valueOrDefault(dataset.spacing, 0);\n const captions = dataset.captions || {};\n const font = toFont(captions.font);\n const padding = valueOrDefault(captions.padding, 3);\n\n function recur(treeElements, gidx, rect, parent, gs) {\n const g = getGroupKey(groups[gidx]);\n const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);\n const gdata = group(treeElements, g, keys, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));\n const gsq = squarify(gdata, rect, keys, g, gidx, gs);\n const ret = gsq.slice();\n if (gidx < glen - 1) {\n gsq.forEach((sq) => {\n const bw = parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2);\n const subRect = {\n ...rect,\n x: sq.x + sp + bw.l,\n y: sq.y + sp + bw.t,\n w: sq.w - 2 * sp - bw.l - bw.r,\n h: sq.h - 2 * sp - bw.t - bw.b,\n };\n if (shouldDrawCaption(subRect, captions)) {\n subRect.y += font.lineHeight + padding * 2;\n subRect.h -= font.lineHeight + padding * 2;\n }\n gdata.forEach((gEl) => {\n ret.push(...recur(gEl.children, gidx + 1, subRect, sq.g, sq.s));\n });\n });\n }\n return ret;\n }\n\n return glen\n ? recur(tree, 0, mainRect)\n : squarify(tree, mainRect, keys);\n}\n\nexport default class TreemapController extends DatasetController {\n constructor(chart, datasetIndex) {\n super(chart, datasetIndex);\n\n this._groups = undefined;\n this._keys = undefined;\n this._rect = undefined;\n this._rectChanged = true;\n }\n\n initialize() {\n this.enableOptionSharing = true;\n super.initialize();\n }\n\n getMinMax(scale) {\n return {\n min: 0,\n max: scale.axis === 'x' ? scale.right - scale.left : scale.bottom - scale.top\n };\n }\n\n configure() {\n super.configure();\n const {xScale, yScale} = this.getMeta();\n if (!xScale || !yScale) {\n // configure is called once before `linkScales`, and at that call we don't have any scales linked yet\n return;\n }\n\n const w = xScale.right - xScale.left;\n const h = yScale.bottom - yScale.top;\n const rect = {x: 0, y: 0, w, h, rtl: !!this.options.rtl};\n\n if (rectNotEqual(this._rect, rect)) {\n this._rect = rect;\n this._rectChanged = true;\n }\n\n if (this._rectChanged) {\n xScale.max = w;\n xScale.configure();\n yScale.max = h;\n yScale.configure();\n }\n }\n\n update(mode) {\n const dataset = this.getDataset();\n const {data} = this.getMeta();\n const groups = dataset.groups || [];\n const keys = [dataset.key || ''].concat(dataset.sumKeys || []);\n const tree = dataset.tree = dataset.tree || dataset.data || [];\n\n if (mode === 'reset') {\n // reset is called before 2nd configure and is only called if animations are enabled. So wen need an extra configure call here.\n this.configure();\n }\n\n if (this._rectChanged || arrayNotEqual(this._keys, keys) || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {\n this._groups = groups.slice();\n this._keys = keys.slice();\n this._prevTree = tree;\n this._rectChanged = false;\n\n dataset.data = buildData(tree, dataset, this._keys, this._rect);\n // @ts-ignore using private stuff\n this._dataCheck();\n // @ts-ignore using private stuff\n this._resyncElements();\n }\n\n this.updateElements(data, 0, data.length, mode);\n }\n\n updateElements(rects, start, count, mode) {\n const reset = mode === 'reset';\n const dataset = this.getDataset();\n const firstOpts = this._rect.options = this.resolveDataElementOptions(start, mode);\n const sharedOptions = this.getSharedOptions(firstOpts);\n const includeOptions = this.includeOptions(mode, sharedOptions);\n const {xScale, yScale} = this.getMeta(this.index);\n\n for (let i = start; i < start + count; i++) {\n const options = sharedOptions || this.resolveDataElementOptions(i, mode);\n const properties = scaleRect(dataset.data[i], xScale, yScale, options.spacing);\n if (reset) {\n properties.width = 0;\n properties.height = 0;\n }\n\n if (includeOptions) {\n properties.options = options;\n }\n this.updateElement(rects[i], i, properties, mode);\n }\n\n this.updateSharedOptions(sharedOptions, mode, firstOpts);\n }\n\n draw() {\n const {ctx, chartArea} = this.chart;\n const metadata = this.getMeta().data || [];\n const dataset = this.getDataset();\n const levels = (dataset.groups || []).length - 1;\n const data = dataset.data;\n\n clipArea(ctx, chartArea);\n for (let i = 0, ilen = metadata.length; i < ilen; ++i) {\n const rect = metadata[i];\n if (!rect.hidden) {\n rect.draw(ctx, data[i], levels);\n }\n }\n unclipArea(ctx);\n }\n}\n\nTreemapController.id = 'treemap';\n\nTreemapController.version = version;\n\nTreemapController.defaults = {\n dataElementType: 'treemap',\n\n animations: {\n numbers: {\n type: 'number',\n properties: ['x', 'y', 'width', 'height']\n },\n },\n\n};\n\nTreemapController.descriptors = {\n _scriptable: true,\n _indexable: false\n};\n\nTreemapController.overrides = {\n interaction: {\n mode: 'point',\n includeInvisible: true,\n intersect: true\n },\n\n hover: {},\n\n plugins: {\n tooltip: {\n position: 'treemap',\n intersect: true,\n callbacks: {\n title(items) {\n if (items.length) {\n const item = items[0];\n return item.dataset.key || '';\n }\n return '';\n },\n label(item) {\n const dataset = item.dataset;\n const dataItem = dataset.data[item.dataIndex];\n const label = dataItem.g || dataItem._data.label || dataset.label;\n return (label ? label + ': ' : '') + dataItem.v;\n }\n }\n },\n },\n scales: {\n x: {\n type: 'linear',\n alignToPixels: true,\n bounds: 'data',\n display: false\n },\n y: {\n type: 'linear',\n alignToPixels: true,\n bounds: 'data',\n display: false,\n reverse: true\n }\n },\n};\n\nTreemapController.beforeRegister = function() {\n requireVersion('chart.js', '3.8', Chart.version);\n};\n\nTreemapController.afterRegister = function() {\n const tooltipPlugin = registry.plugins.get('tooltip');\n if (tooltipPlugin) {\n tooltipPlugin.positioners.treemap = function(active) {\n if (!active.length) {\n return false;\n }\n\n const item = active[active.length - 1];\n const el = item.element;\n\n return el.tooltipPosition();\n };\n } else {\n console.warn('Unable to register the treemap positioner because tooltip plugin is not registered');\n }\n};\n\nTreemapController.afterUnregister = function() {\n const tooltipPlugin = registry.plugins.get('tooltip');\n if (tooltipPlugin) {\n delete tooltipPlugin.positioners.treemap;\n }\n};\n","import {Chart} from 'chart.js';\nimport TreemapController from './controller';\nimport TreemapElement from './element';\n\nChart.register(TreemapController, TreemapElement);\n\nexport * from './utils';\n"],"names":["isOlderPart","act","req","length","slice","getGroupKey","lvl","scanTreeObject","keys","treeLeafKey","obj","tree","result","objIndex","record","reduce","reduced","item","i","forEach","k","push","childKey","Object","child","isObject","splice","normalizeTreeToArray","data","max","maxVal","element","ikeys","groupKey","flatten","input","stack","res","next","pop","Array","isArray","reverse","getPath","groups","value","defaultValue","path","grp","join","group","values","mainGrp","mainValue","key","addKeys","tmp","create","ret","g","n","v","tmpRef","label","children","ak","index","_idx","sort","a","b","sum","s","requireVersion","pkg","min","ver","strict","parts","split","parseInt","Error","widthCache","Map","getBounds","rect","useFinalPosition","x","y","width","height","getProps","left","top","right","bottom","limit","Math","parseBorderWidth","maxW","maxH","o","toTRBL","t","r","l","boundingRects","bounds","border","options","borderWidth","radius","toTRBLCorners","maxR","topLeft","topRight","bottomLeft","bottomRight","parseBorderRadius","borderRadius","outer","w","h","active","inner","inRange","skipX","skipY","addNormalRectPath","ctx","shouldDrawCaption","display","toFont","font","lineHeight","padding","valueOrDefault","drawText","levels","captions","labels","save","beginPath","clip","isLeaf","defined","content","formatter","contents","fonts","hoverFont","optFont","map","f","getFontFromOptions","labelSize","lines","fontsKey","prev","string","mapKey","_measureText","has","count","text","measureText","restore","set","get","measureLabelSize","lblToDraw","overflow","ratio","labelToDraw","isNumber","fitRatio","size","floor","undefined","toFonts","color","hoverColor","align","optColor","colors","xyPoint","position","calculateX","calculateXYLabel","textAlign","textBaseline","lhs","c","lh","fillStyle","fillText","drawLabel","spacing","rtl","oColor","oAlign","oFont","drawCaption","TreemapElement","Element","constructor","cfg","super","this","assign","draw","addRectPath","addRoundedRectPath","borderColor","fill","backgroundColor","dividers","_data","lineColor","lineCapStyle","lineDash","lineDashOffset","lineWidth","strokeStyle","lineCap","setLineDash","w2","moveTo","lineTo","h2","stroke","drawDivider","mouseX","mouseY","inXRange","inYRange","getCenterPoint","tooltipPosition","getRange","axis","getDims","itm","s2","_normalized","ar","d1","sqrt","d2","id","defaults","raw","descriptors","_fallback","_scriptable","_indexable","defaultRoutes","getX","iw","_ix","buildRow","dims","_iy","vs","level","gs","groupSum","Rect","area","ih","dir","side","arr","nsum","row","maxd2","totd1","getNewStat","sa","nmin","nmax","stat","_arr","setStat","StatArray","me","reset","_hist","Infinity","pushIf","fn","args","nstat","compareAspectRatio","oldStat","newStat","os2","ns2","l2","or","squarify","rectangle","gsum","rows","gval","idx","scaleRect","sq","xScale","yScale","sp","sp2","getPixelForValue","hidden","arrayNotEqual","TreemapController","DatasetController","chart","datasetIndex","_groups","_keys","_rect","_rectChanged","initialize","enableOptionSharing","getMinMax","scale","configure","getMeta","r1","r2","update","mode","dataset","getDataset","concat","sumKeys","_prevTree","mainRect","glen","recur","treeElements","gidx","parent","pg","gdata","filter","gsq","bw","subRect","gEl","buildData","_dataCheck","_resyncElements","updateElements","rects","start","firstOpts","resolveDataElementOptions","sharedOptions","getSharedOptions","includeOptions","properties","updateElement","updateSharedOptions","chartArea","metadata","clipArea","ilen","unclipArea","version","dataElementType","animations","numbers","type","overrides","interaction","includeInvisible","intersect","hover","plugins","tooltip","callbacks","title","items","dataItem","dataIndex","scales","alignToPixels","beforeRegister","Chart","afterRegister","tooltipPlugin","registry","positioners","treemap","console","warn","afterUnregister","register"],"mappings":"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"}
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.2.0",
4
+ "version": "2.3.1",
5
5
  "description": "Chart.js module for creating treemap charts",
6
6
  "type": "module",
7
7
  "main": "dist/chartjs-chart-treemap.esm.js",
@@ -16,8 +16,8 @@
16
16
  "scripts": {
17
17
  "autobuild": "rollup -c -w",
18
18
  "build": "rollup -c",
19
- "dev": "karma start ./karma.conf.cjs --no-signle-run --auto-watch --browsers chrome",
20
- "dev:ff": "karma start ./karma.conf.cjs --no-signle-run --auto-watch --browsers firefox",
19
+ "dev": "karma start ./karma.conf.cjs --no-single-run --auto-watch --browsers chrome",
20
+ "dev:ff": "karma start ./karma.conf.cjs --no-single-run --auto-watch --browsers firefox",
21
21
  "docs": "npm run build && vuepress build docs --no-cache",
22
22
  "docs:dev": "concurrently \"npm:autobuild\" \"vuepress dev docs --no-cache\"",
23
23
  "lint": "concurrently -r \"npm:lint-*\"",
@@ -27,7 +27,7 @@
27
27
  "test": "cross-env NODE_ENV=test concurrently \"npm:test-*\"",
28
28
  "test-lint": "npm run lint",
29
29
  "test-types": "tsc -p types/tests/",
30
- "test-karma": "karma start ./karma.conf.cjs --auto-watch --single-run"
30
+ "test-karma": "karma start ./karma.conf.cjs --no-auto-watch --single-run"
31
31
  },
32
32
  "repository": {
33
33
  "type": "git",
@@ -59,7 +59,7 @@
59
59
  "chartjs-plugin-datalabels": "^2.2.0",
60
60
  "chartjs-plugin-zoom": "^2.0.0",
61
61
  "chartjs-test-utils": "^0.5.0",
62
- "concurrently": "^7.4.0",
62
+ "concurrently": "^8.2.2",
63
63
  "cross-env": "^7.0.3",
64
64
  "eslint": "^8.3.0",
65
65
  "eslint-config-chartjs": "^0.3.0",
@@ -41,7 +41,7 @@ export type LabelPosition = 'top' | 'middle' | 'bottom';
41
41
 
42
42
  export type LabelAlign = 'left' | 'center' | 'right';
43
43
 
44
- export type LabelOverflow = 'cut' | 'hidden';
44
+ export type LabelOverflow = 'cut' | 'hidden' | 'fit';
45
45
 
46
46
  type TreemapControllerDatasetDividersOptions = {
47
47
  display?: boolean,
@@ -71,6 +71,7 @@ export interface TreemapControllerDatasetOptions<DType> {
71
71
 
72
72
  data: TreemapDataPoint[]; // This will be auto-generated from `tree`
73
73
  groups?: Array<keyof DType>;
74
+ sumKeys?: Array<keyof DType>;
74
75
  tree: number[] | DType[] | AnyObject;
75
76
  treeLeafKey?: keyof DType;
76
77
  key?: keyof DType;
@@ -101,6 +102,10 @@ export interface TreemapDataPoint {
101
102
  * Group Sum, only available if grouping
102
103
  */
103
104
  gs?: number,
105
+ /**
106
+ * additonal keys sums, only available if grouping
107
+ */
108
+ vs?: AnyObject
104
109
  }
105
110
 
106
111
  /*