svelteplot 0.4.2-pr-194.2 → 0.4.2-pr-194.3

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.
@@ -1,4 +1,4 @@
1
- import type { ChannelName, Channels, DataRecord, RawValue } from '../types/index.js';
1
+ import type { ChannelName, Channels, RawValue } from '../types/index.js';
2
2
  import type { Snippet } from 'svelte';
3
3
  /**
4
4
  * Returns first argument that is not null or undefined
@@ -8,7 +8,6 @@ export declare function testFilter<T>(datum: T, options: Channels<T>): any;
8
8
  export declare function randomId(): string;
9
9
  export declare function isSnippet(value: unknown): value is Snippet;
10
10
  export declare function isValid(value: RawValue | undefined): value is number | Date | string;
11
- export declare function maybeData(data: DataRecord[]): DataRecord[];
12
11
  export declare function isObject<T>(option: object | T): option is object;
13
12
  export declare function maybeNumber(value: RawValue | null): number | null;
14
13
  export declare const constant: <T>(x: T) => () => T;
@@ -27,10 +27,6 @@ export function isValid(value) {
27
27
  !Number.isNaN(value) &&
28
28
  (typeof value !== 'number' || Number.isFinite(value)));
29
29
  }
30
- export function maybeData(data) {
31
- // if (data.type === 'FeatureCollection') return data.features;
32
- return data;
33
- }
34
30
  export function isObject(option) {
35
31
  // doesn't work with Proxies
36
32
  return (typeof option === 'object' && !isDate(option) && !Array.isArray(option) && option !== null);
@@ -48,13 +48,14 @@
48
48
  PlotDefaults
49
49
  } from '../types/index.js';
50
50
  import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
51
- import { coalesce, maybeData, maybeNumber } from '../helpers/index.js';
51
+ import { coalesce, maybeNumber } from '../helpers/index.js';
52
52
  import Mark from '../Mark.svelte';
53
53
  import { arrowPath, maybeSweep, type SweepOption } from '../helpers/arrowPath.js';
54
54
  import { replaceChannels } from '../transforms/rename.js';
55
55
  import { addEventHandlers } from './helpers/events.js';
56
56
  import GroupMultiple from './helpers/GroupMultiple.svelte';
57
57
  import { sort } from '../transforms/sort.js';
58
+ import { indexData } from '../transforms/recordize.js';
58
59
 
59
60
  let markProps: ArrowMarkProps = $props();
60
61
 
@@ -80,7 +81,7 @@
80
81
  const args: ArrowMarkProps = $derived(
81
82
  sort(
82
83
  replaceChannels(
83
- { data: maybeData(data), ...options },
84
+ { data: indexData(data), ...options },
84
85
  { y: ['y1', 'y2'], x: ['x1', 'x2'] }
85
86
  )
86
87
  )
@@ -28,7 +28,7 @@
28
28
  import { sort } from '../index.js';
29
29
  import Mark from '../Mark.svelte';
30
30
  import DotCanvas from './helpers/DotCanvas.svelte';
31
- import { maybeData, isValid } from '../helpers/index.js';
31
+ import { isValid } from '../helpers/index.js';
32
32
  import { recordizeXY } from '../transforms/recordize.js';
33
33
  import { addEventHandlers } from './helpers/events.js';
34
34
  import Anchor from './helpers/Anchor.svelte';
@@ -58,7 +58,7 @@
58
58
  // todo: move sorting to Mark
59
59
  sort(
60
60
  recordizeXY({
61
- data: maybeData(data),
61
+ data,
62
62
  // sort by descending radius by default
63
63
  ...(options.r ? { sort: { channel: '-r' } } : {}),
64
64
  ...options,
@@ -5,14 +5,25 @@
5
5
  interface GridXMarkProps extends Omit<BaseMarkProps<Datum>, 'fill' | 'fillOpacity'> {
6
6
  data?: Datum[];
7
7
  automatic?: boolean;
8
+ y1?: ChannelAccessor<Datum>;
9
+ y2?: ChannelAccessor<Datum>;
8
10
  }
9
11
  import { getContext } from 'svelte';
10
12
  import Mark from '../Mark.svelte';
11
- import type { PlotContext, BaseMarkProps, RawValue, PlotDefaults } from '../types/index.js';
13
+ import type {
14
+ PlotContext,
15
+ BaseMarkProps,
16
+ RawValue,
17
+ PlotDefaults,
18
+ DataRecord,
19
+ ChannelAccessor
20
+ } from '../types/index.js';
12
21
  import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
13
22
  import { autoTicks } from '../helpers/autoTicks.js';
14
23
  import { testFilter } from '../helpers/index.js';
15
24
  import { RAW_VALUE } from '../transforms/recordize.js';
25
+ import isDataRecord from '../helpers/isDataRecord';
26
+ import { INDEX } from '../constants';
16
27
 
17
28
  let markProps: GridXMarkProps = $props();
18
29
 
@@ -37,8 +48,8 @@
37
48
  Math.max(3, Math.round(plot.facetWidth / plot.options.x.tickSpacing))
38
49
  );
39
50
 
40
- const ticks: RawValue[] = $derived(
41
- data.length > 0
51
+ const ticks: DataRecord[] = $derived(
52
+ (data.length > 0
42
53
  ? // use custom tick values if user passed any as prop
43
54
  data
44
55
  : // use custom scale tick values if user passed any as plot scale option
@@ -50,6 +61,9 @@
50
61
  plot.scales.x.fn,
51
62
  autoTickCount
52
63
  )
64
+ ).map((d, i) =>
65
+ isDataRecord(d) ? { ...d, [INDEX]: i } : { [RAW_VALUE]: d, [INDEX]: i }
66
+ ) as DataRecord[]
53
67
  );
54
68
  </script>
55
69
 
@@ -64,17 +78,21 @@
64
78
  {#each ticks as tick, t (t)}
65
79
  {#if testFilter(tick, options)}
66
80
  {@const x =
67
- plot.scales.x.fn(tick) +
81
+ plot.scales.x.fn(tick[RAW_VALUE]) +
68
82
  (plot.scales.x.type === 'band' ? plot.scales.x.fn.bandwidth() * 0.5 : 0)}
69
83
  {@const y1_ = resolveChannel('y1', tick, options)}
70
84
  {@const y2_ = resolveChannel('y2', tick, options)}
71
85
  {@const dx = +resolveProp(options?.dx, tick, 0)}
72
86
  {@const dy = +resolveProp(options?.dy, tick, 0)}
73
- {@const y1 = options.y1 != null ? plot.scales.y.fn(y1_) : 0}
74
- {@const y2 = options.y2 != null ? plot.scales.y.fn(y2_) : plot.facetHeight}
87
+ {@const y1 =
88
+ options.y1 != null ? plot.scales.y.fn(y1_) : plot.options.marginTop}
89
+ {@const y2 =
90
+ options.y2 != null
91
+ ? plot.scales.y.fn(y2_)
92
+ : plot.options.marginTop + plot.facetHeight}
75
93
  {@const [style, styleClass] = resolveStyles(
76
94
  plot,
77
- { datum: { [RAW_VALUE]: tick } },
95
+ { datum: tick },
78
96
  options,
79
97
  'stroke',
80
98
  usedScales,
@@ -82,7 +100,7 @@
82
100
  )}
83
101
  <line
84
102
  class={styleClass}
85
- transform="translate({x + dx},{plot.options.marginTop + dy})"
103
+ transform="translate({x + dx},{dy})"
86
104
  {style}
87
105
  {y1}
88
106
  {y2} />
@@ -1,25 +1,25 @@
1
- import type { RawValue } from '../types/index.js';
1
+ import type { RawValue, ChannelAccessor } from '../types/index.js';
2
2
  declare class __sveltets_Render<Datum = RawValue> {
3
3
  props(): Omit<Partial<{
4
4
  filter?: import("../types/index.js").ConstantAccessor<boolean, Datum>;
5
5
  facet?: "auto" | "include" | "exclude";
6
- fx: import("../types/channel").ChannelAccessor<Datum>;
7
- fy: import("../types/channel").ChannelAccessor<Datum>;
6
+ fx: ChannelAccessor<Datum>;
7
+ fy: ChannelAccessor<Datum>;
8
8
  dx: import("../types/index.js").ConstantAccessor<number, Datum>;
9
9
  dy: import("../types/index.js").ConstantAccessor<number, Datum>;
10
- fill: import("../types/channel").ChannelAccessor<Datum>;
10
+ fill: ChannelAccessor<Datum>;
11
11
  fillOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
12
12
  sort: {
13
13
  channel: string;
14
14
  order?: "ascending" | "descending";
15
15
  } | ((a: RawValue, b: RawValue) => number) | import("../types/index.js").ConstantAccessor<RawValue, Datum>;
16
- stroke: import("../types/channel").ChannelAccessor<Datum>;
16
+ stroke: ChannelAccessor<Datum>;
17
17
  strokeWidth: import("../types/index.js").ConstantAccessor<number, Datum>;
18
18
  strokeOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
19
19
  strokeLinejoin: import("../types/index.js").ConstantAccessor<import("csstype").Property.StrokeLinejoin, Datum>;
20
20
  strokeLinecap: import("../types/index.js").ConstantAccessor<import("csstype").Property.StrokeLinecap, Datum>;
21
21
  strokeMiterlimit: import("../types/index.js").ConstantAccessor<number, Datum>;
22
- opacity: import("../types/channel").ChannelAccessor<Datum>;
22
+ opacity: ChannelAccessor<Datum>;
23
23
  strokeDasharray: import("../types/index.js").ConstantAccessor<string, Datum>;
24
24
  strokeDashoffset: import("../types/index.js").ConstantAccessor<number, Datum>;
25
25
  mixBlendMode: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Datum>;
@@ -62,6 +62,8 @@ declare class __sveltets_Render<Datum = RawValue> {
62
62
  }>, "fill" | "fillOpacity"> & {
63
63
  data?: Datum[] | undefined;
64
64
  automatic?: boolean;
65
+ y1?: ChannelAccessor<Datum>;
66
+ y2?: ChannelAccessor<Datum>;
65
67
  };
66
68
  events(): {};
67
69
  slots(): {};
@@ -5,10 +5,18 @@
5
5
  interface GridYMarkProps extends Omit<BaseMarkProps<Datum>, 'fill' | 'fillOpacity'> {
6
6
  data?: Datum[];
7
7
  automatic?: boolean;
8
+ x1?: ChannelAccessor<Datum>;
9
+ x2?: ChannelAccessor<Datum>;
8
10
  }
9
11
  import { getContext } from 'svelte';
10
12
  import Mark from '../Mark.svelte';
11
- import type { PlotContext, BaseMarkProps, RawValue, PlotDefaults } from '../types/index.js';
13
+ import type {
14
+ PlotContext,
15
+ BaseMarkProps,
16
+ RawValue,
17
+ PlotDefaults,
18
+ ChannelAccessor
19
+ } from '../types/index.js';
12
20
  import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
13
21
  import { autoTicks } from '../helpers/autoTicks.js';
14
22
  import { testFilter } from '../helpers/index.js';
@@ -68,8 +76,12 @@
68
76
  (plot.scales.y.type === 'band' ? plot.scales.y.fn.bandwidth() * 0.5 : 0)}
69
77
  {@const x1_ = resolveChannel('x1', tick, options)}
70
78
  {@const x2_ = resolveChannel('x2', tick, options)}
71
- {@const x1 = options.x1 != null ? plot.scales.x.fn(x1_) : 0}
72
- {@const x2 = options.x2 != null ? plot.scales.x.fn(x2_) : plot.facetWidth}
79
+ {@const x1 =
80
+ options.x1 != null ? plot.scales.x.fn(x1_) : plot.options.marginLeft}
81
+ {@const x2 =
82
+ options.x2 != null
83
+ ? plot.scales.x.fn(x2_)
84
+ : plot.options.marginLeft + plot.facetWidth}
73
85
  {@const dx = +resolveProp(options?.dx, tick, 0)}
74
86
  {@const dy = +resolveProp(options?.dy, tick, 0)}
75
87
  {@const [style, styleClass] = resolveStyles(
@@ -83,7 +95,7 @@
83
95
  <line
84
96
  {style}
85
97
  class={styleClass}
86
- transform="translate({plot.options.marginLeft + dx},{y + dy})"
98
+ transform="translate({dx},{y + dy})"
87
99
  {x1}
88
100
  {x2} />
89
101
  {/if}
@@ -1,25 +1,25 @@
1
- import type { RawValue } from '../types/index.js';
1
+ import type { RawValue, ChannelAccessor } from '../types/index.js';
2
2
  declare class __sveltets_Render<Datum = RawValue> {
3
3
  props(): Omit<Partial<{
4
4
  filter?: import("../types/index.js").ConstantAccessor<boolean, Datum>;
5
5
  facet?: "auto" | "include" | "exclude";
6
- fx: import("../types/channel").ChannelAccessor<Datum>;
7
- fy: import("../types/channel").ChannelAccessor<Datum>;
6
+ fx: ChannelAccessor<Datum>;
7
+ fy: ChannelAccessor<Datum>;
8
8
  dx: import("../types/index.js").ConstantAccessor<number, Datum>;
9
9
  dy: import("../types/index.js").ConstantAccessor<number, Datum>;
10
- fill: import("../types/channel").ChannelAccessor<Datum>;
10
+ fill: ChannelAccessor<Datum>;
11
11
  fillOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
12
12
  sort: {
13
13
  channel: string;
14
14
  order?: "ascending" | "descending";
15
15
  } | ((a: RawValue, b: RawValue) => number) | import("../types/index.js").ConstantAccessor<RawValue, Datum>;
16
- stroke: import("../types/channel").ChannelAccessor<Datum>;
16
+ stroke: ChannelAccessor<Datum>;
17
17
  strokeWidth: import("../types/index.js").ConstantAccessor<number, Datum>;
18
18
  strokeOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
19
19
  strokeLinejoin: import("../types/index.js").ConstantAccessor<import("csstype").Property.StrokeLinejoin, Datum>;
20
20
  strokeLinecap: import("../types/index.js").ConstantAccessor<import("csstype").Property.StrokeLinecap, Datum>;
21
21
  strokeMiterlimit: import("../types/index.js").ConstantAccessor<number, Datum>;
22
- opacity: import("../types/channel").ChannelAccessor<Datum>;
22
+ opacity: ChannelAccessor<Datum>;
23
23
  strokeDasharray: import("../types/index.js").ConstantAccessor<string, Datum>;
24
24
  strokeDashoffset: import("../types/index.js").ConstantAccessor<number, Datum>;
25
25
  mixBlendMode: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Datum>;
@@ -62,6 +62,8 @@ declare class __sveltets_Render<Datum = RawValue> {
62
62
  }>, "fill" | "fillOpacity"> & {
63
63
  data?: Datum[] | undefined;
64
64
  automatic?: boolean;
65
+ x1?: ChannelAccessor<Datum>;
66
+ x2?: ChannelAccessor<Datum>;
65
67
  };
66
68
  events(): {};
67
69
  slots(): {};
@@ -48,7 +48,6 @@
48
48
  PlotDefaults
49
49
  } from '../types/index.js';
50
50
  import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
51
- import { maybeData } from '../helpers/index.js';
52
51
  import Mark from '../Mark.svelte';
53
52
  import MarkerPath from './helpers/MarkerPath.svelte';
54
53
  import { replaceChannels } from '../transforms/rename.js';
@@ -57,6 +56,8 @@
57
56
  import { maybeCurve } from '../helpers/curves.js';
58
57
  import { geoPath } from 'd3-geo';
59
58
  import { pick } from 'es-toolkit';
59
+ import { sort } from '../transforms/sort.js';
60
+ import { indexData } from '../transforms/recordize.js';
60
61
 
61
62
  let markProps: LinkMarkProps = $props();
62
63
  const DEFAULTS = {
@@ -77,17 +78,13 @@
77
78
  const { getPlotState } = getContext<PlotContext>('svelteplot');
78
79
  let plot = $derived(getPlotState());
79
80
 
80
- const sorted = $derived(
81
- options.sort
82
- ? maybeData(data).toSorted((a, b) =>
83
- resolveChannel('sort', a, options) > resolveChannel('sort', b, options) ? 1 : -1
84
- )
85
- : maybeData(data)
86
- );
87
-
88
81
  const args = $derived(
89
82
  replaceChannels(
90
- { data: sorted, stroke: 'currentColor', ...options },
83
+ sort({
84
+ data: indexData(data),
85
+ stroke: 'currentColor',
86
+ ...options
87
+ }),
91
88
  { y: ['y1', 'y2'], x: ['x1', 'x2'] }
92
89
  )
93
90
  );
@@ -30,7 +30,7 @@
30
30
  import { quadtree } from 'd3-quadtree';
31
31
  import { projectXY } from '../helpers/scales.js';
32
32
  import isDataRecord from '../helpers/isDataRecord.js';
33
- import { RAW_VALUE } from '../transforms/recordize.js';
33
+ import { indexData, RAW_VALUE } from '../transforms/recordize.js';
34
34
  import { groupFacetsAndZ } from '../helpers/group.js';
35
35
 
36
36
  const { getPlotState } = getContext<PlotContext>('svelteplot');
@@ -116,7 +116,7 @@
116
116
 
117
117
  const groups = $derived.by(() => {
118
118
  const groups = [];
119
- groupFacetsAndZ(data, { x, y, z, fx, fy }, (d) => groups.push(d));
119
+ groupFacetsAndZ(indexData(data), { x, y, z, fx, fy }, (d) => groups.push(d));
120
120
  return groups;
121
121
  });
122
122
 
@@ -71,6 +71,7 @@
71
71
  import { sort } from '../index.js';
72
72
 
73
73
  import MultilineText from './helpers/MultilineText.svelte';
74
+ import { indexData } from '../transforms/recordize';
74
75
 
75
76
  const DEFAULTS = {
76
77
  fontSize: 12,
@@ -95,7 +96,7 @@
95
96
 
96
97
  const args = $derived(
97
98
  sort({
98
- data,
99
+ data: indexData(data),
99
100
  ...options
100
101
  })
101
102
  ) as TextMarkProps;
@@ -44,8 +44,9 @@
44
44
  import { sort } from '../index.js';
45
45
  import Mark from '../Mark.svelte';
46
46
  //import DotCanvas from './helpers/DotCanvas.svelte';
47
- import { maybeData, testFilter, isValid } from '../helpers/index.js';
47
+ import { isValid } from '../helpers/index.js';
48
48
  import { addEventHandlers } from './helpers/events.js';
49
+ import { indexData } from '../transforms/recordize.js';
49
50
 
50
51
  const defaultRadius = 3.5;
51
52
 
@@ -145,7 +146,7 @@
145
146
 
146
147
  const args = $derived(
147
148
  sort({
148
- data: maybeData(data),
149
+ data: indexData(data),
149
150
  // sort by descending radius by default
150
151
  ...options
151
152
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.4.2-pr-194.2",
3
+ "version": "0.4.2-pr-194.3",
4
4
  "license": "ISC",
5
5
  "author": {
6
6
  "name": "Gregor Aisch",