layerchart 0.53.0 → 0.54.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/Axis.svelte +51 -94
- package/dist/components/Axis.svelte.d.ts +2 -1
- package/dist/components/Bars.svelte +2 -1
- package/dist/components/Bars.svelte.d.ts +1 -0
- package/dist/components/Chart.svelte +6 -4
- package/dist/components/Chart.svelte.d.ts +25 -8
- package/dist/components/ChartContext.svelte +1 -1
- package/dist/components/ChartContext.svelte.d.ts +1 -1
- package/dist/components/Grid.svelte +151 -0
- package/dist/components/Grid.svelte.d.ts +35 -0
- package/dist/components/Labels.svelte +15 -5
- package/dist/components/Labels.svelte.d.ts +2 -0
- package/dist/components/Legend.svelte +1 -1
- package/dist/components/Rule.svelte +20 -4
- package/dist/components/Rule.svelte.d.ts +2 -0
- package/dist/components/TransformContext.svelte +3 -1
- package/dist/components/charts/AreaChart.svelte +59 -35
- package/dist/components/charts/AreaChart.svelte.d.ts +40 -2
- package/dist/components/charts/BarChart.svelte +63 -29
- package/dist/components/charts/BarChart.svelte.d.ts +40 -2
- package/dist/components/charts/LineChart.svelte +44 -16
- package/dist/components/charts/LineChart.svelte.d.ts +40 -2
- package/dist/components/charts/PieChart.svelte +15 -1
- package/dist/components/charts/PieChart.svelte.d.ts +16 -1
- package/dist/components/charts/ScatterChart.svelte +31 -16
- package/dist/components/charts/ScatterChart.svelte.d.ts +38 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/tooltip/Tooltip.svelte +20 -5
- package/dist/components/tooltip/TooltipContext.svelte +2 -1
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +7 -0
- package/dist/docs/Preview.svelte +24 -11
- package/dist/utils/scales.d.ts +1 -1
- package/package.json +1 -1
|
@@ -6,8 +6,8 @@ import { pointRadial } from 'd3-shape';
|
|
|
6
6
|
import { format as formatValue } from '@layerstack/utils';
|
|
7
7
|
import { cls } from '@layerstack/tailwind';
|
|
8
8
|
import { chartContext } from './ChartContext.svelte';
|
|
9
|
-
import Circle from './Circle.svelte';
|
|
10
9
|
import Line from './Line.svelte';
|
|
10
|
+
import Rule from './Rule.svelte';
|
|
11
11
|
import Text from './Text.svelte';
|
|
12
12
|
import { isScaleBand } from '../utils/scales.js';
|
|
13
13
|
const { xScale, yScale, xRange, yRange, width, height, padding } = chartContext();
|
|
@@ -101,35 +101,41 @@ function getDefaultTickLabelProps(tick) {
|
|
|
101
101
|
return {
|
|
102
102
|
textAnchor: 'middle',
|
|
103
103
|
verticalAnchor: 'end',
|
|
104
|
-
dy: -
|
|
104
|
+
dy: -tickLength - 2, // manually adjusted until Text supports custom styles
|
|
105
105
|
};
|
|
106
106
|
case 'bottom':
|
|
107
107
|
return {
|
|
108
108
|
textAnchor: 'middle',
|
|
109
109
|
verticalAnchor: 'start',
|
|
110
|
-
dy:
|
|
110
|
+
dy: tickLength, // manually adjusted until Text supports custom styles
|
|
111
111
|
};
|
|
112
112
|
case 'left':
|
|
113
113
|
return {
|
|
114
114
|
textAnchor: 'end',
|
|
115
115
|
verticalAnchor: 'middle',
|
|
116
|
-
dx: -
|
|
116
|
+
dx: -tickLength,
|
|
117
117
|
dy: -2, // manually adjusted until Text supports custom styles
|
|
118
118
|
};
|
|
119
119
|
case 'right':
|
|
120
120
|
return {
|
|
121
121
|
textAnchor: 'start',
|
|
122
122
|
verticalAnchor: 'middle',
|
|
123
|
-
dx:
|
|
123
|
+
dx: tickLength,
|
|
124
124
|
dy: -2, // manually adjusted until Text supports custom styles
|
|
125
125
|
};
|
|
126
126
|
case 'angle':
|
|
127
|
-
const xValue = _scale(tick);
|
|
127
|
+
const xValue = _scale(tick); // angle in radians
|
|
128
128
|
return {
|
|
129
|
-
textAnchor: xValue === 0 ||
|
|
129
|
+
textAnchor: xValue === 0 ||
|
|
130
|
+
Math.abs(xValue - Math.PI) < 0.01 || // ~180deg
|
|
131
|
+
Math.abs(xValue - Math.PI * 2) < 0.01 // ~360deg
|
|
132
|
+
? 'middle'
|
|
133
|
+
: xValue > Math.PI
|
|
134
|
+
? 'end'
|
|
135
|
+
: 'start',
|
|
130
136
|
verticalAnchor: 'middle',
|
|
131
|
-
dx:
|
|
132
|
-
dy: -
|
|
137
|
+
dx: Math.sin(xValue) * (tickLength + 2),
|
|
138
|
+
dy: -Math.cos(xValue) * (tickLength + 4), // manually adjusted until Text supports custom styles
|
|
133
139
|
};
|
|
134
140
|
case 'radius':
|
|
135
141
|
return {
|
|
@@ -173,44 +179,15 @@ $: resolvedLabelProps = {
|
|
|
173
179
|
|
|
174
180
|
<g class={cls('Axis placement-{placement}', classes.root, $$props.class)}>
|
|
175
181
|
{#if rule !== false}
|
|
176
|
-
{@const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
{...lineProps}
|
|
186
|
-
class={cls('rule stroke-surface-content/50', lineProps?.class)}
|
|
187
|
-
/>
|
|
188
|
-
{/if}
|
|
189
|
-
|
|
190
|
-
{#if orientation === 'horizontal'}
|
|
191
|
-
<Line
|
|
192
|
-
x1={$xRange[0] || 0}
|
|
193
|
-
x2={$xRange[1] || 0}
|
|
194
|
-
y1={placement === 'top' ? yRangeMin : yRangeMax}
|
|
195
|
-
y2={placement === 'top' ? yRangeMin : yRangeMax}
|
|
196
|
-
{tweened}
|
|
197
|
-
{spring}
|
|
198
|
-
{...lineProps}
|
|
199
|
-
class={cls('rule stroke-surface-content/50', lineProps?.class)}
|
|
200
|
-
/>
|
|
201
|
-
{/if}
|
|
202
|
-
|
|
203
|
-
<!-- TODO: angle rule? -->
|
|
204
|
-
|
|
205
|
-
{#if orientation === 'radius'}
|
|
206
|
-
<Circle
|
|
207
|
-
r={$yRange[0] || 0}
|
|
208
|
-
{tweened}
|
|
209
|
-
{spring}
|
|
210
|
-
{...lineProps}
|
|
211
|
-
class={cls('rule stroke-surface-content/20 fill-none', lineProps?.class)}
|
|
212
|
-
/>
|
|
213
|
-
{/if}
|
|
182
|
+
{@const ruleProps = typeof rule === 'object' ? rule : null}
|
|
183
|
+
<Rule
|
|
184
|
+
x={placement === 'left' || placement === 'right' ? placement : placement === 'angle'}
|
|
185
|
+
y={placement === 'top' || placement === 'bottom' ? placement : placement === 'radius'}
|
|
186
|
+
{tweened}
|
|
187
|
+
{spring}
|
|
188
|
+
{...ruleProps}
|
|
189
|
+
class={cls('rule stroke-surface-content/50', ruleProps?.class)}
|
|
190
|
+
/>
|
|
214
191
|
{/if}
|
|
215
192
|
|
|
216
193
|
{#if label}
|
|
@@ -219,10 +196,14 @@ $: resolvedLabelProps = {
|
|
|
219
196
|
|
|
220
197
|
{#each tickVals as tick, index (tick)}
|
|
221
198
|
{@const tickCoords = getCoords(tick)}
|
|
222
|
-
{@const
|
|
199
|
+
{@const [radialTickCoordsX, radialTickCoordsY] = pointRadial(tickCoords.x, tickCoords.y)}
|
|
200
|
+
{@const [radialTickMarkCoordsX, radialTickMarkCoordsY] = pointRadial(
|
|
201
|
+
tickCoords.x,
|
|
202
|
+
tickCoords.y + tickLength
|
|
203
|
+
)}
|
|
223
204
|
{@const resolvedTickLabelProps = {
|
|
224
|
-
x: orientation === 'angle' ?
|
|
225
|
-
y: orientation === 'angle' ?
|
|
205
|
+
x: orientation === 'angle' ? radialTickCoordsX : tickCoords.x,
|
|
206
|
+
y: orientation === 'angle' ? radialTickCoordsY : tickCoords.y,
|
|
226
207
|
value: formatValue(tick, format ?? _scale.tickFormat?.() ?? ((v) => v)),
|
|
227
208
|
...getDefaultTickLabelProps(tick),
|
|
228
209
|
tweened,
|
|
@@ -236,50 +217,15 @@ $: resolvedLabelProps = {
|
|
|
236
217
|
|
|
237
218
|
<g in:transitionIn={transitionInParams}>
|
|
238
219
|
{#if grid !== false}
|
|
239
|
-
{@const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
{...lineProps}
|
|
249
|
-
class={cls('grid stroke-surface-content/10', lineProps?.class)}
|
|
250
|
-
/>
|
|
251
|
-
{:else if orientation === 'vertical'}
|
|
252
|
-
<Line
|
|
253
|
-
x1={0}
|
|
254
|
-
y1={tickCoords.y}
|
|
255
|
-
x2={$width}
|
|
256
|
-
y2={tickCoords.y}
|
|
257
|
-
{tweened}
|
|
258
|
-
{spring}
|
|
259
|
-
{...lineProps}
|
|
260
|
-
class={cls('grid stroke-surface-content/10', lineProps?.class)}
|
|
261
|
-
/>
|
|
262
|
-
{:else if orientation === 'angle'}
|
|
263
|
-
{@const [x1, y1] = pointRadial(tickCoords.x, yRangeMin)}
|
|
264
|
-
{@const [x2, y2] = pointRadial(tickCoords.x, yRangeMax)}
|
|
265
|
-
|
|
266
|
-
<Line
|
|
267
|
-
{x1}
|
|
268
|
-
{y1}
|
|
269
|
-
{x2}
|
|
270
|
-
{y2}
|
|
271
|
-
{tweened}
|
|
272
|
-
{spring}
|
|
273
|
-
{...lineProps}
|
|
274
|
-
class={cls('grid stroke-surface-content/10', lineProps?.class)}
|
|
275
|
-
/>
|
|
276
|
-
{:else if orientation === 'radius'}
|
|
277
|
-
<circle
|
|
278
|
-
r={tickCoords.y}
|
|
279
|
-
{...lineProps}
|
|
280
|
-
class={cls('grid stroke-surface-content/10 fill-none', lineProps?.class)}
|
|
281
|
-
/>
|
|
282
|
-
{/if}
|
|
220
|
+
{@const ruleProps = typeof grid === 'object' ? grid : null}
|
|
221
|
+
<Rule
|
|
222
|
+
x={orientation === 'horizontal' || orientation === 'angle' ? tick : false}
|
|
223
|
+
y={orientation === 'vertical' || orientation === 'radius' ? tick : false}
|
|
224
|
+
{tweened}
|
|
225
|
+
{spring}
|
|
226
|
+
{...ruleProps}
|
|
227
|
+
class={cls('grid stroke-surface-content/10', ruleProps?.class)}
|
|
228
|
+
/>
|
|
283
229
|
{/if}
|
|
284
230
|
|
|
285
231
|
<!-- Tick marks -->
|
|
@@ -303,7 +249,18 @@ $: resolvedLabelProps = {
|
|
|
303
249
|
{spring}
|
|
304
250
|
class="tick stroke-surface-content/50"
|
|
305
251
|
/>
|
|
252
|
+
{:else if orientation === 'angle'}
|
|
253
|
+
<Line
|
|
254
|
+
x1={radialTickCoordsX}
|
|
255
|
+
y1={radialTickCoordsY}
|
|
256
|
+
x2={radialTickMarkCoordsX}
|
|
257
|
+
y2={radialTickMarkCoordsY}
|
|
258
|
+
{tweened}
|
|
259
|
+
{spring}
|
|
260
|
+
class="tick stroke-surface-content/50"
|
|
261
|
+
/>
|
|
306
262
|
{/if}
|
|
263
|
+
<!-- TODO: Add tick marks for radial (angle)? -->
|
|
307
264
|
|
|
308
265
|
<slot name="tickLabel" labelProps={resolvedTickLabelProps} {index}>
|
|
309
266
|
<Text {...resolvedTickLabelProps} />
|
|
@@ -5,6 +5,7 @@ import type { SVGAttributes } from 'svelte/elements';
|
|
|
5
5
|
import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
|
|
6
6
|
import { type FormatType } from '@layerstack/utils';
|
|
7
7
|
import type { TransitionParams } from 'svelte-ux';
|
|
8
|
+
import Rule from './Rule.svelte';
|
|
8
9
|
import Text from './Text.svelte';
|
|
9
10
|
import { type AnyScale } from '../utils/scales.js';
|
|
10
11
|
declare const __propDef: {
|
|
@@ -14,7 +15,7 @@ declare const __propDef: {
|
|
|
14
15
|
label?: string | undefined;
|
|
15
16
|
labelPlacement?: ("start" | "middle" | "end") | undefined;
|
|
16
17
|
labelProps?: Partial<ComponentProps<Text>> | undefined;
|
|
17
|
-
rule?: (boolean |
|
|
18
|
+
rule?: (boolean | Partial<ComponentProps<Rule>>) | undefined;
|
|
18
19
|
grid?: (boolean | Pick<SVGAttributes<SVGElement>, "class" | "style">) | undefined;
|
|
19
20
|
ticks?: number | any[] | ((scale: AnyScale) => any) | null | undefined;
|
|
20
21
|
tickLength?: number | undefined;
|
|
@@ -27,6 +27,7 @@ export let y1 = undefined;
|
|
|
27
27
|
export let stroke = 'black';
|
|
28
28
|
export let strokeWidth = 0;
|
|
29
29
|
export let radius = 0;
|
|
30
|
+
export let fill = undefined;
|
|
30
31
|
/** Inset the rect for amount of padding. Useful with multiple bars (bullet, overlap, etc) */
|
|
31
32
|
export let inset = 0;
|
|
32
33
|
export let spring = undefined;
|
|
@@ -42,7 +43,7 @@ export let tweened = undefined;
|
|
|
42
43
|
{y}
|
|
43
44
|
{x1}
|
|
44
45
|
{y1}
|
|
45
|
-
fill={$config.c ? $cGet(item) : null}
|
|
46
|
+
fill={fill ?? ($config.c ? $cGet(item) : null)}
|
|
46
47
|
{stroke}
|
|
47
48
|
{strokeWidth}
|
|
48
49
|
{radius}
|
|
@@ -13,6 +13,7 @@ declare const __propDef: {
|
|
|
13
13
|
stroke?: string | undefined;
|
|
14
14
|
strokeWidth?: number | undefined;
|
|
15
15
|
radius?: number | undefined;
|
|
16
|
+
fill?: string | undefined;
|
|
16
17
|
inset?: number | undefined;
|
|
17
18
|
spring?: ComponentProps<Rect>["spring"];
|
|
18
19
|
tweened?: ComponentProps<Rect>["tweened"];
|
|
@@ -60,9 +60,11 @@ export let tooltip = undefined;
|
|
|
60
60
|
export let transform = undefined;
|
|
61
61
|
// @ts-expect-error will only be undefined until bind:transformContext runs
|
|
62
62
|
export let transformContext = undefined;
|
|
63
|
-
|
|
64
|
-
let geoProjection = undefined;
|
|
65
|
-
|
|
63
|
+
/** Expose bound geo projection context */
|
|
64
|
+
export let geoProjection = undefined;
|
|
65
|
+
/** Expose bound tooltip context */
|
|
66
|
+
export let tooltipContext = undefined;
|
|
67
|
+
// Track when mounted since LayerCake initializes width/height with `100` until bound `clientWidth`/`clientWidth` can run
|
|
66
68
|
// Useful to key/remount TransformContext with correct `initialTranslate` / `initialScale` values
|
|
67
69
|
let isMounted = false;
|
|
68
70
|
onMount(() => {
|
|
@@ -184,7 +186,7 @@ $: _yRange =
|
|
|
184
186
|
>
|
|
185
187
|
<GeoContext {...geo} bind:geo={geoProjection} let:projection>
|
|
186
188
|
{@const tooltipProps = typeof tooltip === 'object' ? tooltip : {}}
|
|
187
|
-
<TooltipContext {...tooltipProps} let:tooltip>
|
|
189
|
+
<TooltipContext {...tooltipProps} bind:tooltip={tooltipContext} let:tooltip>
|
|
188
190
|
<slot
|
|
189
191
|
{aspectRatio}
|
|
190
192
|
{containerHeight}
|
|
@@ -86,40 +86,40 @@ declare class __sveltets_Render<TData> {
|
|
|
86
86
|
y1Scale?: AnyScale;
|
|
87
87
|
/** The D3 scale that should be used for the color dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleOrdinal */
|
|
88
88
|
cScale?: AnyScale;
|
|
89
|
-
/** Override the default x range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `xReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
89
|
+
/** Override the default x range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `xReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
90
90
|
xRange?: string[] | number[] | ((args: {
|
|
91
91
|
width: number;
|
|
92
92
|
height: number;
|
|
93
93
|
}) => number[] | string[]) | undefined;
|
|
94
|
-
/** Override the default y range of `[0, height]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `yReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
94
|
+
/** Override the default y range of `[0, height]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `yReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
95
95
|
yRange?: string[] | number[] | ((args: {
|
|
96
96
|
width: number;
|
|
97
97
|
height: number;
|
|
98
98
|
}) => number[] | string[]) | undefined;
|
|
99
|
-
/** Override the default z range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `zReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
99
|
+
/** Override the default z range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `zReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
100
100
|
zRange?: string[] | number[] | ((args: {
|
|
101
101
|
width: number;
|
|
102
102
|
height: number;
|
|
103
103
|
}) => number[] | string[]) | undefined;
|
|
104
|
-
/** Override the default r range of `[1, 25]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `rReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
104
|
+
/** Override the default r range of `[1, 25]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `rReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
105
105
|
rRange?: string[] | number[] | ((args: {
|
|
106
106
|
width: number;
|
|
107
107
|
height: number;
|
|
108
108
|
}) => number[] | string[]) | undefined;
|
|
109
|
-
/** Set the x1 range by setting an array or function with argument `({ xScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
109
|
+
/** Set the x1 range by setting an array or function with argument `({ xScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
110
110
|
x1Range?: string[] | number[] | ((args: {
|
|
111
111
|
xScale: AnyScale;
|
|
112
112
|
width: number;
|
|
113
113
|
height: number;
|
|
114
114
|
}) => number[] | string[]) | undefined;
|
|
115
|
-
/** Set the y1 range by setting an array or function with argument `({ yScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
115
|
+
/** Set the y1 range by setting an array or function with argument `({ yScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
116
116
|
y1Range?: string[] | number[] | ((args: {
|
|
117
117
|
yScale: AnyScale;
|
|
118
118
|
width: number;
|
|
119
119
|
height: number;
|
|
120
120
|
}) => number[] | string[]) | undefined;
|
|
121
|
-
/** Override the default y1 range of `[0, width]` by setting an array or function with argument `({ yScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [
|
|
122
|
-
cRange?: string[];
|
|
121
|
+
/** Override the default y1 range of `[0, width]` by setting an array or function with argument `({ yScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */
|
|
122
|
+
cRange?: string[] | readonly string[];
|
|
123
123
|
/** Reverse the default x range. By default this is `false` and the range is `[0, width]`. Ignored if you set the xRange prop. @default false */
|
|
124
124
|
xReverse?: boolean;
|
|
125
125
|
/** Reverse the default y range. By default this is `true` and the range is `[height, 0]` unless using an ordinal scale with a `.bandwidth` method for `yScale`. Ignored if you set the `yRange` prop. @default true */
|
|
@@ -192,6 +192,13 @@ declare class __sveltets_Render<TData> {
|
|
|
192
192
|
onClick?: ({ data }: {
|
|
193
193
|
data: any;
|
|
194
194
|
}) => any;
|
|
195
|
+
tooltip?: import("svelte/store").Writable<{
|
|
196
|
+
y: number;
|
|
197
|
+
x: number;
|
|
198
|
+
data: any;
|
|
199
|
+
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
200
|
+
hide: () => void;
|
|
201
|
+
}>;
|
|
195
202
|
}> | undefined;
|
|
196
203
|
/** Props passed to TransformContext */
|
|
197
204
|
transform?: Partial<{
|
|
@@ -242,6 +249,16 @@ declare class __sveltets_Render<TData> {
|
|
|
242
249
|
}> | undefined;
|
|
243
250
|
/** Expose to support `bind:transformContext` for imperative control (`transformContext.translate(...)`) */
|
|
244
251
|
transformContext?: TransformContext;
|
|
252
|
+
/** Exposed via bind: to support `bind:geoProjection` for external access */
|
|
253
|
+
geoProjection?: import("svelte/store").Writable<import("d3-geo").GeoProjection> | undefined;
|
|
254
|
+
/** Exposed via bind: to support `bind:tooltipContext` for external access (ex. `tooltipContext.data) */
|
|
255
|
+
tooltipContext?: import("svelte/store").Writable<{
|
|
256
|
+
y: number;
|
|
257
|
+
x: number;
|
|
258
|
+
data: any;
|
|
259
|
+
show: (e: PointerEvent, tooltipData?: any) => void;
|
|
260
|
+
hide: () => void;
|
|
261
|
+
}> | undefined;
|
|
245
262
|
};
|
|
246
263
|
events(): {
|
|
247
264
|
resize: any;
|
|
@@ -127,7 +127,7 @@ $: if (isMounted) {
|
|
|
127
127
|
containerHeight: $containerHeight,
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
|
-
// Track when mounted since LayerCake initializes width/height with `100` until
|
|
130
|
+
// Track when mounted since LayerCake initializes width/height with `100` until bound `clientWidth`/`clientWidth` can run
|
|
131
131
|
let isMounted = false;
|
|
132
132
|
onMount(() => {
|
|
133
133
|
isMounted = true;
|
|
@@ -115,7 +115,7 @@ declare class __sveltets_Render<TData> {
|
|
|
115
115
|
c?: import("../utils/common.js").Accessor<TData>;
|
|
116
116
|
cScale?: AnyScale<any, any, any, any> | undefined;
|
|
117
117
|
cDomain?: import("../utils/scales.js").DomainType | undefined;
|
|
118
|
-
cRange?: string[] | undefined;
|
|
118
|
+
cRange?: string[] | readonly string[] | undefined;
|
|
119
119
|
/** 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 */ radial?: boolean;
|
|
120
120
|
data?: SankeyGraph<any, any> | TData[] | HierarchyNode<TData> | undefined;
|
|
121
121
|
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<script>import { fade } from 'svelte/transition';
|
|
2
|
+
import { cubicIn } from 'svelte/easing';
|
|
3
|
+
import { curveLinearClosed } from 'd3-shape';
|
|
4
|
+
import { cls } from '@layerstack/tailwind';
|
|
5
|
+
import { chartContext } from './ChartContext.svelte';
|
|
6
|
+
import { isScaleBand } from '../utils/scales.js';
|
|
7
|
+
import Rule from './Rule.svelte';
|
|
8
|
+
import Spline from './Spline.svelte';
|
|
9
|
+
import Circle from './Circle.svelte';
|
|
10
|
+
const { xScale, yScale, radial } = chartContext();
|
|
11
|
+
/** Draw a x-axis lines */
|
|
12
|
+
export let x = false;
|
|
13
|
+
/** Draw a y-axis lines */
|
|
14
|
+
export let y = false;
|
|
15
|
+
/** Control the number of x-axis ticks */
|
|
16
|
+
export let xTicks = undefined;
|
|
17
|
+
/** Control the number of y-axis ticks */
|
|
18
|
+
export let yTicks = !isScaleBand($yScale) ? 4 : undefined;
|
|
19
|
+
/** Line alignment when band scale is used (x or y axis) */
|
|
20
|
+
export let bandAlign = 'center';
|
|
21
|
+
/** Render `y` lines with circles or linear splines */
|
|
22
|
+
export let radialY = 'circle';
|
|
23
|
+
export let spring = undefined;
|
|
24
|
+
export let tweened = undefined;
|
|
25
|
+
export let transitionIn = tweened
|
|
26
|
+
? fade
|
|
27
|
+
: () => {
|
|
28
|
+
return {};
|
|
29
|
+
};
|
|
30
|
+
export let transitionInParams = { easing: cubicIn };
|
|
31
|
+
export let classes = {};
|
|
32
|
+
function getTickVals(scale, ticks) {
|
|
33
|
+
return Array.isArray(ticks)
|
|
34
|
+
? ticks
|
|
35
|
+
: typeof ticks === 'function'
|
|
36
|
+
? ticks(scale)
|
|
37
|
+
: isScaleBand(scale)
|
|
38
|
+
? ticks
|
|
39
|
+
? scale.domain().filter((v, i) => i % ticks === 0)
|
|
40
|
+
: scale.domain()
|
|
41
|
+
: scale.ticks?.(ticks);
|
|
42
|
+
}
|
|
43
|
+
$: xTickVals = getTickVals($xScale, xTicks);
|
|
44
|
+
$: yTickVals = getTickVals($yScale, yTicks);
|
|
45
|
+
$: xBandOffset = isScaleBand($xScale)
|
|
46
|
+
? bandAlign === 'between'
|
|
47
|
+
? -($xScale.padding() * $xScale.step()) / 2 // before
|
|
48
|
+
: $xScale.step() / 2 - ($xScale.padding() * $xScale.step()) / 2 // center
|
|
49
|
+
: 0;
|
|
50
|
+
$: yBandOffset = isScaleBand($yScale)
|
|
51
|
+
? bandAlign === 'between'
|
|
52
|
+
? -($yScale.padding() * $yScale.step()) / 2 // before
|
|
53
|
+
: $yScale.step() / 2 - ($yScale.padding() * $yScale.step()) / 2 // center
|
|
54
|
+
: 0;
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<g class={cls('Grid', classes.root, $$props.class)}>
|
|
58
|
+
{#if x}
|
|
59
|
+
{@const splineProps = typeof x === 'object' ? x : null}
|
|
60
|
+
<g in:transitionIn={transitionInParams}>
|
|
61
|
+
{#each xTickVals as x}
|
|
62
|
+
{#if $radial}
|
|
63
|
+
<Spline
|
|
64
|
+
data={yTickVals.map((y) => ({ x, y }))}
|
|
65
|
+
x="x"
|
|
66
|
+
y="y"
|
|
67
|
+
xOffset={xBandOffset}
|
|
68
|
+
curve={curveLinearClosed}
|
|
69
|
+
{tweened}
|
|
70
|
+
{spring}
|
|
71
|
+
{...splineProps}
|
|
72
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
73
|
+
/>
|
|
74
|
+
{:else}
|
|
75
|
+
<Rule
|
|
76
|
+
{x}
|
|
77
|
+
xOffset={xBandOffset}
|
|
78
|
+
{tweened}
|
|
79
|
+
{spring}
|
|
80
|
+
{...splineProps}
|
|
81
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
82
|
+
/>
|
|
83
|
+
{/if}
|
|
84
|
+
{/each}
|
|
85
|
+
|
|
86
|
+
<!-- Add extra rule after last band -->
|
|
87
|
+
{#if isScaleBand($xScale) && bandAlign === 'between' && !$radial && xTickVals.length}
|
|
88
|
+
<Rule
|
|
89
|
+
x={xTickVals[xTickVals.length - 1]}
|
|
90
|
+
xOffset={xBandOffset + $xScale.step()}
|
|
91
|
+
{tweened}
|
|
92
|
+
{spring}
|
|
93
|
+
{...splineProps}
|
|
94
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
95
|
+
/>
|
|
96
|
+
{/if}
|
|
97
|
+
</g>
|
|
98
|
+
{/if}
|
|
99
|
+
|
|
100
|
+
{#if y}
|
|
101
|
+
{@const splineProps = typeof y === 'object' ? y : null}
|
|
102
|
+
<g in:transitionIn={transitionInParams}>
|
|
103
|
+
{#each yTickVals as y}
|
|
104
|
+
{#if $radial}
|
|
105
|
+
{#if radialY === 'circle'}
|
|
106
|
+
<Circle
|
|
107
|
+
r={$yScale(y)}
|
|
108
|
+
{tweened}
|
|
109
|
+
{spring}
|
|
110
|
+
{...splineProps}
|
|
111
|
+
class={cls('fill-none stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
112
|
+
/>
|
|
113
|
+
{:else}
|
|
114
|
+
<Spline
|
|
115
|
+
data={xTickVals.map((x) => ({ x, y }))}
|
|
116
|
+
x="x"
|
|
117
|
+
y="y"
|
|
118
|
+
yOffset={yBandOffset}
|
|
119
|
+
{tweened}
|
|
120
|
+
{spring}
|
|
121
|
+
curve={curveLinearClosed}
|
|
122
|
+
{...splineProps}
|
|
123
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
124
|
+
/>
|
|
125
|
+
{/if}
|
|
126
|
+
{:else}
|
|
127
|
+
<Rule
|
|
128
|
+
{y}
|
|
129
|
+
yOffset={yBandOffset}
|
|
130
|
+
{tweened}
|
|
131
|
+
{spring}
|
|
132
|
+
{...splineProps}
|
|
133
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
134
|
+
/>
|
|
135
|
+
{/if}
|
|
136
|
+
{/each}
|
|
137
|
+
|
|
138
|
+
<!-- Add extra rule after last band -->
|
|
139
|
+
{#if isScaleBand($yScale) && bandAlign === 'between' && !$radial && yTickVals.length}
|
|
140
|
+
<Rule
|
|
141
|
+
y={yTickVals[yTickVals.length - 1]}
|
|
142
|
+
yOffset={yBandOffset + $yScale.step()}
|
|
143
|
+
{tweened}
|
|
144
|
+
{spring}
|
|
145
|
+
{...splineProps}
|
|
146
|
+
class={cls('stroke-surface-content/10', classes.line, splineProps?.class)}
|
|
147
|
+
/>
|
|
148
|
+
{/if}
|
|
149
|
+
</g>
|
|
150
|
+
{/if}
|
|
151
|
+
</g>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { SVGAttributes } from 'svelte/elements';
|
|
3
|
+
import { fade } from 'svelte/transition';
|
|
4
|
+
import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
|
|
5
|
+
import type { TransitionParams } from 'svelte-ux';
|
|
6
|
+
import { type AnyScale } from '../utils/scales.js';
|
|
7
|
+
declare const __propDef: {
|
|
8
|
+
props: {
|
|
9
|
+
[x: string]: any;
|
|
10
|
+
x?: (boolean | Pick<SVGAttributes<SVGElement>, "class" | "style">) | undefined;
|
|
11
|
+
y?: (boolean | Pick<SVGAttributes<SVGElement>, "class" | "style">) | undefined;
|
|
12
|
+
xTicks?: number | any[] | ((scale: AnyScale) => any) | null | undefined;
|
|
13
|
+
yTicks?: number | any[] | ((scale: AnyScale) => any) | null | undefined;
|
|
14
|
+
bandAlign?: ("center" | "between") | undefined;
|
|
15
|
+
radialY?: ("circle" | "linear") | undefined;
|
|
16
|
+
spring?: boolean | Parameters<typeof springStore>[1];
|
|
17
|
+
tweened?: boolean | Parameters<typeof tweenedStore>[1];
|
|
18
|
+
transitionIn?: (typeof fade | (() => {})) | undefined;
|
|
19
|
+
transitionInParams?: TransitionParams | undefined;
|
|
20
|
+
classes?: {
|
|
21
|
+
root?: string;
|
|
22
|
+
line?: string;
|
|
23
|
+
} | undefined;
|
|
24
|
+
};
|
|
25
|
+
events: {
|
|
26
|
+
[evt: string]: CustomEvent<any>;
|
|
27
|
+
};
|
|
28
|
+
slots: {};
|
|
29
|
+
};
|
|
30
|
+
export type GridProps = typeof __propDef.props;
|
|
31
|
+
export type GridEvents = typeof __propDef.events;
|
|
32
|
+
export type GridSlots = typeof __propDef.slots;
|
|
33
|
+
export default class Grid extends SvelteComponentTyped<GridProps, GridEvents, GridSlots> {
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -5,16 +5,26 @@ import Text from './Text.svelte';
|
|
|
5
5
|
import { isScaleBand } from '../utils/scales.js';
|
|
6
6
|
import { chartContext } from './ChartContext.svelte';
|
|
7
7
|
import Points, {} from './Points.svelte';
|
|
8
|
+
import { accessor } from '../utils/common.js';
|
|
9
|
+
const { xScale, yScale } = chartContext();
|
|
10
|
+
/** Override display value accessor. By default, uses `y` unless yScale is band scale */
|
|
11
|
+
export let value = undefined;
|
|
8
12
|
export let placement = 'outside';
|
|
9
13
|
export let offset = placement === 'center' ? 0 : 4;
|
|
10
14
|
export let format = undefined;
|
|
11
|
-
const { yScale } = chartContext();
|
|
12
15
|
$: getTextProps = (point) => {
|
|
13
|
-
|
|
14
|
-
const
|
|
16
|
+
// Used for positioning
|
|
17
|
+
const pointValue = isScaleBand($yScale) ? point.xValue : point.yValue;
|
|
18
|
+
const displayValue = value
|
|
19
|
+
? accessor(value)(point.data)
|
|
20
|
+
: isScaleBand($yScale)
|
|
21
|
+
? point.xValue
|
|
22
|
+
: point.yValue;
|
|
23
|
+
const formattedValue = formatValue(displayValue, format ??
|
|
24
|
+
(value ? undefined : isScaleBand($yScale) ? $xScale.tickFormat?.() : $yScale.tickFormat?.()));
|
|
15
25
|
if (isScaleBand($yScale)) {
|
|
16
26
|
// Position label left/right on horizontal bars
|
|
17
|
-
if (
|
|
27
|
+
if (pointValue < 0) {
|
|
18
28
|
// left
|
|
19
29
|
return {
|
|
20
30
|
value: formattedValue,
|
|
@@ -39,7 +49,7 @@ $: getTextProps = (point) => {
|
|
|
39
49
|
}
|
|
40
50
|
else {
|
|
41
51
|
// Position label top/bottom on vertical bars
|
|
42
|
-
if (
|
|
52
|
+
if (pointValue < 0) {
|
|
43
53
|
// bottom
|
|
44
54
|
return {
|
|
45
55
|
value: formattedValue,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import { type FormatType } from '@layerstack/utils';
|
|
3
|
+
import { type Accessor } from '../utils/common.js';
|
|
3
4
|
declare const __propDef: {
|
|
4
5
|
props: {
|
|
5
6
|
[x: string]: any;
|
|
7
|
+
value?: Accessor;
|
|
6
8
|
placement?: ("inside" | "outside" | "center") | undefined;
|
|
7
9
|
offset?: number | undefined;
|
|
8
10
|
format?: FormatType | undefined;
|
|
@@ -182,7 +182,7 @@ else {
|
|
|
182
182
|
class={cls('h-4 w-4 rounded-full', classes.swatch)}
|
|
183
183
|
style:background-color={scale(tick)}
|
|
184
184
|
/>
|
|
185
|
-
<div class={cls('text-xs text-surface-content', classes.label)}>
|
|
185
|
+
<div class={cls('text-xs text-surface-content whitespace-nowrap', classes.label)}>
|
|
186
186
|
{tickFormat ? format(tick, tickFormat) : tick}
|
|
187
187
|
</div>
|
|
188
188
|
</div>
|