svelteplot 0.10.3 → 0.11.0-pr-514.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 (229) hide show
  1. package/dist/Mark.svelte +42 -25
  2. package/dist/Mark.svelte.d.ts +111 -32
  3. package/dist/Plot.svelte +21 -15
  4. package/dist/core/Facet.svelte +1 -1
  5. package/dist/core/FacetAxes.svelte +13 -8
  6. package/dist/core/FacetGrid.svelte +4 -4
  7. package/dist/core/Plot.svelte +70 -36
  8. package/dist/helpers/arrowPath.js +10 -5
  9. package/dist/helpers/autoScales.d.ts +3 -3
  10. package/dist/helpers/autoScales.js +28 -18
  11. package/dist/helpers/autoTicks.js +2 -0
  12. package/dist/helpers/callWithProps.d.ts +1 -2
  13. package/dist/helpers/colors.d.ts +4 -4
  14. package/dist/helpers/facets.d.ts +42 -1
  15. package/dist/helpers/facets.js +83 -1
  16. package/dist/helpers/index.js +1 -1
  17. package/dist/helpers/math.js +1 -1
  18. package/dist/helpers/mergeDeep.d.ts +1 -3
  19. package/dist/helpers/mergeDeep.js +15 -16
  20. package/dist/helpers/noise.js +1 -1
  21. package/dist/helpers/projection.d.ts +4 -3
  22. package/dist/helpers/projection.js +17 -5
  23. package/dist/helpers/reduce.d.ts +4 -4
  24. package/dist/helpers/reduce.js +6 -4
  25. package/dist/helpers/regressionLoess.js +2 -1
  26. package/dist/helpers/resolve.d.ts +6 -3
  27. package/dist/helpers/resolve.js +25 -16
  28. package/dist/helpers/roundedRect.js +1 -1
  29. package/dist/helpers/scales.d.ts +11 -10
  30. package/dist/helpers/scales.js +43 -13
  31. package/dist/helpers/time.d.ts +10 -3
  32. package/dist/helpers/time.js +2 -1
  33. package/dist/hooks/index.d.ts +2 -0
  34. package/dist/hooks/index.js +2 -0
  35. package/dist/hooks/plotDefaults.d.ts +3 -1
  36. package/dist/hooks/plotDefaults.js +33 -1
  37. package/dist/hooks/usePlot.svelte.d.ts +10 -25
  38. package/dist/hooks/usePlot.svelte.js +8 -7
  39. package/dist/index.d.ts +1 -2
  40. package/dist/index.js +1 -3
  41. package/dist/marks/Area.svelte +24 -13
  42. package/dist/marks/Area.svelte.d.ts +118 -34
  43. package/dist/marks/AreaX.svelte +42 -8
  44. package/dist/marks/AreaX.svelte.d.ts +154 -71
  45. package/dist/marks/AreaY.svelte +42 -8
  46. package/dist/marks/AreaY.svelte.d.ts +154 -71
  47. package/dist/marks/Arrow.svelte +42 -23
  48. package/dist/marks/Arrow.svelte.d.ts +114 -35
  49. package/dist/marks/AxisX.svelte +43 -28
  50. package/dist/marks/AxisX.svelte.d.ts +125 -40
  51. package/dist/marks/AxisY.svelte +43 -26
  52. package/dist/marks/AxisY.svelte.d.ts +127 -40
  53. package/dist/marks/BarX.svelte +12 -10
  54. package/dist/marks/BarX.svelte.d.ts +104 -32
  55. package/dist/marks/BarY.svelte +11 -10
  56. package/dist/marks/BarY.svelte.d.ts +106 -34
  57. package/dist/marks/BollingerX.svelte +4 -7
  58. package/dist/marks/BollingerX.svelte.d.ts +105 -30
  59. package/dist/marks/BollingerY.svelte +3 -0
  60. package/dist/marks/BollingerY.svelte.d.ts +105 -30
  61. package/dist/marks/BoxX.svelte +3 -3
  62. package/dist/marks/BoxY.svelte +12 -9
  63. package/dist/marks/BoxY.svelte.d.ts +128 -53
  64. package/dist/marks/Brush.svelte +26 -21
  65. package/dist/marks/Brush.svelte.d.ts +119 -60
  66. package/dist/marks/Cell.svelte +13 -9
  67. package/dist/marks/Cell.svelte.d.ts +105 -30
  68. package/dist/marks/CellX.svelte +2 -1
  69. package/dist/marks/CellX.svelte.d.ts +105 -32
  70. package/dist/marks/CellY.svelte +2 -1
  71. package/dist/marks/CellY.svelte.d.ts +105 -32
  72. package/dist/marks/ColorLegend.svelte +24 -13
  73. package/dist/marks/ColorLegend.svelte.d.ts +1 -0
  74. package/dist/marks/CustomMark.svelte +16 -10
  75. package/dist/marks/CustomMark.svelte.d.ts +112 -31
  76. package/dist/marks/CustomMarkHTML.svelte +8 -2
  77. package/dist/marks/CustomMarkHTML.svelte.d.ts +8 -2
  78. package/dist/marks/DifferenceY.svelte +31 -20
  79. package/dist/marks/DifferenceY.svelte.d.ts +134 -55
  80. package/dist/marks/Dot.svelte +21 -11
  81. package/dist/marks/Dot.svelte.d.ts +117 -38
  82. package/dist/marks/DotX.svelte +2 -0
  83. package/dist/marks/DotX.svelte.d.ts +136 -62
  84. package/dist/marks/DotY.svelte +1 -0
  85. package/dist/marks/DotY.svelte.d.ts +135 -62
  86. package/dist/marks/Frame.svelte +47 -9
  87. package/dist/marks/Frame.svelte.d.ts +124 -41
  88. package/dist/marks/Geo.svelte +21 -12
  89. package/dist/marks/Geo.svelte.d.ts +105 -30
  90. package/dist/marks/Graticule.svelte +3 -0
  91. package/dist/marks/Graticule.svelte.d.ts +3 -0
  92. package/dist/marks/GridX.svelte +31 -16
  93. package/dist/marks/GridX.svelte.d.ts +108 -32
  94. package/dist/marks/GridY.svelte +30 -15
  95. package/dist/marks/GridY.svelte.d.ts +108 -32
  96. package/dist/marks/HTMLTooltip.svelte +37 -27
  97. package/dist/marks/HTMLTooltip.svelte.d.ts +7 -0
  98. package/dist/marks/Image.svelte +50 -25
  99. package/dist/marks/Image.svelte.d.ts +117 -35
  100. package/dist/marks/Line.svelte +67 -44
  101. package/dist/marks/Line.svelte.d.ts +119 -30
  102. package/dist/marks/LineX.svelte +2 -1
  103. package/dist/marks/LineX.svelte.d.ts +142 -69
  104. package/dist/marks/LineY.svelte +2 -1
  105. package/dist/marks/LineY.svelte.d.ts +142 -69
  106. package/dist/marks/Link.svelte +70 -46
  107. package/dist/marks/Link.svelte.d.ts +126 -41
  108. package/dist/marks/Pointer.svelte +46 -35
  109. package/dist/marks/Pointer.svelte.d.ts +7 -0
  110. package/dist/marks/Rect.svelte +13 -5
  111. package/dist/marks/Rect.svelte.d.ts +116 -35
  112. package/dist/marks/RectX.svelte +6 -3
  113. package/dist/marks/RectX.svelte.d.ts +158 -12
  114. package/dist/marks/RectY.svelte +6 -3
  115. package/dist/marks/RectY.svelte.d.ts +158 -12
  116. package/dist/marks/RegressionX.svelte +13 -6
  117. package/dist/marks/RegressionX.svelte.d.ts +8 -3
  118. package/dist/marks/RegressionY.svelte +13 -6
  119. package/dist/marks/RegressionY.svelte.d.ts +8 -3
  120. package/dist/marks/RuleX.svelte +18 -11
  121. package/dist/marks/RuleX.svelte.d.ts +112 -32
  122. package/dist/marks/RuleY.svelte +19 -12
  123. package/dist/marks/RuleY.svelte.d.ts +114 -34
  124. package/dist/marks/Spike.svelte +11 -5
  125. package/dist/marks/Spike.svelte.d.ts +146 -68
  126. package/dist/marks/Text.svelte +24 -7
  127. package/dist/marks/Text.svelte.d.ts +253 -75
  128. package/dist/marks/TickX.svelte +56 -48
  129. package/dist/marks/TickX.svelte.d.ts +114 -40
  130. package/dist/marks/TickY.svelte +59 -51
  131. package/dist/marks/TickY.svelte.d.ts +117 -43
  132. package/dist/marks/Trail.svelte +25 -13
  133. package/dist/marks/Trail.svelte.d.ts +116 -33
  134. package/dist/marks/Vector.svelte +20 -11
  135. package/dist/marks/Vector.svelte.d.ts +116 -35
  136. package/dist/marks/WaffleX.svelte +18 -16
  137. package/dist/marks/WaffleX.svelte.d.ts +131 -57
  138. package/dist/marks/WaffleY.svelte +16 -15
  139. package/dist/marks/WaffleY.svelte.d.ts +129 -56
  140. package/dist/marks/helpers/Anchor.svelte +17 -2
  141. package/dist/marks/helpers/Anchor.svelte.d.ts +16 -1
  142. package/dist/marks/helpers/AreaCanvas.svelte +8 -8
  143. package/dist/marks/helpers/BaseAxisX.svelte +38 -41
  144. package/dist/marks/helpers/BaseAxisX.svelte.d.ts +11 -17
  145. package/dist/marks/helpers/BaseAxisY.svelte +35 -35
  146. package/dist/marks/helpers/BaseAxisY.svelte.d.ts +12 -15
  147. package/dist/marks/helpers/Box.svelte +35 -28
  148. package/dist/marks/helpers/Box.svelte.d.ts +122 -50
  149. package/dist/marks/helpers/DotCanvas.svelte +11 -9
  150. package/dist/marks/helpers/GeoCanvas.svelte +7 -6
  151. package/dist/marks/helpers/LineCanvas.svelte +7 -7
  152. package/dist/marks/helpers/LinearGradientX.svelte +2 -2
  153. package/dist/marks/helpers/LinearGradientX.svelte.d.ts +1 -1
  154. package/dist/marks/helpers/LinearGradientY.svelte +2 -2
  155. package/dist/marks/helpers/LinearGradientY.svelte.d.ts +1 -1
  156. package/dist/marks/helpers/Marker.svelte +2 -2
  157. package/dist/marks/helpers/MarkerPath.svelte +15 -12
  158. package/dist/marks/helpers/MarkerPath.svelte.d.ts +105 -32
  159. package/dist/marks/helpers/MultilineText.svelte +24 -17
  160. package/dist/marks/helpers/MultilineText.svelte.d.ts +1 -1
  161. package/dist/marks/helpers/RectCanvas.svelte +31 -26
  162. package/dist/marks/helpers/RectPath.svelte +2 -2
  163. package/dist/marks/helpers/Regression.svelte +176 -86
  164. package/dist/marks/helpers/Regression.svelte.d.ts +20 -8
  165. package/dist/marks/helpers/RuleCanvas.svelte +9 -6
  166. package/dist/marks/helpers/TextCanvas.svelte +13 -9
  167. package/dist/marks/helpers/TextCanvas.svelte.d.ts +6 -6
  168. package/dist/marks/helpers/TickCanvas.svelte +6 -5
  169. package/dist/marks/helpers/TrailCanvas.svelte +16 -18
  170. package/dist/marks/helpers/TrailCanvas.svelte.d.ts +3 -5
  171. package/dist/marks/helpers/canvas.js +16 -9
  172. package/dist/marks/helpers/events.d.ts +2 -2
  173. package/dist/marks/helpers/events.js +14 -7
  174. package/dist/marks/helpers/trail.js +1 -1
  175. package/dist/marks/helpers/waffle.d.ts +3 -3
  176. package/dist/marks/helpers/waffle.js +7 -5
  177. package/dist/regression/polynomial.d.ts +1 -1
  178. package/dist/regression/polynomial.js +7 -7
  179. package/dist/regression/utils/determination.d.ts +1 -1
  180. package/dist/regression/utils/determination.js +1 -1
  181. package/dist/regression/utils/geometry.d.ts +1 -1
  182. package/dist/regression/utils/interpose.d.ts +1 -1
  183. package/dist/regression/utils/interpose.js +1 -1
  184. package/dist/regression/utils/points.d.ts +1 -1
  185. package/dist/transforms/bin.d.ts +3 -3
  186. package/dist/transforms/bin.js +29 -20
  187. package/dist/transforms/bollinger.d.ts +8 -0
  188. package/dist/transforms/bollinger.js +15 -4
  189. package/dist/transforms/centroid.d.ts +4 -0
  190. package/dist/transforms/centroid.js +4 -0
  191. package/dist/transforms/density.d.ts +4 -4
  192. package/dist/transforms/density.js +23 -16
  193. package/dist/transforms/dodge.d.ts +12 -1
  194. package/dist/transforms/dodge.js +15 -6
  195. package/dist/transforms/group.d.ts +141 -4
  196. package/dist/transforms/group.js +4 -1
  197. package/dist/transforms/interval.d.ts +204 -60
  198. package/dist/transforms/jitter.d.ts +421 -4
  199. package/dist/transforms/jitter.js +10 -1
  200. package/dist/transforms/map.d.ts +412 -4
  201. package/dist/transforms/map.js +5 -5
  202. package/dist/transforms/normalize.d.ts +276 -5
  203. package/dist/transforms/normalize.js +6 -4
  204. package/dist/transforms/recordize.d.ts +17 -5
  205. package/dist/transforms/recordize.js +13 -9
  206. package/dist/transforms/rename.d.ts +11 -4
  207. package/dist/transforms/rename.js +7 -2
  208. package/dist/transforms/select.d.ts +722 -210
  209. package/dist/transforms/select.js +13 -1
  210. package/dist/transforms/shift.d.ts +8 -0
  211. package/dist/transforms/shift.js +20 -6
  212. package/dist/transforms/sort.d.ts +13 -258
  213. package/dist/transforms/sort.js +13 -10
  214. package/dist/transforms/stack.d.ts +58 -9
  215. package/dist/transforms/stack.js +27 -11
  216. package/dist/transforms/window.d.ts +221 -66
  217. package/dist/transforms/window.js +8 -2
  218. package/dist/types/axes.d.ts +43 -0
  219. package/dist/types/axes.js +1 -0
  220. package/dist/types/channel.d.ts +30 -2
  221. package/dist/types/data.d.ts +14 -1
  222. package/dist/types/facet.d.ts +5 -0
  223. package/dist/types/index.d.ts +33 -8
  224. package/dist/types/index.js +11 -7
  225. package/dist/types/mark.d.ts +125 -36
  226. package/dist/types/plot.d.ts +118 -16
  227. package/dist/types/scale.d.ts +125 -8
  228. package/package.json +37 -32
  229. package/dist/helpers/autoTicks.d.ts +0 -12
