layerchart 0.92.0 → 0.93.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/BrushContext.svelte +476 -0
- package/dist/components/BrushContext.svelte.d.ts +73 -0
- package/dist/components/Chart.svelte +64 -47
- package/dist/components/Chart.svelte.d.ts +51 -12
- package/dist/components/charts/AreaChart.svelte +27 -22
- package/dist/components/charts/LineChart.svelte +23 -21
- package/dist/components/charts/PieChart.svelte.d.ts +45 -9
- package/dist/components/charts/ScatterChart.svelte +21 -24
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.js +0 -1
- package/dist/components/tooltip/TooltipContext.svelte +7 -7
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +2 -2
- package/dist/utils/math.d.ts +2 -0
- package/dist/utils/math.js +9 -0
- package/package.json +1 -1
- package/dist/components/Brush.svelte +0 -418
|
@@ -115,8 +115,8 @@
|
|
|
115
115
|
|
|
116
116
|
/** Exposed to allow binding in Chart */
|
|
117
117
|
export let tooltip = writable({
|
|
118
|
-
y: 0,
|
|
119
118
|
x: 0,
|
|
119
|
+
y: 0,
|
|
120
120
|
data: null as any,
|
|
121
121
|
show: showTooltip,
|
|
122
122
|
hide: hideTooltip,
|
|
@@ -393,12 +393,12 @@
|
|
|
393
393
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
394
394
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
395
395
|
<div
|
|
396
|
-
style:width="{$width}px"
|
|
397
|
-
style:height="{$height}px"
|
|
398
396
|
style:top="{$padding.top}px"
|
|
399
397
|
style:left="{$padding.left}px"
|
|
398
|
+
style:width="{$width}px"
|
|
399
|
+
style:height="{$height}px"
|
|
400
400
|
class={cls(
|
|
401
|
-
'
|
|
401
|
+
'TooltipContext absolute touch-none',
|
|
402
402
|
debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
|
|
403
403
|
)}
|
|
404
404
|
on:pointerenter={triggerPointerEvents ? showTooltip : undefined}
|
|
@@ -410,13 +410,13 @@
|
|
|
410
410
|
}
|
|
411
411
|
}}
|
|
412
412
|
>
|
|
413
|
-
<!-- Rendering slot within
|
|
413
|
+
<!-- Rendering slot within TooltipContext to allow pointer events to bubble up (ex. Brush) -->
|
|
414
414
|
<div
|
|
415
415
|
class="absolute"
|
|
416
|
-
style:width="{$containerWidth}px"
|
|
417
|
-
style:height="{$containerHeight}px"
|
|
418
416
|
style:top="-{$padding.top ?? 0}px"
|
|
419
417
|
style:left="-{$padding.left ?? 0}px"
|
|
418
|
+
style:width="{$containerWidth}px"
|
|
419
|
+
style:height="{$containerHeight}px"
|
|
420
420
|
>
|
|
421
421
|
<slot tooltip={$tooltip} />
|
|
422
422
|
|
|
@@ -30,8 +30,8 @@ declare const __propDef: {
|
|
|
30
30
|
data: any;
|
|
31
31
|
}) => any;
|
|
32
32
|
/** Exposed to allow binding in Chart */ tooltip?: import("svelte/store").Writable<{
|
|
33
|
-
y: number;
|
|
34
33
|
x: number;
|
|
34
|
+
y: number;
|
|
35
35
|
data: any;
|
|
36
36
|
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
37
37
|
hide: () => void;
|
|
@@ -44,8 +44,8 @@ declare const __propDef: {
|
|
|
44
44
|
slots: {
|
|
45
45
|
default: {
|
|
46
46
|
tooltip: {
|
|
47
|
-
y: number;
|
|
48
47
|
x: number;
|
|
48
|
+
y: number;
|
|
49
49
|
data: any;
|
|
50
50
|
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
51
51
|
hide: () => void;
|
package/dist/utils/math.d.ts
CHANGED
|
@@ -29,3 +29,5 @@ export declare function celsiusToFahrenheit(temperature: number): number;
|
|
|
29
29
|
export declare function fahrenheitToCelsius(temperature: number): number;
|
|
30
30
|
/** Parse percent string (`50%`) to decimal (`0.5`) */
|
|
31
31
|
export declare function parsePercent(percent: string | number): number;
|
|
32
|
+
/** Add second value while maintaining `Date` or `number` type */
|
|
33
|
+
export declare function add(value1: Date | number, value2: number): number | Date;
|
package/dist/utils/math.js
CHANGED
|
@@ -55,3 +55,12 @@ export function parsePercent(percent) {
|
|
|
55
55
|
return Number(percent.replace('%', '')) / 100;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
/** Add second value while maintaining `Date` or `number` type */
|
|
59
|
+
export function add(value1, value2) {
|
|
60
|
+
if (value1 instanceof Date) {
|
|
61
|
+
return new Date(value1.getTime() + value2);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return value1 + value2;
|
|
65
|
+
}
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { type ComponentProps } from 'svelte';
|
|
3
|
-
import { extent, min, max } from 'd3-array';
|
|
4
|
-
import { clamp } from '@layerstack/utils';
|
|
5
|
-
import { cls } from '@layerstack/tailwind';
|
|
6
|
-
import { format as formatValue, type FormatType } from '@layerstack/utils';
|
|
7
|
-
|
|
8
|
-
import { chartContext } from './ChartContext.svelte';
|
|
9
|
-
import Frame from './Frame.svelte';
|
|
10
|
-
import Group from './Group.svelte';
|
|
11
|
-
import Text from './Text.svelte';
|
|
12
|
-
|
|
13
|
-
import { localPoint } from '../utils/event.js';
|
|
14
|
-
import type { DomainType } from '../utils/scales.js';
|
|
15
|
-
import { asAny } from '../utils/types.js';
|
|
16
|
-
import Rect from './Rect.svelte';
|
|
17
|
-
|
|
18
|
-
const { xScale, yScale, width, height, padding, config } = chartContext();
|
|
19
|
-
|
|
20
|
-
/** Axis to apply brushing */
|
|
21
|
-
export let axis: 'x' | 'y' | 'both' = 'x';
|
|
22
|
-
|
|
23
|
-
/** Size of draggable handles (width/height) */
|
|
24
|
-
export let handleSize = 5;
|
|
25
|
-
|
|
26
|
-
/** Only show range while actively brushing. Useful with `brushEnd` event */
|
|
27
|
-
export let resetOnEnd = false;
|
|
28
|
-
|
|
29
|
-
export let xDomain: DomainType = $xScale.domain() as [number, number];
|
|
30
|
-
export let yDomain: DomainType = $yScale.domain() as [number, number];
|
|
31
|
-
|
|
32
|
-
export let labels: ComponentProps<Text> | boolean = false;
|
|
33
|
-
|
|
34
|
-
/** Mode of operation
|
|
35
|
-
* `integrated`: use with single chart
|
|
36
|
-
* `separated`: use with separate (typically smaller) chart and state can be managed externally (sync with other charts, etc). Show active selection when domain does not equal original
|
|
37
|
-
*/
|
|
38
|
-
export let mode: 'integrated' | 'separated' = 'integrated';
|
|
39
|
-
|
|
40
|
-
// Capture original domains for reset()
|
|
41
|
-
const originalXDomain = $config.xDomain;
|
|
42
|
-
const originalYDomain = $config.yDomain;
|
|
43
|
-
|
|
44
|
-
$: [xDomainMin, xDomainMax] = extent<number>($xScale.domain()) as [number, number];
|
|
45
|
-
$: [yDomainMin, yDomainMax] = extent<number>($yScale.domain()) as [number, number];
|
|
46
|
-
|
|
47
|
-
/** Attributes passed to range <rect> element */
|
|
48
|
-
export let range: Partial<ComponentProps<Rect>> | undefined = undefined;
|
|
49
|
-
|
|
50
|
-
/** Attributes passed to handle <rect> elements */
|
|
51
|
-
export let handle: Partial<ComponentProps<Rect>> | undefined = undefined;
|
|
52
|
-
|
|
53
|
-
/** Apply format to labels, if shown */
|
|
54
|
-
export let format: FormatType | undefined = undefined;
|
|
55
|
-
|
|
56
|
-
export let classes: {
|
|
57
|
-
root?: string;
|
|
58
|
-
frame?: string;
|
|
59
|
-
range?: string;
|
|
60
|
-
handle?: string;
|
|
61
|
-
labels?: string;
|
|
62
|
-
} = {};
|
|
63
|
-
|
|
64
|
-
export let onchange: (detail: { xDomain?: DomainType; yDomain?: DomainType }) => void = () => {};
|
|
65
|
-
export let onbrushstart: (detail: {
|
|
66
|
-
xDomain?: DomainType;
|
|
67
|
-
yDomain?: DomainType;
|
|
68
|
-
}) => void = () => {};
|
|
69
|
-
export let onbrushend: (detail: {
|
|
70
|
-
xDomain?: DomainType;
|
|
71
|
-
yDomain?: DomainType;
|
|
72
|
-
}) => void = () => {};
|
|
73
|
-
export let onreset: (detail: { xDomain?: DomainType; yDomain?: DomainType }) => void = () => {};
|
|
74
|
-
|
|
75
|
-
let frameEl: SVGRectElement;
|
|
76
|
-
|
|
77
|
-
function handler(
|
|
78
|
-
fn: (
|
|
79
|
-
start: {
|
|
80
|
-
xDomain: [number, number];
|
|
81
|
-
yDomain: [number, number];
|
|
82
|
-
value: { x: number; y: number };
|
|
83
|
-
},
|
|
84
|
-
value: { x: number; y: number }
|
|
85
|
-
) => void
|
|
86
|
-
) {
|
|
87
|
-
return (e: PointerEvent) => {
|
|
88
|
-
const start = {
|
|
89
|
-
xDomain: [xDomain?.[0] ?? xDomainMin, xDomain?.[1] ?? xDomainMax] as [number, number],
|
|
90
|
-
yDomain: [yDomain?.[0] ?? yDomainMin, yDomain?.[1] ?? yDomainMax] as [number, number],
|
|
91
|
-
value: {
|
|
92
|
-
x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
|
|
93
|
-
y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
onbrushstart({ xDomain, yDomain });
|
|
98
|
-
|
|
99
|
-
const onPointerMove = (e: PointerEvent) => {
|
|
100
|
-
fn(start, {
|
|
101
|
-
x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
|
|
102
|
-
y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// if (xDomain[0] === xDomain[1] || yDomain[0] === yDomain[1]) {
|
|
106
|
-
// // Ignore?
|
|
107
|
-
// // TODO: What about when using `x` or `y` axis?
|
|
108
|
-
// } else {
|
|
109
|
-
onchange({ xDomain, yDomain });
|
|
110
|
-
// }
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const onPointerUp = (e: PointerEvent) => {
|
|
114
|
-
if (e.target === frameEl) {
|
|
115
|
-
reset();
|
|
116
|
-
onchange({ xDomain, yDomain });
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
onbrushend({ xDomain, yDomain });
|
|
120
|
-
|
|
121
|
-
if (resetOnEnd) {
|
|
122
|
-
reset();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
window.removeEventListener('pointermove', onPointerMove);
|
|
126
|
-
window.removeEventListener('pointerup', onPointerUp);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
window.addEventListener('pointermove', onPointerMove);
|
|
130
|
-
window.addEventListener('pointerup', onPointerUp);
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** Add second value while maintaining `Date` or `number` type */
|
|
135
|
-
function add(value1: Date | number, value2: number) {
|
|
136
|
-
if (value1 instanceof Date) {
|
|
137
|
-
return new Date(value1.getTime() + value2);
|
|
138
|
-
} else {
|
|
139
|
-
return value1 + value2;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const createRange = handler((start, value) => {
|
|
144
|
-
isActive = true;
|
|
145
|
-
|
|
146
|
-
xDomain = [
|
|
147
|
-
// @ts-expect-error
|
|
148
|
-
clamp(min([start.value.x, value.x]), xDomainMin, xDomainMax),
|
|
149
|
-
// @ts-expect-error
|
|
150
|
-
clamp(max([start.value.x, value.x]), xDomainMin, xDomainMax),
|
|
151
|
-
];
|
|
152
|
-
// xDomain = [start.value.x, value.x];
|
|
153
|
-
|
|
154
|
-
yDomain = [
|
|
155
|
-
// @ts-expect-error
|
|
156
|
-
clamp(min([start.value.y, value.y]), yDomainMin, yDomainMax),
|
|
157
|
-
// @ts-expect-error
|
|
158
|
-
clamp(max([start.value.y, value.y]), yDomainMin, yDomainMax),
|
|
159
|
-
];
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
const adjustRange = handler((start, value) => {
|
|
163
|
-
const dx = clamp(
|
|
164
|
-
value.x - start.value.x,
|
|
165
|
-
xDomainMin - start.xDomain[0],
|
|
166
|
-
xDomainMax - start.xDomain[1]
|
|
167
|
-
);
|
|
168
|
-
xDomain = [add(start.xDomain[0], dx), add(start.xDomain[1], dx)];
|
|
169
|
-
|
|
170
|
-
const dy = clamp(
|
|
171
|
-
value.y - start.value.y,
|
|
172
|
-
yDomainMin - start.yDomain[0],
|
|
173
|
-
yDomainMax - start.yDomain[1]
|
|
174
|
-
);
|
|
175
|
-
yDomain = [add(start.yDomain[0], dy), add(start.yDomain[1], dy)];
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
const adjustBottom = handler((start, value) => {
|
|
179
|
-
yDomain = [
|
|
180
|
-
clamp(value.y > start.yDomain[1] ? start.yDomain[1] : value.y, yDomainMin, yDomainMax),
|
|
181
|
-
clamp(value.y > start.yDomain[1] ? value.y : start.yDomain[1], yDomainMin, yDomainMax),
|
|
182
|
-
];
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const adjustTop = handler((start, value) => {
|
|
186
|
-
yDomain = [
|
|
187
|
-
clamp(value.y < start.yDomain[1] ? value.y : start.yDomain[0], yDomainMin, yDomainMax),
|
|
188
|
-
clamp(value.y < start.yDomain[1] ? start.yDomain[0] : value.y, yDomainMin, yDomainMax),
|
|
189
|
-
];
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
const adjustLeft = handler((start, value) => {
|
|
193
|
-
xDomain = [
|
|
194
|
-
clamp(value.x > start.xDomain[1] ? start.xDomain[1] : value.x, xDomainMin, xDomainMax),
|
|
195
|
-
clamp(value.x > start.xDomain[1] ? value.x : start.xDomain[1], xDomainMin, xDomainMax),
|
|
196
|
-
];
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
const adjustRight = handler((start, value) => {
|
|
200
|
-
xDomain = [
|
|
201
|
-
clamp(value.x < start.xDomain[0] ? value.x : start.xDomain[0], xDomainMin, xDomainMax),
|
|
202
|
-
clamp(value.x < start.xDomain[0] ? start.xDomain[0] : value.x, xDomainMin, xDomainMax),
|
|
203
|
-
];
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
function reset() {
|
|
207
|
-
isActive = false;
|
|
208
|
-
|
|
209
|
-
xDomain = originalXDomain;
|
|
210
|
-
yDomain = originalYDomain;
|
|
211
|
-
|
|
212
|
-
onreset({ xDomain, yDomain });
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function selectAll() {
|
|
216
|
-
xDomain = [xDomainMin, xDomainMax];
|
|
217
|
-
yDomain = [yDomainMin, yDomainMax];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
$: top = $yScale(yDomain?.[1]);
|
|
221
|
-
$: bottom = $yScale(yDomain?.[0]);
|
|
222
|
-
$: left = $xScale(xDomain?.[0]);
|
|
223
|
-
$: right = $xScale(xDomain?.[1]);
|
|
224
|
-
|
|
225
|
-
$: rangeTop = axis === 'both' || axis === 'y' ? top : 0;
|
|
226
|
-
$: rangeLeft = axis === 'both' || axis === 'x' ? left : 0;
|
|
227
|
-
$: rangeWidth = axis === 'both' || axis === 'x' ? right - left : $width;
|
|
228
|
-
$: rangeHeight = axis === 'both' || axis === 'y' ? bottom - top : $height;
|
|
229
|
-
|
|
230
|
-
let isActive = false;
|
|
231
|
-
$: if (mode === 'separated') {
|
|
232
|
-
// Set reactively to handle cases where xDomain/yDomain are set externally (ex. `bind:xDomain`)
|
|
233
|
-
isActive =
|
|
234
|
-
xDomain?.[0]?.valueOf() !== originalXDomain?.[0]?.valueOf() ||
|
|
235
|
-
xDomain?.[1]?.valueOf() !== originalXDomain?.[1]?.valueOf() ||
|
|
236
|
-
yDomain?.[0]?.valueOf() !== originalYDomain?.[0]?.valueOf() ||
|
|
237
|
-
yDomain?.[1]?.valueOf() !== originalYDomain?.[1]?.valueOf();
|
|
238
|
-
}
|
|
239
|
-
</script>
|
|
240
|
-
|
|
241
|
-
<g class={cls('Brush select-none', classes.root, $$props.class)}>
|
|
242
|
-
<Frame
|
|
243
|
-
class={cls('frame', 'fill-transparent', classes.frame)}
|
|
244
|
-
onpointerdown={createRange}
|
|
245
|
-
ondblclick={() => selectAll()}
|
|
246
|
-
bind:element={frameEl}
|
|
247
|
-
/>
|
|
248
|
-
|
|
249
|
-
{#if isActive}
|
|
250
|
-
<Group x={rangeLeft} y={rangeTop} class="range">
|
|
251
|
-
<slot name="range" {rangeWidth} {rangeHeight}>
|
|
252
|
-
<Rect
|
|
253
|
-
width={rangeWidth}
|
|
254
|
-
height={rangeHeight}
|
|
255
|
-
class={cls(
|
|
256
|
-
'cursor-move select-none',
|
|
257
|
-
range?.fill == null && 'fill-surface-content/10',
|
|
258
|
-
classes.range
|
|
259
|
-
)}
|
|
260
|
-
onpointerdown={adjustRange}
|
|
261
|
-
ondblclick={() => reset()}
|
|
262
|
-
{...range}
|
|
263
|
-
/>
|
|
264
|
-
</slot>
|
|
265
|
-
</Group>
|
|
266
|
-
|
|
267
|
-
{#if axis === 'both' || axis === 'y'}
|
|
268
|
-
<Group
|
|
269
|
-
x={rangeLeft}
|
|
270
|
-
y={rangeTop}
|
|
271
|
-
class="handle top"
|
|
272
|
-
onpointerdown={adjustTop}
|
|
273
|
-
ondblclick={() => {
|
|
274
|
-
if (yDomain) {
|
|
275
|
-
yDomain[0] = yDomainMin;
|
|
276
|
-
onchange({ xDomain, yDomain });
|
|
277
|
-
}
|
|
278
|
-
}}
|
|
279
|
-
>
|
|
280
|
-
<slot name="handle" edge="top" {rangeWidth} {rangeHeight}>
|
|
281
|
-
<Rect
|
|
282
|
-
width={rangeWidth}
|
|
283
|
-
height={handleSize}
|
|
284
|
-
class={cls('fill-transparent cursor-ns-resize select-none', classes.handle)}
|
|
285
|
-
{...handle}
|
|
286
|
-
/>
|
|
287
|
-
</slot>
|
|
288
|
-
</Group>
|
|
289
|
-
|
|
290
|
-
<Group
|
|
291
|
-
x={rangeLeft}
|
|
292
|
-
y={bottom - handleSize + 1}
|
|
293
|
-
class="handle bottom"
|
|
294
|
-
onpointerdown={adjustBottom}
|
|
295
|
-
ondblclick={() => {
|
|
296
|
-
if (yDomain) {
|
|
297
|
-
yDomain[1] = yDomainMax;
|
|
298
|
-
}
|
|
299
|
-
}}
|
|
300
|
-
>
|
|
301
|
-
<slot name="handle" edge="bottom" {rangeWidth} {rangeHeight}>
|
|
302
|
-
<Rect
|
|
303
|
-
width={rangeWidth}
|
|
304
|
-
height={handleSize}
|
|
305
|
-
class={cls('fill-transparent cursor-ns-resize select-none', classes.handle)}
|
|
306
|
-
{...handle}
|
|
307
|
-
/>
|
|
308
|
-
</slot>
|
|
309
|
-
</Group>
|
|
310
|
-
{/if}
|
|
311
|
-
|
|
312
|
-
{#if axis === 'both' || axis === 'x'}
|
|
313
|
-
<Group
|
|
314
|
-
x={rangeLeft}
|
|
315
|
-
y={rangeTop}
|
|
316
|
-
class="handle left"
|
|
317
|
-
onpointerdown={adjustLeft}
|
|
318
|
-
ondblclick={() => {
|
|
319
|
-
if (xDomain) {
|
|
320
|
-
xDomain[0] = xDomainMin;
|
|
321
|
-
onchange({ xDomain, yDomain });
|
|
322
|
-
}
|
|
323
|
-
}}
|
|
324
|
-
>
|
|
325
|
-
<slot name="handle" edge="left" {rangeWidth} {rangeHeight}>
|
|
326
|
-
<rect
|
|
327
|
-
width={handleSize}
|
|
328
|
-
height={rangeHeight}
|
|
329
|
-
class={cls('fill-transparent cursor-ew-resize select-none', classes.handle)}
|
|
330
|
-
{...handle}
|
|
331
|
-
/>
|
|
332
|
-
</slot>
|
|
333
|
-
</Group>
|
|
334
|
-
|
|
335
|
-
<Group
|
|
336
|
-
x={right - handleSize + 1}
|
|
337
|
-
y={rangeTop}
|
|
338
|
-
class="handle right"
|
|
339
|
-
onpointerdown={adjustRight}
|
|
340
|
-
ondblclick={() => {
|
|
341
|
-
if (xDomain) {
|
|
342
|
-
xDomain[1] = xDomainMax;
|
|
343
|
-
onchange({ xDomain, yDomain });
|
|
344
|
-
}
|
|
345
|
-
}}
|
|
346
|
-
>
|
|
347
|
-
<slot name="handle" edge="right" {rangeWidth} {rangeHeight}>
|
|
348
|
-
<Rect
|
|
349
|
-
width={handleSize}
|
|
350
|
-
height={rangeHeight}
|
|
351
|
-
class={cls('fill-transparent cursor-ew-resize select-none', classes.handle)}
|
|
352
|
-
{...handle}
|
|
353
|
-
/>
|
|
354
|
-
</slot>
|
|
355
|
-
</Group>
|
|
356
|
-
{/if}
|
|
357
|
-
|
|
358
|
-
<slot name="labels">
|
|
359
|
-
{#if labels}
|
|
360
|
-
{@const labelClass = cls(
|
|
361
|
-
'text-xs',
|
|
362
|
-
classes.labels,
|
|
363
|
-
typeof labels === 'object' ? labels.class : null
|
|
364
|
-
)}
|
|
365
|
-
|
|
366
|
-
{#if axis === 'x' || axis === 'both'}
|
|
367
|
-
<Text
|
|
368
|
-
x={left}
|
|
369
|
-
y={rangeTop + rangeHeight / 2}
|
|
370
|
-
dx={-4}
|
|
371
|
-
textAnchor="end"
|
|
372
|
-
verticalAnchor="middle"
|
|
373
|
-
value={formatValue(asAny(xDomain?.[0]), format)}
|
|
374
|
-
{...typeof labels === 'object' ? labels : null}
|
|
375
|
-
class={labelClass}
|
|
376
|
-
/>
|
|
377
|
-
|
|
378
|
-
<Text
|
|
379
|
-
x={right}
|
|
380
|
-
y={rangeTop + rangeHeight / 2}
|
|
381
|
-
dx={4}
|
|
382
|
-
textAnchor="start"
|
|
383
|
-
verticalAnchor="middle"
|
|
384
|
-
value={formatValue(asAny(xDomain?.[1]), format)}
|
|
385
|
-
{...typeof labels === 'object' ? labels : null}
|
|
386
|
-
class={labelClass}
|
|
387
|
-
/>
|
|
388
|
-
{/if}
|
|
389
|
-
|
|
390
|
-
{#if axis === 'y' || axis === 'both'}
|
|
391
|
-
<Text
|
|
392
|
-
x={rangeLeft + rangeWidth / 2}
|
|
393
|
-
y={top}
|
|
394
|
-
dy={-4}
|
|
395
|
-
textAnchor="middle"
|
|
396
|
-
verticalAnchor="end"
|
|
397
|
-
value={formatValue(asAny(yDomain?.[1]), format)}
|
|
398
|
-
{...typeof labels === 'object' ? labels : null}
|
|
399
|
-
class={labelClass}
|
|
400
|
-
/>
|
|
401
|
-
|
|
402
|
-
<Text
|
|
403
|
-
x={rangeLeft + rangeWidth / 2}
|
|
404
|
-
y={bottom}
|
|
405
|
-
dy={4}
|
|
406
|
-
textAnchor="middle"
|
|
407
|
-
verticalAnchor="start"
|
|
408
|
-
value={formatValue(asAny(yDomain?.[0]), format)}
|
|
409
|
-
{...typeof labels === 'object' ? labels : null}
|
|
410
|
-
class={labelClass}
|
|
411
|
-
/>
|
|
412
|
-
{/if}
|
|
413
|
-
{/if}
|
|
414
|
-
</slot>
|
|
415
|
-
|
|
416
|
-
<!-- TODO: Add diagonal/corner handles -->
|
|
417
|
-
{/if}
|
|
418
|
-
</g>
|