@pixerate/editor 0.165.0 → 0.166.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/agent/index.cjs +34 -34
- package/dist/agent/index.js +5 -5
- package/dist/canvas/index.cjs +6 -6
- package/dist/canvas/index.js +2 -2
- package/dist/chart/controller.d.cts +29 -0
- package/dist/chart/controller.d.ts +29 -0
- package/dist/chart/index.cjs +301 -179
- package/dist/chart/index.d.cts +1 -0
- package/dist/chart/index.d.ts +1 -0
- package/dist/chart/index.js +132 -10
- package/dist/chart/layout-families.d.cts +7 -0
- package/dist/chart/layout-families.d.ts +7 -0
- package/dist/chart/layout-shared.d.cts +5 -0
- package/dist/chart/layout-shared.d.ts +5 -0
- package/dist/chart/race.d.cts +26 -0
- package/dist/chart/race.d.ts +26 -0
- package/dist/chart/schemas.d.cts +2 -0
- package/dist/chart/schemas.d.ts +2 -0
- package/dist/chart/spec.d.cts +1 -1
- package/dist/chart/spec.d.ts +1 -1
- package/dist/chart/types.d.cts +6 -2
- package/dist/chart/types.d.ts +6 -2
- package/dist/{chunk-FEU2XVQH.js → chunk-5UNQDC3Q.js} +5 -2
- package/dist/{chunk-64VWWR5U.cjs → chunk-6FYIFGBW.cjs} +16 -16
- package/dist/{chunk-UVXTOZ2B.cjs → chunk-BPX4Z3N3.cjs} +12 -3
- package/dist/{chunk-MKXK6E4O.cjs → chunk-CHLV7UFP.cjs} +51 -51
- package/dist/{chunk-X5W645RI.js → chunk-DFCAR7AW.js} +3 -3
- package/dist/{chunk-2ZRN43IN.js → chunk-FR432ROA.js} +12 -3
- package/dist/{chunk-ODFCS7HF.cjs → chunk-HXOBOHH2.cjs} +8 -8
- package/dist/{chunk-V5GSY3NC.js → chunk-ITANXMZD.js} +78 -2
- package/dist/{chunk-TVQW26AV.cjs → chunk-MZFZSVUJ.cjs} +26 -23
- package/dist/{chunk-N7NBGT2Y.js → chunk-NQQDGGXY.js} +2 -2
- package/dist/{chunk-Q25WAFTD.cjs → chunk-SZWVMB3B.cjs} +21 -18
- package/dist/{chunk-QO2T6KA5.cjs → chunk-UUUTEVX6.cjs} +116 -40
- package/dist/{chunk-IMRXC7OA.cjs → chunk-V5L2G22R.cjs} +153 -77
- package/dist/{chunk-2J5VLJHC.js → chunk-VB2CY6EG.js} +3 -3
- package/dist/{chunk-CRFSQWKQ.js → chunk-XNU45TYA.js} +4 -1
- package/dist/{chunk-FRBRLKNQ.js → chunk-YUFTVNLX.js} +78 -2
- package/dist/export/index.cjs +4 -4
- package/dist/export/index.js +3 -3
- package/dist/extensions/index.cjs +7 -7
- package/dist/extensions/index.js +6 -6
- package/dist/index.cjs +13 -13
- package/dist/index.js +7 -7
- package/package.json +1 -1
- package/skills/pixerate-chart/SKILL.md +20 -2
|
@@ -11,8 +11,8 @@ var _chunkTTCJPX4Ucjs = require('./chunk-TTCJPX4U.cjs');
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
var _chunkQO2T6KA5cjs = require('./chunk-QO2T6KA5.cjs');
|
|
15
14
|
|
|
15
|
+
var _chunkUUUTEVX6cjs = require('./chunk-UUUTEVX6.cjs');
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
@@ -44,7 +44,8 @@ var _chunkQO2T6KA5cjs = require('./chunk-QO2T6KA5.cjs');
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
var _chunkBPX4Z3N3cjs = require('./chunk-BPX4Z3N3.cjs');
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
|
|
@@ -83,7 +84,7 @@ var csvField = (text) => /[",\n]|^\s|\s$/.test(text) ? `"${text.replace(/"/g, '"
|
|
|
83
84
|
var treemapName = (name) => !name.includes('"') ? `"${name}"` : !name.includes("'") ? `'${name}'` : `"${name.replace(/"/g, "'")}"`;
|
|
84
85
|
var yamlText = (text) => /^[\w][\w .,!?()/&+-]*$/.test(text) && !/:\s/.test(text) ? text : JSON.stringify(text);
|
|
85
86
|
function chartMermaidFamily(spec) {
|
|
86
|
-
const family =
|
|
87
|
+
const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, spec);
|
|
87
88
|
if (family === "sankey" && _optionalChain([spec, 'access', _2 => _2.links, 'optionalAccess', _3 => _3.length])) return "sankey";
|
|
88
89
|
if (family === "treemap" || family === "sunburst") return "treemap";
|
|
89
90
|
if (family === "pie" || family === "funnel" || family === "parliament") return "pie";
|
|
@@ -136,7 +137,7 @@ function chartToMermaid(spec, options = {}) {
|
|
|
136
137
|
lines.push("treemap-beta");
|
|
137
138
|
if (spec.title) lines.push(`title ${spec.title}`);
|
|
138
139
|
const first = _nullishCoalesce(visible[0], () => ( spec.series[0]));
|
|
139
|
-
const tree = spec.tree.length ? spec.tree :
|
|
140
|
+
const tree = spec.tree.length ? spec.tree : _chunkBPX4Z3N3cjs.chartTreeFromSeries.call(void 0, spec.categories, _nullishCoalesce(_optionalChain([first, 'optionalAccess', _4 => _4.values]), () => ( [])));
|
|
140
141
|
const write = (nodes, depth) => {
|
|
141
142
|
for (const n of nodes) {
|
|
142
143
|
const pad = ind.repeat(depth);
|
|
@@ -271,8 +272,8 @@ function chartFromMermaid(text, options = {}) {
|
|
|
271
272
|
let title = _nullishCoalesce(frontTitle, () => ( ""));
|
|
272
273
|
const categories = [];
|
|
273
274
|
const series = [];
|
|
274
|
-
const xAxis =
|
|
275
|
-
const yAxis =
|
|
275
|
+
const xAxis = _chunkBPX4Z3N3cjs.defaultChartAxis.call(void 0, false);
|
|
276
|
+
const yAxis = _chunkBPX4Z3N3cjs.defaultChartAxis.call(void 0, true);
|
|
276
277
|
const radarAxes = [];
|
|
277
278
|
const pieSlices = [];
|
|
278
279
|
let legendShow = true;
|
|
@@ -434,7 +435,7 @@ function chartFromMermaid(text, options = {}) {
|
|
|
434
435
|
input.series = metaSeries.map((extra, i) => ({ ..._nullishCoalesce(base[i], () => ( {})), ..._nullishCoalesce(extra, () => ( {})) }));
|
|
435
436
|
}
|
|
436
437
|
}
|
|
437
|
-
const { spec, issues: specIssues } =
|
|
438
|
+
const { spec, issues: specIssues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
|
|
438
439
|
if (!family && !partial && !issues.length) issues.push({ path: "header", message: "The text is empty: expected a chart header (xychart-beta, pie, radar-beta, sankey-beta or treemap-beta)." });
|
|
439
440
|
return { spec, issues: [...issues, ...specIssues], family, hasMeta: !!meta };
|
|
440
441
|
}
|
|
@@ -464,7 +465,7 @@ function readWholeMermaid(family, all, headerLine, partial, title, issues) {
|
|
|
464
465
|
const tree = items.map(toNode);
|
|
465
466
|
const leaf = (n) => !n.children;
|
|
466
467
|
const flatOrOneLevel = tree.every(leaf) || tree.every((n) => _optionalChain([n, 'access', _18 => _18.children, 'optionalAccess', _19 => _19.every, 'call', _20 => _20(leaf)]));
|
|
467
|
-
return { type: flatOrOneLevel ? "treemap" : "sunburst", title: name, tree, categories: tree.map((n) => n.name), series: [{ id: "series-1", name: "Values", values: tree.map(
|
|
468
|
+
return { type: flatOrOneLevel ? "treemap" : "sunburst", title: name, tree, categories: tree.map((n) => n.name), series: [{ id: "series-1", name: "Values", values: tree.map(_chunkBPX4Z3N3cjs.chartTreeTotal) }] };
|
|
468
469
|
}
|
|
469
470
|
function findMermaidCharts(text) {
|
|
470
471
|
const lines = text.replace(/^/, "").split(/\r?\n/);
|
|
@@ -509,11 +510,11 @@ function findMermaidCharts(text) {
|
|
|
509
510
|
}
|
|
510
511
|
|
|
511
512
|
// src/chart/summary.ts
|
|
512
|
-
function summarizeChart(spec, size = { width: 640, height: 400 }, scene =
|
|
513
|
+
function summarizeChart(spec, size = { width: 640, height: 400 }, scene = _chunkUUUTEVX6cjs.layoutChart.call(void 0, spec, { ...size, selection: null })) {
|
|
513
514
|
const visible = spec.series.filter((s) => !s.hidden);
|
|
514
|
-
const series = visible.map((s) =>
|
|
515
|
-
const colors =
|
|
516
|
-
const check =
|
|
515
|
+
const series = visible.map((s) => _chunkUUUTEVX6cjs.summarizeChartSeries.call(void 0, s, spec.categories));
|
|
516
|
+
const colors = _chunkBPX4Z3N3cjs.chartSpecColorsByCategory.call(void 0, spec) ? spec.categories.map((_, i) => _optionalChain([visible, 'access', _24 => _24[0], 'optionalAccess', _25 => _25.pointColors, 'optionalAccess', _26 => _26[i]]) || _chunkBPX4Z3N3cjs.chartSliceColor.call(void 0, spec, i)) : visible.map((s) => _chunkBPX4Z3N3cjs.chartSeriesColor.call(void 0, spec, spec.series.indexOf(s)));
|
|
517
|
+
const check = _chunkBPX4Z3N3cjs.checkChartColors.call(void 0, colors, { surface: scene.theme.surface.startsWith("var(") ? "#ffffff" : scene.theme.surface });
|
|
517
518
|
const axis = (s, a) => s ? { min: s.domain[0], max: s.domain[1], ticks: [...s.ticks], ...s.logBase ? { logBase: s.logBase } : {}, ...a.reverse ? { reversed: true } : {} } : void 0;
|
|
518
519
|
return {
|
|
519
520
|
type: spec.type,
|
|
@@ -528,12 +529,12 @@ function summarizeChart(spec, size = { width: 640, height: 400 }, scene = _chunk
|
|
|
528
529
|
description: describeChart(spec, series)
|
|
529
530
|
};
|
|
530
531
|
}
|
|
531
|
-
function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((s) =>
|
|
532
|
-
const kind =
|
|
532
|
+
function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((s) => _chunkUUUTEVX6cjs.summarizeChartSeries.call(void 0, s, spec.categories))) {
|
|
533
|
+
const kind = _chunkBPX4Z3N3cjs.CHART_TYPE_LABELS[spec.type].toLowerCase();
|
|
533
534
|
const parts = [];
|
|
534
|
-
const family =
|
|
535
|
+
const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, spec);
|
|
535
536
|
const format = spec.yAxis.format;
|
|
536
|
-
const fmt = (v) => v === null ? "blank" :
|
|
537
|
+
const fmt = (v) => v === null ? "blank" : _chunkUUUTEVX6cjs.formatChartNumber.call(void 0, v, format);
|
|
537
538
|
const head = spec.title ? `${spec.title}: a ${kind} chart` : `A ${kind} chart`;
|
|
538
539
|
if (!series.length || series.every((s) => s.count === 0)) return `${head} with no data.`;
|
|
539
540
|
if (family === "pie" || family === "funnel" || family === "treemap" || family === "sunburst") {
|
|
@@ -543,12 +544,19 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
|
|
|
543
544
|
parts.push(`${head} of ${s.name} across ${spec.categories.length} categories, totalling ${fmt(s.sum)}.`);
|
|
544
545
|
parts.push(`The largest is ${s.maxAt} at ${fmt(s.max)}${share(s.max)}; the smallest is ${s.minAt} at ${fmt(s.min)}${share(s.min)}.`);
|
|
545
546
|
if (spec.tree.length) {
|
|
546
|
-
const depth =
|
|
547
|
-
const items =
|
|
547
|
+
const depth = _chunkBPX4Z3N3cjs.chartTreeDepth.call(void 0, spec.tree);
|
|
548
|
+
const items = _chunkBPX4Z3N3cjs.chartTreeToRows.call(void 0, spec.tree).length;
|
|
548
549
|
parts.push(`The data is grouped ${depth} level${depth === 1 ? "" : "s"} deep with ${items} item${items === 1 ? "" : "s"}.`);
|
|
549
550
|
}
|
|
550
551
|
return parts.join(" ");
|
|
551
552
|
}
|
|
553
|
+
if (family === "barrace") {
|
|
554
|
+
const n = spec.categories.length;
|
|
555
|
+
const first = _chunkUUUTEVX6cjs.chartRaceRanking.call(void 0, spec, 0)[0];
|
|
556
|
+
const last = _chunkUUUTEVX6cjs.chartRaceRanking.call(void 0, spec, n - 1)[0];
|
|
557
|
+
const lead = (e, at) => e ? `${e.name} leads at ${at} with ${fmt(e.value)}` : "";
|
|
558
|
+
return `${head} of ${series.length} names over ${n} time points (${spec.categories[0]} to ${spec.categories[n - 1]}), showing the top ${Math.min(spec.raceTopN, series.length)}. ${lead(first, spec.categories[0])}; ${lead(last, spec.categories[n - 1])}.`;
|
|
559
|
+
}
|
|
552
560
|
if (family === "sankey") {
|
|
553
561
|
if (!spec.links.length) return `${head} with no flows yet.`;
|
|
554
562
|
const total = spec.links.reduce((t, l) => t + l.value, 0);
|
|
@@ -625,7 +633,7 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
|
|
|
625
633
|
}
|
|
626
634
|
parts.push(...axes);
|
|
627
635
|
for (const s of spec.series.filter((x) => !x.hidden && (x.errorBars || x.xErrorBars)).slice(0, 8)) {
|
|
628
|
-
const bars = [s.errorBars ?
|
|
636
|
+
const bars = [s.errorBars ? _chunkBPX4Z3N3cjs.describeChartErrorBars.call(void 0, s.errorBars) : "", s.xErrorBars ? `x ${_chunkBPX4Z3N3cjs.describeChartErrorBars.call(void 0, s.xErrorBars)}` : ""].filter(Boolean).join(" and ");
|
|
629
637
|
parts.push(`${s.name} has ${bars}.`);
|
|
630
638
|
}
|
|
631
639
|
return parts.join(" ");
|
|
@@ -690,7 +698,7 @@ function chartSceneToSvg(scene, options = {}) {
|
|
|
690
698
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${scene.width}" height="${scene.height}" viewBox="0 0 ${scene.width} ${scene.height}" role="img"${label ? ` aria-label="${escape(label)}"` : ""}${labelled ? ` aria-labelledby="${labelled}"` : ""}>${head}${body}</svg>`;
|
|
691
699
|
}
|
|
692
700
|
function chartToSvg(spec, options) {
|
|
693
|
-
const scene =
|
|
701
|
+
const scene = _chunkUUUTEVX6cjs.layoutChart.call(void 0, spec, { ...options, selection: null });
|
|
694
702
|
return chartSceneToSvg(scene, { ...options, ariaLabel: _nullishCoalesce(options.ariaLabel, () => ( (spec.title || void 0))), description: _nullishCoalesce(options.description, () => ( describeChart(spec))) });
|
|
695
703
|
}
|
|
696
704
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
@@ -728,10 +736,10 @@ var CHART_LAYOUT_PRESETS = [
|
|
|
728
736
|
];
|
|
729
737
|
function monochromeChartPalette(base, count = 6) {
|
|
730
738
|
const steps = count <= 1 ? [0] : Array.from({ length: count }, (_, i) => -0.45 + 1.05 * i / (count - 1));
|
|
731
|
-
return steps.map((t) =>
|
|
739
|
+
return steps.map((t) => _chunkBPX4Z3N3cjs.shadeChartColor.call(void 0, base, t));
|
|
732
740
|
}
|
|
733
741
|
var CHART_COLOR_SCHEMES = [
|
|
734
|
-
{ id: "default", label: "Default", description: "Ten distinct colours, readable on light and dark backgrounds.", palette:
|
|
742
|
+
{ id: "default", label: "Default", description: "Ten distinct colours, readable on light and dark backgrounds.", palette: _chunkBPX4Z3N3cjs.DEFAULT_CHART_PALETTE },
|
|
735
743
|
{ id: "okabe-ito", label: "Okabe\u2013Ito", description: "Eight colours chosen to stay distinct with colour-blindness.", palette: ["#e69f00", "#56b4e9", "#009e73", "#f0e442", "#0072b2", "#d55e00", "#cc79a7", "#000000"] },
|
|
736
744
|
{ id: "office", label: "Office", description: "The six accent colours of the default Office theme.", palette: ["#4472c4", "#ed7d31", "#a5a5a5", "#ffc000", "#5b9bd5", "#70ad47"] },
|
|
737
745
|
{ id: "warm", label: "Warm", description: "Reds, oranges and yellows.", palette: ["#b2182b", "#d6604d", "#f4a582", "#e08214", "#fdb863", "#8c510a"] },
|
|
@@ -776,6 +784,17 @@ function sameChartJson(a, b) {
|
|
|
776
784
|
if (keys.length !== Object.keys(bo).filter((k) => bo[k] !== void 0).length) return false;
|
|
777
785
|
return keys.every((k) => Object.prototype.hasOwnProperty.call(bo, k) && sameChartJson(ao[k], bo[k]));
|
|
778
786
|
}
|
|
787
|
+
var defaultRaceTicker = {
|
|
788
|
+
now: () => typeof performance !== "undefined" ? performance.now() : Date.now(),
|
|
789
|
+
next: (step) => {
|
|
790
|
+
if (typeof requestAnimationFrame === "function") {
|
|
791
|
+
const id2 = requestAnimationFrame(() => step());
|
|
792
|
+
return () => cancelAnimationFrame(id2);
|
|
793
|
+
}
|
|
794
|
+
const id = setTimeout(step, 16);
|
|
795
|
+
return () => clearTimeout(id);
|
|
796
|
+
}
|
|
797
|
+
};
|
|
779
798
|
var fail = (message, issues) => ({ ok: false, message, ...issues ? { issues } : {} });
|
|
780
799
|
var ChartController = (_class = class {
|
|
781
800
|
|
|
@@ -788,13 +807,17 @@ var ChartController = (_class = class {
|
|
|
788
807
|
__init6() {this.revision = 0}
|
|
789
808
|
__init7() {this.applying = false}
|
|
790
809
|
|
|
791
|
-
|
|
810
|
+
|
|
811
|
+
__init8() {this.raceFrame = null}
|
|
812
|
+
__init9() {this.raceStop = null}
|
|
813
|
+
__init10() {this.listeners = /* @__PURE__ */ new Set()}
|
|
792
814
|
|
|
793
815
|
|
|
794
|
-
constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);
|
|
816
|
+
constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);
|
|
795
817
|
this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkFJ2MSI43cjs.HistoryManager)()));
|
|
796
818
|
this.onChange = options.onChange;
|
|
797
|
-
|
|
819
|
+
this.raceTicker = _nullishCoalesce(options.raceTicker, () => ( defaultRaceTicker));
|
|
820
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, _nullishCoalesce(options.spec, () => ( {})));
|
|
798
821
|
this.spec = spec;
|
|
799
822
|
this.issues = issues;
|
|
800
823
|
this.state = this.computeState();
|
|
@@ -812,9 +835,9 @@ var ChartController = (_class = class {
|
|
|
812
835
|
// State
|
|
813
836
|
// -------------------------------------------------------------------------
|
|
814
837
|
/** The current snapshot (stable until the next change). */
|
|
815
|
-
|
|
838
|
+
__init11() {this.getState = () => this.state}
|
|
816
839
|
/** Calls `listener` after every change. Returns an unsubscribe function. */
|
|
817
|
-
|
|
840
|
+
__init12() {this.subscribe = (listener) => {
|
|
818
841
|
if (!this.unsubscribeHistory) this.connect();
|
|
819
842
|
this.listeners.add(listener);
|
|
820
843
|
return () => {
|
|
@@ -843,6 +866,8 @@ var ChartController = (_class = class {
|
|
|
843
866
|
canRedo: h.canRedo,
|
|
844
867
|
undoLabel: h.undoName,
|
|
845
868
|
redoLabel: h.redoName,
|
|
869
|
+
raceFrame: this.raceFrame === null ? null : Math.min(this.raceFrame, Math.max(0, this.spec.categories.length - 1)),
|
|
870
|
+
racePlaying: this.raceStop !== null,
|
|
846
871
|
revision: this.revision
|
|
847
872
|
};
|
|
848
873
|
}
|
|
@@ -897,7 +922,7 @@ var ChartController = (_class = class {
|
|
|
897
922
|
const hadIssues = this.issues.length > 0;
|
|
898
923
|
this.issues = [];
|
|
899
924
|
if (sameChartJson(before, next)) {
|
|
900
|
-
const reselect = select !== void 0 && !
|
|
925
|
+
const reselect = select !== void 0 && !_chunkUUUTEVX6cjs.sameChartSelection.call(void 0, this.selection, select) && !(select === null && this.selection === null);
|
|
901
926
|
if (reselect) this.selection = select;
|
|
902
927
|
if (reselect || hadIssues) this.notify(false);
|
|
903
928
|
return;
|
|
@@ -920,7 +945,7 @@ var ChartController = (_class = class {
|
|
|
920
945
|
}
|
|
921
946
|
/** A copy of the spec with `edit` applied (series and categories copied as needed). */
|
|
922
947
|
edited(edit) {
|
|
923
|
-
const draft =
|
|
948
|
+
const draft = _chunkBPX4Z3N3cjs.cloneChartSpec.call(void 0, this.spec);
|
|
924
949
|
edit(draft);
|
|
925
950
|
return draft;
|
|
926
951
|
}
|
|
@@ -950,7 +975,7 @@ var ChartController = (_class = class {
|
|
|
950
975
|
legend: patch.legend ? { ...s.legend, ...patch.legend } : s.legend,
|
|
951
976
|
version: 1
|
|
952
977
|
};
|
|
953
|
-
const { spec, issues } =
|
|
978
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, merged);
|
|
954
979
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
955
980
|
if (JSON.stringify(spec) === JSON.stringify(s)) return { ok: true };
|
|
956
981
|
this.commit(_nullishCoalesce(options.label, () => ( updateLabel(patch))), spec);
|
|
@@ -1004,7 +1029,7 @@ var ChartController = (_class = class {
|
|
|
1004
1029
|
const series = this.getSeries(seriesId);
|
|
1005
1030
|
if (!series) return this.unknownSeries(seriesId);
|
|
1006
1031
|
if (!Number.isInteger(index) || index < 0 || index >= this.spec.categories.length) return this.badIndex(index);
|
|
1007
|
-
const parsed =
|
|
1032
|
+
const parsed = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, value);
|
|
1008
1033
|
if (parsed === void 0) return this.reject(`"${String(value)}" is not a number; enter a number or leave the cell blank.`, [{ path: `${seriesId}[${index}]`, message: `"${String(value)}" is not a number.` }]);
|
|
1009
1034
|
if (series.values[index] === parsed) {
|
|
1010
1035
|
if (this.issues.length) {
|
|
@@ -1029,7 +1054,7 @@ var ChartController = (_class = class {
|
|
|
1029
1054
|
if (!this.getSeries(cell.seriesId)) issues.push({ path: cell.seriesId, message: this.unknownSeries(cell.seriesId).message });
|
|
1030
1055
|
else if (!Number.isInteger(cell.index) || cell.index < 0 || cell.index >= this.spec.categories.length) issues.push({ path: `${cell.seriesId}[${cell.index}]`, message: this.badIndex(cell.index).message });
|
|
1031
1056
|
else {
|
|
1032
|
-
const value =
|
|
1057
|
+
const value = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, cell.value);
|
|
1033
1058
|
if (value === void 0) issues.push({ path: `${cell.seriesId}[${cell.index}]`, message: `"${String(cell.value)}" is not a number.` });
|
|
1034
1059
|
else parsed.push({ seriesId: cell.seriesId, index: cell.index, value });
|
|
1035
1060
|
}
|
|
@@ -1043,12 +1068,12 @@ var ChartController = (_class = class {
|
|
|
1043
1068
|
}
|
|
1044
1069
|
/** Adds a series (values padded to the categories) and selects it. Returns its id. */
|
|
1045
1070
|
addSeries(input = {}, options = {}) {
|
|
1046
|
-
const id = input.id && !this.getSeries(input.id) ? input.id :
|
|
1071
|
+
const id = input.id && !this.getSeries(input.id) ? input.id : _chunkBPX4Z3N3cjs.uniqueChartSeriesId.call(void 0, this.spec.series);
|
|
1047
1072
|
const name = _nullishCoalesce(input.name, () => ( `Series ${this.spec.series.length + 1}`));
|
|
1048
1073
|
const at = Math.max(0, Math.min(this.spec.series.length, _nullishCoalesce(options.at, () => ( this.spec.series.length))));
|
|
1049
1074
|
const series = [...this.spec.series];
|
|
1050
1075
|
series.splice(at, 0, { ...input, id, name, values: _nullishCoalesce(input.values, () => ( [])) });
|
|
1051
|
-
const { spec, issues } =
|
|
1076
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, series });
|
|
1052
1077
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1053
1078
|
this.commit(`Add series "${name}"`, spec, { kind: "series", seriesId: id });
|
|
1054
1079
|
return { ok: true, id };
|
|
@@ -1068,7 +1093,7 @@ var ChartController = (_class = class {
|
|
|
1068
1093
|
updateSeries(id, patch) {
|
|
1069
1094
|
const series = this.getSeries(id);
|
|
1070
1095
|
if (!series) return this.unknownSeries(id);
|
|
1071
|
-
const next =
|
|
1096
|
+
const next = _chunkBPX4Z3N3cjs.cloneChartSeries.call(void 0, series);
|
|
1072
1097
|
if (patch.name !== void 0) next.name = String(patch.name);
|
|
1073
1098
|
if (patch.color === null || patch.color === "") delete next.color;
|
|
1074
1099
|
else if (patch.color !== void 0) next.color = patch.color;
|
|
@@ -1088,7 +1113,7 @@ var ChartController = (_class = class {
|
|
|
1088
1113
|
const series2 = this.spec.series.map((s) => s.id === id ? next : s);
|
|
1089
1114
|
const renamed = next.name !== series.name && this.spec.highlight.includes(series.name) && !this.spec.categories.includes(series.name);
|
|
1090
1115
|
const highlight = renamed ? this.spec.highlight.map((h) => h === series.name ? next.name : h) : this.spec.highlight;
|
|
1091
|
-
const { spec, issues } =
|
|
1116
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, series: series2, highlight });
|
|
1092
1117
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1093
1118
|
if (JSON.stringify(spec.series) === JSON.stringify(this.spec.series)) return { ok: true };
|
|
1094
1119
|
const label = patch.hidden !== void 0 && Object.keys(patch).length === 1 ? `${patch.hidden ? "Hide" : "Show"} "${series.name}"` : patch.name !== void 0 && Object.keys(patch).length === 1 ? "Rename series" : `Change series "${series.name}"`;
|
|
@@ -1194,7 +1219,7 @@ var ChartController = (_class = class {
|
|
|
1194
1219
|
const width = Math.max(...rows.map((r) => r.length));
|
|
1195
1220
|
const lastSeries = column + width - 1;
|
|
1196
1221
|
while (d.series.length <= lastSeries) {
|
|
1197
|
-
const id =
|
|
1222
|
+
const id = _chunkBPX4Z3N3cjs.uniqueChartSeriesId.call(void 0, d.series);
|
|
1198
1223
|
d.series.push({ id, name: `Series ${d.series.length + 1}`, values: d.categories.map(() => null) });
|
|
1199
1224
|
}
|
|
1200
1225
|
const lastRow = row + rows.length - 1;
|
|
@@ -1208,7 +1233,7 @@ var ChartController = (_class = class {
|
|
|
1208
1233
|
const index = row + r;
|
|
1209
1234
|
if (col < 0) d.categories[index] = cell === null || cell === void 0 ? "" : String(cell).trim();
|
|
1210
1235
|
else {
|
|
1211
|
-
const parsed =
|
|
1236
|
+
const parsed = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, cell);
|
|
1212
1237
|
if (parsed === void 0) issues.push({ path: `${d.series[col].id}[${index}]`, message: `"${String(cell)}" is not a number; it was left blank.` });
|
|
1213
1238
|
d.series[col].values[index] = _nullishCoalesce(parsed, () => ( null));
|
|
1214
1239
|
}
|
|
@@ -1227,14 +1252,14 @@ var ChartController = (_class = class {
|
|
|
1227
1252
|
* colours and types are kept by name.
|
|
1228
1253
|
*/
|
|
1229
1254
|
importTable(rows, options = {}) {
|
|
1230
|
-
const data =
|
|
1255
|
+
const data = _chunkBPX4Z3N3cjs.chartDataFromTable.call(void 0, rows, options);
|
|
1231
1256
|
if (!data.categories.length || !data.series.length) return this.reject("There is no data to import: expected a header row and at least one row of values.");
|
|
1232
1257
|
const byName = new Map(this.spec.series.map((s) => [s.name, s]));
|
|
1233
1258
|
const series = data.series.map((s) => {
|
|
1234
1259
|
const old = byName.get(s.name);
|
|
1235
1260
|
return { ...s, ..._optionalChain([old, 'optionalAccess', _63 => _63.color]) ? { color: old.color } : {}, ..._optionalChain([old, 'optionalAccess', _64 => _64.type]) ? { type: old.type } : {}, ...old ? { id: old.id } : {} };
|
|
1236
1261
|
});
|
|
1237
|
-
const { spec } =
|
|
1262
|
+
const { spec } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, categories: data.categories, series, tree: [], links: [] });
|
|
1238
1263
|
this.commit("Import data", spec);
|
|
1239
1264
|
if (data.issues.length) {
|
|
1240
1265
|
this.issues = data.issues;
|
|
@@ -1265,7 +1290,7 @@ var ChartController = (_class = class {
|
|
|
1265
1290
|
/** Replaces the grouped data (an empty list goes back to the table, keeping the totals as values). One undo step. */
|
|
1266
1291
|
setTree(tree, options = {}) {
|
|
1267
1292
|
const issues = [];
|
|
1268
|
-
const next =
|
|
1293
|
+
const next = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, tree, issues);
|
|
1269
1294
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1270
1295
|
return this.update({ tree: next, links: [] }, { label: _nullishCoalesce(options.label, () => ( (next.length ? "Replace grouped data" : "Ungroup data"))) });
|
|
1271
1296
|
}
|
|
@@ -1275,11 +1300,11 @@ var ChartController = (_class = class {
|
|
|
1275
1300
|
*/
|
|
1276
1301
|
setTreeRows(rows, options = {}) {
|
|
1277
1302
|
const issues = [];
|
|
1278
|
-
const next =
|
|
1303
|
+
const next = _chunkBPX4Z3N3cjs.chartTreeFromRows.call(void 0, rows, issues);
|
|
1279
1304
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1280
1305
|
const keepColors = (list, prefix) => {
|
|
1281
1306
|
for (const n of list) {
|
|
1282
|
-
const old =
|
|
1307
|
+
const old = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, [...prefix, n.name]);
|
|
1283
1308
|
if (_optionalChain([old, 'optionalAccess', _65 => _65.color])) n.color = old.color;
|
|
1284
1309
|
if (n.children) keepColors(n.children, [...prefix, n.name]);
|
|
1285
1310
|
}
|
|
@@ -1290,15 +1315,15 @@ var ChartController = (_class = class {
|
|
|
1290
1315
|
/** Replaces the data with a table of names and values (group, …, item, value); see `chartTreeFromTable`. */
|
|
1291
1316
|
importTreeTable(rows, options = {}) {
|
|
1292
1317
|
const issues = [];
|
|
1293
|
-
const next =
|
|
1318
|
+
const next = _chunkBPX4Z3N3cjs.chartTreeFromTable.call(void 0, rows, options, issues);
|
|
1294
1319
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1295
1320
|
if (!next.length) return this.reject('There is no grouped data to import: expected rows of names followed by a value, e.g. "Europe,France,40".');
|
|
1296
1321
|
return this.update({ tree: next, links: [] }, { label: "Import grouped data" });
|
|
1297
1322
|
}
|
|
1298
1323
|
nodeAt(path) {
|
|
1299
|
-
const node =
|
|
1324
|
+
const node = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path);
|
|
1300
1325
|
if (node) return node;
|
|
1301
|
-
const known = path.length > 1 ?
|
|
1326
|
+
const known = path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)) : null;
|
|
1302
1327
|
const siblings = _nullishCoalesce((path.length > 1 ? _optionalChain([known, 'optionalAccess', _66 => _66.children]) : this.spec.tree), () => ( []));
|
|
1303
1328
|
return fail(
|
|
1304
1329
|
`There is no node ${JSON.stringify(path)}. ${siblings.length ? `${path.length > 1 && known ? `"${known.name}" contains` : "The top level has"} ${siblings.map((n) => `"${n.name}"`).slice(0, 20).join(", ")}.` : "The chart has no grouped data yet; add nodes with add_chart_tree_node or set_chart_tree."}`
|
|
@@ -1314,12 +1339,12 @@ var ChartController = (_class = class {
|
|
|
1314
1339
|
siblings = group.children;
|
|
1315
1340
|
}
|
|
1316
1341
|
const issues = [];
|
|
1317
|
-
const [node] =
|
|
1342
|
+
const [node] = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, [input], issues, "node");
|
|
1318
1343
|
if (!node || issues.length) return this.reject(issues.map((i) => i.message).join(" ") || "The node is not valid.", issues);
|
|
1319
1344
|
if (siblings.some((n) => n.name === node.name)) return this.reject(`"${node.name}" is already there; names under one group must be unique.`);
|
|
1320
1345
|
const at = Math.max(0, Math.min(siblings.length, _nullishCoalesce(options.at, () => ( siblings.length))));
|
|
1321
|
-
const tree =
|
|
1322
|
-
const list = parent.length ?
|
|
1346
|
+
const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
|
|
1347
|
+
const list = parent.length ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, parent).children : tree;
|
|
1323
1348
|
list.splice(at, 0, node);
|
|
1324
1349
|
const result = this.update({ tree }, { label: `Add "${node.name}"` });
|
|
1325
1350
|
if (!result.ok) return result;
|
|
@@ -1331,16 +1356,16 @@ var ChartController = (_class = class {
|
|
|
1331
1356
|
if ("ok" in node) return node;
|
|
1332
1357
|
if (patch.value !== void 0 && node.children) return this.reject(`"${node.name}" is a group: its value is the sum of its items. Change the items instead.`);
|
|
1333
1358
|
const name = patch.name !== void 0 ? String(patch.name).trim() : node.name;
|
|
1334
|
-
const siblings = (path.length > 1 ?
|
|
1359
|
+
const siblings = (path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)).children : this.spec.tree).filter((n) => n !== node);
|
|
1335
1360
|
if (siblings.some((n) => n.name === name)) return this.reject(`There is already a "${name}" next to "${node.name}"; names under one group must be unique.`);
|
|
1336
|
-
const tree =
|
|
1337
|
-
const target =
|
|
1361
|
+
const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
|
|
1362
|
+
const target = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, path);
|
|
1338
1363
|
const merged = { ...target, name };
|
|
1339
1364
|
if (patch.value !== void 0) merged.value = patch.value;
|
|
1340
1365
|
if (patch.color === null) delete merged.color;
|
|
1341
1366
|
else if (patch.color !== void 0) merged.color = patch.color;
|
|
1342
1367
|
const issues = [];
|
|
1343
|
-
const [checked] =
|
|
1368
|
+
const [checked] = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, [merged], issues, "node");
|
|
1344
1369
|
if (!checked || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1345
1370
|
Object.assign(target, checked);
|
|
1346
1371
|
if (patch.color === null) delete target.color;
|
|
@@ -1352,8 +1377,8 @@ var ChartController = (_class = class {
|
|
|
1352
1377
|
removeTreeNode(path) {
|
|
1353
1378
|
const node = this.nodeAt(path);
|
|
1354
1379
|
if ("ok" in node) return node;
|
|
1355
|
-
const tree =
|
|
1356
|
-
const parent = path.length > 1 ?
|
|
1380
|
+
const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
|
|
1381
|
+
const parent = path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, path.slice(0, -1)) : null;
|
|
1357
1382
|
const list = parent ? parent.children : tree;
|
|
1358
1383
|
list.splice(
|
|
1359
1384
|
list.findIndex((n) => n.name === node.name),
|
|
@@ -1374,7 +1399,7 @@ var ChartController = (_class = class {
|
|
|
1374
1399
|
*/
|
|
1375
1400
|
setLinks(links, options = {}) {
|
|
1376
1401
|
const issues = [];
|
|
1377
|
-
const next =
|
|
1402
|
+
const next = _chunkBPX4Z3N3cjs.normalizeChartLinks.call(void 0, links, issues);
|
|
1378
1403
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1379
1404
|
const used = new Set(next.flatMap((l) => [l.source, l.target]));
|
|
1380
1405
|
const sankeyNodes = options.nodes ? [...options.nodes] : this.spec.sankeyNodes.filter((n) => used.has(n));
|
|
@@ -1382,7 +1407,7 @@ var ChartController = (_class = class {
|
|
|
1382
1407
|
}
|
|
1383
1408
|
/** Replaces the data with flows from a table of source, target and value columns. */
|
|
1384
1409
|
importLinksTable(rows, options = {}) {
|
|
1385
|
-
const raw =
|
|
1410
|
+
const raw = _chunkBPX4Z3N3cjs.chartLinksFromTable.call(void 0, rows, options);
|
|
1386
1411
|
if (!raw.length) return this.reject('There are no flows to import: expected rows of source, target and value, e.g. "Website,Signup,120".');
|
|
1387
1412
|
return this.setLinks(raw, { label: "Import flows" });
|
|
1388
1413
|
}
|
|
@@ -1446,7 +1471,7 @@ var ChartController = (_class = class {
|
|
|
1446
1471
|
/** Why a reference on `axis` at `values` cannot be drawn on this chart, or null. */
|
|
1447
1472
|
referenceProblem(axis, values) {
|
|
1448
1473
|
const s = this.spec;
|
|
1449
|
-
const family =
|
|
1474
|
+
const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, s);
|
|
1450
1475
|
if (family !== "cartesian" && family !== "xy") return `Reference lines and bands are drawn on bar, line, area, scatter and bubble charts; this is a ${s.type} chart.`;
|
|
1451
1476
|
if (axis === "x" && family !== "xy") return 'axis "x" needs a scatter or bubble chart with numeric x values; use "y" for the value axis.';
|
|
1452
1477
|
if (axis === "y2" && (family !== "cartesian" || !s.series.some((x) => !x.hidden && x.axis === "secondary")))
|
|
@@ -1465,7 +1490,7 @@ var ChartController = (_class = class {
|
|
|
1465
1490
|
/** Adds a reference line (a target, floor or average). Returns its index. */
|
|
1466
1491
|
addReferenceLine(input) {
|
|
1467
1492
|
const issues = [];
|
|
1468
|
-
const line =
|
|
1493
|
+
const line = _chunkBPX4Z3N3cjs.normalizeChartReferenceLine.call(void 0, input, "referenceLine", issues);
|
|
1469
1494
|
if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1470
1495
|
const problem = this.referenceProblem(line.axis, [line.value]);
|
|
1471
1496
|
if (problem) return this.reject(problem);
|
|
@@ -1480,7 +1505,7 @@ var ChartController = (_class = class {
|
|
|
1480
1505
|
const merged = { ...current, ...patch };
|
|
1481
1506
|
for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
|
|
1482
1507
|
const issues = [];
|
|
1483
|
-
const line =
|
|
1508
|
+
const line = _chunkBPX4Z3N3cjs.normalizeChartReferenceLine.call(void 0, merged, "referenceLine", issues);
|
|
1484
1509
|
if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1485
1510
|
const problem = this.referenceProblem(line.axis, [line.value]);
|
|
1486
1511
|
if (problem) return this.reject(problem);
|
|
@@ -1495,7 +1520,7 @@ var ChartController = (_class = class {
|
|
|
1495
1520
|
/** Adds a reference band (a target range). Returns its index. */
|
|
1496
1521
|
addReferenceBand(input) {
|
|
1497
1522
|
const issues = [];
|
|
1498
|
-
const band =
|
|
1523
|
+
const band = _chunkBPX4Z3N3cjs.normalizeChartReferenceBand.call(void 0, input, "referenceBand", issues);
|
|
1499
1524
|
if (!band || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1500
1525
|
const problem = this.referenceProblem(band.axis, [band.from, band.to]);
|
|
1501
1526
|
if (problem) return this.reject(problem);
|
|
@@ -1510,7 +1535,7 @@ var ChartController = (_class = class {
|
|
|
1510
1535
|
const merged = { ...current, ...patch };
|
|
1511
1536
|
for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
|
|
1512
1537
|
const issues = [];
|
|
1513
|
-
const band =
|
|
1538
|
+
const band = _chunkBPX4Z3N3cjs.normalizeChartReferenceBand.call(void 0, merged, "referenceBand", issues);
|
|
1514
1539
|
if (!band || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1515
1540
|
const problem = this.referenceProblem(band.axis, [band.from, band.to]);
|
|
1516
1541
|
if (problem) return this.reject(problem);
|
|
@@ -1533,7 +1558,7 @@ var ChartController = (_class = class {
|
|
|
1533
1558
|
const series = this.getSeries(seriesId);
|
|
1534
1559
|
if (!series) return this.unknownSeries(seriesId);
|
|
1535
1560
|
if (!Number.isInteger(index) || index < 0 || index >= this.spec.categories.length) return this.badIndex(index);
|
|
1536
|
-
const family =
|
|
1561
|
+
const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, this.spec);
|
|
1537
1562
|
const text = label === null ? "" : String(label).trim();
|
|
1538
1563
|
if (text && family !== "cartesian" && family !== "xy") return this.reject(`Callouts are drawn on bar, line, area, scatter and bubble charts; this is a ${this.spec.type} chart.`);
|
|
1539
1564
|
if (text && (series.values[index] === null || series.values[index] === void 0))
|
|
@@ -1555,10 +1580,10 @@ var ChartController = (_class = class {
|
|
|
1555
1580
|
addTrendline(seriesId, input) {
|
|
1556
1581
|
const series = this.getSeries(seriesId);
|
|
1557
1582
|
if (!series) return this.unknownSeries(seriesId);
|
|
1558
|
-
if (!
|
|
1583
|
+
if (!_chunkUUUTEVX6cjs.chartSupportsTrendlines.call(void 0, this.spec.type, this.spec.stacking))
|
|
1559
1584
|
return this.reject(`Trendlines need an unstacked bar, line, area, scatter or bubble chart; this is a ${this.spec.stacking !== "none" ? `${this.spec.stacking} ` : ""}${this.spec.type} chart.`);
|
|
1560
1585
|
const issues = [];
|
|
1561
|
-
const line =
|
|
1586
|
+
const line = _chunkBPX4Z3N3cjs.normalizeChartTrendline.call(void 0, input, "trendline", issues);
|
|
1562
1587
|
if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" ") || "The trendline is not valid.", issues);
|
|
1563
1588
|
const index = _nullishCoalesce(_optionalChain([series, 'access', _69 => _69.trendlines, 'optionalAccess', _70 => _70.length]), () => ( 0));
|
|
1564
1589
|
const next = this.edited((d) => {
|
|
@@ -1577,7 +1602,7 @@ var ChartController = (_class = class {
|
|
|
1577
1602
|
const issues = [];
|
|
1578
1603
|
const merged = { ...current, ...patch };
|
|
1579
1604
|
for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
|
|
1580
|
-
const line =
|
|
1605
|
+
const line = _chunkBPX4Z3N3cjs.normalizeChartTrendline.call(void 0, merged, "trendline", issues);
|
|
1581
1606
|
if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1582
1607
|
this.commit(
|
|
1583
1608
|
"Change trendline",
|
|
@@ -1605,7 +1630,7 @@ var ChartController = (_class = class {
|
|
|
1605
1630
|
trendlinePoints(seriesId) {
|
|
1606
1631
|
const series = this.getSeries(seriesId);
|
|
1607
1632
|
if (!series) return [];
|
|
1608
|
-
const xy =
|
|
1633
|
+
const xy = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, this.spec) === "xy";
|
|
1609
1634
|
const out = [];
|
|
1610
1635
|
series.values.forEach((v, i) => {
|
|
1611
1636
|
const x = xy ? _nullishCoalesce(_optionalChain([series, 'access', _77 => _77.x, 'optionalAccess', _78 => _78[i]]), () => ( (this.spec.type === "bubble" ? i + 1 : null))) : i + 1;
|
|
@@ -1617,13 +1642,13 @@ var ChartController = (_class = class {
|
|
|
1617
1642
|
trendlineFit(seriesId, index) {
|
|
1618
1643
|
const line = _optionalChain([this, 'access', _79 => _79.getSeries, 'call', _80 => _80(seriesId), 'optionalAccess', _81 => _81.trendlines, 'optionalAccess', _82 => _82[index]]);
|
|
1619
1644
|
if (!line) return null;
|
|
1620
|
-
return
|
|
1645
|
+
return _chunkUUUTEVX6cjs.fitChartTrendline.call(void 0, line, this.trendlinePoints(seriesId));
|
|
1621
1646
|
}
|
|
1622
1647
|
/** The moving-average points of a trendline (empty for other kinds). */
|
|
1623
1648
|
trendlineMovingAverage(seriesId, index) {
|
|
1624
1649
|
const line = _optionalChain([this, 'access', _83 => _83.getSeries, 'call', _84 => _84(seriesId), 'optionalAccess', _85 => _85.trendlines, 'optionalAccess', _86 => _86[index]]);
|
|
1625
1650
|
if (!line || line.type !== "moving-average") return [];
|
|
1626
|
-
return
|
|
1651
|
+
return _chunkUUUTEVX6cjs.chartMovingAverage.call(void 0, this.trendlinePoints(seriesId), _nullishCoalesce(line.period, () => ( 2)));
|
|
1627
1652
|
}
|
|
1628
1653
|
// -------------------------------------------------------------------------
|
|
1629
1654
|
// Reshaping
|
|
@@ -1644,17 +1669,66 @@ var ChartController = (_class = class {
|
|
|
1644
1669
|
used.add(id);
|
|
1645
1670
|
return { id, name, values: s.series.map((x) => _nullishCoalesce(x.values[i], () => ( null))) };
|
|
1646
1671
|
});
|
|
1647
|
-
const { spec } =
|
|
1672
|
+
const { spec } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...s, categories: s.series.map((x) => x.name), series });
|
|
1648
1673
|
this.commit("Switch rows and columns", spec, null);
|
|
1649
1674
|
return { ok: true };
|
|
1650
1675
|
}
|
|
1651
1676
|
// -------------------------------------------------------------------------
|
|
1652
1677
|
// Selection and gestures
|
|
1653
1678
|
// -------------------------------------------------------------------------
|
|
1679
|
+
/**
|
|
1680
|
+
* Shows a bar race at a moment: a category index, fractional between time points (`null`:
|
|
1681
|
+
* the last one). View state like the selection, so not an undo step. Stops playback.
|
|
1682
|
+
*/
|
|
1683
|
+
setRaceFrame(frame) {
|
|
1684
|
+
const n = this.spec.categories.length;
|
|
1685
|
+
if (frame !== null && !(Number.isFinite(frame) && frame >= 0 && frame <= Math.max(0, n - 1)))
|
|
1686
|
+
return fail(n ? `The race has time points 0 to ${n - 1}${n > 1 ? ` ("${this.spec.categories[0]}" to "${this.spec.categories[n - 1]}")` : ""}; got ${frame}.` : "The chart has no time points (categories) yet.");
|
|
1687
|
+
this.stopRace();
|
|
1688
|
+
if (frame === this.raceFrame) return { ok: true };
|
|
1689
|
+
this.raceFrame = frame;
|
|
1690
|
+
this.notify(false);
|
|
1691
|
+
return { ok: true };
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Plays the bar race from the moment shown (from the start when it is at the end), moving
|
|
1695
|
+
* one time point every `msPerStep` (default 1000) until the last. Not an undo step.
|
|
1696
|
+
*/
|
|
1697
|
+
playRace(options = {}) {
|
|
1698
|
+
const last = this.spec.categories.length - 1;
|
|
1699
|
+
if (last < 1) return fail("A race needs at least two time points (categories) to play.");
|
|
1700
|
+
this.stopRace();
|
|
1701
|
+
const per = Math.max(50, _nullishCoalesce(options.msPerStep, () => ( 1e3)));
|
|
1702
|
+
const from = this.raceFrame === null || this.raceFrame >= last ? 0 : this.raceFrame;
|
|
1703
|
+
const start = this.raceTicker.now();
|
|
1704
|
+
const step = () => {
|
|
1705
|
+
const at = Math.min(last, from + (this.raceTicker.now() - start) / per);
|
|
1706
|
+
this.raceFrame = at;
|
|
1707
|
+
if (at >= last) {
|
|
1708
|
+
this.raceStop = null;
|
|
1709
|
+
this.raceFrame = null;
|
|
1710
|
+
} else this.raceStop = this.raceTicker.next(step);
|
|
1711
|
+
this.notify(false);
|
|
1712
|
+
};
|
|
1713
|
+
this.raceFrame = from;
|
|
1714
|
+
this.raceStop = this.raceTicker.next(step);
|
|
1715
|
+
this.notify(false);
|
|
1716
|
+
return { ok: true };
|
|
1717
|
+
}
|
|
1718
|
+
/** Pauses bar race playback where it is. */
|
|
1719
|
+
pauseRace() {
|
|
1720
|
+
if (!this.raceStop) return;
|
|
1721
|
+
this.stopRace();
|
|
1722
|
+
this.notify(false);
|
|
1723
|
+
}
|
|
1724
|
+
stopRace() {
|
|
1725
|
+
_optionalChain([this, 'access', _87 => _87.raceStop, 'optionalCall', _88 => _88()]);
|
|
1726
|
+
this.raceStop = null;
|
|
1727
|
+
}
|
|
1654
1728
|
/** Selects a chart element (view state; not an undo step). */
|
|
1655
1729
|
select(selection) {
|
|
1656
1730
|
const next = this.validSelection(selection, this.spec);
|
|
1657
|
-
if (
|
|
1731
|
+
if (_chunkUUUTEVX6cjs.sameChartSelection.call(void 0, next, this.selection) || next === null && this.selection === null) return;
|
|
1658
1732
|
this.selection = next;
|
|
1659
1733
|
this.notify(false);
|
|
1660
1734
|
}
|
|
@@ -1731,14 +1805,14 @@ var ChartController = (_class = class {
|
|
|
1731
1805
|
// -------------------------------------------------------------------------
|
|
1732
1806
|
/** The spec, for saving (a copy). */
|
|
1733
1807
|
toJSON() {
|
|
1734
|
-
return
|
|
1808
|
+
return _chunkBPX4Z3N3cjs.cloneChartSpec.call(void 0, this.spec);
|
|
1735
1809
|
}
|
|
1736
1810
|
/**
|
|
1737
1811
|
* Replaces the chart without an undo step (e.g. when opening a document). Problems are
|
|
1738
1812
|
* fixed with defaults and reported in `state.issues` (and returned).
|
|
1739
1813
|
*/
|
|
1740
1814
|
load(input, options = {}) {
|
|
1741
|
-
const { spec, issues } =
|
|
1815
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
|
|
1742
1816
|
this.spec = spec;
|
|
1743
1817
|
this.issues = issues;
|
|
1744
1818
|
this.selection = this.validSelection(this.selection, spec);
|
|
@@ -1758,7 +1832,7 @@ var ChartController = (_class = class {
|
|
|
1758
1832
|
* nothing changes and every problem is returned (and shown in `state.issues`).
|
|
1759
1833
|
*/
|
|
1760
1834
|
replace(input, options = {}) {
|
|
1761
|
-
const { spec, issues } =
|
|
1835
|
+
const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
|
|
1762
1836
|
if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
|
|
1763
1837
|
this.commit(_nullishCoalesce(options.label, () => ( "Replace chart")), spec, this.validSelection(this.selection, spec));
|
|
1764
1838
|
return { ok: true };
|
|
@@ -1773,7 +1847,8 @@ var ChartController = (_class = class {
|
|
|
1773
1847
|
}
|
|
1774
1848
|
/** Stops listening to the history (reconnected by the next `subscribe`). */
|
|
1775
1849
|
destroy() {
|
|
1776
|
-
|
|
1850
|
+
this.stopRace();
|
|
1851
|
+
_optionalChain([this, 'access', _89 => _89.unsubscribeHistory, 'optionalCall', _90 => _90()]);
|
|
1777
1852
|
this.unsubscribeHistory = void 0;
|
|
1778
1853
|
this.listeners.clear();
|
|
1779
1854
|
}
|
|
@@ -1808,6 +1883,7 @@ function updateLabel(patch) {
|
|
|
1808
1883
|
parliamentArc: "Change hemicycle sweep",
|
|
1809
1884
|
parliamentMajority: "Change majority",
|
|
1810
1885
|
parliamentLabel: "Edit seat caption",
|
|
1886
|
+
raceTopN: "Change bars shown",
|
|
1811
1887
|
sunburstLabel: "Edit centre caption",
|
|
1812
1888
|
tree: "Replace grouped data",
|
|
1813
1889
|
links: "Replace flows",
|
|
@@ -1835,7 +1911,7 @@ function layoutSparkline(values, options) {
|
|
|
1835
1911
|
const h = Number.isFinite(options.height) ? Math.max(1, options.height) : 1;
|
|
1836
1912
|
const color = _nullishCoalesce(options.color, () => ( "#4269d0"));
|
|
1837
1913
|
const negative = _nullishCoalesce(options.negativeColor, () => ( "#e5484d"));
|
|
1838
|
-
const theme = { ...
|
|
1914
|
+
const theme = { ..._chunkBPX4Z3N3cjs.DEFAULT_CHART_THEME, background: "transparent" };
|
|
1839
1915
|
const marks = [];
|
|
1840
1916
|
const scene = { width: w, height: h, plot: { x: 0, y: 0, width: w, height: h }, marks, percent: false, theme, warnings: [] };
|
|
1841
1917
|
const vals = values.slice(0, MAX_POINTS).map((v) => v !== null && Number.isFinite(v) ? Math.max(-1e300, Math.min(1e300, v)) : null);
|
|
@@ -1868,7 +1944,7 @@ function layoutSparkline(values, options) {
|
|
|
1868
1944
|
const flush = () => {
|
|
1869
1945
|
if (run.length >= 2) {
|
|
1870
1946
|
const pts = run.length > 4e3 ? run.filter((_, i) => i % (Math.floor(run.length / 2e3) + 1) === 0) : run;
|
|
1871
|
-
d += pts.map(([x, y], i) => `${i ? "L" : "M"}${
|
|
1947
|
+
d += pts.map(([x, y], i) => `${i ? "L" : "M"}${_chunkUUUTEVX6cjs.r2.call(void 0, x)},${_chunkUUUTEVX6cjs.r2.call(void 0, y)}`).join("");
|
|
1872
1948
|
}
|
|
1873
1949
|
run = [];
|
|
1874
1950
|
};
|