@fundar/data-chart-telling 0.0.13 → 0.0.15

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 (141) hide show
  1. package/README.md +121 -17
  2. package/dist/charts/{Chart.svelte.d.ts → BaseChart.svelte.d.ts} +3 -3
  3. package/dist/charts/bar/Chart.svelte +5 -5
  4. package/dist/charts/bar/Chart.svelte.d.ts +1 -2
  5. package/dist/charts/heatmap/Chart.svelte +8 -7
  6. package/dist/charts/heatmap/Chart.svelte.d.ts +2 -3
  7. package/dist/charts/line/Chart.svelte +5 -5
  8. package/dist/charts/line/Chart.svelte.d.ts +1 -2
  9. package/dist/charts/pyramid/Chart.svelte +7 -6
  10. package/dist/charts/pyramid/Chart.svelte.d.ts +2 -3
  11. package/dist/configuration/config.svelte.js +1 -1
  12. package/dist/configuration/themes/index.d.ts +56 -40
  13. package/dist/index.d.ts +26 -12
  14. package/dist/index.js +12 -7
  15. package/dist/layout/facet/FacetLayout.svelte +1 -1
  16. package/dist/layout/facet/FacetLayout.svelte.d.ts +1 -1
  17. package/dist/layout/geo/GeoLayout.svelte +47 -0
  18. package/dist/layout/geo/GeoLayout.svelte.d.ts +22 -0
  19. package/dist/layout/geo/resolveProjection.d.ts +10 -0
  20. package/dist/layout/geo/resolveProjection.js +48 -0
  21. package/dist/layout/legend/DiscreteSection.svelte +1 -1
  22. package/dist/layout/plot/AxisLayout.svelte +95 -0
  23. package/dist/layout/plot/AxisLayout.svelte.d.ts +39 -0
  24. package/dist/layout/plot/BasePlotLayout.svelte +302 -0
  25. package/dist/layout/plot/BasePlotLayout.svelte.d.ts +95 -0
  26. package/dist/layout/plot/GridLayout.svelte +30 -0
  27. package/dist/layout/plot/GridLayout.svelte.d.ts +27 -0
  28. package/dist/layout/plot/RuleLayout.svelte +111 -0
  29. package/dist/layout/plot/RuleLayout.svelte.d.ts +40 -0
  30. package/dist/layout/plot/margins.d.ts +34 -0
  31. package/dist/layout/plot/margins.js +26 -0
  32. package/dist/layout/timeline/TimelineLayout.svelte +1 -1
  33. package/dist/layout/timeline/TimelineLayout.svelte.d.ts +1 -1
  34. package/dist/layout/tooltip/Tooltip.svelte +15 -0
  35. package/dist/layout/tooltip/Tooltip.svelte.d.ts +7 -0
  36. package/dist/layout/tooltip/TooltipLayout.svelte +45 -0
  37. package/dist/layout/tooltip/TooltipLayout.svelte.d.ts +41 -0
  38. package/dist/layout/tooltip/controller.svelte.d.ts +4 -3
  39. package/dist/layout/tooltip/controller.svelte.js +5 -6
  40. package/dist/layout/tooltip/hover.svelte.d.ts +1 -1
  41. package/dist/layout/tooltip/hover.svelte.js +1 -1
  42. package/dist/layout/tooltip/utils.d.ts +2 -2
  43. package/dist/markers/ContourClipMarker.svelte +77 -0
  44. package/dist/markers/ContourClipMarker.svelte.d.ts +10 -0
  45. package/dist/{plots/markers → markers}/DeltaMarker.svelte +4 -4
  46. package/dist/{plots/markers → markers}/DeltaMarker.svelte.d.ts +3 -3
  47. package/dist/{plots/markers → markers}/DotMarker.svelte +3 -3
  48. package/dist/{plots/markers → markers}/DotMarker.svelte.d.ts +3 -3
  49. package/dist/markers/HoverMarker.svelte +136 -0
  50. package/dist/{plots/markers → markers}/HoverMarker.svelte.d.ts +4 -4
  51. package/dist/{plots/markers → markers}/PeakMarker.svelte +2 -2
  52. package/dist/{plots/markers → markers}/PeakMarker.svelte.d.ts +2 -2
  53. package/dist/{plots/markers → markers}/TextMarker.svelte +11 -4
  54. package/dist/{plots/markers → markers}/TextMarker.svelte.d.ts +3 -3
  55. package/dist/markers/inset/InsetMarker.svelte +170 -0
  56. package/dist/markers/inset/InsetMarker.svelte.d.ts +51 -0
  57. package/dist/markers/inset/insetLayout.d.ts +25 -0
  58. package/dist/markers/inset/insetLayout.js +39 -0
  59. package/dist/markers/inset/insetProjection.d.ts +8 -0
  60. package/dist/markers/inset/insetProjection.js +39 -0
  61. package/dist/plots/bar/BarSegments.svelte +66 -0
  62. package/dist/plots/bar/BarSegments.svelte.d.ts +36 -0
  63. package/dist/plots/bar/Plot.svelte +132 -76
  64. package/dist/plots/bar/Plot.svelte.d.ts +7 -3
  65. package/dist/plots/bar/ValueLabels.svelte +89 -0
  66. package/dist/plots/bar/ValueLabels.svelte.d.ts +39 -0
  67. package/dist/plots/bar/hoverPoints.d.ts +15 -0
  68. package/dist/plots/bar/hoverPoints.js +35 -0
  69. package/dist/plots/bar/layout.svelte.d.ts +37 -0
  70. package/dist/plots/bar/layout.svelte.js +132 -0
  71. package/dist/plots/geo/Plot.svelte +548 -0
  72. package/dist/plots/geo/Plot.svelte.d.ts +29 -0
  73. package/dist/plots/geo/TileLayer.svelte +77 -0
  74. package/dist/plots/geo/TileLayer.svelte.d.ts +11 -0
  75. package/dist/plots/geo/projections/argentina.d.ts +8 -0
  76. package/dist/plots/geo/projections/argentina.js +35 -0
  77. package/dist/plots/geo/projections/fit.d.ts +8 -0
  78. package/dist/plots/geo/projections/fit.js +14 -0
  79. package/dist/plots/geo/rotate.svelte.d.ts +26 -0
  80. package/dist/plots/geo/rotate.svelte.js +79 -0
  81. package/dist/plots/geo/zoom.svelte.d.ts +32 -0
  82. package/dist/plots/geo/zoom.svelte.js +50 -0
  83. package/dist/plots/heatmap/Plot.svelte +129 -47
  84. package/dist/plots/heatmap/Plot.svelte.d.ts +7 -3
  85. package/dist/plots/line/Plot.svelte +44 -16
  86. package/dist/plots/line/Plot.svelte.d.ts +7 -3
  87. package/dist/plots/pyramid/Plot.svelte +70 -25
  88. package/dist/plots/pyramid/Plot.svelte.d.ts +7 -3
  89. package/dist/plots/utils/delta.d.ts +1 -1
  90. package/dist/plots/utils/geoAccessors.d.ts +64 -0
  91. package/dist/plots/utils/geoAccessors.js +188 -0
  92. package/dist/plots/utils/geoSegments.d.ts +14 -0
  93. package/dist/plots/utils/geoSegments.js +17 -0
  94. package/dist/plots/utils/segments.d.ts +14 -5
  95. package/dist/plots/utils/segments.js +25 -13
  96. package/dist/plots/utils/tiles.d.ts +89 -0
  97. package/dist/plots/utils/tiles.js +159 -0
  98. package/dist/plots/utils/topojson.d.ts +9 -0
  99. package/dist/plots/utils/topojson.js +30 -0
  100. package/dist/types/charts/common.d.ts +2 -1
  101. package/dist/types/charts/legend.d.ts +1 -1
  102. package/dist/types/charts/props.d.ts +9 -6
  103. package/dist/types/configuration/styling.d.ts +11 -5
  104. package/dist/types/layout/tooltip.d.ts +14 -21
  105. package/dist/types/{plots/markers.d.ts → markers/common.d.ts} +2 -18
  106. package/dist/types/markers/geo.d.ts +237 -0
  107. package/dist/types/markers/props.d.ts +11 -0
  108. package/dist/types/plots/axis.d.ts +55 -0
  109. package/dist/types/plots/axis.js +1 -0
  110. package/dist/types/plots/constants.d.ts +30 -0
  111. package/dist/types/plots/constants.js +1 -0
  112. package/dist/types/plots/data/common.d.ts +40 -0
  113. package/dist/types/plots/data/common.js +1 -0
  114. package/dist/types/plots/data/geo.d.ts +74 -0
  115. package/dist/types/plots/data/geo.js +1 -0
  116. package/dist/types/plots/delta.d.ts +2 -2
  117. package/dist/types/plots/props.d.ts +105 -16
  118. package/dist/types/plots/scales/geo.d.ts +44 -0
  119. package/dist/types/plots/scales/geo.js +1 -0
  120. package/dist/types/plots/segments/common.d.ts +25 -0
  121. package/dist/types/plots/segments/common.js +1 -0
  122. package/dist/types/plots/segments/config.d.ts +51 -0
  123. package/dist/types/plots/segments/config.js +1 -0
  124. package/dist/types/plots/styles/common.d.ts +37 -0
  125. package/dist/types/plots/styles/common.js +1 -0
  126. package/dist/types/plots/styles/geo.d.ts +42 -0
  127. package/dist/types/plots/styles/geo.js +1 -0
  128. package/dist/types/plots/styling.d.ts +45 -0
  129. package/dist/types/plots/styling.js +1 -0
  130. package/dist/utils/grouping.d.ts +2 -1
  131. package/dist/utils/interpolate.d.ts +2 -1
  132. package/package.json +27 -13
  133. package/dist/layout/plot/PlotLayout.svelte +0 -237
  134. package/dist/layout/plot/PlotLayout.svelte.d.ts +0 -70
  135. package/dist/plots/markers/HoverMarker.svelte +0 -98
  136. package/dist/types/plots/common.d.ts +0 -100
  137. package/dist/types/plots/styles.d.ts +0 -187
  138. /package/dist/charts/{Chart.svelte → BaseChart.svelte} +0 -0
  139. /package/dist/types/{plots → markers}/common.js +0 -0
  140. /package/dist/types/{plots/markers.js → markers/geo.js} +0 -0
  141. /package/dist/types/{plots/styles.js → markers/props.js} +0 -0
