@carbon/charts
Version:
Carbon Charts component library
1,325 lines (1,324 loc) • 45.5 kB
JavaScript
import { a1 as tt, a2 as et, av as st, aw as w, ax as $, ad as N, ay as at, az as nt, aA as ot, aq as P, as as k, g as p, w as E, c as V, v as rt, ap as L, J as z, aB as H, a as R, r as Z, V as Q, ac as C, L as W, aj as it, aC as lt, aa as A } from "../color-scale-utils-BzjNNGXE.mjs";
import { S as b, $ as U, d as X, e as q, s as ct } from "../axis-scales-CPuwbFQf.mjs";
import { b as ut, c as I, a as pt } from "../array-CmsYzTI6.mjs";
function ht(u, t, e, s) {
for (var a = -1, n = u == null ? 0 : u.length; ++a < n; ) {
var o = u[a];
t(s, o, e(o), u);
}
return s;
}
function gt(u, t, e, s) {
return ut(u, function(a, n, o) {
t(s, a, e(a), o);
}), s;
}
function ft(u, t) {
return function(e, s) {
var a = et(e) ? ht : gt, n = {};
return a(e, u, tt(s), n);
};
}
function dt(u) {
for (var t = -1, e = u == null ? 0 : u.length, s = {}; ++t < e; ) {
var a = u[t];
s[a[0]] = a[1];
}
return s;
}
var mt = Object.prototype, Dt = mt.hasOwnProperty, yt = ft(function(u, t, e) {
Dt.call(u, e) ? u[e].push(t) : st(u, e, [t]);
});
function bt(u, t) {
let e = 0;
for (let s of u)
s != null && (s = +s) >= s && ++e;
return e;
}
function vt(u) {
return u;
}
function xt(u = w) {
if (u === w) return Y;
if (typeof u != "function") throw new TypeError("compare is not a function");
return (t, e) => {
const s = u(t, e);
return s || s === 0 ? s : (u(e, e) === 0) - (u(t, t) === 0);
};
}
function Y(u, t) {
return (u == null || !(u >= u)) - (t == null || !(t >= t)) || (u < t ? -1 : u > t ? 1 : 0);
}
var Ct = Array.prototype, Tt = Ct.slice;
function F(u) {
return () => u;
}
function At(u, t, e) {
let s;
for (; ; ) {
const a = $(u, t, e);
if (a === s || a === 0 || !isFinite(a))
return [u, t];
a > 0 ? (u = Math.floor(u / a) * a, t = Math.ceil(t / a) * a) : a < 0 && (u = Math.ceil(u * a) / a, t = Math.floor(t * a) / a), s = a;
}
}
function Ot(u) {
return Math.max(1, Math.ceil(Math.log(bt(u)) / Math.LN2) + 1);
}
function Mt() {
var u = vt, t = N, e = Ot;
function s(a) {
Array.isArray(a) || (a = Array.from(a));
var n, o = a.length, r, i, l = new Array(o);
for (n = 0; n < o; ++n)
l[n] = u(a[n], n, a);
var c = t(l), h = c[0], g = c[1], f = e(l, h, g);
if (!Array.isArray(f)) {
const y = g, S = +f;
if (t === N && ([h, g] = At(h, g, S)), f = at(h, g, S), f[0] <= h && (i = $(h, g, S)), f[f.length - 1] >= g)
if (y >= g && t === N) {
const T = $(h, g, S);
isFinite(T) && (T > 0 ? g = (Math.floor(g / T) + 1) * T : T < 0 && (g = (Math.ceil(g * -T) + 1) / -T));
} else
f.pop();
}
for (var d = f.length, m = 0, D = d; f[m] <= h; ) ++m;
for (; f[D - 1] > g; ) --D;
(m || D < d) && (f = f.slice(m, D), d = D - m);
var x = new Array(d + 1), O;
for (n = 0; n <= d; ++n)
O = x[n] = [], O.x0 = n > 0 ? f[n - 1] : h, O.x1 = n < d ? f[n] : g;
if (isFinite(i)) {
if (i > 0)
for (n = 0; n < o; ++n)
(r = l[n]) != null && h <= r && r <= g && x[Math.min(d, Math.floor((r - h) / i))].push(a[n]);
else if (i < 0) {
for (n = 0; n < o; ++n)
if ((r = l[n]) != null && h <= r && r <= g) {
const y = Math.floor((h - r) * i);
x[Math.min(d, y + (f[y] <= r))].push(a[n]);
}
}
} else
for (n = 0; n < o; ++n)
(r = l[n]) != null && h <= r && r <= g && x[nt(f, r, 0, d)].push(a[n]);
return x;
}
return s.value = function(a) {
return arguments.length ? (u = typeof a == "function" ? a : F(a), s) : u;
}, s.domain = function(a) {
return arguments.length ? (t = typeof a == "function" ? a : F([a[0], a[1]]), s) : t;
}, s.thresholds = function(a) {
return arguments.length ? (e = typeof a == "function" ? a : F(Array.isArray(a) ? Tt.call(a) : a), s) : e;
}, s;
}
function J(u, t, e = 0, s = 1 / 0, a) {
if (t = Math.floor(t), e = Math.floor(Math.max(0, e)), s = Math.floor(Math.min(u.length - 1, s)), !(e <= t && t <= s)) return u;
for (a = a === void 0 ? Y : xt(a); s > e; ) {
if (s - e > 600) {
const i = s - e + 1, l = t - e + 1, c = Math.log(i), h = 0.5 * Math.exp(2 * c / 3), g = 0.5 * Math.sqrt(c * h * (i - h) / i) * (l - i / 2 < 0 ? -1 : 1), f = Math.max(e, Math.floor(t - l * h / i + g)), d = Math.min(s, Math.floor(t + (i - l) * h / i + g));
J(u, t, f, d, a);
}
const n = u[t];
let o = e, r = s;
for (G(u, e, t), a(u[s], n) > 0 && G(u, e, s); o < r; ) {
for (G(u, o, r), ++o, --r; a(u[o], n) < 0; ) ++o;
for (; a(u[r], n) > 0; ) --r;
}
a(u[e], n) === 0 ? G(u, e, r) : (++r, G(u, r, s)), r <= t && (e = r + 1), t <= r && (s = r - 1);
}
return u;
}
function G(u, t, e) {
const s = u[t];
u[t] = u[e], u[e] = s;
}
function B(u, t, e) {
if (u = Float64Array.from(ot(u)), !(!(s = u.length) || isNaN(t = +t))) {
if (t <= 0 || s < 2) return P(u);
if (t >= 1) return k(u);
var s, a = (s - 1) * t, n = Math.floor(a), o = k(J(u, n).subarray(0, n + 1)), r = P(u.subarray(n + 1));
return o + (r - o) * (a - n);
}
}
function K(u, t) {
if ((o = u.length) > 1)
for (var e = 1, s, a, n = u[t[0]], o, r = n.length; e < o; ++e)
for (a = n, n = u[t[e]], s = 0; s < r; ++s)
n[s][1] += n[s][0] = isNaN(a[s][1]) ? a[s][0] : a[s][1];
}
function j(u) {
for (var t = u.length, e = new Array(t); --t >= 0; ) e[t] = t;
return e;
}
function Gt(u, t) {
return u[t];
}
function St(u) {
const t = [];
return t.key = u, t;
}
function _() {
var u = I([]), t = j, e = K, s = Gt;
function a(n) {
var o = Array.from(u.apply(this, arguments), St), r, i = o.length, l = -1, c;
for (const h of n)
for (r = 0, ++l; r < i; ++r)
(o[r][l] = [0, +s(h, o[r].key, l, n)]).data = h;
for (r = 0, c = pt(t(o)); r < i; ++r)
o[c[r]].index = r;
return e(o, c), o;
}
return a.keys = function(n) {
return arguments.length ? (u = typeof n == "function" ? n : I(Array.from(n)), a) : u;
}, a.value = function(n) {
return arguments.length ? (s = typeof n == "function" ? n : I(+n), a) : s;
}, a.order = function(n) {
return arguments.length ? (t = n == null ? j : typeof n == "function" ? n : I(Array.from(n)), a) : t;
}, a.offset = function(n) {
return arguments.length ? (e = n ?? K, a) : e;
}, a;
}
function Et(u, t) {
if ((i = u.length) > 0)
for (var e, s = 0, a, n, o, r, i, l = u[t[0]].length; s < l; ++s)
for (o = r = 0, e = 0; e < i; ++e)
(n = (a = u[t[e]][s])[1] - a[0]) > 0 ? (a[0] = o, a[1] = o += n) : n < 0 ? (a[1] = r, a[0] = r += n) : (a[0] = 0, a[1] = n);
}
function qt(u) {
const t = u.trim();
return ["=", "+", "-", "@", " ", "\r"].includes(t.charAt(0)) ? ` ${t}` : /[,\"\n]/.test(t) ? `"${t}"` : t;
}
class v {
constructor(t) {
this.state = {
options: {}
}, this.colorScale = {}, this.colorClassNames = {}, this.services = t;
}
formatTable({ headers: t, cells: e }) {
const s = this.getOptions(), {
code: a,
date: n,
number: o
} = p(s, "locale"), r = p(s, "tabularRepModal", "tableHeadingFormatter"), i = p(s, "tabularRepModal", "tableCellFormatter"), { cartesianScales: l } = this.services, c = l?.getDomainAxisScaleType();
let h;
return c === b.TIME && (h = (f) => n(f, a, { month: "short", day: "numeric", year: "numeric" })), [
typeof r == "function" ? r(t) : t,
...typeof i == "function" ? i(e) : e.map((f) => {
h && (f[1] = h(f[1]));
for (const d in f) {
const m = f[d];
typeof m == "number" && (f[d] = o(m, a));
}
return f;
})
];
}
getAllDataFromDomain(t) {
if (!this.getData())
return null;
const e = this.getOptions();
let s = this.getData();
const a = this.getDataGroups(), { groupMapsTo: n } = p(e, "data"), o = p(e, "axes");
return t && (s = s.filter((r) => t.includes(r[n]))), o && Object.keys(o).forEach((r) => {
const i = o[r].mapsTo, l = o[r].scaleType;
if ((l === b.LINEAR || l === b.LOG) && (s = s.map((c) => ({
...c,
[i]: c[i] === null ? c[i] : Number(c[i])
}))), i && o[r].domain)
if (l === b.LABELS)
s = s.filter(
(c) => o[r].domain.includes(c[i])
);
else {
const [c, h] = o[r].domain;
s = s.filter(
(g) => !(i in g) || g[i] >= c && g[i] <= h
);
}
}), s.filter((r) => a.find((i) => i.name === r[n]));
}
/**
* Charts that have group configs passed into them, only want to retrieve the display data relevant to that chart
* @param groups the included datasets for the particular chart
*/
getDisplayData(t) {
if (!this.get("data"))
return null;
const { ACTIVE: e } = E.items.status, s = this.getDataGroups(t), { groupMapsTo: a } = this.getOptions().data;
return this.getAllDataFromDomain(t).filter((o) => s.find(
(r) => r.name === o[a] && r.status === e
));
}
getData() {
return this.get("data");
}
isDataEmpty() {
return !this.getData().length;
}
/**
* Sets the data for the current instance.
*
* This method sanitizes the provided data, generates data groups,
* and updates the instance's state with the sanitized data and data groups.
*
* @param {any} newData - The new data to be set. This data will be cloned and sanitized.
* @returns {any} - The sanitized version of the provided data.
*/
setData(t) {
const e = this.sanitize(V(t)), s = this.generateDataGroups(e);
return this.set({
data: e,
dataGroups: s
}), e;
}
getDataGroups(t) {
return p(this.getOptions(), "data", "loading") ? [] : t ? this.get("dataGroups").filter((s) => t.includes(s.name)) : this.get("dataGroups");
}
getActiveDataGroups(t) {
const { ACTIVE: e } = E.items.status;
return this.getDataGroups(t).filter((s) => s.status === e);
}
getDataGroupNames(t) {
return this.getDataGroups(t).map((s) => s.name);
}
getActiveDataGroupNames(t) {
return this.getActiveDataGroups(t).map((s) => s.name);
}
aggregateBinDataByGroup(t) {
return yt(t, "group");
}
getBinConfigurations() {
const t = this.getDisplayData(), e = this.getOptions(), s = this.services.cartesianScales.getMainXAxisPosition(), a = this.services.cartesianScales.getDomainIdentifier(), n = e.axes[s], { groupMapsTo: o } = e.data, { bins: r = rt.defaultBins } = n, i = Array.isArray(r), l = Mt().value((f) => f[a]).thresholds(r)(t);
if (i)
l[l.length - 1].x1 = r[r.length - 1];
else {
const f = l[0].x1 - l[0].x0;
l[l.length - 1].x1 = +l[l.length - 1].x0 + f;
}
const c = i ? [r[0], r[r.length - 1]] : [l[0].x0, l[l.length - 1].x1], h = Array.from(new Set(t.map((f) => f[o]))), g = [];
return l.forEach((f) => {
const d = `${f.x0}-${f.x1}`, m = this.aggregateBinDataByGroup(f);
h.forEach((D) => {
g.push({
group: D,
key: d,
value: m[D] || 0,
bin: f.x0
});
});
}), {
bins: l,
binsDomain: c
};
}
getBinnedStackedData() {
const t = this.getOptions(), { groupMapsTo: e } = t.data, s = this.getActiveDataGroupNames(), { bins: a } = this.getBinConfigurations(), n = this.getDataValuesGroupedByKeys({
bins: a
});
return _().keys(s)(n).map((o, r) => Object.keys(o).filter((i) => !isNaN(i)).map((i) => {
const l = o[i];
return l[e] = s[r], l;
}));
}
getGroupedData(t) {
const e = this.getDisplayData(t), s = {}, { groupMapsTo: a } = this.getOptions().data;
return e.map((n) => {
const o = n[a];
s[o] !== null && s[o] !== void 0 ? s[o].push(n) : s[o] = [n];
}), Object.keys(s).map((n) => ({
name: n,
data: s[n]
}));
}
getStackKeys({ bins: t = null, groups: e = null } = { bins: null, groups: null }) {
const s = this.getOptions(), a = this.getDisplayData(e);
let n;
t ? n = t.map((i) => `${i.x0}:${i.x1}`) : n = L(
a.map((i) => {
const l = this.services.cartesianScales.getDomainIdentifier(i);
return i[l] instanceof Date ? z(i[l]) : i[l] && typeof i[l].toString == "function" ? i[l].toString() : i[l];
})
);
const o = this.services.cartesianScales.domainAxisPosition, r = s.axes[o].scaleType;
return r === b.TIME ? n.sort((i, l) => {
const c = new Date(i), h = new Date(l);
return c - h;
}) : (r === b.LOG || r === b.LINEAR) && n.sort((i, l) => i - l), n;
}
getDataValuesGroupedByKeys({ bins: t = null, groups: e = null }) {
const s = this.getOptions(), { groupMapsTo: a } = s.data, n = this.getDisplayData(e), o = this.getDataGroupNames(), r = this.getStackKeys({ bins: t, groups: e });
return t ? r.map((i) => {
const [l, c] = i.split(":"), h = { x0: l, x1: c }, g = t.find((f) => f.x0.toString() === l.toString());
return o.forEach((f) => {
h[f] = g.filter(
(d) => d[a] === f
).length;
}), h;
}) : r.map((i) => {
const l = { sharedStackKey: i };
return o.forEach((c) => {
const h = n.find((f) => {
const d = this.services.cartesianScales.getDomainIdentifier(f);
return f[a] === c && Object.prototype.hasOwnProperty.call(f, d) && (f[d] instanceof Date ? z(f[d]) === i : f[d].toString() === i);
}), g = this.services.cartesianScales.getRangeIdentifier(l);
l[c] = h ? h[g] : null;
}), l;
});
}
getStackedData({ percentage: t = !1, groups: e = null, divergent: s = !1 }) {
const a = this.getOptions(), { groupMapsTo: n } = a.data, o = this.getActiveDataGroupNames(e), r = this.getDataValuesGroupedByKeys({
groups: e
});
if (t) {
const l = dt(r.map((c) => [c.sharedStackKey, 0]));
r.forEach((c) => {
o.forEach((h) => {
l[c.sharedStackKey] += c[h];
});
}), r.forEach((c) => {
o.forEach((h) => {
const g = l[c.sharedStackKey];
l[c.sharedStackKey] ? c[h] = c[h] / g * 100 : c[h] = 0;
});
});
}
return (s ? _().offset(Et) : _()).keys(o)(r).map((l, c) => Object.keys(l).filter((h) => !isNaN(h)).map((h) => {
const g = l[h];
return g[n] = o[c], g;
}));
}
/**
* Retrieves the current options from the instance's state.
*
* @returns {any} - The current options stored in the instance's state.
*/
getOptions() {
return this.state.options;
}
set(t, e) {
this.state = Object.assign({}, this.state, t);
const s = Object.assign(
{ skipUpdate: !1, animate: !0 },
// default configs
e
);
s.skipUpdate || this.update(s.animate);
}
get(t) {
return t ? this.state[t] : this.state;
}
/**
* Updates the current options for the instance.
*
* This method retrieves the existing options, updates the legend additional items,
* and merges the new options with the existing ones. The instance's state is then updated
* with the merged options.
*
* @param {any} newOptions - The new options to be set. These options will be merged with the existing options.
*/
setOptions(t) {
const e = this.getOptions();
H(e, t), this.set({
options: R(e, t)
});
}
/**
*
* Updates miscellanous information within the model
* such as the color scales, or the legend data labels
*/
update(t = !0) {
this.getDisplayData() && (this.updateAllDataGroups(), this.setCustomColorScale(), this.setColorClassNames(), this.services.events.dispatchEvent(U.Model.UPDATE, { animate: t }));
}
/*
* Data labels
*/
toggleDataLabel(t) {
const { ACTIVE: e, DISABLED: s } = E.items.status, a = this.getDataGroups(), n = a.some((c) => c.status === s), o = a.filter((c) => c.status === e);
if (n)
if (o.length === 1 && o[0].name === t)
a.forEach((c, h) => {
a[h].status = e;
});
else {
const c = a.findIndex((h) => h.name === t);
a[c].status = a[c].status === s ? e : s;
}
else
a.forEach((c, h) => {
a[h].status = c.name === t ? e : s;
});
const r = a.filter((c) => c.status === e), i = this.getOptions();
a.some((c) => c.status === s) ? i.data.selectedGroups = r.map((c) => c.name) : i.data.selectedGroups = [], this.services.events.dispatchEvent(U.Legend.ITEMS_UPDATE, {
dataGroups: a
}), this.set({
dataGroups: a
});
}
/**
* Should the data point be filled?
* @param group
* @param key
* @param data
* @param defaultFilled the default for this chart
*/
getIsFilled(t, e, s, a) {
const n = this.getOptions();
return n.getIsFilled ? n.getIsFilled(t, e, s, a) : a;
}
getFillColor(t, e, s) {
const a = this.getOptions(), n = p(this.colorScale, t);
return a.getFillColor ? a.getFillColor(t, e, s, n) : n;
}
getStrokeColor(t, e, s) {
const a = this.getOptions(), n = p(this.colorScale, t);
return a.getStrokeColor ? a.getStrokeColor(t, e, s, n) : n;
}
isUserProvidedColorScaleValid() {
const t = p(this.getOptions(), "color", "scale"), e = this.getDataGroups();
return t == null || Object.keys(t).length == 0 ? !1 : e.some(
(s) => Object.keys(t).includes(s.name)
);
}
getColorClassName(t) {
const e = this.colorClassNames(t.dataGroupName);
let s = t.originalClassName;
return t.classNameTypes.forEach(
(a) => s = t.originalClassName ? `${s} ${a}-${e}` : `${a}-${e}`
), s || "";
}
/**
* For charts that might hold an associated status for their dataset
*/
getStatus() {
return null;
}
getAllDataGroupsNames() {
return this.allDataGroups;
}
/**
* Converts data provided in the older format to tabular
*
*/
transformToTabularData(t) {
console.warn(
"We've updated the charting data format to be tabular by default. The current format you're using is deprecated and will be removed in v1.0, read more here https://charts.carbondesignsystem.com/"
);
const e = [], { datasets: s, labels: a } = t;
return s.forEach((n) => {
n.data.forEach((o, r) => {
let i;
const l = p(n, "label");
if (l === null) {
const h = p(a, r);
h ? i = h : i = "Ungrouped";
} else
i = l;
const c = {
group: i,
key: a[r]
};
isNaN(o) ? (c.value = o.value, c.date = o.date) : c.value = o, e.push(c);
});
}), e;
}
getTabularDataArray() {
return [];
}
exportToCSV() {
const e = this.getTabularDataArray().map(
(o) => o.map((r) => `"${(r === "–" ? "–" : r).split(/[,;'"`]/).map((c) => qt(c)).join("")}"`)
).map((o) => o.join(",")).join(`
`), s = this.getOptions();
let a = "myChart";
const n = p(s, "fileDownload", "fileName");
typeof n == "function" ? a = n("csv") : typeof n == "string" && (a = n), this.services.files.downloadCSV(e, `${a}.csv`);
}
getTabularData(t) {
return Array.isArray(t) ? t : this.transformToTabularData(t);
}
sanitize(t) {
return t = this.getTabularData(t), t;
}
/*
* Data groups
*/
updateAllDataGroups() {
this.allDataGroups ? this.getDataGroupNames().forEach((t) => {
this.allDataGroups.indexOf(t) === -1 && this.allDataGroups.push(t);
}) : this.allDataGroups = this.getDataGroupNames();
}
generateDataGroups(t) {
const { groupMapsTo: e } = this.getOptions().data, { ACTIVE: s, DISABLED: a } = E.items.status, n = this.getOptions(), o = L(t.map((i) => i[e]));
n.data.selectedGroups.length && (n.data.selectedGroups.every(
(l) => o.includes(l)
) || (n.data.selectedGroups = []));
const r = (i) => !n.data.selectedGroups.length || n.data.selectedGroups.includes(i) ? s : a;
return o.map((i) => ({
name: i,
status: r(i)
}));
}
/*
* Fill scales
*/
setCustomColorScale() {
if (!this.isUserProvidedColorScaleValid())
return;
const t = this.getOptions(), e = p(t, "color", "scale");
Object.keys(e).forEach((a) => {
this.allDataGroups.includes(a) || console.warn(`"${a}" does not exist in data groups.`);
}), this.allDataGroups.filter((a) => e[a]).forEach(
(a) => this.colorScale[a] = e[a]
);
}
/*
* Color palette
*/
setColorClassNames() {
const t = p(this.getOptions(), "color", "pairing");
let e = p(t, "numberOfVariants");
(!e || e < this.allDataGroups.length) && (e = this.allDataGroups.length);
let s = p(t, "option");
const a = Z.pairingOptions, n = e > 5 ? 14 : e, o = `${n}-color`;
s = s <= a[o] ? s : 1;
const r = this.allDataGroups.map(
(i, l) => `${n}-${s}-${l % 14 + 1}`
);
this.colorClassNames = Q().range(r).domain(this.allDataGroups);
}
}
class M extends v {
// can't be protected as it's used by two-dimensional-axes.ts
constructor(t) {
super(t), this.axisFlavor = X.DEFAULT;
}
// get the scales information
// needed for getTabularArray()
assignRangeAndDomains() {
const { cartesianScales: t } = this.services, e = this.getOptions(), s = t.isDualAxes(), a = {
primaryDomain: t.domainAxisPosition,
primaryRange: t.rangeAxisPosition,
secondaryDomain: null,
secondaryRange: null
};
return s && (a.secondaryDomain = t.secondaryDomainAxisPosition, a.secondaryRange = t.secondaryRangeAxisPosition), Object.keys(a).forEach(
(n) => {
const o = a[n];
t.scales[o] ? a[n] = {
position: o,
label: t.getScaleLabel(o),
identifier: p(e, "axes", o, "mapsTo")
} : a[n] = null;
}
), a;
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { groupMapsTo: s } = e.data, { primaryDomain: a, primaryRange: n, secondaryDomain: o, secondaryRange: r } = this.assignRangeAndDomains(), { number: i, code: l } = p(this.getOptions(), "locale"), c = [
"Group",
a.label,
n.label,
...o ? [o.label] : [],
...r ? [r.label] : []
], h = t.map((g) => [
g[s],
g[a.identifier] === null ? "–" : g[a.identifier],
g[n.identifier] === null || isNaN(g[n.identifier]) ? "–" : i(g[n.identifier], l),
...o ? [
g[o.identifier] === null ? "–" : g[o.identifier]
] : [],
...r ? [
g[r.identifier] === null || isNaN(g[r.identifier]) ? "–" : g[r.identifier]
] : []
]);
return super.formatTable({ headers: c, cells: h });
}
setData(t) {
let e;
if (t && (e = super.setData(t), p(this.getOptions(), "zoomBar", q.TOP, "enabled"))) {
const s = p(
this.getOptions(),
"zoomBar",
q.TOP,
"data"
);
this.setZoomBarData(s);
}
return e;
}
/**
* Sets the zoom bar data for the current instance.
*
* This method sanitizes the provided zoom bar data or uses the display data if no explicit
* zoom data is provided. It normalizes the zoom bar data by aggregating values based on unique
* dates and updates the instance's state with the normalized data.
*
* @param {any} [newZoomBarData] - The new zoom bar data to be set. If not provided, the display data will be used.
*/
setZoomBarData(t) {
const e = t ? this.sanitize(V(t)) : this.getDisplayData();
let s = e;
const { cartesianScales: a } = this.services;
if (e && a.domainAxisPosition && a.rangeAxisPosition) {
const n = a.getDomainIdentifier(), o = a.getRangeIdentifier();
let r = e.map((i) => i[n].getTime());
r = L(r).sort(), s = r.map((i) => {
let l = 0;
const c = {};
return e.forEach((h) => {
h[n].getTime() === i && (l += h[o]);
}), c[n] = new Date(i), c[o] = l, c;
});
}
this.set({ zoomBarData: s });
}
getZoomBarData() {
return this.get("zoomBarData");
}
sanitizeDateValues(t) {
const e = this.getOptions();
if (!e.axes)
return t;
const s = [];
return Object.keys(q).forEach((a) => {
const n = q[a], o = e.axes[n];
if (o && o.scaleType === b.TIME) {
const r = o.mapsTo;
(r !== null || r !== void 0) && s.push(r);
}
}), s.length > 0 && t.forEach((a) => {
s.forEach((n) => {
p(a, n, "getTime") === null && (a[n] = new Date(a[n]));
});
}), t;
}
sanitize(t) {
return t = super.sanitize(t), t = this.sanitizeDateValues(t), t;
}
}
class kt extends M {
constructor(t) {
super(t);
}
getTabularDataArray() {
const t = this.getDisplayData(), { number: e, code: s } = p(this.getOptions(), "locale");
t.sort((o, r) => o.source.localeCompare(r.source));
const a = ["Source", "Target", "Value"], n = [
...t.map((o) => [
o.source,
o.target,
o.value === null ? "–" : e(o.value, s)
])
];
return super.formatTable({ headers: a, cells: n });
}
}
class Vt extends M {
constructor(t) {
super(t);
}
getBoxQuartiles(t) {
return {
q_25: B(t, 0.25),
q_50: B(t, 0.5),
q_75: B(t, 0.75)
};
}
getBoxplotData() {
const t = this.getOptions(), { groupMapsTo: e } = t.data, s = this.getGroupedData(), a = [];
for (const { name: n, data: o } of s) {
const r = this.services.cartesianScales.getRangeIdentifier(), i = o.map((y) => y[r]).sort(w), l = {
[e]: n,
counts: i,
quartiles: this.getBoxQuartiles(i),
outliers: null,
whiskers: null
}, c = l.quartiles.q_25, h = l.quartiles.q_75, g = (h - c) * 1.5, f = c - g, d = h + g, m = [], D = [];
for (const y of i)
y < f || y > d ? m.push(y) : D.push(y);
l.outliers = m;
const x = P(D), O = k(D);
l.whiskers = {
min: x || P([l.quartiles.q_25, l.quartiles.q_50, l.quartiles.q_75]),
max: O || k([l.quartiles.q_25, l.quartiles.q_50, l.quartiles.q_75])
}, a.push(l);
}
return a;
}
getTabularDataArray() {
const t = this.getOptions(), { groupMapsTo: e } = t.data, s = this.getBoxplotData(), { number: a, code: n } = p(t, "locale"), o = ["Group", "Minimum", "Q1", "Median", "Q3", "Maximum", "IQR", "Outlier(s)"], r = [
...s.map((i) => {
let l = p(i, "outliers");
return (l === null || l.length === 0) && (l = ["–"]), [
i[e],
p(i, "whiskers", "min") !== null ? a(p(i, "whiskers", "min"), n) : "–",
p(i, "quartiles", "q_25") !== null ? a(p(i, "quartiles", "q_25"), n) : "–",
p(i, "quartiles", "q_50") !== null ? a(p(i, "quartiles", "q_50"), n) : "–",
p(i, "quartiles", "q_75") !== null ? a(p(i, "quartiles", "q_75"), n) : "–",
p(i, "whiskers", "max") !== null ? a(p(i, "whiskers", "max"), n) : "–",
p(i, "quartiles", "q_75") !== null && p(i, "quartiles", "q_25") !== null ? (a(
p(i, "quartiles", "q_75") - p(i, "quartiles", "q_25")
), n) : "–",
l.map((c) => a(c, n)).join(",")
];
})
];
return super.formatTable({ headers: o, cells: r });
}
setColorClassNames() {
const e = p(this.getOptions(), "color", "pairing");
let s = p(e, "option");
const a = Z.pairingOptions;
s = s <= a["1-color"] ? s : 1;
const n = this.allDataGroups.map(() => `1-${s}-1`);
this.colorClassNames = Q().range(n).domain(this.allDataGroups);
}
}
class Ft extends M {
constructor(t) {
super(t);
}
/**
* Determines the index of the performance area titles to use
* @param datum
* @returns number
*/
getMatchingRangeIndexForDatapoint(t) {
let e;
for (let s = t.ranges.length - 1; s > 0; s--) {
const a = t.ranges[s];
if (t.value >= a)
return e = s, e;
}
return 0;
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { groupMapsTo: s } = e.data, a = this.services.cartesianScales.getRangeIdentifier(), { number: n, code: o } = p(e, "locale"), r = p(e, "bullet", "performanceAreaTitles"), i = ["Title", "Group", "Value", "Target", "Percentage", "Performance"], l = [
...t.map((c) => [
c.title,
c[s],
c.value === null ? "–" : n(c.value, o),
p(c, "marker") === null ? "–" : n(c.marker, o),
p(c, "marker") === null ? "–" : `${n(Math.floor(c[a] / c.marker * 100), o)}%`,
r[this.getMatchingRangeIndexForDatapoint(c)]
])
];
return super.formatTable({ headers: i, cells: l });
}
}
class Bt extends v {
constructor(t) {
super(t), this._colorScale = void 0, this._matrix = {};
}
/**
* @override
* @param value
* @returns string
*/
getFillColor(t) {
return this._colorScale(t);
}
/**
* Helper function that will generate a dictionary
*/
getCombinedData() {
if (C(this._matrix)) {
const t = this.getOptions(), e = this.getDisplayData();
!C(e) && !C(t.geoData.objects.countries) && (t.geoData.objects.countries.geometries.forEach((s) => {
this._matrix[s.properties.NAME] = s;
}), e.forEach((s) => {
this._matrix[s.name] ? this._matrix[s.name].value = s.value || null : console.warn(`Data point ${s} is missing geographical data.`);
}));
}
return this._matrix;
}
/**
* Generate tabular data from display data
* @returns Array<Object>
*/
getTabularDataArray() {
const t = this.getDisplayData(), { number: e, code: s } = p(this.getOptions(), "locale"), a = ["Country ID", "Country Name", "Value"], n = [
...t.map((o) => [
o.id === null ? "–" : o.id,
o.name,
o.value === null ? "–" : e(o.value, s)
])
];
return super.formatTable({ headers: a, cells: n });
}
// Uses quantize scale to return class names
getColorClassName(t) {
return `${t.originalClassName || ""} ${this._colorScale(t.value)}`;
}
setColorClassNames() {
const t = p(this.getOptions(), "color");
this._colorScale = W(this.getDisplayData(), t);
}
}
class _t extends v {
constructor(t) {
super(t), this.parentNode = !1, this.set({ depth: 2 }, { skipUpdate: !0 });
}
setData(t) {
super.setData(t), this.setDataGroups(), t.length === 1 && (this.parentNode = !0), this.setZoom();
}
setOptions(t) {
const e = this.getOptions(), s = R({}, t, this.getZoomOptions(t));
H(e, s);
const a = this.getHierarchyLevel(), n = p(e, "circlePack", "depth");
this.set({
options: R(e, s),
depth: n && n < 4 ? n : a
});
}
getZoomOptions(t) {
if (!this.getDisplayData())
return {};
const e = this.getDisplayData(), s = t || this.getOptions(), a = e.length === 1 && p(e, 0, "children") ? p(e, 0, "children") : e;
let n = this.getHierarchyLevel();
return a.some((o) => {
if (o.children && o.children.some((r) => r.children))
return n = 3, !1;
}), p(s, "canvasZoom", "enabled") === !0 && n > 2 ? {
legend: {
additionalItems: [
{
type: ct.ZOOM,
name: "Click to zoom"
}
]
}
} : null;
}
setZoom(t) {
this.setOptions(this.getZoomOptions(t));
}
// update the hierarchy level
updateHierarchyLevel(t) {
this.set({ depth: t });
}
getHierarchyLevel() {
return this.get("depth");
}
hasParentNode() {
return this.parentNode;
}
// set the datagroup name on the items that are it's children
setDataGroups() {
const t = this.getData(), e = this.getOptions(), { groupMapsTo: s } = e.data, a = t.map((n) => {
const o = n[s];
return this.setChildrenDataGroup(n, o);
});
this.set(
{
data: a
},
{ skipUpdate: !0 }
);
}
// sets name recursively down the node tree
setChildrenDataGroup(t, e) {
return t.children ? {
...t,
dataGroupName: e,
children: t.children.map((s) => this.setChildrenDataGroup(s, e))
} : { ...t, dataGroupName: e };
}
getTabularDataArray() {
const t = this.getDisplayData(), { number: e, code: s } = p(this.getOptions(), "locale"), a = ["Child", "Parent", "Value"], n = [];
return t.forEach((o) => {
let r = o.value ? o.value : 0;
o.children && (r += this.getChildrenDatums(o.children, o.name, n, 0)), n.push(["–", o.name, e(r, s)]);
}), super.formatTable({ headers: a, cells: n });
}
/**
* Recursively determine the relationship between all the nested elements in the child
* @private
* @param {any} children - The children nodes to process.
* @param {any} parent - The parent node associated with the children.
* @param {string[][]} [result=[]] - An array to accumulate the resulting data.
* @param {number} [totalSum=0] - The running total sum of values processed.
* @returns {number} Sum.
*/
getChildrenDatums(t, e, s = [], a = 0) {
const n = e, { number: o, code: r } = p(this.getOptions(), "locale");
return t.forEach((i) => {
const l = i.name;
let c = 0;
if (i.children)
i.children.length > 0 && (typeof i.value == "number" && (a += i.value), c += this.getChildrenDatums(i.children, l, s, c), s.push([l, n, o(c, r)]), a += c);
else {
let h = 0;
typeof i.value == "number" && (h = i.value, a += i.value), s.push([i.name, n, o(h, r)]);
}
}), a;
}
}
class wt extends v {
constructor(t) {
super(t);
}
getTabularData(t) {
const e = super.getTabularData(t);
return t !== e && e.forEach((s) => {
s.key && s.key !== s.group && (s.group = s.key);
}), e;
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { groupMapsTo: s } = e.data, { valueMapsTo: a } = e.pie, { number: n, code: o } = p(e, "locale"), r = ["Group", "Value"], i = [
...t.map((l) => [
l[s],
l[a] === null ? "–" : n(l[a], o)
])
];
return super.formatTable({ headers: r, cells: i });
}
sanitize(t) {
return this.getTabularData(t).sort((s, a) => a.value - s.value);
}
}
class $t extends v {
constructor(t) {
super(t);
}
getDataGroups() {
return super.getDataGroups().filter((t) => t.name !== "delta");
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { groupMapsTo: s } = e.data, { number: a, code: n } = p(this.getOptions(), "locale"), o = ["Group", "Value"], r = [
...t.map((i) => [
i[s],
i.value === null ? "–" : a(i.value, n)
])
];
return super.formatTable({ headers: o, cells: r });
}
}
class Lt extends M {
constructor(t) {
super(t), this.axisFlavor = X.HOVERABLE, this._colorScale = void 0, this._domains = [], this._ranges = [], this._matrix = {};
const e = p(this.getOptions(), "axes");
if (p(e, "left", "scaleType") && p(e, "left", "scaleType") !== b.LABELS || p(e, "right", "scaleType") && p(e, "right", "scaleType") !== b.LABELS || p(e, "top", "scaleType") && p(e, "top", "scaleType") !== b.LABELS || p(e, "bottom", "scaleType") && p(e, "bottom", "scaleType") !== b.LABELS)
throw Error("Heatmap only supports label scaletypes.");
}
/**
* Get min and maximum value of the display data
* @returns Array consisting of smallest and largest values in data
*/
getValueDomain() {
const t = N(this.getDisplayData(), (s) => s.value), e = it().domain(t).nice().domain();
if (e[0] > 0)
e[0] = 0;
else if (e[0] === 0 && e[1] === 0)
return [0, 1];
return e[0] < 0 && e[1] > 0 && (Math.abs(e[0]) > e[1] ? e[1] = Math.abs(e[0]) : e[0] = -e[1]), e;
}
/**
* @override
* @param value
* @returns string
*/
getFillColor(t) {
return this._colorScale(t);
}
/**
* Generate a list of all unique domains
* @returns String[]
*/
getUniqueDomain() {
if (C(this._domains)) {
const t = this.getDisplayData(), { cartesianScales: e } = this.services, s = e.getDomainIdentifier(), a = e.getMainXAxisPosition(), n = e.getCustomDomainValuesByposition(a);
if (n)
return n;
this._domains = Array.from(
new Set(
t.map((o) => o[s])
)
);
}
return this._domains;
}
/**
* Generates a list of all unique ranges
* @returns String[]
*/
getUniqueRanges() {
if (C(this._ranges)) {
const t = this.getDisplayData(), { cartesianScales: e } = this.services, s = e.getRangeIdentifier(), a = e.getMainYAxisPosition(), n = e.getCustomDomainValuesByposition(a);
if (n)
return n;
this._ranges = Array.from(
new Set(
t.map((o) => o[s])
)
);
}
return this._ranges;
}
/**
* Generates a matrix (If doesn't exist) and returns it
* @returns Object
*/
getMatrix() {
if (C(this._matrix)) {
const t = this.getUniqueDomain(), e = this.getUniqueRanges(), s = this.services.cartesianScales.getDomainIdentifier(), a = this.services.cartesianScales.getRangeIdentifier(), n = {};
e.forEach((o) => {
n[o] = {
value: null,
index: -1
};
}), t.forEach((o) => {
this._matrix[o] = V(n);
}), this.getDisplayData().forEach((o, r) => {
this._matrix[o[s]][o[a]] = {
value: o.value,
index: r
};
});
}
return this._matrix;
}
/**
* Sets the data for the current instance.
*
* This method sanitizes the provided data, generates data groups,
* and updates the instance's state with the sanitized data and data groups.
* It also resets the `_domains`, `_ranges`, and `_matrix` attributes to their empty states.
*
* @param {any} newData - The new data to be set. This data will be cloned and sanitized.
* @returns {any} - The sanitized version of the provided data.
*/
setData(t) {
const e = this.sanitize(V(t)), s = this.generateDataGroups(e);
return this.set({
data: e,
dataGroups: s
}), this._domains = [], this._ranges = [], this._matrix = {}, e;
}
/**
* Converts Object matrix into a single array
* @returns object[]
*/
getMatrixAsArray() {
C(this._matrix) && this.getMatrix();
const t = this.getUniqueDomain(), e = this.getUniqueRanges(), s = this.services.cartesianScales.getDomainIdentifier(), a = this.services.cartesianScales.getRangeIdentifier(), n = [];
return t.forEach((o) => {
e.forEach((r) => {
const i = {
value: this._matrix[o][r].value,
index: this._matrix[o][r].index
};
i[s] = o, i[a] = r, n.push(i);
});
}), n;
}
/**
* Generate tabular data from display data
* @returns Array<Object>
*/
getTabularDataArray() {
const t = this.getDisplayData(), { primaryDomain: e, primaryRange: s } = this.assignRangeAndDomains(), { number: a, code: n } = p(this.getOptions(), "locale"), o = [e.label, s.label, "Value"], r = [
...t.map((i) => [
i[e.identifier] === null ? "–" : i[e.identifier],
i[s.identifier] === null ? "–" : i[s.identifier],
i.value === null ? "–" : a(i.value, n)
])
];
return super.formatTable({ headers: o, cells: r });
}
// Uses quantize scale to return class names
getColorClassName(t) {
return `${t.originalClassName} ${this._colorScale(t.value)}`;
}
setColorClassNames() {
const t = this.getOptions(), e = p(t, "color", "gradient", "colors"), s = !C(e);
let a = p(t, "color", "pairing", "option");
const n = this.getValueDomain(), o = n[0] < 0 && n[1] > 0 ? "diverge" : "mono";
(a < 1 && a > 4 && o === "mono" || a < 1 && a > 2 && o === "diverge") && (a = 1);
const r = s ? e : [];
if (!s) {
const l = o === "diverge" ? 17 : 11;
for (let c = 1; c < l + 1; c++)
r.push(`fill-${o}-${a}-${c}`);
}
this._colorScale = lt().domain(n).range(r);
const i = p(this.getOptions(), "color");
this._colorScale = W(this.getDisplayData(), i);
}
}
class Rt extends M {
getTabularDataArray() {
const t = this.getOptions(), { groupMapsTo: e } = t.data, { number: s, code: a } = p(this.getOptions(), "locale"), n = this.getBinnedStackedData(), o = [
A(t, "bins.rangeLabel") || "Range",
...n.map((i) => A(i, `0.${e}`))
], r = [
...A(n, 0).map((i, l) => [
`${s(Number(A(i, "data.x0")), a)} – ${s(
Number(A(i, "data.x1")),
a
)}`,
...n.map(
(c) => s(A(c[l], `data.${A(c[l], e)}`), a)
)
])
];
return super.formatTable({ headers: o, cells: r });
}
}
class zt extends v {
constructor(t) {
super(t);
}
getMaximumDomain(t) {
return t.reduce((s, a) => s + a.value, 0);
}
/**
* Use a provided color for the bar or default to carbon color if no status provided.
* Defaults to carbon color otherwise.
* @param group dataset group label
*/
getFillColor(t) {
const e = this.getOptions(), s = p(e, "color", "scale"), a = this.getStatus();
return s || !a ? super.getFillColor(t) : null;
}
/**
* Get the associated status for the data by checking the ranges
*/
getStatus() {
const t = this.getOptions(), s = p(this.getDisplayData())?.reduce((o, r) => o + r.value, 0) ?? 0, a = p(t, "meter", "proportional") ? s : s > 100 ? 100 : s, n = p(t, "meter", "status", "ranges");
if (n) {
const o = n.filter(
(r) => r.range[0] <= a && a <= r.range[1]
);
if (o.length > 0)
return o[0].status;
}
return null;
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { groupMapsTo: s } = e.data, a = this.getStatus(), n = p(e, "meter", "proportional"), { number: o, code: r } = p(this.getOptions(), "locale");
let i = [], l = [], c;
if (n === null) {
c = 100;
const h = t[0];
i = ["Group", "Value", ...a ? ["Status"] : []], l = [
[
h[s],
h.value === null ? "–" : o(h.value, r),
...a ? [a] : []
]
];
} else {
const h = p(n, "total");
c = h || this.getMaximumDomain(t), i = ["Group", "Value", "Percentage of total"], l = [
...t.map((g) => {
let f;
g.value !== null && g.value !== void 0 ? f = Number(g.value) : f = 0;
const d = Number((g.value / c * 100).toFixed(2));
return [
g[s],
g.value === null ? "–" : o(f, r),
o(d, r) + " %"
];
})
];
}
return super.formatTable({ headers: i, cells: l });
}
}
class Ut extends M {
constructor(t) {
super(t);
}
getTabularDataArray() {
const t = this.getOptions(), e = this.getGroupedData(), { angle: s, value: a } = p(t, "radar", "axes"), { number: n, code: o } = p(t, "locale"), r = p(e, "0", "data").map((c) => c[s]), i = ["Group", ...r], l = [
...e.map((c) => [
c.name,
...r.map(
(h, g) => p(c, "data", g, a) !== null ? n(p(c, "data", g, a), o) : "–"
)
])
];
return super.formatTable({ headers: i, cells: l });
}
}
class Kt extends v {
constructor(t) {
super(t);
}
/**
* Retrieves and formats tabular data from the display data.
*
* @returns {any[]} An object containing the headers and cells of the tabular data.
*/
getTabularDataArray() {
const t = this.getDisplayData(), e = ["Child", "Parent"], s = [];
return t.forEach((a) => {
this.getChildrenDatums(a, s), s.push([a.name, "–"]);
}), super.formatTable({ headers: e, cells: s });
}
/**
* Determine the child parent relationship in nested data
* @private
* @param {any} datum - The datum node to process.
* @param {any[]} [result=[]] - An array to accumulate the resulting data.
* @returns {any[]} The accumulated result array.
*/
getChildrenDatums(t, e = []) {
t.children && t.children.length > 0 && t.children.forEach((s) => {
this.getChildrenDatums(s, e), e.push([s.name, t.name]);
});
}
}
class jt extends v {
constructor(t) {
super(t);
}
getTabularDataArray() {
const t = this.getDisplayData(), { number: e, code: s } = p(this.getOptions(), "locale"), a = ["Child", "Group", "Value"], n = [];
return t.forEach((o) => {
Array.isArray(o.children) ? o.children.forEach((r) => {
n.push([
r.name,
o.name,
r.value === null ? "–" : e(r.value, s)
]);
}) : p(o.name) !== null && p(o.value) && n.push(["–", o.name, e(o.value, s)]);
}), super.formatTable({ headers: a, cells: n });
}
}
class Ht extends v {
constructor(t) {
super(t);
}
getTabularDataArray() {
const t = this.getDisplayData(), e = this.getOptions(), { fontSizeMapsTo: s, wordMapsTo: a } = e.wordCloud, { groupMapsTo: n } = e.data, { code: o, number: r } = p(e, "locale"), i = [e.tooltip.wordLabel, "Group", e.tooltip.valueLabel], l = [
...t.map((c) => [
c[a],
c[n],
r(c[s], o)
])
];
return super.formatTable({ headers: i, cells: l });
}
}
export {
kt as AlluvialChartModel,
Vt as BoxplotChartModel,
Ft as BulletChartModel,
v as ChartModel,
Rt as ChartModelBinned,
M as ChartModelCartesian,
Bt as ChoroplethModel,
_t as CirclePackChartModel,
$t as GaugeChartModel,
Lt as HeatmapModel,
zt as MeterChartModel,
wt as PieChartModel,
Ut as RadarChartModel,
Kt as TreeChartModel,
jt as TreemapChartModel,
Ht as WordCloudModel
};
//# sourceMappingURL=index.mjs.map