svelteplot 0.10.3-pr-488.4 → 0.10.3-pr-490.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.
@@ -21,7 +21,8 @@
21
21
  BaseMarkProps,
22
22
  BaseRectMarkProps,
23
23
  ChannelAccessor,
24
- LinkableMarkProps
24
+ LinkableMarkProps,
25
+ MarkType
25
26
  } from '../types/index.js';
26
27
  import Mark from '../Mark.svelte';
27
28
  import { recordizeY, sort } from '../index.js';
@@ -67,11 +68,11 @@
67
68
  </script>
68
69
 
69
70
  <Mark
70
- type="cell"
71
71
  required={['x', 'y']}
72
72
  requiredScales={{ x: ['band'], y: ['band'] }}
73
73
  channels={['x', 'y', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
74
- {...args}>
74
+ {...args}
75
+ type={"cell" as MarkType}>
75
76
  {#snippet children({ scaledData, usedScales })}
76
77
  {@const bwx = plot.scales.x.fn.bandwidth()}
77
78
  {@const bwy = plot.scales.y.fn.bandwidth()}
@@ -85,10 +86,10 @@
85
86
  )
86
87
  .map((d) => ({
87
88
  ...d,
88
- x1: d.x - bwx * 0.5,
89
- x2: d.x + bwx * 0.5,
90
- y1: d.y - bwy * 0.5,
91
- y2: d.y + bwy * 0.5
89
+ x1: (d.x as number) - bwx * 0.5,
90
+ x2: (d.x as number) + bwx * 0.5,
91
+ y1: (d.y as number) - bwy * 0.5,
92
+ y2: (d.y as number) + bwy * 0.5
92
93
  }))}
93
94
  <RectCanvas options={args} data={rectCanvasData} {usedScales} />
94
95
  {:else}
@@ -99,8 +100,8 @@
99
100
  class={className}
100
101
  {usedScales}
101
102
  options={args}
102
- x={d.x - bwx * 0.5}
103
- y={d.y - bwy * 0.5}
103
+ x={(d.x as number) - bwx * 0.5}
104
+ y={(d.y as number) - bwy * 0.5}
104
105
  width={bwx}
105
106
  height={bwy} />
106
107
  {/if}
@@ -27,7 +27,7 @@
27
27
  /** CSS class applied to the wrapper element */
28
28
  class: string | null;
29
29
  /** snippet rendered for each data point with the datum and its projected coordinates */
30
- children: Snippet<{ datum: Datum; x: number; y: number }>;
30
+ children: Snippet<[{ datum: Datum; x: number; y: number }]>;
31
31
  }
32
32
  import { type Snippet } from 'svelte';
33
33
  import type { ChannelAccessor, ConstantAccessor, DataRecord } from '../types/index.js';
@@ -49,7 +49,7 @@
49
49
  }: CustomMarkHTMLProps = $props();
50
50
 
