@pixerate/editor 0.52.0 → 0.54.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.
Files changed (142) hide show
  1. package/dist/agent/index.cjs +37 -29
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +4 -3
  4. package/dist/agent/index.d.ts +4 -3
  5. package/dist/agent/index.js +16 -8
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/animation/index.cjs +15 -1
  8. package/dist/animation/index.cjs.map +1 -1
  9. package/dist/animation/index.d.cts +3 -226
  10. package/dist/animation/index.d.ts +3 -226
  11. package/dist/animation/index.js +14 -0
  12. package/dist/bridge/cli.cjs +36 -0
  13. package/dist/bridge/cli.cjs.map +1 -0
  14. package/dist/bridge/cli.d.cts +1 -0
  15. package/dist/bridge/cli.d.ts +1 -0
  16. package/dist/bridge/cli.js +36 -0
  17. package/dist/bridge/cli.js.map +1 -0
  18. package/dist/bridge/index.cjs +16 -0
  19. package/dist/bridge/index.cjs.map +1 -0
  20. package/dist/bridge/index.d.cts +65 -0
  21. package/dist/bridge/index.d.ts +65 -0
  22. package/dist/bridge/index.js +16 -0
  23. package/dist/bridge/index.js.map +1 -0
  24. package/dist/bridge-client-C5OziCRK.d.cts +148 -0
  25. package/dist/bridge-client-C5dRjrz5.d.ts +148 -0
  26. package/dist/canvas/index.cjs +1308 -528
  27. package/dist/canvas/index.cjs.map +1 -1
  28. package/dist/canvas/index.d.cts +309 -5
  29. package/dist/canvas/index.d.ts +309 -5
  30. package/dist/canvas/index.js +1295 -515
  31. package/dist/canvas/index.js.map +1 -1
  32. package/dist/chart/index.cjs +193 -192
  33. package/dist/chart/index.cjs.map +1 -1
  34. package/dist/chart/index.d.cts +77 -59
  35. package/dist/chart/index.d.ts +77 -59
  36. package/dist/chart/index.js +87 -86
  37. package/dist/chart/index.js.map +1 -1
  38. package/dist/{chunk-UAW5FEMD.js → chunk-3S72F46R.js} +66 -8
  39. package/dist/chunk-3S72F46R.js.map +1 -0
  40. package/dist/{chunk-5TWIN7ZJ.js → chunk-47WWV3LI.js} +34 -4
  41. package/dist/chunk-47WWV3LI.js.map +1 -0
  42. package/dist/{chunk-OV7UAKIY.js → chunk-633QC34G.js} +172 -1
  43. package/dist/chunk-633QC34G.js.map +1 -0
  44. package/dist/chunk-AWKPSOSX.js +401 -0
  45. package/dist/chunk-AWKPSOSX.js.map +1 -0
  46. package/dist/chunk-B6DSIEXA.js +96 -0
  47. package/dist/chunk-B6DSIEXA.js.map +1 -0
  48. package/dist/{chunk-5N6AQCVB.js → chunk-BQQZ6MOI.js} +3 -3
  49. package/dist/{chunk-M5Z77GFH.cjs → chunk-C3JHII3M.cjs} +53 -53
  50. package/dist/{chunk-M5Z77GFH.cjs.map → chunk-C3JHII3M.cjs.map} +1 -1
  51. package/dist/{chunk-JOX6MJW4.cjs → chunk-CKRNELPO.cjs} +176 -5
  52. package/dist/chunk-CKRNELPO.cjs.map +1 -0
  53. package/dist/{chunk-TGBCBQFV.cjs → chunk-DK6QBGCS.cjs} +45 -15
  54. package/dist/chunk-DK6QBGCS.cjs.map +1 -0
  55. package/dist/chunk-EGFUVXKK.cjs +96 -0
  56. package/dist/chunk-EGFUVXKK.cjs.map +1 -0
  57. package/dist/{chunk-AMWXSYCI.js → chunk-GPWNYQ7R.js} +2 -370
  58. package/dist/chunk-GPWNYQ7R.js.map +1 -0
  59. package/dist/chunk-H5K77C7Y.cjs +3848 -0
  60. package/dist/chunk-H5K77C7Y.cjs.map +1 -0
  61. package/dist/chunk-K73CKYUM.cjs +458 -0
  62. package/dist/chunk-K73CKYUM.cjs.map +1 -0
  63. package/dist/{chunk-GTZXF4BI.cjs → chunk-NK3WL5TJ.cjs} +298 -133
  64. package/dist/chunk-NK3WL5TJ.cjs.map +1 -0
  65. package/dist/{chunk-3ZBAXET6.cjs → chunk-NN3JGUSX.cjs} +80 -22
  66. package/dist/chunk-NN3JGUSX.cjs.map +1 -0
  67. package/dist/chunk-NV22EMOZ.cjs +401 -0
  68. package/dist/chunk-NV22EMOZ.cjs.map +1 -0
  69. package/dist/{chunk-YMKPMXZ4.js → chunk-OIKYP7XC.js} +4 -4
  70. package/dist/{chunk-FEMIVHN3.cjs → chunk-P43HUQRX.cjs} +16 -16
  71. package/dist/{chunk-FEMIVHN3.cjs.map → chunk-P43HUQRX.cjs.map} +1 -1
  72. package/dist/chunk-PTMIGXZ2.js +467 -0
  73. package/dist/chunk-PTMIGXZ2.js.map +1 -0
  74. package/dist/chunk-QIWFEEWG.cjs +467 -0
  75. package/dist/chunk-QIWFEEWG.cjs.map +1 -0
  76. package/dist/{chunk-QFTVLEVN.js → chunk-RIXTW3C4.js} +3 -3
  77. package/dist/{chunk-WBOAXDKD.js → chunk-VODBAO32.js} +222 -57
  78. package/dist/chunk-VODBAO32.js.map +1 -0
  79. package/dist/chunk-WWJNC7SX.js +3848 -0
  80. package/dist/chunk-WWJNC7SX.js.map +1 -0
  81. package/dist/{chunk-2DEBI6KU.cjs → chunk-YZZMX6V7.cjs} +10 -10
  82. package/dist/{chunk-2DEBI6KU.cjs.map → chunk-YZZMX6V7.cjs.map} +1 -1
  83. package/dist/commands/index.d.cts +1 -1
  84. package/dist/commands/index.d.ts +1 -1
  85. package/dist/{controller-DS3drIvy.d.cts → controller-CX0QfSv0.d.cts} +53 -2
  86. package/dist/{controller-BdKzaxs2.d.ts → controller-DscWQbjO.d.ts} +53 -2
  87. package/dist/diagram/index.cjs +1146 -0
  88. package/dist/diagram/index.cjs.map +1 -0
  89. package/dist/diagram/index.d.cts +787 -0
  90. package/dist/diagram/index.d.ts +787 -0
  91. package/dist/diagram/index.js +1146 -0
  92. package/dist/diagram/index.js.map +1 -0
  93. package/dist/{easing-DTmX99QG.d.cts → easing-CNGk-W6d.d.cts} +1 -1
  94. package/dist/{easing-DTmX99QG.d.ts → easing-CNGk-W6d.d.ts} +1 -1
  95. package/dist/export/index.cjs +4 -4
  96. package/dist/export/index.js +3 -3
  97. package/dist/extensions/index.cjs +6 -6
  98. package/dist/extensions/index.d.cts +2 -2
  99. package/dist/extensions/index.d.ts +2 -2
  100. package/dist/extensions/index.js +5 -5
  101. package/dist/generation/index.d.cts +2 -2
  102. package/dist/generation/index.d.ts +2 -2
  103. package/dist/image-editor/index.d.cts +1 -1
  104. package/dist/image-editor/index.d.ts +1 -1
  105. package/dist/{index-Dt9lzydb.d.ts → index-CALDD35B.d.ts} +1 -1
  106. package/dist/{index-DOy9HzfC.d.cts → index-DIWB6xMf.d.cts} +1 -1
  107. package/dist/index.cjs +13 -13
  108. package/dist/index.d.cts +3 -3
  109. package/dist/index.d.ts +3 -3
  110. package/dist/index.js +6 -6
  111. package/dist/parameters/index.d.cts +1 -1
  112. package/dist/parameters/index.d.ts +1 -1
  113. package/dist/player-DSMjdgQ9.d.cts +225 -0
  114. package/dist/player-DdfVrKWq.d.ts +225 -0
  115. package/dist/presence-Cb6WhcrQ.d.cts +77 -0
  116. package/dist/presence-Cb6WhcrQ.d.ts +77 -0
  117. package/dist/{registry-CSlH4iUn.d.ts → registry-7AZFuand.d.ts} +1 -1
  118. package/dist/{registry-B4l-lYts.d.cts → registry-DIpIaCkH.d.cts} +1 -1
  119. package/dist/tools/index.cjs +10 -2
  120. package/dist/tools/index.cjs.map +1 -1
  121. package/dist/tools/index.d.cts +3 -74
  122. package/dist/tools/index.d.ts +3 -74
  123. package/dist/tools/index.js +12 -4
  124. package/dist/types-BULrFyuQ.d.cts +316 -0
  125. package/dist/types-BULrFyuQ.d.ts +316 -0
  126. package/dist/vector/index.d.cts +1 -1
  127. package/dist/vector/index.d.ts +1 -1
  128. package/package.json +14 -1
  129. package/dist/chunk-3ZBAXET6.cjs.map +0 -1
  130. package/dist/chunk-5TWIN7ZJ.js.map +0 -1
  131. package/dist/chunk-AMWXSYCI.js.map +0 -1
  132. package/dist/chunk-GTZXF4BI.cjs.map +0 -1
  133. package/dist/chunk-JOX6MJW4.cjs.map +0 -1
  134. package/dist/chunk-OV7UAKIY.js.map +0 -1
  135. package/dist/chunk-TGBCBQFV.cjs.map +0 -1
  136. package/dist/chunk-UAW5FEMD.js.map +0 -1
  137. package/dist/chunk-WBOAXDKD.js.map +0 -1
  138. package/dist/chunk-XFYUFVAX.cjs +0 -826
  139. package/dist/chunk-XFYUFVAX.cjs.map +0 -1
  140. /package/dist/{chunk-5N6AQCVB.js.map → chunk-BQQZ6MOI.js.map} +0 -0
  141. /package/dist/{chunk-YMKPMXZ4.js.map → chunk-OIKYP7XC.js.map} +0 -0
  142. /package/dist/{chunk-QFTVLEVN.js.map → chunk-RIXTW3C4.js.map} +0 -0
