svelteplot 0.4.1 → 0.4.2

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.
package/dist/Mark.svelte CHANGED
@@ -211,8 +211,8 @@
211
211
  valid: true
212
212
  };
213
213
  // compute dx/dy
214
- const dx = Number(resolveProp<number>(options.dx, out.datum, 0));
215
- const dy = Number(resolveProp<number>(options.dy, out.datum, 0));
214
+ out.dx = Number(resolveProp<number>(options.dx, out.datum, 0));
215
+ out.dy = Number(resolveProp<number>(options.dy, out.datum, 0));
216
216
 
217
217
  // special handling if there's a projection, e.g. a line mark
218
218
  if (plot.scales.projection && mark.type !== 'geo') {
@@ -271,7 +271,7 @@
271
271
  // apply dx/dy transform
272
272
  out[channel] =
273
273
  Number.isFinite(scaled) && (scale === 'x' || scale === 'y')
274
- ? scaled + (scale === 'x' ? dx : dy)
274
+ ? scaled + (scale === 'x' ? out.dx : out.dy)
275
275
  : scaled;
276
276
  } else if (defaults[channel]) {
277
277
  out[channel] = defaults[channel];
@@ -3,7 +3,7 @@ import type { ScaleName, ChannelName, ScaledChannelName, ChannelAccessor, DataRo
3
3
  type ChannelAlias = {
4
4
  channel: ScaledChannelName;
5
5
  };
6
- export declare function resolveProp<T>(accessor: ConstantAccessor<T>, datum: DataRecord | null, _defaultValue?: T | null): T | typeof _defaultValue;
6
+ export declare function resolveProp<K, T>(accessor: ConstantAccessor<K, T>, datum: DataRecord | null, _defaultValue?: K | null): K | typeof _defaultValue;
7
7
  type ChannelOptions = {
8
8
  value: ChannelAccessor;
9
9
  scale?: ScaleName | null;
@@ -128,7 +128,9 @@ export function resolveStyles(plot, datum, channels, defaultColorProp = null, us
128
128
  ...getBaseStylesObject(datum?.datum, channels),
129
129
  fill: 'none',
130
130
  stroke: 'none',
131
- ...(defaultColorProp && channels[oppositeColor[defaultColorProp]] == null
131
+ ...(defaultColorProp &&
132
+ (channels[oppositeColor[defaultColorProp]] == null ||
133
+ channels[oppositeColor[defaultColorProp]] === 'none')
132
134
  ? { [defaultColorProp]: 'currentColor' }
133
135
  : {}),
134
136
  ...Object.fromEntries(Object.entries(scaledStyleProps)
@@ -147,6 +149,9 @@ export function resolveStyles(plot, datum, channels, defaultColorProp = null, us
147
149
  return [cssAttr, plot.options.color.unknown];
148
150
  }
149
151
  }
152
+ else if ((key === 'fill' || key === 'stroke') && value === true) {
153
+ return [cssAttr, 'currentColor'];
154
+ }
150
155
  return [cssAttr, value];
151
156
  }))
152
157
  };
@@ -11,6 +11,7 @@
11
11
  stroke?: string;
12
12
  fillOpacity?: number;
13
13
  strokeOpacity?: number;
14
+ opacity?: number;
14
15
  automatic?: boolean;
15
16
  inset?: number;
16
17
  insetLeft?: number;
@@ -29,13 +30,14 @@
29
30
  } from '../types/index.js';
30
31
  import type { BaseMarkProps } from '../types/index.js';
31
32
  import RectPath from './helpers/RectPath.svelte';
33
+ import { resolveProp } from '../helpers/resolve';
32
34
 
33
35
  let markProps: FrameMarkProps = $props();
34
36
 
35
37
  const DEFAULTS: FrameMarkProps = {
36
- fill: 'none',
38
+ fill: undefined,
37
39
  class: 'frame',
38
- stroke: 'currentColor',
40
+ stroke: undefined,
39
41
  fillOpacity: 1,
40
42
  strokeOpacity: 1,
41
43
  ...getContext<PlotDefaults>('svelteplot/_defaults').frame
@@ -46,6 +48,7 @@
46
48
  class: className,
47
49
  fill,
48
50
  stroke,
51
+ opacity,
49
52
  fillOpacity,
50
53
  strokeOpacity,
51
54
  ...options
@@ -54,6 +57,9 @@
54
57
  ...markProps
55
58
  });
56
59
 
60
+ const dx = $derived(resolveProp(options.dx, null, 0) || 0);
61
+ const dy = $derived(resolveProp(options.dy, null, 0) || 0);
62
+
57
63
  const { getPlotState } = getContext<PlotContext>('svelteplot');
58
64
  const plot = $derived(getPlotState());
59
65
  </script>
