layerchart 0.71.3 → 0.72.1

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.
@@ -47,6 +47,9 @@
47
47
  export let spring: ComponentProps<Rect>['spring'] = undefined;
48
48
  export let tweened: ComponentProps<Rect>['tweened'] = undefined;
49
49
 
50
+ /** Event dispatched when individual Bar is clicked */
51
+ export let onBarClick: (e: { data: any }) => void = () => {};
52
+
50
53
  $: _data = chartDataArray(data ?? $contextData);
51
54
  </script>
52
55
 
@@ -66,6 +69,7 @@
66
69
  {inset}
67
70
  {spring}
68
71
  {tweened}
72
+ on:click={() => onBarClick({ data: d })}
69
73
  {...$$restProps}
70
74
  />
71
75
  {/each}
@@ -1,3 +1,7 @@
1
+ <script lang="ts" context="module">
2
+ export type HighlightPointData = { x: any; y: any };
3
+ </script>
4
+
1
5
  <script lang="ts">
2
6
  import { type ComponentProps } from 'svelte';
3
7
  import { max, min } from 'd3-array';
@@ -62,10 +66,14 @@
62
66
  /** Set to false to disable spring transitions */
63
67
  export let motion = true;
64
68
 
69
+ export let onAreaClick: (e: { data: any }) => void = () => {};
70
+ export let onBarClick: (e: { data: any }) => void = () => {};
71
+ export let onPointClick: (e: { point: (typeof _points)[number]; data: any }) => void = () => {};
72
+
65
73
  const _x = accessor(x);
66
74
  const _y = accessor(y);
67
75
 
68
- let _points: { x: number; y: number; fill: string }[] = [];
76
+ let _points: { x: number; y: number; fill: string; data: HighlightPointData }[] = [];
69
77
  let _lines: { x1: number; y1: number; x2: number; y2: number }[] = [];
70
78
  let _area = {
71
79
  x: 0,
@@ -217,6 +225,10 @@
217
225
  x: $xScale(seriesPoint.point[1]) + xOffset,
218
226
  y: yCoord + yOffset,
219
227
  fill: $config.c ? $cGet(seriesPoint.series) : null,
228
+ data: {
229
+ x: seriesPoint.point[1],
230
+ y: yValue,
231
+ },
220
232
  };
221
233
  });
222
234
  }
@@ -229,6 +241,10 @@
229
241
  y: yCoord + yOffset,
230
242
  // TODO: is there a better way to expose the series key/value?
231
243
  fill: $config.c ? $cGet({ ...highlightData, $key }) : null,
244
+ data: {
245
+ x: xValue, // TODO: use highlightData[$key]?
246
+ y: yValue,
247
+ },
232
248
  };
233
249
  });
234
250
  }
@@ -256,6 +272,10 @@
256
272
  x: xCoord + xOffset,
257
273
  y: $yScale(seriesPoint.point[1]) + yOffset,
258
274
  fill: $config.c ? $cGet(seriesPoint.series) : null,
275
+ data: {
276
+ x: xValue,
277
+ y: seriesPoint.point[1],
278
+ },
259
279
  }));
260
280
  }
261
281
  } else {
@@ -267,6 +287,10 @@
267
287
  y: yItem + yOffset,
268
288
  // TODO: is there a better way to expose the series key/value?
269
289
  fill: $config.c ? $cGet({ ...highlightData, $key }) : null,
290
+ data: {
291
+ x: xValue,
292
+ y: yValue, // TODO: use highlightData[$key] ?
293
+ },
270
294
  };
271
295
  });
272
296
  }
@@ -276,6 +300,10 @@
276
300
  x: xCoord + xOffset,
277
301
  y: yCoord + yOffset,
278
302
  fill: $config.c ? $cGet(highlightData) : null,
303
+ data: {
304
+ x: xValue,
305
+ y: yValue,
306
+ },
279
307
  },
280
308
  ];
281
309
  } else {
@@ -322,7 +350,7 @@
322
350
  !area.fill && 'fill-surface-content/5',
323
351
  typeof area === 'object' ? area.class : null
324
352
  )}
