chartjs-chart-treemap 2.1.0 → 2.1.2

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.6.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.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)
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,5 +1,5 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.0
2
+ * chartjs-chart-treemap v2.1.2
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
4
  * (c) 2022 Jukka Kurkela
5
5
  * Released under the MIT license
@@ -192,6 +192,18 @@ function requireVersion(min, ver) {
192
192
  }
193
193
  }
194
194
 
195
+ const rasterize = (v, dpr) => Math.round(v * dpr) / dpr;
196
+
197
+ function rasterizeRect(rect, dpr) {
198
+ return {
199
+ ...rect,
200
+ x: rasterize(rect.x, dpr),
201
+ y: rasterize(rect.y, dpr),
202
+ w: rasterize(rect.w, dpr),
203
+ h: rasterize(rect.h, dpr),
204
+ };
205
+ }
206
+
195
207
  const widthCache = new Map();
196
208
 
197
209
  /**
@@ -233,26 +245,29 @@ function parseBorderRadius(value, maxW, maxH) {
233
245
  };
234
246
  }
235
247
 
236
- function boundingRects(rect) {
248
+ function boundingRects(rect, dpr) {
237
249
  const bounds = getBounds(rect);
238
250
  const width = bounds.right - bounds.left;
239
251
  const height = bounds.bottom - bounds.top;
240
252
  const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
241
253
  const radius = parseBorderRadius(rect.options.borderRadius, width / 2, height / 2);
254
+ const outer = rasterizeRect({
255
+ x: bounds.left,
256
+ y: bounds.top,
257
+ w: width,
258
+ h: height,
259
+ active: rect.active,
260
+ radius
261
+ }, dpr);
242
262
 
243
263
  return {
244
- outer: {
245
- x: bounds.left,
246
- y: bounds.top,
247
- w: width,
248
- h: height,
249
- radius
250
- },
264
+ outer,
251
265
  inner: {
252
- x: bounds.left + border.l,
253
- y: bounds.top + border.t,
254
- w: width - border.l - border.r,
255
- h: height - border.t - border.b,
266
+ x: outer.x + border.l,
267
+ y: outer.y + border.t,
268
+ w: outer.w - border.l - border.r,
269
+ h: outer.h - border.t - border.b,
270
+ active: rect.active,
256
271
  radius: {
257
272
  topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
258
273
  topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
@@ -287,7 +302,7 @@ function addNormalRectPath(ctx, rect) {
287
302
  }
288
303
 
289
304
  function shouldDrawCaption(rect, options) {
290
- if (!options || !options.display) {
305
+ if (!options || options.display === false) {
291
306
  return false;
292
307
  }
293
308
  const {w, h} = rect;
@@ -457,12 +472,12 @@ class TreemapElement extends Element {
457
472
  }
458
473
  }
459
474
 
460
- draw(ctx, data, levels = 0) {
475
+ draw(ctx, data, levels = 0, dpr) {
461
476
  if (!data) {
462
477
  return;
463
478
  }
464
479
  const options = this.options;
465
- const {inner, outer} = boundingRects(this);
480
+ const {inner, outer} = boundingRects(this, dpr);
466
481
 
467
482
  const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
468
483
 
@@ -511,6 +526,9 @@ class TreemapElement extends Element {
511
526
  return this.getCenterPoint();
512
527
  }
513
528
 
529
+ /**
530
+ * @todo: remove this unused function in v3
531
+ */
514
532
  getRange(axis) {
515
533
  return axis === 'x' ? this.width / 2 : this.height / 2;
516
534
  }
@@ -573,35 +591,30 @@ TreemapElement.defaultRoutes = {
573
591
  borderColor: 'borderColor'
574
592
  };
575
593
 
