layerchart 0.81.3 → 0.91.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/Arc.svelte +49 -14
- package/dist/components/Area.svelte +35 -11
- package/dist/components/Bar.svelte +15 -10
- package/dist/components/Bars.svelte +3 -3
- package/dist/components/Brush.svelte +38 -33
- package/dist/components/Calendar.svelte +2 -2
- package/dist/components/Chart.svelte +17 -4
- package/dist/components/Chart.svelte.d.ts +21 -10
- package/dist/components/ChartClipPath.svelte +0 -1
- package/dist/components/ChartClipPath.svelte.d.ts +0 -2
- package/dist/components/ChartContext.svelte +4 -11
- package/dist/components/ChartContext.svelte.d.ts +1 -1
- package/dist/components/Circle.svelte +35 -11
- package/dist/components/ClipPath.svelte +1 -1
- package/dist/components/ClipPath.svelte.d.ts +0 -5
- package/dist/components/ForceSimulation.svelte +8 -12
- package/dist/components/ForceSimulation.svelte.d.ts +6 -8
- package/dist/components/Frame.svelte +4 -7
- package/dist/components/Frame.svelte.d.ts +1 -5
- package/dist/components/GeoCircle.svelte +7 -1
- package/dist/components/GeoCircle.svelte.d.ts +6 -7
- package/dist/components/GeoPath.svelte +68 -39
- package/dist/components/GeoPath.svelte.d.ts +6 -12
- package/dist/components/GeoPoint.svelte +3 -24
- package/dist/components/GeoPoint.svelte.d.ts +4 -5
- package/dist/components/Graticule.svelte.d.ts +12 -6
- package/dist/components/Group.svelte +26 -6
- package/dist/components/Highlight.svelte +22 -12
- package/dist/components/Hull.svelte +20 -15
- package/dist/components/Hull.svelte.d.ts +7 -9
- package/dist/components/Legend.svelte +7 -7
- package/dist/components/Legend.svelte.d.ts +3 -3
- package/dist/components/Line.svelte +35 -10
- package/dist/components/Link.svelte +16 -9
- package/dist/components/Points.svelte +24 -57
- package/dist/components/Points.svelte.d.ts +0 -1
- package/dist/components/Rect.svelte +46 -15
- package/dist/components/Sankey.svelte +3 -4
- package/dist/components/Sankey.svelte.d.ts +1 -2
- package/dist/components/Spline.svelte +47 -11
- package/dist/components/Text.svelte +12 -6
- package/dist/components/TransformContext.svelte +8 -10
- package/dist/components/TransformContext.svelte.d.ts +9 -9
- package/dist/components/Voronoi.svelte +62 -40
- package/dist/components/Voronoi.svelte.d.ts +14 -13
- package/dist/components/charts/AreaChart.svelte +25 -17
- package/dist/components/charts/BarChart.svelte +24 -11
- package/dist/components/charts/LineChart.svelte +25 -17
- package/dist/components/charts/PieChart.svelte +22 -15
- package/dist/components/charts/PieChart.svelte.d.ts +29 -7
- package/dist/components/charts/ScatterChart.svelte +15 -9
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.js +0 -1
- package/dist/components/layout/Canvas.svelte +148 -7
- package/dist/components/layout/Canvas.svelte.d.ts +15 -2
- package/dist/components/tooltip/TooltipContext.svelte +25 -20
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +6 -2
- package/dist/utils/canvas.js +39 -33
- package/dist/utils/color.d.ts +15 -0
- package/dist/utils/color.js +15 -0
- package/package.json +1 -1
- package/dist/components/Brush.svelte.d.ts +0 -65
- package/dist/components/HitCanvas.svelte +0 -118
- package/dist/components/HitCanvas.svelte.d.ts +0 -32
|
@@ -4,12 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
export const tooltipContextKey = Symbol();
|
|
6
6
|
|
|
7
|
+
type TooltipMode =
|
|
8
|
+
| 'bisect-x'
|
|
9
|
+
| 'bisect-y'
|
|
10
|
+
| 'band'
|
|
11
|
+
| 'bisect-band'
|
|
12
|
+
| 'bounds'
|
|
13
|
+
| 'voronoi'
|
|
14
|
+
| 'quadtree'
|
|
15
|
+
| 'manual';
|
|
16
|
+
|
|
7
17
|
export type TooltipContextValue = {
|
|
8
18
|
x: number;
|
|
9
19
|
y: number;
|
|
10
20
|
data: any;
|
|
11
21
|
show(e: PointerEvent, tooltipData?: any): void;
|
|
12
22
|
hide(e?: PointerEvent): void;
|
|
23
|
+
mode: TooltipMode;
|
|
13
24
|
};
|
|
14
25
|
|
|
15
26
|
export type TooltipContext = Readable<TooltipContextValue>;
|
|
@@ -20,6 +31,7 @@
|
|
|
20
31
|
data: null as any,
|
|
21
32
|
show: () => {},
|
|
22
33
|
hide: () => {},
|
|
34
|
+
mode: 'manual',
|
|
23
35
|
});
|
|
24
36
|
export function tooltipContext() {
|
|
25
37
|
return getContext<TooltipContext>(tooltipContextKey) ?? defaultContext;
|
|
@@ -80,15 +92,7 @@
|
|
|
80
92
|
/**
|
|
81
93
|
* @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
|
|
82
94
|
*/
|
|
83
|
-
export let mode:
|
|
84
|
-
| 'bisect-x'
|
|
85
|
-
| 'bisect-y'
|
|
86
|
-
| 'band'
|
|
87
|
-
| 'bisect-band'
|
|
88
|
-
| 'bounds'
|
|
89
|
-
| 'voronoi'
|
|
90
|
-
| 'quadtree'
|
|
91
|
-
| 'manual' = 'manual';
|
|
95
|
+
export let mode: TooltipMode = 'manual';
|
|
92
96
|
/**
|
|
93
97
|
* @type {'closest' | 'left' | 'right'}
|
|
94
98
|
*/
|
|
@@ -107,7 +111,7 @@
|
|
|
107
111
|
/** Enable debug view (show hit targets, etc) */
|
|
108
112
|
export let debug = false;
|
|
109
113
|
|
|
110
|
-
export let
|
|
114
|
+
export let onclick: ({ data }: { data: any }) => any = () => {};
|
|
111
115
|
|
|
112
116
|
/** Exposed to allow binding in Chart */
|
|
113
117
|
export let tooltip = writable({
|
|
@@ -116,6 +120,7 @@
|
|
|
116
120
|
data: null as any,
|
|
117
121
|
show: showTooltip,
|
|
118
122
|
hide: hideTooltip,
|
|
123
|
+
mode,
|
|
119
124
|
});
|
|
120
125
|
setTooltipContext(tooltip);
|
|
121
126
|
|
|
@@ -401,7 +406,7 @@
|
|
|
401
406
|
on:pointerleave={triggerPointerEvents ? hideTooltip : undefined}
|
|
402
407
|
on:click={(e) => {
|
|
403
408
|
if (triggerPointerEvents) {
|
|
404
|
-
|
|
409
|
+
onclick({ data: $tooltip?.data });
|
|
405
410
|
}
|
|
406
411
|
}}
|
|
407
412
|
>
|
|
@@ -418,22 +423,22 @@
|
|
|
418
423
|
{#if mode === 'voronoi'}
|
|
419
424
|
<Svg>
|
|
420
425
|
<Voronoi
|
|
421
|
-
|
|
422
|
-
showTooltip(e
|
|
426
|
+
onpointerenter={(e, { data }) => {
|
|
427
|
+
showTooltip(e, data);
|
|
423
428
|
}}
|
|
424
|
-
|
|
425
|
-
showTooltip(e
|
|
429
|
+
onpointermove={(e, { data }) => {
|
|
430
|
+
showTooltip(e, data);
|
|
426
431
|
}}
|
|
427
|
-
|
|
428
|
-
|
|
432
|
+
onpointerleave={hideTooltip}
|
|
433
|
+
onpointerdown={(e) => {
|
|
429
434
|
// @ts-expect-error
|
|
430
435
|
if (e.target?.hasPointerCapture(e.pointerId)) {
|
|
431
436
|
// @ts-expect-error
|
|
432
437
|
e.target.releasePointerCapture(e.pointerId);
|
|
433
438
|
}
|
|
434
439
|
}}
|
|
435
|
-
|
|
436
|
-
|
|
440
|
+
onclick={(e, { data }) => {
|
|
441
|
+
onclick({ data });
|
|
437
442
|
}}
|
|
438
443
|
classes={{ path: cls(debug && 'fill-danger/10 stroke-danger') }}
|
|
439
444
|
/>
|
|
@@ -459,7 +464,7 @@
|
|
|
459
464
|
}
|
|
460
465
|
}}
|
|
461
466
|
on:click={(e) => {
|
|
462
|
-
|
|
467
|
+
onclick({ data: rect.data });
|
|
463
468
|
}}
|
|
464
469
|
/>
|
|
465
470
|
{/each}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { Readable } from 'svelte/store';
|
|
3
3
|
export declare const tooltipContextKey: unique symbol;
|
|
4
|
+
type TooltipMode = 'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual';
|
|
4
5
|
export type TooltipContextValue = {
|
|
5
6
|
x: number;
|
|
6
7
|
y: number;
|
|
7
8
|
data: any;
|
|
8
9
|
show(e: PointerEvent, tooltipData?: any): void;
|
|
9
10
|
hide(e?: PointerEvent): void;
|
|
11
|
+
mode: TooltipMode;
|
|
10
12
|
};
|
|
11
13
|
export type TooltipContext = Readable<TooltipContextValue>;
|
|
12
14
|
export declare function tooltipContext(): TooltipContext;
|
|
@@ -14,7 +16,7 @@ declare const __propDef: {
|
|
|
14
16
|
props: {
|
|
15
17
|
/**
|
|
16
18
|
* @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
|
|
17
|
-
*/ mode?:
|
|
19
|
+
*/ mode?: TooltipMode;
|
|
18
20
|
/**
|
|
19
21
|
* @type {'closest' | 'left' | 'right'}
|
|
20
22
|
*/ findTooltipData?: "closest" | "left" | "right";
|
|
@@ -24,7 +26,7 @@ declare const __propDef: {
|
|
|
24
26
|
* @type {number}
|
|
25
27
|
*/ radius?: number;
|
|
26
28
|
/** Enable debug view (show hit targets, etc) */ debug?: boolean;
|
|
27
|
-
|
|
29
|
+
onclick?: ({ data }: {
|
|
28
30
|
data: any;
|
|
29
31
|
}) => any;
|
|
30
32
|
/** Exposed to allow binding in Chart */ tooltip?: import("svelte/store").Writable<{
|
|
@@ -33,6 +35,7 @@ declare const __propDef: {
|
|
|
33
35
|
data: any;
|
|
34
36
|
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
35
37
|
hide: () => void;
|
|
38
|
+
mode: TooltipMode;
|
|
36
39
|
}>;
|
|
37
40
|
};
|
|
38
41
|
events: {
|
|
@@ -46,6 +49,7 @@ declare const __propDef: {
|
|
|
46
49
|
data: any;
|
|
47
50
|
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
48
51
|
hide: () => void;
|
|
52
|
+
mode: TooltipMode;
|
|
49
53
|
};
|
|
50
54
|
};
|
|
51
55
|
};
|
package/dist/utils/canvas.js
CHANGED
|
@@ -39,40 +39,40 @@ export function getComputedStyles(canvas, { styles, classes } = {}) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
/** Render onto canvas context. Supports CSS variables and classes by tranferring to hidden `<svg>` element before retrieval) */
|
|
42
|
-
function render(
|
|
42
|
+
function render(ctx, render, styleOptions = {}) {
|
|
43
43
|
// console.count('render');
|
|
44
44
|
// TODO: Consider memoizing? How about reactiving to CSS variable changes (light/dark mode toggle)
|
|
45
|
-
const computedStyles = getComputedStyles(
|
|
45
|
+
const computedStyles = getComputedStyles(ctx.canvas, styleOptions);
|
|
46
46
|
// Adhere to CSS paint order: https://developer.mozilla.org/en-US/docs/Web/CSS/paint-order
|
|
47
47
|
const paintOrder = computedStyles?.paintOrder === 'stroke' ? ['stroke', 'fill'] : ['fill', 'stroke'];
|
|
48
48
|
if (computedStyles?.opacity) {
|
|
49
|
-
|
|
49
|
+
ctx.globalAlpha = Number(computedStyles?.opacity);
|
|
50
50
|
}
|
|
51
51
|
// Text properties
|
|
52
|
-
|
|
52
|
+
ctx.font = `${computedStyles.fontSize} ${computedStyles.fontFamily}`; // build string instead of using `computedStyles.font` to fix/workaround `tabular-nums` returning `null`
|
|
53
53
|
// TODO: Hack to handle `textAnchor` with canvas. Try to find a better approach
|
|
54
54
|
if (computedStyles.textAnchor === 'middle') {
|
|
55
|
-
|
|
55
|
+
ctx.textAlign = 'center';
|
|
56
56
|
}
|
|
57
57
|
else if (computedStyles.textAnchor === 'end') {
|
|
58
|
-
|
|
58
|
+
ctx.textAlign = 'right';
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
|
|
61
|
+
ctx.textAlign = computedStyles.textAlign; // TODO: Handle/map `justify` and `match-parent`?
|
|
62
62
|
}
|
|
63
63
|
// TODO: Handle `textBaseline` / `verticalAnchor` (Text)
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
64
|
+
// ctx.textBaseline = 'top';
|
|
65
|
+
// ctx.textBaseline = 'middle';
|
|
66
|
+
// ctx.textBaseline = 'bottom';
|
|
67
|
+
// ctx.textBaseline = 'alphabetic';
|
|
68
|
+
// ctx.textBaseline = 'hanging';
|
|
69
|
+
// ctx.textBaseline = 'ideographic';
|
|
70
70
|
// Dashed lines
|
|
71
71
|
if (computedStyles.strokeDasharray.includes(',')) {
|
|
72
72
|
const dashArray = computedStyles.strokeDasharray
|
|
73
73
|
.split(',')
|
|
74
74
|
.map((s) => Number(s.replace('px', '')));
|
|
75
|
-
|
|
75
|
+
ctx.setLineDash(dashArray);
|
|
76
76
|
}
|
|
77
77
|
paintOrder.forEach((attr) => {
|
|
78
78
|
if (attr === 'fill') {
|
|
@@ -82,14 +82,14 @@ function render(canvasCtx, render, styleOptions = {}) {
|
|
|
82
82
|
? null
|
|
83
83
|
: computedStyles?.fill;
|
|
84
84
|
if (fill) {
|
|
85
|
-
const currentGlobalAlpha =
|
|
85
|
+
const currentGlobalAlpha = ctx.globalAlpha;
|
|
86
86
|
const fillOpacity = Number(computedStyles?.fillOpacity);
|
|
87
87
|
const opacity = Number(computedStyles?.opacity);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
render.fill(
|
|
88
|
+
ctx.globalAlpha = fillOpacity * opacity;
|
|
89
|
+
ctx.fillStyle = fill;
|
|
90
|
+
render.fill(ctx);
|
|
91
91
|
// Restore in case it was modified by `fillOpacity`
|
|
92
|
-
|
|
92
|
+
ctx.globalAlpha = currentGlobalAlpha;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
else if (attr === 'stroke') {
|
|
@@ -99,42 +99,42 @@ function render(canvasCtx, render, styleOptions = {}) {
|
|
|
99
99
|
? null
|
|
100
100
|
: computedStyles?.stroke;
|
|
101
101
|
if (stroke) {
|
|
102
|
-
|
|
102
|
+
ctx.lineWidth =
|
|
103
103
|
typeof computedStyles?.strokeWidth === 'string'
|
|
104
104
|
? Number(computedStyles?.strokeWidth?.replace('px', ''))
|
|
105
105
|
: (computedStyles?.strokeWidth ?? 1);
|
|
106
|
-
|
|
107
|
-
render.stroke(
|
|
106
|
+
ctx.strokeStyle = stroke;
|
|
107
|
+
render.stroke(ctx);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
/** Render SVG path data onto canvas context. Supports CSS variables and classes by tranferring to hidden `<svg>` element before retrieval) */
|
|
113
|
-
export function renderPathData(
|
|
113
|
+
export function renderPathData(ctx, pathData, styleOptions = {}) {
|
|
114
114
|
const path = new Path2D(pathData ?? '');
|
|
115
|
-
render(
|
|
115
|
+
render(ctx, {
|
|
116
116
|
fill: (ctx) => ctx.fill(path),
|
|
117
117
|
stroke: (ctx) => ctx.stroke(path),
|
|
118
118
|
}, styleOptions);
|
|
119
119
|
}
|
|
120
|
-
export function renderText(
|
|
120
|
+
export function renderText(ctx, text, coords, styleOptions = {}) {
|
|
121
121
|
if (text) {
|
|
122
|
-
render(
|
|
122
|
+
render(ctx, {
|
|
123
123
|
fill: (ctx) => ctx.fillText(text.toString(), coords.x, coords.y),
|
|
124
124
|
stroke: (ctx) => ctx.strokeText(text.toString(), coords.x, coords.y),
|
|
125
125
|
}, styleOptions);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
export function renderRect(
|
|
129
|
-
render(
|
|
128
|
+
export function renderRect(ctx, coords, styleOptions = {}) {
|
|
129
|
+
render(ctx, {
|
|
130
130
|
fill: (ctx) => ctx.fillRect(coords.x, coords.y, coords.width, coords.height),
|
|
131
131
|
stroke: (ctx) => ctx.strokeRect(coords.x, coords.y, coords.width, coords.height),
|
|
132
132
|
}, styleOptions);
|
|
133
133
|
}
|
|
134
134
|
/** Clear canvas accounting for Canvas `context.translate(...)` */
|
|
135
|
-
export function clearCanvasContext(
|
|
135
|
+
export function clearCanvasContext(ctx, options) {
|
|
136
136
|
// Clear with negative offset due to Canvas `context.translate(...)`
|
|
137
|
-
|
|
137
|
+
ctx.clearRect(-options.padding.left, -options.padding.top, options.containerWidth, options.containerHeight);
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
140
|
Scales a canvas for high DPI / retina displays.
|
|
@@ -150,15 +150,21 @@ export function scaleCanvas(ctx, width, height) {
|
|
|
150
150
|
ctx.scale(devicePixelRatio, devicePixelRatio);
|
|
151
151
|
return { width: ctx.canvas.width, height: ctx.canvas.height };
|
|
152
152
|
}
|
|
153
|
-
export function _createLinearGradient(
|
|
154
|
-
const gradient =
|
|
153
|
+
export function _createLinearGradient(ctx, x0, y0, x1, y1, stops) {
|
|
154
|
+
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
155
155
|
stops.forEach(({ offset, color }) => {
|
|
156
156
|
gradient.addColorStop(offset, color);
|
|
157
157
|
});
|
|
158
158
|
return gradient;
|
|
159
159
|
}
|
|
160
160
|
/** Create linear gradient and memoize result to fix reactivity */
|
|
161
|
-
export const createLinearGradient = memoize(_createLinearGradient, (
|
|
161
|
+
export const createLinearGradient = memoize(_createLinearGradient, (ctx, x0, y0, x1, y1, stops) => {
|
|
162
162
|
const key = JSON.stringify({ x0, y0, x1, y1, stops });
|
|
163
163
|
return key;
|
|
164
164
|
});
|
|
165
|
+
export function getPixelColor(ctx, x, y) {
|
|
166
|
+
const dpr = window.devicePixelRatio ?? 1;
|
|
167
|
+
const imageData = ctx.getImageData(x * dpr, y * dpr, 1, 1);
|
|
168
|
+
const [r, g, b, a] = imageData.data;
|
|
169
|
+
return { r, g, b, a };
|
|
170
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Generator to create a new color on each call */
|
|
2
|
+
export declare function rgbColorGenerator(step?: number): Generator<{
|
|
3
|
+
r: number;
|
|
4
|
+
g: number;
|
|
5
|
+
b: number;
|
|
6
|
+
}, {
|
|
7
|
+
r: number;
|
|
8
|
+
g: number;
|
|
9
|
+
b: number;
|
|
10
|
+
}, unknown>;
|
|
11
|
+
export declare function getColorStr(color: {
|
|
12
|
+
r: number;
|
|
13
|
+
g: number;
|
|
14
|
+
b: number;
|
|
15
|
+
}): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Generator to create a new color on each call */
|
|
2
|
+
export function* rgbColorGenerator(step = 500) {
|
|
3
|
+
let nextColor = 1;
|
|
4
|
+
while (nextColor < 16777216) {
|
|
5
|
+
const r = nextColor & 0xff;
|
|
6
|
+
const g = (nextColor & 0xff00) >> 8;
|
|
7
|
+
const b = (nextColor & 0xff0000) >> 16;
|
|
8
|
+
nextColor += step;
|
|
9
|
+
yield { r, g, b };
|
|
10
|
+
}
|
|
11
|
+
return { r: 0, g: 0, b: 0 };
|
|
12
|
+
}
|
|
13
|
+
export function getColorStr(color) {
|
|
14
|
+
return `rgb(${color.r},${color.g},${color.b})`;
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import { type ComponentProps } from 'svelte';
|
|
3
|
-
import type { SVGAttributes } from 'svelte/elements';
|
|
4
|
-
import { type FormatType } from '@layerstack/utils';
|
|
5
|
-
import Text from './Text.svelte';
|
|
6
|
-
import type { DomainType } from '../utils/scales.js';
|
|
7
|
-
declare const __propDef: {
|
|
8
|
-
props: {
|
|
9
|
-
[x: string]: any;
|
|
10
|
-
axis?: "x" | "y" | "both" | undefined;
|
|
11
|
-
handleSize?: number | undefined;
|
|
12
|
-
resetOnEnd?: boolean | undefined;
|
|
13
|
-
xDomain?: DomainType | undefined;
|
|
14
|
-
yDomain?: DomainType | undefined;
|
|
15
|
-
labels?: (ComponentProps<Text> | boolean) | undefined;
|
|
16
|
-
mode?: "integrated" | "separated" | undefined;
|
|
17
|
-
range?: SVGAttributes<SVGRectElement> | undefined;
|
|
18
|
-
handle?: SVGAttributes<SVGRectElement> | undefined;
|
|
19
|
-
format?: FormatType | undefined;
|
|
20
|
-
classes?: {
|
|
21
|
-
root?: string;
|
|
22
|
-
frame?: string;
|
|
23
|
-
range?: string;
|
|
24
|
-
handle?: string;
|
|
25
|
-
labels?: string;
|
|
26
|
-
} | undefined;
|
|
27
|
-
onChange?: ((e: {
|
|
28
|
-
xDomain?: DomainType;
|
|
29
|
-
yDomain?: DomainType;
|
|
30
|
-
}) => void) | undefined;
|
|
31
|
-
onBrushStart?: ((e: {
|
|
32
|
-
xDomain?: DomainType;
|
|
33
|
-
yDomain?: DomainType;
|
|
34
|
-
}) => void) | undefined;
|
|
35
|
-
onBrushEnd?: ((e: {
|
|
36
|
-
xDomain?: DomainType;
|
|
37
|
-
yDomain?: DomainType;
|
|
38
|
-
}) => void) | undefined;
|
|
39
|
-
onReset?: ((e: {
|
|
40
|
-
xDomain?: DomainType;
|
|
41
|
-
yDomain?: DomainType;
|
|
42
|
-
}) => void) | undefined;
|
|
43
|
-
};
|
|
44
|
-
events: {
|
|
45
|
-
[evt: string]: CustomEvent<any>;
|
|
46
|
-
};
|
|
47
|
-
slots: {
|
|
48
|
-
range: {
|
|
49
|
-
rangeWidth: any;
|
|
50
|
-
rangeHeight: any;
|
|
51
|
-
};
|
|
52
|
-
handle: {
|
|
53
|
-
edge: string;
|
|
54
|
-
rangeWidth: any;
|
|
55
|
-
rangeHeight: any;
|
|
56
|
-
};
|
|
57
|
-
labels: {};
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
export type BrushProps = typeof __propDef.props;
|
|
61
|
-
export type BrushEvents = typeof __propDef.events;
|
|
62
|
-
export type BrushSlots = typeof __propDef.slots;
|
|
63
|
-
export default class Brush extends SvelteComponentTyped<BrushProps, BrushEvents, BrushSlots> {
|
|
64
|
-
}
|
|
65
|
-
export {};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { createEventDispatcher } from 'svelte';
|
|
3
|
-
import { cls } from '@layerstack/tailwind';
|
|
4
|
-
|
|
5
|
-
import { chartContext } from './ChartContext.svelte';
|
|
6
|
-
import Canvas from './layout/Canvas.svelte';
|
|
7
|
-
import { transformContext } from './TransformContext.svelte';
|
|
8
|
-
|
|
9
|
-
const { width, height } = chartContext();
|
|
10
|
-
|
|
11
|
-
// @ts-expect-error: this will immediately be defined on mount via `bind:context`
|
|
12
|
-
export let context: CanvasRenderingContext2D = undefined;
|
|
13
|
-
|
|
14
|
-
/** Show canvas for debugging */
|
|
15
|
-
export let debug = false;
|
|
16
|
-
|
|
17
|
-
const dispatch = createEventDispatcher<{
|
|
18
|
-
pointermove: {
|
|
19
|
-
event: PointerEvent;
|
|
20
|
-
data: any;
|
|
21
|
-
};
|
|
22
|
-
click: {
|
|
23
|
-
event: MouseEvent;
|
|
24
|
-
data: any;
|
|
25
|
-
};
|
|
26
|
-
}>();
|
|
27
|
-
|
|
28
|
-
function* rgbColorGenerator(step = 500) {
|
|
29
|
-
let nextColor = 1;
|
|
30
|
-
|
|
31
|
-
while (nextColor < 16777216) {
|
|
32
|
-
const rgb = [
|
|
33
|
-
nextColor & 0xff, // red
|
|
34
|
-
(nextColor & 0xff00) >> 8, // green
|
|
35
|
-
(nextColor & 0xff0000) >> 16, // blue
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
nextColor += step;
|
|
39
|
-
yield `rgb(${rgb.join(',')})`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return 'rgb(0,0,0)';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
$: colorGenerator = rgbColorGenerator();
|
|
46
|
-
|
|
47
|
-
// Reset color generator whenever updated (width/height) so always reusing same colors (and not exhausting)
|
|
48
|
-
const { translate, scale, dragging } = transformContext();
|
|
49
|
-
$: {
|
|
50
|
-
$width;
|
|
51
|
-
$height;
|
|
52
|
-
$translate;
|
|
53
|
-
$scale;
|
|
54
|
-
|
|
55
|
-
colorGenerator = rgbColorGenerator();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const dataByColor = new Map<string, any>();
|
|
59
|
-
function setColorData(color: string, data: any) {
|
|
60
|
-
dataByColor.set(color, data);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let activePointer = false;
|
|
64
|
-
|
|
65
|
-
function getPointerData(e: PointerEvent | MouseEvent) {
|
|
66
|
-
const { offsetX, offsetY } = e;
|
|
67
|
-
|
|
68
|
-
const dpr = window.devicePixelRatio ?? 1;
|
|
69
|
-
const imageData = context.getImageData(offsetX * dpr, offsetY * dpr, 1, 1);
|
|
70
|
-
const [r, g, b, a] = imageData.data;
|
|
71
|
-
const colorKey = `rgb(${r},${g},${b})`;
|
|
72
|
-
const data = dataByColor.get(colorKey);
|
|
73
|
-
|
|
74
|
-
return data;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function dispatchPointerMove(e: PointerEvent) {
|
|
78
|
-
const data = getPointerData(e);
|
|
79
|
-
|
|
80
|
-
if (data) {
|
|
81
|
-
activePointer = true;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Still dispatch with `undefined data` to hide tooltip, etc
|
|
85
|
-
dispatch('pointermove', { event: e, data });
|
|
86
|
-
}
|
|
87
|
-
</script>
|
|
88
|
-
|
|
89
|
-
<Canvas
|
|
90
|
-
bind:context
|
|
91
|
-
willReadFrequently
|
|
92
|
-
class={cls(
|
|
93
|
-
'HitCanvas absolute w-full h-full border border-danger',
|
|
94
|
-
// '[image-rendering:pixelated]', // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
|
|
95
|
-
!debug && 'opacity-0'
|
|
96
|
-
)}
|
|
97
|
-
on:pointerenter={dispatchPointerMove}
|
|
98
|
-
on:pointermove={dispatchPointerMove}
|
|
99
|
-
on:pointerleave={() => (activePointer = false)}
|
|
100
|
-
on:pointerleave
|
|
101
|
-
on:touchmove={(e) => {
|
|
102
|
-
// Prevent touch to not interfer with pointer if over data
|
|
103
|
-
if (activePointer) {
|
|
104
|
-
e.preventDefault();
|
|
105
|
-
}
|
|
106
|
-
}}
|
|
107
|
-
on:click={(e) => {
|
|
108
|
-
const data = getPointerData(e);
|
|
109
|
-
if (data) {
|
|
110
|
-
dispatch('click', { event: e, data });
|
|
111
|
-
}
|
|
112
|
-
}}
|
|
113
|
-
>
|
|
114
|
-
<!-- Do not render while dragging to improve interaction performance -->
|
|
115
|
-
{#if !$dragging}
|
|
116
|
-
<slot nextColor={() => colorGenerator.next().value} {setColorData}></slot>
|
|
117
|
-
{/if}
|
|
118
|
-
</Canvas>
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
declare const __propDef: {
|
|
3
|
-
props: {
|
|
4
|
-
context?: CanvasRenderingContext2D;
|
|
5
|
-
/** Show canvas for debugging */ debug?: boolean;
|
|
6
|
-
};
|
|
7
|
-
events: {
|
|
8
|
-
pointerleave: PointerEvent;
|
|
9
|
-
pointermove: CustomEvent<{
|
|
10
|
-
event: PointerEvent;
|
|
11
|
-
data: any;
|
|
12
|
-
}>;
|
|
13
|
-
click: CustomEvent<{
|
|
14
|
-
event: MouseEvent;
|
|
15
|
-
data: any;
|
|
16
|
-
}>;
|
|
17
|
-
} & {
|
|
18
|
-
[evt: string]: CustomEvent<any>;
|
|
19
|
-
};
|
|
20
|
-
slots: {
|
|
21
|
-
default: {
|
|
22
|
-
nextColor: () => string;
|
|
23
|
-
setColorData: (color: string, data: any) => void;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
export type HitCanvasProps = typeof __propDef.props;
|
|
28
|
-
export type HitCanvasEvents = typeof __propDef.events;
|
|
29
|
-
export type HitCanvasSlots = typeof __propDef.slots;
|
|
30
|
-
export default class HitCanvas extends SvelteComponentTyped<HitCanvasProps, HitCanvasEvents, HitCanvasSlots> {
|
|
31
|
-
}
|
|
32
|
-
export {};
|