package/dist/index.d.ts CHANGED
@@ -2,35 +2,49 @@ export { default as BarPlot } from './plots/bar/Plot.svelte';
2
2
  export { default as HeatmapPlot } from './plots/heatmap/Plot.svelte';
3
3
  export { default as LinePlot } from './plots/line/Plot.svelte';
4
4
  export { default as PyramidPlot } from './plots/pyramid/Plot.svelte';
5
- export { default as Chart } from './charts/Chart.svelte';
5
+ export { default as GeoPlot } from './plots/geo/Plot.svelte';
6
+ export { default as BaseChart } from './charts/BaseChart.svelte';
6
7
  export { default as BarChart } from './charts/bar/Chart.svelte';
7
8
  export { default as HeatmapChart } from './charts/heatmap/Chart.svelte';
8
9
  export { default as LineChart } from './charts/line/Chart.svelte';
9
10
  export { default as PyramidChart } from './charts/pyramid/Chart.svelte';
10
11
  export { default as ChartContainer } from './charts/container/ChartContainer.svelte';
11
- export { default as PlotLayout } from './layout/plot/PlotLayout.svelte';
12
+ export { default as BasePlotLayout } from './layout/plot/BasePlotLayout.svelte';
13
+ export { default as GeoLayout } from './layout/geo/GeoLayout.svelte';
14
+ export { default as TileLayer } from './plots/geo/TileLayer.svelte';
15
+ export { argentinaBicontinental } from './plots/geo/projections/argentina';
12
16
  export { default as Timeline } from './layout/timeline/Timeline.svelte';
