@opendata-ai/openchart-engine 6.26.0 → 6.27.2

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _opendata_ai_openchart_core from '@opendata-ai/openchart-core';
2
- import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, AnimationSpec, ResolvedAnimation, TileMapEncoding, TileMapPalette, LegendConfig, ThemeConfig, DarkMode, MarkType, MarkDef, DataRow, Encoding, ChromeText, Annotation, LabelConfig, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, VizSpec, ScaleType, EncodingChannel, Rect, LayoutStrategy, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
2
+ import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, AnimationSpec, ResolvedAnimation, TileMapEncoding, TileMapPalette, LegendConfig, ThemeConfig, DarkMode, MarkType, MarkDef, DataRow, Encoding, ChromeText, Annotation, LabelConfig, Display, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, VizSpec, ScaleType, EncodingChannel, Rect, LayoutStrategy, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
3
3
  export { ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GraphLayout, GraphSpec, LayerSpec, SankeyLayout, SankeySpec, TableLayout, TableSpec, TileMapLayout, TileMapSpec, VizSpec } from '@opendata-ai/openchart-core';
4
4
  import { ScaleLinear, ScaleTime, ScaleLogarithmic, ScalePower, ScaleSymLog, ScaleBand, ScalePoint, ScaleOrdinal, ScaleQuantile, ScaleQuantize, ScaleThreshold } from 'd3-scale';
5
5
 
@@ -232,6 +232,34 @@ interface NormalizedChrome {
232
232
  byline?: ChromeText;
233
233
  footer?: ChromeText;
234
234
  }
235
+ /**
236
+ * Tracks which top-level fields the user explicitly set in their input spec.
237
+ *
238
+ * Built from the raw expandedSpec (post-breakpoint-merge, pre-normalize) so
239
+ * that "user wrote chrome.title" vs "user wrote nothing" is distinguishable
240
+ * after normalization fills in defaults.
241
+ *
242
+ * Used by sparkline display mode to decide whether to suppress chrome/axes/
243
+ * legend/etc. by default vs. respecting an explicit user opt-in.
244
+ */
245
+ interface UserExplicit {
246
+ /** True if user wrote `chrome` (any non-empty chrome). */
247
+ chrome: boolean;
248
+ /** True if user wrote `legend`. */
249
+ legend: boolean;
250
+ /** True if user wrote `encoding.x.axis`. */
251
+ xAxis: boolean;
252
+ /** True if user wrote `encoding.y.axis`. */
253
+ yAxis: boolean;
254
+ /** True if user wrote `labels`. */
255
+ labels: boolean;
256
+ /** True if user wrote `animation`. */
257
+ animation: boolean;
258
+ /** True if user wrote `watermark`. */
259
+ watermark: boolean;
260
+ /** True if user wrote `crosshair`. */
261
+ crosshair: boolean;
262
+ }
235
263
  /** A ChartSpec with all optional fields filled with sensible defaults. */
236
264
  interface NormalizedChartSpec {
237
265
  /** Resolved mark type string (extracted from spec.mark). */
@@ -255,6 +283,14 @@ interface NormalizedChartSpec {
255
283
  hiddenSeries: string[];
256
284
  /** Per-series visual style overrides. */
257
285
  seriesStyles: Record<string, _opendata_ai_openchart_core.SeriesStyle>;
286
+ /** Display mode controlling chrome/axes/legend stripping. Defaults to `'full'`. */
287
+ display: Display;
288
+ /**
289
+ * Which top-level fields the user explicitly set. Populated by compileChart
290
+ * from the raw expanded spec before normalization. NormalizeChartSpec runs
291
+ * with a default-empty descriptor; compileChart overwrites it post-normalize.
292
+ */
293
+ userExplicit: UserExplicit;
258
294
  }
259
295
  /** A TableSpec with all optional fields filled with sensible defaults. */
260
296
  interface NormalizedTableSpec {
package/dist/index.js CHANGED
@@ -3692,6 +3692,22 @@ function resolvePosition(value2, scale) {
3692
3692
  }
3693
3693
  return null;
3694
3694
  }
3695
+ function resolvePositionEdge(value2, scale, edge) {
3696
+ const center2 = resolvePosition(value2, scale);
3697
+ if (center2 === null || !scale) return null;
3698
+ const type = scale.type;
3699
+ if (type === "point") {
3700
+ const s = scale.scale;
3701
+ const halfStep = (s.step?.() ?? 0) / 2;
3702
+ return edge === "start" ? center2 - halfStep : center2 + halfStep;
3703
+ }
3704
+ if (type === "band") {
3705
+ const s = scale.scale;
3706
+ const halfBw = (s.bandwidth?.() ?? 0) / 2;
3707
+ return edge === "start" ? center2 - halfBw : center2 + halfBw;
3708
+ }
3709
+ return center2;
3710
+ }
3695
3711
 
3696
3712
  // src/annotations/collisions.ts
3697
3713
  function generateNudgeCandidates(selfBounds, obstacles, padding) {
@@ -3924,15 +3940,15 @@ function resolveRangeAnnotation(annotation, scales, chartArea, isDark) {
3924
3940
  let width = chartArea.width;
3925
3941
  let height = chartArea.height;
3926
3942
  if (annotation.x1 !== void 0 && annotation.x2 !== void 0) {
3927
- const x1px = resolvePosition(annotation.x1, scales.x);
3928
- const x2px = resolvePosition(annotation.x2, scales.x);
3943
+ const x1px = resolvePositionEdge(annotation.x1, scales.x, "start");
3944
+ const x2px = resolvePositionEdge(annotation.x2, scales.x, "end");
3929
3945
  if (x1px === null || x2px === null) return null;
3930
3946
  x2 = Math.min(x1px, x2px);
3931
3947
  width = Math.abs(x2px - x1px);
3932
3948
  }
3933
3949
  if (annotation.y1 !== void 0 && annotation.y2 !== void 0) {
3934
- const y1px = resolvePosition(annotation.y1, scales.y);
3935
- const y2px = resolvePosition(annotation.y2, scales.y);
3950
+ const y1px = resolvePositionEdge(annotation.y1, scales.y, "end");
3951
+ const y2px = resolvePositionEdge(annotation.y2, scales.y, "start");
3936
3952
  if (y1px === null || y2px === null) return null;
3937
3953
  y2 = Math.min(y1px, y2px);
3938
3954
  height = Math.abs(y2px - y1px);
@@ -5351,7 +5367,7 @@ function computeSingleArea(spec, scales, _chartArea) {
5351
5367
  fill: fillValue,
5352
5368
  fillOpacity,
5353
5369
  stroke: getRepresentativeColor4(isGradientDef3(fillValue) ? color2 : fillValue),
5354
- strokeWidth: 2,
5370
+ strokeWidth: spec.display === "sparkline" ? 1.25 : 2,
5355
5371
  seriesKey: seriesKey === "__default__" ? void 0 : seriesKey,
5356
5372
  data: validPoints.map((p) => p.row),
5357
5373
  dataPoints: validPoints.map((p) => ({ x: p.x, y: p.yTop, datum: p.row })),
@@ -5468,6 +5484,7 @@ function computeAreaMarks(spec, scales, chartArea) {
5468
5484
  // src/charts/line/compute.ts
5469
5485
  import { getRepresentativeColor as getRepresentativeColor5 } from "@opendata-ai/openchart-core";
5470
5486
  var DEFAULT_STROKE_WIDTH = 2.5;
5487
+ var SPARKLINE_STROKE_WIDTH = 1.25;
5471
5488
  var DEFAULT_POINT_RADIUS = 3;
5472
5489
  function computeLineMarks(spec, scales, _chartArea, _strategy) {
5473
5490
  const encoding = spec.encoding;
@@ -5534,7 +5551,7 @@ function computeLineMarks(spec, scales, _chartArea, _strategy) {
5534
5551
  points: allPoints,
5535
5552
  path: combinedPath,
5536
5553
  stroke: strokeColor,
5537
- strokeWidth: styleOverride?.strokeWidth ?? DEFAULT_STROKE_WIDTH,
5554
+ strokeWidth: styleOverride?.strokeWidth ?? (spec.display === "sparkline" ? SPARKLINE_STROKE_WIDTH : DEFAULT_STROKE_WIDTH),
5538
5555
  strokeDasharray,
5539
5556
  opacity: styleOverride?.opacity,
5540
5557
  seriesKey: seriesStyleKey,
@@ -6812,6 +6829,12 @@ function normalizeChartSpec(spec, warnings) {
6812
6829
  const encoding = inferEncodingTypes(spec.encoding, spec.data, warnings);
6813
6830
  const markType = resolveMarkType(spec.mark);
6814
6831
  const markDef = resolveMarkDef(spec.mark);
6832
+ const display = spec.display ?? "full";
6833
+ if (display === "sparkline" && markType !== "line" && markType !== "area" && markType !== "bar" && markType !== "point") {
6834
+ warnings.push(
6835
+ `[openchart] display: 'sparkline' works best with mark: 'line' | 'area' | 'bar' | 'point'. Got mark: '${markType}' \u2014 rendering may degrade.`
6836
+ );
6837
+ }
6815
6838
  return {
6816
6839
  markType,
6817
6840
  markDef,
@@ -6826,7 +6849,20 @@ function normalizeChartSpec(spec, warnings) {
6826
6849
  darkMode: spec.darkMode ?? "off",
6827
6850
  hiddenSeries: spec.hiddenSeries ?? [],
6828
6851
  seriesStyles: spec.seriesStyles ?? {},
6829
- watermark: spec.watermark ?? true
6852
+ watermark: spec.watermark ?? true,
6853
+ display,
6854
+ // Default empty userExplicit; compileChart overwrites this with the real
6855
+ // descriptor built from the raw expanded spec before normalize runs.
6856
+ userExplicit: {
6857
+ chrome: false,
6858
+ legend: false,
6859
+ xAxis: false,
6860
+ yAxis: false,
6861
+ labels: false,
6862
+ animation: false,
6863
+ watermark: false,
6864
+ crosshair: false
6865
+ }
6830
6866
  };
6831
6867
  }
6832
6868
  function normalizeTableSpec(spec, _warnings) {
@@ -8213,9 +8249,9 @@ import {
8213
8249
  formatNumber as formatNumber2
8214
8250
  } from "@opendata-ai/openchart-core";
8215
8251
  var Y_PX_PER_TICK = {
8216
- full: 55,
8217
- reduced: 90,
8218
- minimal: 140
8252
+ full: 40,
8253
+ reduced: 70,
8254
+ minimal: 120
8219
8255
  };
8220
8256
  var X_PX_PER_TICK = {
8221
8257
  full: 110,
@@ -8293,7 +8329,21 @@ function buildContinuousTicks(resolvedScale, count) {
8293
8329
  return continuousTicks(resolvedScale, "full");
8294
8330
  }
8295
8331
  const raw = scale.ticks(count);
8296
- return raw.map((value2) => ({
8332
+ let ticks2 = raw;
8333
+ if (resolvedScale.type === "log" && raw.length > count) {
8334
+ const base = resolvedScale.channel.scale?.base ?? 10;
8335
+ const logBase = Math.log(base);
8336
+ const powered = raw.filter((v) => {
8337
+ const n = v;
8338
+ if (n <= 0) return false;
8339
+ const exp = Math.log(n) / logBase;
8340
+ return Math.abs(exp - Math.round(exp)) < 1e-9;
8341
+ });
8342
+ if (powered.length >= 2) {
8343
+ ticks2 = powered;
8344
+ }
8345
+ }
8346
+ return ticks2.map((value2) => ({
8297
8347
  value: value2,
8298
8348
  position: scale(value2),
8299
8349
  label: formatTickLabel(value2, resolvedScale)
@@ -8396,8 +8446,8 @@ function resolveExplicitTicks(values, resolvedScale) {
8396
8446
  }
8397
8447
 
8398
8448
  // src/layout/axes.ts
8399
- var HEIGHT_MINIMAL_THRESHOLD = 120;
8400
- var HEIGHT_REDUCED_THRESHOLD = 200;
8449
+ var HEIGHT_MINIMAL_THRESHOLD = 80;
8450
+ var HEIGHT_REDUCED_THRESHOLD = 100;
8401
8451
  var WIDTH_MINIMAL_THRESHOLD = 150;
8402
8452
  var WIDTH_REDUCED_THRESHOLD = 300;
8403
8453
  var DENSITY_ORDER = ["full", "reduced", "minimal"];
@@ -8473,7 +8523,7 @@ function computeAxes(scales, chartArea, strategy, theme, measureText, dataContex
8473
8523
  };
8474
8524
  const { fontSize } = tickLabelStyle;
8475
8525
  const { fontWeight } = tickLabelStyle;
8476
- if (scales.x) {
8526
+ if (scales.x && !dataContext?.skipX) {
8477
8527
  const axisConfig = scales.x.channel.axis;
8478
8528
  const isContinuousX = scales.x.type !== "band" && scales.x.type !== "point" && scales.x.type !== "ordinal";
8479
8529
  const xTargetCount = isContinuousX ? targetTickCount(chartArea.width, xDensity, "x") : void 0;
@@ -8551,7 +8601,7 @@ function computeAxes(scales, chartArea, strategy, theme, measureText, dataContex
8551
8601
  labelFlush: axisConfig?.labelFlush
8552
8602
  };
8553
8603
  }
8554
- if (scales.y) {
8604
+ if (scales.y && !dataContext?.skipY) {
8555
8605
  const axisConfig = scales.y.channel.axis;
8556
8606
  const isContinuousY = scales.y.type !== "band" && scales.y.type !== "point" && scales.y.type !== "ordinal";
8557
8607
  const yTargetCount = isContinuousY ? targetTickCount(chartArea.height, yDensity, "y") : void 0;
@@ -8703,12 +8753,24 @@ function scalePadding(basePadding, width, height) {
8703
8753
  }
8704
8754
  var MIN_CHART_WIDTH = 60;
8705
8755
  var MIN_CHART_HEIGHT = 40;
8756
+ function getMinChartDims(display) {
8757
+ return display === "sparkline" ? { width: 30, height: 20 } : { width: MIN_CHART_WIDTH, height: MIN_CHART_HEIGHT };
8758
+ }
8759
+ function getSparklinePad(spec) {
8760
+ const strokeWidth = spec.markDef.strokeWidth ?? 2;
8761
+ return Math.max(strokeWidth / 2 + 1, 2);
8762
+ }
8706
8763
  function computeDimensions(spec, options, legendLayout, theme, strategy, watermark = true) {
8707
8764
  const { width, height } = options;
8708
8765
  const padding = scalePadding(theme.spacing.padding, width, height);
8709
8766
  const hPad = width < BREAKPOINT_COMPACT_MAX ? Math.max(Math.round(padding * HPAD_COMPACT_FRACTION), HPAD_COMPACT_MIN) : padding;
8710
8767
  const axisMargin = theme.spacing.axisMargin;
8711
- const chromeMode = strategy?.chromeMode ?? "full";
8768
+ const userExplicit = spec.userExplicit;
8769
+ const isSparkline = spec.display === "sparkline";
8770
+ let chromeMode = strategy?.chromeMode ?? "full";
8771
+ if (isSparkline && !userExplicit.chrome) {
8772
+ chromeMode = "hidden";
8773
+ }
8712
8774
  const chrome = computeChrome2(
8713
8775
  chromeToInput(spec.chrome),
8714
8776
  theme,
@@ -8718,6 +8780,35 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
8718
8780
  padding,
8719
8781
  watermark
8720
8782
  );
8783
+ if (isSparkline) {
8784
+ const total2 = { x: 0, y: 0, width, height };
8785
+ const sparkPad = getSparklinePad(spec);
8786
+ const xAxisSpace = userExplicit.xAxis ? 26 : 0;
8787
+ const yAxisSpace = userExplicit.yAxis ? 30 : 0;
8788
+ const margins2 = {
8789
+ top: chrome.topHeight + sparkPad,
8790
+ right: sparkPad,
8791
+ bottom: chrome.bottomHeight + sparkPad + xAxisSpace,
8792
+ left: sparkPad + yAxisSpace
8793
+ };
8794
+ if (userExplicit.legend && "entries" in legendLayout && legendLayout.entries.length > 0) {
8795
+ const gap = legendGap(width);
8796
+ if (legendLayout.position === "right" || legendLayout.position === "bottom-right") {
8797
+ margins2.right += legendLayout.bounds.width + 8;
8798
+ } else if (legendLayout.position === "top") {
8799
+ margins2.top += legendLayout.bounds.height + gap;
8800
+ } else if (legendLayout.position === "bottom") {
8801
+ margins2.bottom += legendLayout.bounds.height + gap;
8802
+ }
8803
+ }
8804
+ const chartArea2 = {
8805
+ x: margins2.left,
8806
+ y: margins2.top,
8807
+ width: Math.max(0, width - margins2.left - margins2.right),
8808
+ height: Math.max(0, height - margins2.top - margins2.bottom)
8809
+ };
8810
+ return { total: total2, chrome, chartArea: chartArea2, margins: margins2, theme };
8811
+ }
8721
8812
  const total = { x: 0, y: 0, width, height };
8722
8813
  const isRadial = spec.markType === "arc";
8723
8814
  const encoding = spec.encoding;
@@ -8891,7 +8982,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
8891
8982
  width: Math.max(0, width - margins.left - margins.right),
8892
8983
  height: Math.max(0, height - margins.top - margins.bottom)
8893
8984
  };
8894
- if ((chartArea.width < MIN_CHART_WIDTH || chartArea.height < MIN_CHART_HEIGHT) && chromeMode !== "hidden") {
8985
+ const minDims = getMinChartDims(spec.display);
8986
+ if ((chartArea.width < minDims.width || chartArea.height < minDims.height) && chromeMode !== "hidden") {
8895
8987
  const fallbackMode = chromeMode === "full" ? "compact" : "hidden";
8896
8988
  const fallbackChrome = computeChrome2(
8897
8989
  chromeToInput(spec.chrome),
@@ -9438,7 +9530,8 @@ function truncateEntries(entries, maxCount) {
9438
9530
  return truncated;
9439
9531
  }
9440
9532
  function computeLegend(spec, strategy, theme, chartArea, watermark = true) {
9441
- if (spec.legend?.show === false || strategy.legendMaxHeight === 0) {
9533
+ const sparklineHidden = spec.display === "sparkline" && !spec.userExplicit.legend;
9534
+ if (sparklineHidden || spec.legend?.show === false || strategy.legendMaxHeight === 0) {
9442
9535
  return {
9443
9536
  position: "top",
9444
9537
  entries: [],
@@ -12176,7 +12269,7 @@ function compileChart(spec, options) {
12176
12269
  }
12177
12270
  let chartSpec = normalized;
12178
12271
  const rawWatermark = expandedSpec.watermark;
12179
- const watermark = rawWatermark !== void 0 ? chartSpec.watermark : options.watermark ?? true;
12272
+ let watermark = rawWatermark !== void 0 ? chartSpec.watermark : options.watermark ?? true;
12180
12273
  const rawTransforms = expandedSpec.transform;
12181
12274
  if (rawTransforms && rawTransforms.length > 0) {
12182
12275
  chartSpec = { ...chartSpec, data: runTransforms(chartSpec.data, rawTransforms) };
@@ -12186,6 +12279,21 @@ function compileChart(spec, options) {
12186
12279
  let strategy = getLayoutStrategy(breakpoint, heightClass);
12187
12280
  const rawSpec = expandedSpec;
12188
12281
  const overrides = rawSpec.overrides;
12282
+ const rawEncoding = rawSpec.encoding;
12283
+ const bpForExplicit = overrides?.[breakpoint];
12284
+ const bpEncoding = bpForExplicit?.encoding;
12285
+ const hasChromeKeys = (v) => !!v && typeof v === "object" && Object.keys(v).length > 0;
12286
+ const userExplicit = {
12287
+ chrome: hasChromeKeys(rawSpec.chrome) || hasChromeKeys(bpForExplicit?.chrome),
12288
+ legend: rawSpec.legend !== void 0 || bpForExplicit?.legend !== void 0,
12289
+ xAxis: rawEncoding?.x?.axis !== void 0 || bpEncoding?.x?.axis !== void 0,
12290
+ yAxis: rawEncoding?.y?.axis !== void 0 || bpEncoding?.y?.axis !== void 0,
12291
+ labels: rawSpec.labels !== void 0 || bpForExplicit?.labels !== void 0,
12292
+ animation: rawSpec.animation !== void 0 || bpForExplicit?.animation !== void 0,
12293
+ watermark: rawSpec.watermark !== void 0 || bpForExplicit?.watermark !== void 0,
12294
+ crosshair: rawSpec.crosshair !== void 0 || bpForExplicit?.crosshair !== void 0
12295
+ };
12296
+ chartSpec = { ...chartSpec, userExplicit };
12189
12297
  if (overrides?.[breakpoint]) {
12190
12298
  const bp = overrides[breakpoint];
12191
12299
  if (bp.chrome) {
@@ -12229,9 +12337,80 @@ function compileChart(spec, options) {
12229
12337
  };
12230
12338
  strategy = { ...strategy, annotationPosition: "inline" };
12231
12339
  }
12340
+ if (bp.display !== void 0) {
12341
+ chartSpec = {
12342
+ ...chartSpec,
12343
+ display: bp.display
12344
+ };
12345
+ }
12346
+ if (bp.encoding !== void 0) {
12347
+ const bpEnc = bp.encoding;
12348
+ const mergedEncoding = { ...chartSpec.encoding };
12349
+ const NESTED_CHANNEL_KEYS = ["axis", "scale"];
12350
+ for (const channel of Object.keys(bpEnc)) {
12351
+ const baseCh = mergedEncoding[channel];
12352
+ const bpCh = bpEnc[channel];
12353
+ if (bpCh && baseCh) {
12354
+ const merged = { ...baseCh, ...bpCh };
12355
+ for (const key of NESTED_CHANNEL_KEYS) {
12356
+ const baseNested = baseCh[key];
12357
+ const bpNested = bpCh[key];
12358
+ if (baseNested && bpNested && typeof baseNested === "object" && typeof bpNested === "object" && !Array.isArray(baseNested) && !Array.isArray(bpNested)) {
12359
+ merged[key] = { ...baseNested, ...bpNested };
12360
+ }
12361
+ }
12362
+ mergedEncoding[channel] = merged;
12363
+ } else if (bpCh) {
12364
+ mergedEncoding[channel] = bpCh;
12365
+ }
12366
+ }
12367
+ chartSpec = {
12368
+ ...chartSpec,
12369
+ encoding: mergedEncoding
12370
+ };
12371
+ }
12372
+ if (typeof bp.watermark === "boolean") {
12373
+ watermark = bp.watermark;
12374
+ chartSpec = { ...chartSpec, watermark };
12375
+ }
12376
+ }
12377
+ if (chartSpec.display === "sparkline" && !chartSpec.userExplicit.labels) {
12378
+ chartSpec = {
12379
+ ...chartSpec,
12380
+ labels: { ...chartSpec.labels, density: "none" }
12381
+ };
12382
+ }
12383
+ let rawAnimationSpec = overrides?.[breakpoint]?.animation ?? rawSpec.animation;
12384
+ if (rawAnimationSpec === void 0 && chartSpec.display === "sparkline") {
12385
+ rawAnimationSpec = false;
12386
+ }
12387
+ if (chartSpec.display === "sparkline" && rawAnimationSpec !== false && rawAnimationSpec !== void 0) {
12388
+ const SPARK_DURATION = 1100;
12389
+ if (rawAnimationSpec === true) {
12390
+ rawAnimationSpec = { enter: { duration: SPARK_DURATION } };
12391
+ } else if (typeof rawAnimationSpec === "object") {
12392
+ const cfg = rawAnimationSpec;
12393
+ const enter = cfg.enter;
12394
+ if (enter === void 0 || enter === true) {
12395
+ rawAnimationSpec = {
12396
+ ...cfg,
12397
+ enter: { duration: SPARK_DURATION }
12398
+ };
12399
+ } else if (typeof enter === "object" && enter !== null && enter.duration === void 0) {
12400
+ rawAnimationSpec = {
12401
+ ...cfg,
12402
+ enter: { ...enter, duration: SPARK_DURATION }
12403
+ };
12404
+ }
12405
+ }
12232
12406
  }
12233
- const rawAnimationSpec = overrides?.[breakpoint]?.animation ?? rawSpec.animation;
12234
12407
  const resolvedAnimation = resolveAnimation(rawAnimationSpec);
12408
+ const rawCrosshair = bpForExplicit?.crosshair ?? rawSpec.crosshair;
12409
+ const crosshair = chartSpec.display === "sparkline" && !chartSpec.userExplicit.crosshair ? false : rawCrosshair === true;
12410
+ if (chartSpec.display === "sparkline" && !chartSpec.userExplicit.watermark) {
12411
+ watermark = false;
12412
+ chartSpec = { ...chartSpec, watermark: false };
12413
+ }
12235
12414
  const mergedThemeConfig = options.theme ? { ...chartSpec.theme, ...options.theme } : chartSpec.theme;
12236
12415
  let theme = resolveTheme4(mergedThemeConfig);
12237
12416
  if (options.darkMode) {
@@ -12276,9 +12455,13 @@ function compileChart(spec, options) {
12276
12455
  applyColorScaleRange(scales, renderSpec.encoding, theme);
12277
12456
  scales.defaultColor = chartSpec.markDef.fill ?? chartSpec.markDef.stroke ?? theme.colors.categorical[0];
12278
12457
  const isRadial = chartSpec.markType === "arc";
12458
+ const skipX = chartSpec.display === "sparkline" && !chartSpec.userExplicit.xAxis;
12459
+ const skipY = chartSpec.display === "sparkline" && !chartSpec.userExplicit.yAxis;
12279
12460
  const axes = isRadial ? { x: void 0, y: void 0 } : computeAxes(scales, chartArea, strategy, theme, options.measureText, {
12280
12461
  data: renderSpec.data,
12281
- encoding: renderSpec.encoding
12462
+ encoding: renderSpec.encoding,
12463
+ skipX,
12464
+ skipY
12282
12465
  });
12283
12466
  if (!isRadial) {
12284
12467
  computeGridlines(axes, chartArea);
@@ -12354,6 +12537,8 @@ function compileChart(spec, options) {
12354
12537
  },
12355
12538
  animation: resolvedAnimation,
12356
12539
  watermark,
12540
+ display: chartSpec.display,
12541
+ crosshair,
12357
12542
  measureText: options.measureText
12358
12543
  };
12359
12544
  }