chartjs-chart-treemap 2.1.3 → 2.3.0

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,17 +1,19 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.3
2
+ * chartjs-chart-treemap v2.3.0
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2023 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
+
10
+ const isOlderPart = (act, req) => req > act || (act.length > req.length && act.slice(0, req.length) === req);
9
11
 
10
12
  const getGroupKey = (lvl) => '' + lvl;
11
13
 
12
- function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
14
+ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
13
15
  const objIndex = lvl - 1;
14
- if (key in obj && lvl > 0) {
16
+ if (keys[0] in obj && lvl > 0) {
15
17
  const record = tree.reduce(function(reduced, item, i) {
16
18
  if (i !== objIndex) {
17
19
  reduced[getGroupKey(i)] = item;
@@ -19,14 +21,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
19
21
  return reduced;
20
22
  }, {});
21
23
  record[treeLeafKey] = tree[objIndex];
22
- record[key] = obj[key];
24
+ keys.forEach(function(k) {
25
+ record[k] = obj[k];
26
+ });
23
27
  result.push(record);
24
28
  } else {
25
29
  for (const childKey of Object.keys(obj)) {
26
30
  const child = obj[childKey];
27
31
  if (isObject(child)) {
28
32
  tree.push(childKey);
29
- scanTreeObject(key, treeLeafKey, child, tree, lvl + 1, result);
33
+ scanTreeObject(keys, treeLeafKey, child, tree, lvl + 1, result);
30
34
  }
31
35
  }
32
36
  }
@@ -34,16 +38,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
34
38
  return result;
35
39
  }
36
40
 
37
- function normalizeTreeToArray(key, treeLeafKey, obj) {
38
- const data = scanTreeObject(key, treeLeafKey, obj);
41
+ function normalizeTreeToArray(keys, treeLeafKey, obj) {
42
+ const data = scanTreeObject(keys, treeLeafKey, obj);
39
43
  if (!data.length) {
40
44
  return data;
41
45
  }
42
46
  const max = data.reduce(function(maxVal, element) {
43
47
  // minus 2 because _leaf and value properties are added
44
48
  // on top to groups ones
45
- const keys = Object.keys(element).length - 2;
46
- return maxVal > keys ? maxVal : keys;
49
+ const ikeys = Object.keys(element).length - 2;
50
+ return maxVal > ikeys ? maxVal : ikeys;
47
51
  });
48
52
  data.forEach(function(element) {
49
53
  for (let i = 0; i < max; i++) {
@@ -93,13 +97,15 @@ function getPath(groups, value, defaultValue) {
93
97
  /**
94
98
  * @param {[]} values
95
99
  * @param {string} grp
96
- * @param {string} key
100
+ * @param {[string]} keys
97
101
  * @param {string} treeeLeafKey
98
102
  * @param {string} [mainGrp]
99
103
  * @param {*} [mainValue]
100
104
  * @param {[]} groups
101
105
  */
102
- 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);
103
109
  const tmp = Object.create(null);
104
110
  const data = Object.create(null);
105
111
  const ret = [];
@@ -111,11 +117,18 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
111
117
  }
112
118
  g = v[grp] || v[treeLeafKey] || '';
113
119
  if (!(g in tmp)) {
114
- tmp[g] = {value: 0};
120
+ const tmpRef = tmp[g] = {value: 0};
121
+ addKeys.forEach(function(k) {
122
+ tmpRef[k] = 0;
123
+ });
115
124
  data[g] = [];
116
125
  }
117
126
  tmp[g].value += +v[key];
118
127
  tmp[g].label = v[grp] || '';
128
+ const tmpRef = tmp[g];
129
+ addKeys.forEach(function(k) {
130
+ tmpRef[k] += v[k];
131
+ });
119
132
  tmp[g].path = getPath(groups, v, g);
120
133
  data[g].push(v);
121
134
  }
@@ -123,6 +136,9 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
123
136
  Object.keys(tmp).forEach((k) => {
124
137
  const v = {children: data[k]};
125
138
  v[key] = +tmp[k].value;
139
+ addKeys.forEach(function(ak) {
140
+ v[ak] = +tmp[k][ak];
141
+ });
126
142
  v[grp] = tmp[k].label;
127
143
  v.label = k;
128
144
  v.path = tmp[k].path;
@@ -175,11 +191,30 @@ function sum(values, key) {
175
191
  return s;
176
192
  }
177
193
 
178
- function requireVersion(min, ver) {
194
+ /**
195
+ * @param {string} pkg
196
+ * @param {string} min
197
+ * @param {string} ver
198
+ * @param {boolean} [strict=true]
199
+ * @returns {boolean}
200
+ */
201
+ function requireVersion(pkg, min, ver, strict = true) {
179
202
  const parts = ver.split('.');
180
- if (!min.split('.').reduce((a, c, i) => a && c <= parts[i], true)) {
181
- throw new Error(`Chart.js v${ver} is not supported. v${min} or newer is required.`);
203
+ let i = 0;
204
+ for (const req of min.split('.')) {
205
+ const act = parts[i++];
206
+ if (parseInt(req, 10) < parseInt(act, 10)) {
207
+ break;
208
+ }
209
+ if (isOlderPart(act, req)) {
210
+ if (strict) {
211
+ throw new Error(`${pkg} v${ver} is not supported. v${min} or newer is required.`);
212
+ } else {
213
+ return false;
214
+ }
215
+ }
182
216
  }
217
+ return true;
183
218
  }
184
219
 
185
220
  const widthCache = new Map();
@@ -345,15 +380,34 @@ function measureLabelSize(ctx, lines, fonts) {
345
380
  return widthCache.get(mapKey);
346
381
  }
347
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
+
348
391
  function labelToDraw(ctx, rect, options, labelSize) {
349
392
  const {overflow, padding} = options;
350
393
  const {width, height} = labelSize;
351
394
  if (overflow === 'hidden') {
352
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
+ }
353
401
  }
354
402
  return true;
355
403
  }
356
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
+
357
411
  function drawLabel(ctx, rect, options) {
358
412
  const labels = options.labels;
359
413
  const content = labels.formatter;
@@ -361,13 +415,16 @@ function drawLabel(ctx, rect, options) {
361
415
  return;
362
416
  }
363
417
  const contents = isArray(content) ? content : [content];
364
- const {font, hoverFont} = labels;
365
- const optFont = (rect.active ? hoverFont : font) || font;
366
- const fonts = isArray(optFont) ? optFont.map(f => toFont(f)) : [toFont(optFont)];
367
- const labelSize = measureLabelSize(ctx, contents, fonts);
368
- 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) {
369
422
  return;
370
423
  }
424
+ if (isNumber(lblToDraw)) {
425
+ labelSize = {width: labelSize.width * lblToDraw, height: labelSize.height * lblToDraw};
426
+ fonts = toFonts(fonts, lblToDraw);
427
+ }
371
428
  const {color, hoverColor, align} = labels;
372
429
  const optColor = (rect.active ? hoverColor : color) || color;
373
430
  const colors = isArray(optColor) ? optColor : [optColor];
@@ -590,6 +647,7 @@ function buildRow(rect, itm, dims, sum) {
590
647
  h: dims.h,
591
648
  a: itm._normalized,
592
649
  v: itm.value,
650
+ vs: itm.values,
593
651
  s: sum,
594
652
  _data: itm._data
595
653
  };
@@ -760,11 +818,11 @@ function compareAspectRatio(oldStat, newStat, args) {
760
818
  * @param {number} [lvl]
761
819
  * @param {number} [gsum]
762
820
  */
763
- function squarify(values, rectangle, key, grp, lvl, gsum) {
821
+ function squarify(values, rectangle, keys = [], grp, lvl, gsum) {
764
822
  values = values || [];
765
823
  const rows = [];
766
824
  const rect = new Rect(rectangle);
767
- const row = new StatArray('value', rect.area / sum(values, key));
825
+ const row = new StatArray('value', rect.area / sum(values, keys[0]));
768
826
  let length = rect.side;
769
827
  const n = values.length;
770
828
  let i, o;
@@ -774,7 +832,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
774
832
  }
775
833
 
776
834
  const tmp = values.slice();
777
- key = index(tmp, key);
835
+ let key = index(tmp, keys[0]);
778
836
  sort(tmp, key);
779
837
 
780
838
  const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
@@ -785,6 +843,11 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
785
843
  if (grp) {
786
844
  o.level = lvl;
787
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
+ }, {});
788
851
  }
789
852
  o = row.pushIf(o, compareAspectRatio, length);
790
853
  if (o) {
@@ -800,7 +863,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
800
863
  return flatten(rows);
801
864
  }
802
865
 
803
- var version = "2.1.3";
866
+ var version = "2.3.0";
804
867
 
805
868
  function scaleRect(sq, xScale, yScale, sp) {
806
869
  const sp2 = sp * 2;
@@ -849,11 +912,10 @@ function arrayNotEqual(a, b) {
849
912
  return false;
850
913
  }
851
914
 
852
- function buildData(tree, dataset, mainRect) {
853
- const key = dataset.key || '';
915
+ function buildData(tree, dataset, keys, mainRect) {
854
916
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
855
917
  if (isObject(tree)) {
856
- tree = normalizeTreeToArray(key, treeLeafKey, tree);
918
+ tree = normalizeTreeToArray(keys, treeLeafKey, tree);
857
919
  }
858
920
  const groups = dataset.groups || [];
859
921
  const glen = groups.length;
@@ -865,8 +927,8 @@ function buildData(tree, dataset, mainRect) {
865
927
  function recur(gidx, rect, parent, gs) {
866
928
  const g = getGroupKey(groups[gidx]);
867
929
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
868
- const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
869
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
930
+ const gdata = group(tree, g, keys, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
931
+ const gsq = squarify(gdata, rect, keys, g, gidx, gs);
870
932
  const ret = gsq.slice();
871
933
  if (gidx < glen - 1) {
872
934
  gsq.forEach((sq) => {
@@ -890,7 +952,7 @@ function buildData(tree, dataset, mainRect) {
890
952
 
891
953
  return glen
892
954
  ? recur(0, mainRect)
893
- : squarify(tree, mainRect, key);
955
+ : squarify(tree, mainRect, keys);
894
956
  }
895
957
 
896
958
  class TreemapController extends DatasetController {
@@ -898,7 +960,7 @@ class TreemapController extends DatasetController {
898
960
  super(chart, datasetIndex);
899
961
 
900
962
  this._groups = undefined;
901
- this._key = undefined;
963
+ this._keys = undefined;
902
964
  this._rect = undefined;
903
965
  this._rectChanged = true;
904
966
  }
@@ -943,8 +1005,8 @@ class TreemapController extends DatasetController {
943
1005
  update(mode) {
944
1006
  const dataset = this.getDataset();
945
1007
  const {data} = this.getMeta();
946
- const groups = dataset.groups || (dataset.groups = []);
947
- const key = dataset.key;
1008
+ const groups = dataset.groups || [];
1009
+ const keys = [dataset.key || ''].concat(dataset.sumKeys || []);
948
1010
  const tree = dataset.tree = dataset.tree || dataset.data || [];
949
1011
 
950
1012
  if (mode === 'reset') {
@@ -952,13 +1014,13 @@ class TreemapController extends DatasetController {
952
1014
  this.configure();
953
1015
  }
954
1016
 
955
- if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
1017
+ if (this._rectChanged || arrayNotEqual(this._keys, keys) || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
956
1018
  this._groups = groups.slice();
957
- this._key = key;
1019
+ this._keys = keys.slice();
958
1020
  this._prevTree = tree;
959
1021
  this._rectChanged = false;
960
1022
 
961
- dataset.data = buildData(tree, dataset, this._rect);
1023
+ dataset.data = buildData(tree, dataset, this._keys, this._rect);
962
1024
  // @ts-ignore using private stuff
963
1025
  this._dataCheck();
964
1026
  // @ts-ignore using private stuff
@@ -1080,7 +1142,7 @@ TreemapController.overrides = {
1080
1142
  };
1081
1143
 
1082
1144
  TreemapController.beforeRegister = function() {
1083
- requireVersion('3.8', Chart.version);
1145
+ requireVersion('chart.js', '3.8', Chart.version);
1084
1146
  };
1085
1147
 
1086
1148
  TreemapController.afterRegister = function() {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.3
2
+ * chartjs-chart-treemap v2.3.0
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2023 Jukka Kurkela
5
5
  * Released under the MIT license
6
6
  */
7
7
  (function (global, factory) {
@@ -10,11 +10,13 @@ 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 isOlderPart = (act, req) => req > act || (act.length > req.length && act.slice(0, req.length) === req);
14
+
13
15
  const getGroupKey = (lvl) => '' + lvl;
14
16
 
15
- function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
17
+ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = []) {
16
18
  const objIndex = lvl - 1;
17
- if (key in obj && lvl > 0) {
19
+ if (keys[0] in obj && lvl > 0) {
18
20
  const record = tree.reduce(function(reduced, item, i) {
19
21
  if (i !== objIndex) {
20
22
  reduced[getGroupKey(i)] = item;
@@ -22,14 +24,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
22
24
  return reduced;
23
25
  }, {});
24
26
  record[treeLeafKey] = tree[objIndex];
25
- record[key] = obj[key];
27
+ keys.forEach(function(k) {
28
+ record[k] = obj[k];
29
+ });
26
30
  result.push(record);
27
31
  } else {
28
32
  for (const childKey of Object.keys(obj)) {
29
33
  const child = obj[childKey];
30
34
  if (helpers.isObject(child)) {
31
35
  tree.push(childKey);
32
- scanTreeObject(key, treeLeafKey, child, tree, lvl + 1, result);
36
+ scanTreeObject(keys, treeLeafKey, child, tree, lvl + 1, result);
33
37
  }
34
38
  }
35
39
  }
@@ -37,16 +41,16 @@ function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = [])
37
41
  return result;
38
42
  }
39
43
 
40
- function normalizeTreeToArray(key, treeLeafKey, obj) {
41
- const data = scanTreeObject(key, treeLeafKey, obj);
44
+ function normalizeTreeToArray(keys, treeLeafKey, obj) {
45
+ const data = scanTreeObject(keys, treeLeafKey, obj);
42
46
  if (!data.length) {
43
47
  return data;
44
48
  }
45
49
  const max = data.reduce(function(maxVal, element) {
46
50
  // minus 2 because _leaf and value properties are added
47
51
  // on top to groups ones
48
- const keys = Object.keys(element).length - 2;
49
- return maxVal > keys ? maxVal : keys;
52
+ const ikeys = Object.keys(element).length - 2;
53
+ return maxVal > ikeys ? maxVal : ikeys;
50
54
  });
51
55
  data.forEach(function(element) {
52
56
  for (let i = 0; i < max; i++) {
@@ -96,13 +100,15 @@ function getPath(groups, value, defaultValue) {
96
100
  /**
97
101
  * @param {[]} values
98
102
  * @param {string} grp
99
- * @param {string} key
103
+ * @param {[string]} keys
100
104
  * @param {string} treeeLeafKey
101
105
  * @param {string} [mainGrp]
102
106
  * @param {*} [mainValue]
103
107
  * @param {[]} groups
104
108
  */
105
- 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);
106
112
  const tmp = Object.create(null);
107
113
  const data = Object.create(null);
108
114
  const ret = [];
@@ -114,11 +120,18 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
114
120
  }
115
121
  g = v[grp] || v[treeLeafKey] || '';
116
122
  if (!(g in tmp)) {
117
- tmp[g] = {value: 0};
123
+ const tmpRef = tmp[g] = {value: 0};
124
+ addKeys.forEach(function(k) {
125
+ tmpRef[k] = 0;
126
+ });
118
127
  data[g] = [];
119
128
  }
120
129
  tmp[g].value += +v[key];
121
130
  tmp[g].label = v[grp] || '';
131
+ const tmpRef = tmp[g];
132
+ addKeys.forEach(function(k) {
133
+ tmpRef[k] += v[k];
134
+ });
122
135
  tmp[g].path = getPath(groups, v, g);
123
136
  data[g].push(v);
124
137
  }
@@ -126,6 +139,9 @@ function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) {
126
139
  Object.keys(tmp).forEach((k) => {
127
140
  const v = {children: data[k]};
128
141
  v[key] = +tmp[k].value;
142
+ addKeys.forEach(function(ak) {
143
+ v[ak] = +tmp[k][ak];
144
+ });
129
145
  v[grp] = tmp[k].label;
130
146
  v.label = k;
131
147
  v.path = tmp[k].path;
@@ -178,11 +194,30 @@ function sum(values, key) {
178
194
  return s;
179
195
  }
180
196
 
181
- function requireVersion(min, ver) {
197
+ /**
198
+ * @param {string} pkg
199
+ * @param {string} min
200
+ * @param {string} ver
201
+ * @param {boolean} [strict=true]
202
+ * @returns {boolean}
203
+ */
204
+ function requireVersion(pkg, min, ver, strict = true) {
182
205
  const parts = ver.split('.');
183
- if (!min.split('.').reduce((a, c, i) => a && c <= parts[i], true)) {
184
- throw new Error(`Chart.js v${ver} is not supported. v${min} or newer is required.`);
206
+ let i = 0;
207
+ for (const req of min.split('.')) {
208
+ const act = parts[i++];
209
+ if (parseInt(req, 10) < parseInt(act, 10)) {
210
+ break;
211
+ }
212
+ if (isOlderPart(act, req)) {
213
+ if (strict) {
214
+ throw new Error(`${pkg} v${ver} is not supported. v${min} or newer is required.`);
215
+ } else {
216
+ return false;
217
+ }
218
+ }
185
219
  }
220
+ return true;
186
221
  }
187
222
 
188
223
  const widthCache = new Map();
@@ -348,15 +383,34 @@ function measureLabelSize(ctx, lines, fonts) {
348
383
  return widthCache.get(mapKey);
349
384
  }
350
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
+
351
394
  function labelToDraw(ctx, rect, options, labelSize) {
352
395
  const {overflow, padding} = options;
353
396
  const {width, height} = labelSize;
354
397
  if (overflow === 'hidden') {
355
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
+ }
356
404
  }
357
405
  return true;
358
406
  }
359
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
+
360
414
  function drawLabel(ctx, rect, options) {
361
415
  const labels = options.labels;
362
416
  const content = labels.formatter;
@@ -364,13 +418,16 @@ function drawLabel(ctx, rect, options) {
364
418
  return;
365
419
  }
366
420
  const contents = helpers.isArray(content) ? content : [content];
367
- const {font, hoverFont} = labels;
368
- const optFont = (rect.active ? hoverFont : font) || font;
369
- const fonts = helpers.isArray(optFont) ? optFont.map(f => helpers.toFont(f)) : [helpers.toFont(optFont)];
370
- const labelSize = measureLabelSize(ctx, contents, fonts);
371
- 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) {
372
425
  return;
373
426
  }
427
+ if (helpers.isNumber(lblToDraw)) {
428
+ labelSize = {width: labelSize.width * lblToDraw, height: labelSize.height * lblToDraw};
429
+ fonts = toFonts(fonts, lblToDraw);
430
+ }
374
431
  const {color, hoverColor, align} = labels;
375
432
  const optColor = (rect.active ? hoverColor : color) || color;
376
433
  const colors = helpers.isArray(optColor) ? optColor : [optColor];
@@ -593,6 +650,7 @@ function buildRow(rect, itm, dims, sum) {
593
650
  h: dims.h,
594
651
  a: itm._normalized,
595
652
  v: itm.value,
653
+ vs: itm.values,
596
654
  s: sum,
597
655
  _data: itm._data
598
656
  };
@@ -763,11 +821,11 @@ function compareAspectRatio(oldStat, newStat, args) {
763
821
  * @param {number} [lvl]
764
822
  * @param {number} [gsum]
765
823
  */
766
- function squarify(values, rectangle, key, grp, lvl, gsum) {
824
+ function squarify(values, rectangle, keys = [], grp, lvl, gsum) {
767
825
  values = values || [];
768
826
  const rows = [];
769
827
  const rect = new Rect(rectangle);
770
- const row = new StatArray('value', rect.area / sum(values, key));
828
+ const row = new StatArray('value', rect.area / sum(values, keys[0]));
771
829
  let length = rect.side;
772
830
  const n = values.length;
773
831
  let i, o;
@@ -777,7 +835,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
777
835
  }
778
836
 
779
837
  const tmp = values.slice();
780
- key = index(tmp, key);
838
+ let key = index(tmp, keys[0]);
781
839
  sort(tmp, key);
782
840
 
783
841
  const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
@@ -788,6 +846,11 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
788
846
  if (grp) {
789
847
  o.level = lvl;
790
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
+ }, {});
791
854
  }
792
855
  o = row.pushIf(o, compareAspectRatio, length);
793
856
  if (o) {
@@ -803,7 +866,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
803
866
  return flatten(rows);
804
867
  }
805
868
 
806
- var version = "2.1.3";
869
+ var version = "2.3.0";
807
870
 
808
871
  function scaleRect(sq, xScale, yScale, sp) {
809
872
  const sp2 = sp * 2;
@@ -852,11 +915,10 @@ function arrayNotEqual(a, b) {
852
915
  return false;
853
916
  }
854
917
 
855
- function buildData(tree, dataset, mainRect) {
856
- const key = dataset.key || '';
918
+ function buildData(tree, dataset, keys, mainRect) {
857
919
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
858
920
  if (helpers.isObject(tree)) {
859
- tree = normalizeTreeToArray(key, treeLeafKey, tree);
921
+ tree = normalizeTreeToArray(keys, treeLeafKey, tree);
860
922
  }
861
923
  const groups = dataset.groups || [];
862
924
  const glen = groups.length;
@@ -868,8 +930,8 @@ function buildData(tree, dataset, mainRect) {
868
930
  function recur(gidx, rect, parent, gs) {
869
931
  const g = getGroupKey(groups[gidx]);
870
932
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
871
- const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
872
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
933
+ const gdata = group(tree, g, keys, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
934
+ const gsq = squarify(gdata, rect, keys, g, gidx, gs);
873
935
  const ret = gsq.slice();
874
936
  if (gidx < glen - 1) {
875
937
  gsq.forEach((sq) => {
@@ -893,7 +955,7 @@ function buildData(tree, dataset, mainRect) {
893
955
 
894
956
  return glen
895
957
  ? recur(0, mainRect)
896
- : squarify(tree, mainRect, key);
958
+ : squarify(tree, mainRect, keys);
897
959
  }
898
960
 
899
961
  class TreemapController extends chart_js.DatasetController {
@@ -901,7 +963,7 @@ class TreemapController extends chart_js.DatasetController {
901
963
  super(chart, datasetIndex);
902
964
 
903
965
  this._groups = undefined;
904
- this._key = undefined;
966
+ this._keys = undefined;
905
967
  this._rect = undefined;
906
968
  this._rectChanged = true;
907
969
  }
@@ -946,8 +1008,8 @@ class TreemapController extends chart_js.DatasetController {
946
1008
  update(mode) {
947
1009
  const dataset = this.getDataset();
948
1010
  const {data} = this.getMeta();
949
- const groups = dataset.groups || (dataset.groups = []);
950
- const key = dataset.key;
1011
+ const groups = dataset.groups || [];
1012
+ const keys = [dataset.key || ''].concat(dataset.sumKeys || []);
951
1013
  const tree = dataset.tree = dataset.tree || dataset.data || [];
952
1014
 
953
1015
  if (mode === 'reset') {
@@ -955,13 +1017,13 @@ class TreemapController extends chart_js.DatasetController {
955
1017
  this.configure();
956
1018
  }
957
1019
 
958
- if (this._rectChanged || this._key !== key || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
1020
+ if (this._rectChanged || arrayNotEqual(this._keys, keys) || arrayNotEqual(this._groups, groups) || this._prevTree !== tree) {
959
1021
  this._groups = groups.slice();
960
- this._key = key;
1022
+ this._keys = keys.slice();
961
1023
  this._prevTree = tree;
962
1024
  this._rectChanged = false;
963
1025
 
964
- dataset.data = buildData(tree, dataset, this._rect);
1026
+ dataset.data = buildData(tree, dataset, this._keys, this._rect);
965
1027
  // @ts-ignore using private stuff
966
1028
  this._dataCheck();
967
1029
  // @ts-ignore using private stuff
@@ -1083,7 +1145,7 @@ TreemapController.overrides = {
1083
1145
  };
1084
1146
 
1085
1147
  TreemapController.beforeRegister = function() {
1086
- requireVersion('3.8', chart_js.Chart.version);
1148
+ requireVersion('chart.js', '3.8', chart_js.Chart.version);
1087
1149
  };
1088
1150
 
1089
1151
  TreemapController.afterRegister = function() {
@@ -1122,6 +1184,4 @@ exports.requireVersion = requireVersion;
1122
1184
  exports.sort = sort;
1123
1185
  exports.sum = sum;
1124
1186
 
1125
- Object.defineProperty(exports, '__esModule', { value: true });
1126
-
1127
1187
  }));
@@ -1,7 +1,8 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.3
2
+ * chartjs-chart-treemap v2.3.0
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
- * (c) 2022 Jukka Kurkela
4
+ * (c) 2023 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=>""+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})}));
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 n(o,s,p,m){const b=r(h[o]),y=o>0&&r(h[o-1]),v=l(t,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((t=>{const i=x(e.borderWidth,t.w/2,t.h/2),r={...s,x:t.x+u+i.l,y:t.y+u+i.t,w:t.w-2*u-i.l-i.r,h:t.h-2*u-i.t-i.b};w(r,f)&&(r.y+=d.lineHeight+2*g,r.h-=d.lineHeight+2*g),M.push(...n(o+1,r,t.g,t.s))})),M}(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.0",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(gidx, rect, parent, gs) {\n const g = getGroupKey(groups[gidx]);\n const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);\n const gdata = group(tree, 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 ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));\n });\n }\n return ret;\n }\n\n return glen\n ? recur(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","gidx","parent","pg","gdata","filter","gsq","bw","subRect","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,16 +1,23 @@
1
1
  {
2
2
  "name": "chartjs-chart-treemap",
3
3
  "homepage": "https://chartjs-chart-treemap.pages.dev/",
4
- "version": "2.1.3",
4
+ "version": "2.3.0",
5
5
  "description": "Chart.js module for creating treemap charts",
6
- "main": "dist/chartjs-chart-treemap.js",
7
- "module": "dist/chartjs-chart-treemap.esm.js",
6
+ "type": "module",
7
+ "main": "dist/chartjs-chart-treemap.esm.js",
8
8
  "types": "types/index.esm.d.ts",
9
+ "jsdelivr": "dist/chartjs-chart-treemap.min.js",
10
+ "unpkg": "dist/chartjs-chart-treemap.min.js",
11
+ "exports": {
12
+ "types": "./types/index.esm.d.ts",
13
+ "import": "./dist/chartjs-chart-treemap.esm.js",
14
+ "require": "./dist/chartjs-chart-treemap.min.js"
15
+ },
9
16
  "scripts": {
10
17
  "autobuild": "rollup -c -w",
11
18
  "build": "rollup -c",
12
- "dev": "karma start --no-signle-run --auto-watch --browsers chrome",
13
- "dev:ff": "karma start --no-signle-run --auto-watch --browsers firefox",
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",
14
21
  "docs": "npm run build && vuepress build docs --no-cache",
15
22
  "docs:dev": "concurrently \"npm:autobuild\" \"vuepress dev docs --no-cache\"",
16
23
  "lint": "concurrently -r \"npm:lint-*\"",
@@ -20,7 +27,7 @@
20
27
  "test": "cross-env NODE_ENV=test concurrently \"npm:test-*\"",
21
28
  "test-lint": "npm run lint",
22
29
  "test-types": "tsc -p types/tests/",
23
- "test-karma": "karma start --auto-watch --single-run"
30
+ "test-karma": "karma start ./karma.conf.cjs --auto-watch --single-run"
24
31
  },
25
32
  "repository": {
26
33
  "type": "git",
@@ -32,7 +39,8 @@
32
39
  "treemap"
33
40
  ],
34
41
  "files": [
35
- "dist/*.js",
42
+ "dist/*",
43
+ "!dist/docs/**",
36
44
  "types/index.esm.d.ts"
37
45
  ],
38
46
  "author": "Jukka Kurkela",
@@ -41,19 +49,18 @@
41
49
  "url": "https://github.com/kurkle/chartjs-chart-treemap/issues"
42
50
  },
43
51
  "devDependencies": {
44
- "@rollup/plugin-commonjs": "^23.0.0",
45
- "@rollup/plugin-json": "^5.0.0",
46
- "@rollup/plugin-node-resolve": "^15.0.0",
52
+ "@rollup/plugin-commonjs": "^23.0.2",
53
+ "@rollup/plugin-json": "^5.0.1",
54
+ "@rollup/plugin-node-resolve": "^15.0.1",
55
+ "@rollup/plugin-terser": "^0.1.0",
47
56
  "@typescript-eslint/eslint-plugin": "^5.4.0",
48
57
  "@typescript-eslint/parser": "^5.4.0",
49
- "chart.js": "^3.8.0",
50
- "chartjs-adapter-date-fns": "^2.0.0",
51
- "chartjs-plugin-datalabels": "^2.0.0",
52
- "chartjs-plugin-zoom": "^1.2.0",
58
+ "chart.js": "^4.0.1",
59
+ "chartjs-plugin-datalabels": "^2.2.0",
60
+ "chartjs-plugin-zoom": "^2.0.0",
53
61
  "chartjs-test-utils": "^0.5.0",
54
62
  "concurrently": "^7.4.0",
55
63
  "cross-env": "^7.0.3",
56
- "date-fns": "^2.20.2",
57
64
  "eslint": "^8.3.0",
58
65
  "eslint-config-chartjs": "^0.3.0",
59
66
  "eslint-plugin-es": "^4.1.0",
@@ -67,21 +74,20 @@
67
74
  "karma-jasmine": "^5.1.0",
68
75
  "karma-jasmine-html-reporter": "^2.0.0",
69
76
  "karma-rollup-preprocessor": "7.0.7",
70
- "karma-spec-reporter": "^0.0.34",
77
+ "karma-spec-reporter": "^0.0.35",
71
78
  "karma-summary-reporter": "^3.0.0",
72
79
  "ng-hammerjs": "^2.0.8",
73
80
  "pixelmatch": "^5.2.1",
74
- "rollup": "^2.79.1",
81
+ "rollup": "^3.3.0",
75
82
  "rollup-plugin-analyzer": "^4.0.0",
76
- "rollup-plugin-istanbul": "^3.0.0",
77
- "rollup-plugin-terser": "^7.0.2",
78
- "typescript": "^4.3.5",
79
- "vuepress": "^1.8.2",
83
+ "rollup-plugin-istanbul": "^4.0.0",
84
+ "typescript": "^4.7.4",
85
+ "vuepress": "^1.9.7",
80
86
  "vuepress-plugin-flexsearch": "^0.3.0",
81
87
  "vuepress-plugin-redirect": "^1.2.5",
82
88
  "vuepress-theme-chartjs": "^0.2.0"
83
89
  },
84
90
  "peerDependencies": {
85
- "chart.js": "^3.0.0"
91
+ "chart.js": ">=3.0.0"
86
92
  }
87
93
  }
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  Chart,
3
3
  ChartComponent,
4
+ CoreChartOptions,
4
5
  DatasetController,
5
6
  Element, VisualElement,
6
7
  ScriptableContext, Color, Scriptable, FontSpec
7
8
  } from 'chart.js';
8
- import { AnyObject } from 'chart.js/types/basic';
9
+
10
+ type AnyObject = Record<string, unknown>;
9
11
 
10
12
  type TreemapScriptableContext = ScriptableContext<'treemap'> & {
11
13
  raw: TreemapDataPoint
@@ -39,7 +41,7 @@ export type LabelPosition = 'top' | 'middle' | 'bottom';
39
41
 
40
42
  export type LabelAlign = 'left' | 'center' | 'right';
41
43
 
42
- export type LabelOverflow = 'cut' | 'hidden';
44
+ export type LabelOverflow = 'cut' | 'hidden' | 'fit';
43
45
 
44
46
  type TreemapControllerDatasetDividersOptions = {
45
47
  display?: boolean,
@@ -69,6 +71,7 @@ export interface TreemapControllerDatasetOptions<DType> {
69
71
 
70
72
  data: TreemapDataPoint[]; // This will be auto-generated from `tree`
71
73
  groups?: Array<keyof DType>;
74
+ sumKeys?: Array<keyof DType>;
72
75
  tree: number[] | DType[] | AnyObject;
73
76
  treeLeafKey?: keyof DType;
74
77
  key?: keyof DType;
@@ -99,6 +102,10 @@ export interface TreemapDataPoint {
99
102
  * Group Sum, only available if grouping
100
103
  */
101
104
  gs?: number,
105
+ /**
106
+ * additonal keys sums, only available if grouping
107
+ */
108
+ vs?: AnyObject
102
109
  }
103
110
 
104
111
  /*