svelteplot 0.2.9-pr-109.1 → 0.2.10-pr-110.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SveltePlot
2
2
 
3
- ![Tests](https://github.com/svelteplot/svelteplot/actions/workflows/test.yml/badge.svg)
3
+ ![License](https://img.shields.io/npm/l/svelteplot.svg) ![Tests](https://github.com/svelteplot/svelteplot/actions/workflows/test.yml/badge.svg)
4
4
 
5
5
  SveltePlot is a visualization framework based on the [layered grammar of graphics](https://vita.had.co.nz/papers/layered-grammar.html) ideas. It's API is heavily inspired by [Observable Plot](https://github.com/observablehq/plot). Created by Gregor Aisch.
6
6
 
package/dist/Plot.svelte CHANGED
@@ -12,7 +12,7 @@
12
12
  <script lang="ts">
13
13
  import Plot from './core/Plot.svelte';
14
14
 
15
- import type { PlotOptions } from './types.js';
15
+ import type { PlotDefaults, PlotOptions } from './types.js';
16
16
 
17
17
  // implicit marks
18
18
  import AxisX from './marks/AxisX.svelte';
@@ -28,6 +28,7 @@
28
28
  import { autoScale, autoScaleColor } from './helpers/autoScales.js';
29
29
  import { namedProjection } from './helpers/autoProjection.js';
30
30
  import { isObject } from './helpers/index.js';
31
+ import { getContext } from 'svelte';
31
32
 
32
33
  let {
33
34
  header: userHeader,
@@ -51,22 +51,17 @@
51
51
  const maxMarginBottom = $derived(Math.max(...$autoMarginBottom.values()));
52
52
  const maxMarginTop = $derived(Math.max(...$autoMarginTop.values()));
53
53
 
54
+ const USER_DEFAULTS = getContext<Partial<PlotDefaults>>('svelteplot/defaults') || {};
55
+
54
56
  // default settings in the plot and marks can be overwritten by
55
57
  // defining the svelteplot/defaults context outside of Plot
56
58
  const DEFAULTS: PlotDefaults = {
57
- axisXAnchor: 'bottom',
58
- axisYAnchor: 'left',
59
- xTickSpacing: 80,
60
- yTickSpacing: 50,
61
59
  height: 350,
62
60
  initialWidth: 500,
63
61
  inset: 0,
64
62
  colorScheme: 'turbo',
65
63
  unknown: '#cccccc99',
66
- dotRadius: 3,
67
- frame: false,
68
- axes: true,
69
- grid: false,
64
+
70
65
  categoricalColorScheme: 'observable10',
71
66
  pointScaleHeight: 18,
72
67
  bandScaleHeight: 30,
@@ -77,7 +72,29 @@
77
72
  compactDisplay: 'short'
78
73
  },
79
74
  markerDotRadius: 3,
80
- ...getContext<Partial<PlotDefaults>>('svelteplot/defaults')
75
+ ...USER_DEFAULTS,
76
+ axisX: {
77
+ anchor: 'bottom',
78
+ implicit: true,
79
+ ...USER_DEFAULTS.axis,
80
+ ...USER_DEFAULTS.axisX
81
+ },
82
+ axisY: {
83
+ anchor: 'left',
84
+ implicit: true,
85
+ ...USER_DEFAULTS.axis,
86
+ ...USER_DEFAULTS.axisY
87
+ },
88
+ gridX: {
89
+ implicit: false,
90
+ ...USER_DEFAULTS.grid,
91
+ ...USER_DEFAULTS.gridX
92
+ },
93
+ gridY: {
94
+ implicit: false,
95
+ ...USER_DEFAULTS.grid,
96
+ ...USER_DEFAULTS.gridY
97
+ }
81
98
  };
82
99
 
83
100
  let {
@@ -390,16 +407,16 @@
390
407
  ? margins
391
408
  : Math.max(5, maxMarginBottom),
392
409
  inset: isOneDimensional ? 10 : DEFAULTS.inset,
393
- grid: DEFAULTS.grid,
394
- axes: DEFAULTS.axes,
395
- frame: DEFAULTS.frame,
410
+ grid: (DEFAULTS.gridX?.implicit ?? false) && (DEFAULTS.gridY?.implicit ?? false),
411
+ axes: (DEFAULTS.axisX?.implicit ?? false) && (DEFAULTS.axisY?.implicit ?? false),
412
+ frame: DEFAULTS.frame?.implicit ?? false,
396
413
  projection: null,
397
414
  aspectRatio: null,
398
415
  facet: {},
399
416
  padding: 0.1,
400
417
  x: {
401
418
  type: 'auto',
402
- axis: autoXAxis ? DEFAULTS.axisXAnchor : false,
419
+ axis: DEFAULTS.axisX.implicit && autoXAxis ? DEFAULTS.axisX.anchor : false,
403
420
  labelAnchor: 'auto',
404
421
  reverse: false,
405
422
  clamp: false,
@@ -408,13 +425,13 @@
408
425
  round: false,
409
426
  percent: false,
410
427
  align: 0.5,
411
- tickSpacing: DEFAULTS.xTickSpacing,
428
+ tickSpacing: DEFAULTS.axisX.tickSpacing ?? 80,
412
429
  tickFormat: 'auto',
413
- grid: false
430
+ grid: DEFAULTS.gridX.implicit ?? false
414
431
  },
415
432
  y: {
416
433
  type: 'auto',
417
- axis: autoYAxis ? DEFAULTS.axisYAnchor : false,
434
+ axis: DEFAULTS.axisY.implicit && autoYAxis ? DEFAULTS.axisY.anchor : false,
418
435
  labelAnchor: 'auto',
419
436
  reverse: false,
420
437
  clamp: false,
@@ -423,9 +440,9 @@
423
440
  round: false,
424
441
  percent: false,
425
442
  align: 0.5,
426
- tickSpacing: DEFAULTS.yTickSpacing,
443
+ tickSpacing: DEFAULTS.axisY.tickSpacing ?? 50,
427
444
  tickFormat: 'auto',
428
- grid: false
445
+ grid: DEFAULTS.gridY.implicit ?? false
429
446
  },
430
447
  opacity: {
431
448
  type: 'linear',
@@ -39,12 +39,22 @@
39
39
  ConstantAccessor,
40
40
  ChannelAccessor,
41
41
  ScaledDataRecord,
42
- LinkableMarkProps
42
+ LinkableMarkProps,
43
+ PlotDefaults
43
44
  } from '../types.js';
44
45
  import type { RawValue } from '../types.js';
45
46
  import type { StackOptions } from '../transforms/stack.js';
46
47
 
47
- let {
48
+ let markProps: AreaMarkProps = $props();
49
+
50
+ const DEFAULTS = {
51
+ fill: 'currentColor',
52
+ curve: 'linear',
53
+ tension: 0,
54
+ ...getContext<PlotDefaults>('svelteplot/_defaults').area
55
+ };
56
+
57
+ const {
48
58
  data,
49
59
  /** the curve */
50
60
  curve = 'linear',
@@ -52,7 +62,7 @@
52
62
  class: className = '',
53
63
  canvas = false,
54
64
  ...options
55
- }: AreaMarkProps = $props();
65
+ }: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
56
66
 
57
67
  const { getPlotState } = getContext<PlotContext>('svelteplot');
58
68
  const plot = $derived(getPlotState());
@@ -7,15 +7,19 @@
7
7
  import { renameChannels } from '../transforms/rename.js';
8
8
  import { stackX } from '../transforms/stack.js';
9
9
  import { recordizeX } from '../transforms/recordize.js';
10
- import type { ChannelAccessor } from '../types.js';
10
+ import type { ChannelAccessor, PlotDefaults } from '../types.js';
11
+ import { getContext } from 'svelte';
11
12
 
12
13
  type AreaXProps = Omit<AreaMarkProps, 'y1' | 'y2'> & {
13
14
  x?: ChannelAccessor;
14
15
  y?: ChannelAccessor;
15
16
  };
16
17
 
17
- // we're discarding y1 and y2 props since they are not
18
- let { data, stack, ...options }: AreaXProps = $props();
18
+ let markProps: AreaMarkProps = $props();
19
+
20
+ const DEFAULTS = getContext<PlotDefaults>('svelteplot/_defaults').areaX;
21
+
22
+ const { data, stack, ...options }: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
19
23
 
20
24
  const args = $derived(
21
25
  renameChannels<AreaXProps>(
@@ -1,13 +1,8 @@
1
1
  import { type AreaMarkProps } from './Area.svelte';
2
- import type { ChannelAccessor } from '../types.js';
3
- type AreaXProps = Omit<AreaMarkProps, 'y1' | 'y2'> & {
4
- x?: ChannelAccessor;
5
- y?: ChannelAccessor;
6
- };
7
2
  /**
8
3
  * Creates a horizontal area chart with x value and baseline. Areas are implicitly
9
4
  * stacked horizontally if just the x channel is defined.
10
5
  */
11
- declare const AreaX: import("svelte").Component<AreaXProps, {}, "">;
6
+ declare const AreaX: import("svelte").Component<AreaMarkProps, {}, "">;
12
7
  type AreaX = ReturnType<typeof AreaX>;
13
8
  export default AreaX;
@@ -7,7 +7,8 @@
7
7
  import { renameChannels } from '../transforms/rename.js';
8
8
  import { stackY } from '../transforms/stack.js';
9
9
  import { recordizeY } from '../transforms/recordize.js';
10
- import type { ChannelAccessor } from '../types.js';
10
+ import type { ChannelAccessor, PlotDefaults } from '../types.js';
11
+ import { getContext } from 'svelte';
11
12
 
12
13
  /**
13
14
  * AreaY mark foo
@@ -17,7 +18,11 @@
17
18
  y?: ChannelAccessor;
18
19
  };
19
20
 
20
- let { data, stack, ...options }: AreaYProps = $props();
21
+ let markProps: AreaMarkProps = $props();
22
+
23
+ const DEFAULTS = getContext<PlotDefaults>('svelteplot/_defaults').areaY;
24
+
25
+ const { data, stack, ...options }: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
21
26
 
22
27
  const args = $derived(
23
28
  renameChannels<AreaYProps>(
@@ -1,16 +1,8 @@
1
1
  import { type AreaMarkProps } from './Area.svelte';
2
- import type { ChannelAccessor } from '../types.js';
3
- /**
4
- * AreaY mark foo
5
- */
6
- type AreaYProps = Omit<AreaMarkProps, 'x1' | 'x2'> & {
7
- x?: ChannelAccessor;
8
- y?: ChannelAccessor;
9
- };
10
2
  /**
11
3
  * Creates a vertical area chart with y value and baseline. Areas are implicitly
12
4
  * stacked vertically if just the y channel is defined.
13
5
  */
14
- declare const AreaY: import("svelte").Component<AreaYProps, {}, "">;
6
+ declare const AreaY: import("svelte").Component<AreaMarkProps, {}, "">;
15
7
  type AreaY = ReturnType<typeof AreaY>;
16
8
  export default AreaY;
@@ -38,14 +38,15 @@
38
38
  </script>
39
39
 
40
40
  <script lang="ts">
41
- import { getContext, type Snippet } from 'svelte';
41
+ import { getContext } from 'svelte';
42
42
  import type {
43
43
  PlotContext,
44
44
  DataRecord,
45
45
  BaseMarkProps,
46
46
  ConstantAccessor,
47
47
  ChannelAccessor,
48
- RawValue
48
+ RawValue,
49
+ PlotDefaults
49
50
  } from '../types.js';
50
51
  import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
51
52
  import { coalesce, maybeData, maybeNumber } from '../helpers/index.js';
@@ -55,7 +56,20 @@
55
56
  import { addEventHandlers } from './helpers/events.js';
56
57
  import GroupMultiple from './helpers/GroupMultiple.svelte';
57
58
 
58
- let { data = [{}], class: className = null, ...options }: ArrowMarkProps = $props();
59
+ let markProps: ArrowMarkProps = $props();
60
+
61
+ const DEFAULTS = {
62
+ headAngle: 60,
63
+ headLength: 8,
64
+ inset: 0,
65
+ ...getContext<PlotDefaults>('svelteplot/_defaults').arrow
66
+ };
67
+
68
+ const {
69
+ data = [{}],
70
+ class: className = null,
71
+ ...options
72
+ }: ArrowMarkProps = $derived({ ...DEFAULTS, ...markProps });
59
73
 
60
74
  const { getPlotState } = getContext<PlotContext>('svelteplot');
61
75
  const plot = $derived(getPlotState());
@@ -68,7 +82,7 @@
68
82
  : maybeData(data)
69
83
  );
70
84
 
71
- const args: ArrowProps = $derived(
85
+ const args: ArrowMarkProps = $derived(
72
86
  replaceChannels({ data: sorted, ...options }, { y: ['y1', 'y2'], x: ['x1', 'x2'] })
73
87
  );
74
88
  </script>
@@ -78,7 +92,7 @@
78
92
  required={['x1', 'x2', 'y1', 'y2']}
79
93
  channels={['x1', 'y1', 'x2', 'y2', 'opacity', 'stroke', 'strokeOpacity']}
80
94
  {...args}>
81
- {#snippet children({ mark, usedScales, scaledData })}
95
+ {#snippet children({ usedScales, scaledData })}
82
96
  {@const sweep = maybeSweep(args.sweep)}
83
97
  <GroupMultiple class="arrow" length={scaledData.length}>
84
98
  {#each scaledData as d, i (i)}
@@ -86,8 +100,8 @@
86
100
  {@const inset = resolveProp(args.inset, d.datum, 0)}
87
101
  {@const insetStart = resolveProp(args.insetStart, d.datum)}
88
102
  {@const insetEnd = resolveProp(args.insetEnd, d.datum)}
89
- {@const headAngle = resolveProp(args.headAngle, d.datum, 60)}
90
- {@const headLength = resolveProp(args.headLength, d.datum, 8)}
103
+ {@const headAngle = resolveProp(args.headAngle, d.datum)}
104
+ {@const headLength = resolveProp(args.headLength, d.datum)}
91
105
  {@const bend = resolveProp(args.bend, d.datum, 0)}
92
106
  {@const strokeWidth = resolveProp(args.strokeWidth, d.datum, 1)}
93
107
  {@const arrPath = arrowPath(
@@ -27,16 +27,11 @@
27
27
  ticks?: number | string | RawValue[];
28
28
  /** set to false or null to disable tick labels */
29
29
  text: boolean | null;
30
- } & XOR<
31
- {
32
- /** approximate number of ticks to be generated */
33
- tickCount?: number;
34
- },
35
- {
36
- /** approximate number of pixels between generated ticks */
37
- tickSpacing?: number;
38
- }
39
- >;
30
+ /** approximate number of ticks to be generated */
31
+ tickCount?: number;
32
+ /** approximate number of pixels between generated ticks */
33
+ tickSpacing?: number;
34
+ };
40
35
  </script>
41
36
 
42
37
  <script lang="ts">
@@ -49,32 +44,36 @@
49
44
  RawValue,
50
45
  ConstantAccessor,
51
46
  FacetContext,
52
- DefaultOptions
47
+ PlotDefaults,
48
+ ChannelName
53
49
  } from '../types.js';
54
50
  import autoTimeFormat from '../helpers/autoTimeFormat.js';
55
51
  import { derived } from 'svelte/store';
56
52
  import { autoTicks } from '../helpers/autoTicks.js';
57
53
  import { resolveScaledStyles } from '../helpers/resolve.js';
58
54
 
59
- const DEFAULTS = {
55
+ let markProps: AxisXMarkProps = $props();
56
+
57
+ const DEFAULTS: Omit<AxisXMarkProps, 'data' | ChannelName> = {
60
58
  tickSize: 6,
61
59
  tickPadding: 3,
62
60
  tickFontSize: 11,
63
- axisXAnchor: 'bottom',
64
- ...getContext<Partial<DefaultOptions>>('svelteplot/_defaults')
61
+ anchor: 'bottom',
62
+ ...getContext<PlotDefaults>('svelteplot/_defaults').axis,
63
+ ...getContext<PlotDefaults>('svelteplot/_defaults').axisX
65
64
  };
66
65
 
67
- let {
66
+ const {
68
67
  ticks: magicTicks,
69
68
  data = Array.isArray(magicTicks) ? magicTicks : [],
70
69
  automatic = false,
71
70
  title,
72
- anchor = DEFAULTS.axisXAnchor as 'top' | 'bottom',
71
+ anchor,
73
72
  facetAnchor = 'auto',
74
73
  interval = typeof magicTicks === 'string' ? magicTicks : undefined,
75
- tickSize = DEFAULTS.tickSize,
76
- tickFontSize = DEFAULTS.tickFontSize,
77
- tickPadding = DEFAULTS.tickPadding,
74
+ tickSize,
75
+ tickFontSize,
76
+ tickPadding,
78
77
  labelAnchor,
79
78
  tickFormat,
80
79
  tickClass,
@@ -83,7 +82,7 @@
83
82
  tickSpacing,
84
83
  text = true,
85
84
  ...options
86
- }: AxisXMarkProps = $props();
85
+ }: AxisXMarkProps = $derived({ ...DEFAULTS, ...markProps });
87
86
 
88
87
  const { getPlotState } = getContext<PlotContext>('svelteplot');
89
88
  const plot = $derived(getPlotState());
@@ -1,4 +1,3 @@
1
- import type { XOR } from 'ts-essentials';
2
1
  export type AxisXMarkProps = Omit<BaseMarkProps, 'fill' | 'fillOpacity' | 'paintOrder' | 'title' | 'href' | 'target'> & {
3
2
  data?: RawValue[];
4
3
  automatic?: boolean;
@@ -16,13 +15,11 @@ export type AxisXMarkProps = Omit<BaseMarkProps, 'fill' | 'fillOpacity' | 'paint
16
15
  ticks?: number | string | RawValue[];
17
16
  /** set to false or null to disable tick labels */
18
17
  text: boolean | null;
19
- } & XOR<{
20
18
  /** approximate number of ticks to be generated */
21
19
  tickCount?: number;
22
- }, {
23
20
  /** approximate number of pixels between generated ticks */
24
21
  tickSpacing?: number;
25
- }>;
22
+ };
26
23
  import type { BaseMarkProps, RawValue, ConstantAccessor } from '../types.js';
27
24
  /** Renders a horizontal axis with labels and tick marks */
28
25
  declare const AxisX: import("svelte").Component<AxisXMarkProps, {}, "">;
@@ -28,16 +28,11 @@
28
28
  ticks?: number | string | RawValue[];
29
29
  /** set to false or null to disable tick labels */
30
30
  text: boolean | null;
31
- } & XOR<
32
- {
33
- /** approximate number of ticks to be generated */
34
- tickCount?: number;
35
- },
36
- {
37
- /** approximate number of pixels between generated ticks */
38
- tickSpacing?: number;
39
- }
40
- >;
31
+ /** approximate number of ticks to be generated */
32
+ tickCount?: number;
33
+ /** approximate number of pixels between generated ticks */
34
+ tickSpacing?: number;
35
+ };
41
36
  </script>
42
37
 
43
38
  <script lang="ts">
@@ -49,40 +44,44 @@
49
44
  BaseMarkProps,
50
45
  RawValue,
51
46
  FacetContext,
52
- DefaultOptions
47
+ PlotDefaults,
48
+ ChannelName
53
49
  } from '../types.js';
54
50
  import autoTimeFormat from '../helpers/autoTimeFormat.js';
55
51
  import type { ConstantAccessor } from '../types.js';
56
52
  import { autoTicks } from '../helpers/autoTicks.js';
57
53
  import { resolveScaledStyles } from '../helpers/resolve.js';
58
54
 
59
- const DEFAULTS = {
55
+ let markProps: AxisYMarkProps = $props();
56
+
57
+ const DEFAULTS: Omit<AxisYMarkProps, 'data' | ChannelName> = {
60
58
  tickSize: 6,
61
59
  tickPadding: 3,
62
60
  tickFontSize: 11,
63
- axisYAnchor: 'left',
64
- ...getContext<Partial<DefaultOptions>>('svelteplot/_defaults')
61
+ anchor: 'left',
62
+ ...getContext<PlotDefaults>('svelteplot/_defaults').axis,
63
+ ...getContext<PlotDefaults>('svelteplot/_defaults').axisY
65
64
  };
66
65
 
67
- let {
66
+ const {
68
67
  ticks: magicTicks,
69
68
  data = Array.isArray(magicTicks) ? magicTicks : [],
70
69
  automatic = false,
71
70
  title,
72
- anchor = DEFAULTS.axisYAnchor as 'left' | 'right',
71
+ anchor,
73
72
  facetAnchor = 'auto',
74
73
  interval = typeof magicTicks === 'string' ? magicTicks : undefined,
75
74
  lineAnchor = 'center',
76
- tickSize = DEFAULTS.tickSize,
77
- tickFontSize = DEFAULTS.tickFontSize,
78
- tickPadding = DEFAULTS.tickPadding,
75
+ tickSize,
76
+ tickFontSize,
77
+ tickPadding,
79
78
  tickFormat,
80
79
  tickClass,
81
80
  tickCount = typeof magicTicks === 'number' ? magicTicks : undefined,
82
81
  tickSpacing,
83
82
  text = true,
84
83
  ...options
85
- }: AxisYMarkProps = $props();
84
+ }: AxisYMarkProps = $derived({ ...DEFAULTS, ...markProps });
86
85
 
87
86
  const { getPlotState } = getContext<PlotContext>('svelteplot');
88
87
  const plot = $derived(getPlotState());
@@ -1,4 +1,3 @@
1
- import type { XOR } from 'ts-essentials';
2
1
  export type AxisYMarkProps = Omit<BaseMarkProps, 'fill' | 'fillOpacity' | 'paintOrder' | 'title' | 'href' | 'target'> & {
3
2
  data?: RawValue[];
4
3
  automatic?: boolean;
@@ -17,13 +16,11 @@ export type AxisYMarkProps = Omit<BaseMarkProps, 'fill' | 'fillOpacity' | 'paint
17
16
  ticks?: number | string | RawValue[];
18
17
  /** set to false or null to disable tick labels */
19
18
  text: boolean | null;
20
- } & XOR<{
21
19
  /** approximate number of ticks to be generated */
22
20
  tickCount?: number;
23
- }, {
24
21
  /** approximate number of pixels between generated ticks */
25
22
  tickSpacing?: number;
26
- }>;
23
+ };
27
24
  import type { BaseMarkProps, RawValue } from '../types.js';
28
25
  import type { ConstantAccessor } from '../types.js';
29
26
  /** Renders a vertical axis with labels and tick marks */
@@ -8,7 +8,8 @@
8
8
  BaseMarkProps,
9
9
  BaseRectMarkProps,
10
10
  ChannelAccessor,
11
- LinkableMarkProps
11
+ LinkableMarkProps,
12
+ PlotDefaults
12
13
  } from '../types.js';
13
14
 
14
15
  export type BarXMarkProps = BaseMarkProps &
@@ -38,7 +39,20 @@
38
39
  import GroupMultiple from './helpers/GroupMultiple.svelte';
39
40
  import RectPath from './helpers/RectPath.svelte';
40
41
 
41
- let { data = [{}], class: className = null, stack, ...options }: BarXMarkProps = $props();
42
+ const DEFAULTS = {
43
+ fill: 'currentColor',
44
+ ...getContext<PlotDefaults>('svelteplot/_defaults').bar,
45
+ ...getContext<PlotDefaults>('svelteplot/_defaults').barX
46
+ };
47
+
48
+ let markProps: BarXMarkProps = $props();
49
+
50
+ const {
51
+ data = [{}],
52
+ class: className = null,
53
+ stack,
54
+ ...options
55
+ }: BarXMarkProps = $derived({ ...DEFAULTS, ...markProps });
42
56
 
43
57
  const { getPlotState } = getContext<PlotContext>('svelteplot');
44
58
  const plot = $derived(getPlotState());
@@ -8,7 +8,8 @@
8
8
  BaseMarkProps,
9
9
  BaseRectMarkProps,
10
10
  ChannelAccessor,
11
- DataRow
11
+ DataRow,
12
+ PlotDefaults
12
13
  } from '../types.js';
13
14
 
14
15
  export type BarYMarkProps = BaseMarkProps &
@@ -37,11 +38,24 @@
37
38
  import GroupMultiple from './helpers/GroupMultiple.svelte';
38
39
  import RectPath from './helpers/RectPath.svelte';
39
40
 
40
- let { data = [{}], class: className = null, stack, ...options }: BarYMarkProps = $props();
41
-
42
41
  const { getPlotState } = getContext<PlotContext>('svelteplot');
43
42
  const plot = $derived(getPlotState());
44
43
 
44
+ const DEFAULTS = {
45
+ fill: 'currentColor',
46
+ ...getContext<PlotDefaults>('svelteplot/_defaults').bar,
47
+ ...getContext<PlotDefaults>('svelteplot/_defaults').barY
48
+ };
49
+
50
+ let markProps: BarYMarkProps = $props();
51
+
52
+ const {
53
+ data = [{}],
54
+ class: className = null,
55
+ stack,
56
+ ...options
57
+ }: BarYMarkProps = $derived({ ...DEFAULTS, ...markProps });
58
+
45
59
  const args = $derived(
46
60
  stackY(
47
61
  intervalY(
@@ -11,14 +11,14 @@
11
11
  import { range as d3Range, extent } from 'd3-array';
12
12
  import { maybeSymbol } from '../helpers/symbols.js';
13
13
 
14
- import type { DefaultOptions, PlotContext } from '../types.js';
14
+ import type { PlotDefaults, PlotContext } from '../types.js';
15
15
 
16
16
  let { class: className = null }: ColorLegendMarkProps = $props();
17
17
 
18
18
  const { getPlotState } = getContext<PlotContext>('svelteplot');
19
19
  const plot = $derived(getPlotState());
20
20
 
21
- const DEFAULTS = getContext<Partial<DefaultOptions>>('svelteplot/_defaults');
21
+ const DEFAULTS = getContext<Partial<PlotDefaults>>('svelteplot/_defaults');
22
22
 
23
23
  const legendTitle = $derived(plot.options.color.label);
24
24
  const scaleType = $derived(plot.scales.color.type);
@@ -35,13 +35,19 @@
35
35
  import { addEventHandlers } from './helpers/events.js';
36
36
  import Anchor from './helpers/Anchor.svelte';
37
37
 
38
- let {
38
+ const DEFAULTS = {
39
+ ...getContext<PlotDefaults>('svelteplot/_defaults').dot
40
+ };
41
+
42
+ let markProps: DotMarkProps = $props();
43
+
44
+ const {
39
45
  data = [{}],
40
46
  canvas = false,
41
47
  class: className = '',
42
48
  dotClass = null,
43
49
  ...options
44
- }: DotMarkProps = $props();
50
+ }: DotMarkProps = $derived({ ...DEFAULTS, ...markProps });
45
51
 
46
52
  const { getPlotState } = getContext<PlotContext>('svelteplot');
47
53
  const plot = $derived(getPlotState());
@@ -50,8 +56,6 @@
50
56
  return d3Symbol(maybeSymbol(symbolType), size)();
51
57
  }
52
58
 
53
- const { dotRadius } = getContext<PlotDefaults>('svelteplot/_defaults');
54
-
55
59
  const args = $derived(
56
60
  // todo: move sorting to Mark
57
61
  sort(
@@ -80,7 +84,7 @@
80
84
  'fillOpacity',
81
85
  'strokeOpacity'
82
86
  ]}
83
- defaults={{ r: dotRadius, symbol: 'circle' }}
87
+ defaults={{ r: 3, symbol: 'circle' }}
84
88
  {...args}>
85
89
  {#snippet children({ mark, usedScales, scaledData })}
86
90
  <g class="dot {className || ''}">
@@ -28,19 +28,38 @@
28
28
  <script lang="ts">
29
29
  import Mark from '../Mark.svelte';
30
30
  import { getContext } from 'svelte';
31
- import type { PlotContext, BaseRectMarkProps, LinkableMarkProps } from '../types.js';
31
+ import type {
32
+ PlotContext,
33
+ BaseRectMarkProps,
34
+ LinkableMarkProps,
35
+ PlotDefaults
36
+ } from '../types.js';
32
37
  import type { BaseMarkProps } from '../types.js';
33
38
  import RectPath from './helpers/RectPath.svelte';
34
39
 
35
- let {
40
+ let markProps: FrameMarkProps = $props();
41
+
42
+ const DEFAULTS: FrameMarkProps = {
43
+ fill: 'none',
44
+ class: 'frame',
45
+ stroke: 'currentColor',
46
+ fillOpacity: 1,
47
+ strokeOpacity: 1,
48
+ ...getContext<PlotDefaults>('svelteplot/_defaults').frame
49
+ };
50
+
51
+ const {
36
52
  automatic,
37
- class: className = 'frame',
53
+ class: className,
38
54
  fill,
39
55
  stroke,
40
56
  fillOpacity,
41
57
  strokeOpacity,
42
58
  ...options
43
- }: FrameMarkProps = $props();
59
+ }: FrameMarkProps = $derived({
60
+ ...DEFAULTS,
61
+ ...markProps
62
+ });
44
63
 
45
64
  const { getPlotState } = getContext<PlotContext>('svelteplot');
46
65
  const plot = $derived(getPlotState());
@@ -2,7 +2,7 @@
2
2
  Renders a geographic graticule grid with customizable step sizes
3
3
  -->
4
4
  <script module lang="ts">
5
- import type { DefaultOptions, BaseMarkProps } from '../types.js';
5
+ import type { PlotDefaults, BaseMarkProps } from '../types.js';
6
6
  export type GraticuleMarkProps = Omit<
7
7
  BaseMarkProps,
8
8
  'fill' | 'fillOpacity' | 'paintOrder' | 'title' | 'href' | 'target' | 'cursor'
@@ -20,7 +20,7 @@
20
20
 
21
21
  const DEFAULTS = {
22
22
  graticuleStep: 10,
23
- ...getContext<Partial<DefaultOptions>>('svelteplot/defaults')
23
+ ...getContext<Partial<PlotDefaults>>('svelteplot/defaults')
24
24
  };
25
25
 
26
26
  let { step = DEFAULTS.graticuleStep, stepX, stepY, ...options }: GraticuleMarkProps = $props();
package/dist/types.d.ts CHANGED
@@ -4,6 +4,34 @@ import type { MouseEventHandler } from 'svelte/elements';
4
4
  import type { MarkerShape } from './marks/helpers/Marker.svelte';
5
5
  import type { Writable } from 'svelte/store';
6
6
  import type * as CSS from 'csstype';
7
+ import type { AreaMarkProps } from './marks/Area.svelte';
8
+ import type { ArrowMarkProps } from './marks/Arrow.svelte';
9
+ import type { AxisXMarkProps } from './marks/AxisX.svelte';
10
+ import type { AxisYMarkProps } from './marks/AxisY.svelte';
11
+ import type { BarXMarkProps } from './marks/BarX.svelte';
12
+ import type { CellMarkProps } from './marks/Cell.svelte';
13
+ import type { DotMarkProps } from './marks/Dot.svelte';
14
+ import type { FrameMarkProps } from './marks/Frame.svelte';
15
+ import type { GeoMarkProps } from './marks/Geo.svelte';
16
+ import type { GraticuleMarkProps } from './marks/Graticule.svelte';
17
+ import type { LineMarkProps } from './marks/Line.svelte';
18
+ import type { LinkMarkProps } from './marks/Link.svelte';
19
+ import type { RectMarkProps } from './marks/Rect.svelte';
20
+ import type { RuleXMarkProps } from './marks/RuleX.svelte';
21
+ import type { SphereMarkProps } from './marks/Sphere.svelte';
22
+ import type { SpikeMarkProps } from './marks/Spike.svelte';
23
+ import type { TextMarkProps } from './marks/Text.svelte';
24
+ import type { TickXMarkProps } from './marks/TickX.svelte';
25
+ import type { VectorMarkProps } from './marks/Vector.svelte';
26
+ import type { BrushMarkProps } from './marks/Brush.svelte';
27
+ import type { BrushXMarkProps } from './marks/BrushX.svelte';
28
+ import type { BrushYMarkProps } from './marks/BrushY.svelte';
29
+ import type { RectXMarkProps } from './marks/RectX.svelte';
30
+ import type { RectYMarkProps } from './marks/RectY.svelte';
31
+ import type { RuleYMarkProps } from './marks/RuleY.svelte';
32
+ import type { TickYMarkProps } from './marks/TickY.svelte';
33
+ import type { GridYMarkProps } from './marks/GridY.svelte';
34
+ import type { GridXMarkProps } from './marks/GridX.svelte';
7
35
  export type MarkType = 'area' | 'arrow' | 'axisX' | 'axisY' | 'barX' | 'barY' | 'cell' | 'dot' | 'vector' | 'frame' | 'geo' | 'gridX' | 'gridY' | 'line' | 'rect' | 'regression' | 'ruleX' | 'ruleY' | 'swoopyArrow' | 'text' | 'tickX' | 'tickY';
8
36
  export type ScaleName = 'x' | 'y' | 'r' | 'color' | 'opacity' | 'length' | 'symbol' | 'fx' | 'fy' | 'projection';
9
37
  export type ScaleType = 'linear' | 'pow' | 'sqrt' | 'log' | 'symlog' | 'time' | 'point' | 'ordinal' | 'sequential' | 'band' | 'categorical' | 'cyclical' | 'threshold' | 'quantile-cont' | 'quantile' | 'quantize' | 'diverging' | 'diverging-log' | 'diverging-pow' | 'diverging-sqrt' | 'diverging-symlog';
@@ -300,51 +328,6 @@ export type PlotOptions = {
300
328
  */
301
329
  css: (d: string) => string | undefined;
302
330
  };
303
- export type PlotDefaults = {
304
- axisXAnchor: AxisXAnchor;
305
- axisYAnchor: AxisYAnchor;
306
- xTickSpacing: number;
307
- yTickSpacing: number;
308
- height: number;
309
- inset: number;
310
- colorScheme: ColorScheme | string[];
311
- categoricalColorScheme: ColorScheme | string[];
312
- dotRadius: number;
313
- /**
314
- * for computing the automatic height based on the number of
315
- * domain items in a point scale
316
- */
317
- pointScaleHeight: number;
318
- /**
319
- * for computing the automatic height based on the number of
320
- * domain items in a band scale
321
- */
322
- bandScaleHeight: number;
323
- /**
324
- * add frame to plots by default
325
- */
326
- frame: boolean;
327
- grid: boolean;
328
- axes: boolean;
329
- /**
330
- * initial width of the plot before measuring the actual width
331
- */
332
- initialWidth: number;
333
- /**
334
- * locale, used for automatic axis ticks
335
- */
336
- locale: string;
337
- /**
338
- * default number format for axis ticks
339
- */
340
- numberFormat: Intl.NumberFormatOptions;
341
- markerDotRadius: number;
342
- /**
343
- * fallback color to be used for null/NA
344
- */
345
- unknown: string;
346
- css: (d: string) => string | undefined;
347
- };
348
331
  export type GenericMarkOptions = Record<string | symbol, any>;
349
332
  export type DataRecord = Record<string | symbol, RawValue> & {
350
333
  ___orig___?: RawValue | [RawValue, RawValue];
@@ -492,27 +475,27 @@ export type LinkableMarkProps = {
492
475
  /**
493
476
  * if set, the mark element will be wrapped in a <a> link element
494
477
  */
495
- href: ConstantAccessor<string>;
478
+ href?: ConstantAccessor<string>;
496
479
  /**
497
480
  * the relationship of the target object to the link object (e.g. "noopener")
498
481
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#rel
499
482
  */
500
- rel: ConstantAccessor<string>;
483
+ rel?: ConstantAccessor<string>;
501
484
  /**
502
485
  * the link target mime type, e.g. "text/csv"
503
486
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#type
504
487
  */
505
- type: ConstantAccessor<string>;
488
+ type?: ConstantAccessor<string>;
506
489
  /**
507
490
  * the target of the link, e.g. "_blank" or "_self"
508
491
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#target
509
492
  */
510
- target: ConstantAccessor<'_self' | '_blank' | '_parent' | '_top' | string>;
493
+ target?: ConstantAccessor<'_self' | '_blank' | '_parent' | '_top' | string>;
511
494
  /**
512
495
  * if set to true, the link will be downloaded instead of navigating to it
513
496
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download
514
497
  */
515
- download: ConstantAccessor<boolean>;
498
+ download?: ConstantAccessor<boolean>;
516
499
  [key: `data-sveltekit-${string}`]: string | boolean;
517
500
  };
518
501
  export type BaseMarkProps = Partial<{
@@ -618,11 +601,12 @@ export type AutoMarginStores = {
618
601
  autoMarginRight: Writable<Map<string, number>>;
619
602
  autoMarginBottom: Writable<Map<string, number>>;
620
603
  };
604
+ type IgnoreDefaults = 'data' | 'facet' | ChannelName | 'title' | 'automatic';
621
605
  /**
622
606
  * these are the default options for the plot marks that can be set using
623
607
  * the 'svelteplot/defaults' context.
624
608
  */
625
- export type DefaultOptions = {
609
+ export type PlotDefaults = {
626
610
  /**
627
611
  * default plot height
628
612
  */
@@ -632,41 +616,32 @@ export type DefaultOptions = {
632
616
  */
633
617
  inset: number;
634
618
  /**
635
- * default tick line length
636
- */
637
- tickSize: number;
638
- /**
639
- * default padding between tick line and tick label
640
- */
641
- tickPadding: number;
642
- /**
643
- * default font size for tick labels
644
- */
645
- tickFontSize: number;
646
- /**
647
- * default anchor for x axis
619
+ * default color scheme
648
620
  */
649
- axisXAnchor: 'bottom' | 'top';
621
+ colorScheme: ColorScheme;
622
+ categoricalColorScheme: ColorScheme | string[];
650
623
  /**
651
- * default anchor for y axis
624
+ * fallback color to be used for null/NA
652
625
  */
653
- axisYAnchor: 'left' | 'right';
626
+ unknown: string;
654
627
  /**
655
- * default spacing between ticks in AxisX and GridX
628
+ * optional @emotion/css function to style the plot
656
629
  */
657
- xTickSpacing: number;
630
+ css: (d: string) => string | undefined;
658
631
  /**
659
- * default spacing between ticks in AxisY and GridY
632
+ * for computing the automatic height based on the number of
633
+ * domain items in a point scale
660
634
  */
661
- yTickSpacing: number;
635
+ pointScaleHeight: number;
662
636
  /**
663
- * default color scheme
637
+ * for computing the automatic height based on the number of
638
+ * domain items in a band scale
664
639
  */
665
- colorScheme: ColorScheme;
640
+ bandScaleHeight: number;
666
641
  /**
667
- * default step for graticule, in degrees
642
+ * initial width of the plot before measuring the actual width
668
643
  */
669
- graticuleStep: number;
644
+ initialWidth: number;
670
645
  /**
671
646
  * locale, used for automatic axis ticks
672
647
  */
@@ -679,6 +654,164 @@ export type DefaultOptions = {
679
654
  * default dot radius for line markers, used in dot, circle, and circle-stroke markers
680
655
  */
681
656
  markerDotRadius: number;
657
+ /**
658
+ * default props for area marks, applied to area, areaX, and areaY marks
659
+ */
660
+ area: Partial<Omit<AreaMarkProps, IgnoreDefaults>>;
661
+ /**
662
+ * default props for areaX marks
663
+ */
664
+ areaX: Partial<Omit<AreaMarkProps, IgnoreDefaults>>;
665
+ /**
666
+ * default props for areaY marks
667
+ */
668
+ areaY: Partial<Omit<AreaMarkProps, IgnoreDefaults>>;
669
+ /**
670
+ * default props for arrow marks
671
+ */
672
+ arrow: Partial<Omit<ArrowMarkProps, IgnoreDefaults>>;
673
+ /**
674
+ * default props for axis marks, applied to both axisX and axisY marks
675
+ */
676
+ axis: Partial<Omit<AxisXMarkProps, 'data' | 'facet' | ChannelName | 'facetAnchor' | 'labelAnchor' | 'anchor'> & {
677
+ implicit: boolean;
678
+ }>;
679
+ /**
680
+ * default props for axisX marks
681
+ */
682
+ axisX: Partial<Omit<AxisXMarkProps, IgnoreDefaults> & {
683
+ implicit: boolean;
684
+ }>;
685
+ /**
686
+ * default props for axisY marks
687
+ */
688
+ axisY: Partial<Omit<AxisYMarkProps, IgnoreDefaults> & {
689
+ implicit: boolean;
690
+ }>;
691
+ /**
692
+ * default props for bar marks, applied to both barX and barY marks
693
+ */
694
+ bar: Partial<Omit<BarXMarkProps, IgnoreDefaults>>;
695
+ /**
696
+ * default props for barX marks
697
+ */
698
+ barX: Partial<Omit<BarXMarkProps, IgnoreDefaults>>;
699
+ /**
700
+ * default props for barY marks
701
+ */
702
+ barY: Partial<Omit<BarXMarkProps, IgnoreDefaults>>;
703
+ /**
704
+ * default props for brush marks, applied to brush, brushX and brushY marks
705
+ */
706
+ brush: Partial<Omit<BrushMarkProps, IgnoreDefaults | 'limitDimension'>>;
707
+ /**
708
+ * default props for brushX marks
709
+ */
710
+ brushX: Partial<Omit<BrushXMarkProps, IgnoreDefaults>>;
711
+ /**
712
+ * default props for brushY marks
713
+ */
714
+ brushY: Partial<Omit<BrushYMarkProps, IgnoreDefaults>>;
715
+ /**
716
+ * default props for cell marks
717
+ */
718
+ cell: Partial<Omit<CellMarkProps, IgnoreDefaults>>;
719
+ /**
720
+ * default props for dot marks
721
+ */
722
+ dot: Partial<Omit<DotMarkProps, IgnoreDefaults>>;
723
+ /**
724
+ * default props for frame marks
725
+ */
726
+ frame: Partial<FrameMarkProps & {
727
+ implicit: boolean;
728
+ }>;
729
+ /**
730
+ * default props for geo marks
731
+ */
732
+ geo: Partial<Omit<GeoMarkProps, IgnoreDefaults>>;
733
+ /**
734
+ * default props for graticule marks
735
+ */
736
+ graticule: Partial<Omit<GraticuleMarkProps, IgnoreDefaults>>;
737
+ /**
738
+ * default props for grid marks, applied to both gridX and gridY marks
739
+ */
740
+ grid: Partial<Omit<GridXMarkProps, IgnoreDefaults> & {
741
+ implicit: boolean;
742
+ }>;
743
+ /**
744
+ * default props for gridX marks
745
+ */
746
+ gridX: Partial<Omit<GridXMarkProps, IgnoreDefaults> & {
747
+ implicit: boolean;
748
+ }>;
749
+ /**
750
+ * default props for gridY marks
751
+ */
752
+ gridY: Partial<Omit<GridYMarkProps, IgnoreDefaults> & {
753
+ implicit: boolean;
754
+ }>;
755
+ /**
756
+ * default props for line marks
757
+ */
758
+ line: Partial<Omit<LineMarkProps, IgnoreDefaults>>;
759
+ /**
760
+ * default props for link marks
761
+ */
762
+ link: Partial<Omit<LinkMarkProps, IgnoreDefaults>>;
763
+ /**
764
+ * default props for rect marks, applied to rect and rectX marks
765
+ */
766
+ rect: Partial<Omit<RectMarkProps, IgnoreDefaults>>;
767
+ /**
768
+ * default props for rectX marks
769
+ */
770
+ rectX: Partial<Omit<RectXMarkProps, IgnoreDefaults>>;
771
+ /**
772
+ * default props for rectY marks
773
+ */
774
+ rectY: Partial<Omit<RectYMarkProps, IgnoreDefaults>>;
775
+ /**
776
+ * default props for rule marks
777
+ */
778
+ rule: Partial<Omit<RuleXMarkProps, IgnoreDefaults>>;
779
+ /**
780
+ * default props for rule marks
781
+ */
782
+ ruleX: Partial<Omit<RuleXMarkProps, IgnoreDefaults>>;
783
+ /**
784
+ * default props for rule marks
785
+ */
786
+ ruleY: Partial<Omit<RuleYMarkProps, IgnoreDefaults>>;
787
+ /**
788
+ * default props for sphere marks
789
+ */
790
+ sphere: Partial<SphereMarkProps>;
791
+ /**
792
+ * default props for spike marks
793
+ */
794
+ spike: Partial<Omit<SpikeMarkProps, IgnoreDefaults>>;
795
+ /**
796
+ * default props for text marks
797
+ */
798
+ text: Partial<Omit<TextMarkProps, IgnoreDefaults>>;
799
+ /**
800
+ * default props for tick marks, applied to tickX and tickY marks
801
+ */
802
+ tick: Partial<Omit<TickXMarkProps, IgnoreDefaults>>;
803
+ /**
804
+ * default props for tickX marks
805
+ */
806
+ tickX: Partial<Omit<TickXMarkProps, IgnoreDefaults>>;
807
+ /**
808
+ * default props for tickY marks
809
+ */
810
+ tickY: Partial<Omit<TickYMarkProps, IgnoreDefaults>>;
811
+ /**
812
+ * default props for vector marks
813
+ */
814
+ vector: Partial<Omit<VectorMarkProps, IgnoreDefaults>>;
682
815
  };
683
816
  export type MapIndexObject = {
684
817
  mapIndex: (I: number[], S: RawValue[], T: RawValue[]) => void;
@@ -36,7 +36,7 @@
36
36
  border: 1px solid #88888822;
37
37
  border-radius: 2px;
38
38
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
39
- padding: 1.5ex;
39
+ padding: 1.5ex 1.5ex 0.4ex 1.5ex;
40
40
  }
41
41
 
42
42
  &:hover {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.2.9-pr-109.1",
3
+ "version": "0.2.10-pr-110.0",
4
4
  "license": "ISC",
5
5
  "author": {
6
6
  "name": "Gregor Aisch",