@martinomagnifico/tablechart 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/tablechart-shared.mjs +156 -138
- package/dist/tablechart.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -811,20 +811,24 @@ var Pe = (e) => e.map((e) => ({
|
|
|
811
811
|
y2: ue
|
|
812
812
|
}));
|
|
813
813
|
}
|
|
814
|
-
}), Ie = Fe(!1), Le = Fe(!0), Re = {
|
|
814
|
+
}), Ie = Fe(!1), Le = Fe(!0), Re = /* @__PURE__ */ new Set(), ze = (t, n) => {
|
|
815
|
+
if (Math.abs(t - n) <= Math.abs(n) / 100) return;
|
|
816
|
+
let r = `[${e}] A total reads ${t}, but the steps before it add up to ${Number(n.toFixed(6))}. The chart shows what you wrote; this is only a check.`;
|
|
817
|
+
Re.has(r) || (Re.add(r), console.warn(r));
|
|
818
|
+
}, Be = {
|
|
815
819
|
segments: (e) => {
|
|
816
|
-
let t = 0;
|
|
820
|
+
let t = 0, n = !1;
|
|
817
821
|
return e.map((e) => {
|
|
818
|
-
if (e.isTotal) return t = e.value, {
|
|
822
|
+
if (e.isTotal) return n && ze(e.value, t), n = !1, t = e.value, {
|
|
819
823
|
...e,
|
|
820
824
|
from: 0,
|
|
821
825
|
to: e.value,
|
|
822
826
|
kind: "total"
|
|
823
827
|
};
|
|
824
|
-
let
|
|
825
|
-
return t += e.value, {
|
|
828
|
+
let r = t;
|
|
829
|
+
return t += e.value, n = !0, {
|
|
826
830
|
...e,
|
|
827
|
-
from:
|
|
831
|
+
from: r,
|
|
828
832
|
to: t,
|
|
829
833
|
kind: e.value >= 0 ? "up" : "down"
|
|
830
834
|
};
|
|
@@ -891,7 +895,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
891
895
|
let i = performance.now(), a = r(), o = performance.now() - i, s = n.querySelectorAll("tbody tr").length;
|
|
892
896
|
return o > 50 ? console.warn(`[${e}] ${t} took ${o.toFixed(1)} ms for ${s} rows, more than 50 ms.`, n) : Z.log(`${t} took ${o.toFixed(1)} ms for ${s} rows.`, n), a;
|
|
893
897
|
}
|
|
894
|
-
},
|
|
898
|
+
}, Ve = (e) => {
|
|
895
899
|
let t = (e?.textContent || "").trim(), n = t.match(/^(.*?)(-?\d+(?:[.,]\d+)?)(.*)$/);
|
|
896
900
|
return {
|
|
897
901
|
raw: t,
|
|
@@ -901,9 +905,9 @@ var Pe = (e) => e.map((e) => ({
|
|
|
901
905
|
missing: !n,
|
|
902
906
|
value: n ? Number.parseFloat(n[2].replace(",", ".")) : 0
|
|
903
907
|
};
|
|
904
|
-
},
|
|
905
|
-
let r = e.querySelector("th"), i = Array.from(e.querySelectorAll("td")).map(
|
|
906
|
-
return i.length || i.push(
|
|
908
|
+
}, He = (e, t = "data-i18n") => Array.from(e.querySelectorAll("tbody tr")).map((e, n) => {
|
|
909
|
+
let r = e.querySelector("th"), i = Array.from(e.querySelectorAll("td")).map(Ve);
|
|
910
|
+
return i.length || i.push(Ve(null)), {
|
|
907
911
|
...i[0],
|
|
908
912
|
label: (r?.textContent || "").trim(),
|
|
909
913
|
key: t && r?.getAttribute(t) || null,
|
|
@@ -912,8 +916,8 @@ var Pe = (e) => e.map((e) => ({
|
|
|
912
916
|
isTotal: e.getAttribute("data-kind") === "total",
|
|
913
917
|
slot: n
|
|
914
918
|
};
|
|
915
|
-
}),
|
|
916
|
-
let r =
|
|
919
|
+
}), Ue = (e) => Array.from(e.querySelector("thead tr:last-child")?.children ?? []).slice(1), We = (e) => e === "dashed" || e === "dotted" ? e : null, Ge = (e, t, n = "data-i18n") => {
|
|
920
|
+
let r = Ue(e), i = Math.max(1, U(t.map((e) => e.cells.length)));
|
|
917
921
|
return Array.from({ length: i }, (e, t) => {
|
|
918
922
|
let i = r[t];
|
|
919
923
|
return {
|
|
@@ -921,10 +925,10 @@ var Pe = (e) => e.map((e) => ({
|
|
|
921
925
|
key: n && i?.getAttribute(n) || null,
|
|
922
926
|
focus: i?.getAttribute("data-kind") === "focus",
|
|
923
927
|
marker: i?.getAttribute("data-marker") ?? null,
|
|
924
|
-
line:
|
|
928
|
+
line: We(i?.getAttribute("data-line"))
|
|
925
929
|
};
|
|
926
930
|
});
|
|
927
|
-
},
|
|
931
|
+
}, Ke = (t, n) => {
|
|
928
932
|
if (!n) return;
|
|
929
933
|
let r = /* @__PURE__ */ new Map();
|
|
930
934
|
for (let i of t) {
|
|
@@ -937,22 +941,26 @@ var Pe = (e) => e.map((e) => ({
|
|
|
937
941
|
i.querySelectorAll("tbody th").forEach((e, r) => {
|
|
938
942
|
e.getAttribute(n) || e.setAttribute(n, `${t}-row${r + 1}`);
|
|
939
943
|
});
|
|
940
|
-
let a =
|
|
944
|
+
let a = Ue(i);
|
|
941
945
|
a.length > 1 && a.forEach((e, r) => {
|
|
942
946
|
e.getAttribute(n) || e.setAttribute(n, `${t}-col${r + 1}`);
|
|
943
947
|
}), Z?.log?.(`Keys for "${t}" written onto ${i.querySelectorAll("tbody th").length} rows`);
|
|
944
948
|
}
|
|
945
|
-
},
|
|
949
|
+
}, qe = [
|
|
946
950
|
"axis-break",
|
|
947
951
|
"trend",
|
|
948
952
|
"bracket"
|
|
949
|
-
],
|
|
950
|
-
let t = e.hasAttribute("data-fragment"), n = Array.from(e.querySelectorAll("tbody tr")), r = Array.from(e.querySelector("thead tr:last-child")?.children ?? []).slice(1), i = Array.from(e.querySelectorAll("[data-annotation]")).filter((e) =>
|
|
953
|
+
], Je = (e) => {
|
|
954
|
+
let t = e.hasAttribute("data-fragment"), n = Array.from(e.querySelectorAll("tbody tr")), r = Array.from(e.querySelector("thead tr:last-child")?.children ?? []).slice(1), i = Array.from(e.querySelectorAll("[data-annotation]")).filter((e) => qe.includes(e.getAttribute("data-annotation") ?? "")), a = (e) => e.hasAttribute("data-fragment");
|
|
951
955
|
if (!t && !n.some(a) && !r.some(a) && !i.some(a)) return null;
|
|
952
956
|
let o = [], s = /* @__PURE__ */ new Map(), c = [], l = (e) => {
|
|
953
957
|
let t = e === null ? void 0 : s.get(e);
|
|
954
958
|
return t === void 0 && (t = o.length, o.push(e), c.push(0), e !== null && s.set(e, t)), t;
|
|
955
|
-
}, u = 0, d = n.map((e) => {
|
|
959
|
+
}, u = 0, d = e.getAttribute("data-chart") === "donut", f = (e) => d && e.getAttribute("data-kind") === "total", p = n.map((e) => {
|
|
960
|
+
if (f(e)) return {
|
|
961
|
+
step: null,
|
|
962
|
+
slot: 0
|
|
963
|
+
};
|
|
956
964
|
if (!t && !a(e)) return {
|
|
957
965
|
step: null,
|
|
958
966
|
slot: u++
|
|
@@ -962,22 +970,27 @@ var Pe = (e) => e.map((e) => ({
|
|
|
962
970
|
step: n,
|
|
963
971
|
slot: c[n]++
|
|
964
972
|
};
|
|
965
|
-
}),
|
|
973
|
+
}), m = Math.max(-1, ...p.map((e) => e.step ?? -1));
|
|
974
|
+
if (m >= 0) for (let [e, t] of n.entries()) f(t) && (p[e] = {
|
|
975
|
+
step: m,
|
|
976
|
+
slot: c[m]++
|
|
977
|
+
});
|
|
978
|
+
let h = r.map((e) => ({ step: a(e) ? l(e.getAttribute("data-fragment-index")) : null }));
|
|
966
979
|
return {
|
|
967
|
-
rows:
|
|
968
|
-
series:
|
|
980
|
+
rows: p,
|
|
981
|
+
series: h,
|
|
969
982
|
notes: i.map((e) => {
|
|
970
983
|
let t = (t, n) => {
|
|
971
984
|
let r = Number.parseInt(e.getAttribute(t) ?? "", 10);
|
|
972
985
|
return Number.isFinite(r) ? r - 1 : n;
|
|
973
|
-
}, [n, r] = e.getAttribute("data-annotation") === "bracket" ? [t("data-from", 0), t("data-to",
|
|
986
|
+
}, [n, r] = e.getAttribute("data-annotation") === "bracket" ? [t("data-from", 0), t("data-to", p.length - 1)] : [0, p.length - 1], i = null;
|
|
974
987
|
for (let e = Math.min(n, r); e <= Math.max(n, r); e++) {
|
|
975
|
-
let t =
|
|
988
|
+
let t = p[e]?.step ?? null;
|
|
976
989
|
t !== null && (i === null || t > i) && (i = t);
|
|
977
990
|
}
|
|
978
|
-
let o =
|
|
991
|
+
let o = h[t("data-series", 0)]?.step ?? null;
|
|
979
992
|
o !== null && (i === null || o > i) && (i = o), a(e) && (i = l(e.getAttribute("data-fragment-index")));
|
|
980
|
-
let s = i === null ?
|
|
993
|
+
let s = i === null ? p.length : p.filter((e) => e.step === i).length;
|
|
981
994
|
return {
|
|
982
995
|
step: i,
|
|
983
996
|
after: s
|
|
@@ -986,7 +999,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
986
999
|
count: o.length,
|
|
987
1000
|
indexes: o
|
|
988
1001
|
};
|
|
989
|
-
},
|
|
1002
|
+
}, Ye = (e) => {
|
|
990
1003
|
let t = e.plan;
|
|
991
1004
|
if (!t) return;
|
|
992
1005
|
let n = (t) => t === null || e.step - t >= 1;
|
|
@@ -997,7 +1010,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
997
1010
|
let c = r.hasAttribute("data-flat") ? (s - e + 1) / (i - e + 1) : i > e ? Math.max(0, s - e) / (i - e) : 0;
|
|
998
1011
|
r.style.setProperty("--reveal", String(c));
|
|
999
1012
|
}
|
|
1000
|
-
},
|
|
1013
|
+
}, Xe = (e) => {
|
|
1001
1014
|
let t = e.plan;
|
|
1002
1015
|
if (!t) return;
|
|
1003
1016
|
let n = t.rows.length - 1, r = (e, t, n, r) => {
|
|
@@ -1023,12 +1036,17 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1023
1036
|
let o = i.dataset.series ? t.series[Number(i.dataset.series) - 1] : void 0;
|
|
1024
1037
|
o && o.step !== null ? r(i, o.step, "--i", a) : t.rows[a] && r(i, t.rows[a].step, "--i", t.rows[a].slot);
|
|
1025
1038
|
}
|
|
1026
|
-
|
|
1039
|
+
let i = e.figure.querySelector(`.${x}`);
|
|
1040
|
+
if (i) {
|
|
1041
|
+
let e = Math.max(-1, ...t.rows.map((e) => e.step ?? -1));
|
|
1042
|
+
e < 0 ? r(i, null, "--i", 0) : r(i, e, "--i", t.rows.filter((t) => t.step === e).length);
|
|
1043
|
+
}
|
|
1044
|
+
Ye(e);
|
|
1027
1045
|
}, Q = (e, t, n = !1) => {
|
|
1028
1046
|
let r = e.plan;
|
|
1029
1047
|
if (!r) return;
|
|
1030
1048
|
let i = Math.min(Math.max(Math.round(t), 0), r.count), a = i !== e.step;
|
|
1031
|
-
e.step = i, e.figure.style.setProperty("--tablechart-step", String(i)),
|
|
1049
|
+
e.step = i, e.figure.style.setProperty("--tablechart-step", String(i)), Ye(e);
|
|
1032
1050
|
let [o, s] = e.controls?.querySelectorAll("button") ?? [];
|
|
1033
1051
|
o && (o.disabled = i === 0), s && (s.disabled = i === r.count), a && !n && e.figure.dispatchEvent(new CustomEvent("tablechart:step", {
|
|
1034
1052
|
bubbles: !0,
|
|
@@ -1037,7 +1055,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1037
1055
|
steps: r.count
|
|
1038
1056
|
}
|
|
1039
1057
|
}));
|
|
1040
|
-
},
|
|
1058
|
+
}, Ze = (e, t, n) => {
|
|
1041
1059
|
let r = document.createElement("div");
|
|
1042
1060
|
r.className = A;
|
|
1043
1061
|
let i = (r) => {
|
|
@@ -1066,35 +1084,35 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1066
1084
|
]), i;
|
|
1067
1085
|
};
|
|
1068
1086
|
return r.append(i("previous"), i("next")), r;
|
|
1069
|
-
},
|
|
1087
|
+
}, Qe = {
|
|
1070
1088
|
area: Le,
|
|
1071
1089
|
bar: Se,
|
|
1072
1090
|
column: Ce,
|
|
1073
1091
|
donut: Ee,
|
|
1074
1092
|
line: Ie,
|
|
1075
|
-
waterfall:
|
|
1076
|
-
},
|
|
1093
|
+
waterfall: Be
|
|
1094
|
+
}, $e = {
|
|
1077
1095
|
"axis-break": H,
|
|
1078
1096
|
trend: ce,
|
|
1079
1097
|
bracket: ie
|
|
1080
|
-
},
|
|
1098
|
+
}, et = Object.keys($e), tt = (e) => {
|
|
1081
1099
|
let t = "";
|
|
1082
1100
|
for (let n = e.previousSibling; n && (t = (n.textContent ?? "") + t, !t.trim()); n = n.previousSibling);
|
|
1083
1101
|
return t.trim();
|
|
1084
|
-
},
|
|
1102
|
+
}, nt = [
|
|
1085
1103
|
"straight",
|
|
1086
1104
|
"step",
|
|
1087
1105
|
"smooth"
|
|
1088
|
-
],
|
|
1106
|
+
], rt = (e, t) => {
|
|
1089
1107
|
let n = e.dataset.chartShape;
|
|
1090
|
-
return n &&
|
|
1091
|
-
},
|
|
1108
|
+
return n && nt.includes(n) ? n : nt.includes(t.shape) ? t.shape : "straight";
|
|
1109
|
+
}, it = (e) => {
|
|
1092
1110
|
for (let t of e.querySelectorAll("br")) {
|
|
1093
|
-
if (t.previousElementSibling?.classList.contains("tablechart-sr") || /[.!?:;,…]$/.test(
|
|
1111
|
+
if (t.previousElementSibling?.classList.contains("tablechart-sr") || /[.!?:;,…]$/.test(tt(t))) continue;
|
|
1094
1112
|
let e = document.createElement("span");
|
|
1095
1113
|
e.className = E, e.textContent = ". ", t.before(e);
|
|
1096
1114
|
}
|
|
1097
|
-
},
|
|
1115
|
+
}, at = (e, t, n) => {
|
|
1098
1116
|
let r = e.querySelector("table");
|
|
1099
1117
|
if (!r) return null;
|
|
1100
1118
|
let i = r.querySelector("tfoot [data-chart-total]");
|
|
@@ -1105,23 +1123,23 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1105
1123
|
s && n.langattribute && o.setAttribute(n.langattribute, `${s}-total`);
|
|
1106
1124
|
let c = a.insertCell();
|
|
1107
1125
|
return c.setAttribute("data-chart-total", ""), c.dataset.value = t.dataset.value ?? "0", a.prepend(o), c;
|
|
1108
|
-
},
|
|
1126
|
+
}, ot = 0, st = (e) => {
|
|
1109
1127
|
let t = e.querySelector(":scope > figcaption");
|
|
1110
1128
|
if (!t) return;
|
|
1111
|
-
|
|
1129
|
+
it(t);
|
|
1112
1130
|
let n = (e) => e.hasAttribute("aria-label") || e.hasAttribute("aria-labelledby"), r = (e) => {
|
|
1113
|
-
t.id || (t.id = `tablechart-caption-${++
|
|
1131
|
+
t.id || (t.id = `tablechart-caption-${++ot}`), e.setAttribute("aria-labelledby", t.id);
|
|
1114
1132
|
};
|
|
1115
1133
|
e.tagName === "FIGURE" && !n(e) && r(e);
|
|
1116
1134
|
let i = e.querySelector("table");
|
|
1117
1135
|
i && !n(i) && !i.querySelector(":scope > caption") && r(i);
|
|
1118
|
-
},
|
|
1119
|
-
let s = o ?? (i.getAttribute("data-chart") || "column"), c =
|
|
1120
|
-
if (!c) return console.warn(`[${e}] Unknown chart type "${s}". Known types: ${Object.keys(
|
|
1121
|
-
let l =
|
|
1136
|
+
}, ct = (i, a, o = null) => {
|
|
1137
|
+
let s = o ?? (i.getAttribute("data-chart") || "column"), c = Qe[s];
|
|
1138
|
+
if (!c) return console.warn(`[${e}] Unknown chart type "${s}". Known types: ${Object.keys(Qe).join(", ")}.`), i.setAttribute("data-chart-empty", ""), null;
|
|
1139
|
+
let l = He(i, a.langattribute);
|
|
1122
1140
|
if (!l.length) return console.warn(`[${e}] A chart has no rows in its table, so there is nothing to draw.`), i.setAttribute("data-chart-empty", ""), null;
|
|
1123
|
-
|
|
1124
|
-
let u =
|
|
1141
|
+
st(i);
|
|
1142
|
+
let u = Ge(i, l, a.langattribute);
|
|
1125
1143
|
u.length > 1 && !c.series && (console.warn(`[${e}] A ${s} chart draws one series; only the first of the table's ${u.length} value columns is used.`), u = u.slice(0, 1));
|
|
1126
1144
|
let d = u.length > 1;
|
|
1127
1145
|
d && i.style.setProperty("--tablechart-series-count", String(u.length));
|
|
@@ -1150,7 +1168,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1150
1168
|
let n = L(_, D ?? m);
|
|
1151
1169
|
D && (n.dataset.place = "legend");
|
|
1152
1170
|
let r = c.legend ?? c.swatch;
|
|
1153
|
-
if (r && (n.dataset.swatch = r), n.textContent = e.name, !r &&
|
|
1171
|
+
if (r && (n.dataset.swatch = r), n.textContent = e.name, !r && rt(i, a) !== "step") {
|
|
1154
1172
|
let e = Oe(u, t);
|
|
1155
1173
|
n.dataset.marker = e.shape, n.toggleAttribute("data-open", e.open);
|
|
1156
1174
|
}
|
|
@@ -1160,7 +1178,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1160
1178
|
let e = l.find((e) => e.isTotal), t = e ? e.value : l.reduce((e, t) => e + Math.abs(t.value), 0);
|
|
1161
1179
|
k.dataset.value = String(t), e && (k.dataset.decimals = String(W(e.number)));
|
|
1162
1180
|
}
|
|
1163
|
-
let A = k && !l.some((e) => e.isTotal) ?
|
|
1181
|
+
let A = k && !l.some((e) => e.isTotal) ? at(i, k, a) : null, j = c.categories === "beside", M = document.createElement("div");
|
|
1164
1182
|
M.className = n, M.setAttribute("aria-hidden", "true"), M.inert = !0, j ? M.dataset.place = "beside" : c.centre && (M.dataset.place = "key"), M.style.setProperty("--tablechart-columns", String(l.length));
|
|
1165
1183
|
let N = 0;
|
|
1166
1184
|
for (let [e, t] of l.entries()) {
|
|
@@ -1168,9 +1186,9 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1168
1186
|
n.classList.add(...t.classes), n.textContent = t.label, t.key && a.langattribute && n.setAttribute(a.langattribute, t.key), c.centre && (n.dataset.kind = t.isTotal ? "total" : "slice", t.isTotal || (n.dataset.slice = String(N + 1), n.style.setProperty("--n", String(N)), n.style.setProperty("--palette", `var(--tablechart-color-${N + 1})`), N += 1)), n.style.setProperty("--i", String(t.slot)), n.dataset.row = String(e + 1), M.appendChild(n);
|
|
1169
1187
|
}
|
|
1170
1188
|
(j ? m : i).appendChild(M), D && i.appendChild(D);
|
|
1171
|
-
let P = a.animate ?
|
|
1189
|
+
let P = a.animate ? Je(i) : null;
|
|
1172
1190
|
P && (i.setAttribute("data-steps", ""), i.setAttribute("data-chart-animate", "across"));
|
|
1173
|
-
let I = i.getAttribute("data-chart-keys"), R = P && a.controls ?
|
|
1191
|
+
let I = i.getAttribute("data-chart-keys"), R = P && a.controls ? Ze({
|
|
1174
1192
|
previous: a.previouslabel,
|
|
1175
1193
|
next: a.nextlabel,
|
|
1176
1194
|
hint: a.stephint
|
|
@@ -1181,8 +1199,8 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1181
1199
|
}, a.langattribute) : null;
|
|
1182
1200
|
R && i.appendChild(R);
|
|
1183
1201
|
let z = Array.from(i.querySelectorAll("[data-annotation]")).map((t) => {
|
|
1184
|
-
let n = t.getAttribute("data-annotation"), r =
|
|
1185
|
-
if (!r) return console.warn(`[${e}] Unknown annotation "${n}". Known annotations: ${Object.keys(
|
|
1202
|
+
let n = t.getAttribute("data-annotation"), r = $e[n];
|
|
1203
|
+
if (!r) return console.warn(`[${e}] Unknown annotation "${n}". Known annotations: ${Object.keys($e).join(", ")}.`), null;
|
|
1186
1204
|
let i = Number.parseInt(t.getAttribute("data-series") ?? "1", 10), a = i >= 1 && i <= u.length ? i - 1 : 0;
|
|
1187
1205
|
return i !== a + 1 && console.warn(`[${e}] An annotation reads line ${i}, which the chart does not have; it reads the first.`), {
|
|
1188
1206
|
spec: t,
|
|
@@ -1223,16 +1241,16 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1223
1241
|
return R?.addEventListener("click", (e) => {
|
|
1224
1242
|
let t = e.target.closest("button")?.dataset.go;
|
|
1225
1243
|
t && Q(B, B.step + (t === "next" ? 1 : -1));
|
|
1226
|
-
}), Q(B, 0, !0), a.hover && i.getAttribute("data-chart-hover") !== "false" &&
|
|
1227
|
-
},
|
|
1244
|
+
}), Q(B, 0, !0), a.hover && i.getAttribute("data-chart-hover") !== "false" && gt(B), pt(B, a), B;
|
|
1245
|
+
}, lt = (e) => {
|
|
1228
1246
|
let t = getComputedStyle(e).getPropertyValue("--tablechart-inside-align").trim();
|
|
1229
1247
|
return t === "start" || t === "center" || t === "end" ? t : null;
|
|
1230
|
-
},
|
|
1248
|
+
}, ut = (e, t, n, r) => {
|
|
1231
1249
|
let i = getComputedStyle(e), a = (i.getPropertyValue(n).trim() || r).match(/^(\d+(?:\.\d+)?)(px|%|em|rem)$/);
|
|
1232
1250
|
if (!a) return null;
|
|
1233
1251
|
let o = Number(a[1]);
|
|
1234
1252
|
return a[2] === "%" ? o / 100 * j : o * (a[2] === "em" ? Number.parseFloat(i.fontSize) : a[2] === "rem" ? Number.parseFloat(getComputedStyle(document.documentElement).fontSize) : 1) * t;
|
|
1235
|
-
},
|
|
1253
|
+
}, dt = (e, t) => ut(e, t, "--tablechart-bar-max", "60px") ?? Infinity, ft = (t, n) => {
|
|
1236
1254
|
let { plot: r, svg: i, rows: a, type: o, values: s, series: c, seriesValues: l, names: u, annotations: d } = t, f = r.clientWidth;
|
|
1237
1255
|
if (!f) return !1;
|
|
1238
1256
|
let p = j / f, m = Number.parseFloat(t.figure.dataset.chartAspect ?? ""), h = j * (m > 0 ? m : o.aspect ?? n.aspect);
|
|
@@ -1245,7 +1263,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1245
1263
|
...t.categories,
|
|
1246
1264
|
...d.map((e) => e.badge)
|
|
1247
1265
|
]);
|
|
1248
|
-
let g = (s[0] ? Y(s[0]).height : 0) * p, _ = d[0]?.badge ? Y(d[0].badge).height * p : 0, v = Math.max(h,
|
|
1266
|
+
let g = (s[0] ? Y(s[0]).height : 0) * p, _ = d[0]?.badge ? Y(d[0].badge).height * p : 0, v = Math.max(h, ut(t.figure, p, "--tablechart-min-height", "200px") ?? 0, o.minHeight?.({
|
|
1249
1267
|
labelHeight: g,
|
|
1250
1268
|
nameHeight: Math.max(0, U(t.categories.map((e) => Y(e).height))) * p,
|
|
1251
1269
|
unit: p,
|
|
@@ -1297,7 +1315,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1297
1315
|
share: s
|
|
1298
1316
|
} : console.warn(`[${e}] This kind of chart cannot break its scale.`);
|
|
1299
1317
|
}
|
|
1300
|
-
let L = I ? I.gap : null, R = (I &&
|
|
1318
|
+
let L = I ? I.gap : null, R = (I && ut(t.figure, p, "--tablechart-break-gap", "")) ?? 13, z = v - T, ee = (e) => z - e / k * O;
|
|
1301
1319
|
if (I) {
|
|
1302
1320
|
let { lo: e, hi: t, gap: n, share: r } = I, i = O * r, a = (O - i - R) / (e + (k - t)), o = i / (t - e);
|
|
1303
1321
|
ee = (r) => r <= e ? z - r * a : r <= n ? z - e * a - (r - e) * o : r <= t ? z - e * a - (r - e) * o - R : z - e * a - i - R - (r - t) * a;
|
|
@@ -1323,8 +1341,8 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1323
1341
|
segments: x,
|
|
1324
1342
|
cx: te,
|
|
1325
1343
|
y: ee,
|
|
1326
|
-
barWidth: Math.min(W * n.barfill,
|
|
1327
|
-
barMax:
|
|
1344
|
+
barWidth: Math.min(W * n.barfill, dt(t.figure, p)),
|
|
1345
|
+
barMax: dt(t.figure, p),
|
|
1328
1346
|
height: v,
|
|
1329
1347
|
unit: p,
|
|
1330
1348
|
labelHeight: g,
|
|
@@ -1333,12 +1351,12 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1333
1351
|
note: 0,
|
|
1334
1352
|
labels: t.figure.dataset.chartLabels === "inside" || t.figure.dataset.chartLabels !== "outside" && n.labels === "inside" ? "inside" : "outside",
|
|
1335
1353
|
closing: (t.figure.dataset.chartClosing ?? n.closing) === "up" ? "up" : "down",
|
|
1336
|
-
insideAlign:
|
|
1354
|
+
insideAlign: lt(t.figure),
|
|
1337
1355
|
breakAt: L,
|
|
1338
1356
|
squeeze: I,
|
|
1339
1357
|
breakGap: R,
|
|
1340
1358
|
stacked: t.stacked,
|
|
1341
|
-
shape:
|
|
1359
|
+
shape: rt(t.figure, n),
|
|
1342
1360
|
totals: t.totals,
|
|
1343
1361
|
svg: i,
|
|
1344
1362
|
plot: r,
|
|
@@ -1379,7 +1397,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1379
1397
|
note: e + 1
|
|
1380
1398
|
});
|
|
1381
1399
|
}
|
|
1382
|
-
|
|
1400
|
+
Xe(t);
|
|
1383
1401
|
let ne = t.categories[0]?.parentElement;
|
|
1384
1402
|
return ne && o.categories !== "beside" && !o.centre && be(ne, t.categories.filter((e) => e.offsetParent !== null), (e) => ({
|
|
1385
1403
|
size: e.scrollWidth,
|
|
@@ -1400,7 +1418,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1400
1418
|
style: ["--after", "--step"].map((t) => e.style.getPropertyValue(t) && `${t}:${e.style.getPropertyValue(t)}`).filter(Boolean).join("; ")
|
|
1401
1419
|
})];
|
|
1402
1420
|
}), j, v), !0;
|
|
1403
|
-
},
|
|
1421
|
+
}, pt = (e, t) => {
|
|
1404
1422
|
let n = [
|
|
1405
1423
|
...e.seriesValues.flat(),
|
|
1406
1424
|
...e.totals,
|
|
@@ -1418,11 +1436,11 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1418
1436
|
e.className = D, e.textContent = o, r.prepend(e);
|
|
1419
1437
|
}
|
|
1420
1438
|
}
|
|
1421
|
-
},
|
|
1439
|
+
}, mt = (e) => {
|
|
1422
1440
|
e.plot.remove(), e.categories[0]?.parentElement?.remove(), e.figure.querySelector(`:scope > .${v}`)?.remove(), e.controls?.remove();
|
|
1423
|
-
},
|
|
1441
|
+
}, ht = (e, t) => {
|
|
1424
1442
|
e.figure.classList.toggle(O, t), t || e.plot.removeAttribute("data-pointed");
|
|
1425
|
-
},
|
|
1443
|
+
}, gt = (e) => {
|
|
1426
1444
|
let { plot: t } = e, n = () => [...e.seriesValues.flat(), ...e.totals], r = (e, t) => {
|
|
1427
1445
|
let n = Number(e.dataset.row), r = Number(e.dataset.rowEnd ?? n);
|
|
1428
1446
|
return t >= n && t <= r;
|
|
@@ -1457,25 +1475,25 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1457
1475
|
}), document.addEventListener("pointerdown", (e) => {
|
|
1458
1476
|
t.contains(e.target) || a();
|
|
1459
1477
|
});
|
|
1460
|
-
},
|
|
1478
|
+
}, _t = (e) => e === "id" || e === "style" || e.startsWith("data-chart"), vt = /^\s*(?:Table)?:\s+/, yt = (e) => e?.tagName === "P" && vt.test(e.textContent ?? ""), bt = (e) => {
|
|
1461
1479
|
let t = document.createElement("figcaption");
|
|
1462
1480
|
for (let { name: n, value: r } of Array.from(e.attributes)) t.setAttribute(n, r);
|
|
1463
1481
|
let n = e.firstChild;
|
|
1464
|
-
n?.nodeType === Node.TEXT_NODE && (n.textContent = (n.textContent ?? "").replace(
|
|
1482
|
+
n?.nodeType === Node.TEXT_NODE && (n.textContent = (n.textContent ?? "").replace(vt, ""), n.textContent || n.remove());
|
|
1465
1483
|
let r = Array.from(e.childNodes), i = r.findIndex((e) => e.nodeName === "BR");
|
|
1466
1484
|
if (t.append(...i === -1 ? r : r.slice(0, i + 1)), i !== -1 && i < r.length - 1) {
|
|
1467
1485
|
let e = document.createElement("span");
|
|
1468
1486
|
e.append(...r.slice(i + 1)), t.append(e);
|
|
1469
1487
|
}
|
|
1470
1488
|
return e.remove(), t;
|
|
1471
|
-
},
|
|
1472
|
-
let t =
|
|
1489
|
+
}, xt = /^\s*([a-z][\w-]*)((?:\s+[\w-]+=[^\s:]+)*)\s*(:\s*|$)/, St = (e) => {
|
|
1490
|
+
let t = kt(e);
|
|
1473
1491
|
return t?.tagName === "P" ? t : e;
|
|
1474
|
-
},
|
|
1475
|
-
let t =
|
|
1492
|
+
}, Ct = (e) => {
|
|
1493
|
+
let t = St(e).firstChild;
|
|
1476
1494
|
if (t?.nodeType !== Node.TEXT_NODE) return null;
|
|
1477
|
-
let n =
|
|
1478
|
-
if (!n || !
|
|
1495
|
+
let n = xt.exec(t.textContent ?? "");
|
|
1496
|
+
if (!n || !et.includes(n[1]) || !n[3] && t.nextSibling) return null;
|
|
1479
1497
|
let r = n[2].trim().split(/\s+/).filter(Boolean).map((e) => e.split("="));
|
|
1480
1498
|
return {
|
|
1481
1499
|
name: n[1],
|
|
@@ -1483,11 +1501,11 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1483
1501
|
text: t,
|
|
1484
1502
|
length: n[0].length
|
|
1485
1503
|
};
|
|
1486
|
-
},
|
|
1504
|
+
}, wt = (e) => {
|
|
1487
1505
|
if (e?.tagName !== "UL" && e?.tagName !== "OL") return null;
|
|
1488
|
-
let t = Array.from(e.children), n = t.map((e) => e.hasAttribute("data-annotation") ? null :
|
|
1506
|
+
let t = Array.from(e.children), n = t.map((e) => e.hasAttribute("data-annotation") ? null : Ct(e));
|
|
1489
1507
|
return !t.length || t.some((e, t) => !n[t] && !e.hasAttribute("data-annotation")) ? null : (t.forEach((e, t) => {
|
|
1490
|
-
let r = n[t], i =
|
|
1508
|
+
let r = n[t], i = St(e);
|
|
1491
1509
|
if (i !== e && i.replaceWith(...i.childNodes), r) {
|
|
1492
1510
|
e.setAttribute("data-annotation", r.name);
|
|
1493
1511
|
for (let [t, n] of r.options) e.setAttribute(`data-${t}`, n);
|
|
@@ -1498,18 +1516,18 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1498
1516
|
t === 0 && e instanceof HTMLElement && e.matches("em, i") ? (n.className = d, n.append(...e.childNodes), e.replaceWith(n)) : e.nodeType === Node.TEXT_NODE && (n.textContent = (e.textContent ?? "").trim(), e.replaceWith(n));
|
|
1499
1517
|
});
|
|
1500
1518
|
}), e.classList.add("chart-annotations"), e);
|
|
1501
|
-
},
|
|
1502
|
-
for (let { name: n, value: r } of Array.from(e.attributes)) (n === "class" ||
|
|
1503
|
-
},
|
|
1504
|
-
let t = e.closest("p"), n =
|
|
1519
|
+
}, Tt = (e, t) => {
|
|
1520
|
+
for (let { name: n, value: r } of Array.from(e.attributes)) (n === "class" || _t(n)) && (t.setAttribute(n, r), e.removeAttribute(n));
|
|
1521
|
+
}, Et = (e) => e.map((e) => {
|
|
1522
|
+
let t = e.closest("p"), n = yt(t) ? t : e;
|
|
1505
1523
|
if (n.tagName !== "TABLE" && n.tagName !== "P") return n;
|
|
1506
1524
|
let r = document.createElement("div");
|
|
1507
|
-
|
|
1508
|
-
let i = n.tagName === "TABLE" ? n : null, a = n.previousElementSibling, o = n.nextElementSibling, s = i ?
|
|
1525
|
+
Tt(e, r), e.classList.length || e.removeAttribute("class");
|
|
1526
|
+
let i = n.tagName === "TABLE" ? n : null, a = n.previousElementSibling, o = n.nextElementSibling, s = i ? yt(a) ? a : yt(o) ? o : null : n;
|
|
1509
1527
|
i && s === o && (o = o?.nextElementSibling ?? null);
|
|
1510
|
-
let c = o?.classList.contains("chart-annotations") ? o :
|
|
1511
|
-
return n.replaceWith(r), s && r.append(
|
|
1512
|
-
}),
|
|
1528
|
+
let c = o?.classList.contains("chart-annotations") ? o : wt(o);
|
|
1529
|
+
return n.replaceWith(r), s && r.append(bt(s)), i && r.append(i), c && r.append(c), Z?.log?.(`A ${i ? "table" : "caption"} with chart attributes was wrapped in a figure of its own`), r;
|
|
1530
|
+
}), Dt = (e, t = []) => {
|
|
1513
1531
|
let n = document.createElement("table");
|
|
1514
1532
|
if (t.length) {
|
|
1515
1533
|
let e = n.createTHead().insertRow();
|
|
@@ -1528,7 +1546,7 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1528
1546
|
for (let n of t.values ?? [t.value ?? null]) e.insertCell().textContent = n === null ? "" : String(n);
|
|
1529
1547
|
}
|
|
1530
1548
|
return n;
|
|
1531
|
-
},
|
|
1549
|
+
}, Ot = async (t) => {
|
|
1532
1550
|
await Promise.all(t.filter((e) => e.hasAttribute("data-chart-src")).map(async (t) => {
|
|
1533
1551
|
let n = t.getAttribute("data-chart-src");
|
|
1534
1552
|
for (let e of t.querySelectorAll("table")) e.remove();
|
|
@@ -1537,17 +1555,17 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1537
1555
|
if (!e.ok) throw Error(`${e.status} ${e.statusText}`);
|
|
1538
1556
|
let r = await e.json(), i = Array.isArray(r) ? r : r?.rows;
|
|
1539
1557
|
if (!Array.isArray(i)) throw Error("no array of rows in it");
|
|
1540
|
-
let a = Array.isArray(r?.series) ? r.series.map(String) : [], o = t.querySelector(":scope > figcaption"), s =
|
|
1558
|
+
let a = Array.isArray(r?.series) ? r.series.map(String) : [], o = t.querySelector(":scope > figcaption"), s = Dt(i, a);
|
|
1541
1559
|
o ? o.after(s) : t.prepend(s), Z?.log?.(`Read ${i.length} rows from "${n}"`);
|
|
1542
1560
|
} catch (t) {
|
|
1543
1561
|
let r = window.location.protocol === "file:";
|
|
1544
1562
|
console.warn(`[${e}] Could not read the chart data in "${n}": ${t.message}.` + (r ? " A page opened from the file system cannot fetch files; open the page from a server instead." : ""));
|
|
1545
1563
|
}
|
|
1546
1564
|
}));
|
|
1547
|
-
},
|
|
1565
|
+
}, kt = (e) => {
|
|
1548
1566
|
let t = Array.from(e.childNodes).filter((e) => e.nodeType === Node.ELEMENT_NODE || e.nodeType === Node.TEXT_NODE && e.textContent?.trim());
|
|
1549
1567
|
return t.length === 1 && t[0] instanceof HTMLElement ? t[0] : null;
|
|
1550
|
-
},
|
|
1568
|
+
}, At = "strong, b, span.total", jt = (e) => {
|
|
1551
1569
|
for (let t of e) {
|
|
1552
1570
|
for (let e of t.querySelectorAll("tbody tr")) {
|
|
1553
1571
|
let t = e.cells[0];
|
|
@@ -1555,16 +1573,16 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1555
1573
|
let n = document.createElement("th");
|
|
1556
1574
|
for (let { name: e, value: r } of Array.from(t.attributes)) n.setAttribute(e, r);
|
|
1557
1575
|
n.append(...t.childNodes), t.replaceWith(n);
|
|
1558
|
-
for (let t =
|
|
1576
|
+
for (let t = kt(n); t?.matches(At); t = kt(n)) e.dataset.kind = "total", t.replaceWith(...t.childNodes);
|
|
1559
1577
|
}
|
|
1560
1578
|
let e = Array.from(t.querySelector("thead tr:last-child")?.children ?? []);
|
|
1561
|
-
for (let t of e.slice(1)) for (let e =
|
|
1579
|
+
for (let t of e.slice(1)) for (let e = kt(t); e?.matches(At); e = kt(t)) t.setAttribute("data-kind", "focus"), e.replaceWith(...e.childNodes);
|
|
1562
1580
|
}
|
|
1563
|
-
},
|
|
1581
|
+
}, Mt = "data-chart-made", Nt = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches, Pt = (e) => new Promise((t) => setTimeout(t, e)), Ft = (e, t) => {
|
|
1564
1582
|
let n = Number.parseFloat(e.dataset.chartEntrance ?? ""), r = Number.isFinite(n) ? n : t.entrance;
|
|
1565
1583
|
return Math.min(Math.max(r, 0), 1);
|
|
1566
|
-
},
|
|
1567
|
-
if (
|
|
1584
|
+
}, It = async (e, t) => {
|
|
1585
|
+
if (Nt()) return;
|
|
1568
1586
|
await new Promise(requestAnimationFrame);
|
|
1569
1587
|
let n = e.getAnimations().filter((e) => e instanceof CSSAnimation);
|
|
1570
1588
|
for (let t = e.parentElement; t && t !== document.body; t = t.parentElement) n.push(...t.getAnimations());
|
|
@@ -1575,11 +1593,11 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1575
1593
|
let a = Number(n.delay ?? 0) + i * t;
|
|
1576
1594
|
r = Math.max(r, a - Number(e.currentTime ?? 0));
|
|
1577
1595
|
}
|
|
1578
|
-
r > 0 && await
|
|
1579
|
-
},
|
|
1596
|
+
r > 0 && await Pt(r);
|
|
1597
|
+
}, Lt = (e) => {
|
|
1580
1598
|
for (let t = e; t && t !== document.body; t = t.parentElement) if (getComputedStyle(t).opacity === "0") return t;
|
|
1581
1599
|
return null;
|
|
1582
|
-
},
|
|
1600
|
+
}, Rt = (e) => new Promise((t) => {
|
|
1583
1601
|
let n = ["animationstart", "transitionrun"], r = () => {
|
|
1584
1602
|
for (let e of n) document.removeEventListener(e, i, !0);
|
|
1585
1603
|
a.disconnect(), t();
|
|
@@ -1593,54 +1611,54 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1593
1611
|
attributes: !0,
|
|
1594
1612
|
attributeFilter: ["class", "style"]
|
|
1595
1613
|
});
|
|
1596
|
-
}),
|
|
1597
|
-
|
|
1598
|
-
for (let e of
|
|
1614
|
+
}), zt = /* @__PURE__ */ new Set(), $ = null, Bt = (e) => {
|
|
1615
|
+
zt.add(e), !$ && ($ = new MutationObserver(() => {
|
|
1616
|
+
for (let e of zt) e.relabel();
|
|
1599
1617
|
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
1600
|
-
for (let e of
|
|
1618
|
+
for (let e of zt) e.refresh();
|
|
1601
1619
|
}));
|
|
1602
1620
|
}), $.observe(document.documentElement, {
|
|
1603
1621
|
attributes: !0,
|
|
1604
1622
|
attributeFilter: ["lang"]
|
|
1605
1623
|
}));
|
|
1606
|
-
},
|
|
1607
|
-
|
|
1608
|
-
},
|
|
1624
|
+
}, Vt = (e) => {
|
|
1625
|
+
zt.delete(e), !(zt.size || !$) && ($.disconnect(), $ = null);
|
|
1626
|
+
}, Ht = ["column", "bar"], Ut = (e) => {
|
|
1609
1627
|
let t = e.getAttribute("data-chart") || "column";
|
|
1610
|
-
if (!
|
|
1628
|
+
if (!Ht.includes(t)) return null;
|
|
1611
1629
|
let n = getComputedStyle(e).getPropertyValue("--tablechart-type").trim();
|
|
1612
|
-
return
|
|
1613
|
-
},
|
|
1614
|
-
let n = e, r =
|
|
1615
|
-
if (!t.animate) return
|
|
1630
|
+
return Ht.includes(n) ? n : t;
|
|
1631
|
+
}, Wt = (e, t) => {
|
|
1632
|
+
let n = e, r = Ut(n.figure), i = null, a = !1, o = !1, s = async () => {
|
|
1633
|
+
if (!t.animate) return ht(n, !0);
|
|
1616
1634
|
let e = n.figure.classList.contains("is-shown");
|
|
1617
1635
|
if (a && i !== null && !e && !o) {
|
|
1618
1636
|
o = !0;
|
|
1619
|
-
let e =
|
|
1620
|
-
e && await
|
|
1621
|
-
} else !a && t.replay && e &&
|
|
1637
|
+
let e = Nt() ? null : Lt(n.figure);
|
|
1638
|
+
e && await Rt(e), await It(n.figure, Ft(n.figure, t)), o = !1, (a || !t.replay) && ht(n, !0);
|
|
1639
|
+
} else !a && t.replay && e && ht(n, !1);
|
|
1622
1640
|
}, c = () => {
|
|
1623
|
-
let e =
|
|
1641
|
+
let e = Ut(n.figure);
|
|
1624
1642
|
if (!e || e === r) return;
|
|
1625
|
-
let a = Z.timed("Building", n.figure, () =>
|
|
1626
|
-
a && (
|
|
1643
|
+
let a = Z.timed("Building", n.figure, () => ct(n.figure, t, e));
|
|
1644
|
+
a && (mt(n), Q(a, n.step, !0), n = a, r = e, i = null);
|
|
1627
1645
|
}, l = () => {
|
|
1628
1646
|
c();
|
|
1629
1647
|
let e = n.plot.clientWidth;
|
|
1630
|
-
!e || e === i || Z.timed("Layout", n.figure, () =>
|
|
1648
|
+
!e || e === i || Z.timed("Layout", n.figure, () => ft(n, t)) && (i = e, s());
|
|
1631
1649
|
}, u = !1, d = new ResizeObserver(() => {
|
|
1632
1650
|
u || (u = !0, requestAnimationFrame(() => {
|
|
1633
1651
|
u = !1, l();
|
|
1634
1652
|
}));
|
|
1635
1653
|
}), f = new IntersectionObserver((e) => {
|
|
1636
1654
|
for (let t of e) a = t.isIntersecting, s();
|
|
1637
|
-
}, { threshold: t.threshold }), p = () =>
|
|
1655
|
+
}, { threshold: t.threshold }), p = () => ht(n, !0), m = () => {
|
|
1638
1656
|
i = null, l();
|
|
1639
1657
|
}, h = {
|
|
1640
|
-
relabel: () =>
|
|
1658
|
+
relabel: () => pt(n, t),
|
|
1641
1659
|
refresh: m
|
|
1642
1660
|
};
|
|
1643
|
-
c(), l(), d.observe(n.figure), f.observe(n.figure), window.addEventListener("beforeprint", p),
|
|
1661
|
+
c(), l(), d.observe(n.figure), f.observe(n.figure), window.addEventListener("beforeprint", p), Bt(h);
|
|
1644
1662
|
let g = {
|
|
1645
1663
|
figure: n.figure,
|
|
1646
1664
|
refresh: m,
|
|
@@ -1654,32 +1672,32 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1654
1672
|
return n.plan?.count ?? 0;
|
|
1655
1673
|
},
|
|
1656
1674
|
destroy() {
|
|
1657
|
-
d.disconnect(), f.disconnect(), window.removeEventListener("beforeprint", p),
|
|
1675
|
+
d.disconnect(), f.disconnect(), window.removeEventListener("beforeprint", p), Vt(h), n.figure.tablechart === g && delete n.figure.tablechart;
|
|
1658
1676
|
}
|
|
1659
1677
|
};
|
|
1660
1678
|
return n.figure.tablechart = g, g;
|
|
1661
|
-
},
|
|
1662
|
-
let n =
|
|
1663
|
-
return await
|
|
1664
|
-
},
|
|
1665
|
-
let n = Z.timed("Building", e, () =>
|
|
1666
|
-
return n ? (e.setAttribute(
|
|
1667
|
-
},
|
|
1679
|
+
}, Gt = async (e, t) => {
|
|
1680
|
+
let n = Et(e.filter((e) => !e.hasAttribute(Mt)));
|
|
1681
|
+
return await Ot(n), jt(n), Ke(n, t.langattribute), n;
|
|
1682
|
+
}, Kt = (e, t) => {
|
|
1683
|
+
let n = Z.timed("Building", e, () => ct(e, t));
|
|
1684
|
+
return n ? (e.setAttribute(Mt, ""), Wt(n, t)) : null;
|
|
1685
|
+
}, qt = async (e, t = {}) => {
|
|
1668
1686
|
if (e.tablechart) return e.tablechart;
|
|
1669
1687
|
let n = {
|
|
1670
1688
|
...M,
|
|
1671
1689
|
...t
|
|
1672
1690
|
};
|
|
1673
1691
|
n.debug && (Z.enabled = !0);
|
|
1674
|
-
let [r] = await
|
|
1675
|
-
return r ?
|
|
1676
|
-
},
|
|
1692
|
+
let [r] = await Gt([e], n);
|
|
1693
|
+
return r ? Kt(r, n) : null;
|
|
1694
|
+
}, Jt = async (e = {}, t = document) => {
|
|
1677
1695
|
let n = {
|
|
1678
1696
|
...M,
|
|
1679
1697
|
...e
|
|
1680
1698
|
};
|
|
1681
1699
|
n.debug && (Z.enabled = !0);
|
|
1682
|
-
let r = (await
|
|
1700
|
+
let r = (await Gt(Array.from(t.querySelectorAll(n.selector)), n)).map((e) => Kt(e, n)).filter((e) => e !== null);
|
|
1683
1701
|
return Z.log(`Made ${r.length} chart(s).`), {
|
|
1684
1702
|
charts: r,
|
|
1685
1703
|
refresh: () => {
|
|
@@ -1691,4 +1709,4 @@ var Pe = (e) => e.map((e) => ({
|
|
|
1691
1709
|
};
|
|
1692
1710
|
};
|
|
1693
1711
|
//#endregion
|
|
1694
|
-
export { k as _,
|
|
1712
|
+
export { k as _, Et as a, ct as c, ht as d, mt as f, t as g, w as h, Gt as i, ft as l, Ke as m, Ft as n, Ot as o, Q as p, Jt as r, jt as s, qt as t, pt as u, O as v, M as y };
|
package/dist/tablechart.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){var t="tablechart",e="tablechart-value",n="tablechart-bar",a="tablechart-rule",o="tablechart-line",r="tablechart-head",s="tablechart-slice",c="tablechart-legend",i="tablechart-hole",l="tablechart-break",u="tablechart-sr",d=1e3,h={selector:"[data-chart]",aspect:.38,barfill:.58,ringfill:.42,animate:!0,entrance:.5,labels:"outside",shape:"straight",closing:"down",legend:!1,hover:!0,totallabel:"Total",controls:!0,previouslabel:"Previous",nextlabel:"Next",stephint:"step of the chart",threshold:.5,replay:!1,langattribute:"data-i18n"},f=(t,e)=>`${t}:${e}`,b=(t,e={})=>{const n=document.createElementNS("http://www.w3.org/2000/svg",t);for(const a in e)n.setAttribute(a,String(e[a]));return n},m=(t,e)=>[t,...e.classes].join(" "),g=(t,e)=>{const n=document.createElement("span");return n.className=t,n.inert=!0,e.appendChild(n),n},$=(t,e,n,a,o)=>{t.style.left=e/a*100+"%",t.style.top=n/o*100+"%"},p=0,y=(t,e,n,a)=>{if(!e.length)return;const o="tablechart-cut-"+ ++p,r=b("mask",{id:o,maskUnits:"userSpaceOnUse"});r.appendChild(b("rect",{x:-n,y:-a,width:3*n,height:3*a,fill:"white"}));for(const i of e)i.setAttribute("fill","black"),r.appendChild(i);let s=t.querySelector(":scope > defs");s||(s=b("defs"),t.prepend(s)),s.appendChild(r);const c=b("g",{mask:`url(#${o})`});for(const i of Array.from(t.childNodes))i!==s&&c.appendChild(i);t.appendChild(c)},w=0,v={create:()=>null,draw(t,e,a){const{rows:o,y:r,svg:s,breakAt:c}=a;if(null===c)return;const i="zigzag"===t.getAttribute("data-mark"),u=(t,e)=>{const n=t.sideways?t.height:t.width,a=.09*n,o=n+2*a,r=.3*o,s=.06*o;if(t.sideways){const n=t.y-a;if(!i)return[[e-r/2,n],[e+r/2,n+o]];const c=o/3;return[[e-s,n],[e+s,n+c],[e-s,n+2*c],[e+s,n+o]]}const c=t.x-a;if(!i)return[[c,e+r/2],[c+o,e-r/2]];const l=o/3;return[[c,e+s],[c+l,e-s],[c+2*l,e+s],[c+o,e-s]]},d=(t,e=!1)=>t.map(([t,e],n)=>`${0===n?"M":"L"} ${t.toFixed(1)} ${e.toFixed(1)}`).join(" ")+(e?" Z":""),h="tablechart-break-"+ ++w,m=b("mask",{id:h,maskUnits:"userSpaceOnUse"});m.appendChild(b("rect",{x:-1e3,y:-a.height,width:3e3,height:3*a.height,fill:"white"}));const g=[],$=r(c);for(const w of(t=>Array.from(t.querySelectorAll(`.${n}`)).map(t=>{const e="rect"===t.tagName?[t]:Array.from(t.querySelectorAll("rect")),n=(t,e)=>Number(t.getAttribute(e)),a=Math.min(...e.map(t=>n(t,"x"))),o=Math.min(...e.map(t=>n(t,"y"))),r=Math.max(...e.map(t=>n(t,"x")+n(t,"width"))),s=Math.max(...e.map(t=>n(t,"y")+n(t,"height")));return{row:Number(t.dataset.row),x:a,y:o,width:r-a,height:s-o,sideways:"right"===t.dataset.grow}}))(s)){const t=w.sideways?a.breakX:$;if(void 0===t)continue;if(!(w.sideways?w.x<t&&w.x+w.width>t:w.y<$&&w.y+w.height>$))continue;const[e,n]=w.sideways?[u(w,t),u(w,t+a.breakGap)]:[u(w,$-a.breakGap),u(w,$)];m.appendChild(b("path",{d:d([...e,...n.slice().reverse()],!0),fill:"black"})),g.push(e,n);const r=f("--after",o[w.row-1]?.slot??0);for(const o of[e,n])s.appendChild(b("path",{class:l,"data-part":"edge","data-note":a.note,d:d(o),style:r}))}if(!g.length)return;const p=Array.from(s.querySelectorAll(`.${l}`)),y=b("g",{mask:`url(#${h})`});for(const n of Array.from(s.childNodes))p.includes(n)||y.appendChild(n);const v=b("defs");v.appendChild(m),s.prepend(v,y)}},M=t=>{let e=Number.NEGATIVE_INFINITY;for(const n of t)e=Math.max(e,n);return e},k=t=>(t.split(/[.,]/)[1]||"").length,x=(t,e,n)=>{const a=((t,e)=>new Intl.NumberFormat(e||document.documentElement.lang||void 0,{minimumFractionDigits:t,maximumFractionDigits:t}))(e,n).formatToParts(t),o="minusSign"===a[0]?.type?a[0].value:"";return[o,a.slice(o?1:0).map(t=>t.value).join("")]},A=(t,e)=>{const n=document.createElement("span");if(n.className="tablechart-badge",n.inert=!0,t.childElementCount>0)for(const a of Array.from(t.children))n.appendChild(a.cloneNode(!0));else{n.textContent=(t.textContent||"").trim();const e=t.getAttribute("data-i18n");e&&n.setAttribute("data-i18n",e)}return e.appendChild(n),n},N=(e,n,a,o)=>{const r=(s=e?.textContent||"",Number.parseFloat((s.match(/-?[\d.,]+/)||["NaN"])[0].replace(",",".")));var s;const c=!!Number.isNaN(r)||Math.abs(n-r)<=.5,i={label:a,computed:n,stated:r,agrees:c};o.checks.push(i),c||console.warn(`[${t}] An annotation reads ${r}%, but ${a} is ${n.toFixed(1)}%. The chart shows what you wrote; this is only a check.`)},S={create:A,draw(e,n,a){const{rows:s,cx:c,y:i,unit:l,labelHeight:u,badgeHeight:h,height:m,svg:g,after:p}=a,[y,w]=((t,e)=>{const n=(e,n)=>{const a=Number.parseInt(t.getAttribute(e)??"",10);return Number.isFinite(a)?a-1:n};return[n("data-from",0),n("data-to",e-1)]})(e,s.length),v=s[y],M=s[w];if(!v||!M)return void console.warn(`[${t}] A bracket points at a row that is not there (row ${y+1} to ${w+1}, of ${s.length}).`);const k=7*l,x=4*l,A=c(y),S=c(w),H=Math.min(i(v.value),i(M.value))-u-x-.9*h,L=t=>i(t)-u-x,T=`M ${A} ${L(v.value)} L ${A} ${H} L ${S} ${H} L ${S} ${L(M.value)-k}`,z=(L(v.value)-H+Math.abs(S-A)+(L(M.value)-k-H))/l+1;g.appendChild(b("path",{class:o,"data-note":a.note,d:T,style:`--len:${z.toFixed(1)}; ${f("--after",p)}`}));const C=L(M.value);var O;g.appendChild(b("polygon",{class:r,"data-note":a.note,points:`${S},${C} ${S-.45*k},${C-k} ${S+.45*k},${C-k}`,style:f("--after",p)})),n&&($(n,(A+S)/2,H,d,m),n.style.setProperty("--after",String(p))),N(n,(O=v.value,(M.value-O)/Math.abs(O)*100),`${v.value} to ${M.value}`,a)}},H=new WeakMap,L=t=>H.get(t)??{width:t.offsetWidth,height:t.offsetHeight},T={create:A,draw(t,e,n){const{rows:a,cx:s,y:c,unit:i,labelHeight:l,height:u,svg:h,values:m,after:g}=n,p=a[0],y=a[a.length-1];if(!p||!y)return;const w=l+18*i,v=10*i,M=10*i;let k=s(0),x=c(p.value)-w,A=s(a.length-1),S=c(y.value)-w,H=0;a.forEach((t,e)=>{const n=A===k?0:(s(e)-k)/(A-k),a=x+n*(S-x)-(c(t.value)-w);a>H&&(H=a)}),x-=H,S-=H;const T=A-k,z=S-x,C=Math.hypot(T,z)||1,O=T/C,U=z/C;k-=O*v,x-=U*v,A+=O*v,S+=U*v;const B=Number.parseFloat(t.getAttribute("data-at")||"0.5");if(e){const t=k+(A-k)*B,n=x+(S-x)*B,o=L(e).width*i/2,r=n+L(e).height*i/2+8*i;let u=0;a.forEach((e,n)=>{const a=(m[n]?L(m[n]).width:0)*i/2;if(Math.abs(s(n)-t)>=o+a)return;const d=c(e.value)-7*i-l;u=Math.max(u,r-d)}),x-=u,S-=u}const E=A-O*M,F=S-U*M,P=Math.hypot(E-k,F-x)/i+1;h.appendChild(b("line",{class:o,"data-note":n.note,x1:k,y1:x,x2:E,y2:F,style:`--len:${P.toFixed(1)}; ${f("--after",g)}`}));const q=-U,I=O,V=.42*M;h.appendChild(b("polygon",{class:r,"data-note":n.note,points:[`${A},${S}`,`${E+q*V},${F+I*V}`,`${E-q*V},${F-I*V}`].join(" "),style:f("--after",g)})),e&&($(e,k+(A-k)*B,x+(S-x)*B,d,u),e.style.setProperty("--after",String(g)));const j=Number.parseFloat(t.getAttribute("data-years")||"");!Number.isNaN(j)&&j>0&&N(e,((t,e,n)=>100*(Math.pow(e/t,1/n)-1))(p.value,y.value,j),`${p.value} to ${y.value} over ${j} years`,n)}},z=(t,e,n)=>{const a=.15,o=Math.min(.7*t/(e+(e-1)*a),n),r=e*o+(e-1)*o*a;return{size:o,gap:o*a,offset:t=>-r/2+t*o*1.15}},C=(t,e,n)=>{const a=t.series[n],o=t.series.some(t=>t.focus)&&!a.focus;return{"data-series":n+1,...o&&{"data-muted":""},style:`--n:${n}; --m:${o?1:0}; --palette:var(--tablechart-color-${n+1}); ${f("--i",e.slot)}`}},O=(t,e)=>{let n=0;return Array.from({length:e},(e,a)=>{const o=t.cells[a]??t.cells[0],r=n;return!o.missing&&o.value>0&&(n+=o.value),{from:r,to:n,cell:o}})},U=(t,e)=>O(t,e).at(-1)?.to??0,B=(t,e,n)=>{const a=e.series.some(t=>t.focus);t.style.setProperty("--n",String(n)),t.style.setProperty("--m",a&&!e.series[n].focus?"1":"0"),t.style.setProperty("--palette",`var(--tablechart-color-${n+1})`)},E=(t,e,a,o={})=>{const r=b("g",{class:m(n,e),"data-kind":"bar","data-row":a+1,...o,"data-stack":"",style:f("--i",e.slot)});return t.svg.appendChild(r),(n,a)=>{r.appendChild(b("rect",{...a,class:m("tablechart-piece",e),...C(t,e,n)}))}},F=(t,e,n)=>t.some(t=>L(t).width*n>e-6*n),P=(t,e,n)=>e>=L(t).height*n*1.6,q=(t,e,n)=>e>=L(t).width*n*1.5,I=(t,e,n,a,o=.7)=>{t.style.setProperty(a,"1");let r=1;for(const c of e){const{size:t,room:e}=n(c);t>e&&(r=Math.min(r,e/t))}const s=r>=o?r:0;return t.style.setProperty(a,String(s||o)),s},V={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,breakable:!0,aspect:.5,minHeight:({labelHeight:t,nameHeight:e,rows:n,series:a,stacked:o})=>{const r=1.1*t,s=a>1&&!o?r*(a+.15*(a-1))/.7:r/.58;return n*Math.max(s,1.2*e)},categories:"beside",headroom:()=>0,draw(t){const{segments:e,height:o,unit:r,svg:s,values:c,categories:i,config:l,barMax:u}=t,h=t.series.length>1,g=Math.max(M(i.map(t=>L(t).width*r)),0),p=Math.min(g+10*r,420),y=d-4*r,w=t.stacked?Math.max(M(t.rows.map(e=>U(e,t.series.length))),0)||1:Math.max(M(t.rows.flatMap(e=>e.cells.slice(0,t.series.length).map(t=>Math.abs(t.value)))),0)||1,v=Math.max(w,t.squeeze?.hi??0),k=(e,n)=>((t,e,n,a,o)=>{if(!a)return t/e*n;const{lo:r,hi:s,gap:c,share:i}=a,l=n*i,u=(n-l-o)/(r+(e-s)),d=l/(s-r);return t<=r?t*u:t<=c?r*u+(t-r)*d:t<=s?r*u+(t-r)*d+o:r*u+l+o+(t-s)*u})(Math.abs(e),v,n,t.squeeze,t.breakGap),x=o/e.length,A=t=>(t+.5)*x,N=Math.min(x*l.barfill,u),S=z(x,t.series.length,u),H=c[0]??t.totals[0],T=H?L(H).height*r*.56:0,F=Math.max(((h&&!t.stacked?S.size:N)-T)/2,5*r),P=t=>L(t).width*r,V=t=>t.length?M(t.map(P))+F+4*r:0;let j=t.stacked?V(t.totals):h?V(t.seriesValues.flat()):0;if(!h)for(let n=0;n<3;n++){const t=y-p-j,n=V(e.map((t,e)=>({seg:t,label:c[e]})).filter(({seg:e,label:n})=>!q(n,k(e.value,t),r)).map(({label:t})=>t));if(n<=j)break;j=n}const K=y-p-j,R=t=>p+k(t,K);if(t.squeeze&&(t.breakX=R(t.squeeze.gap)),t.stacked)return t.rows.forEach((e,n)=>{const a=E(t,e,n,{"data-grow":"right"}),s=A(n)-N/2,c=O(e,t.series.length);c.forEach(({from:e,to:c,cell:i},l)=>{const u=t.seriesValues[l][n];if(u.dataset.place="none",i.missing||c===e)return;const h=R(e),f=R(c);a(l,{x:h,y:s,width:Math.max(f-h,1),height:N}),u.dataset.place="inside",u.toggleAttribute("data-left-out",!q(u,f-h,r)||L(u).height*r>N),B(u,t,l),$(u,(h+f)/2,A(n),d,o)});const l=t.totals[n];l&&(l.dataset.place="after",$(l,R(c.at(-1)?.to??0)+F,A(n),d,o));const u=i[n];u&&$(u,p-8*r,A(n),d,o)}),void s.appendChild(b("line",{class:a,x1:p,x2:p,y1:0,y2:o}));if(h){t.plot.dataset.grouped="";const e=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),c=I(t.plot,e,t=>({size:L(t).height*r,room:S.size+.5*S.gap}),"--tablechart-fit");return t.rows.forEach((e,a)=>{t.series.forEach((r,i)=>{const l=e.cells[i]??e.cells[0],u=t.seriesValues[i][a];if(l.missing)return void(u.dataset.place="none");const h=R(l.value),f=A(a)+S.offset(i);s.appendChild(b("rect",{class:m(n,e),"data-kind":"bar","data-row":a+1,"data-grow":"right",x:p,y:f,width:Math.max(h-p,1),height:S.size,...C(t,e,i)})),u.dataset.place="after",u.toggleAttribute("data-left-out",!c),$(u,h+F,f+S.size/2,d,o)});const l=i[a];l&&$(l,p-8*r,A(a),d,o)}),void s.appendChild(b("line",{class:a,x1:p,x2:p,y1:0,y2:o}))}const W=e.map((t,e)=>q(c[e],R(t.value)-p,r));e.forEach((e,a)=>{const l=R(e.value),u=A(a);s.appendChild(b("rect",{class:m(n,e),"data-kind":e.kind,"data-row":a+1,"data-grow":"right",x:p,y:u-N/2,width:Math.max(l-p,1),height:N,style:f("--i",e.slot)}));const h=c[a],g=Math.max(Math.min(F,l-p-P(h)-6*r),6*r);h.dataset.place=W[a]?"inside":"after",h.dataset.kind=e.kind,$(h,W[a]?"center"===t.insideAlign?(p+l)/2:"start"===t.insideAlign?p+g+P(h)/2:l-g-P(h)/2:l+F,u,d,o);const y=i[a];y&&$(y,p-8*r,u,d,o)}),s.appendChild(b("line",{class:a,x1:p,x2:p,y1:0,y2:o}))}},j={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:n,unit:a})=>t+4*a+(n?1.6*e:0),draw(t){const{segments:e,cx:o,y:r,barWidth:s,height:c,unit:i,svg:l,values:u,labels:h,insideAlign:g}=t,p=r(0);if(t.stacked)return t.rows.forEach((e,n)=>{const a=E(t,e,n),l=o(n)-s/2;O(e,t.series.length).forEach(({from:e,to:u,cell:h},f)=>{const b=t.seriesValues[f][n];if(b.dataset.place="none",h.missing||u===e)return;const m=r(u),g=r(e);a(f,{x:l,y:m,width:s,height:Math.max(g-m,1)}),b.dataset.place="inside",b.toggleAttribute("data-left-out",!P(b,g-m,i)||L(b).width*i>s-4*i),B(b,t,f),$(b,o(n),(m+g)/2,d,c)});const u=t.totals[n],h=O(e,t.series.length).at(-1)?.to??0;u&&(u.dataset.place="outside",$(u,o(n),r(h)-4*i,d,c))}),void l.appendChild(b("line",{class:a,x1:0,x2:d,y1:p,y2:p}));if(t.series.length>1){const e=z(o(1)-o(0)||2*o(0),t.series.length,t.barMax);t.plot.dataset.grouped="";const s=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),u=I(t.plot,s,t=>({size:L(t).width*i,room:e.size+.5*e.gap}),"--tablechart-fit");return t.rows.forEach((a,s)=>{t.series.forEach((h,f)=>{const g=a.cells[f]??a.cells[0],y=t.seriesValues[f][s],w=o(s)+e.offset(f);if(g.missing)return void(y.dataset.place="none");const v=r(g.value);l.appendChild(b("rect",{class:m(n,a),"data-kind":"bar","data-row":s+1,x:w,y:v,width:e.size,height:Math.max(p-v,1),...C(t,a,f)})),y.dataset.place="outside",y.toggleAttribute("data-left-out",!u),$(y,w+e.size/2,v-4*i,d,c)})}),void l.appendChild(b("line",{class:a,x1:0,x2:d,y1:p,y2:p}))}const y=F(u,s,i),w=e.map((t,e)=>"inside"===h&&!y&&!t.missing&&P(u[e],p-r(t.value),i)),v=u[0]?L(u[0]).height*i*.56:0;let M=Number.POSITIVE_INFINITY;for(const[n,a]of u.entries())w[n]&&(M=Math.min(M,(s-L(a).width*i)/2));e.forEach((t,e)=>{const a=r(t.value);if(t.missing)return $(u[e],o(e),p-4*i,d,c),void(u[e].dataset.place="outside");l.appendChild(b("rect",{class:m(n,t),"data-kind":t.kind,"data-row":e+1,x:o(e)-s/2,y:a,width:s,height:Math.max(p-a,1),style:f("--i",t.slot)}));const h=Math.min(M,(p-a-v)/2),y="center"===g?(a+p)/2:"start"===g?p-h-v/2:a+h+v/2;$(u[e],o(e),w[e]?y:a-4*i,d,c),u[e].dataset.place=w[e]?"inside":"outside"}),l.appendChild(b("line",{class:a,x1:0,x2:d,y1:p,y2:p}))}},K=0,R={aspect:.66,centre:!0,headroom:()=>0,segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),draw({rows:t,height:e,unit:n,labelHeight:a,svg:o,values:r,config:c,centre:i}){const l=500,u=e/2,h=(t=>t.filter(t=>!t.isTotal))(t).reduce((t,e)=>t+Math.abs(e.value),0);if(!h)return;const g=1.2*a+10*n,p=Math.max(Math.min(d,e)/2-g,10),y=p*c.ringfill,w=p-y/2,v=2*Math.PI*w,M=[];let k=0,x=0;if(t.forEach((t,c)=>{const i=r[c];if(t.isTotal)return void(i.dataset.place="none");const g=Math.abs(t.value)/h*v,A=k/v*2*Math.PI-Math.PI/2;M.push(A),o.appendChild(b("circle",{class:m(s,t),"data-slice":x+1,"data-row":c+1,cx:l,cy:u,r:w,"stroke-width":y,transform:`rotate(-90 500 ${u})`,"stroke-dasharray":`${g.toFixed(1)} ${(v-g).toFixed(1)}`,"stroke-dashoffset":(-k).toFixed(1),style:`--n:${x}; --palette:var(--tablechart-color-${x+1}); --arc:${g.toFixed(1)}; --circ:${v.toFixed(1)}; ${f("--i",t.slot)}`}));const N=A+g/v*Math.PI,S=Math.cos(N),H=Math.sin(N);o.appendChild(b("line",{class:"tablechart-leader",x1:l+S*(p+2*n),y1:u+H*(p+2*n),x2:l+S*(p+7*n),y2:u+H*(p+7*n),"data-row":c+1,style:f("--i",t.slot)}));const T=p+9*n,z=L(i).width*n/2;$(i,l+S*(T+Math.abs(S)*z),u+H*(T+Math.abs(H)*a*.7),d,e),i.dataset.place="around",k+=g,x+=1}),M.length>1){const t=w-y/2-1,n=w+y/2+1,a="tablechart-slices-"+ ++K,r=b("mask",{id:a,maskUnits:"userSpaceOnUse"});r.appendChild(b("rect",{x:0,y:0,width:d,height:e,fill:"white"}));for(const e of M)r.appendChild(b("line",{class:"tablechart-divide",x1:l+Math.cos(e)*t,y1:u+Math.sin(e)*t,x2:l+Math.cos(e)*n,y2:u+Math.sin(e)*n}));const c=b("g",{mask:`url(#${a})`});for(const e of Array.from(o.querySelectorAll(`.${s}`)))c.appendChild(e);const i=b("defs");i.appendChild(r),o.prepend(i,c)}i&&$(i,l,u,d,e)}},W=["circle","square","diamond"],D=(t,e)=>{const n=t[e]?.marker?.toLowerCase().split(/\s+/)??[],a=W.find(t=>n.includes(t));return{shape:a??W[Math.floor(e/2)%W.length],open:n.includes("open")||!n.includes("filled")&&!a&&e%2==1}},G=t=>Number(t.toFixed(2));function Z(t,e,n){const a=new Array(t).fill(0);let o=[];const r=()=>{(function(t,e){const n=t.length;if(n<2)return t.map(()=>0);const a=n=>(e[n+1]-e[n])/(t[n+1]-t[n]||1),o=new Array(n).fill(0);for(let s=1;s<n-1;s++){const e=a(s-1),n=a(s);if(e*n<=0)continue;const r=t[s]-t[s-1],c=t[s+1]-t[s],i=(e*c+n*r)/(r+c||1),l=Math.min(2*Math.abs(e),2*Math.abs(n),Math.abs(i));o[s]=Math.sign(e)*l||0}if(2===n)return o[0]=a(0),o[1]=a(0),o;const r=(n,a,o)=>{const r=t[a]-t[n];return r?((e[a]-e[n])/r*3-o)/2:o};return o[0]=r(0,1,o[1]),o[n-1]=r(n-2,n-1,o[n-2]),o})(o.map(t=>n(t)[0]),o.map(t=>n(t)[1])).forEach((t,e)=>{a[o[e]]=t}),o=[]};for(let s=0;s<t;s++)e(s)?r():o.push(s);return r(),a}var J=t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),Q=t=>({segments:J,series:!0,stackable:!0,swatch:t?"box":void 0,headroom:({labelHeight:t,unit:e})=>1.6*t+6*e,footroom:({labelHeight:e,unit:n,series:a,focused:o,stacked:r})=>t||r||2!==a||o?0:e+7*n,draw(e){const{rows:n,series:o,seriesValues:r,names:s,cx:c,y:l,height:u,unit:h,labelHeight:f,svg:m,stacked:g}=e,p="step"===e.shape,w="smooth"===e.shape,v=o.length>1,M=o.some(t=>t.focus),k=n.length-1,x=l(0),A=n.length>1?c(1)-c(0):2*c(0);m.style.setProperty("--tablechart-base",`${G(x)}px`);const N=(t,e)=>n[e]?.cells[t]??n[e]?.cells[0],S=(t,e)=>!N(t,e)||!!N(t,e)?.missing,H=n.map(t=>g?O(t,o.length):null),T=(t,e)=>H[e]?.[t].to??N(t,e)?.value??0,z=(t,e)=>H[e]?.[t].from??0,C=(t,e)=>[c(e),l(T(t,e))],U=o.map((t,e)=>{if(!v)return{attrs:{},ink:""};const n=M&&!t.focus;return{attrs:{"data-series":e+1,...n&&{"data-muted":""}},ink:`--n:${e}; --m:${n?1:0}; --palette:var(--tablechart-color-${e+1}); `}}),B=Math.min(k,6),E=k>0?B/(p?n.length:k):1,F=t=>t*E,P=t=>`--i:${G(F(t))}`,q=t=>{const e=[];let a=-1;return n.forEach((n,o)=>{S(t,o)||(a<0&&(a=o),(o===k||S(t,o+1))&&((p||o>a)&&e.push([a,o]),a=-1))}),e},I=(t,e)=>`--i:${G(F(t)+1)}; --d:${G(F(p?e+1:e)-F(t))}`,V=(t,e)=>({"data-from":t+1,"data-to":e+1,...p&&{"data-flat":""}}),j=w?o.map((t,e)=>Z(n.length,t=>S(e,t),t=>C(e,t))):[],K=w&&t?o.map((t,e)=>Z(n.length,t=>S(e,t),t=>[c(t),l(z(e,t))])):[],R=(t,e,n)=>{const a=[];return t.forEach(([o,r],s)=>{p?(a.push(`H${G(o+n*A/2)}`),s<t.length-1&&a.push(`V${G(t[s+1][1])}`)):s>0&&a.push(e?function(t,e,n,a){const[o,r]=function(t,e,n,a){const o=(e[0]-t[0])/3;return[[t[0]+o,t[1]+n*o],[e[0]-o,e[1]-a*o]]}(t,e,n,a),s=([t,e])=>`${G(t)},${G(e)}`;return`C${s(o)} ${s(r)} ${s(e)}`}(t[s-1],[o,r],e[s-1],e[s]):`L${G(o)},${G(r)}`)}),a},W=(t,e,a,o)=>n.slice(e,a+1).map((n,a)=>[c(e+a),l(o(t,e+a))]),J=(t,e,n,a)=>w?t[e].slice(n,a+1):null,Q=t=>c(t)-(p?A/2:0),X=t=>c(t)+(p?A/2:0);t&&o.forEach((t,e)=>(t=>{const e=b("g",{class:"tablechart-area",...U[t].attrs,...g&&{"data-stacked":""},style:U[t].ink}),n=q(t),a=b("g",{class:"tablechart-area-fill",style:`--rows:${G(B+1)}; ${n.length?I(...n[0]):""}`});e.appendChild(a);for(const[o,r]of n){const e=W(t,o,r,T),n=W(t,o,r,z),s=J(K,t,o,r)?.reverse()??null,c=[`M${G(Q(o))},${G(n[0][1])}`,`L${G(Q(o))},${G(e[0][1])}`,...R(e,J(j,t,o,r),1),`L${G(X(r))},${G(n[n.length-1][1])}`,...R(n.reverse(),s,-1),"Z"].join(" ");a.appendChild(b("path",{d:c,...V(o,r),style:I(o,r)}))}m.appendChild(e)})(e)),o.forEach((t,e)=>(t=>{const e=o[t];for(const[n,a]of q(t)){const o=W(t,n,a,T),r=[`M${G(Q(n))},${G(o[0][1])}`,...R(o,J(j,t,n,a),1)].join(" ");m.appendChild(b("path",{class:"tablechart-series",...U[t].attrs,d:r,...e.line&&{"data-line":e.line},...V(n,a),style:`${U[t].ink}${I(n,a)}`}))}})(e)),p||(()=>{const t=o.map((t,e)=>v?D(o,e):{shape:"circle",open:!1}),e=(e,n,a)=>{const[o,r]=C(e,n);return((t,e,n,a,o={})=>{if("square"===t){const t=.88*a;return b("rect",{x:e-t,y:n-t,width:2*t,height:2*t,...o})}if("diamond"===t){const t=1.2*a;return b("polygon",{points:`${e},${n-t} ${e+t},${n} ${e},${n+t} ${e-t},${n}`,...o})}return b("circle",{cx:e,cy:n,r:a,...o})})(t[e].shape,o,r,4*h,{...a,style:`${a.style??""}${s=r,`--rise:${G(x-s)}px; `}${P(n)}`});var s},a=t=>n.map((t,e)=>e).filter(e=>!S(t,e));y(m,o.flatMap((n,o)=>t[o].open?a(o).map(t=>e(o,t,{class:i,"data-row":t+1,...v&&{"data-series":o+1}})):[]),d,u),o.forEach((n,o)=>{for(const r of a(o))m.appendChild(e(o,r,{class:"tablechart-point",...U[o].attrs,"data-marker":t[o].shape,...t[o].open&&{"data-open":""},"data-row":r+1,style:U[o].ink}))})})();const Y=(t,e)=>{let n=e;for(;n<k&&!S(t,n+1)&&N(t,n+1)?.value===N(t,e)?.value;)n++;return n};r.forEach((e,n)=>{e.forEach((e,a)=>{e.style.setProperty("--i",String(G(p?(F(a)+F(a+1))/2:F(a))));const s=((e,n)=>{const a=N(e,n);if(!a||a.missing)return"none";if(p&&n>0&&!S(e,n-1)&&N(e,n-1)?.value===a.value)return"none";if(M&&!o[e].focus)return"none";if(g)return"middle";if(!v||M||o.length>2)return"above";const r=N(1-e,n);return!r||r.missing||a.value>r.value||a.value===r.value&&0===e||t&&C(e,n)[1]+7*h+f>x?"above":"below"})(n,a);if(e.dataset.place="above"===s?"outside":s,e.toggleAttribute("data-left-out","none"!==s&&((t,e)=>g||p?L(r[t][e]).width*h>(p?Y(t,e)-e+1:1)*A-4*h||g&&l(z(t,e))-l(T(t,e))<1.2*f:v&&!M&&o.length>2)(n,a)),p&&"none"!==s?e.dataset.rowEnd=String(Y(n,a)+1):delete e.dataset.rowEnd,"none"===s)return;const i=L(e).width*h/2+4*h;let b=c(a);p?b=(c(a)+c(Y(n,a)))/2:"middle"===s&&0===a?b+=i:"middle"===s&&a===k&&(b-=i);const m=l(T(n,a)),y={middle:(l(z(n,a))-m)/2,above:-7*h,below:7*h};$(e,b,m+y[s],d,u)})});const _=s.map((t,e)=>{let n=k;for(;n>0&&S(e,n);)n--;const[a,o]=C(e,n);return{name:t,x:(p?a+A/2:a)+10*h,y:g?(o+l(z(e,n)))/2:o}}),tt=(s[0]?L(s[0]).height:0)*h;for(const t of((t,e)=>(t.sort((t,e)=>t.y-e.y),t.forEach((n,a)=>{const o=t[a-1];o&&n.y<o.y+e&&(n.y=o.y+e)}),t))(_,tt))$(t.name,t.x,t.y,d,u);const et=t||g||2!==o.length||M?x:u-2*h;m.appendChild(b("line",{class:a,x1:0,x2:c(k)+c(0),y1:et,y2:et}))}}),X=Q(!1),Y=Q(!0),_={segments:t=>{let e=0;return t.map(t=>{if(t.isTotal)return e=t.value,{...t,from:0,to:t.value,kind:"total"};const n=e;return e+=t.value,{...t,from:n,to:e,kind:t.value>=0?"up":"down"}})},breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:n,unit:a})=>t+6*a+(n?1.6*e:0),draw({segments:t,cx:e,y:o,barWidth:r,height:s,unit:c,svg:i,values:l,breakAt:u,closing:h,insideAlign:g}){const p=o(0),y=F(l,r,c),w=g??"center",v=t.map((e,n)=>{const a=o(Math.max(e.from,e.to)),r=Math.abs(o(e.from)-o(e.to)),s=null!==u&&Math.min(e.from,e.to)<u&&Math.max(e.from,e.to)>u;return{top:a,length:r,down:"down"===e.kind||"total"===e.kind&&n>0&&n===t.length-1&&"down"===h,inside:!s&&!y&&P(l[n],r,c)}}),M=l[0]?L(l[0]).height*c*.56:0;let k=Number.POSITIVE_INFINITY;for(const[n,a]of v.entries())a.inside&&(k=Math.min(k,(r-L(l[n]).width*c)/2));t.forEach((n,a)=>{const s=t[a+1];if(!s)return;const c=o(n.to),l=e(a)+r/2,u=e(a+1)-r/2;i.appendChild(b("line",{class:"tablechart-connector",x1:l,x2:u,y1:c,y2:c,"data-row":a+2,style:f("--i",s.slot)}))}),t.forEach((t,a)=>{const{top:o,length:u,down:h,inside:g}=v[a];i.appendChild(b("rect",{class:m(n,t),"data-kind":t.kind,"data-row":a+1,"data-grow":h?"down":"up",x:e(a)-r/2,y:o,width:r,height:Math.max(u,1),style:f("--i",t.slot)}));const p=l[a],y=Math.min(k,(u-M)/2),x="center"===w?o+u/2:"end"===w!==h?o+y+M/2:o+u-y-M/2;p.dataset.place=g?"inside":"outside",p.dataset.kind=t.kind;const A=g?x:"down"===t.kind?o+u+L(p).height*c+3*c:o-3*c;$(p,e(a),A,d,s)}),i.appendChild(b("line",{class:a,x1:0,x2:d,y1:p,y2:p}))}},tt={enabled:!1,log(...e){tt.enabled&&console.log(`[${t}]`,...e)},timed(e,n,a){if(!tt.enabled)return a();const o=performance.now(),r=a(),s=performance.now()-o,c=n.querySelectorAll("tbody tr").length;return s>50?console.warn(`[${t}] ${e} took ${s.toFixed(1)} ms for ${c} rows, more than 50 ms.`,n):tt.log(`${e} took ${s.toFixed(1)} ms for ${c} rows.`,n),r}},et=t=>{const e=(t?.textContent||"").trim(),n=e.match(/^(.*?)(-?\d+(?:[.,]\d+)?)(.*)$/);return{raw:e,number:n?.[2]??"",prefix:n?.[1]??"",suffix:n?.[3]??"",missing:!n,value:n?Number.parseFloat(n[2].replace(",",".")):0}},nt=t=>Array.from(t.querySelector("thead tr:last-child")?.children??[]).slice(1),at=["axis-break","trend","bracket"],ot=t=>{const e=t.plan;if(!e)return;const n=e=>null===e||t.step-e>=1;for(const a of t.figure.querySelectorAll("[data-from]")){const t=Number(a.dataset.from)-1,o=Number(a.dataset.to)-1,r=a.closest("[data-series]")?.dataset.series,s=r?e.series[Number(r)-1]:void 0;let c=t-1;if(s&&null!==s.step)c=n(s.step)?o:t-1;else for(;c<o&&n(e.rows[c+1]?.step??null);)c++;const i=a.hasAttribute("data-flat")?(c-t+1)/(o-t+1):o>t?Math.max(0,c-t)/(o-t):0;a.style.setProperty("--reveal",String(i))}},rt=(t,e,n=!1)=>{const a=t.plan;if(!a)return;const o=Math.min(Math.max(Math.round(e),0),a.count),r=o!==t.step;t.step=o,t.figure.style.setProperty("--tablechart-step",String(o)),ot(t);const[s,c]=t.controls?.querySelectorAll("button")??[];s&&(s.disabled=0===o),c&&(c.disabled=o===a.count),r&&!n&&t.figure.dispatchEvent(new CustomEvent("tablechart:step",{bubbles:!0,detail:{step:o,steps:a.count}}))},st={area:Y,bar:V,column:j,donut:R,line:X,waterfall:_},ct={"axis-break":v,trend:T,bracket:S},it=Object.keys(ct),lt=t=>{let e="";for(let n=t.previousSibling;n&&(e=(n.textContent??"")+e,!e.trim());n=n.previousSibling);return e.trim()},ut=["straight","step","smooth"],dt=(t,e)=>{const n=t.dataset.chartShape;return n&&ut.includes(n)?n:ut.includes(e.shape)?e.shape:"straight"},ht=0,ft=(n,a,o=null)=>{const r=o??(n.getAttribute("data-chart")||"column"),s=st[r];if(!s)return console.warn(`[${t}] Unknown chart type "${r}". Known types: ${Object.keys(st).join(", ")}.`),n.setAttribute("data-chart-empty",""),null;const i=((t,e="data-i18n")=>Array.from(t.querySelectorAll("tbody tr")).map((t,n)=>{const a=t.querySelector("th"),o=Array.from(t.querySelectorAll("td")).map(et);return o.length||o.push(et(null)),{...o[0],label:(a?.textContent||"").trim(),key:e&&a?.getAttribute(e)||null,cells:o,classes:Array.from(t.classList),isTotal:"total"===t.getAttribute("data-kind"),slot:n}}))(n,a.langattribute);if(!i.length)return console.warn(`[${t}] A chart has no rows in its table, so there is nothing to draw.`),n.setAttribute("data-chart-empty",""),null;(t=>{const e=t.querySelector(":scope > figcaption");if(!e)return;(t=>{for(const e of t.querySelectorAll("br")){if(e.previousElementSibling?.classList.contains("tablechart-sr"))continue;if(/[.!?:;,…]$/.test(lt(e)))continue;const t=document.createElement("span");t.className=u,t.textContent=". ",e.before(t)}})(e);const n=t=>t.hasAttribute("aria-label")||t.hasAttribute("aria-labelledby"),a=t=>{e.id||(e.id="tablechart-caption-"+ ++ht),t.setAttribute("aria-labelledby",e.id)};"FIGURE"!==t.tagName||n(t)||a(t);const o=t.querySelector("table");!o||n(o)||o.querySelector(":scope > caption")||a(o)})(n);let l=((t,e,n="data-i18n")=>{const a=nt(t),o=Math.max(1,M(e.map(t=>t.cells.length)));return Array.from({length:o},(t,e)=>{const o=a[e];return{name:(o?.textContent||"").trim(),key:n&&o?.getAttribute(n)||null,focus:"focus"===o?.getAttribute("data-kind"),marker:o?.getAttribute("data-marker")??null,line:(r=o?.getAttribute("data-line"),"dashed"===r||"dotted"===r?r:null)};var r})})(n,i,a.langattribute);l.length>1&&!s.series&&(console.warn(`[${t}] A ${r} chart draws one series; only the first of the table's ${l.length} value columns is used.`),l=l.slice(0,1));const d=l.length>1;d&&n.style.setProperty("--tablechart-series-count",String(l.length));const h=n.hasAttribute("data-chart-stack");h&&!s.stackable&&console.warn(`[${t}] A ${r} chart cannot be stacked.`);const f=h&&!!s.stackable&&d;f&&i.some(t=>t.cells.slice(0,l.length).some(t=>t.value<0))&&console.warn(`[${t}] A stacked chart has a value below zero. It takes no room in the stack.`);const m=document.createElement("div");m.className="tablechart-plot",m.setAttribute("aria-hidden","true");const $=b("svg",{role:"presentation",focusable:"false"});m.appendChild($),n.appendChild(m);const p=s.centre?i.filter(t=>!t.isTotal):i,y=Math.max(0,M(p.flatMap(t=>t.cells.slice(0,l.length).map(t=>k(t.number))))),w=l.map((t,n)=>i.map((t,a)=>{const o=t.cells[n]??t.cells[0],r=g(e,m);return r.classList.add(...t.classes),r.dataset.value=String(o.value),o.prefix&&(r.dataset.prefix=o.prefix),o.suffix&&(r.dataset.suffix=o.suffix),o.missing&&(r.dataset.missing=o.raw),d&&(r.dataset.series=String(n+1)),r.dataset.row=String(a+1),r.style.setProperty("--i",String(t.slot)),r})),v=w[0],x=f&&s.totals?i.map((t,n)=>{const a=g(e,m);a.classList.add(...t.classes),a.dataset.kind="total",a.dataset.row=String(n+1),a.dataset.value=String(U(t,l.length));const o=t.cells[0];return o.prefix&&(a.dataset.prefix=o.prefix),o.suffix&&(a.dataset.suffix=o.suffix),a.style.setProperty("--i",String(t.slot)),a}):[],A=i[i.length-1],N=l.some(t=>t.focus),S=n.getAttribute("data-chart-legend"),H=d&&(null===S?a.legend||void 0!==s.legend:"false"!==S)?document.createElement("div"):null;H&&(H.className=c,H.setAttribute("aria-hidden","true"),H.inert=!0);const L=d?l.map((t,e)=>{const o=g("tablechart-name",H??m);H&&(o.dataset.place="legend");const r=s.legend??s.swatch;if(r&&(o.dataset.swatch=r),o.textContent=t.name,!r&&"step"!==dt(n,a)){const t=D(l,e);o.dataset.marker=t.shape,o.toggleAttribute("data-open",t.open)}return t.line&&!r&&(o.dataset.line=t.line),t.key&&a.langattribute&&o.setAttribute(a.langattribute,t.key),o.dataset.series=String(e+1),o.style.setProperty("--n",String(e)),o.style.setProperty("--palette",`var(--tablechart-color-${e+1})`),o.style.setProperty("--m",N&&!t.focus?"1":"0"),o.style.setProperty("--i",String(A.slot)),o}):[],T=s.centre?g("tablechart-centre",m):null;if(T){const t=i.find(t=>t.isTotal),e=t?t.value:i.reduce((t,e)=>t+Math.abs(e.value),0);T.dataset.value=String(e),t&&(T.dataset.decimals=String(k(t.number)))}const z=T&&!i.some(t=>t.isTotal)?((t,e,n)=>{const a=t.querySelector("table");if(!a)return null;const o=a.querySelector("tfoot [data-chart-total]");if(o)return o.dataset.value=e.dataset.value??"0",o;const r=(a.tFoot??a.createTFoot()).insertRow(),s=document.createElement("th");s.scope="row",s.textContent=n.totallabel;const c=t.getAttribute("data-chart-keys");c&&n.langattribute&&s.setAttribute(n.langattribute,`${c}-total`);const i=r.insertCell();return i.setAttribute("data-chart-total",""),i.dataset.value=e.dataset.value??"0",r.prepend(s),i})(n,T,a):null,C="beside"===s.categories,O=document.createElement("div");O.className="tablechart-categories",O.setAttribute("aria-hidden","true"),O.inert=!0,C?O.dataset.place="beside":s.centre&&(O.dataset.place="key"),O.style.setProperty("--tablechart-columns",String(i.length));let B=0;for(const[t,e]of i.entries()){const n=document.createElement("span");n.classList.add(...e.classes),n.textContent=e.label,e.key&&a.langattribute&&n.setAttribute(a.langattribute,e.key),s.centre&&(n.dataset.kind=e.isTotal?"total":"slice",e.isTotal||(n.dataset.slice=String(B+1),n.style.setProperty("--n",String(B)),n.style.setProperty("--palette",`var(--tablechart-color-${B+1})`),B+=1)),n.style.setProperty("--i",String(e.slot)),n.dataset.row=String(t+1),O.appendChild(n)}(C?m:n).appendChild(O),H&&n.appendChild(H);const E=a.animate?(t=>{const e=t.hasAttribute("data-fragment"),n=Array.from(t.querySelectorAll("tbody tr")),a=Array.from(t.querySelector("thead tr:last-child")?.children??[]).slice(1),o=Array.from(t.querySelectorAll("[data-annotation]")).filter(t=>at.includes(t.getAttribute("data-annotation")??"")),r=t=>t.hasAttribute("data-fragment");if(!(e||n.some(r)||a.some(r)||o.some(r)))return null;const s=[],c=new Map,i=[],l=t=>{let e=null!==t?c.get(t):void 0;return void 0===e&&(e=s.length,s.push(t),i.push(0),null!==t&&c.set(t,e)),e};let u=0;const d=n.map(t=>{if(!e&&!r(t))return{step:null,slot:u++};const n=l(t.getAttribute("data-fragment-index"));return{step:n,slot:i[n]++}}),h=a.map(t=>({step:r(t)?l(t.getAttribute("data-fragment-index")):null}));return{rows:d,series:h,notes:o.map(t=>{const e=(e,n)=>{const a=Number.parseInt(t.getAttribute(e)??"",10);return Number.isFinite(a)?a-1:n},[n,a]="bracket"===t.getAttribute("data-annotation")?[e("data-from",0),e("data-to",d.length-1)]:[0,d.length-1];let o=null;for(let r=Math.min(n,a);r<=Math.max(n,a);r++){const t=d[r]?.step??null;null!==t&&(null===o||t>o)&&(o=t)}const s=h[e("data-series",0)]?.step??null;null!==s&&(null===o||s>o)&&(o=s),r(t)&&(o=l(t.getAttribute("data-fragment-index")));const c=null===o?d.length:d.filter(t=>t.step===o).length;return{step:o,after:c}}),count:s.length,indexes:s}})(n):null;E&&(n.setAttribute("data-steps",""),n.setAttribute("data-chart-animate","across"));const F=n.getAttribute("data-chart-keys"),P=E&&a.controls?((t,e,n)=>{const a=document.createElement("div");a.className="tablechart-controls";const o=a=>{const o=document.createElement("button");o.type="button",o.className=`tablechart-${a}`,o.dataset.go=a;const r=document.createElement("span");r.className="tablechart-control-icon",r.setAttribute("aria-hidden","true");const s=b("svg",{viewBox:"0 0 16 16",focusable:"false"});s.appendChild(b("path",{d:"next"===a?"M6 3l5 5-5 5":"M10 3L5 8l5 5"})),r.appendChild(s);const c=document.createElement("span");c.className="tablechart-control-label",c.textContent=t[a];const i=e[a];i&&n&&c.setAttribute(n,i);const l=document.createElement("span");return l.className=u,l.textContent=t.hint,e.hint&&n&&l.setAttribute(n,e.hint),o.append(..."next"===a?[c,l,r]:[r,c,l]),o};return a.append(o("previous"),o("next")),a})({previous:a.previouslabel,next:a.nextlabel,hint:a.stephint},{previous:F&&`${F}-previous`,next:F&&`${F}-next`,hint:F&&`${F}-step`},a.langattribute):null;P&&n.appendChild(P);const q=Array.from(n.querySelectorAll("[data-annotation]")).map(e=>{const n=e.getAttribute("data-annotation"),a=ct[n];if(!a)return console.warn(`[${t}] Unknown annotation "${n}". Known annotations: ${Object.keys(ct).join(", ")}.`),null;const o=Number.parseInt(e.getAttribute("data-series")??"1",10),r=o>=1&&o<=l.length?o-1:0;return o!==r+1&&console.warn(`[${t}] An annotation reads line ${o}, which the chart does not have; it reads the first.`),{spec:e,type:a,badge:a.create(e,m),series:r,after:i.length}}).filter(t=>null!==t);if(a.animate){const t=n.getAttribute("data-chart-animate"),e="up"===("up"===t||"across"===t?t:a.animate)&&("line"===r||"area"===r);n.setAttribute("data-animate",e?"up":"")}const I={figure:n,plot:m,svg:$,rows:i,decimals:y,type:s,values:v,series:l,seriesValues:w,names:H?[]:L,categories:Array.from(O.children),centre:T,stacked:f,totals:x,totalCell:z,rowAt:null,rowBox:null,annotations:q,checks:[],plan:E,step:0,controls:P};return P?.addEventListener("click",t=>{const e=t.target.closest("button")?.dataset.go;e&&rt(I,I.step+("next"===e?1:-1))}),rt(I,0,!0),a.hover&&"false"!==n.getAttribute("data-chart-hover")&&yt(I),$t(I,a),I},bt=t=>{const e=getComputedStyle(t).getPropertyValue("--tablechart-inside-align").trim();return"start"===e||"center"===e||"end"===e?e:null},mt=(t,e,n,a)=>{const o=getComputedStyle(t),r=(o.getPropertyValue(n).trim()||a).match(/^(\d+(?:\.\d+)?)(px|%|em|rem)$/);if(!r)return null;const s=Number(r[1]);return"%"===r[2]?s/100*d:s*("em"===r[2]?Number.parseFloat(o.fontSize):"rem"===r[2]?Number.parseFloat(getComputedStyle(document.documentElement).fontSize):1)*e},gt=(t,e)=>mt(t,e,"--tablechart-bar-max","60px")??Number.POSITIVE_INFINITY,$t=(t,e)=>{const n=[...t.seriesValues.flat(),...t.totals,...t.totalCell?[t.totalCell]:[]];for(const a of t.centre?[...n,t.centre]:n){const{missing:n,prefix:o="",suffix:r=""}=a.dataset;if(void 0!==n){a.textContent=n;continue}const[s,c]=x(Number.parseFloat(a.dataset.value||"0"),a.dataset.decimals?Number(a.dataset.decimals):t.decimals,e.locale);if(a.textContent=o+(o?s:"")+c+r,s&&!o){const t=document.createElement("span");t.className="tablechart-minus",t.textContent=s,a.prepend(t)}}},pt=(t,e)=>{t.figure.classList.toggle("is-shown",e),e||t.plot.removeAttribute("data-pointed")},yt=t=>{const{plot:e}=t,n=()=>[...t.seriesValues.flat(),...t.totals];e.setAttribute("data-hover","");const a=document.createElement("div");a.className="tablechart-pointer",e.prepend(a);const o=()=>{e.removeAttribute("data-active");for(const t of n())t.removeAttribute("data-active")},r=r=>{if(!e.classList.contains("is-placed")||!t.rowAt)return;const s=e.getBoundingClientRect(),c=s.width/e.offsetWidth||1,i=t.rowAt((r.clientX-s.left)/c,(r.clientY-s.top)/c),l=null===i?null:i+1,u=t=>"none"!==t.dataset.place,d=null===l?[]:n().filter(t=>((t,e)=>{const n=Number(t.dataset.row),a=Number(t.dataset.rowEnd??n);return e>=n&&e<=a})(t,l)&&u(t));if(!n().some(t=>t.hasAttribute("data-left-out")&&u(t))||!d.length)return o();e.setAttribute("data-pointed",""),e.setAttribute("data-active",String(l));const[h,f,b,m]=t.rowBox?.(l-1)??[0,0,0,0];Object.assign(a.style,{left:`${h}%`,top:`${f}%`,width:`${b}%`,height:`${m}%`});for(const t of n())t.toggleAttribute("data-active",d.includes(t))};e.addEventListener("pointermove",r),e.addEventListener("pointerdown",r),e.addEventListener("pointerleave",t=>{"mouse"===t.pointerType&&o()}),document.addEventListener("pointerdown",t=>{e.contains(t.target)||o()})},wt=t=>"id"===t||"style"===t||t.startsWith("data-chart"),vt=/^\s*(?:Table)?:\s+/,Mt=t=>"P"===t?.tagName&&vt.test(t.textContent??""),kt=/^\s*([a-z][\w-]*)((?:\s+[\w-]+=[^\s:]+)*)\s*(:\s*|$)/,xt=t=>{const e=At(t);return"P"===e?.tagName?e:t},At=t=>{const e=Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.nodeType===Node.TEXT_NODE&&t.textContent?.trim());return 1===e.length&&e[0]instanceof HTMLElement?e[0]:null},Nt="strong, b, span.total",St="data-chart-made",Ht=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches,Lt=new Set,Tt=null,zt=["column","bar"],Ct=t=>{const e=t.getAttribute("data-chart")||"column";if(!zt.includes(e))return null;const n=getComputedStyle(t).getPropertyValue("--tablechart-type").trim();return zt.includes(n)?n:e},Ot=async(e,n)=>{const a=(t=>t.map(t=>{const e=t.closest("p"),n=Mt(e)?e:t;if("TABLE"!==n.tagName&&"P"!==n.tagName)return n;const a=document.createElement("div");((t,e)=>{for(const{name:n,value:a}of Array.from(t.attributes))("class"===n||wt(n))&&(e.setAttribute(n,a),t.removeAttribute(n))})(t,a),t.classList.length||t.removeAttribute("class");const o="TABLE"===n.tagName?n:null,r=n.previousElementSibling;let s=n.nextElementSibling;const c=o?Mt(r)?r:Mt(s)?s:null:n;o&&c===s&&(s=s?.nextElementSibling??null);const i=s?.classList.contains("chart-annotations")?s:(t=>{if("UL"!==t?.tagName&&"OL"!==t?.tagName)return null;const e=Array.from(t.children),n=e.map(t=>t.hasAttribute("data-annotation")?null:(t=>{const e=xt(t).firstChild;if(e?.nodeType!==Node.TEXT_NODE)return null;const n=kt.exec(e.textContent??"");if(!n||!it.includes(n[1]))return null;if(!n[3]&&e.nextSibling)return null;const a=n[2].trim().split(/\s+/).filter(Boolean).map(t=>t.split("="));return{name:n[1],options:a,text:e,length:n[0].length}})(t));return!e.length||e.some((t,e)=>!n[e]&&!t.hasAttribute("data-annotation"))?null:(e.forEach((t,e)=>{const a=n[e],o=xt(t);if(o!==t&&o.replaceWith(...o.childNodes),a){t.setAttribute("data-annotation",a.name);for(const[e,n]of a.options)t.setAttribute(`data-${e}`,n);a.text.textContent=(a.text.textContent??"").slice(a.length)}t.children.length&&Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.textContent?.trim()).forEach((t,e)=>{const n=document.createElement("span");0===e&&t instanceof HTMLElement&&t.matches("em, i")?(n.className="tablechart-caption",n.append(...t.childNodes),t.replaceWith(n)):t.nodeType===Node.TEXT_NODE&&(n.textContent=(t.textContent??"").trim(),t.replaceWith(n))})}),t.classList.add("chart-annotations"),t)})(s);return n.replaceWith(a),c&&a.append((t=>{const e=document.createElement("figcaption");for(const{name:r,value:s}of Array.from(t.attributes))e.setAttribute(r,s);const n=t.firstChild;n?.nodeType===Node.TEXT_NODE&&(n.textContent=(n.textContent??"").replace(vt,""),n.textContent||n.remove());const a=Array.from(t.childNodes),o=a.findIndex(t=>"BR"===t.nodeName);if(e.append(...-1===o?a:a.slice(0,o+1)),-1!==o&&o<a.length-1){const t=document.createElement("span");t.append(...a.slice(o+1)),e.append(t)}return t.remove(),e})(c)),o&&a.append(o),i&&a.append(i),tt?.log?.(`A ${o?"table":"caption"} with chart attributes was wrapped in a figure of its own`),a}))(e.filter(t=>!t.hasAttribute(St)));return await(async e=>{await Promise.all(e.filter(t=>t.hasAttribute("data-chart-src")).map(async e=>{const n=e.getAttribute("data-chart-src");for(const t of e.querySelectorAll("table"))t.remove();try{const t=await fetch(n);if(!t.ok)throw new Error(`${t.status} ${t.statusText}`);const a=await t.json(),o=Array.isArray(a)?a:a?.rows;if(!Array.isArray(o))throw new Error("no array of rows in it");const r=Array.isArray(a?.series)?a.series.map(String):[],s=e.querySelector(":scope > figcaption"),c=((t,e=[])=>{const n=document.createElement("table");if(e.length){const t=n.createTHead().insertRow();t.append(document.createElement("th"));for(const n of e){const e=document.createElement("th");e.textContent=n,t.append(e)}}const a=n.createTBody();for(const o of t){const t=a.insertRow();"total"===o.kind&&(t.dataset.kind="total");const e=document.createElement("th");e.textContent=String(o.label??""),t.append(e);for(const n of o.values??[o.value??null])t.insertCell().textContent=null===n?"":String(n)}return n})(o,r);s?s.after(c):e.prepend(c),tt?.log?.(`Read ${o.length} rows from "${n}"`)}catch(a){const e="file:"===window.location.protocol;console.warn(`[${t}] Could not read the chart data in "${n}": ${a.message}.`+(e?" A page opened from the file system cannot fetch files; open the page from a server instead.":""))}}))})(a),(t=>{for(const e of t){for(const n of e.querySelectorAll("tbody tr")){const t=n.cells[0];if("TD"!==t?.tagName||n.cells.length<2)continue;const e=document.createElement("th");for(const{name:n,value:a}of Array.from(t.attributes))e.setAttribute(n,a);e.append(...t.childNodes),t.replaceWith(e);for(let a=At(e);a?.matches(Nt);a=At(e))n.dataset.kind="total",a.replaceWith(...a.childNodes)}const t=Array.from(e.querySelector("thead tr:last-child")?.children??[]);for(const e of t.slice(1))for(let t=At(e);t?.matches(Nt);t=At(e))e.setAttribute("data-kind","focus"),t.replaceWith(...t.childNodes)}})(a),((e,n)=>{if(!n)return;const a=new Map;for(const o of e){let e=o.getAttribute("data-chart-keys")||null;if(!e)continue;if(a.has(e)){const n=a.get(e)+1;a.set(e,n),console.warn(`[${t}] Two charts on the page have data-chart-keys="${e}". If two charts use the same keys, they get the same translations. This one uses "${e}-${n}".`),e=`${e}-${n}`}else a.set(e,1);o.querySelectorAll("tbody th").forEach((t,a)=>{t.getAttribute(n)||t.setAttribute(n,`${e}-row${a+1}`)});const r=nt(o);r.length>1&&r.forEach((t,a)=>{t.getAttribute(n)||t.setAttribute(n,`${e}-col${a+1}`)}),tt?.log?.(`Keys for "${e}" written onto ${o.querySelectorAll("tbody th").length} rows`)}})(a,n.langattribute),a},Ut=(e,n)=>{const a=tt.timed("Building",e,()=>ft(e,n));return a?(e.setAttribute(St,""),((e,n)=>{let a=e,o=Ct(a.figure),r=null,s=!1,l=!1;const u=async()=>{if(!n.animate)return pt(a,!0);const t=a.figure.classList.contains("is-shown");if(!s||null===r||t||l)!s&&n.replay&&t&&pt(a,!1);else{l=!0;const t=Ht()?null:(t=>{for(let e=t;e&&e!==document.body;e=e.parentElement)if("0"===getComputedStyle(e).opacity)return e;return null})(a.figure);t&&await(e=t,new Promise(t=>{const n=["animationstart","transitionrun"],a=()=>{for(const t of n)document.removeEventListener(t,o,!0);r.disconnect(),t()},o=t=>{t.target instanceof Node&&t.target.contains(e)&&a()},r=new MutationObserver(()=>{"0"!==getComputedStyle(e).opacity&&a()});for(const e of n)document.addEventListener(e,o,!0);r.observe(e,{attributes:!0,attributeFilter:["class","style"]})})),await(async(t,e)=>{if(Ht())return;await new Promise(requestAnimationFrame);const n=t.getAnimations().filter(t=>t instanceof CSSAnimation);for(let r=t.parentElement;r&&r!==document.body;r=r.parentElement)n.push(...r.getAnimations());let a=0;for(const r of n){const t=r.effect?.getComputedTiming(),n=Number(t?.activeDuration??0);if(!t||!Number.isFinite(n))continue;const o=Number(t.delay??0)+n*e;a=Math.max(a,o-Number(r.currentTime??0))}var o;a>0&&await(o=a,new Promise(t=>setTimeout(t,o)))})(a.figure,((t,e)=>{const n=Number.parseFloat(t.dataset.chartEntrance??""),a=Number.isFinite(n)?n:e.entrance;return Math.min(Math.max(a,0),1)})(a.figure,n)),l=!1,!s&&n.replay||pt(a,!0)}var e},h=()=>{const t=Ct(a.figure);if(!t||t===o)return;const e=tt.timed("Building",a.figure,()=>ft(a.figure,n,t));e&&((t=>{t.plot.remove(),t.categories[0]?.parentElement?.remove(),t.figure.querySelector(`:scope > .${c}`)?.remove(),t.controls?.remove()})(a),rt(e,a.step,!0),a=e,o=t,r=null)},f=()=>{h();const e=a.plot.clientWidth;e&&e!==r&&tt.timed("Layout",a.figure,()=>((e,n)=>{const{plot:a,svg:o,rows:r,type:s,values:c,series:l,seriesValues:u,names:h,annotations:f}=e,m=a.clientWidth;if(!m)return!1;const g=d/m,$=Number.parseFloat(e.figure.dataset.chartAspect??""),p=d*($>0?$:s.aspect??n.aspect);a.classList.add("is-placed");for(const t of[...u.flat(),...e.totals])delete t.dataset.place;a.style.removeProperty("--tablechart-fit"),(t=>{const e=[...t].filter(t=>!!t),n=e.map(t=>({width:t.offsetWidth,height:t.offsetHeight}));e.forEach((t,e)=>H.set(t,n[e]))})([...u.flat(),...e.totals,...h,...e.categories,...f.map(t=>t.badge)]);const w=(c[0]?L(c[0]).height:0)*g,v=f[0]?.badge?L(f[0].badge).height*g:0,k=Math.max(p,mt(e.figure,g,"--tablechart-min-height","200px")??0,s.minHeight?.({labelHeight:w,nameHeight:Math.max(0,M(e.categories.map(t=>L(t).height)))*g,unit:g,rows:r.length,series:l.length,stacked:e.stacked})??0),x=e.stacked?r.map(t=>{const e=U(t,l.length);return{...t,value:e,cells:t.cells.map((t,n)=>0===n?{...t,value:e}:t)}}):r,A=(s.segments??(t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"}))))(e.stacked?x.map(t=>({...t,cells:[t.cells[0]]})):r),N={labelHeight:w,badgeHeight:v,hasAnnotations:f.length>0,unit:g,series:l.length,focused:l.some(t=>t.focus),stacked:e.stacked},S=s.headroom?.(N)??w,T=2*g+(s.footroom?.(N)??0),z=S,C=e.stacked?Math.max(M(x.map(t=>t.value)),0):Math.max(M(A.flatMap(t=>[t.from,t.to,t.value])),M(r.flatMap(t=>t.cells.slice(0,l.length).map(t=>t.value)))),O=k-z-T,B=1.02*C,E=f.find(t=>"axis-break"===t.spec.getAttribute("data-annotation"))?.spec,F=t=>{const e=Number.parseFloat(E?.getAttribute(t)??"");return Number.isFinite(e)?e:null},P=F("data-from")??F("data-at"),q=F("data-to");let V=null;if(E&&(null!==P||null!==q)){const e=P??0,n=q??B,a=null===q?e:null===P?n:(e+n)/2,o=E.getAttribute("data-size"),r=o?.match(/^\s*(\d+(?:\.\d+)?)\s*%\s*$/);null===o||r||console.warn(`[${t}] data-size="${o}" is not a percentage, such as 30%. Using the default.`);const c=Math.min(Math.max(r?Number(r[1])/100:null===q?.22:.3,.05),.8),i=A.filter(t=>("up"===t.kind||"down"===t.kind)&&Math.max(t.from,t.to)>e&&Math.min(t.from,t.to)<n);s.breakable?e<0||n<=e||n>B||0===e&&n===B?console.warn(`[${t}] A break from ${e} to ${n} does not fit a scale that runs from 0 to ${C}.`):i.length?console.warn(`[${t}] A break from ${e} to ${n} would cut a step that floats. Keep it below or above the steps.`):V={lo:e,hi:n,gap:a,share:c}:console.warn(`[${t}] This kind of chart cannot break its scale.`)}const j=V?V.gap:null,K=(V&&mt(e.figure,g,"--tablechart-break-gap",""))??13,R=k-T;let W=t=>R-t/B*O;if(V){const{lo:t,hi:e,gap:n,share:a}=V,o=O*a,r=(O-o-K)/(t+(B-e)),s=o/(e-t);W=a=>a<=t?R-a*r:a<=n?R-t*r-(a-t)*s:a<=e?R-t*r-(a-t)*s-K:R-t*r-o-K-(a-e)*r}const D=h.length?M(h.map(t=>L(t).width))*g+12*g:0,G=e.categories[0]?.parentElement;G&&(G.style.paddingRight=D?D/d*100+"%":"");const Z=(d-D)/r.length,J=t=>t>=0&&t<r.length?t:null;e.rowAt=s.centre?null:"beside"===s.categories?(t,e)=>J(Math.floor(e*g/(k/r.length))):t=>J(Math.floor(t*g/Z));const Q=Z/d*100,X=100/r.length;e.rowBox="beside"===s.categories?t=>[0,t*X,100,X]:t=>[t*Q,0,Q,100],o.setAttribute("viewBox",`0 0 1000 ${k}`),o.textContent="",e.checks=[];const Y={rows:r,segments:A,cx:t=>(t+.5)*Z,y:W,barWidth:Math.min(Z*n.barfill,gt(e.figure,g)),barMax:gt(e.figure,g),height:k,unit:g,labelHeight:w,badgeHeight:v,after:r.length,note:0,labels:"inside"===e.figure.dataset.chartLabels||"outside"!==e.figure.dataset.chartLabels&&"inside"===n.labels?"inside":"outside",closing:"up"===(e.figure.dataset.chartClosing??n.closing)?"up":"down",insideAlign:bt(e.figure),breakAt:j,squeeze:V,breakGap:K,stacked:e.stacked,shape:dt(e.figure,n),totals:e.totals,svg:o,plot:a,values:c,series:l,seriesValues:u,names:h,categories:e.categories,centre:e.centre,config:n,checks:e.checks};s.draw(Y);for(const[t,i]of f.entries()){i.badge?.setAttribute("data-note",String(t+1));const n=i.series,a=t=>({...t,...t.cells[n]??t.cells[0]});i.type.draw(i.spec,i.badge,{...Y,...e.stacked&&{rows:x,...e.totals.length&&{values:e.totals}},...n>0&&!e.stacked&&{rows:r.map(a),segments:A.map(t=>{const e=a(t);return"bar"===t.kind?{...e,to:e.value}:e}),values:u[n]},after:i.after,note:t+1})}(t=>{const e=t.plan;if(!e)return;const n=e.rows.length-1,a=(t,e,n,a)=>{t.style.setProperty(n,String(a)),t.style.removeProperty("--d"),null===e?t.style.removeProperty("--step"):t.style.setProperty("--step",String(e))};for(const o of t.figure.querySelectorAll("[data-row], [data-series], [data-note]")){if(o.closest("table, .tablechart-controls")||o.hasAttribute("data-from"))continue;const t=Number(o.dataset.note);if(t>0){const n=e.notes[t-1];n&&a(o,n.step,"--after",n.after);continue}const r=o.dataset.row?Number(o.dataset.row)-1:n;if(o.classList.contains("tablechart-connector")){const t=e.rows[r-1],n=e.rows[r];if(t&&n){const e=(t.step??-1)>(n.step??-1);a(o,e?t.step:n.step,"--i",e?t.slot+1:n.slot)}continue}const s=o.dataset.series?e.series[Number(o.dataset.series)-1]:void 0;s&&null!==s.step?a(o,s.step,"--i",r):e.rows[r]&&a(o,e.rows[r].step,"--i",e.rows[r].slot)}ot(t)})(e);const _=e.categories[0]?.parentElement;return _&&"beside"!==s.categories&&!s.centre&&I(_,e.categories.filter(t=>null!==t.offsetParent),t=>({size:t.scrollWidth,room:t.clientWidth}),"--tablechart-name-fit"),y(o,f.flatMap(({badge:t})=>{if(!(t instanceof HTMLElement&&t.offsetWidth))return[];const e=t.offsetWidth*g,n=t.offsetHeight*g,a=Number.parseFloat(t.style.left)/100*d,o=Number.parseFloat(t.style.top)/100*k,r=getComputedStyle(t).borderTopLeftRadius,s=r.endsWith("%")?Number.parseFloat(r)/100:null,c=(Number.parseFloat(r)||0)*g;return[b("rect",{class:i,"data-for":"badge","data-note":t.dataset.note??"",x:a-e/2,y:o-n/2,width:e,height:n,rx:null===s?c:e*s,ry:null===s?c:n*s,style:["--after","--step"].map(e=>t.style.getPropertyValue(e)&&`${e}:${t.style.getPropertyValue(e)}`).filter(Boolean).join("; ")})]}),d,k),!0})(a,n))&&(r=e,u())};let m=!1;const g=new ResizeObserver(()=>{m||(m=!0,requestAnimationFrame(()=>{m=!1,f()}))}),$=new IntersectionObserver(t=>{for(const e of t)s=e.isIntersecting,u()},{threshold:n.threshold}),p=()=>pt(a,!0),w=()=>{r=null,f()},v={relabel:()=>$t(a,n),refresh:w};h(),f(),g.observe(a.figure),$.observe(a.figure),window.addEventListener("beforeprint",p),(t=>{Lt.add(t),Tt||(Tt=new MutationObserver(()=>{for(const t of Lt)t.relabel();requestAnimationFrame(()=>requestAnimationFrame(()=>{for(const t of Lt)t.refresh()}))})).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"]})})(v);const k={figure:a.figure,refresh:w,next:()=>rt(a,a.step+1),previous:()=>rt(a,a.step-1),stepTo:t=>rt(a,t),get step(){return a.step},get steps(){return a.plan?.count??0},destroy(){g.disconnect(),$.disconnect(),window.removeEventListener("beforeprint",p),(t=>{Lt.delete(t),!Lt.size&&Tt&&(Tt.disconnect(),Tt=null)})(v),a.figure.tablechart===k&&delete a.figure.tablechart}};return a.figure.tablechart=k,k})(a,n)):null};window.Tablechart={init:async(t={},e=document)=>{const n={...h,...t};n.debug&&(tt.enabled=!0);const a=(await Ot(Array.from(e.querySelectorAll(n.selector)),n)).map(t=>Ut(t,n)).filter(t=>null!==t);return tt.log(`Made ${a.length} chart(s).`),{charts:a,refresh:()=>{for(const t of a)t.refresh()},destroy:()=>{for(const t of a)t.destroy()}}},create:async(t,e={})=>{if(t.tablechart)return t.tablechart;const n={...h,...e};n.debug&&(tt.enabled=!0);const[a]=await Ot([t],n);return a?Ut(a,n):null},defaultConfig:h}}();
|
|
1
|
+
!function(){var t="tablechart",e="tablechart-value",n="tablechart-bar",a="tablechart-rule",o="tablechart-line",r="tablechart-head",s="tablechart-slice",c="tablechart-legend",i="tablechart-hole",l="tablechart-centre",u="tablechart-break",d="tablechart-sr",h=1e3,f={selector:"[data-chart]",aspect:.38,barfill:.58,ringfill:.42,animate:!0,entrance:.5,labels:"outside",shape:"straight",closing:"down",legend:!1,hover:!0,totallabel:"Total",controls:!0,previouslabel:"Previous",nextlabel:"Next",stephint:"step of the chart",threshold:.5,replay:!1,langattribute:"data-i18n"},b=(t,e)=>`${t}:${e}`,m=(t,e={})=>{const n=document.createElementNS("http://www.w3.org/2000/svg",t);for(const a in e)n.setAttribute(a,String(e[a]));return n},g=(t,e)=>[t,...e.classes].join(" "),$=(t,e)=>{const n=document.createElement("span");return n.className=t,n.inert=!0,e.appendChild(n),n},p=(t,e,n,a,o)=>{t.style.left=e/a*100+"%",t.style.top=n/o*100+"%"},w=0,y=(t,e,n,a)=>{if(!e.length)return;const o="tablechart-cut-"+ ++w,r=m("mask",{id:o,maskUnits:"userSpaceOnUse"});r.appendChild(m("rect",{x:-n,y:-a,width:3*n,height:3*a,fill:"white"}));for(const i of e)i.setAttribute("fill","black"),r.appendChild(i);let s=t.querySelector(":scope > defs");s||(s=m("defs"),t.prepend(s)),s.appendChild(r);const c=m("g",{mask:`url(#${o})`});for(const i of Array.from(t.childNodes))i!==s&&c.appendChild(i);t.appendChild(c)},M=0,v={create:()=>null,draw(t,e,a){const{rows:o,y:r,svg:s,breakAt:c}=a;if(null===c)return;const i="zigzag"===t.getAttribute("data-mark"),l=(t,e)=>{const n=t.sideways?t.height:t.width,a=.09*n,o=n+2*a,r=.3*o,s=.06*o;if(t.sideways){const n=t.y-a;if(!i)return[[e-r/2,n],[e+r/2,n+o]];const c=o/3;return[[e-s,n],[e+s,n+c],[e-s,n+2*c],[e+s,n+o]]}const c=t.x-a;if(!i)return[[c,e+r/2],[c+o,e-r/2]];const l=o/3;return[[c,e+s],[c+l,e-s],[c+2*l,e+s],[c+o,e-s]]},d=(t,e=!1)=>t.map(([t,e],n)=>`${0===n?"M":"L"} ${t.toFixed(1)} ${e.toFixed(1)}`).join(" ")+(e?" Z":""),h="tablechart-break-"+ ++M,f=m("mask",{id:h,maskUnits:"userSpaceOnUse"});f.appendChild(m("rect",{x:-1e3,y:-a.height,width:3e3,height:3*a.height,fill:"white"}));const g=[],$=r(c);for(const M of(t=>Array.from(t.querySelectorAll(`.${n}`)).map(t=>{const e="rect"===t.tagName?[t]:Array.from(t.querySelectorAll("rect")),n=(t,e)=>Number(t.getAttribute(e)),a=Math.min(...e.map(t=>n(t,"x"))),o=Math.min(...e.map(t=>n(t,"y"))),r=Math.max(...e.map(t=>n(t,"x")+n(t,"width"))),s=Math.max(...e.map(t=>n(t,"y")+n(t,"height")));return{row:Number(t.dataset.row),x:a,y:o,width:r-a,height:s-o,sideways:"right"===t.dataset.grow}}))(s)){const t=M.sideways?a.breakX:$;if(void 0===t)continue;if(!(M.sideways?M.x<t&&M.x+M.width>t:M.y<$&&M.y+M.height>$))continue;const[e,n]=M.sideways?[l(M,t),l(M,t+a.breakGap)]:[l(M,$-a.breakGap),l(M,$)];f.appendChild(m("path",{d:d([...e,...n.slice().reverse()],!0),fill:"black"})),g.push(e,n);const r=b("--after",o[M.row-1]?.slot??0);for(const o of[e,n])s.appendChild(m("path",{class:u,"data-part":"edge","data-note":a.note,d:d(o),style:r}))}if(!g.length)return;const p=Array.from(s.querySelectorAll(`.${u}`)),w=m("g",{mask:`url(#${h})`});for(const n of Array.from(s.childNodes))p.includes(n)||w.appendChild(n);const y=m("defs");y.appendChild(f),s.prepend(y,w)}},k=t=>{let e=Number.NEGATIVE_INFINITY;for(const n of t)e=Math.max(e,n);return e},x=t=>(t.split(/[.,]/)[1]||"").length,A=(t,e,n)=>{const a=((t,e)=>new Intl.NumberFormat(e||document.documentElement.lang||void 0,{minimumFractionDigits:t,maximumFractionDigits:t}))(e,n).formatToParts(t),o="minusSign"===a[0]?.type?a[0].value:"";return[o,a.slice(o?1:0).map(t=>t.value).join("")]},N=(t,e)=>{const n=document.createElement("span");if(n.className="tablechart-badge",n.inert=!0,t.childElementCount>0)for(const a of Array.from(t.children))n.appendChild(a.cloneNode(!0));else{n.textContent=(t.textContent||"").trim();const e=t.getAttribute("data-i18n");e&&n.setAttribute("data-i18n",e)}return e.appendChild(n),n},S=(e,n,a,o)=>{const r=(s=e?.textContent||"",Number.parseFloat((s.match(/-?[\d.,]+/)||["NaN"])[0].replace(",",".")));var s;const c=!!Number.isNaN(r)||Math.abs(n-r)<=.5,i={label:a,computed:n,stated:r,agrees:c};o.checks.push(i),c||console.warn(`[${t}] An annotation reads ${r}%, but ${a} is ${n.toFixed(1)}%. The chart shows what you wrote; this is only a check.`)},H={create:N,draw(e,n,a){const{rows:s,cx:c,y:i,unit:l,labelHeight:u,badgeHeight:d,height:f,svg:g,after:$}=a,[w,y]=((t,e)=>{const n=(e,n)=>{const a=Number.parseInt(t.getAttribute(e)??"",10);return Number.isFinite(a)?a-1:n};return[n("data-from",0),n("data-to",e-1)]})(e,s.length),M=s[w],v=s[y];if(!M||!v)return void console.warn(`[${t}] A bracket points at a row that is not there (row ${w+1} to ${y+1}, of ${s.length}).`);const k=7*l,x=4*l,A=c(w),N=c(y),H=Math.min(i(M.value),i(v.value))-u-x-.9*d,L=t=>i(t)-u-x,T=`M ${A} ${L(M.value)} L ${A} ${H} L ${N} ${H} L ${N} ${L(v.value)-k}`,z=(L(M.value)-H+Math.abs(N-A)+(L(v.value)-k-H))/l+1;g.appendChild(m("path",{class:o,"data-note":a.note,d:T,style:`--len:${z.toFixed(1)}; ${b("--after",$)}`}));const C=L(v.value);var O;g.appendChild(m("polygon",{class:r,"data-note":a.note,points:`${N},${C} ${N-.45*k},${C-k} ${N+.45*k},${C-k}`,style:b("--after",$)})),n&&(p(n,(A+N)/2,H,h,f),n.style.setProperty("--after",String($))),S(n,(O=M.value,(v.value-O)/Math.abs(O)*100),`${M.value} to ${v.value}`,a)}},L=new WeakMap,T=t=>L.get(t)??{width:t.offsetWidth,height:t.offsetHeight},z={create:N,draw(t,e,n){const{rows:a,cx:s,y:c,unit:i,labelHeight:l,height:u,svg:d,values:f,after:g}=n,$=a[0],w=a[a.length-1];if(!$||!w)return;const y=l+18*i,M=10*i,v=10*i;let k=s(0),x=c($.value)-y,A=s(a.length-1),N=c(w.value)-y,H=0;a.forEach((t,e)=>{const n=A===k?0:(s(e)-k)/(A-k),a=x+n*(N-x)-(c(t.value)-y);a>H&&(H=a)}),x-=H,N-=H;const L=A-k,z=N-x,C=Math.hypot(L,z)||1,O=L/C,U=z/C;k-=O*M,x-=U*M,A+=O*M,N+=U*M;const B=Number.parseFloat(t.getAttribute("data-at")||"0.5");if(e){const t=k+(A-k)*B,n=x+(N-x)*B,o=T(e).width*i/2,r=n+T(e).height*i/2+8*i;let u=0;a.forEach((e,n)=>{const a=(f[n]?T(f[n]).width:0)*i/2;if(Math.abs(s(n)-t)>=o+a)return;const d=c(e.value)-7*i-l;u=Math.max(u,r-d)}),x-=u,N-=u}const E=A-O*v,F=N-U*v,P=Math.hypot(E-k,F-x)/i+1;d.appendChild(m("line",{class:o,"data-note":n.note,x1:k,y1:x,x2:E,y2:F,style:`--len:${P.toFixed(1)}; ${b("--after",g)}`}));const q=-U,I=O,V=.42*v;d.appendChild(m("polygon",{class:r,"data-note":n.note,points:[`${A},${N}`,`${E+q*V},${F+I*V}`,`${E-q*V},${F-I*V}`].join(" "),style:b("--after",g)})),e&&(p(e,k+(A-k)*B,x+(N-x)*B,h,u),e.style.setProperty("--after",String(g)));const j=Number.parseFloat(t.getAttribute("data-years")||"");!Number.isNaN(j)&&j>0&&S(e,((t,e,n)=>100*(Math.pow(e/t,1/n)-1))($.value,w.value,j),`${$.value} to ${w.value} over ${j} years`,n)}},C=(t,e,n)=>{const a=.15,o=Math.min(.7*t/(e+(e-1)*a),n),r=e*o+(e-1)*o*a;return{size:o,gap:o*a,offset:t=>-r/2+t*o*1.15}},O=(t,e,n)=>{const a=t.series[n],o=t.series.some(t=>t.focus)&&!a.focus;return{"data-series":n+1,...o&&{"data-muted":""},style:`--n:${n}; --m:${o?1:0}; --palette:var(--tablechart-color-${n+1}); ${b("--i",e.slot)}`}},U=(t,e)=>{let n=0;return Array.from({length:e},(e,a)=>{const o=t.cells[a]??t.cells[0],r=n;return!o.missing&&o.value>0&&(n+=o.value),{from:r,to:n,cell:o}})},B=(t,e)=>U(t,e).at(-1)?.to??0,E=(t,e,n)=>{const a=e.series.some(t=>t.focus);t.style.setProperty("--n",String(n)),t.style.setProperty("--m",a&&!e.series[n].focus?"1":"0"),t.style.setProperty("--palette",`var(--tablechart-color-${n+1})`)},F=(t,e,a,o={})=>{const r=m("g",{class:g(n,e),"data-kind":"bar","data-row":a+1,...o,"data-stack":"",style:b("--i",e.slot)});return t.svg.appendChild(r),(n,a)=>{r.appendChild(m("rect",{...a,class:g("tablechart-piece",e),...O(t,e,n)}))}},P=(t,e,n)=>t.some(t=>T(t).width*n>e-6*n),q=(t,e,n)=>e>=T(t).height*n*1.6,I=(t,e,n)=>e>=T(t).width*n*1.5,V=(t,e,n,a,o=.7)=>{t.style.setProperty(a,"1");let r=1;for(const c of e){const{size:t,room:e}=n(c);t>e&&(r=Math.min(r,e/t))}const s=r>=o?r:0;return t.style.setProperty(a,String(s||o)),s},j={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,breakable:!0,aspect:.5,minHeight:({labelHeight:t,nameHeight:e,rows:n,series:a,stacked:o})=>{const r=1.1*t,s=a>1&&!o?r*(a+.15*(a-1))/.7:r/.58;return n*Math.max(s,1.2*e)},categories:"beside",headroom:()=>0,draw(t){const{segments:e,height:o,unit:r,svg:s,values:c,categories:i,config:l,barMax:u}=t,d=t.series.length>1,f=Math.max(k(i.map(t=>T(t).width*r)),0),$=Math.min(f+10*r,420),w=h-4*r,y=t.stacked?Math.max(k(t.rows.map(e=>B(e,t.series.length))),0)||1:Math.max(k(t.rows.flatMap(e=>e.cells.slice(0,t.series.length).map(t=>Math.abs(t.value)))),0)||1,M=Math.max(y,t.squeeze?.hi??0),v=(e,n)=>((t,e,n,a,o)=>{if(!a)return t/e*n;const{lo:r,hi:s,gap:c,share:i}=a,l=n*i,u=(n-l-o)/(r+(e-s)),d=l/(s-r);return t<=r?t*u:t<=c?r*u+(t-r)*d:t<=s?r*u+(t-r)*d+o:r*u+l+o+(t-s)*u})(Math.abs(e),M,n,t.squeeze,t.breakGap),x=o/e.length,A=t=>(t+.5)*x,N=Math.min(x*l.barfill,u),S=C(x,t.series.length,u),H=c[0]??t.totals[0],L=H?T(H).height*r*.56:0,z=Math.max(((d&&!t.stacked?S.size:N)-L)/2,5*r),P=t=>T(t).width*r,q=t=>t.length?k(t.map(P))+z+4*r:0;let j=t.stacked?q(t.totals):d?q(t.seriesValues.flat()):0;if(!d)for(let n=0;n<3;n++){const t=w-$-j,n=q(e.map((t,e)=>({seg:t,label:c[e]})).filter(({seg:e,label:n})=>!I(n,v(e.value,t),r)).map(({label:t})=>t));if(n<=j)break;j=n}const K=w-$-j,R=t=>$+v(t,K);if(t.squeeze&&(t.breakX=R(t.squeeze.gap)),t.stacked)return t.rows.forEach((e,n)=>{const a=F(t,e,n,{"data-grow":"right"}),s=A(n)-N/2,c=U(e,t.series.length);c.forEach(({from:e,to:c,cell:i},l)=>{const u=t.seriesValues[l][n];if(u.dataset.place="none",i.missing||c===e)return;const d=R(e),f=R(c);a(l,{x:d,y:s,width:Math.max(f-d,1),height:N}),u.dataset.place="inside",u.toggleAttribute("data-left-out",!I(u,f-d,r)||T(u).height*r>N),E(u,t,l),p(u,(d+f)/2,A(n),h,o)});const l=t.totals[n];l&&(l.dataset.place="after",p(l,R(c.at(-1)?.to??0)+z,A(n),h,o));const u=i[n];u&&p(u,$-8*r,A(n),h,o)}),void s.appendChild(m("line",{class:a,x1:$,x2:$,y1:0,y2:o}));if(d){t.plot.dataset.grouped="";const e=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),c=V(t.plot,e,t=>({size:T(t).height*r,room:S.size+.5*S.gap}),"--tablechart-fit");return t.rows.forEach((e,a)=>{t.series.forEach((r,i)=>{const l=e.cells[i]??e.cells[0],u=t.seriesValues[i][a];if(l.missing)return void(u.dataset.place="none");const d=R(l.value),f=A(a)+S.offset(i);s.appendChild(m("rect",{class:g(n,e),"data-kind":"bar","data-row":a+1,"data-grow":"right",x:$,y:f,width:Math.max(d-$,1),height:S.size,...O(t,e,i)})),u.dataset.place="after",u.toggleAttribute("data-left-out",!c),p(u,d+z,f+S.size/2,h,o)});const l=i[a];l&&p(l,$-8*r,A(a),h,o)}),void s.appendChild(m("line",{class:a,x1:$,x2:$,y1:0,y2:o}))}const W=e.map((t,e)=>I(c[e],R(t.value)-$,r));e.forEach((e,a)=>{const l=R(e.value),u=A(a);s.appendChild(m("rect",{class:g(n,e),"data-kind":e.kind,"data-row":a+1,"data-grow":"right",x:$,y:u-N/2,width:Math.max(l-$,1),height:N,style:b("--i",e.slot)}));const d=c[a],f=Math.max(Math.min(z,l-$-P(d)-6*r),6*r);d.dataset.place=W[a]?"inside":"after",d.dataset.kind=e.kind,p(d,W[a]?"center"===t.insideAlign?($+l)/2:"start"===t.insideAlign?$+f+P(d)/2:l-f-P(d)/2:l+z,u,h,o);const w=i[a];w&&p(w,$-8*r,u,h,o)}),s.appendChild(m("line",{class:a,x1:$,x2:$,y1:0,y2:o}))}},K={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:n,unit:a})=>t+4*a+(n?1.6*e:0),draw(t){const{segments:e,cx:o,y:r,barWidth:s,height:c,unit:i,svg:l,values:u,labels:d,insideAlign:f}=t,$=r(0);if(t.stacked)return t.rows.forEach((e,n)=>{const a=F(t,e,n),l=o(n)-s/2;U(e,t.series.length).forEach(({from:e,to:u,cell:d},f)=>{const b=t.seriesValues[f][n];if(b.dataset.place="none",d.missing||u===e)return;const m=r(u),g=r(e);a(f,{x:l,y:m,width:s,height:Math.max(g-m,1)}),b.dataset.place="inside",b.toggleAttribute("data-left-out",!q(b,g-m,i)||T(b).width*i>s-4*i),E(b,t,f),p(b,o(n),(m+g)/2,h,c)});const u=t.totals[n],d=U(e,t.series.length).at(-1)?.to??0;u&&(u.dataset.place="outside",p(u,o(n),r(d)-4*i,h,c))}),void l.appendChild(m("line",{class:a,x1:0,x2:h,y1:$,y2:$}));if(t.series.length>1){const e=C(o(1)-o(0)||2*o(0),t.series.length,t.barMax);t.plot.dataset.grouped="";const s=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),u=V(t.plot,s,t=>({size:T(t).width*i,room:e.size+.5*e.gap}),"--tablechart-fit");return t.rows.forEach((a,s)=>{t.series.forEach((d,f)=>{const b=a.cells[f]??a.cells[0],w=t.seriesValues[f][s],y=o(s)+e.offset(f);if(b.missing)return void(w.dataset.place="none");const M=r(b.value);l.appendChild(m("rect",{class:g(n,a),"data-kind":"bar","data-row":s+1,x:y,y:M,width:e.size,height:Math.max($-M,1),...O(t,a,f)})),w.dataset.place="outside",w.toggleAttribute("data-left-out",!u),p(w,y+e.size/2,M-4*i,h,c)})}),void l.appendChild(m("line",{class:a,x1:0,x2:h,y1:$,y2:$}))}const w=P(u,s,i),y=e.map((t,e)=>"inside"===d&&!w&&!t.missing&&q(u[e],$-r(t.value),i)),M=u[0]?T(u[0]).height*i*.56:0;let v=Number.POSITIVE_INFINITY;for(const[n,a]of u.entries())y[n]&&(v=Math.min(v,(s-T(a).width*i)/2));e.forEach((t,e)=>{const a=r(t.value);if(t.missing)return p(u[e],o(e),$-4*i,h,c),void(u[e].dataset.place="outside");l.appendChild(m("rect",{class:g(n,t),"data-kind":t.kind,"data-row":e+1,x:o(e)-s/2,y:a,width:s,height:Math.max($-a,1),style:b("--i",t.slot)}));const d=Math.min(v,($-a-M)/2),w="center"===f?(a+$)/2:"start"===f?$-d-M/2:a+d+M/2;p(u[e],o(e),y[e]?w:a-4*i,h,c),u[e].dataset.place=y[e]?"inside":"outside"}),l.appendChild(m("line",{class:a,x1:0,x2:h,y1:$,y2:$}))}},R=0,W={aspect:.66,centre:!0,headroom:()=>0,segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),draw({rows:t,height:e,unit:n,labelHeight:a,svg:o,values:r,config:c,centre:i}){const l=500,u=e/2,d=(t=>t.filter(t=>!t.isTotal))(t).reduce((t,e)=>t+Math.abs(e.value),0);if(!d)return;const f=1.2*a+10*n,$=Math.max(Math.min(h,e)/2-f,10),w=$*c.ringfill,y=$-w/2,M=2*Math.PI*y,v=[];let k=0,x=0;if(t.forEach((t,c)=>{const i=r[c];if(t.isTotal)return void(i.dataset.place="none");const f=Math.abs(t.value)/d*M,A=k/M*2*Math.PI-Math.PI/2;v.push(A),o.appendChild(m("circle",{class:g(s,t),"data-slice":x+1,"data-row":c+1,cx:l,cy:u,r:y,"stroke-width":w,transform:`rotate(-90 500 ${u})`,"stroke-dasharray":`${f.toFixed(1)} ${(M-f).toFixed(1)}`,"stroke-dashoffset":(-k).toFixed(1),style:`--n:${x}; --palette:var(--tablechart-color-${x+1}); --arc:${f.toFixed(1)}; --circ:${M.toFixed(1)}; ${b("--i",t.slot)}`}));const N=A+f/M*Math.PI,S=Math.cos(N),H=Math.sin(N);o.appendChild(m("line",{class:"tablechart-leader",x1:l+S*($+2*n),y1:u+H*($+2*n),x2:l+S*($+7*n),y2:u+H*($+7*n),"data-row":c+1,style:b("--i",t.slot)}));const L=$+9*n,z=T(i).width*n/2;p(i,l+S*(L+Math.abs(S)*z),u+H*(L+Math.abs(H)*a*.7),h,e),i.dataset.place="around",k+=f,x+=1}),v.length>1){const t=y-w/2-1,n=y+w/2+1,a="tablechart-slices-"+ ++R,r=m("mask",{id:a,maskUnits:"userSpaceOnUse"});r.appendChild(m("rect",{x:0,y:0,width:h,height:e,fill:"white"}));for(const e of v)r.appendChild(m("line",{class:"tablechart-divide",x1:l+Math.cos(e)*t,y1:u+Math.sin(e)*t,x2:l+Math.cos(e)*n,y2:u+Math.sin(e)*n}));const c=m("g",{mask:`url(#${a})`});for(const e of Array.from(o.querySelectorAll(`.${s}`)))c.appendChild(e);const i=m("defs");i.appendChild(r),o.prepend(i,c)}i&&p(i,l,u,h,e)}},D=["circle","square","diamond"],G=(t,e)=>{const n=t[e]?.marker?.toLowerCase().split(/\s+/)??[],a=D.find(t=>n.includes(t));return{shape:a??D[Math.floor(e/2)%D.length],open:n.includes("open")||!n.includes("filled")&&!a&&e%2==1}},Z=t=>Number(t.toFixed(2));function J(t,e,n){const a=new Array(t).fill(0);let o=[];const r=()=>{(function(t,e){const n=t.length;if(n<2)return t.map(()=>0);const a=n=>(e[n+1]-e[n])/(t[n+1]-t[n]||1),o=new Array(n).fill(0);for(let s=1;s<n-1;s++){const e=a(s-1),n=a(s);if(e*n<=0)continue;const r=t[s]-t[s-1],c=t[s+1]-t[s],i=(e*c+n*r)/(r+c||1),l=Math.min(2*Math.abs(e),2*Math.abs(n),Math.abs(i));o[s]=Math.sign(e)*l||0}if(2===n)return o[0]=a(0),o[1]=a(0),o;const r=(n,a,o)=>{const r=t[a]-t[n];return r?((e[a]-e[n])/r*3-o)/2:o};return o[0]=r(0,1,o[1]),o[n-1]=r(n-2,n-1,o[n-2]),o})(o.map(t=>n(t)[0]),o.map(t=>n(t)[1])).forEach((t,e)=>{a[o[e]]=t}),o=[]};for(let s=0;s<t;s++)e(s)?r():o.push(s);return r(),a}var Q=t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),X=t=>({segments:Q,series:!0,stackable:!0,swatch:t?"box":void 0,headroom:({labelHeight:t,unit:e})=>1.6*t+6*e,footroom:({labelHeight:e,unit:n,series:a,focused:o,stacked:r})=>t||r||2!==a||o?0:e+7*n,draw(e){const{rows:n,series:o,seriesValues:r,names:s,cx:c,y:l,height:u,unit:d,labelHeight:f,svg:b,stacked:g}=e,$="step"===e.shape,w="smooth"===e.shape,M=o.length>1,v=o.some(t=>t.focus),k=n.length-1,x=l(0),A=n.length>1?c(1)-c(0):2*c(0);b.style.setProperty("--tablechart-base",`${Z(x)}px`);const N=(t,e)=>n[e]?.cells[t]??n[e]?.cells[0],S=(t,e)=>!N(t,e)||!!N(t,e)?.missing,H=n.map(t=>g?U(t,o.length):null),L=(t,e)=>H[e]?.[t].to??N(t,e)?.value??0,z=(t,e)=>H[e]?.[t].from??0,C=(t,e)=>[c(e),l(L(t,e))],O=o.map((t,e)=>{if(!M)return{attrs:{},ink:""};const n=v&&!t.focus;return{attrs:{"data-series":e+1,...n&&{"data-muted":""}},ink:`--n:${e}; --m:${n?1:0}; --palette:var(--tablechart-color-${e+1}); `}}),B=Math.min(k,6),E=k>0?B/($?n.length:k):1,F=t=>t*E,P=t=>`--i:${Z(F(t))}`,q=t=>{const e=[];let a=-1;return n.forEach((n,o)=>{S(t,o)||(a<0&&(a=o),(o===k||S(t,o+1))&&(($||o>a)&&e.push([a,o]),a=-1))}),e},I=(t,e)=>`--i:${Z(F(t)+1)}; --d:${Z(F($?e+1:e)-F(t))}`,V=(t,e)=>({"data-from":t+1,"data-to":e+1,...$&&{"data-flat":""}}),j=w?o.map((t,e)=>J(n.length,t=>S(e,t),t=>C(e,t))):[],K=w&&t?o.map((t,e)=>J(n.length,t=>S(e,t),t=>[c(t),l(z(e,t))])):[],R=(t,e,n)=>{const a=[];return t.forEach(([o,r],s)=>{$?(a.push(`H${Z(o+n*A/2)}`),s<t.length-1&&a.push(`V${Z(t[s+1][1])}`)):s>0&&a.push(e?function(t,e,n,a){const[o,r]=function(t,e,n,a){const o=(e[0]-t[0])/3;return[[t[0]+o,t[1]+n*o],[e[0]-o,e[1]-a*o]]}(t,e,n,a),s=([t,e])=>`${Z(t)},${Z(e)}`;return`C${s(o)} ${s(r)} ${s(e)}`}(t[s-1],[o,r],e[s-1],e[s]):`L${Z(o)},${Z(r)}`)}),a},W=(t,e,a,o)=>n.slice(e,a+1).map((n,a)=>[c(e+a),l(o(t,e+a))]),D=(t,e,n,a)=>w?t[e].slice(n,a+1):null,Q=t=>c(t)-($?A/2:0),X=t=>c(t)+($?A/2:0);t&&o.forEach((t,e)=>(t=>{const e=m("g",{class:"tablechart-area",...O[t].attrs,...g&&{"data-stacked":""},style:O[t].ink}),n=q(t),a=m("g",{class:"tablechart-area-fill",style:`--rows:${Z(B+1)}; ${n.length?I(...n[0]):""}`});e.appendChild(a);for(const[o,r]of n){const e=W(t,o,r,L),n=W(t,o,r,z),s=D(K,t,o,r)?.reverse()??null,c=[`M${Z(Q(o))},${Z(n[0][1])}`,`L${Z(Q(o))},${Z(e[0][1])}`,...R(e,D(j,t,o,r),1),`L${Z(X(r))},${Z(n[n.length-1][1])}`,...R(n.reverse(),s,-1),"Z"].join(" ");a.appendChild(m("path",{d:c,...V(o,r),style:I(o,r)}))}b.appendChild(e)})(e)),o.forEach((t,e)=>(t=>{const e=o[t];for(const[n,a]of q(t)){const o=W(t,n,a,L),r=[`M${Z(Q(n))},${Z(o[0][1])}`,...R(o,D(j,t,n,a),1)].join(" ");b.appendChild(m("path",{class:"tablechart-series",...O[t].attrs,d:r,...e.line&&{"data-line":e.line},...V(n,a),style:`${O[t].ink}${I(n,a)}`}))}})(e)),$||(()=>{const t=o.map((t,e)=>M?G(o,e):{shape:"circle",open:!1}),e=(e,n,a)=>{const[o,r]=C(e,n);return((t,e,n,a,o={})=>{if("square"===t){const t=.88*a;return m("rect",{x:e-t,y:n-t,width:2*t,height:2*t,...o})}if("diamond"===t){const t=1.2*a;return m("polygon",{points:`${e},${n-t} ${e+t},${n} ${e},${n+t} ${e-t},${n}`,...o})}return m("circle",{cx:e,cy:n,r:a,...o})})(t[e].shape,o,r,4*d,{...a,style:`${a.style??""}${s=r,`--rise:${Z(x-s)}px; `}${P(n)}`});var s},a=t=>n.map((t,e)=>e).filter(e=>!S(t,e));y(b,o.flatMap((n,o)=>t[o].open?a(o).map(t=>e(o,t,{class:i,"data-row":t+1,...M&&{"data-series":o+1}})):[]),h,u),o.forEach((n,o)=>{for(const r of a(o))b.appendChild(e(o,r,{class:"tablechart-point",...O[o].attrs,"data-marker":t[o].shape,...t[o].open&&{"data-open":""},"data-row":r+1,style:O[o].ink}))})})();const Y=(t,e)=>{let n=e;for(;n<k&&!S(t,n+1)&&N(t,n+1)?.value===N(t,e)?.value;)n++;return n};r.forEach((e,n)=>{e.forEach((e,a)=>{e.style.setProperty("--i",String(Z($?(F(a)+F(a+1))/2:F(a))));const s=((e,n)=>{const a=N(e,n);if(!a||a.missing)return"none";if($&&n>0&&!S(e,n-1)&&N(e,n-1)?.value===a.value)return"none";if(v&&!o[e].focus)return"none";if(g)return"middle";if(!M||v||o.length>2)return"above";const r=N(1-e,n);return!r||r.missing||a.value>r.value||a.value===r.value&&0===e||t&&C(e,n)[1]+7*d+f>x?"above":"below"})(n,a);if(e.dataset.place="above"===s?"outside":s,e.toggleAttribute("data-left-out","none"!==s&&((t,e)=>g||$?T(r[t][e]).width*d>($?Y(t,e)-e+1:1)*A-4*d||g&&l(z(t,e))-l(L(t,e))<1.2*f:M&&!v&&o.length>2)(n,a)),$&&"none"!==s?e.dataset.rowEnd=String(Y(n,a)+1):delete e.dataset.rowEnd,"none"===s)return;const i=T(e).width*d/2+4*d;let b=c(a);$?b=(c(a)+c(Y(n,a)))/2:"middle"===s&&0===a?b+=i:"middle"===s&&a===k&&(b-=i);const m=l(L(n,a)),w={middle:(l(z(n,a))-m)/2,above:-7*d,below:7*d};p(e,b,m+w[s],h,u)})});const _=s.map((t,e)=>{let n=k;for(;n>0&&S(e,n);)n--;const[a,o]=C(e,n);return{name:t,x:($?a+A/2:a)+10*d,y:g?(o+l(z(e,n)))/2:o}}),tt=(s[0]?T(s[0]).height:0)*d;for(const t of((t,e)=>(t.sort((t,e)=>t.y-e.y),t.forEach((n,a)=>{const o=t[a-1];o&&n.y<o.y+e&&(n.y=o.y+e)}),t))(_,tt))p(t.name,t.x,t.y,h,u);const et=t||g||2!==o.length||v?x:u-2*d;b.appendChild(m("line",{class:a,x1:0,x2:c(k)+c(0),y1:et,y2:et}))}}),Y=X(!1),_=X(!0),tt=new Set,et={segments:e=>{let n=0,a=!1;return e.map(e=>{if(e.isTotal)return a&&((e,n)=>{if(Math.abs(e-n)<=Math.abs(n)/100)return;const a=`[${t}] A total reads ${e}, but the steps before it add up to ${Number(n.toFixed(6))}. The chart shows what you wrote; this is only a check.`;tt.has(a)||(tt.add(a),console.warn(a))})(e.value,n),a=!1,n=e.value,{...e,from:0,to:e.value,kind:"total"};const o=n;return n+=e.value,a=!0,{...e,from:o,to:n,kind:e.value>=0?"up":"down"}})},breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:n,unit:a})=>t+6*a+(n?1.6*e:0),draw({segments:t,cx:e,y:o,barWidth:r,height:s,unit:c,svg:i,values:l,breakAt:u,closing:d,insideAlign:f}){const $=o(0),w=P(l,r,c),y=f??"center",M=t.map((e,n)=>{const a=o(Math.max(e.from,e.to)),r=Math.abs(o(e.from)-o(e.to)),s=null!==u&&Math.min(e.from,e.to)<u&&Math.max(e.from,e.to)>u;return{top:a,length:r,down:"down"===e.kind||"total"===e.kind&&n>0&&n===t.length-1&&"down"===d,inside:!s&&!w&&q(l[n],r,c)}}),v=l[0]?T(l[0]).height*c*.56:0;let k=Number.POSITIVE_INFINITY;for(const[n,a]of M.entries())a.inside&&(k=Math.min(k,(r-T(l[n]).width*c)/2));t.forEach((n,a)=>{const s=t[a+1];if(!s)return;const c=o(n.to),l=e(a)+r/2,u=e(a+1)-r/2;i.appendChild(m("line",{class:"tablechart-connector",x1:l,x2:u,y1:c,y2:c,"data-row":a+2,style:b("--i",s.slot)}))}),t.forEach((t,a)=>{const{top:o,length:u,down:d,inside:f}=M[a];i.appendChild(m("rect",{class:g(n,t),"data-kind":t.kind,"data-row":a+1,"data-grow":d?"down":"up",x:e(a)-r/2,y:o,width:r,height:Math.max(u,1),style:b("--i",t.slot)}));const $=l[a],w=Math.min(k,(u-v)/2),x="center"===y?o+u/2:"end"===y!==d?o+w+v/2:o+u-w-v/2;$.dataset.place=f?"inside":"outside",$.dataset.kind=t.kind;const A=f?x:"down"===t.kind?o+u+T($).height*c+3*c:o-3*c;p($,e(a),A,h,s)}),i.appendChild(m("line",{class:a,x1:0,x2:h,y1:$,y2:$}))}},nt={enabled:!1,log(...e){nt.enabled&&console.log(`[${t}]`,...e)},timed(e,n,a){if(!nt.enabled)return a();const o=performance.now(),r=a(),s=performance.now()-o,c=n.querySelectorAll("tbody tr").length;return s>50?console.warn(`[${t}] ${e} took ${s.toFixed(1)} ms for ${c} rows, more than 50 ms.`,n):nt.log(`${e} took ${s.toFixed(1)} ms for ${c} rows.`,n),r}},at=t=>{const e=(t?.textContent||"").trim(),n=e.match(/^(.*?)(-?\d+(?:[.,]\d+)?)(.*)$/);return{raw:e,number:n?.[2]??"",prefix:n?.[1]??"",suffix:n?.[3]??"",missing:!n,value:n?Number.parseFloat(n[2].replace(",",".")):0}},ot=t=>Array.from(t.querySelector("thead tr:last-child")?.children??[]).slice(1),rt=["axis-break","trend","bracket"],st=t=>{const e=t.plan;if(!e)return;const n=e=>null===e||t.step-e>=1;for(const a of t.figure.querySelectorAll("[data-from]")){const t=Number(a.dataset.from)-1,o=Number(a.dataset.to)-1,r=a.closest("[data-series]")?.dataset.series,s=r?e.series[Number(r)-1]:void 0;let c=t-1;if(s&&null!==s.step)c=n(s.step)?o:t-1;else for(;c<o&&n(e.rows[c+1]?.step??null);)c++;const i=a.hasAttribute("data-flat")?(c-t+1)/(o-t+1):o>t?Math.max(0,c-t)/(o-t):0;a.style.setProperty("--reveal",String(i))}},ct=(t,e,n=!1)=>{const a=t.plan;if(!a)return;const o=Math.min(Math.max(Math.round(e),0),a.count),r=o!==t.step;t.step=o,t.figure.style.setProperty("--tablechart-step",String(o)),st(t);const[s,c]=t.controls?.querySelectorAll("button")??[];s&&(s.disabled=0===o),c&&(c.disabled=o===a.count),r&&!n&&t.figure.dispatchEvent(new CustomEvent("tablechart:step",{bubbles:!0,detail:{step:o,steps:a.count}}))},it={area:_,bar:j,column:K,donut:W,line:Y,waterfall:et},lt={"axis-break":v,trend:z,bracket:H},ut=Object.keys(lt),dt=t=>{let e="";for(let n=t.previousSibling;n&&(e=(n.textContent??"")+e,!e.trim());n=n.previousSibling);return e.trim()},ht=["straight","step","smooth"],ft=(t,e)=>{const n=t.dataset.chartShape;return n&&ht.includes(n)?n:ht.includes(e.shape)?e.shape:"straight"},bt=0,mt=(n,a,o=null)=>{const r=o??(n.getAttribute("data-chart")||"column"),s=it[r];if(!s)return console.warn(`[${t}] Unknown chart type "${r}". Known types: ${Object.keys(it).join(", ")}.`),n.setAttribute("data-chart-empty",""),null;const i=((t,e="data-i18n")=>Array.from(t.querySelectorAll("tbody tr")).map((t,n)=>{const a=t.querySelector("th"),o=Array.from(t.querySelectorAll("td")).map(at);return o.length||o.push(at(null)),{...o[0],label:(a?.textContent||"").trim(),key:e&&a?.getAttribute(e)||null,cells:o,classes:Array.from(t.classList),isTotal:"total"===t.getAttribute("data-kind"),slot:n}}))(n,a.langattribute);if(!i.length)return console.warn(`[${t}] A chart has no rows in its table, so there is nothing to draw.`),n.setAttribute("data-chart-empty",""),null;(t=>{const e=t.querySelector(":scope > figcaption");if(!e)return;(t=>{for(const e of t.querySelectorAll("br")){if(e.previousElementSibling?.classList.contains("tablechart-sr"))continue;if(/[.!?:;,…]$/.test(dt(e)))continue;const t=document.createElement("span");t.className=d,t.textContent=". ",e.before(t)}})(e);const n=t=>t.hasAttribute("aria-label")||t.hasAttribute("aria-labelledby"),a=t=>{e.id||(e.id="tablechart-caption-"+ ++bt),t.setAttribute("aria-labelledby",e.id)};"FIGURE"!==t.tagName||n(t)||a(t);const o=t.querySelector("table");!o||n(o)||o.querySelector(":scope > caption")||a(o)})(n);let u=((t,e,n="data-i18n")=>{const a=ot(t),o=Math.max(1,k(e.map(t=>t.cells.length)));return Array.from({length:o},(t,e)=>{const o=a[e];return{name:(o?.textContent||"").trim(),key:n&&o?.getAttribute(n)||null,focus:"focus"===o?.getAttribute("data-kind"),marker:o?.getAttribute("data-marker")??null,line:(r=o?.getAttribute("data-line"),"dashed"===r||"dotted"===r?r:null)};var r})})(n,i,a.langattribute);u.length>1&&!s.series&&(console.warn(`[${t}] A ${r} chart draws one series; only the first of the table's ${u.length} value columns is used.`),u=u.slice(0,1));const h=u.length>1;h&&n.style.setProperty("--tablechart-series-count",String(u.length));const f=n.hasAttribute("data-chart-stack");f&&!s.stackable&&console.warn(`[${t}] A ${r} chart cannot be stacked.`);const b=f&&!!s.stackable&&h;b&&i.some(t=>t.cells.slice(0,u.length).some(t=>t.value<0))&&console.warn(`[${t}] A stacked chart has a value below zero. It takes no room in the stack.`);const g=document.createElement("div");g.className="tablechart-plot",g.setAttribute("aria-hidden","true");const p=m("svg",{role:"presentation",focusable:"false"});g.appendChild(p),n.appendChild(g);const w=s.centre?i.filter(t=>!t.isTotal):i,y=Math.max(0,k(w.flatMap(t=>t.cells.slice(0,u.length).map(t=>x(t.number))))),M=u.map((t,n)=>i.map((t,a)=>{const o=t.cells[n]??t.cells[0],r=$(e,g);return r.classList.add(...t.classes),r.dataset.value=String(o.value),o.prefix&&(r.dataset.prefix=o.prefix),o.suffix&&(r.dataset.suffix=o.suffix),o.missing&&(r.dataset.missing=o.raw),h&&(r.dataset.series=String(n+1)),r.dataset.row=String(a+1),r.style.setProperty("--i",String(t.slot)),r})),v=M[0],A=b&&s.totals?i.map((t,n)=>{const a=$(e,g);a.classList.add(...t.classes),a.dataset.kind="total",a.dataset.row=String(n+1),a.dataset.value=String(B(t,u.length));const o=t.cells[0];return o.prefix&&(a.dataset.prefix=o.prefix),o.suffix&&(a.dataset.suffix=o.suffix),a.style.setProperty("--i",String(t.slot)),a}):[],N=i[i.length-1],S=u.some(t=>t.focus),H=n.getAttribute("data-chart-legend"),L=h&&(null===H?a.legend||void 0!==s.legend:"false"!==H)?document.createElement("div"):null;L&&(L.className=c,L.setAttribute("aria-hidden","true"),L.inert=!0);const T=h?u.map((t,e)=>{const o=$("tablechart-name",L??g);L&&(o.dataset.place="legend");const r=s.legend??s.swatch;if(r&&(o.dataset.swatch=r),o.textContent=t.name,!r&&"step"!==ft(n,a)){const t=G(u,e);o.dataset.marker=t.shape,o.toggleAttribute("data-open",t.open)}return t.line&&!r&&(o.dataset.line=t.line),t.key&&a.langattribute&&o.setAttribute(a.langattribute,t.key),o.dataset.series=String(e+1),o.style.setProperty("--n",String(e)),o.style.setProperty("--palette",`var(--tablechart-color-${e+1})`),o.style.setProperty("--m",S&&!t.focus?"1":"0"),o.style.setProperty("--i",String(N.slot)),o}):[],z=s.centre?$(l,g):null;if(z){const t=i.find(t=>t.isTotal),e=t?t.value:i.reduce((t,e)=>t+Math.abs(e.value),0);z.dataset.value=String(e),t&&(z.dataset.decimals=String(x(t.number)))}const C=z&&!i.some(t=>t.isTotal)?((t,e,n)=>{const a=t.querySelector("table");if(!a)return null;const o=a.querySelector("tfoot [data-chart-total]");if(o)return o.dataset.value=e.dataset.value??"0",o;const r=(a.tFoot??a.createTFoot()).insertRow(),s=document.createElement("th");s.scope="row",s.textContent=n.totallabel;const c=t.getAttribute("data-chart-keys");c&&n.langattribute&&s.setAttribute(n.langattribute,`${c}-total`);const i=r.insertCell();return i.setAttribute("data-chart-total",""),i.dataset.value=e.dataset.value??"0",r.prepend(s),i})(n,z,a):null,O="beside"===s.categories,U=document.createElement("div");U.className="tablechart-categories",U.setAttribute("aria-hidden","true"),U.inert=!0,O?U.dataset.place="beside":s.centre&&(U.dataset.place="key"),U.style.setProperty("--tablechart-columns",String(i.length));let E=0;for(const[t,e]of i.entries()){const n=document.createElement("span");n.classList.add(...e.classes),n.textContent=e.label,e.key&&a.langattribute&&n.setAttribute(a.langattribute,e.key),s.centre&&(n.dataset.kind=e.isTotal?"total":"slice",e.isTotal||(n.dataset.slice=String(E+1),n.style.setProperty("--n",String(E)),n.style.setProperty("--palette",`var(--tablechart-color-${E+1})`),E+=1)),n.style.setProperty("--i",String(e.slot)),n.dataset.row=String(t+1),U.appendChild(n)}(O?g:n).appendChild(U),L&&n.appendChild(L);const F=a.animate?(t=>{const e=t.hasAttribute("data-fragment"),n=Array.from(t.querySelectorAll("tbody tr")),a=Array.from(t.querySelector("thead tr:last-child")?.children??[]).slice(1),o=Array.from(t.querySelectorAll("[data-annotation]")).filter(t=>rt.includes(t.getAttribute("data-annotation")??"")),r=t=>t.hasAttribute("data-fragment");if(!(e||n.some(r)||a.some(r)||o.some(r)))return null;const s=[],c=new Map,i=[],l=t=>{let e=null!==t?c.get(t):void 0;return void 0===e&&(e=s.length,s.push(t),i.push(0),null!==t&&c.set(t,e)),e};let u=0;const d="donut"===t.getAttribute("data-chart"),h=t=>d&&"total"===t.getAttribute("data-kind"),f=n.map(t=>{if(h(t))return{step:null,slot:0};if(!e&&!r(t))return{step:null,slot:u++};const n=l(t.getAttribute("data-fragment-index"));return{step:n,slot:i[n]++}}),b=Math.max(-1,...f.map(t=>t.step??-1));if(b>=0)for(const[g,$]of n.entries())h($)&&(f[g]={step:b,slot:i[b]++});const m=a.map(t=>({step:r(t)?l(t.getAttribute("data-fragment-index")):null}));return{rows:f,series:m,notes:o.map(t=>{const e=(e,n)=>{const a=Number.parseInt(t.getAttribute(e)??"",10);return Number.isFinite(a)?a-1:n},[n,a]="bracket"===t.getAttribute("data-annotation")?[e("data-from",0),e("data-to",f.length-1)]:[0,f.length-1];let o=null;for(let r=Math.min(n,a);r<=Math.max(n,a);r++){const t=f[r]?.step??null;null!==t&&(null===o||t>o)&&(o=t)}const s=m[e("data-series",0)]?.step??null;null!==s&&(null===o||s>o)&&(o=s),r(t)&&(o=l(t.getAttribute("data-fragment-index")));const c=null===o?f.length:f.filter(t=>t.step===o).length;return{step:o,after:c}}),count:s.length,indexes:s}})(n):null;F&&(n.setAttribute("data-steps",""),n.setAttribute("data-chart-animate","across"));const P=n.getAttribute("data-chart-keys"),q=F&&a.controls?((t,e,n)=>{const a=document.createElement("div");a.className="tablechart-controls";const o=a=>{const o=document.createElement("button");o.type="button",o.className=`tablechart-${a}`,o.dataset.go=a;const r=document.createElement("span");r.className="tablechart-control-icon",r.setAttribute("aria-hidden","true");const s=m("svg",{viewBox:"0 0 16 16",focusable:"false"});s.appendChild(m("path",{d:"next"===a?"M6 3l5 5-5 5":"M10 3L5 8l5 5"})),r.appendChild(s);const c=document.createElement("span");c.className="tablechart-control-label",c.textContent=t[a];const i=e[a];i&&n&&c.setAttribute(n,i);const l=document.createElement("span");return l.className=d,l.textContent=t.hint,e.hint&&n&&l.setAttribute(n,e.hint),o.append(..."next"===a?[c,l,r]:[r,c,l]),o};return a.append(o("previous"),o("next")),a})({previous:a.previouslabel,next:a.nextlabel,hint:a.stephint},{previous:P&&`${P}-previous`,next:P&&`${P}-next`,hint:P&&`${P}-step`},a.langattribute):null;q&&n.appendChild(q);const I=Array.from(n.querySelectorAll("[data-annotation]")).map(e=>{const n=e.getAttribute("data-annotation"),a=lt[n];if(!a)return console.warn(`[${t}] Unknown annotation "${n}". Known annotations: ${Object.keys(lt).join(", ")}.`),null;const o=Number.parseInt(e.getAttribute("data-series")??"1",10),r=o>=1&&o<=u.length?o-1:0;return o!==r+1&&console.warn(`[${t}] An annotation reads line ${o}, which the chart does not have; it reads the first.`),{spec:e,type:a,badge:a.create(e,g),series:r,after:i.length}}).filter(t=>null!==t);if(a.animate){const t=n.getAttribute("data-chart-animate"),e="up"===("up"===t||"across"===t?t:a.animate)&&("line"===r||"area"===r);n.setAttribute("data-animate",e?"up":"")}const V={figure:n,plot:g,svg:p,rows:i,decimals:y,type:s,values:v,series:u,seriesValues:M,names:L?[]:T,categories:Array.from(U.children),centre:z,stacked:b,totals:A,totalCell:C,rowAt:null,rowBox:null,annotations:I,checks:[],plan:F,step:0,controls:q};return q?.addEventListener("click",t=>{const e=t.target.closest("button")?.dataset.go;e&&ct(V,V.step+("next"===e?1:-1))}),ct(V,0,!0),a.hover&&"false"!==n.getAttribute("data-chart-hover")&&Mt(V),wt(V,a),V},gt=t=>{const e=getComputedStyle(t).getPropertyValue("--tablechart-inside-align").trim();return"start"===e||"center"===e||"end"===e?e:null},$t=(t,e,n,a)=>{const o=getComputedStyle(t),r=(o.getPropertyValue(n).trim()||a).match(/^(\d+(?:\.\d+)?)(px|%|em|rem)$/);if(!r)return null;const s=Number(r[1]);return"%"===r[2]?s/100*h:s*("em"===r[2]?Number.parseFloat(o.fontSize):"rem"===r[2]?Number.parseFloat(getComputedStyle(document.documentElement).fontSize):1)*e},pt=(t,e)=>$t(t,e,"--tablechart-bar-max","60px")??Number.POSITIVE_INFINITY,wt=(t,e)=>{const n=[...t.seriesValues.flat(),...t.totals,...t.totalCell?[t.totalCell]:[]];for(const a of t.centre?[...n,t.centre]:n){const{missing:n,prefix:o="",suffix:r=""}=a.dataset;if(void 0!==n){a.textContent=n;continue}const[s,c]=A(Number.parseFloat(a.dataset.value||"0"),a.dataset.decimals?Number(a.dataset.decimals):t.decimals,e.locale);if(a.textContent=o+(o?s:"")+c+r,s&&!o){const t=document.createElement("span");t.className="tablechart-minus",t.textContent=s,a.prepend(t)}}},yt=(t,e)=>{t.figure.classList.toggle("is-shown",e),e||t.plot.removeAttribute("data-pointed")},Mt=t=>{const{plot:e}=t,n=()=>[...t.seriesValues.flat(),...t.totals];e.setAttribute("data-hover","");const a=document.createElement("div");a.className="tablechart-pointer",e.prepend(a);const o=()=>{e.removeAttribute("data-active");for(const t of n())t.removeAttribute("data-active")},r=r=>{if(!e.classList.contains("is-placed")||!t.rowAt)return;const s=e.getBoundingClientRect(),c=s.width/e.offsetWidth||1,i=t.rowAt((r.clientX-s.left)/c,(r.clientY-s.top)/c),l=null===i?null:i+1,u=t=>"none"!==t.dataset.place,d=null===l?[]:n().filter(t=>((t,e)=>{const n=Number(t.dataset.row),a=Number(t.dataset.rowEnd??n);return e>=n&&e<=a})(t,l)&&u(t));if(!n().some(t=>t.hasAttribute("data-left-out")&&u(t))||!d.length)return o();e.setAttribute("data-pointed",""),e.setAttribute("data-active",String(l));const[h,f,b,m]=t.rowBox?.(l-1)??[0,0,0,0];Object.assign(a.style,{left:`${h}%`,top:`${f}%`,width:`${b}%`,height:`${m}%`});for(const t of n())t.toggleAttribute("data-active",d.includes(t))};e.addEventListener("pointermove",r),e.addEventListener("pointerdown",r),e.addEventListener("pointerleave",t=>{"mouse"===t.pointerType&&o()}),document.addEventListener("pointerdown",t=>{e.contains(t.target)||o()})},vt=t=>"id"===t||"style"===t||t.startsWith("data-chart"),kt=/^\s*(?:Table)?:\s+/,xt=t=>"P"===t?.tagName&&kt.test(t.textContent??""),At=/^\s*([a-z][\w-]*)((?:\s+[\w-]+=[^\s:]+)*)\s*(:\s*|$)/,Nt=t=>{const e=St(t);return"P"===e?.tagName?e:t},St=t=>{const e=Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.nodeType===Node.TEXT_NODE&&t.textContent?.trim());return 1===e.length&&e[0]instanceof HTMLElement?e[0]:null},Ht="strong, b, span.total",Lt="data-chart-made",Tt=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches,zt=new Set,Ct=null,Ot=["column","bar"],Ut=t=>{const e=t.getAttribute("data-chart")||"column";if(!Ot.includes(e))return null;const n=getComputedStyle(t).getPropertyValue("--tablechart-type").trim();return Ot.includes(n)?n:e},Bt=async(e,n)=>{const a=(t=>t.map(t=>{const e=t.closest("p"),n=xt(e)?e:t;if("TABLE"!==n.tagName&&"P"!==n.tagName)return n;const a=document.createElement("div");((t,e)=>{for(const{name:n,value:a}of Array.from(t.attributes))("class"===n||vt(n))&&(e.setAttribute(n,a),t.removeAttribute(n))})(t,a),t.classList.length||t.removeAttribute("class");const o="TABLE"===n.tagName?n:null,r=n.previousElementSibling;let s=n.nextElementSibling;const c=o?xt(r)?r:xt(s)?s:null:n;o&&c===s&&(s=s?.nextElementSibling??null);const i=s?.classList.contains("chart-annotations")?s:(t=>{if("UL"!==t?.tagName&&"OL"!==t?.tagName)return null;const e=Array.from(t.children),n=e.map(t=>t.hasAttribute("data-annotation")?null:(t=>{const e=Nt(t).firstChild;if(e?.nodeType!==Node.TEXT_NODE)return null;const n=At.exec(e.textContent??"");if(!n||!ut.includes(n[1]))return null;if(!n[3]&&e.nextSibling)return null;const a=n[2].trim().split(/\s+/).filter(Boolean).map(t=>t.split("="));return{name:n[1],options:a,text:e,length:n[0].length}})(t));return!e.length||e.some((t,e)=>!n[e]&&!t.hasAttribute("data-annotation"))?null:(e.forEach((t,e)=>{const a=n[e],o=Nt(t);if(o!==t&&o.replaceWith(...o.childNodes),a){t.setAttribute("data-annotation",a.name);for(const[e,n]of a.options)t.setAttribute(`data-${e}`,n);a.text.textContent=(a.text.textContent??"").slice(a.length)}t.children.length&&Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.textContent?.trim()).forEach((t,e)=>{const n=document.createElement("span");0===e&&t instanceof HTMLElement&&t.matches("em, i")?(n.className="tablechart-caption",n.append(...t.childNodes),t.replaceWith(n)):t.nodeType===Node.TEXT_NODE&&(n.textContent=(t.textContent??"").trim(),t.replaceWith(n))})}),t.classList.add("chart-annotations"),t)})(s);return n.replaceWith(a),c&&a.append((t=>{const e=document.createElement("figcaption");for(const{name:r,value:s}of Array.from(t.attributes))e.setAttribute(r,s);const n=t.firstChild;n?.nodeType===Node.TEXT_NODE&&(n.textContent=(n.textContent??"").replace(kt,""),n.textContent||n.remove());const a=Array.from(t.childNodes),o=a.findIndex(t=>"BR"===t.nodeName);if(e.append(...-1===o?a:a.slice(0,o+1)),-1!==o&&o<a.length-1){const t=document.createElement("span");t.append(...a.slice(o+1)),e.append(t)}return t.remove(),e})(c)),o&&a.append(o),i&&a.append(i),nt?.log?.(`A ${o?"table":"caption"} with chart attributes was wrapped in a figure of its own`),a}))(e.filter(t=>!t.hasAttribute(Lt)));return await(async e=>{await Promise.all(e.filter(t=>t.hasAttribute("data-chart-src")).map(async e=>{const n=e.getAttribute("data-chart-src");for(const t of e.querySelectorAll("table"))t.remove();try{const t=await fetch(n);if(!t.ok)throw new Error(`${t.status} ${t.statusText}`);const a=await t.json(),o=Array.isArray(a)?a:a?.rows;if(!Array.isArray(o))throw new Error("no array of rows in it");const r=Array.isArray(a?.series)?a.series.map(String):[],s=e.querySelector(":scope > figcaption"),c=((t,e=[])=>{const n=document.createElement("table");if(e.length){const t=n.createTHead().insertRow();t.append(document.createElement("th"));for(const n of e){const e=document.createElement("th");e.textContent=n,t.append(e)}}const a=n.createTBody();for(const o of t){const t=a.insertRow();"total"===o.kind&&(t.dataset.kind="total");const e=document.createElement("th");e.textContent=String(o.label??""),t.append(e);for(const n of o.values??[o.value??null])t.insertCell().textContent=null===n?"":String(n)}return n})(o,r);s?s.after(c):e.prepend(c),nt?.log?.(`Read ${o.length} rows from "${n}"`)}catch(a){const e="file:"===window.location.protocol;console.warn(`[${t}] Could not read the chart data in "${n}": ${a.message}.`+(e?" A page opened from the file system cannot fetch files; open the page from a server instead.":""))}}))})(a),(t=>{for(const e of t){for(const n of e.querySelectorAll("tbody tr")){const t=n.cells[0];if("TD"!==t?.tagName||n.cells.length<2)continue;const e=document.createElement("th");for(const{name:n,value:a}of Array.from(t.attributes))e.setAttribute(n,a);e.append(...t.childNodes),t.replaceWith(e);for(let a=St(e);a?.matches(Ht);a=St(e))n.dataset.kind="total",a.replaceWith(...a.childNodes)}const t=Array.from(e.querySelector("thead tr:last-child")?.children??[]);for(const e of t.slice(1))for(let t=St(e);t?.matches(Ht);t=St(e))e.setAttribute("data-kind","focus"),t.replaceWith(...t.childNodes)}})(a),((e,n)=>{if(!n)return;const a=new Map;for(const o of e){let e=o.getAttribute("data-chart-keys")||null;if(!e)continue;if(a.has(e)){const n=a.get(e)+1;a.set(e,n),console.warn(`[${t}] Two charts on the page have data-chart-keys="${e}". If two charts use the same keys, they get the same translations. This one uses "${e}-${n}".`),e=`${e}-${n}`}else a.set(e,1);o.querySelectorAll("tbody th").forEach((t,a)=>{t.getAttribute(n)||t.setAttribute(n,`${e}-row${a+1}`)});const r=ot(o);r.length>1&&r.forEach((t,a)=>{t.getAttribute(n)||t.setAttribute(n,`${e}-col${a+1}`)}),nt?.log?.(`Keys for "${e}" written onto ${o.querySelectorAll("tbody th").length} rows`)}})(a,n.langattribute),a},Et=(e,n)=>{const a=nt.timed("Building",e,()=>mt(e,n));return a?(e.setAttribute(Lt,""),((e,n)=>{let a=e,o=Ut(a.figure),r=null,s=!1,u=!1;const d=async()=>{if(!n.animate)return yt(a,!0);const t=a.figure.classList.contains("is-shown");if(!s||null===r||t||u)!s&&n.replay&&t&&yt(a,!1);else{u=!0;const t=Tt()?null:(t=>{for(let e=t;e&&e!==document.body;e=e.parentElement)if("0"===getComputedStyle(e).opacity)return e;return null})(a.figure);t&&await(e=t,new Promise(t=>{const n=["animationstart","transitionrun"],a=()=>{for(const t of n)document.removeEventListener(t,o,!0);r.disconnect(),t()},o=t=>{t.target instanceof Node&&t.target.contains(e)&&a()},r=new MutationObserver(()=>{"0"!==getComputedStyle(e).opacity&&a()});for(const e of n)document.addEventListener(e,o,!0);r.observe(e,{attributes:!0,attributeFilter:["class","style"]})})),await(async(t,e)=>{if(Tt())return;await new Promise(requestAnimationFrame);const n=t.getAnimations().filter(t=>t instanceof CSSAnimation);for(let r=t.parentElement;r&&r!==document.body;r=r.parentElement)n.push(...r.getAnimations());let a=0;for(const r of n){const t=r.effect?.getComputedTiming(),n=Number(t?.activeDuration??0);if(!t||!Number.isFinite(n))continue;const o=Number(t.delay??0)+n*e;a=Math.max(a,o-Number(r.currentTime??0))}var o;a>0&&await(o=a,new Promise(t=>setTimeout(t,o)))})(a.figure,((t,e)=>{const n=Number.parseFloat(t.dataset.chartEntrance??""),a=Number.isFinite(n)?n:e.entrance;return Math.min(Math.max(a,0),1)})(a.figure,n)),u=!1,!s&&n.replay||yt(a,!0)}var e},f=()=>{const t=Ut(a.figure);if(!t||t===o)return;const e=nt.timed("Building",a.figure,()=>mt(a.figure,n,t));e&&((t=>{t.plot.remove(),t.categories[0]?.parentElement?.remove(),t.figure.querySelector(`:scope > .${c}`)?.remove(),t.controls?.remove()})(a),ct(e,a.step,!0),a=e,o=t,r=null)},b=()=>{f();const e=a.plot.clientWidth;e&&e!==r&&nt.timed("Layout",a.figure,()=>((e,n)=>{const{plot:a,svg:o,rows:r,type:s,values:c,series:u,seriesValues:d,names:f,annotations:b}=e,g=a.clientWidth;if(!g)return!1;const $=h/g,p=Number.parseFloat(e.figure.dataset.chartAspect??""),w=h*(p>0?p:s.aspect??n.aspect);a.classList.add("is-placed");for(const t of[...d.flat(),...e.totals])delete t.dataset.place;a.style.removeProperty("--tablechart-fit"),(t=>{const e=[...t].filter(t=>!!t),n=e.map(t=>({width:t.offsetWidth,height:t.offsetHeight}));e.forEach((t,e)=>L.set(t,n[e]))})([...d.flat(),...e.totals,...f,...e.categories,...b.map(t=>t.badge)]);const M=(c[0]?T(c[0]).height:0)*$,v=b[0]?.badge?T(b[0].badge).height*$:0,x=Math.max(w,$t(e.figure,$,"--tablechart-min-height","200px")??0,s.minHeight?.({labelHeight:M,nameHeight:Math.max(0,k(e.categories.map(t=>T(t).height)))*$,unit:$,rows:r.length,series:u.length,stacked:e.stacked})??0),A=e.stacked?r.map(t=>{const e=B(t,u.length);return{...t,value:e,cells:t.cells.map((t,n)=>0===n?{...t,value:e}:t)}}):r,N=(s.segments??(t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"}))))(e.stacked?A.map(t=>({...t,cells:[t.cells[0]]})):r),S={labelHeight:M,badgeHeight:v,hasAnnotations:b.length>0,unit:$,series:u.length,focused:u.some(t=>t.focus),stacked:e.stacked},H=s.headroom?.(S)??M,z=2*$+(s.footroom?.(S)??0),C=H,O=e.stacked?Math.max(k(A.map(t=>t.value)),0):Math.max(k(N.flatMap(t=>[t.from,t.to,t.value])),k(r.flatMap(t=>t.cells.slice(0,u.length).map(t=>t.value)))),U=x-C-z,E=1.02*O,F=b.find(t=>"axis-break"===t.spec.getAttribute("data-annotation"))?.spec,P=t=>{const e=Number.parseFloat(F?.getAttribute(t)??"");return Number.isFinite(e)?e:null},q=P("data-from")??P("data-at"),I=P("data-to");let j=null;if(F&&(null!==q||null!==I)){const e=q??0,n=I??E,a=null===I?e:null===q?n:(e+n)/2,o=F.getAttribute("data-size"),r=o?.match(/^\s*(\d+(?:\.\d+)?)\s*%\s*$/);null===o||r||console.warn(`[${t}] data-size="${o}" is not a percentage, such as 30%. Using the default.`);const c=Math.min(Math.max(r?Number(r[1])/100:null===I?.22:.3,.05),.8),i=N.filter(t=>("up"===t.kind||"down"===t.kind)&&Math.max(t.from,t.to)>e&&Math.min(t.from,t.to)<n);s.breakable?e<0||n<=e||n>E||0===e&&n===E?console.warn(`[${t}] A break from ${e} to ${n} does not fit a scale that runs from 0 to ${O}.`):i.length?console.warn(`[${t}] A break from ${e} to ${n} would cut a step that floats. Keep it below or above the steps.`):j={lo:e,hi:n,gap:a,share:c}:console.warn(`[${t}] This kind of chart cannot break its scale.`)}const K=j?j.gap:null,R=(j&&$t(e.figure,$,"--tablechart-break-gap",""))??13,W=x-z;let D=t=>W-t/E*U;if(j){const{lo:t,hi:e,gap:n,share:a}=j,o=U*a,r=(U-o-R)/(t+(E-e)),s=o/(e-t);D=a=>a<=t?W-a*r:a<=n?W-t*r-(a-t)*s:a<=e?W-t*r-(a-t)*s-R:W-t*r-o-R-(a-e)*r}const G=f.length?k(f.map(t=>T(t).width))*$+12*$:0,Z=e.categories[0]?.parentElement;Z&&(Z.style.paddingRight=G?G/h*100+"%":"");const J=(h-G)/r.length,Q=t=>t>=0&&t<r.length?t:null;e.rowAt=s.centre?null:"beside"===s.categories?(t,e)=>Q(Math.floor(e*$/(x/r.length))):t=>Q(Math.floor(t*$/J));const X=J/h*100,Y=100/r.length;e.rowBox="beside"===s.categories?t=>[0,t*Y,100,Y]:t=>[t*X,0,X,100],o.setAttribute("viewBox",`0 0 1000 ${x}`),o.textContent="",e.checks=[];const _={rows:r,segments:N,cx:t=>(t+.5)*J,y:D,barWidth:Math.min(J*n.barfill,pt(e.figure,$)),barMax:pt(e.figure,$),height:x,unit:$,labelHeight:M,badgeHeight:v,after:r.length,note:0,labels:"inside"===e.figure.dataset.chartLabels||"outside"!==e.figure.dataset.chartLabels&&"inside"===n.labels?"inside":"outside",closing:"up"===(e.figure.dataset.chartClosing??n.closing)?"up":"down",insideAlign:gt(e.figure),breakAt:K,squeeze:j,breakGap:R,stacked:e.stacked,shape:ft(e.figure,n),totals:e.totals,svg:o,plot:a,values:c,series:u,seriesValues:d,names:f,categories:e.categories,centre:e.centre,config:n,checks:e.checks};s.draw(_);for(const[t,i]of b.entries()){i.badge?.setAttribute("data-note",String(t+1));const n=i.series,a=t=>({...t,...t.cells[n]??t.cells[0]});i.type.draw(i.spec,i.badge,{..._,...e.stacked&&{rows:A,...e.totals.length&&{values:e.totals}},...n>0&&!e.stacked&&{rows:r.map(a),segments:N.map(t=>{const e=a(t);return"bar"===t.kind?{...e,to:e.value}:e}),values:d[n]},after:i.after,note:t+1})}(t=>{const e=t.plan;if(!e)return;const n=e.rows.length-1,a=(t,e,n,a)=>{t.style.setProperty(n,String(a)),t.style.removeProperty("--d"),null===e?t.style.removeProperty("--step"):t.style.setProperty("--step",String(e))};for(const r of t.figure.querySelectorAll("[data-row], [data-series], [data-note]")){if(r.closest("table, .tablechart-controls")||r.hasAttribute("data-from"))continue;const t=Number(r.dataset.note);if(t>0){const n=e.notes[t-1];n&&a(r,n.step,"--after",n.after);continue}const o=r.dataset.row?Number(r.dataset.row)-1:n;if(r.classList.contains("tablechart-connector")){const t=e.rows[o-1],n=e.rows[o];if(t&&n){const e=(t.step??-1)>(n.step??-1);a(r,e?t.step:n.step,"--i",e?t.slot+1:n.slot)}continue}const s=r.dataset.series?e.series[Number(r.dataset.series)-1]:void 0;s&&null!==s.step?a(r,s.step,"--i",o):e.rows[o]&&a(r,e.rows[o].step,"--i",e.rows[o].slot)}const o=t.figure.querySelector(`.${l}`);if(o){const t=Math.max(-1,...e.rows.map(t=>t.step??-1));t<0?a(o,null,"--i",0):a(o,t,"--i",e.rows.filter(e=>e.step===t).length)}st(t)})(e);const tt=e.categories[0]?.parentElement;return tt&&"beside"!==s.categories&&!s.centre&&V(tt,e.categories.filter(t=>null!==t.offsetParent),t=>({size:t.scrollWidth,room:t.clientWidth}),"--tablechart-name-fit"),y(o,b.flatMap(({badge:t})=>{if(!(t instanceof HTMLElement&&t.offsetWidth))return[];const e=t.offsetWidth*$,n=t.offsetHeight*$,a=Number.parseFloat(t.style.left)/100*h,o=Number.parseFloat(t.style.top)/100*x,r=getComputedStyle(t).borderTopLeftRadius,s=r.endsWith("%")?Number.parseFloat(r)/100:null,c=(Number.parseFloat(r)||0)*$;return[m("rect",{class:i,"data-for":"badge","data-note":t.dataset.note??"",x:a-e/2,y:o-n/2,width:e,height:n,rx:null===s?c:e*s,ry:null===s?c:n*s,style:["--after","--step"].map(e=>t.style.getPropertyValue(e)&&`${e}:${t.style.getPropertyValue(e)}`).filter(Boolean).join("; ")})]}),h,x),!0})(a,n))&&(r=e,d())};let g=!1;const $=new ResizeObserver(()=>{g||(g=!0,requestAnimationFrame(()=>{g=!1,b()}))}),p=new IntersectionObserver(t=>{for(const e of t)s=e.isIntersecting,d()},{threshold:n.threshold}),w=()=>yt(a,!0),M=()=>{r=null,b()},v={relabel:()=>wt(a,n),refresh:M};f(),b(),$.observe(a.figure),p.observe(a.figure),window.addEventListener("beforeprint",w),(t=>{zt.add(t),Ct||(Ct=new MutationObserver(()=>{for(const t of zt)t.relabel();requestAnimationFrame(()=>requestAnimationFrame(()=>{for(const t of zt)t.refresh()}))})).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"]})})(v);const x={figure:a.figure,refresh:M,next:()=>ct(a,a.step+1),previous:()=>ct(a,a.step-1),stepTo:t=>ct(a,t),get step(){return a.step},get steps(){return a.plan?.count??0},destroy(){$.disconnect(),p.disconnect(),window.removeEventListener("beforeprint",w),(t=>{zt.delete(t),!zt.size&&Ct&&(Ct.disconnect(),Ct=null)})(v),a.figure.tablechart===x&&delete a.figure.tablechart}};return a.figure.tablechart=x,x})(a,n)):null};window.Tablechart={init:async(t={},e=document)=>{const n={...f,...t};n.debug&&(nt.enabled=!0);const a=(await Bt(Array.from(e.querySelectorAll(n.selector)),n)).map(t=>Et(t,n)).filter(t=>null!==t);return nt.log(`Made ${a.length} chart(s).`),{charts:a,refresh:()=>{for(const t of a)t.refresh()},destroy:()=>{for(const t of a)t.destroy()}}},create:async(t,e={})=>{if(t.tablechart)return t.tablechart;const n={...f,...e};n.debug&&(nt.enabled=!0);const[a]=await Bt([t],n);return a?Et(a,n):null},defaultConfig:f}}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@martinomagnifico/tablechart",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Simple charts from an HTML or Markdown table: column, bar, line, area, waterfall and donut, with annotations. A chart builds when it scrolls into view.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|