Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chartjs-chart-treemap

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chartjs-chart-treemap - npm Package Compare versions

Comparing version 1.0.0-beta.3 to 1.0.0-beta.4

1159

dist/chartjs-chart-treemap.esm.js
/*!
* chartjs-chart-treemap v1.0.0-beta.3
* chartjs-chart-treemap v1.0.0-beta.4
* https://github.com/kurkle/chartjs-chart-treemap#readme
* (c) 2020 Jukka Kurkela
* (c) 2021 Jukka Kurkela
* Released under the MIT license

@@ -12,16 +12,16 @@ */

function flatten(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// pop value from stack
const next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push(...next);
} else {
res.push(next);
}
}
// reverse to restore input order
return res.reverse();
const stack = [...input];
const res = [];
while (stack.length) {
// pop value from stack
const next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push(...next);
} else {
res.push(next);
}
}
// reverse to restore input order
return res.reverse();
}

@@ -37,90 +37,90 @@

function group(values, grp, key, mainGrp, mainValue) {
const tmp = Object.create(null);
const data = Object.create(null);
const ret = [];
let g, i, n, v;
for (i = 0, n = values.length; i < n; ++i) {
v = values[i];
if (mainGrp && v[mainGrp] !== mainValue) {
continue;
}
g = v[grp] || '';
if (!(g in tmp)) {
tmp[g] = 0;
data[g] = [];
}
tmp[g] += +v[key];
data[g].push(v);
}
const tmp = Object.create(null);
const data = Object.create(null);
const ret = [];
let g, i, n, v;
for (i = 0, n = values.length; i < n; ++i) {
v = values[i];
if (mainGrp && v[mainGrp] !== mainValue) {
continue;
}
g = v[grp] || '';
if (!(g in tmp)) {
tmp[g] = 0;
data[g] = [];
}
tmp[g] += +v[key];
data[g].push(v);
}
Object.keys(tmp).forEach((k) => {
v = {children: data[k]};
v[key] = +tmp[k];
v[grp] = k;
if (mainGrp) {
v[mainGrp] = mainValue;
}
ret.push(v);
});
Object.keys(tmp).forEach((k) => {
v = {children: data[k]};
v[key] = +tmp[k];
v[grp] = k;
if (mainGrp) {
v[mainGrp] = mainValue;
}
ret.push(v);
});
return ret;
return ret;
}
function isObject(obj) {
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function index(values, key) {
let n = values.length;
let i;
let n = values.length;
let i;
if (!n) {
return key;
}
if (!n) {
return key;
}
const obj = isObject(values[0]);
key = obj ? key : 'v';
const obj = isObject(values[0]);
key = obj ? key : 'v';
for (i = 0, n = values.length; i < n; ++i) {
if (obj) {
values[i]._idx = i;
} else {
values[i] = {v: values[i], _idx: i};
}
}
return key;
for (i = 0, n = values.length; i < n; ++i) {
if (obj) {
values[i]._idx = i;
} else {
values[i] = {v: values[i], _idx: i};
}
}
return key;
}
function sort(values, key) {
if (key) {
values.sort((a, b) => +b[key] - +a[key]);
} else {
values.sort((a, b) => +b - +a);
}
if (key) {
values.sort((a, b) => +b[key] - +a[key]);
} else {
values.sort((a, b) => +b - +a);
}
}
function sum(values, key) {
let s, i, n;
let s, i, n;
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
return s;
return s;
}
function round(v, n) {
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
}
function getDims(itm, w2, s2, key) {
const a = itm._normalized;
const ar = w2 * a / s2;
const d1 = Math.sqrt(a * ar);
const d2 = a / d1;
const w = key === '_ix' ? d1 : d2;
const h = key === '_ix' ? d2 : d1;
const a = itm._normalized;
const ar = w2 * a / s2;
const d1 = Math.sqrt(a * ar);
const d2 = a / d1;
const w = key === '_ix' ? d1 : d2;
const h = key === '_ix' ? d2 : d1;
return {d1, d2, w, h};
return {d1, d2, w, h};
}

@@ -131,77 +131,77 @@

function buildRow(rect, itm, dims, sum) {
const r = {
x: getX(rect, dims.w),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: round(itm._normalized, 4),
v: itm.value,
s: sum,
_data: itm._data
};
if (itm.group) {
r.g = itm.group;
r.l = itm.level;
r.gs = itm.groupSum;
}
return r;
const r = {
x: getX(rect, dims.w),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: round(itm._normalized, 4),
v: itm.value,
s: sum,
_data: itm._data
};
if (itm.group) {
r.g = itm.group;
r.l = itm.level;
r.gs = itm.groupSum;
}
return r;
}
class Rect {
constructor(r) {
const me = this;
r = r || {w: 1, h: 1};
me.rtl = !!r.rtl;
me.x = r.x || r.left || 0;
me.y = r.y || r.top || 0;
me._ix = 0;
me._iy = 0;
me.w = r.w || r.width || (r.right - r.left);
me.h = r.h || r.height || (r.bottom - r.top);
}
constructor(r) {
const me = this;
r = r || {w: 1, h: 1};
me.rtl = !!r.rtl;
me.x = r.x || r.left || 0;
me.y = r.y || r.top || 0;
me._ix = 0;
me._iy = 0;
me.w = r.w || r.width || (r.right - r.left);
me.h = r.h || r.height || (r.bottom - r.top);
}
get area() {
return this.w * this.h;
}
get area() {
return this.w * this.h;
}
get iw() {
return this.w - this._ix;
}
get iw() {
return this.w - this._ix;
}
get ih() {
return this.h - this._iy;
}
get ih() {
return this.h - this._iy;
}
get dir() {
const ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
get dir() {
const ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
get side() {
return this.dir === 'x' ? this.iw : this.ih;
}
get side() {
return this.dir === 'x' ? this.iw : this.ih;
}
map(arr) {
const me = this;
const ret = [];
const sum = arr.nsum;
const row = arr.get();
const dir = me.dir;
const side = me.side;
const w2 = side * side;
const key = dir === 'x' ? '_ix' : '_iy';
const s2 = sum * sum;
let maxd2 = 0;
let totd1 = 0;
for (const itm of row) {
const dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
maxd2 = Math.max(maxd2, dims.d2);
ret.push(buildRow(me, itm, dims, arr.sum));
me[key] += dims.d1;
}
me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
me[key] -= totd1;
return ret;
}
map(arr) {
const me = this;
const ret = [];
const sum = arr.nsum;
const row = arr.get();
const dir = me.dir;
const side = me.side;
const w2 = side * side;
const key = dir === 'x' ? '_ix' : '_iy';
const s2 = sum * sum;
let maxd2 = 0;
let totd1 = 0;
for (const itm of row) {
const dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
maxd2 = Math.max(maxd2, dims.d2);
ret.push(buildRow(me, itm, dims, arr.sum));
me[key] += dims.d1;
}
me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
me[key] -= totd1;
return ret;
}
}

@@ -213,89 +213,89 @@

function getStat(sa) {
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
}
function getNewStat(sa, o) {
const v = +o[sa.key];
const n = v * sa.ratio;
o._normalized = n;
const v = +o[sa.key];
const n = v * sa.ratio;
o._normalized = n;
return {
min: min(sa.min, v),
max: max(sa.max, v),
sum: sa.sum + v,
nmin: min(sa.nmin, n),
nmax: max(sa.nmax, n),
nsum: sa.nsum + n
};
return {
min: min(sa.min, v),
max: max(sa.max, v),
sum: sa.sum + v,
nmin: min(sa.nmin, n),
nmax: max(sa.nmax, n),
nsum: sa.nsum + n
};
}
function setStat(sa, stat) {
Object.assign(sa, stat);
Object.assign(sa, stat);
}
function push(sa, o, stat) {
sa._arr.push(o);
setStat(sa, stat);
sa._arr.push(o);
setStat(sa, stat);
}
class StatArray {
constructor(key, ratio) {
const me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
constructor(key, ratio) {
const me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
get length() {
return this._arr.length;
}
get length() {
return this._arr.length;
}
reset() {
const me = this;
me._arr = [];
me._hist = [];
me.sum = 0;
me.nsum = 0;
me.min = Infinity;
me.max = -Infinity;
me.nmin = Infinity;
me.nmax = -Infinity;
}
reset() {
const me = this;
me._arr = [];
me._hist = [];
me.sum = 0;
me.nsum = 0;
me.min = Infinity;
me.max = -Infinity;
me.nmin = Infinity;
me.nmax = -Infinity;
}
push(o) {
push(this, o, getNewStat(this, o));
}
push(o) {
push(this, o, getNewStat(this, o));
}
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
get() {
return this._arr;
}
get() {
return this._arr;
}
}
function compareAspectRatio(oldStat, newStat, args) {
if (oldStat.sum === 0) {
return true;
}
if (oldStat.sum === 0) {
return true;
}
const [length] = args;
const os2 = oldStat.nsum * oldStat.nsum;
const ns2 = newStat.nsum * newStat.nsum;
const l2 = length * length;
const or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
return nr <= or;
const [length] = args;
const os2 = oldStat.nsum * oldStat.nsum;
const ns2 = newStat.nsum * newStat.nsum;
const l2 = length * length;
const or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
return nr <= or;
}

@@ -313,43 +313,43 @@

function squarify(values, rectangle, key, grp, lvl, gsum) {
values = values || [];
const rows = [];
const rect = new Rect(rectangle);
const row = new StatArray('value', rect.area / sum(values, key));
let length = rect.side;
const n = values.length;
let i, o;
values = values || [];
const rows = [];
const rect = new Rect(rectangle);
const row = new StatArray('value', rect.area / sum(values, key));
let length = rect.side;
const n = values.length;
let i, o;
if (!n) {
return rows;
}
if (!n) {
return rows;
}
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
for (i = 0; i < n; ++i) {
o = {value: val(i), groupSum: gsum, _data: values[tmp[i]._idx]};
if (grp) {
o.level = lvl;
o.group = gval(i);
}
o = row.pushIf(o, compareAspectRatio, length);
if (o) {
rows.push(rect.map(row));
length = rect.side;
row.reset();
row.push(o);
}
}
if (row.length) {
rows.push(rect.map(row));
}
return flatten(rows);
for (i = 0; i < n; ++i) {
o = {value: val(i), groupSum: gsum, _data: values[tmp[i]._idx]};
if (grp) {
o.level = lvl;
o.group = gval(i);
}
o = row.pushIf(o, compareAspectRatio, length);
if (o) {
rows.push(rect.map(row));
length = rect.side;
row.reset();
row.push(o);
}
}
if (row.length) {
rows.push(rect.map(row));
}
return flatten(rows);
}
function rectNotEqual(r1, r2) {
return !r1 || !r2
return !r1 || !r2
|| r1.x !== r2.x

@@ -362,222 +362,222 @@ || r1.y !== r2.y

function arrayNotEqual(a1, a2) {
let i, n;
let i, n;
if (a1.lenght !== a2.length) {
return true;
}
if (a1.lenght !== a2.length) {
return true;
}
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
}
function shouldDrawCaption(rect, font) {
if (!font) {
return false;
}
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const min = font.lineHeight * 2;
return w > min && h > min;
if (!font) {
return false;
}
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const min = font.lineHeight * 2;
return w > min && h > min;
}
function drawCaption(ctx, rect, item, opts, levels) {
ctx.save();
ctx.fillStyle = opts.font.color;
ctx.font = opts.font.string;
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.clip();
if (!('l' in item) || item.l === levels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
drawLabels(ctx, item, rect);
} else if (opts.groupLabels) {
ctx.textAlign = opts.rtl ? 'end' : 'start';
ctx.textBaseline = 'top';
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
}
ctx.restore();
ctx.save();
ctx.fillStyle = opts.color;
ctx.font = opts.font.string;
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.clip();
if (!('l' in item) || item.l === levels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
drawLabels(ctx, item, rect);
} else if (opts.groupLabels) {
ctx.textAlign = opts.rtl ? 'end' : 'start';
ctx.textBaseline = 'top';
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
function drawDivider(ctx, rect) {
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
ctx.save();
ctx.strokeStyle = opts.dividerColor || 'black';
ctx.lineCap = opts.dividerCapStyle;
ctx.setLineDash(opts.dividerDash || []);
ctx.lineDashOffset = opts.dividerDashOffset;
ctx.lineWidth = opts.dividerWidth;
ctx.beginPath();
if (w > h) {
const w2 = w / 2;
ctx.moveTo(rect.x + w2, rect.y);
ctx.lineTo(rect.x + w2, rect.y + h);
} else {
const h2 = h / 2;
ctx.moveTo(rect.x, rect.y + h2);
ctx.lineTo(rect.x + w, rect.y + h2);
}
ctx.stroke();
ctx.restore();
ctx.save();
ctx.strokeStyle = opts.dividerColor || 'black';
ctx.lineCap = opts.dividerCapStyle;
ctx.setLineDash(opts.dividerDash || []);
ctx.lineDashOffset = opts.dividerDashOffset;
ctx.lineWidth = opts.dividerWidth;
ctx.beginPath();
if (w > h) {
const w2 = w / 2;
ctx.moveTo(rect.x + w2, rect.y);
ctx.lineTo(rect.x + w2, rect.y + h);
} else {
const h2 = h / 2;
ctx.moveTo(rect.x, rect.y + h2);
ctx.lineTo(rect.x + w, rect.y + h2);
}
ctx.stroke();
ctx.restore();
}
function buildData(dataset, mainRect, font) {
const key = dataset.key || '';
let tree = dataset.tree || [];
const groups = dataset.groups || [];
const glen = groups.length;
const sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
const key = dataset.key || '';
let tree = dataset.tree || [];
const groups = dataset.groups || [];
const glen = groups.length;
const sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
function recur(gidx, rect, parent, gs) {
const g = groups[gidx];
const pg = (gidx > 0) && groups[gidx - 1];
const gdata = group(tree, g, key, pg, parent);
const gsq = squarify(gdata, rect, key, g, gidx, gs);
const ret = gsq.slice();
let subRect;
if (gidx < glen - 1) {
gsq.forEach((sq) => {
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
function recur(gidx, rect, parent, gs) {
const g = groups[gidx];
const pg = (gidx > 0) && groups[gidx - 1];
const gdata = group(tree, g, key, pg, parent);
const gsq = squarify(gdata, rect, key, g, gidx, gs);
const ret = gsq.slice();
let subRect;
if (gidx < glen - 1) {
gsq.forEach((sq) => {
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
if (valueOrDefault(dataset.groupLabels, true) && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
if (valueOrDefault(dataset.groupLabels, true) && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
return glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
return glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
}
function drawLabels(ctx, item, rect) {
const opts = rect.options;
const lh = opts.font.lineHeight;
const labels = (opts.label || item.g + '\n' + item.v).split('\n');
const y = rect.y + rect.height / 2 - labels.length * lh / 4;
labels.forEach((l, i) => ctx.fillText(l, rect.x + rect.width / 2, y + i * lh));
const opts = rect.options;
const lh = opts.font.lineHeight;
const labels = (opts.label || item.g + '\n' + item.v).split('\n');
const y = rect.y + rect.height / 2 - labels.length * lh / 4;
labels.forEach((l, i) => ctx.fillText(l, rect.x + rect.width / 2, y + i * lh));
}
class TreemapController extends DatasetController {
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
update(mode) {
const me = this;
const meta = me.getMeta();
const dataset = me.getDataset();
const groups = dataset.groups || (dataset.groups = []);
const font = toFont(dataset.font, me.chart.options.font);
const area = me.chart.chartArea;
const key = dataset.key || '';
const rtl = !!dataset.rtl;
update(mode) {
const me = this;
const meta = me.getMeta();
const dataset = me.getDataset();
const groups = dataset.groups || (dataset.groups = []);
const font = toFont(dataset.font, me.chart.options.font);
const area = me.chart.chartArea;
const key = dataset.key || '';
const rtl = !!dataset.rtl;
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top, rtl};
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top, rtl};
if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
me._rect = mainRect;
me._groups = groups.slice();
me._key = key;
dataset.data = buildData(dataset, mainRect, font);
me._dataCheck();
me._resyncElements();
}
if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
me._rect = mainRect;
me._groups = groups.slice();
me._key = key;
dataset.data = buildData(dataset, mainRect, font);
me._dataCheck();
me._resyncElements();
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
resolveDataElementOptions(index, mode) {
const options = super.resolveDataElementOptions(index, mode);
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
result.font = toFont(options.font, this.chart.options.font);
return result;
}
resolveDataElementOptions(index, mode) {
const options = super.resolveDataElementOptions(index, mode);
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
result.font = toFont(options.font, this.chart.options.font);
return result;
}
updateElements(rects, start, count, mode) {
const me = this;
const reset = mode === 'reset';
const dataset = me.getDataset();
const firstOpts = me._rect.options = me.resolveDataElementOptions(start, mode);
const sharedOptions = me.getSharedOptions(firstOpts);
const includeOptions = me.includeOptions(mode, sharedOptions);
updateElements(rects, start, count, mode) {
const me = this;
const reset = mode === 'reset';
const dataset = me.getDataset();
const firstOpts = me._rect.options = me.resolveDataElementOptions(start, mode);
const sharedOptions = me.getSharedOptions(firstOpts);
const includeOptions = me.includeOptions(mode, sharedOptions);
for (let i = start; i < start + count; i++) {
const sq = dataset.data[i];
const options = sharedOptions || me.resolveDataElementOptions(i, mode);
const height = reset ? 0 : sq.h - options.spacing * 2;
const width = reset ? 0 : sq.w - options.spacing * 2;
const x = sq.x + options.spacing;
const y = sq.y + options.spacing;
const properties = {
x,
y,
width,
height
};
for (let i = start; i < start + count; i++) {
const sq = dataset.data[i];
const options = sharedOptions || me.resolveDataElementOptions(i, mode);
const height = reset ? 0 : sq.h - options.spacing * 2;
const width = reset ? 0 : sq.w - options.spacing * 2;
const x = sq.x + options.spacing;
const y = sq.y + options.spacing;
const properties = {
x,
y,
width,
height
};
if (includeOptions) {
properties.options = options;
}
me.updateElement(rects[i], i, properties, mode);
}
if (includeOptions) {
properties.options = options;
}
me.updateElement(rects[i], i, properties, mode);
}
me.updateSharedOptions(sharedOptions, mode, firstOpts);
}
me.updateSharedOptions(sharedOptions, mode, firstOpts);
}
_drawDividers(ctx, data, metadata) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (rect.options.groupDividers && item._data.children.length > 1) {
drawDivider(ctx, rect);
}
}
if (this.getDataset().groupDividers) {
drawDivider(ctx, this._rect);
}
}
_drawDividers(ctx, data, metadata) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (rect.options.groupDividers && item._data.children.length > 1) {
drawDivider(ctx, rect);
}
}
if (this.getDataset().groupDividers) {
drawDivider(ctx, this._rect);
}
}
_drawRects(ctx, data, metadata, levels) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (!rect.hidden) {
rect.draw(ctx);
const opts = rect.options;
if (shouldDrawCaption(rect, opts.font) && item.g) {
drawCaption(ctx, rect, item, opts, levels);
}
}
}
}
_drawRects(ctx, data, metadata, levels) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (!rect.hidden) {
rect.draw(ctx);
const opts = rect.options;
if (shouldDrawCaption(rect, opts.font) && item.g) {
drawCaption(ctx, rect, item, opts, levels);
}
}
}
}
draw() {
const me = this;
const ctx = me.chart.ctx;
const metadata = me.getMeta().data || [];
const dataset = me.getDataset();
const levels = (dataset.groups || []).length - 1;
const data = dataset.data || [];
draw() {
const me = this;
const ctx = me.chart.ctx;
const metadata = me.getMeta().data || [];
const dataset = me.getDataset();
const levels = (dataset.groups || []).length - 1;
const data = dataset.data || [];
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
}

@@ -588,61 +588,52 @@

TreemapController.defaults = {
dataElementType: 'treemap',
dataElementOptions: [
'backgroundColor',
'borderColor',
'borderSkipped',
'borderWidth',
'dividerColor',
'dividerDash',
'dividerDashOffset',
'dividerWidth',
'font',
'groupLabels',
'groupDividers',
'spacing',
'label',
'rtl'
],
hover: {
mode: 'point',
intersect: true
},
tooltips: {
mode: 'point',
position: 'treemap',
intersect: true,
callbacks: {
title(items) {
if (items.length) {
const item = items[0];
return item.dataset.key || '';
}
return '';
},
label(item) {
const dataset = item.dataset;
const dataItem = dataset.data[item.dataIndex];
return dataset.label + ': ' + dataItem.v;
}
}
},
datasets: {
groupLabels: true,
borderWidth: 0,
spacing: 0.5,
groupDividers: false,
dividerWidth: 1
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
dataElementType: 'treemap',
groupLabels: true,
borderWidth: 0,
spacing: 0.5,
groupDividers: false,
dividerWidth: 1
};
TreemapController.overrides = {
interaction: {
mode: 'point',
intersect: true
},
hover: {},
plugins: {
tooltip: {
position: 'treemap',
intersect: true,
callbacks: {
title(items) {
if (items.length) {
const item = items[0];
return item.dataset.key || '';
}
return '';
},
label(item) {
const dataset = item.dataset;
const dataItem = dataset.data[item.dataIndex];
const label = dataItem.g || dataset.label;
return (label ? label + ': ' : '') + dataItem.v;
}
}
},
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
};
/**

@@ -656,58 +647,58 @@ * Helper function to get the bounds of the rect

function getBounds(rect, useFinalPosition) {
const {x, y, width, height} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {left: x, top: y, right: x + width, bottom: y + height};
const {x, y, width, height} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {left: x, top: y, right: x + width, bottom: y + height};
}
function limit(value, min, max) {
return Math.max(Math.min(value, max), min);
return Math.max(Math.min(value, max), min);
}
function parseBorderWidth(value, maxW, maxH) {
let t, r, b, l;
let t, r, b, l;
if (isObject(value)) {
t = +value.top || 0;
r = +value.right || 0;
b = +value.bottom || 0;
l = +value.left || 0;
} else {
t = r = b = l = +value || 0;
}
if (isObject(value)) {
t = +value.top || 0;
r = +value.right || 0;
b = +value.bottom || 0;
l = +value.left || 0;
} else {
t = r = b = l = +value || 0;
}
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
}
function boundingRects(rect) {
const bounds = getBounds(rect);
const width = bounds.right - bounds.left;
const height = bounds.bottom - bounds.top;
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
const bounds = getBounds(rect);
const width = bounds.right - bounds.left;
const height = bounds.bottom - bounds.top;
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
return {
outer: {
x: bounds.left,
y: bounds.top,
w: width,
h: height
},
inner: {
x: bounds.left + border.l,
y: bounds.top + border.t,
w: width - border.l - border.r,
h: height - border.t - border.b
}
};
return {
outer: {
x: bounds.left,
y: bounds.top,
w: width,
h: height
},
inner: {
x: bounds.left + border.l,
y: bounds.top + border.t,
w: width - border.l - border.r,
h: height - border.t - border.b
}
};
}
function inRange(rect, x, y, useFinalPosition) {
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
return bounds
return bounds
&& (skipX || x >= bounds.left && x <= bounds.right)

@@ -719,64 +710,64 @@ && (skipY || y >= bounds.top && y <= bounds.bottom);

constructor(cfg) {
super();
constructor(cfg) {
super();
this.options = undefined;
this.width = undefined;
this.height = undefined;
this.options = undefined;
this.width = undefined;
this.height = undefined;
if (cfg) {
Object.assign(this, cfg);
}
}
if (cfg) {
Object.assign(this, cfg);
}
}
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
ctx.save();
ctx.save();
if (outer.w !== inner.w || outer.h !== inner.h) {
ctx.beginPath();
ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fillStyle = options.backgroundColor;
ctx.fill();
ctx.fillStyle = options.borderColor;
ctx.fill('evenodd');
} else {
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
}
if (outer.w !== inner.w || outer.h !== inner.h) {
ctx.beginPath();
ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fillStyle = options.backgroundColor;
ctx.fill();
ctx.fillStyle = options.borderColor;
ctx.fill('evenodd');
} else {
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
}
ctx.restore();
}
ctx.restore();
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
tooltipPosition() {
return this.getCenterPoint();
}
tooltipPosition() {
return this.getCenterPoint();
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
}

@@ -787,15 +778,23 @@

TreemapElement.defaults = {
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
groupDividers: false,
borderSkipped: undefined,
borderWidth: undefined,
color: undefined,
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
font: {},
groupDividers: false,
groupLabels: undefined,
spacing: undefined,
label: undefined,
rtl: undefined
};
TreemapElement.defaultRoutes = {
backgroundColor: 'color',
borderColor: 'color'
backgroundColor: 'backgroundColor',
borderColor: 'borderColor'
};
export { Rect, TreemapElement as Rectangle, StatArray, TreemapController, flatten, group, index, isObject, sort, squarify, sum };
/*!
* chartjs-chart-treemap v1.0.0-beta.3
* chartjs-chart-treemap v1.0.0-beta.4
* https://github.com/kurkle/chartjs-chart-treemap#readme
* (c) 2020 Jukka Kurkela
* (c) 2021 Jukka Kurkela
* Released under the MIT license
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('chart.js'), require('chart.js/helpers')) :
typeof define === 'function' && define.amd ? define(['chart.js', 'chart.js/helpers'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Chart, global.Chart.helpers));
}(this, (function (chart_js, helpers) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('chart.js'), require('chart.js/helpers')) :
typeof define === 'function' && define.amd ? define(['exports', 'chart.js', 'chart.js/helpers'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['chartjs-chart-treemap'] = {}, global.Chart, global.Chart.helpers));
}(this, (function (exports, chart_js, helpers) { 'use strict';
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatten(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// pop value from stack
const next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push(...next);
} else {
res.push(next);
}
}
// reverse to restore input order
return res.reverse();
const stack = [...input];
const res = [];
while (stack.length) {
// pop value from stack
const next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push(...next);
} else {
res.push(next);
}
}
// reverse to restore input order
return res.reverse();
}

@@ -39,90 +39,90 @@

function group(values, grp, key, mainGrp, mainValue) {
const tmp = Object.create(null);
const data = Object.create(null);
const ret = [];
let g, i, n, v;
for (i = 0, n = values.length; i < n; ++i) {
v = values[i];
if (mainGrp && v[mainGrp] !== mainValue) {
continue;
}
g = v[grp] || '';
if (!(g in tmp)) {
tmp[g] = 0;
data[g] = [];
}
tmp[g] += +v[key];
data[g].push(v);
}
const tmp = Object.create(null);
const data = Object.create(null);
const ret = [];
let g, i, n, v;
for (i = 0, n = values.length; i < n; ++i) {
v = values[i];
if (mainGrp && v[mainGrp] !== mainValue) {
continue;
}
g = v[grp] || '';
if (!(g in tmp)) {
tmp[g] = 0;
data[g] = [];
}
tmp[g] += +v[key];
data[g].push(v);
}
Object.keys(tmp).forEach((k) => {
v = {children: data[k]};
v[key] = +tmp[k];
v[grp] = k;
if (mainGrp) {
v[mainGrp] = mainValue;
}
ret.push(v);
});
Object.keys(tmp).forEach((k) => {
v = {children: data[k]};
v[key] = +tmp[k];
v[grp] = k;
if (mainGrp) {
v[mainGrp] = mainValue;
}
ret.push(v);
});
return ret;
return ret;
}
function isObject(obj) {
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function index(values, key) {
let n = values.length;
let i;
let n = values.length;
let i;
if (!n) {
return key;
}
if (!n) {
return key;
}
const obj = isObject(values[0]);
key = obj ? key : 'v';
const obj = isObject(values[0]);
key = obj ? key : 'v';
for (i = 0, n = values.length; i < n; ++i) {
if (obj) {
values[i]._idx = i;
} else {
values[i] = {v: values[i], _idx: i};
}
}
return key;
for (i = 0, n = values.length; i < n; ++i) {
if (obj) {
values[i]._idx = i;
} else {
values[i] = {v: values[i], _idx: i};
}
}
return key;
}
function sort(values, key) {
if (key) {
values.sort((a, b) => +b[key] - +a[key]);
} else {
values.sort((a, b) => +b - +a);
}
if (key) {
values.sort((a, b) => +b[key] - +a[key]);
} else {
values.sort((a, b) => +b - +a);
}
}
function sum(values, key) {
let s, i, n;
let s, i, n;
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
return s;
return s;
}
function round(v, n) {
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
}
function getDims(itm, w2, s2, key) {
const a = itm._normalized;
const ar = w2 * a / s2;
const d1 = Math.sqrt(a * ar);
const d2 = a / d1;
const w = key === '_ix' ? d1 : d2;
const h = key === '_ix' ? d2 : d1;
const a = itm._normalized;
const ar = w2 * a / s2;
const d1 = Math.sqrt(a * ar);
const d2 = a / d1;
const w = key === '_ix' ? d1 : d2;
const h = key === '_ix' ? d2 : d1;
return {d1, d2, w, h};
return {d1, d2, w, h};
}

@@ -133,77 +133,77 @@

function buildRow(rect, itm, dims, sum) {
const r = {
x: getX(rect, dims.w),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: round(itm._normalized, 4),
v: itm.value,
s: sum,
_data: itm._data
};
if (itm.group) {
r.g = itm.group;
r.l = itm.level;
r.gs = itm.groupSum;
}
return r;
const r = {
x: getX(rect, dims.w),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: round(itm._normalized, 4),
v: itm.value,
s: sum,
_data: itm._data
};
if (itm.group) {
r.g = itm.group;
r.l = itm.level;
r.gs = itm.groupSum;
}
return r;
}
class Rect {
constructor(r) {
const me = this;
r = r || {w: 1, h: 1};
me.rtl = !!r.rtl;
me.x = r.x || r.left || 0;
me.y = r.y || r.top || 0;
me._ix = 0;
me._iy = 0;
me.w = r.w || r.width || (r.right - r.left);
me.h = r.h || r.height || (r.bottom - r.top);
}
constructor(r) {
const me = this;
r = r || {w: 1, h: 1};
me.rtl = !!r.rtl;
me.x = r.x || r.left || 0;
me.y = r.y || r.top || 0;
me._ix = 0;
me._iy = 0;
me.w = r.w || r.width || (r.right - r.left);
me.h = r.h || r.height || (r.bottom - r.top);
}
get area() {
return this.w * this.h;
}
get area() {
return this.w * this.h;
}
get iw() {
return this.w - this._ix;
}
get iw() {
return this.w - this._ix;
}
get ih() {
return this.h - this._iy;
}
get ih() {
return this.h - this._iy;
}
get dir() {
const ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
get dir() {
const ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
get side() {
return this.dir === 'x' ? this.iw : this.ih;
}
get side() {
return this.dir === 'x' ? this.iw : this.ih;
}
map(arr) {
const me = this;
const ret = [];
const sum = arr.nsum;
const row = arr.get();
const dir = me.dir;
const side = me.side;
const w2 = side * side;
const key = dir === 'x' ? '_ix' : '_iy';
const s2 = sum * sum;
let maxd2 = 0;
let totd1 = 0;
for (const itm of row) {
const dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
maxd2 = Math.max(maxd2, dims.d2);
ret.push(buildRow(me, itm, dims, arr.sum));
me[key] += dims.d1;
}
me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
me[key] -= totd1;
return ret;
}
map(arr) {
const me = this;
const ret = [];
const sum = arr.nsum;
const row = arr.get();
const dir = me.dir;
const side = me.side;
const w2 = side * side;
const key = dir === 'x' ? '_ix' : '_iy';
const s2 = sum * sum;
let maxd2 = 0;
let totd1 = 0;
for (const itm of row) {
const dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
maxd2 = Math.max(maxd2, dims.d2);
ret.push(buildRow(me, itm, dims, arr.sum));
me[key] += dims.d1;
}
me[dir === 'y' ? '_ix' : '_iy'] += maxd2;
me[key] -= totd1;
return ret;
}
}

@@ -215,89 +215,89 @@

function getStat(sa) {
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
}
function getNewStat(sa, o) {
const v = +o[sa.key];
const n = v * sa.ratio;
o._normalized = n;
const v = +o[sa.key];
const n = v * sa.ratio;
o._normalized = n;
return {
min: min(sa.min, v),
max: max(sa.max, v),
sum: sa.sum + v,
nmin: min(sa.nmin, n),
nmax: max(sa.nmax, n),
nsum: sa.nsum + n
};
return {
min: min(sa.min, v),
max: max(sa.max, v),
sum: sa.sum + v,
nmin: min(sa.nmin, n),
nmax: max(sa.nmax, n),
nsum: sa.nsum + n
};
}
function setStat(sa, stat) {
Object.assign(sa, stat);
Object.assign(sa, stat);
}
function push(sa, o, stat) {
sa._arr.push(o);
setStat(sa, stat);
sa._arr.push(o);
setStat(sa, stat);
}
class StatArray {
constructor(key, ratio) {
const me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
constructor(key, ratio) {
const me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
get length() {
return this._arr.length;
}
get length() {
return this._arr.length;
}
reset() {
const me = this;
me._arr = [];
me._hist = [];
me.sum = 0;
me.nsum = 0;
me.min = Infinity;
me.max = -Infinity;
me.nmin = Infinity;
me.nmax = -Infinity;
}
reset() {
const me = this;
me._arr = [];
me._hist = [];
me.sum = 0;
me.nsum = 0;
me.min = Infinity;
me.max = -Infinity;
me.nmin = Infinity;
me.nmax = -Infinity;
}
push(o) {
push(this, o, getNewStat(this, o));
}
push(o) {
push(this, o, getNewStat(this, o));
}
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
get() {
return this._arr;
}
get() {
return this._arr;
}
}
function compareAspectRatio(oldStat, newStat, args) {
if (oldStat.sum === 0) {
return true;
}
if (oldStat.sum === 0) {
return true;
}
const [length] = args;
const os2 = oldStat.nsum * oldStat.nsum;
const ns2 = newStat.nsum * newStat.nsum;
const l2 = length * length;
const or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
return nr <= or;
const [length] = args;
const os2 = oldStat.nsum * oldStat.nsum;
const ns2 = newStat.nsum * newStat.nsum;
const l2 = length * length;
const or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
const nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
return nr <= or;
}

@@ -315,43 +315,43 @@

function squarify(values, rectangle, key, grp, lvl, gsum) {
values = values || [];
const rows = [];
const rect = new Rect(rectangle);
const row = new StatArray('value', rect.area / sum(values, key));
let length = rect.side;
const n = values.length;
let i, o;
values = values || [];
const rows = [];
const rect = new Rect(rectangle);
const row = new StatArray('value', rect.area / sum(values, key));
let length = rect.side;
const n = values.length;
let i, o;
if (!n) {
return rows;
}
if (!n) {
return rows;
}
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
for (i = 0; i < n; ++i) {
o = {value: val(i), groupSum: gsum, _data: values[tmp[i]._idx]};
if (grp) {
o.level = lvl;
o.group = gval(i);
}
o = row.pushIf(o, compareAspectRatio, length);
if (o) {
rows.push(rect.map(row));
length = rect.side;
row.reset();
row.push(o);
}
}
if (row.length) {
rows.push(rect.map(row));
}
return flatten(rows);
for (i = 0; i < n; ++i) {
o = {value: val(i), groupSum: gsum, _data: values[tmp[i]._idx]};
if (grp) {
o.level = lvl;
o.group = gval(i);
}
o = row.pushIf(o, compareAspectRatio, length);
if (o) {
rows.push(rect.map(row));
length = rect.side;
row.reset();
row.push(o);
}
}
if (row.length) {
rows.push(rect.map(row));
}
return flatten(rows);
}
function rectNotEqual(r1, r2) {
return !r1 || !r2
return !r1 || !r2
|| r1.x !== r2.x

@@ -364,222 +364,222 @@ || r1.y !== r2.y

function arrayNotEqual(a1, a2) {
let i, n;
let i, n;
if (a1.lenght !== a2.length) {
return true;
}
if (a1.lenght !== a2.length) {
return true;
}
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
}
function shouldDrawCaption(rect, font) {
if (!font) {
return false;
}
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const min = font.lineHeight * 2;
return w > min && h > min;
if (!font) {
return false;
}
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const min = font.lineHeight * 2;
return w > min && h > min;
}
function drawCaption(ctx, rect, item, opts, levels) {
ctx.save();
ctx.fillStyle = opts.font.color;
ctx.font = opts.font.string;
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.clip();
if (!('l' in item) || item.l === levels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
drawLabels(ctx, item, rect);
} else if (opts.groupLabels) {
ctx.textAlign = opts.rtl ? 'end' : 'start';
ctx.textBaseline = 'top';
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
}
ctx.restore();
ctx.save();
ctx.fillStyle = opts.color;
ctx.font = opts.font.string;
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.clip();
if (!('l' in item) || item.l === levels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
drawLabels(ctx, item, rect);
} else if (opts.groupLabels) {
ctx.textAlign = opts.rtl ? 'end' : 'start';
ctx.textBaseline = 'top';
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
function drawDivider(ctx, rect) {
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
ctx.save();
ctx.strokeStyle = opts.dividerColor || 'black';
ctx.lineCap = opts.dividerCapStyle;
ctx.setLineDash(opts.dividerDash || []);
ctx.lineDashOffset = opts.dividerDashOffset;
ctx.lineWidth = opts.dividerWidth;
ctx.beginPath();
if (w > h) {
const w2 = w / 2;
ctx.moveTo(rect.x + w2, rect.y);
ctx.lineTo(rect.x + w2, rect.y + h);
} else {
const h2 = h / 2;
ctx.moveTo(rect.x, rect.y + h2);
ctx.lineTo(rect.x + w, rect.y + h2);
}
ctx.stroke();
ctx.restore();
ctx.save();
ctx.strokeStyle = opts.dividerColor || 'black';
ctx.lineCap = opts.dividerCapStyle;
ctx.setLineDash(opts.dividerDash || []);
ctx.lineDashOffset = opts.dividerDashOffset;
ctx.lineWidth = opts.dividerWidth;
ctx.beginPath();
if (w > h) {
const w2 = w / 2;
ctx.moveTo(rect.x + w2, rect.y);
ctx.lineTo(rect.x + w2, rect.y + h);
} else {
const h2 = h / 2;
ctx.moveTo(rect.x, rect.y + h2);
ctx.lineTo(rect.x + w, rect.y + h2);
}
ctx.stroke();
ctx.restore();
}
function buildData(dataset, mainRect, font) {
const key = dataset.key || '';
let tree = dataset.tree || [];
const groups = dataset.groups || [];
const glen = groups.length;
const sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
const key = dataset.key || '';
let tree = dataset.tree || [];
const groups = dataset.groups || [];
const glen = groups.length;
const sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
function recur(gidx, rect, parent, gs) {
const g = groups[gidx];
const pg = (gidx > 0) && groups[gidx - 1];
const gdata = group(tree, g, key, pg, parent);
const gsq = squarify(gdata, rect, key, g, gidx, gs);
const ret = gsq.slice();
let subRect;
if (gidx < glen - 1) {
gsq.forEach((sq) => {
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
function recur(gidx, rect, parent, gs) {
const g = groups[gidx];
const pg = (gidx > 0) && groups[gidx - 1];
const gdata = group(tree, g, key, pg, parent);
const gsq = squarify(gdata, rect, key, g, gidx, gs);
const ret = gsq.slice();
let subRect;
if (gidx < glen - 1) {
gsq.forEach((sq) => {
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
if (helpers.valueOrDefault(dataset.groupLabels, true) && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
if (helpers.valueOrDefault(dataset.groupLabels, true) && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
return glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
return glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
}
function drawLabels(ctx, item, rect) {
const opts = rect.options;
const lh = opts.font.lineHeight;
const labels = (opts.label || item.g + '\n' + item.v).split('\n');
const y = rect.y + rect.height / 2 - labels.length * lh / 4;
labels.forEach((l, i) => ctx.fillText(l, rect.x + rect.width / 2, y + i * lh));
const opts = rect.options;
const lh = opts.font.lineHeight;
const labels = (opts.label || item.g + '\n' + item.v).split('\n');
const y = rect.y + rect.height / 2 - labels.length * lh / 4;
labels.forEach((l, i) => ctx.fillText(l, rect.x + rect.width / 2, y + i * lh));
}
class TreemapController extends chart_js.DatasetController {
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
update(mode) {
const me = this;
const meta = me.getMeta();
const dataset = me.getDataset();
const groups = dataset.groups || (dataset.groups = []);
const font = helpers.toFont(dataset.font, me.chart.options.font);
const area = me.chart.chartArea;
const key = dataset.key || '';
const rtl = !!dataset.rtl;
update(mode) {
const me = this;
const meta = me.getMeta();
const dataset = me.getDataset();
const groups = dataset.groups || (dataset.groups = []);
const font = helpers.toFont(dataset.font, me.chart.options.font);
const area = me.chart.chartArea;
const key = dataset.key || '';
const rtl = !!dataset.rtl;
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top, rtl};
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top, rtl};
if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
me._rect = mainRect;
me._groups = groups.slice();
me._key = key;
dataset.data = buildData(dataset, mainRect, font);
me._dataCheck();
me._resyncElements();
}
if (mode === 'reset' || rectNotEqual(me._rect, mainRect) || me._key !== key || arrayNotEqual(me._groups, groups)) {
me._rect = mainRect;
me._groups = groups.slice();
me._key = key;
dataset.data = buildData(dataset, mainRect, font);
me._dataCheck();
me._resyncElements();
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
resolveDataElementOptions(index, mode) {
const options = super.resolveDataElementOptions(index, mode);
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
result.font = helpers.toFont(options.font, this.chart.options.font);
return result;
}
resolveDataElementOptions(index, mode) {
const options = super.resolveDataElementOptions(index, mode);
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
result.font = helpers.toFont(options.font, this.chart.options.font);
return result;
}
updateElements(rects, start, count, mode) {
const me = this;
const reset = mode === 'reset';
const dataset = me.getDataset();
const firstOpts = me._rect.options = me.resolveDataElementOptions(start, mode);
const sharedOptions = me.getSharedOptions(firstOpts);
const includeOptions = me.includeOptions(mode, sharedOptions);
updateElements(rects, start, count, mode) {
const me = this;
const reset = mode === 'reset';
const dataset = me.getDataset();
const firstOpts = me._rect.options = me.resolveDataElementOptions(start, mode);
const sharedOptions = me.getSharedOptions(firstOpts);
const includeOptions = me.includeOptions(mode, sharedOptions);
for (let i = start; i < start + count; i++) {
const sq = dataset.data[i];
const options = sharedOptions || me.resolveDataElementOptions(i, mode);
const height = reset ? 0 : sq.h - options.spacing * 2;
const width = reset ? 0 : sq.w - options.spacing * 2;
const x = sq.x + options.spacing;
const y = sq.y + options.spacing;
const properties = {
x,
y,
width,
height
};
for (let i = start; i < start + count; i++) {
const sq = dataset.data[i];
const options = sharedOptions || me.resolveDataElementOptions(i, mode);
const height = reset ? 0 : sq.h - options.spacing * 2;
const width = reset ? 0 : sq.w - options.spacing * 2;
const x = sq.x + options.spacing;
const y = sq.y + options.spacing;
const properties = {
x,
y,
width,
height
};
if (includeOptions) {
properties.options = options;
}
me.updateElement(rects[i], i, properties, mode);
}
if (includeOptions) {
properties.options = options;
}
me.updateElement(rects[i], i, properties, mode);
}
me.updateSharedOptions(sharedOptions, mode, firstOpts);
}
me.updateSharedOptions(sharedOptions, mode, firstOpts);
}
_drawDividers(ctx, data, metadata) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (rect.options.groupDividers && item._data.children.length > 1) {
drawDivider(ctx, rect);
}
}
if (this.getDataset().groupDividers) {
drawDivider(ctx, this._rect);
}
}
_drawDividers(ctx, data, metadata) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (rect.options.groupDividers && item._data.children.length > 1) {
drawDivider(ctx, rect);
}
}
if (this.getDataset().groupDividers) {
drawDivider(ctx, this._rect);
}
}
_drawRects(ctx, data, metadata, levels) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (!rect.hidden) {
rect.draw(ctx);
const opts = rect.options;
if (shouldDrawCaption(rect, opts.font) && item.g) {
drawCaption(ctx, rect, item, opts, levels);
}
}
}
}
_drawRects(ctx, data, metadata, levels) {
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
const rect = metadata[i];
const item = data[i];
if (!rect.hidden) {
rect.draw(ctx);
const opts = rect.options;
if (shouldDrawCaption(rect, opts.font) && item.g) {
drawCaption(ctx, rect, item, opts, levels);
}
}
}
}
draw() {
const me = this;
const ctx = me.chart.ctx;
const metadata = me.getMeta().data || [];
const dataset = me.getDataset();
const levels = (dataset.groups || []).length - 1;
const data = dataset.data || [];
draw() {
const me = this;
const ctx = me.chart.ctx;
const metadata = me.getMeta().data || [];
const dataset = me.getDataset();
const levels = (dataset.groups || []).length - 1;
const data = dataset.data || [];
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
}

@@ -590,61 +590,52 @@

TreemapController.defaults = {
dataElementType: 'treemap',
dataElementOptions: [
'backgroundColor',
'borderColor',
'borderSkipped',
'borderWidth',
'dividerColor',
'dividerDash',
'dividerDashOffset',
'dividerWidth',
'font',
'groupLabels',
'groupDividers',
'spacing',
'label',
'rtl'
],
hover: {
mode: 'point',
intersect: true
},
tooltips: {
mode: 'point',
position: 'treemap',
intersect: true,
callbacks: {
title(items) {
if (items.length) {
const item = items[0];
return item.dataset.key || '';
}
return '';
},
label(item) {
const dataset = item.dataset;
const dataItem = dataset.data[item.dataIndex];
return dataset.label + ': ' + dataItem.v;
}
}
},
datasets: {
groupLabels: true,
borderWidth: 0,
spacing: 0.5,
groupDividers: false,
dividerWidth: 1
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
dataElementType: 'treemap',
groupLabels: true,
borderWidth: 0,
spacing: 0.5,
groupDividers: false,
dividerWidth: 1
};
TreemapController.overrides = {
interaction: {
mode: 'point',
intersect: true
},
hover: {},
plugins: {
tooltip: {
position: 'treemap',
intersect: true,
callbacks: {
title(items) {
if (items.length) {
const item = items[0];
return item.dataset.key || '';
}
return '';
},
label(item) {
const dataset = item.dataset;
const dataItem = dataset.data[item.dataIndex];
const label = dataItem.g || dataset.label;
return (label ? label + ': ' : '') + dataItem.v;
}
}
},
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
};
/**

@@ -658,58 +649,58 @@ * Helper function to get the bounds of the rect

function getBounds(rect, useFinalPosition) {
const {x, y, width, height} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {left: x, top: y, right: x + width, bottom: y + height};
const {x, y, width, height} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {left: x, top: y, right: x + width, bottom: y + height};
}
function limit(value, min, max) {
return Math.max(Math.min(value, max), min);
return Math.max(Math.min(value, max), min);
}
function parseBorderWidth(value, maxW, maxH) {
let t, r, b, l;
let t, r, b, l;
if (isObject(value)) {
t = +value.top || 0;
r = +value.right || 0;
b = +value.bottom || 0;
l = +value.left || 0;
} else {
t = r = b = l = +value || 0;
}
if (isObject(value)) {
t = +value.top || 0;
r = +value.right || 0;
b = +value.bottom || 0;
l = +value.left || 0;
} else {
t = r = b = l = +value || 0;
}
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
}
function boundingRects(rect) {
const bounds = getBounds(rect);
const width = bounds.right - bounds.left;
const height = bounds.bottom - bounds.top;
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
const bounds = getBounds(rect);
const width = bounds.right - bounds.left;
const height = bounds.bottom - bounds.top;
const border = parseBorderWidth(rect.options.borderWidth, width / 2, height / 2);
return {
outer: {
x: bounds.left,
y: bounds.top,
w: width,
h: height
},
inner: {
x: bounds.left + border.l,
y: bounds.top + border.t,
w: width - border.l - border.r,
h: height - border.t - border.b
}
};
return {
outer: {
x: bounds.left,
y: bounds.top,
w: width,
h: height
},
inner: {
x: bounds.left + border.l,
y: bounds.top + border.t,
w: width - border.l - border.r,
h: height - border.t - border.b
}
};
}
function inRange(rect, x, y, useFinalPosition) {
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
return bounds
return bounds
&& (skipX || x >= bounds.left && x <= bounds.right)

@@ -721,64 +712,64 @@ && (skipY || y >= bounds.top && y <= bounds.bottom);

constructor(cfg) {
super();
constructor(cfg) {
super();
this.options = undefined;
this.width = undefined;
this.height = undefined;
this.options = undefined;
this.width = undefined;
this.height = undefined;
if (cfg) {
Object.assign(this, cfg);
}
}
if (cfg) {
Object.assign(this, cfg);
}
}
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
ctx.save();
ctx.save();
if (outer.w !== inner.w || outer.h !== inner.h) {
ctx.beginPath();
ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fillStyle = options.backgroundColor;
ctx.fill();
ctx.fillStyle = options.borderColor;
ctx.fill('evenodd');
} else {
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
}
if (outer.w !== inner.w || outer.h !== inner.h) {
ctx.beginPath();
ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fillStyle = options.backgroundColor;
ctx.fill();
ctx.fillStyle = options.borderColor;
ctx.fill('evenodd');
} else {
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
}
ctx.restore();
}
ctx.restore();
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
tooltipPosition() {
return this.getCenterPoint();
}
tooltipPosition() {
return this.getCenterPoint();
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
}

@@ -789,13 +780,21 @@

TreemapElement.defaults = {
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
groupDividers: false,
borderSkipped: undefined,
borderWidth: undefined,
color: undefined,
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
font: {},
groupDividers: false,
groupLabels: undefined,
spacing: undefined,
label: undefined,
rtl: undefined
};
TreemapElement.defaultRoutes = {
backgroundColor: 'color',
borderColor: 'color'
backgroundColor: 'backgroundColor',
borderColor: 'borderColor'
};

@@ -807,12 +806,21 @@

tooltipPlugin.positioners.treemap = function(active) {
if (!active.length) {
return false;
}
if (!active.length) {
return false;
}
const item = active[active.length - 1];
const el = item.element;
const item = active[active.length - 1];
const el = item.element;
return el.tooltipPosition();
return el.tooltipPosition();
};
exports.flatten = flatten;
exports.group = group;
exports.index = index;
exports.isObject = isObject;
exports.sort = sort;
exports.sum = sum;
Object.defineProperty(exports, '__esModule', { value: true });
})));
/*!
* chartjs-chart-treemap v1.0.0-beta.3
* chartjs-chart-treemap v1.0.0-beta.4
* https://github.com/kurkle/chartjs-chart-treemap#readme
* (c) 2020 Jukka Kurkela
* (c) 2021 Jukka Kurkela
* Released under the MIT license
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Chart,t.Chart.helpers)}(this,(function(t,e){"use strict";function n(t){const e=typeof t;return"function"===e||"object"===e&&!!t}function i(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)||0}function r(t,e,n,i){const r=t._normalized,o=e*r/n,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===i?s:a,h:"_ix"===i?a:s}}const o=(t,e)=>i(t.rtl?t.x+t.w-t._ix-e:t.x+t._ix,4);function s(t,e,n,r){const s={x:o(t,n.w),y:i(t.y+t._iy,4),w:i(n.w,4),h:i(n.h,4),a:i(e._normalized,4),v:e.value,s:r,_data:e._data};return e.group&&(s.g=e.group,s.l=e.level,s.gs=e.groupSum),s}class a{constructor(t){const e=this;t=t||{w:1,h:1},e.rtl=!!t.rtl,e.x=t.x||t.left||0,e.y=t.y||t.top||0,e._ix=0,e._iy=0,e.w=t.w||t.width||t.right-t.left,e.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return"x"===this.dir?this.iw:this.ih}map(t){const e=this,n=[],i=t.nsum,o=t.get(),a=e.dir,h=e.side,l=h*h,u="x"===a?"_ix":"_iy",d=i*i;let c=0,g=0;for(const i of o){const o=r(i,l,d,u);g+=o.d1,c=Math.max(c,o.d2),n.push(s(e,i,o,t.sum)),e[u]+=o.d1}return e["y"===a?"_ix":"_iy"]+=c,e[u]-=g,n}}const h=Math.min,l=Math.max;function u(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:h(t.min,n),max:l(t.max,n),sum:t.sum+n,nmin:h(t.nmin,i),nmax:l(t.nmax,i),nsum:t.nsum+i}}function d(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class c{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){d(this,t,u(this,t))}pushIf(t,e,...n){const i=u(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;d(this,t,i)}get(){return this._arr}}function g(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 p(t,e,i,r,o,s){t=t||[];const h=[],l=new a(e),u=new c("value",l.area/function(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}(t,i));let d=l.side;const p=t.length;let f,m;if(!p)return h;const x=t.slice();i=function(t,e){let i,r=t.length;if(!r)return e;const o=n(t[0]);for(e=o?e:"v",i=0,r=t.length;i<r;++i)o?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}(x,i),function(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}(x,i);const y=t=>r&&x[t][r];for(f=0;f<p;++f)m={value:(v=f,i?+x[v][i]:+x[v]),groupSum:s,_data:t[x[f]._idx]},r&&(m.level=o,m.group=y(f)),m=u.pushIf(m,g,d),m&&(h.push(l.map(u)),d=l.side,u.reset(),u.push(m));var v;return u.length&&h.push(l.map(u)),function(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}(h)}function f(t,e){if(!e)return!1;const n=t.width||t.w,i=t.height||t.h,r=2*e.lineHeight;return n>r&&i>r}function m(t,e,n,i,r){if(t.save(),t.fillStyle=i.font.color,t.font=i.font.string,t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.clip(),"l"in n&&n.l!==r){if(i.groupLabels){t.textAlign=i.rtl?"end":"start",t.textBaseline="top";const r=i.rtl?e.x+e.width-i.borderWidth-3:e.x+i.borderWidth+3;t.fillText(n.g,r,e.y+i.borderWidth+3)}}else t.textAlign="center",t.textBaseline="middle",function(t,e,n){const i=n.options,r=i.font.lineHeight,o=(i.label||e.g+"\n"+e.v).split("\n"),s=n.y+n.height/2-o.length*r/4;o.forEach(((e,i)=>t.fillText(e,n.x+n.width/2,s+i*r)))}(t,n,e);t.restore()}function x(t,e){const n=e.options,i=e.width||e.w,r=e.height||e.h;if(t.save(),t.strokeStyle=n.dividerColor||"black",t.lineCap=n.dividerCapStyle,t.setLineDash(n.dividerDash||[]),t.lineDashOffset=n.dividerDashOffset,t.lineWidth=n.dividerWidth,t.beginPath(),i>r){const n=i/2;t.moveTo(e.x+n,e.y),t.lineTo(e.x+n,e.y+r)}else{const n=r/2;t.moveTo(e.x,e.y+n),t.lineTo(e.x+i,e.y+n)}t.stroke(),t.restore()}function y(t,n,i){const r=t.key||"";let o=t.tree||[];const s=t.groups||[],a=s.length,h=(t.spacing||0)+(t.borderWidth||0);return!o.length&&t.data.length&&(o=t.tree=t.data),a?function n(l,u,d,c){const g=s[l],m=l>0&&s[l-1],x=p(function(t,e,n,i,r){const o=Object.create(null),s=Object.create(null),a=[];let h,l,u,d;for(l=0,u=t.length;l<u;++l)d=t[l],i&&d[i]!==r||(h=d[e]||"",h in o||(o[h]=0,s[h]=[]),o[h]+=+d[n],s[h].push(d));return Object.keys(o).forEach((t=>{d={children:s[t]},d[n]=+o[t],d[e]=t,i&&(d[i]=r),a.push(d)})),a}(o,g,r,m,d),u,r,g,l,c),y=x.slice();let v;return l<a-1&&x.forEach((r=>{v={x:r.x+h,y:r.y+h,w:r.w-2*h,h:r.h-2*h},e.valueOrDefault(t.groupLabels,!0)&&f(r,i)&&(v.y+=i.lineHeight,v.h-=i.lineHeight),y.push(...n(l+1,v,r.g,r.s))})),y}(0,n):p(o,n,r)}class v extends t.DatasetController{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const n=this,i=n.getMeta(),r=n.getDataset(),o=r.groups||(r.groups=[]),s=e.toFont(r.font,n.chart.options.font),a=n.chart.chartArea,h=r.key||"",l=!!r.rtl,u={x:a.left,y:a.top,w:a.right-a.left,h:a.bottom-a.top,rtl:l};var d,c;"reset"!==t&&(d=n._rect,c=u,d&&c&&d.x===c.x&&d.y===c.y&&d.w===c.w&&d.h===c.h)&&n._key===h&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(n._groups,o)||(n._rect=u,n._groups=o.slice(),n._key=h,r.data=y(r,u,s),n._dataCheck(),n._resyncElements()),n.updateElements(i.data,0,i.data.length,t)}resolveDataElementOptions(t,n){const i=super.resolveDataElementOptions(t,n),r=Object.isFrozen(i)?Object.assign({},i):i;return r.font=e.toFont(i.font,this.chart.options.font),r}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),h=r.getSharedOptions(a),l=r.includeOptions(i,h);for(let a=e;a<e+n;a++){const e=s.data[a],n=h||r.resolveDataElementOptions(a,i),u=o?0:e.h-2*n.spacing,d=o?0:e.w-2*n.spacing,c={x:e.x+n.spacing,y:e.y+n.spacing,width:d,height:u};l&&(c.options=n),r.updateElement(t[a],a,c,i)}r.updateSharedOptions(h,i,a)}_drawDividers(t,e,n){for(let i=0,r=n.length;i<r;++i){const r=n[i],o=e[i];r.options.groupDividers&&o._data.children.length>1&&x(t,r)}this.getDataset().groupDividers&&x(t,this._rect)}_drawRects(t,e,n,i){for(let r=0,o=n.length;r<o;++r){const o=n[r],s=e[r];if(!o.hidden){o.draw(t);const e=o.options;f(o,e.font)&&s.g&&m(t,o,s,e,i)}}}draw(){const t=this,e=t.chart.ctx,n=t.getMeta().data||[],i=t.getDataset(),r=(i.groups||[]).length-1,o=i.data||[];t._drawRects(e,o,n,r),t._drawDividers(e,o,n)}}function b(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function w(t,e,n){return Math.max(Math.min(t,n),e)}function _(t){const e=b(t),i=e.right-e.left,r=e.bottom-e.top,o=function(t,e,i){let r,o,s,a;return n(t)?(r=+t.top||0,o=+t.right||0,s=+t.bottom||0,a=+t.left||0):r=o=s=a=+t||0,{t:w(r,0,i),r:w(o,0,e),b:w(s,0,i),l:w(a,0,e)}}(t.options.borderWidth,i/2,r/2);return{outer:{x:e.left,y:e.top,w:i,h:r},inner:{x:e.left+o.l,y:e.top+o.t,w:i-o.l-o.r,h:r-o.t-o.b}}}function D(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&b(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}v.id="treemap",v.defaults={dataElementType:"treemap",dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","dividerColor","dividerDash","dividerDashOffset","dividerWidth","font","groupLabels","groupDividers","spacing","label","rtl"],hover:{mode:"point",intersect:!0},tooltips:{mode:"point",position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex];return e.label+": "+n.v}}},datasets:{groupLabels:!0,borderWidth:0,spacing:.5,groupDividers:!1,dividerWidth:1},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}};class C extends t.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const e=this.options,{inner:n,outer:i}=_(this);t.save(),i.w!==n.w||i.h!==n.h?(t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.rect(n.x,n.y,n.w,n.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(n.x,n.y,n.w,n.h)),t.restore()}inRange(t,e,n){return D(this,t,e,n)}inXRange(t,e){return D(this,t,null,e)}inYRange(t,e){return D(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}C.id="treemap",C.defaults={dividerCapStyle:"butt",dividerColor:"black",dividerDash:void 0,dividerDashOffset:0,dividerWidth:0,groupDividers:!1},C.defaultRoutes={backgroundColor:"color",borderColor:"color"},t.Chart.register(v,C);t.Chart.registry.plugins.get("tooltip").positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()}}));
!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){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function r(t,e,n,i,r){const o=Object.create(null),s=Object.create(null),a=[];let h,l,u,d;for(l=0,u=t.length;l<u;++l)d=t[l],i&&d[i]!==r||(h=d[e]||"",h in o||(o[h]=0,s[h]=[]),o[h]+=+d[n],s[h].push(d));return Object.keys(o).forEach((t=>{d={children:s[t]},d[n]=+o[t],d[e]=t,i&&(d[i]=r),a.push(d)})),a}function o(t){const e=typeof t;return"function"===e||"object"===e&&!!t}function s(t,e){let n,i=t.length;if(!i)return e;const r=o(t[0]);for(e=r?e:"v",n=0,i=t.length;n<i;++n)r?t[n]._idx=n:t[n]={v:t[n],_idx:n};return e}function a(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function h(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 l(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)||0}function u(t,e,n,i){const r=t._normalized,o=e*r/n,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===i?s:a,h:"_ix"===i?a:s}}const d=(t,e)=>l(t.rtl?t.x+t.w-t._ix-e:t.x+t._ix,4);function c(t,e,n,i){const r={x:d(t,n.w),y:l(t.y+t._iy,4),w:l(n.w,4),h:l(n.h,4),a:l(e._normalized,4),v:e.value,s:i,_data:e._data};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class g{constructor(t){const e=this;t=t||{w:1,h:1},e.rtl=!!t.rtl,e.x=t.x||t.left||0,e.y=t.y||t.top||0,e._ix=0,e._iy=0,e.w=t.w||t.width||t.right-t.left,e.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return"x"===this.dir?this.iw:this.ih}map(t){const e=this,n=[],i=t.nsum,r=t.get(),o=e.dir,s=e.side,a=s*s,h="x"===o?"_ix":"_iy",l=i*i;let d=0,g=0;for(const i of r){const r=u(i,a,l,h);g+=r.d1,d=Math.max(d,r.d2),n.push(c(e,i,r,t.sum)),e[h]+=r.d1}return e["y"===o?"_ix":"_iy"]+=d,e[h]-=g,n}}const p=Math.min,f=Math.max;function m(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:p(t.min,n),max:f(t.max,n),sum:t.sum+n,nmin:p(t.nmin,i),nmax:f(t.nmax,i),nsum:t.nsum+i}}function x(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class y{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){x(this,t,m(this,t))}pushIf(t,e,...n){const i=m(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;x(this,t,i)}get(){return this._arr}}function v(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function b(t,e,n,r,o,l){t=t||[];const u=[],d=new g(e),c=new y("value",d.area/h(t,n));let p=d.side;const f=t.length;let m,x;if(!f)return u;const b=t.slice();n=s(b,n),a(b,n);const w=t=>r&&b[t][r];for(m=0;m<f;++m)x={value:(_=m,n?+b[_][n]:+b[_]),groupSum:l,_data:t[b[m]._idx]},r&&(x.level=o,x.group=w(m)),x=c.pushIf(x,v,p),x&&(u.push(d.map(c)),p=d.side,c.reset(),c.push(x));var _;return c.length&&u.push(d.map(c)),i(u)}function w(t,e){if(!e)return!1;const n=t.width||t.w,i=t.height||t.h,r=2*e.lineHeight;return n>r&&i>r}function _(t,e,n,i,r){if(t.save(),t.fillStyle=i.color,t.font=i.font.string,t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.clip(),"l"in n&&n.l!==r){if(i.groupLabels){t.textAlign=i.rtl?"end":"start",t.textBaseline="top";const r=i.rtl?e.x+e.width-i.borderWidth-3:e.x+i.borderWidth+3;t.fillText(n.g,r,e.y+i.borderWidth+3)}}else t.textAlign="center",t.textBaseline="middle",function(t,e,n){const i=n.options,r=i.font.lineHeight,o=(i.label||e.g+"\n"+e.v).split("\n"),s=n.y+n.height/2-o.length*r/4;o.forEach(((e,i)=>t.fillText(e,n.x+n.width/2,s+i*r)))}(t,n,e);t.restore()}function D(t,e){const n=e.options,i=e.width||e.w,r=e.height||e.h;if(t.save(),t.strokeStyle=n.dividerColor||"black",t.lineCap=n.dividerCapStyle,t.setLineDash(n.dividerDash||[]),t.lineDashOffset=n.dividerDashOffset,t.lineWidth=n.dividerWidth,t.beginPath(),i>r){const n=i/2;t.moveTo(e.x+n,e.y),t.lineTo(e.x+n,e.y+r)}else{const n=r/2;t.moveTo(e.x,e.y+n),t.lineTo(e.x+i,e.y+n)}t.stroke(),t.restore()}class O extends e.DatasetController{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this,i=e.getMeta(),o=e.getDataset(),s=o.groups||(o.groups=[]),a=n.toFont(o.font,e.chart.options.font),h=e.chart.chartArea,l=o.key||"",u=!!o.rtl,d={x:h.left,y:h.top,w:h.right-h.left,h:h.bottom-h.top,rtl:u};var c,g;"reset"!==t&&(c=e._rect,g=d,c&&g&&c.x===g.x&&c.y===g.y&&c.w===g.w&&c.h===g.h)&&e._key===l&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(e._groups,s)||(e._rect=d,e._groups=s.slice(),e._key=l,o.data=function(t,e,i){const o=t.key||"";let s=t.tree||[];const a=t.groups||[],h=a.length,l=(t.spacing||0)+(t.borderWidth||0);return!s.length&&t.data.length&&(s=t.tree=t.data),h?function e(u,d,c,g){const p=a[u],f=u>0&&a[u-1],m=b(r(s,p,o,f,c),d,o,p,u,g),x=m.slice();let y;return u<h-1&&m.forEach((r=>{y={x:r.x+l,y:r.y+l,w:r.w-2*l,h:r.h-2*l},n.valueOrDefault(t.groupLabels,!0)&&w(r,i)&&(y.y+=i.lineHeight,y.h-=i.lineHeight),x.push(...e(u+1,y,r.g,r.s))})),x}(0,e):b(s,e,o)}(o,d,a),e._dataCheck(),e._resyncElements()),e.updateElements(i.data,0,i.data.length,t)}resolveDataElementOptions(t,e){const i=super.resolveDataElementOptions(t,e),r=Object.isFrozen(i)?Object.assign({},i):i;return r.font=n.toFont(i.font,this.chart.options.font),r}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),h=r.getSharedOptions(a),l=r.includeOptions(i,h);for(let a=e;a<e+n;a++){const e=s.data[a],n=h||r.resolveDataElementOptions(a,i),u=o?0:e.h-2*n.spacing,d=o?0:e.w-2*n.spacing,c={x:e.x+n.spacing,y:e.y+n.spacing,width:d,height:u};l&&(c.options=n),r.updateElement(t[a],a,c,i)}r.updateSharedOptions(h,i,a)}_drawDividers(t,e,n){for(let i=0,r=n.length;i<r;++i){const r=n[i],o=e[i];r.options.groupDividers&&o._data.children.length>1&&D(t,r)}this.getDataset().groupDividers&&D(t,this._rect)}_drawRects(t,e,n,i){for(let r=0,o=n.length;r<o;++r){const o=n[r],s=e[r];if(!o.hidden){o.draw(t);const e=o.options;w(o,e.font)&&s.g&&_(t,o,s,e,i)}}}draw(){const t=this,e=t.chart.ctx,n=t.getMeta().data||[],i=t.getDataset(),r=(i.groups||[]).length-1,o=i.data||[];t._drawRects(e,o,n,r),t._drawDividers(e,o,n)}}function C(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function k(t,e,n){return Math.max(Math.min(t,n),e)}function j(t){const e=C(t),n=e.right-e.left,i=e.bottom-e.top,r=function(t,e,n){let i,r,s,a;return o(t)?(i=+t.top||0,r=+t.right||0,s=+t.bottom||0,a=+t.left||0):i=r=s=a=+t||0,{t:k(i,0,n),r:k(r,0,e),b:k(s,0,n),l:k(a,0,e)}}(t.options.borderWidth,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+r.l,y:e.top+r.t,w:n-r.l-r.r,h:i-r.t-r.b}}}function E(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&C(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}O.id="treemap",O.defaults={dataElementType:"treemap",groupLabels:!0,borderWidth:0,spacing:.5,groupDividers:!1,dividerWidth:1},O.overrides={interaction:{mode:"point",intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}};class S extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const e=this.options,{inner:n,outer:i}=j(this);t.save(),i.w!==n.w||i.h!==n.h?(t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.rect(n.x,n.y,n.w,n.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(n.x,n.y,n.w,n.h)),t.restore()}inRange(t,e,n){return E(this,t,e,n)}inXRange(t,e){return E(this,t,null,e)}inYRange(t,e){return E(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}S.id="treemap",S.defaults={borderSkipped:void 0,borderWidth:void 0,color:void 0,dividerCapStyle:"butt",dividerColor:"black",dividerDash:void 0,dividerDashOffset:0,dividerWidth:0,font:{},groupDividers:!1,groupLabels:void 0,spacing:void 0,label:void 0,rtl:void 0},S.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},e.Chart.register(O,S);e.Chart.registry.plugins.get("tooltip").positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()},t.flatten=i,t.group=r,t.index=s,t.isObject=o,t.sort=a,t.sum=h,Object.defineProperty(t,"__esModule",{value:!0})}));
{
"name": "chartjs-chart-treemap",
"version": "1.0.0-beta.3",
"version": "1.0.0-beta.4",
"description": "Chart.js module for creating treemap charts",

@@ -10,6 +10,8 @@ "main": "dist/chartjs-chart-treemap.js",

"build": "rollup -c",
"dev": "karma start ---auto-watch --no-single-run --browsers chrome",
"docs": "cd docs && npm install && npm run build && mkdir -p ../dist && cp -r build ../dist/docs",
"lint": "eslint samples/**/*.html samples/**/*.js src/**/*.js test/**/*.js",
"test": "npm run lint && karma start --no-auto-watch --single-run --coverage"
"dev": "karma start --no-signle-run --auto-watch --browsers chrome",
"lint": "eslint --ignore-path .gitignore .",
"lint-fix": "eslint --ignore-path .gitignore --fix .",
"test": "cross-env NODE_ENV=test concurrently \"npm:test-*\"",
"test-lint": "npm run lint",
"test-karma": "karma start --auto-watch --single-run"
},

@@ -35,30 +37,33 @@ "repository": {

"devDependencies": {
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"chart.js": "^3.0.0-beta.6",
"eslint": "^7.13.0",
"eslint-config-chartjs": "^0.2.0",
"eslint-config-esnext": "^4.1.0",
"eslint-plugin-html": "^6.1.1",
"jasmine": "^3.6.3",
"jasmine-core": "^3.6.0",
"karma": "^5.2.3",
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-node-resolve": "^11.2.0",
"chart.js": "^3.0.0-rc.2",
"chartjs-adapter-date-fns": "^1.1.0-beta.1",
"chartjs-test-utils": "^0.2.2",
"concurrently": "^6.0.0",
"cross-env": "^7.0.3",
"date-fns": "^2.19.0",
"eslint": "^7.22.0",
"eslint-config-chartjs": "^0.3.0",
"eslint-plugin-es": "^4.1.0",
"eslint-plugin-html": "^6.1.2",
"jasmine-core": "^3.7.1",
"karma": "^6.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-instrumenter": "^1.0.3",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-coverage": "^2.0.3",
"karma-firefox-launcher": "^2.1.0",
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"karma-rollup-preprocessor": "^7.0.5",
"karma-rollup-preprocessor": "^7.0.7",
"karma-spec-reporter": "0.0.32",
"karma-summary-reporter": "^1.9.0",
"minimist": "^1.2.5",
"karma-summary-reporter": "^2.0.2",
"pixelmatch": "^5.2.1",
"rollup": "^2.33.2",
"rollup": "^2.42.1",
"rollup-plugin-istanbul": "^3.0.0",
"rollup-plugin-terser": "^7.0.2"
},
"peerDependencies": {
"chart.js": "^3.0.0-beta.3"
"chart.js": "^3.0.0-beta.10"
},
"dependencies": {}
}
# chartjs-chart-treemap
[Chart.js](https://www.chartjs.org/) **v3.0.0-beta.3** module for creating treemap charts. Implementation for Chart.js v2 is in [2.x branch](https://github.com/kurkle/chartjs-chart-treemap/tree/2.x)
[Chart.js](https://www.chartjs.org/) **v3.0.0-beta.10** module for creating treemap charts. Implementation for Chart.js v2 is in [2.x branch](https://github.com/kurkle/chartjs-chart-treemap/tree/2.x)
![npm](https://img.shields.io/npm/v/chartjs-chart-treemap.svg) [![release](https://img.shields.io/github/release/kurkle/chartjs-chart-treemap.svg?style=flat-square)](https://github.com/kurkle/chartjs-chart-treemap/releases/latest) [![travis](https://img.shields.io/travis/kurkle/chartjs-chart-treemap.svg?style=flat-square&maxAge=60)](https://travis-ci.org/kurkle/chartjs-chart-treemap) ![npm bundle size](https://img.shields.io/bundlephobia/min/chartjs-chart-treemap.svg) ![GitHub](https://img.shields.io/github/license/kurkle/chartjs-chart-treemap.svg)
[![npm](https://img.shields.io/npm/v/chartjs-chart-treemap.svg)](https://www.npmjs.com/package/chartjs-chart-matrix)
[![release](https://img.shields.io/github/release/kurkle/chartjs-chart-treemap.svg?style=flat-square)](https://github.com/kurkle/chartjs-chart-treemap/releases/latest)
![npm bundle size](https://img.shields.io/bundlephobia/min/chartjs-chart-treemap.svg)
![GitHub](https://img.shields.io/github/license/kurkle/chartjs-chart-treemap.svg)

@@ -83,9 +86,7 @@ ## Documentation

```bash
> gulp build // build dist files
> gulp build --watch // build and watch for changes
> gulp test // run all tests
> gulp test --watch // run all tests and watch for changes
> gulp test --coverage // run all tests and generate code coverage
> gulp lint // perform code linting
> gulp package // create an archive with dist files and samples
> npm run build // build dist files
> npm run dev // build and watch for changes
> npm test // run all tests
> npm run lint // perform code linting
> npm package // create an archive with dist files and samples
```

@@ -95,2 +96,2 @@

chartjs-chart-treemap is available under the [MIT license](https://opensource.org/licenses/MIT).
chartjs-chart-treemap is available under the [MIT license](https://opensource.org/licenses/MIT).
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc