@fundar/data-chart-telling 0.0.29 → 0.0.31

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 (48) hide show
  1. package/dist/charts/BaseChart.svelte +1 -0
  2. package/dist/charts/bar/Chart.svelte +2 -2
  3. package/dist/charts/bar/Chart.svelte.d.ts +2 -2
  4. package/dist/charts/line/Chart.svelte +2 -2
  5. package/dist/charts/line/Chart.svelte.d.ts +2 -2
  6. package/dist/charts/pyramid/Chart.svelte +2 -2
  7. package/dist/charts/pyramid/Chart.svelte.d.ts +3 -2
  8. package/dist/configuration/config.svelte.js +2 -0
  9. package/dist/configuration/themes/index.d.ts +88 -0
  10. package/dist/index.d.ts +4 -3
  11. package/dist/layout/coordinates/CoordinatesLayout.svelte +10 -5
  12. package/dist/layout/coordinates/CoordinatesLayout.svelte.d.ts +2 -0
  13. package/dist/layout/facet/FacetLayout.svelte +77 -20
  14. package/dist/layout/facet/FacetLayout.svelte.d.ts +2 -1
  15. package/dist/layout/plot/BasePlotLayout.svelte +19 -0
  16. package/dist/layout/plot/BasePlotLayout.svelte.d.ts +17 -0
  17. package/dist/plots/bar/Plot.svelte +13 -2
  18. package/dist/plots/bar/Plot.svelte.d.ts +2 -2
  19. package/dist/plots/bar/ValueLabels.svelte +5 -1
  20. package/dist/plots/bar/buildBarMarkers.d.ts +10 -3
  21. package/dist/plots/bar/buildBarMarkers.js +80 -57
  22. package/dist/plots/bar/hoverPoints.js +2 -1
  23. package/dist/plots/bar/layout.svelte.d.ts +2 -0
  24. package/dist/plots/bar/layout.svelte.js +6 -1
  25. package/dist/plots/heatmap/Plot.svelte +2 -2
  26. package/dist/plots/heatmap/Plot.svelte.d.ts +2 -2
  27. package/dist/plots/line/Plot.svelte +9 -9
  28. package/dist/plots/line/Plot.svelte.d.ts +2 -6
  29. package/dist/plots/line/ValueLabels.svelte +17 -2
  30. package/dist/plots/line/buildGapMarkers.d.ts +1 -1
  31. package/dist/plots/pyramid/Plot.svelte +39 -14
  32. package/dist/plots/pyramid/Plot.svelte.d.ts +2 -2
  33. package/dist/plots/pyramid/ValueLabels.svelte +5 -1
  34. package/dist/plots/pyramid/buildPyramidBarMarkers.d.ts +8 -1
  35. package/dist/plots/pyramid/buildPyramidBarMarkers.js +43 -3
  36. package/dist/plots/scatter/Plot.svelte +2 -2
  37. package/dist/plots/scatter/Plot.svelte.d.ts +2 -2
  38. package/dist/plots/utils/gaps.d.ts +20 -0
  39. package/dist/plots/utils/gaps.js +67 -0
  40. package/dist/plots/utils/labelOverflow.svelte.d.ts +9 -0
  41. package/dist/plots/utils/labelOverflow.svelte.js +11 -0
  42. package/dist/types/charts/props.d.ts +11 -2
  43. package/dist/types/configuration/styling.d.ts +11 -1
  44. package/dist/types/layout/facet.d.ts +2 -0
  45. package/dist/types/layout/styles.d.ts +29 -11
  46. package/dist/types/plots/gaps.d.ts +17 -2
  47. package/dist/types/plots/props.d.ts +1 -10
  48. package/package.json +1 -1
@@ -1,23 +1,34 @@
1
1
  import { resolveAccessor } from '../utils/accessors';
2
+ import { getConfiguration } from '../../configuration/config.svelte';
3
+ import { isGapValue, resolveGapAreaStyle } from '../utils/gaps';
4
+ const GAP_KINDS = ['start', 'middle', 'end'];
2
5
  /**
3
6
  * Every `'bar'` marker for one PyramidPlot render — reuses `BarMarkerConfig`
4
7
  * directly, always horizontal (category on y, signed magnitude on x) and
5
8
  * with no insets. Emits no `role: 'hitArea'` markers, since PyramidPlot's
6
- * hover matches nearest points rather than hit-testing category bands.
9
+ * hover matches nearest points rather than hit-testing category bands. A
10
+ * row whose value is missing and *not* filled by a `styles.gaps` zone is
11
+ * skipped entirely; a filled one gets one additional, distinctly-styled
12
+ * marker per zone kind, at its interpolated value.
7
13
  */
8
14
  export function buildPyramidBarMarkers(args) {
9
- const { groupedSeries, valueFor, colorFor, disabledFillFor } = args;
15
+ const { groupedSeries, valueFor, signFor, colorFor, disabledFillFor, gapFillMaps } = args;
16
+ const gapDefaults = getConfiguration().pyramid.gap;
10
17
  const markers = [];
11
18
  for (const group of groupedSeries) {
12
19
  const getCategory = resolveAccessor(group.series.x);
20
+ const getMagnitude = resolveAccessor(group.series.y);
13
21
  const defaultColor = colorFor(group.series);
14
22
  const disabledFill = disabledFillFor(group.series.name);
15
23
  for (const seg of group.visualSegments) {
24
+ const realData = seg.data.filter((d) => !isGapValue(getMagnitude(d)));
25
+ if (realData.length === 0)
26
+ continue;
16
27
  markers.push({
17
28
  type: 'bar',
18
29
  role: 'segment',
19
30
  isHorizontal: true,
20
- data: seg.data,
31
+ data: realData,
21
32
  y: getCategory,
22
33
  x1: 0,
23
34
  x2: (d) => valueFor(group.series, d),
@@ -27,6 +38,35 @@ export function buildPyramidBarMarkers(args) {
27
38
  },
28
39
  });
29
40
  }
41
+ const fillMap = gapFillMaps.get(group.series.name) ?? new Map();
42
+ for (const kind of GAP_KINDS) {
43
+ const filledRows = group.series.data.filter((d) => fillMap.get(d)?.kind === kind);
44
+ if (filledRows.length === 0)
45
+ continue;
46
+ const base = resolveGapAreaStyle(fillMap.get(filledRows[0]).style, defaultColor, gapDefaults);
47
+ // svelteplot shallow-clones each row before invoking a mark's own
48
+ // geometry accessors, so a `fillMap.get(d)` lookup inside `x2` would
49
+ // see a clone, not the original key — tag the resolved value onto the
50
+ // row as a plain field instead, which survives that clone.
51
+ const taggedData = filledRows.map((d) => ({
52
+ ...d,
53
+ __gapValue: signFor(group.series, Math.abs(fillMap.get(d).value)),
54
+ }));
55
+ markers.push({
56
+ type: 'bar',
57
+ role: 'segment',
58
+ isHorizontal: true,
59
+ data: taggedData,
60
+ y: getCategory,
61
+ x1: 0,
62
+ x2: (d) => d.__gapValue,
63
+ style: {
64
+ ...base,
65
+ fill: disabledFill?.fill ?? base.fill,
66
+ fillOpacity: disabledFill?.fillOpacity ?? base.fillOpacity,
67
+ },
68
+ });
69
+ }
30
70
  }
31
71
  return markers;
32
72
  }
@@ -20,7 +20,7 @@
20
20
  import type { AxisValue, AxisBasedScalesConfig } from '../../types/layout/scales';
21
21
  import type { Series } from '../../types/plots/data/common';
22
22
  import type { ScatterDataProps } from '../../types/plots/data/scatter';
23
- import type { BasePlotStylesConfig } from '../../types/layout/styles';
23
+ import type { AxisBasedStylesConfig } from '../../types/layout/styles';
24
24
  import type { ScatterSegmentStyle } from '../../types/plots/segments/common';
25
25
  import type { AxisBasedMarkersConfig } from '../../types/markers/common';
26
26
  import type { LegendDisabledStyle } from '../../types/layout/legend';
@@ -36,7 +36,7 @@
36
36
  type Props = BasePlotProps<
37
37
  ScatterDataProps<TData>,
38
38
  TData,
39
- BasePlotStylesConfig,
39
+ AxisBasedStylesConfig,
40
40
  ScatterSegmentStyle,
41
41
  AxisBasedMarkersConfig,
42
42
  AxisBasedScalesConfig<TData>
@@ -1,10 +1,10 @@
1
1
  import type { BasePlotProps } from '../../types/plots/props';
2
2
  import type { AxisBasedScalesConfig } from '../../types/layout/scales';
3
3
  import type { ScatterDataProps } from '../../types/plots/data/scatter';
4
- import type { BasePlotStylesConfig } from '../../types/layout/styles';
4
+ import type { AxisBasedStylesConfig } from '../../types/layout/styles';
5
5
  import type { AxisBasedMarkersConfig } from '../../types/markers/common';
6
6
  declare function $$render<TData extends Record<string, unknown>>(): {
7
- props: BasePlotProps<ScatterDataProps<TData>, TData, BasePlotStylesConfig, import("../..").DotStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
7
+ props: BasePlotProps<ScatterDataProps<TData>, TData, AxisBasedStylesConfig, import("../..").DotStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
8
8
  exports: {};
9
9
  bindings: "";
10
10
  slots: {};
@@ -1,5 +1,6 @@
1
1
  import type { Series } from '../../types/plots/data/common';
2
2
  import type { GapZonesConfig, GapZoneConfig } from '../../types/plots/gaps';
3
+ import type { AreaStyle } from '../../types/plots/styling';
3
4
  /**
4
5
  * Resolves one series' zone config out of `LinePlot`'s full `gaps` prop: a
5
6
  * named entry (keyed by the series' own `name`) applies only to that
@@ -30,3 +31,22 @@ export declare function isGapValue(v: unknown): boolean;
30
31
  * no runs — there's nothing to bridge from or to.
31
32
  */
32
33
  export declare function resolveGapRuns<T extends Record<string, unknown>, TStyle>(series: Series<T>, gaps: GapZonesConfig<TStyle>): GapRun<TStyle>[];
34
+ /** One gap row's resolved fill — the interpolated value to render instead of the missing one, and which zone produced it. */
35
+ export type DiscreteGapFill<TStyle> = {
36
+ value: number;
37
+ kind: 'start' | 'middle' | 'end';
38
+ style?: TStyle;
39
+ };
40
+ /**
41
+ * Bar/pyramid analog of `resolveGapRuns`: a category axis has no continuous
42
+ * bridge to sample, so this returns one interpolated value per *individual*
43
+ * gap row instead. Runs are detected by `series.data`'s own array order
44
+ * (not a numeric `x` sort like `resolveGapRuns` — a category axis is often
45
+ * nominal, so there's no meaningful numeric ordering to sort by). Keyed by
46
+ * row object reference rather than category, since a series' `y` accessor
47
+ * may be an arbitrary function — there's no general way to write the
48
+ * interpolated value back onto a row, so callers look it up here instead.
49
+ */
50
+ export declare function resolveDiscreteGapFills<T extends Record<string, unknown>, TStyle>(series: Series<T>, gaps: GapZonesConfig<TStyle>): Map<T, DiscreteGapFill<TStyle>>;
51
+ /** Field-by-field style fallback for a discrete gap-fill marker — mirrors how `buildGapMarkers.ts` merges a line gap zone's style under `cfg.line.gap`. */
52
+ export declare function resolveGapAreaStyle(zoneStyle: AreaStyle | undefined, defaultColor: string, gapDefaults: AreaStyle): AreaStyle;
@@ -87,3 +87,70 @@ export function resolveGapRuns(series, gaps) {
87
87
  }
88
88
  return runs;
89
89
  }
90
+ /**
91
+ * Bar/pyramid analog of `resolveGapRuns`: a category axis has no continuous
92
+ * bridge to sample, so this returns one interpolated value per *individual*
93
+ * gap row instead. Runs are detected by `series.data`'s own array order
94
+ * (not a numeric `x` sort like `resolveGapRuns` — a category axis is often
95
+ * nominal, so there's no meaningful numeric ordering to sort by). Keyed by
96
+ * row object reference rather than category, since a series' `y` accessor
97
+ * may be an arbitrary function — there's no general way to write the
98
+ * interpolated value back onto a row, so callers look it up here instead.
99
+ */
100
+ export function resolveDiscreteGapFills(series, gaps) {
101
+ const result = new Map();
102
+ if (!gaps.start && !gaps.middle && !gaps.end)
103
+ return result;
104
+ const yFn = resolveAccessor(series.y);
105
+ const rows = series.data;
106
+ const valueAt = (i) => Number(yFn(rows[i]));
107
+ const validIdx = rows.reduce((acc, row, i) => {
108
+ if (!isGapValue(yFn(row)))
109
+ acc.push(i);
110
+ return acc;
111
+ }, []);
112
+ if (validIdx.length === 0)
113
+ return result;
114
+ function fillRun(indices, from, to, zone, kind) {
115
+ const ease = resolveEasing(zone.interpolate);
116
+ const span = indices.length + 1;
117
+ indices.forEach((idx, i) => {
118
+ const t = (i + 1) / span;
119
+ result.set(rows[idx], { value: from + (to - from) * ease(t), kind, style: zone.style });
120
+ });
121
+ }
122
+ const firstValid = validIdx[0];
123
+ if (firstValid > 0 && gaps.start) {
124
+ const to = valueAt(firstValid);
125
+ const from = gaps.start.y != null ? Number(gaps.start.y) : to;
126
+ fillRun(Array.from({ length: firstValid }, (_, i) => i), from, to, gaps.start, 'start');
127
+ }
128
+ if (gaps.middle) {
129
+ for (let k = 0; k < validIdx.length - 1; k++) {
130
+ const a = validIdx[k];
131
+ const b = validIdx[k + 1];
132
+ if (b - a > 1) {
133
+ fillRun(Array.from({ length: b - a - 1 }, (_, i) => a + 1 + i), valueAt(a), valueAt(b), gaps.middle, 'middle');
134
+ }
135
+ }
136
+ }
137
+ const lastValid = validIdx[validIdx.length - 1];
138
+ if (lastValid < rows.length - 1 && gaps.end) {
139
+ const from = valueAt(lastValid);
140
+ const to = gaps.end.y != null ? Number(gaps.end.y) : from;
141
+ fillRun(Array.from({ length: rows.length - 1 - lastValid }, (_, i) => lastValid + 1 + i), from, to, gaps.end, 'end');
142
+ }
143
+ return result;
144
+ }
145
+ /** Field-by-field style fallback for a discrete gap-fill marker — mirrors how `buildGapMarkers.ts` merges a line gap zone's style under `cfg.line.gap`. */
146
+ export function resolveGapAreaStyle(zoneStyle, defaultColor, gapDefaults) {
147
+ return {
148
+ fill: zoneStyle?.fill ?? gapDefaults.fill ?? defaultColor,
149
+ fillOpacity: zoneStyle?.fillOpacity ?? gapDefaults.fillOpacity ?? 1,
150
+ stroke: zoneStyle?.stroke ?? gapDefaults.stroke,
151
+ strokeWidth: zoneStyle?.strokeWidth ?? gapDefaults.strokeWidth,
152
+ strokeOpacity: zoneStyle?.strokeOpacity ?? gapDefaults.strokeOpacity,
153
+ strokeDasharray: zoneStyle?.strokeDasharray ?? gapDefaults.strokeDasharray,
154
+ borderRadius: zoneStyle?.borderRadius ?? gapDefaults.borderRadius,
155
+ };
156
+ }
@@ -48,4 +48,13 @@ export declare function createLabelMarginTracker(margins: () => MarginConfig | u
48
48
  bottom: number | "auto";
49
49
  left: number | "auto";
50
50
  }> | undefined;
51
+ readonly plotProps: {
52
+ margins: Partial<{
53
+ top: number | "auto";
54
+ right: number | "auto";
55
+ bottom: number | "auto";
56
+ left: number | "auto";
57
+ }> | undefined;
58
+ marginRemountKey: string;
59
+ };
51
60
  };
@@ -109,8 +109,19 @@ export function createLabelMarginTracker(margins) {
109
109
  out.bottom = measured.bottom;
110
110
  return out;
111
111
  });
112
+ // Bundles `resolvedMargins` with a remount key derived from `measured`,
113
+ // ready to spread straight onto `<BasePlotLayout>` as its `margins`/
114
+ // `marginRemountKey` props (see that prop's doc comment for *why* a
115
+ // remount key is needed here at all) — keeps the caller from re-deriving
116
+ // the same key by hand, and from having to know it's `measured` that key
117
+ // must track.
118
+ const plotProps = $derived.by(() => ({
119
+ margins: resolvedMargins,
120
+ marginRemountKey: JSON.stringify(measured),
121
+ }));
112
122
  return {
113
123
  report,
114
124
  get resolvedMargins() { return resolvedMargins; },
125
+ get plotProps() { return plotProps; },
115
126
  };
116
127
  }
@@ -1,7 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { AxisValue, AxisBasedScalesConfig } from '../layout/scales';
3
3
  import type { Accessor } from '../plots/data/common';
4
- import type { BasePlotStylesConfig } from '../layout/styles';
4
+ import type { AxisBasedStylesConfig, GapsAwarePlotStylesConfig } from '../layout/styles';
5
5
  import type { SegmentsConfig, MarginConfig } from '../plots/props';
6
6
  import type { AxisBasedMarkersConfig } from '../markers/common';
7
7
  import type { TooltipProp } from '../layout/tooltip';
@@ -30,7 +30,7 @@ export type ChartProps<TRow extends Record<string, unknown>, TSegmentStyle exten
30
30
  x: Accessor<TRow, AxisValue>;
31
31
  y: Accessor<TRow, AxisValue>;
32
32
  z?: Accessor<TRow, unknown>;
33
- styles?: BasePlotStylesConfig;
33
+ styles?: AxisBasedStylesConfig;
34
34
  segments?: SegmentsConfig<TSegmentStyle>;
35
35
  markers?: AxisBasedMarkersConfig[];
36
36
  scales?: AxisBasedScalesConfig<TRow>;
@@ -39,3 +39,12 @@ export type ChartProps<TRow extends Record<string, unknown>, TSegmentStyle exten
39
39
  timeline?: TimelineConfig<TRow>;
40
40
  tooltip?: TooltipProp<TRow>;
41
41
  };
42
+ /**
43
+ * `ChartProps` for the chart kinds with gap-fill (`BarChart`/`LineChart`/
44
+ * `PyramidChart`) — identical shape, but `styles` accepts
45
+ * `GapsAwarePlotStylesConfig<TSegmentStyle>` (adds `styles.gaps`) instead of
46
+ * the plain `AxisBasedStylesConfig` every other chart kind uses.
47
+ */
48
+ export type GapsAwareChartProps<TRow extends Record<string, unknown>, TSegmentStyle extends object = object> = Omit<ChartProps<TRow, TSegmentStyle>, 'styles'> & {
49
+ styles?: GapsAwarePlotStylesConfig<TSegmentStyle>;
50
+ };
@@ -84,7 +84,7 @@ export type ChartConfig = {
84
84
  strokeWidth: number;
85
85
  dotRadius: number;
86
86
  /**
87
- * Default gap-fill bridge styling (`LinePlot`'s `gaps` prop) — the
87
+ * Default gap-fill bridge styling (`LinePlot`'s `styles.gaps`) — the
88
88
  * fallback merged under whatever a gap zone's own `style` sets, the
89
89
  * same way `hover.rule`/`hover.dot` back every hover marker's style.
90
90
  */
@@ -110,6 +110,16 @@ export type ChartConfig = {
110
110
  connectorWidth: number;
111
111
  };
112
112
  };
