@rokkit/chart 1.3.7 → 1.3.9
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 +51 -65
- package/dist/FacetPlot.svelte +1 -1
- package/dist/Plot/Axis.svelte +19 -10
- package/dist/Plot/Root.svelte +67 -46
- package/dist/Plot/Root.svelte.d.ts +29 -2
- package/dist/Plot/Timeline.svelte +39 -13
- package/dist/Plot/index.d.ts +5 -5
- package/dist/Plot/index.js +5 -5
- package/dist/Plot.svelte +95 -178
- package/dist/Plot.svelte.d.ts +4 -0
- package/dist/PlotState.svelte.d.ts +29 -1
- package/dist/PlotState.svelte.js +163 -19
- package/dist/PlotSurface.svelte +162 -0
- package/dist/PlotSurface.svelte.d.ts +25 -0
- package/dist/charts/AreaChart.svelte +12 -2
- package/dist/charts/AreaChart.svelte.d.ts +6 -0
- package/dist/charts/BarChart.svelte +40 -4
- package/dist/charts/BarChart.svelte.d.ts +15 -1
- package/dist/charts/BoxPlot.svelte +7 -3
- package/dist/charts/BoxPlot.svelte.d.ts +2 -0
- package/dist/charts/BubbleChart.svelte +37 -4
- package/dist/charts/BubbleChart.svelte.d.ts +12 -1
- package/dist/charts/LineChart.svelte +4 -2
- package/dist/charts/LineChart.svelte.d.ts +1 -0
- package/dist/charts/PieChart.svelte +5 -3
- package/dist/charts/PieChart.svelte.d.ts +1 -0
- package/dist/charts/ScatterPlot.svelte +35 -4
- package/dist/charts/ScatterPlot.svelte.d.ts +11 -1
- package/dist/charts/ViolinPlot.svelte +7 -3
- package/dist/charts/ViolinPlot.svelte.d.ts +2 -0
- package/dist/examples/BarChartExample.svelte +1 -1
- package/dist/geoms/Arc.svelte +21 -54
- package/dist/geoms/Arc.svelte.d.ts +4 -4
- package/dist/geoms/Area.svelte +45 -44
- package/dist/geoms/Area.svelte.d.ts +8 -1
- package/dist/geoms/Bar.svelte +33 -45
- package/dist/geoms/Bar.svelte.d.ts +9 -0
- package/dist/geoms/Box.svelte +103 -61
- package/dist/geoms/Box.svelte.d.ts +12 -3
- package/dist/geoms/Candlestick.svelte +26 -75
- package/dist/geoms/Candlestick.svelte.d.ts +2 -0
- package/dist/geoms/Heatmap.svelte +21 -66
- package/dist/geoms/Heatmap.svelte.d.ts +2 -0
- package/dist/geoms/Hexbin.svelte +20 -100
- package/dist/geoms/Hexbin.svelte.d.ts +2 -0
- package/dist/geoms/Jitter.svelte +67 -0
- package/dist/geoms/Jitter.svelte.d.ts +17 -0
- package/dist/geoms/Line.svelte +27 -31
- package/dist/geoms/Line.svelte.d.ts +5 -0
- package/dist/geoms/Point.svelte +31 -60
- package/dist/geoms/Point.svelte.d.ts +5 -1
- package/dist/geoms/Ribbon.svelte +30 -124
- package/dist/geoms/Ribbon.svelte.d.ts +2 -0
- package/dist/geoms/Rule.svelte +117 -0
- package/dist/geoms/Rule.svelte.d.ts +19 -0
- package/dist/geoms/Violin.svelte +36 -31
- package/dist/geoms/Violin.svelte.d.ts +10 -3
- package/dist/geoms/Waterfall.svelte +25 -79
- package/dist/geoms/Waterfall.svelte.d.ts +2 -0
- package/dist/geoms/lib/GeomState.svelte.d.ts +51 -0
- package/dist/geoms/lib/GeomState.svelte.js +79 -0
- package/dist/geoms/lib/aesthetics.d.ts +36 -0
- package/dist/geoms/lib/aesthetics.js +45 -0
- package/dist/geoms/lib/areas.d.ts +6 -2
- package/dist/geoms/lib/areas.js +20 -12
- package/dist/geoms/lib/bars.d.ts +18 -3
- package/dist/geoms/lib/bars.js +80 -101
- package/dist/geoms/lib/marks/arc.d.ts +24 -0
- package/dist/geoms/lib/marks/arc.js +28 -0
- package/dist/geoms/lib/marks/area.d.ts +23 -0
- package/dist/geoms/lib/marks/area.js +38 -0
- package/dist/geoms/lib/marks/bar.d.ts +16 -0
- package/dist/geoms/lib/marks/bar.js +43 -0
- package/dist/geoms/lib/marks/box.d.ts +14 -0
- package/dist/geoms/lib/marks/box.js +30 -0
- package/dist/geoms/lib/marks/candlestick.d.ts +27 -0
- package/dist/geoms/lib/marks/candlestick.js +52 -0
- package/dist/geoms/lib/marks/heatmap.d.ts +24 -0
- package/dist/geoms/lib/marks/heatmap.js +41 -0
- package/dist/geoms/lib/marks/hexbin.d.ts +29 -0
- package/dist/geoms/lib/marks/hexbin.js +62 -0
- package/dist/geoms/lib/marks/jitter.d.ts +21 -0
- package/dist/geoms/lib/marks/jitter.js +36 -0
- package/dist/geoms/lib/marks/line.d.ts +26 -0
- package/dist/geoms/lib/marks/line.js +25 -0
- package/dist/geoms/lib/marks/point.d.ts +25 -0
- package/dist/geoms/lib/marks/point.js +58 -0
- package/dist/geoms/lib/marks/ribbon.d.ts +31 -0
- package/dist/geoms/lib/marks/ribbon.js +77 -0
- package/dist/geoms/lib/marks/violin.d.ts +13 -0
- package/dist/geoms/lib/marks/violin.js +31 -0
- package/dist/geoms/lib/marks/waterfall.d.ts +25 -0
- package/dist/geoms/lib/marks/waterfall.js +58 -0
- package/dist/index.d.ts +25 -12
- package/dist/index.js +26 -13
- 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 +4 -1
- package/dist/lib/brewing/marks/lines.js +18 -15
- 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/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/preset.d.ts +11 -1
- package/dist/lib/preset.js +16 -4
- package/package.json +1 -1
- package/dist/Plot/Arc.svelte +0 -30
- package/dist/Plot/Arc.svelte.d.ts +0 -18
- 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/lib/brewer.d.ts +0 -9
- package/dist/lib/brewer.js +0 -25
- package/dist/lib/brewing/BoxBrewer.svelte.d.ts +0 -8
- package/dist/lib/brewing/BoxBrewer.svelte.js +0 -14
- package/dist/lib/brewing/CartesianBrewer.svelte.d.ts +0 -8
- package/dist/lib/brewing/CartesianBrewer.svelte.js +0 -21
- package/dist/lib/brewing/PieBrewer.svelte.d.ts +0 -8
- package/dist/lib/brewing/PieBrewer.svelte.js +0 -14
- package/dist/lib/brewing/QuartileBrewer.svelte.d.ts +0 -9
- package/dist/lib/brewing/QuartileBrewer.svelte.js +0 -51
- package/dist/lib/brewing/ViolinBrewer.svelte.d.ts +0 -8
- package/dist/lib/brewing/ViolinBrewer.svelte.js +0 -14
- package/dist/lib/brewing/axes.svelte.d.ts +0 -66
- package/dist/lib/brewing/axes.svelte.js +0 -270
- package/dist/lib/brewing/bars.svelte.d.ts +0 -56
- package/dist/lib/brewing/bars.svelte.js +0 -201
- package/dist/lib/brewing/brewer.svelte.d.ts +0 -124
- package/dist/lib/brewing/brewer.svelte.js +0 -277
- package/dist/lib/brewing/dimensions.svelte.d.ts +0 -35
- package/dist/lib/brewing/dimensions.svelte.js +0 -56
- package/dist/lib/brewing/index.svelte.d.ts +0 -118
- package/dist/lib/brewing/index.svelte.js +0 -205
- package/dist/lib/brewing/legends.svelte.d.ts +0 -48
- package/dist/lib/brewing/legends.svelte.js +0 -137
- package/dist/lib/brewing/marks/areas.d.ts +0 -31
- package/dist/lib/brewing/marks/areas.js +0 -72
- package/dist/lib/brewing/marks/bars.d.ts +0 -1
- package/dist/lib/brewing/marks/bars.js +0 -49
- package/dist/lib/brewing/scales.svelte.d.ts +0 -24
- package/dist/lib/brewing/scales.svelte.js +0 -82
- package/dist/lib/context.d.ts +0 -13
- package/dist/lib/context.js +0 -131
- package/dist/lib/plot/chartProps.d.ts +0 -177
- package/dist/lib/plot/chartProps.js +0 -76
- package/dist/lib/scales.svelte.d.ts +0 -35
- package/dist/lib/scales.svelte.js +0 -151
- package/dist/lib/ticks.d.ts +0 -36
- package/dist/lib/ticks.js +0 -46
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
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { setContext } from 'svelte'
|
|
3
2
|
import type { Snippet } from 'svelte'
|
|
4
|
-
import
|
|
3
|
+
import Plot from './Plot.svelte'
|
|
5
4
|
import type { ChartSpec } from './spec/chart-spec.js'
|
|
6
|
-
|
|
7
|
-
type Channels = {
|
|
8
|
-
x?: string
|
|
9
|
-
y?: string
|
|
10
|
-
color?: string
|
|
11
|
-
pattern?: string
|
|
12
|
-
fill?: string
|
|
13
|
-
size?: string
|
|
14
|
-
label?: string
|
|
15
|
-
symbol?: string
|
|
16
|
-
}
|
|
5
|
+
import type { PlotSpec, GeomSpec } from './lib/plot/types.js'
|
|
17
6
|
|
|
18
7
|
type Props = {
|
|
19
8
|
spec?: ChartSpec
|
|
@@ -45,63 +34,60 @@
|
|
|
45
34
|
symbol = undefined,
|
|
46
35
|
width = 600,
|
|
47
36
|
height = 400,
|
|
48
|
-
mode =
|
|
37
|
+
mode = undefined,
|
|
49
38
|
children
|
|
50
39
|
}: Props = $props()
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (y) channels.y = y
|
|
59
|
-
if (color) channels.color = color
|
|
60
|
-
if (pattern) channels.pattern = pattern
|
|
61
|
-
if (fill) channels.fill = fill
|
|
62
|
-
if (size) channels.size = size
|
|
63
|
-
if (label) channels.label = label
|
|
64
|
-
if (symbol) channels.symbol = symbol
|
|
65
|
-
return channels
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
$effect(() => {
|
|
41
|
+
// `Chart` is a thin wrapper over the geom-path host (`Plot`). It maps the fluent
|
|
42
|
+
// `ChartSpec` builder (data / channels / layers / options) onto a `PlotSpec` and renders
|
|
43
|
+
// the layers as geoms. Axes/grid stay off by default — `Chart` historically rendered just
|
|
44
|
+
// the marks (plus any declarative geom children). See the brewer-consolidation spec
|
|
45
|
+
// (docs/backlog/2026-08-17-chart-aesthetics-unification.md §9).
|
|
46
|
+
const plotSpec = $derived.by((): PlotSpec => {
|
|
69
47
|
if (spec) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
48
|
+
const ch = (spec.channels ?? {}) as {
|
|
49
|
+
x?: string
|
|
50
|
+
y?: string
|
|
51
|
+
color?: string
|
|
52
|
+
pattern?: string
|
|
53
|
+
}
|
|
54
|
+
const opts = (spec.options ?? {}) as {
|
|
55
|
+
width?: number
|
|
56
|
+
height?: number
|
|
57
|
+
grid?: unknown
|
|
58
|
+
legend?: unknown
|
|
59
|
+
}
|
|
60
|
+
const layers = (spec.layers ?? []) as GeomSpec[]
|
|
61
|
+
return {
|
|
62
|
+
data: spec.data as Record<string, unknown>[],
|
|
63
|
+
x: ch.x,
|
|
64
|
+
y: ch.y,
|
|
65
|
+
color: ch.color,
|
|
66
|
+
pattern: ch.pattern,
|
|
67
|
+
width: opts.width ?? width,
|
|
68
|
+
height: opts.height ?? height,
|
|
69
|
+
grid: 'grid' in opts,
|
|
70
|
+
legend: 'legend' in opts,
|
|
71
|
+
geoms: layers.map((l) => ({ pattern: ch.pattern, ...l }))
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
data,
|
|
76
|
+
x,
|
|
77
|
+
y,
|
|
78
|
+
color: color ?? fill,
|
|
79
|
+
pattern,
|
|
80
|
+
size,
|
|
81
|
+
symbol,
|
|
82
|
+
width,
|
|
83
|
+
height,
|
|
84
|
+
grid: false,
|
|
85
|
+
legend: false,
|
|
86
|
+
geoms: []
|
|
80
87
|
}
|
|
81
88
|
})
|
|
82
89
|
</script>
|
|
83
90
|
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{@render children?.()}
|
|
88
|
-
</g>
|
|
89
|
-
</svg>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<style>
|
|
93
|
-
.chart-container {
|
|
94
|
-
position: relative;
|
|
95
|
-
width: 100%;
|
|
96
|
-
height: auto;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
svg {
|
|
100
|
-
display: block;
|
|
101
|
-
overflow: visible;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.chart-area {
|
|
105
|
-
pointer-events: all;
|
|
106
|
-
}
|
|
107
|
-
</style>
|
|
91
|
+
<Plot spec={plotSpec} axes={false} label={label ?? false} {mode}>
|
|
92
|
+
{@render children?.()}
|
|
93
|
+
</Plot>
|
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,17 +135,21 @@
|
|
|
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);
|
|
144
153
|
/* Decoration only — never intercept clicks meant for data marks beneath it. */
|
|
145
154
|
pointer-events: none;
|
|
146
155
|
}
|
package/dist/Plot/Root.svelte
CHANGED
|
@@ -1,20 +1,46 @@
|
|
|
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
|
|
14
|
+
/** Interior aesthetic default (field); geoms inherit unless they set their own. */
|
|
15
|
+
fill?: string
|
|
14
16
|
width?: number
|
|
15
17
|
height?: number
|
|
16
18
|
margin?: Margin
|
|
17
19
|
mode?: 'light' | 'dark'
|
|
20
|
+
/** Chart direction. 'horizontal' stands the category axis up and runs the value
|
|
21
|
+
* axis sideways — x/y channels are unchanged. `flip` is sugar for 'horizontal'. */
|
|
22
|
+
orientation?: 'vertical' | 'horizontal'
|
|
23
|
+
flip?: boolean
|
|
24
|
+
/** Order the category (band) axis by aggregated value instead of by label — bars sorted
|
|
25
|
+
* by size (histogram-style). 'desc' (largest first) | 'asc'. */
|
|
26
|
+
sort?: 'asc' | 'desc'
|
|
27
|
+
/** Explicit scale domain overrides. */
|
|
28
|
+
xDomain?: unknown[]
|
|
29
|
+
yDomain?: unknown[]
|
|
30
|
+
/** Continuous colour scale controls (sequential/diverging). */
|
|
31
|
+
colorScale?: unknown
|
|
32
|
+
colorScheme?: string
|
|
33
|
+
colorDomain?: unknown[]
|
|
34
|
+
colorMidpoint?: number
|
|
35
|
+
/** Enable d3-zoom pan/zoom. */
|
|
36
|
+
zoom?: boolean
|
|
37
|
+
/** Opt-in click-to-select; fires onselect(detail) and syncs bind:selected (row refs). */
|
|
38
|
+
selectable?: boolean
|
|
39
|
+
onselect?: (detail: unknown) => void
|
|
40
|
+
selected?: Row[]
|
|
41
|
+
/** Animate marks on data/flip changes. Enabled one frame after mount so the
|
|
42
|
+
* initial layout paints un-animated. Default `true`. */
|
|
43
|
+
animate?: boolean
|
|
18
44
|
children?: Snippet
|
|
19
45
|
}
|
|
20
46
|
|
|
@@ -23,55 +49,50 @@
|
|
|
23
49
|
x = undefined,
|
|
24
50
|
y = undefined,
|
|
25
51
|
color = undefined,
|
|
52
|
+
fill = undefined,
|
|
26
53
|
width = 600,
|
|
27
54
|
height = 400,
|
|
28
55
|
margin = undefined,
|
|
29
|
-
mode =
|
|
56
|
+
mode = undefined,
|
|
57
|
+
orientation = undefined,
|
|
58
|
+
flip = false,
|
|
59
|
+
sort = undefined,
|
|
60
|
+
xDomain = undefined,
|
|
61
|
+
yDomain = undefined,
|
|
62
|
+
colorScale = undefined,
|
|
63
|
+
colorScheme = undefined,
|
|
64
|
+
colorDomain = undefined,
|
|
65
|
+
colorMidpoint = undefined,
|
|
66
|
+
zoom = false,
|
|
67
|
+
selectable = false,
|
|
68
|
+
onselect = undefined,
|
|
69
|
+
selected = $bindable([]),
|
|
70
|
+
animate = true,
|
|
30
71
|
children
|
|
31
72
|
}: Props = $props()
|
|
32
73
|
|
|
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
|
-
})
|
|
74
|
+
// The composable root is just PlotSurface (the shared shell) fed a config from these props.
|
|
75
|
+
const config = $derived({
|
|
76
|
+
data,
|
|
77
|
+
channels: { x, y, color, fill },
|
|
78
|
+
width,
|
|
79
|
+
height,
|
|
80
|
+
margin,
|
|
81
|
+
mode,
|
|
82
|
+
orientation: flip ? 'horizontal' : orientation,
|
|
83
|
+
sort,
|
|
84
|
+
xDomain,
|
|
85
|
+
yDomain,
|
|
86
|
+
colorScale,
|
|
87
|
+
colorScheme,
|
|
88
|
+
colorDomain,
|
|
89
|
+
colorMidpoint,
|
|
90
|
+
onselect,
|
|
91
|
+
selectable,
|
|
92
|
+
chartPreset: defaultPreset
|
|
56
93
|
})
|
|
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
94
|
</script>
|
|
65
95
|
|
|
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>
|
|
96
|
+
<PlotSurface {config} {animate} {zoom} bind:selected>
|
|
97
|
+
{@render children?.()}
|
|
98
|
+
</PlotSurface>
|
|
@@ -5,17 +5,44 @@ 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
|
+
/** Interior aesthetic default (field); geoms inherit unless they set their own. */
|
|
15
|
+
fill?: string;
|
|
13
16
|
width?: number;
|
|
14
17
|
height?: number;
|
|
15
18
|
margin?: Margin;
|
|
16
19
|
mode?: 'light' | 'dark';
|
|
20
|
+
/** Chart direction. 'horizontal' stands the category axis up and runs the value
|
|
21
|
+
* axis sideways — x/y channels are unchanged. `flip` is sugar for 'horizontal'. */
|
|
22
|
+
orientation?: 'vertical' | 'horizontal';
|
|
23
|
+
flip?: boolean;
|
|
24
|
+
/** Order the category (band) axis by aggregated value instead of by label — bars sorted
|
|
25
|
+
* by size (histogram-style). 'desc' (largest first) | 'asc'. */
|
|
26
|
+
sort?: 'asc' | 'desc';
|
|
27
|
+
/** Explicit scale domain overrides. */
|
|
28
|
+
xDomain?: unknown[];
|
|
29
|
+
yDomain?: unknown[];
|
|
30
|
+
/** Continuous colour scale controls (sequential/diverging). */
|
|
31
|
+
colorScale?: unknown;
|
|
32
|
+
colorScheme?: string;
|
|
33
|
+
colorDomain?: unknown[];
|
|
34
|
+
colorMidpoint?: number;
|
|
35
|
+
/** Enable d3-zoom pan/zoom. */
|
|
36
|
+
zoom?: boolean;
|
|
37
|
+
/** Opt-in click-to-select; fires onselect(detail) and syncs bind:selected (row refs). */
|
|
38
|
+
selectable?: boolean;
|
|
39
|
+
onselect?: (detail: unknown) => void;
|
|
40
|
+
selected?: Row[];
|
|
41
|
+
/** Animate marks on data/flip changes. Enabled one frame after mount so the
|
|
42
|
+
* initial layout paints un-animated. Default `true`. */
|
|
43
|
+
animate?: boolean;
|
|
17
44
|
children?: Snippet;
|
|
18
45
|
};
|
|
19
|
-
declare const Root: import("svelte").Component<Props, {}, "">;
|
|
46
|
+
declare const Root: import("svelte").Component<Props, {}, "selected">;
|
|
20
47
|
type Root = ReturnType<typeof Root>;
|
|
21
48
|
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 "
|
|
9
|
-
export { default as Arc } 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
|
+
export { default as Arc } from "../geoms/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 '
|
|
9
|
-
export { default as Arc } 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
|
+
export { default as Arc } from '../geoms/Arc.svelte'
|