576
- function round(v, n) {
577
- // @ts-ignore
578
- return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
579
- }
580
-
581
- function getDims(itm, w2, s2, key) {
594
+ function getDims(itm, w2, s2, key, dpr, maxd2) {
582
595
  const a = itm._normalized;
583
596
  const ar = w2 * a / s2;
584
- const d1 = Math.sqrt(a * ar);
585
- const d2 = a / d1;
597
+ const d1 = rasterize(Math.sqrt(a * ar), dpr);
598
+ const d2 = Math.min(rasterize(a / d1, dpr), maxd2);
586
599
  const w = key === '_ix' ? d1 : d2;
587
600
  const h = key === '_ix' ? d2 : d1;
588
601
 
589
602
  return {d1, d2, w, h};
590
603
  }
591
604
 
592
- const getX = (rect, w) => round(rect.rtl ? rect.x + rect.w - rect._ix - w : rect.x + rect._ix, 4);
605
+ const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
593
606
 
594
- function buildRow(rect, itm, dims, sum) {
595
- const r = {
607
+ function buildRow(rect, itm, dims, sum, dpr) {
608
+ const r = rasterizeRect({
596
609
  x: getX(rect, dims.w),
597
- y: round(rect.y + rect._iy, 4),
598
- w: round(dims.w, 4),
599
- h: round(dims.h, 4),
600
- a: round(itm._normalized, 4),
610
+ y: rect.y + rect._iy,
611
+ w: dims.w,
612
+ h: dims.h,
613
+ a: itm._normalized,
601
614
  v: itm.value,
602
615
  s: sum,
603
616
  _data: itm._data
604
- };
617
+ }, dpr);
605
618
  if (itm.group) {
606
619
  r.g = itm.group;
607
620
  r.l = itm.level;
@@ -611,16 +624,16 @@ function buildRow(rect, itm, dims, sum) {
611
624
  }
612
625
 
613
626
  class Rect {
614
- constructor(r) {
615
- const me = this;
627
+ constructor(r, dpr) {
628
+ this.dpr = dpr;
616
629
  r = r || {w: 1, h: 1};
617
- me.rtl = !!r.rtl;
618
- me.x = r.x || r.left || 0;
619
- me.y = r.y || r.top || 0;
620
- me._ix = 0;
621
- me._iy = 0;
622
- me.w = r.w || r.width || (r.right - r.left);
623
- me.h = r.h || r.height || (r.bottom - r.top);
630
+ this.rtl = !!r.rtl;
631
+ this.x = r.x || r.left || 0;
632
+ this.y = r.y || r.top || 0;
633
+ this._ix = 0;
634
+ this._iy = 0;
635
+ this.w = r.w || r.width || (r.right - r.left);
636
+ this.h = r.h || r.height || (r.bottom - r.top);
624
637
  }
625
638
 
626
639
  get area() {
@@ -641,34 +654,61 @@ class Rect {
641
654
  }
642
655
 
643
656
  get side() {
644
- return this.dir === 'x' ? this.iw : this.ih;
657
+ return rasterize(this.dir === 'x' ? this.iw : this.ih, this.dpr);
645
658
  }
646
659
 
647
660
  map(arr) {
648
- const me = this;
649
- const ret = [];
661
+ const {dir, side, dpr} = this;
662
+ const {key, d2prop, id2prop, d2key} = getPropNames(dir);
650
663
  const sum = arr.nsum;
651
664
  const row = arr.get();
652
- const dir = me.dir;
653
- const side = me.side;
654
665
  const w2 = side * side;
655
- const key = dir === 'x' ? '_ix' : '_iy';
666
+ const availd2 = rasterize(this[id2prop], dpr);
656
667
  const s2 = sum * sum;
668
+ const ret = [];
657
669
  let maxd2 = 0;
658
670
  let totd1 = 0;
659
671
  for (const itm of row) {
660
- const dims = getDims(itm, w2, s2, key);
672
+ const dims = getDims(itm, w2, s2, key, dpr, availd2);
661
673
  totd1 += dims.d1;
662
- maxd2 = Math.max(maxd2, dims.d2);
663
- ret.push(buildRow(me, itm, dims, arr.sum));
664
- me[key] += dims.d1;
674
+ maxd2 = Math.min(Math.max(maxd2, dims.d2), availd2);
675
+ ret.push(buildRow(this, itm, dims, arr.sum, dpr));
676
+ this[key] += dims.d1;
665
677
  }
666
- me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
667
- me[key] -= totd1;
678
+ // make sure all rects are same size in d2 direction
679
+ for (const r of ret) {
680
+ const d2 = r[d2prop];
681
+ if (d2 !== maxd2) {
682
+ if (this.rtl && dir === 'y') {
683
+ // for RTL, x-coordinate needs to be adjusted too
684
+ r.x -= maxd2 - d2;
685
+ }
686
+ r[d2prop] = maxd2;
687
+ }
688
+ }
689
+ this[d2key] += maxd2;
690
+ this[key] -= totd1;
668
691
  return ret;
669
692
  }
670
693
  }
671
694
 
695
+ function getPropNames(dir) {
696
+ if (dir === 'x') {
697
+ return {
698
+ key: '_ix',
699
+ d2prop: 'h',
700
+ id2prop: 'ih',
701
+ d2key: '_iy'
702
+ };
703
+ }
704
+ return {
705
+ key: '_iy',
706
+ d2prop: 'w',
707
+ id2prop: 'iw',
708
+ d2key: '_ix'
709
+ };
710
+ }
711
+
672
712
  const min = Math.min;
673
713
  const max = Math.max;
674
714
 
@@ -766,15 +806,16 @@ function compareAspectRatio(oldStat, newStat, args) {
766
806
  *
767
807
  * @param {number[]|object[]} values
768
808
  * @param {object} rectangle
769
- * @param {string} key
770
- * @param {*} grp
771
- * @param {*} lvl
772
- * @param {*} gsum
809
+ * @param {string} [key]
810
+ * @param {number} [dpr=1]
811
+ * @param {*} [grp]
812
+ * @param {*} [lvl]
813
+ * @param {*} [gsum]
773
814
  */
774
- function squarify(values, rectangle, key, grp, lvl, gsum) {
815
+ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
775
816
  values = values || [];
776
817
  const rows = [];
777
- const rect = new Rect(rectangle);
818
+ const rect = new Rect(rectangle, dpr);
778
819
  const row = new StatArray('value', rect.area / sum(values, key));
779
820
  let length = rect.side;
780
821
  const n = values.length;
@@ -811,7 +852,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
811
852
  return flatten(rows);
812
853
  }
813
854
 
814
- var version = "2.1.0";
855
+ var version = "2.1.2";
815
856
 
816
857
  function rectNotEqual(r1, r2) {
817
858
  return !r1 || !r2
@@ -836,7 +877,7 @@ function arrayNotEqual(a1, a2) {
836
877
  return false;
837
878
  }
838
879
 
839
- function buildData(dataset, mainRect) {
880
+ function buildData(dataset, mainRect, dpr) {
840
881
  const key = dataset.key || '';
841
882
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
842
883
  let tree = dataset.tree || [];
@@ -846,7 +887,7 @@ function buildData(dataset, mainRect) {
846
887
  const groups = dataset.groups || [];
847
888
  const glen = groups.length;
848
889
  const sp = valueOrDefault(dataset.spacing, 0);
849
- const captions = dataset.captions || {display: true};
890
+ const captions = dataset.captions || {};
850
891
  const font = toFont(captions.font);
851
892
  const padding = valueOrDefault(captions.padding, 3);
852
893
 
@@ -854,24 +895,23 @@ function buildData(dataset, mainRect) {
854
895
  const g = getGroupKey(groups[gidx]);
855
896
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
856
897
  const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
857
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
898
+ const gsq = squarify(gdata, rect, key, dpr, g, gidx, gs);
858
899
  const ret = gsq.slice();
859
- let subRect;
860
900
  if (gidx < glen - 1) {
861
901
  gsq.forEach((sq) => {
862
902
  const bw = parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2);
863
- subRect = {
903
+ const subRect = {
904
+ ...rect,
864
905
  x: sq.x + sp + bw.l,
865
906
  y: sq.y + sp + bw.t,
866
907
  w: sq.w - 2 * sp - bw.l - bw.r,
867
908
  h: sq.h - 2 * sp - bw.t - bw.b,
868
- rtl: rect.rtl
869
909
  };
870
910
  if (shouldDrawCaption(subRect, captions)) {
871
911
  subRect.y += font.lineHeight + padding * 2;
872
912
  subRect.h -= font.lineHeight + padding * 2;
873
913
  }
874
- ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
914
+ ret.push(...recur(gidx + 1, rasterizeRect(subRect, dpr), sq.g, sq.s));
875
915
  });
876
916
  }
877
917
  return ret;
@@ -883,7 +923,7 @@ function buildData(dataset, mainRect) {
883
923
 
884
924
  return glen
885
925
  ? recur(0, mainRect)
886
- : squarify(tree, mainRect, key);
926
+ : squarify(tree, mainRect, key, dpr);
887
927
  }
888
928
 
889
929
  function getMinMax(data, useTree) {
@@ -917,8 +957,7 @@ class TreemapController extends DatasetController {
917
957
  }
918
958
 
919
959
  /**
920
- * TODO: to be removed when https://github.com/kurkle/chartjs-chart-treemap/issues/137
921
- * will be implemented
960
+ * @todo: Remove with https://github.com/kurkle/chartjs-chart-treemap/issues/137
922
961
  */
923
962
  updateRangeFromParsed(range, scale) {
924
963
  if (range.updated) {
@@ -930,39 +969,39 @@ class TreemapController extends DatasetController {
930
969
  range.max = 1;
931
970
  return;
932
971
  }
933
- const me = this;
934
- const dataset = me.getDataset();
935
- const {vMin, vMax} = getMinMax(dataset.data, me._useTree);
972
+ const dataset = this.getDataset();
973
+ const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
936
974
  range.min = vMin;
937
975
  range.max = vMax;
938
976
  }
939
977
 
940
978
  update(mode) {
941
- const me = this;
942
- const meta = me.getMeta();
943
- const dataset = me.getDataset();
944
- if (!defined(me._useTree)) {
945
- me._useTree = !!dataset.tree;
979
+ const meta = this.getMeta();
980
+ const dataset = this.getDataset();
981
+ const dpr = this.chart.currentDevicePixelRatio;
982
+
983
+ if (!defined(this._useTree)) {
984
+ this._useTree = !!dataset.tree;
946
985
  }
947
986
  const groups = dataset.groups || (dataset.groups = []);
948
987
  const key = dataset.key || '';
949
988
  const rtl = !!dataset.rtl;
950
989
 
951
- const mainRect = getArea(meta, dataset.data, rtl, me._useTree);
990
+ const mainRect = rasterizeRect(getArea(meta, dataset.data, rtl, this._useTree), dpr);
952
991
 
953
- if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
954
- me._rect = mainRect;
955
- me._groups = groups.slice();
956
- me._key = key;
992
+ if (mode === 'reset' || rectNotEqual(this._rect, mainRect) || this._key !== key || arrayNotEqual(this._groups, groups)) {
993
+ this._rect = mainRect;
994
+ this._groups = groups.slice();
995
+ this._key = key;
957
996
 
958
- dataset.data = buildData(dataset, mainRect);
997
+ dataset.data = buildData(dataset, mainRect, dpr);
959
998
  // @ts-ignore using private stuff
960
- me._dataCheck();
999
+ this._dataCheck();
961
1000
  // @ts-ignore using private stuff
962
- me._resyncElements();
1001
+ this._resyncElements();
963
1002
  }
964
1003
 
965
- me.updateElements(meta.data, 0, meta.data.length, mode);
1004
+ this.updateElements(meta.data, 0, meta.data.length, mode);
966
1005
  }
967
1006
 
968
1007
  updateElements(rects, start, count, mode) {
@@ -996,19 +1035,17 @@ class TreemapController extends DatasetController {
996
1035
  }
997
1036
 
998
1037
  draw() {
999
- const me = this;
1000
- const ctx = me.chart.ctx;
1001
- const area = me.chart.chartArea;
1002
- const metadata = me.getMeta().data || [];
1003
- const dataset = me.getDataset();
1038
+ const {ctx, chartArea, currentDevicePixelRatio: dpr} = this.chart;
1039
+ const metadata = this.getMeta().data || [];
1040
+ const dataset = this.getDataset();
1004
1041
  const levels = (dataset.groups || []).length - 1;
1005
1042
  const data = dataset.data;
1006
1043
 
1007
- clipArea(ctx, area);
1044
+ clipArea(ctx, chartArea);
1008
1045
  for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
1009
1046
  const rect = metadata[i];
1010
1047
  if (!rect.hidden) {
1011
- rect.draw(ctx, data[i], levels);
1048
+ rect.draw(ctx, data[i], levels, dpr);
1012
1049
  }
1013
1050
  }
1014
1051
  unclipArea(ctx);
@@ -1039,6 +1076,7 @@ TreemapController.descriptors = {
1039
1076
  TreemapController.overrides = {
1040
1077
  interaction: {
1041
1078
  mode: 'point',
1079
+ includeInvisible: true,
1042
1080
  intersect: true
1043
1081
  },
1044
1082
 
@@ -1078,7 +1116,7 @@ TreemapController.overrides = {
1078
1116
  };
1079
1117
 
1080
1118
  TreemapController.beforeRegister = function() {
1081
- requireVersion('3.6', Chart.version);
1119
+ requireVersion('3.8', Chart.version);
1082
1120
  };
1083
1121
 
1084
1122
  TreemapController.afterRegister = function() {
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.0
2
+ * chartjs-chart-treemap v2.1.2
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
4
  * (c) 2022 Jukka Kurkela
5
5
  * Released under the MIT license
@@ -195,6 +195,18 @@ function requireVersion(min, ver) {
195
195
  }
196
196
  }
197
197
 
198
+ const rasterize = (v, dpr) => Math.round(v * dpr) / dpr;
199
+
200
+ function rasterizeRect(rect, dpr) {
201
+ return {
202
+ ...rect,
203
+ x: rasterize(rect.x, dpr),
204
+ y: rasterize(rect.y, dpr),
205
+ w: rasterize(rect.w, dpr),
206
+ h: rasterize(rect.h, dpr),
207
+ };
208
+ }
209
+
198
210
  const widthCache = new Map();
199
211
 
200
212
  /**
@@ -236,26 +248,29 @@ function parseBorderRadius(value, maxW, maxH) {
236
248
  };
237
249
  }
238
250
 
239
- function boundingRects(rect) {
251
+ function boundingRects(rect, dpr) {
240
252
  const bounds = getBounds(rect);
241
253
  const width = bounds.right - bounds.left;
242
254
  const height = bounds.bottom - bounds.top;
243
255
  const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
244
256
  const radius = parseBorderRadius(rect.options.borderRadius, width / 2, height / 2);
257
+ const outer = rasterizeRect({
258
+ x: bounds.left,
259
+ y: bounds.top,
260
+ w: width,
261
+ h: height,
262
+ active: rect.active,
263
+ radius
264
+ }, dpr);
245
265
 
246
266
  return {
247
- outer: {
248
- x: bounds.left,
249
- y: bounds.top,
250
- w: width,
251
- h: height,
252
- radius
253
- },
267
+ outer,
254
268
  inner: {
255
- x: bounds.left + border.l,
256
- y: bounds.top + border.t,
257
- w: width - border.l - border.r,
258
- h: height - border.t - border.b,
269
+ x: outer.x + border.l,
270
+ y: outer.y + border.t,
271
+ w: outer.w - border.l - border.r,
272
+ h: outer.h - border.t - border.b,
273
+ active: rect.active,
259
274
  radius: {
260
275
  topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
261
276
  topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
@@ -290,7 +305,7 @@ function addNormalRectPath(ctx, rect) {
290
305
  }
291
306
 
292
307
  function shouldDrawCaption(rect, options) {
293
- if (!options || !options.display) {
308
+ if (!options || options.display === false) {
294
309
  return false;
295
310
  }
296
311
  const {w, h} = rect;
@@ -460,12 +475,12 @@ class TreemapElement extends chart_js.Element {
460
475
  }
461
476
  }
462
477
 
463
- draw(ctx, data, levels = 0) {
478
+ draw(ctx, data, levels = 0, dpr) {
464
479
  if (!data) {
465
480
  return;
466
481
  }
467
482
  const options = this.options;
468
- const {inner, outer} = boundingRects(this);
483
+ const {inner, outer} = boundingRects(this, dpr);
469
484
 
470
485
  const addRectPath = hasRadius(outer.radius) ? helpers.addRoundedRectPath : addNormalRectPath;
471
486
 
@@ -514,6 +529,9 @@ class TreemapElement extends chart_js.Element {
514
529
  return this.getCenterPoint();
515
530
  }
516
531
 
532
+ /**
533
+ * @todo: remove this unused function in v3
534
+ */
517
535
  getRange(axis) {
518
536
  return axis === 'x' ? this.width / 2 : this.height / 2;
519
537
  }
@@ -576,35 +594,30 @@ TreemapElement.defaultRoutes = {
576
594
  borderColor: 'borderColor'
577
595
  };
578
596
 
579
- function round(v, n) {
580
- // @ts-ignore
581
- return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
582
- }
583
-
584
- function getDims(itm, w2, s2, key) {
597
+ function getDims(itm, w2, s2, key, dpr, maxd2) {
585
598
  const a = itm._normalized;
586
599
  const ar = w2 * a / s2;
587
- const d1 = Math.sqrt(a * ar);
588
- const d2 = a / d1;
600
+ const d1 = rasterize(Math.sqrt(a * ar), dpr);
601
+ const d2 = Math.min(rasterize(a / d1, dpr), maxd2);
589
602
  const w = key === '_ix' ? d1 : d2;
590
603
  const h = key === '_ix' ? d2 : d1;
591
604
 
592
605
  return {d1, d2, w, h};
593
606
  }
594
607
 
595
- const getX = (rect, w) => round(rect.rtl ? rect.x + rect.w - rect._ix - w : rect.x + rect._ix, 4);
608
+ const getX = (rect, w) => rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix;
596
609
 
597
- function buildRow(rect, itm, dims, sum) {
598
- const r = {
610
+ function buildRow(rect, itm, dims, sum, dpr) {
611
+ const r = rasterizeRect({
599
612
  x: getX(rect, dims.w),
600
- y: round(rect.y + rect._iy, 4),
601
- w: round(dims.w, 4),
602
- h: round(dims.h, 4),
603
- a: round(itm._normalized, 4),
613
+ y: rect.y + rect._iy,
614
+ w: dims.w,
615
+ h: dims.h,
616
+ a: itm._normalized,
604
617
  v: itm.value,
605
618
  s: sum,
606
619
  _data: itm._data
607
- };
620
+ }, dpr);
608
621
  if (itm.group) {
609
622
  r.g = itm.group;
610
623
  r.l = itm.level;
@@ -614,16 +627,16 @@ function buildRow(rect, itm, dims, sum) {
614
627
  }
615
628
 
616
629
  class Rect {
617
- constructor(r) {
618
- const me = this;
630
+ constructor(r, dpr) {
631
+ this.dpr = dpr;
619
632
  r = r || {w: 1, h: 1};
620
- me.rtl = !!r.rtl;
621
- me.x = r.x || r.left || 0;
622
- me.y = r.y || r.top || 0;
623
- me._ix = 0;
624
- me._iy = 0;
625
- me.w = r.w || r.width || (r.right - r.left);
626
- me.h = r.h || r.height || (r.bottom - r.top);
633
+ this.rtl = !!r.rtl;
634
+ this.x = r.x || r.left || 0;
635
+ this.y = r.y || r.top || 0;
636
+ this._ix = 0;
637
+ this._iy = 0;
638
+ this.w = r.w || r.width || (r.right - r.left);
639
+ this.h = r.h || r.height || (r.bottom - r.top);
627
640
  }
628
641
 
629
642
  get area() {
@@ -644,34 +657,61 @@ class Rect {
644
657
  }
645
658
 
646
659
  get side() {
647
- return this.dir === 'x' ? this.iw : this.ih;
660
+ return rasterize(this.dir === 'x' ? this.iw : this.ih, this.dpr);
648
661
  }
649
662
 
650
663
  map(arr) {
651
- const me = this;
652
- const ret = [];
664
+ const {dir, side, dpr} = this;
665
+ const {key, d2prop, id2prop, d2key} = getPropNames(dir);
653
666
  const sum = arr.nsum;
654
667
  const row = arr.get();
655
- const dir = me.dir;
656
- const side = me.side;
657
668
  const w2 = side * side;
658
- const key = dir === 'x' ? '_ix' : '_iy';
669
+ const availd2 = rasterize(this[id2prop], dpr);
659
670
  const s2 = sum * sum;
671
+ const ret = [];
660
672
  let maxd2 = 0;
661
673
  let totd1 = 0;
662
674
  for (const itm of row) {
663
- const dims = getDims(itm, w2, s2, key);
675
+ const dims = getDims(itm, w2, s2, key, dpr, availd2);
664
676
  totd1 += dims.d1;
665
- maxd2 = Math.max(maxd2, dims.d2);
666
- ret.push(buildRow(me, itm, dims, arr.sum));
667
- me[key] += dims.d1;
677
+ maxd2 = Math.min(Math.max(maxd2, dims.d2), availd2);
678
+ ret.push(buildRow(this, itm, dims, arr.sum, dpr));
679
+ this[key] += dims.d1;
668
680
  }
669
- me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
670
- me[key] -= totd1;
681
+ // make sure all rects are same size in d2 direction
682
+ for (const r of ret) {
683
+ const d2 = r[d2prop];
684
+ if (d2 !== maxd2) {
685
+ if (this.rtl && dir === 'y') {
686
+ // for RTL, x-coordinate needs to be adjusted too
687
+ r.x -= maxd2 - d2;
688
+ }
689
+ r[d2prop] = maxd2;
690
+ }
691
+ }
692
+ this[d2key] += maxd2;
693
+ this[key] -= totd1;
671
694
  return ret;
672
695
  }
673
696
  }
674
697
 
698
+ function getPropNames(dir) {
699
+ if (dir === 'x') {
700
+ return {
701
+ key: '_ix',
702
+ d2prop: 'h',
703
+ id2prop: 'ih',
704
+ d2key: '_iy'
705
+ };
706
+ }
707
+ return {
708
+ key: '_iy',
709
+ d2prop: 'w',
710
+ id2prop: 'iw',
711
+ d2key: '_ix'
712
+ };
713
+ }
714
+
675
715
  const min = Math.min;
676
716
  const max = Math.max;
677
717
 
@@ -769,15 +809,16 @@ function compareAspectRatio(oldStat, newStat, args) {
769
809
  *
770
810
  * @param {number[]|object[]} values
771
811
  * @param {object} rectangle
772
- * @param {string} key
773
- * @param {*} grp
774
- * @param {*} lvl
775
- * @param {*} gsum
812
+ * @param {string} [key]
813
+ * @param {number} [dpr=1]
814
+ * @param {*} [grp]
815
+ * @param {*} [lvl]
816
+ * @param {*} [gsum]
776
817
  */
777
- function squarify(values, rectangle, key, grp, lvl, gsum) {
818
+ function squarify(values, rectangle, key, dpr = 1, grp, lvl, gsum) {
778
819
  values = values || [];
779
820
  const rows = [];
780
- const rect = new Rect(rectangle);
821
+ const rect = new Rect(rectangle, dpr);
781
822
  const row = new StatArray('value', rect.area / sum(values, key));
782
823
  let length = rect.side;
783
824
  const n = values.length;
@@ -814,7 +855,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
814
855
  return flatten(rows);
815
856
  }
816
857
 
817
- var version = "2.1.0";
858
+ var version = "2.1.2";
818
859
 
819
860
  function rectNotEqual(r1, r2) {
820
861
  return !r1 || !r2
@@ -839,7 +880,7 @@ function arrayNotEqual(a1, a2) {
839
880
  return false;
840
881
  }
841
882
 
842
- function buildData(dataset, mainRect) {
883
+ function buildData(dataset, mainRect, dpr) {
843
884
  const key = dataset.key || '';
844
885
  const treeLeafKey = dataset.treeLeafKey || '_leaf';
845
886
  let tree = dataset.tree || [];
@@ -849,7 +890,7 @@ function buildData(dataset, mainRect) {
849
890
  const groups = dataset.groups || [];
850
891
  const glen = groups.length;
851
892
  const sp = helpers.valueOrDefault(dataset.spacing, 0);
852
- const captions = dataset.captions || {display: true};
893
+ const captions = dataset.captions || {};
853
894
  const font = helpers.toFont(captions.font);
854
895
  const padding = helpers.valueOrDefault(captions.padding, 3);
855
896
 
@@ -857,24 +898,23 @@ function buildData(dataset, mainRect) {
857
898
  const g = getGroupKey(groups[gidx]);
858
899
  const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]);
859
900
  const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx));
860
- const gsq = squarify(gdata, rect, key, g, gidx, gs);
901
+ const gsq = squarify(gdata, rect, key, dpr, g, gidx, gs);
861
902
  const ret = gsq.slice();
862
- let subRect;
863
903
  if (gidx < glen - 1) {
864
904
  gsq.forEach((sq) => {
865
905
  const bw = parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2);
866
- subRect = {
906
+ const subRect = {
907
+ ...rect,
867
908
  x: sq.x + sp + bw.l,
868
909
  y: sq.y + sp + bw.t,
869
910
  w: sq.w - 2 * sp - bw.l - bw.r,
870
911
  h: sq.h - 2 * sp - bw.t - bw.b,
871
- rtl: rect.rtl
872
912
  };
873
913
  if (shouldDrawCaption(subRect, captions)) {
874
914
  subRect.y += font.lineHeight + padding * 2;
875
915
  subRect.h -= font.lineHeight + padding * 2;
876
916
  }
877
- ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
917
+ ret.push(...recur(gidx + 1, rasterizeRect(subRect, dpr), sq.g, sq.s));
878
918
  });
879
919
  }
880
920
  return ret;
@@ -886,7 +926,7 @@ function buildData(dataset, mainRect) {
886
926
 
887
927
  return glen
888
928
  ? recur(0, mainRect)
889
- : squarify(tree, mainRect, key);
929
+ : squarify(tree, mainRect, key, dpr);
890
930
  }
891
931
 
892
932
  function getMinMax(data, useTree) {
@@ -920,8 +960,7 @@ class TreemapController extends chart_js.DatasetController {
920
960
  }
921
961
 
922
962
  /**
923
- * TODO: to be removed when https://github.com/kurkle/chartjs-chart-treemap/issues/137
924
- * will be implemented
963
+ * @todo: Remove with https://github.com/kurkle/chartjs-chart-treemap/issues/137
925
964
  */
926
965
  updateRangeFromParsed(range, scale) {
927
966
  if (range.updated) {
@@ -933,39 +972,39 @@ class TreemapController extends chart_js.DatasetController {
933
972
  range.max = 1;
934
973
  return;
935
974
  }
936
- const me = this;
937
- const dataset = me.getDataset();
938
- const {vMin, vMax} = getMinMax(dataset.data, me._useTree);
975
+ const dataset = this.getDataset();
976
+ const {vMin, vMax} = getMinMax(dataset.data, this._useTree);
939
977
  range.min = vMin;
940
978
  range.max = vMax;
941
979
  }
942
980
 
943
981
  update(mode) {
944
- const me = this;
945
- const meta = me.getMeta();
946
- const dataset = me.getDataset();
947
- if (!helpers.defined(me._useTree)) {
948
- me._useTree = !!dataset.tree;
982
+ const meta = this.getMeta();
983
+ const dataset = this.getDataset();
984
+ const dpr = this.chart.currentDevicePixelRatio;
985
+
986
+ if (!helpers.defined(this._useTree)) {
987
+ this._useTree = !!dataset.tree;
949
988
  }
950
989
  const groups = dataset.groups || (dataset.groups = []);
951
990
  const key = dataset.key || '';
952
991
  const rtl = !!dataset.rtl;
953
992
 
954
- const mainRect = getArea(meta, dataset.data, rtl, me._useTree);
993
+ const mainRect = rasterizeRect(getArea(meta, dataset.data, rtl, this._useTree), dpr);
955
994
 
956
- if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
957
- me._rect = mainRect;
958
- me._groups = groups.slice();
959
- me._key = key;
995
+ if (mode === 'reset' || rectNotEqual(this._rect, mainRect) || this._key !== key || arrayNotEqual(this._groups, groups)) {
996
+ this._rect = mainRect;
997
+ this._groups = groups.slice();
998
+ this._key = key;
960
999
 
961
- dataset.data = buildData(dataset, mainRect);
1000
+ dataset.data = buildData(dataset, mainRect, dpr);
962
1001
  // @ts-ignore using private stuff
963
- me._dataCheck();
1002
+ this._dataCheck();
964
1003
  // @ts-ignore using private stuff
965
- me._resyncElements();
1004
+ this._resyncElements();
966
1005
  }
967
1006
 
968
- me.updateElements(meta.data, 0, meta.data.length, mode);
1007
+ this.updateElements(meta.data, 0, meta.data.length, mode);
969
1008
  }
970
1009
 
971
1010
  updateElements(rects, start, count, mode) {
@@ -999,19 +1038,17 @@ class TreemapController extends chart_js.DatasetController {
999
1038
  }
1000
1039
 
1001
1040
  draw() {
1002
- const me = this;
1003
- const ctx = me.chart.ctx;
1004
- const area = me.chart.chartArea;
1005
- const metadata = me.getMeta().data || [];
1006
- const dataset = me.getDataset();
1041
+ const {ctx, chartArea, currentDevicePixelRatio: dpr} = this.chart;
1042
+ const metadata = this.getMeta().data || [];
1043
+ const dataset = this.getDataset();
1007
1044
  const levels = (dataset.groups || []).length - 1;
1008
1045
  const data = dataset.data;
1009
1046
 
1010
- helpers.clipArea(ctx, area);
1047
+ helpers.clipArea(ctx, chartArea);
1011
1048
  for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
1012
1049
  const rect = metadata[i];
1013
1050
  if (!rect.hidden) {
1014
- rect.draw(ctx, data[i], levels);
1051
+ rect.draw(ctx, data[i], levels, dpr);
1015
1052
  }
1016
1053
  }
1017
1054
  helpers.unclipArea(ctx);
@@ -1042,6 +1079,7 @@ TreemapController.descriptors = {
1042
1079
  TreemapController.overrides = {
1043
1080
  interaction: {
1044
1081
  mode: 'point',
1082
+ includeInvisible: true,
1045
1083
  intersect: true
1046
1084
  },
1047
1085
 
@@ -1081,7 +1119,7 @@ TreemapController.overrides = {
1081
1119
  };
1082
1120
 
1083
1121
  TreemapController.beforeRegister = function() {
1084
- requireVersion('3.6', chart_js.Chart.version);
1122
+ requireVersion('3.8', chart_js.Chart.version);
1085
1123
  };
1086
1124
 
1087
1125
  TreemapController.afterRegister = function() {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * chartjs-chart-treemap v2.1.0
2
+ * chartjs-chart-treemap v2.1.2
3
3
  * https://chartjs-chart-treemap.pages.dev/
4
4
  * (c) 2022 Jukka Kurkela
5
5
  * Released under the MIT license
6
6
  */
7
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["exports","chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-chart-treemap"]={},t.Chart,t.Chart.helpers)}(this,(function(t,e,n){"use strict";const i=t=>n.isObject(t)?t.v:t,r=t=>t.reduce((function(t,e){return t>i(e)?t:i(e)}),0),o=(t,e)=>t.reduce((function(t,e){return t<i(e)?t:i(e)}),e),s=t=>""+t;function a(t,e,i,r=[],o=0,l=[]){const h=o-1;if(t in i&&o>0){const n=r.reduce((function(t,e,n){return n!==h&&(t[s(n)]=e),t}),{});n[e]=r[h],n[t]=i[t],l.push(n)}else for(const s of Object.keys(i)){const h=i[s];n.isObject(h)&&(r.push(s),a(t,e,h,r,o+1,l))}return r.splice(h,1),l}function l(t,e,n){const i=a(t,e,n);if(!i.length)return i;const r=i.reduce((function(t,e){const n=Object.keys(e).length-2;return t>n?t:n}));return i.forEach((function(t){for(let e=0;e<r;e++){const n=s(e);t[n]||(t[n]="")}})),i}function h(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function u(t,e,n){if(!t.length)return;const i=[];for(const r of t){const t=e[r];if(""===t){i.push(n);break}i.push(t)}return i.length?i.join("."):n}function c(t,e,n,i,r,o,s=[]){const a=Object.create(null),l=Object.create(null),h=[];let c,d,f;for(d=0,f=t.length;d<f;++d){const h=t[d];r&&h[r]!==o||(c=h[e]||h[i]||"",c in a||(a[c]={value:0},l[c]=[]),a[c].value+=+h[n],a[c].label=h[e]||"",a[c].path=u(s,h,c),l[c].push(h))}return Object.keys(a).forEach((t=>{const i={children:l[t]};i[n]=+a[t].value,i[e]=a[t].label,i.label=t,i.path=a[t].path,r&&(i[r]=o),h.push(i)})),h}function d(t,e){let i,r=t.length;if(!r)return e;const o=n.isObject(t[0]);for(e=o?e:"v",i=0,r=t.length;i<r;++i)o?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}function f(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function p(t,e){let n,i,r;for(n=0,i=0,r=t.length;i<r;++i)n+=e?+t[i][e]:+t[i];return n}function g(t,e){const n=e.split(".");if(!t.split(".").reduce(((t,e,i)=>t&&e<=n[i]),!0))throw new Error(`Chart.js v${e} is not supported. v${t} or newer is required.`)}const m=new Map;function x(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 y(t,e,n){return Math.max(Math.min(t,n),e)}function b(t,e,i){const r=n.toTRBL(t);return{t:y(r.top,0,i),r:y(r.right,0,e),b:y(r.bottom,0,i),l:y(r.left,0,e)}}function v(t){const e=x(t),i=e.right-e.left,r=e.bottom-e.top,o=b(t.options.borderWidth,i/2,r/2),s=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:y(r.topLeft,0,o),topRight:y(r.topRight,0,o),bottomLeft:y(r.bottomLeft,0,o),bottomRight:y(r.bottomRight,0,o)}}(t.options.borderRadius,i/2,r/2);return{outer:{x:e.left,y:e.top,w:i,h:r,radius:s},inner:{x:e.left+o.l,y:e.top+o.t,w:i-o.l-o.r,h:r-o.t-o.b,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 w(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&x(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function _(t,e){t.rect(e.x,e.y,e.w,e.h)}function M(t,e){if(!e||!e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=y(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function k(t,e,i,r,o){const{captions:s,labels:a}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const l=!("l"in r)||r.l===o;l&&a.display?function(t,e,i){const r=i.labels,o=r.formatter;if(!o)return;const s=n.isArray(o)?o:[o],{font:a,hoverFont:l}=r,h=(e.active?l:a)||a,u=n.isArray(h)?h.map((t=>n.toFont(t))):[n.toFont(h)],c=function(t,e,n){const i=n.reduce((function(t,e){return t+=e.string}),""),r=e.join()+i+(t._measureText?"-spriting":"");if(!m.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(),m.set(r,{width:o,height:s})}return m.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,g=(e.active?f:d)||d,x=n.isArray(g)?g:[g],y=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=O(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 b=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,y.x,y.y+o/2+b),b+=o}))}(t,e,i):!l&&M(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:l,hoverColor:h,font:u,hoverFont:c,padding:d,align:f,formatter:p}=o,g=(e.active?h:l)||l,m=f||(a?"right":"left"),x=(e.active?c:u)||u,y=n.toFont(x),b=y.lineHeight/2,v=O(e,m,d);t.fillStyle=g,t.font=y.string,t.textAlign=m,t.textBaseline="middle",t.fillText(p||r.g,v,e.y+d+s+b)}(t,e,i,r),t.restore()}function O(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class R 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}=v(this),a=(l=s.radius).topLeft||l.topRight||l.bottomLeft||l.bottomRight?n.addRoundedRectPath:_;var l;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:l}=e,{lineColor:h,lineCapStyle:u,lineDash:c,lineDashOffset:d,lineWidth:f}=r;if(t.save(),t.strokeStyle=h,t.lineCap=u,t.setLineDash(c),t.lineDashOffset=d,t.lineWidth=f,t.beginPath(),a>l){const e=a/2;t.moveTo(o+e,s),t.lineTo(o+e,s+l)}else{const e=l/2;t.moveTo(o,s+e),t.lineTo(o+a,s+e)}t.stroke(),t.restore()}(t,o,r,e),k(t,o,r,e,i),t.restore()}inRange(t,e,n){return w(this,t,e,n)}inXRange(t,e){return w(this,t,null,e)}inYRange(t,e){return w(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){return+(Math.round(t+"e+"+e)+"e-"+e)||0}function j(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}}R.id="treemap",R.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},R.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},R.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const T=(t,e)=>C(t.rtl?t.x+t.w-t._ix-e:t.x+t._ix,4);function P(t,e,n,i){const r={x:T(t,n.w),y:C(t.y+t._iy,4),w:C(n.w,4),h:C(n.h,4),a:C(e._normalized,4),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 D{constructor(t){const e=this;t=t||{w:1,h:1},e.rtl=!!t.rtl,e.x=t.x||t.left||0,e.y=t.y||t.top||0,e._ix=0,e._iy=0,e.w=t.w||t.width||t.right-t.left,e.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 e=this,n=[],i=t.nsum,r=t.get(),o=e.dir,s=e.side,a=s*s,l="x"===o?"_ix":"_iy",h=i*i;let u=0,c=0;for(const i of r){const r=j(i,a,h,l);c+=r.d1,u=Math.max(u,r.d2),n.push(P(e,i,r,t.sum)),e[l]+=r.d1}return e["y"===o?"_ix":"_iy"]+=u,e[l]-=c,n}}const L=Math.min,S=Math.max;function E(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:L(t.min,n),max:S(t.max,n),sum:t.sum+n,nmin:L(t.nmin,i),nmax:S(t.nmax,i),nsum:t.nsum+i}}function F(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class A{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){F(this,t,E(this,t))}pushIf(t,e,...n){const i=E(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;F(this,t,i)}get(){return this._arr}}function V(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 z(t,e,n,i,r,o){t=t||[];const s=[],a=new D(e),l=new A("value",a.area/p(t,n));let u=a.side;const c=t.length;let g,m;if(!c)return s;const x=t.slice();n=d(x,n),f(x,n);const y=t=>i&&x[t][i];for(g=0;g<c;++g)m={value:(b=g,n?+x[b][n]:+x[b]),groupSum:o,_data:t[x[g]._idx],level:void 0,group:void 0},i&&(m.level=r,m.group=y(g)),m=l.pushIf(m,V,u),m&&(s.push(a.map(l)),u=a.side,l.reset(),l.push(m));var b;return l.length&&s.push(a.map(l)),h(s)}function H(t,e){const n=e?1:r(t);return{vMin:e?0:o(t,n),vMax:n}}class W extends e.DatasetController{constructor(t,e){super(t,e),this._rect=void 0,this._key=void 0,this._groups=void 0,this._useTree=void 0}initialize(){this.enableOptionSharing=!0,super.initialize()}updateRangeFromParsed(t,e){if(t.updated)return;if(t.updated=!0,"x"===e.axis)return t.min=0,void(t.max=1);const n=this.getDataset(),{vMin:i,vMax:r}=H(n.data,this._useTree);t.min=i,t.max=r}update(t){const e=this,i=e.getMeta(),r=e.getDataset();n.defined(e._useTree)||(e._useTree=!!r.tree);const o=r.groups||(r.groups=[]),a=r.key||"",h=!!r.rtl,u=function({xScale:t,yScale:e},n,i,r){const{vMin:o,vMax:s}=H(n,r),a=t.getPixelForValue(0),l=t.getPixelForValue(1),h=e.getPixelForValue(o),u=e.getPixelForValue(s);return{x:a,y:u,w:l-a,h:h-u,rtl:i}}(i,r.data,h,e._useTree);var d,f;"reset"!==t&&(d=e._rect,f=u,d&&f&&d.x===f.x&&d.y===f.y&&d.w===f.w&&d.h===f.h)&&e._key===a&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(e._groups,o)||(e._rect=u,e._groups=o.slice(),e._key=a,r.data=function(t,e){const i=t.key||"",r=t.treeLeafKey||"_leaf";let o=t.tree||[];n.isObject(o)&&(o=l(i,r,o));const a=t.groups||[],h=a.length,u=n.valueOrDefault(t.spacing,0),d=t.captions||{display:!0},f=n.toFont(d.font),p=n.valueOrDefault(d.padding,3);return!o.length&&t.data.length&&(o=t.tree=t.data),h?function e(n,l,g,m){const x=s(a[n]),y=n>0&&s(a[n-1]),v=c(o,x,i,r,y,g,a.filter(((t,e)=>e<=n))),w=z(v,l,i,x,n,m),_=w.slice();let k;return n<h-1&&w.forEach((i=>{const r=b(t.borderWidth,i.w/2,i.h/2);k={x:i.x+u+r.l,y:i.y+u+r.t,w:i.w-2*u-r.l-r.r,h:i.h-2*u-r.t-r.b,rtl:l.rtl},M(k,d)&&(k.y+=f.lineHeight+2*p,k.h-=f.lineHeight+2*p),_.push(...e(n+1,k,i.g,i.s))})),_}(0,e):z(o,e,i)}(r,u),e._dataCheck(),e._resyncElements()),e.updateElements(i.data,0,i.data.length,t)}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),l=r.getSharedOptions(a),h=r.includeOptions(i,l);for(let a=e;a<e+n;a++){const e=s.data[a],n=l||r.resolveDataElementOptions(a,i),u=n.spacing,c=2*u,d={x:e.x+u,y:e.y+u,width:o?0:e.w-c,height:o?0:e.h-c,hidden:c>e.w||c>e.h};h&&(d.options=n),r.updateElement(t[a],a,d,i)}r.updateSharedOptions(l,i,a)}draw(){const t=this,e=t.chart.ctx,i=t.chart.chartArea,r=t.getMeta().data||[],o=t.getDataset(),s=(o.groups||[]).length-1,a=o.data;n.clipArea(e,i);for(let t=0,n=r.length;t<n;++t){const n=r[t];n.hidden||n.draw(e,a[t],s)}n.unclipArea(e)}}W.id="treemap",W.version="2.1.0",W.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},W.descriptors={_scriptable:!0,_indexable:!1},W.overrides={interaction:{mode:"point",intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}},W.beforeRegister=function(){g("3.6",e.Chart.version)},W.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")},W.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(W,R),t.flatten=h,t.getGroupKey=s,t.group=c,t.index=d,t.maxValue=r,t.minValue=o,t.normalizeTreeToArray=l,t.requireVersion=g,t.sort=f,t.sum=p,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=>n.isObject(t)?t.v:t,r=t=>t.reduce((function(t,e){return t>i(e)?t:i(e)}),0),o=(t,e)=>t.reduce((function(t,e){return t<i(e)?t:i(e)}),e),s=t=>""+t;function a(t,e,i,r=[],o=0,l=[]){const h=o-1;if(t in i&&o>0){const n=r.reduce((function(t,e,n){return n!==h&&(t[s(n)]=e),t}),{});n[e]=r[h],n[t]=i[t],l.push(n)}else for(const s of Object.keys(i)){const h=i[s];n.isObject(h)&&(r.push(s),a(t,e,h,r,o+1,l))}return r.splice(h,1),l}function l(t,e,n){const i=a(t,e,n);if(!i.length)return i;const r=i.reduce((function(t,e){const n=Object.keys(e).length-2;return t>n?t:n}));return i.forEach((function(t){for(let e=0;e<r;e++){const n=s(e);t[n]||(t[n]="")}})),i}function h(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function u(t,e,n){if(!t.length)return;const i=[];for(const r of t){const t=e[r];if(""===t){i.push(n);break}i.push(t)}return i.length?i.join("."):n}function c(t,e,n,i,r,o,s=[]){const a=Object.create(null),l=Object.create(null),h=[];let c,d,p;for(d=0,p=t.length;d<p;++d){const h=t[d];r&&h[r]!==o||(c=h[e]||h[i]||"",c in a||(a[c]={value:0},l[c]=[]),a[c].value+=+h[n],a[c].label=h[e]||"",a[c].path=u(s,h,c),l[c].push(h))}return Object.keys(a).forEach((t=>{const i={children:l[t]};i[n]=+a[t].value,i[e]=a[t].label,i.label=t,i.path=a[t].path,r&&(i[r]=o),h.push(i)})),h}function d(t,e){let i,r=t.length;if(!r)return e;const o=n.isObject(t[0]);for(e=o?e:"v",i=0,r=t.length;i<r;++i)o?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}function p(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function f(t,e){let n,i,r;for(n=0,i=0,r=t.length;i<r;++i)n+=e?+t[i][e]:+t[i];return n}function g(t,e){const n=e.split(".");if(!t.split(".").reduce(((t,e,i)=>t&&e<=n[i]),!0))throw new Error(`Chart.js v${e} is not supported. v${t} or newer is required.`)}const m=(t,e)=>Math.round(t*e)/e;function x(t,e){return{...t,x:m(t.x,e),y:m(t.y,e),w:m(t.w,e),h:m(t.h,e)}}const y=new Map;function b(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function v(t,e,n){return Math.max(Math.min(t,n),e)}function w(t,e,i){const r=n.toTRBL(t);return{t:v(r.top,0,i),r:v(r.right,0,e),b:v(r.bottom,0,i),l:v(r.left,0,e)}}function _(t,e){const i=b(t),r=i.right-i.left,o=i.bottom-i.top,s=w(t.options.borderWidth,r/2,o/2),a=function(t,e,i){const r=n.toTRBLCorners(t),o=Math.min(e,i);return{topLeft:v(r.topLeft,0,o),topRight:v(r.topRight,0,o),bottomLeft:v(r.bottomLeft,0,o),bottomRight:v(r.bottomRight,0,o)}}(t.options.borderRadius,r/2,o/2),l=x({x:i.left,y:i.top,w:r,h:o,active:t.active,radius:a},e);return{outer:l,inner:{x:l.x+s.l,y:l.y+s.t,w:l.w-s.l-s.r,h:l.h-s.t-s.b,active:t.active,radius:{topLeft:Math.max(0,a.topLeft-Math.max(s.t,s.l)),topRight:Math.max(0,a.topRight-Math.max(s.t,s.r)),bottomLeft:Math.max(0,a.bottomLeft-Math.max(s.b,s.l)),bottomRight:Math.max(0,a.bottomRight-Math.max(s.b,s.r))}}}}function M(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&b(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function k(t,e){t.rect(e.x,e.y,e.w,e.h)}function R(t,e){if(!e||!1===e.display)return!1;const{w:i,h:r}=t,o=n.toFont(e.font).lineHeight,s=v(2*n.valueOrDefault(e.padding,3),0,Math.min(i,r));return i-s>o&&r-s>o}function O(t,e,i,r,o){const{captions:s,labels:a}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const l=!("l"in r)||r.l===o;l&&a.display?function(t,e,i){const r=i.labels,o=r.formatter;if(!o)return;const s=n.isArray(o)?o:[o],{font:a,hoverFont:l}=r,h=(e.active?l:a)||a,u=n.isArray(h)?h.map((t=>n.toFont(t))):[n.toFont(h)],c=function(t,e,n){const i=n.reduce((function(t,e){return t+=e.string}),""),r=e.join()+i+(t._measureText?"-spriting":"");if(!y.has(r)){t.save();const i=e.length;let o=0,s=0;for(let r=0;r<i;r++){const i=n[Math.min(r,n.length-1)];t.font=i.string;const a=e[r];o=Math.max(o,t.measureText(a).width),s+=i.lineHeight}t.restore(),y.set(r,{width:o,height:s})}return y.get(r)}(t,s,u);if(!function(t,e,n,i){const{overflow:r,padding:o}=n,{width:s,height:a}=i;if("hidden"===r)return!(s+2*o>e.w||a+2*o>e.h);return!0}(0,e,r,c))return;const{color:d,hoverColor:p,align:f}=r,g=(e.active?p:d)||d,m=n.isArray(g)?g:[g],x=function(t,e,n){const{align:i,position:r,padding:o}=e;let s,a;s=C(t,i,o),a="top"===r?t.y+o:"bottom"===r?t.y+t.h-o-n.height:t.y+(t.h-n.height)/2+o;return{x:s,y:a}}(e,r,c);t.textAlign=f,t.textBaseline="middle";let b=0;s.forEach((function(e,n){const i=m[Math.min(n,m.length-1)],r=u[Math.min(n,u.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,x.x,x.y+o/2+b),b+=o}))}(t,e,i):!l&&R(e,s)&&function(t,e,i,r){const{captions:o,spacing:s,rtl:a}=i,{color:l,hoverColor:h,font:u,hoverFont:c,padding:d,align:p,formatter:f}=o,g=(e.active?h:l)||l,m=p||(a?"right":"left"),x=(e.active?c:u)||u,y=n.toFont(x),b=y.lineHeight/2,v=C(e,m,d);t.fillStyle=g,t.font=y.string,t.textAlign=m,t.textBaseline="middle",t.fillText(f||r.g,v,e.y+d+s+b)}(t,e,i,r),t.restore()}function C(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}class j extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t,e,i=0,r){if(!e)return;const o=this.options,{inner:s,outer:a}=_(this,r),l=(h=a.radius).topLeft||h.topRight||h.bottomLeft||h.bottomRight?n.addRoundedRectPath:k;var h;t.save(),a.w===s.w&&a.h===s.h||(t.beginPath(),l(t,a),t.clip(),l(t,s),t.fillStyle=o.borderColor,t.fill("evenodd")),t.beginPath(),l(t,s),t.fillStyle=o.backgroundColor,t.fill(),function(t,e,n,i){const r=n.dividers;if(!r.display||!i._data.children.length)return;const{x:o,y:s,w:a,h:l}=e,{lineColor:h,lineCapStyle:u,lineDash:c,lineDashOffset:d,lineWidth:p}=r;if(t.save(),t.strokeStyle=h,t.lineCap=u,t.setLineDash(c),t.lineDashOffset=d,t.lineWidth=p,t.beginPath(),a>l){const e=a/2;t.moveTo(o+e,s),t.lineTo(o+e,s+l)}else{const e=l/2;t.moveTo(o,s+e),t.lineTo(o+a,s+e)}t.stroke(),t.restore()}(t,s,o,e),O(t,s,o,e,i),t.restore()}inRange(t,e,n){return M(this,t,e,n)}inXRange(t,e){return M(this,t,null,e)}inYRange(t,e){return M(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}function T(t,e,n,i,r,o){const s=t._normalized,a=e*s/n,l=m(Math.sqrt(s*a),r),h=Math.min(m(s/l,r),o);return{d1:l,d2:h,w:"_ix"===i?l:h,h:"_ix"===i?h:l}}j.id="treemap",j.defaults={label:void 0,borderRadius:0,borderWidth:0,captions:{align:void 0,color:"black",display:!0,font:{},formatter:t=>t.raw.g||t.raw._data.label||"",padding:3},dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:[],lineDashOffset:0,lineWidth:1},labels:{align:"center",color:"black",display:!1,font:{},formatter:t=>t.raw.g?[t.raw.g,t.raw.v+""]:t.raw._data.label?[t.raw._data.label,t.raw.v+""]:t.raw.v+"",overflow:"cut",position:"middle",padding:3},rtl:!1,spacing:.5},j.descriptors={labels:{_fallback:!0},captions:{_fallback:!0},_scriptable:!0,_indexable:!1},j.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};const P=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function D(t,e,n,i,r){const o=x({x:P(t,n.w),y:t.y+t._iy,w:n.w,h:n.h,a:e._normalized,v:e.value,s:i,_data:e._data},r);return e.group&&(o.g=e.group,o.l=e.level,o.gs=e.groupSum),o}class L{constructor(t,e){this.dpr=e,t=t||{w:1,h:1},this.rtl=!!t.rtl,this.x=t.x||t.left||0,this.y=t.y||t.top||0,this._ix=0,this._iy=0,this.w=t.w||t.width||t.right-t.left,this.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return m("x"===this.dir?this.iw:this.ih,this.dpr)}map(t){const{dir:e,side:n,dpr:i}=this,{key:r,d2prop:o,id2prop:s,d2key:a}=function(t){if("x"===t)return{key:"_ix",d2prop:"h",id2prop:"ih",d2key:"_iy"};return{key:"_iy",d2prop:"w",id2prop:"iw",d2key:"_ix"}}(e),l=t.nsum,h=t.get(),u=n*n,c=m(this[s],i),d=l*l,p=[];let f=0,g=0;for(const e of h){const n=T(e,u,d,r,i,c);g+=n.d1,f=Math.min(Math.max(f,n.d2),c),p.push(D(this,e,n,t.sum,i)),this[r]+=n.d1}for(const t of p){const n=t[o];n!==f&&(this.rtl&&"y"===e&&(t.x-=f-n),t[o]=f)}return this[a]+=f,this[r]-=g,p}}const S=Math.min,E=Math.max;function F(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:S(t.min,n),max:E(t.max,n),sum:t.sum+n,nmin:S(t.nmin,i),nmax:E(t.nmax,i),nsum:t.nsum+i}}function A(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class V{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){A(this,t,F(this,t))}pushIf(t,e,...n){const i=F(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;A(this,t,i)}get(){return this._arr}}function z(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function H(t,e,n,i=1,r,o,s){t=t||[];const a=[],l=new L(e,i),u=new V("value",l.area/f(t,n));let c=l.side;const g=t.length;let m,x;if(!g)return a;const y=t.slice();n=d(y,n),p(y,n);const b=t=>r&&y[t][r];for(m=0;m<g;++m)x={value:(v=m,n?+y[v][n]:+y[v]),groupSum:s,_data:t[y[m]._idx],level:void 0,group:void 0},r&&(x.level=o,x.group=b(m)),x=u.pushIf(x,z,c),x&&(a.push(l.map(u)),c=l.side,u.reset(),u.push(x));var v;return u.length&&a.push(l.map(u)),h(a)}function W(t,e){const n=e?1:r(t);return{vMin:e?0:o(t,n),vMax:n}}class q extends e.DatasetController{constructor(t,e){super(t,e),this._rect=void 0,this._key=void 0,this._groups=void 0,this._useTree=void 0}initialize(){this.enableOptionSharing=!0,super.initialize()}updateRangeFromParsed(t,e){if(t.updated)return;if(t.updated=!0,"x"===e.axis)return t.min=0,void(t.max=1);const n=this.getDataset(),{vMin:i,vMax:r}=W(n.data,this._useTree);t.min=i,t.max=r}update(t){const e=this.getMeta(),i=this.getDataset(),r=this.chart.currentDevicePixelRatio;n.defined(this._useTree)||(this._useTree=!!i.tree);const o=i.groups||(i.groups=[]),a=i.key||"",h=!!i.rtl,u=x(function({xScale:t,yScale:e},n,i,r){const{vMin:o,vMax:s}=W(n,r),a=t.getPixelForValue(0),l=t.getPixelForValue(1),h=e.getPixelForValue(o),u=e.getPixelForValue(s);return{x:a,y:u,w:l-a,h:h-u,rtl:i}}(e,i.data,h,this._useTree),r);var d,p;"reset"!==t&&(d=this._rect,p=u,d&&p&&d.x===p.x&&d.y===p.y&&d.w===p.w&&d.h===p.h)&&this._key===a&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(this._groups,o)||(this._rect=u,this._groups=o.slice(),this._key=a,i.data=function(t,e,i){const r=t.key||"",o=t.treeLeafKey||"_leaf";let a=t.tree||[];n.isObject(a)&&(a=l(r,o,a));const h=t.groups||[],u=h.length,d=n.valueOrDefault(t.spacing,0),p=t.captions||{},f=n.toFont(p.font),g=n.valueOrDefault(p.padding,3);return!a.length&&t.data.length&&(a=t.tree=t.data),u?function e(n,l,m,y){const b=s(h[n]),v=n>0&&s(h[n-1]),_=c(a,b,r,o,v,m,h.filter(((t,e)=>e<=n))),M=H(_,l,r,i,b,n,y),k=M.slice();return n<u-1&&M.forEach((r=>{const o=w(t.borderWidth,r.w/2,r.h/2),s={...l,x:r.x+d+o.l,y:r.y+d+o.t,w:r.w-2*d-o.l-o.r,h:r.h-2*d-o.t-o.b};R(s,p)&&(s.y+=f.lineHeight+2*g,s.h-=f.lineHeight+2*g),k.push(...e(n+1,x(s,i),r.g,r.s))})),k}(0,e):H(a,e,r,i)}(i,u,r),this._dataCheck(),this._resyncElements()),this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),l=r.getSharedOptions(a),h=r.includeOptions(i,l);for(let a=e;a<e+n;a++){const e=s.data[a],n=l||r.resolveDataElementOptions(a,i),u=n.spacing,c=2*u,d={x:e.x+u,y:e.y+u,width:o?0:e.w-c,height:o?0:e.h-c,hidden:c>e.w||c>e.h};h&&(d.options=n),r.updateElement(t[a],a,d,i)}r.updateSharedOptions(l,i,a)}draw(){const{ctx:t,chartArea:e,currentDevicePixelRatio:i}=this.chart,r=this.getMeta().data||[],o=this.getDataset(),s=(o.groups||[]).length-1,a=o.data;n.clipArea(t,e);for(let e=0,n=r.length;e<n;++e){const n=r[e];n.hidden||n.draw(t,a[e],s,i)}n.unclipArea(t)}}q.id="treemap",q.version="2.1.2",q.defaults={dataElementType:"treemap",animations:{numbers:{type:"number",properties:["x","y","width","height"]}}},q.descriptors={_scriptable:!0,_indexable:!1},q.overrides={interaction:{mode:"point",includeInvisible:!0,intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}},q.beforeRegister=function(){g("3.8",e.Chart.version)},q.afterRegister=function(){const t=e.registry.plugins.get("tooltip");t?t.positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()}:console.warn("Unable to register the treemap positioner because tooltip plugin is not registered")},q.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap},e.Chart.register(q,j),t.flatten=h,t.getGroupKey=s,t.group=c,t.index=d,t.maxValue=r,t.minValue=o,t.normalizeTreeToArray=l,t.requireVersion=g,t.sort=p,t.sum=f,Object.defineProperty(t,"__esModule",{value:!0})}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "chartjs-chart-treemap",
3
3
  "homepage": "https://chartjs-chart-treemap.pages.dev/",
4
- "version": "2.1.0",
4
+ "version": "2.1.2",
5
5
  "description": "Chart.js module for creating treemap charts",
6
6
  "main": "dist/chartjs-chart-treemap.js",
7
7
  "module": "dist/chartjs-chart-treemap.esm.js",
@@ -12,7 +12,7 @@
12
12
  "dev": "karma start --no-signle-run --auto-watch --browsers chrome",
13
13
  "dev:ff": "karma start --no-signle-run --auto-watch --browsers firefox",
14
14
  "docs": "npm run build && vuepress build docs --no-cache",
15
- "docs:dev": "npm run build && vuepress dev docs --no-cache",
15
+ "docs:dev": "concurrently \"npm:autobuild\" \"vuepress dev docs --no-cache\"",
16
16
  "lint": "concurrently -r \"npm:lint-*\"",
17
17
  "lint-js": "eslint \"src/**/*.js\" \"test/**/*.js\" \"docs/**/*.js\"",
18
18
  "lint-md": "eslint \"**/*.md\"",
@@ -46,7 +46,7 @@
46
46
  "@rollup/plugin-node-resolve": "^15.0.0",
47
47
  "@typescript-eslint/eslint-plugin": "^5.4.0",
48
48
  "@typescript-eslint/parser": "^5.4.0",
49
- "chart.js": "^3.6.0",
49
+ "chart.js": "^3.8.0",
50
50
  "chartjs-adapter-date-fns": "^2.0.0",
51
51
  "chartjs-plugin-datalabels": "^2.0.0",
52
52
  "chartjs-plugin-zoom": "^1.2.0",
@@ -69,6 +69,7 @@
69
69
  "karma-rollup-preprocessor": "7.0.7",
70
70
  "karma-spec-reporter": "^0.0.34",
71
71
  "karma-summary-reporter": "^3.0.0",
72
+ "ng-hammerjs": "^2.0.8",
72
73
  "pixelmatch": "^5.2.1",
73
74
  "rollup": "^2.79.1",
74
75
  "rollup-plugin-analyzer": "^4.0.0",