13
17
  export { default as TimelineLayout } from './layout/timeline/TimelineLayout.svelte';
14
18
  export { default as FacetLayout } from './layout/facet/FacetLayout.svelte';
15
19
  export { default as LegendLayout } from './layout/legend/LegendLayout.svelte';
16
20
  export { default as Tooltip } from './layout/tooltip/Tooltip.svelte';
17
- export { default as DeltaMarker } from './plots/markers/DeltaMarker.svelte';
18
- export { default as DotMarker } from './plots/markers/DotMarker.svelte';
19
- export { default as HoverMarker } from './plots/markers/HoverMarker.svelte';
20
- export { default as PeakMarker } from './plots/markers/PeakMarker.svelte';
21
- export { default as TextMarker } from './plots/markers/TextMarker.svelte';
21
+ export { default as DeltaMarker } from './markers/DeltaMarker.svelte';
22
+ export { default as DotMarker } from './markers/DotMarker.svelte';
23
+ export { default as HoverMarker } from './markers/HoverMarker.svelte';
24
+ export { default as PeakMarker } from './markers/PeakMarker.svelte';
25
+ export { default as TextMarker } from './markers/TextMarker.svelte';
22
26
  export { setConfiguration, getConfiguration, resetConfiguration, configToCssVars, cssVarsStyle, DEFAULT_CONFIG, } from './configuration/config.svelte';