325
- on:click
353
+ on:click={() => onAreaClick({ data: highlightData })}
326
354
  />
327
355
  </slot>
328
356
  {/if}
@@ -343,7 +371,7 @@
343
371
  !bar.fill && 'fill-primary',
344
372
  typeof bar === 'object' ? bar.class : null
345
373
  )}
346
- on:click
374
+ on:click={() => onBarClick({ data: highlightData })}
347
375
  />
348
376
  </slot>
349
377
  {/if}
@@ -382,6 +410,7 @@
382
410
  !point.fill && (typeof points === 'boolean' || !points.fill) && 'fill-primary',
383
411
  typeof points === 'object' ? points.class : null
384
412
  )}
413
+ on:click={() => onPointClick({ point, data: highlightData })}
385
414
  />
386
415
  {/each}
387
416
  </slot>
@@ -10,7 +10,7 @@
10
10
  import Canvas from '../layout/Canvas.svelte';
11
11
  import Chart from '../Chart.svelte';
12
12
  import Grid from '../Grid.svelte';
13
- import Highlight from '../Highlight.svelte';
13
+ import Highlight, { type HighlightPointData } from '../Highlight.svelte';
14
14
  import Labels from '../Labels.svelte';
15
15
  import Legend from '../Legend.svelte';
16
16
  import Line from '../Line.svelte';
@@ -26,6 +26,7 @@
26
26
  findRelatedData,
27
27
  type Accessor,
28
28
  } from '../../utils/common.js';
29
+ import { asAny } from '../../utils/types.js';
29
30
 
30
31
  interface $$Props extends ComponentProps<Chart<TData>> {
31
32
  axis?: typeof axis;
@@ -38,6 +39,8 @@
38
39
  series?: typeof series;
39
40
  seriesLayout?: typeof seriesLayout;
40
41
  renderContext?: typeof renderContext;
42
+ onPointClick?: typeof onPointClick;
43
+ onTooltipClick?: typeof onTooltipClick;
41
44
  }
42
45
 
43
46
  export let data: $$Props['data'] = [];
@@ -69,6 +72,15 @@
69
72
  export let legend: ComponentProps<Legend> | boolean = false;
70
73
  export let points: ComponentProps<Points> | boolean = false;
71
74
 
75
+ /** Event dispatched with current tooltip data */
76
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
77
+
78
+ /** Event dispatched when Highlight point is clicked (useful with multiple series) */
79
+ export let onPointClick: (e: {
80
+ data: HighlightPointData;
81
+ series: (typeof series)[number];
82
+ }) => void = () => {};
83
+
72
84
  export let props: {
73
85
  xAxis?: Partial<ComponentProps<Axis>>;
74
86
  yAxis?: Partial<ComponentProps<Axis>>;
@@ -162,7 +174,7 @@
162
174
  yNice
163
175
  {radial}
164
176
  padding={radial ? undefined : defaultChartPadding(axis, legend)}
165
- tooltip={{ mode: 'bisect-x' }}
177
+ tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
166
178
  {...$$restProps}
167
179
  let:x
168
180
  let:xScale
@@ -262,6 +274,7 @@
262
274
  y={stackSeries ? (d) => d.stackData[i][1] : (s.value ?? (s.data ? undefined : s.key))}
263
275
  points={{ fill: s.color }}
264
276
  lines={i == 0}
277
+ onPointClick={(e) => onPointClick({ ...e, series: s })}
265
278
  {...props.highlight}
266
279
  />
267
280
  {/each}
@@ -297,7 +310,7 @@
297
310
  {@const seriesItems = stackSeries ? [...series].reverse() : series}
298
311
  {#each seriesItems as s}
299
312
  {@const seriesTooltipData = s.data ? findRelatedData(s.data, data, x) : data}
300
- {@const valueAccessor = accessor(s.value ?? (s.data ? (y as any) : s.key))}
313
+ {@const valueAccessor = accessor(s.value ?? (s.data ? asAny(y) : s.key))}
301
314
 
302
315
  <Tooltip.Item
303
316
  label={s.label ?? (s.key !== 'default' ? s.key : 'value')}
@@ -315,7 +328,7 @@
315
328
  label="total"
316
329
  value={sum(series, (s) => {
317
330
  const seriesTooltipData = s.data ? s.data.find((d) => x(d) === x(data)) : data;
318
- const valueAccessor = accessor(s.value ?? (s.data ? (y as any) : s.key));
331
+ const valueAccessor = accessor(s.value ?? (s.data ? asAny(y) : s.key));
319
332
 
320
333
  return valueAccessor(seriesTooltipData);
321
334
  })}
@@ -21,6 +21,7 @@
21
21
  accessor,
22
22
  chartDataArray,
23
23
  defaultChartPadding,
24
+ findRelatedData,
24
25
  type Accessor,
25
26
  } from '../../utils/common.js';
26
27
 
@@ -39,6 +40,8 @@
39
40
  series?: typeof series;
40
41
  seriesLayout?: typeof seriesLayout;
41
42
  renderContext?: typeof renderContext;
43
+ onBarClick?: typeof onBarClick;
44
+ onTooltipClick?: typeof onTooltipClick;
42
45
  }