113
+ /** Default bar-mark styling. */
114
+ bar: {
115
+ /** Default gap-fill styling (`BarPlot`'s `styles.gaps`) — the fallback merged under whatever a gap zone's own `style` sets. */
116
+ gap: AreaStyle;
117
+ };
118
+ /** Default pyramid-bar styling. */
119
+ pyramid: {
120
+ /** Default gap-fill styling (`PyramidPlot`'s `styles.gaps`) — the fallback merged under whatever a gap zone's own `style` sets. */
121
+ gap: AreaStyle;
122
+ };
113
123
  /** Default scatter point geometry. */
114
124
  scatter: {
115
125
  dotRadius: number;
@@ -6,6 +6,7 @@ export type Responsive<T> = T | {
6
6
  };
7
7
  export type FacetColumns = Responsive<number>;
8
8
  export type FacetMode = 'grid' | 'carousel' | 'paginated';
9
+ export type FacetNavLayout = 'overlay' | 'below';
9
10
  export type FacetCellContext<TRow extends Record<string, unknown>> = {
10
11
  facetValue: string;
11
12
  data: TRow[];
@@ -35,6 +36,7 @@ export type FacetConfig<TRow extends Record<string, unknown>> = {
35
36
  mode?: Responsive<FacetMode>;
36
37
  visible?: number;
37
38
  pageSize?: number;
39
+ navLayout?: FacetNavLayout;
38
40
  formatIndicator?: (current: number, total: number) => string;
39
41
  indicator?: FacetIndicatorSnippet;
40
42
  navButton?: FacetNavSnippet;
@@ -1,6 +1,7 @@
1
1
  import type { ValueAnchor } from '../plots/constants';
2
2
  import type { FontStyle, StrokeStyle, AreaStyle } from '../plots/styling';
3
3
  import type { GeoFeature } from '../plots/data/geo';
4
+ import type { GapsConfig } from '../plots/gaps';
4
5
  /**
5
6
  * Controls if and how value labels are rendered on a plot. The high-level
6
7
  * `anchor` sets sensible defaults for placement; `fontStyle` (`dx`, `dy`,
@@ -47,16 +48,34 @@ export type FrameStyle = AreaStyle & {
47
48
  };
48
49
  /** Author-facing `styles.frame` prop — see {@link FrameStyle}. */
49
50
  export type FrameProp = boolean | FrameStyle;
51
+ /**
52
+ * The fields every plot kind's own `styles` shape shares, regardless of
53
+ * whether it's built on axes ({@link AxisBasedStylesConfig}) or geometry
54
+ * ({@link GeoStylesConfig}) — the true common parent of the two, unlike the
55
+ * name `AxisBasedStylesConfig` might suggest before this split existed.
56
+ */
57
+ export type BasePlotStylesConfig = {
58
+ /** Decorative border around the plot's content box — see {@link FrameStyle}. Available on every plot kind. */
59
+ frame?: FrameProp;
60
+ };
50
61
  /**
51
62
  * Top-level rendering style overrides shared by the non-geo plot kinds.
52
63
  * Passed as the `styles` prop. Each plot reads only the fields it cares
53
64
  * about.
54
65
  */
55
- export type BasePlotStylesConfig = {
66
+ export type AxisBasedStylesConfig = BasePlotStylesConfig & {
56
67
  values?: ValuesStyle;
57
68
  colors?: ColorsStyle;
58
- /** Decorative border around the plot's content box — see {@link FrameStyle}. Available on every plot kind. */
59
- frame?: FrameProp;
69
+ };
70
+ /**
71
+ * `AxisBasedStylesConfig` extended with `gaps` — the interpolated
72
+ * missing-data bridge fill available to plot kinds with an inherent
73
+ * category/sequence ordering (`LinePlot`, `BarPlot`, `PyramidPlot`).
74
+ * Resolved per series like `segments`, at zone granularity — see
75
+ * {@link GapsConfig}.
76
+ */
77
+ export type GapsAwarePlotStylesConfig<TSegmentStyle extends object> = AxisBasedStylesConfig & {
78
+ gaps?: GapsConfig<TSegmentStyle>;
60
79
  };
61
80
  export type GeoTileLayerConfig = {
62
81
  /** XYZ tile URL template, e.g. `'https://tile.openstreetmap.org/{z}/{x}/{y}.png'`. */
@@ -69,12 +88,13 @@ export type GeoTileLayerConfig = {
69
88
  tileSize?: number;
70
89
  };
71
90
  /**
72
- * `styles` prop for GeoPlot — the geo analog of `BasePlotStylesConfig`.
73
- * Unlike the other plot kinds, GeoPlot's styling needs (base map, choropleth
74
- * ramp, tile background, click handling) are unlike anything x/y plots need,
75
- * so this is its own type rather than a reuse of `BasePlotStylesConfig`.
91
+ * `styles` prop for GeoPlot — the geo analog of `AxisBasedStylesConfig`,
92
+ * sharing only {@link BasePlotStylesConfig}'s common ground with it. Unlike
93
+ * the other plot kinds, GeoPlot's styling needs (base map, choropleth ramp,
94
+ * tile background, click handling) are unlike anything x/y plots need, so
95
+ * this is its own type rather than a reuse of `AxisBasedStylesConfig`.
76
96
  */
77
- export type GeoStylesConfig<TProps extends Record<string, unknown> = Record<string, unknown>> = {
97
+ export type GeoStylesConfig<TProps extends Record<string, unknown> = Record<string, unknown>> = BasePlotStylesConfig & {
78
98
  /** Base map fill, used when a feature isn't styled by `segments` or the choropleth ramp. */
79
99
  fill?: string;
80
100
  fillOpacity?: number;
@@ -86,8 +106,6 @@ export type GeoStylesConfig<TProps extends Record<string, unknown> = Record<stri
86
106
  tileLayer?: GeoTileLayerConfig;
87
107
  /** Fired when a base-map feature is clicked. */
88
108
  onFeatureClick?: (feature: GeoFeature<TProps>, event: Event) => void;
89
- /** Decorative border around the plot's content box — see {@link FrameStyle}. Available on every plot kind. */
90
- frame?: FrameProp;
91
109
  };
92
110
  /**
93
111
  * `GeoTileLayerConfig`, plus `features` — never author-facing (the public
@@ -103,7 +121,7 @@ type GeoTileLayerConfigWithFeatures = GeoTileLayerConfig & {
103
121
  };
104
122
  /**
105
123
  * The minimal slice of a plot kind's own `styles` prop `StylesLayout` reads —
106
- * every concrete `styles` type ({@link BasePlotStylesConfig},
124
+ * every concrete `styles` type ({@link AxisBasedStylesConfig},
107
125
  * {@link GeoStylesConfig}) structurally satisfies this whether or not it
108
126
  * declares `tileLayer` at all (a missing optional field type-checks fine).
109
127
  */
@@ -18,6 +18,11 @@ export type GapZoneConfig<TStyle> = {
18
18
  * value, i.e. a flat extrapolation). Omitting the zone entirely leaves that
19
19
  * end of the series unfilled — extrapolating without an explicit target
20
20
  * would imply data that doesn't exist.
21
+ *
22
+ * On `LinePlot`, `x`'s value is the actual spatial target the bridge draws
23
+ * out to (its axis is continuous). On `BarPlot`/`PyramidPlot`, each gap row
24
+ * already has its own real category, so `x`'s *presence* is only the opt-in
25
+ * gate — its value isn't read; `y` is what drives the fill.
21
26
  */
22
27
  export type OpenGapZoneConfig<TStyle> = GapZoneConfig<TStyle> & {
23
28
  x: AxisValue;
@@ -29,11 +34,21 @@ export type OpenGapZoneConfig<TStyle> = GapZoneConfig<TStyle> & {
29
34
  * sides) and `end` (after its last real point). A row counts as missing
30
35
  * when its resolved value is `null`, `undefined`, or `NaN` — the same
31
36
  * convention svelteplot's own `Line` mark already uses to break the line
32
- * there. See {@link GapsConfig} (`types/plots/props.ts`) for how this is
33
- * keyed per series on `LinePlot`'s own `gaps` prop.
37
+ * there. See {@link GapsConfig} for how this is keyed per series on a
38
+ * gap-aware plot kind's `styles.gaps`.
34
39
  */
35
40
  export type GapZonesConfig<TStyle> = {
36
41
  start?: OpenGapZoneConfig<TStyle>;
37
42
  middle?: GapZoneConfig<TStyle>;
38
43
  end?: OpenGapZoneConfig<TStyle>;
39
44
  };
45
+ /**
46
+ * The `gaps` field a gap-aware plot kind's `styles` accepts (see
47
+ * {@link GapsAwarePlotStylesConfig}, `types/layout/styles.ts`) — series name
48
+ * (or `'default'` for all series) to that series' {@link GapZonesConfig}.
49
+ * Mirrors `SegmentsConfig`'s series-keyed shape: a named entry applies only
50
+ * to that series; `'default'` fills in whichever of its zones
51
+ * (`start`/`middle`/`end`) the named entry itself leaves unset, at zone
52
+ * granularity rather than a merged style.
53
+ */
54
+ export type GapsConfig<TStyle> = Record<string, GapZonesConfig<TStyle>>;
@@ -1,10 +1,9 @@
1
1
  import type { HoverPoint, HoverStrategy, TooltipOptions } from '../layout/tooltip';
2
2
  import type { Segment } from './segments/config';
3
- import type { GapZonesConfig } from './gaps';
4
3
  import type { AxisBasedScalesConfig } from '../layout/scales';
5
4
  import type { GeoScalesConfig } from '../layout/coordinates';
6
5
  /** The `styles` prop accepted by every plot kind — its own
7
- * styles shape ({@link BasePlotStylesConfig}, `GeoStylesConfig`, …). */
6
+ * styles shape ({@link AxisBasedStylesConfig}, `GeoStylesConfig`, …). */
8
7
  export type StylesConfig<TStyles extends object> = TStyles;
9
8
  /** The `markers` prop accepted by every plot kind — a list of that kind's own marker union. */
10
9
  export type MarkersConfig<TMarker> = TMarker[];
@@ -15,14 +14,6 @@ export type MarkersConfig<TMarker> = TMarker[];
15
14
  * area-specific segments merge on top and win on conflict.
16
15
  */
17
16
  export type SegmentsConfig<TStyle> = Record<string, Segment<TStyle>[]>;
18
- /**
19
- * The `gaps` prop `LinePlot` accepts — series name (or `'default'` for all
20
- * series) to that series' {@link GapZonesConfig}. Mirrors `SegmentsConfig`'s
21
- * series-keyed shape: a named entry applies only to that series; `'default'`
22
- * fills in whichever of its zones (`start`/`middle`/`end`) the named entry
23
- * itself leaves unset, at zone granularity rather than a merged style.
24
- */
25
- export type GapsConfig<TStyle> = Record<string, GapZonesConfig<TStyle>>;
26
17
  /**
27
18
  * Partial margin override — unset sides fall back to the theme (itself
28
19
  * `'auto'` by default). `'auto'` fits the side to its rendered content; a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fundar/data-chart-telling",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"