23
27
  export { THEMES } from './configuration/themes';
24
28
  export type { ThemeName } from './configuration/themes';
25
29
  export { groupBy, buildSeries } from './utils/grouping';
26
30
  export { makeColorScale, normalize, resolveCssColor, paletteColor } from './utils/color';
27
- export type { AxisValue, Accessor, AxisScale, ScalesConfig, Series, SeriesProps, DataProps } from './types/plots/common';
31
+ export type { AxisValue, AxisScale } from './types/plots/axis';
32
+ export type { Accessor, Series, SeriesProps, DataProps } from './types/plots/data/common';
33
+ export type { BasePlotProps, StylesConfig, MarkersConfig, SegmentsConfig, AxisBasedScalesConfig, GeoScalesConfig, ScalesConfig, MarginConfig, TooltipConfig, } from './types/plots/props';
28
34
  export type { DeltaConfig, } from './types/plots/delta';
29
- export type { SymbolType, LineStyle, StrokeStyle, DotStyle, FontStyle, LineSegmentStyle, BarSegmentStyle, CellSegmentStyle, Range, Area, Segment, SeriesAwareSegmentsMap, DefaultSegmentsMap, SegmentsStyle, Segments, ValueAnchor, ValuesStyle, ColorsStyle, PlotStyles, } from './types/plots/styles';
30
- export type { Marker, MarkerProps } from './types/plots/markers';
31
- export type { PlotProps } from './types/plots/props';
35
+ export type { ValuesStyle, ColorsStyle, BasePlotStyles, } from './types/plots/styles/common';
36
+ export type { LineSegmentStyle, BarSegmentStyle, CellSegmentStyle, GeoSegmentStyle } from './types/plots/segments/common';
37
+ export type { Range, Area, Segment } from './types/plots/segments/config';
38
+ export type { ValueAnchor, SymbolType, LineStyle, LineCap, LineJoin, FontWeight, FontStyleKeyword, TextAnchor, LineAnchor, } from './types/plots/constants';
39
+ export type { FontStyle, StrokeStyle, DotStyle } from './types/plots/styling';
40
+ export type { Marker } from './types/markers/common';
41
+ export type { MarkerProps } from './types/markers/props';
42
+ export type { GeoFeature, GeoJsonInput, GeoDataProps, Topology } from './types/plots/data/geo';
43
+ export type { GeoProjectionName, GeoProjectionConfig, GeoCustomProjection, GeoCustomProjectionFactory, } from './types/plots/scales/geo';
44
+ export type { GeoStyles, GeoTileLayerConfig, GeoZoomConfig } from './types/plots/styles/geo';
45
+ export type { GeoMarker, GeoInsetMarker, GeoInsetLocation, GeoInsetProjectionName, GeoInsetProjectionConfig, } from './types/markers/geo';
32
46
  export type { TimeValue, Orientation, FacetColumns, FacetConfig, TimelineConfig, ChartPlotContext, ChartPlotSnippet, } from './types/charts/common';
33
47
  export type { LegendSection, DiscreteLegendSection, ContinuousLegendSection, LegendItem, } from './types/charts/legend';
34
- export type { HoverStrategy, TooltipOptions, TooltipProp, TooltipRuntime, } from './types/layout/tooltip';
48
+ export type { HoverStrategy, TooltipOptions, TooltipProp, } from './types/layout/tooltip';
35
49
  export type { ChartConfig, ChartConfigInput, TextStyle } from './types/configuration/styling';
36
50
  export type { ChartProps } from './types/charts/props';
