layerchart 0.92.1 → 0.93.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.
@@ -9,6 +9,7 @@
9
9
  import GeoContext from './GeoContext.svelte';
10
10
  import TooltipContext from './tooltip/TooltipContext.svelte';
11
11
  import TransformContext from './TransformContext.svelte';
12
+ import BrushContext from './BrushContext.svelte';
12
13
 
13
14
  import { accessor, type Accessor } from '../utils/common.js';
14
15
  import { isScaleBand, type AnyScale, type DomainType } from '../utils/scales.js';
@@ -195,20 +196,26 @@
195
196
  /** Props passed to GeoContext */
196
197
  geo?: typeof geo;
197
198
 
199
+ /** Exposed via bind: to support `bind:geoProjection` for external access */
200
+ geoProjection?: typeof geoProjection;
201
+
198
202
  /** Props passed to TooltipContext */
199
203
  tooltip?: typeof tooltip;
200
204
 
205
+ /** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
206
+ tooltipContext?: typeof tooltipContext;
207
+
201
208
  /** Props passed to TransformContext */
202
209
  transform?: typeof transform;
203
210
 
204
211
  /** Expose to support `bind:transformContext` for imperative control (`transformContext.translate(...)`) */
205
212
  transformContext?: typeof transformContext;
206
213
 
207
- /** Exposed via bind: to support `bind:geoProjection` for external access */
208
- geoProjection?: typeof geoProjection;
214
+ /** Props passed to BrushContext */
215
+ brush?: typeof brush;
209
216
 
210
- /** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
211
- tooltipContext?: typeof tooltipContext;
217
+ /** Exposed via bind: to support `bind:brushContext` for external access (ex. `brushContext.xDomain) */
218
+ brushContext?: typeof brushContext;
212
219
 
213
220
  // ChartContext callback events
214
221
  onresize?: typeof onresize;
@@ -278,19 +285,25 @@
278
285
  /** Props passed to GeoContext */
279
286
  export let geo: Partial<ComponentProps<GeoContext>> | undefined = undefined;
280
287
 
288
+ /** Expose bound geo projection context */
289
+ export let geoProjection: ComponentProps<GeoContext>['geo'] = undefined;
290
+
281
291
  /** Props passed to TooltipContext */
282
292
  export let tooltip: Partial<ComponentProps<TooltipContext>> | boolean | undefined = undefined;
283
293
 
294
+ /** Expose bound tooltip context */
295
+ export let tooltipContext: ComponentProps<TooltipContext>['tooltip'] = undefined;
296
+
284
297
  /** Props passed to TransformContext */
285
298
  export let transform: Partial<ComponentProps<TransformContext>> | undefined = undefined;
286
299
  // @ts-expect-error will only be undefined until bind:transformContext runs
287
300
  export let transformContext: TransformContext = undefined;
288
301
 
289
- /** Expose bound geo projection context */
290
- export let geoProjection: ComponentProps<GeoContext>['geo'] = undefined;
302
+ /** Props passed to BrushContext */
303
+ export let brush: Partial<ComponentProps<BrushContext>> | boolean | undefined = undefined;
291
304
 
292
- /** Expose bound tooltip context */
293
- export let tooltipContext: ComponentProps<TooltipContext>['tooltip'] = undefined;
305
+ /** Expose bound brush context */
306
+ export let brushContext: ComponentProps<BrushContext>['brush'] = undefined;
294
307
 
295
308
  export let onresize: ComponentProps<ChartContext<TData>>['onresize'] = undefined;
296
309
  export let ondragstart: ComponentProps<TransformContext>['ondragstart'] = undefined;
@@ -419,45 +432,49 @@
419
432
  {ondragend}
420
433
  >
421
434
  <GeoContext {...geo} bind:geo={geoProjection} let:projection>