43
46
 
44
47
  export let data: $$Props['data'] = [];
@@ -81,6 +84,13 @@
81
84
  /** Padding between group/series items when using 'seriesLayout="group"', applied to scaleBand().padding() */
82
85
  export let groupPadding = 0;
83
86
 
87
+ /** Event dispatched with current tooltip data */
88
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
89
+
90
+ // TODO: Need to find a way to have this play nice with `tooltip={{ mode: 'band' }}`
91
+ /** Event dispatched when individual Bar is clicked (useful with multiple series) */
92
+ export let onBarClick: (e: { data: any; series: (typeof series)[number] }) => void = () => {};
93
+
84
94
  $: xScale = $$props.xScale ?? (isVertical ? scaleBand().padding(bandPadding) : scaleLinear());
85
95
  $: xBaseline = isVertical ? undefined : 0;
86
96
 
@@ -172,6 +182,7 @@
172
182
  radius: 4,
173
183
  strokeWidth: 1,
174
184
  fill: s.color,
185
+ onBarClick: (e) => onBarClick({ data: e.data, series: s }),
175
186
  ...props.bars,
176
187
  ...s.props,
177
188
  };
@@ -205,7 +216,7 @@
205
216
  c={isVertical ? y : x}
206
217
  cRange={['hsl(var(--color-primary))']}
207
218
  padding={defaultChartPadding(axis, legend)}
208
- tooltip={{ mode: 'band' }}
219
+ tooltip={{ mode: 'band', onClick: onTooltipClick }}
209
220
  {...$$restProps}
210
221
  let:x
211
222
  let:xScale
@@ -331,10 +342,11 @@
331
342
  <!-- Reverse series order so tooltip items match stacks -->
332
343
  {@const seriesItems = stackSeries ? [...series].reverse() : series}
333
344
  {#each seriesItems as s}
334
- {@const valueAccessor = accessor(s.value ?? s.key)}
345
+ {@const seriesTooltipData = s.data ? findRelatedData(s.data, data, x) : data}
346
+ {@const valueAccessor = accessor(s.value ?? (s.data ? (y as any) : s.key))}
335
347
  <Tooltip.Item
336
348
  label={s.label ?? (s.key !== 'default' ? s.key : 'value')}
337
- value={valueAccessor(data)}
349
+ value={seriesTooltipData ? valueAccessor(seriesTooltipData) : null}
338
350
  color={s.color ?? cScale?.(c(data))}
339
351
  {format}
340
352
  valueAlign="right"
@@ -347,8 +359,9 @@
347
359
  <Tooltip.Item
348
360
  label="total"
349
361
  value={sum(series, (s) => {
350
- const valueAccessor = accessor(s.value ?? s.key);
351
- return valueAccessor(data);
362
+ const seriesTooltipData = s.data ? findRelatedData(s.data, data, x) : data;
363
+ const valueAccessor = accessor(s.value ?? (s.data ? (y as any) : s.key));
364
+ return valueAccessor(seriesTooltipData);
352
365
  })}
353
366
  format="integer"
354
367
  valueAlign="right"
@@ -7,7 +7,7 @@
7
7
  import Canvas from '../layout/Canvas.svelte';
8
8
  import Chart from '../Chart.svelte';
9
9
  import Grid from '../Grid.svelte';
10
- import Highlight from '../Highlight.svelte';
10
+ import Highlight, { type HighlightPointData } from '../Highlight.svelte';
11
11
  import Labels from '../Labels.svelte';
12
12
  import Legend from '../Legend.svelte';
13
13
  import Points from '../Points.svelte';
@@ -23,6 +23,7 @@
23
23
  findRelatedData,
24
24
  type Accessor,
25
25
  } from '../../utils/common.js';