package/dist/index.js CHANGED
@@ -4,27 +4,32 @@ export { default as BarPlot } from './plots/bar/Plot.svelte';
4
4
  export { default as HeatmapPlot } from './plots/heatmap/Plot.svelte';
5
5
  export { default as LinePlot } from './plots/line/Plot.svelte';
6
6
  export { default as PyramidPlot } from './plots/pyramid/Plot.svelte';
7
+ export { default as GeoPlot } from './plots/geo/Plot.svelte';
7
8
  // ── Charts ──────────────────────────────────────────────────────────────────
8
9
  // High-level, plot-agnostic chrome plus ready-made chart kinds.
9
- export { default as Chart } from './charts/Chart.svelte';
10
+ export { default as BaseChart } from './charts/BaseChart.svelte';
10
11
  export { default as BarChart } from './charts/bar/Chart.svelte';
11
12
  export { default as HeatmapChart } from './charts/heatmap/Chart.svelte';
12
13
  export { default as LineChart } from './charts/line/Chart.svelte';
13
14
  export { default as PyramidChart } from './charts/pyramid/Chart.svelte';
14
15
  // Interchangeable layout primitives (compose your own chart kinds with these).
15
16
  export { default as ChartContainer } from './charts/container/ChartContainer.svelte';
16
- export { default as PlotLayout } from './layout/plot/PlotLayout.svelte';
17
+ export { default as BasePlotLayout } from './layout/plot/BasePlotLayout.svelte';
18
+ export { default as GeoLayout } from './layout/geo/GeoLayout.svelte';
19
+ export { default as TileLayer } from './plots/geo/TileLayer.svelte';
20
+ // Custom geo projections — usable as `scales.projection.type`.
21
+ export { argentinaBicontinental } from './plots/geo/projections/argentina';
17
22
  export { default as Timeline } from './layout/timeline/Timeline.svelte';
18
23
  export { default as TimelineLayout } from './layout/timeline/TimelineLayout.svelte';
19
24
  export { default as FacetLayout } from './layout/facet/FacetLayout.svelte';
20
25
  export { default as LegendLayout } from './layout/legend/LegendLayout.svelte';
21
26
  export { default as Tooltip } from './layout/tooltip/Tooltip.svelte';
22
27
  // Markers
23
- export { default as DeltaMarker } from './plots/markers/DeltaMarker.svelte';
24
- export { default as DotMarker } from './plots/markers/DotMarker.svelte';
25
- export { default as HoverMarker } from './plots/markers/HoverMarker.svelte';
26
- export { default as PeakMarker } from './plots/markers/PeakMarker.svelte';
27
- export { default as TextMarker } from './plots/markers/TextMarker.svelte';
28
+ export { default as DeltaMarker } from './markers/DeltaMarker.svelte';
29
+ export { default as DotMarker } from './markers/DotMarker.svelte';
30
+ export { default as HoverMarker } from './markers/HoverMarker.svelte';
31
+ export { default as PeakMarker } from './markers/PeakMarker.svelte';
32
+ export { default as TextMarker } from './markers/TextMarker.svelte';
28
33
  export { setConfiguration, getConfiguration, resetConfiguration, configToCssVars, cssVarsStyle, DEFAULT_CONFIG, } from './configuration/config.svelte';
29
34
  export { THEMES } from './configuration/themes';
30
35
  // ── Utils ─────────────────────────────────────────────────────────────────────
@@ -5,7 +5,7 @@
5
5
  FacetColumns,
6
6
  FacetCellSnippet,
7
7
  } from '../../types/charts/common';
8
- import type { Accessor } from '../../types/plots/common';
8
+ import type { Accessor } from '../../types/plots/data/common';
9
9
 
