layerchart 0.53.0 → 0.54.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 (34) hide show
  1. package/dist/components/Axis.svelte +51 -94
  2. package/dist/components/Axis.svelte.d.ts +2 -1
  3. package/dist/components/Bars.svelte +2 -1
  4. package/dist/components/Bars.svelte.d.ts +1 -0
  5. package/dist/components/Chart.svelte +6 -4
  6. package/dist/components/Chart.svelte.d.ts +25 -8
  7. package/dist/components/ChartContext.svelte +1 -1
  8. package/dist/components/ChartContext.svelte.d.ts +1 -1
  9. package/dist/components/Grid.svelte +151 -0
  10. package/dist/components/Grid.svelte.d.ts +35 -0
  11. package/dist/components/Labels.svelte +15 -5
  12. package/dist/components/Labels.svelte.d.ts +2 -0
  13. package/dist/components/Legend.svelte +1 -1
  14. package/dist/components/Rule.svelte +20 -4
  15. package/dist/components/Rule.svelte.d.ts +2 -0
  16. package/dist/components/TransformContext.svelte +3 -1
  17. package/dist/components/charts/AreaChart.svelte +59 -35
  18. package/dist/components/charts/AreaChart.svelte.d.ts +40 -2
  19. package/dist/components/charts/BarChart.svelte +63 -29
  20. package/dist/components/charts/BarChart.svelte.d.ts +40 -2
  21. package/dist/components/charts/LineChart.svelte +44 -16
  22. package/dist/components/charts/LineChart.svelte.d.ts +40 -2
  23. package/dist/components/charts/PieChart.svelte +15 -1
  24. package/dist/components/charts/PieChart.svelte.d.ts +16 -1
  25. package/dist/components/charts/ScatterChart.svelte +31 -16
  26. package/dist/components/charts/ScatterChart.svelte.d.ts +38 -2
  27. package/dist/components/index.d.ts +1 -0
  28. package/dist/components/index.js +1 -0
  29. package/dist/components/tooltip/Tooltip.svelte +20 -5
  30. package/dist/components/tooltip/TooltipContext.svelte +2 -1
  31. package/dist/components/tooltip/TooltipContext.svelte.d.ts +7 -0
  32. package/dist/docs/Preview.svelte +24 -11
  33. package/dist/utils/scales.d.ts +1 -1
  34. package/package.json +1 -1
@@ -3,6 +3,7 @@ import { scaleLinear, scaleOrdinal, scaleTime } from 'd3-scale';
3
3
  import { format } from '@layerstack/utils';
4
4
  import Axis from '../Axis.svelte';
5
5
  import Chart from '../Chart.svelte';
6
+ import Grid from '../Grid.svelte';
6
7
  import Highlight from '../Highlight.svelte';
7
8
  import Labels from '../Labels.svelte';
8
9
  import Legend from '../Legend.svelte';
@@ -18,8 +19,10 @@ export let y = undefined;
18
19
  /** Use radial instead of cartesian coordinates, mapping `x` to `angle` and `y`` to radial. Radial lines are positioned relative to the origin, use transform (ex. `<Group center>`) to change the origin */
19
20
  export let radial = false;
20
21
  export let series = [{ key: 'default', value: y, color: 'hsl(var(--color-primary))' }];
22
+ $: isDefaultSeries = series.length === 1 && series[0].key === 'default';
21
23
  export let axis = true;
22
24
  export let rule = true;
25
+ export let grid = true;
23
26
  export let labels = false;
24
27
  export let legend = false;
25
28
  export let points = false;
@@ -30,6 +33,17 @@ $: allSeriesData = series
30
33
  $: chartData = (allSeriesData.length ? allSeriesData : chartDataArray(data));
31
34
  // Default xScale based on first data's `x` value
32
35
  $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear();
36
+ function getSplineProps(s, i) {
37
+ const splineProps = {
38
+ data: s.data,
39
+ y: s.value ?? (s.data ? undefined : s.key),
40
+ class: 'stroke-2',
41
+ stroke: s.color,
42
+ ...props.spline,
43
+ ...s.props,
44
+ };
45
+ return splineProps;
46
+ }
33
47
  </script>