26
+ import { asAny } from '../../utils/types.js';
26
27
 
27
28
  interface $$Props extends ComponentProps<Chart<TData>> {
28
29
  axis?: typeof axis;
@@ -34,6 +35,8 @@
34
35
  rule?: typeof rule;
35
36
  series?: typeof series;
36
37
  renderContext?: typeof renderContext;
38
+ onPointClick?: typeof onPointClick;
39
+ onTooltipClick?: typeof onTooltipClick;
37
40
  }
38
41
 
39
42
  export let data: $$Props['data'] = [];
@@ -61,6 +64,15 @@
61
64
  export let legend: ComponentProps<Legend> | boolean = false;
62
65
  export let points: ComponentProps<Points> | boolean = false;
63
66
 
67
+ /** Event dispatched with current tooltip data */
68
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
69
+
70
+ /** Event dispatched when Highlight point is clicked (useful with multiple series) */
71
+ export let onPointClick: (e: {
72
+ data: HighlightPointData;
73
+ series: (typeof series)[number];
74
+ }) => void = () => {};
75
+
64
76
  export let props: {
65
77
  xAxis?: Partial<ComponentProps<Axis>>;
66
78
  yAxis?: Partial<ComponentProps<Axis>>;
@@ -110,7 +122,7 @@
110
122
  yNice
111
123
  {radial}
112
124
  padding={radial ? undefined : defaultChartPadding(axis, legend)}
113
- tooltip={{ mode: 'bisect-x' }}
125
+ tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
114
126
  {...$$restProps}
115
127
  let:x
116
128
  let:xScale
@@ -206,6 +218,7 @@
206
218
  y={s.value ?? (s.data ? undefined : s.key)}
207
219
  points={{ fill: s.color }}
208
220
  lines={i === 0}
221
+ onPointClick={(e) => onPointClick({ ...e, series: s })}
209
222
  {...props.highlight}
210
223
  />
211
224
  {/each}
@@ -235,7 +248,7 @@
235
248
  <Tooltip.List>
236
249
  {#each series as s}
237
250
  {@const seriesTooltipData = s.data ? findRelatedData(s.data, data, x) : data}
238
- {@const valueAccessor = accessor(s.value ?? (s.data ? (y as any) : s.key))}
251
+ {@const valueAccessor = accessor(s.value ?? (s.data ? asAny(y) : s.key))}
239
252
 
240
253
  <Tooltip.Item
241
254
  label={s.label ?? (s.key !== 'default' ? s.key : 'value')}
@@ -30,8 +30,10 @@
30
30
  props?: typeof props;
31
31
  range?: typeof range;
32
32
  series?: typeof series;
33
- value?: typeof label;
33
+ value?: typeof value;
34
34
  renderContext?: typeof renderContext;
35
+ onArcClick?: typeof onArcClick;
36
+ onTooltipClick?: typeof onTooltipClick;
35
37
  }
36
38
 
37
39
  export let data: ChartProps['data'] = [];
@@ -93,6 +95,13 @@
93
95
  /** Center chart. Override and use `props.group` for more control */
94
96
  export let center = placement === 'center';
95
97
 
98
+ // TODO: Not usable with manual tooltip / arc path. Use `onArcClick`?
99
+ /** Event dispatched with current tooltip data */
100
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
101
+
102
+ /** Event dispatched when individual Arc is clicked (useful with multiple series) */
103
+ export let onArcClick: (e: { data: any; series: (typeof series)[number] }) => void = () => {};
104
+
96
105
  export let props: {
97
106
  pie?: Partial<ComponentProps<Pie>>;
98
107
  group?: Partial<ComponentProps<Group>>;
@@ -184,6 +193,11 @@
184
193
  track={{ fill: s.color ?? cScale?.(c(d)), 'fill-opacity': 0.1 }}
185
194
  {tooltip}
186
195
  data={d}
196
+ on:click={() => {
197
+ onArcClick({ data: d, series: s });
198
+ // Workaround for `tooltip={{ mode: 'manual' }}
199
+ onTooltipClick({ data: d });
200
+ }}
187
201
  {...props.arc}
188
202
  {...s.props}
189
203
  />
@@ -209,6 +223,11 @@
209
223
  fill={cScale?.(c(arc.data))}
210
224
  data={arc.data}
211
225
  {tooltip}
226
+ on:click={() => {
227
+ onArcClick({ data: arc.data, series: s });
228
+ // Workaround for `tooltip={{ mode: 'manual' }}
229
+ onTooltipClick({ data: arc.data });
230
+ }}
212
231
  {...props.arc}
213
232
  {...s.props}
214
233
  />
@@ -245,6 +245,23 @@ declare class __sveltets_Render<TData> {
245
245
  }[] | undefined;
246
246
  value?: Accessor<TData>;
247
247
  renderContext?: "canvas" | "svg";
248
+ onArcClick?: ((e: {
249
+ data: any;
250
+ series: {
251
+ key: string | number;
252
+ label?: string;
253
+ value?: Accessor<TData>;
254
+ /** Provider series data, else uses chart data (with value/key accessor) */
255
+ data?: TData[] | undefined;
256
+ /** Maximum possible value, useful when `data` is single item */
257
+ maxValue?: number;
258
+ color?: string;
259
+ props?: Partial<ComponentProps<Arc>>;
260
+ };
261
+ }) => void) | undefined;
262
+ onTooltipClick?: ((e: {
263
+ data: any;
264
+ }) => void) | undefined;
248
265
  };
249
266
  events(): {} & {
250
267
  [evt: string]: CustomEvent<any>;
@@ -30,6 +30,7 @@
30
30
  props?: typeof props;
31
31
  series?: typeof series;
32
32
  renderContext?: typeof renderContext;
33
+ onTooltipClick?: typeof onTooltipClick;
33
34
  }
34
35
 
35
36
  export let data: $$Props['data'] = [];
@@ -51,6 +52,9 @@
51
52
  export let legend: ComponentProps<Legend> | boolean = false;
52
53
  export let rule: ComponentProps<Rule> | boolean = true;
53
54
 
55
+ /** Event dispatched with current tooltip data */
56
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
57
+
54
58
  export let props: {
55
59
  xAxis?: Partial<ComponentProps<Axis>>;
56
60
  yAxis?: Partial<ComponentProps<Axis>>;
@@ -100,7 +104,7 @@
100
104
  {yScale}
101
105
  yNice
102
106
  padding={defaultChartPadding(axis, legend)}
103
- tooltip={{ mode: 'voronoi' }}
107
+ tooltip={{ mode: 'voronoi', onClick: onTooltipClick }}
104
108
  {...$$restProps}
105
109
  let:x
106
110
  let:xScale
@@ -0,0 +1 @@
1
+ export declare function asAny(x: any): any;
@@ -0,0 +1,3 @@
1
+ export function asAny(x) {
2
+ return x;
3
+ }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Sean Lynch <techniq35@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": "techniq/layerchart",
7
- "version": "0.71.3",
7
+ "version": "0.72.1",
8
8
  "devDependencies": {
9
9
  "@changesets/cli": "^2.27.10",
10
10
  "@mdi/js": "^7.4.47",