@rokkit/chart 1.3.6 → 1.3.8
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/AnimatedPlot.svelte +26 -8
- package/dist/AnimatedPlot.svelte.d.ts +5 -0
- package/dist/Chart.svelte +1 -1
- package/dist/FacetPlot.svelte +1 -1
- package/dist/Plot/Axis.svelte +21 -10
- package/dist/Plot/Grid.svelte +32 -13
- package/dist/Plot/Grid.svelte.d.ts +6 -1
- package/dist/Plot/Root.svelte +64 -46
- package/dist/Plot/Root.svelte.d.ts +27 -2
- package/dist/Plot/Timeline.svelte +39 -13
- package/dist/Plot/index.d.ts +4 -4
- package/dist/Plot/index.js +4 -4
- package/dist/Plot.svelte +128 -164
- package/dist/Plot.svelte.d.ts +18 -2
- package/dist/PlotState.svelte.d.ts +23 -0
- package/dist/PlotState.svelte.js +155 -16
- package/dist/PlotSurface.svelte +162 -0
- package/dist/PlotSurface.svelte.d.ts +25 -0
- package/dist/charts/AreaChart.svelte +37 -4
- package/dist/charts/AreaChart.svelte.d.ts +12 -2
- package/dist/charts/BarChart.svelte +32 -3
- package/dist/charts/BarChart.svelte.d.ts +10 -1
- package/dist/charts/BoxPlot.svelte +4 -2
- package/dist/charts/BoxPlot.svelte.d.ts +1 -0
- package/dist/charts/BubbleChart.svelte +34 -3
- package/dist/charts/BubbleChart.svelte.d.ts +11 -1
- package/dist/charts/LineChart.svelte +35 -4
- package/dist/charts/LineChart.svelte.d.ts +11 -2
- package/dist/charts/PieChart.svelte +1 -1
- package/dist/charts/ScatterPlot.svelte +32 -3
- package/dist/charts/ScatterPlot.svelte.d.ts +10 -1
- package/dist/charts/ViolinPlot.svelte +4 -2
- package/dist/charts/ViolinPlot.svelte.d.ts +1 -0
- package/dist/examples/BarChartExample.svelte +1 -1
- package/dist/geoms/Arc.svelte +3 -2
- package/dist/geoms/Area.svelte +20 -3
- package/dist/geoms/Bar.svelte +57 -13
- package/dist/geoms/Box.svelte +131 -76
- package/dist/geoms/Box.svelte.d.ts +7 -0
- package/dist/geoms/Candlestick.svelte +17 -11
- package/dist/geoms/Highlight.svelte +105 -0
- package/dist/geoms/Highlight.svelte.d.ts +10 -0
- package/dist/geoms/Jitter.svelte +82 -0
- package/dist/geoms/Jitter.svelte.d.ts +15 -0
- package/dist/geoms/Line.svelte +26 -9
- package/dist/geoms/Point.svelte +37 -11
- package/dist/geoms/Rule.svelte +113 -0
- package/dist/geoms/Rule.svelte.d.ts +16 -0
- package/dist/geoms/Trend.svelte +66 -0
- package/dist/geoms/Trend.svelte.d.ts +12 -0
- package/dist/geoms/Violin.svelte +30 -6
- package/dist/geoms/Violin.svelte.d.ts +5 -0
- package/dist/geoms/Waterfall.svelte +16 -9
- package/dist/geoms/lib/areas.d.ts +6 -2
- package/dist/geoms/lib/areas.js +17 -11
- package/dist/geoms/lib/bars.d.ts +18 -3
- package/dist/geoms/lib/bars.js +70 -96
- package/dist/index.d.ts +30 -4
- package/dist/index.js +31 -5
- package/dist/lib/brewing/ViolinBrewer.svelte.d.ts +1 -1
- package/dist/lib/brewing/brewer.svelte.d.ts +1 -0
- package/dist/lib/brewing/marks/arcs.js +7 -1
- package/dist/lib/brewing/marks/boxes.d.ts +11 -2
- package/dist/lib/brewing/marks/boxes.js +32 -11
- package/dist/lib/brewing/marks/lines.d.ts +6 -2
- package/dist/lib/brewing/marks/lines.js +19 -12
- package/dist/lib/brewing/marks/swarm.d.ts +32 -0
- package/dist/lib/brewing/marks/swarm.js +125 -0
- package/dist/lib/brewing/marks/violins.d.ts +4 -20
- package/dist/lib/brewing/marks/violins.js +41 -25
- package/dist/lib/brewing/stats.d.ts +3 -1
- package/dist/lib/brewing/stats.js +28 -11
- package/dist/lib/highlight.d.ts +10 -0
- package/dist/lib/highlight.js +43 -0
- package/dist/lib/plot/scales.js +12 -7
- package/dist/lib/plot/types.d.ts +9 -1
- package/dist/lib/plot/types.js +3 -1
- package/dist/lib/scale.d.ts +10 -0
- package/dist/lib/scale.js +14 -0
- package/dist/lib/select.d.ts +22 -0
- package/dist/lib/select.js +22 -0
- package/dist/lib/trend.d.ts +27 -0
- package/dist/lib/trend.js +113 -0
- package/dist/patterns/README.md +1 -1
- package/package.json +1 -1
- package/dist/Plot/Area.svelte +0 -54
- package/dist/Plot/Area.svelte.d.ts +0 -14
- package/dist/Plot/Bar.svelte +0 -69
- package/dist/Plot/Bar.svelte.d.ts +0 -11
- package/dist/Plot/Line.svelte +0 -54
- package/dist/Plot/Line.svelte.d.ts +0 -13
- package/dist/Plot/Point.svelte +0 -58
- package/dist/Plot/Point.svelte.d.ts +0 -13
package/dist/AnimatedPlot.svelte
CHANGED
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
tween?: boolean
|
|
35
35
|
sorted?: boolean
|
|
36
36
|
dynamicDomain?: boolean
|
|
37
|
+
/** Chart direction for standard (non-race) animations — flips via the same geom
|
|
38
|
+
* place() mechanism as static charts. `flip` is sugar for 'horizontal'. Ignored for
|
|
39
|
+
* the bar-chart race, which is inherently horizontal. */
|
|
40
|
+
orientation?: 'vertical' | 'horizontal'
|
|
41
|
+
flip?: boolean
|
|
37
42
|
label?: boolean | string | ((data: Row) => string)
|
|
38
43
|
children?: Snippet
|
|
39
44
|
}
|
|
@@ -53,16 +58,22 @@
|
|
|
53
58
|
helpers = {},
|
|
54
59
|
width = 600,
|
|
55
60
|
height = 400,
|
|
56
|
-
mode =
|
|
61
|
+
mode = undefined,
|
|
57
62
|
grid = true,
|
|
58
63
|
legend = false,
|
|
59
64
|
tween = true,
|
|
60
65
|
sorted = false,
|
|
61
66
|
dynamicDomain = false,
|
|
67
|
+
orientation = undefined,
|
|
68
|
+
flip = false,
|
|
62
69
|
label = false,
|
|
63
70
|
children
|
|
64
71
|
}: Props = $props()
|
|
65
72
|
|
|
73
|
+
// Standard-animation direction (non-race). Flows to the frameSpec so the geoms flip via the
|
|
74
|
+
// same place() path as static charts; the frame tween interpolates values orientation-agnostically.
|
|
75
|
+
const resolvedOrientation = $derived(flip ? 'horizontal' : orientation)
|
|
76
|
+
|
|
66
77
|
// Effective geom list: explicit array takes precedence; otherwise build from shorthand props
|
|
67
78
|
const effectiveGeoms = $derived(
|
|
68
79
|
geoms.length > 0
|
|
@@ -348,23 +359,30 @@
|
|
|
348
359
|
}))
|
|
349
360
|
)
|
|
350
361
|
|
|
351
|
-
|
|
362
|
+
// The race's value-axis domain (the caller's x = the measured value), dynamic or static.
|
|
363
|
+
const valueDomainForFrame = $derived(
|
|
352
364
|
isHorizontalRace && dynamicDomain ? $xDomainTween : staticDomains.xDomain
|
|
353
365
|
)
|
|
354
366
|
const frameSpec = $derived<PlotSpec>({
|
|
355
367
|
data: $displayTween,
|
|
356
|
-
|
|
357
|
-
|
|
368
|
+
// Race uses the STANDARD convention so it flips through the same place() path as every
|
|
369
|
+
// chart: x = the continuous `_rank` (category/position axis), y = the caller's value.
|
|
370
|
+
// `continuousCategory` keeps the rank scale linear so fractional ranks tween smoothly.
|
|
371
|
+
x: isHorizontalRace ? '_rank' : x,
|
|
372
|
+
y: isHorizontalRace ? x : y,
|
|
358
373
|
color,
|
|
359
374
|
geoms: isHorizontalRace ? raceGeoms : prepared.geoms,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
375
|
+
// Pad the rank axis half a slot each end so the first/last bar's thickness doesn't spill
|
|
376
|
+
// past the axis (a continuous-category bar centres on the rank with a step-derived height).
|
|
377
|
+
xDomain: isHorizontalRace ? [-0.5, entityCount - 0.5] : staticDomains.xDomain,
|
|
378
|
+
yDomain: isHorizontalRace ? valueDomainForFrame : staticDomains.yDomain,
|
|
379
|
+
orientation: isHorizontalRace ? 'horizontal' : resolvedOrientation,
|
|
380
|
+
continuousCategory: isHorizontalRace
|
|
363
381
|
})
|
|
364
382
|
</script>
|
|
365
383
|
|
|
366
384
|
<div data-plot-animated>
|
|
367
|
-
<PlotChart spec={frameSpec} {helpers} {width} {height} {mode} {grid} {legend}>
|
|
385
|
+
<PlotChart spec={frameSpec} {helpers} {width} {height} {mode} {grid} {legend} animate={false}>
|
|
368
386
|
{@render children?.()}
|
|
369
387
|
</PlotChart>
|
|
370
388
|
|
|
@@ -27,6 +27,11 @@ type Props = {
|
|
|
27
27
|
tween?: boolean;
|
|
28
28
|
sorted?: boolean;
|
|
29
29
|
dynamicDomain?: boolean;
|
|
30
|
+
/** Chart direction for standard (non-race) animations — flips via the same geom
|
|
31
|
+
* place() mechanism as static charts. `flip` is sugar for 'horizontal'. Ignored for
|
|
32
|
+
* the bar-chart race, which is inherently horizontal. */
|
|
33
|
+
orientation?: 'vertical' | 'horizontal';
|
|
34
|
+
flip?: boolean;
|
|
30
35
|
label?: boolean | string | ((data: Row) => string);
|
|
31
36
|
children?: Snippet;
|
|
32
37
|
};
|
package/dist/Chart.svelte
CHANGED
package/dist/FacetPlot.svelte
CHANGED
package/dist/Plot/Axis.svelte
CHANGED
|
@@ -59,16 +59,21 @@
|
|
|
59
59
|
const xTicks = $derived(buildTicks(state.xScale))
|
|
60
60
|
const yTicks = $derived(buildTicks(state.yScale))
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
// When flipped, the x-channel (category) axis stands up on the left and the value (y)
|
|
63
|
+
// axis lies along the bottom — each axis type renders on the opposite screen orientation.
|
|
64
|
+
const flipped = $derived(state.isFlipped)
|
|
65
|
+
const renderAsX = $derived((type === 'x') !== flipped)
|
|
66
|
+
const ticks = $derived(type === 'x' ? xTicks : yTicks)
|
|
67
|
+
const hAxisY = $derived(flipped ? state.innerHeight : (state.xAxisY ?? state.innerHeight))
|
|
68
|
+
const vAxisX = $derived(flipped ? 0 : (state.yAxisX ?? 0))
|
|
64
69
|
</script>
|
|
65
70
|
|
|
66
|
-
{#if
|
|
67
|
-
<g class="axis x-axis" transform={
|
|
71
|
+
{#if renderAsX}
|
|
72
|
+
<g class="axis x-axis" transform={`translate(0, ${hAxisY})`} data-plot-axis="x">
|
|
68
73
|
{#if showLine}
|
|
69
74
|
<line x1="0" y1="0" x2={state.innerWidth} y2="0" data-plot-axis-line />
|
|
70
75
|
{/if}
|
|
71
|
-
{#each
|
|
76
|
+
{#each ticks as tick (tick.minor ? `minor-${tick.pos}` : tick.value)}
|
|
72
77
|
<g transform="translate({tick.pos}, 0)" data-plot-tick>
|
|
73
78
|
{#if showTicks}
|
|
74
79
|
<line
|
|
@@ -96,11 +101,11 @@
|
|
|
96
101
|
{/if}
|
|
97
102
|
</g>
|
|
98
103
|
{:else}
|
|
99
|
-
<g class="axis y-axis" transform={
|
|
104
|
+
<g class="axis y-axis" transform={`translate(${vAxisX}, 0)`} data-plot-axis="y">
|
|
100
105
|
{#if showLine}
|
|
101
106
|
<line x1="0" y1="0" x2="0" y2={state.innerHeight} data-plot-axis-line />
|
|
102
107
|
{/if}
|
|
103
|
-
{#each
|
|
108
|
+
{#each ticks as tick (tick.minor ? `minor-${tick.pos}` : tick.value)}
|
|
104
109
|
<g transform="translate(0, {tick.pos})" data-plot-tick>
|
|
105
110
|
{#if showTicks}
|
|
106
111
|
<line
|
|
@@ -130,16 +135,22 @@
|
|
|
130
135
|
{/if}
|
|
131
136
|
|
|
132
137
|
<style>
|
|
138
|
+
/* Readable, theme-adaptive axis colours (fall back to currentColor for a base-only
|
|
139
|
+
consumer that doesn't provide the --ink token vocabulary). currentColor alone was a
|
|
140
|
+
mode-hardcoded surface tone that went faint on a dark theme paper. */
|
|
133
141
|
.axis {
|
|
134
142
|
font-size: 11px;
|
|
135
|
-
fill: currentColor;
|
|
136
|
-
stroke: currentColor;
|
|
143
|
+
fill: var(--ink-mute, currentColor);
|
|
144
|
+
stroke: var(--ink-mute, currentColor);
|
|
137
145
|
}
|
|
138
146
|
.axis-label {
|
|
139
147
|
font-size: 13px;
|
|
140
148
|
font-weight: 500;
|
|
149
|
+
fill: var(--ink, currentColor);
|
|
141
150
|
}
|
|
142
151
|
[data-plot-axis-line] {
|
|
143
|
-
stroke: currentColor;
|
|
152
|
+
stroke: var(--paper-edge, currentColor);
|
|
153
|
+
/* Decoration only — never intercept clicks meant for data marks beneath it. */
|
|
154
|
+
pointer-events: none;
|
|
144
155
|
}
|
|
145
156
|
</style>
|
package/dist/Plot/Grid.svelte
CHANGED
|
@@ -2,26 +2,44 @@
|
|
|
2
2
|
import { getContext } from 'svelte'
|
|
3
3
|
import type { PlotState } from '../PlotState.svelte.js'
|
|
4
4
|
|
|
5
|
+
type Props = {
|
|
6
|
+
lines?: 'auto' | 'x' | 'y' | 'both'
|
|
7
|
+
xTicks?: number
|
|
8
|
+
yTicks?: number
|
|
9
|
+
}
|
|
10
|
+
let { lines = 'auto', xTicks = 6, yTicks = 6 }: Props = $props()
|
|
11
|
+
|
|
5
12
|
const state = getContext<PlotState>('plot-state')
|
|
6
13
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
if (!s || typeof s.bandwidth !== 'function') return []
|
|
10
|
-
return s.domain().map((val: unknown) => ({ pos: (s(val) ?? 0) + s.bandwidth() / 2 }))
|
|
11
|
-
})
|
|
14
|
+
const isBand = (s: unknown) =>
|
|
15
|
+
!!s && typeof (s as { bandwidth?: unknown }).bandwidth === 'function'
|
|
12
16
|
|
|
13
|
-
const
|
|
17
|
+
const showX = $derived(
|
|
18
|
+
lines === 'x' || lines === 'both' || (lines === 'auto' && isBand(state.xScale))
|
|
19
|
+
)
|
|
20
|
+
const showY = $derived(lines === 'auto' || lines === 'y' || lines === 'both')
|
|
21
|
+
|
|
22
|
+
const yLines = $derived.by(() => {
|
|
14
23
|
const s = state.yScale
|
|
15
|
-
if (!s || typeof s.ticks !== 'function') return []
|
|
16
|
-
return s.ticks(
|
|
24
|
+
if (!showY || !s || typeof s.ticks !== 'function') return []
|
|
25
|
+
return s.ticks(yTicks).map((val: number) => ({ pos: s(val) }))
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const xLines = $derived.by(() => {
|
|
29
|
+
const s = state.xScale
|
|
30
|
+
if (!showX || !s) return []
|
|
31
|
+
if (isBand(s))
|
|
32
|
+
return s.domain().map((val: unknown) => ({ pos: (s(val) ?? 0) + s.bandwidth() / 2 }))
|
|
33
|
+
if (typeof s.ticks !== 'function') return []
|
|
34
|
+
return s.ticks(xTicks).map((val: number) => ({ pos: s(val) }))
|
|
17
35
|
})
|
|
18
36
|
</script>
|
|
19
37
|
|
|
20
38
|
<g class="grid" data-plot-grid>
|
|
21
|
-
{#each
|
|
22
|
-
<line x1="0" y1={line.pos} x2={state.innerWidth} y2={line.pos} data-plot-grid-line />
|
|
39
|
+
{#each yLines as line (line.pos)}
|
|
40
|
+
<line x1="0" y1={line.pos} x2={state.innerWidth} y2={line.pos} data-plot-grid-line="y" />
|
|
23
41
|
{/each}
|
|
24
|
-
{#each
|
|
42
|
+
{#each xLines as line (line.pos)}
|
|
25
43
|
<line x1={line.pos} y1="0" x2={line.pos} y2={state.innerHeight} data-plot-grid-line="x" />
|
|
26
44
|
{/each}
|
|
27
45
|
</g>
|
|
@@ -29,7 +47,8 @@
|
|
|
29
47
|
<style>
|
|
30
48
|
[data-plot-grid-line] {
|
|
31
49
|
stroke: var(--chart-grid-color, currentColor);
|
|
32
|
-
|
|
33
|
-
stroke-dasharray: 2 4;
|
|
50
|
+
stroke-width: var(--chart-grid-width, 1);
|
|
51
|
+
stroke-dasharray: var(--chart-grid-dash, 2 4);
|
|
52
|
+
opacity: var(--chart-grid-opacity, 0.15);
|
|
34
53
|
}
|
|
35
54
|
</style>
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
type Props = {
|
|
2
|
+
lines?: 'auto' | 'x' | 'y' | 'both';
|
|
3
|
+
xTicks?: number;
|
|
4
|
+
yTicks?: number;
|
|
5
|
+
};
|
|
6
|
+
declare const Grid: import("svelte").Component<Props, {}, "">;
|
|
2
7
|
type Grid = ReturnType<typeof Grid>;
|
|
3
8
|
export default Grid;
|
package/dist/Plot/Root.svelte
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { setContext, untrack } from 'svelte'
|
|
3
2
|
import type { Snippet } from 'svelte'
|
|
4
|
-
import { PlotState } from '../PlotState.svelte.js'
|
|
5
3
|
import { defaultPreset } from '../lib/preset.js'
|
|
4
|
+
import PlotSurface from '../PlotSurface.svelte'
|
|
6
5
|
|
|
7
6
|
type Margin = { top?: number; right?: number; bottom?: number; left?: number }
|
|
7
|
+
type Row = Record<string, unknown>
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
|
-
data?:
|
|
10
|
+
data?: Row[]
|
|
11
11
|
x?: string
|
|
12
12
|
y?: string
|
|
13
13
|
color?: string
|
|
@@ -15,6 +15,30 @@
|
|
|
15
15
|
height?: number
|
|
16
16
|
margin?: Margin
|
|
17
17
|
mode?: 'light' | 'dark'
|
|
18
|
+
/** Chart direction. 'horizontal' stands the category axis up and runs the value
|
|
19
|
+
* axis sideways — x/y channels are unchanged. `flip` is sugar for 'horizontal'. */
|
|
20
|
+
orientation?: 'vertical' | 'horizontal'
|
|
21
|
+
flip?: boolean
|
|
22
|
+
/** Order the category (band) axis by aggregated value instead of by label — bars sorted
|
|
23
|
+
* by size (histogram-style). 'desc' (largest first) | 'asc'. */
|
|
24
|
+
sort?: 'asc' | 'desc'
|
|
25
|
+
/** Explicit scale domain overrides. */
|
|
26
|
+
xDomain?: unknown[]
|
|
27
|
+
yDomain?: unknown[]
|
|
28
|
+
/** Continuous colour scale controls (sequential/diverging). */
|
|
29
|
+
colorScale?: unknown
|
|
30
|
+
colorScheme?: string
|
|
31
|
+
colorDomain?: unknown[]
|
|
32
|
+
colorMidpoint?: number
|
|
33
|
+
/** Enable d3-zoom pan/zoom. */
|
|
34
|
+
zoom?: boolean
|
|
35
|
+
/** Opt-in click-to-select; fires onselect(detail) and syncs bind:selected (row refs). */
|
|
36
|
+
selectable?: boolean
|
|
37
|
+
onselect?: (detail: unknown) => void
|
|
38
|
+
selected?: Row[]
|
|
39
|
+
/** Animate marks on data/flip changes. Enabled one frame after mount so the
|
|
40
|
+
* initial layout paints un-animated. Default `true`. */
|
|
41
|
+
animate?: boolean
|
|
18
42
|
children?: Snippet
|
|
19
43
|
}
|
|
20
44
|
|
|
@@ -26,52 +50,46 @@
|
|
|
26
50
|
width = 600,
|
|
27
51
|
height = 400,
|
|
28
52
|
margin = undefined,
|
|
29
|
-
mode =
|
|
53
|
+
mode = undefined,
|
|
54
|
+
orientation = undefined,
|
|
55
|
+
flip = false,
|
|
56
|
+
sort = undefined,
|
|
57
|
+
xDomain = undefined,
|
|
58
|
+
yDomain = undefined,
|
|
59
|
+
colorScale = undefined,
|
|
60
|
+
colorScheme = undefined,
|
|
61
|
+
colorDomain = undefined,
|
|
62
|
+
colorMidpoint = undefined,
|
|
63
|
+
zoom = false,
|
|
64
|
+
selectable = false,
|
|
65
|
+
onselect = undefined,
|
|
66
|
+
selected = $bindable([]),
|
|
67
|
+
animate = true,
|
|
30
68
|
children
|
|
31
69
|
}: Props = $props()
|
|
32
70
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
margin,
|
|
53
|
-
mode,
|
|
54
|
-
chartPreset: defaultPreset
|
|
55
|
-
})
|
|
71
|
+
// The composable root is just PlotSurface (the shared shell) fed a config from these props.
|
|
72
|
+
const config = $derived({
|
|
73
|
+
data,
|
|
74
|
+
channels: { x, y, color },
|
|
75
|
+
width,
|
|
76
|
+
height,
|
|
77
|
+
margin,
|
|
78
|
+
mode,
|
|
79
|
+
orientation: flip ? 'horizontal' : orientation,
|
|
80
|
+
sort,
|
|
81
|
+
xDomain,
|
|
82
|
+
yDomain,
|
|
83
|
+
colorScale,
|
|
84
|
+
colorScheme,
|
|
85
|
+
colorDomain,
|
|
86
|
+
colorMidpoint,
|
|
87
|
+
onselect,
|
|
88
|
+
selectable,
|
|
89
|
+
chartPreset: defaultPreset
|
|
56
90
|
})
|
|
57
|
-
|
|
58
|
-
setContext('plot-state', plotState)
|
|
59
|
-
|
|
60
|
-
const svgWidth = $derived(plotState.innerWidth + (margin?.left ?? 50) + (margin?.right ?? 30))
|
|
61
|
-
const svgHeight = $derived(plotState.innerHeight + (margin?.top ?? 20) + (margin?.bottom ?? 40))
|
|
62
|
-
const marginLeft = $derived(margin?.left ?? 50)
|
|
63
|
-
const marginTop = $derived(margin?.top ?? 20)
|
|
64
91
|
</script>
|
|
65
92
|
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
viewBox="0 0 {svgWidth} {svgHeight}"
|
|
70
|
-
role="img"
|
|
71
|
-
aria-label="Chart visualization"
|
|
72
|
-
data-plot-root
|
|
73
|
-
>
|
|
74
|
-
<g transform="translate({marginLeft}, {marginTop})" data-plot-canvas>
|
|
75
|
-
{@render children?.()}
|
|
76
|
-
</g>
|
|
77
|
-
</svg>
|
|
93
|
+
<PlotSurface {config} {animate} {zoom} bind:selected>
|
|
94
|
+
{@render children?.()}
|
|
95
|
+
</PlotSurface>
|
|
@@ -5,8 +5,9 @@ type Margin = {
|
|
|
5
5
|
bottom?: number;
|
|
6
6
|
left?: number;
|
|
7
7
|
};
|
|
8
|
+
type Row = Record<string, unknown>;
|
|
8
9
|
type Props = {
|
|
9
|
-
data?:
|
|
10
|
+
data?: Row[];
|
|
10
11
|
x?: string;
|
|
11
12
|
y?: string;
|
|
12
13
|
color?: string;
|
|
@@ -14,8 +15,32 @@ type Props = {
|
|
|
14
15
|
height?: number;
|
|
15
16
|
margin?: Margin;
|
|
16
17
|
mode?: 'light' | 'dark';
|
|
18
|
+
/** Chart direction. 'horizontal' stands the category axis up and runs the value
|
|
19
|
+
* axis sideways — x/y channels are unchanged. `flip` is sugar for 'horizontal'. */
|
|
20
|
+
orientation?: 'vertical' | 'horizontal';
|
|
21
|
+
flip?: boolean;
|
|
22
|
+
/** Order the category (band) axis by aggregated value instead of by label — bars sorted
|
|
23
|
+
* by size (histogram-style). 'desc' (largest first) | 'asc'. */
|
|
24
|
+
sort?: 'asc' | 'desc';
|
|
25
|
+
/** Explicit scale domain overrides. */
|
|
26
|
+
xDomain?: unknown[];
|
|
27
|
+
yDomain?: unknown[];
|
|
28
|
+
/** Continuous colour scale controls (sequential/diverging). */
|
|
29
|
+
colorScale?: unknown;
|
|
30
|
+
colorScheme?: string;
|
|
31
|
+
colorDomain?: unknown[];
|
|
32
|
+
colorMidpoint?: number;
|
|
33
|
+
/** Enable d3-zoom pan/zoom. */
|
|
34
|
+
zoom?: boolean;
|
|
35
|
+
/** Opt-in click-to-select; fires onselect(detail) and syncs bind:selected (row refs). */
|
|
36
|
+
selectable?: boolean;
|
|
37
|
+
onselect?: (detail: unknown) => void;
|
|
38
|
+
selected?: Row[];
|
|
39
|
+
/** Animate marks on data/flip changes. Enabled one frame after mount so the
|
|
40
|
+
* initial layout paints un-animated. Default `true`. */
|
|
41
|
+
animate?: boolean;
|
|
17
42
|
children?: Snippet;
|
|
18
43
|
};
|
|
19
|
-
declare const Root: import("svelte").Component<Props, {}, "">;
|
|
44
|
+
declare const Root: import("svelte").Component<Props, {}, "selected">;
|
|
20
45
|
type Root = ReturnType<typeof Root>;
|
|
21
46
|
export default Root;
|
|
@@ -24,8 +24,6 @@
|
|
|
24
24
|
const safeIndex = $derived(
|
|
25
25
|
frameKeys.length === 0 ? 0 : Math.min(currentIndex, frameKeys.length - 1)
|
|
26
26
|
)
|
|
27
|
-
|
|
28
|
-
const SPEEDS = [0.5, 1, 1.5, 2, 4]
|
|
29
27
|
</script>
|
|
30
28
|
|
|
31
29
|
<div class="timeline" data-plot-timeline>
|
|
@@ -56,17 +54,20 @@
|
|
|
56
54
|
data-plot-timeline-scrub
|
|
57
55
|
/>
|
|
58
56
|
|
|
59
|
-
<!-- Speed
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
<!-- Speed (× multiplier) — themed numeric input -->
|
|
58
|
+
<div class="speed">
|
|
59
|
+
<input
|
|
60
|
+
type="number"
|
|
61
|
+
min="0.25"
|
|
62
|
+
max="8"
|
|
63
|
+
step="0.25"
|
|
64
|
+
value={speed}
|
|
65
|
+
aria-label="Playback speed"
|
|
66
|
+
onchange={(e) => onspeed?.(Math.max(0.25, Number(e.currentTarget.value) || 1))}
|
|
67
|
+
data-plot-timeline-speed
|
|
68
|
+
/>
|
|
69
|
+
<span class="speed-unit" aria-hidden="true">×</span>
|
|
70
|
+
</div>
|
|
70
71
|
</div>
|
|
71
72
|
|
|
72
73
|
<style>
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
gap: 8px;
|
|
77
78
|
padding: 8px 0;
|
|
78
79
|
font-size: 12px;
|
|
80
|
+
color: var(--ink-mute, currentColor);
|
|
79
81
|
}
|
|
80
82
|
.play-pause {
|
|
81
83
|
font-size: 16px;
|
|
@@ -83,12 +85,36 @@
|
|
|
83
85
|
background: none;
|
|
84
86
|
border: none;
|
|
85
87
|
padding: 0;
|
|
88
|
+
color: var(--ink, currentColor);
|
|
86
89
|
}
|
|
87
90
|
.scrub {
|
|
88
91
|
flex: 1;
|
|
92
|
+
accent-color: var(--accent, currentColor);
|
|
89
93
|
}
|
|
90
94
|
.frame-label {
|
|
91
95
|
min-width: 4ch;
|
|
92
96
|
text-align: right;
|
|
97
|
+
color: var(--ink, currentColor);
|
|
98
|
+
}
|
|
99
|
+
.speed {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
gap: 2px;
|
|
103
|
+
}
|
|
104
|
+
.speed input {
|
|
105
|
+
width: 3.5em;
|
|
106
|
+
font: inherit;
|
|
107
|
+
color: var(--ink, currentColor);
|
|
108
|
+
background: var(--paper, transparent);
|
|
109
|
+
border: 1px solid var(--paper-edge, currentColor);
|
|
110
|
+
border-radius: 4px;
|
|
111
|
+
padding: 2px 4px;
|
|
112
|
+
}
|
|
113
|
+
.speed input:focus-visible {
|
|
114
|
+
outline: 2px solid var(--accent, currentColor);
|
|
115
|
+
outline-offset: 1px;
|
|
116
|
+
}
|
|
117
|
+
.speed-unit {
|
|
118
|
+
color: var(--ink-mute, currentColor);
|
|
93
119
|
}
|
|
94
120
|
</style>
|
package/dist/Plot/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { default as Root } from "./Root.svelte";
|
|
2
2
|
export { default as Axis } from "./Axis.svelte";
|
|
3
|
-
export { default as Bar } from "
|
|
3
|
+
export { default as Bar } from "../geoms/Bar.svelte";
|
|
4
4
|
export { default as Legend } from "./Legend.svelte";
|
|
5
5
|
export { default as Grid } from "./Grid.svelte";
|
|
6
|
-
export { default as Line } from "
|
|
7
|
-
export { default as Area } from "
|
|
8
|
-
export { default as Point } from "
|
|
6
|
+
export { default as Line } from "../geoms/Line.svelte";
|
|
7
|
+
export { default as Area } from "../geoms/Area.svelte";
|
|
8
|
+
export { default as Point } from "../geoms/Point.svelte";
|
|
9
9
|
export { default as Arc } from "./Arc.svelte";
|
package/dist/Plot/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { default as Root } from './Root.svelte'
|
|
2
2
|
export { default as Axis } from './Axis.svelte'
|
|
3
|
-
export { default as Bar } from '
|
|
3
|
+
export { default as Bar } from '../geoms/Bar.svelte'
|
|
4
4
|
export { default as Legend } from './Legend.svelte'
|
|
5
5
|
export { default as Grid } from './Grid.svelte'
|
|
6
|
-
export { default as Line } from '
|
|
7
|
-
export { default as Area } from '
|
|
8
|
-
export { default as Point } from '
|
|
6
|
+
export { default as Line } from '../geoms/Line.svelte'
|
|
7
|
+
export { default as Area } from '../geoms/Area.svelte'
|
|
8
|
+
export { default as Point } from '../geoms/Point.svelte'
|
|
9
9
|
export { default as Arc } from './Arc.svelte'
|