@@ -62,13 +68,13 @@
62
68
  {#snippet children({ usedScales })}
63
69
  <RectPath
64
70
  class={className}
65
- datum={{ fill, stroke, fillOpacity, strokeOpacity, datum: {}, valid: true }}
66
- x={plot.options.marginLeft}
67
- y={plot.options.marginTop}
71
+ datum={{ fill, stroke, fillOpacity, strokeOpacity, opacity, datum: {}, valid: true }}
72
+ x={plot.options.marginLeft + dx}
73
+ y={plot.options.marginTop + dy}
68
74
  width={plot.facetWidth}
69
75
  height={plot.facetHeight}
70
76
  {usedScales}
71
- fallbackStyle="stroke"
72
- options={{ ...options, fill, stroke, fillOpacity, strokeOpacity }} />
77
+ fallbackStyle={fill == null || fill === 'none' ? 'stroke' : 'fill'}
78
+ options={{ ...options, fill, stroke, fillOpacity, opacity, strokeOpacity }} />
73
79
  {/snippet}
74
80
  </Mark>
@@ -5,6 +5,7 @@ interface FrameMarkProps extends Omit<BaseMarkProps<Datum>, 'fill' | 'stroke' |
5
5
  stroke?: string;
6
6
  fillOpacity?: number;
7
7
  strokeOpacity?: number;
8
+ opacity?: number;
8
9
  automatic?: boolean;
9
10
  inset?: number;
10
11
  insetLeft?: number;
@@ -157,8 +157,6 @@
157
157
  <g class={['link', className]} data-use-x={usedScales.x ? 1 : 0}>
158
158
  {#each scaledData as d, i (i)}
159
159
  {#if d.valid || true}
160
- {@const dx = resolveProp(args.dx, d.datum, 0)}
161
- {@const dy = resolveProp(args.dx, d.datum, 0)}
162
160
  {@const [style, styleClass] = resolveStyles(
163
161
  plot,
164
162
  d,
@@ -196,8 +194,7 @@
196
194
  text={text ? resolveProp(text, d.datum) : null}
197
195
  startOffset={resolveProp(args.textStartOffset, d.datum, '50%')}
198
196
  {textStyle}
199
- {textStyleClass}
200
- transform={dx || dy ? `translate(${dx}, ${dy})` : null} />
197
+ {textStyleClass} />
201
198
  {/if}
202
199
  {/each}
203
200
  </g>
@@ -31,6 +31,7 @@
31
31
  } from '../types/index.js';
32
32
  import GroupMultiple from './helpers/GroupMultiple.svelte';
33
33
  import RectPath from './helpers/RectPath.svelte';
34
+ import { resolveProp } from '../helpers/resolve';
34
35
 
35
36
  let markProps: RectMarkProps = $props();
36
37
 
@@ -64,10 +65,12 @@
64
65
  <GroupMultiple class={scaledData.length > 1 ? className : null} length={scaledData.length}>
65
66
  {#each scaledData as d, i (i)}
66
67
  {#if d.valid}
67
- {@const x1 = d.x1 == null ? plot.options.marginLeft : d.x1}
68
- {@const x2 = d.x2 == null ? plot.options.marginLeft + plot.facetWidth : d.x2}
69
- {@const y1 = d.y1 == null ? plot.options.marginTop : d.y1}
70
- {@const y2 = d.y2 == null ? plot.options.marginTop + plot.facetHeight : d.y2}
68
+ {@const x1 = d.x1 == null ? plot.options.marginLeft + d.dx : d.x1}
69
+ {@const x2 =
70
+ d.x2 == null ? plot.options.marginLeft + plot.facetWidth + d.dx : d.x2}
71
+ {@const y1 = d.y1 == null ? plot.options.marginTop + d.dy : d.y1}
72
+ {@const y2 =
73
+ d.y2 == null ? plot.options.marginTop + plot.facetHeight + d.dy : d.y2}
71
74
 
72
75
  {@const miny = Math.min(y1, y2)}
73
76
  {@const maxy = Math.max(y1, y2)}
@@ -52,15 +52,13 @@
52
52
  {@const inset = resolveProp(args.inset, d.datum, 0)}
53
53
  {@const insetTop = resolveProp(args.insetTop, d.datum, 0)}
54
54
  {@const insetBottom = resolveProp(args.insetBottom, d.datum, 0)}
55
- {@const dx = resolveProp(args.dx, d.datum, 0)}
56
- {@const dy = resolveProp(args.dy, d.datum, 0)}
57
55
  {@const [style, styleClass] = resolveStyles(plot, d, args, 'stroke', usedScales)}
58
56
  <line
59
- transform="translate({d.x + dx}, {dy})"
57
+ transform="translate({d.x}, 0)"
60
58
  {style}
61
59
  class={[styleClass]}
62
- y1={(inset || insetTop) + (d.y1 != null ? d.y1 : plot.options.marginTop)}
63
- y2={(d.y2 != null ? d.y2 : plot.facetHeight + plot.options.marginTop) -
60
+ y1={(inset || insetTop) + (d.y1 != null ? d.y1 : plot.options.marginTop + d.dy)}
61
+ y2={(d.y2 != null ? d.y2 : plot.facetHeight + plot.options.marginTop + d.dy) -
64
62
  (inset || insetBottom)} />
65
63
  {/each}
66
64
  </GroupMultiple>
@@ -51,15 +51,14 @@
51
51
  {@const inset = resolveProp(args.inset, d.datum, 0)}
52
52
  {@const insetLeft = resolveProp(args.insetLeft, d.datum, 0)}
53
53
  {@const insetRight = resolveProp(args.insetRight, d.datum, 0)}
54
- {@const dx = resolveProp(args.dx, d.datum, 0)}
55
- {@const dy = resolveProp(args.dy, d.datum, 0)}
56
54
  {@const [style, styleClass] = resolveStyles(plot, d, args, 'stroke', usedScales)}
57
55
  <line
58
- transform="translate({dx}, {d.y + dy})"
56
+ transform="translate(0, {d.y})"
59
57
  {style}
60
58
  class={[styleClass]}
61
- x1={(inset || insetLeft) + (d.x1 != null ? d.x1 : plot.options.marginLeft)}
62
- x2={(d.x2 != null ? d.x2 : plot.facetWidth + plot.options.marginLeft) -
59
+ x1={(inset || insetLeft) +
60
+ (d.x1 != null ? d.x1 : plot.options.marginLeft + d.dx)}
61
+ x2={(d.x2 != null ? d.x2 : plot.facetWidth + plot.options.marginLeft + d.dx) -
63
62
  (inset || insetRight)} />
64
63
  {/each}
65
64
  </GroupMultiple>
@@ -177,8 +177,6 @@
177
177
  {#each scaledData as d, i (i)}
178
178
  {@const r = resolveChannel('r', d.datum, { r: 3, ...args })}
179
179
  {#if d.valid && isValid(r)}
180
- {@const dx = +resolveProp(args.dx, d.datum, 0)}
181
- {@const dy = +resolveProp(args.dx, d.datum, 0)}
182
180
  {@const [style, styleClass] = resolveStyles(
183
181
  plot,
184
182
  d,
@@ -193,7 +191,7 @@
193
191
  )}
194
192
  <path
195
193
  d={shapePath(shape, d.length, r)}
196
- transform="translate({d.x + dx}, {d.y + dy}) rotate({resolveProp(
194
+ transform="translate({d.x}, {d.y}) rotate({resolveProp(
197
195
  args.rotate,
198
196
  d.datum,
199
197
  0
@@ -58,8 +58,6 @@ Helper component for rendering rectangular marks in SVG
58
58
  const { getPlotState } = getContext<PlotContext>('svelteplot');
59
59
  const plot = $derived(getPlotState());
60
60
 
61
- const dx = $derived(+(resolveProp(options.dx, datum?.datum, 0) as number));
62
- const dy = $derived(+(resolveProp(options.dy, datum?.datum, 0) as number));
63
61
  const inset = $derived(+(resolveProp(options.inset, datum?.datum, 0) as number));
64
62
  const insetLeft = $derived(
65
63
  +(resolveProp(
@@ -108,7 +106,7 @@ Helper component for rendering rectangular marks in SVG
108
106
  <Anchor {options} datum={datum?.datum}>
109
107
  {#if hasBorderRadius}
110
108
  <path
111
- transform="translate({x + dx + insetLeft},{y + insetBottom + dy})"
109
+ transform="translate({x + insetLeft},{y + insetBottom})"
112
110
  d={roundedRect(
113
111
  0,
114
112
  0,
@@ -125,7 +123,7 @@ Helper component for rendering rectangular marks in SVG
125
123
  }} />
126
124
  {:else}
127
125
  <rect
128
- transform="translate({x + dx + insetLeft},{y + insetBottom + dy})"
126
+ transform="translate({x + insetLeft},{y + insetBottom})"
129
127
  width={width - insetLeft - insetRight}
130
128
  height={height - insetTop - insetBottom}
131
129
  class={[styleClass, className]}
@@ -7,6 +7,8 @@ export type ResolvedDataRecord<T = Record<string | symbol, RawValue>> = Partial<
7
7
  export type ScaledDataRecord<T = Record<string | symbol, RawValue>> = Partial<{
8
8
  [K in ScaledChannelName]?: ScaledChannelType<K>;
9
9
  }> & {
10
+ dx: number;
11
+ dy: number;
10
12
  datum: DataRecord<T>;
11
13
  valid: Boolean;
12
14
  };
@@ -24,7 +24,7 @@ export type MarkerOptions = {
24
24
  */
25
25
  marker?: boolean | MarkerShape | Snippet;
26
26
  };
27
- export type ConstantAccessor<T, D = Record<string | symbol, RawValue>> = T | ((d: D) => T) | null | undefined;
27
+ export type ConstantAccessor<K, T = Record<string | symbol, RawValue>> = K | ((d: T) => K) | null | undefined;
28
28
  export type TransformArg<T> = Channels<T> & BaseMarkProps<T> & {
29
29
  data: T[];
30
30
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "license": "ISC",
5
5
  "author": {
6
6
  "name": "Gregor Aisch",