layerchart 0.75.1 → 0.76.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.
- package/dist/components/Chart.svelte.d.ts +1 -0
- package/dist/components/charts/AreaChart.svelte +7 -4
- package/dist/components/charts/BarChart.svelte +13 -7
- package/dist/components/charts/LineChart.svelte +6 -4
- package/dist/components/charts/PieChart.svelte +4 -2
- package/dist/components/charts/PieChart.svelte.d.ts +1 -0
- package/dist/components/charts/ScatterChart.svelte +10 -6
- package/dist/components/tooltip/Tooltip.svelte +4 -1
- package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -0
- package/dist/components/tooltip/TooltipContext.svelte +19 -6
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +1 -0
- package/dist/components/tooltip/TooltipHeader.svelte +4 -1
- package/dist/components/tooltip/TooltipHeader.svelte.d.ts +3 -0
- package/package.json +1 -1
|
@@ -187,6 +187,7 @@ declare class __sveltets_Render<TData> {
|
|
|
187
187
|
mode?: "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree" | "manual";
|
|
188
188
|
findTooltipData?: "closest" | "left" | "right";
|
|
189
189
|
raiseTarget?: boolean;
|
|
190
|
+
locked?: boolean;
|
|
190
191
|
radius?: number;
|
|
191
192
|
debug?: boolean;
|
|
192
193
|
onClick?: ({ data }: {
|
|
@@ -214,8 +214,8 @@
|
|
|
214
214
|
yNice
|
|
215
215
|
{radial}
|
|
216
216
|
padding={radial ? undefined : defaultChartPadding(axis, legend)}
|
|
217
|
-
tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
|
|
218
217
|
{...$$restProps}
|
|
218
|
+
tooltip={{ mode: 'bisect-x', onClick: onTooltipClick, ...$$props.tooltip, ...props.tooltip }}
|
|
219
219
|
let:x
|
|
220
220
|
let:xScale
|
|
221
221
|
let:y
|
|
@@ -342,21 +342,24 @@
|
|
|
342
342
|
onClick={(item) => $selectedSeries.toggleSelected(item.value)}
|
|
343
343
|
onPointerEnter={(item) => (highlightSeriesKey = item.value)}
|
|
344
344
|
onPointerLeave={(item) => (highlightSeriesKey = null)}
|
|
345
|
+
{...props.legend}
|
|
346
|
+
{...typeof legend === 'object' ? legend : null}
|
|
345
347
|
classes={{
|
|
346
348
|
item: (item) =>
|
|
347
349
|
visibleSeries.length && !visibleSeries.some((s) => s.key === item.value)
|
|
348
350
|
? 'opacity-50'
|
|
349
351
|
: '',
|
|
352
|
+
...props.legend?.classes,
|
|
353
|
+
...(typeof legend === 'object' ? legend.classes : null),
|
|
350
354
|
}}
|
|
351
|
-
{...props.legend}
|
|
352
|
-
{...typeof legend === 'object' ? legend : null}
|
|
353
355
|
/>
|
|
354
356
|
{/if}
|
|
355
357
|
</slot>
|
|
356
358
|
|
|
357
359
|
<slot name="tooltip" {...slotProps}>
|
|
358
360
|
<Tooltip.Root {...props.tooltip?.root} let:data>
|
|
359
|
-
<Tooltip.Header {...props.tooltip?.header}
|
|
361
|
+
<Tooltip.Header value={x(data)} {format} {...props.tooltip?.header} />
|
|
362
|
+
|
|
360
363
|
<Tooltip.List {...props.tooltip?.list}>
|
|
361
364
|
<!-- Reverse series order so tooltip items match stacks -->
|
|
362
365
|
{@const seriesItems = stackSeries ? [...visibleSeries].reverse() : visibleSeries}
|
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
list?: Partial<ComponentProps<Tooltip.List>>;
|
|
141
141
|
item?: Partial<ComponentProps<Tooltip.Item>>;
|
|
142
142
|
separator?: Partial<ComponentProps<Tooltip.Separator>>;
|
|
143
|
+
hideTotal?: boolean;
|
|
143
144
|
};
|
|
144
145
|
} = {};
|
|
145
146
|
|
|
@@ -279,8 +280,8 @@
|
|
|
279
280
|
c={isVertical ? y : x}
|
|
280
281
|
cRange={['hsl(var(--color-primary))']}
|
|
281
282
|
padding={defaultChartPadding(axis, legend)}
|
|
282
|
-
tooltip={{ mode: 'band', onClick: onTooltipClick }}
|
|
283
283
|
{...$$restProps}
|
|
284
|
+
tooltip={{ mode: 'band', onClick: onTooltipClick, ...$$props.tooltip, ...props.tooltip }}
|
|
284
285
|
let:x
|
|
285
286
|
let:xScale
|
|
286
287
|
let:y
|
|
@@ -396,23 +397,28 @@
|
|
|
396
397
|
onClick={(item) => $selectedSeries.toggleSelected(item.value)}
|
|
397
398
|
onPointerEnter={(item) => (highlightSeriesKey = item.value)}
|
|
398
399
|
onPointerLeave={(item) => (highlightSeriesKey = null)}
|
|
400
|
+
{...props.legend}
|
|
401
|
+
{...typeof legend === 'object' ? legend : null}
|
|
399
402
|
classes={{
|
|
400
403
|
item: (item) =>
|
|
401
404
|
visibleSeries.length && !visibleSeries.some((s) => s.key === item.value)
|
|
402
405
|
? 'opacity-50'
|
|
403
406
|
: '',
|
|
407
|
+
...props.legend?.classes,
|
|
408
|
+
...(typeof legend === 'object' ? legend.classes : null),
|
|
404
409
|
}}
|
|
405
|
-
{...props.legend}
|
|
406
|
-
{...typeof legend === 'object' ? legend : null}
|
|
407
410
|
/>
|
|
408
411
|
{/if}
|
|
409
412
|
</slot>
|
|
410
413
|
|
|
411
414
|
<slot name="tooltip" {...slotProps}>
|
|
412
415
|
<Tooltip.Root {...props.tooltip?.root} let:data>
|
|
413
|
-
<Tooltip.Header
|
|
414
|
-
|
|
415
|
-
|
|
416
|
+
<Tooltip.Header
|
|
417
|
+
value={isVertical ? x(data) : y(data)}
|
|
418
|
+
{format}
|
|
419
|
+
{...props.tooltip?.header}
|
|
420
|
+
/>
|
|
421
|
+
|
|
416
422
|
<Tooltip.List {...props.tooltip?.list}>
|
|
417
423
|
<!-- Reverse series order so tooltip items match stacks -->
|
|
418
424
|
{@const seriesItems = stackSeries ? [...visibleSeries].reverse() : visibleSeries}
|
|
@@ -429,7 +435,7 @@
|
|
|
429
435
|
/>
|
|
430
436
|
{/each}
|
|
431
437
|
|
|
432
|
-
{#if (stackSeries || groupSeries) && visibleSeries.length > 1}
|
|
438
|
+
{#if (stackSeries || groupSeries) && visibleSeries.length > 1 && !props.tooltip?.hideTotal}
|
|
433
439
|
<Tooltip.Separator {...props.tooltip?.separator} />
|
|
434
440
|
|
|
435
441
|
<Tooltip.Item
|
|
@@ -156,8 +156,8 @@
|
|
|
156
156
|
yNice
|
|
157
157
|
{radial}
|
|
158
158
|
padding={radial ? undefined : defaultChartPadding(axis, legend)}
|
|
159
|
-
tooltip={{ mode: 'bisect-x', onClick: onTooltipClick }}
|
|
160
159
|
{...$$restProps}
|
|
160
|
+
tooltip={{ mode: 'bisect-x', onClick: onTooltipClick, ...$$props.tooltip, ...props.tooltip }}
|
|
161
161
|
let:x
|
|
162
162
|
let:xScale
|
|
163
163
|
let:y
|
|
@@ -276,21 +276,23 @@
|
|
|
276
276
|
onClick={(item) => $selectedSeries.toggleSelected(item.value)}
|
|
277
277
|
onPointerEnter={(item) => (highlightSeriesKey = item.value)}
|
|
278
278
|
onPointerLeave={(item) => (highlightSeriesKey = null)}
|
|
279
|
+
{...props.legend}
|
|
280
|
+
{...typeof legend === 'object' ? legend : null}
|
|
279
281
|
classes={{
|
|
280
282
|
item: (item) =>
|
|
281
283
|
visibleSeries.length && !visibleSeries.some((s) => s.key === item.value)
|
|
282
284
|
? 'opacity-50'
|
|
283
285
|
: '',
|
|
286
|
+
...props.legend?.classes,
|
|
287
|
+
...(typeof legend === 'object' ? legend.classes : null),
|
|
284
288
|
}}
|
|
285
|
-
{...props.legend}
|
|
286
|
-
{...typeof legend === 'object' ? legend : null}
|
|
287
289
|
/>
|
|
288
290
|
{/if}
|
|
289
291
|
</slot>
|
|
290
292
|
|
|
291
293
|
<slot name="tooltip" {...slotProps}>
|
|
292
294
|
<Tooltip.Root {...props.tooltip?.root} let:data>
|
|
293
|
-
<Tooltip.Header {...props.tooltip?.header}
|
|
295
|
+
<Tooltip.Header value={x(data)} {format} {...props.tooltip?.header} />
|
|
294
296
|
<Tooltip.List {...props.tooltip?.list}>
|
|
295
297
|
{#each visibleSeries as s}
|
|
296
298
|
{@const seriesTooltipData = s.data ? findRelatedData(s.data, data, x) : data}
|
|
@@ -294,14 +294,16 @@
|
|
|
294
294
|
onClick={(item) => $selectedKeys.toggleSelected(item.value)}
|
|
295
295
|
onPointerEnter={(item) => (highlightKey = item.value)}
|
|
296
296
|
onPointerLeave={(item) => (highlightKey = null)}
|
|
297
|
+
{...props.legend}
|
|
298
|
+
{...typeof legend === 'object' ? legend : null}
|
|
297
299
|
classes={{
|
|
298
300
|
item: (item) =>
|
|
299
301
|
visibleData.length && !visibleData.some((d) => keyAccessor(d) === item.value)
|
|
300
302
|
? 'opacity-50'
|
|
301
303
|
: '',
|
|
304
|
+
...props.legend?.classes,
|
|
305
|
+
...(typeof legend === 'object' ? legend.classes : null),
|
|
302
306
|
}}
|
|
303
|
-
{...props.legend}
|
|
304
|
-
{...typeof legend === 'object' ? legend : null}
|
|
305
307
|
/>
|
|
306
308
|
{/if}
|
|
307
309
|
</slot>
|
|
@@ -124,6 +124,7 @@ declare class __sveltets_Render<TData> {
|
|
|
124
124
|
mode?: "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree" | "manual";
|
|
125
125
|
findTooltipData?: "closest" | "left" | "right";
|
|
126
126
|
raiseTarget?: boolean;
|
|
127
|
+
locked?: boolean;
|
|
127
128
|
radius?: number;
|
|
128
129
|
debug?: boolean;
|
|
129
130
|
onClick?: ({ data }: {
|
|
@@ -139,8 +139,8 @@
|
|
|
139
139
|
{yScale}
|
|
140
140
|
yNice
|
|
141
141
|
padding={defaultChartPadding(axis, legend)}
|
|
142
|
-
tooltip={{ mode: 'voronoi', onClick: onTooltipClick }}
|
|
143
142
|
{...$$restProps}
|
|
143
|
+
tooltip={{ mode: 'voronoi', onClick: onTooltipClick, ...$$props.tooltip, ...props.tooltip }}
|
|
144
144
|
let:x
|
|
145
145
|
let:xScale
|
|
146
146
|
let:y
|
|
@@ -231,14 +231,16 @@
|
|
|
231
231
|
onClick={(item) => $selectedSeries.toggleSelected(item.value)}
|
|
232
232
|
onPointerEnter={(item) => (highlightSeriesKey = item.value)}
|
|
233
233
|
onPointerLeave={(item) => (highlightSeriesKey = null)}
|
|
234
|
+
{...props.legend}
|
|
235
|
+
{...typeof legend === 'object' ? legend : null}
|
|
234
236
|
classes={{
|
|
235
237
|
item: (item) =>
|
|
236
238
|
visibleSeries.length && !visibleSeries.some((s) => s.key === item.value)
|
|
237
239
|
? 'opacity-50'
|
|
238
240
|
: '',
|
|
241
|
+
...props.legend?.classes,
|
|
242
|
+
...(typeof legend === 'object' ? legend.classes : null),
|
|
239
243
|
}}
|
|
240
|
-
{...props.legend}
|
|
241
|
-
{...typeof legend === 'object' ? legend : null}
|
|
242
244
|
/>
|
|
243
245
|
{/if}
|
|
244
246
|
</slot>
|
|
@@ -246,9 +248,11 @@
|
|
|
246
248
|
<slot name="tooltip" {...slotProps}>
|
|
247
249
|
<Tooltip.Root {...props.tooltip?.root} let:data>
|
|
248
250
|
{#if activeSeries?.key !== 'default'}
|
|
249
|
-
<Tooltip.Header
|
|
250
|
-
{activeSeries?.label ?? activeSeries?.key}
|
|
251
|
-
|
|
251
|
+
<Tooltip.Header
|
|
252
|
+
value={activeSeries?.label ?? activeSeries?.key}
|
|
253
|
+
color={activeSeries?.color}
|
|
254
|
+
{...props.tooltip?.header}
|
|
255
|
+
/>
|
|
252
256
|
{/if}
|
|
253
257
|
<Tooltip.List {...props.tooltip?.list}>
|
|
254
258
|
<Tooltip.Item
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
/** Set to `false` to disable spring transitions */
|
|
38
38
|
export let motion = true;
|
|
39
39
|
|
|
40
|
+
/** Allow pointer events. Disabled by default to reduce accidental selection, but useful to enable to allow interactdive tooltips (using `locked`) */
|
|
41
|
+
export let pointerEvents = false;
|
|
42
|
+
|
|
40
43
|
export let classes: {
|
|
41
44
|
root?: string;
|
|
42
45
|
container?: string;
|
|
@@ -203,7 +206,7 @@
|
|
|
203
206
|
|
|
204
207
|
{#if $tooltip.data}
|
|
205
208
|
<div
|
|
206
|
-
class={cls('absolute
|
|
209
|
+
class={cls('absolute z-50 select-none', !pointerEvents && 'pointer-events-none', classes.root)}
|
|
207
210
|
style:top="{$yPos}px"
|
|
208
211
|
style:left="{$xPos}px"
|
|
209
212
|
transition:fade={{ duration: 100 }}
|
|
@@ -10,6 +10,7 @@ declare const __propDef: {
|
|
|
10
10
|
contained?: "container" | "window" | false | undefined;
|
|
11
11
|
variant?: "default" | "invert" | "none" | undefined;
|
|
12
12
|
motion?: boolean | undefined;
|
|
13
|
+
pointerEvents?: boolean | undefined;
|
|
13
14
|
classes?: {
|
|
14
15
|
root?: string;
|
|
15
16
|
container?: string;
|
|
@@ -97,6 +97,9 @@
|
|
|
97
97
|
/** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */
|
|
98
98
|
export let raiseTarget = false;
|
|
99
99
|
|
|
100
|
+
/** Lock tooltip (keep open, do not update on mouse movement). Allows for kicking on tooltip */
|
|
101
|
+
export let locked = false;
|
|
102
|
+
|
|
100
103
|
/** quadtree search radius
|
|
101
104
|
* @type {number}
|
|
102
105
|
*/
|
|
@@ -169,6 +172,11 @@
|
|
|
169
172
|
// Cancel hiding tooltip if from previous event loop
|
|
170
173
|
clearTimeout(hideTimeoutId);
|
|
171
174
|
|
|
175
|
+
if (locked) {
|
|
176
|
+
// Ignore (keep current position / data)
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
172
180
|
const referenceNode = (e.target as Element).closest('.layercake-container')!;
|
|
173
181
|
const point = localPoint(referenceNode, e);
|
|
174
182
|
const pointerX = point?.x ?? 0;
|
|
@@ -275,6 +283,11 @@
|
|
|
275
283
|
}
|
|
276
284
|
|
|
277
285
|
function hideTooltip() {
|
|
286
|
+
if (locked) {
|
|
287
|
+
// Ignore (keep open)
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
278
291
|
// Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
|
|
279
292
|
hideTimeoutId = setTimeout(() => {
|
|
280
293
|
$tooltip = { ...$tooltip, data: null };
|
|
@@ -369,7 +382,7 @@
|
|
|
369
382
|
.sort(sortFunc('x'));
|
|
370
383
|
}
|
|
371
384
|
|
|
372
|
-
$:
|
|
385
|
+
$: triggerPointerEvents = ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode);
|
|
373
386
|
</script>
|
|
374
387
|
|
|
375
388
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
@@ -381,13 +394,13 @@
|
|
|
381
394
|
style:left="{$padding.left}px"
|
|
382
395
|
class={cls(
|
|
383
396
|
'tooltip-trigger absolute touch-none',
|
|
384
|
-
debug &&
|
|
397
|
+
debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
|
|
385
398
|
)}
|
|
386
|
-
on:pointerenter={
|
|
387
|
-
on:pointermove={
|
|
388
|
-
on:pointerleave={
|
|
399
|
+
on:pointerenter={triggerPointerEvents ? showTooltip : undefined}
|
|
400
|
+
on:pointermove={triggerPointerEvents ? showTooltip : undefined}
|
|
401
|
+
on:pointerleave={triggerPointerEvents ? hideTooltip : undefined}
|
|
389
402
|
on:click={(e) => {
|
|
390
|
-
if (
|
|
403
|
+
if (triggerPointerEvents) {
|
|
391
404
|
onClick({ data: $tooltip?.data });
|
|
392
405
|
}
|
|
393
406
|
}}
|
|
@@ -19,6 +19,7 @@ declare const __propDef: {
|
|
|
19
19
|
* @type {'closest' | 'left' | 'right'}
|
|
20
20
|
*/ findTooltipData?: "closest" | "left" | "right";
|
|
21
21
|
/** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */ raiseTarget?: boolean;
|
|
22
|
+
/** Lock tooltip (keep open, do not update on mouse movement). Allows for kicking on tooltip */ locked?: boolean;
|
|
22
23
|
/** quadtree search radius
|
|
23
24
|
* @type {number}
|
|
24
25
|
*/ radius?: number;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { format as formatUtil, type FormatType } from '@layerstack/utils';
|
|
2
3
|
import { cls } from '@layerstack/tailwind';
|
|
3
4
|
|
|
5
|
+
export let value: any = undefined;
|
|
6
|
+
export let format: FormatType | undefined = undefined;
|
|
4
7
|
export let color: string | undefined = undefined;
|
|
5
8
|
|
|
6
9
|
export let classes: {
|
|
@@ -23,5 +26,5 @@
|
|
|
23
26
|
style:--color={color}
|
|
24
27
|
></div>
|
|
25
28
|
{/if}
|
|
26
|
-
<slot
|
|
29
|
+
<slot>{format ? formatUtil(value, format) : value}</slot>
|
|
27
30
|
</div>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import { type FormatType } from '@layerstack/utils';
|
|
2
3
|
declare const __propDef: {
|
|
3
4
|
props: {
|
|
4
5
|
[x: string]: any;
|
|
6
|
+
value?: any;
|
|
7
|
+
format?: FormatType | undefined;
|
|
5
8
|
color?: string | undefined | undefined;
|
|
6
9
|
classes?: {
|
|
7
10
|
root?: string;
|