422
- {@const tooltipProps = typeof tooltip === 'object' ? tooltip : {}}
423
- <TooltipContext {...tooltipProps} bind:tooltip={tooltipContext} let:tooltip>
424
- <slot
425
- {aspectRatio}
426
- {containerHeight}
427
- {containerWidth}
428
- {height}
429
- {width}
430
- {element}
431
- {projection}
432
- transform={_transform}
433
- {tooltip}
434
- {x}
435
- {xScale}
436
- {xGet}
437
- {y}
438
- {yScale}
439
- {yGet}
440
- {z}
441
- {zScale}
442
- {zGet}
443
- {r}
444
- {rScale}
445
- {rGet}
446
- {x1}
447
- {x1Scale}
448
- {x1Get}
449
- {y1}
450
- {y1Scale}
451
- {y1Get}
452
- {c}
453
- {cScale}
454
- {cGet}
455
- {padding}
456
- {data}
457
- {flatData}
458
- {config}
459
- />
460
- </TooltipContext>
435
+ {@const brushProps = typeof brush === 'object' ? brush : { disabled: !brush }}
436
+ <BrushContext {...brushProps} bind:brush={brushContext} let:brush>
437
+ {@const tooltipProps = typeof tooltip === 'object' ? tooltip : {}}
438
+ <TooltipContext {...tooltipProps} bind:tooltip={tooltipContext} let:tooltip>
439
+ <slot
440
+ {aspectRatio}
441
+ {containerHeight}
442
+ {containerWidth}
443
+ {height}
444
+ {width}
445
+ {element}
446
+ {projection}
447
+ transform={_transform}
448
+ {tooltip}
449
+ {brush}
450
+ {x}
451
+ {xScale}
452
+ {xGet}
453
+ {y}
454
+ {yScale}
455
+ {yGet}
456
+ {z}
457
+ {zScale}
458
+ {zGet}
459
+ {r}
460
+ {rScale}
461
+ {rGet}
462
+ {x1}
463
+ {x1Scale}
464
+ {x1Get}
465
+ {y1}
466
+ {y1Scale}
467
+ {y1Get}
468
+ {c}
469
+ {cScale}
470
+ {cGet}
471
+ {padding}
472
+ {data}
473
+ {flatData}
474
+ {config}
475
+ />
476
+ </TooltipContext>
477
+ </BrushContext>
461
478
  </GeoContext>
462
479
  </TransformContext>
463
480
  {/key}
@@ -182,6 +182,8 @@ declare class __sveltets_Render<TData> {
182
182
  reflectY?: boolean | undefined;
183
183
  geo?: import("svelte/store").Writable<import("d3-geo").GeoProjection>;
184
184
  }> | undefined;
185
+ /** Exposed via bind: to support `bind:geoProjection` for external access */
186
+ geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
185
187
  /** Props passed to TooltipContext */
186
188
  tooltip?: boolean | Partial<{
187
189
  mode?: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
@@ -194,14 +196,23 @@ declare class __sveltets_Render<TData> {
194
196
  data: any;
195
197
  }) => any;
196
198
  tooltip?: import("svelte/store").Writable<{
197
- y: number;
198
199
  x: number;
200
+ y: number;
199
201
  data: any;
200
202
  show: (e: PointerEvent, tooltipData?: any) => void;
201
203
  hide: () => void;
202
204
  mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
203
205
  }>;
204
206
  }> | undefined;
207
+ /** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
208
+ tooltipContext?: import("svelte/store").Writable<{
209
+ x: number;
210
+ y: number;
211
+ data: any;
212
+ show: (e: PointerEvent, tooltipData?: any) => void;
213
+ hide: () => void;
214
+ mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
215
+ }> | undefined;
205
216
  /** Props passed to TransformContext */
206
217
  transform?: Partial<{
207
218
  mode?: "canvas" | "manual" | "none";
@@ -260,17 +271,44 @@ declare class __sveltets_Render<TData> {
260
271
  }> | undefined;
261
272
  /** Expose to support `bind:transformContext` for imperative control (`transformContext.translate(...)`) */
262
273
  transformContext?: TransformContext;
263
- /** Exposed via bind: to support `bind:geoProjection` for external access */
264
- geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
265
- /** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
266
- tooltipContext?: import("svelte/store").Writable<{
267
- y: number;
268
- x: number;
269
- data: any;
270
- show: (e: PointerEvent, tooltipData?: any) => void;
271
- hide: () => void;
272
- mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
274
+ /** Props passed to BrushContext */
275
+ brush?: boolean | Partial<{
276
+ axis?: "x" | "y" | "both";
277
+ handleSize?: number;
278
+ resetOnEnd?: boolean;
279
+ xDomain?: DomainType;
280
+ yDomain?: DomainType;
281
+ mode?: "integrated" | "separated";
282
+ disabled?: boolean;
283
+ range?: Partial<import("svelte/elements").HTMLAttributes<HTMLDivElement>> | undefined;
284
+ handle?: Partial<import("svelte/elements").HTMLAttributes<HTMLDivElement>> | undefined;
285
+ classes?: {
286
+ root?: string;
287
+ frame?: string;
288
+ range?: string;
289
+ handle?: string;
290
+ labels?: string;
291
+ };
292
+ onchange?: (detail: {
293
+ xDomain?: DomainType;
294
+ yDomain?: DomainType;
295
+ }) => void;
296
+ onbrushstart?: (detail: {
297
+ xDomain?: DomainType;
298
+ yDomain?: DomainType;
299
+ }) => void;
300
+ onbrushend?: (detail: {
301
+ xDomain?: DomainType;
302
+ yDomain?: DomainType;
303
+ }) => void;
304
+ onreset?: (detail: {
305
+ xDomain?: DomainType;
306
+ yDomain?: DomainType;
307
+ }) => void;
308
+ brush?: import("svelte/store").Writable<import("./BrushContext.svelte").BrushContextValue>;
273
309
  }> | undefined;
310
+ /** Exposed via bind: to support `bind:brushContext` for external access (ex. `brushContext.xDomain) */
311
+ brushContext?: import("svelte/store").Writable<import("./BrushContext.svelte").BrushContextValue> | undefined;
274
312
  onresize?: ((e: import("./ChartContext.svelte").ChartResizeDetail) => void) | undefined;
275
313
  ondragstart?: (() => void) | undefined;
276
314
  ondragend?: (() => void) | undefined;
@@ -315,13 +353,14 @@ declare class __sveltets_Render<TData> {
315
353
  reset: () => void;
316
354
  };
317
355
  tooltip: {
318
- y: number;
319
356
  x: number;
357
+ y: number;
320
358
  data: any;
321
359
  show: (e: PointerEvent, tooltipData?: any) => void;
322
360
  hide: () => void;
323
361
  mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
324
362
  };
363
+ brush: import("./BrushContext.svelte").BrushContextValue;
325
364
  x: Function;
326
365
  xScale: any;
327
366
  xGet: any;
@@ -31,6 +31,7 @@
31
31
  export { className as class };
32
32
 
33
33
  export let onclick: ((e: MouseEvent) => void) | undefined = undefined;
34
+ export let onpointerdown: ((e: PointerEvent) => void) | undefined = undefined;
34
35
  export let onpointerenter: ((e: PointerEvent) => void) | undefined = undefined;
35
36
  export let onpointermove: ((e: PointerEvent) => void) | undefined = undefined;
36
37
  export let onpointerleave: ((e: PointerEvent) => void) | undefined = undefined;
@@ -89,6 +90,7 @@
89
90
  render,
90
91
  events: {
91
92
  click: onclick,
93
+ pointerdown: onpointerdown,
92
94
  pointerenter: onpointerenter,
93
95
  pointermove: onpointermove,
94
96
  pointerleave: onpointerleave,
@@ -116,6 +118,7 @@
116
118
  class={cls(fill == null && 'fill-surface-content', className)}
117
119
  {...$$restProps}
118
120
  on:click={onclick}
121
+ on:pointerdown={onpointerdown}
119
122
  on:pointerenter={onpointerenter}
120
123
  on:pointermove={onpointermove}
121
124
  on:pointerleave={onpointerleave}
@@ -66,21 +66,18 @@
66
66
  /** Set to false to disable spring transitions */
67
67
  export let motion = true;
68
68
 
69
- export let onareaclick: (e: MouseEvent, data: { data: any }) => void = () => {};
70
- export let onbarclick: (e: MouseEvent, data: { data: any }) => void = () => {};
71
-
72
- export let onpointclick: (
73
- e: MouseEvent,
74
- data: { point: (typeof _points)[number]; data: any }
75
- ) => void = () => {};
76
- export let onpointenter: (
77
- e: MouseEvent,
78
- datae: { point: (typeof _points)[number]; data: any }
79
- ) => void = () => {};
80
- export let onpointleave: (
81
- e: MouseEvent,
82
- datae: { point: (typeof _points)[number]; data: any }
83
- ) => void = () => {};
69
+ export let onareaclick: ((e: MouseEvent, detail: { data: any }) => void) | undefined = undefined;
70
+ export let onbarclick: ((e: MouseEvent, detail: { data: any }) => void) | undefined = undefined;
71
+
72
+ export let onpointclick:
73
+ | ((e: MouseEvent, detail: { point: (typeof _points)[number]; data: any }) => void)
74
+ | undefined = undefined;
75
+ export let onpointenter:
76
+ | ((e: MouseEvent, detail: { point: (typeof _points)[number]; data: any }) => void)
77
+ | undefined = undefined;
78
+ export let onpointleave:
79
+ | ((e: MouseEvent, detail: { point: (typeof _points)[number]; data: any }) => void)
80
+ | undefined = undefined;
84
81
 
85
82
  const _x = accessor(x);
86
83
  const _y = accessor(y);
@@ -362,7 +359,7 @@
362
359
  !area.fill && 'fill-surface-content/5',
363
360
  typeof area === 'object' ? area.class : null
364
361
  )}