@@ -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-OV7UAKIY.js";
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 domain = [scale.min, scale.max];
1184
- const raw = (v) => linearMap(v, domain, range);
1185
- const px = (v) => raw(Math.min(scale.max, Math.max(scale.min, v)));
1186
- return { scale, range, px, raw, zero: px(0), format, tickText: (t) => formatChartNumber(t, format, format.decimals ?? stepDecimals(scale.step)) };
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
- if (t.type === "moving-average") px = chartMovingAverage(points, t.period ?? 2).map(([x, y]) => toPx(x, y));
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
- if (y !== null) px.push(toPx(x, y));
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 && Number.isFinite(v) && see(v));
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 at = barLabel(ctx, text, rect, horizontal, seg[1] >= seg[0], stacked, fill, plot);
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[Math.round((pt.c - catStart) / band - 0.5)]?.[0] ?? 0) })).reverse() : [
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: catStart + band * (x - 0.5), v: info.raw(y) });
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 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) => p.x !== null && p.y !== null && Number.isFinite(p.x) && Number.isFinite(p.y));
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
- xlo = Math.min(xlo, p.x);
1653
- xhi = Math.max(xhi, p.x);
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
- xlo = Math.min(xlo, Math.min(...pts.map((p) => p.x)) - (t.backward ?? 0));
1661
- xhi = Math.max(xhi, Math.max(...pts.map((p) => p.x)) + (t.forward ?? 0));
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, ylo, yhi] = [0, 1, 0, 1];
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 xRaw = (x) => linearMap(x, [xScale.min, xScale.max], xRange);
1680
- const yRaw = (y) => linearMap(y, [yScale.min, yScale.max], yRange);
1681
- const xPx = (x) => xRaw(Math.min(xScale.max, Math.max(xScale.min, x)));
1682
- const yPx = (y) => yRaw(Math.min(yScale.max, Math.max(yScale.min, y)));
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.length > 1 ? Math.abs(xPx(xScale.ticks[1]) - xPx(xScale.ticks[0])) : Infinity;
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
- if (s.trendlines?.length) drawTrendlines(ctx, plot, s, color, pts.map((p) => [p.x, p.y]), (x, y) => [xRaw(x), yRaw(y)], trendLabels);
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: { axis: "y", domain: [yScale.min, yScale.max], range: yRange, ticks: yScale.ticks },
1750
- xScale: { axis: "x", domain: [xScale.min, xScale.max], range: xRange, ticks: xScale.ticks }
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 linearMap(px, scale.range, scale.domain);
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 linearMap(point.x, scale.range, scale.domain);
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-WBOAXDKD.js.map
3589
+ //# sourceMappingURL=chunk-VODBAO32.js.map