@@ -1,25 +1,24 @@
1
1
  function isObject(item) {
2
- return item && typeof item === 'object' && !Array.isArray(item);
2
+ return item != null && typeof item === 'object' && !Array.isArray(item);
3
3
  }
4
4
  export default function mergeDeep(target, ...sources) {
5
- if (!sources.length)
6
- return target;
7
- const source = sources.shift();
8
- if (isObject(target) && isObject(source)) {
9
- for (const key in source) {
10
- if (isObject(source[key])) {
11
- if (!target[key]) {
12
- Object.assign(target, { [key]: {} });
5
+ for (const source of sources) {
6
+ if (isObject(target) && isObject(source)) {
7
+ for (const key in source) {
8
+ if (isObject(source[key])) {
9
+ if (!target[key]) {
10
+ Object.assign(target, { [key]: {} });
11
+ }
12
+ else {
13
+ target[key] = Object.assign({}, target[key]);
14
+ }
15
+ mergeDeep(target[key], source[key]);
13
16
  }
14
- else {
15
- target[key] = Object.assign({}, target[key]);
17
+ else if (source[key] !== null) {
18
+ Object.assign(target, { [key]: source[key] });
16
19
  }
17
- mergeDeep(target[key], source[key]);
18
- }
19
- else if (source[key] !== null) {
20
- Object.assign(target, { [key]: source[key] });
21
20
  }
22
21
  }
23
22
  }
24
- return mergeDeep(target, ...sources);
23
+ return target;
25
24
  }
@@ -9,7 +9,7 @@ const scaled_cosine = (i) => 0.5 * (1.0 - Math.cos(i * Math.PI));
9
9
  let perlin; // will be initialized lazily by noise() or noiseSeed()
10
10
  export function noise(x, y = 0, z = 0) {
11
11
  if (perlin == null) {
12
- perlin = new Array(PERLIN_SIZE + 1);
12
+ perlin = Array.from({ length: PERLIN_SIZE + 1 });
13
13
  for (let i = 0; i < PERLIN_SIZE + 1; i++) {
14
14
  perlin[i] = Math.random();
15
15
  }
@@ -1,3 +1,4 @@
1
+ import { type GeoStream } from 'd3-geo';
1
2
  export type Clip = boolean | null | number | 'frame';
2
3
  type ProjectionOptions = {
3
4
  type: string;
@@ -25,9 +26,9 @@ export declare function createProjection({ projOptions, inset: globalInset, inse
25
26
  insetRight?: number;
26
27
  insetBottom?: number;
27
28
  insetLeft?: number;
28
- } | undefined, dimensions: Dimensions): string | ProjectionOptions | {
29
+ } | undefined, dimensions: Dimensions): ProjectionOptions | {
29
30
  aspectRatio: number;
30
- invert([x, y]: [any, any]): any;
31
- stream: (s: any) => any;
31
+ invert([x, y]: [number, number]): any;
32
+ stream: (s: GeoStream) => any;
32
33
  } | undefined;
33
34
  export {};
@@ -7,7 +7,7 @@ export function createProjection({ projOptions, inset: globalInset = 2, insetTop
7
7
  if (projOptions == null)
8
8
  return;
9
9
  // projection function passed as projection option
10
- if (typeof projOptions.stream === 'function')
10
+ if (typeof projOptions !== 'string' && typeof projOptions.stream === 'function')
11
11
  return projOptions; // d3 projection
12
12
  let options;
13
13
  let domain;
@@ -34,7 +34,16 @@ export function createProjection({ projOptions, inset: globalInset = 2, insetTop
34
34
  }
35
35
  // let projFactory;
36
36
  let aspectRatio = defaultAspectRatio;
37
- const projFactory = projOptions;
37
+ let projFactory;
38
+ if (typeof projOptions === 'function') {
39
+ // After destructuring, projOptions may be reassigned from an object `type` property,
40
+ // which can be a projection initializer function.
41
+ projFactory = projOptions;
42
+ }
43
+ else if (typeof projOptions === 'string') {
44
+ // String projection types are not handled here; treat as no projection.
45
+ return;
46
+ }
38
47
  // Compute the frame dimensions and invoke the projection initializer.
39
48
  const { width, height, marginLeft, marginRight, marginTop, marginBottom } = dimensions;
40
49
  const dx = width - marginLeft - marginRight - insetLeft - insetRight;
@@ -43,7 +52,7 @@ export function createProjection({ projOptions, inset: globalInset = 2, insetTop
43
52
  // The projection initializer might decide to not use a projection.
44
53
  if (projInstance == null)
45
54
  return;
46
- clip = maybePostClip(clip, marginLeft, marginTop, width - marginRight, height - marginBottom);
55
+ const postClip = maybePostClip(clip, marginLeft, marginTop, width - marginRight, height - marginBottom);
47
56
  // Translate the origin to the top-left corner, respecting margins and insets.
48
57
  let tx = marginLeft + insetLeft;
49
58
  let ty = marginTop + insetTop;
@@ -63,7 +72,10 @@ export function createProjection({ projOptions, inset: globalInset = 2, insetTop
63
72
  this.stream.point(x * k + tx, y * k + ty);
64
73
  }
65
74
  });
66
- invertTransform = ([x, y]) => [(x - tx) / k, (y - ty) / k];
75
+ invertTransform = ([x, y]) => [
76
+ (x - tx) / k,
77
+ (y - ty) / k
78
+ ];
67
79
  }
68
80
  else {
69
81
  // eslint-disable-next-line no-console
@@ -88,7 +100,7 @@ export function createProjection({ projOptions, inset: globalInset = 2, insetTop
88
100
  invert([x, y]) {
89
101
  return projInstance.invert(invertTransform([x, y]));
90
102
  },
91
- stream: (s) => projInstance.stream(transform.stream(clip(s)))
103
+ stream: (s) => projInstance.stream(transform.stream(postClip(s)))
92
104
  };
93
105
  }
94
106
  function maybePostClip(clip, x1, y1, x2, y2) {
@@ -1,10 +1,10 @@
1
- import type { ChannelName, Channels, DataRecord, DataRow, RawValue } from '../types/index.js';
2
- type ReducerFunc = (group: Iterable<DataRow>) => RawValue;
1
+ import type { ChannelName, Channels, DataRecord } from '../types/index.js';
2
+ type ReducerFunc = (group: Iterable<any>, ...rest: any[]) => any;
3
3
  type ReducerOption = ReducerName | ReducerFunc;
4
4
  type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
5
5
  export type ReducerPercentile = (`p${Digit}${Digit}` & Record<never, never>) | 'p25' | 'p50' | 'p75';
6
6
  export type ReducerName = 'count' | 'deviation' | 'difference' | 'first' | 'last' | 'max' | 'mean' | 'median' | 'min' | 'mode' | 'ratio' | 'sum' | 'variance' | ReducerPercentile;
7
- export declare const Reducer: Record<ReducerName, ReducerFunc>;
7
+ export declare const Reducer: Record<string, ReducerFunc>;
8
8
  export declare function mayberReducer(r: ReducerOption): ReducerFunc;
9
- export declare function reduceOutputs(newDatum: DataRecord, data: DataRecord[], options: Record<ChannelName, ReducerOption>, outputs: Iterable<ChannelName>, channels: Channels, newChannels: Channels): void;
9
+ export declare function reduceOutputs(newDatum: DataRecord, data: DataRecord[], options: Record<ChannelName, ReducerOption>, outputs: Iterable<ChannelName>, channels: Channels<any>, newChannels: Channels<any>): void;
10
10
  export {};
@@ -7,6 +7,8 @@ const niceReduceNames = {
7
7
  deviation: 'Standard Deviation',
8
8
  mean: 'Average'
9
9
  };
10
+ // Typed as Record<string, ...> because the Proxy wrapper adds virtual
11
+ // percentile keys (p00–p99) that don't exist on the static object
10
12
  const StaticReducer = {
11
13
  count: (d) => Array.from(d).length,
12
14
  min,
@@ -18,10 +20,10 @@ const StaticReducer = {
18
20
  identity: (d) => d,
19
21
  variance,
20
22
  deviation,
21
- first: (d) => d[0],
22
- last: (d) => d.at(-1),
23
- difference: (d) => d.at(-1) - d[0],
24
- ratio: (d) => d.at(-1) / d[0]
23
+ first: ((d) => d[0]),
24
+ last: ((d) => d.at(-1)),
25
+ difference: ((d) => d.at(-1) - d[0]),
26
+ ratio: ((d) => d.at(-1) / d[0])
25
27
  // TODO: proportion
26
28
  // TODO: proportion-facet
27
29
  // TODO: min-index
@@ -1,6 +1,7 @@
1
+ // @ts-expect-error loess has no type declarations
1
2
  import Loess from 'loess';
2
3
  function toNumber(d) {
3
- if (typeof d.getTime === 'function')
4
+ if (d instanceof Date)
4
5
  return d.getTime();
5
6
  return d;
6
7
  }
@@ -11,11 +11,14 @@ type ChannelOptions = {
11
11
  };
12
12
  export declare function toChannelOption(name: ScaledChannelName, channel: ChannelAccessor | ChannelAlias): ChannelOptions;
13
13
  export declare function resolveChannel<T>(channel: ChannelName, datum: DataRow<T>, channels: Partial<Record<ChannelName, ChannelAccessor<T> | ChannelAlias>>): RawValue;
14
- export declare function resolveScaledStyleProps(datum: DataRecord, channels: Partial<Record<ScaledChannelName, ChannelAccessor>>, useScale: Record<ScaledChannelName, boolean>, plot: PlotState, defaultColorProp?: 'fill' | 'stroke' | null): any;
15
- export declare function resolveScaledStyles(datum: DataRecord, channels: Partial<Record<ScaledChannelName, ChannelAccessor> & {
14
+ export declare function resolveScaledStyleProps(datum: DataRecord, channels: Partial<Record<ScaledChannelName | MarkStyleProps, ChannelAccessor>>, useScale: Record<ScaledChannelName, boolean>, plot: PlotState, defaultColorProp?: 'fill' | 'stroke' | null): {
15
+ fill: string;
16
+ stroke: string;
17
+ };
18
+ export declare function resolveScaledStyles(datum: DataRecord, channels: Partial<Record<ScaledChannelName | MarkStyleProps, ChannelAccessor> & {
16
19
  style: string;
17
20
  }>, useScale: Record<ScaledChannelName, boolean>, plot: PlotState, defaultColorProp?: 'fill' | 'stroke' | null): string;
18
- export declare function resolveStyles(plot: PlotState, datum: ScaledDataRecord, channels: Partial<Record<ChannelName & MarkStyleProps, ChannelAccessor> & {
21
+ export declare function resolveStyles(plot: PlotState, datum: ScaledDataRecord, channels: Partial<Record<ScaledChannelName | MarkStyleProps, ChannelAccessor> & {
19
22
  style: string;
20
23
  }>, defaultColorProp: "fill" | "stroke" | null | undefined, useScale: Record<ScaledChannelName, boolean>, recomputeChannels?: boolean): [string | null, string | null];
21
24
  export {};
@@ -8,19 +8,21 @@ export function resolveProp(accessor, datum, _defaultValue = null) {
8
8
  if (typeof accessor === 'function') {
9
9
  const accessorFn = accessor;
10
10
  // datum[RAW_VALUE] exists if an array of raw values was used as dataset and got
11
- // "recordized" by the recordi e transform. We want to hide this wrapping to the user
11
+ // "recordized" by the recordize transform. We want to hide this wrapping to the user
12
12
  // so we're passing the original value to accessor functions instead of our wrapped record
13
+ const d = datum;
13
14
  return datum == null
14
15
  ? accessorFn()
15
- : accessorFn(datum.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum, datum[INDEX]);
16
+ : accessorFn(d[RAW_VALUE] != null ? d[RAW_VALUE] : datum, d[INDEX]);
16
17
  }
17
18
  else {
18
19
  const accessorValue = accessor;
19
- // accessor may be a
20
- if ((typeof accessorValue === 'string' || typeof accessorValue === 'symbol') &&
21
- datum &&
22
- datum[accessorValue] !== undefined) {
23
- return datum[accessor];
20
+ // accessor may be a column name
21
+ if ((typeof accessorValue === 'string' || typeof accessorValue === 'symbol') && datum) {
22
+ const d = datum;
23
+ if (d[accessorValue] !== undefined) {
24
+ return d[accessorValue];
25
+ }
24
26
  }
25
27
  }
26
28
  return isRawValue(accessor) ? accessor : _defaultValue;
@@ -51,19 +53,20 @@ export function resolveChannel(channel, datum, channels) {
51
53
  }
52
54
  function resolve(datum, accessor, channel, scale) {
53
55
  if (isDataRecord(datum)) {
56
+ const d = datum;
54
57
  // use accessor function
55
58
  if (typeof accessor === 'function')
56
59
  // datum[RAW_VALUE] exists if an array of raw values was used as dataset and got
57
60
  // "recordized" by the recordize transform. We want to hide this wrapping to the user
58
61
  // so we're passing the original value to accessor functions instead of our wrapped record
59
- return accessor(datum[RAW_VALUE] != null ? datum[RAW_VALUE] : datum, datum?.[INDEX]);
62
+ return accessor(d[RAW_VALUE] != null ? d[RAW_VALUE] : datum, d[INDEX]);
60
63
  // use accessor string
61
64
  if ((typeof accessor === 'string' || typeof accessor === 'symbol') &&
62
- datum[accessor] !== undefined)
63
- return datum[accessor];
65
+ d[accessor] !== undefined)
66
+ return d[accessor];
64
67
  // fallback to channel name as accessor
65
- if (accessor === null && datum[channel] !== undefined)
66
- return datum[channel];
68
+ if (accessor === null && d[channel] !== undefined)
69
+ return d[channel];
67
70
  return isRawValue(accessor) ? accessor : null;
68
71
  }
69
72
  else if (Array.isArray(datum) &&
@@ -73,8 +76,9 @@ function resolve(datum, accessor, channel, scale) {
73
76
  }
74
77
  else {
75
78
  // return single value or accessor
79
+ const d = datum;
76
80
  return typeof accessor === 'function'
77
- ? accessor(datum, datum?.[INDEX])
81
+ ? accessor(datum, d?.[INDEX])
78
82
  : accessor !== null && isRawValue(accessor)
79
83
  ? accessor
80
84
  : !Array.isArray(datum) && (scale === 'x' || scale === 'y')
@@ -89,7 +93,6 @@ const scaledStyleProps = {
89
93
  strokeOpacity: 'stroke-opacity',
90
94
  opacity: 'opacity'
91
95
  };
92
- const scaledStylePropsKeys = Object.keys(scaledStyleProps);
93
96
  // TODO: find a better name
94
97
  const oppositeColor = {
95
98
  fill: 'stroke',
@@ -105,7 +108,11 @@ export function resolveScaledStyleProps(datum, channels, useScale, plot, default
105
108
  : {}),
106
109
  ...Object.fromEntries(Object.entries(scaledStyleProps)
107
110
  .filter(([key]) => channels[key] != null)
108
- .map(([key, cssAttr]) => [key, cssAttr, resolveChannel(key, datum, channels)])
111
+ .map(([key, cssAttr]) => [
112
+ key,
113
+ cssAttr,
114
+ resolveChannel(key, datum, channels)
115
+ ])
109
116
  .filter(([key, , value]) => isValid(value) || key === 'fill' || key === 'stroke')
110
117
  .map(([key, cssAttr, value]) => {
111
118
  if (useScale[key]) {
@@ -143,7 +150,9 @@ export function resolveStyles(plot, datum, channels, defaultColorProp = null, us
143
150
  .map(([key, cssAttr]) => [
144
151
  key,
145
152
  cssAttr,
146
- recomputeChannels ? resolveChannel(key, datum?.datum, channels) : datum?.[key]
153
+ (recomputeChannels
154
+ ? resolveChannel(key, datum?.datum, channels)
155
+ : datum?.[key])
147
156
  ])
148
157
  .filter(([key, , value]) => isValid(value) || key === 'fill' || key === 'stroke')
149
158
  .map(([key, cssAttr, value]) => {
@@ -9,7 +9,7 @@ export function roundedRect(x, y, width, height, borderRadius = {
9
9
  }) {
10
10
  const maxRadius = Math.min(width, height) / 2;
11
11
  const [tl, tr, bl, br] = (typeof borderRadius === 'number'
12
- ? new Array(4).fill(borderRadius)
12
+ ? Array.from({ length: 4 }, () => borderRadius)
13
13
  : [
14
14
  borderRadius?.topLeft || 0,
15
15
  borderRadius?.topRight || 0,
@@ -1,23 +1,24 @@
1
- import type { ChannelAccessor, GenericMarkOptions, Mark, MarkType, PlotDefaults, PlotOptions, PlotScales, PlotState, RawValue, ScaleName, ScaleOptions, ScaleType, ScaledChannelName, UsedScales } from '../types/index.js';
1
+ import type { ChannelAccessor, GenericMarkOptions, Mark, MarkType, PlotDefaults, PlotScaleFunction, ResolvedPlotOptions, PlotScales, PlotState, RawValue, ScaleName, ScaleOptions, ScaleType, ScaledChannelName, UsedScales } from '../types/index.js';
2
+ export declare function normalizeScaleFn(fn: any): PlotScaleFunction;
2
3
  /**
3
4
  * compute the plot scales
4
5
  */
5
- export declare function computeScales(plotOptions: PlotOptions, plotWidth: number, plotHeight: number, plotHasFilledDotMarks: boolean, marks: Mark<GenericMarkOptions>[], plotDefaults: PlotDefaults): PlotScales;
6
- export declare function createScale<T extends ScaleOptions>(name: ScaleName, scaleOptions: T, marks: Mark<GenericMarkOptions>[], plotOptions: PlotOptions, plotWidth: number, plotHeight: number, plotHasFilledDotMarks: boolean, plotDefaults: PlotDefaults): {
7
- type: string;
6
+ export declare function computeScales(plotOptions: ResolvedPlotOptions, plotWidth: number, plotHeight: number, plotHasFilledDotMarks: boolean, marks: Mark<GenericMarkOptions>[], plotDefaults: PlotDefaults): PlotScales;
7
+ export declare function createScale(name: ScaleName, scaleOptions: Partial<ScaleOptions>, marks: Mark<GenericMarkOptions>[], plotOptions: ResolvedPlotOptions, plotWidth: number, plotHeight: number, plotHasFilledDotMarks: boolean, plotDefaults: PlotDefaults): {
8
+ type: ScaleType;
8
9
  domain: number[];
9
10
  range: number[];
10
- fn: (() => string) | (() => number);
11
+ fn: PlotScaleFunction;
11
12
  skip: Map<any, any>;
12
13
  isDummy: boolean;
13
- manualActiveMarks?: undefined;
14
- uniqueScaleProps?: undefined;
14
+ manualActiveMarks: number;
15
+ uniqueScaleProps: Set<unknown>;
15
16
  autoTitle?: undefined;
16
17
  } | {
17
18
  type: ScaleType;
18
- domain: RawValue[] | [undefined, undefined];
19
- range: any;
20
- fn: any;
19
+ domain: RawValue[];
20
+ range: RawValue[];
21
+ fn: PlotScaleFunction;
21
22
  skip: Map<ScaledChannelName, Set<symbol>>;
22
23
  manualActiveMarks: number;
23
24
  uniqueScaleProps: Set<ChannelAccessor>;
@@ -7,6 +7,17 @@ import isDataRecord from './isDataRecord.js';
7
7
  import { createProjection } from './projection.js';
8
8
  import { maybeInterval } from './autoTicks.js';
9
9
  import { IS_SORTED } from '../transforms/sort.js';
10
+ export function normalizeScaleFn(fn) {
11
+ const out = fn;
12
+ out.range ||= () => [];
13
+ out.invert ||= (value) => value;
14
+ out.bandwidth ||= () => 0;
15
+ out.ticks ||= () => [];
16
+ out.quantiles ||= () => [];
17
+ out.thresholds ||= () => [];
18
+ out.domain ||= () => [];
19
+ return out;
20
+ }
10
21
  /**
11
22
  * compute the plot scales
12
23
  */
@@ -38,7 +49,17 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
38
49
  // no scale defined, return a dummy scale
39
50
  const fn = name === 'color' ? () => 'currentColor' : () => 0;
40
51
  fn.range = name === 'color' ? () => ['currentColor'] : () => [0];
41
- return { type: 'linear', domain: [0], range: [0], fn, skip: new Map(), isDummy: true };
52
+ const normalizedFn = normalizeScaleFn(fn);
53
+ return {
54
+ type: 'linear',
55
+ domain: [0],
56
+ range: [0],
57
+ fn: normalizedFn,
58
+ skip: new Map(),
59
+ isDummy: true,
60
+ manualActiveMarks: 0,
61
+ uniqueScaleProps: new Set()
62
+ };
42
63
  }
43
64
  // gather all marks that use channels which support this scale
44
65
  const dataValues = new Set();
@@ -145,7 +166,7 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
145
166
  }
146
167
  // construct domain from data values
147
168
  const valueArr = [...dataValues.values(), ...(scaleOptions.domain || [])].filter((d) => d != null);
148
- const type = scaleOptions.type === 'auto'
169
+ const type = !scaleOptions.type || scaleOptions.type === 'auto'
149
170
  ? inferScaleType(name, valueArr, markTypes, scaleOptions)
150
171
  : scaleOptions.type;
151
172
  if (VALID_SCALE_TYPES[name] && !VALID_SCALE_TYPES[name].has(type)) {
@@ -181,10 +202,12 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
181
202
  }
182
203
  }
183
204
  }
184
- if (!scaleOptions.scale) {
205
+ // `scale` is a factory function injected by Plot.svelte (autoScale/autoScaleColor)
206
+ const scaleFn = scaleOptions.scale;
207
+ if (!scaleFn) {
185
208
  throw new Error(`No scale function defined for ${name}`);
186
209
  }
187
- const fn = scaleOptions.scale({
210
+ const rawFn = scaleFn({
188
211
  name,
189
212
  type,
190
213
  domain,
@@ -195,6 +218,7 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
195
218
  plotHasFilledDotMarks,
196
219
  plotDefaults
197
220
  });
221
+ const fn = normalizeScaleFn(rawFn);
198
222
  const range = fn.range();
199
223
  return {
200
224
  type,
@@ -241,14 +265,16 @@ export function inferScaleType(name, dataValues, markTypes, scaleOptions = {}) {
241
265
  return 'ordinal';
242
266
  if (name === 'x' || name === 'y') {
243
267
  // if for a positional scale we may infer the scale type from the scale options
244
- if (scaleOptions.nice || scaleOptions.zero)
245
- return 'linear';
246
268
  if (scaleOptions.domain && scaleOptions.domain.length === 2) {
247
269
  if (scaleOptions.domain.every(Number.isFinite))
248
270
  return 'linear';
249
271
  if (scaleOptions.domain.every(isDate))
250
272
  return 'time';
251
273
  }
274
+ if (scaleOptions.zero)
275
+ return 'linear';
276
+ if (scaleOptions.nice)
277
+ return dataValues.length > 0 && dataValues.every(isDateOrNull) ? 'time' : 'linear';
252
278
  }
253
279
  // for positional scales, try to pick a scale that's required by the mark types
254
280
  if (name === 'y' && Array.from(markTypes).some((d) => markTypesWithBandDefault.y.has(d)))
@@ -316,7 +342,7 @@ export function projectXY(scales, x, y, useXScale = true, useYScale = true) {
316
342
  // TODO: pretty sure this is not how projection streams are supposed to be used
317
343
  // efficiently, in observable plot, all data points of a mark are projected using
318
344
  // the same stream
319
- let x_, y_;
345
+ let x_ = 0, y_ = 0;
320
346
  const stream = scales.projection.stream({
321
347
  point(px, py) {
322
348
  x_ = px;
@@ -332,19 +358,23 @@ export function projectXY(scales, x, y, useXScale = true, useYScale = true) {
332
358
  ];
333
359
  }
334
360
  export function projectX(channel, scales, value) {
335
- return (scales.x.fn(value) +
361
+ const x = scales.x.fn(value) ?? NaN;
362
+ const xBandwidth = scales.x.type === 'band' ? scales.x.fn.bandwidth() : 0;
363
+ return (x +
336
364
  (channel === 'x' && scales.x.type === 'band'
337
- ? scales.x.fn.bandwidth() * 0.5
365
+ ? xBandwidth * 0.5
338
366
  : channel === 'x2' && scales.x.type === 'band'
339
- ? scales.x.fn.bandwidth()
367
+ ? xBandwidth
340
368
  : 0));
341
369
  }
342
370
  export function projectY(channel, scales, value) {
343
- return (scales.y.fn(value) +
371
+ const y = scales.y.fn(value) ?? NaN;
372
+ const yBandwidth = scales.y.type === 'band' ? scales.y.fn.bandwidth() : 0;
373
+ return (y +
344
374
  (channel === 'y' && scales.y.type === 'band'
345
- ? scales.y.fn.bandwidth() * 0.5
375
+ ? yBandwidth * 0.5
346
376
  : channel === 'y2' && scales.y.type === 'band'
347
- ? scales.y.fn.bandwidth()
377
+ ? yBandwidth
348
378
  : 0));
349
379
  }
350
380
  export function isOrdinalScale(scaleType) {
@@ -1,7 +1,14 @@
1
+ type CountableTimeInterval = {
2
+ floor: (date: Date) => Date;
3
+ offset: (date: Date, step?: number) => Date;
4
+ range: (start: Date, stop: Date, step?: number) => Date[];
5
+ every: (step: number) => CountableTimeInterval | null | undefined;
6
+ };
1
7
  export declare const durations: Map<string, number>;
2
8
  export declare const intervalDuration: unique symbol;
3
9
  export declare const intervalType: unique symbol;
4
10
  export declare function parseTimeInterval(input: string): [string, number];
5
- export declare function maybeTimeInterval(input: string): any;
6
- export declare function maybeUtcInterval(input: string): any;
7
- export declare function generalizeTimeInterval(interval: any, n: any): any;
11
+ export declare function maybeTimeInterval(input: string): CountableTimeInterval | undefined;
12
+ export declare function maybeUtcInterval(input: string): CountableTimeInterval | undefined;
13
+ export declare function generalizeTimeInterval(interval: CountableTimeInterval, n: number): CountableTimeInterval | undefined;
14
+ export {};
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import { bisector } from 'd3-array';
10
10
  import { utcSecond, utcMinute, utcHour, unixDay, utcWeek, utcMonth, utcYear, utcMonday, utcTuesday, utcWednesday, utcThursday, utcFriday, utcSaturday, utcSunday, timeSecond, timeMinute, timeHour, timeDay, timeWeek, timeMonth, timeYear, timeMonday, timeTuesday, timeWednesday, timeThursday, timeFriday, timeSaturday, timeSunday } from 'd3-time';
11
- // import {orderof} from "./options.js";
12
11
  const durationSecond = 1000;
13
12
  const durationMinute = durationSecond * 60;
14
13
  const durationHour = durationMinute * 60;
@@ -187,6 +186,8 @@ export function maybeUtcInterval(input) {
187
186
  }
188
187
  function asInterval([name, period], type) {
189
188
  let interval = (type === 'time' ? timeIntervals : utcIntervals).get(name);
189
+ if (!interval)
190
+ throw new Error('invalid interval: ' + name);
190
191
  if (period > 1) {
191
192
  interval = interval.every(period);
192
193
  interval[intervalDuration] = durations.get(name) * period;
@@ -0,0 +1,2 @@
1
+ export * from './plotDefaults.js';
2
+ export { usePlot } from './usePlot.svelte.js';
@@ -0,0 +1,2 @@
1
+ export * from './plotDefaults.js';
2
+ export { usePlot } from './usePlot.svelte.js';
@@ -1,3 +1,5 @@
1
- import type { PlotDefaults } from '../types';
1
+ import type { PlotDefaults } from '../types/index.js';
2
+ /** sets default options for all Plot components in this component tree, merging with any existing defaults from parent contexts */
2
3
  export declare function setPlotDefaults(plotDefaults: Partial<PlotDefaults>): void;
4
+ /** retrieves the current plot defaults from the Svelte context, or an empty object if none have been set */
3
5
  export declare function getPlotDefaults(): Partial<PlotDefaults>;
@@ -1,10 +1,13 @@
1
1
  import { getContext, hasContext, setContext } from 'svelte';
2
2
  const PLOT_DEFAULTS_KEY = Symbol('svelteplot/defaults');
3
+ /** sets default options for all Plot components in this component tree, merging with any existing defaults from parent contexts */
3
4
  export function setPlotDefaults(plotDefaults) {
4
5
  const existingDefaults = getPlotDefaults();
5
- const mergedDefaults = { ...existingDefaults, ...plotDefaults };
6
+ const normalizedDefaults = normalizePlotDefaults(plotDefaults, existingDefaults);
7
+ const mergedDefaults = { ...existingDefaults, ...normalizedDefaults };
6
8
  setContext(PLOT_DEFAULTS_KEY, mergedDefaults);
7
9
  }
10
+ /** retrieves the current plot defaults from the Svelte context, or an empty object if none have been set */
8
11
  export function getPlotDefaults() {
9
12
  return hasContext(PLOT_DEFAULTS_KEY)
10
13
  ? getContext(PLOT_DEFAULTS_KEY)
@@ -14,3 +17,32 @@ export function getPlotDefaults() {
14
17
  getContext('svelteplot/defaults'))
15
18
  : {};
16
19
  }
20
+ function normalizePlotDefaults(plotDefaults, existingDefaults) {
21
+ const grid = normalizeGridDefaults(plotDefaults.grid, existingDefaults.grid);
22
+ const gridX = normalizeGridDefaults(plotDefaults.gridX, existingDefaults.gridX);
23
+ const gridY = normalizeGridDefaults(plotDefaults.gridY, existingDefaults.gridY);
24
+ const frame = normalizeFrameDefaults(plotDefaults.frame, existingDefaults.frame);
25
+ return {
26
+ ...plotDefaults,
27
+ ...(grid !== undefined ? { grid } : {}),
28
+ ...(gridX !== undefined ? { gridX } : {}),
29
+ ...(gridY !== undefined ? { gridY } : {}),
30
+ ...(frame !== undefined ? { frame } : {})
31
+ };
32
+ }
33
+ function normalizeGridDefaults(input, existing) {
34
+ if (input !== true)
35
+ return input;
36
+ return {
37
+ ...(typeof existing === 'object' ? existing : {}),
38
+ implicit: true
39
+ };
40
+ }
41
+ function normalizeFrameDefaults(input, existing) {
42
+ if (input !== true)
43
+ return input;
44
+ return {
45
+ ...(typeof existing === 'object' ? existing : {}),
46
+ implicit: true
47
+ };
48
+ }
@@ -1,12 +1,12 @@
1
- import type { PlotOptions } from '../types/plot';
2
- import type { PlotScales, PlotState as TPlotState } from '../types';
1
+ import type { ResolvedPlotOptions } from '../types/plot.js';
2
+ import type { PlotScales, PlotState as TPlotState } from '../types/index.js';
3
3
  /**
4
- * Internal state representation of a Plot.
4
+ * internal state representation of a Plot, using Svelte 5 runes for reactivity
5
5
  */
6
6
  declare class PlotState implements TPlotState {
7
7
  width: number;
8
8
  height: number;
9
- options: PlotOptions;
9
+ options: ResolvedPlotOptions;
10
10
  facetWidth: number;
11
11
  facetHeight: number;
12
12
  plotWidth: number;
@@ -24,28 +24,13 @@ declare class PlotState implements TPlotState {
24
24
  hasFilledDotMarks: boolean;
25
25
  css: ((d: string) => string) | null;
26
26
  constructor(state: PlotState);
27
+ /** merges partial state into the current plot state */
27
28
  update(newState: Partial<PlotState>): void;
28
- get publicState(): PublicPlotState;
29
+ /** returns a read-only wrapper exposing only public properties */
30
+ get publicState(): Readonly<TPlotState>;
29
31
  }
30
- /**
31
- * A public-facing wrapper around PlotState that exposes only read-only properties.
32
- */
33
- declare class PublicPlotState {
34
- #private;
35
- constructor(plotState: PlotState);
36
- get width(): number;
37
- get height(): number;
38
- get options(): PlotOptions;
39
- get scales(): PlotScales;
40
- get plotWidth(): number;
41
- get plotHeight(): number;
42
- get facetWidth(): number;
43
- get facetHeight(): number;
44
- get body(): HTMLDivElement;
45
- get colorSymbolRedundant(): boolean;
46
- get hasFilledDotMarks(): boolean;
47
- get css(): ((d: string) => string) | null;
48
- }
49
- export declare function setPlot(initialState: PlotState): PlotState;
32
+ /** creates a new PlotState instance from the given initial state */
33
+ export declare function setPlot(initialState: TPlotState): PlotState;
34
+ /** returns the current Plot's public state from Svelte context. Must be called within a `<Plot>` component tree. */
50
35
  export declare function usePlot(): Readonly<TPlotState>;
51
36
  export {};