365
- onclick={(e) => onareaclick(e, { data: highlightData })}
362
+ onclick={onareaclick && ((e) => onareaclick(e, { data: highlightData }))}
366
363
  />
367
364
  </slot>
368
365
  {/if}
@@ -383,7 +380,7 @@
383
380
  !bar.fill && 'fill-primary',
384
381
  typeof bar === 'object' ? bar.class : null
385
382
  )}
386
- onclick={(e) => onbarclick(e, { data: highlightData })}
383
+ onclick={onbarclick && ((e) => onbarclick(e, { data: highlightData }))}
387
384
  />
388
385
  </slot>
389
386
  {/if}
@@ -423,9 +420,14 @@
423
420
  !point.fill && (typeof points === 'boolean' || !points.fill) && 'fill-primary',
424
421
  typeof points === 'object' ? points.class : null
425
422
  )}
426
- onclick={(e) => onpointclick(e, { point, data: highlightData })}
427
- onpointerenter={(e) => onpointenter(e, { point, data: highlightData })}
428
- onpointerleave={(e) => onpointleave(e, { point, data: highlightData })}
423
+ onpointerdown={onpointclick &&
424
+ ((e) => {
425
+ // Do not propagate `pointerdown` event to `BrushContext` if `onclick` is provided
426
+ e.stopPropagation();
427
+ })}
428
+ onclick={onpointclick && ((e) => onpointclick(e, { point, data: highlightData }))}
429
+ onpointerenter={onpointenter && ((e) => onpointenter(e, { point, data: highlightData }))}
430
+ onpointerleave={onpointleave && ((e) => onpointleave(e, { point, data: highlightData }))}
429
431
  />
430
432
  {/each}
431
433
  </slot>
@@ -9,7 +9,7 @@
9
9
 
10
10
  import Area from '../Area.svelte';
11
11
  import Axis from '../Axis.svelte';
12
- import Brush from '../Brush.svelte';
12
+ import BrushContext from '../BrushContext.svelte';
13
13
  import Canvas from '../layout/Canvas.svelte';
14
14
  import Chart from '../Chart.svelte';
15
15
  import ChartClipPath from '../ChartClipPath.svelte';
@@ -55,7 +55,7 @@
55
55
  export let y: Accessor<TData> = undefined;
56
56
 
57
57
  /** Set xDomain. Useful for external brush control */
58
- export let xDomain: ComponentProps<typeof Brush>['xDomain'] = undefined;
58
+ export let xDomain: ComponentProps<typeof BrushContext>['xDomain'] = undefined;
59
59
 
60
60
  /** 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 */
61
61
  export let radial = false;
@@ -76,7 +76,7 @@
76
76
  $: stackSeries = seriesLayout.startsWith('stack');
77
77
 
78
78
  export let axis: ComponentProps<Axis> | 'x' | 'y' | boolean = true;
79
- export let brush: ComponentProps<Brush> | boolean = false;
79
+ export let brush: ComponentProps<BrushContext> | boolean = false;
80
80
  export let grid: ComponentProps<Grid> | boolean = true;
81
81
  export let labels: ComponentProps<Labels> | boolean = false;
82
82
  export let legend: ComponentProps<Legend> | boolean = false;
@@ -87,17 +87,19 @@
87
87
  export let ontooltipclick: (e: MouseEvent, details: { data: any }) => void = () => {};
88
88
 
89
89
  /** Event dispatched when Highlight point is clicked (useful with multiple series) */
90
- export let onpointclick: (
91
- e: MouseEvent,
92
- details: {
93
- data: HighlightPointData;
94
- series: (typeof series)[number];
95
- }
96
- ) => void = () => {};
90
+ export let onpointclick:
91
+ | ((
92
+ e: MouseEvent,
93
+ details: {
94
+ data: HighlightPointData;
95
+ series: (typeof series)[number];
96
+ }
97
+ ) => void)
98
+ | undefined = undefined;
97
99
 
