chartjs-chart-treemap 4.1.2 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,9 +5,10 @@
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)
7
7
  ![npm bundle size](https://img.shields.io/bundlephobia/min/chartjs-chart-treemap.svg)
8
- ![GitHub](https://img.shields.io/github/license/kurkle/chartjs-chart-treemap.svg)
9
8
  [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=kurkle_chartjs-chart-treemap&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=kurkle_chartjs-chart-treemap)
9
+ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=kurkle_chartjs-chart-treemap&metric=coverage)](https://sonarcloud.io/summary/new_code?id=kurkle_chartjs-chart-treemap)
10
10
  [![documentation](https://img.shields.io/static/v1?message=Documentation&color=informational)](https://chartjs-chart-treemap.pages.dev)
11
+ ![GitHub](https://img.shields.io/github/license/kurkle/chartjs-chart-treemap.svg)
11
12
 
12
13
  ![TreeMap Example Image](treemap.png)
13
14
 
@@ -841,8 +841,22 @@ function buildData(tree, dataset, keys, mainRect) {
841
841
  };
842
842
  }).filter(Boolean);
843
843
  }
844
+ function registerTooltipPositioner() {
845
+ const tooltipPlugin = chart_js.registry.plugins.get('tooltip');
846
+ if (!tooltipPlugin || tooltipPlugin.positioners.treemap) {
847
+ return;
848
+ }
849
+ tooltipPlugin.positioners.treemap = (active)=>{
850
+ if (!active.length) {
851
+ return false;
852
+ }
853
+ const item = active.at(-1);
854
+ return item.element.tooltipPosition();
855
+ };
856
+ }
844
857
  class TreemapController extends chart_js.DatasetController {
845
858
  initialize() {
859
+ registerTooltipPositioner();
846
860
  this.enableOptionSharing = true;
847
861
  super.initialize();
848
862
  }
@@ -888,13 +902,15 @@ class TreemapController extends chart_js.DatasetController {
888
902
  ].concat(dataset.sumKeys || []);
889
903
  dataset.tree = dataset.tree || dataset.data || [];
890
904
  const tree = dataset.tree;
905
+ const treeVersion = dataset.treeVersion;
891
906
  if (mode === 'reset') {
892
907
  this.configure();
893
908
  }
894
- if (this._rectChanged || arrayNotEqual(this._keys || [], keys) || arrayNotEqual(this._groups || [], groups) || this._prevTree !== tree) {
909
+ if (this._rectChanged || arrayNotEqual(this._keys || [], keys) || arrayNotEqual(this._groups || [], groups) || this._prevTree !== tree || this._prevTreeVersion !== treeVersion) {
895
910
  this._groups = groups.slice();
896
911
  this._keys = keys.slice();
897
912
  this._prevTree = tree;
913
+ this._prevTreeVersion = treeVersion;
898
914
  this._rectChanged = false;
899
915
  dataset.data = buildData(tree, dataset, this._keys, this._rect);
900
916
  this._dataCheck();
@@ -1022,19 +1038,7 @@ TreemapController.beforeRegister = ()=>{
1022
1038
  requireVersion('chart.js', '3.8', chart_js.Chart.version);
1023
1039
  };
1024
1040
  TreemapController.afterRegister = ()=>{
1025
- const tooltipPlugin = chart_js.registry.plugins.get('tooltip');
1026
- if (tooltipPlugin) {
1027
- tooltipPlugin.positioners.treemap = (active)=>{
1028
- if (!active.length) {
1029
- return false;
1030
- }
1031
- const item = active.at(-1);
1032
- const el = item.element;
1033
- return el.tooltipPosition();
1034
- };
1035
- } else {
1036
- console.warn('Unable to register the treemap positioner because tooltip plugin is not registered');
1037
- }
1041
+ registerTooltipPositioner();
1038
1042
  };
1039
1043
  TreemapController.afterUnregister = ()=>{
1040
1044
  const tooltipPlugin = chart_js.registry.plugins.get('tooltip');
@@ -832,8 +832,22 @@ function buildData(tree, dataset, keys, mainRect) {
832
832
  };
833
833
  }).filter(Boolean);
834
834
  }
835
+ function registerTooltipPositioner() {
836
+ const tooltipPlugin = registry.plugins.get('tooltip');
837
+ if (!tooltipPlugin || tooltipPlugin.positioners.treemap) {
838
+ return;
839
+ }
840
+ tooltipPlugin.positioners.treemap = (active)=>{
841
+ if (!active.length) {
842
+ return false;
843
+ }
844
+ const item = active.at(-1);
845
+ return item.element.tooltipPosition();
846
+ };
847
+ }
835
848
  class TreemapController extends DatasetController {
836
849
  initialize() {
850
+ registerTooltipPositioner();
837
851
  this.enableOptionSharing = true;
838
852
  super.initialize();
839
853
  }
@@ -879,13 +893,15 @@ class TreemapController extends DatasetController {
879
893
  ].concat(dataset.sumKeys || []);
880
894
  dataset.tree = dataset.tree || dataset.data || [];
881
895
  const tree = dataset.tree;
896
+ const treeVersion = dataset.treeVersion;
882
897
  if (mode === 'reset') {
883
898
  this.configure();
884
899
  }
885
- if (this._rectChanged || arrayNotEqual(this._keys || [], keys) || arrayNotEqual(this._groups || [], groups) || this._prevTree !== tree) {
900
+ if (this._rectChanged || arrayNotEqual(this._keys || [], keys) || arrayNotEqual(this._groups || [], groups) || this._prevTree !== tree || this._prevTreeVersion !== treeVersion) {
886
901
  this._groups = groups.slice();
887
902
  this._keys = keys.slice();
888
903
  this._prevTree = tree;
904
+ this._prevTreeVersion = treeVersion;
889
905
  this._rectChanged = false;
890
906
  dataset.data = buildData(tree, dataset, this._keys, this._rect);
891
907
  this._dataCheck();
@@ -1013,19 +1029,7 @@ TreemapController.beforeRegister = ()=>{
1013
1029
  requireVersion('chart.js', '3.8', Chart.version);
1014
1030
  };
1015
1031
  TreemapController.afterRegister = ()=>{
1016
- const tooltipPlugin = registry.plugins.get('tooltip');
1017
- if (tooltipPlugin) {
1018
- tooltipPlugin.positioners.treemap = (active)=>{
1019
- if (!active.length) {
1020
- return false;
1021
- }
1022
- const item = active.at(-1);
1023
- const el = item.element;
1024
- return el.tooltipPosition();
1025
- };
1026
- } else {
1027
- console.warn('Unable to register the treemap positioner because tooltip plugin is not registered');
1028
- }
1032
+ registerTooltipPositioner();
1029
1033
  };
1030
1034
  TreemapController.afterUnregister = ()=>{
1031
1035
  const tooltipPlugin = registry.plugins.get('tooltip');
@@ -4,5 +4,5 @@
4
4
  * (c) 2026 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";function i(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{height:h-r,hidden:r>a||r>h,width:a-r,x:o+i,y:s+i}}function r(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}function o(t,e,n){return Math.max(Math.min(t,n),e)}function s(t,e,i){const r=n.toTRBL(t);return{b:o(r.bottom,0,i),l:o(r.left,0,e),r:o(r.right,0,e),t:o(r.top,0,i)}}function a(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,h:"_ix"===i?a:s,w:"_ix"===i?s:a}}const h=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function l(t,e,n,i){const r={_data:e._data,a:e._normalized,h:n.h,s:i,v:e.value,vs:e.values,w:n.w,x:h(t,n.w),y:t.y+t._iy};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class u{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,h=r*r,u=[];let c=0,d=0;for(const e of o){const n=a(e,s,h,i);d+=n.d1,c=Math.max(c,n.d2),u.push(l(this,e,n,t.sum)),this[i]+=n.d1}return this["x"===e?"_iy":"_ix"]+=c,this[i]-=d,u}constructor(t){t=t||{h:1,w:1},this.rtl=!!t.rtl,this.unsorted=!!t.unsorted,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}}const c=Math.min,d=Math.max;function f(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{max:d(t.max,n),min:c(t.min,n),nmax:d(t.nmax,i),nmin:c(t.nmin,i),nsum:t.nsum+i,sum:t.sum+n}}function p(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class g{get length(){return this._arr.length}reset(){this._arr=[],this._hist=[],this.sum=0,this.nsum=0,this.min=1/0,this.max=-1/0,this.nmin=1/0,this.nmax=-1/0}push(t){p(this,t,f(this,t))}pushIf(t,e,...n){const i=f(this,t);if(!e((r=this,{max:r.max,min:r.min,nmax:r.nmax,nmin:r.nmin,nsum:r.nsum,sum:r.sum}),i,n))return t;var r;p(this,t,i)}get(){return this._arr}constructor(t,e){this._arr=[],this._hist=[],this.sum=0,this.nsum=0,this.min=1/0,this.max=-1/0,this.nmin=1/0,this.nmax=-1/0,this.key=t,this.ratio=e,this.reset()}}const m=(t,e)=>e>t||t.length>e.length&&t.startsWith(e),x=t=>String(t),y=t=>null!=t&&""!==t;function b(t,e,i,r=[],o=0,s=[]){const a=o-1;if(t[0]in i&&o>0){const n=r.reduce((t,e,n)=>(n!==a&&(t[x(n)]=e),t),{});n[e]=r[a],t.forEach(t=>{n[t]=i[t]}),s.push(n)}else for(const a of Object.keys(i)){const h=i[a];n.isObject(h)&&(r.push(a),b(t,e,h,r,o+1,s))}return r.splice(a,1),s}function v(t,e,n){const i=b(t,e,n);if(!i.length)return i;const r=i.reduce((t,e)=>{const n=Object.keys(e).length-2;return Math.max(t,n)},0);return i.forEach(t=>{for(let e=0;e<r;e++){const n=x(e);t[n]||(t[n]="")}}),i}function w(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 _(t,e,n){const i=[];for(const n of t){const t=e[n];y(t)&&i.push(t)}return i.length?i.join("."):n}function M(t,e,n,i){for(let e=i;e<n.length;e++){const i=x(n[e]);if(y(t[i]))return{group:i,groupIndex:e,value:t[i]}}if(y(t[e]))return{group:e,groupIndex:i,value:t[e]}}function C(t,e,n,i){if(n in t)return;t[n]={value:0};const r=t[n];i.forEach(t=>{r[t]=0}),e[n]=[]}function k(t,e,n,i,r,o,s=[],a=s,h=s.length-1){const l=n[0],u=n.slice(1),c=Object.create(null),d=Object.create(null),f=[],p=a.length?a:[e],g=a.length?h:0;let m,x;for(m=0,x=t.length;m<x;++m){const e=t[m];if(r&&e[r]!==o)continue;const n=M(e,i,p,g);if(!n)return[];const s=n.value;C(c,d,s,u),c[s].value+=+e[l],c[s].label=s,c[s].group=n.group,c[s].groupIndex=n.groupIndex;const a=c[s];u.forEach(t=>{a[t]+=e[t]}),c[s].path=_(p.slice(0,n.groupIndex+1),e,s),d[s].push(e)}return Object.keys(c).forEach(t=>{const n={children:d[t]};n[l]=+c[t].value,u.forEach(e=>{n[e]=+c[t][e]}),n[e]=c[t].label,n.group=c[t].group,n.groupIndex=c[t].groupIndex,n.label=t,n.path=c[t].path,r&&(n[r]=o),f.push(n)}),f}function O(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]={_idx:i,v:t[i]};return e}function R(t,e){e?t.sort((t,n)=>+n[e]-+t[e]):t.sort((t,e)=>+e-+t)}function T(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 j(t,e,n,i=!0){const r=n.split(".");let o=0;for(const s of e.split(".")){const a=r[o++];if(Number.parseInt(s,10)<Number.parseInt(a,10))break;if(m(a,s)){if(i)throw new Error(`${t} v${n} is not supported. v${e} or newer is required.`);return!1}}return!0}function E(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function L(t,e,n=[],i,r,o){t=t||[];const s=[],a=new u(e),h=new g("value",a.area/T(t,n[0]));let l=a.side;const c=t.length;let d,f;if(!c)return s;const p=t.slice(),m=O(p,n[0]);e?.unsorted||R(p,m);const x=t=>m?+p[t][m]:+p[t],y=t=>i&&p[t][i];for(d=0;d<c;++d){if(f={_data:t[p[d]._idx],group:void 0,groupSum:o,level:void 0,value:x(d)},i){f.level=p[d].groupIndex??r,f.group=y(d);const t=p[d];f.values=n.reduce((e,n)=>(e[n]=+t[n],e),{})}f=h.pushIf(f,E,l),f&&(s.push(a.map(h)),l=a.side,h.reset(),h.push(f))}return h.length&&s.push(a.map(h)),w(s)}const P=new Map;function S(t,e,i){if(!i||!1===i.display)return!1;if("headerBoxes"===t)return!0;const{w:r,h:o}=e,s=n.toFont(i.font||{}).lineHeight,a=Math.max(Math.min(2*n.valueOrDefault(i.padding,3),Math.min(r,o)),0);return r-a>s&&o-a>s}function D(t,e,n,i){if("headerBoxes"!==t)return n.lineHeight+2*i;const r=n.lineHeight+2*i;return e.h<2*r?e.h/3:r}function I(t,e,i,r,o){const{captions:s,labels:a,displayMode:h}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const l=r&&(!n.defined(r.l)||r.isLeaf);l&&a.display?function(t,e,i,r,o){const s=i.labels,a=B(s.formatter,A(o,r));if(!a)return;const h=n.isArray(a)?a:[a];let l=function(t,e){const{font:i,hoverFont:r}=e,o=(t.active?r:i)||i;return Array.isArray(o)?o.map(t=>n.toFont(t)):[n.toFont(o)]}(e,s),u=F(t,h,l);const c=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,s,u);if(!c)return;n.isNumber(c)&&(u={height:u.height*c,width:u.width*c},l=function(t,e){return t.map(t=>{const{lineHeight:i,...r}=t;return n.toFont({...r,size:Math.floor(t.size*e)})})}(l,c));const{color:d,hoverColor:f,align:p}=s,g=(e.active?f:d)||d,m=n.isArray(g)?g:[g],x=function(t,e,n){const{align:i,position:r,padding:o}=e,s=z(t,i,o);let a;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,s,u);t.textAlign=p,t.textBaseline="middle";let y=0;h.forEach((e,n)=>{const i=m[Math.min(n,m.length-1)],r=l[Math.min(n,l.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,x.x,x.y+o/2+y),y+=o})}(t,e,i,r,o):!l&&S(h,e,s)&&function(t,e,i,r,o){const{captions:s,spacing:a,rtl:h,displayMode:l}=i,{color:u,hoverColor:c,font:d,hoverFont:f,padding:p,align:g}=s,m=(e.active?c:u)||u,x=g||(h?"right":"left"),y=(e.active?f:d)||d,b=n.toFont(y),v=[b];if(b.lineHeight>e.h)return;let w=function(t,e,n){return B(t.formatter,A(e,n))||n.g||""}(s,o,r);if(!w)return;const _=F(t,[w],v);_.width+2*p>e.w&&(w=function(t,e,n,i){const r="...",o=F(t,[r],i).width;if(o>=n)return"";let s,a=1,h=e.length;for(;a<=h;){const r=Math.floor((a+h)/2);s=F(t,[e.slice(0,r)],i).width,s+o>n?h=r-1:a=r+1}const l=e.slice(0,Math.max(0,a-1));return l?l+r:""}(t,w,e.w-2*p,v));const M=b.lineHeight/2,C=z(e,x,p);t.fillStyle=m,t.font=b.string,t.textAlign=x,t.textBaseline="middle";const k="headerBoxes"===l?e.y+e.h/2:e.y+p+a+M;t.fillText(w,C,k)}(t,e,i,r,o),t.restore()}function A(t,e){const n=t.$context||{active:!!t.active,raw:e,type:"data"};return n.active=!!t.active,n.raw=e,n}function B(t,e){return"function"==typeof t?t(e):t}function F(t,e,n){const i=n.reduce((t,e)=>t+=e.string,""),r=e.join()+i+(t._measureText?"-spriting":"");let o=P.get(r);if(!o){t.save();const i=e.length;let s=0,a=0;for(let r=0;r<i;r++){const i=n[Math.min(r,n.length-1)];t.font=i.string;const o=e[r];s=Math.max(s,t.measureText(o).width),a+=i.lineHeight}t.restore(),o={height:a,width:s},P.set(r,o)}return o}function z(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}function H(t,e,i,r){const o=e.treeLeafKey||"_leaf";n.isObject(t)&&(t=v(i,o,t));const a=e.groups||[],h=a.length,l="headerBoxes"===e.displayMode?0:n.valueOrDefault(e.spacing,0),u=e.captions||{},c=n.toFont(u.font),d=n.valueOrDefault(u.padding,3);const f=h?function t(n,r,f,p,g){const m=x(a[r]),y=k(n,m,i,o,void 0,p,a.filter((t,e)=>e<=r),a,r),b=L(y,f,i,m,r,g),v=b.slice();return r<h-1?b.forEach(n=>{const i=function(t,n){const i="headerBoxes"===e.displayMode?{b:0,l:0,r:0,t:0}:s(e.borderWidth,t.w/2,t.h/2),r={...n,h:t.h-2*l-i.t-i.b,w:t.w-2*l-i.l-i.r,x:t.x+l+i.l,y:t.y+l+i.t};if(S(e.displayMode,r,u)){const t=D(e.displayMode,r,c,d);r.y+=t,r.h-=t}return r}(n,f),r=[],o=n._data.groupIndex+1;o<h&&r.push(...t(n._data.children,o,i,n.g,n.s)),v.push(...r),n.isLeaf=!r.length}):b.forEach(t=>{t.isLeaf=!0}),v}(t,0,r):L(t,r,i);return f.map(t=>{if("headerBoxes"!==e.displayMode||t.isLeaf)return t;if(!S(e.displayMode,t,u))return;const n=D(e.displayMode,t,c,d);return{...t,h:n}}).filter(Boolean)}class $ extends e.DatasetController{initialize(){this.enableOptionSharing=!0,super.initialize()}getMinMax(t){return{max:"x"===t.axis?t.right-t.left:t.bottom-t.top,min:0}}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={h:i,rtl:!!this.options.rtl,unsorted:!!this.options.unsorted,w:n,x:0,y:0};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&&o.unsorted===s.unsorted||(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:n}=this.getMeta(),i=e.groups||[],o=[e.key||""].concat(e.sumKeys||[]);e.tree=e.tree||e.data||[];const s=e.tree;"reset"===t&&this.configure(),(this._rectChanged||r(this._keys||[],o)||r(this._groups||[],i)||this._prevTree!==s)&&(this._groups=i.slice(),this._keys=o.slice(),this._prevTree=s,this._rectChanged=!1,e.data=H(s,e,this._keys,this._rect),this._dataCheck(),this._resyncElements()),this.updateElements(n,0,n.length,t)}updateElements(t,e,n,r){const o="reset"===r,s=this.getDataset(),a=this.resolveDataElementOptions(e,r);this._rect.options=a;const h=this.getSharedOptions(a),l=this.includeOptions(r,h||{}),{xScale:u,yScale:c}=this.getMeta();for(let a=e;a<e+n;a++){const e=h||this.resolveDataElementOptions(a,r),n=i(s.data[a],u,c,e.spacing);o&&(n.width=0,n.height=0),l&&(n.options=e),this.updateElement(t[a],a,n,r)}this.updateSharedOptions(h||{},r,a)}draw(){const{ctx:t,chartArea:e}=this.chart,i=this.getMeta().data||[],r=this.getDataset().data;n.clipArea(t,e);for(let e=0,n=i.length;e<n;++e){const n=i[e];n.hidden||n.draw(t,r[e])}n.unclipArea(t)}constructor(t,e){super(t,e),this._groups=void 0,this._keys=void 0,this._rect=void 0,this._rectChanged=!0}}function W(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{bottom:i+o,left:n,right:n+r,top:i}}function q(t){const e=W(t),i=e.right-e.left,r=e.bottom-e.top,a=s(t.options.borderWidth,i/2,r/2),h=function(t,e,i){const r=n.toTRBLCorners(t),s=Math.min(e,i);return{bottomLeft:o(r.bottomLeft,0,s),bottomRight:o(r.bottomRight,0,s),topLeft:o(r.topLeft,0,s),topRight:o(r.topRight,0,s)}}(t.options.borderRadius,i/2,r/2),l={active:t.active,h:r,radius:h,w:i,x:e.left,y:e.top};return{inner:{active:t.active,h:l.h-a.t-a.b,radius:{bottomLeft:Math.max(0,h.bottomLeft-Math.max(a.b,a.l)),bottomRight:Math.max(0,h.bottomRight-Math.max(a.b,a.r)),topLeft:Math.max(0,h.topLeft-Math.max(a.t,a.l)),topRight:Math.max(0,h.topRight-Math.max(a.t,a.r))},w:l.w-a.l-a.r,x:l.x+a.l,y:l.y+a.t},outer:l}}function V(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&W(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)}$.id="treemap",$.version="0.0.0-development",$.defaults={animations:{numbers:{properties:["x","y","width","height"],type:"number"}},dataElementType:"treemap"},$.descriptors={_indexable:!1,_scriptable:!0,captions:{_fallback:!0,_scriptable:t=>"formatter"!==t},labels:{_fallback:!0,_scriptable:t=>"formatter"!==t}},$.overrides={hover:{},interaction:{includeInvisible:!0,intersect:!0,mode:"point"},plugins:{tooltip:{callbacks:{label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?`${i}: `:"")+n.v},title(t){if(t.length){return t[0].dataset.key||""}return""}},intersect:!0,position:"treemap"}},scales:{x:{alignToPixels:!0,bounds:"data",display:!1,type:"linear"},y:{alignToPixels:!0,bounds:"data",display:!1,reverse:!0,type:"linear"}}},$.beforeRegister=()=>{j("chart.js","3.8",e.Chart.version)},$.afterRegister=()=>{const t=e.registry.plugins.get("tooltip");t?t.positioners.treemap=t=>{if(!t.length)return!1;return t.at(-1).element.tooltipPosition()}:console.warn("Unable to register the treemap positioner because tooltip plugin is not registered")},$.afterUnregister=()=>{const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap};class N extends e.Element{draw(t,e){if(!e)return;const i=this.options,{inner:r,outer:o}=q(this),s=(a=o.radius).topLeft||a.topRight||a.bottomLeft||a.bottomRight?n.addRoundedRectPath:K;var a;t.save(),o.w===r.w&&o.h===r.h||(t.beginPath(),s(t,o),t.clip(),s(t,r),t.fillStyle=i.borderColor,t.fill("evenodd")),t.beginPath(),s(t,r),t.fillStyle=i.backgroundColor,t.fill(),function(t,e,n,i){const r=n.dividers,o=i._data?.children;if(!r.display||!Array.isArray(o)||!o.length)return;const{x:s,y:a,w:h,h:l}=e,{lineColor:u,lineCapStyle:c,lineDash:d,lineDashOffset:f,lineWidth:p}=r;if(t.save(),t.strokeStyle=u,t.lineCap=c,t.setLineDash(d),t.lineDashOffset=f,t.lineWidth=p,t.beginPath(),h>l){const e=h/2;t.moveTo(s+e,a),t.lineTo(s+e,a+l)}else{const e=l/2;t.moveTo(s,a+e),t.lineTo(s+h,a+e)}t.stroke(),t.restore()}(t,r,i,e),I(t,r,i,e,this),t.restore()}inRange(t,e,n){return V(this,t,e,n)}inXRange(t,e){return V(this,t,null,e)}inYRange(t,e){return V(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()}constructor(t){super(),this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}}N.id="treemap",N.defaults={borderRadius:0,borderWidth:0,captions:{align:void 0,color:"black",display:!0,font:{},formatter:t=>{const e=t.raw._data?.label;return t.raw.g||("string"==typeof e?e:"")},padding:3},displayMode:"containerBoxes",dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:[],lineDashOffset:0,lineWidth:1},label:void 0,labels:{align:"center",color:"black",display:!1,font:{},formatter(t){const e=t.raw._data?.label;return t.raw.g?[t.raw.g,`${t.raw.v}`]:"string"==typeof e?[e,`${t.raw.v}`]:`${t.raw.v}`},overflow:"cut",padding:3,position:"middle"},rtl:!1,spacing:.5,unsorted:!1},N.descriptors={_indexable:!1,_scriptable:!0,captions:{_fallback:!0,_scriptable:t=>"formatter"!==t},labels:{_fallback:!0,_scriptable:t=>"formatter"!==t}},N.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},e.Chart.register($,N),t.TreemapController=$,t.TreemapElement=N,t.flatten=w,t.getGroupKey=x,t.group=k,t.index=O,t.normalizeTreeToArray=v,t.requireVersion=j,t.sort=R,t.sum=T});
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";function i(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{height:h-r,hidden:r>a||r>h,width:a-r,x:o+i,y:s+i}}function r(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}function o(t,e,n){return Math.max(Math.min(t,n),e)}function s(t,e,i){const r=n.toTRBL(t);return{b:o(r.bottom,0,i),l:o(r.left,0,e),r:o(r.right,0,e),t:o(r.top,0,i)}}function a(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,h:"_ix"===i?a:s,w:"_ix"===i?s:a}}const h=(t,e)=>t.rtl?t.x+t.iw-e:t.x+t._ix;function l(t,e,n,i){const r={_data:e._data,a:e._normalized,h:n.h,s:i,v:e.value,vs:e.values,w:n.w,x:h(t,n.w),y:t.y+t._iy};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class u{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,h=r*r,u=[];let c=0,d=0;for(const e of o){const n=a(e,s,h,i);d+=n.d1,c=Math.max(c,n.d2),u.push(l(this,e,n,t.sum)),this[i]+=n.d1}return this["x"===e?"_iy":"_ix"]+=c,this[i]-=d,u}constructor(t){t=t||{h:1,w:1},this.rtl=!!t.rtl,this.unsorted=!!t.unsorted,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}}const c=Math.min,d=Math.max;function f(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{max:d(t.max,n),min:c(t.min,n),nmax:d(t.nmax,i),nmin:c(t.nmin,i),nsum:t.nsum+i,sum:t.sum+n}}function p(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class g{get length(){return this._arr.length}reset(){this._arr=[],this._hist=[],this.sum=0,this.nsum=0,this.min=1/0,this.max=-1/0,this.nmin=1/0,this.nmax=-1/0}push(t){p(this,t,f(this,t))}pushIf(t,e,...n){const i=f(this,t);if(!e((r=this,{max:r.max,min:r.min,nmax:r.nmax,nmin:r.nmin,nsum:r.nsum,sum:r.sum}),i,n))return t;var r;p(this,t,i)}get(){return this._arr}constructor(t,e){this._arr=[],this._hist=[],this.sum=0,this.nsum=0,this.min=1/0,this.max=-1/0,this.nmin=1/0,this.nmax=-1/0,this.key=t,this.ratio=e,this.reset()}}const m=(t,e)=>e>t||t.length>e.length&&t.startsWith(e),x=t=>String(t),y=t=>null!=t&&""!==t;function b(t,e,i,r=[],o=0,s=[]){const a=o-1;if(t[0]in i&&o>0){const n=r.reduce((t,e,n)=>(n!==a&&(t[x(n)]=e),t),{});n[e]=r[a],t.forEach(t=>{n[t]=i[t]}),s.push(n)}else for(const a of Object.keys(i)){const h=i[a];n.isObject(h)&&(r.push(a),b(t,e,h,r,o+1,s))}return r.splice(a,1),s}function v(t,e,n){const i=b(t,e,n);if(!i.length)return i;const r=i.reduce((t,e)=>{const n=Object.keys(e).length-2;return Math.max(t,n)},0);return i.forEach(t=>{for(let e=0;e<r;e++){const n=x(e);t[n]||(t[n]="")}}),i}function w(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 _(t,e,n){const i=[];for(const n of t){const t=e[n];y(t)&&i.push(t)}return i.length?i.join("."):n}function M(t,e,n,i){for(let e=i;e<n.length;e++){const i=x(n[e]);if(y(t[i]))return{group:i,groupIndex:e,value:t[i]}}if(y(t[e]))return{group:e,groupIndex:i,value:t[e]}}function C(t,e,n,i){if(n in t)return;t[n]={value:0};const r=t[n];i.forEach(t=>{r[t]=0}),e[n]=[]}function k(t,e,n,i,r,o,s=[],a=s,h=s.length-1){const l=n[0],u=n.slice(1),c=Object.create(null),d=Object.create(null),f=[],p=a.length?a:[e],g=a.length?h:0;let m,x;for(m=0,x=t.length;m<x;++m){const e=t[m];if(r&&e[r]!==o)continue;const n=M(e,i,p,g);if(!n)return[];const s=n.value;C(c,d,s,u),c[s].value+=+e[l],c[s].label=s,c[s].group=n.group,c[s].groupIndex=n.groupIndex;const a=c[s];u.forEach(t=>{a[t]+=e[t]}),c[s].path=_(p.slice(0,n.groupIndex+1),e,s),d[s].push(e)}return Object.keys(c).forEach(t=>{const n={children:d[t]};n[l]=+c[t].value,u.forEach(e=>{n[e]=+c[t][e]}),n[e]=c[t].label,n.group=c[t].group,n.groupIndex=c[t].groupIndex,n.label=t,n.path=c[t].path,r&&(n[r]=o),f.push(n)}),f}function T(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]={_idx:i,v:t[i]};return e}function O(t,e){e?t.sort((t,n)=>+n[e]-+t[e]):t.sort((t,e)=>+e-+t)}function R(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 j(t,e,n,i=!0){const r=n.split(".");let o=0;for(const s of e.split(".")){const a=r[o++];if(Number.parseInt(s,10)<Number.parseInt(a,10))break;if(m(a,s)){if(i)throw new Error(`${t} v${n} is not supported. v${e} or newer is required.`);return!1}}return!0}function E(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function L(t,e,n=[],i,r,o){t=t||[];const s=[],a=new u(e),h=new g("value",a.area/R(t,n[0]));let l=a.side;const c=t.length;let d,f;if(!c)return s;const p=t.slice(),m=T(p,n[0]);e?.unsorted||O(p,m);const x=t=>m?+p[t][m]:+p[t],y=t=>i&&p[t][i];for(d=0;d<c;++d){if(f={_data:t[p[d]._idx],group:void 0,groupSum:o,level:void 0,value:x(d)},i){f.level=p[d].groupIndex??r,f.group=y(d);const t=p[d];f.values=n.reduce((e,n)=>(e[n]=+t[n],e),{})}f=h.pushIf(f,E,l),f&&(s.push(a.map(h)),l=a.side,h.reset(),h.push(f))}return h.length&&s.push(a.map(h)),w(s)}const P=new Map;function S(t,e,i){if(!i||!1===i.display)return!1;if("headerBoxes"===t)return!0;const{w:r,h:o}=e,s=n.toFont(i.font||{}).lineHeight,a=Math.max(Math.min(2*n.valueOrDefault(i.padding,3),Math.min(r,o)),0);return r-a>s&&o-a>s}function D(t,e,n,i){if("headerBoxes"!==t)return n.lineHeight+2*i;const r=n.lineHeight+2*i;return e.h<2*r?e.h/3:r}function I(t,e,i,r,o){const{captions:s,labels:a,displayMode:h}=i;t.save(),t.beginPath(),t.rect(e.x,e.y,e.w,e.h),t.clip();const l=r&&(!n.defined(r.l)||r.isLeaf);l&&a.display?function(t,e,i,r,o){const s=i.labels,a=B(s.formatter,A(o,r));if(!a)return;const h=n.isArray(a)?a:[a];let l=function(t,e){const{font:i,hoverFont:r}=e,o=(t.active?r:i)||i;return Array.isArray(o)?o.map(t=>n.toFont(t)):[n.toFont(o)]}(e,s),u=F(t,h,l);const c=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,s,u);if(!c)return;n.isNumber(c)&&(u={height:u.height*c,width:u.width*c},l=function(t,e){return t.map(t=>{const{lineHeight:i,...r}=t;return n.toFont({...r,size:Math.floor(t.size*e)})})}(l,c));const{color:d,hoverColor:f,align:p}=s,g=(e.active?f:d)||d,m=n.isArray(g)?g:[g],x=function(t,e,n){const{align:i,position:r,padding:o}=e,s=z(t,i,o);let a;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,s,u);t.textAlign=p,t.textBaseline="middle";let y=0;h.forEach((e,n)=>{const i=m[Math.min(n,m.length-1)],r=l[Math.min(n,l.length-1)],o=r.lineHeight;t.font=r.string,t.fillStyle=i,t.fillText(e,x.x,x.y+o/2+y),y+=o})}(t,e,i,r,o):!l&&S(h,e,s)&&function(t,e,i,r,o){const{captions:s,spacing:a,rtl:h,displayMode:l}=i,{color:u,hoverColor:c,font:d,hoverFont:f,padding:p,align:g}=s,m=(e.active?c:u)||u,x=g||(h?"right":"left"),y=(e.active?f:d)||d,b=n.toFont(y),v=[b];if(b.lineHeight>e.h)return;let w=function(t,e,n){return B(t.formatter,A(e,n))||n.g||""}(s,o,r);if(!w)return;const _=F(t,[w],v);_.width+2*p>e.w&&(w=function(t,e,n,i){const r="...",o=F(t,[r],i).width;if(o>=n)return"";let s,a=1,h=e.length;for(;a<=h;){const r=Math.floor((a+h)/2);s=F(t,[e.slice(0,r)],i).width,s+o>n?h=r-1:a=r+1}const l=e.slice(0,Math.max(0,a-1));return l?l+r:""}(t,w,e.w-2*p,v));const M=b.lineHeight/2,C=z(e,x,p);t.fillStyle=m,t.font=b.string,t.textAlign=x,t.textBaseline="middle";const k="headerBoxes"===l?e.y+e.h/2:e.y+p+a+M;t.fillText(w,C,k)}(t,e,i,r,o),t.restore()}function A(t,e){const n=t.$context||{active:!!t.active,raw:e,type:"data"};return n.active=!!t.active,n.raw=e,n}function B(t,e){return"function"==typeof t?t(e):t}function F(t,e,n){const i=n.reduce((t,e)=>t+=e.string,""),r=e.join()+i+(t._measureText?"-spriting":"");let o=P.get(r);if(!o){t.save();const i=e.length;let s=0,a=0;for(let r=0;r<i;r++){const i=n[Math.min(r,n.length-1)];t.font=i.string;const o=e[r];s=Math.max(s,t.measureText(o).width),a+=i.lineHeight}t.restore(),o={height:a,width:s},P.set(r,o)}return o}function z(t,e,n){return"left"===e?t.x+n:"right"===e?t.x+t.w-n:t.x+t.w/2}function H(t,e,i,r){const o=e.treeLeafKey||"_leaf";n.isObject(t)&&(t=v(i,o,t));const a=e.groups||[],h=a.length,l="headerBoxes"===e.displayMode?0:n.valueOrDefault(e.spacing,0),u=e.captions||{},c=n.toFont(u.font),d=n.valueOrDefault(u.padding,3);const f=h?function t(n,r,f,p,g){const m=x(a[r]),y=k(n,m,i,o,void 0,p,a.filter((t,e)=>e<=r),a,r),b=L(y,f,i,m,r,g),v=b.slice();return r<h-1?b.forEach(n=>{const i=function(t,n){const i="headerBoxes"===e.displayMode?{b:0,l:0,r:0,t:0}:s(e.borderWidth,t.w/2,t.h/2),r={...n,h:t.h-2*l-i.t-i.b,w:t.w-2*l-i.l-i.r,x:t.x+l+i.l,y:t.y+l+i.t};if(S(e.displayMode,r,u)){const t=D(e.displayMode,r,c,d);r.y+=t,r.h-=t}return r}(n,f),r=[],o=n._data.groupIndex+1;o<h&&r.push(...t(n._data.children,o,i,n.g,n.s)),v.push(...r),n.isLeaf=!r.length}):b.forEach(t=>{t.isLeaf=!0}),v}(t,0,r):L(t,r,i);return f.map(t=>{if("headerBoxes"!==e.displayMode||t.isLeaf)return t;if(!S(e.displayMode,t,u))return;const n=D(e.displayMode,t,c,d);return{...t,h:n}}).filter(Boolean)}function V(){const t=e.registry.plugins.get("tooltip");t&&!t.positioners.treemap&&(t.positioners.treemap=t=>{if(!t.length)return!1;return t.at(-1).element.tooltipPosition()})}class $ extends e.DatasetController{initialize(){V(),this.enableOptionSharing=!0,super.initialize()}getMinMax(t){return{max:"x"===t.axis?t.right-t.left:t.bottom-t.top,min:0}}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={h:i,rtl:!!this.options.rtl,unsorted:!!this.options.unsorted,w:n,x:0,y:0};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&&o.unsorted===s.unsorted||(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:n}=this.getMeta(),i=e.groups||[],o=[e.key||""].concat(e.sumKeys||[]);e.tree=e.tree||e.data||[];const s=e.tree,a=e.treeVersion;"reset"===t&&this.configure(),(this._rectChanged||r(this._keys||[],o)||r(this._groups||[],i)||this._prevTree!==s||this._prevTreeVersion!==a)&&(this._groups=i.slice(),this._keys=o.slice(),this._prevTree=s,this._prevTreeVersion=a,this._rectChanged=!1,e.data=H(s,e,this._keys,this._rect),this._dataCheck(),this._resyncElements()),this.updateElements(n,0,n.length,t)}updateElements(t,e,n,r){const o="reset"===r,s=this.getDataset(),a=this.resolveDataElementOptions(e,r);this._rect.options=a;const h=this.getSharedOptions(a),l=this.includeOptions(r,h||{}),{xScale:u,yScale:c}=this.getMeta();for(let a=e;a<e+n;a++){const e=h||this.resolveDataElementOptions(a,r),n=i(s.data[a],u,c,e.spacing);o&&(n.width=0,n.height=0),l&&(n.options=e),this.updateElement(t[a],a,n,r)}this.updateSharedOptions(h||{},r,a)}draw(){const{ctx:t,chartArea:e}=this.chart,i=this.getMeta().data||[],r=this.getDataset().data;n.clipArea(t,e);for(let e=0,n=i.length;e<n;++e){const n=i[e];n.hidden||n.draw(t,r[e])}n.unclipArea(t)}constructor(t,e){super(t,e),this._groups=void 0,this._keys=void 0,this._rect=void 0,this._rectChanged=!0}}function W(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{bottom:i+o,left:n,right:n+r,top:i}}function q(t){const e=W(t),i=e.right-e.left,r=e.bottom-e.top,a=s(t.options.borderWidth,i/2,r/2),h=function(t,e,i){const r=n.toTRBLCorners(t),s=Math.min(e,i);return{bottomLeft:o(r.bottomLeft,0,s),bottomRight:o(r.bottomRight,0,s),topLeft:o(r.topLeft,0,s),topRight:o(r.topRight,0,s)}}(t.options.borderRadius,i/2,r/2),l={active:t.active,h:r,radius:h,w:i,x:e.left,y:e.top};return{inner:{active:t.active,h:l.h-a.t-a.b,radius:{bottomLeft:Math.max(0,h.bottomLeft-Math.max(a.b,a.l)),bottomRight:Math.max(0,h.bottomRight-Math.max(a.b,a.r)),topLeft:Math.max(0,h.topLeft-Math.max(a.t,a.l)),topRight:Math.max(0,h.topRight-Math.max(a.t,a.r))},w:l.w-a.l-a.r,x:l.x+a.l,y:l.y+a.t},outer:l}}function K(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&W(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}function N(t,e){t.rect(e.x,e.y,e.w,e.h)}$.id="treemap",$.version="0.0.0-development",$.defaults={animations:{numbers:{properties:["x","y","width","height"],type:"number"}},dataElementType:"treemap"},$.descriptors={_indexable:!1,_scriptable:!0,captions:{_fallback:!0,_scriptable:t=>"formatter"!==t},labels:{_fallback:!0,_scriptable:t=>"formatter"!==t}},$.overrides={hover:{},interaction:{includeInvisible:!0,intersect:!0,mode:"point"},plugins:{tooltip:{callbacks:{label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||n._data.label||e.label;return(i?`${i}: `:"")+n.v},title(t){if(t.length){return t[0].dataset.key||""}return""}},intersect:!0,position:"treemap"}},scales:{x:{alignToPixels:!0,bounds:"data",display:!1,type:"linear"},y:{alignToPixels:!0,bounds:"data",display:!1,reverse:!0,type:"linear"}}},$.beforeRegister=()=>{j("chart.js","3.8",e.Chart.version)},$.afterRegister=()=>{V()},$.afterUnregister=()=>{const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap};class G extends e.Element{draw(t,e){if(!e)return;const i=this.options,{inner:r,outer:o}=q(this),s=(a=o.radius).topLeft||a.topRight||a.bottomLeft||a.bottomRight?n.addRoundedRectPath:N;var a;t.save(),o.w===r.w&&o.h===r.h||(t.beginPath(),s(t,o),t.clip(),s(t,r),t.fillStyle=i.borderColor,t.fill("evenodd")),t.beginPath(),s(t,r),t.fillStyle=i.backgroundColor,t.fill(),function(t,e,n,i){const r=n.dividers,o=i._data?.children;if(!r.display||!Array.isArray(o)||!o.length)return;const{x:s,y:a,w:h,h:l}=e,{lineColor:u,lineCapStyle:c,lineDash:d,lineDashOffset:f,lineWidth:p}=r;if(t.save(),t.strokeStyle=u,t.lineCap=c,t.setLineDash(d),t.lineDashOffset=f,t.lineWidth=p,t.beginPath(),h>l){const e=h/2;t.moveTo(s+e,a),t.lineTo(s+e,a+l)}else{const e=l/2;t.moveTo(s,a+e),t.lineTo(s+h,a+e)}t.stroke(),t.restore()}(t,r,i,e),I(t,r,i,e,this),t.restore()}inRange(t,e,n){return K(this,t,e,n)}inXRange(t,e){return K(this,t,null,e)}inYRange(t,e){return K(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()}constructor(t){super(),this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}}G.id="treemap",G.defaults={borderRadius:0,borderWidth:0,captions:{align:void 0,color:"black",display:!0,font:{},formatter:t=>{const e=t.raw._data?.label;return t.raw.g||("string"==typeof e?e:"")},padding:3},displayMode:"containerBoxes",dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:[],lineDashOffset:0,lineWidth:1},label:void 0,labels:{align:"center",color:"black",display:!1,font:{},formatter(t){const e=t.raw._data?.label;return t.raw.g?[t.raw.g,`${t.raw.v}`]:"string"==typeof e?[e,`${t.raw.v}`]:`${t.raw.v}`},overflow:"cut",padding:3,position:"middle"},rtl:!1,spacing:.5,unsorted:!1},G.descriptors={_indexable:!1,_scriptable:!0,captions:{_fallback:!0,_scriptable:t=>"formatter"!==t},labels:{_fallback:!0,_scriptable:t=>"formatter"!==t}},G.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},e.Chart.register($,G),t.TreemapController=$,t.TreemapElement=G,t.flatten=w,t.getGroupKey=x,t.group=k,t.index=T,t.normalizeTreeToArray=v,t.requireVersion=j,t.sort=O,t.sum=R});
8
8
  //# sourceMappingURL=chartjs-chart-treemap.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chartjs-chart-treemap.min.js","sources":["../src/helpers/index.ts","../src/options.ts","../src/rect.ts","../src/statArray.ts","../src/utils.ts","../src/squarify.ts","../src/text.ts","../src/controller.ts","../src/geometry.ts","../src/element.ts","../src/index.ts"],"sourcesContent":["export function scaleRect(sq: any, xScale: any, yScale: any, sp: number) {\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 height: h - sp2,\n hidden: sp2 > w || sp2 > h,\n width: w - sp2,\n x: x + sp,\n y: y + sp,\n }\n}\n\nexport function rectNotEqual(r1: any, r2: any) {\n return (\n !r1 ||\n !r2 ||\n r1.x !== r2.x ||\n r1.y !== r2.y ||\n r1.w !== r2.w ||\n r1.h !== r2.h ||\n r1.rtl !== r2.rtl ||\n r1.unsorted !== r2.unsorted\n )\n}\n\nexport function arrayNotEqual(a: any[], b: any[]) {\n let i: number\n let n: number\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 type { TreemapBorderRadius, TreemapBorderWidth, TreemapOptions } from './types'\n\nimport { toTRBL, toTRBLCorners } from 'chart.js/helpers'\n\nexport type ParsedBorderWidth = {\n b: number\n l: number\n r: number\n t: number\n}\n\nfunction limit(value: number, min: number, max: number) {\n return Math.max(Math.min(value, max), min)\n}\n\nexport function parseBorderWidth(\n value: TreemapBorderWidth,\n maxW: number,\n maxH: number\n): ParsedBorderWidth {\n const o = toTRBL(value as Parameters<typeof toTRBL>[0])\n\n return {\n b: limit(o.bottom, 0, maxH),\n l: limit(o.left, 0, maxW),\n r: limit(o.right, 0, maxW),\n t: limit(o.top, 0, maxH),\n }\n}\n\nexport function parseBorderRadius(\n value: TreemapOptions['borderRadius'],\n maxW: number,\n maxH: number\n): TreemapBorderRadius {\n const o = toTRBLCorners(value as Parameters<typeof toTRBLCorners>[0])\n const maxR = Math.min(maxW, maxH)\n\n return {\n bottomLeft: limit(o.bottomLeft, 0, maxR),\n bottomRight: limit(o.bottomRight, 0, maxR),\n topLeft: limit(o.topLeft, 0, maxR),\n topRight: limit(o.topRight, 0, maxR),\n }\n}\n","function getDims(itm: any, w2: number, s2: number, key: string) {\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, h, w }\n}\n\nconst getX = (rect: Rect, w: number) => (rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix)\n\nfunction buildRow(rect: Rect, itm: any, dims: any, sum: number) {\n const r: Record<string, any> = {\n _data: itm._data,\n a: itm._normalized,\n h: dims.h,\n s: sum,\n v: itm.value,\n vs: itm.values,\n w: dims.w,\n x: getX(rect, dims.w),\n y: rect.y + rect._iy,\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 [key: string]: any\n rtl: boolean\n unsorted: boolean\n x: number\n y: number\n _ix: number\n _iy: number\n w: number\n h: number\n\n constructor(r?: any) {\n r = r || { h: 1, w: 1 }\n this.rtl = !!r.rtl\n this.unsorted = !!r.unsorted\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: any) {\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: any[] = []\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: StatArray) {\n return {\n max: sa.max,\n min: sa.min,\n nmax: sa.nmax,\n nmin: sa.nmin,\n nsum: sa.nsum,\n sum: sa.sum,\n }\n}\n\nfunction getNewStat(sa: StatArray, o: any) {\n const v = +o[sa.key]\n const n = v * sa.ratio\n o._normalized = n\n\n return {\n max: max(sa.max, v),\n min: min(sa.min, v),\n nmax: max(sa.nmax, n),\n nmin: min(sa.nmin, n),\n nsum: sa.nsum + n,\n sum: sa.sum + v,\n }\n}\n\nfunction setStat(sa: StatArray, stat: any) {\n Object.assign(sa, stat)\n}\n\nfunction push(sa: StatArray, o: any, stat: any) {\n sa._arr.push(o)\n setStat(sa, stat)\n}\n\nexport default class StatArray {\n key: string\n ratio: number\n _arr: any[] = []\n _hist: any[] = []\n sum = 0\n nsum = 0\n min = Infinity\n max = -Infinity\n nmin = Infinity\n nmax = -Infinity\n\n constructor(key: string, ratio: number) {\n this.key = key\n this.ratio = ratio\n this.reset()\n }\n\n get length() {\n return this._arr.length\n }\n\n reset() {\n this._arr = []\n this._hist = []\n this.sum = 0\n this.nsum = 0\n this.min = Infinity\n this.max = -Infinity\n this.nmin = Infinity\n this.nmax = -Infinity\n }\n\n push(o: any) {\n push(this, o, getNewStat(this, o))\n }\n\n pushIf(o: any, fn: any, ...args: any[]) {\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 { isObject } from 'chart.js/helpers'\n\nconst isOlderPart = (act: string, req: string) =>\n req > act || (act.length > req.length && act.startsWith(req))\n\nexport const getGroupKey = (lvl: unknown) => String(lvl)\n\nconst hasGroupValue = (value: unknown) => value !== undefined && value !== null && value !== ''\n\nfunction scanTreeObject(\n keys: string[],\n treeLeafKey: string,\n obj: Record<string, any>,\n tree: string[] = [],\n lvl = 0,\n result: Record<string, any>[] = []\n) {\n const objIndex = lvl - 1\n if (keys[0] in obj && lvl > 0) {\n const record = tree.reduce<Record<string, any>>((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((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(\n keys: string[],\n treeLeafKey: string,\n obj: Record<string, any>\n) {\n const data = scanTreeObject(keys, treeLeafKey, obj)\n if (!data.length) {\n return data\n }\n const max = data.reduce((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 Math.max(maxVal, ikeys)\n }, 0)\n data.forEach((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: any[]) {\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: string[], value: Record<string, any>, defaultValue: string) {\n const path = []\n for (const grp of groups) {\n const item = value[grp]\n if (!hasGroupValue(item)) {\n continue\n }\n path.push(item)\n }\n return path.length ? path.join('.') : defaultValue\n}\n\nfunction resolveGroup(\n value: Record<string, any>,\n treeLeafKey: string,\n allGroups: string[],\n groupIndex: number\n) {\n for (let idx = groupIndex; idx < allGroups.length; idx++) {\n const groupKey = getGroupKey(allGroups[idx])\n if (hasGroupValue(value[groupKey])) {\n return { group: groupKey, groupIndex: idx, value: value[groupKey] }\n }\n }\n if (hasGroupValue(value[treeLeafKey])) {\n return { group: treeLeafKey, groupIndex, value: value[treeLeafKey] }\n }\n return undefined\n}\n\nfunction ensureGroup(\n tmp: Record<string, any>,\n data: Record<string, any[]>,\n groupValue: string,\n addKeys: string[]\n) {\n if (groupValue in tmp) {\n return\n }\n tmp[groupValue] = { value: 0 }\n const tmpRef = tmp[groupValue]\n addKeys.forEach((k) => {\n tmpRef[k] = 0\n })\n data[groupValue] = []\n}\n\nexport function group(\n values: Record<string, any>[],\n grp: string,\n keys: string[],\n treeLeafKey: string,\n mainGrp?: string,\n mainValue?: any,\n groups: string[] = [],\n allGroups: string[] = groups,\n groupIndex = groups.length - 1\n) {\n const key = keys[0]\n const addKeys = keys.slice(1)\n const tmp: Record<string, any> = Object.create(null)\n const data: Record<string, any[]> = Object.create(null)\n const ret: Record<string, any>[] = []\n const resolvedAllGroups = allGroups.length ? allGroups : [grp]\n const resolvedGroupIndex = allGroups.length ? groupIndex : 0\n let i: number\n let n: number\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 const itemGroup = resolveGroup(v, treeLeafKey, resolvedAllGroups, resolvedGroupIndex)\n if (!itemGroup) {\n return []\n }\n const g = itemGroup.value\n ensureGroup(tmp, data, g, addKeys)\n tmp[g].value += +v[key]\n tmp[g].label = g\n tmp[g].group = itemGroup.group\n tmp[g].groupIndex = itemGroup.groupIndex\n const tmpRef = tmp[g]\n addKeys.forEach((k) => {\n tmpRef[k] += v[k]\n })\n tmp[g].path = getPath(resolvedAllGroups.slice(0, itemGroup.groupIndex + 1), v, g)\n data[g].push(v)\n }\n\n Object.keys(tmp).forEach((k) => {\n const v: Record<string, any> = { children: data[k] }\n v[key] = +tmp[k].value\n addKeys.forEach((ak) => {\n v[ak] = +tmp[k][ak]\n })\n v[grp] = tmp[k].label\n v.group = tmp[k].group\n v.groupIndex = tmp[k].groupIndex\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: any[], key: string) {\n let n = values.length\n let i: number\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] = { _idx: i, v: values[i] }\n }\n }\n return key\n}\n\nexport function sort(values: any[], key?: string) {\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: any[], key?: string) {\n let s: number\n let i: number\n let n: number\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\nexport function requireVersion(pkg: string, min: string, ver: string, 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 (Number.parseInt(req, 10) < Number.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 Rect from './rect'\nimport StatArray from './statArray'\nimport { flatten, index, sort, sum } from './utils'\n\nfunction compareAspectRatio(oldStat: any, newStat: any, args: any[]) {\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\nexport default function squarify(\n values: any[],\n rectangle: any,\n keys: string[] = [],\n grp?: string,\n lvl?: number,\n gsum?: number\n) {\n values = values || []\n const rows: any[] = []\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: number\n let o: any\n\n if (!n) {\n return rows\n }\n\n const tmp = values.slice()\n const key = index(tmp, keys[0])\n\n if (!rectangle?.unsorted) {\n sort(tmp, key)\n }\n\n const val = (idx: number) => (key ? +tmp[idx][key] : +tmp[idx])\n const gval = (idx: number) => grp && tmp[idx][grp]\n\n for (i = 0; i < n; ++i) {\n o = {\n _data: values[tmp[i]._idx],\n group: undefined,\n groupSum: gsum,\n level: undefined,\n value: val(i),\n }\n if (grp) {\n o.level = tmp[i].groupIndex ?? lvl\n o.group = gval(i)\n const tmpRef = tmp[i]\n o.values = keys.reduce<Record<string, number>>((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","import type { Element } from 'chart.js'\nimport type { DrawRect } from './geometry'\nimport type {\n TreemapCaptionsOptions,\n TreemapConfig,\n TreemapDataPoint,\n TreemapDisplayMode,\n TreemapLabelsOptions,\n TreemapOptions,\n TreemapScriptableContext,\n} from './types'\n\nimport { defined, isArray, isNumber, toFont, valueOrDefault } from 'chart.js/helpers'\n\ntype RectSize = {\n h: number\n w: number\n}\n\ntype RectHeight = {\n h: number\n}\n\ntype LabelSize = {\n height: number\n width: number\n}\n\ntype Font = ReturnType<typeof toFont>\n\ntype TextElement = Element<TreemapConfig, TreemapOptions> & {\n $context?: TreemapScriptableContext\n}\n\nconst widthCache = new Map<string, LabelSize>()\n\nexport function shouldDrawCaption(\n displayMode: TreemapDisplayMode,\n rect: RectSize,\n options?: Partial<TreemapCaptionsOptions>\n) {\n if (!options || options.display === false) {\n return false\n }\n if (displayMode === 'headerBoxes') {\n return true\n }\n const { w, h } = rect\n const font = toFont(options.font || {})\n const min = font.lineHeight\n const padding = Math.max(Math.min(valueOrDefault(options.padding, 3) * 2, Math.min(w, h)), 0)\n return w - padding > min && h - padding > min\n}\n\nexport function getCaptionHeight(\n displayMode: TreemapDisplayMode,\n rect: RectHeight,\n font: { lineHeight: number },\n padding: number\n) {\n if (displayMode !== 'headerBoxes') {\n return font.lineHeight + padding * 2\n }\n const captionHeight = font.lineHeight + padding * 2\n return rect.h < 2 * captionHeight ? rect.h / 3 : captionHeight\n}\n\nexport function drawText(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const { captions, labels, displayMode } = 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.isLeaf)\n if (isLeaf && labels.display) {\n drawLabel(ctx, rect, options, item, element)\n } else if (!isLeaf && shouldDrawCaption(displayMode, rect, captions)) {\n drawCaption(ctx, rect, options, item, element)\n }\n ctx.restore()\n}\n\nfunction callbackContext(element: TextElement, item: TreemapDataPoint): TreemapScriptableContext {\n const context =\n element.$context ||\n ({ active: !!element.active, raw: item, type: 'data' } as TreemapScriptableContext)\n context.active = !!element.active\n context.raw = item\n return context\n}\n\nfunction resolveOption<T>(\n option: T | ((context: TreemapScriptableContext) => T) | undefined,\n context: TreemapScriptableContext\n) {\n return typeof option === 'function'\n ? (option as (context: TreemapScriptableContext) => T)(context)\n : option\n}\n\nfunction resolveCaptionText(\n captions: TreemapCaptionsOptions,\n element: TextElement,\n item: TreemapDataPoint\n) {\n return resolveOption(captions.formatter, callbackContext(element, item)) || item.g || ''\n}\n\nfunction drawCaption(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const { captions, spacing, rtl, displayMode } = options\n const { color, hoverColor, font, hoverFont, padding, align } = 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 fonts = [oFont]\n if (oFont.lineHeight > rect.h) {\n return\n }\n let text = resolveCaptionText(captions, element, item)\n if (!text) {\n return\n }\n const captionSize = measureLabelSize(ctx, [text], fonts)\n if (captionSize.width + 2 * padding > rect.w) {\n text = sliceTextToFitWidth(ctx, text, rect.w - 2 * padding, fonts)\n }\n\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 const y = displayMode === 'headerBoxes' ? rect.y + rect.h / 2 : rect.y + padding + spacing + lh\n ctx.fillText(text, x, y)\n}\n\nfunction sliceTextToFitWidth(\n ctx: CanvasRenderingContext2D,\n text: string,\n width: number,\n fonts: Font[]\n) {\n const ellipsis = '...'\n const ellipsisWidth = measureLabelSize(ctx, [ellipsis], fonts).width\n if (ellipsisWidth >= width) {\n return ''\n }\n let lowerBoundLen = 1\n let upperBoundLen = text.length\n let currentWidth: number\n while (lowerBoundLen <= upperBoundLen) {\n const currentLen = Math.floor((lowerBoundLen + upperBoundLen) / 2)\n const currentText = text.slice(0, currentLen)\n currentWidth = measureLabelSize(ctx, [currentText], fonts).width\n if (currentWidth + ellipsisWidth > width) {\n upperBoundLen = currentLen - 1\n } else {\n lowerBoundLen = currentLen + 1\n }\n }\n const slicedText = text.slice(0, Math.max(0, lowerBoundLen - 1))\n return slicedText ? slicedText + ellipsis : ''\n}\n\nfunction measureLabelSize(\n ctx: CanvasRenderingContext2D & { _measureText?: unknown },\n lines: string[],\n fonts: Font[]\n) {\n const fontsKey = fonts.reduce((prev, item) => {\n prev += item.string\n return prev\n }, '')\n const mapKey = lines.join() + fontsKey + (ctx._measureText ? '-spriting' : '')\n let size = widthCache.get(mapKey)\n if (!size) {\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 size = { height, width }\n widthCache.set(mapKey, size)\n }\n return size\n}\n\nfunction toFonts(fonts: Font[], fitRatio: number) {\n return fonts.map((f) => {\n const { lineHeight: _lineHeight, ...font } = f\n return toFont({ ...font, size: Math.floor(f.size * fitRatio) })\n })\n}\n\nfunction labelToDraw(\n _ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapLabelsOptions,\n labelSize: LabelSize\n) {\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: DrawRect, labels: TreemapLabelsOptions) {\n const { font, hoverFont } = labels\n const optFont = (rect.active ? hoverFont : font) || font\n return Array.isArray(optFont) ? optFont.map((f) => toFont(f)) : [toFont(optFont)]\n}\n\nfunction drawLabel(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const labels = options.labels\n const content = resolveOption(labels.formatter, callbackContext(element, item))\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 = { height: labelSize.height * lblToDraw, width: labelSize.width * 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((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\nexport function drawDivider(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint\n) {\n const dividers = options.dividers\n const children = item._data?.children\n if (!dividers.display || !Array.isArray(children) || !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: DrawRect, options: TreemapLabelsOptions, labelSize: LabelSize) {\n const { align, position, padding } = options\n const x = calculateX(rect, align, padding)\n let y: number\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: DrawRect, align: CanvasTextAlign, padding: number) {\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","import { Chart, DatasetController, registry } from 'chart.js'\nimport { clipArea, isObject, toFont, unclipArea, valueOrDefault } from 'chart.js/helpers'\n\nimport { version } from '../package.json'\nimport { arrayNotEqual, rectNotEqual, scaleRect } from './helpers/index'\nimport { parseBorderWidth } from './options'\nimport squarify from './squarify'\nimport { getCaptionHeight, shouldDrawCaption } from './text'\nimport { getGroupKey, group, normalizeTreeToArray, requireVersion } from './utils'\n\nfunction buildData(tree: any, dataset: any, keys: any[], mainRect: any) {\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 = dataset.displayMode === 'headerBoxes' ? 0 : 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 getSubRect(sq: any, rect: any) {\n const bw =\n dataset.displayMode === 'headerBoxes'\n ? { b: 0, l: 0, r: 0, t: 0 }\n : parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2)\n const subRect = {\n ...rect,\n h: sq.h - 2 * sp - bw.t - bw.b,\n w: sq.w - 2 * sp - bw.l - bw.r,\n x: sq.x + sp + bw.l,\n y: sq.y + sp + bw.t,\n }\n if (shouldDrawCaption(dataset.displayMode, subRect, captions)) {\n const captionHeight = getCaptionHeight(dataset.displayMode, subRect, font, padding)\n subRect.y += captionHeight\n subRect.h -= captionHeight\n }\n return subRect\n }\n\n function recur(treeElements: any, gidx: number, rect: any, parent?: any, gs?: any) {\n const g = getGroupKey(groups[gidx])\n const gdata = group(\n treeElements,\n g,\n keys,\n treeLeafKey,\n undefined,\n parent,\n groups.filter((_item: any, index: number) => index <= gidx),\n groups,\n gidx\n )\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 subRect = getSubRect(sq, rect)\n const children: any[] = []\n const nextGroupIndex = sq._data.groupIndex + 1\n if (nextGroupIndex < glen) {\n children.push(...recur(sq._data.children, nextGroupIndex, subRect, sq.g, sq.s))\n }\n ret.push(...children)\n sq.isLeaf = !children.length\n })\n } else {\n gsq.forEach((sq) => {\n sq.isLeaf = true\n })\n }\n return ret\n }\n\n const result = glen ? recur(tree, 0, mainRect) : squarify(tree, mainRect, keys)\n return result\n .map((d) => {\n if (dataset.displayMode !== 'headerBoxes' || d.isLeaf) {\n return d\n }\n if (!shouldDrawCaption(dataset.displayMode, d, captions)) {\n return undefined\n }\n const captionHeight = getCaptionHeight(dataset.displayMode, d, font, padding)\n return { ...d, h: captionHeight }\n })\n .filter(Boolean)\n}\n\nexport default class TreemapController extends DatasetController {\n declare static readonly id: string\n declare static readonly defaults: Record<string, unknown>\n declare static readonly descriptors: Record<string, unknown>\n declare static readonly overrides: Record<string, unknown>\n declare static readonly beforeRegister: () => void\n declare static readonly afterRegister: () => void\n declare static readonly afterUnregister: () => void\n\n options: any\n _groups: any[] | undefined\n _keys: any[] | undefined\n _rect: any\n _rectChanged: boolean\n _prevTree: any\n\n constructor(chart: any, datasetIndex: number) {\n super(chart, datasetIndex)\n\n this._groups = undefined\n this._keys = undefined\n this._rect = undefined\n this._rectChanged = true\n }\n\n override initialize() {\n this.enableOptionSharing = true\n super.initialize()\n }\n\n override getMinMax(scale: any) {\n return {\n max: scale.axis === 'x' ? scale.right - scale.left : scale.bottom - scale.top,\n min: 0,\n }\n }\n\n override configure() {\n super.configure()\n const { xScale, yScale } = this.getMeta() as any\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 = { h, rtl: !!this.options.rtl, unsorted: !!this.options.unsorted, w, x: 0, y: 0 }\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 override update(mode: any) {\n const dataset = this.getDataset() as any\n const { data } = this.getMeta()\n const groups = dataset.groups || []\n const keys = [dataset.key || ''].concat(dataset.sumKeys || [])\n dataset.tree = dataset.tree || dataset.data || []\n const tree = dataset.tree\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 (\n this._rectChanged ||\n arrayNotEqual(this._keys || [], keys) ||\n arrayNotEqual(this._groups || [], groups) ||\n this._prevTree !== tree\n ) {\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-expect-error using private stuff\n this._dataCheck()\n // @ts-expect-error using private stuff\n this._resyncElements()\n }\n\n this.updateElements(data, 0, data.length, mode)\n }\n\n override updateElements(rects: any[], start: number, count: number, mode: any) {\n const reset = mode === 'reset'\n const dataset = this.getDataset() as any\n const firstOpts = this.resolveDataElementOptions(start, mode)\n this._rect.options = firstOpts\n const sharedOptions = this.getSharedOptions(firstOpts)\n const includeOptions = this.includeOptions(mode, sharedOptions || {})\n const { xScale, yScale } = this.getMeta() as any\n\n for (let i = start; i < start + count; i++) {\n const options = sharedOptions || this.resolveDataElementOptions(i, mode)\n const properties: any = 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 override draw() {\n const { ctx, chartArea } = this.chart\n const metadata = ((this.getMeta() as any).data || []) as any[]\n const dataset = this.getDataset() as any\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])\n }\n }\n unclipArea(ctx)\n }\n}\n\n;(TreemapController as any).id = 'treemap'\n\n;(TreemapController as any).version = version\n\n;(TreemapController as any).defaults = {\n animations: {\n numbers: {\n properties: ['x', 'y', 'width', 'height'],\n type: 'number',\n },\n },\n dataElementType: 'treemap',\n}\n\n;(TreemapController as any).descriptors = {\n _indexable: false,\n _scriptable: true,\n captions: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n labels: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n}\n\n;(TreemapController as any).overrides = {\n hover: {},\n interaction: {\n includeInvisible: true,\n intersect: true,\n mode: 'point',\n },\n\n plugins: {\n tooltip: {\n callbacks: {\n label(item: any) {\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 title(items: any[]) {\n if (items.length) {\n const item = items[0]\n return item.dataset.key || ''\n }\n return ''\n },\n },\n intersect: true,\n position: 'treemap',\n },\n },\n scales: {\n x: {\n alignToPixels: true,\n bounds: 'data',\n display: false,\n type: 'linear',\n },\n y: {\n alignToPixels: true,\n bounds: 'data',\n display: false,\n reverse: true,\n type: 'linear',\n },\n },\n}\n\n;(TreemapController as any).beforeRegister = () => {\n requireVersion('chart.js', '3.8', Chart.version)\n}\n\n;(TreemapController as any).afterRegister = () => {\n const tooltipPlugin = registry.plugins.get('tooltip') as any\n if (tooltipPlugin) {\n tooltipPlugin.positioners.treemap = (active: any[]) => {\n if (!active.length) {\n return false\n }\n\n const item = active.at(-1)\n const el = item.element\n\n return el.tooltipPosition()\n }\n } else {\n console.warn(\n 'Unable to register the treemap positioner because tooltip plugin is not registered'\n )\n }\n}\n\n;(TreemapController as any).afterUnregister = () => {\n const tooltipPlugin = registry.plugins.get('tooltip') as any\n if (tooltipPlugin) {\n delete tooltipPlugin.positioners.treemap\n }\n}\n","import type { Element } from 'chart.js'\nimport type { TreemapBorderRadius, TreemapConfig, TreemapOptions } from './types'\n\nimport { parseBorderRadius, parseBorderWidth } from './options'\n\nexport type DrawRect = {\n active?: boolean\n h: number\n radius: TreemapBorderRadius\n w: number\n x: number\n y: number\n}\n\ntype TreemapElementBase = Element<TreemapConfig, TreemapOptions>\n\nfunction getBounds(rect: TreemapElementBase, useFinalPosition?: boolean) {\n const { x, y, width, height } = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition)\n return { bottom: y + height, left: x, right: x + width, top: y }\n}\n\nexport function boundingRects(rect: TreemapElementBase) {\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 active: rect.active,\n h: height,\n radius,\n w: width,\n x: bounds.left,\n y: bounds.top,\n }\n\n return {\n inner: {\n active: rect.active,\n h: outer.h - border.t - border.b,\n radius: {\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 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 },\n w: outer.w - border.l - border.r,\n x: outer.x + border.l,\n y: outer.y + border.t,\n },\n outer,\n }\n}\n\nexport function inRange(\n rect: TreemapElementBase,\n x: number | null,\n y: number | null,\n useFinalPosition?: boolean\n) {\n const skipX = x === null\n const skipY = y === null\n const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition)\n\n return (\n bounds &&\n (skipX || (x >= bounds.left && x <= bounds.right)) &&\n (skipY || (y >= bounds.top && y <= bounds.bottom))\n )\n}\n\nexport function hasRadius(radius: TreemapBorderRadius) {\n return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight\n}\n\nexport function addNormalRectPath(ctx: CanvasRenderingContext2D, rect: DrawRect) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h)\n}\n","import type {\n TreemapConfig,\n TreemapDataPoint,\n TreemapOptions,\n TreemapScriptableContext,\n} from './types'\n\nimport { Element } from 'chart.js'\nimport { addRoundedRectPath } from 'chart.js/helpers'\n\nimport { addNormalRectPath, boundingRects, hasRadius, inRange } from './geometry'\nimport { drawDivider, drawText } from './text'\n\nexport default class TreemapElement extends Element<TreemapConfig, TreemapOptions> {\n static readonly id = 'treemap'\n\n static override readonly defaults = {\n borderRadius: 0,\n borderWidth: 0,\n captions: {\n align: undefined,\n color: 'black',\n display: true,\n font: {},\n formatter: (ctx: TreemapScriptableContext) => {\n const label = ctx.raw._data?.label\n return ctx.raw.g || (typeof label === 'string' ? label : '')\n },\n padding: 3,\n },\n displayMode: 'containerBoxes',\n dividers: {\n display: false,\n lineCapStyle: 'butt',\n lineColor: 'black',\n lineDash: [],\n lineDashOffset: 0,\n lineWidth: 1,\n },\n label: undefined,\n labels: {\n align: 'center',\n color: 'black',\n display: false,\n font: {},\n formatter(ctx: TreemapScriptableContext) {\n const label = ctx.raw._data?.label\n if (ctx.raw.g) {\n return [ctx.raw.g, `${ctx.raw.v}`]\n }\n return typeof label === 'string' ? [label, `${ctx.raw.v}`] : `${ctx.raw.v}`\n },\n overflow: 'cut',\n padding: 3,\n position: 'middle',\n },\n rtl: false,\n spacing: 0.5,\n unsorted: false,\n }\n\n static readonly descriptors = {\n _indexable: false,\n _scriptable: true,\n captions: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n labels: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n }\n\n static override readonly defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor',\n }\n\n $context?: TreemapScriptableContext\n width: number | undefined\n height: number | undefined\n\n constructor(cfg?: Partial<TreemapConfig> & { options?: TreemapOptions }) {\n super()\n\n this.width = undefined\n this.height = undefined\n\n if (cfg) {\n Object.assign(this, cfg)\n }\n }\n\n draw(ctx: CanvasRenderingContext2D, data?: TreemapDataPoint) {\n if (!data) {\n return\n }\n const options = this.options\n const { inner, outer } = boundingRects(this)\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, this)\n ctx.restore()\n }\n\n inRange(mouseX: number, mouseY: number, useFinalPosition?: boolean) {\n return inRange(this, mouseX, mouseY, useFinalPosition)\n }\n\n inXRange(mouseX: number, useFinalPosition?: boolean) {\n return inRange(this, mouseX, null, useFinalPosition)\n }\n\n inYRange(mouseY: number, useFinalPosition?: boolean) {\n return inRange(this, null, mouseY, useFinalPosition)\n }\n\n getCenterPoint(useFinalPosition?: boolean) {\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 override tooltipPosition() {\n return this.getCenterPoint()\n }\n}\n","import { Chart } from 'chart.js'\n\nimport TreemapController from './controller'\nimport TreemapElement from './element'\n\nChart.register(TreemapController as any, TreemapElement as any)\n\nexport type {\n LabelAlign,\n LabelOverflow,\n LabelPosition,\n TreemapConfig,\n TreemapControllerDatasetOptions,\n TreemapDataPoint,\n TreemapElement as TreemapElementType,\n TreemapOptions,\n} from './types'\n\nexport * from './utils'\nexport { TreemapController, TreemapElement }\n"],"names":["scaleRect","sq","xScale","yScale","sp","sp2","x","getPixelForValue","y","w","h","height","hidden","width","arrayNotEqual","a","b","i","n","length","limit","value","min","max","Math","parseBorderWidth","maxW","maxH","o","toTRBL","bottom","l","left","r","right","t","top","getDims","itm","w2","s2","key","_normalized","ar","d1","sqrt","d2","getX","rect","rtl","iw","_ix","buildRow","dims","sum","_data","s","v","vs","values","_iy","group","g","level","gs","groupSum","Rect","area","this","ih","dir","side","map","arr","nsum","row","get","ret","maxd2","totd1","push","constructor","unsorted","getNewStat","sa","ratio","nmax","nmin","stat","_arr","Object","assign","setStat","StatArray","reset","_hist","Infinity","pushIf","fn","args","nstat","isOlderPart","act","req","startsWith","getGroupKey","lvl","String","hasGroupValue","scanTreeObject","keys","treeLeafKey","obj","tree","result","objIndex","record","reduce","reduced","item","forEach","k","childKey","child","isObject","splice","normalizeTreeToArray","data","maxVal","element","ikeys","groupKey","flatten","input","stack","res","next","pop","Array","isArray","reverse","getPath","groups","defaultValue","path","grp","join","resolveGroup","allGroups","groupIndex","idx","ensureGroup","tmp","groupValue","addKeys","tmpRef","mainGrp","mainValue","slice","create","resolvedAllGroups","resolvedGroupIndex","itemGroup","label","children","ak","index","_idx","sort","requireVersion","pkg","ver","strict","parts","split","Number","parseInt","Error","compareAspectRatio","oldStat","newStat","os2","ns2","l2","or","squarify","rectangle","gsum","rows","val","gval","undefined","widthCache","Map","shouldDrawCaption","displayMode","options","display","toFont","font","lineHeight","padding","valueOrDefault","getCaptionHeight","captionHeight","drawText","ctx","captions","labels","save","beginPath","clip","isLeaf","defined","content","resolveOption","formatter","callbackContext","contents","fonts","hoverFont","optFont","active","f","getFontFromOptions","labelSize","measureLabelSize","lblToDraw","_ctx","overflow","labelToDraw","isNumber","fitRatio","_lineHeight","size","floor","toFonts","color","hoverColor","align","optColor","colors","xyPoint","position","calculateX","calculateXYLabel","textAlign","textBaseline","lhs","c","lh","string","fillStyle","fillText","drawLabel","spacing","oColor","oAlign","oFont","text","resolveCaptionText","captionSize","ellipsis","ellipsisWidth","currentWidth","lowerBoundLen","upperBoundLen","currentLen","slicedText","sliceTextToFitWidth","drawCaption","restore","context","$context","raw","type","option","lines","fontsKey","prev","mapKey","_measureText","count","measureText","set","buildData","dataset","mainRect","glen","recur","treeElements","gidx","parent","gdata","filter","_item","gsq","subRect","bw","borderWidth","getSubRect","nextGroupIndex","d","Boolean","TreemapController","DatasetController","initialize","enableOptionSharing","super","getMinMax","scale","axis","configure","getMeta","r1","r2","_rect","_rectChanged","update","mode","getDataset","concat","sumKeys","_keys","_groups","_prevTree","_dataCheck","_resyncElements","updateElements","rects","start","firstOpts","resolveDataElementOptions","sharedOptions","getSharedOptions","includeOptions","properties","updateElement","updateSharedOptions","draw","chartArea","chart","metadata","clipArea","ilen","unclipArea","datasetIndex","getBounds","useFinalPosition","getProps","boundingRects","bounds","border","radius","toTRBLCorners","maxR","bottomLeft","bottomRight","topLeft","topRight","parseBorderRadius","borderRadius","outer","inner","inRange","skipX","skipY","addNormalRectPath","id","version","defaults","animations","numbers","dataElementType","descriptors","_indexable","_scriptable","_fallback","name","overrides","hover","interaction","includeInvisible","intersect","plugins","tooltip","callbacks","dataItem","dataIndex","title","items","scales","alignToPixels","beforeRegister","Chart","afterRegister","tooltipPlugin","registry","positioners","treemap","at","tooltipPosition","console","warn","afterUnregister","TreemapElement","Element","addRectPath","addRoundedRectPath","borderColor","fill","backgroundColor","dividers","lineColor","lineCapStyle","lineDash","lineDashOffset","lineWidth","strokeStyle","lineCap","setLineDash","moveTo","lineTo","h2","stroke","drawDivider","mouseX","mouseY","inXRange","inYRange","getCenterPoint","cfg","defaultRoutes","register"],"mappings":"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"}
1
+ {"version":3,"file":"chartjs-chart-treemap.min.js","sources":["../src/helpers/index.ts","../src/options.ts","../src/rect.ts","../src/statArray.ts","../src/utils.ts","../src/squarify.ts","../src/text.ts","../src/controller.ts","../src/geometry.ts","../src/element.ts","../src/index.ts"],"sourcesContent":["export function scaleRect(sq: any, xScale: any, yScale: any, sp: number) {\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 height: h - sp2,\n hidden: sp2 > w || sp2 > h,\n width: w - sp2,\n x: x + sp,\n y: y + sp,\n }\n}\n\nexport function rectNotEqual(r1: any, r2: any) {\n return (\n !r1 ||\n !r2 ||\n r1.x !== r2.x ||\n r1.y !== r2.y ||\n r1.w !== r2.w ||\n r1.h !== r2.h ||\n r1.rtl !== r2.rtl ||\n r1.unsorted !== r2.unsorted\n )\n}\n\nexport function arrayNotEqual(a: any[], b: any[]) {\n let i: number\n let n: number\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 type { TreemapBorderRadius, TreemapBorderWidth, TreemapOptions } from './types'\n\nimport { toTRBL, toTRBLCorners } from 'chart.js/helpers'\n\nexport type ParsedBorderWidth = {\n b: number\n l: number\n r: number\n t: number\n}\n\nfunction limit(value: number, min: number, max: number) {\n return Math.max(Math.min(value, max), min)\n}\n\nexport function parseBorderWidth(\n value: TreemapBorderWidth,\n maxW: number,\n maxH: number\n): ParsedBorderWidth {\n const o = toTRBL(value as Parameters<typeof toTRBL>[0])\n\n return {\n b: limit(o.bottom, 0, maxH),\n l: limit(o.left, 0, maxW),\n r: limit(o.right, 0, maxW),\n t: limit(o.top, 0, maxH),\n }\n}\n\nexport function parseBorderRadius(\n value: TreemapOptions['borderRadius'],\n maxW: number,\n maxH: number\n): TreemapBorderRadius {\n const o = toTRBLCorners(value as Parameters<typeof toTRBLCorners>[0])\n const maxR = Math.min(maxW, maxH)\n\n return {\n bottomLeft: limit(o.bottomLeft, 0, maxR),\n bottomRight: limit(o.bottomRight, 0, maxR),\n topLeft: limit(o.topLeft, 0, maxR),\n topRight: limit(o.topRight, 0, maxR),\n }\n}\n","function getDims(itm: any, w2: number, s2: number, key: string) {\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, h, w }\n}\n\nconst getX = (rect: Rect, w: number) => (rect.rtl ? rect.x + rect.iw - w : rect.x + rect._ix)\n\nfunction buildRow(rect: Rect, itm: any, dims: any, sum: number) {\n const r: Record<string, any> = {\n _data: itm._data,\n a: itm._normalized,\n h: dims.h,\n s: sum,\n v: itm.value,\n vs: itm.values,\n w: dims.w,\n x: getX(rect, dims.w),\n y: rect.y + rect._iy,\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 [key: string]: any\n rtl: boolean\n unsorted: boolean\n x: number\n y: number\n _ix: number\n _iy: number\n w: number\n h: number\n\n constructor(r?: any) {\n r = r || { h: 1, w: 1 }\n this.rtl = !!r.rtl\n this.unsorted = !!r.unsorted\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: any) {\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: any[] = []\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: StatArray) {\n return {\n max: sa.max,\n min: sa.min,\n nmax: sa.nmax,\n nmin: sa.nmin,\n nsum: sa.nsum,\n sum: sa.sum,\n }\n}\n\nfunction getNewStat(sa: StatArray, o: any) {\n const v = +o[sa.key]\n const n = v * sa.ratio\n o._normalized = n\n\n return {\n max: max(sa.max, v),\n min: min(sa.min, v),\n nmax: max(sa.nmax, n),\n nmin: min(sa.nmin, n),\n nsum: sa.nsum + n,\n sum: sa.sum + v,\n }\n}\n\nfunction setStat(sa: StatArray, stat: any) {\n Object.assign(sa, stat)\n}\n\nfunction push(sa: StatArray, o: any, stat: any) {\n sa._arr.push(o)\n setStat(sa, stat)\n}\n\nexport default class StatArray {\n key: string\n ratio: number\n _arr: any[] = []\n _hist: any[] = []\n sum = 0\n nsum = 0\n min = Infinity\n max = -Infinity\n nmin = Infinity\n nmax = -Infinity\n\n constructor(key: string, ratio: number) {\n this.key = key\n this.ratio = ratio\n this.reset()\n }\n\n get length() {\n return this._arr.length\n }\n\n reset() {\n this._arr = []\n this._hist = []\n this.sum = 0\n this.nsum = 0\n this.min = Infinity\n this.max = -Infinity\n this.nmin = Infinity\n this.nmax = -Infinity\n }\n\n push(o: any) {\n push(this, o, getNewStat(this, o))\n }\n\n pushIf(o: any, fn: any, ...args: any[]) {\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 { isObject } from 'chart.js/helpers'\n\nconst isOlderPart = (act: string, req: string) =>\n req > act || (act.length > req.length && act.startsWith(req))\n\nexport const getGroupKey = (lvl: unknown) => String(lvl)\n\nconst hasGroupValue = (value: unknown) => value !== undefined && value !== null && value !== ''\n\nfunction scanTreeObject(\n keys: string[],\n treeLeafKey: string,\n obj: Record<string, any>,\n tree: string[] = [],\n lvl = 0,\n result: Record<string, any>[] = []\n) {\n const objIndex = lvl - 1\n if (keys[0] in obj && lvl > 0) {\n const record = tree.reduce<Record<string, any>>((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((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(\n keys: string[],\n treeLeafKey: string,\n obj: Record<string, any>\n) {\n const data = scanTreeObject(keys, treeLeafKey, obj)\n if (!data.length) {\n return data\n }\n const max = data.reduce((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 Math.max(maxVal, ikeys)\n }, 0)\n data.forEach((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: any[]) {\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: string[], value: Record<string, any>, defaultValue: string) {\n const path = []\n for (const grp of groups) {\n const item = value[grp]\n if (!hasGroupValue(item)) {\n continue\n }\n path.push(item)\n }\n return path.length ? path.join('.') : defaultValue\n}\n\nfunction resolveGroup(\n value: Record<string, any>,\n treeLeafKey: string,\n allGroups: string[],\n groupIndex: number\n) {\n for (let idx = groupIndex; idx < allGroups.length; idx++) {\n const groupKey = getGroupKey(allGroups[idx])\n if (hasGroupValue(value[groupKey])) {\n return { group: groupKey, groupIndex: idx, value: value[groupKey] }\n }\n }\n if (hasGroupValue(value[treeLeafKey])) {\n return { group: treeLeafKey, groupIndex, value: value[treeLeafKey] }\n }\n return undefined\n}\n\nfunction ensureGroup(\n tmp: Record<string, any>,\n data: Record<string, any[]>,\n groupValue: string,\n addKeys: string[]\n) {\n if (groupValue in tmp) {\n return\n }\n tmp[groupValue] = { value: 0 }\n const tmpRef = tmp[groupValue]\n addKeys.forEach((k) => {\n tmpRef[k] = 0\n })\n data[groupValue] = []\n}\n\nexport function group(\n values: Record<string, any>[],\n grp: string,\n keys: string[],\n treeLeafKey: string,\n mainGrp?: string,\n mainValue?: any,\n groups: string[] = [],\n allGroups: string[] = groups,\n groupIndex = groups.length - 1\n) {\n const key = keys[0]\n const addKeys = keys.slice(1)\n const tmp: Record<string, any> = Object.create(null)\n const data: Record<string, any[]> = Object.create(null)\n const ret: Record<string, any>[] = []\n const resolvedAllGroups = allGroups.length ? allGroups : [grp]\n const resolvedGroupIndex = allGroups.length ? groupIndex : 0\n let i: number\n let n: number\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 const itemGroup = resolveGroup(v, treeLeafKey, resolvedAllGroups, resolvedGroupIndex)\n if (!itemGroup) {\n return []\n }\n const g = itemGroup.value\n ensureGroup(tmp, data, g, addKeys)\n tmp[g].value += +v[key]\n tmp[g].label = g\n tmp[g].group = itemGroup.group\n tmp[g].groupIndex = itemGroup.groupIndex\n const tmpRef = tmp[g]\n addKeys.forEach((k) => {\n tmpRef[k] += v[k]\n })\n tmp[g].path = getPath(resolvedAllGroups.slice(0, itemGroup.groupIndex + 1), v, g)\n data[g].push(v)\n }\n\n Object.keys(tmp).forEach((k) => {\n const v: Record<string, any> = { children: data[k] }\n v[key] = +tmp[k].value\n addKeys.forEach((ak) => {\n v[ak] = +tmp[k][ak]\n })\n v[grp] = tmp[k].label\n v.group = tmp[k].group\n v.groupIndex = tmp[k].groupIndex\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: any[], key: string) {\n let n = values.length\n let i: number\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] = { _idx: i, v: values[i] }\n }\n }\n return key\n}\n\nexport function sort(values: any[], key?: string) {\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: any[], key?: string) {\n let s: number\n let i: number\n let n: number\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\nexport function requireVersion(pkg: string, min: string, ver: string, 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 (Number.parseInt(req, 10) < Number.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 Rect from './rect'\nimport StatArray from './statArray'\nimport { flatten, index, sort, sum } from './utils'\n\nfunction compareAspectRatio(oldStat: any, newStat: any, args: any[]) {\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\nexport default function squarify(\n values: any[],\n rectangle: any,\n keys: string[] = [],\n grp?: string,\n lvl?: number,\n gsum?: number\n) {\n values = values || []\n const rows: any[] = []\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: number\n let o: any\n\n if (!n) {\n return rows\n }\n\n const tmp = values.slice()\n const key = index(tmp, keys[0])\n\n if (!rectangle?.unsorted) {\n sort(tmp, key)\n }\n\n const val = (idx: number) => (key ? +tmp[idx][key] : +tmp[idx])\n const gval = (idx: number) => grp && tmp[idx][grp]\n\n for (i = 0; i < n; ++i) {\n o = {\n _data: values[tmp[i]._idx],\n group: undefined,\n groupSum: gsum,\n level: undefined,\n value: val(i),\n }\n if (grp) {\n o.level = tmp[i].groupIndex ?? lvl\n o.group = gval(i)\n const tmpRef = tmp[i]\n o.values = keys.reduce<Record<string, number>>((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","import type { Element } from 'chart.js'\nimport type { DrawRect } from './geometry'\nimport type {\n TreemapCaptionsOptions,\n TreemapConfig,\n TreemapDataPoint,\n TreemapDisplayMode,\n TreemapLabelsOptions,\n TreemapOptions,\n TreemapScriptableContext,\n} from './types'\n\nimport { defined, isArray, isNumber, toFont, valueOrDefault } from 'chart.js/helpers'\n\ntype RectSize = {\n h: number\n w: number\n}\n\ntype RectHeight = {\n h: number\n}\n\ntype LabelSize = {\n height: number\n width: number\n}\n\ntype Font = ReturnType<typeof toFont>\n\ntype TextElement = Element<TreemapConfig, TreemapOptions> & {\n $context?: TreemapScriptableContext\n}\n\nconst widthCache = new Map<string, LabelSize>()\n\nexport function shouldDrawCaption(\n displayMode: TreemapDisplayMode,\n rect: RectSize,\n options?: Partial<TreemapCaptionsOptions>\n) {\n if (!options || options.display === false) {\n return false\n }\n if (displayMode === 'headerBoxes') {\n return true\n }\n const { w, h } = rect\n const font = toFont(options.font || {})\n const min = font.lineHeight\n const padding = Math.max(Math.min(valueOrDefault(options.padding, 3) * 2, Math.min(w, h)), 0)\n return w - padding > min && h - padding > min\n}\n\nexport function getCaptionHeight(\n displayMode: TreemapDisplayMode,\n rect: RectHeight,\n font: { lineHeight: number },\n padding: number\n) {\n if (displayMode !== 'headerBoxes') {\n return font.lineHeight + padding * 2\n }\n const captionHeight = font.lineHeight + padding * 2\n return rect.h < 2 * captionHeight ? rect.h / 3 : captionHeight\n}\n\nexport function drawText(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const { captions, labels, displayMode } = 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.isLeaf)\n if (isLeaf && labels.display) {\n drawLabel(ctx, rect, options, item, element)\n } else if (!isLeaf && shouldDrawCaption(displayMode, rect, captions)) {\n drawCaption(ctx, rect, options, item, element)\n }\n ctx.restore()\n}\n\nfunction callbackContext(element: TextElement, item: TreemapDataPoint): TreemapScriptableContext {\n const context =\n element.$context ||\n ({ active: !!element.active, raw: item, type: 'data' } as TreemapScriptableContext)\n context.active = !!element.active\n context.raw = item\n return context\n}\n\nfunction resolveOption<T>(\n option: T | ((context: TreemapScriptableContext) => T) | undefined,\n context: TreemapScriptableContext\n) {\n return typeof option === 'function'\n ? (option as (context: TreemapScriptableContext) => T)(context)\n : option\n}\n\nfunction resolveCaptionText(\n captions: TreemapCaptionsOptions,\n element: TextElement,\n item: TreemapDataPoint\n) {\n return resolveOption(captions.formatter, callbackContext(element, item)) || item.g || ''\n}\n\nfunction drawCaption(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const { captions, spacing, rtl, displayMode } = options\n const { color, hoverColor, font, hoverFont, padding, align } = 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 fonts = [oFont]\n if (oFont.lineHeight > rect.h) {\n return\n }\n let text = resolveCaptionText(captions, element, item)\n if (!text) {\n return\n }\n const captionSize = measureLabelSize(ctx, [text], fonts)\n if (captionSize.width + 2 * padding > rect.w) {\n text = sliceTextToFitWidth(ctx, text, rect.w - 2 * padding, fonts)\n }\n\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 const y = displayMode === 'headerBoxes' ? rect.y + rect.h / 2 : rect.y + padding + spacing + lh\n ctx.fillText(text, x, y)\n}\n\nfunction sliceTextToFitWidth(\n ctx: CanvasRenderingContext2D,\n text: string,\n width: number,\n fonts: Font[]\n) {\n const ellipsis = '...'\n const ellipsisWidth = measureLabelSize(ctx, [ellipsis], fonts).width\n if (ellipsisWidth >= width) {\n return ''\n }\n let lowerBoundLen = 1\n let upperBoundLen = text.length\n let currentWidth: number\n while (lowerBoundLen <= upperBoundLen) {\n const currentLen = Math.floor((lowerBoundLen + upperBoundLen) / 2)\n const currentText = text.slice(0, currentLen)\n currentWidth = measureLabelSize(ctx, [currentText], fonts).width\n if (currentWidth + ellipsisWidth > width) {\n upperBoundLen = currentLen - 1\n } else {\n lowerBoundLen = currentLen + 1\n }\n }\n const slicedText = text.slice(0, Math.max(0, lowerBoundLen - 1))\n return slicedText ? slicedText + ellipsis : ''\n}\n\nfunction measureLabelSize(\n ctx: CanvasRenderingContext2D & { _measureText?: unknown },\n lines: string[],\n fonts: Font[]\n) {\n const fontsKey = fonts.reduce((prev, item) => {\n prev += item.string\n return prev\n }, '')\n const mapKey = lines.join() + fontsKey + (ctx._measureText ? '-spriting' : '')\n let size = widthCache.get(mapKey)\n if (!size) {\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 size = { height, width }\n widthCache.set(mapKey, size)\n }\n return size\n}\n\nfunction toFonts(fonts: Font[], fitRatio: number) {\n return fonts.map((f) => {\n const { lineHeight: _lineHeight, ...font } = f\n return toFont({ ...font, size: Math.floor(f.size * fitRatio) })\n })\n}\n\nfunction labelToDraw(\n _ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapLabelsOptions,\n labelSize: LabelSize\n) {\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: DrawRect, labels: TreemapLabelsOptions) {\n const { font, hoverFont } = labels\n const optFont = (rect.active ? hoverFont : font) || font\n return Array.isArray(optFont) ? optFont.map((f) => toFont(f)) : [toFont(optFont)]\n}\n\nfunction drawLabel(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint,\n element: TextElement\n) {\n const labels = options.labels\n const content = resolveOption(labels.formatter, callbackContext(element, item))\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 = { height: labelSize.height * lblToDraw, width: labelSize.width * 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((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\nexport function drawDivider(\n ctx: CanvasRenderingContext2D,\n rect: DrawRect,\n options: TreemapOptions,\n item: TreemapDataPoint\n) {\n const dividers = options.dividers\n const children = item._data?.children\n if (!dividers.display || !Array.isArray(children) || !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: DrawRect, options: TreemapLabelsOptions, labelSize: LabelSize) {\n const { align, position, padding } = options\n const x = calculateX(rect, align, padding)\n let y: number\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: DrawRect, align: CanvasTextAlign, padding: number) {\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","import { Chart, DatasetController, registry } from 'chart.js'\nimport { clipArea, isObject, toFont, unclipArea, valueOrDefault } from 'chart.js/helpers'\n\nimport { version } from '../package.json'\nimport { arrayNotEqual, rectNotEqual, scaleRect } from './helpers/index'\nimport { parseBorderWidth } from './options'\nimport squarify from './squarify'\nimport { getCaptionHeight, shouldDrawCaption } from './text'\nimport { getGroupKey, group, normalizeTreeToArray, requireVersion } from './utils'\n\nfunction buildData(tree: any, dataset: any, keys: any[], mainRect: any) {\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 = dataset.displayMode === 'headerBoxes' ? 0 : 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 getSubRect(sq: any, rect: any) {\n const bw =\n dataset.displayMode === 'headerBoxes'\n ? { b: 0, l: 0, r: 0, t: 0 }\n : parseBorderWidth(dataset.borderWidth, sq.w / 2, sq.h / 2)\n const subRect = {\n ...rect,\n h: sq.h - 2 * sp - bw.t - bw.b,\n w: sq.w - 2 * sp - bw.l - bw.r,\n x: sq.x + sp + bw.l,\n y: sq.y + sp + bw.t,\n }\n if (shouldDrawCaption(dataset.displayMode, subRect, captions)) {\n const captionHeight = getCaptionHeight(dataset.displayMode, subRect, font, padding)\n subRect.y += captionHeight\n subRect.h -= captionHeight\n }\n return subRect\n }\n\n function recur(treeElements: any, gidx: number, rect: any, parent?: any, gs?: any) {\n const g = getGroupKey(groups[gidx])\n const gdata = group(\n treeElements,\n g,\n keys,\n treeLeafKey,\n undefined,\n parent,\n groups.filter((_item: any, index: number) => index <= gidx),\n groups,\n gidx\n )\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 subRect = getSubRect(sq, rect)\n const children: any[] = []\n const nextGroupIndex = sq._data.groupIndex + 1\n if (nextGroupIndex < glen) {\n children.push(...recur(sq._data.children, nextGroupIndex, subRect, sq.g, sq.s))\n }\n ret.push(...children)\n sq.isLeaf = !children.length\n })\n } else {\n gsq.forEach((sq) => {\n sq.isLeaf = true\n })\n }\n return ret\n }\n\n const result = glen ? recur(tree, 0, mainRect) : squarify(tree, mainRect, keys)\n return result\n .map((d) => {\n if (dataset.displayMode !== 'headerBoxes' || d.isLeaf) {\n return d\n }\n if (!shouldDrawCaption(dataset.displayMode, d, captions)) {\n return undefined\n }\n const captionHeight = getCaptionHeight(dataset.displayMode, d, font, padding)\n return { ...d, h: captionHeight }\n })\n .filter(Boolean)\n}\n\nfunction registerTooltipPositioner() {\n const tooltipPlugin = registry.plugins.get('tooltip') as any\n if (!tooltipPlugin || tooltipPlugin.positioners.treemap) {\n return\n }\n tooltipPlugin.positioners.treemap = (active: any[]) => {\n if (!active.length) {\n return false\n }\n\n const item = active.at(-1)\n return item.element.tooltipPosition()\n }\n}\n\nexport default class TreemapController extends DatasetController {\n declare static readonly id: string\n declare static readonly defaults: Record<string, unknown>\n declare static readonly descriptors: Record<string, unknown>\n declare static readonly overrides: Record<string, unknown>\n declare static readonly beforeRegister: () => void\n declare static readonly afterRegister: () => void\n declare static readonly afterUnregister: () => void\n\n options: any\n _groups: any[] | undefined\n _keys: any[] | undefined\n _rect: any\n _rectChanged: boolean\n _prevTree: any\n _prevTreeVersion: unknown\n\n constructor(chart: any, datasetIndex: number) {\n super(chart, datasetIndex)\n\n this._groups = undefined\n this._keys = undefined\n this._rect = undefined\n this._rectChanged = true\n }\n\n override initialize() {\n // The tooltip can be registered after the treemap controller. At chart creation time all\n // components are available, so retry here to make registration order irrelevant.\n registerTooltipPositioner()\n this.enableOptionSharing = true\n super.initialize()\n }\n\n override getMinMax(scale: any) {\n return {\n max: scale.axis === 'x' ? scale.right - scale.left : scale.bottom - scale.top,\n min: 0,\n }\n }\n\n override configure() {\n super.configure()\n const { xScale, yScale } = this.getMeta() as any\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 = { h, rtl: !!this.options.rtl, unsorted: !!this.options.unsorted, w, x: 0, y: 0 }\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 override update(mode: any) {\n const dataset = this.getDataset() as any\n const { data } = this.getMeta()\n const groups = dataset.groups || []\n const keys = [dataset.key || ''].concat(dataset.sumKeys || [])\n dataset.tree = dataset.tree || dataset.data || []\n const tree = dataset.tree\n const treeVersion = dataset.treeVersion\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 (\n this._rectChanged ||\n arrayNotEqual(this._keys || [], keys) ||\n arrayNotEqual(this._groups || [], groups) ||\n this._prevTree !== tree ||\n this._prevTreeVersion !== treeVersion\n ) {\n this._groups = groups.slice()\n this._keys = keys.slice()\n this._prevTree = tree\n this._prevTreeVersion = treeVersion\n this._rectChanged = false\n\n dataset.data = buildData(tree, dataset, this._keys, this._rect)\n // @ts-expect-error using private stuff\n this._dataCheck()\n // @ts-expect-error using private stuff\n this._resyncElements()\n }\n\n this.updateElements(data, 0, data.length, mode)\n }\n\n override updateElements(rects: any[], start: number, count: number, mode: any) {\n const reset = mode === 'reset'\n const dataset = this.getDataset() as any\n const firstOpts = this.resolveDataElementOptions(start, mode)\n this._rect.options = firstOpts\n const sharedOptions = this.getSharedOptions(firstOpts)\n const includeOptions = this.includeOptions(mode, sharedOptions || {})\n const { xScale, yScale } = this.getMeta() as any\n\n for (let i = start; i < start + count; i++) {\n const options = sharedOptions || this.resolveDataElementOptions(i, mode)\n const properties: any = 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 override draw() {\n const { ctx, chartArea } = this.chart\n const metadata = ((this.getMeta() as any).data || []) as any[]\n const dataset = this.getDataset() as any\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])\n }\n }\n unclipArea(ctx)\n }\n}\n\n;(TreemapController as any).id = 'treemap'\n\n;(TreemapController as any).version = version\n\n;(TreemapController as any).defaults = {\n animations: {\n numbers: {\n properties: ['x', 'y', 'width', 'height'],\n type: 'number',\n },\n },\n dataElementType: 'treemap',\n}\n\n;(TreemapController as any).descriptors = {\n _indexable: false,\n _scriptable: true,\n captions: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n labels: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n}\n\n;(TreemapController as any).overrides = {\n hover: {},\n interaction: {\n includeInvisible: true,\n intersect: true,\n mode: 'point',\n },\n\n plugins: {\n tooltip: {\n callbacks: {\n label(item: any) {\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 title(items: any[]) {\n if (items.length) {\n const item = items[0]\n return item.dataset.key || ''\n }\n return ''\n },\n },\n intersect: true,\n position: 'treemap',\n },\n },\n scales: {\n x: {\n alignToPixels: true,\n bounds: 'data',\n display: false,\n type: 'linear',\n },\n y: {\n alignToPixels: true,\n bounds: 'data',\n display: false,\n reverse: true,\n type: 'linear',\n },\n },\n}\n\n;(TreemapController as any).beforeRegister = () => {\n requireVersion('chart.js', '3.8', Chart.version)\n}\n\n;(TreemapController as any).afterRegister = () => {\n registerTooltipPositioner()\n}\n\n;(TreemapController as any).afterUnregister = () => {\n const tooltipPlugin = registry.plugins.get('tooltip') as any\n if (tooltipPlugin) {\n delete tooltipPlugin.positioners.treemap\n }\n}\n","import type { Element } from 'chart.js'\nimport type { TreemapBorderRadius, TreemapConfig, TreemapOptions } from './types'\n\nimport { parseBorderRadius, parseBorderWidth } from './options'\n\nexport type DrawRect = {\n active?: boolean\n h: number\n radius: TreemapBorderRadius\n w: number\n x: number\n y: number\n}\n\ntype TreemapElementBase = Element<TreemapConfig, TreemapOptions>\n\nfunction getBounds(rect: TreemapElementBase, useFinalPosition?: boolean) {\n const { x, y, width, height } = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition)\n return { bottom: y + height, left: x, right: x + width, top: y }\n}\n\nexport function boundingRects(rect: TreemapElementBase) {\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 active: rect.active,\n h: height,\n radius,\n w: width,\n x: bounds.left,\n y: bounds.top,\n }\n\n return {\n inner: {\n active: rect.active,\n h: outer.h - border.t - border.b,\n radius: {\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 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 },\n w: outer.w - border.l - border.r,\n x: outer.x + border.l,\n y: outer.y + border.t,\n },\n outer,\n }\n}\n\nexport function inRange(\n rect: TreemapElementBase,\n x: number | null,\n y: number | null,\n useFinalPosition?: boolean\n) {\n const skipX = x === null\n const skipY = y === null\n const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition)\n\n return (\n bounds &&\n (skipX || (x >= bounds.left && x <= bounds.right)) &&\n (skipY || (y >= bounds.top && y <= bounds.bottom))\n )\n}\n\nexport function hasRadius(radius: TreemapBorderRadius) {\n return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight\n}\n\nexport function addNormalRectPath(ctx: CanvasRenderingContext2D, rect: DrawRect) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h)\n}\n","import type {\n TreemapConfig,\n TreemapDataPoint,\n TreemapOptions,\n TreemapScriptableContext,\n} from './types'\n\nimport { Element } from 'chart.js'\nimport { addRoundedRectPath } from 'chart.js/helpers'\n\nimport { addNormalRectPath, boundingRects, hasRadius, inRange } from './geometry'\nimport { drawDivider, drawText } from './text'\n\nexport default class TreemapElement extends Element<TreemapConfig, TreemapOptions> {\n static readonly id = 'treemap'\n\n static override readonly defaults = {\n borderRadius: 0,\n borderWidth: 0,\n captions: {\n align: undefined,\n color: 'black',\n display: true,\n font: {},\n formatter: (ctx: TreemapScriptableContext) => {\n const label = ctx.raw._data?.label\n return ctx.raw.g || (typeof label === 'string' ? label : '')\n },\n padding: 3,\n },\n displayMode: 'containerBoxes',\n dividers: {\n display: false,\n lineCapStyle: 'butt',\n lineColor: 'black',\n lineDash: [],\n lineDashOffset: 0,\n lineWidth: 1,\n },\n label: undefined,\n labels: {\n align: 'center',\n color: 'black',\n display: false,\n font: {},\n formatter(ctx: TreemapScriptableContext) {\n const label = ctx.raw._data?.label\n if (ctx.raw.g) {\n return [ctx.raw.g, `${ctx.raw.v}`]\n }\n return typeof label === 'string' ? [label, `${ctx.raw.v}`] : `${ctx.raw.v}`\n },\n overflow: 'cut',\n padding: 3,\n position: 'middle',\n },\n rtl: false,\n spacing: 0.5,\n unsorted: false,\n }\n\n static readonly descriptors = {\n _indexable: false,\n _scriptable: true,\n captions: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n labels: {\n _fallback: true,\n _scriptable: (name: string) => name !== 'formatter',\n },\n }\n\n static override readonly defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor',\n }\n\n $context?: TreemapScriptableContext\n width: number | undefined\n height: number | undefined\n\n constructor(cfg?: Partial<TreemapConfig> & { options?: TreemapOptions }) {\n super()\n\n this.width = undefined\n this.height = undefined\n\n if (cfg) {\n Object.assign(this, cfg)\n }\n }\n\n draw(ctx: CanvasRenderingContext2D, data?: TreemapDataPoint) {\n if (!data) {\n return\n }\n const options = this.options\n const { inner, outer } = boundingRects(this)\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, this)\n ctx.restore()\n }\n\n inRange(mouseX: number, mouseY: number, useFinalPosition?: boolean) {\n return inRange(this, mouseX, mouseY, useFinalPosition)\n }\n\n inXRange(mouseX: number, useFinalPosition?: boolean) {\n return inRange(this, mouseX, null, useFinalPosition)\n }\n\n inYRange(mouseY: number, useFinalPosition?: boolean) {\n return inRange(this, null, mouseY, useFinalPosition)\n }\n\n getCenterPoint(useFinalPosition?: boolean) {\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 override tooltipPosition() {\n return this.getCenterPoint()\n }\n}\n","import { Chart } from 'chart.js'\n\nimport TreemapController from './controller'\nimport TreemapElement from './element'\n\nChart.register(TreemapController as any, TreemapElement as any)\n\nexport type {\n LabelAlign,\n LabelOverflow,\n LabelPosition,\n TreemapConfig,\n TreemapControllerDatasetOptions,\n TreemapDataPoint,\n TreemapElement as TreemapElementType,\n TreemapOptions,\n} from './types'\n\nexport * from './utils'\nexport { TreemapController, TreemapElement }\n"],"names":["scaleRect","sq","xScale","yScale","sp","sp2","x","getPixelForValue","y","w","h","height","hidden","width","arrayNotEqual","a","b","i","n","length","limit","value","min","max","Math","parseBorderWidth","maxW","maxH","o","toTRBL","bottom","l","left","r","right","t","top","getDims","itm","w2","s2","key","_normalized","ar","d1","sqrt","d2","getX","rect","rtl","iw","_ix","buildRow","dims","sum","_data","s","v","vs","values","_iy","group","g","level","gs","groupSum","Rect","area","this","ih","dir","side","map","arr","nsum","row","get","ret","maxd2","totd1","push","constructor","unsorted","getNewStat","sa","ratio","nmax","nmin","stat","_arr","Object","assign","setStat","StatArray","reset","_hist","Infinity","pushIf","fn","args","nstat","isOlderPart","act","req","startsWith","getGroupKey","lvl","String","hasGroupValue","scanTreeObject","keys","treeLeafKey","obj","tree","result","objIndex","record","reduce","reduced","item","forEach","k","childKey","child","isObject","splice","normalizeTreeToArray","data","maxVal","element","ikeys","groupKey","flatten","input","stack","res","next","pop","Array","isArray","reverse","getPath","groups","defaultValue","path","grp","join","resolveGroup","allGroups","groupIndex","idx","ensureGroup","tmp","groupValue","addKeys","tmpRef","mainGrp","mainValue","slice","create","resolvedAllGroups","resolvedGroupIndex","itemGroup","label","children","ak","index","_idx","sort","requireVersion","pkg","ver","strict","parts","split","Number","parseInt","Error","compareAspectRatio","oldStat","newStat","os2","ns2","l2","or","squarify","rectangle","gsum","rows","val","gval","undefined","widthCache","Map","shouldDrawCaption","displayMode","options","display","toFont","font","lineHeight","padding","valueOrDefault","getCaptionHeight","captionHeight","drawText","ctx","captions","labels","save","beginPath","clip","isLeaf","defined","content","resolveOption","formatter","callbackContext","contents","fonts","hoverFont","optFont","active","f","getFontFromOptions","labelSize","measureLabelSize","lblToDraw","_ctx","overflow","labelToDraw","isNumber","fitRatio","_lineHeight","size","floor","toFonts","color","hoverColor","align","optColor","colors","xyPoint","position","calculateX","calculateXYLabel","textAlign","textBaseline","lhs","c","lh","string","fillStyle","fillText","drawLabel","spacing","oColor","oAlign","oFont","text","resolveCaptionText","captionSize","ellipsis","ellipsisWidth","currentWidth","lowerBoundLen","upperBoundLen","currentLen","slicedText","sliceTextToFitWidth","drawCaption","restore","context","$context","raw","type","option","lines","fontsKey","prev","mapKey","_measureText","count","measureText","set","buildData","dataset","mainRect","glen","recur","treeElements","gidx","parent","gdata","filter","_item","gsq","subRect","bw","borderWidth","getSubRect","nextGroupIndex","d","Boolean","registerTooltipPositioner","tooltipPlugin","registry","plugins","positioners","treemap","at","tooltipPosition","TreemapController","DatasetController","initialize","enableOptionSharing","super","getMinMax","scale","axis","configure","getMeta","r1","r2","_rect","_rectChanged","update","mode","getDataset","concat","sumKeys","treeVersion","_keys","_groups","_prevTree","_prevTreeVersion","_dataCheck","_resyncElements","updateElements","rects","start","firstOpts","resolveDataElementOptions","sharedOptions","getSharedOptions","includeOptions","properties","updateElement","updateSharedOptions","draw","chartArea","chart","metadata","clipArea","ilen","unclipArea","datasetIndex","getBounds","useFinalPosition","getProps","boundingRects","bounds","border","radius","toTRBLCorners","maxR","bottomLeft","bottomRight","topLeft","topRight","parseBorderRadius","borderRadius","outer","inner","inRange","skipX","skipY","addNormalRectPath","id","version","defaults","animations","numbers","dataElementType","descriptors","_indexable","_scriptable","_fallback","name","overrides","hover","interaction","includeInvisible","intersect","tooltip","callbacks","dataItem","dataIndex","title","items","scales","alignToPixels","beforeRegister","Chart","afterRegister","afterUnregister","TreemapElement","Element","addRectPath","addRoundedRectPath","borderColor","fill","backgroundColor","dividers","lineColor","lineCapStyle","lineDash","lineDashOffset","lineWidth","strokeStyle","lineCap","setLineDash","moveTo","lineTo","h2","stroke","drawDivider","mouseX","mouseY","inXRange","inYRange","getCenterPoint","cfg","defaultRoutes","register"],"mappings":"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"}
@@ -13,6 +13,7 @@ export default class TreemapController extends DatasetController {
13
13
  _rect: any;
14
14
  _rectChanged: boolean;
15
15
  _prevTree: any;
16
+ _prevTreeVersion: unknown;
16
17
  constructor(chart: any, datasetIndex: number);
17
18
  initialize(): void;
18
19
  getMinMax(scale: any): {
package/dist/types.d.ts CHANGED
@@ -91,6 +91,7 @@ export interface TreemapControllerDatasetOptions<DType> {
91
91
  sumKeys?: Array<keyof DType>;
92
92
  tree: number[] | DType[] | AnyObject;
93
93
  treeLeafKey?: keyof DType;
94
+ treeVersion?: number | string;
94
95
  key?: keyof DType;
95
96
  }
96
97
  export interface TreemapDataPoint {
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "description": "Chart.js module for creating treemap charts",
7
7
  "devDependencies": {
8
8
  "@astrojs/check": "^0.9.9",
9
- "@astrojs/mdx": "^7.0.2",
10
- "@astrojs/starlight": "^0.41.3",
9
+ "@astrojs/mdx": "^8.0.0",
10
+ "@astrojs/starlight": "^0.42.0",
11
11
  "@biomejs/biome": "^2.4.14",
12
12
  "@emnapi/core": "^1.11.2",
13
13
  "@emnapi/runtime": "^1.11.2",
@@ -23,7 +23,7 @@
23
23
  "@types/jasmine": "^6.0.0",
24
24
  "@types/node": "^26.0.0",
25
25
  "astro": "^7.0.6",
26
- "c8": "^11.0.0",
26
+ "c8": "^12.0.0",
27
27
  "chart.js": "^4.0.1",
28
28
  "chartjs-plugin-datalabels": "^2.2.0",
29
29
  "chartjs-plugin-zoom": "^2.0.0",
@@ -31,8 +31,8 @@
31
31
  "concurrently": "^10.0.3",
32
32
  "cross-env": "^10.1.0",
33
33
  "globals": "^17.0.0",
34
- "jasmine": "^6.2.0",
35
- "jasmine-core": "^6.3.0",
34
+ "jasmine": "^7.0.0",
35
+ "jasmine-core": "^7.0.2",
36
36
  "karma": "^6.3.2",
37
37
  "karma-chrome-launcher": "^3.1.0",
38
38
  "karma-coverage": "^2.0.3",
@@ -107,5 +107,5 @@
107
107
  "type": "module",
108
108
  "types": "dist/index.esm.d.ts",
109
109
  "unpkg": "dist/chartjs-chart-treemap.min.js",
110
- "version": "4.1.2"
110
+ "version": "4.2.1"
111
111
  }