layerchart 0.71.3 → 0.72.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.
@@ -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';
@@ -38,6 +38,8 @@
38
38
  series?: typeof series;
39
39
  seriesLayout?: typeof seriesLayout;
40
40
  renderContext?: typeof renderContext;
41
+ onPointClick?: typeof onPointClick;
42
+ onTooltipClick?: typeof onTooltipClick;
41
43
  }
42
44
 
43
45
  export let data: $$Props['data'] = [];
@@ -69,6 +71,15 @@
69
71
  export let legend: ComponentProps<Legend> | boolean = false;
70
72
  export let points: ComponentProps<Points> | boolean = false;
71
73
 
74
+ /** Event dispatched with current tooltip data */
75
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
76
+
77
+ /** Event dispatched when Highlight point is clicked (useful with multiple series) */
78
+ export let onPointClick: (e: {
79
+ data: HighlightPointData;
80
+ series: (typeof series)[number];
81
+ }) => void = () => {};
82
+
72
83
  export let props: {
73
84
  xAxis?: Partial<ComponentProps<Axis>>;
74
85
  yAxis?: Partial<ComponentProps<Axis>>;
@@ -162,7 +173,7 @@
162
173
  yNice
163
174
  {radial}
164
175
  padding={radial ? undefined : defaultChartPadding(axis, legend)}
165
- tooltip={{ mode: 'bisect-x' }}
176
+ tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
166
177
  {...$$restProps}
167
178
  let:x
168
179
  let:xScale
@@ -262,6 +273,7 @@
262
273
  y={stackSeries ? (d) => d.stackData[i][1] : (s.value ?? (s.data ? undefined : s.key))}
263
274
  points={{ fill: s.color }}
264
275
  lines={i == 0}
276
+ onPointClick={(e) => onPointClick({ ...e, series: s })}
265
277
  {...props.highlight}
266
278
  />
267
279
  {/each}
@@ -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';
@@ -34,6 +34,8 @@
34
34
  rule?: typeof rule;
35
35
  series?: typeof series;
36
36
  renderContext?: typeof renderContext;
37
+ onPointClick?: typeof onPointClick;
38
+ onTooltipClick?: typeof onTooltipClick;
37
39
  }
38
40
 
39
41
  export let data: $$Props['data'] = [];
@@ -61,6 +63,15 @@
61
63
  export let legend: ComponentProps<Legend> | boolean = false;
62
64
  export let points: ComponentProps<Points> | boolean = false;
63
65
 
66
+ /** Event dispatched with current tooltip data */
67
+ export let onTooltipClick: (e: { data: any }) => void = () => {};
68
+
69
+ /** Event dispatched when Highlight point is clicked (useful with multiple series) */
70
+ export let onPointClick: (e: {
71
+ data: HighlightPointData;
72
+ series: (typeof series)[number];
73
+ }) => void = () => {};
74
+
64
75
  export let props: {
65
76
  xAxis?: Partial<ComponentProps<Axis>>;
66
77
  yAxis?: Partial<ComponentProps<Axis>>;
@@ -110,7 +121,7 @@
110
121
  yNice
111
122
  {radial}
112
123
  padding={radial ? undefined : defaultChartPadding(axis, legend)}
113
- tooltip={{ mode: 'bisect-x' }}
124
+ tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
114
125
  {...$$restProps}
115
126
  let:x
116
127
  let:xScale
@@ -206,6 +217,7 @@
206
217
  y={s.value ?? (s.data ? undefined : s.key)}
207
218
  points={{ fill: s.color }}
208
219
  lines={i === 0}
220
+ onPointClick={(e) => onPointClick({ ...e, series: s })}
209
221
  {...props.highlight}
210
222
  />
211
223
  {/each}
@@ -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
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.0",
8
8
  "devDependencies": {
9
9
  "@changesets/cli": "^2.27.10",
10
10
  "@mdi/js": "^7.4.47",