10
10
  /**
11
11
  * Small-multiples layout. It splits the data by `by`, arranges the groups in a
@@ -1,5 +1,5 @@
1
1
  import type { FacetColumns, FacetCellSnippet } from '../../types/charts/common';
2
- import type { Accessor } from '../../types/plots/common';
2
+ import type { Accessor } from '../../types/plots/data/common';
3
3
  declare function $$render<TRow extends Record<string, unknown>>(): {
4
4
  props: {
5
5
  data: TRow[];
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import TileLayer from '../../plots/geo/TileLayer.svelte';
4
+ import type { GeoTileLayerConfig } from '../../types/plots/styles/geo';
5
+
6
+ /**
7
+ * Geo-only chrome nested inside `BasePlotLayout` (the `GeoPlot` analog of
8
+ * `AxisLayout`/`GridLayout`/`RuleLayout`) — just the pan/zoom transform
9
+ * group and the raster tile layer underneath the map's own marks.
10
+ * Everything else GeoPlot used to duplicate from `BasePlotLayout` (the hover
11
+ * state machine, `<Plot>` itself, `<Pointer>`, the tooltip) now lives
12
+ * exclusively in `BasePlotLayout`; the zoom/rotate *gesture* state itself lives
13
+ * in `GeoPlot`'s own `Plot.svelte` (it also feeds the projection's
14
+ * `rotate`, which has to reach `BasePlotLayout`'s `<Plot projection>` prop —
15
+ * something a component nested *inside* that same `<Plot>` has no way to
16
+ * reach back out to), and is only handed down here as an already-resolved
17
+ * `zoomTransform` to apply.
18
+ */
19
+ let {
20
+ width,
21
+ height,
22
+ numericMargins,
23
+ zoomTransform,
24
+ tileLayer,
25
+ children,
26
+ }: {
27
+ width: number;
28
+ height: number;
29
+ numericMargins: { top: number; right: number; bottom: number; left: number };
30
+ zoomTransform: { x: number; y: number; k: number };
31
+ tileLayer?: GeoTileLayerConfig;
32
+ children: Snippet;
33
+ } = $props();
34
+ </script>
35
+
36
+ <g transform="translate({zoomTransform.x}, {zoomTransform.y}) scale({zoomTransform.k})">
37
+ {#if tileLayer}
38
+ <TileLayer
39
+ config={tileLayer}
40
+ left={numericMargins.left}
41
+ top={numericMargins.top}
42
+ width={Math.max(0, width - numericMargins.left - numericMargins.right)}
43
+ height={Math.max(0, height - numericMargins.top - numericMargins.bottom)}
44
+ />
45
+ {/if}
46
+ {@render children()}
47
+ </g>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { GeoTileLayerConfig } from '../../types/plots/styles/geo';
3
+ type $$ComponentProps = {
4
+ width: number;
5
+ height: number;
6
+ numericMargins: {
7
+ top: number;
8
+ right: number;
9
+ bottom: number;
10
+ left: number;
11
+ };
12
+ zoomTransform: {
13
+ x: number;
14
+ y: number;
15
+ k: number;
16
+ };
17
+ tileLayer?: GeoTileLayerConfig;
18
+ children: Snippet;
19
+ };
20
+ declare const GeoLayout: import("svelte").Component<$$ComponentProps, {}, "">;
21
+ type GeoLayout = ReturnType<typeof GeoLayout>;
22
+ export default GeoLayout;
@@ -0,0 +1,10 @@
1
+ import type { GeoProjectionConfig } from '../../types/plots/scales/geo';
2
+ /**
3
+ * Resolves a `GeoScalesConfig['projection']` into what svelteplot's own
4
+ * `<Plot projection>` expects — kept separate from `GeoPlot`'s own
5
+ * `Plot.svelte` so adding more projection-level behavior (like the
6
+ * `domain: 'data'` sentinel below) doesn't grow that component itself.
7
+ */
8
+ export declare function resolveProjection<TFeature extends Record<string, unknown> & {
9
+ geometry?: unknown;
10
+ }>(projection: GeoProjectionConfig | undefined, data: TFeature[]): GeoProjectionConfig;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `data` (see `resolveProjection`) is one row per disjoint geometry *part*
3
+ * (see `Plot.svelte`'s `hoverCandidates` — needed so hover-matching finds
4
+ * every part of a multi-part feature, not just whichever one its combined
5
+ * centroid happens to land near), not one row per feature. Several rows
6
+ * therefore share the exact same `geometry` object by reference — spread
7
+ * from the same tagged feature, only `__cx`/`__cy` differ. Deduping by that
8
+ * reference before handing rows to d3-geo's bounds/fit computation matters:
9
+ * a feature with many parts (e.g. a province whose `MultiPolygon` has
10
+ * hundreds of small islands) would otherwise have its *entire* geometry
11
+ * re-traversed once per part it contributed, an accidental O(parts²) cost
12
+ * that got severe enough to be visible (multi-second) on real IGN data.
13
+ */
14
+ function dedupeByGeometry(data) {
15
+ const seen = new Set();
16
+ const result = [];
17
+ for (const row of data) {
18
+ if (seen.has(row.geometry))
19
+ continue;
20
+ seen.add(row.geometry);
21
+ result.push(row);
22
+ }
23
+ return result;
24
+ }
25
+ /**
26
+ * Resolves a `GeoScalesConfig['projection']` into what svelteplot's own
27
+ * `<Plot projection>` expects — kept separate from `GeoPlot`'s own
28
+ * `Plot.svelte` so adding more projection-level behavior (like the
29
+ * `domain: 'data'` sentinel below) doesn't grow that component itself.
30
+ */
31
+ export function resolveProjection(projection, data) {
32
+ if (!projection)
33
+ return 'equal-earth';
34
+ if (typeof projection === 'string')
35
+ return projection;
36
+ const domain = projection.domain === 'data'
37
+ ? { type: 'FeatureCollection', features: dedupeByGeometry(data) }
38
+ : projection.domain;
39
+ return {
40
+ type: projection.type,
41
+ rotate: projection.rotate,
42
+ center: projection.center,
43
+ parallels: projection.parallels,
44
+ inset: projection.inset,
45
+ clip: projection.clip,
46
+ domain,
47
+ };
48
+ }
@@ -2,7 +2,7 @@
2
2
  import { getConfiguration } from '../../configuration/config.svelte';
3
3
  import { paletteColor } from '../../utils/color';
4
4
  import type { DiscreteLegendSection } from '../../types/charts/legend';
5
- import type { LineStyle } from '../../types/plots/styles';
5
+ import type { LineStyle } from '../../types/plots/constants';
6
6
 
7
7
  let { section }: { section: DiscreteLegendSection } = $props();
8
8
 
@@ -0,0 +1,95 @@
1
+ <script lang="ts" generics="TData extends Record<string, unknown>">
2
+ import { AxisX, AxisY } from 'svelteplot';
3
+ import { getConfiguration } from '../../configuration/config.svelte';
4
+ import type { AxisValue } from '../../types/plots/axis';
5
+ import type { AxisBasedScalesConfig } from '../../types/plots/props';
6
+
7
+ /**
8
+ * Axis ticks/titles for the plot kinds that have an x/y axis pair
9
+ * (line/bar/heatmap/pyramid) — reads the scale/tick config off `scales`,
10
+ * against the plot's own resolved margins. Not used by `GeoPlot`, whose
11
+ * position comes from a `d3-geo` projection instead (see `GeoLayout`).
12
+ * `AxisX`/`AxisY` themselves inherit their actual scale from svelteplot's
13
+ * `<Plot>` context — this only supplies their cosmetic/tick-count props.
14
+ */
15
+ let {
16
+ data,
17
+ getX,
18
+ getY,
19
+ width,
20
+ height,
21
+ numericMargins,
22
+ scales,
23
+ }: {
24
+ data: TData[];
25
+ getX: (d: TData) => AxisValue;
26
+ getY: (d: TData) => AxisValue;
27
+ width: number;
28
+ height: number;
29
+ numericMargins: { top: number; right: number; bottom: number; left: number };
30
+ scales?: AxisBasedScalesConfig<TData>;
31
+ } = $props();
32
+
33
+ const cfg = $derived(getConfiguration());
34
+
35
+ const xValues = $derived(data.map(getX));
36
+ const yValues = $derived(data.map(getY));
37
+
38
+ /**
39
+ * Caps the requested tick count to the axis's own number of distinct
40
+ * values, but never above what the pixel width would naturally request —
41
+ * so a narrow domain (e.g. 5 whole years) never gets subdivided into
42
+ * fractional ticks (2020, 2020.5, 2021, …) just to fill the space. Skipped
43
+ * whenever the caller already controls tick density directly.
44
+ */
45
+ function autoTickCount(scale: AxisBasedScalesConfig<TData>['x'], values: AxisValue[], span: number, spacing: number, min: number): number | undefined {
46
+ if (scale?.ticks != null || scale?.tickSpacing != null || scale?.interval != null) return undefined;
47
+ const uniqueCount = new Set(values.map(String)).size;
48
+ const natural = Math.max(min, Math.round(span / spacing));
49
+ return uniqueCount >= 2 && uniqueCount < natural ? uniqueCount : undefined;
50
+ }
51
+
52
+ const xTickCount = $derived(
53
+ autoTickCount(scales?.x, xValues, Math.max(0, width - numericMargins.left - numericMargins.right), 80, 3),
54
+ );
55
+ const yTickCount = $derived(
56
+ autoTickCount(scales?.y, yValues, Math.max(0, height - numericMargins.top - numericMargins.bottom), 50, 2),
57
+ );
58
+
59
+ /** Vertical Y-axis title placement, when `scales.y.labelOrientation === 'vertical'`. */
60
+ const verticalYLabel = $derived.by(() => {
61
+ if (!scales?.y?.label || scales.y.labelOrientation !== 'vertical') return null;
62
+ const position = scales.y.labelPosition ?? 'middle';
63
+ const x = 14;
64
+ const top = numericMargins.top;
65
+ const bottom = height - numericMargins.bottom;
66
+ const y = position === 'top' ? top : (top + bottom) / 2;
67
+ return { text: scales.y.label, x, y, anchor: position === 'top' ? ('end' as const) : ('middle' as const) };
68
+ });
69
+ </script>
70
+
71
+ <AxisX
72
+ tickCount={xTickCount}
73
+ tickSize={scales?.x?.tickSize ?? cfg.axis.xTickSize}
74
+ tickPadding={scales?.x?.tickPadding ?? cfg.axis.xTickPadding}
75
+ tickFontSize={cfg.axis.fontSize}
76
+ titleFontSize={scales?.x?.titleFontSize ?? cfg.axis.titleFontSize}
77
+ />
78
+ <AxisY
79
+ tickCount={yTickCount}
80
+ tickSize={scales?.y?.tickSize ?? cfg.axis.yTickSize}
81
+ tickPadding={scales?.y?.tickPadding ?? cfg.axis.yTickPadding}
82
+ tickFontSize={cfg.axis.fontSize}
83
+ titleFontSize={scales?.y?.titleFontSize ?? cfg.axis.titleFontSize}
84
+ />
85
+ {#if verticalYLabel}
86
+ <text
87
+ x={verticalYLabel.x}
88
+ y={verticalYLabel.y}
89
+ transform="rotate(-90, {verticalYLabel.x}, {verticalYLabel.y})"
90
+ text-anchor={verticalYLabel.anchor}
91
+ font-size={scales?.y?.titleFontSize ?? cfg.axis.titleFontSize}
92
+ fill={cfg.axis.color}
93
+ opacity="0.8"
94
+ >{verticalYLabel.text}</text>
95
+ {/if}
@@ -0,0 +1,39 @@
1
+ import type { AxisValue } from '../../types/plots/axis';
2
+ import type { AxisBasedScalesConfig } from '../../types/plots/props';
3
+ declare function $$render<TData extends Record<string, unknown>>(): {
4
+ props: {
5
+ data: TData[];
6
+ getX: (d: TData) => AxisValue;
7
+ getY: (d: TData) => AxisValue;
8
+ width: number;
9
+ height: number;
10
+ numericMargins: {
11
+ top: number;
12
+ right: number;
13
+ bottom: number;
14
+ left: number;
15
+ };
16
+ scales?: AxisBasedScalesConfig<TData>;
17
+ };
18
+ exports: {};
19
+ bindings: "";
20
+ slots: {};
21
+ events: {};
22
+ };
23
+ declare class __sveltets_Render<TData extends Record<string, unknown>> {
24
+ props(): ReturnType<typeof $$render<TData>>['props'];
25
+ events(): ReturnType<typeof $$render<TData>>['events'];
26
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
27
+ bindings(): "";
28
+ exports(): {};
29
+ }
30
+ interface $$IsomorphicComponent {
31
+ new <TData extends Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
32
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
33
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
34
+ <TData extends Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
35
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
36
+ }
37
+ declare const AxisLayout: $$IsomorphicComponent;
38
+ type AxisLayout<TData extends Record<string, unknown>> = InstanceType<typeof AxisLayout<TData>>;
39
+ export default AxisLayout;