layerchart 0.94.2 → 0.95.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.
- package/dist/components/Chart.svelte.d.ts +1 -0
- package/dist/components/Highlight.svelte +3 -2
- package/dist/components/charts/AreaChart.svelte +7 -0
- package/dist/components/charts/BarChart.svelte +7 -0
- package/dist/components/charts/LineChart.svelte +7 -0
- package/dist/components/charts/PieChart.svelte +7 -0
- package/dist/components/charts/PieChart.svelte.d.ts +1 -0
- package/dist/components/charts/ScatterChart.svelte +11 -0
- package/dist/components/tooltip/TooltipContext.svelte +25 -6
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +2 -1
- package/dist/components/tooltip/TooltipHeader.svelte +1 -1
- package/dist/components/tooltip/TooltipItem.svelte +12 -2
- package/dist/components/tooltip/TooltipItem.svelte.d.ts +3 -0
- package/package.json +2 -2
|
@@ -203,6 +203,7 @@ declare class __sveltets_Render<TData> {
|
|
|
203
203
|
hide: () => void;
|
|
204
204
|
mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
|
|
205
205
|
}>;
|
|
206
|
+
hideDelay?: number;
|
|
206
207
|
}> | undefined;
|
|
207
208
|
/** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
|
|
208
209
|
tooltipContext?: import("svelte/store").Writable<{
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { isScaleBand } from '../utils/scales.js';
|
|
20
20
|
import { accessor, type Accessor } from '../utils/common.js';
|
|
21
|
+
import { asAny } from '../utils/types.js';
|
|
21
22
|
|
|
22
23
|
const {
|
|
23
24
|
data: contextData,
|
|
@@ -424,14 +425,14 @@
|
|
|
424
425
|
onpointerenter={onpointenter &&
|
|
425
426
|
((e) => {
|
|
426
427
|
if (onpointclick) {
|
|
427
|
-
(e.target
|
|
428
|
+
asAny(e.target).style.cursor = 'pointer';
|
|
428
429
|
}
|
|
429
430
|
onpointenter(e, { point, data: highlightData });
|
|
430
431
|
})}
|
|
431
432
|
onpointerleave={onpointleave &&
|
|
432
433
|
((e) => {
|
|
433
434
|
if (onpointclick) {
|
|
434
|
-
(e.target
|
|
435
|
+
asAny(e.target).style.cursor = 'default';
|
|
435
436
|
}
|
|
436
437
|
onpointleave(e, { point, data: highlightData });
|
|
437
438
|
})}
|
|
@@ -166,6 +166,10 @@
|
|
|
166
166
|
|
|
167
167
|
let highlightSeriesKey: (typeof series)[number]['key'] | null = null;
|
|
168
168
|
|
|
169
|
+
function setHighlightSeriesKey(seriesKey: typeof highlightSeriesKey) {
|
|
170
|
+
highlightSeriesKey = seriesKey;
|
|
171
|
+
}
|
|
172
|
+
|
|
169
173
|
function getAreaProps(s: (typeof series)[number], i: number) {
|
|
170
174
|
const lineProps = {
|
|
171
175
|
...props.line,
|
|
@@ -336,6 +340,7 @@
|
|
|
336
340
|
getAreaProps,
|
|
337
341
|
getLabelsProps,
|
|
338
342
|
getPointsProps,
|
|
343
|
+
setHighlightSeriesKey,
|
|
339
344
|
}}
|
|
340
345
|
|
|
341
346
|
<slot {...slotProps}>
|
|
@@ -486,6 +491,8 @@
|
|
|
486
491
|
color={s.color}
|
|
487
492
|
{format}
|
|
488
493
|
valueAlign="right"
|
|
494
|
+
onpointerenter={() => (highlightSeriesKey = s.key)}
|
|
495
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
489
496
|
{...props.tooltip?.item}
|
|
490
497
|
/>
|
|
491
498
|
{/each}
|
|
@@ -196,6 +196,10 @@
|
|
|
196
196
|
|
|
197
197
|
let highlightSeriesKey: (typeof series)[number]['key'] | null = null;
|
|
198
198
|
|
|
199
|
+
function setHighlightSeriesKey(seriesKey: typeof highlightSeriesKey) {
|
|
200
|
+
highlightSeriesKey = seriesKey;
|
|
201
|
+
}
|
|
202
|
+
|
|
199
203
|
function getBarsProps(s: (typeof series)[number], i: number) {
|
|
200
204
|
const isFirst = i == 0;
|
|
201
205
|
const isLast = i == visibleSeries.length - 1;
|
|
@@ -343,6 +347,7 @@
|
|
|
343
347
|
visibleSeries,
|
|
344
348
|
getBarsProps,
|
|
345
349
|
getLabelsProps,
|
|
350
|
+
setHighlightSeriesKey,
|
|
346
351
|
}}
|
|
347
352
|
<slot {...slotProps}>
|
|
348
353
|
<slot name="belowContext" {...slotProps} />
|
|
@@ -474,6 +479,8 @@
|
|
|
474
479
|
color={s.color ?? cScale?.(c(data))}
|
|
475
480
|
{format}
|
|
476
481
|
valueAlign="right"
|
|
482
|
+
onpointerenter={() => (highlightSeriesKey = s.key)}
|
|
483
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
477
484
|
{...props.tooltip?.item}
|
|
478
485
|
/>
|
|
479
486
|
{/each}
|
|
@@ -132,6 +132,10 @@
|
|
|
132
132
|
|
|
133
133
|
let highlightSeriesKey: (typeof series)[number]['key'] | null = null;
|
|
134
134
|
|
|
135
|
+
function setHighlightSeriesKey(seriesKey: typeof highlightSeriesKey) {
|
|
136
|
+
highlightSeriesKey = seriesKey;
|
|
137
|
+
}
|
|
138
|
+
|
|
135
139
|
function getSplineProps(s: (typeof series)[number], i: number) {
|
|
136
140
|
const splineProps: ComponentProps<Spline> = {
|
|
137
141
|
data: s.data,
|
|
@@ -267,6 +271,7 @@
|
|
|
267
271
|
getLabelsProps,
|
|
268
272
|
getPointsProps,
|
|
269
273
|
getSplineProps,
|
|
274
|
+
setHighlightSeriesKey,
|
|
270
275
|
}}
|
|
271
276
|
<slot {...slotProps}>
|
|
272
277
|
<slot name="belowContext" {...slotProps} />
|
|
@@ -406,6 +411,8 @@
|
|
|
406
411
|
value={seriesTooltipData ? valueAccessor(seriesTooltipData) : null}
|
|
407
412
|
color={s.color}
|
|
408
413
|
{format}
|
|
414
|
+
onpointerenter={() => (highlightSeriesKey = s.key)}
|
|
415
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
409
416
|
{...props.tooltip?.item}
|
|
410
417
|
/>
|
|
411
418
|
{/each}
|
|
@@ -140,6 +140,10 @@
|
|
|
140
140
|
|
|
141
141
|
let highlightKey: (typeof series)[number]['key'] | null = null;
|
|
142
142
|
|
|
143
|
+
function setHighlightKey(key: typeof highlightKey) {
|
|
144
|
+
highlightKey = key ?? null;
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
const selectedKeys = selectionStore();
|
|
144
148
|
$: visibleData = chartData.filter((d) => {
|
|
145
149
|
const dataKey = keyAccessor(d);
|
|
@@ -204,6 +208,7 @@
|
|
|
204
208
|
tooltip,
|
|
205
209
|
series,
|
|
206
210
|
visibleData,
|
|
211
|
+
setHighlightKey,
|
|
207
212
|
}}
|
|
208
213
|
<slot {...slotProps}>
|
|
209
214
|
<slot name="belowContext" {...slotProps} />
|
|
@@ -331,6 +336,8 @@
|
|
|
331
336
|
value={valueAccessor(data)}
|
|
332
337
|
color={cScale?.(c(data))}
|
|
333
338
|
{format}
|
|
339
|
+
onpointerenter={() => (highlightKey = keyAccessor(data))}
|
|
340
|
+
onpointerleave={() => (highlightKey = null)}
|
|
334
341
|
{...props.tooltip?.item}
|
|
335
342
|
/>
|
|
336
343
|
</Tooltip.List>
|
|
@@ -139,6 +139,7 @@ declare class __sveltets_Render<TData> {
|
|
|
139
139
|
hide: () => void;
|
|
140
140
|
mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
|
|
141
141
|
}>;
|
|
142
|
+
hideDelay?: number;
|
|
142
143
|
}> | undefined;
|
|
143
144
|
tooltipContext?: import("svelte/store").Writable<{
|
|
144
145
|
x: number;
|
|
@@ -113,6 +113,10 @@
|
|
|
113
113
|
|
|
114
114
|
let highlightSeriesKey: (typeof series)[number]['key'] | null = null;
|
|
115
115
|
|
|
116
|
+
function setHighlightSeriesKey(seriesKey: typeof highlightSeriesKey) {
|
|
117
|
+
highlightSeriesKey = seriesKey ?? null;
|
|
118
|
+
}
|
|
119
|
+
|
|
116
120
|
function getPointsProps(s: (typeof series)[number], i: number) {
|
|
117
121
|
const pointsProps: ComponentProps<Points> = {
|
|
118
122
|
data: s.data,
|
|
@@ -229,6 +233,7 @@
|
|
|
229
233
|
visibleSeries,
|
|
230
234
|
getLabelsProps,
|
|
231
235
|
getPointsProps,
|
|
236
|
+
setHighlightSeriesKey,
|
|
232
237
|
}}
|
|
233
238
|
{@const activeSeries = tooltip.data
|
|
234
239
|
? (series.find((s) => s.key === tooltip.data.seriesKey) ?? series[0])
|
|
@@ -349,12 +354,16 @@
|
|
|
349
354
|
label={typeof config.x === 'string' ? config.x : 'x'}
|
|
350
355
|
value={x(data)}
|
|
351
356
|
{format}
|
|
357
|
+
onpointerenter={() => (highlightSeriesKey = activeSeries?.key ?? null)}
|
|
358
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
352
359
|
{...props.tooltip?.item}
|
|
353
360
|
/>
|
|
354
361
|
<Tooltip.Item
|
|
355
362
|
label={typeof config.y === 'string' ? config.y : 'y'}
|
|
356
363
|
value={y(data)}
|
|
357
364
|
{format}
|
|
365
|
+
onpointerenter={() => (highlightSeriesKey = activeSeries?.key ?? null)}
|
|
366
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
358
367
|
{...props.tooltip?.item}
|
|
359
368
|
/>
|
|
360
369
|
{#if config.r}
|
|
@@ -362,6 +371,8 @@
|
|
|
362
371
|
label={typeof config.r === 'string' ? config.r : 'r'}
|
|
363
372
|
value={r(data)}
|
|
364
373
|
{format}
|
|
374
|
+
onpointerenter={() => (highlightSeriesKey = activeSeries?.key ?? null)}
|
|
375
|
+
onpointerleave={() => (highlightSeriesKey = null)}
|
|
365
376
|
{...props.tooltip?.item}
|
|
366
377
|
/>
|
|
367
378
|
{/if}
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
/** 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 */
|
|
102
102
|
export let raiseTarget = false;
|
|
103
103
|
|
|
104
|
-
/** Lock tooltip (keep open, do not update on mouse movement). Allows for
|
|
104
|
+
/** Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip */
|
|
105
105
|
export let locked = false;
|
|
106
106
|
|
|
107
107
|
/** quadtree search radius
|
|
@@ -124,6 +124,10 @@
|
|
|
124
124
|
});
|
|
125
125
|
setTooltipContext(tooltip);
|
|
126
126
|
|
|
127
|
+
/** Delay in ms before hiding tooltip */
|
|
128
|
+
export let hideDelay = 0;
|
|
129
|
+
|
|
130
|
+
let isHoveringTooltip = false;
|
|
127
131
|
let hideTimeoutId: NodeJS.Timeout;
|
|
128
132
|
|
|
129
133
|
$: bisectX = bisector((d: any) => {
|
|
@@ -175,7 +179,9 @@
|
|
|
175
179
|
|
|
176
180
|
function showTooltip(e: PointerEvent, tooltipData?: any) {
|
|
177
181
|
// Cancel hiding tooltip if from previous event loop
|
|
178
|
-
|
|
182
|
+
if (hideTimeoutId) {
|
|
183
|
+
clearTimeout(hideTimeoutId);
|
|
184
|
+
}
|
|
179
185
|
|
|
180
186
|
if (locked) {
|
|
181
187
|
// Ignore (keep current position / data)
|
|
@@ -294,9 +300,12 @@
|
|
|
294
300
|
}
|
|
295
301
|
|
|
296
302
|
// Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
|
|
303
|
+
// Additional hideDelay can be configured to extend this delay further
|
|
297
304
|
hideTimeoutId = setTimeout(() => {
|
|
298
|
-
|
|
299
|
-
|
|
305
|
+
if (!isHoveringTooltip) {
|
|
306
|
+
$tooltip = { ...$tooltip, data: null };
|
|
307
|
+
}
|
|
308
|
+
}, hideDelay);
|
|
300
309
|
}
|
|
301
310
|
|
|
302
311
|
let quadtree: Quadtree<[number, number]>;
|
|
@@ -401,9 +410,19 @@
|
|
|
401
410
|
'TooltipContext absolute touch-none',
|
|
402
411
|
debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
|
|
403
412
|
)}
|
|
404
|
-
on:pointerenter={
|
|
413
|
+
on:pointerenter={(e) => {
|
|
414
|
+
isHoveringTooltip = true;
|
|
415
|
+
if (triggerPointerEvents) {
|
|
416
|
+
showTooltip(e);
|
|
417
|
+
}
|
|
418
|
+
}}
|
|
405
419
|
on:pointermove={triggerPointerEvents ? showTooltip : undefined}
|
|
406
|
-
on:pointerleave={
|
|
420
|
+
on:pointerleave={(e) => {
|
|
421
|
+
isHoveringTooltip = false;
|
|
422
|
+
if (triggerPointerEvents) {
|
|
423
|
+
hideTooltip();
|
|
424
|
+
}
|
|
425
|
+
}}
|
|
407
426
|
on:click={(e) => {
|
|
408
427
|
if (triggerPointerEvents) {
|
|
409
428
|
onclick(e, { data: $tooltip?.data });
|
|
@@ -21,7 +21,7 @@ declare const __propDef: {
|
|
|
21
21
|
* @type {'closest' | 'left' | 'right'}
|
|
22
22
|
*/ findTooltipData?: "closest" | "left" | "right";
|
|
23
23
|
/** 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;
|
|
24
|
-
/** Lock tooltip (keep open, do not update on mouse movement). Allows for
|
|
24
|
+
/** Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip */ locked?: boolean;
|
|
25
25
|
/** quadtree search radius
|
|
26
26
|
* @type {number}
|
|
27
27
|
*/ radius?: number;
|
|
@@ -37,6 +37,7 @@ declare const __propDef: {
|
|
|
37
37
|
hide: () => void;
|
|
38
38
|
mode: TooltipMode;
|
|
39
39
|
}>;
|
|
40
|
+
/** Delay in ms before hiding tooltip */ hideDelay?: number;
|
|
40
41
|
};
|
|
41
42
|
events: {
|
|
42
43
|
[evt: string]: CustomEvent<any>;
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
export let valueAlign: 'left' | 'right' | 'center' = 'left';
|
|
10
10
|
export let color: string | undefined = undefined;
|
|
11
11
|
|
|
12
|
+
export let onclick: ((e: MouseEvent) => void) | undefined = undefined;
|
|
13
|
+
export let onpointerenter: ((e: PointerEvent) => void) | undefined = undefined;
|
|
14
|
+
export let onpointerleave: ((e: PointerEvent) => void) | undefined = undefined;
|
|
15
|
+
|
|
12
16
|
export let classes: {
|
|
13
17
|
root?: string;
|
|
14
18
|
label?: string;
|
|
@@ -17,11 +21,17 @@
|
|
|
17
21
|
} = {};
|
|
18
22
|
</script>
|
|
19
23
|
|
|
20
|
-
<div
|
|
24
|
+
<div
|
|
25
|
+
class={cls('contents', classes.root, $$props.class)}
|
|
26
|
+
on:click={onclick}
|
|
27
|
+
on:pointerenter={onpointerenter}
|
|
28
|
+
on:pointerleave={onpointerleave}
|
|
29
|
+
{...$$restProps}
|
|
30
|
+
>
|
|
21
31
|
<div class={cls('label', 'flex items-center gap-2 whitespace-nowrap', classes.label)}>
|
|
22
32
|
{#if color}
|
|
23
33
|
<div
|
|
24
|
-
class={cls('color', 'inline-block size-2 rounded-full bg-[--color]', classes.color)}
|
|
34
|
+
class={cls('color', 'inline-block size-2 rounded-full bg-[var(--color)]', classes.color)}
|
|
25
35
|
style:--color={color}
|
|
26
36
|
></div>
|
|
27
37
|
{/if}
|
|
@@ -8,6 +8,9 @@ declare const __propDef: {
|
|
|
8
8
|
format?: FormatType | undefined;
|
|
9
9
|
valueAlign?: "left" | "right" | "center" | undefined;
|
|
10
10
|
color?: string | undefined | undefined;
|
|
11
|
+
onclick?: ((e: MouseEvent) => void) | undefined | undefined;
|
|
12
|
+
onpointerenter?: ((e: PointerEvent) => void) | undefined | undefined;
|
|
13
|
+
onpointerleave?: ((e: PointerEvent) => void) | undefined | undefined;
|
|
11
14
|
classes?: {
|
|
12
15
|
root?: string;
|
|
13
16
|
label?: string;
|
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.
|
|
7
|
+
"version": "0.95.0",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@changesets/cli": "^2.27.12",
|
|
10
10
|
"@mdi/js": "^7.4.47",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"rehype-slug": "^6.0.0",
|
|
51
51
|
"shapefile": "^0.6.6",
|
|
52
52
|
"solar-calculator": "^0.3.0",
|
|
53
|
-
"svelte": "
|
|
53
|
+
"svelte": "5.19.4",
|
|
54
54
|
"svelte-check": "^4.1.4",
|
|
55
55
|
"svelte-json-tree": "^2.2.0",
|
|
56
56
|
"svelte-ux": "^0.90.0",
|