98
100
  export let props: {
99
101
  area?: Partial<ComponentProps<Area>>;
100
- brush?: Partial<ComponentProps<Brush>>;
102
+ brush?: Partial<ComponentProps<BrushContext>>;
101
103
  grid?: Partial<ComponentProps<Grid>>;
102
104
  highlight?: Partial<ComponentProps<Highlight>>;
103
105
  labels?: Partial<ComponentProps<Labels>>;
@@ -185,7 +187,11 @@
185
187
  ...s.props,
186
188
  class: cls(
187
189
  'transition-opacity',
188
- highlightSeriesKey && highlightSeriesKey !== s.key && 'opacity-10',
190
+ // Checking `visibleSeries.length > 1` fixes re-animated tweened areas on hover
191
+ visibleSeries.length > 1 &&
192
+ highlightSeriesKey &&
193
+ highlightSeriesKey !== s.key &&
194
+ 'opacity-10',
189
195
  props.area?.class,
190
196
  s.props?.class
191
197
  ),
@@ -194,7 +200,10 @@
194
200
  ...lineProps,
195
201
  class: cls(
196
202
  'transition-opacity',
197
- highlightSeriesKey && highlightSeriesKey !== s.key && 'opacity-10',
203
+ visibleSeries.length > 1 &&
204
+ highlightSeriesKey &&
205
+ highlightSeriesKey !== s.key &&
206
+ 'opacity-10',
198
207
  lineProps.class
199
208
  ),
200
209
  },
@@ -255,6 +264,8 @@
255
264
  );
256
265
  });
257
266
 
267
+ $: brushProps = { ...(typeof brush === 'object' ? brush : null), ...props.brush };
268
+
258
269
  if (profile) {
259
270
  console.time('AreaChart render');
260
271
  onMount(() => {
@@ -286,6 +297,18 @@
286
297
  ...props.tooltip?.context,
287
298
  ...$$props.tooltip,
288
299
  }}
300
+ brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
301
+ ? {
302
+ axis: 'x',
303
+ resetOnEnd: true,
304
+ xDomain,
305
+ ...brushProps,
306
+ onbrushend: (e) => {
307
+ xDomain = e.xDomain;
308
+ brushProps.onbrushend?.(e);
309
+ },
310
+ }
311
+ : false}
289
312
  let:x
290
313
  let:xScale
291
314
  let:y
@@ -389,7 +412,9 @@
389
412
  ),
390
413
  }}
391
414
  lines={i == 0}
392
- onpointclick={(e, detail) => onpointclick(e, { ...detail, series: s })}
415
+ onpointclick={onpointclick
416
+ ? (e, detail) => onpointclick(e, { ...detail, series: s })
417
+ : undefined}
393
418
  onpointenter={() => (highlightSeriesKey = s.key)}
394
419
  onpointleave={() => (highlightSeriesKey = null)}
395
420
  {...props.highlight}
@@ -404,22 +429,6 @@
404
429
  {/if}
405
430
  </svelte:component>
406
431
 