51
51
  function getXY(datum: Datum) {
52
- const fa = frameAnchor || 'center';
52
+ const fa = (frameAnchor || 'center') as string;
53
53
  const isLeft = fa.endsWith('left');
54
54
  const isRight = fa.endsWith('right');
55
55
  const isTop = fa.startsWith('top');
@@ -13,11 +13,11 @@ declare function $$render<Datum extends DataRecord>(): {
13
13
  /** CSS class applied to the wrapper element */
14
14
  class: string | null;
15
15
  /** snippet rendered for each data point with the datum and its projected coordinates */
16
- children: Snippet<{
16
+ children: Snippet<[{
17
17
  datum: Datum;
18
18
  x: number;
19
19
  y: number;
20
- }>;
20
+ }]>;
21
21
  };
22
22
  exports: {};
23
23
  bindings: "";
@@ -81,7 +81,7 @@
81
81
  const {
82
82
  data,
83
83
  stroke,
84
- class: className = null,
84
+ class: className = '',
85
85
  ...options
86
86
  }: DifferenceYMarkProps = $derived({
87
87
  ...DEFAULTS,
@@ -92,27 +92,33 @@
92
92
  const x1x2Differ = $derived((x1 == null || x2 == null) && x1 !== x2);
93
93
 
94
94
  const xExtent = $derived(
95
- x1x2Differ && x != null ? extent(data, (d) => resolveChannel('x', d, options)) : null
95
+ x1x2Differ && x != null
96
+ ? extent(data, (d) => resolveChannel('x', d, options) as number | null | undefined)
97
+ : null
96
98
  );
97
99
  const x1Extent = $derived(
98
- x1x2Differ && x1 != null ? extent(data, (d) => resolveChannel('x1', d, options)) : null
100
+ x1x2Differ && x1 != null
101
+ ? extent(data, (d) => resolveChannel('x1', d, options) as number | null | undefined)
102
+ : null
99
103
  );
100
104
  const x2Extent = $derived(
101
- x1x2Differ && x2 != null ? extent(data, (d) => resolveChannel('x2', d, options)) : null
105
+ x1x2Differ && x2 != null
106
+ ? extent(data, (d) => resolveChannel('x2', d, options) as number | null | undefined)
107
+ : null
102
108
  );
103
109
 
104
110
  const maxMin = $derived(
105
- max([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d[0]))
111
+ max([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d![0] as number))
106
112
  );
107
113
  const minMax = $derived(
108
- min([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d[1]))
114
+ min([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d![1] as number))
109
115
  );
110
116
 
111
117
  const croppedX1 = $derived(
112
118
  x1x2Differ
113
119
  ? data.filter((d) => {
114
- const x1val = resolveChannel(x1 != null ? 'x1' : 'x', d, options);
115
- return x1val >= maxMin && x1val <= minMax;
120
+ const x1val = resolveChannel(x1 != null ? 'x1' : 'x', d, options) as number;
121
+ return x1val >= (maxMin as number) && x1val <= (minMax as number);
116
122
  })
117
123
  : data
118
124
  );
@@ -120,8 +126,8 @@
120
126
  const croppedX2 = $derived(
121
127
  x1x2Differ
122
128
  ? data.filter((d) => {
123
- const x2val = resolveChannel(x2 != null ? 'x2' : 'x', d, options);
124
- return x2val >= maxMin && x2val <= minMax;
129
+ const x2val = resolveChannel(x2 != null ? 'x2' : 'x', d, options) as number;
130
+ return x2val >= (maxMin as number) && x2val <= (minMax as number);
125
131
  })
126
132
  : data
127
133
  );
@@ -146,7 +152,7 @@
146
152
  data={croppedX1}
147
153
  {...options}
148
154
  fill={options.positiveFill || 'pink'}
149
- fillOpacity={coalesce(options.positiveFillOpacity, options.fillOpacity, 1)}
155
+ fillOpacity={coalesce(options.positiveFillOpacity, options.fillOpacity, 1) as number}
150
156
  x1={coalesce(x1, x2, x)}
151
157
  y1={{ scale: null, value: 0 }}
152
158
  y2={coalesce(y1, x1x2Differ ? coalesce(y2, y) : 0)} />
@@ -168,7 +174,7 @@
168
174
  data={croppedX2}
169
175
  {...options}
170
176
  fill={options.negativeFill || 'cyan'}
171
- fillOpacity={coalesce(options.negativeFillOpacity, options.fillOpacity, 1)}
177
+ fillOpacity={coalesce(options.negativeFillOpacity, options.fillOpacity, 1) as number}
172
178
  x1={coalesce(x2, x)}
173
179
  y1={{ scale: null, value: 0 }}
174
180
  y2={coalesce(y2, y)} />
@@ -57,7 +57,7 @@
57
57
 
58
58
  const plot = usePlot();
59
59
 
60
- function getSymbolPath(symbolType, size) {
60
+ function getSymbolPath(symbolType: string, size: number) {
61
61
  return d3Symbol(maybeSymbol(symbolType), size)();
62
62
  }
63
63
 
@@ -65,7 +65,7 @@
65
65
  // todo: move sorting to Mark
66
66
  sort(
67
67
  recordizeXY({
68
- data,
68
+ data: data as any[],
69
69
  // sort by descending radius by default
70
70
  ...(options.r &&
71
71
  !isOrdinalScale(plot.scales.x.type) &&
@@ -98,7 +98,7 @@
98
98
  {#snippet children({ mark, usedScales, scaledData })}
99
99
  <g class="dot {className || ''}">
100
100
  {#if canvas}
101
- <DotCanvas data={scaledData} {mark} />
101
+ <DotCanvas data={scaledData} {mark} {plot} />
102
102
  {:else}
103
103
  {#each scaledData as d, i (i)}
104
104
  {#if d.valid && isValid(d.r)}
@@ -109,18 +109,18 @@
109
109
  'stroke',
110
110
  usedScales
111
111
  )}
112
- <Anchor {options} datum={d.datum}>
112
+ <Anchor options={options as any} datum={d.datum}>
113
113
  <path
114
114
  transform="translate({d.x}, {d.y})"
115
- d={getSymbolPath(d.symbol, d.r ** 2 * Math.PI)}
115
+ d={getSymbolPath(d.symbol as string, (d.r as number) ** 2 * Math.PI)}
116
116
  class={[
117
- dotClass ? resolveProp(dotClass, d.datum, null) : null,
117
+ dotClass ? resolveProp(dotClass, d.datum as Datum, null) : null,
118
118
  styleClass
119
119
  ]}
120
120
  {style}
121
121
  {@attach addEventHandlers({
122
122
  plot,
123
- options: args,
123
+ options: args as any,
124
124
  datum: d?.datum
125
125
  })} />
126
126
  </Anchor>
@@ -71,7 +71,7 @@
71
71
  geoPath,
72
72
  [plot.scales.projection],
73
73
  options.r
74
- ? { pointRadius: (d) => plot.scales.r.fn(resolveChannel('r', d, options)) }
74
+ ? { pointRadius: (d: any) => plot.scales.r.fn(resolveChannel('r', d, options)) }
75
75
  : { pointRadius: 3 }
76
76
  )
77
77
  );
@@ -79,7 +79,7 @@
79
79
  const args = $derived(
80
80
  sort(
81
81
  recordize({
82
- data,
82
+ data: data as any[],
83
83
  ...(options.r ? { sort: { channel: '-r' } } : {}),
84
84
  ...options
85
85
  })
@@ -101,24 +101,24 @@
101
101
  {:else}
102
102
  {#each scaledData as d, i (i)}
103
103
  {#if d.valid}
104
- <Anchor {options} datum={d.datum}>
104
+ <Anchor options={options as any} datum={d.datum}>
105
105
  {@const title = resolveProp(args.title, d.datum, '')}
106
106
  {@const geometry = resolveProp(args.geometry, d.datum, d.datum)}
107
107
  {@const [style, styleClass] = resolveStyles(
108
108
  plot,
109
109
  d,
110
- args,
111
- GEOJSON_PREFER_STROKE.has(geometry.type) ? 'stroke' : 'fill',
110
+ args as any,
111
+ GEOJSON_PREFER_STROKE.has((geometry as any)?.type) ? 'stroke' : 'fill',
112
112
  usedScales
113
113
  )}
114
114
  <path
115
- d={path(geometry)}
115
+ d={path(geometry as any)}
116
116
  {style}
117
117
  class={[styleClass]}
118
- filter={resolveProp(args.svgFilter, d.datum, undefined)}
118
+ filter={resolveProp(args.svgFilter, d.datum, undefined) as string | undefined}
119
119
  {@attach addEventHandlers({
120
120
  plot,
121
- options: args,
121
+ options: args as any,
122
122
  datum: d?.datum
123
123
  })}>
124
124
  {#if title}<title>{title}</title>{/if}
@@ -32,7 +32,7 @@
32
32
 
33
33
  let { data, x, y, r, fx, fy, children }: HTMLTooltipMarkProps = $props();
34
34
 
35
- let datum = $state(false);
35
+ let datum = $state<Datum | false>(false);
36
36
  let tooltipX = $state();
37
37
  let tooltipY = $state();
38
38
 
@@ -41,12 +41,12 @@
41
41
 
42
42
  function onPointerMove(evt: MouseEvent) {
43
43
  const plotRect = plot.body.getBoundingClientRect();
44
- let facetEl = evt.target as SVGElement;
44
+ let facetEl: Element | null = evt.target as Element;
45
45
  while (facetEl && !facetEl.classList.contains('facet')) {
46
- facetEl = facetEl.parentElement;
46
+ facetEl = facetEl.parentElement as Element | null;
47
47
  }
48
- const facetIndex = +(facetEl?.dataset?.facet ?? 0);
49
- const facetRect = (facetEl?.firstChild ?? plot.body).getBoundingClientRect();
48
+ const facetIndex = +((facetEl as HTMLElement)?.dataset?.facet ?? 0);
49
+ const facetRect = ((facetEl?.firstChild as Element) ?? plot.body).getBoundingClientRect();
50
50
 
51
51
  facetOffsetX = facetRect.left - plotRect.left - plot.options.marginLeft;
52
52
  facetOffsetY = facetRect.top - plotRect.top - plot.options.marginTop;
@@ -86,7 +86,7 @@
86
86
 
87
87
  const trees = $derived(
88
88
  groups.map((items) =>
89
- quadtree()
89
+ quadtree<Datum>()
90
90
  .x((d) => projectX('x', plot.scales, resolveChannel('x', d, { x, y, r })))
91
91
  .y((d) => projectY('y', plot.scales, resolveChannel('y', d, { x, y, r })))
92
92
  .addAll(items)
@@ -98,7 +98,7 @@
98
98
  class={['svelteplot-tooltip', { hide: !datum }]}
99
99
  style:left="{tooltipX ? facetOffsetX + projectX('x', plot.scales, tooltipX) : 0}px"
100
100
  style:top="{tooltipY ? facetOffsetY + projectY('y', plot.scales, tooltipY) : 0}px">
101
- {@render children({ datum })}
101
+ {@render children({ datum: datum as Datum })}
102
102
  </div>
103
103
 
104
104
  <style>
@@ -53,7 +53,7 @@
53
53
  };
54
54
 
55
55
  const {
56
- data = [{}],
56
+ data = [] as Datum[],
57
57
  children,
58
58
  x,
59
59
  y,
@@ -62,20 +62,20 @@
62
62
  fy,
63
63
  maxDistance = 15,
64
64
  tolerance = Number.NEGATIVE_INFINITY,
65
- onupdate = null
65
+ onupdate = undefined
66
66
  }: PointerMarkProps = $derived({
67
67
  ...DEFAULTS,
68
68
  ...markProps
69
69
  });
70
70
 
71
- let selectedData = $state([]);
71
+ let selectedData = $state<any[]>([]);
72
72
 
73
73
  function onPointerMove(evt: MouseEvent) {
74
- let facetEl = evt.target as SVGElement;
74
+ let facetEl: Element | null = evt.target as Element;
75
75
  while (facetEl && !facetEl.classList.contains('facet')) {
76
- facetEl = facetEl.parentElement;
76
+ facetEl = facetEl.parentElement as Element | null;
77
77
  }
78
- const facetRect = (facetEl?.firstChild ?? plot.body).getBoundingClientRect();
78
+ const facetRect = ((facetEl?.firstChild as Element) ?? plot.body).getBoundingClientRect();
79
79
 
80
80
  const relativeX = evt.clientX - facetRect.left + (plot.options.marginLeft ?? 0);
81
81
  const relativeY = evt.clientY - facetRect.top + (plot.options.marginTop ?? 0);
@@ -100,11 +100,11 @@
100
100
  .data()
101
101
  .filter((d) => d !== points[i])
102
102
  .filter(
103
- (d) =>
103
+ (d: any) =>
104
104
  (!isFinite(d[POINTER_X]) ||
105
- Math.abs(d[POINTER_X] - points[i]?.[POINTER_X]) < tolerance) &&
105
+ Math.abs(d[POINTER_X] - (points[i] as any)?.[POINTER_X]) < tolerance) &&
106
106
  (!isFinite(d[POINTER_Y]) ||
107
- Math.abs(d[POINTER_Y] - points[i]?.[POINTER_Y]) < tolerance)
107
+ Math.abs(d[POINTER_Y] - (points[i] as any)?.[POINTER_Y]) < tolerance)
108
108
  );
109
109
  });
110
110
  selectedData = [...points, ...otherPoints].filter((d) => d != null);
@@ -122,18 +122,18 @@
122
122
  });
123
123
 
124
124
  const groups = $derived.by(() => {
125
- const groups = [];
126
- groupFacetsAndZ(indexData(data), { x, y, z, fx, fy }, (d) => groups.push(d));
125
+ const groups: any[][] = [];
126
+ groupFacetsAndZ(indexData(data as object[]) as any, { x, y, z, fx, fy }, (d) => groups.push(d));
127
127
  return groups;
128
128
  });
129
129
 
130
130
  const trees = $derived(
131
131
  groups.map((items) =>
132
- quadtree()
133
- .x(x != null ? (d) => d[POINTER_X] : () => 0)
134
- .y(y != null ? (d) => d[POINTER_Y] : () => 0)
132
+ quadtree<any>()
133
+ .x(x != null ? (d: any) => d[POINTER_X] : () => 0)
134
+ .y(y != null ? (d: any) => d[POINTER_Y] : () => 0)
135
135
  .addAll(
136
- items?.map((d) => {
136
+ items?.map((d: any) => {
137
137
  const [px, py] = projectXY(
138
138
  plot.scales,
139
139
  resolveChannel('x', d, { x }),
@@ -71,7 +71,7 @@
71
71
  r: defaultRadius
72
72
  };
73
73
  const {
74
- data = [{}],
74
+ data = [{} as Datum],
75
75
  canvas,
76
76
  shape = 'arrow',
77
77
  anchor = 'middle',
@@ -151,7 +151,7 @@
151
151
 
152
152
  const args = $derived(
153
153
  sort({
154
- data: indexData(data),
154
+ data: indexData(data as object[]) as unknown as Datum[],
155
155
  // sort by descending radius by default
156
156
  ...options
157
157
  })
@@ -173,7 +173,7 @@
173
173
  'fillOpacity',
174
174
  'strokeOpacity'
175
175
  ]}
176
- {...args}>
176
+ {...(args as any)}>
177
177
  {#snippet children({ scaledData, usedScales })}
178
178
  <g class="vector" data-l={usedScales.length}>
179
179
  {#if canvas}
@@ -190,25 +190,25 @@
190
190
  strokeLinejoin: 'round',
191
191
  strokeLinecap: 'round',
192
192
  ...args
193
- },
193
+ } as any,
194
194
  shape === 'arrow-filled' ? 'fill' : 'stroke',
195
195
  usedScales
196
196
  )}
197
197
  <path
198
- d={shapePath(shape, d.length, d.r)}
198
+ d={shapePath(shape, d.length as number, d.r as number)}
199
199
  transform="translate({d.x}, {d.y}) rotate({resolveProp(
200
200
  args.rotate,
201
- d.datum,
201
+ d.datum as any,
202
202
  0
203
- )}) {anchor === 'start'
203
+ ) as number}) {anchor === 'start'
204
204
  ? ''
205
205
  : anchor === 'end'
206
- ? `translate(0, ${d.length})`
207
- : `translate(0, ${d.length / 2})`}"
206
+ ? `translate(0, ${d.length as number})`
207
+ : `translate(0, ${(d.length as number) / 2})`}"
208
208
  {style}
209
209
  {@attach addEventHandlers({
210
210
  plot,
211
- options: args,
211
+ options: args as any,
212
212
  datum: d?.datum
213
213
  })}
214
214
  class={[styleClass]} />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.10.3-pr-488.4",
3
+ "version": "0.10.3-pr-490.0",
4
4
  "description": "A Svelte-native data visualization framework based on the layered grammar of graphics principles.",
5
5
  "keywords": [
6
6
  "svelte",