@pixerate/editor 0.51.0 → 0.53.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 +23 -23
- package/dist/agent/index.js +4 -4
- package/dist/chart/index.cjs +475 -124
- package/dist/chart/index.cjs.map +1 -1
- package/dist/chart/index.d.cts +174 -25
- package/dist/chart/index.d.ts +174 -25
- package/dist/chart/index.js +375 -24
- package/dist/chart/index.js.map +1 -1
- package/dist/{chunk-GJBIVWB2.js → chunk-3S72F46R.js} +387 -9
- package/dist/chunk-3S72F46R.js.map +1 -0
- package/dist/{chunk-5TWIN7ZJ.js → chunk-47WWV3LI.js} +34 -4
- package/dist/chunk-47WWV3LI.js.map +1 -0
- package/dist/{chunk-OV7UAKIY.js → chunk-633QC34G.js} +172 -1
- package/dist/chunk-633QC34G.js.map +1 -0
- package/dist/{chunk-MR2764X2.js → chunk-AGGUNWT6.js} +2 -322
- package/dist/chunk-AGGUNWT6.js.map +1 -0
- package/dist/{chunk-T6XU4B54.js → chunk-BQQZ6MOI.js} +7 -7
- package/dist/{chunk-LNKZPIQD.cjs → chunk-C3JHII3M.cjs} +67 -67
- package/dist/{chunk-LNKZPIQD.cjs.map → chunk-C3JHII3M.cjs.map} +1 -1
- package/dist/{chunk-JOX6MJW4.cjs → chunk-CKRNELPO.cjs} +176 -5
- package/dist/chunk-CKRNELPO.cjs.map +1 -0
- package/dist/{chunk-TGBCBQFV.cjs → chunk-DK6QBGCS.cjs} +45 -15
- package/dist/chunk-DK6QBGCS.cjs.map +1 -0
- package/dist/{chunk-GTZXF4BI.cjs → chunk-NK3WL5TJ.cjs} +298 -133
- package/dist/chunk-NK3WL5TJ.cjs.map +1 -0
- package/dist/{chunk-3JNRQVTS.cjs → chunk-NN3JGUSX.cjs} +402 -24
- package/dist/chunk-NN3JGUSX.cjs.map +1 -0
- package/dist/{chunk-3CC7OPUQ.cjs → chunk-O6FO6VI3.cjs} +3 -323
- package/dist/chunk-O6FO6VI3.cjs.map +1 -0
- package/dist/{chunk-DQPBQXKG.js → chunk-OIKYP7XC.js} +8 -8
- package/dist/{chunk-FEMIVHN3.cjs → chunk-P43HUQRX.cjs} +16 -16
- package/dist/{chunk-FEMIVHN3.cjs.map → chunk-P43HUQRX.cjs.map} +1 -1
- package/dist/{chunk-QFTVLEVN.js → chunk-RIXTW3C4.js} +3 -3
- package/dist/{chunk-WBOAXDKD.js → chunk-VODBAO32.js} +222 -57
- package/dist/chunk-VODBAO32.js.map +1 -0
- package/dist/{chunk-2Q46FKZK.cjs → chunk-YZZMX6V7.cjs} +25 -25
- package/dist/{chunk-2Q46FKZK.cjs.map → chunk-YZZMX6V7.cjs.map} +1 -1
- package/dist/{controller-DS3drIvy.d.cts → controller-CX0QfSv0.d.cts} +53 -2
- package/dist/{controller-BdKzaxs2.d.ts → controller-DscWQbjO.d.ts} +53 -2
- package/dist/export/index.cjs +5 -5
- package/dist/export/index.js +4 -4
- package/dist/extensions/index.cjs +7 -7
- package/dist/extensions/index.d.cts +2 -2
- package/dist/extensions/index.d.ts +2 -2
- package/dist/extensions/index.js +6 -6
- package/dist/{index-Dt9lzydb.d.ts → index-CALDD35B.d.ts} +1 -1
- package/dist/{index-DOy9HzfC.d.cts → index-DIWB6xMf.d.cts} +1 -1
- package/dist/index.cjs +15 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -113
- package/dist/index.d.ts +6 -113
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/zip-4nG0YAH7.d.cts +110 -0
- package/dist/zip-4nG0YAH7.d.ts +110 -0
- package/package.json +1 -1
- package/dist/chunk-3CC7OPUQ.cjs.map +0 -1
- package/dist/chunk-3JNRQVTS.cjs.map +0 -1
- package/dist/chunk-5TWIN7ZJ.js.map +0 -1
- package/dist/chunk-GJBIVWB2.js.map +0 -1
- package/dist/chunk-GTZXF4BI.cjs.map +0 -1
- package/dist/chunk-JOX6MJW4.cjs.map +0 -1
- package/dist/chunk-MR2764X2.js.map +0 -1
- package/dist/chunk-OV7UAKIY.js.map +0 -1
- package/dist/chunk-TGBCBQFV.cjs.map +0 -1
- package/dist/chunk-WBOAXDKD.js.map +0 -1
- /package/dist/{chunk-T6XU4B54.js.map → chunk-BQQZ6MOI.js.map} +0 -0
- /package/dist/{chunk-DQPBQXKG.js.map → chunk-OIKYP7XC.js.map} +0 -0
- /package/dist/{chunk-QFTVLEVN.js.map → chunk-RIXTW3C4.js.map} +0 -0
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
describeChart,
|
|
7
7
|
layoutChart,
|
|
8
8
|
layoutSparkline
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VODBAO32.js";
|
|
10
10
|
import {
|
|
11
11
|
DEFAULT_CHART_THEME,
|
|
12
12
|
normalizeChartSpec
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-633QC34G.js";
|
|
14
14
|
import {
|
|
15
15
|
isTrackChangesEnabled
|
|
16
16
|
} from "./chunk-SWE3NPOU.js";
|
|
@@ -2057,4 +2057,4 @@ export {
|
|
|
2057
2057
|
getTableState,
|
|
2058
2058
|
createTableStore
|
|
2059
2059
|
};
|
|
2060
|
-
//# sourceMappingURL=chunk-
|
|
2060
|
+
//# sourceMappingURL=chunk-RIXTW3C4.js.map
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
DEFAULT_CHART_THEME,
|
|
5
5
|
chartColorsByCategory,
|
|
6
6
|
chartDataFromTable,
|
|
7
|
+
chartErrorAmounts,
|
|
7
8
|
chartFamily,
|
|
8
9
|
chartPointColor,
|
|
9
10
|
chartSeriesColor,
|
|
@@ -13,12 +14,13 @@ import {
|
|
|
13
14
|
cloneChartSeries,
|
|
14
15
|
cloneChartSpec,
|
|
15
16
|
defaultChartAxis,
|
|
17
|
+
describeChartErrorBars,
|
|
16
18
|
normalizeChartSpec,
|
|
17
19
|
normalizeChartTrendline,
|
|
18
20
|
parseChartValue,
|
|
19
21
|
shadeChartColor,
|
|
20
22
|
uniqueChartSeriesId
|
|
21
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-633QC34G.js";
|
|
22
24
|
import {
|
|
23
25
|
NumberFormat
|
|
24
26
|
} from "./chunk-EKYHKQPG.js";
|
|
@@ -639,6 +641,50 @@ function linearMap(value, domain, range) {
|
|
|
639
641
|
if (d1 === d0) return (r0 + r1) / 2;
|
|
640
642
|
return r0 + (value - d0) / (d1 - d0) * (r1 - r0);
|
|
641
643
|
}
|
|
644
|
+
var tidy = (n) => n === 0 ? 0 : Number(n.toPrecision(12));
|
|
645
|
+
function niceLogScale(lo, hi, count = 5, base = 10, fixedMin = null, fixedMax = null) {
|
|
646
|
+
if (!(base > 1) || !Number.isFinite(base)) base = 10;
|
|
647
|
+
if (fixedMin !== null && !(fixedMin > 0 && Number.isFinite(fixedMin))) fixedMin = null;
|
|
648
|
+
if (fixedMax !== null && !(fixedMax > 0 && Number.isFinite(fixedMax))) fixedMax = null;
|
|
649
|
+
if (!(lo > 0) || !Number.isFinite(lo)) lo = hi > 0 && Number.isFinite(hi) ? hi : fixedMin ?? 1;
|
|
650
|
+
if (!(hi > 0) || !Number.isFinite(hi)) hi = Math.max(lo, fixedMax ?? lo * base);
|
|
651
|
+
if (lo > hi) [lo, hi] = [hi, lo];
|
|
652
|
+
const log = (v) => Math.log(v) / Math.log(base);
|
|
653
|
+
const e0 = Math.floor(log(fixedMin ?? lo) + 1e-9);
|
|
654
|
+
let e1 = Math.ceil(log(fixedMax ?? hi) - 1e-9);
|
|
655
|
+
if (e1 <= e0) e1 = e0 + 1;
|
|
656
|
+
let min = fixedMin ?? tidy(Math.pow(base, e0));
|
|
657
|
+
let max = fixedMax ?? tidy(Math.pow(base, e1));
|
|
658
|
+
if (!(max > min)) {
|
|
659
|
+
if (fixedMax === null) max = tidy(min * base);
|
|
660
|
+
else min = tidy(max / base);
|
|
661
|
+
}
|
|
662
|
+
if (!Number.isFinite(max)) max = Number.MAX_VALUE;
|
|
663
|
+
if (!(min > 0)) min = Number.MIN_VALUE;
|
|
664
|
+
const inside = (t) => t >= min * (1 - 1e-9) && t <= max * (1 + 1e-9);
|
|
665
|
+
const decades = Math.max(1, log(max) - log(min));
|
|
666
|
+
let ticks = [];
|
|
667
|
+
const first = Math.ceil(log(min) - 1e-9);
|
|
668
|
+
const last = Math.floor(log(max) + 1e-9);
|
|
669
|
+
if (base === 10 && decades * 3 <= count + 1) {
|
|
670
|
+
for (let e = first - 1; e <= last; e++) for (const m of [1, 2, 5]) ticks.push(tidy(m * Math.pow(10, e)));
|
|
671
|
+
} else {
|
|
672
|
+
const every = Math.max(1, Math.ceil((last - first + 1) / (count + 2)));
|
|
673
|
+
for (let e = Math.ceil(first / every) * every; e <= last && ticks.length < 1e3; e += every) ticks.push(tidy(Math.pow(base, e)));
|
|
674
|
+
}
|
|
675
|
+
ticks = ticks.filter((t) => Number.isFinite(t) && t > 0 && inside(t));
|
|
676
|
+
if (ticks.length < 2) ticks = niceScale(min, max, count, min, max).ticks.filter((t) => t > 0);
|
|
677
|
+
return { min, max, step: base, ticks: [...new Set(ticks)].sort((a, b) => a - b) };
|
|
678
|
+
}
|
|
679
|
+
function chartScaleToPixel(value, scale) {
|
|
680
|
+
if (!scale.logBase) return linearMap(value, scale.domain, scale.range);
|
|
681
|
+
if (!(value > 0)) return NaN;
|
|
682
|
+
return linearMap(Math.log(value), [Math.log(scale.domain[0]), Math.log(scale.domain[1])], scale.range);
|
|
683
|
+
}
|
|
684
|
+
function chartScaleFromPixel(px, scale) {
|
|
685
|
+
if (!scale.logBase) return linearMap(px, scale.range, scale.domain);
|
|
686
|
+
return Math.exp(linearMap(px, scale.range, [Math.log(scale.domain[0]), Math.log(scale.domain[1])]));
|
|
687
|
+
}
|
|
642
688
|
|
|
643
689
|
// src/chart/layout-shared.ts
|
|
644
690
|
var estimateChartTextWidth = (text, size, weight = 400) => text.length * size * (weight >= 600 ? 0.6 : 0.56);
|
|
@@ -752,6 +798,7 @@ var tickCount = (length) => Math.max(2, Math.min(10, Math.round(length / 56)));
|
|
|
752
798
|
function axisScale(lo, hi, length, axis, frozen, headroom = false) {
|
|
753
799
|
const fixedMin = frozen && Number.isFinite(frozen.min) ? frozen.min : axis.min;
|
|
754
800
|
const fixedMax = frozen && Number.isFinite(frozen.max) ? frozen.max : axis.max;
|
|
801
|
+
if (axis.scale === "log") return niceLogScale(lo, hi, tickCount(length), axis.logBase ?? 10, fixedMin, fixedMax);
|
|
755
802
|
const step = axis.step;
|
|
756
803
|
if (step && step > 0 && Number.isFinite(lo) && Number.isFinite(hi)) {
|
|
757
804
|
let min = fixedMin ?? Math.floor(lo / step + 1e-9) * step;
|
|
@@ -1179,11 +1226,14 @@ function chartSupportsTrendlines(type, stacking) {
|
|
|
1179
1226
|
var MAX_CHART_DATA_LABELS = 200;
|
|
1180
1227
|
var MAX_CHART_LINE_POINTS = 2e3;
|
|
1181
1228
|
var MAX_CHART_MARKERS = 1e3;
|
|
1182
|
-
function scaleInfo(scale, range, format) {
|
|
1183
|
-
const
|
|
1184
|
-
const
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1229
|
+
function scaleInfo(scale, range, format, axis) {
|
|
1230
|
+
const logBase = axis?.scale === "log" ? axis.logBase ?? 10 : void 0;
|
|
1231
|
+
const r = axis?.reverse ? [range[1], range[0]] : range;
|
|
1232
|
+
const vs = { domain: [scale.min, scale.max], range: r, logBase };
|
|
1233
|
+
const raw = (v) => chartScaleToPixel(v, vs);
|
|
1234
|
+
const px = (v) => logBase && !(v > 0) ? r[0] : raw(Math.min(scale.max, Math.max(scale.min, v)));
|
|
1235
|
+
const tickText = (t) => formatChartNumber(t, format, logBase ? format.decimals : format.decimals ?? stepDecimals(scale.step));
|
|
1236
|
+
return { scale, range: r, px, raw, zero: px(0), format, tickText, ...logBase ? { logBase } : {} };
|
|
1187
1237
|
}
|
|
1188
1238
|
function categoryFrame(ctx, area, input) {
|
|
1189
1239
|
const { spec, theme, measure, fs, marks } = ctx;
|
|
@@ -1194,7 +1244,7 @@ function categoryFrame(ctx, area, input) {
|
|
|
1194
1244
|
const labelTarget = input.labelTarget ?? ((i) => ({ kind: "category", index: i }));
|
|
1195
1245
|
const estimate = (v, length) => {
|
|
1196
1246
|
const s = axisScale(v.lo, v.hi, length, v.axis, v.frozen, v.headroom);
|
|
1197
|
-
const info = scaleInfo(s, [0, 1], v.format);
|
|
1247
|
+
const info = scaleInfo(s, [0, 1], v.format, v.axis);
|
|
1198
1248
|
return Math.max(0, ...s.ticks.map((t) => measure(info.tickText(t), fs)));
|
|
1199
1249
|
};
|
|
1200
1250
|
const valueLen0 = horizontal ? area.width : area.height;
|
|
@@ -1232,12 +1282,12 @@ function categoryFrame(ctx, area, input) {
|
|
|
1232
1282
|
};
|
|
1233
1283
|
const valueLen = horizontal ? plot.width : plot.height;
|
|
1234
1284
|
const range = horizontal ? [plot.x, plot.x + plot.width] : [plot.y + plot.height, plot.y];
|
|
1235
|
-
const value = scaleInfo(axisScale(primary.lo, primary.hi, valueLen, primary.axis, primary.frozen, primary.headroom), range, primary.format);
|
|
1236
|
-
const value2 = secondary ? scaleInfo(axisScale(secondary.lo, secondary.hi, valueLen, secondary.axis, secondary.frozen, secondary.headroom), range, secondary.format) : void 0;
|
|
1285
|
+
const value = scaleInfo(axisScale(primary.lo, primary.hi, valueLen, primary.axis, primary.frozen, primary.headroom), range, primary.format, primary.axis);
|
|
1286
|
+
const value2 = secondary ? scaleInfo(axisScale(secondary.lo, secondary.hi, valueLen, secondary.axis, secondary.frozen, secondary.headroom), range, secondary.format, secondary.axis) : void 0;
|
|
1237
1287
|
const catStart = horizontal ? plot.y : plot.x;
|
|
1238
1288
|
const catLen = horizontal ? plot.height : plot.width;
|
|
1239
1289
|
const band = catLen / n;
|
|
1240
|
-
const catCenter = (i) => catStart + band * (i + 0.5);
|
|
1290
|
+
const catCenter = (i) => catStart + band * (xAxis.reverse ? n - i - 0.5 : i + 0.5);
|
|
1241
1291
|
const map = (p) => horizontal ? [p.v, p.c] : [p.c, p.v];
|
|
1242
1292
|
const gridAt = (info, key) => info.scale.ticks.forEach((t, i) => {
|
|
1243
1293
|
const p = info.px(t);
|
|
@@ -1341,20 +1391,29 @@ function categoryFrame(ctx, area, input) {
|
|
|
1341
1391
|
}
|
|
1342
1392
|
return { plot, horizontal, n, band, catStart, catLen, catCenter, map, value, value2 };
|
|
1343
1393
|
}
|
|
1344
|
-
var toValueScale = (info, axis) => ({ axis, domain: [info.scale.min, info.scale.max], range: info.range, ticks: info.scale.ticks });
|
|
1394
|
+
var toValueScale = (info, axis) => ({ axis, domain: [info.scale.min, info.scale.max], range: info.range, ticks: info.scale.ticks, ...info.logBase ? { logBase: info.logBase } : {} });
|
|
1395
|
+
function errorBarPath(map, c, a, b, width, capA, capB) {
|
|
1396
|
+
if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(c) || Math.abs(a - b) < 0.01 && !capA && !capB) return "";
|
|
1397
|
+
const at = (across, along) => map({ c: across, v: along }).map(r2).join(",");
|
|
1398
|
+
let d = `M${at(c, a)}L${at(c, b)}`;
|
|
1399
|
+
if (capA) d += `M${at(c - width / 2, a)}L${at(c + width / 2, a)}`;
|
|
1400
|
+
if (capB) d += `M${at(c - width / 2, b)}L${at(c + width / 2, b)}`;
|
|
1401
|
+
return d;
|
|
1402
|
+
}
|
|
1345
1403
|
var order = (t) => t === "area" ? 0 : t === "bar" ? 1 : t === "line" ? 2 : 3;
|
|
1346
1404
|
function pointMark(base, shape, cx, cy, r, fill, stroke, strokeWidth) {
|
|
1347
1405
|
if (shape === "circle" || shape === "hit" || shape === "none") return { kind: "circle", role: "point", ...base, cx, cy, r, fill, ...stroke ? { stroke, strokeWidth } : {} };
|
|
1348
1406
|
const closed = shape !== "cross";
|
|
1349
1407
|
return { kind: "path", role: "point", ...base, d: markerPath(shape, cx, cy, r), fill: closed ? fill : "none", stroke: stroke ?? fill, strokeWidth: strokeWidth ?? 2 };
|
|
1350
1408
|
}
|
|
1351
|
-
function drawTrendlines(ctx, plot, series, color, points, toPx, labels) {
|
|
1409
|
+
function drawTrendlines(ctx, plot, series, color, points, toPx, labels, logAxis = false) {
|
|
1352
1410
|
(series.trendlines ?? []).forEach((t, ti) => {
|
|
1353
1411
|
const target = { kind: "trendline", seriesId: series.id, index: ti };
|
|
1354
1412
|
const selected = ctx.isSelected(target);
|
|
1355
1413
|
const stroke = t.color ?? color;
|
|
1356
1414
|
let px = [];
|
|
1357
|
-
|
|
1415
|
+
const finitePx = (q) => Number.isFinite(q[0]) && Number.isFinite(q[1]);
|
|
1416
|
+
if (t.type === "moving-average") px = chartMovingAverage(points, t.period ?? 2).map(([x, y]) => toPx(x, y)).filter(finitePx);
|
|
1358
1417
|
else {
|
|
1359
1418
|
const fit = fitChartTrendline(t, points);
|
|
1360
1419
|
if (!fit) {
|
|
@@ -1364,11 +1423,12 @@ function drawTrendlines(ctx, plot, series, color, points, toPx, labels) {
|
|
|
1364
1423
|
const xs = points.map((p) => p[0]);
|
|
1365
1424
|
const lo = Math.min(...xs) - (t.backward ?? 0);
|
|
1366
1425
|
const hi = Math.max(...xs) + (t.forward ?? 0);
|
|
1367
|
-
const steps = t.type === "linear" ? 1 : 200;
|
|
1426
|
+
const steps = t.type === "linear" && !logAxis ? 1 : 200;
|
|
1368
1427
|
for (let k = 0; k <= steps; k++) {
|
|
1369
1428
|
const x = lo + (hi - lo) * k / steps;
|
|
1370
1429
|
const y = fit.evaluate(x);
|
|
1371
|
-
|
|
1430
|
+
const q = y === null ? null : toPx(x, y);
|
|
1431
|
+
if (q && finitePx(q)) px.push(q);
|
|
1372
1432
|
}
|
|
1373
1433
|
if (t.showEquation) labels.push({ text: fit.equation, color: stroke, target });
|
|
1374
1434
|
if (t.showR2) labels.push({ text: fit.r2 === null ? "R\xB2 = #N/A" : `R\xB2 = ${trendNumberText(fit.r2)}`, color: stroke, target });
|
|
@@ -1444,10 +1504,29 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1444
1504
|
}
|
|
1445
1505
|
}
|
|
1446
1506
|
}
|
|
1507
|
+
const logOf = (secondary) => (secondary ? spec.yAxis2 : spec.yAxis).scale === "log";
|
|
1508
|
+
const errors = /* @__PURE__ */ new Map();
|
|
1509
|
+
for (const s of visible) {
|
|
1510
|
+
if (!s.errorBars) continue;
|
|
1511
|
+
const stack = stacks.get(s.id);
|
|
1512
|
+
errors.set(
|
|
1513
|
+
s.id,
|
|
1514
|
+
chartErrorAmounts(s.errorBars, s.values).map((e, i) => {
|
|
1515
|
+
const raw = s.values[i];
|
|
1516
|
+
const seg = stack?.segments[i];
|
|
1517
|
+
if (!e || raw === null || stack && !seg) return null;
|
|
1518
|
+
const k = seg && percent ? raw ? (seg[1] - seg[0]) / raw : 0 : 1;
|
|
1519
|
+
const center = (seg ? seg[1] : raw) + (e.center - raw) * k;
|
|
1520
|
+
return { center, lo: center - e.minus * k, hi: center + e.plus * k };
|
|
1521
|
+
})
|
|
1522
|
+
);
|
|
1523
|
+
}
|
|
1447
1524
|
const range = (secondary) => {
|
|
1448
1525
|
let lo = Infinity;
|
|
1449
1526
|
let hi = -Infinity;
|
|
1527
|
+
const log = logOf(secondary);
|
|
1450
1528
|
const see = (v) => {
|
|
1529
|
+
if (!Number.isFinite(v) || log && !(v > 0)) return;
|
|
1451
1530
|
lo = Math.min(lo, v);
|
|
1452
1531
|
hi = Math.max(hi, v);
|
|
1453
1532
|
};
|
|
@@ -1455,13 +1534,18 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1455
1534
|
for (const s of group) {
|
|
1456
1535
|
const stack = stacks.get(s.id);
|
|
1457
1536
|
if (stack) stack.segments.forEach((seg) => seg && (see(seg[0]), see(seg[1])));
|
|
1458
|
-
else s.values.forEach((v) => v !== null &&
|
|
1537
|
+
else s.values.forEach((v) => v !== null && see(v));
|
|
1538
|
+
errors.get(s.id)?.forEach((e) => e && (see(e.lo), see(e.hi)));
|
|
1539
|
+
}
|
|
1540
|
+
if (log) {
|
|
1541
|
+
const skipped = group.reduce((t, s) => t + s.values.filter((v) => v !== null && Number.isFinite(v) && v <= 0).length, 0);
|
|
1542
|
+
if (skipped) ctx.warn("values-skipped", `${skipped} value${skipped === 1 ? "" : "s"} of 0 or less cannot be drawn on the logarithmic ${secondary ? "secondary " : ""}value axis and ${skipped === 1 ? "was" : "were"} skipped.`);
|
|
1459
1543
|
}
|
|
1460
1544
|
if (!Number.isFinite(lo)) {
|
|
1461
|
-
lo = 0;
|
|
1462
|
-
hi = 1;
|
|
1545
|
+
lo = log ? 1 : 0;
|
|
1546
|
+
hi = log ? 10 : 1;
|
|
1463
1547
|
}
|
|
1464
|
-
if (group.some((s) => types.get(s.id) === "bar" || types.get(s.id) === "area")) {
|
|
1548
|
+
if (!log && group.some((s) => types.get(s.id) === "bar" || types.get(s.id) === "area")) {
|
|
1465
1549
|
lo = Math.min(lo, 0);
|
|
1466
1550
|
hi = Math.max(hi, 0);
|
|
1467
1551
|
}
|
|
@@ -1487,6 +1571,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1487
1571
|
const barWidth = slots ? groupWidth / (slots - (slots - 1) * o) : 0;
|
|
1488
1572
|
const slotOf = (s) => stacked ? barAxes.indexOf(onSecondary(s)) : bars.indexOf(s);
|
|
1489
1573
|
const labelMarks = [];
|
|
1574
|
+
const errorMarks = [];
|
|
1490
1575
|
const trendLabels = [];
|
|
1491
1576
|
let hiddenLabels = 0;
|
|
1492
1577
|
const trendsAllowed = chartSupportsTrendlines(spec.type, spec.stacking);
|
|
@@ -1500,6 +1585,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1500
1585
|
const seriesTarget = { kind: "series", seriesId: s.id };
|
|
1501
1586
|
const info = infoOf(s);
|
|
1502
1587
|
const valuePx = info.px;
|
|
1588
|
+
const log = logOf(onSecondary(s));
|
|
1503
1589
|
const labelsOn = (s.dataLabels ?? spec.dataLabels) && s.values.length <= MAX_CHART_DATA_LABELS;
|
|
1504
1590
|
if ((s.dataLabels ?? spec.dataLabels) && !labelsOn) ctx.warn("data-labels-hidden", `Data labels are off for "${s.name}": it has more than ${MAX_CHART_DATA_LABELS} points.`);
|
|
1505
1591
|
const labelFormat = s.format ?? info.format;
|
|
@@ -1509,6 +1595,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1509
1595
|
s.values.forEach((raw, i) => {
|
|
1510
1596
|
const seg = stack ? stack.segments[i] : raw === null ? null : [0, raw];
|
|
1511
1597
|
if (!seg || raw === null || !Number.isFinite(raw)) return;
|
|
1598
|
+
if (log && (raw <= 0 || seg[1] <= 0)) return;
|
|
1512
1599
|
const a = valuePx(seg[0]);
|
|
1513
1600
|
const b = valuePx(seg[1]);
|
|
1514
1601
|
const c0 = catCenter(i) - groupWidth / 2 + slot * barWidth * (1 - o);
|
|
@@ -1533,7 +1620,8 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1533
1620
|
if (labelsOn) {
|
|
1534
1621
|
const v = percent ? seg[1] - seg[0] : raw;
|
|
1535
1622
|
const text = dataLabel(v);
|
|
1536
|
-
const
|
|
1623
|
+
const grows = horizontal ? b >= a : b <= a;
|
|
1624
|
+
const at = barLabel(ctx, text, rect, horizontal, grows, stacked, fill, plot);
|
|
1537
1625
|
if (!at) {
|
|
1538
1626
|
hiddenLabels++;
|
|
1539
1627
|
return;
|
|
@@ -1545,7 +1633,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1545
1633
|
const curve = s.curve ?? spec.curve;
|
|
1546
1634
|
const pointValue = (i) => {
|
|
1547
1635
|
const v = stack ? stack.segments[i]?.[1] ?? null : s.values[i];
|
|
1548
|
-
return v !== null && Number.isFinite(v) ? v : null;
|
|
1636
|
+
return v !== null && Number.isFinite(v) && !(log && (v <= 0 || (s.values[i] ?? 0) <= 0)) ? v : null;
|
|
1549
1637
|
};
|
|
1550
1638
|
const runs = [];
|
|
1551
1639
|
let run = [];
|
|
@@ -1556,7 +1644,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1556
1644
|
run = [];
|
|
1557
1645
|
continue;
|
|
1558
1646
|
}
|
|
1559
|
-
run.push({ c: catCenter(i), v: valuePx(v) });
|
|
1647
|
+
run.push({ c: catCenter(i), v: valuePx(v), i });
|
|
1560
1648
|
}
|
|
1561
1649
|
if (run.length) runs.push(run);
|
|
1562
1650
|
const thin = (r) => {
|
|
@@ -1568,7 +1656,7 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1568
1656
|
const drawn = runs.map(thin);
|
|
1569
1657
|
if (type === "area") {
|
|
1570
1658
|
const parts = drawn.map((r) => {
|
|
1571
|
-
const baseline = stack ? r.map((pt) => ({ c: pt.c, v: valuePx(stack.segments[
|
|
1659
|
+
const baseline = stack ? r.map((pt) => ({ c: pt.c, v: valuePx(stack.segments[pt.i]?.[0] ?? 0) })).reverse() : [
|
|
1572
1660
|
{ c: r[r.length - 1].c, v: info.zero },
|
|
1573
1661
|
{ c: r[0].c, v: info.zero }
|
|
1574
1662
|
];
|
|
@@ -1620,14 +1708,26 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1620
1708
|
}
|
|
1621
1709
|
}
|
|
1622
1710
|
}
|
|
1711
|
+
const errs = errors.get(s.id);
|
|
1712
|
+
if (errs) {
|
|
1713
|
+
const slot = type === "bar" ? slotOf(s) : 0;
|
|
1714
|
+
const capWidth = type === "bar" ? Math.min(10, barWidth * 0.5) : 8;
|
|
1715
|
+
const cap = s.errorBars.cap !== false;
|
|
1716
|
+
errs.forEach((e, i) => {
|
|
1717
|
+
if (!e || log && !((s.values[i] ?? 0) > 0)) return;
|
|
1718
|
+
const c = type === "bar" ? catCenter(i) - groupWidth / 2 + slot * barWidth * (1 - o) + barWidth / 2 : catCenter(i);
|
|
1719
|
+
const d = errorBarPath(map, c, valuePx(e.lo), valuePx(e.hi), capWidth, cap && e.lo < e.center, cap && e.hi > e.center);
|
|
1720
|
+
if (d) errorMarks.push({ kind: "path", key: `error-bar-${s.id}-${i}`, role: "error-bar", d, fill: "none", stroke: type === "bar" ? theme.text : color, strokeWidth: selSeries ? 2 : 1.25, target: seriesTarget, selected: selSeries });
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1623
1723
|
if (trendsAllowed && s.trendlines?.length) {
|
|
1624
1724
|
const points = [];
|
|
1625
1725
|
s.values.forEach((v, i) => v !== null && Number.isFinite(v) && points.push([i + 1, v]));
|
|
1626
|
-
const toPx = (x, y) => map({ c:
|
|
1627
|
-
drawTrendlines(ctx, plot, s, color, points, toPx, trendLabels);
|
|
1726
|
+
const toPx = (x, y) => map({ c: catCenter(x - 1), v: info.raw(y) });
|
|
1727
|
+
drawTrendlines(ctx, plot, s, color, points, toPx, trendLabels, !!info.logBase);
|
|
1628
1728
|
}
|
|
1629
1729
|
}
|
|
1630
|
-
marks.push(...labelMarks);
|
|
1730
|
+
marks.push(...errorMarks, ...labelMarks);
|
|
1631
1731
|
drawTrendLabels(ctx, plot, trendLabels);
|
|
1632
1732
|
if (hiddenLabels) ctx.warn("data-labels-hidden", `${hiddenLabels} data label${hiddenLabels === 1 ? "" : "s"} did not fit and ${hiddenLabels === 1 ? "is" : "are"} hidden.`);
|
|
1633
1733
|
return {
|
|
@@ -1640,33 +1740,60 @@ function layoutCartesian(ctx, area, visible) {
|
|
|
1640
1740
|
function layoutXy(ctx, area, visible) {
|
|
1641
1741
|
const { spec, theme, marks, measure, fs } = ctx;
|
|
1642
1742
|
const bubble = spec.type === "bubble";
|
|
1643
|
-
const
|
|
1743
|
+
const yAxis = spec.yAxis;
|
|
1744
|
+
const xAxis = spec.xAxis;
|
|
1745
|
+
const xLog = xAxis.scale === "log";
|
|
1746
|
+
const yLog = yAxis.scale === "log";
|
|
1747
|
+
let skipped = 0;
|
|
1748
|
+
const pointsOf = (s) => s.values.map((y, i) => ({ i, x: s.x?.[i] ?? (bubble || !s.x ? i + 1 : null), y, size: s.sizes?.[i] ?? null })).filter((p) => {
|
|
1749
|
+
if (p.x === null || p.y === null || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return false;
|
|
1750
|
+
if (xLog && p.x <= 0 || yLog && p.y <= 0) return skipped++, false;
|
|
1751
|
+
return true;
|
|
1752
|
+
});
|
|
1644
1753
|
const all = visible.map((s) => ({ s, pts: pointsOf(s) }));
|
|
1754
|
+
if (skipped) ctx.warn("values-skipped", `${skipped} point${skipped === 1 ? "" : "s"} with a value of 0 or less cannot be drawn on the logarithmic ${xLog && yLog ? "axes" : xLog ? "x axis" : "value axis"} and ${skipped === 1 ? "was" : "were"} skipped.`);
|
|
1755
|
+
const yErrors = /* @__PURE__ */ new Map();
|
|
1756
|
+
const xErrors = /* @__PURE__ */ new Map();
|
|
1757
|
+
for (const { s } of all) {
|
|
1758
|
+
if (s.errorBars) yErrors.set(s.id, chartErrorAmounts(s.errorBars, s.values));
|
|
1759
|
+
if (s.xErrorBars) xErrors.set(s.id, chartErrorAmounts(s.xErrorBars, s.values.map((_, i) => s.x?.[i] ?? (bubble || !s.x ? i + 1 : null))));
|
|
1760
|
+
}
|
|
1645
1761
|
let xlo = Infinity;
|
|
1646
1762
|
let xhi = -Infinity;
|
|
1647
1763
|
let ylo = Infinity;
|
|
1648
1764
|
let yhi = -Infinity;
|
|
1649
1765
|
let maxSize = 0;
|
|
1766
|
+
const seeX = (v) => {
|
|
1767
|
+
if (!Number.isFinite(v) || xLog && !(v > 0)) return;
|
|
1768
|
+
xlo = Math.min(xlo, v);
|
|
1769
|
+
xhi = Math.max(xhi, v);
|
|
1770
|
+
};
|
|
1771
|
+
const seeY = (v) => {
|
|
1772
|
+
if (!Number.isFinite(v) || yLog && !(v > 0)) return;
|
|
1773
|
+
ylo = Math.min(ylo, v);
|
|
1774
|
+
yhi = Math.max(yhi, v);
|
|
1775
|
+
};
|
|
1650
1776
|
for (const { s, pts } of all) {
|
|
1651
1777
|
for (const p of pts) {
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
ylo = Math.min(ylo, p.y);
|
|
1655
|
-
yhi = Math.max(yhi, p.y);
|
|
1778
|
+
seeX(p.x);
|
|
1779
|
+
seeY(p.y);
|
|
1656
1780
|
if (p.size !== null && p.size > maxSize) maxSize = p.size;
|
|
1781
|
+
const ey = yErrors.get(s.id)?.[p.i];
|
|
1782
|
+
if (ey) seeY(ey.center - ey.minus), seeY(ey.center + ey.plus);
|
|
1783
|
+
const ex = xErrors.get(s.id)?.[p.i];
|
|
1784
|
+
if (ex) seeX(ex.center - ex.minus), seeX(ex.center + ex.plus);
|
|
1657
1785
|
}
|
|
1658
1786
|
for (const t of s.trendlines ?? []) {
|
|
1659
1787
|
if (!pts.length) continue;
|
|
1660
|
-
|
|
1661
|
-
|
|
1788
|
+
seeX(Math.min(...pts.map((p) => p.x)) - (t.backward ?? 0));
|
|
1789
|
+
seeX(Math.max(...pts.map((p) => p.x)) + (t.forward ?? 0));
|
|
1662
1790
|
}
|
|
1663
1791
|
}
|
|
1664
|
-
if (!Number.isFinite(xlo)) [xlo, xhi
|
|
1792
|
+
if (!Number.isFinite(xlo)) [xlo, xhi] = xLog ? [1, 10] : [0, 1];
|
|
1793
|
+
if (!Number.isFinite(ylo)) [ylo, yhi] = yLog ? [1, 10] : [0, 1];
|
|
1665
1794
|
const titleBand = fs * 1.3 + 6;
|
|
1666
|
-
const yAxis = spec.yAxis;
|
|
1667
|
-
const xAxis = spec.xAxis;
|
|
1668
1795
|
const yEst = axisScale(ylo, yhi, area.height, yAxis, ctx.options.valueDomain, true);
|
|
1669
|
-
const yText = (t, step) => formatChartNumber(t, yAxis.format, yAxis.format.decimals ?? stepDecimals(step));
|
|
1796
|
+
const yText = (t, step) => formatChartNumber(t, yAxis.format, yAxis.format.decimals ?? (yLog ? void 0 : stepDecimals(step)));
|
|
1670
1797
|
const left = (yAxis.show ? Math.max(0, ...yEst.ticks.map((t) => measure(yText(t, yEst.step), fs))) + 8 : 2) + (yAxis.title ? titleBand : 0);
|
|
1671
1798
|
const bottom = (xAxis.show ? fs * 1.6 : 2) + (xAxis.title ? titleBand : 0);
|
|
1672
1799
|
const plot = { x: area.x + left, y: area.y + fs / 2 + 2, width: Math.max(1, area.width - left - 12), height: Math.max(1, area.height - bottom - fs / 2 - 2) };
|
|
@@ -1676,21 +1803,21 @@ function layoutXy(ctx, area, visible) {
|
|
|
1676
1803
|
const xScale = axisScale(xlo, xhi, plot.width, xAxis, ctx.options.xDomain, true);
|
|
1677
1804
|
const xRange = [plot.x + inset, plot.x + plot.width - inset];
|
|
1678
1805
|
const yRange = [plot.y + plot.height - inset, plot.y + inset];
|
|
1679
|
-
const
|
|
1680
|
-
const
|
|
1681
|
-
const
|
|
1682
|
-
const
|
|
1806
|
+
const xInfo = scaleInfo(xScale, xRange, xAxis.format, xAxis);
|
|
1807
|
+
const yInfo = scaleInfo(yScale, yRange, yAxis.format, yAxis);
|
|
1808
|
+
const { raw: xRaw, px: xPx } = xInfo;
|
|
1809
|
+
const { raw: yRaw, px: yPx } = yInfo;
|
|
1683
1810
|
const xTarget = { kind: "axis", axis: "x" };
|
|
1684
1811
|
const yTarget = { kind: "axis", axis: "y" };
|
|
1685
1812
|
if (yAxis.gridlines) yScale.ticks.forEach((t, i) => marks.push({ kind: "line", key: `grid-y-${i}`, role: "grid", x1: plot.x, y1: yPx(t), x2: plot.x + plot.width, y2: yPx(t), stroke: theme.grid, strokeWidth: 1 }));
|
|
1686
1813
|
if (xAxis.gridlines) xScale.ticks.forEach((t, i) => marks.push({ kind: "line", key: `grid-x-${i}`, role: "grid", x1: xPx(t), y1: plot.y, x2: xPx(t), y2: plot.y + plot.height, stroke: theme.grid, strokeWidth: 1 }));
|
|
1687
1814
|
if (yAxis.show) yScale.ticks.forEach((t, i) => marks.push({ kind: "text", key: `tick-y-${i}`, role: "tick-label", x: plot.x - 8, y: yPx(t), text: yText(t, yScale.step), anchor: "end", baseline: "middle", size: fs, fill: theme.mutedText, target: yTarget }));
|
|
1688
1815
|
if (xAxis.show) {
|
|
1689
|
-
const y0 = yScale.min <= 0 && yScale.max >= 0 ? yPx(0) : plot.y + plot.height;
|
|
1816
|
+
const y0 = !yLog && yScale.min <= 0 && yScale.max >= 0 ? yPx(0) : yAxis.reverse ? plot.y : plot.y + plot.height;
|
|
1690
1817
|
marks.push({ kind: "line", key: "axis-x", role: "axis", x1: plot.x, y1: y0, x2: plot.x + plot.width, y2: y0, stroke: theme.axis, strokeWidth: 1, target: xTarget });
|
|
1691
|
-
const texts = xScale.ticks.map((t) => formatChartNumber(t, xAxis.format, xAxis.format.decimals ?? stepDecimals(xScale.step)));
|
|
1818
|
+
const texts = xScale.ticks.map((t) => formatChartNumber(t, xAxis.format, xAxis.format.decimals ?? (xLog ? void 0 : stepDecimals(xScale.step))));
|
|
1692
1819
|
const widest = Math.max(0, ...texts.map((t) => measure(t, fs)));
|
|
1693
|
-
const spacing = xScale.ticks.
|
|
1820
|
+
const spacing = Math.min(Infinity, ...xScale.ticks.slice(1).map((t, i) => Math.abs(xPx(t) - xPx(xScale.ticks[i]))));
|
|
1694
1821
|
const every = Math.max(1, Math.ceil((widest + 8) / spacing));
|
|
1695
1822
|
xScale.ticks.forEach((t, i) => {
|
|
1696
1823
|
if (i % every) return;
|
|
@@ -1704,6 +1831,7 @@ function layoutXy(ctx, area, visible) {
|
|
|
1704
1831
|
ctx.outline(`axis-${axis}-selection`, axis === "y" ? { x: area.x, y: plot.y - fs / 2, width: left - 2, height: plot.height + fs } : { x: plot.x - 4, y: plot.y + plot.height + 2, width: plot.width + 8, height: area.y + area.height - plot.y - plot.height - 2 });
|
|
1705
1832
|
}
|
|
1706
1833
|
const labelMarks = [];
|
|
1834
|
+
const errorMarks = [];
|
|
1707
1835
|
const trendLabels = [];
|
|
1708
1836
|
for (const { s, pts } of all) {
|
|
1709
1837
|
const si = spec.series.indexOf(s);
|
|
@@ -1740,14 +1868,32 @@ function layoutXy(ctx, area, visible) {
|
|
|
1740
1868
|
if (selected) marks.push({ kind: "circle", key: `point-${s.id}-${p.i}-selection`, role: "selection", cx, cy, r: r + 3.5, fill: "none", stroke: theme.selection, strokeWidth: 1.5 });
|
|
1741
1869
|
if (labelsOn) labelMarks.push({ kind: "text", key: `label-${s.id}-${p.i}`, role: "data-label", x: cx, y: cy - r - 4, text: formatChartNumber(p.y, labelFormat), anchor: "middle", baseline: "bottom", size: fs - 1, fill: theme.text, target });
|
|
1742
1870
|
}
|
|
1743
|
-
|
|
1871
|
+
const stroke = color;
|
|
1872
|
+
const errorBar = (key, d) => d && errorMarks.push({ kind: "path", key, role: "error-bar", d, fill: "none", stroke, strokeWidth: selSeries ? 2 : 1.25, target: seriesTarget, selected: selSeries });
|
|
1873
|
+
for (const p of pts) {
|
|
1874
|
+
const ey = yErrors.get(s.id)?.[p.i];
|
|
1875
|
+
if (ey) {
|
|
1876
|
+
const lo = ey.center - ey.minus;
|
|
1877
|
+
const hi = ey.center + ey.plus;
|
|
1878
|
+
const cap = s.errorBars.cap !== false;
|
|
1879
|
+
errorBar(`error-bar-${s.id}-${p.i}`, errorBarPath((q) => [q.c, q.v], xPx(p.x), yPx(lo), yPx(hi), 8, cap && lo < ey.center, cap && hi > ey.center));
|
|
1880
|
+
}
|
|
1881
|
+
const ex = xErrors.get(s.id)?.[p.i];
|
|
1882
|
+
if (ex) {
|
|
1883
|
+
const lo = ex.center - ex.minus;
|
|
1884
|
+
const hi = ex.center + ex.plus;
|
|
1885
|
+
const cap = s.xErrorBars.cap !== false;
|
|
1886
|
+
errorBar(`error-bar-x-${s.id}-${p.i}`, errorBarPath((q) => [q.v, q.c], yPx(p.y), xPx(lo), xPx(hi), 8, cap && lo < ex.center, cap && hi > ex.center));
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
if (s.trendlines?.length) drawTrendlines(ctx, plot, s, color, pts.map((p) => [p.x, p.y]), (x, y) => [xRaw(x), yRaw(y)], trendLabels, xLog || yLog);
|
|
1744
1890
|
}
|
|
1745
|
-
marks.push(...labelMarks);
|
|
1891
|
+
marks.push(...errorMarks, ...labelMarks);
|
|
1746
1892
|
drawTrendLabels(ctx, plot, trendLabels);
|
|
1747
1893
|
return {
|
|
1748
1894
|
plot,
|
|
1749
|
-
valueScale:
|
|
1750
|
-
xScale:
|
|
1895
|
+
valueScale: toValueScale(yInfo, "y"),
|
|
1896
|
+
xScale: toValueScale(xInfo, "x")
|
|
1751
1897
|
};
|
|
1752
1898
|
}
|
|
1753
1899
|
function trendlineLegendItems(spec, color) {
|
|
@@ -2364,14 +2510,15 @@ function chartValueAtPoint(scene, point, secondary = false) {
|
|
|
2364
2510
|
const scale = secondary ? scene.valueScale2 ?? scene.valueScale : scene.valueScale;
|
|
2365
2511
|
if (!scale || scene.percent) return void 0;
|
|
2366
2512
|
const px = scale.axis === "y" ? point.y : point.x;
|
|
2367
|
-
return
|
|
2513
|
+
return chartScaleFromPixel(px, scale);
|
|
2368
2514
|
}
|
|
2369
2515
|
function chartXAtPoint(scene, point) {
|
|
2370
2516
|
const scale = scene.xScale;
|
|
2371
2517
|
if (!scale) return void 0;
|
|
2372
|
-
return
|
|
2518
|
+
return chartScaleFromPixel(point.x, scale);
|
|
2373
2519
|
}
|
|
2374
|
-
function snapChartValue(scene, value, step, ticks = scene.valueScale?.ticks ?? []) {
|
|
2520
|
+
function snapChartValue(scene, value, step, ticks = scene.valueScale?.ticks ?? [], logBase) {
|
|
2521
|
+
if (logBase && step === void 0) return value > 0 && Number.isFinite(value) ? Number(value.toPrecision(2)) : value;
|
|
2375
2522
|
const unit = step ?? (ticks.length > 1 ? (ticks[1] - ticks[0]) / 10 : 1);
|
|
2376
2523
|
if (!(unit > 0)) return value;
|
|
2377
2524
|
const snapped = Math.round(value / unit) * unit;
|
|
@@ -2384,15 +2531,15 @@ function summarizeChart(spec, size = { width: 640, height: 400 }, scene = layout
|
|
|
2384
2531
|
const series = visible.map((s) => summarizeChartSeries(s, spec.categories));
|
|
2385
2532
|
const colors = chartColorsByCategory(spec.type) ? spec.categories.map((_, i) => visible[0]?.pointColors?.[i] || chartSliceColor(spec, i)) : visible.map((s) => chartSeriesColor(spec, spec.series.indexOf(s)));
|
|
2386
2533
|
const check = checkChartColors(colors, { surface: scene.theme.surface.startsWith("var(") ? "#ffffff" : scene.theme.surface });
|
|
2387
|
-
const axis = (s) => s ? { min: s.domain[0], max: s.domain[1], ticks: [...s.ticks] } : void 0;
|
|
2534
|
+
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;
|
|
2388
2535
|
return {
|
|
2389
2536
|
type: spec.type,
|
|
2390
2537
|
title: spec.title,
|
|
2391
2538
|
categories: spec.categories.length,
|
|
2392
2539
|
series,
|
|
2393
|
-
...scene.valueScale ? { valueAxis: axis(scene.valueScale) } : {},
|
|
2394
|
-
...scene.valueScale2 ? { secondaryAxis: axis(scene.valueScale2) } : {},
|
|
2395
|
-
...scene.xScale ? { xAxis: axis(scene.xScale) } : {},
|
|
2540
|
+
...scene.valueScale ? { valueAxis: axis(scene.valueScale, spec.yAxis) } : {},
|
|
2541
|
+
...scene.valueScale2 ? { secondaryAxis: axis(scene.valueScale2, spec.yAxis2) } : {},
|
|
2542
|
+
...scene.xScale ? { xAxis: axis(scene.xScale, spec.xAxis) } : {},
|
|
2396
2543
|
warnings: scene.warnings,
|
|
2397
2544
|
colors: { ok: check.ok, issues: check.issues },
|
|
2398
2545
|
description: describeChart(spec, series)
|
|
@@ -2439,6 +2586,21 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
|
|
|
2439
2586
|
parts.push(`${s.name} ranges from ${fmt(s.min)} (${s.minAt}) to ${fmt(s.max)} (${s.maxAt})${trend}.`);
|
|
2440
2587
|
}
|
|
2441
2588
|
if (series.length > 8) parts.push(`${series.length - 8} more series are not described.`);
|
|
2589
|
+
const axes = [];
|
|
2590
|
+
for (const [a, name] of [
|
|
2591
|
+
[spec.yAxis, "value axis"],
|
|
2592
|
+
[spec.yAxis2, "secondary value axis"],
|
|
2593
|
+
[spec.xAxis, family === "xy" ? "x axis" : "category axis"]
|
|
2594
|
+
]) {
|
|
2595
|
+
if (name === "secondary value axis" && !spec.series.some((s) => !s.hidden && s.axis === "secondary")) continue;
|
|
2596
|
+
const log = a.scale === "log" && name !== "category axis";
|
|
2597
|
+
if (log || a.reverse) axes.push(`The ${name} is ${[log ? `logarithmic (base ${a.logBase ?? 10})` : "", a.reverse ? "reversed" : ""].filter(Boolean).join(" and ")}.`);
|
|
2598
|
+
}
|
|
2599
|
+
parts.push(...axes);
|
|
2600
|
+
for (const s of spec.series.filter((x) => !x.hidden && (x.errorBars || x.xErrorBars)).slice(0, 8)) {
|
|
2601
|
+
const bars = [s.errorBars ? describeChartErrorBars(s.errorBars) : "", s.xErrorBars ? `x ${describeChartErrorBars(s.xErrorBars)}` : ""].filter(Boolean).join(" and ");
|
|
2602
|
+
parts.push(`${s.name} has ${bars}.`);
|
|
2603
|
+
}
|
|
2442
2604
|
return parts.join(" ");
|
|
2443
2605
|
}
|
|
2444
2606
|
|
|
@@ -2879,7 +3041,7 @@ var ChartController = class {
|
|
|
2879
3041
|
if (patch.hidden) next.hidden = true;
|
|
2880
3042
|
else delete next.hidden;
|
|
2881
3043
|
}
|
|
2882
|
-
const resettable = ["axis", "x", "sizes", "pointColors", "marker", "curve", "dataLabels", "format"];
|
|
3044
|
+
const resettable = ["axis", "x", "sizes", "pointColors", "marker", "curve", "dataLabels", "format", "errorBars", "xErrorBars"];
|
|
2883
3045
|
for (const key of resettable) {
|
|
2884
3046
|
if (!(key in patch) || patch[key] === void 0) continue;
|
|
2885
3047
|
if (patch[key] === null) delete next[key];
|
|
@@ -3384,6 +3546,9 @@ export {
|
|
|
3384
3546
|
stepDecimals,
|
|
3385
3547
|
formatChartNumber,
|
|
3386
3548
|
linearMap,
|
|
3549
|
+
niceLogScale,
|
|
3550
|
+
chartScaleToPixel,
|
|
3551
|
+
chartScaleFromPixel,
|
|
3387
3552
|
estimateChartTextWidth,
|
|
3388
3553
|
sameChartSelection,
|
|
3389
3554
|
contrastingTextColor,
|
|
@@ -3421,4 +3586,4 @@ export {
|
|
|
3421
3586
|
layoutSparkline,
|
|
3422
3587
|
sparklineToSvg
|
|
3423
3588
|
};
|
|
3424
|
-
//# sourceMappingURL=chunk-
|
|
3589
|
+
//# sourceMappingURL=chunk-VODBAO32.js.map
|