@blueprint-chart/lib 1.8.3 → 2.1.0
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/dist/charts/axis/axis-service.d.ts +9 -0
- package/dist/charts/axis-options.d.ts +3 -0
- package/dist/charts/canvas/canvas.d.ts +2 -5
- package/dist/charts/category-label-line.d.ts +16 -0
- package/dist/charts/chart-helpers.d.ts +2 -3
- package/dist/charts/chart-options.d.ts +2 -0
- package/dist/charts/contrast.d.ts +4 -3
- package/dist/charts/date-parse.d.ts +6 -0
- package/dist/charts/frame/frame.d.ts +6 -0
- package/dist/charts/legend/legend-size.d.ts +13 -0
- package/dist/charts/parse-data.d.ts +2 -0
- package/dist/charts/plugins/annotations/shared.d.ts +13 -2
- package/dist/charts/plugins/arc-labels.d.ts +9 -1
- package/dist/charts/plugins/highlight.d.ts +9 -3
- package/dist/charts/scale-helpers.d.ts +15 -8
- package/dist/charts/series-helpers.d.ts +22 -1
- package/dist/charts/stack-helpers.d.ts +1 -1
- package/dist/charts/text-measure.d.ts +25 -0
- package/dist/charts/themes/index.d.ts +6 -0
- package/dist/charts/types.d.ts +10 -4
- package/dist/charts/value-label-fit.d.ts +31 -0
- package/dist/dsl/converter.d.ts +5 -0
- package/dist/dsl/quoting.d.ts +16 -0
- package/dist/dsl/types.d.ts +42 -0
- package/dist/dsl/validate.d.ts +6 -0
- package/dist/embed.js +1 -1
- package/dist/enums.d.ts +23 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +625 -302
- package/dist/lib/lib.iife.js +44 -16
- package/dist/node-backend/index.js +3410 -2223
- package/dist/render/chart-a11y.d.ts +14 -0
- package/dist/render/frame-svg.d.ts +51 -0
- package/dist/render/index.d.ts +3 -0
- package/dist/render/post-render.d.ts +2 -0
- package/dist/{render-bpc-Bgb7rsgM.js → render-bpc-BSt4wOjf.js} +4191 -2972
- package/dist/runtime/chart-css.d.ts +1 -1
- package/dist/runtime-DDhsXDn5.js +84 -0
- package/dist/runtime.js +2 -2
- package/dist/transforms/applyFilter.d.ts +2 -0
- package/dist/transforms/applyGroupBy.d.ts +2 -0
- package/dist/transforms/applyHideColumns.d.ts +2 -0
- package/dist/transforms/applyParse.d.ts +3 -0
- package/dist/transforms/applyRename.d.ts +2 -0
- package/dist/transforms/applySort.d.ts +2 -0
- package/dist/transforms/applyTranspose.d.ts +2 -0
- package/dist/transforms/index.d.ts +30 -0
- package/dist/transforms/parseOperations.d.ts +15 -0
- package/dist/transforms/shared.d.ts +4 -0
- package/dist/transforms/table.d.ts +22 -0
- package/dist/transforms/transformValue.d.ts +1 -0
- package/dist/transforms/types.d.ts +13 -0
- package/package.json +1 -1
- package/src/charts/chart.scss +29 -4
- package/dist/runtime-BnrDRLyH.js +0 -84
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as e, A as t,
|
|
2
|
-
import { t as
|
|
3
|
-
import
|
|
1
|
+
import { $ as e, A as t, At as n, B as r, Bt as i, C as a, Ct as o, D as s, Dt as c, E as l, Et as u, F as d, Ft as f, G as p, Gt as m, H as h, Ht as g, I as _, It as v, J as y, Jt as ee, K as te, Kt as ne, L as re, Lt as ie, M as ae, Mt as oe, N as se, Nt as ce, O as le, Ot as ue, P as b, Pt as de, Q as fe, R as pe, Rt as me, S as he, St as ge, T as _e, Tt as ve, U as x, Ut as ye, V as be, Vt as xe, W as Se, Wt as Ce, X as we, Xt as Te, Y as Ee, Yt as De, Z as Oe, Zt as ke, _ as Ae, _t as je, a as Me, at as Ne, b as Pe, bt as S, c as Fe, ct as Ie, d as Le, dt as Re, et as ze, f as Be, ft as Ve, g as He, gt as Ue, h as We, ht as Ge, i as Ke, it as qe, j as Je, jt as Ye, k as Xe, kt as Ze, l as Qe, lt as $e, m as et, mt as tt, n as nt, nt as rt, o as it, ot as at, p as ot, pt as st, q as ct, qt as lt, r as ut, rt as dt, s as ft, st as pt, t as mt, tt as ht, u as gt, ut as _t, v as vt, vt as yt, w as bt, wt as xt, x as St, xt as Ct, y as wt, yt as Tt, z as C, zt as Et } from "./render-bpc-BSt4wOjf.js";
|
|
2
|
+
import { t as Dt } from "./runtime-DDhsXDn5.js";
|
|
3
|
+
import w from "chroma-js";
|
|
4
4
|
//#region src/recommendations/intent.ts
|
|
5
|
-
var
|
|
5
|
+
var Ot = [
|
|
6
6
|
{
|
|
7
7
|
intent: "range",
|
|
8
8
|
pattern: /\b(range|high and low|high\/low|margin of error|confidence interval|confidence|interval|plus or minus|spread between)\b/i
|
|
@@ -28,92 +28,92 @@ var ot = [
|
|
|
28
28
|
pattern: /\b(compares?|compared|comparison|versus|vs\.?|more than|difference between|across|than)\b/i
|
|
29
29
|
}
|
|
30
30
|
];
|
|
31
|
-
function
|
|
31
|
+
function T(e) {
|
|
32
32
|
if (e === void 0 || e.trim() === "") return "none";
|
|
33
|
-
for (let t of
|
|
33
|
+
for (let t of Ot) if (t.pattern.test(e)) return t.intent;
|
|
34
34
|
return "none";
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/recommendations/decisionTable.ts
|
|
38
|
-
var
|
|
38
|
+
var E = (e, t, n) => ({
|
|
39
39
|
type: e,
|
|
40
40
|
fitness: t,
|
|
41
41
|
reason: n
|
|
42
|
-
}),
|
|
42
|
+
}), D = {
|
|
43
43
|
"1cat+1num": {
|
|
44
44
|
none: (e) => {
|
|
45
|
-
let t = [
|
|
46
|
-
return e <= 8 && (t.push(
|
|
45
|
+
let t = [E("bar-vertical", "best", "1 categorical + 1 numeric — classic bar chart"), E("bar-horizontal", "good", "Horizontal bars work well for long labels")];
|
|
46
|
+
return e <= 8 && (t.push(E("donut", "good", `${e} items — suitable for part-of-whole`)), t.push(E("pie", "alternative", "Pie chart for part-of-whole"))), t;
|
|
47
47
|
},
|
|
48
|
-
comparison: (e) =>
|
|
49
|
-
ranking: () => [
|
|
48
|
+
comparison: (e) => D["1cat+1num"].none(e),
|
|
49
|
+
ranking: () => [E("bar-horizontal", "best", "Ranked categories read best as horizontal bars"), E("bar-vertical", "good", "Vertical bars also work for ranking")],
|
|
50
50
|
"part-to-whole": (e) => e <= 5 ? [
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
E("pie", "best", `${e} slices — pie reads cleanly for very small N`),
|
|
52
|
+
E("donut", "good", "Donut for part-of-whole with a center label"),
|
|
53
|
+
E("bar-vertical", "alternative", "Bars if precise comparison matters")
|
|
54
54
|
] : e <= 8 ? [
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
] : [
|
|
59
|
-
range: () => [
|
|
55
|
+
E("donut", "best", `${e} slices — donut for part-of-whole`),
|
|
56
|
+
E("pie", "good", "Pie for part-of-whole"),
|
|
57
|
+
E("bar-vertical", "alternative", "Bars if precise comparison matters")
|
|
58
|
+
] : [E("bar-vertical", "best", `${e} categories — too many for a readable pie`), E("bar-horizontal", "good", "Horizontal bars for long labels")],
|
|
59
|
+
range: () => [E("bar-vertical", "best", "A single numeric column carries no range — plain bars read the value directly"), E("bar-horizontal", "good", "Horizontal bars work well for long labels")]
|
|
60
60
|
},
|
|
61
61
|
"1cat+Nnum": {
|
|
62
|
-
none: () => [
|
|
63
|
-
comparison: (e) =>
|
|
64
|
-
ranking: (e) =>
|
|
65
|
-
trend: () => [
|
|
62
|
+
none: () => [E("bar-multi", "best", "1 categorical + multiple numeric columns — compare groups"), E("line-multi", "good", "Can also show as a multi-line chart")],
|
|
63
|
+
comparison: (e) => D["1cat+Nnum"].none(e),
|
|
64
|
+
ranking: (e) => D["1cat+Nnum"].none(e),
|
|
65
|
+
trend: () => [E("line-multi", "best", "A trend or crossover story reads best as lines, even over categorical periods"), E("bar-multi", "alternative", "Grouped bars if per-period comparison matters more than the trend")],
|
|
66
66
|
"part-to-whole": () => [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
E("bar-stacked", "best", "Stacked bars show composition within each category"),
|
|
68
|
+
E("column-stacked", "good", "Stacked columns for the same composition"),
|
|
69
|
+
E("bar-multi", "alternative", "Grouped bars if comparison beats composition")
|
|
70
70
|
],
|
|
71
71
|
"composition-over-time": () => [
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
E("column-stacked", "best", "Stacked columns show composition across discrete periods"),
|
|
73
|
+
E("bar-stacked", "good", "Stacked bars for the same composition"),
|
|
74
|
+
E("area-stacked", "alternative", "Stacked area if the periods are continuous time")
|
|
75
75
|
],
|
|
76
|
-
range: () => [
|
|
76
|
+
range: () => [E("bar-split", "best", "Diverging bars show values around a shared baseline"), E("bar-multi", "alternative", "Grouped bars if there is no shared baseline")]
|
|
77
77
|
},
|
|
78
78
|
"1date+1num": {
|
|
79
|
-
none: () => [
|
|
79
|
+
none: () => [E("line", "best", "1 date + 1 numeric column — ideal for trend"), E("bar-vertical", "alternative", "Can also show as bars")],
|
|
80
80
|
trend: () => [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
E("line", "best", "1 date + 1 numeric column — ideal for trend"),
|
|
82
|
+
E("area", "good", "Filled area emphasizes magnitude over time"),
|
|
83
|
+
E("bar-vertical", "alternative", "Can also show as bars")
|
|
84
84
|
],
|
|
85
|
-
comparison: () => [
|
|
86
|
-
ranking: () => [
|
|
87
|
-
"part-to-whole": () => [
|
|
88
|
-
"composition-over-time": () => [
|
|
85
|
+
comparison: () => [E("bar-vertical", "best", "Bars for comparing discrete time points"), E("line", "good", "Line if the trend matters more than the comparison")],
|
|
86
|
+
ranking: () => [E("bar-vertical", "best", "Bars for ranking discrete time points"), E("line", "good", "Line for the underlying trend")],
|
|
87
|
+
"part-to-whole": () => [E("area", "best", "Filled area reads as magnitude/share over time"), E("line", "good", "Line for the underlying trend")],
|
|
88
|
+
"composition-over-time": () => [E("area", "best", "Filled area shows magnitude over time"), E("line", "good", "Line for the underlying trend")]
|
|
89
89
|
},
|
|
90
90
|
"1date+Nnum": {
|
|
91
|
-
none: () => [
|
|
92
|
-
trend: (e) =>
|
|
93
|
-
comparison: (e) =>
|
|
94
|
-
ranking: (e) =>
|
|
91
|
+
none: () => [E("line-multi", "best", "1 date + multiple numeric columns — compare trends"), E("bar-multi", "alternative", "Can also show as grouped bars")],
|
|
92
|
+
trend: (e) => D["1date+Nnum"].none(e),
|
|
93
|
+
comparison: (e) => D["1date+Nnum"].none(e),
|
|
94
|
+
ranking: (e) => D["1date+Nnum"].none(e),
|
|
95
95
|
"composition-over-time": () => [
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
E("area-stacked", "best", "Stacked area shows composition over continuous time"),
|
|
97
|
+
E("column-stacked", "good", "Stacked columns for the same composition"),
|
|
98
|
+
E("line-multi", "alternative", "Multi-line if composition is not the point")
|
|
99
99
|
],
|
|
100
|
-
"part-to-whole": () => [
|
|
100
|
+
"part-to-whole": () => [E("area-stacked", "best", "Stacked area shows share over time"), E("line-multi", "good", "Multi-line if absolute trends matter more")]
|
|
101
101
|
},
|
|
102
|
-
other: { none: () => [
|
|
102
|
+
other: { none: () => [E("bar-vertical", "good", "Default bar chart recommendation")] }
|
|
103
103
|
};
|
|
104
|
-
function
|
|
105
|
-
let r =
|
|
106
|
-
return i ? i(n) : [
|
|
104
|
+
function kt(e, t, n) {
|
|
105
|
+
let r = D[e], i = r[t] ?? r.none;
|
|
106
|
+
return i ? i(n) : [E("bar-vertical", "good", "Default bar chart recommendation")];
|
|
107
107
|
}
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region src/recommendations/shape.ts
|
|
110
|
-
function
|
|
110
|
+
function O(e, t) {
|
|
111
111
|
let n = e.filter((e) => e === "string").length, r = e.filter((e) => e === "number").length, i = e.filter((e) => e === "date").length;
|
|
112
112
|
return i === 1 && n === 0 && r >= 1 ? r === 1 ? "1date+1num" : "1date+Nnum" : n === 1 && i === 0 && r >= 1 ? r === 1 ? "1cat+1num" : "1cat+Nnum" : "other";
|
|
113
113
|
}
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region src/recommendations/types.ts
|
|
116
|
-
var
|
|
116
|
+
var At = {
|
|
117
117
|
"bar-vertical": "Vertical Bar Chart",
|
|
118
118
|
"bar-horizontal": "Horizontal Bar Chart",
|
|
119
119
|
"bar-multi": "Grouped Bar Chart",
|
|
@@ -130,21 +130,43 @@ var ct = {
|
|
|
130
130
|
};
|
|
131
131
|
//#endregion
|
|
132
132
|
//#region src/recommendations/recommend.ts
|
|
133
|
-
function
|
|
134
|
-
return e.length === 0 ? [] :
|
|
133
|
+
function jt(e, t, n) {
|
|
134
|
+
return e.length === 0 ? [] : kt(O(e, t), T(n), t).map((e) => ({
|
|
135
135
|
chartType: e.type,
|
|
136
|
-
label:
|
|
136
|
+
label: At[e.type] ?? e.type,
|
|
137
137
|
fitness: e.fitness,
|
|
138
138
|
reason: e.reason
|
|
139
139
|
}));
|
|
140
140
|
}
|
|
141
141
|
//#endregion
|
|
142
|
+
//#region src/charts/themes/index.ts
|
|
143
|
+
var Mt = [
|
|
144
|
+
{
|
|
145
|
+
name: "blueprint",
|
|
146
|
+
label: "Blueprint",
|
|
147
|
+
description: "The default Blueprint Chart theme"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "blueprint-framed",
|
|
151
|
+
label: "Blueprint Framed",
|
|
152
|
+
description: "Adds borders and a tinted footer"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "blueprint-bold",
|
|
156
|
+
label: "Blueprint Bold",
|
|
157
|
+
description: "Charts on the blueprint canvas with the full brand palette"
|
|
158
|
+
}
|
|
159
|
+
];
|
|
160
|
+
function Nt() {
|
|
161
|
+
return Mt;
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
142
164
|
//#region src/charts/colorblind.ts
|
|
143
|
-
var
|
|
165
|
+
var Pt = {
|
|
144
166
|
protanopia: "Protanopia (no red)",
|
|
145
167
|
deuteranopia: "Deuteranopia (no green)",
|
|
146
168
|
tritanopia: "Tritanopia (no blue)"
|
|
147
|
-
},
|
|
169
|
+
}, Ft = {
|
|
148
170
|
protanopia: [
|
|
149
171
|
.152286,
|
|
150
172
|
1.052583,
|
|
@@ -212,27 +234,27 @@ var ut = {
|
|
|
212
234
|
0
|
|
213
235
|
]
|
|
214
236
|
};
|
|
215
|
-
function
|
|
237
|
+
function It(e) {
|
|
216
238
|
return `bc-cvd-${e}`;
|
|
217
239
|
}
|
|
218
|
-
function
|
|
240
|
+
function Lt(e) {
|
|
219
241
|
let t = "http://www.w3.org/2000/svg", n = document.createElementNS(t, "filter");
|
|
220
|
-
n.setAttribute("id",
|
|
242
|
+
n.setAttribute("id", It(e)), n.setAttribute("color-interpolation-filters", "linearRGB");
|
|
221
243
|
let r = document.createElementNS(t, "feColorMatrix");
|
|
222
|
-
return r.setAttribute("type", "matrix"), r.setAttribute("values",
|
|
244
|
+
return r.setAttribute("type", "matrix"), r.setAttribute("values", Ft[e].join(" ")), n.appendChild(r), n;
|
|
223
245
|
}
|
|
224
|
-
function
|
|
246
|
+
function Rt(e) {
|
|
225
247
|
return e <= .04045 ? e / 12.92 : ((e + .055) / 1.055) ** 2.4;
|
|
226
248
|
}
|
|
227
|
-
function
|
|
249
|
+
function k(e) {
|
|
228
250
|
return e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055;
|
|
229
251
|
}
|
|
230
|
-
function
|
|
231
|
-
let [n, r, i] =
|
|
232
|
-
return
|
|
252
|
+
function zt(e, t) {
|
|
253
|
+
let [n, r, i] = (w.valid(e) ? w(e) : w("#000")).rgb().map((e) => Rt(e / 255)), a = Ft[t], o = k(a[0] * n + a[1] * r + a[2] * i), s = k(a[5] * n + a[6] * r + a[7] * i), c = k(a[10] * n + a[11] * r + a[12] * i), l = (e) => Math.min(255, Math.max(0, Math.round(e * 255)));
|
|
254
|
+
return w(l(o), l(s), l(c)).hex();
|
|
233
255
|
}
|
|
234
|
-
var
|
|
235
|
-
function
|
|
256
|
+
var Bt = 10;
|
|
257
|
+
function Vt(e) {
|
|
236
258
|
if (e.length < 2) return [];
|
|
237
259
|
let t = [
|
|
238
260
|
"protanopia",
|
|
@@ -240,10 +262,10 @@ function mt(e) {
|
|
|
240
262
|
"tritanopia"
|
|
241
263
|
], n = [];
|
|
242
264
|
for (let r of t) {
|
|
243
|
-
let t = e.map((e) =>
|
|
265
|
+
let t = e.map((e) => zt(e, r)), i = [];
|
|
244
266
|
for (let n = 0; n < t.length; n++) for (let r = n + 1; r < t.length; r++) {
|
|
245
|
-
let a =
|
|
246
|
-
a <
|
|
267
|
+
let a = w.deltaE(t[n], t[r]);
|
|
268
|
+
a < Bt && i.push({
|
|
247
269
|
a: e[n],
|
|
248
270
|
b: e[r],
|
|
249
271
|
deltaE: a
|
|
@@ -251,7 +273,7 @@ function mt(e) {
|
|
|
251
273
|
}
|
|
252
274
|
i.length > 0 && n.push({
|
|
253
275
|
type: r,
|
|
254
|
-
label:
|
|
276
|
+
label: Pt[r],
|
|
255
277
|
pairs: i
|
|
256
278
|
});
|
|
257
279
|
}
|
|
@@ -262,150 +284,159 @@ function mt(e) {
|
|
|
262
284
|
function A(e, t) {
|
|
263
285
|
return (e ?? []).flatMap((e) => e.split("\n").map((e) => `${t}// ${e.trim()}`));
|
|
264
286
|
}
|
|
265
|
-
function j(e) {
|
|
266
|
-
return
|
|
287
|
+
function j(e, t) {
|
|
288
|
+
return t == null ? e : t.includes("\n") ? `${e} /* ${t} */` : `${e} // ${t}`;
|
|
267
289
|
}
|
|
268
290
|
function M(e, t) {
|
|
269
|
-
|
|
270
|
-
return [...A(e.leadingComments, t), n].join("\n");
|
|
291
|
+
return [...A(e.trailingComments, `${t} `), j(`${t}}`, e.trailingComment)];
|
|
271
292
|
}
|
|
272
|
-
function
|
|
273
|
-
|
|
274
|
-
return n = e.key === "series" && e.quotedKey && !(e.values && e.values.length > 1) ? `${t}"series" = ${j(e)}` : e.values && e.values.length > 1 ? `${t}${e.key === "series" && !e.quotedKey ? e.key : `"${e.key}"`} = ${e.values.map((e) => typeof e == "number" ? `${e}` : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",")}` : `${t}${/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(e.key) ? e.key : `"${e.key}"`} = ${j(e)}`, [...A(e.leadingComments, t), n].join("\n");
|
|
293
|
+
function N(e) {
|
|
294
|
+
return typeof e.value == "number" ? e.isPercentage ? `${e.value}%` : `${e.value}` : typeof e.value == "string" && e.value.startsWith("#") ? C(e.value) : typeof e.value == "string" && /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(e.value) ? e.value : C(String(e.value));
|
|
275
295
|
}
|
|
276
|
-
function
|
|
277
|
-
|
|
278
|
-
for (let r of e.entries) n.push(ht(r, `${t} `));
|
|
279
|
-
return n.push(`${t}}`), n.join("\n");
|
|
296
|
+
function Ht(e) {
|
|
297
|
+
return /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(e) ? e : C(e);
|
|
280
298
|
}
|
|
281
299
|
function P(e, t) {
|
|
282
|
-
let n =
|
|
283
|
-
|
|
284
|
-
|
|
300
|
+
let n = j(`${t}${Ht(e.key)} = ${N(e)}`, e.trailingComment);
|
|
301
|
+
return [...A(e.leadingComments, t), n].join("\n");
|
|
302
|
+
}
|
|
303
|
+
function Ut(e, t) {
|
|
304
|
+
let n;
|
|
305
|
+
return n = e.key === "series" && e.quotedKey && !(e.values && e.values.length > 1) ? `${t}"series" = ${N(e)}` : e.values && e.values.length > 1 ? `${t}${e.key === "series" && !e.quotedKey ? e.key : C(e.key)} = ${e.values.map((e) => typeof e == "number" ? `${e}` : C(String(e))).join(",")}` : `${t}${Ht(e.key)} = ${N(e)}`, [...A(e.leadingComments, t), j(n, e.trailingComment)].join("\n");
|
|
285
306
|
}
|
|
286
307
|
function F(e, t) {
|
|
287
|
-
|
|
308
|
+
let n = [...A(e.leadingComments, t), `${t}data {`];
|
|
309
|
+
for (let r of e.entries) n.push(Ut(r, `${t} `));
|
|
310
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
288
311
|
}
|
|
289
312
|
function I(e, t) {
|
|
290
|
-
let n = [...A(e.leadingComments, t), `${t}
|
|
291
|
-
for (let
|
|
292
|
-
return
|
|
313
|
+
let n = e.fromHighlight ? "highlight" : "colorize", r = [...A(e.leadingComments, t), `${t}${n} ${C(e.target)} {`];
|
|
314
|
+
for (let n of e.properties) r.push(P(n, `${t} `));
|
|
315
|
+
return r.push(...M(e, t)), r.join("\n");
|
|
293
316
|
}
|
|
294
317
|
function L(e, t) {
|
|
295
|
-
|
|
296
|
-
|
|
318
|
+
return [...A(e.leadingComments, t), j(`${t}highlight ${C(e.target)}`, e.trailingComment)].join("\n");
|
|
319
|
+
}
|
|
320
|
+
function R(e, t) {
|
|
321
|
+
let n = [...A(e.leadingComments, t), `${t}area-fill ${C(e.from)} ${C(e.to)} {`];
|
|
322
|
+
for (let r of e.properties) n.push(P(r, `${t} `));
|
|
323
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
324
|
+
}
|
|
325
|
+
function z(e, t) {
|
|
326
|
+
let n = e.kind ?? S.Point;
|
|
327
|
+
if (n === S.Range) {
|
|
297
328
|
let n = [...A(e.leadingComments, t), `${t}range {`];
|
|
298
|
-
for (let r of e.properties) n.push(
|
|
299
|
-
return n.push(
|
|
329
|
+
for (let r of e.properties) n.push(P(r, `${t} `));
|
|
330
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
300
331
|
}
|
|
301
|
-
if (n ===
|
|
332
|
+
if (n === S.Free) {
|
|
302
333
|
let n = [...A(e.leadingComments, t), `${t}note {`];
|
|
303
|
-
for (let r of e.properties) n.push(
|
|
304
|
-
return n.push(
|
|
334
|
+
for (let r of e.properties) n.push(P(r, `${t} `));
|
|
335
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
305
336
|
}
|
|
306
|
-
let r = "target" in e ? e.target : "", i = [...A(e.leadingComments, t), `${t}annotation
|
|
307
|
-
for (let n of e.properties) i.push(
|
|
308
|
-
return i.push(
|
|
337
|
+
let r = "target" in e ? e.target : "", i = [...A(e.leadingComments, t), `${t}annotation ${C(r)} {`];
|
|
338
|
+
for (let n of e.properties) i.push(P(n, `${t} `));
|
|
339
|
+
return i.push(...M(e, t)), i.join("\n");
|
|
309
340
|
}
|
|
310
|
-
function
|
|
311
|
-
let n = [...A(e.leadingComments, t), `${t}series
|
|
312
|
-
for (let r of e.properties) n.push(
|
|
313
|
-
return n.push(
|
|
341
|
+
function B(e, t) {
|
|
342
|
+
let n = [...A(e.leadingComments, t), `${t}series ${C(e.name)} {`];
|
|
343
|
+
for (let r of e.properties) n.push(P(r, `${t} `));
|
|
344
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
314
345
|
}
|
|
315
|
-
function
|
|
316
|
-
let n = e.name == null ? `${t}scene {` : `${t}scene
|
|
317
|
-
for (let n of e.properties) r.push(
|
|
318
|
-
e.data && r.push(
|
|
319
|
-
for (let n of e.colorizes) r.push(
|
|
320
|
-
for (let n of e.highlights) r.push(
|
|
321
|
-
for (let n of e.areaFills) r.push(
|
|
322
|
-
for (let n of e.annotations) r.push(
|
|
323
|
-
for (let n of e.series) r.push(
|
|
324
|
-
for (let n of e.transforms) r.push(
|
|
325
|
-
return r.push(
|
|
346
|
+
function Wt(e, t) {
|
|
347
|
+
let n = e.name == null ? `${t}scene {` : `${t}scene ${C(e.name)} {`, r = [...A(e.leadingComments, t), n];
|
|
348
|
+
for (let n of e.properties) r.push(P(n, `${t} `));
|
|
349
|
+
e.data && r.push(F(e.data, `${t} `));
|
|
350
|
+
for (let n of e.colorizes) r.push(I(n, `${t} `));
|
|
351
|
+
for (let n of e.highlights) r.push(L(n, `${t} `));
|
|
352
|
+
for (let n of e.areaFills) r.push(R(n, `${t} `));
|
|
353
|
+
for (let n of e.annotations) r.push(z(n, `${t} `));
|
|
354
|
+
for (let n of e.series) r.push(B(n, `${t} `));
|
|
355
|
+
for (let n of e.transforms) r.push(V(n, `${t} `));
|
|
356
|
+
return r.push(...M(e, t)), r.join("\n");
|
|
326
357
|
}
|
|
327
|
-
function
|
|
358
|
+
function V(e, t) {
|
|
328
359
|
let n = [...A(e.leadingComments, t), `${t}transform ${e.transformType} {`];
|
|
329
|
-
for (let r of e.properties) n.push(
|
|
330
|
-
return n.push(
|
|
360
|
+
for (let r of e.properties) n.push(P(r, `${t} `));
|
|
361
|
+
return n.push(...M(e, t)), n.join("\n");
|
|
331
362
|
}
|
|
332
|
-
function
|
|
333
|
-
let r =
|
|
363
|
+
function Gt(e, t, n) {
|
|
364
|
+
let r = h(n).find((t) => t.key === e);
|
|
334
365
|
return !r || r.default === void 0 ? !1 : String(r.default) === String(t);
|
|
335
366
|
}
|
|
336
|
-
function
|
|
367
|
+
function Kt(e) {
|
|
337
368
|
let t = [`chart ${e.chartType} {`];
|
|
338
|
-
for (let n of e.properties) t.push(
|
|
339
|
-
e.data && t.push(
|
|
340
|
-
for (let n of e.colorizes) t.push(
|
|
341
|
-
for (let n of e.highlights) t.push(
|
|
342
|
-
for (let n of e.areaFills) t.push(
|
|
343
|
-
for (let n of e.annotations) t.push(
|
|
344
|
-
for (let n of e.series) t.push(
|
|
345
|
-
for (let n of e.scenes) t.push(
|
|
346
|
-
for (let n of e.transforms) t.push(
|
|
347
|
-
return t.push("}"), t.join("\n");
|
|
348
|
-
}
|
|
349
|
-
function
|
|
369
|
+
for (let n of e.properties) t.push(P(n, " "));
|
|
370
|
+
e.data && t.push(F(e.data, " "));
|
|
371
|
+
for (let n of e.colorizes) t.push(I(n, " "));
|
|
372
|
+
for (let n of e.highlights) t.push(L(n, " "));
|
|
373
|
+
for (let n of e.areaFills) t.push(R(n, " "));
|
|
374
|
+
for (let n of e.annotations) t.push(z(n, " "));
|
|
375
|
+
for (let n of e.series) t.push(B(n, " "));
|
|
376
|
+
for (let n of e.scenes) t.push(Wt(n, " "));
|
|
377
|
+
for (let n of e.transforms) t.push(V(n, " "));
|
|
378
|
+
return t.push(...A(e.trailingComments, " "), "}"), t.join("\n");
|
|
379
|
+
}
|
|
380
|
+
function qt(e) {
|
|
350
381
|
return new Map(e.map((e) => [e.key, e.value]));
|
|
351
382
|
}
|
|
352
|
-
function
|
|
353
|
-
let i =
|
|
383
|
+
function H(e, t, n, r) {
|
|
384
|
+
let i = h(n).find((t) => t.key === e);
|
|
354
385
|
return i ? r.has(e) ? String(r.get(e)) === String(t) : i.default !== void 0 && String(i.default) === String(t) : !1;
|
|
355
386
|
}
|
|
356
|
-
function
|
|
357
|
-
let i = [...A(e.leadingComments, t), `${t}series
|
|
358
|
-
for (let a of e.properties) (a.isPercentage || !
|
|
359
|
-
return i.push(
|
|
387
|
+
function Jt(e, t, n, r) {
|
|
388
|
+
let i = [...A(e.leadingComments, t), `${t}series ${C(e.name)} {`];
|
|
389
|
+
for (let a of e.properties) (a.isPercentage || !H(a.key, a.value, n, r)) && i.push(P(a, `${t} `));
|
|
390
|
+
return i.push(...M(e, t)), i.join("\n");
|
|
360
391
|
}
|
|
361
|
-
function
|
|
362
|
-
let i = e.properties.find((e) => e.key === "type"), a = i ? String(i.value) : n, o = e.name == null ? `${t}scene {` : `${t}scene
|
|
392
|
+
function Yt(e, t, n, r) {
|
|
393
|
+
let i = e.properties.find((e) => e.key === "type"), a = i ? String(i.value) : n, o = e.name == null ? `${t}scene {` : `${t}scene ${C(e.name)} {`, s = [...A(e.leadingComments, t), o], c = new Map(r);
|
|
363
394
|
for (let n of e.properties) {
|
|
364
395
|
if (n.key === "type") {
|
|
365
|
-
s.push(
|
|
396
|
+
s.push(P(n, `${t} `));
|
|
366
397
|
continue;
|
|
367
398
|
}
|
|
368
|
-
c.set(n.key, n.value), (n.isPercentage || !
|
|
399
|
+
c.set(n.key, n.value), (n.isPercentage || !H(n.key, n.value, a, r)) && s.push(P(n, `${t} `));
|
|
369
400
|
}
|
|
370
|
-
e.data && s.push(
|
|
371
|
-
for (let n of e.colorizes) s.push(
|
|
372
|
-
for (let n of e.highlights) s.push(
|
|
373
|
-
for (let n of e.areaFills) s.push(
|
|
374
|
-
for (let n of e.annotations) s.push(
|
|
375
|
-
for (let n of e.series) s.push(
|
|
376
|
-
for (let n of e.transforms) s.push(
|
|
377
|
-
return s.push(
|
|
378
|
-
}
|
|
379
|
-
function
|
|
401
|
+
e.data && s.push(F(e.data, `${t} `));
|
|
402
|
+
for (let n of e.colorizes) s.push(I(n, `${t} `));
|
|
403
|
+
for (let n of e.highlights) s.push(L(n, `${t} `));
|
|
404
|
+
for (let n of e.areaFills) s.push(R(n, `${t} `));
|
|
405
|
+
for (let n of e.annotations) s.push(z(n, `${t} `));
|
|
406
|
+
for (let n of e.series) s.push(Jt(n, `${t} `, a, c));
|
|
407
|
+
for (let n of e.transforms) s.push(V(n, `${t} `));
|
|
408
|
+
return s.push(...M(e, t)), s.join("\n");
|
|
409
|
+
}
|
|
410
|
+
function Xt(e) {
|
|
380
411
|
let t = [`chart ${e.chartType} {`], n = /* @__PURE__ */ new Map();
|
|
381
|
-
for (let r of e.properties) (r.isPercentage || !
|
|
382
|
-
e.data && t.push(
|
|
383
|
-
for (let n of e.colorizes) t.push(
|
|
384
|
-
for (let n of e.highlights) t.push(
|
|
385
|
-
for (let n of e.areaFills) t.push(
|
|
386
|
-
for (let n of e.annotations) t.push(
|
|
387
|
-
let r =
|
|
388
|
-
for (let n of e.series) t.push(
|
|
389
|
-
for (let n of e.scenes) t.push(
|
|
390
|
-
for (let n of e.transforms) t.push(
|
|
391
|
-
return t.push("}"), t.join("\n");
|
|
392
|
-
}
|
|
393
|
-
function
|
|
412
|
+
for (let r of e.properties) (r.isPercentage || !H(r.key, r.value, e.chartType, n)) && t.push(P(r, " "));
|
|
413
|
+
e.data && t.push(F(e.data, " "));
|
|
414
|
+
for (let n of e.colorizes) t.push(I(n, " "));
|
|
415
|
+
for (let n of e.highlights) t.push(L(n, " "));
|
|
416
|
+
for (let n of e.areaFills) t.push(R(n, " "));
|
|
417
|
+
for (let n of e.annotations) t.push(z(n, " "));
|
|
418
|
+
let r = qt(e.properties);
|
|
419
|
+
for (let n of e.series) t.push(Jt(n, " ", e.chartType, r));
|
|
420
|
+
for (let n of e.scenes) t.push(Yt(n, " ", e.chartType, r));
|
|
421
|
+
for (let n of e.transforms) t.push(V(n, " "));
|
|
422
|
+
return t.push(...A(e.trailingComments, " "), "}"), t.join("\n");
|
|
423
|
+
}
|
|
424
|
+
function Zt(e) {
|
|
394
425
|
let t = [`chart ${e.chartType} {`];
|
|
395
|
-
for (let n of e.properties)
|
|
396
|
-
e.data && t.push(
|
|
397
|
-
for (let n of e.colorizes) t.push(
|
|
398
|
-
for (let n of e.highlights) t.push(
|
|
399
|
-
for (let n of e.areaFills) t.push(
|
|
400
|
-
for (let n of e.annotations) t.push(
|
|
401
|
-
for (let n of e.series) t.push(
|
|
402
|
-
for (let n of e.scenes) t.push(
|
|
403
|
-
for (let n of e.transforms) t.push(
|
|
404
|
-
return t.push("}"), t.join("\n");
|
|
426
|
+
for (let n of e.properties) Gt(n.key, n.value, e.chartType) || t.push(P(n, " "));
|
|
427
|
+
e.data && t.push(F(e.data, " "));
|
|
428
|
+
for (let n of e.colorizes) t.push(I(n, " "));
|
|
429
|
+
for (let n of e.highlights) t.push(L(n, " "));
|
|
430
|
+
for (let n of e.areaFills) t.push(R(n, " "));
|
|
431
|
+
for (let n of e.annotations) t.push(z(n, " "));
|
|
432
|
+
for (let n of e.series) t.push(B(n, " "));
|
|
433
|
+
for (let n of e.scenes) t.push(Wt(n, " "));
|
|
434
|
+
for (let n of e.transforms) t.push(V(n, " "));
|
|
435
|
+
return t.push(...A(e.trailingComments, " "), "}"), t.join("\n");
|
|
405
436
|
}
|
|
406
437
|
//#endregion
|
|
407
438
|
//#region src/dsl/validate.ts
|
|
408
|
-
var
|
|
439
|
+
var Qt = /* @__PURE__ */ new Set([
|
|
409
440
|
"title",
|
|
410
441
|
"description",
|
|
411
442
|
"byline",
|
|
@@ -420,8 +451,33 @@ var U = /* @__PURE__ */ new Set([
|
|
|
420
451
|
"theme",
|
|
421
452
|
"heightMode",
|
|
422
453
|
"aspectRatio",
|
|
423
|
-
"fixedHeight"
|
|
424
|
-
|
|
454
|
+
"fixedHeight",
|
|
455
|
+
"sizing",
|
|
456
|
+
"fixedWidth",
|
|
457
|
+
"maxWidth",
|
|
458
|
+
"player",
|
|
459
|
+
"playerPosition"
|
|
460
|
+
]), $t = /* @__PURE__ */ new Map([
|
|
461
|
+
["theme", Nt().map((e) => e.name)],
|
|
462
|
+
["player", [
|
|
463
|
+
"buttons",
|
|
464
|
+
"progress-bar",
|
|
465
|
+
"dot-stepper",
|
|
466
|
+
"minimal-arrows",
|
|
467
|
+
"none"
|
|
468
|
+
]],
|
|
469
|
+
["playerPosition", [
|
|
470
|
+
"left",
|
|
471
|
+
"center",
|
|
472
|
+
"right"
|
|
473
|
+
]]
|
|
474
|
+
]), en = /* @__PURE__ */ new Set([
|
|
475
|
+
"lineSymbolSize",
|
|
476
|
+
"circleSize",
|
|
477
|
+
"fixedHeight",
|
|
478
|
+
"fixedWidth",
|
|
479
|
+
"maxWidth"
|
|
480
|
+
]), U = it, tn = /* @__PURE__ */ new Set([
|
|
425
481
|
"text",
|
|
426
482
|
"repeat",
|
|
427
483
|
"textColor",
|
|
@@ -439,7 +495,26 @@ var U = /* @__PURE__ */ new Set([
|
|
|
439
495
|
"circleSize",
|
|
440
496
|
"circleStyle",
|
|
441
497
|
"circleColor"
|
|
442
|
-
]),
|
|
498
|
+
]), nn = /* @__PURE__ */ new Set([
|
|
499
|
+
"color",
|
|
500
|
+
"lineWidth",
|
|
501
|
+
"dash",
|
|
502
|
+
"interpolation",
|
|
503
|
+
"labelMode",
|
|
504
|
+
"labelText",
|
|
505
|
+
"valueLabels",
|
|
506
|
+
"lineSymbols",
|
|
507
|
+
"hidden",
|
|
508
|
+
"symbolShape",
|
|
509
|
+
"symbolShowOn",
|
|
510
|
+
"symbolStyle",
|
|
511
|
+
"symbolSize",
|
|
512
|
+
"symbolOpacity"
|
|
513
|
+
]), rn = /* @__PURE__ */ new Map([
|
|
514
|
+
["symbolShape", "lineSymbolShape"],
|
|
515
|
+
["symbolShowOn", "lineSymbolShowOn"],
|
|
516
|
+
["symbolStyle", "lineSymbolStyle"]
|
|
517
|
+
]), an = /* @__PURE__ */ new Set([
|
|
443
518
|
"start",
|
|
444
519
|
"end",
|
|
445
520
|
"repeat",
|
|
@@ -451,7 +526,7 @@ var U = /* @__PURE__ */ new Set([
|
|
|
451
526
|
"direction",
|
|
452
527
|
"text",
|
|
453
528
|
"textColor"
|
|
454
|
-
]),
|
|
529
|
+
]), on = /* @__PURE__ */ new Set([
|
|
455
530
|
"text",
|
|
456
531
|
"x",
|
|
457
532
|
"y",
|
|
@@ -460,7 +535,7 @@ var U = /* @__PURE__ */ new Set([
|
|
|
460
535
|
"maxWidth",
|
|
461
536
|
"textOutline"
|
|
462
537
|
]);
|
|
463
|
-
function
|
|
538
|
+
function sn(e, t) {
|
|
464
539
|
let n = e.length, r = t.length;
|
|
465
540
|
if (n === 0) return r;
|
|
466
541
|
if (r === 0) return n;
|
|
@@ -475,22 +550,39 @@ function Tt(e, t) {
|
|
|
475
550
|
}
|
|
476
551
|
return i[r];
|
|
477
552
|
}
|
|
478
|
-
function
|
|
553
|
+
function W(e, t) {
|
|
479
554
|
let n, r = Infinity;
|
|
480
555
|
for (let i of t) {
|
|
481
|
-
let t =
|
|
556
|
+
let t = sn(e.toLowerCase(), i.toLowerCase());
|
|
482
557
|
t < r && (r = t, n = i);
|
|
483
558
|
}
|
|
484
559
|
if (n === void 0) return;
|
|
485
560
|
let i = Math.max(1, Math.min(3, Math.floor(e.length / 2)));
|
|
486
561
|
return r <= i ? n : void 0;
|
|
487
562
|
}
|
|
488
|
-
function
|
|
563
|
+
function cn(e, t) {
|
|
489
564
|
return e.find((e) => e.key === t);
|
|
490
565
|
}
|
|
491
|
-
function
|
|
566
|
+
function G(e, t, n, r, i) {
|
|
567
|
+
i.push({
|
|
568
|
+
code: "invalid-choice",
|
|
569
|
+
path: r,
|
|
570
|
+
message: `${e} must be one of: ${n.map((e) => `"${e}"`).join(", ")}; got "${t}".`,
|
|
571
|
+
suggestion: W(String(t), n.filter((e) => e !== ""))
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function ln(e, t, n) {
|
|
575
|
+
if (!en.has(e.key)) return;
|
|
576
|
+
let r = parseFloat(String(e.value));
|
|
577
|
+
Number.isFinite(r) && r < 0 && n.push({
|
|
578
|
+
code: "invalid-number",
|
|
579
|
+
path: t,
|
|
580
|
+
message: `${e.key} must not be negative; got "${e.value}".`
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
function un(e, t, n, r) {
|
|
492
584
|
let i = t.value, a = String(i).toLowerCase();
|
|
493
|
-
if (e.type ===
|
|
585
|
+
if (e.type === o.Boolean) {
|
|
494
586
|
if (e.key === "valueLabels" && a === "percent" || i === !0 || i === !1 || a === "true" || a === "false") return;
|
|
495
587
|
r.push({
|
|
496
588
|
code: "invalid-boolean",
|
|
@@ -503,88 +595,153 @@ function Dt(e, t, n, r) {
|
|
|
503
595
|
if (e.choices && e.choices.length > 0) {
|
|
504
596
|
let t = e.choices.map((e) => e.value);
|
|
505
597
|
if (t.includes(String(i)) || String(i) === "" && t.includes("")) return;
|
|
506
|
-
|
|
507
|
-
r.push({
|
|
508
|
-
code: "invalid-choice",
|
|
509
|
-
path: n,
|
|
510
|
-
message: `${e.key} must be one of: ${t.map((e) => `"${e}"`).join(", ")}; got "${i}".`,
|
|
511
|
-
suggestion: a
|
|
512
|
-
});
|
|
598
|
+
G(e.key, i, t, n, r);
|
|
513
599
|
}
|
|
514
600
|
}
|
|
515
|
-
function
|
|
516
|
-
let i =
|
|
601
|
+
function dn(e, t, n, r) {
|
|
602
|
+
let i = h(e), a = /* @__PURE__ */ new Set([...i.map((e) => e.key), ...Qt]);
|
|
517
603
|
for (let o of t) {
|
|
518
604
|
let t = `${n}.${o.key}`;
|
|
519
|
-
|
|
520
|
-
let s =
|
|
521
|
-
if (!s)
|
|
605
|
+
ln(o, t, r);
|
|
606
|
+
let s = $t.get(o.key);
|
|
607
|
+
if (s && String(o.value) !== "" && !s.includes(String(o.value)) && G(o.key, o.value, s, t, r), Qt.has(o.key)) continue;
|
|
608
|
+
let c = cn(i, o.key);
|
|
609
|
+
if (!c) {
|
|
522
610
|
r.push({
|
|
523
611
|
code: "unknown-property",
|
|
524
612
|
path: t,
|
|
525
613
|
message: `Unknown property "${o.key}" for chart type "${e}".`,
|
|
526
|
-
suggestion:
|
|
614
|
+
suggestion: W(o.key, a)
|
|
527
615
|
});
|
|
528
616
|
continue;
|
|
529
617
|
}
|
|
530
|
-
|
|
618
|
+
un(c, o, t, r);
|
|
531
619
|
}
|
|
532
620
|
}
|
|
533
|
-
function
|
|
534
|
-
return e ===
|
|
621
|
+
function fn(e) {
|
|
622
|
+
return e === S.Range ? an : e === S.Free ? on : tn;
|
|
535
623
|
}
|
|
536
|
-
function
|
|
537
|
-
return
|
|
624
|
+
function pn(e) {
|
|
625
|
+
return yt[e];
|
|
538
626
|
}
|
|
539
|
-
function
|
|
627
|
+
function mn(e, t, n) {
|
|
540
628
|
e.forEach((e, r) => {
|
|
541
|
-
let i = e.kind ??
|
|
542
|
-
for (let i of e.properties)
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
629
|
+
let i = e.kind ?? S.Point, a = fn(i), o = pn(i);
|
|
630
|
+
for (let i of e.properties) {
|
|
631
|
+
let e = `${t}.${o}[${r}].${i.key}`;
|
|
632
|
+
ln(i, e, n), !a.has(i.key) && n.push({
|
|
633
|
+
code: "unknown-annotation-property",
|
|
634
|
+
path: e,
|
|
635
|
+
message: `Unknown ${o} property "${i.key}"; it will be silently ignored.`,
|
|
636
|
+
suggestion: W(i.key, a)
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
let s = ae(e.properties).get("repeat");
|
|
640
|
+
if (s !== void 0) {
|
|
641
|
+
let e = String(s).toLowerCase();
|
|
642
|
+
e === "true" || e === "false" || typeof s == "number" && Number.isInteger(s) && s >= 1 || n.push({
|
|
643
|
+
code: "invalid-annotation-repeat",
|
|
644
|
+
message: `repeat must be false, true, or a positive integer (got ${String(s)})`,
|
|
645
|
+
path: `${t}.${o}[${r}].repeat`
|
|
646
|
+
});
|
|
647
|
+
}
|
|
554
648
|
});
|
|
555
649
|
}
|
|
556
|
-
function
|
|
650
|
+
function hn(e, t, n, r) {
|
|
651
|
+
let i = h(e);
|
|
652
|
+
t.forEach((e, t) => {
|
|
653
|
+
for (let a of e.properties) {
|
|
654
|
+
let e = `${n}.series[${t}].${a.key}`;
|
|
655
|
+
if (!nn.has(a.key)) {
|
|
656
|
+
r.push({
|
|
657
|
+
code: "unknown-series-property",
|
|
658
|
+
path: e,
|
|
659
|
+
message: `Unknown series property "${a.key}"; it will be silently ignored.`,
|
|
660
|
+
suggestion: W(a.key, nn)
|
|
661
|
+
});
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
let o = cn(i, rn.get(a.key) ?? a.key)?.choices?.map((e) => e.value);
|
|
665
|
+
o?.length && !o.includes(String(a.value)) && G(a.key, a.value, o, e, r);
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
function gn(e, t, n) {
|
|
557
670
|
e.forEach((e, r) => {
|
|
558
|
-
|
|
671
|
+
U.has(e.transformType) || n.push({
|
|
559
672
|
code: "unknown-transform",
|
|
560
673
|
path: `${t}.transform[${r}]`,
|
|
561
|
-
message: `Unknown transform type "${e.transformType}". Known types: ${[...
|
|
562
|
-
suggestion:
|
|
674
|
+
message: `Unknown transform type "${e.transformType}". Known types: ${[...U].map((e) => `"${e}"`).join(", ")}.`,
|
|
675
|
+
suggestion: W(e.transformType, U)
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
function _n(e) {
|
|
680
|
+
let t = /* @__PURE__ */ new Set();
|
|
681
|
+
for (let n of [e.data, ...e.scenes.map((e) => e.data)]) for (let e of n?.entries ?? []) {
|
|
682
|
+
if (e.key === "series" && !e.quotedKey) {
|
|
683
|
+
for (let n of e.values ?? [e.value]) t.add(String(n));
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
t.add(e.key);
|
|
687
|
+
}
|
|
688
|
+
return t;
|
|
689
|
+
}
|
|
690
|
+
function vn(e, t) {
|
|
691
|
+
let n = _n(e);
|
|
692
|
+
if (n.size === 0) return;
|
|
693
|
+
let r = [
|
|
694
|
+
{
|
|
695
|
+
basePath: "chart",
|
|
696
|
+
keyword: "highlight",
|
|
697
|
+
nodes: e.highlights
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
basePath: "chart",
|
|
701
|
+
keyword: "colorize",
|
|
702
|
+
nodes: e.colorizes
|
|
703
|
+
},
|
|
704
|
+
...e.scenes.flatMap((e, t) => [{
|
|
705
|
+
basePath: `scene[${t}]`,
|
|
706
|
+
keyword: "highlight",
|
|
707
|
+
nodes: e.highlights
|
|
708
|
+
}, {
|
|
709
|
+
basePath: `scene[${t}]`,
|
|
710
|
+
keyword: "colorize",
|
|
711
|
+
nodes: e.colorizes
|
|
712
|
+
}])
|
|
713
|
+
];
|
|
714
|
+
for (let { basePath: e, keyword: i, nodes: a } of r) a.forEach((r, a) => {
|
|
715
|
+
n.has(r.target) || t.push({
|
|
716
|
+
code: "unresolved-target",
|
|
717
|
+
path: `${e}.${i}[${a}]`,
|
|
718
|
+
message: `${i} "${r.target}" matches no category or series; it has no effect.`,
|
|
719
|
+
suggestion: W(r.target, n)
|
|
563
720
|
});
|
|
564
721
|
});
|
|
565
722
|
}
|
|
566
|
-
function
|
|
567
|
-
let t = [], n = [], r =
|
|
723
|
+
function yn(e) {
|
|
724
|
+
let t = [], n = [], r = x(), i = r.includes(e.chartType);
|
|
568
725
|
i || t.push({
|
|
569
726
|
code: "unknown-chart-type",
|
|
570
727
|
path: "chartType",
|
|
571
728
|
message: `Unknown chart type "${e.chartType}".`,
|
|
572
|
-
suggestion:
|
|
573
|
-
}), i &&
|
|
729
|
+
suggestion: W(e.chartType, r)
|
|
730
|
+
}), i && dn(e.chartType, e.properties, "chart", t), gn(e.transforms, "chart", t), mn(e.annotations, "chart", t), i && hn(e.chartType, e.series, "chart", t);
|
|
574
731
|
let a = !!e.data && e.data.entries.length > 0, o = e.scenes.some((e) => !!e.data && e.data.entries.length > 0);
|
|
575
732
|
return !a && !o && t.push({
|
|
576
733
|
code: "missing-data",
|
|
577
734
|
path: "data",
|
|
578
735
|
message: e.data && e.data.entries.length === 0 ? "Data block is empty." : "Chart has no data."
|
|
579
|
-
}), e.data &&
|
|
580
|
-
|
|
736
|
+
}), e.data && bn(e.data.entries, n), e.data && xn(e.data.entries, n), vn(e, n), e.scenes.forEach((n, r) => {
|
|
737
|
+
Sn(n, e.chartType, r, t);
|
|
581
738
|
}), {
|
|
582
739
|
valid: t.length === 0,
|
|
583
740
|
errors: t,
|
|
584
741
|
warnings: n
|
|
585
742
|
};
|
|
586
743
|
}
|
|
587
|
-
function
|
|
744
|
+
function bn(e, t) {
|
|
588
745
|
let n = e.findIndex((e) => e.key === "series" && !e.quotedKey);
|
|
589
746
|
if (n === -1) return;
|
|
590
747
|
let r = e[n], i = r.values ?? [r.value];
|
|
@@ -600,25 +757,35 @@ function jt(e, t) {
|
|
|
600
757
|
suggestion: "Move the series row to the top of the data block."
|
|
601
758
|
});
|
|
602
759
|
}
|
|
603
|
-
function
|
|
760
|
+
function xn(e, t) {
|
|
761
|
+
let n = /* @__PURE__ */ new Map();
|
|
762
|
+
for (let t of e) t.key === "series" && !t.quotedKey || n.set(t.key, (n.get(t.key) ?? 0) + 1);
|
|
763
|
+
for (let [e, r] of n) r > 1 && t.push({
|
|
764
|
+
code: "duplicate-data-key",
|
|
765
|
+
path: `data.${e}`,
|
|
766
|
+
message: `${r} rows share the label "${e}", so the chart numbers the repeats "${e} (2)" and up. Rename them, or combine the rows, if they are the same category.`,
|
|
767
|
+
suggestion: `"${e} (2)"`
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
function Sn(e, t, n, r) {
|
|
604
771
|
let i = `scene[${n}]`, a = e.properties.find((e) => e.key === "type")?.value, o = a == null ? t : String(a);
|
|
605
|
-
a != null && !
|
|
772
|
+
a != null && !x().includes(o) ? r.push({
|
|
606
773
|
code: "unknown-chart-type",
|
|
607
774
|
path: `${i}.type`,
|
|
608
775
|
message: `Unknown chart type "${o}".`,
|
|
609
|
-
suggestion:
|
|
610
|
-
}) :
|
|
776
|
+
suggestion: W(o, x())
|
|
777
|
+
}) : (dn(o, e.properties, i, r), hn(o, e.series, i, r)), gn(e.transforms, i, r), mn(e.annotations, i, r);
|
|
611
778
|
}
|
|
612
779
|
//#endregion
|
|
613
780
|
//#region src/samples/letter-frequency.bpc?raw
|
|
614
|
-
var Nt = "chart bar-vertical {\n title = \"E is the most frequent letter in English\"\n description = \"How often each letter appears in typical English text\"\n byline = \"Pierre Romera\"\n source = \"Lewand, Cryptological Mathematics\"\n sourceUrl = \"https://en.wikipedia.org/wiki/Letter_frequency\"\n note = \"Based on analysis of 40,000 words from English prose\"\n colorPalette = \"London\"\n sort = descending\n\n highlight \"E\"\n\n data {\n \"E\" = 12.70\n \"T\" = 9.06\n \"A\" = 8.17\n \"O\" = 7.51\n \"I\" = 6.97\n \"N\" = 6.75\n \"S\" = 6.33\n \"H\" = 6.09\n \"R\" = 5.99\n \"D\" = 4.25\n }\n}\n", Pt = "chart bar-vertical {\n // the headline above the chart\n title = \"China emits more CO₂ than the US and India combined\"\n description = \"Annual emissions in billion tonnes, 2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/co2-emissions\"\n\n // one row per country: \"label\" = value\n data {\n \"China\" = 12.17\n \"United States\" = 4.92\n \"India\" = 3.06\n \"Russia\" = 1.73\n \"Japan\" = 0.99\n \"Germany\" = 0.59\n }\n\n // highlight pops one bar in the accent color\n highlight \"China\"\n\n // an annotation points a callout at a single bar\n annotation \"India\" {\n text = \"Surpassed EU in 2023\"\n showLine = true\n anchorDirection = N\n textOffsetX = 66\n textOffsetY = -41\n lineStyle = curve-left\n showArrow = true\n lineTargetDistance = 26\n showCircle = false\n }\n}\n", Ft = "chart bar-horizontal {\n title = \"Mandarin has nearly twice as many native speakers as Spanish\"\n description = \"Number of native speakers worldwide, in millions\"\n source = \"Ethnologue\"\n sourceUrl = \"https://ethnologue.com\"\n byline = \"Pierre Romera\"\n sort = descending\n\n highlight \"Mandarin\"\n\n data {\n \"Mandarin\" = 988\n \"Spanish\" = 487\n \"English\" = 372\n \"Hindi\" = 347\n \"Bengali\" = 232\n \"Portuguese\" = 252\n \"Russian\" = 133\n \"Japanese\" = 124\n }\n}\n", It = "chart line-multi {\n title = \"China now buys more electric cars than the rest of the world combined\"\n description = \"Electric car sales by region, millions per year\"\n source = \"IEA Global EV Outlook 2024\"\n sourceUrl = \"https://www.iea.org/reports/global-ev-outlook-2024\"\n colorPalette = \"Maya\"\n tooltips = true\n\n data {\n series = \"China\",\"Europe\",\"United States\",\"Rest of world\"\n \"2018\" = 1.1,0.4,0.36,0.1\n \"2020\" = 1.3,1.4,0.30,0.2\n \"2021\" = 3.3,2.3,0.63,0.4\n \"2022\" = 6.0,2.7,1.0,0.7\n \"2023\" = 8.1,3.2,1.4,1.0\n }\n}\n", Lt = "chart bar-multi {\n title = \"USA tops Paris 2024 with 126 medals across all categories\"\n description = \"2024 Paris Summer Games — top six nations\"\n source = \"Olympics.com\"\n sourceUrl = \"https://olympics.com\"\n colors = \"#eeca3b, #c0c0c0, #cd7f32\"\n sort = descending\n\n data {\n series = \"Gold\",\"Silver\",\"Bronze\"\n \"USA\" = 40,44,42\n \"China\" = 40,27,24\n \"Japan\" = 20,12,13\n \"Great Britain\" = 14,22,29\n \"Australia\" = 18,19,16\n \"France\" = 16,26,22\n }\n}\n", Rt = "chart line {\n title = \"2024 was the hottest year on record\"\n description = \"Deviation from the 1951–1980 average, in °C\"\n source = \"NASA GISS\"\n sourceUrl = \"https://data.giss.nasa.gov/gistemp/\"\n tooltips = true\n crosshair = false\n lineSymbols = true\n\n data {\n \"1980\" = 0.26\n \"1985\" = 0.12\n \"1990\" = 0.45\n \"1995\" = 0.45\n \"2000\" = 0.39\n \"2005\" = 0.68\n \"2010\" = 0.73\n \"2015\" = 0.9\n \"2020\" = 1.01\n \"2024\" = 1.28\n }\n\n annotation \"2015\" {\n text = \"2015 Paris Agreement to limit global warming to 1.5°C \"\n maxWidth = 224\n showLine = true\n lineStyle = curve-right\n showArrow = true\n showCircle = true\n }\n}\n", zt = "chart line {\n title = \"Bitcoin surged past $90,000 in 2024\"\n description = \"USD, year-end closing price\"\n source = \"CoinGecko\"\n sourceUrl = \"https://www.coingecko.com\"\n colors = \"#f7931a\"\n lineSymbols = true\n lineSymbolShowOn = \"all\"\n lineSymbolShape = \"diamond\"\n verticalNumberFormat = \",.0f\"\n tooltips = true\n\n annotation \"2021\" {\n text = \"All-time high cycle\"\n textOffsetY = -12\n showArrow = true\n }\n\n data {\n \"2016\" = 963\n \"2017\" = 14156\n \"2018\" = 3742\n \"2019\" = 7194\n \"2020\" = 29080\n \"2021\" = 46306\n \"2022\" = 16547\n \"2023\" = 42258\n \"2024\" = 93429\n }\n}\n", Bt = "chart line-multi {\n title = \"The income share of the top 1% has surged since 1980\"\n description = \"Pre-tax national income captured by the top 1%, percent\"\n source = \"World Inequality Database\"\n sourceUrl = \"https://wid.world\"\n colorPalette = \"Egypt\"\n tooltips = true\n lineSymbols = true\n lineSymbolShowOn = \"all\"\n\n data {\n series = \"United States\",\"India\",\"China\",\"France\"\n \"1980\" = 10.4,7.5,6.6,7.5\n \"1990\" = 14.7,10.7,8.3,9.0\n \"2000\" = 17.3,10.5,10.5,11.3\n \"2010\" = 17.9,16.4,15.2,11.0\n \"2021\" = 19.9,22.1,15.7,12.7\n }\n\n scene \"US doubles\" {\n title = \"The US top 1% nearly doubled its income share since 1980\"\n highlight \"United States\"\n }\n\n scene \"India overtakes\" {\n title = \"India is now the most unequal of these major economies\"\n highlight \"India\"\n }\n\n scene \"France's modest rise\" {\n title = \"France's top 1% rose far less than the US or India\"\n highlight \"France\"\n }\n}\n", Vt = "chart pie {\n title = \"Asia is home to nearly 60% of the world's population\"\n description = \"Estimated share, 2024\"\n source = \"United Nations\"\n sourceUrl = \"https://population.un.org\"\n colorPalette = \"Klimt\"\n legendPosition = \"right\"\n tooltips = true\n\n data {\n \"Asia\" = 58.9\n \"Africa\" = 18.6\n \"Europe\" = 9.1\n \"Latin America\" = 8.1\n \"North America\" = 4.7\n }\n}\n", Ht = "chart bar-vertical {\n title = \"Brazil produces more coffee than the next three countries combined\"\n description = \"Million 60-kg bags, 2023/24 crop year\"\n source = \"USDA Foreign Agricultural Service\"\n sourceUrl = \"https://www.fas.usda.gov/data/coffee-world-markets-and-trade\"\n colorPalette = \"Harvey\"\n\n data {\n \"Brazil\" = 66.4\n \"Vietnam\" = 27.5\n \"Colombia\" = 12.76\n \"Ethiopia\" = 9.13\n \"Indonesia\" = 7.65\n \"Honduras\" = 5.5\n }\n\n highlight \"Brazil\"\n\n transform sort {\n column = \"value\"\n direction = descending\n }\n}\n", Ut = "chart donut {\n title = \"The richest 1% own more wealth than the entire bottom 90% combined\"\n description = \"Share of global wealth by group, 2021\"\n source = \"World Inequality Report 2022\"\n sourceUrl = \"https://wir2022.wid.world\"\n colorPalette = \"Imperator\"\n legendPosition = \"right\"\n displayAsPercentage = true\n tooltips = true\n\n data {\n \"Top 1%\" = 38\n \"Next 9%\" = 38\n \"Middle 40%\" = 22\n \"Bottom 50%\" = 2\n }\n\n scene \"Top 1% spotlight\" {\n title = \"The top 1% hold 38% of all global wealth\"\n description = \"Share of global wealth by group, 2021\"\n highlight \"Top 1%\"\n }\n\n scene \"Bottom half\" {\n title = \"The bottom half of humanity owns just 2%\"\n description = \"Share of global wealth by group, 2021\"\n highlight \"Bottom 50%\"\n }\n\n scene \"Income tells a softer story\" {\n title = \"Income is concentrated too — but less than wealth\"\n description = \"Share of global income by the same groups, 2021\"\n highlight \"Top 1%\"\n data {\n \"Top 1%\" = 19\n \"Next 9%\" = 33\n \"Middle 40%\" = 39\n \"Bottom 50%\" = 9\n }\n }\n}\n", Wt = "chart area {\n title = \"The US national debt has more than tripled since 2008\"\n description = \"Total federal debt outstanding, trillions of dollars\"\n source = \"U.S. Treasury, Fiscal Data\"\n sourceUrl = \"https://fiscaldata.treasury.gov\"\n\n annotation \"2008\" {\n text = \"Financial crisis\"\n showArrow = true\n textOffsetY = -14\n }\n\n data {\n \"2000\" = 5.7\n \"2004\" = 7.4\n \"2008\" = 10.0\n \"2012\" = 16.1\n \"2016\" = 19.6\n \"2020\" = 26.9\n \"2024\" = 35.5\n }\n}\n", Gt = "chart area-stacked {\n title = \"Renewables' share of global energy has more than doubled since 2000\"\n description = \"Share of global primary energy by source, 2000–2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/energy-mix\"\n stackPercent = true\n areaSortMode = descending\n\n data {\n series = \"Coal\",\"Oil\",\"Gas\",\"Renewables\"\n \"2000\" = 27456,43017,23994,2997\n \"2005\" = 36201,47017,27439,3510\n \"2010\" = 42016,48193,31593,4868\n \"2015\" = 43695,51294,34780,6400\n \"2020\" = 42316,49101,38704,8569\n \"2023\" = 45319,54839,40151,10325\n }\n}\n", Kt = "chart column-stacked {\n title = \"Natural gas and renewables pushed coal off the US power grid\"\n description = \"Share of US electricity generation by source, percent\"\n source = \"U.S. Energy Information Administration\"\n sourceUrl = \"https://www.eia.gov/electricity\"\n stackMode = \"percent\"\n\n data {\n series = \"Coal\",\"Natural gas\",\"Nuclear\",\"Renewables\"\n \"2010\" = 45,24,20,10\n \"2015\" = 33,33,20,13\n \"2020\" = 19,39,20,20\n \"2023\" = 16,43,19,21\n }\n}\n", qt = "chart bar-stacked {\n title = \"India has far more children than China, and a workforce nearly as large\"\n description = \"Millions of people, 2023\"\n source = \"UN Population Division\"\n sourceUrl = \"https://population.un.org\"\n colorPalette = \"London\"\n\n data {\n series = \"0-14\",\"15-64\",\"65+\"\n \"China\" = 232,988,200\n \"India\" = 354,978,97\n \"USA\" = 58,216,59\n \"Indonesia\" = 67,189,21\n \"Brazil\" = 43,148,24\n }\n}\n", Jt = "chart area-stacked {\n title = \"EU subsidies to new members surged after enlargement\"\n description = \"Agricultural subsidies to post-socialist EU members, million euros\"\n source = \"Eurostat\"\n sourceUrl = \"https://ec.europa.eu/eurostat\"\n colorPalette = \"Enara\"\n interpolation = \"linear\"\n heightMode = \"aspect-ratio\"\n aspectRatio = \"1:1\"\n\n data {\n series = \"Indirect subsidies\",\"Direct subsidies\"\n \"2000\" = 370,800\n \"2001\" = 445,896\n \"2002\" = 567,816\n \"2003\" = 641,950\n \"2004\" = 1908,2434\n \"2005\" = 2234,3509\n \"2006\" = 2576,4356\n \"2007\" = 2467,5429\n \"2008\" = 2672,6655\n \"2009\" = 2474,7195\n \"2010\" = 2117,8207\n \"2011\" = 1863,9230\n \"2012\" = 1528,9191\n \"2013\" = 1251,10252\n \"2014\" = 1132,10987\n \"2015\" = 1687,10145\n }\n\n scene \"Indirect subsidies shrank\" {\n title = \"Indirect subsidies were cut under WTO pressure\"\n description = \"Subsidies tied to specific crops fell foul of World Trade Organization rules\"\n\n highlight \"Indirect subsidies\"\n }\n\n scene \"Direct subsidies dominate\" {\n title = \"Direct per-hectare payments now dominate\"\n description = \"The larger the fields, the more money farmers receive\"\n\n highlight \"Direct subsidies\"\n }\n\n scene \"Bulgaria: subsidies explode\" {\n title = \"Bulgarian farmers received almost nothing before 2007 accession\"\n description = \"More than three-quarters of Bulgarian subsidies are direct payments — the highest share among new members\"\n\n data {\n series = \"Indirect subsidies\",\"Direct subsidies\"\n \"2000\" = 0,5\n \"2001\" = 0,33\n \"2002\" = 0,48\n \"2003\" = 0,69\n \"2004\" = 0,67\n \"2005\" = 0,87\n \"2006\" = 0,57\n \"2007\" = 59,250\n \"2008\" = 75,484\n \"2009\" = 97,415\n \"2010\" = 79,466\n \"2011\" = 94,458\n \"2012\" = 120,617\n \"2013\" = 132,852\n \"2014\" = 143,821\n \"2015\" = 213,677\n }\n\n highlight \"Direct subsidies\"\n }\n\n scene \"Bulgarian farms grew\" {\n title = \"Average farm size in Bulgaria quadrupled\"\n description = \"Average farm size in hectares\"\n type = line\n\n data {\n \"2005\" = 5\n \"2007\" = 6\n \"2010\" = 12\n \"2013\" = 18\n }\n }\n\n scene \"Production rose\" {\n title = \"Bulgarian farm production rose from 3 to 4 billion euros\"\n description = \"Total production of Bulgarian farms, million euros\"\n type = area\n\n data {\n \"2000\" = 2933\n \"2001\" = 3240\n \"2002\" = 3051\n \"2003\" = 2816\n \"2004\" = 3049\n \"2005\" = 3011\n \"2006\" = 3111\n \"2007\" = 3038\n \"2008\" = 4148\n \"2009\" = 3437\n \"2010\" = 3486\n \"2011\" = 4038\n \"2012\" = 4161\n \"2013\" = 4115\n \"2014\" = 4138\n \"2015\" = 3915\n }\n }\n\n scene \"Cash crops replaced vegetables\" {\n title = \"Cash crops replaced vegetables in Bulgaria\"\n description = \"Production of Bulgarian farms, million euros\"\n type = area-stacked\n\n data {\n series = \"Vegetables\",\"Cash crops\",\"Other production\"\n \"2000\" = 464,615,1854\n \"2001\" = 458,777,2005\n \"2002\" = 577,850,1624\n \"2003\" = 539,818,1459\n \"2004\" = 483,1103,1463\n \"2005\" = 492,994,1525\n \"2006\" = 510,1083,1518\n \"2007\" = 436,936,1666\n \"2008\" = 541,2045,1563\n \"2009\" = 243,1553,1641\n \"2010\" = 184,2173,1128\n \"2011\" = 120,2853,1065\n \"2012\" = 117,2900,1144\n \"2013\" = 139,2802,1174\n \"2014\" = 143,3082,914\n \"2015\" = 144,2986,785\n }\n\n highlight \"Cash crops\"\n }\n\n scene \"Vegetables collapsed\" {\n title = \"Vegetable production fell by a factor of three\"\n description = \"A traditional Bulgarian cultivation shrank as subsidies favoured large fields\"\n\n highlight \"Vegetables\"\n }\n\n scene \"Every vegetable declined\" {\n title = \"Bulgarian vegetable production collapsed across the board\"\n description = \"Production volume indexed to 2001 = 100\"\n type = line-multi\n lineSymbols = false\n\n data {\n series = \"Cabbages\",\"Tomatoes\",\"Watermelons\",\"Carrots\",\"Onions\",\"Garlic\",\"Strawberries\"\n \"2001\" = 100,100,100,100,100,100,100\n \"2002\" = 79,90,124,64,106,95,100\n \"2003\" = 100,157,177,142,118,98,72\n \"2004\" = 84,87,83,245,124,138,74\n \"2005\" = 50,46,62,30,40,93,42\n \"2006\" = 52,78,113,95,56,80,56\n \"2007\" = 36,49,64,74,29,30,38\n \"2008\" = 47,49,66,97,44,29,55\n \"2009\" = 28,38,74,105,23,39,55\n \"2010\" = 57,42,51,76,53,57,37\n \"2011\" = 32,38,56,86,47,43,45\n \"2012\" = 34,34,46,69,29,43,31\n \"2013\" = 33,43,53,39,36,40,24\n \"2014\" = 31,44,28,69,37,8,27\n \"2015\" = 31,45,50,57,25,18,32\n }\n }\n\n scene \"Jobs disappeared\" {\n title = \"Family farmers disappeared while salaried ag jobs held steady\"\n description = \"EU agricultural employment, thousands of full-time equivalents\"\n type = line-multi\n lineSymbols = false\n\n data {\n series = \"Salaried workers\",\"Non-salaried workers\"\n \"2000\" = 2678,12194\n \"2001\" = 2598,11586\n \"2002\" = 2658,10795\n \"2003\" = 2563,10609\n \"2004\" = 2560,9999\n \"2005\" = 2501,10047\n \"2006\" = 2499,9782\n \"2007\" = 2437,9231\n \"2008\" = 2416,8971\n \"2009\" = 2348,8672\n \"2010\" = 2335,7808\n \"2011\" = 2322,7551\n \"2012\" = 2325,7501\n \"2013\" = 2297,7425\n \"2014\" = 2366,7183\n \"2015\" = 2413,6928\n \"2016\" = 2457,6741\n }\n\n highlight \"Non-salaried workers\"\n }\n}\n", Yt = "chart bar-horizontal {\n title = \"China emits more CO₂ than the US and India combined\"\n description = \"Annual emissions in billion tonnes, 2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/co2-emissions\"\n byline = \"Pierre Romera\"\n\n data {\n \"China\" = 12.17\n \"United States\" = 4.92\n \"India\" = 3.06\n \"Russia\" = 1.73\n \"Japan\" = 0.99\n \"Germany\" = 0.59\n }\n\n scene \"China spotlight\" {\n title = \"China alone emits more than the US and India together\"\n highlight \"China\"\n }\n\n scene \"India rising\" {\n title = \"India passed the EU to become the third-largest emitter\"\n highlight \"India\"\n }\n\n scene \"Japan declining\" {\n title = \"Japan's emissions have fallen since their 2013 peak\"\n highlight \"Japan\"\n }\n\n scene \"Per capita reframe\" {\n title = \"Per person, Gulf states dwarf the biggest emitters\"\n description = \"CO₂ emissions per capita, tonnes per person, 2023\"\n highlight \"Qatar\"\n data {\n \"Qatar\" = 40.13\n \"United Arab Emirates\" = 19.77\n \"United States\" = 14.32\n \"China\" = 8.56\n \"India\" = 2.13\n }\n }\n}\n", Xt = "chart bar-split {\n title = \"CDU/CSU led German polls at 29 % ahead of the 2021 election\"\n description = \"How Germany would vote in the September 2021 federal election, according to polling in the previous June\"\n source = \"FG Wahlen\"\n sourceUrl = \"https://www.forschungsgruppe.de\"\n note = \"Margin of error at 10%: +/- 2 percentage points; at 40%: +/- 3 percentage points\"\n\n data {\n series = \"Poll\",\"High\",\"Low\"\n \"CDU/CSU\" = 29,32,27\n \"Greens\" = 22,25,20\n \"SPD\" = 14,16,12\n \"AfD\" = 10,12,8\n \"FDP\" = 10,12,8\n \"Left\" = 7,9,5\n }\n}\n", Zt = "chart bar-grouped {\n title = \"Asia Pacific holds more renewable capacity than all other regions combined\"\n description = \"Installed capacity in gigawatts (GW), 2023\"\n source = \"IRENA\"\n sourceUrl = \"https://www.irena.org/Publications/2024/Mar/Renewable-capacity-statistics-2024\"\n colorPalette = \"Folklore\"\n\n data {\n series = \"Solar\",\"Wind\",\"Hydro\"\n \"Asia Pacific\" = 870,520,650\n \"Europe\" = 290,260,230\n \"North America\" = 150,170,200\n \"Latin America\" = 50,40,190\n \"Africa\" = 12,9,40\n }\n}\n";
|
|
781
|
+
var Cn = "chart bar-vertical {\n title = \"E is the most frequent letter in English\"\n description = \"How often each letter appears in typical English text\"\n byline = \"Pierre Romera\"\n source = \"Lewand, Cryptological Mathematics\"\n sourceUrl = \"https://en.wikipedia.org/wiki/Letter_frequency\"\n note = \"Based on analysis of 40,000 words from English prose\"\n colorPalette = \"London\"\n sort = descending\n\n highlight \"E\"\n\n data {\n \"E\" = 12.70\n \"T\" = 9.06\n \"A\" = 8.17\n \"O\" = 7.51\n \"I\" = 6.97\n \"N\" = 6.75\n \"S\" = 6.33\n \"H\" = 6.09\n \"R\" = 5.99\n \"D\" = 4.25\n }\n}\n", wn = "chart bar-vertical {\n // the headline above the chart\n title = \"China emits more CO₂ than the US and India combined\"\n description = \"Annual emissions in billion tonnes, 2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/co2-emissions\"\n\n // one row per country: \"label\" = value\n data {\n \"China\" = 12.17\n \"United States\" = 4.92\n \"India\" = 3.06\n \"Russia\" = 1.73\n \"Japan\" = 0.99\n \"Germany\" = 0.59\n }\n\n // highlight pops one bar in the accent color\n highlight \"China\"\n\n // an annotation points a callout at a single bar\n annotation \"India\" {\n text = \"Surpassed EU in 2023\"\n showLine = true\n anchorDirection = N\n textOffsetX = 66\n textOffsetY = -41\n lineStyle = curve-left\n showArrow = true\n lineTargetDistance = 26\n showCircle = false\n }\n}\n", Tn = "chart bar-horizontal {\n title = \"Mandarin has nearly twice as many native speakers as Spanish\"\n description = \"Number of native speakers worldwide, in millions\"\n source = \"Ethnologue\"\n sourceUrl = \"https://ethnologue.com\"\n byline = \"Pierre Romera\"\n sort = descending\n\n highlight \"Mandarin\"\n\n data {\n \"Mandarin\" = 988\n \"Spanish\" = 487\n \"English\" = 372\n \"Hindi\" = 347\n \"Bengali\" = 232\n \"Portuguese\" = 252\n \"Russian\" = 133\n \"Japanese\" = 124\n }\n}\n", En = "chart line-multi {\n title = \"China now buys more electric cars than the rest of the world combined\"\n description = \"Electric car sales by region, millions per year\"\n source = \"IEA Global EV Outlook 2024\"\n sourceUrl = \"https://www.iea.org/reports/global-ev-outlook-2024\"\n colorPalette = \"Maya\"\n tooltips = true\n\n data {\n series = \"China\",\"Europe\",\"United States\",\"Rest of world\"\n \"2018\" = 1.1,0.4,0.36,0.1\n \"2020\" = 1.3,1.4,0.30,0.2\n \"2021\" = 3.3,2.3,0.63,0.4\n \"2022\" = 6.0,2.7,1.0,0.7\n \"2023\" = 8.1,3.2,1.4,1.0\n }\n}\n", Dn = "chart bar-multi {\n title = \"USA tops Paris 2024 with 126 medals across all categories\"\n description = \"2024 Paris Summer Games — top six nations\"\n source = \"Olympics.com\"\n sourceUrl = \"https://olympics.com\"\n colors = \"#eeca3b, #c0c0c0, #cd7f32\"\n sort = descending\n\n data {\n series = \"Gold\",\"Silver\",\"Bronze\"\n \"USA\" = 40,44,42\n \"China\" = 40,27,24\n \"Japan\" = 20,12,13\n \"Great Britain\" = 14,22,29\n \"Australia\" = 18,19,16\n \"France\" = 16,26,22\n }\n}\n", On = "chart line {\n title = \"2024 was the hottest year on record\"\n description = \"Deviation from the 1951–1980 average, in °C\"\n source = \"NASA GISS\"\n sourceUrl = \"https://data.giss.nasa.gov/gistemp/\"\n tooltips = true\n crosshair = false\n lineSymbols = true\n\n data {\n \"1980\" = 0.26\n \"1985\" = 0.12\n \"1990\" = 0.45\n \"1995\" = 0.45\n \"2000\" = 0.39\n \"2005\" = 0.68\n \"2010\" = 0.73\n \"2015\" = 0.9\n \"2020\" = 1.01\n \"2024\" = 1.28\n }\n\n annotation \"2015\" {\n text = \"2015 Paris Agreement to limit global warming to 1.5°C \"\n maxWidth = 224\n showLine = true\n lineStyle = curve-right\n showArrow = true\n showCircle = true\n }\n}\n", kn = "chart line {\n title = \"Bitcoin surged past $90,000 in 2024\"\n description = \"USD, year-end closing price\"\n source = \"CoinGecko\"\n sourceUrl = \"https://www.coingecko.com\"\n colors = \"#f7931a\"\n lineSymbols = true\n lineSymbolShowOn = \"all\"\n lineSymbolShape = \"diamond\"\n verticalNumberFormat = \",.0f\"\n tooltips = true\n\n annotation \"2021\" {\n text = \"All-time high cycle\"\n textOffsetY = -12\n showArrow = true\n }\n\n data {\n \"2016\" = 963\n \"2017\" = 14156\n \"2018\" = 3742\n \"2019\" = 7194\n \"2020\" = 29080\n \"2021\" = 46306\n \"2022\" = 16547\n \"2023\" = 42258\n \"2024\" = 93429\n }\n}\n", An = "chart line-multi {\n title = \"The income share of the top 1% has surged since 1980\"\n description = \"Pre-tax national income captured by the top 1%, percent\"\n source = \"World Inequality Database\"\n sourceUrl = \"https://wid.world\"\n colorPalette = \"Egypt\"\n tooltips = true\n lineSymbols = true\n lineSymbolShowOn = \"all\"\n\n data {\n series = \"United States\",\"India\",\"China\",\"France\"\n \"1980\" = 10.4,7.5,6.6,7.5\n \"1990\" = 14.7,10.7,8.3,9.0\n \"2000\" = 17.3,10.5,10.5,11.3\n \"2010\" = 17.9,16.4,15.2,11.0\n \"2021\" = 19.9,22.1,15.7,12.7\n }\n\n scene \"US doubles\" {\n title = \"The US top 1% nearly doubled its income share since 1980\"\n highlight \"United States\"\n }\n\n scene \"India overtakes\" {\n title = \"India is now the most unequal of these major economies\"\n highlight \"India\"\n }\n\n scene \"France's modest rise\" {\n title = \"France's top 1% rose far less than the US or India\"\n highlight \"France\"\n }\n}\n", jn = "chart pie {\n title = \"Asia is home to nearly 60% of the world's population\"\n description = \"Estimated share, 2024\"\n source = \"United Nations\"\n sourceUrl = \"https://population.un.org\"\n colorPalette = \"Klimt\"\n legendPosition = \"right\"\n tooltips = true\n\n data {\n \"Asia\" = 58.9\n \"Africa\" = 18.6\n \"Europe\" = 9.1\n \"Latin America\" = 8.1\n \"North America\" = 4.7\n }\n}\n", Mn = "chart bar-vertical {\n title = \"Brazil produces more coffee than the next three countries combined\"\n description = \"Million 60-kg bags, 2023/24 crop year\"\n source = \"USDA Foreign Agricultural Service\"\n sourceUrl = \"https://www.fas.usda.gov/data/coffee-world-markets-and-trade\"\n colorPalette = \"Harvey\"\n\n data {\n \"Brazil\" = 66.4\n \"Vietnam\" = 27.5\n \"Colombia\" = 12.76\n \"Ethiopia\" = 9.13\n \"Indonesia\" = 7.65\n \"Honduras\" = 5.5\n }\n\n highlight \"Brazil\"\n\n transform sort {\n column = \"value\"\n direction = descending\n }\n}\n", Nn = "chart donut {\n title = \"The richest 1% own more wealth than the entire bottom 90% combined\"\n description = \"Share of global wealth by group, 2021\"\n source = \"World Inequality Report 2022\"\n sourceUrl = \"https://wir2022.wid.world\"\n colorPalette = \"Imperator\"\n legendPosition = \"right\"\n displayAsPercentage = true\n tooltips = true\n\n data {\n \"Top 1%\" = 38\n \"Next 9%\" = 38\n \"Middle 40%\" = 22\n \"Bottom 50%\" = 2\n }\n\n scene \"Top 1% spotlight\" {\n title = \"The top 1% hold 38% of all global wealth\"\n description = \"Share of global wealth by group, 2021\"\n highlight \"Top 1%\"\n }\n\n scene \"Bottom half\" {\n title = \"The bottom half of humanity owns just 2%\"\n description = \"Share of global wealth by group, 2021\"\n highlight \"Bottom 50%\"\n }\n\n scene \"Income tells a softer story\" {\n title = \"Income is concentrated too — but less than wealth\"\n description = \"Share of global income by the same groups, 2021\"\n highlight \"Top 1%\"\n data {\n \"Top 1%\" = 19\n \"Next 9%\" = 33\n \"Middle 40%\" = 39\n \"Bottom 50%\" = 9\n }\n }\n}\n", Pn = "chart area {\n title = \"The US national debt has more than tripled since 2008\"\n description = \"Total federal debt outstanding, trillions of dollars\"\n source = \"U.S. Treasury, Fiscal Data\"\n sourceUrl = \"https://fiscaldata.treasury.gov\"\n\n annotation \"2008\" {\n text = \"Financial crisis\"\n showArrow = true\n textOffsetY = -14\n }\n\n data {\n \"2000\" = 5.7\n \"2004\" = 7.4\n \"2008\" = 10.0\n \"2012\" = 16.1\n \"2016\" = 19.6\n \"2020\" = 26.9\n \"2024\" = 35.5\n }\n}\n", Fn = "chart area-stacked {\n title = \"Renewables' share of global energy has more than doubled since 2000\"\n description = \"Share of global primary energy by source, 2000–2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/energy-mix\"\n stackPercent = true\n areaSortMode = descending\n\n data {\n series = \"Coal\",\"Oil\",\"Gas\",\"Renewables\"\n \"2000\" = 27456,43017,23994,2997\n \"2005\" = 36201,47017,27439,3510\n \"2010\" = 42016,48193,31593,4868\n \"2015\" = 43695,51294,34780,6400\n \"2020\" = 42316,49101,38704,8569\n \"2023\" = 45319,54839,40151,10325\n }\n}\n", In = "chart column-stacked {\n title = \"Natural gas and renewables pushed coal off the US power grid\"\n description = \"Share of US electricity generation by source, percent\"\n source = \"U.S. Energy Information Administration\"\n sourceUrl = \"https://www.eia.gov/electricity\"\n stackMode = \"percent\"\n\n data {\n series = \"Coal\",\"Natural gas\",\"Nuclear\",\"Renewables\"\n \"2010\" = 45,24,20,10\n \"2015\" = 33,33,20,13\n \"2020\" = 19,39,20,20\n \"2023\" = 16,43,19,21\n }\n}\n", Ln = "chart bar-stacked {\n title = \"India has far more children than China, and a workforce nearly as large\"\n description = \"Millions of people, 2023\"\n source = \"UN Population Division\"\n sourceUrl = \"https://population.un.org\"\n colorPalette = \"London\"\n\n data {\n series = \"0-14\",\"15-64\",\"65+\"\n \"China\" = 232,988,200\n \"India\" = 354,978,97\n \"USA\" = 58,216,59\n \"Indonesia\" = 67,189,21\n \"Brazil\" = 43,148,24\n }\n}\n", Rn = "chart area-stacked {\n title = \"EU subsidies to new members surged after enlargement\"\n description = \"Agricultural subsidies to post-socialist EU members, million euros\"\n source = \"Eurostat\"\n sourceUrl = \"https://ec.europa.eu/eurostat\"\n colorPalette = \"Enara\"\n interpolation = \"linear\"\n heightMode = \"aspect-ratio\"\n aspectRatio = \"1:1\"\n\n data {\n series = \"Indirect subsidies\",\"Direct subsidies\"\n \"2000\" = 370,800\n \"2001\" = 445,896\n \"2002\" = 567,816\n \"2003\" = 641,950\n \"2004\" = 1908,2434\n \"2005\" = 2234,3509\n \"2006\" = 2576,4356\n \"2007\" = 2467,5429\n \"2008\" = 2672,6655\n \"2009\" = 2474,7195\n \"2010\" = 2117,8207\n \"2011\" = 1863,9230\n \"2012\" = 1528,9191\n \"2013\" = 1251,10252\n \"2014\" = 1132,10987\n \"2015\" = 1687,10145\n }\n\n scene \"Indirect subsidies shrank\" {\n title = \"Indirect subsidies were cut under WTO pressure\"\n description = \"Subsidies tied to specific crops fell foul of World Trade Organization rules\"\n\n highlight \"Indirect subsidies\"\n }\n\n scene \"Direct subsidies dominate\" {\n title = \"Direct per-hectare payments now dominate\"\n description = \"The larger the fields, the more money farmers receive\"\n\n highlight \"Direct subsidies\"\n }\n\n scene \"Bulgaria: subsidies explode\" {\n title = \"Bulgarian farmers received almost nothing before 2007 accession\"\n description = \"More than three-quarters of Bulgarian subsidies are direct payments — the highest share among new members\"\n\n data {\n series = \"Indirect subsidies\",\"Direct subsidies\"\n \"2000\" = 0,5\n \"2001\" = 0,33\n \"2002\" = 0,48\n \"2003\" = 0,69\n \"2004\" = 0,67\n \"2005\" = 0,87\n \"2006\" = 0,57\n \"2007\" = 59,250\n \"2008\" = 75,484\n \"2009\" = 97,415\n \"2010\" = 79,466\n \"2011\" = 94,458\n \"2012\" = 120,617\n \"2013\" = 132,852\n \"2014\" = 143,821\n \"2015\" = 213,677\n }\n\n highlight \"Direct subsidies\"\n }\n\n scene \"Bulgarian farms grew\" {\n title = \"Average farm size in Bulgaria quadrupled\"\n description = \"Average farm size in hectares\"\n type = line\n\n data {\n \"2005\" = 5\n \"2007\" = 6\n \"2010\" = 12\n \"2013\" = 18\n }\n }\n\n scene \"Production rose\" {\n title = \"Bulgarian farm production rose from 3 to 4 billion euros\"\n description = \"Total production of Bulgarian farms, million euros\"\n type = area\n\n data {\n \"2000\" = 2933\n \"2001\" = 3240\n \"2002\" = 3051\n \"2003\" = 2816\n \"2004\" = 3049\n \"2005\" = 3011\n \"2006\" = 3111\n \"2007\" = 3038\n \"2008\" = 4148\n \"2009\" = 3437\n \"2010\" = 3486\n \"2011\" = 4038\n \"2012\" = 4161\n \"2013\" = 4115\n \"2014\" = 4138\n \"2015\" = 3915\n }\n }\n\n scene \"Cash crops replaced vegetables\" {\n title = \"Cash crops replaced vegetables in Bulgaria\"\n description = \"Production of Bulgarian farms, million euros\"\n type = area-stacked\n\n data {\n series = \"Vegetables\",\"Cash crops\",\"Other production\"\n \"2000\" = 464,615,1854\n \"2001\" = 458,777,2005\n \"2002\" = 577,850,1624\n \"2003\" = 539,818,1459\n \"2004\" = 483,1103,1463\n \"2005\" = 492,994,1525\n \"2006\" = 510,1083,1518\n \"2007\" = 436,936,1666\n \"2008\" = 541,2045,1563\n \"2009\" = 243,1553,1641\n \"2010\" = 184,2173,1128\n \"2011\" = 120,2853,1065\n \"2012\" = 117,2900,1144\n \"2013\" = 139,2802,1174\n \"2014\" = 143,3082,914\n \"2015\" = 144,2986,785\n }\n\n highlight \"Cash crops\"\n }\n\n scene \"Vegetables collapsed\" {\n title = \"Vegetable production fell by a factor of three\"\n description = \"A traditional Bulgarian cultivation shrank as subsidies favoured large fields\"\n\n highlight \"Vegetables\"\n }\n\n scene \"Every vegetable declined\" {\n title = \"Bulgarian vegetable production collapsed across the board\"\n description = \"Production volume indexed to 2001 = 100\"\n type = line-multi\n lineSymbols = false\n\n data {\n series = \"Cabbages\",\"Tomatoes\",\"Watermelons\",\"Carrots\",\"Onions\",\"Garlic\",\"Strawberries\"\n \"2001\" = 100,100,100,100,100,100,100\n \"2002\" = 79,90,124,64,106,95,100\n \"2003\" = 100,157,177,142,118,98,72\n \"2004\" = 84,87,83,245,124,138,74\n \"2005\" = 50,46,62,30,40,93,42\n \"2006\" = 52,78,113,95,56,80,56\n \"2007\" = 36,49,64,74,29,30,38\n \"2008\" = 47,49,66,97,44,29,55\n \"2009\" = 28,38,74,105,23,39,55\n \"2010\" = 57,42,51,76,53,57,37\n \"2011\" = 32,38,56,86,47,43,45\n \"2012\" = 34,34,46,69,29,43,31\n \"2013\" = 33,43,53,39,36,40,24\n \"2014\" = 31,44,28,69,37,8,27\n \"2015\" = 31,45,50,57,25,18,32\n }\n }\n\n scene \"Jobs disappeared\" {\n title = \"Family farmers disappeared while salaried ag jobs held steady\"\n description = \"EU agricultural employment, thousands of full-time equivalents\"\n type = line-multi\n lineSymbols = false\n\n data {\n series = \"Salaried workers\",\"Non-salaried workers\"\n \"2000\" = 2678,12194\n \"2001\" = 2598,11586\n \"2002\" = 2658,10795\n \"2003\" = 2563,10609\n \"2004\" = 2560,9999\n \"2005\" = 2501,10047\n \"2006\" = 2499,9782\n \"2007\" = 2437,9231\n \"2008\" = 2416,8971\n \"2009\" = 2348,8672\n \"2010\" = 2335,7808\n \"2011\" = 2322,7551\n \"2012\" = 2325,7501\n \"2013\" = 2297,7425\n \"2014\" = 2366,7183\n \"2015\" = 2413,6928\n \"2016\" = 2457,6741\n }\n\n highlight \"Non-salaried workers\"\n }\n}\n", zn = "chart bar-horizontal {\n title = \"China emits more CO₂ than the US and India combined\"\n description = \"Annual emissions in billion tonnes, 2023\"\n source = \"Our World in Data\"\n sourceUrl = \"https://ourworldindata.org/co2-emissions\"\n byline = \"Pierre Romera\"\n\n data {\n \"China\" = 12.17\n \"United States\" = 4.92\n \"India\" = 3.06\n \"Russia\" = 1.73\n \"Japan\" = 0.99\n \"Germany\" = 0.59\n }\n\n scene \"China spotlight\" {\n title = \"China alone emits more than the US and India together\"\n highlight \"China\"\n }\n\n scene \"India rising\" {\n title = \"India passed the EU to become the third-largest emitter\"\n highlight \"India\"\n }\n\n scene \"Japan declining\" {\n title = \"Japan's emissions have fallen since their 2013 peak\"\n highlight \"Japan\"\n }\n\n scene \"Per capita reframe\" {\n title = \"Per person, Gulf states dwarf the biggest emitters\"\n description = \"CO₂ emissions per capita, tonnes per person, 2023\"\n highlight \"Qatar\"\n data {\n \"Qatar\" = 40.13\n \"United Arab Emirates\" = 19.77\n \"United States\" = 14.32\n \"China\" = 8.56\n \"India\" = 2.13\n }\n }\n}\n", Bn = "chart bar-split {\n title = \"CDU/CSU led German polls at 29 % ahead of the 2021 election\"\n description = \"How Germany would vote in the September 2021 federal election, according to polling in the previous June\"\n source = \"FG Wahlen\"\n sourceUrl = \"https://www.forschungsgruppe.de\"\n note = \"Margin of error at 10%: +/- 2 percentage points; at 40%: +/- 3 percentage points\"\n\n data {\n series = \"Poll\",\"High\",\"Low\"\n \"CDU/CSU\" = 29,32,27\n \"Greens\" = 22,25,20\n \"SPD\" = 14,16,12\n \"AfD\" = 10,12,8\n \"FDP\" = 10,12,8\n \"Left\" = 7,9,5\n }\n}\n", Vn = "chart bar-grouped {\n title = \"Asia Pacific holds more renewable capacity than all other regions combined\"\n description = \"Installed capacity in gigawatts (GW), 2023\"\n source = \"IRENA\"\n sourceUrl = \"https://www.irena.org/Publications/2024/Mar/Renewable-capacity-statistics-2024\"\n colorPalette = \"Folklore\"\n\n data {\n series = \"Solar\",\"Wind\",\"Hydro\"\n \"Asia Pacific\" = 870,520,650\n \"Europe\" = 290,260,230\n \"North America\" = 150,170,200\n \"Latin America\" = 50,40,190\n \"Africa\" = 12,9,40\n }\n}\n";
|
|
615
782
|
//#endregion
|
|
616
783
|
//#region src/samples.ts
|
|
617
|
-
function
|
|
784
|
+
function Hn(e, t) {
|
|
618
785
|
let n = e.properties.find((e) => e.key === t);
|
|
619
786
|
return n ? String(n.value) : "";
|
|
620
787
|
}
|
|
621
|
-
function
|
|
788
|
+
function Un(e) {
|
|
622
789
|
if (!e.data) return "";
|
|
623
790
|
let t = e.data.entries, n = t.find((e) => e.key === "series" && !e.quotedKey);
|
|
624
791
|
return n ? [["category", ...String(n.value).split(",")].join(" "), ...t.filter((e) => !(e.key === "series" && !e.quotedKey)).map((e) => {
|
|
@@ -626,70 +793,70 @@ function Qt(e) {
|
|
|
626
793
|
return [e.key, ...t].join(" ");
|
|
627
794
|
})].join("\n") : [["label", "value"].join(" "), ...t.map((e) => [e.key, String(e.value)].join(" "))].join("\n");
|
|
628
795
|
}
|
|
629
|
-
function
|
|
796
|
+
function Wn(e) {
|
|
630
797
|
if (!e.data) return "";
|
|
631
798
|
let t = e.data.entries, n = t.find((e) => e.key === "series" && !e.quotedKey);
|
|
632
799
|
return n ? [`series = "${String(n.value)}"`, ...t.filter((e) => !(e.key === "series" && !e.quotedKey)).map((e) => `"${e.key}" = "${String(e.value)}"`)].join("\n") : t.map((e) => `"${e.key}" = ${String(e.value)}`).join("\n");
|
|
633
800
|
}
|
|
634
|
-
function
|
|
635
|
-
let n =
|
|
801
|
+
function K(e, t) {
|
|
802
|
+
let n = b(t);
|
|
636
803
|
return {
|
|
637
804
|
id: e,
|
|
638
|
-
title:
|
|
639
|
-
description:
|
|
805
|
+
title: Hn(n, "title"),
|
|
806
|
+
description: Hn(n, "description"),
|
|
640
807
|
chartType: n.chartType,
|
|
641
|
-
tsvData:
|
|
642
|
-
serializedData:
|
|
808
|
+
tsvData: Un(n),
|
|
809
|
+
serializedData: Wn(n),
|
|
643
810
|
dsl: t
|
|
644
811
|
};
|
|
645
812
|
}
|
|
646
|
-
var
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
],
|
|
813
|
+
var Gn = [
|
|
814
|
+
K("letter-frequency", Cn),
|
|
815
|
+
K("co2-emissions", wn),
|
|
816
|
+
K("coffee-production", Mn),
|
|
817
|
+
K("spoken-languages", Tn),
|
|
818
|
+
K("quarterly-revenue", En),
|
|
819
|
+
K("medal-count", Dn),
|
|
820
|
+
K("temperature-anomaly", On),
|
|
821
|
+
K("bitcoin-price", kn),
|
|
822
|
+
K("unemployment-rates", An),
|
|
823
|
+
K("browser-market", Nn),
|
|
824
|
+
K("world-population", jn),
|
|
825
|
+
K("stock-price-area", Pn),
|
|
826
|
+
K("energy-mix-stacked-area", Fn),
|
|
827
|
+
K("quarterly-stacked-columns", In),
|
|
828
|
+
K("population-stacked-bar", Ln),
|
|
829
|
+
K("election-polls", Bn),
|
|
830
|
+
K("renewable-capacity", Vn),
|
|
831
|
+
K("farm-compass", Rn),
|
|
832
|
+
K("co2-emissions-story", zn)
|
|
833
|
+
], Kn = class extends Error {
|
|
667
834
|
constructor(e, t) {
|
|
668
835
|
super(e, t), this.name = "ChartParseError";
|
|
669
836
|
}
|
|
670
|
-
},
|
|
837
|
+
}, qn = class extends Error {
|
|
671
838
|
constructor(e = "PNG export is only available in Node. Use toSvg() in the browser.") {
|
|
672
839
|
super(e), this.name = "PngBrowserUnsupportedError";
|
|
673
840
|
}
|
|
674
|
-
},
|
|
841
|
+
}, Jn = class extends Error {
|
|
675
842
|
constructor(e) {
|
|
676
843
|
super(e), this.name = "MissingNodeRenderDepsError";
|
|
677
844
|
}
|
|
678
845
|
};
|
|
679
846
|
//#endregion
|
|
680
847
|
//#region src/render/backends/dom-backend.ts
|
|
681
|
-
function
|
|
848
|
+
function Yn() {
|
|
682
849
|
return {
|
|
683
850
|
kind: "dom",
|
|
684
851
|
createContainer(e, t) {
|
|
685
852
|
let n = document.createElement("div");
|
|
686
|
-
return n.style.cssText = `position:absolute;left:-99999px;top:0;width:${e}px;height:${t}px`, document.body.appendChild(n), {
|
|
853
|
+
return n.style.cssText = `position:absolute;left:-99999px;top:0;width:${e}px;height:${t}px`, n.dataset.bcContentWidth = String(e), n.dataset.bcContentHeight = String(t), document.body.appendChild(n), {
|
|
687
854
|
container: n,
|
|
688
855
|
cleanup: () => n.remove()
|
|
689
856
|
};
|
|
690
857
|
},
|
|
691
858
|
renderToContainer(e, t, n) {
|
|
692
|
-
|
|
859
|
+
nt(e, t, {
|
|
693
860
|
sceneIndex: n.sceneIndex,
|
|
694
861
|
thumbnail: n.thumbnail ?? !1,
|
|
695
862
|
transition: !1,
|
|
@@ -708,78 +875,234 @@ function nn() {
|
|
|
708
875
|
throw Error("dom-backend: renderToContainer produced no frame");
|
|
709
876
|
},
|
|
710
877
|
rasterizePng() {
|
|
711
|
-
return Promise.reject(new
|
|
878
|
+
return Promise.reject(new qn());
|
|
712
879
|
}
|
|
713
880
|
};
|
|
714
881
|
}
|
|
715
882
|
//#endregion
|
|
883
|
+
//#region src/render/frame-svg.ts
|
|
884
|
+
var Xn = {
|
|
885
|
+
background: "#ffffff",
|
|
886
|
+
color: "#333333"
|
|
887
|
+
}, Zn = {
|
|
888
|
+
background: "#1c1c1c",
|
|
889
|
+
color: "rgba(255, 255, 255, 0.9)"
|
|
890
|
+
}, Qn = "sans-serif", $n = 20, q = 14, J = 12, Y = 1.25, er = 4, tr = 8, nr = 12, rr = 40, ir = "16px", ar = "Blueprint Chart", or = "Source: ", sr = " · ", cr = .6;
|
|
891
|
+
function lr(e) {
|
|
892
|
+
return e === "dark" ? { ...Zn } : { ...Xn };
|
|
893
|
+
}
|
|
894
|
+
function ur() {
|
|
895
|
+
if (typeof document > "u") return null;
|
|
896
|
+
try {
|
|
897
|
+
return document.createElement("canvas").getContext("2d");
|
|
898
|
+
} catch {
|
|
899
|
+
return null;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function dr() {
|
|
903
|
+
let e = ur();
|
|
904
|
+
return (t, n, r) => {
|
|
905
|
+
let i = t.length * n * cr;
|
|
906
|
+
return e ? (e.font = `${r ? "bold " : ""}${n}px ${Qn}`, Math.max(e.measureText(t).width, i)) : i;
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function X(e, t, n, r, i) {
|
|
910
|
+
let a = [];
|
|
911
|
+
for (let o of e.split("\n")) {
|
|
912
|
+
let e = o.split(/\s+/).filter(Boolean);
|
|
913
|
+
if (e.length === 0) continue;
|
|
914
|
+
let s = e[0];
|
|
915
|
+
for (let o of e.slice(1)) {
|
|
916
|
+
let e = `${s} ${o}`;
|
|
917
|
+
i(e, n, r) <= t ? s = e : (a.push(s), s = o);
|
|
918
|
+
}
|
|
919
|
+
a.push(s);
|
|
920
|
+
}
|
|
921
|
+
return a;
|
|
922
|
+
}
|
|
923
|
+
function Z(e, t, n) {
|
|
924
|
+
let r = n.top;
|
|
925
|
+
for (let i of t) e.push({
|
|
926
|
+
text: i,
|
|
927
|
+
x: n.x,
|
|
928
|
+
y: r + n.fontSize,
|
|
929
|
+
fontSize: n.fontSize,
|
|
930
|
+
fontWeight: n.fontWeight,
|
|
931
|
+
fontStyle: n.fontStyle,
|
|
932
|
+
fill: n.fill,
|
|
933
|
+
anchor: n.anchor
|
|
934
|
+
}), r += n.fontSize * Y;
|
|
935
|
+
return r;
|
|
936
|
+
}
|
|
937
|
+
function fr(e) {
|
|
938
|
+
let t = parseFloat(e) || 0;
|
|
939
|
+
return /r?em$/.test(e) ? t * 16 : t;
|
|
940
|
+
}
|
|
941
|
+
function pr(e) {
|
|
942
|
+
let t = e.frame ?? {}, n = lr(e.theme), [r, i, a, o] = je(t.padding ?? ir).map(fr), s = Math.max(e.width - o - i, 1), c = dr(), l = [], u = r;
|
|
943
|
+
t.title && (u = Z(l, X(t.title, s, $n, !0, c), {
|
|
944
|
+
x: o,
|
|
945
|
+
top: u,
|
|
946
|
+
fontSize: $n,
|
|
947
|
+
fontWeight: "bold",
|
|
948
|
+
fill: n.color
|
|
949
|
+
})), t.description && (u = Z(l, X(t.description, s, q, !1, c), {
|
|
950
|
+
x: o,
|
|
951
|
+
top: t.title ? u + er : u,
|
|
952
|
+
fontSize: q,
|
|
953
|
+
fill: n.color
|
|
954
|
+
}));
|
|
955
|
+
let d = u, f = t.note ? X(t.note, s, J, !1, c) : [], p = c(ar, J, !1), m = [t.byline, t.source ? or + t.source : ""].filter(Boolean).join(sr), h = m ? X(m, Math.max(s - p - nr, 1), J, !1, c) : [], g = Math.max(h.length, 1), _ = f.length * J * Y + tr + g * J * Y + a, v = Math.max(e.height - d - _, rr), y = d + v;
|
|
956
|
+
return y = Z(l, f, {
|
|
957
|
+
x: o,
|
|
958
|
+
top: y,
|
|
959
|
+
fontSize: J,
|
|
960
|
+
fontStyle: "italic",
|
|
961
|
+
fill: n.color
|
|
962
|
+
}) + tr, Z(l, h, {
|
|
963
|
+
x: o,
|
|
964
|
+
top: y,
|
|
965
|
+
fontSize: J,
|
|
966
|
+
fill: n.color
|
|
967
|
+
}), Z(l, [ar], {
|
|
968
|
+
x: e.width - i,
|
|
969
|
+
top: y,
|
|
970
|
+
fontSize: J,
|
|
971
|
+
fontWeight: "600",
|
|
972
|
+
fill: n.color,
|
|
973
|
+
anchor: "end"
|
|
974
|
+
}), {
|
|
975
|
+
width: e.width,
|
|
976
|
+
height: e.height,
|
|
977
|
+
plot: {
|
|
978
|
+
x: o,
|
|
979
|
+
y: d,
|
|
980
|
+
width: s,
|
|
981
|
+
height: v
|
|
982
|
+
},
|
|
983
|
+
blocks: l,
|
|
984
|
+
background: t.transparentBackground ? null : n.background,
|
|
985
|
+
color: n.color,
|
|
986
|
+
fontFamily: Qn
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
function Q(e) {
|
|
990
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
991
|
+
}
|
|
992
|
+
function $(e) {
|
|
993
|
+
return Q(e).replace(/"/g, """);
|
|
994
|
+
}
|
|
995
|
+
function mr(e, t) {
|
|
996
|
+
return [
|
|
997
|
+
`<text x="${e.x}" y="${e.y}" font-size="${e.fontSize}px"`,
|
|
998
|
+
e.fontFamily ? ` font-family="${$(e.fontFamily)}"` : "",
|
|
999
|
+
e.fontWeight ? ` font-weight="${$(e.fontWeight)}"` : "",
|
|
1000
|
+
e.fontStyle ? ` font-style="${$(e.fontStyle)}"` : "",
|
|
1001
|
+
e.anchor ? ` text-anchor="${e.anchor}"` : "",
|
|
1002
|
+
` fill="${$(e.fill ?? t.color)}">`,
|
|
1003
|
+
Q(e.text),
|
|
1004
|
+
"</text>"
|
|
1005
|
+
].join("");
|
|
1006
|
+
}
|
|
1007
|
+
function hr(e, t, n) {
|
|
1008
|
+
return [
|
|
1009
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${e.width}" height="${e.height}"`,
|
|
1010
|
+
` viewBox="0 0 ${e.width} ${e.height}" role="img" aria-label="${$(n.label)}"`,
|
|
1011
|
+
` font-family="${$(e.fontFamily)}" color="${$(e.color)}">`,
|
|
1012
|
+
`<title>${Q(n.label)}</title>`,
|
|
1013
|
+
`<desc>${Q(n.description)}</desc>`,
|
|
1014
|
+
e.background ? `<rect width="100%" height="100%" fill="${$(e.background)}"></rect>` : "",
|
|
1015
|
+
...e.blocks.map((t) => mr(t, e)),
|
|
1016
|
+
`<g transform="translate(${e.plot.x},${e.plot.y})">${t}</g>`,
|
|
1017
|
+
"</svg>"
|
|
1018
|
+
].join("");
|
|
1019
|
+
}
|
|
1020
|
+
//#endregion
|
|
716
1021
|
//#region src/render/public-render.ts
|
|
717
|
-
var
|
|
718
|
-
function
|
|
1022
|
+
var gr = 640, _r = 400;
|
|
1023
|
+
function vr() {
|
|
719
1024
|
return typeof document < "u" && typeof document.createElement == "function";
|
|
720
1025
|
}
|
|
721
|
-
async function
|
|
722
|
-
return
|
|
1026
|
+
async function yr() {
|
|
1027
|
+
return vr() ? Yn() : (await import("@blueprint-chart/lib/internal/node-backend")).createNodeBackend();
|
|
723
1028
|
}
|
|
724
|
-
async function
|
|
1029
|
+
async function br(e, t = {}) {
|
|
725
1030
|
let n;
|
|
726
1031
|
try {
|
|
727
|
-
n =
|
|
1032
|
+
n = Me(b(e));
|
|
728
1033
|
} catch (e) {
|
|
729
|
-
throw new
|
|
1034
|
+
throw new Kn(e instanceof Error ? e.message : String(e), { cause: e });
|
|
730
1035
|
}
|
|
731
|
-
let r = await
|
|
1036
|
+
let r = await yr(), i = t.frame ?? !0, a = {
|
|
732
1037
|
sceneIndex: t.scene,
|
|
733
|
-
width: t.width ??
|
|
734
|
-
height: t.height ??
|
|
1038
|
+
width: t.width ?? gr,
|
|
1039
|
+
height: t.height ?? _r
|
|
735
1040
|
};
|
|
736
|
-
function o(e) {
|
|
1041
|
+
function o(e, t) {
|
|
1042
|
+
let { background: n, color: r } = lr(t);
|
|
1043
|
+
e.style.backgroundColor = n, e.style.setProperty("--bc-text-color", r);
|
|
1044
|
+
}
|
|
1045
|
+
function s(e, i) {
|
|
737
1046
|
r.renderToContainer(e, n, {
|
|
738
1047
|
sceneIndex: a.sceneIndex,
|
|
739
|
-
thumbnail:
|
|
1048
|
+
thumbnail: i,
|
|
740
1049
|
theme: t.theme
|
|
741
1050
|
});
|
|
742
1051
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
1052
|
+
function c(e) {
|
|
1053
|
+
let c = e.width ?? a.width, l = e.height ?? a.height, u = Ke(n, a.sceneIndex), d = t.theme ?? u.theme;
|
|
1054
|
+
if (!i) {
|
|
1055
|
+
let { container: e, cleanup: t } = r.createContainer(c, l);
|
|
746
1056
|
try {
|
|
747
|
-
return o(
|
|
1057
|
+
return o(e, d), s(e, !0), r.serializeSvg(e);
|
|
748
1058
|
} finally {
|
|
749
|
-
|
|
1059
|
+
t();
|
|
750
1060
|
}
|
|
1061
|
+
}
|
|
1062
|
+
let f = pr({
|
|
1063
|
+
width: c,
|
|
1064
|
+
height: l,
|
|
1065
|
+
frame: u.frame,
|
|
1066
|
+
theme: d
|
|
1067
|
+
}), { container: p, cleanup: m } = r.createContainer(f.plot.width, f.plot.height);
|
|
1068
|
+
try {
|
|
1069
|
+
o(p, d), s(p, !0);
|
|
1070
|
+
let e = ut(u.chartType, u.frame, u.data);
|
|
1071
|
+
return hr(f, r.serializeSvg(p), e);
|
|
1072
|
+
} finally {
|
|
1073
|
+
m();
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
let l = {
|
|
1077
|
+
async toSvg(e = {}) {
|
|
1078
|
+
return c(e);
|
|
751
1079
|
},
|
|
752
1080
|
async toHtml(e = {}) {
|
|
753
1081
|
let { container: t, cleanup: n } = r.createContainer(e.width ?? a.width, e.height ?? a.height);
|
|
754
1082
|
try {
|
|
755
|
-
return
|
|
1083
|
+
return s(t, !i), r.serializeFrame(t);
|
|
756
1084
|
} finally {
|
|
757
1085
|
n();
|
|
758
1086
|
}
|
|
759
1087
|
},
|
|
760
1088
|
async toPng(e = {}) {
|
|
761
|
-
let
|
|
762
|
-
|
|
763
|
-
o(t), i = r.serializeSvg(t);
|
|
764
|
-
} finally {
|
|
765
|
-
n();
|
|
766
|
-
}
|
|
767
|
-
return r.rasterizePng(i, {
|
|
1089
|
+
let t = c(e);
|
|
1090
|
+
return r.rasterizePng(t, {
|
|
768
1091
|
width: e.width ?? a.width,
|
|
769
1092
|
height: e.height ?? a.height
|
|
770
1093
|
});
|
|
771
1094
|
},
|
|
772
1095
|
mount(e) {
|
|
773
|
-
if (r.kind !== "dom") return console.warn("Blueprint Chart: mount() is a no-op outside a browser environment."),
|
|
1096
|
+
if (r.kind !== "dom") return console.warn("Blueprint Chart: mount() is a no-op outside a browser environment."), l;
|
|
774
1097
|
let t = typeof e == "string" ? document.querySelector(e) : e;
|
|
775
1098
|
if (!t) throw Error(`Blueprint Chart: mount target "${String(e)}" not found`);
|
|
776
|
-
return
|
|
1099
|
+
return s(t, !i), l;
|
|
777
1100
|
},
|
|
778
1101
|
scene(e) {
|
|
779
|
-
return a.sceneIndex = e,
|
|
1102
|
+
return a.sceneIndex = e, l;
|
|
780
1103
|
}
|
|
781
1104
|
};
|
|
782
|
-
return
|
|
1105
|
+
return l;
|
|
783
1106
|
}
|
|
784
1107
|
//#endregion
|
|
785
|
-
export {
|
|
1108
|
+
export { yt as ANNOTATION_KIND_KEYWORD, Tt as Anchor, S as AnnotationKind, Ct as AnnotationLineStyle, ge as AxisDirection, fe as BC_TRANSITION_NAME, o as ChartOptionType, Kn as ChartParseError, xt as ChartType, ve as CompassDirection, u as CrosshairDirection, c as CrosshairStyle, tt as DEFAULT_BAR_GAP, ue as DirectLabelMode, Ze as DslNodeType, n as FilterCondition, Ye as FrameSizing, oe as GridStyle, ce as Interpolation, de as LabelPosition, f as LabelRotation, v as LegendPosition, ie as LineStyle, Jn as MissingNodeRenderDepsError, vt as NULL_VALUE, me as Orientation, Et as ParseOperationCategory, qn as PngBrowserUnsupportedError, i as RangeAnchor, xe as ScaleType, we as SceneTransition, g as SortDirection, ye as SortMode, Ce as StackMode, m as StrokeStyle, ne as SymbolShape, lt as SymbolShowOn, ee as SymbolStyle, it as TRANSFORM_TYPES, De as TickPosition, Te as TransformType, ke as ValueLabelPosition, _t as adjustColorsForBackground, ft as applyTransformNodes, Fe as applyTransformNodesToChartData, Qe as applyTransformSteps, Me as astToDefinition, re as buildChartOptions, hr as buildFrameSvg, Dt as buildSrcdoc, Le as chartDataToTable, Vt as checkCvdColors, T as classifyIntent, Be as cleanNumericValue, Ne as commitFadeOut, Zt as compactSerialize, Xt as compactSerializeDeep, bt as convertAnnotations, _e as convertAreaFills, l as convertColorizes, s as convertHighlights, le as convertSeriesOverrides, $e as createCanvas, Lt as createCvdSvgFilter, Ue as createFrame, Xe as dataEntriesToString, ot as detectColumnTypes, t as extractChartTypeOptions, Je as extractSceneOverrides, at as fadeIn, y as featureJoin, e as getCachedChart, be as getChart, h as getChartOptions, d as getChartTypeDefaults, It as getCvdFilterId, Pe as getOutputType, Oe as getSceneTransition, pt as getTransitionDuration, et as isDateValue, We as isNumberValue, p as isSeriesHidden, St as isTypeCompatible, x as listCharts, ze as listPalettes, Nt as listThemes, b as parse, He as parseBpcData, pe as parseData, he as parseOperationMap, a as parseOperations, ae as propertyMap, C as quoteDslString, jt as recommendCharts, Se as registerChart, br as render, mt as renderBpc, nt as renderChart, dt as renderHorizontalAxis, rt as renderLegend, qe as renderVerticalAxis, Re as resolveBackgroundColor, Ge as resolveBarGapPadding, _ as resolveChartTypeOptions, ht as resolvePalette, Ke as resolveScene, te as resolveSeriesColor, ct as resolveSeriesInterpolation, Gn as samples, Kt as serialize, Ae as serializeTableData, O as shapeOf, zt as simulateCvdColor, Ie as snapshotForFadeOut, Ee as snapshotLiveAttrs, r as stripDigitGroupSpaces, se as toBool, gt as transformNodesToSteps, wt as transformValue, yn as validateChart, Ve as wcagContrastRatio, st as wcagLevel };
|