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-alpha to 1.0.0-beta

1319

dist/chartjs-chart-treemap.esm.js
/*!
* chartjs-chart-treemap v1.0.0-alpha
* chartjs-chart-treemap v1.0.0-beta
* https://github.com/kurkle/chartjs-chart-treemap#readme

@@ -7,798 +7,791 @@ * (c) 2020 Jukka Kurkela

*/
import Chart from 'chart.js';
import { DatasetController, Element } from 'chart.js';
import { toFont } from 'chart.js/helpers';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatten(input) {
var stack = [...input];
var res = [];
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();
}
while (stack.length) {
// pop value from stack
var next = stack.pop();
/**
* @param {[]} values
* @param {string} grp
* @param {string} key
* @param {string} [mainGrp]
* @param {*} [mainValue]
*/
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);
}
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
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 res.reverse();
return ret;
}
function group(values, grp, key, mainGrp, mainValue) {
var tmp = Object.create(null);
var data = Object.create(null);
var ret = [];
var 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);
});
return ret;
}
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function index(values, key) {
var n = values.length;
var i;
let n = values.length;
let i;
if (!n) {
return key;
}
if (!n) {
return key;
}
var 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
};
}
}
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;
}
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) {
var 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);
return +(Math.round(v + 'e+' + n) + 'e-' + n);
}
function getDims(itm, w2, s2, key) {
var a = itm._normalized;
var ar = w2 * a / s2;
var d1 = Math.sqrt(a * ar);
var d2 = a / d1;
var w = key === '_ix' ? d1 : d2;
var h = key === '_ix' ? d2 : d1;
return {
d1,
d2,
w,
h
};
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};
}
function buildRow(rect, itm, dims, sum) {
var r = {
x: round(rect.x + rect._ix, 4),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: itm._normalized,
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: round(rect.x + rect._ix, 4),
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) {
var me = this;
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.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() {
var 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) {
var me = this;
var ret = [];
var sum = arr.nsum;
var row = arr.get();
var n = row.length;
var dir = me.dir;
var side = me.side;
var w2 = side * side;
var key = dir === 'x' ? '_ix' : '_iy';
var s2 = sum * sum;
var maxd2 = 0;
var totd1 = 0;
var i, itm, dims;
for (i = 0; i < n; ++i) {
itm = row[i];
dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
if (dims.d2 > maxd2) {
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 n = row.length;
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;
let i, itm, dims;
for (i = 0; i < n; ++i) {
itm = row[i];
dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
if (dims.d2 > maxd2) {
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;
}
}
var min = Math.min;
var max = Math.max;
const min = Math.min;
const max = Math.max;
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) {
var v = +o[sa.key];
var 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
};
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
};
}
function setStat(sa, stat) {
_extends(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) {
var me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
class StatArray {
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() {
var 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) {
var nstat = getNewStat(this, o);
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
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;
}
var [length] = args;
var os2 = oldStat.nsum * oldStat.nsum;
var ns2 = newStat.nsum * newStat.nsum;
var l2 = length * length;
var or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
var 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;
}
function squarify(values, r, key, grp, lvl, gsum) {
var rows = [];
var rect = new Rect(r);
var row = new statArray('value', rect.area / sum(values, key));
var length = rect.side;
var n = values.length;
var i, o;
/**
*
* @param {number[]|object[]} values
* @param {object} rectangle
* @param {string} key
* @param {*} grp
* @param {*} lvl
* @param {*} gsum
*/
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;
if (!n) {
return rows;
}
if (!n) {
return rows;
}
var tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
function val(idx) {
return key ? +tmp[idx][key] : +tmp[idx];
}
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
function gval(idx) {
return 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]
};
function rectNotEqual(r1, r2) {
return !r1 || !r2
|| r1.x !== r2.x
|| r1.y !== r2.y
|| r1.w !== r2.w
|| r1.h !== r2.h;
}
if (grp) {
o.level = lvl;
o.group = gval(i);
}
function arrayNotEqual(a1, a2) {
let i, n;
o = row.pushIf(o, compareAspectRatio, length);
if (a1.lenght !== a2.length) {
return true;
}
if (o) {
rows.push(rect.map(row));
length = rect.side;
row.reset();
row.push(o);
}
}
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
}
if (row.length) {
rows.push(rect.map(row));
}
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;
}
return flatten(rows);
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 = 'start';
ctx.textBaseline = 'top';
ctx.fillText(item.g, rect.x + opts.borderWidth + 3, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
/**
* Helper function to get the bounds of the rect
* @param {Rectangle} rect the rect
* @param {boolean} [useFinalPosition]
* @return {object} bounds of the rect
* @private
*/
function drawDivider(ctx, rect) {
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
function getBounds(rect, useFinalPosition) {
var {
x,
y,
width,
height
} = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
left: x,
top: y,
right: x + width,
bottom: y + height
};
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 limit(value, min, max) {
return Math.max(Math.min(value, max), min);
}
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);
function parseBorderWidth(rect, maxW, maxH) {
var value = rect.options.borderWidth;
var t, r, b, l;
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 (Chart.helpers.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 (dataset.groupLabels && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
function boundingRects(rect) {
var bounds = getBounds(rect);
var width = bounds.right - bounds.left;
var height = bounds.bottom - bounds.top;
var border = parseBorderWidth(rect, 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 glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
}
function inRange(rect, x, y, useFinalPosition) {
var skipX = x === null;
var skipY = y === null;
var bounds = !rect || skipX && skipY ? false : getBounds(rect, useFinalPosition);
return bounds && (skipX || x >= bounds.left && x <= bounds.right) && (skipY || y >= bounds.top && y <= bounds.bottom);
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));
}
class Rectangle extends Chart.Element {
constructor(cfg) {
super();
this.options = undefined;
this.width = undefined;
this.height = undefined;
class TreemapController extends DatasetController {
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
if (cfg) {
_extends(this, cfg);
}
}
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 || '';
draw(ctx) {
var options = this.options;
var {
inner,
outer
} = boundingRects(this);
ctx.save();
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top};
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 (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();
}
ctx.restore();
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
_updateOptionsWithDefaults(options) {
const me = this;
const dataset = me.getDataset();
const treemapDefaults = me.chart.options.treemap.datasets;
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
options.dividerColor = dataset.dividerColor || treemapDefaults.dividerColor;
options.dividerDash = dataset.dividerDash || treemapDefaults.dividerDash;
options.dividerDashOffset = dataset.dividerDashOffset || treemapDefaults.dividerDashOffset;
options.dividerWidth = dataset.dividerWidth || treemapDefaults.dividerWidth;
options.font = toFont(options.font, me.chart.options.font);
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
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);
// me._updateOptionsWithDefaults(firstOpts);
getCenterPoint(useFinalPosition) {
var {
x,
y,
width,
height
} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
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
};
tooltipPosition() {
return this.getCenterPoint();
}
if (includeOptions) {
properties.options = options;
}
// me._updateOptionsWithDefaults(options);
me.updateElement(rects[i], i, properties, mode);
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
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);
}
}
_defineProperty(Rectangle, "_type", 'rectangle');
_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);
}
}
}
}
var defaults = Chart.defaults;
var helpers = Chart.helpers;
var optionHelpers = helpers.options;
var parseFont = optionHelpers._parseFont;
var resolve = optionHelpers.resolve;
var valueOrDefault = helpers.valueOrDefault;
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 || [];
function rectNotEqual(r1, r2) {
return !r1 || !r2 || r1.x !== r2.x || r1.y !== r2.y || r1.w !== r2.w || r1.h !== r2.h;
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
}
function arrayNotEqual(a1, a2) {
var i, n;
TreemapController.id = 'treemap';
if (a1.lenght !== a2.length) {
return true;
}
TreemapController.defaults = {
dataElementType: 'treemap',
dataElementOptions: [
'backgroundColor',
'borderColor',
'borderSkipped',
'borderWidth',
'dividerColor',
'dividerDash',
'dividerDashOffset',
'dividerWidth',
'font',
'groupLabels',
'groupDividers',
'spacing',
'label'
],
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
}
},
};
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
/**
* Helper function to get the bounds of the rect
* @param {TreemapElement} rect the rect
* @param {boolean} [useFinalPosition]
* @return {object} bounds of the rect
* @private
*/
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};
}
function drawCaption(rect, font) {
var w = rect.width || rect.w;
var h = rect.height || rect.h;
var min = font.lineHeight * 2;
return w > min && h > min;
function limit(value, min, max) {
return Math.max(Math.min(value, max), min);
}
function buildData(dataset, mainRect, font) {
var key = dataset.key || '';
var tree = dataset.tree || [];
var groups = dataset.groups || [];
var glen = groups.length;
var sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
function parseBorderWidth(value, maxW, maxH) {
let t, r, b, l;
function recur(gidx, rect, parent, gs) {
var g = groups[gidx];
var pg = gidx > 0 && groups[gidx - 1];
var gdata = group(tree, g, key, pg, parent);
var gsq = squarify(gdata, rect, key, g, gidx, gs);
var ret = gsq.slice();
var subRect;
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 (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
};
return {
t: limit(t, 0, maxH),
r: limit(r, 0, maxW),
b: limit(b, 0, maxH),
l: limit(l, 0, maxW)
};
}
if (drawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
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);
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
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 ret;
}
function inRange(rect, x, y, useFinalPosition) {
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
return glen ? recur(0, mainRect) : squarify(tree, mainRect, key);
return bounds
&& (skipX || x >= bounds.left && x <= bounds.right)
&& (skipY || y >= bounds.top && y <= bounds.bottom);
}
function parseFontOptions(options) {
return _extends(parseFont({
fontFamily: valueOrDefault(options.fontFamily, defaults.fontFamily),
fontSize: valueOrDefault(options.fontSize, defaults.fontSize),
fontStyle: valueOrDefault(options.fontStyle, defaults.fontStyle),
lineHeight: valueOrDefault(options.lineHeight, defaults.lineHeight)
}), {
color: resolve([options.fontColor, defaults.fontColor])
});
}
class TreemapElement extends Element {
class TreemapController extends Chart.DatasetController {
update(mode) {
var me = this;
var meta = me.getMeta();
var dataset = me.getDataset();
var groups = dataset.groups || (dataset.groups = []);
var font = parseFontOptions(dataset);
var area = me.chart.chartArea;
var key = dataset.key || '';
var mainRect = {
x: area.left,
y: area.top,
w: area.right - area.left,
h: area.bottom - area.top
};
constructor(cfg) {
super();
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);
this.options = undefined;
this.width = undefined;
this.height = undefined;
me._dataCheck();
if (cfg) {
Object.assign(this, cfg);
}
}
me._resyncElements();
}
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
me.updateElements(meta.data, 0, mode);
}
ctx.save();
updateElements(rects, start, mode) {
var me = this;
var reset = mode === 'reset';
var dataset = me.getDataset();
var firstOpts = me.resolveDataElementOptions(start, mode);
var sharedOptions = me.getSharedOptions(mode, rects[start], firstOpts);
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);
}
for (var i = 0; i < rects.length; i++) {
var index = start + i;
var sq = dataset.data[index];
var options = me.resolveDataElementOptions(i, mode);
var height = reset ? 0 : sq.h - options.spacing * 2;
var width = reset ? 0 : sq.w - options.spacing * 2;
var x = sq.x + options.spacing;
var y = sq.y + options.spacing;
var properties = {
x,
y,
width,
height,
options
};
options.font = parseFont(options);
me.updateElement(rects[i], index, properties, mode);
}
ctx.restore();
}
me.updateSharedOptions(sharedOptions, mode);
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
draw() {
var me = this;
var metadata = me.getMeta().data || [];
var dataset = me.getDataset();
var levels = (dataset.groups || []).length - 1;
var data = dataset.data || [];
var ctx = me.chart.ctx;
var i, ilen, rect, item;
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
for (i = 0, ilen = metadata.length; i < ilen; ++i) {
rect = metadata[i];
item = data[i];
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
if (!rect.hidden) {
rect.draw(ctx);
var opts = rect.options;
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
if (drawCaption(rect, opts.font) && item.g) {
ctx.save();
ctx.fillStyle = opts.fontColor;
ctx.font = opts.font.string;
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.clip();
tooltipPosition() {
return this.getCenterPoint();
}
if (!('l' in item) || item.l === levels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(item.g, rect.x + rect.width / 2, rect.y + rect.height / 2);
} else {
ctx.textAlign = 'start';
ctx.textBaseline = 'top';
ctx.fillText(item.g, rect.x + opts.borderWidth + 3, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
}
}
}
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
}
TreemapController.prototype.dataElementType = Rectangle;
TreemapController.prototype.dataElementOptions = ['backgroundColor', 'borderColor', 'borderSkipped', 'borderWidth', 'fontColor', 'fontFamily', 'fontSize', 'fontStyle', 'spacing'];
var defaults$1 = {
hover: {
mode: 'point',
intersect: true
},
tooltips: {
mode: 'point',
position: 'treemap',
intersect: true,
callbacks: {
title(item, data) {
return data.datasets[item[0].datasetIndex].key;
},
TreemapElement.id = 'treemap';
label(item, data) {
var dataset = data.datasets[item.datasetIndex];
var dataItem = dataset.data[item.index];
return dataset.label + ': ' + dataItem.v;
}
TreemapElement.defaults = {
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
groupDividers: false,
};
}
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
elements: {
rectangle: {
borderWidth: 0,
spacing: 0.5
}
}
TreemapElement.defaultRoutes = {
backgroundColor: 'color',
borderColor: 'color'
};
Chart.controllers.treemap = TreemapController;
Chart.defaults.treemap = defaults$1;
var tooltipPlugin = Chart.plugins.getAll().find(p => p.id === 'tooltip');
tooltipPlugin.positioners.treemap = function (active) {
if (!active.length) {
return false;
}
var item = active[active.length - 1];
var el = item.element;
return {
x: el.x + el.width / 2,
y: el.y + el.height / 2
};
};
export { Rect, TreemapElement as Rectangle, StatArray, TreemapController, flatten, group, index, isObject, sort, squarify, sum };
/*!
* chartjs-chart-treemap v1.0.0-alpha
* chartjs-chart-treemap v1.0.0-beta
* https://github.com/kurkle/chartjs-chart-treemap#readme

@@ -8,625 +8,646 @@ * (c) 2020 Jukka Kurkela

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('chart.js')) :
typeof define === 'function' && define.amd ? define(['chart.js'], factory) :
(global = global || self, factory(global.Chart));
}(this, (function (Chart) { 'use strict';
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';
Chart = Chart && Object.prototype.hasOwnProperty.call(Chart, 'default') ? Chart['default'] : Chart;
// 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();
}
function _typeof(obj) {
"@babel/helpers - typeof";
/**
* @param {[]} values
* @param {string} grp
* @param {string} key
* @param {string} [mainGrp]
* @param {*} [mainValue]
*/
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);
}
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
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 _typeof(obj);
return ret;
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
function isObject(obj) {
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function index(values, key) {
let n = values.length;
let i;
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
if (!n) {
return key;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
const obj = isObject(values[0]);
key = obj ? key : 'v';
return obj;
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 _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
function sort(values, key) {
if (key) {
values.sort((a, b) => +b[key] - +a[key]);
} else {
values.sort((a, b) => +b - +a);
}
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
function sum(values, key) {
let s, i, n;
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
return s;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
function round(v, n) {
return +(Math.round(v + 'e+' + n) + 'e-' + n);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
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;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
return {d1, d2, w, h};
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
function buildRow(rect, itm, dims, sum) {
const r = {
x: round(rect.x + rect._ix, 4),
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.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);
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
get area() {
return this.w * this.h;
}
return _assertThisInitialized(self);
}
get iw() {
return this.w - this._ix;
}
function _createSuper(Derived) {
return function () {
var Super = _getPrototypeOf(Derived),
result;
get ih() {
return this.h - this._iy;
}
if (_isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
get dir() {
const ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
get side() {
return this.dir === 'x' ? this.iw : this.ih;
}
return _possibleConstructorReturn(this, result);
};
map(arr) {
const me = this;
const ret = [];
const sum = arr.nsum;
const row = arr.get();
const n = row.length;
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;
let i, itm, dims;
for (i = 0; i < n; ++i) {
itm = row[i];
dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
if (dims.d2 > maxd2) {
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;
}
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
const min = Math.min;
const max = Math.max;
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
function getStat(sa) {
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function getNewStat(sa, o) {
const v = +o[sa.key];
const n = v * sa.ratio;
o._normalized = n;
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
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 _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
function setStat(sa, stat) {
Object.assign(sa, stat);
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
function push(sa, o, stat) {
sa._arr.push(o);
setStat(sa, stat);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
class StatArray {
constructor(key, ratio) {
const me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
get length() {
return this._arr.length;
}
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
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;
}
return arr2;
}
push(o) {
push(this, o, getNewStat(this, o));
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
pushIf(o, fn, ...args) {
const nstat = getNewStat(this, o);
if (!fn(getStat(this), nstat, args)) {
return o;
}
push(this, o, nstat);
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
get() {
return this._arr;
}
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatten(input) {
var stack = _toConsumableArray(input);
function compareAspectRatio(oldStat, newStat, args) {
if (oldStat.sum === 0) {
return true;
}
var res = [];
while (stack.length) {
// pop value from stack
var next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push.apply(stack, _toConsumableArray(next));
} else {
res.push(next);
}
} // reverse to restore input order
return res.reverse();
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;
}
function group(values, grp, key, mainGrp, mainValue) {
var tmp = Object.create(null);
var data = Object.create(null);
var ret = [];
var g, i, n, v;
for (i = 0, n = values.length; i < n; ++i) {
v = values[i];
/**
*
* @param {number[]|object[]} values
* @param {object} rectangle
* @param {string} key
* @param {*} grp
* @param {*} lvl
* @param {*} gsum
*/
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;
if (mainGrp && v[mainGrp] !== mainValue) {
continue;
}
if (!n) {
return rows;
}
g = v[grp] || '';
const tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
if (!(g in tmp)) {
tmp[g] = 0;
data[g] = [];
}
const val = (idx) => key ? +tmp[idx][key] : +tmp[idx];
const gval = (idx) => grp && tmp[idx][grp];
tmp[g] += +v[key];
data[g].push(v);
}
Object.keys(tmp).forEach(function (k) {
v = {
children: data[k]
};
v[key] = +tmp[k];
v[grp] = k;
if (mainGrp) {
v[mainGrp] = mainValue;
}
ret.push(v);
});
return ret;
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 isObject(obj) {
var type = _typeof(obj);
return type === 'function' || type === 'object' && !!obj;
function rectNotEqual(r1, r2) {
return !r1 || !r2
|| r1.x !== r2.x
|| r1.y !== r2.y
|| r1.w !== r2.w
|| r1.h !== r2.h;
}
function index(values, key) {
var n = values.length;
var i;
if (!n) {
return key;
}
function arrayNotEqual(a1, a2) {
let i, n;
var obj = isObject(values[0]);
key = obj ? key : 'v';
if (a1.lenght !== a2.length) {
return true;
}
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 = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
return false;
}
function sort(values, key) {
if (key) {
values.sort(function (a, b) {
return +b[key] - +a[key];
});
} else {
values.sort(function (a, b) {
return +b - +a;
});
}
}
function sum(values, key) {
var s, i, n;
for (s = 0, i = 0, n = values.length; i < n; ++i) {
s += key ? +values[i][key] : +values[i];
}
return s;
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;
}
function round(v, n) {
return +(Math.round(v + 'e+' + n) + 'e-' + n);
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 = 'start';
ctx.textBaseline = 'top';
ctx.fillText(item.g, rect.x + opts.borderWidth + 3, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
function getDims(itm, w2, s2, key) {
var a = itm._normalized;
var ar = w2 * a / s2;
var d1 = Math.sqrt(a * ar);
var d2 = a / d1;
var w = key === '_ix' ? d1 : d2;
var h = key === '_ix' ? d2 : d1;
return {
d1: d1,
d2: d2,
w: w,
h: h
};
}
function drawDivider(ctx, rect) {
const opts = rect.options;
const w = rect.width || rect.w;
const h = rect.height || rect.h;
function buildRow(rect, itm, dims, sum) {
var r = {
x: round(rect.x + rect._ix, 4),
y: round(rect.y + rect._iy, 4),
w: round(dims.w, 4),
h: round(dims.h, 4),
a: itm._normalized,
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;
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();
}
var Rect = /*#__PURE__*/function () {
function Rect(r) {
_classCallCheck(this, Rect);
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);
var me = this;
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;
}
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};
_createClass(Rect, [{
key: "map",
value: function map(arr) {
var me = this;
var ret = [];
var sum = arr.nsum;
var row = arr.get();
var n = row.length;
var dir = me.dir;
var side = me.side;
var w2 = side * side;
var key = dir === 'x' ? '_ix' : '_iy';
var s2 = sum * sum;
var maxd2 = 0;
var totd1 = 0;
var i, itm, dims;
if (dataset.groupLabels && shouldDrawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
});
}
return ret;
}
for (i = 0; i < n; ++i) {
itm = row[i];
dims = getDims(itm, w2, s2, key);
totd1 += dims.d1;
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
if (dims.d2 > maxd2) {
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;
}
}, {
key: "area",
get: function get() {
return this.w * this.h;
}
}, {
key: "iw",
get: function get() {
return this.w - this._ix;
}
}, {
key: "ih",
get: function get() {
return this.h - this._iy;
}
}, {
key: "dir",
get: function get() {
var ih = this.ih;
return ih <= this.iw && ih > 0 ? 'y' : 'x';
}
}, {
key: "side",
get: function get() {
return this.dir === 'x' ? this.iw : this.ih;
}
}]);
return Rect;
}();
var min = Math.min;
var max = Math.max;
function getStat(sa) {
return {
min: sa.min,
max: sa.max,
sum: sa.sum,
nmin: sa.nmin,
nmax: sa.nmax,
nsum: sa.nsum
};
return glen
? recur(0, mainRect)
: squarify(tree, mainRect, key);
}
function getNewStat(sa, o) {
var v = +o[sa.key];
var 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
};
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));
}
function setStat(sa, stat) {
_extends(sa, stat);
}
class TreemapController extends chart_js.DatasetController {
initialize() {
this.enableOptionSharing = true;
super.initialize();
}
function _push(sa, o, stat) {
sa._arr.push(o);
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 || '';
setStat(sa, stat);
}
const mainRect = {x: area.left, y: area.top, w: area.right - area.left, h: area.bottom - area.top};
var statArray = /*#__PURE__*/function () {
function statArray(key, ratio) {
_classCallCheck(this, statArray);
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();
}
var me = this;
me.key = key;
me.ratio = ratio;
me.reset();
}
me.updateElements(meta.data, 0, meta.data.length, mode);
}
_createClass(statArray, [{
key: "reset",
value: function reset() {
var me = this;
me._arr = [];
me._hist = [];
me.sum = 0;
me.nsum = 0;
me.min = Infinity;
me.max = -Infinity;
me.nmin = Infinity;
me.nmax = -Infinity;
}
}, {
key: "push",
value: function push(o) {
_push(this, o, getNewStat(this, o));
}
}, {
key: "pushIf",
value: function pushIf(o, fn) {
var nstat = getNewStat(this, o);
_updateOptionsWithDefaults(options) {
const me = this;
const dataset = me.getDataset();
const treemapDefaults = me.chart.options.treemap.datasets;
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
options.dividerColor = dataset.dividerColor || treemapDefaults.dividerColor;
options.dividerDash = dataset.dividerDash || treemapDefaults.dividerDash;
options.dividerDashOffset = dataset.dividerDashOffset || treemapDefaults.dividerDashOffset;
options.dividerWidth = dataset.dividerWidth || treemapDefaults.dividerWidth;
options.font = helpers.toFont(options.font, me.chart.options.font);
}
if (!fn(getStat(this), nstat, args)) {
return o;
}
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);
// me._updateOptionsWithDefaults(firstOpts);
_push(this, o, nstat);
}
}, {
key: "get",
value: function get() {
return this._arr;
}
}, {
key: "length",
get: function get() {
return this._arr.length;
}
}]);
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
};
return statArray;
}();
if (includeOptions) {
properties.options = options;
}
// me._updateOptionsWithDefaults(options);
me.updateElement(rects[i], i, properties, mode);
}
function compareAspectRatio(oldStat, newStat, args) {
if (oldStat.sum === 0) {
return true;
}
me.updateSharedOptions(sharedOptions, mode, firstOpts);
}
var _args = _slicedToArray(args, 1),
length = _args[0];
_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);
}
}
var os2 = oldStat.nsum * oldStat.nsum;
var ns2 = newStat.nsum * newStat.nsum;
var l2 = length * length;
var or = Math.max(l2 * oldStat.nmax / os2, os2 / (l2 * oldStat.nmin));
var nr = Math.max(l2 * newStat.nmax / ns2, ns2 / (l2 * newStat.nmin));
return nr <= or;
}
_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);
}
}
}
}
function squarify(values, r, key, grp, lvl, gsum) {
var rows = [];
var rect = new Rect(r);
var row = new statArray('value', rect.area / sum(values, key));
var length = rect.side;
var n = values.length;
var i, o;
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 || [];
if (!n) {
return rows;
}
me._drawRects(ctx, data, metadata, levels);
me._drawDividers(ctx, data, metadata);
}
}
var tmp = values.slice();
key = index(tmp, key);
sort(tmp, key);
TreemapController.id = 'treemap';
function val(idx) {
return key ? +tmp[idx][key] : +tmp[idx];
}
TreemapController.defaults = {
dataElementType: 'treemap',
dataElementOptions: [
'backgroundColor',
'borderColor',
'borderSkipped',
'borderWidth',
'dividerColor',
'dividerDash',
'dividerDashOffset',
'dividerWidth',
'font',
'groupLabels',
'groupDividers',
'spacing',
'label'
],
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
}
},
};
function gval(idx) {
return 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);
}
/**
* Helper function to get the bounds of the rect
* @param {Rectangle} rect the rect
* @param {TreemapElement} rect the rect
* @param {boolean} [useFinalPosition]

@@ -636,431 +657,159 @@ * @return {object} bounds of the rect

*/
function getBounds(rect, useFinalPosition) {
var _rect$getProps = rect.getProps(['x', 'y', 'width', 'height'], useFinalPosition),
x = _rect$getProps.x,
y = _rect$getProps.y,
width = _rect$getProps.width,
height = _rect$getProps.height;
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(rect, maxW, maxH) {
var value = rect.options.borderWidth;
var t, r, b, l;
function parseBorderWidth(value, maxW, maxH) {
let t, r, b, l;
if (Chart.helpers.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) {
var bounds = getBounds(rect);
var width = bounds.right - bounds.left;
var height = bounds.bottom - bounds.top;
var border = parseBorderWidth(rect, 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
}
};
}
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);
function _inRange(rect, x, y, useFinalPosition) {
var skipX = x === null;
var skipY = y === null;
var bounds = !rect || skipX && skipY ? false : getBounds(rect, useFinalPosition);
return bounds && (skipX || x >= bounds.left && x <= bounds.right) && (skipY || y >= bounds.top && y <= bounds.bottom);
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
}
};
}
var Rectangle = /*#__PURE__*/function (_Chart$Element) {
_inherits(Rectangle, _Chart$Element);
function inRange(rect, x, y, useFinalPosition) {
const skipX = x === null;
const skipY = y === null;
const bounds = !rect || (skipX && skipY) ? false : getBounds(rect, useFinalPosition);
var _super = _createSuper(Rectangle);
function Rectangle(cfg) {
var _this;
_classCallCheck(this, Rectangle);
_this = _super.call(this);
_this.options = undefined;
_this.width = undefined;
_this.height = undefined;
if (cfg) {
_extends(_assertThisInitialized(_this), cfg);
}
return _this;
}
_createClass(Rectangle, [{
key: "draw",
value: function draw(ctx) {
var options = this.options;
var _boundingRects = boundingRects(this),
inner = _boundingRects.inner,
outer = _boundingRects.outer;
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);
}
ctx.restore();
}
}, {
key: "inRange",
value: function inRange(mouseX, mouseY, useFinalPosition) {
return _inRange(this, mouseX, mouseY, useFinalPosition);
}
}, {
key: "inXRange",
value: function inXRange(mouseX, useFinalPosition) {
return _inRange(this, mouseX, null, useFinalPosition);
}
}, {
key: "inYRange",
value: function inYRange(mouseY, useFinalPosition) {
return _inRange(this, null, mouseY, useFinalPosition);
}
}, {
key: "getCenterPoint",
value: function getCenterPoint(useFinalPosition) {
var _this$getProps = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition),
x = _this$getProps.x,
y = _this$getProps.y,
width = _this$getProps.width,
height = _this$getProps.height;
return {
x: x + width / 2,
y: y + height / 2
};
}
}, {
key: "tooltipPosition",
value: function tooltipPosition() {
return this.getCenterPoint();
}
}, {
key: "getRange",
value: function getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
}]);
return Rectangle;
}(Chart.Element);
_defineProperty(Rectangle, "_type", 'rectangle');
var defaults = Chart.defaults;
var helpers = Chart.helpers;
var optionHelpers = helpers.options;
var parseFont = optionHelpers._parseFont;
var resolve = optionHelpers.resolve;
var valueOrDefault = helpers.valueOrDefault;
function rectNotEqual(r1, r2) {
return !r1 || !r2 || r1.x !== r2.x || r1.y !== r2.y || r1.w !== r2.w || r1.h !== r2.h;
return bounds
&& (skipX || x >= bounds.left && x <= bounds.right)
&& (skipY || y >= bounds.top && y <= bounds.bottom);
}
function arrayNotEqual(a1, a2) {
var i, n;
class TreemapElement extends chart_js.Element {
if (a1.lenght !== a2.length) {
return true;
}
constructor(cfg) {
super();
for (i = 0, n = a1.length; i < n; ++i) {
if (a1[i] !== a2[i]) {
return true;
}
}
this.options = undefined;
this.width = undefined;
this.height = undefined;
return false;
}
if (cfg) {
Object.assign(this, cfg);
}
}
function drawCaption(rect, font) {
var w = rect.width || rect.w;
var h = rect.height || rect.h;
var min = font.lineHeight * 2;
return w > min && h > min;
}
draw(ctx) {
const options = this.options;
const {inner, outer} = boundingRects(this);
function buildData(dataset, mainRect, font) {
var key = dataset.key || '';
var tree = dataset.tree || [];
var groups = dataset.groups || [];
var glen = groups.length;
var sp = (dataset.spacing || 0) + (dataset.borderWidth || 0);
ctx.save();
function recur(gidx, rect, parent, gs) {
var g = groups[gidx];
var pg = gidx > 0 && groups[gidx - 1];
var gdata = group(tree, g, key, pg, parent);
var gsq = squarify(gdata, rect, key, g, gidx, gs);
var ret = gsq.slice();
var subRect;
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 (gidx < glen - 1) {
gsq.forEach(function (sq) {
subRect = {
x: sq.x + sp,
y: sq.y + sp,
w: sq.w - 2 * sp,
h: sq.h - 2 * sp
};
ctx.restore();
}
if (drawCaption(sq, font)) {
subRect.y += font.lineHeight;
subRect.h -= font.lineHeight;
}
inRange(mouseX, mouseY, useFinalPosition) {
return inRange(this, mouseX, mouseY, useFinalPosition);
}
ret.push.apply(ret, _toConsumableArray(recur(gidx + 1, subRect, sq.g, sq.s)));
});
}
inXRange(mouseX, useFinalPosition) {
return inRange(this, mouseX, null, useFinalPosition);
}
return ret;
}
inYRange(mouseY, useFinalPosition) {
return inRange(this, null, mouseY, useFinalPosition);
}
if (!tree.length && dataset.data.length) {
tree = dataset.tree = dataset.data;
}
getCenterPoint(useFinalPosition) {
const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height'], useFinalPosition);
return {
x: x + width / 2,
y: y + height / 2
};
}
return glen ? recur(0, mainRect) : squarify(tree, mainRect, key);
}
tooltipPosition() {
return this.getCenterPoint();
}
function parseFontOptions(options) {
return _extends(parseFont({
fontFamily: valueOrDefault(options.fontFamily, defaults.fontFamily),
fontSize: valueOrDefault(options.fontSize, defaults.fontSize),
fontStyle: valueOrDefault(options.fontStyle, defaults.fontStyle),
lineHeight: valueOrDefault(options.lineHeight, defaults.lineHeight)
}), {
color: resolve([options.fontColor, defaults.fontColor])
});
getRange(axis) {
return axis === 'x' ? this.width / 2 : this.height / 2;
}
}
var TreemapController = /*#__PURE__*/function (_Chart$DatasetControl) {
_inherits(TreemapController, _Chart$DatasetControl);
TreemapElement.id = 'treemap';
var _super = _createSuper(TreemapController);
TreemapElement.defaults = {
dividerCapStyle: 'butt',
dividerColor: 'black',
dividerDash: undefined,
dividerDashOffset: 0,
dividerWidth: 0,
groupDividers: false,
};
function TreemapController() {
_classCallCheck(this, TreemapController);
TreemapElement.defaultRoutes = {
backgroundColor: 'color',
borderColor: 'color'
};
return _super.apply(this, arguments);
}
chart_js.Chart.register(TreemapController, TreemapElement);
_createClass(TreemapController, [{
key: "update",
value: function update(mode) {
var me = this;
var meta = me.getMeta();
var dataset = me.getDataset();
var groups = dataset.groups || (dataset.groups = []);
var font = parseFontOptions(dataset);
var area = me.chart.chartArea;
var key = dataset.key || '';
var mainRect = {
x: area.left,
y: area.top,
w: area.right - area.left,
h: area.bottom - area.top
};
const tooltipPlugin = chart_js.Chart.registry.plugins.get('tooltip');
tooltipPlugin.positioners.treemap = function(active) {
if (!active.length) {
return false;
}
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);
const item = active[active.length - 1];
const el = item.element;
me._dataCheck();
me._resyncElements();
}
me.updateElements(meta.data, 0, mode);
}
}, {
key: "updateElements",
value: function updateElements(rects, start, mode) {
var me = this;
var reset = mode === 'reset';
var dataset = me.getDataset();
var firstOpts = me.resolveDataElementOptions(start, mode);
var sharedOptions = me.getSharedOptions(mode, rects[start], firstOpts);
for (var i = 0; i < rects.length; i++) {
var index = start + i;
var sq = dataset.data[index];
var options = me.resolveDataElementOptions(i, mode);
var height = reset ? 0 : sq.h - options.spacing * 2;
var width = reset ? 0 : sq.w - options.spacing * 2;
var x = sq.x + options.spacing;
var y = sq.y + options.spacing;
var properties = {
x: x,
y: y,
width: width,
height: height,
options: options
};
options.font = parseFont(options);
me.updateElement(rects[i], index, properties, mode);
}
me.updateSharedOptions(sharedOptions, mode);
}
}, {
key: "draw",
value: function draw() {
var me = this;
var metadata = me.getMeta().data || [];
var dataset = me.getDataset();
var levels = (dataset.groups || []).length - 1;
var data = dataset.data || [];
var ctx = me.chart.ctx;
var i, ilen, rect, item;
for (i = 0, ilen = metadata.length; i < ilen; ++i) {
rect = metadata[i];
item = data[i];
if (!rect.hidden) {
rect.draw(ctx);
var opts = rect.options;
if (drawCaption(rect, opts.font) && item.g) {
ctx.save();
ctx.fillStyle = opts.fontColor;
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';
ctx.fillText(item.g, rect.x + rect.width / 2, rect.y + rect.height / 2);
} else {
ctx.textAlign = 'start';
ctx.textBaseline = 'top';
ctx.fillText(item.g, rect.x + opts.borderWidth + 3, rect.y + opts.borderWidth + 3);
}
ctx.restore();
}
}
}
}
}]);
return TreemapController;
}(Chart.DatasetController);
TreemapController.prototype.dataElementType = Rectangle;
TreemapController.prototype.dataElementOptions = ['backgroundColor', 'borderColor', 'borderSkipped', 'borderWidth', 'fontColor', 'fontFamily', 'fontSize', 'fontStyle', 'spacing'];
var defaults$1 = {
hover: {
mode: 'point',
intersect: true
},
tooltips: {
mode: 'point',
position: 'treemap',
intersect: true,
callbacks: {
title: function title(item, data) {
return data.datasets[item[0].datasetIndex].key;
},
label: function label(item, data) {
var dataset = data.datasets[item.datasetIndex];
var dataItem = dataset.data[item.index];
return dataset.label + ': ' + dataItem.v;
}
}
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
}
},
elements: {
rectangle: {
borderWidth: 0,
spacing: 0.5
}
}
return el.tooltipPosition();
};
Chart.controllers.treemap = TreemapController;
Chart.defaults.treemap = defaults$1;
var tooltipPlugin = Chart.plugins.getAll().find(function (p) {
return p.id === 'tooltip';
});
tooltipPlugin.positioners.treemap = function (active) {
if (!active.length) {
return false;
}
var item = active[active.length - 1];
var el = item.element;
return {
x: el.x + el.width / 2,
y: el.y + el.height / 2
};
};
})));
/*!
* chartjs-chart-treemap v1.0.0-alpha
* chartjs-chart-treemap v1.0.0-beta
* https://github.com/kurkle/chartjs-chart-treemap#readme

@@ -7,2 +7,2 @@ * (c) 2020 Jukka Kurkela

*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("chart.js")):"function"==typeof define&&define.amd?define(["chart.js"],e):e((t=t||self).Chart)}(this,(function(t){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function i(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function o(){return(o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}).apply(this,arguments)}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&l(t,e)}function u(t){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function l(t,e){return(l=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function f(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}function s(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function c(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?s(t):e}function h(t){return function(){var e,n=u(t);if(f()){var r=u(this).constructor;e=Reflect.construct(n,arguments,r)}else e=n.apply(this,arguments);return c(this,e)}}function p(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var n=[],r=!0,i=!1,o=void 0;try{for(var a,u=t[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(t,e)||d(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(t){return function(t){if(Array.isArray(t))return g(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||d(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(t,e){if(t){if("string"==typeof t)return g(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?g(t,e):void 0}}function g(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function m(t,n){var r,i=t.length;if(!i)return n;var o=function(t){var n=e(t);return"function"===n||"object"===n&&!!t}(t[0]);for(n=o?n:"v",r=0,i=t.length;r<i;++r)o?t[r]._idx=r:t[r]={v:t[r],_idx:r};return n}function v(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)}function b(t,e,n,r){var i=t._normalized,o=e*i/n,a=Math.sqrt(i*o),u=i/a;return{d1:a,d2:u,w:"_ix"===r?a:u,h:"_ix"===r?u:a}}function x(t,e,n,r){var i={x:v(t.x+t._ix,4),y:v(t.y+t._iy,4),w:v(n.w,4),h:v(n.h,4),a:e._normalized,v:e.value,s:r,_data:e._data};return e.group&&(i.g=e.group,i.l=e.level,i.gs=e.groupSum),i}t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var w=function(){function t(e){n(this,t);var r=this;r.x=e.x||e.left||0,r.y=e.y||e.top||0,r._ix=0,r._iy=0,r.w=e.w||e.width||e.right-e.left,r.h=e.h||e.height||e.bottom-e.top}return i(t,[{key:"map",value:function(t){var e,n,r,i=this,o=[],a=t.nsum,u=t.get(),l=u.length,f=i.dir,s=i.side,c=s*s,h="x"===f?"_ix":"_iy",p=a*a,y=0,d=0;for(e=0;e<l;++e)d+=(r=b(n=u[e],c,p,h)).d1,r.d2>y&&(y=r.d2),o.push(x(i,n,r,t.sum)),i[h]+=r.d1;return i["y"===f?"_ix":"_iy"]+=y,i[h]-=d,o}},{key:"area",get:function(){return this.w*this.h}},{key:"iw",get:function(){return this.w-this._ix}},{key:"ih",get:function(){return this.h-this._iy}},{key:"dir",get:function(){var t=this.ih;return t<=this.iw&&t>0?"y":"x"}},{key:"side",get:function(){return"x"===this.dir?this.iw:this.ih}}]),t}(),_=Math.min,k=Math.max;function S(t){return{min:t.min,max:t.max,sum:t.sum,nmin:t.nmin,nmax:t.nmax,nsum:t.nsum}}function O(t,e){var n=+e[t.key],r=n*t.ratio;return e._normalized=r,{min:_(t.min,n),max:k(t.max,n),sum:t.sum+n,nmin:_(t.nmin,r),nmax:k(t.nmax,r),nsum:t.nsum+r}}function j(t,e,n){t._arr.push(e),function(t,e){o(t,e)}(t,n)}var A=function(){function t(e,r){n(this,t);this.key=e,this.ratio=r,this.reset()}return i(t,[{key:"reset",value:function(){var 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}},{key:"push",value:function(t){j(this,t,O(this,t))}},{key:"pushIf",value:function(t,e){for(var n=O(this,t),r=arguments.length,i=new Array(r>2?r-2:0),o=2;o<r;o++)i[o-2]=arguments[o];if(!e(S(this),n,i))return t;j(this,t,n)}},{key:"get",value:function(){return this._arr}},{key:"length",get:function(){return this._arr.length}}]),t}();function C(t,e,n){if(0===t.sum)return!0;var r=p(n,1)[0],i=t.nsum*t.nsum,o=e.nsum*e.nsum,a=r*r,u=Math.max(a*t.nmax/i,i/(a*t.nmin));return Math.max(a*e.nmax/o,o/(a*e.nmin))<=u}function E(t,e,n,r,i,o){var a,u,l=[],f=new w(e),s=new A("value",f.area/function(t,e){var n,r,i;for(n=0,r=0,i=t.length;r<i;++r)n+=e?+t[r][e]:+t[r];return n}(t,n)),c=f.side,h=t.length;if(!h)return l;var p,d=t.slice();function g(t){return r&&d[t][r]}for(n=m(d,n),function(t,e){e?t.sort((function(t,n){return+n[e]-+t[e]})):t.sort((function(t,e){return+e-+t}))}(d,n),a=0;a<h;++a)u={value:(p=a,n?+d[p][n]:+d[p]),groupSum:o,_data:t[d[a]._idx]},r&&(u.level=i,u.group=g(a)),(u=s.pushIf(u,C,c))&&(l.push(f.map(s)),c=f.side,s.reset(),s.push(u));return s.length&&l.push(f.map(s)),function(t){for(var e=y(t),n=[];e.length;){var r=e.pop();Array.isArray(r)?e.push.apply(e,y(r)):n.push(r)}return n.reverse()}(l)}function P(t,e){var n=t.getProps(["x","y","width","height"],e),r=n.x,i=n.y;return{left:r,top:i,right:r+n.width,bottom:i+n.height}}function M(t,e,n){return Math.max(Math.min(t,n),e)}function R(e){var n=P(e),r=n.right-n.left,i=n.bottom-n.top,o=function(e,n,r){var i,o,a,u,l=e.options.borderWidth;return t.helpers.isObject(l)?(i=+l.top||0,o=+l.right||0,a=+l.bottom||0,u=+l.left||0):i=o=a=u=+l||0,{t:M(i,0,r),r:M(o,0,n),b:M(a,0,r),l:M(u,0,n)}}(e,r/2,i/2);return{outer:{x:n.left,y:n.top,w:r,h:i},inner:{x:n.left+o.l,y:n.top+o.t,w:r-o.l-o.r,h:i-o.t-o.b}}}function D(t,e,n,r){var i=null===e,o=null===n,a=!(!t||i&&o)&&P(t,r);return a&&(i||e>=a.left&&e<=a.right)&&(o||n>=a.top&&n<=a.bottom)}var I,z,T,H=function(t){a(r,t);var e=h(r);function r(t){var i;return n(this,r),(i=e.call(this)).options=void 0,i.width=void 0,i.height=void 0,t&&o(s(i),t),i}return i(r,[{key:"draw",value:function(t){var e=this.options,n=R(this),r=n.inner,i=n.outer;t.save(),i.w!==r.w||i.h!==r.h?(t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.rect(r.x,r.y,r.w,r.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(r.x,r.y,r.w,r.h)),t.restore()}},{key:"inRange",value:function(t,e,n){return D(this,t,e,n)}},{key:"inXRange",value:function(t,e){return D(this,t,null,e)}},{key:"inYRange",value:function(t,e){return D(this,null,t,e)}},{key:"getCenterPoint",value:function(t){var e=this.getProps(["x","y","width","height"],t),n=e.x,r=e.y;return{x:n+e.width/2,y:r+e.height/2}}},{key:"tooltipPosition",value:function(){return this.getCenterPoint()}},{key:"getRange",value:function(t){return"x"===t?this.width/2:this.height/2}}]),r}(t.Element);T="rectangle",(z="_type")in(I=H)?Object.defineProperty(I,z,{value:T,enumerable:!0,configurable:!0,writable:!0}):I[z]=T;var W=t.defaults,F=t.helpers,q=F.options,B=q._parseFont,U=q.resolve,X=F.valueOrDefault;function Y(t,e){var n=t.width||t.w,r=t.height||t.h,i=2*e.lineHeight;return n>i&&r>i}function $(t,e,n){var r=t.key||"",i=t.tree||[],o=t.groups||[],a=o.length,u=(t.spacing||0)+(t.borderWidth||0);return!i.length&&t.data.length&&(i=t.tree=t.data),a?function t(e,l,f,s){var c,h=o[e],p=e>0&&o[e-1],d=E(function(t,e,n,r,i){var o,a,u,l,f=Object.create(null),s=Object.create(null),c=[];for(a=0,u=t.length;a<u;++a)l=t[a],r&&l[r]!==i||((o=l[e]||"")in f||(f[o]=0,s[o]=[]),f[o]+=+l[n],s[o].push(l));return Object.keys(f).forEach((function(t){(l={children:s[t]})[n]=+f[t],l[e]=t,r&&(l[r]=i),c.push(l)})),c}(i,h,r,p,f),l,r,h,e,s),g=d.slice();return e<a-1&&d.forEach((function(r){c={x:r.x+u,y:r.y+u,w:r.w-2*u,h:r.h-2*u},Y(r,n)&&(c.y+=n.lineHeight,c.h-=n.lineHeight),g.push.apply(g,y(t(e+1,c,r.g,r.s)))})),g}(0,e):E(i,e,r)}var G=function(t){a(r,t);var e=h(r);function r(){return n(this,r),e.apply(this,arguments)}return i(r,[{key:"update",value:function(t){var e,n,r,i=this,a=i.getMeta(),u=i.getDataset(),l=u.groups||(u.groups=[]),f=o(B({fontFamily:X((e=u).fontFamily,W.fontFamily),fontSize:X(e.fontSize,W.fontSize),fontStyle:X(e.fontStyle,W.fontStyle),lineHeight:X(e.lineHeight,W.lineHeight)}),{color:U([e.fontColor,W.fontColor])}),s=i.chart.chartArea,c=u.key||"",h={x:s.left,y:s.top,w:s.right-s.left,h:s.bottom-s.top};"reset"!==t&&(n=i._rect,r=h,n&&r&&n.x===r.x&&n.y===r.y&&n.w===r.w&&n.h===r.h)&&i._key===c&&!function(t,e){var n,r;if(t.lenght!==e.length)return!0;for(n=0,r=t.length;n<r;++n)if(t[n]!==e[n])return!0;return!1}(i._groups,l)||(i._rect=h,i._groups=l.slice(),i._key=c,u.data=$(u,h,f),i._dataCheck(),i._resyncElements()),i.updateElements(a.data,0,t)}},{key:"updateElements",value:function(t,e,n){for(var r=this,i="reset"===n,o=r.getDataset(),a=r.resolveDataElementOptions(e,n),u=r.getSharedOptions(n,t[e],a),l=0;l<t.length;l++){var f=e+l,s=o.data[f],c=r.resolveDataElementOptions(l,n),h=i?0:s.h-2*c.spacing,p=i?0:s.w-2*c.spacing,y={x:s.x+c.spacing,y:s.y+c.spacing,width:p,height:h,options:c};c.font=B(c),r.updateElement(t[l],f,y,n)}r.updateSharedOptions(u,n)}},{key:"draw",value:function(){var t,e,n,r,i=this.getMeta().data||[],o=this.getDataset(),a=(o.groups||[]).length-1,u=o.data||[],l=this.chart.ctx;for(t=0,e=i.length;t<e;++t)if(n=i[t],r=u[t],!n.hidden){n.draw(l);var f=n.options;Y(n,f.font)&&r.g&&(l.save(),l.fillStyle=f.fontColor,l.font=f.font.string,l.beginPath(),l.rect(n.x,n.y,n.width,n.height),l.clip(),"l"in r&&r.l!==a?(l.textAlign="start",l.textBaseline="top",l.fillText(r.g,n.x+f.borderWidth+3,n.y+f.borderWidth+3)):(l.textAlign="center",l.textBaseline="middle",l.fillText(r.g,n.x+n.width/2,n.y+n.height/2)),l.restore())}}}]),r}(t.DatasetController);G.prototype.dataElementType=H,G.prototype.dataElementOptions=["backgroundColor","borderColor","borderSkipped","borderWidth","fontColor","fontFamily","fontSize","fontStyle","spacing"];t.controllers.treemap=G,t.defaults.treemap={hover:{mode:"point",intersect:!0},tooltips:{mode:"point",position:"treemap",intersect:!0,callbacks:{title:function(t,e){return e.datasets[t[0].datasetIndex].key},label:function(t,e){var n=e.datasets[t.datasetIndex],r=n.data[t.index];return n.label+": "+r.v}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}},elements:{rectangle:{borderWidth:0,spacing:.5}}},t.plugins.getAll().find((function(t){return"tooltip"===t.id})).positioners.treemap=function(t){if(!t.length)return!1;var e=t[t.length-1].element;return{x:e.x+e.width/2,y:e.y+e.height/2}}}));
!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 i(t){const e=typeof t;return"function"===e||"object"===e&&!!t}function n(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)}function r(t,e,i,n){const r=t._normalized,o=e*r/i,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===n?s:a,h:"_ix"===n?a:s}}function o(t,e,i,r){const o={x:n(t.x+t._ix,4),y:n(t.y+t._iy,4),w:n(i.w,4),h:n(i.h,4),a:n(e._normalized,4),v:e.value,s:r,_data:e._data};return e.group&&(o.g=e.group,o.l=e.level,o.gs=e.groupSum),o}class s{constructor(t){const e=this;t=t||{w:1,h:1},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,i=[],n=t.nsum,s=t.get(),a=s.length,h=e.dir,l=e.side,d=l*l,u="x"===h?"_ix":"_iy",c=n*n;let g,p,f,m=0,x=0;for(g=0;g<a;++g)p=s[g],f=r(p,d,c,u),x+=f.d1,f.d2>m&&(m=f.d2),i.push(o(e,p,f,t.sum)),e[u]+=f.d1;return e["y"===h?"_ix":"_iy"]+=m,e[u]-=x,i}}const a=Math.min,h=Math.max;function l(t,e){const i=+e[t.key],n=i*t.ratio;return e._normalized=n,{min:a(t.min,i),max:h(t.max,i),sum:t.sum+i,nmin:a(t.nmin,n),nmax:h(t.nmax,n),nsum:t.nsum+n}}function d(t,e,i){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,i)}class u{constructor(t,e){const i=this;i.key=t,i.ratio=e,i.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,l(this,t))}pushIf(t,e,...i){const n=l(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),n,i))return t;var r;d(this,t,n)}get(){return this._arr}}function c(t,e,i){if(0===t.sum)return!0;const[n]=i,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=n*n,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function g(t,e,n,r,o,a){t=t||[];const h=[],l=new s(e),d=new u("value",l.area/function(t,e){let i,n,r;for(i=0,n=0,r=t.length;n<r;++n)i+=e?+t[n][e]:+t[n];return i}(t,n));let g=l.side;const p=t.length;let f,m;if(!p)return h;const x=t.slice();n=function(t,e){let n,r=t.length;if(!r)return e;const o=i(t[0]);for(e=o?e:"v",n=0,r=t.length;n<r;++n)o?t[n]._idx=n:t[n]={v:t[n],_idx:n};return e}(x,n),function(t,e){e?t.sort(((t,i)=>+i[e]-+t[e])):t.sort(((t,e)=>+e-+t))}(x,n);const y=t=>r&&x[t][r];for(f=0;f<p;++f)m={value:(v=f,n?+x[v][n]:+x[v]),groupSum:a,_data:t[x[f]._idx]},r&&(m.level=o,m.group=y(f)),m=d.pushIf(m,c,g),m&&(h.push(l.map(d)),g=l.side,d.reset(),d.push(m));var v;return d.length&&h.push(l.map(d)),function(t){const e=[...t],i=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):i.push(t)}return i.reverse()}(h)}function p(t,e){if(!e)return!1;const i=t.width||t.w,n=t.height||t.h,r=2*e.lineHeight;return i>r&&n>r}function f(t,e,i,n,r){t.save(),t.fillStyle=n.font.color,t.font=n.font.string,t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.clip(),"l"in i&&i.l!==r?n.groupLabels&&(t.textAlign="start",t.textBaseline="top",t.fillText(i.g,e.x+n.borderWidth+3,e.y+n.borderWidth+3)):(t.textAlign="center",t.textBaseline="middle",function(t,e,i){const n=i.options,r=n.font.lineHeight,o=(n.label||e.g+"\n"+e.v).split("\n"),s=i.y+i.height/2-o.length*r/4;o.forEach(((e,n)=>t.fillText(e,i.x+i.width/2,s+n*r)))}(t,i,e)),t.restore()}function m(t,e){const i=e.options,n=e.width||e.w,r=e.height||e.h;if(t.save(),t.strokeStyle=i.dividerColor||"black",t.lineCap=i.dividerCapStyle,t.setLineDash(i.dividerDash||[]),t.lineDashOffset=i.dividerDashOffset,t.lineWidth=i.dividerWidth,t.beginPath(),n>r){const i=n/2;t.moveTo(e.x+i,e.y),t.lineTo(e.x+i,e.y+r)}else{const i=r/2;t.moveTo(e.x,e.y+i),t.lineTo(e.x+n,e.y+i)}t.stroke(),t.restore()}function x(t,e,i){const n=t.key||"";let r=t.tree||[];const o=t.groups||[],s=o.length,a=(t.spacing||0)+(t.borderWidth||0);return!r.length&&t.data.length&&(r=t.tree=t.data),s?function e(h,l,d,u){const c=o[h],f=h>0&&o[h-1],m=g(function(t,e,i,n,r){const o=Object.create(null),s=Object.create(null),a=[];let h,l,d,u;for(l=0,d=t.length;l<d;++l)u=t[l],n&&u[n]!==r||(h=u[e]||"",h in o||(o[h]=0,s[h]=[]),o[h]+=+u[i],s[h].push(u));return Object.keys(o).forEach((t=>{u={children:s[t]},u[i]=+o[t],u[e]=t,n&&(u[n]=r),a.push(u)})),a}(r,c,n,f,d),l,n,c,h,u),x=m.slice();let y;return h<s-1&&m.forEach((n=>{y={x:n.x+a,y:n.y+a,w:n.w-2*a,h:n.h-2*a},t.groupLabels&&p(n,i)&&(y.y+=i.lineHeight,y.h-=i.lineHeight),x.push(...e(h+1,y,n.g,n.s))})),x}(0,e):g(r,e,n)}class y extends t.DatasetController{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const i=this,n=i.getMeta(),r=i.getDataset(),o=r.groups||(r.groups=[]),s=e.toFont(r.font,i.chart.options.font),a=i.chart.chartArea,h=r.key||"",l={x:a.left,y:a.top,w:a.right-a.left,h:a.bottom-a.top};var d,u;"reset"!==t&&(d=i._rect,u=l,d&&u&&d.x===u.x&&d.y===u.y&&d.w===u.w&&d.h===u.h)&&i._key===h&&!function(t,e){let i,n;if(t.lenght!==e.length)return!0;for(i=0,n=t.length;i<n;++i)if(t[i]!==e[i])return!0;return!1}(i._groups,o)||(i._rect=l,i._groups=o.slice(),i._key=h,r.data=x(r,l,s),i._dataCheck(),i._resyncElements()),i.updateElements(n.data,0,n.data.length,t)}_updateOptionsWithDefaults(t){const i=this,n=i.getDataset(),r=i.chart.options.treemap.datasets;t.dividerColor=n.dividerColor||r.dividerColor,t.dividerDash=n.dividerDash||r.dividerDash,t.dividerDashOffset=n.dividerDashOffset||r.dividerDashOffset,t.dividerWidth=n.dividerWidth||r.dividerWidth,t.font=e.toFont(t.font,i.chart.options.font)}updateElements(t,e,i,n){const r=this,o="reset"===n,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,n),h=r.getSharedOptions(a),l=r.includeOptions(n,h);for(let a=e;a<e+i;a++){const e=s.data[a],i=h||r.resolveDataElementOptions(a,n),d=o?0:e.h-2*i.spacing,u=o?0:e.w-2*i.spacing,c={x:e.x+i.spacing,y:e.y+i.spacing,width:u,height:d};l&&(c.options=i),r.updateElement(t[a],a,c,n)}r.updateSharedOptions(h,n,a)}_drawDividers(t,e,i){for(let n=0,r=i.length;n<r;++n){const r=i[n],o=e[n];r.options.groupDividers&&o._data.children.length>1&&m(t,r)}this.getDataset().groupDividers&&m(t,this._rect)}_drawRects(t,e,i,n){for(let r=0,o=i.length;r<o;++r){const o=i[r],s=e[r];if(!o.hidden){o.draw(t);const e=o.options;p(o,e.font)&&s.g&&f(t,o,s,e,n)}}}draw(){const t=this,e=t.chart.ctx,i=t.getMeta().data||[],n=t.getDataset(),r=(n.groups||[]).length-1,o=n.data||[];t._drawRects(e,o,i,r),t._drawDividers(e,o,i)}}function v(t,e){const{x:i,y:n,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:i,top:n,right:i+r,bottom:n+o}}function b(t,e,i){return Math.max(Math.min(t,i),e)}function w(t){const e=v(t),n=e.right-e.left,r=e.bottom-e.top,o=function(t,e,n){let r,o,s,a;return i(t)?(r=+t.top||0,o=+t.right||0,s=+t.bottom||0,a=+t.left||0):r=o=s=a=+t||0,{t:b(r,0,n),r:b(o,0,e),b:b(s,0,n),l:b(a,0,e)}}(t.options.borderWidth,n/2,r/2);return{outer:{x:e.left,y:e.top,w:n,h:r},inner:{x:e.left+o.l,y:e.top+o.t,w:n-o.l-o.r,h:r-o.t-o.b}}}function _(t,e,i,n){const r=null===e,o=null===i,s=!(!t||r&&o)&&v(t,n);return s&&(r||e>=s.left&&e<=s.right)&&(o||i>=s.top&&i<=s.bottom)}y.id="treemap",y.defaults={dataElementType:"treemap",dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","dividerColor","dividerDash","dividerDashOffset","dividerWidth","font","groupLabels","groupDividers","spacing","label"],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,i=e.data[t.dataIndex];return e.label+": "+i.v}}},datasets:{groupLabels:!0,borderWidth:0,spacing:.5,groupDividers:!1,dividerWidth:1},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}};class D 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:i,outer:n}=w(this);t.save(),n.w!==i.w||n.h!==i.h?(t.beginPath(),t.rect(n.x,n.y,n.w,n.h),t.clip(),t.rect(i.x,i.y,i.w,i.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h)),t.restore()}inRange(t,e,i){return _(this,t,e,i)}inXRange(t,e){return _(this,t,null,e)}inYRange(t,e){return _(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,width:n,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+n/2,y:i+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}D.id="treemap",D.defaults={dividerCapStyle:"butt",dividerColor:"black",dividerDash:void 0,dividerDashOffset:0,dividerWidth:0,groupDividers:!1},D.defaultRoutes={backgroundColor:"color",borderColor:"color"},t.Chart.register(y,D);t.Chart.registry.plugins.get("tooltip").positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()}}));
{
"name": "chartjs-chart-treemap",
"version": "1.0.0-alpha",
"version": "1.0.0-beta",
"description": "Chart.js module for creating treemap charts",

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

"scripts": {
"test": "gulp test"
"autobuild": "rollup -c -w",
"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"
},

@@ -30,38 +35,32 @@ "repository": {

"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-transform-object-assign": "^7.8.3",
"@babel/preset-env": "^7.9.5",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
"babel-eslint": "^10.1.0",
"babel-plugin-istanbul": "^6.0.0",
"chart.js": "^3.0.0-alpha",
"eslint": "^6.8.0",
"@babel/preset-env": "^7.11.5",
"@rollup/plugin-babel": "^5.2.1",
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"chart.js": "^3.0.0-beta.3",
"eslint": "^7.10.0",
"eslint-config-chartjs": "^0.2.0",
"eslint-config-esnext": "^4.0.0",
"eslint-plugin-html": "^6.0.1",
"gulp": "^4.0.2",
"gulp-eslint": "^6.0.0",
"gulp-replace": "^1.0.0",
"gulp-streamify": "^1.0.2",
"gulp-zip": "^4.2.0",
"jasmine-core": "^3.5.0",
"karma": "^5.0.1",
"karma-coverage": "^1.1.2",
"eslint-config-esnext": "^4.1.0",
"eslint-plugin-html": "^6.1.0",
"jasmine": "^3.6.1",
"jasmine-core": "^3.6.0",
"karma": "^5.2.3",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-instrumenter": "^1.0.3",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-firefox-launcher": "^1.3.0",
"karma-jasmine": "^2.0.1",
"karma-jasmine-html-reporter": "^1.5.3",
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"karma-rollup-preprocessor": "^7.0.5",
"karma-spec-reporter": "0.0.32",
"merge2": "^1.3.0",
"pixelmatch": "^4.0.2",
"rollup": "^2.6.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-terser": "^5.3.0",
"yargs": "^13.3.2"
"karma-summary-reporter": "^1.8.0",
"minimist": "^1.2.5",
"pixelmatch": "^5.2.1",
"rollup": "^2.28.2",
"rollup-plugin-terser": "^7.0.2"
},
"peerDependencies": {
"chart.js": "^3.0.0-alpha"
}
"chart.js": "^3.0.0-beta.3"
},
"dependencies": {}
}

@@ -32,6 +32,8 @@ # chartjs-chart-treemap

tree: [6,6,5,4,3,2,2,1],
fontColor: '#000',
fontFamily: 'serif',
fontSize: 12,
fontStyle: 'normal',
font: {
color: '#000',
family: 'serif',
size: 12,
style: 'normal',
},
backgroundColor: function(ctx) {

@@ -38,0 +40,0 @@ var value = ctx.dataset.data[ctx.dataIndex];

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