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,4 +1,4 @@
1
- import { CSS_URL, CSS_VAR } from '../../constants';
1
+ import { CSS_URL, CSS_VAR } from '../../constants.js';
2
2
  export function resolveColor(color, canvas) {
3
3
  if (`${color}`.toLowerCase() === 'currentcolor') {
4
4
  color = getComputedStyle(canvas?.parentElement?.parentElement).getPropertyValue('color');
@@ -9,20 +9,27 @@ export function resolveColor(color, canvas) {
9
9
  if (CSS_URL.test(color)) {
10
10
  // might be a gradient we can parse!
11
11
  const m = color.match(/^url\((#[^)]+)\)/);
12
+ if (!m)
13
+ return color;
12
14
  const gradientId = m[1];
13
15
  const gradient = canvas.ownerDocument.querySelector(gradientId);
14
16
  if (gradient) {
15
17
  // parse gradient
16
18
  if (gradient.nodeName.toLowerCase() === 'lineargradient') {
17
- const x0 = +gradient.getAttribute('x1');
18
- const x1 = +gradient.getAttribute('x2');
19
- const y0 = +gradient.getAttribute('y1');
20
- const y1 = +gradient.getAttribute('y2');
21
- const ctxGradient = canvas.getContext('2d').createLinearGradient(x0, y0, x1, y1);
19
+ const x0 = +(gradient.getAttribute('x1') ?? 0);
20
+ const x1 = +(gradient.getAttribute('x2') ?? 0);
21
+ const y0 = +(gradient.getAttribute('y1') ?? 0);
22
+ const y1 = +(gradient.getAttribute('y2') ?? 0);
23
+ const ctx = canvas.getContext('2d');
24
+ // If we cannot obtain a 2D context, fall back to a safe color instead of returning
25
+ // the original gradient URL (e.g., "url(#gradient1)"), which is not a valid canvas color.
26
+ if (!ctx)
27
+ return 'transparent';
28
+ const ctxGradient = ctx.createLinearGradient(x0, y0, x1, y1);
22
29
  for (const stop of gradient.querySelectorAll('stop')) {
23
- const offset = +stop.getAttribute('offset');
24
- const color = resolveColor(stop.getAttribute('stop-color'), canvas);
25
- ctxGradient.addColorStop(Math.min(1, Math.max(0, offset)), color);
30
+ const offset = +(stop.getAttribute('offset') ?? 0);
31
+ const stopColor = resolveColor(stop.getAttribute('stop-color') ?? '', canvas);
32
+ ctxGradient.addColorStop(Math.min(1, Math.max(0, offset)), stopColor);
26
33
  }
27
34
  return ctxGradient;
28
35
  }
@@ -2,8 +2,8 @@ import type { BaseMarkProps, DataRecord, DataRow, PlotState } from '../../types/
2
2
  import type { Attachment } from 'svelte/attachments';
3
3
  declare global {
4
4
  interface MouseEvent {
5
- layerX?: number;
6
- layerY?: number;
5
+ readonly layerX: number;
6
+ readonly layerY: number;
7
7
  dataX?: number | string | Date;
8
8
  dataY?: number | string | Date;
9
9
  }
@@ -72,7 +72,10 @@ export function addEventHandlers({ options, datum, plot }) {
72
72
  const relativeX = origEvent.clientX - facetRect.left + (plotOptions.marginLeft ?? 0);
73
73
  const relativeY = origEvent.clientY - facetRect.top + (plotOptions.marginTop ?? 0);
74
74
  if (scales.projection) {
75
- const [x, y] = scales.projection.invert([relativeX, relativeY]);
75
+ const [x, y] = scales.projection.invert([
76
+ relativeX,
77
+ relativeY
78
+ ]);
76
79
  origEvent.dataX = x;
77
80
  origEvent.dataY = y;
78
81
  }
@@ -100,13 +103,17 @@ export function addEventHandlers({ options, datum, plot }) {
100
103
  }
101
104
  function invertScale(scale, position) {
102
105
  if (scale.type === 'band') {
103
- const range = scale.fn.range();
104
- const domain = scale.fn.domain();
105
- const eachBand = scale.fn.step();
106
- const extent = range[1] - range[0];
107
- const posInRange = (position - range[0]) * Math.sign(extent);
106
+ const bandScale = scale.fn;
107
+ const range = bandScale.range();
108
+ const domain = bandScale.domain();
109
+ const eachBand = bandScale.step();
110
+ const start = range[0] ?? 0;
111
+ const end = range[1] ?? start;
112
+ const extent = end - start;
113
+ const posInRange = (position - start) * Math.sign(extent);
108
114
  const index = Math.floor(posInRange / eachBand);
109
115
  return domain[index];
110
116
  }
111
- return scale.fn.invert ? scale.fn.invert(position) : undefined;
117
+ const maybeInvert = scale.fn;
118
+ return maybeInvert.invert ? maybeInvert.invert(position) : undefined;
112
119
  }
@@ -29,7 +29,7 @@ export function trailPath(samples, defined, context, options = {}) {
29
29
  }
30
30
  const resampled = resampleCurve(segment, curveFactory, Math.max(1, samplesPerSegment));
31
31
  smoothedSamples.push(...resampled);
32
- smoothedDefined.push(...new Array(resampled.length).fill(true));
32
+ smoothedDefined.push(...Array.from({ length: resampled.length }, () => true));
33
33
  // preserve a gap between defined segments
34
34
  if (i < len) {
35
35
  smoothedSamples.push(samples[i]);
@@ -5,8 +5,8 @@
5
5
  * Kept the comments from the original implementation for clarity.
6
6
  */
7
7
  import type { Snippet } from 'svelte';
8
- import type { StackOptions } from '../../transforms/stack';
9
- import type { BorderRadius, ConstantAccessor, PlotScales, ScaledDataRecord } from '../../types';
8
+ import type { StackOptions } from '../../transforms/stack.js';
9
+ import type { BorderRadius, ConstantAccessor, PlotScales, ScaledDataRecord } from '../../types/index.js';
10
10
  type Point = [number, number];
11
11
  export type WaffleOptions<T> = {
12
12
  /**
@@ -58,7 +58,7 @@ type WaffleProps = {
58
58
  d: string;
59
59
  };
60
60
  };
61
- export declare function wafflePolygon(y: 'x' | 'y', options: WaffleOptions, scales: PlotScales): (d: ScaledDataRecord) => WaffleProps;
61
+ export declare function wafflePolygon(y: 'x' | 'y', options: WaffleOptions<any>, scales: PlotScales): (d: ScaledDataRecord) => WaffleProps;
62
62
  export declare function wafflePoints(i1: number, i2: number, columns: number): Point[];
63
63
  export declare function maybeRound(round: boolean | ((x: number) => number) | undefined): (x: number) => number;
64
64
  export {};
@@ -4,18 +4,20 @@
4
4
  *
5
5
  * Kept the comments from the original implementation for clarity.
6
6
  */
7
- import { getPatternId } from '../../helpers/getBaseStyles';
7
+ import { getPatternId } from '../../helpers/getBaseStyles.js';
8
8
  export function wafflePolygon(y, options, scales) {
9
9
  const x = y === 'y' ? 'x' : 'y';
10
10
  const y1 = `${y}1`;
11
11
  const y2 = `${y}2`;
12
12
  const xScale = scales[x];
13
13
  const yScale = scales[y];
14
- const barwidth = xScale.fn.bandwidth();
14
+ const xBandScale = xScale.fn;
15
+ const mapY = (value) => yScale.fn(value) ?? 0;
16
+ const barwidth = xBandScale.bandwidth();
15
17
  const { unit = 1, gap = 1 } = options;
16
18
  const round = maybeRound(options.round);
17
19
  // The length of a unit along y in pixels.
18
- const scale = Math.abs(yScale.fn(unit) - yScale.fn(0));
20
+ const scale = Math.abs(mapY(unit) - mapY(0));
19
21
  // The number of cells on each row (or column) of the waffle.
20
22
  const multiple = options.multiple ?? Math.max(1, Math.floor(Math.sqrt(barwidth / scale)));
21
23
  // The outer size of each square cell, in pixels, including the gap.
@@ -26,7 +28,7 @@ export function wafflePolygon(y, options, scales) {
26
28
  const transform = y === 'y' ? ([x, y]) => [x * cx, -y * cy] : ([x, y]) => [y * cy, x * cx];
27
29
  // const mx = typeof x0 === 'function' ? (i) => x0(i) - barwidth / 2 : () => x0;
28
30
  const [ix, iy] = y === 'y' ? [0, 1] : [1, 0];
29
- const y0 = yScale.fn(0);
31
+ const y0 = mapY(0);
30
32
  const mx = -barwidth / 2;
31
33
  return (d) => {
32
34
  const y1val = d.resolved[y1];
@@ -157,6 +159,6 @@ export function maybeRound(round) {
157
159
  if (round === true)
158
160
  return Math.round;
159
161
  if (typeof round !== 'function')
160
- throw new Error(`invalid round: ${round}`);
162
+ throw new Error(`invalid round: ${String(round)}`);
161
163
  return round;
162
164
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Adapted from https://github.com/HarryStevens/d3-regression
3
3
  */
4
- import type { PredictFunction, Accessor, DataPoint, Domain } from './types';
4
+ import type { PredictFunction, Accessor, DataPoint, Domain } from './types.js';
5
5
  export type PolynomialOutput = [DataPoint, DataPoint] & {
6
6
  coefficients: number[];
7
7
  predict: PredictFunction;
@@ -7,11 +7,11 @@
7
7
  // ...with ideas from vega-statistics by Jeffrey Heer
8
8
  // Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js
9
9
  // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE
10
- import { determination } from './utils/determination';
11
- import { interpose } from './utils/interpose';
12
- import { points, visitPoints } from './utils/points';
13
- import linear from './linear';
14
- import quad from './quadratic';
10
+ import { determination } from './utils/determination.js';
11
+ import { interpose } from './utils/interpose.js';
12
+ import { points, visitPoints } from './utils/points.js';
13
+ import linear from './linear.js';
14
+ import quad from './quadratic.js';
15
15
  export default function polynomial() {
16
16
  let x = (d) => d[0], y = (d) => d[1], order = 3, domain;
17
17
  const polynomialRegression = function polynomialRegression(data) {
@@ -110,7 +110,7 @@ export default function polynomial() {
110
110
  return polynomialRegression;
111
111
  }
112
112
  function uncenter(k, a, x, y) {
113
- const z = new Array(k).fill(0);
113
+ const z = Array.from({ length: k }, () => 0);
114
114
  for (let i = k - 1; i >= 0; --i) {
115
115
  let v = a[i];
116
116
  z[i] += v;
@@ -127,7 +127,7 @@ function uncenter(k, a, x, y) {
127
127
  // Solve A * x = b using Gaussian elimination
128
128
  function gaussianElimination(matrix) {
129
129
  const n = matrix.length - 1;
130
- const coef = new Array(n);
130
+ const coef = Array.from({ length: n });
131
131
  for (let i = 0; i < n; i++) {
132
132
  let r = i;
133
133
  // find pivot row
@@ -1,4 +1,4 @@
1
- import type { Accessor, PredictFunction } from '../types';
1
+ import type { Accessor, PredictFunction } from '../types.js';
2
2
  /**
3
3
  * Given a dataset, x- and y-accessors, the mean center of the y-values (uY),
4
4
  * and a prediction function, return the coefficient of determination, R^2.
@@ -1,4 +1,4 @@
1
- import { visitPoints } from './points';
1
+ import { visitPoints } from './points.js';
2
2
  /**
3
3
  * Given a dataset, x- and y-accessors, the mean center of the y-values (uY),
4
4
  * and a prediction function, return the coefficient of determination, R^2.
@@ -1,4 +1,4 @@
1
- import type { DataPoint } from '../types';
1
+ import type { DataPoint } from '../types.js';
2
2
  /**
3
3
  * Returns the angle of a line in degrees.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { PredictFunction, DataPoint } from '../types';
1
+ import type { PredictFunction, DataPoint } from '../types.js';
2
2
  /**
3
3
  * Given a start point (xmin), an end point (xmax),
4
4
  * and a prediction function, returns a smooth line.
@@ -1,4 +1,4 @@
1
- import { angle, midpoint } from './geometry';
1
+ import { angle, midpoint } from './geometry.js';
2
2
  /**
3
3
  * Given a start point (xmin), an end point (xmax),
4
4
  * and a prediction function, returns a smooth line.
@@ -1,4 +1,4 @@
1
- import type { Accessor } from '../types';
1
+ import type { Accessor } from '../types.js';
2
2
  /**
3
3
  * Adapted from vega-statistics by Jeffrey Heer
4
4
  * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE
@@ -36,16 +36,16 @@ type BinOptions = BinBaseOptions & AdditionalOutputChannels;
36
36
  * @param param0
37
37
  * @param options
38
38
  */
39
- export declare function binX<T>({ data, ...channels }: TransformArg<T, DataRecord>, options?: BinXOptions): TransformArg<T, DataRecord>;
39
+ export declare function binX({ data, ...channels }: TransformArg<DataRecord>, options?: BinXOptions): TransformArg<DataRecord>;
40
40
  /**
41
41
  * Bins on y. Also groups on y and the first channel of z, fill, or stroke, if any.
42
42
  *
43
43
  * @param param0
44
44
  * @param options
45
45
  */
46
- export declare function binY<T>({ data, ...channels }: TransformArg<T, DataRecord>, options?: BinYOptions): TransformArg<T, DataRecord>;
46
+ export declare function binY({ data, ...channels }: TransformArg<DataRecord>, options?: BinYOptions): TransformArg<DataRecord>;
47
47
  /**
48
48
  * for binning in x and y dimension simultaneously
49
49
  */
50
- export declare function bin<T>({ data, ...channels }: TransformArg<T, DataRecord>, options?: BinOptions): TransformArg<T, DataRecord>;
50
+ export declare function bin({ data, ...channels }: TransformArg<DataRecord>, options?: BinOptions): TransformArg<DataRecord>;
51
51
  export {};
@@ -4,7 +4,7 @@ import { bin as d3Bin, extent, thresholdFreedmanDiaconis, thresholdScott, thresh
4
4
  import { reduceOutputs } from '../helpers/reduce.js';
5
5
  import { groupFacetsAndZ } from '../helpers/group.js';
6
6
  import { isDate } from '../helpers/typeChecks.js';
7
- import { ORIGINAL_NAME_KEYS } from '../constants';
7
+ import { ORIGINAL_NAME_KEYS } from '../constants.js';
8
8
  const CHANNELS = {
9
9
  x: Symbol('x'),
10
10
  x1: Symbol('x1'),
@@ -26,7 +26,9 @@ function binBy(byDim, { data, ...channels }, options) {
26
26
  bin.domain(domain);
27
27
  if (interval) {
28
28
  const [lo, hi] = extent(data.map((d) => resolveChannel(byDim, d, channels)));
29
- bin.thresholds(maybeInterval(interval).range(lo, hi));
29
+ const iv = maybeInterval(interval);
30
+ if (iv)
31
+ bin.thresholds(iv.range(lo, hi));
30
32
  }
31
33
  else if (thresholds)
32
34
  bin.thresholds(
@@ -58,13 +60,15 @@ function binBy(byDim, { data, ...channels }, options) {
58
60
  const newData = [];
59
61
  let passedGroups = [];
60
62
  const bins = bin(data);
61
- (options.cumulative < 0 ? bins.toReversed() : bins).forEach((group) => {
63
+ ((options.cumulative ?? 0) < 0 ? bins.toReversed() : bins).forEach((group) => {
64
+ const x0 = group.x0;
65
+ const x1 = group.x1;
62
66
  const itemBinProps = {
63
- [CHANNELS[`${byDim}1`]]: group.x0,
64
- [CHANNELS[`${byDim}2`]]: group.x1,
65
- [CHANNELS[`${byDim}`]]: isDate(group.x0)
66
- ? new Date(Math.round((group.x0.getTime() + group.x1.getTime()) * 0.5))
67
- : (group.x0 + group.x1) * 0.5
67
+ [CHANNELS[`${byDim}1`]]: x0,
68
+ [CHANNELS[`${byDim}2`]]: x1,
69
+ [CHANNELS[`${byDim}`]]: isDate(x0)
70
+ ? new Date(Math.round((x0.getTime() + x1.getTime()) * 0.5))
71
+ : ((x0 ?? 0) + (x1 ?? 0)) * 0.5
68
72
  };
69
73
  if (options.cumulative)
70
74
  passedGroups = [...passedGroups, ...group];
@@ -99,7 +103,7 @@ export function binY({ data, ...channels }, options = { thresholds: 'auto', cumu
99
103
  * for binning in x and y dimension simultaneously
100
104
  */
101
105
  export function bin({ data, ...channels }, options = { thresholds: 'auto', cumulative: false }) {
102
- const { domain, thresholds = 'auto', interval, cumulative = false } = options;
106
+ const { domain, thresholds = 'auto', interval } = options;
103
107
  const binX = d3Bin();
104
108
  const binY = d3Bin();
105
109
  if (domain) {
@@ -114,8 +118,11 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
114
118
  if (interval) {
115
119
  const [xlo, xhi] = extent(data.map((d) => resolveChannel('x', d, channels)));
116
120
  const [ylo, yhi] = extent(data.map((d) => resolveChannel('y', d, channels)));
117
- binX.thresholds(maybeInterval(interval).range(xlo, xhi));
118
- binY.thresholds((yThresholds = maybeInterval(interval).range(ylo, yhi)));
121
+ const ivl = maybeInterval(interval);
122
+ if (ivl) {
123
+ binX.thresholds(ivl.range(xlo, xhi));
124
+ binY.thresholds((yThresholds = ivl.range(ylo, yhi)));
125
+ }
119
126
  }
120
127
  else if (thresholds) {
121
128
  // when binning in x and y, we need to ensure we are using consistent thresholds
@@ -150,17 +157,19 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
150
157
  // consistent intervals
151
158
  const newData = [];
152
159
  binX(data).forEach((groupX) => {
160
+ const gx0 = groupX.x0;
161
+ const gx1 = groupX.x1;
153
162
  const newRecordBaseX = {
154
- [CHANNELS.x1]: groupX.x0,
155
- [CHANNELS.x2]: groupX.x1,
156
- [CHANNELS.x]: isDate(groupX.x0)
157
- ? new Date(Math.round((groupX.x0.getTime() + groupX.x1.getTime()) * 0.5))
158
- : (groupX.x0 + groupX.x1) * 0.5
163
+ [CHANNELS.x1]: gx0,
164
+ [CHANNELS.x2]: gx1,
165
+ [CHANNELS.x]: isDate(gx0)
166
+ ? new Date(Math.round((gx0.getTime() + gx1.getTime()) * 0.5))
167
+ : ((gx0 ?? 0) + (gx1 ?? 0)) * 0.5
159
168
  };
160
169
  const [ylo, yhi] = extent(groupX.map((d) => resolveChannel('y', d, channels)));
161
- const tExtentLo = yThresholds.filter((d) => d < ylo).at(-1);
162
- const tExtentHi = yThresholds.filter((d) => d > yhi).at(0);
163
- binY(groupX).forEach((groupY, i) => {
170
+ const tExtentLo = yThresholds.filter((d) => d < ylo).at(-1) ?? ylo;
171
+ const tExtentHi = yThresholds.filter((d) => d > yhi).at(0) ?? yhi;
172
+ binY(groupX).forEach((groupY) => {
164
173
  if (groupY.length === 0)
165
174
  return;
166
175
  // The first bin.x0 is always equal to the minimum domain value,
@@ -174,7 +183,7 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
174
183
  [CHANNELS.y2]: y2,
175
184
  [CHANNELS.y]: isDate(y1)
176
185
  ? new Date(Math.round((y1.getTime() + y2.getTime()) * 0.5))
177
- : (y1 + y2) * 0.5
186
+ : ((y1 ?? 0) + (y2 ?? 0)) * 0.5
178
187
  };
179
188
  const newGroupChannels = groupFacetsAndZ(groupY, channels, (items, itemGroupProps) => {
180
189
  const newRecord = {
@@ -9,6 +9,14 @@ export type BollingerOptions = {
9
9
  */
10
10
  k?: number;
11
11
  };
12
+ /**
13
+ * computes Bollinger bands for the x channel, producing x1 (lower), x (mean),
14
+ * and x2 (upper) channels
15
+ */
12
16
  export declare function bollingerX<T>(args: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
17
+ /**
18
+ * computes Bollinger bands for the y channel, producing y1 (lower), y (mean),
19
+ * and y2 (upper) channels
20
+ */
13
21
  export declare function bollingerY<T>(args: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
14
22
  export declare function bollingerDim<T>(dim: 'x' | 'y', { data, ...channels }: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
@@ -1,7 +1,15 @@
1
1
  import { resolveChannel } from '../helpers/resolve.js';
2
+ /**
3
+ * computes Bollinger bands for the x channel, producing x1 (lower), x (mean),
4
+ * and x2 (upper) channels
5
+ */
2
6
  export function bollingerX(args, options = {}) {
3
7
  return bollingerDim('x', args, options);
4
8
  }
9
+ /**
10
+ * computes Bollinger bands for the y channel, producing y1 (lower), y (mean),
11
+ * and y2 (upper) channels
12
+ */
5
13
  export function bollingerY(args, options = {}) {
6
14
  return bollingerDim('y', args, options);
7
15
  }
@@ -36,18 +44,21 @@ function bollinger(values, N, K) {
36
44
  // compute sum and square of sums
37
45
  for (let n = Math.min(N - 1, values.length); i < n; ++i) {
38
46
  const value = values[i];
39
- ((sum += value), (sumSquared += value ** 2));
47
+ sum += value;
48
+ sumSquared += value ** 2;
40
49
  }
41
- for (let n = values.length, m = bands.length; i < n; ++i) {
50
+ for (let n = values.length; i < n; ++i) {
42
51
  const value = values[i];
43
- ((sum += value), (sumSquared += value ** 2));
52
+ sum += value;
53
+ sumSquared += value ** 2;
44
54
  const mean = sum / N;
45
55
  const deviation = Math.sqrt((sumSquared - sum ** 2 / N) / (N - 1));
46
56
  for (let j = 0; j < K.length; ++j) {
47
57
  bands[j][i] = mean + deviation * K[j];
48
58
  }
49
59
  const value0 = values[i - N + 1];
50
- ((sum -= value0), (sumSquared -= value0 ** 2));
60
+ sum -= value0;
61
+ sumSquared -= value0 ** 2;
51
62
  }
52
63
  return bands;
53
64
  }
@@ -3,6 +3,10 @@ declare const CENTROID: unique symbol;
3
3
  type WithCentroid<T> = T & {
4
4
  [CENTROID]: [number, number];
5
5
  };
6
+ /**
7
+ * computes the geographic centroid of each geometry feature, producing
8
+ * x (longitude) and y (latitude) channels
9
+ */
6
10
  export declare function geoCentroid<Datum extends DataRecord>({ data, ...options }: {
7
11
  data: Datum[];
8
12
  } & TransformArg<Datum>): TransformArg<WithCentroid<Datum>>;
@@ -1,6 +1,10 @@
1
1
  import { resolveProp } from '../helpers/resolve.js';
2
2
  import { geoCentroid as d3GeoCentroid } from 'd3-geo';
3
3
  const CENTROID = Symbol('centroid');
4
+ /**
5
+ * computes the geographic centroid of each geometry feature, producing
6
+ * x (longitude) and y (latitude) channels
7
+ */
4
8
  export function geoCentroid({ data, ...options }) {
5
9
  const transformedData = data.map((d) => ({
6
10
  ...d,
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * implementation based on science.js by Jason Davies
3
3
  */
4
- import type { TransformArg } from '../types';
5
- type Kernel = 'uniform' | 'triangular' | 'epanechnikov' | 'quartic' | 'triweight' | 'gaussian' | 'cosine' | ((u: number) => number);
6
- type DensityOptions<T> = {
4
+ import type { TransformArg } from '../types/index.js';
5
+ export type KernelName = 'uniform' | 'triangular' | 'epanechnikov' | 'quartic' | 'triweight' | 'gaussian' | 'cosine';
6
+ export type Kernel = KernelName | ((u: number) => number);
7
+ export type DensityOptions<_T> = {
7
8
  /**
8
9
  * The kernel function to use for smoothing.
9
10
  */
@@ -37,4 +38,3 @@ export declare function densityX<T>(args: TransformArg<T>, options: DensityOptio
37
38
  export declare function densityY<T>(args: TransformArg<T>, options: DensityOptions<T> & {
38
39
  channel?: 'x' | 'x1' | 'x2';
39
40
  }): TransformArg<T>;
40
- export {};
@@ -9,11 +9,11 @@
9
9
  *
10
10
  */
11
11
  import { extent, quantileSorted, variance } from 'd3-array';
12
- import { isValid } from '../helpers';
13
- import { maybeInterval } from '../helpers/autoTicks';
14
- import { groupFacetsAndZ } from '../helpers/group';
15
- import isDataRecord from '../helpers/isDataRecord';
16
- import { resolveChannel } from '../helpers/resolve';
12
+ import { isValid } from '../helpers/index.js';
13
+ import { maybeInterval } from '../helpers/autoTicks.js';
14
+ import { groupFacetsAndZ } from '../helpers/group.js';
15
+ import isDataRecord from '../helpers/isDataRecord.js';
16
+ import { resolveChannel } from '../helpers/resolve.js';
17
17
  import { ORIGINAL_NAME_KEYS } from '../constants.js';
18
18
  // see https://github.com/jasondavies/science.js/blob/master/src/stats/kernel.js
19
19
  const KERNEL = {
@@ -80,13 +80,16 @@ const BANDWIDTH_FACTOR = {
80
80
  triweight: 3.15,
81
81
  cosine: 1.06
82
82
  };
83
+ function isKernelName(value) {
84
+ return value in KERNEL;
85
+ }
83
86
  function bandwidthSilverman(x) {
84
87
  const iqr = quantileSorted(x, 0.75) - quantileSorted(x, 0.25);
85
88
  const xvar = variance(x);
86
89
  const hi = Math.sqrt(xvar);
87
90
  let lo;
88
91
  if (!(lo = Math.min(hi, iqr / 1.34))) {
89
- (lo = hi) || (lo = Math.abs(x[1])) || (lo = 1);
92
+ lo = hi || Math.abs(x[1]) || 1;
90
93
  }
91
94
  return lo * Math.pow(x.length, -0.2);
92
95
  }
@@ -128,17 +131,21 @@ function density1d(independent, { data, weight, ...channels }, options = {}) {
128
131
  }))).filter((d) => isValid(d[VALUE]) && isValid(d[WEIGHT]) && d[WEIGHT] >= 0);
129
132
  const values = resolvedData.map((d) => d[VALUE]);
130
133
  // compute bandwidth from full data
134
+ const kernelName = typeof kernel === 'string' && isKernelName(kernel) ? kernel : null;
131
135
  const bw = typeof bandwidth === 'function'
132
- ? (BANDWIDTH_FACTOR[kernel] ?? 1) * bandwidth(values.toSorted((a, b) => a - b))
136
+ ? ((kernelName ? BANDWIDTH_FACTOR[kernelName] : null) ?? 1) *
137
+ bandwidth(values.toSorted((a, b) => a - b))
133
138
  : bandwidth;
134
139
  const I = maybeInterval(interval ?? roundToTerminating(bw / 5));
135
140
  let [min, max] = extent(values);
136
141
  if (!trim) {
137
- const r = max - min;
138
- min = I.floor(min - r * 0.2);
139
- max = I.floor(max + r * 0.2);
142
+ const r = (max ?? 0) - (min ?? 0);
143
+ min = I.floor((min ?? 0) - r * 0.2);
144
+ max = I.floor((max ?? 0) + r * 0.2);
140
145
  }
141
- const atValues = I.range(I.floor(min), I.offset(max)).map((d) => +d.toFixed(5));
146
+ const atValues = I
147
+ .range(I.floor(min), I.offset(max))
148
+ .map((d) => +d.toFixed(5));
142
149
  // let minX = Infinity;
143
150
  // let maxX = -Infinity;
144
151
  const res = groupFacetsAndZ(resolvedData, channels, (items, groupProps) => {
@@ -149,9 +156,9 @@ function density1d(independent, { data, weight, ...channels }, options = {}) {
149
156
  .sort((a, b) => a[0] - b[0]);
150
157
  if (!trim) {
151
158
  // trim zero values at begin and end except first and last
152
- const firstNonZero = kdeValues.findIndex(([x, v]) => v > 0);
159
+ const firstNonZero = kdeValues.findIndex(([_x, v]) => v > 0);
153
160
  // if (firstNonZero > 0) minX = Math.min(minX, kdeValues[firstNonZero - 1][0]);
154
- const lastNonZero = kdeValues.length - 1 - [...kdeValues].reverse().findIndex(([x, v]) => v > 0);
161
+ const lastNonZero = kdeValues.length - 1 - [...kdeValues].reverse().findIndex(([_x, v]) => v > 0);
155
162
  // if (lastNonZero > -1 && lastNonZero < kdeValues.length - 1)
156
163
  // maxX = Math.max(maxX, kdeValues[lastNonZero + 1][0]);
157
164
  kdeValues = kdeValues.slice(firstNonZero < 1 ? 0 : firstNonZero - 1, lastNonZero < 0 ? kdeValues.length : lastNonZero + 1);
@@ -195,7 +202,7 @@ function kde1d(values, weights, atValues, kernel, bw, cumulative) {
195
202
  return densities;
196
203
  if (cumulative === -1) {
197
204
  let area = 0;
198
- const cdf = new Array(densities.length);
205
+ const cdf = Array.from({ length: densities.length });
199
206
  for (let i = densities.length - 1; i >= 0; i--) {
200
207
  if (i < densities.length - 1) {
201
208
  const dx = densities[i + 1][0] - densities[i][0];
@@ -206,7 +213,7 @@ function kde1d(values, weights, atValues, kernel, bw, cumulative) {
206
213
  return cdf;
207
214
  }
208
215
  let area = 0;
209
- const cdf = new Array(densities.length);
216
+ const cdf = Array.from({ length: densities.length });
210
217
  for (let i = 0; i < densities.length; i++) {
211
218
  if (i > 0) {
212
219
  const dx = densities[i][0] - densities[i - 1][0];
@@ -219,7 +226,7 @@ function kde1d(values, weights, atValues, kernel, bw, cumulative) {
219
226
  function maybeKernel(kernel) {
220
227
  if (typeof kernel === 'function')
221
228
  return kernel;
222
- return KERNEL[kernel] || KERNEL.epanechnikov;
229
+ return isKernelName(kernel) ? KERNEL[kernel] : KERNEL.epanechnikov;
223
230
  }
224
231
  // See <http://en.wikipedia.org/wiki/Kernel_(statistics)>.
225
232
  // science.stats.kernel = {
@@ -1,17 +1,28 @@
1
- import type { ScaledDataRecord, TransformArg, PlotState } from '../types';
1
+ import type { ScaledDataRecord, TransformArg, PlotState } from '../types/index.js';
2
2
  type BaseDodgeOptions = {
3
+ /** the anchor side for placing dodged marks */
3
4
  anchor?: string;
5
+ /** the padding between dodged marks, in pixels */
4
6
  padding?: number;
7
+ /** the radius of dodged marks, in pixels */
5
8
  r?: number;
6
9
  };
7
10
  type AnchorX = 'left' | 'right' | 'middle';
8
11
  type AnchorY = 'top' | 'bottom' | 'middle';
12
+ /** options for horizontal dodge positioning; can be an anchor string or a full options object */
9
13
  export type DodgeXOptions = AnchorX | (BaseDodgeOptions & {
10
14
  anchor?: 'left' | 'right' | 'middle';
11
15
  });
16
+ /** options for vertical dodge positioning; can be an anchor string or a full options object */
12
17
  export type DodgeYOptions = AnchorY | (BaseDodgeOptions & {
13
18
  anchor?: 'top' | 'bottom' | 'middle';
14
19
  });
20
+ /**
21
+ * offsets marks horizontally to avoid overlap, using circle-packing
22
+ */
15
23
  export declare function dodgeX(args: TransformArg<ScaledDataRecord>, plotState: PlotState): ScaledDataRecord[];
24
+ /**
25
+ * offsets marks vertically to avoid overlap, using circle-packing
26
+ */
16
27
  export declare function dodgeY(args: TransformArg<ScaledDataRecord>, plotState: PlotState): ScaledDataRecord[];
17
28
  export {};