34
48
 
35
49
  <Chart
@@ -52,20 +66,40 @@ $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinea
52
66
  let:xScale
53
67
  let:y
54
68
  let:yScale
69
+ let:c
70
+ let:cScale
55
71
  let:width
56
72
  let:height
57
73
  let:padding
58
74
  let:tooltip
59
75
  >
60
- {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }}
76
+ {@const slotProps = {
77
+ x,
78
+ xScale,
79
+ y,
80
+ yScale,
81
+ c,
82
+ cScale,
83
+ width,
84
+ height,
85
+ padding,
86
+ tooltip,
87
+ series,
88
+ getSplineProps,
89
+ }}
61
90
  <slot {...slotProps}>
62
91
  <Svg center={radial}>
92
+ <slot name="grid" {...slotProps}>
93
+ {#if grid}
94
+ <Grid x={radial} y {...typeof grid === 'object' ? grid : null} {...props.grid} />
95
+ {/if}
96
+ </slot>
97
+
63
98
  <slot name="axis" {...slotProps}>
64
99
  {#if axis}
65
100
  {#if axis !== 'x'}
66
101
  <Axis
67
102
  placement={radial ? 'radius' : 'left'}
68
- grid
69
103
  format={(value) => format(value, undefined, { variant: 'short' })}
70
104
  {...typeof axis === 'object' ? axis : null}
71
105
  {...props.yAxis}
@@ -75,7 +109,6 @@ $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinea
75
109
  {#if axis !== 'y'}
76
110
  <Axis
77
111
  placement={radial ? 'angle' : 'bottom'}
78
- grid={radial}
79
112
  format={(value) => format(value, undefined, { variant: 'short' })}
80
113
  {...typeof axis === 'object' ? axis : null}
81
114
  {...props.xAxis}
@@ -91,15 +124,8 @@ $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinea
91
124
  <slot name="below-marks" {...slotProps} />
92
125
 
93
126
  <slot name="marks" {...slotProps}>
94
- {#each series as s}
95
- <Spline
96
- data={s.data}
97
- y={s.value ?? (s.data ? undefined : s.key)}
98
- class="stroke-2"
99
- stroke={s.color}
100
- {...props.spline}
101
- {...s.props}
102
- />
127
+ {#each series as s, i}
128
+ <Spline {...getSplineProps(s, i)} />
103
129
  {/each}
104
130
  </slot>
105
131
 
@@ -137,10 +163,12 @@ $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinea
137
163
  <slot name="legend" {...slotProps}>
138
164
  {#if legend}
139
165
  <Legend
140
- scale={scaleOrdinal(
141
- series.map((s) => s.label ?? s.key),
142
- series.map((s) => s.color)
143
- )}
166
+ scale={isDefaultSeries
167
+ ? undefined
168
+ : scaleOrdinal(
169
+ series.map((s) => s.label ?? s.key),
170
+ series.map((s) => s.color)
171
+ )}
144
172
  placement="bottom"
145
173
  variant="swatches"
146
174
  {...props.legend}
@@ -1,6 +1,7 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import { type ComponentProps } from 'svelte';
3
3
  import Axis from '../Axis.svelte';
4
+ import Grid from '../Grid.svelte';
4
5
  import Highlight from '../Highlight.svelte';
5
6
  import Labels from '../Labels.svelte';
6
7
  import Legend from '../Legend.svelte';
@@ -76,7 +77,7 @@ declare class __sveltets_Render<TData> {
76
77
  width: number;
77
78
  height: number;
78
79
  }) => number[] | string[]) | undefined;
79
- cRange?: string[];
80
+ cRange?: string[] | readonly string[];
80
81
  xReverse?: boolean;
81
82
  yReverse?: boolean;
82
83
  zReverse?: boolean;
@@ -131,6 +132,13 @@ declare class __sveltets_Render<TData> {
131
132
  onClick?: ({ data }: {
132
133
  data: any;
133
134
  }) => any;
135
+ tooltip?: import("svelte/store").Writable<{
136
+ y: number;
137
+ x: number;
138
+ data: any;
139
+ show: (e: PointerEvent, tooltipData?: any) => void;
140
+ hide: () => void;
141
+ }>;
134
142
  }> | undefined;
135
143
  transform?: Partial<{
136
144
  mode?: "canvas" | "manual" | "none";
@@ -179,6 +187,14 @@ declare class __sveltets_Render<TData> {
179
187
  setScale?: (value: number, options?: import("../../stores/motionStore").MotionOptions) => void;
180
188
  }> | undefined;
181
189
  transformContext?: import("..").TransformContext;
190
+ geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
191
+ tooltipContext?: import("svelte/store").Writable<{
192
+ y: number;
193
+ x: number;
194
+ data: any;
195
+ show: (e: PointerEvent, tooltipData?: any) => void;
196
+ hide: () => void;
197
+ }> | undefined;
182
198
  } & {
183
199
  axis?: boolean | "x" | "y" | {
184
200
  [x: string]: any;
@@ -186,7 +202,7 @@ declare class __sveltets_Render<TData> {
186
202
  label?: string | undefined;
187
203
  labelPlacement?: ("start" | "middle" | "end") | undefined;
188
204
  labelProps?: Partial<ComponentProps<import("..").Text>> | undefined;
189
- rule?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
205
+ rule?: (boolean | Partial<ComponentProps<Rule>>) | undefined;
190
206
  grid?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
191
207
  ticks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
192
208
  tickLength?: number | undefined;
@@ -202,8 +218,26 @@ declare class __sveltets_Render<TData> {
202
218
  label?: string;
203
219
  } | undefined;
204
220
  };
221
+ grid?: boolean | {
222
+ [x: string]: any;
223
+ x?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
224
+ y?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
225
+ xTicks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
226
+ yTicks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
227
+ bandAlign?: ("center" | "between") | undefined;
228
+ radialY?: ("circle" | "linear") | undefined;
229
+ spring?: boolean | Parameters<typeof import("svelte/motion").spring>[1];
230
+ tweened?: boolean | Parameters<typeof import("svelte/motion").tweened>[1];
231
+ transitionIn?: (typeof import("svelte/transition").fade | (() => {})) | undefined;
232
+ transitionInParams?: import("svelte-ux").TransitionParams | undefined;
233
+ classes?: {
234
+ root?: string;
235
+ line?: string;
236
+ } | undefined;
237
+ };
205
238
  labels?: boolean | {
206
239
  [x: string]: any;
240
+ value?: Accessor;
207
241
  placement?: ("inside" | "outside" | "center") | undefined;
208
242
  offset?: number | undefined;
209
243
  format?: import("@layerstack/utils").FormatType | undefined;
@@ -247,6 +281,7 @@ declare class __sveltets_Render<TData> {
247
281
  props?: {
248
282
  xAxis?: Partial<ComponentProps<Axis>>;
249
283
  yAxis?: Partial<ComponentProps<Axis>>;
284
+ grid?: Partial<ComponentProps<Grid>>;
250
285
  rule?: Partial<ComponentProps<Rule>>;
251
286
  spline?: Partial<ComponentProps<Spline>>;
252
287
  legend?: Partial<ComponentProps<Legend>>;
@@ -257,7 +292,9 @@ declare class __sveltets_Render<TData> {
257
292
  rule?: boolean | {
258
293
  [x: string]: any;
259
294
  x?: (number | Date | boolean | "left" | "right") | undefined;
295
+ xOffset?: number | undefined;
260
296
  y?: (number | Date | boolean | "top" | "bottom") | undefined;
297
+ yOffset?: number | undefined;
261
298
  };
262
299
  series?: {
263
300
  key: string | number;
@@ -274,6 +311,7 @@ declare class __sveltets_Render<TData> {
274
311
  };
275
312
  slots(): {
276
313
  default: any;
314
+ grid: any;
277
315
  axis: any;
278
316
  'below-marks': any;
279
317
  marks: any;
@@ -77,7 +77,21 @@ $: seriesColors = series.map((s) => s.color).filter((d) => d != null);
77
77
  let:padding
78
78
  let:tooltip
79
79
  >
80
- {@const slotProps = { key, label, value, x, xScale, y, yScale, width, height, padding, tooltip }}
80
+ {@const slotProps = {
81
+ key,
82
+ label,
83
+ value,
84
+ x,
85
+ xScale,
86
+ y,
87
+ yScale,
88
+ c,
89
+ cScale,
90
+ width,
91
+ height,
92
+ padding,
93
+ tooltip,
94
+ }}
81
95
  <slot {...slotProps}>
82
96
  <Svg center>
83
97
  <slot name="below-marks" {...slotProps} />
@@ -73,7 +73,7 @@ declare class __sveltets_Render<TData> {
73
73
  width: number;
74
74
  height: number;
75
75
  }) => number[] | string[]) | undefined;
76
- cRange?: string[];
76
+ cRange?: string[] | readonly string[];
77
77
  xReverse?: boolean;
78
78
  yReverse?: boolean;
79
79
  zReverse?: boolean;
@@ -128,6 +128,13 @@ declare class __sveltets_Render<TData> {
128
128
  onClick?: ({ data }: {
129
129
  data: any;
130
130
  }) => any;
131
+ tooltip?: import("svelte/store").Writable<{
132
+ y: number;
133
+ x: number;
134
+ data: any;
135
+ show: (e: PointerEvent, tooltipData?: any) => void;
136
+ hide: () => void;
137
+ }>;
131
138
  }> | undefined;
132
139
  transform?: Partial<{
133
140
  mode?: "canvas" | "manual" | "none";
@@ -176,6 +183,14 @@ declare class __sveltets_Render<TData> {
176
183
  setScale?: (value: number, options?: import("../../stores/motionStore").MotionOptions) => void;
177
184
  }> | undefined;
178
185
  transformContext?: import("..").TransformContext;
186
+ geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
187
+ tooltipContext?: import("svelte/store").Writable<{
188
+ y: number;
189
+ x: number;
190
+ data: any;
191
+ show: (e: PointerEvent, tooltipData?: any) => void;
192
+ hide: () => void;
193
+ }> | undefined;
179
194
  } & {
180
195
  cornerRadius?: number;
181
196
  innerRadius?: number | undefined;
@@ -3,6 +3,7 @@ import { scaleLinear, scaleOrdinal, scaleTime } from 'd3-scale';
3
3
  import { format } from '@layerstack/utils';
4
4
  import Axis from '../Axis.svelte';
5
5
  import Chart from '../Chart.svelte';
6
+ import Grid from '../Grid.svelte';
6
7
  import Highlight from '../Highlight.svelte';
7
8
  import Labels from '../Labels.svelte';
8
9
  import Legend from '../Legend.svelte';
@@ -15,7 +16,9 @@ export let data = [];
15
16
  export let x = undefined;
16
17
  export let y = undefined;
17
18
  export let series = [{ key: 'default', data: chartDataArray(data), color: 'hsl(var(--color-primary))' }];
19
+ $: isDefaultSeries = series.length === 1 && series[0].key === 'default';
18
20
  export let axis = true;
21
+ export let grid = true;
19
22
  export let labels = false;
20
23
  export let legend = false;
21
24
  export let rule = true;
@@ -25,6 +28,17 @@ $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() :
25
28
  let chartData = series
26
29
  .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
27
30
  .filter((d) => d);
31
+ function getPointsProps(s, i) {
32
+ const pointsProps = {
33
+ data: s.data,
34
+ stroke: s.color,
35
+ fill: s.color,
36
+ 'fill-opacity': 0.3,
37
+ ...props.points,
38
+ ...s.props,
39
+ };
40
+ return pointsProps;
41
+ }
28
42
  </script>
29
43
 
30
44
  <Chart
@@ -45,6 +59,8 @@ let chartData = series
45
59
  let:xScale
46
60
  let:y
47
61
  let:yScale
62
+ let:c
63
+ let:cScale
48
64
  let:r
49
65
  let:width
50
66
  let:height
@@ -52,19 +68,24 @@ let chartData = series
52
68
  let:tooltip
53
69
  let:config
54
70
  >
55
- {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }}
71
+ {@const slotProps = { x, xScale, y, yScale, c, cScale, width, height, padding, tooltip, series }}
56
72
  {@const activeSeries = tooltip.data
57
73
  ? (series.find((s) => s.key === tooltip.data.seriesKey) ?? series[0])
58
74
  : null}
59
75
 
60
76
  <slot {...slotProps}>
61
77
  <Svg>
78
+ <slot name="grid" {...slotProps}>
79
+ {#if grid}
80
+ <Grid x y {...typeof grid === 'object' ? grid : null} {...props.grid} />
81
+ {/if}
82
+ </slot>
83
+
62
84
  <slot name="axis" {...slotProps}>
63
85
  {#if axis}
64
86
  {#if axis !== 'x'}
65
87
  <Axis
66
88
  placement="left"
67
- grid
68
89
  format={(value) => format(value, undefined, { variant: 'short' })}
69
90
  {...typeof axis === 'object' ? axis : null}
70
91
  {...props.yAxis}
@@ -74,7 +95,6 @@ let chartData = series
74
95
  {#if axis !== 'y'}
75
96
  <Axis
76
97
  placement="bottom"
77
- grid
78
98
  format={(value) => format(value, undefined, { variant: 'short' })}
79
99
  {...typeof axis === 'object' ? axis : null}
80
100
  {...props.xAxis}
@@ -90,15 +110,8 @@ let chartData = series
90
110
  <slot name="below-marks" {...slotProps} />
91
111
 
92
112
  <slot name="marks" {...slotProps}>
93
- {#each series as s}
94
- <Points
95
- data={s.data}
96
- stroke={s.color}
97
- fill={s.color}
98
- fill-opacity={0.3}
99
- {...props.points}
100
- {...s.props}
101
- />
113
+ {#each series as s, i}
114
+ <Points {...getPointsProps(s, i)} />
102
115
  {/each}
103
116
  </slot>
104
117
 
@@ -120,10 +133,12 @@ let chartData = series
120
133
  <slot name="legend" {...slotProps}>
121
134
  {#if legend}
122
135
  <Legend
123
- scale={scaleOrdinal(
124
- series.map((s) => s.label ?? s.key),
125
- series.map((s) => s.color)
126
- )}
136
+ scale={isDefaultSeries
137
+ ? undefined
138
+ : scaleOrdinal(
139
+ series.map((s) => s.label ?? s.key),
140
+ series.map((s) => s.color)
141
+ )}
127
142
  placement="bottom"
128
143
  variant="swatches"
129
144
  {...props.legend}
@@ -1,6 +1,7 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import { type ComponentProps } from 'svelte';
3
3
  import Axis from '../Axis.svelte';
4
+ import Grid from '../Grid.svelte';
4
5
  import Highlight from '../Highlight.svelte';
5
6
  import Labels from '../Labels.svelte';
6
7
  import Legend from '../Legend.svelte';
@@ -75,7 +76,7 @@ declare class __sveltets_Render<TData> {
75
76
  width: number;
76
77
  height: number;
77
78
  }) => number[] | string[]) | undefined;
78
- cRange?: string[];
79
+ cRange?: string[] | readonly string[];
79
80
  xReverse?: boolean;
80
81
  yReverse?: boolean;
81
82
  zReverse?: boolean;
@@ -130,6 +131,13 @@ declare class __sveltets_Render<TData> {
130
131
  onClick?: ({ data }: {
131
132
  data: any;
132
133
  }) => any;
134
+ tooltip?: import("svelte/store").Writable<{
135
+ y: number;
136
+ x: number;
137
+ data: any;
138
+ show: (e: PointerEvent, tooltipData?: any) => void;
139
+ hide: () => void;
140
+ }>;
133
141
  }> | undefined;
134
142
  transform?: Partial<{
135
143
  mode?: "canvas" | "manual" | "none";
@@ -178,6 +186,14 @@ declare class __sveltets_Render<TData> {
178
186
  setScale?: (value: number, options?: import("../../stores/motionStore").MotionOptions) => void;
179
187
  }> | undefined;
180
188
  transformContext?: import("..").TransformContext;
189
+ geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
190
+ tooltipContext?: import("svelte/store").Writable<{
191
+ y: number;
192
+ x: number;
193
+ data: any;
194
+ show: (e: PointerEvent, tooltipData?: any) => void;
195
+ hide: () => void;
196
+ }> | undefined;
181
197
  } & {
182
198
  axis?: boolean | "x" | "y" | {
183
199
  [x: string]: any;
@@ -185,7 +201,7 @@ declare class __sveltets_Render<TData> {
185
201
  label?: string | undefined;
186
202
  labelPlacement?: ("start" | "middle" | "end") | undefined;
187
203
  labelProps?: Partial<ComponentProps<import("..").Text>> | undefined;
188
- rule?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
204
+ rule?: (boolean | Partial<ComponentProps<Rule>>) | undefined;
189
205
  grid?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
190
206
  ticks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
191
207
  tickLength?: number | undefined;
@@ -201,8 +217,26 @@ declare class __sveltets_Render<TData> {
201
217
  label?: string;
202
218
  } | undefined;
203
219
  };
220
+ grid?: boolean | {
221
+ [x: string]: any;
222
+ x?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
223
+ y?: (boolean | Pick<import("svelte/elements").SVGAttributes<SVGElement>, "class" | "style">) | undefined;
224
+ xTicks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
225
+ yTicks?: number | any[] | ((scale: import("../../utils/scales").AnyScale) => any) | null | undefined;
226
+ bandAlign?: ("center" | "between") | undefined;
227
+ radialY?: ("circle" | "linear") | undefined;
228
+ spring?: boolean | Parameters<typeof import("svelte/motion").spring>[1];
229
+ tweened?: boolean | Parameters<typeof import("svelte/motion").tweened>[1];
230
+ transitionIn?: (typeof import("svelte/transition").fade | (() => {})) | undefined;
231
+ transitionInParams?: import("svelte-ux").TransitionParams | undefined;
232
+ classes?: {
233
+ root?: string;
234
+ line?: string;
235
+ } | undefined;
236
+ };
204
237
  labels?: boolean | {
205
238
  [x: string]: any;
239
+ value?: Accessor;
206
240
  placement?: ("inside" | "outside" | "center") | undefined;
207
241
  offset?: number | undefined;
208
242
  format?: import("@layerstack/utils").FormatType | undefined;
@@ -233,6 +267,7 @@ declare class __sveltets_Render<TData> {
233
267
  props?: {
234
268
  xAxis?: Partial<ComponentProps<Axis>>;
235
269
  yAxis?: Partial<ComponentProps<Axis>>;
270
+ grid?: Partial<ComponentProps<Grid>>;
236
271
  points?: Partial<ComponentProps<Points>>;
237
272
  highlight?: Partial<ComponentProps<Highlight>>;
238
273
  labels?: Partial<ComponentProps<Labels>>;
@@ -252,6 +287,7 @@ declare class __sveltets_Render<TData> {
252
287
  };
253
288
  slots(): {
254
289
  default: any;
290
+ grid: any;
255
291
  axis: any;
256
292
  'below-marks': any;
257
293
  marks: any;
@@ -27,6 +27,7 @@ export { default as GeoSpline } from './GeoSpline.svelte';
27
27
  export { default as GeoTile } from './GeoTile.svelte';
28
28
  export { default as GeoVisible } from './GeoVisible.svelte';
29
29
  export { default as Graticule } from './Graticule.svelte';
30
+ export { default as Grid } from './Grid.svelte';
30
31
  export { default as Group } from './Group.svelte';
31
32
  export { default as Highlight } from './Highlight.svelte';
32
33
  export { default as HitCanvas } from './HitCanvas.svelte';
@@ -28,6 +28,7 @@ export { default as GeoSpline } from './GeoSpline.svelte';
28
28
  export { default as GeoTile } from './GeoTile.svelte';
29
29
  export { default as GeoVisible } from './GeoVisible.svelte';
30
30
  export { default as Graticule } from './Graticule.svelte';
31
+ export { default as Grid } from './Grid.svelte';
31
32
  export { default as Group } from './Group.svelte';
32
33
  export { default as Highlight } from './Highlight.svelte';
33
34
  export { default as HitCanvas } from './HitCanvas.svelte';
@@ -3,21 +3,22 @@ import { cls } from '@layerstack/tailwind';
3
3
  import { chartContext } from './../ChartContext.svelte';
4
4
  import { tooltipContext } from './TooltipContext.svelte';
5
5
  import { motionStore } from '../../stores/motionStore.js';
6
+ import { isScaleBand } from '../../utils/scales.js';
6
7
  /** `x` position of tooltip. By default uses the pointer/mouse, can also snap to data or an explicit fixed position. */
7
8
  export let x = 'pointer';
8
9
  /** `y` position of tooltip. By default uses the pointer/mouse, can also snap to data or an explicit fixed position. */
9
10
  export let y = 'pointer';
10
11
  /** Offset added to `x` position */
11
- export let xOffset = typeof x === 'number' || typeof y === 'number' ? 0 : 10;
12
+ export let xOffset = x === 'pointer' ? 10 : 0;
12
13
  /** Offset added to `y` position */
13
- export let yOffset = typeof x === 'number' || typeof y === 'number' ? 0 : 10;
14
+ export let yOffset = y === 'pointer' ? 10 : 0;
14
15
  export let anchor = 'top-left';
15
16
  export let contained = 'container'; // TODO: Support 'window' using getBoundingClientRect()
16
17
  export let variant = 'default';
17
18
  /** Set to `false` to disable spring transitions */
18
19
  export let motion = true;
19
20
  export let classes = {};
20
- const { padding, xGet, yGet, containerWidth, containerHeight } = chartContext();
21
+ const { padding, xScale, xGet, yScale, yGet, containerWidth, containerHeight } = chartContext();
21
22
  const tooltip = tooltipContext();
22
23
  let tooltipWidth = 0;
23
24
  let tooltipHeight = 0;
@@ -28,7 +29,14 @@ function alignValue(value, align, addlOffset, tooltipSize) {
28
29
  return value + (align === 'end' ? -addlOffset : addlOffset) - alignOffset;
29
30
  }
30
31
  $: if ($tooltip?.data) {
31
- const xValue = typeof x === 'number' ? x : x === 'data' ? $xGet($tooltip.data) + $padding.left : $tooltip.x;
32
+ const xBandOffset = isScaleBand($xScale)
33
+ ? $xScale.step() / 2 - ($xScale.padding() * $xScale.step()) / 2
34
+ : 0;
35
+ const xValue = typeof x === 'number'
36
+ ? x
37
+ : x === 'data'
38
+ ? $xGet($tooltip.data) + $padding.left + xBandOffset
39
+ : $tooltip.x;
32
40
  let xAlign = 'start';
33
41
  switch (anchor) {
34
42
  case 'top-left':
@@ -47,7 +55,14 @@ $: if ($tooltip?.data) {
47
55
  xAlign = 'end';
48
56
  break;
49
57
  }
50
- const yValue = typeof y === 'number' ? y : y === 'data' ? $yGet($tooltip.data) + $padding.top : $tooltip.y;
58
+ const yBandOffset = isScaleBand($yScale)
59
+ ? $yScale.step() / 2 - ($yScale.padding() * $yScale.step()) / 2
60
+ : 0;
61
+ const yValue = typeof y === 'number'
62
+ ? y
63
+ : y === 'data'
64
+ ? $yGet($tooltip.data) + $padding.top + yBandOffset
65
+ : $tooltip.y;
51
66
  let yAlign = 'start';
52
67
  switch (anchor) {
53
68
  case 'top-left':
@@ -57,7 +57,8 @@ export let radius = Infinity;
57
57
  /** Enable debug view (show hit targets, etc) */
58
58
  export let debug = false;
59
59
  export let onClick = () => { };
60
- const tooltip = writable({
60
+ /** Exposed to allow binding in Chart */
61
+ export let tooltip = writable({
61
62
  y: 0,
62
63
  x: 0,
63
64
  data: null,
@@ -26,6 +26,13 @@ declare const __propDef: {
26
26
  onClick?: ({ data }: {
27
27
  data: any;
28
28
  }) => any;
29
+ /** Exposed to allow binding in Chart */ tooltip?: import("svelte/store").Writable<{
30
+ y: number;
31
+ x: number;
32
+ data: any;
33
+ show: (e: PointerEvent, tooltipData?: any) => void;
34
+ hide: () => void;
35
+ }>;
29
36
  };
30
37
  events: {
31
38
  [evt: string]: CustomEvent<any>;
@@ -5,6 +5,8 @@ import 'prism-svelte';
5
5
  import { mdiCodeTags, mdiTable } from '@mdi/js';
6
6
  import { Button, CopyButton, Dialog, Toggle, Tooltip } from 'svelte-ux';
7
7
  import { cls } from '@layerstack/tailwind';
8
+ import { entries, fromEntries } from '@layerstack/utils';
9
+ import { isLiteralObject } from '@layerstack/utils/object';
8
10
  import Code from './Code.svelte';
9
11
  import Json from './Json.svelte';
10
12
  export let code = undefined;
@@ -12,13 +14,26 @@ export let data = undefined;
12
14
  export let language = 'svelte';
13
15
  export let highlightedCode = code ? Prism.highlight(code, Prism.languages.svelte, language) : '';
14
16
  export let showCode = false;
15
- let copyValue = null;
16
- try {
17
- // TODO: Improve handling of circular structures
18
- copyValue = JSON.stringify(data, null, 2);
17
+ /**
18
+ * Custom JSON replacer (to use with JSON.stringify()) to convert `Date` instances to `new Date()`
19
+ */
20
+ function replacer(key, value) {
21
+ // TODO: Improve handling of circular structures and handle other data types (Map, Set, etc)
22
+ if (this[key] instanceof Date) {
23
+ return `new Date('${this[key].toISOString()}')`;
24
+ }
25
+ return value;
19
26
  }
20
- catch (e) {
21
- console.error('Error capturing value to copy', e);
27
+ function getDataAsString(_data) {
28
+ try {
29
+ // Regular expression to match quoted instantiation (ex. `"new Date(...)"`) and stripe the quotes (`new Date(...)`)
30
+ const datePattern = /"(new \w+\([^)]*\))"/g;
31
+ return JSON.stringify(_data, replacer, 2).replace(datePattern, '$1');
32
+ }
33
+ catch (e) {
34
+ console.error('Error capturing value to copy', e);
35
+ return '';
36
+ }
22
37
  }
23
38
  </script>
24
39
 
@@ -58,11 +73,9 @@ catch (e) {
58
73
  <div class="text-lg font-semibold">Chart data</div>
59
74
  </div>
60
75
 
61
- {#if copyValue}
62
- <Tooltip title="Copy">
63
- <CopyButton value={copyValue} variant="fill-light" color="primary" />
64
- </Tooltip>
65
- {/if}
76
+ <Tooltip title="Copy">
77
+ <CopyButton value={() => getDataAsString(data)} variant="fill-light" color="primary" />
78
+ </Tooltip>
66
79
  </div>
67
80
 
68
81
  <Json value={data} />
@@ -32,7 +32,7 @@ export declare function isScaleBand(scale: AnyScale<any, any>): scale is ScaleBa
32
32
  */
33
33
  export declare function scaleInvert(scale: AnyScale<any, any>, value: number): any;
34
34
  /** Create new copy of scale with domain and range */
35
- export declare function createScale(scale: AnyScale, domain: DomainType, range: any[] | Function, context?: Record<any, any>): AnyScale<any, any, any, any>;
35
+ export declare function createScale(scale: AnyScale, domain: DomainType, range: any[] | readonly any[] | Function, context?: Record<any, any>): AnyScale<any, any, any, any>;
36
36
  /** Create a `scaleBand()` within another scaleBand()'s bandwidth (typically a x1 of an x0 scale, used for grouping) */
37
37
  export declare function groupScaleBand<Domain extends {
38
38
  toString(): string;