407
- {#if brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')}
408
- <Svg>
409
- {@const brushProps = { ...(typeof brush === 'object' ? brush : null), ...props.brush }}
410
- <Brush
411
- axis="x"
412
- resetOnEnd
413
- {xDomain}
414
- {...brushProps}
415
- onbrushend={(e) => {
416
- xDomain = e.xDomain;
417
- brushProps.onbrushend?.(e);
418
- }}
419
- />
420
- </Svg>
421
- {/if}
422
-
423
432
  <slot name="legend" {...slotProps}>
424
433
  {#if legend}
425
434
  <Legend
@@ -6,7 +6,7 @@
6
6
  import { selectionStore } from '@layerstack/svelte-stores';
7
7
 
8
8
  import Axis from '../Axis.svelte';
9
- import Brush from '../Brush.svelte';
9
+ import BrushContext from '../BrushContext.svelte';
10
10
  import Canvas from '../layout/Canvas.svelte';
11
11
  import Chart from '../Chart.svelte';
12
12
  import ChartClipPath from '../ChartClipPath.svelte';
@@ -51,7 +51,7 @@
51
51
  export let y: Accessor<TData> = undefined;
52
52
 
53
53
  /** Set xDomain. Useful for external brush control */
54
- export let xDomain: ComponentProps<typeof Brush>['xDomain'] = undefined;
54
+ export let xDomain: ComponentProps<typeof BrushContext>['xDomain'] = undefined;
55
55
 
56
56
  /** 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 */
57
57
  export let radial = false;
@@ -68,7 +68,7 @@
68
68
  $: isDefaultSeries = series.length === 1 && series[0].key === 'default';
69
69
 
70
70
  export let axis: ComponentProps<Axis> | 'x' | 'y' | boolean = true;
71
- export let brush: ComponentProps<Brush> | boolean = false;
71
+ export let brush: ComponentProps<BrushContext> | boolean = false;
72
72
  export let grid: ComponentProps<Grid> | boolean = true;
73
73
  export let labels: ComponentProps<Labels> | boolean = false;
74
74
  export let legend: ComponentProps<Legend> | boolean = false;
@@ -79,16 +79,18 @@
79
79
  export let ontooltipclick: (e: MouseEvent, details: { data: any }) => void = () => {};
80
80
 
81
81
  /** Event dispatched when Highlight point is clicked (useful with multiple series) */
82
- export let onpointclick: (
83
- e: MouseEvent,
84
- details: {
85
- data: HighlightPointData;
86
- series: (typeof series)[number];
87
- }
88
- ) => void = () => {};
82
+ export let onpointclick:
83
+ | ((
84
+ e: MouseEvent,
85
+ details: {
86
+ data: HighlightPointData;
87
+ series: (typeof series)[number];
88
+ }
89
+ ) => void)
90
+ | undefined = undefined;
89
91
 
90
92
  export let props: {
91
- brush?: Partial<ComponentProps<Brush>>;
93
+ brush?: Partial<ComponentProps<BrushContext>>;
92
94
  grid?: Partial<ComponentProps<Grid>>;
93
95
  highlight?: Partial<ComponentProps<Highlight>>;
94
96
  labels?: Partial<ComponentProps<Labels>>;
@@ -139,7 +141,11 @@
139
141
  ...s.props,
140
142
  class: cls(
141
143
  'transition-opacity',
142
- highlightSeriesKey && highlightSeriesKey !== s.key && 'opacity-10',
144
+ // Checking `visibleSeries.length > 1` fixes re-animated tweened areas on hover
145
+ visibleSeries.length > 1 &&
146
+ highlightSeriesKey &&
147
+ highlightSeriesKey !== s.key &&
148
+ 'opacity-10',
143
149
  props.spline?.class,
144
150
  s.props?.class
145
151
  ),
@@ -192,6 +198,8 @@
192
198
  );
193
199
  });
194
200
 
201
+ $: brushProps = { ...(typeof brush === 'object' ? brush : null), ...props.brush };
202
+
195
203
  if (profile) {
196
204
  console.time('LineChart render');
197
205
  onMount(() => {
@@ -220,6 +228,18 @@
220
228
  ...props.tooltip?.context,
221
229
  ...$$props.tooltip,
222
230
  }}
231
+ brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
232
+ ? {
233
+ axis: 'x',
234
+ resetOnEnd: true,
235
+ xDomain,
236
+ ...brushProps,
237
+ onbrushend: (e) => {
238
+ xDomain = e.xDomain;
239
+ brushProps.onbrushend?.(e);
240
+ },
241
+ }
242
+ : false}
223
243
  let:x
224
244
  let:xScale
225
245
  let:y
@@ -321,7 +341,9 @@
321
341
  ),
322
342
  }}
323
343
  lines={i === 0}
324
- onpointclick={(e, detail) => onpointclick(e, { ...detail, series: s })}
344
+ onpointclick={onpointclick
345
+ ? (e, detail) => onpointclick(e, { ...detail, series: s })
346
+ : undefined}
325
347
  onpointenter={() => (highlightSeriesKey = s.key)}
326
348
  onpointleave={() => (highlightSeriesKey = null)}
327
349
  {...props.highlight}
@@ -330,22 +352,6 @@
330
352
  </slot>
331
353
  </svelte:component>
332
354
 
333
- {#if brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')}
334
- <Svg>
335
- {@const brushProps = { ...(typeof brush === 'object' ? brush : null), ...props.brush }}
336
- <Brush
337
- axis="x"
338
- resetOnEnd
339
- {xDomain}
340
- {...brushProps}
341
- onbrushend={(e) => {
342
- xDomain = e.xDomain;
343
- brushProps.onbrushend?.(e);
344
- }}
345
- />
346
- </Svg>
347
- {/if}
348
-
349
355
  <slot name="legend" {...slotProps}>
350
356
  {#if legend}
351
357
  <Legend