svelteplot 0.0.1-alpha.9 → 0.1.3-next.3
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/LICENSE.md +5 -0
- package/README.md +3 -36
- package/dist/Mark.svelte +292 -0
- package/dist/Mark.svelte.d.ts +22 -0
- package/dist/Plot.svelte +148 -156
- package/dist/Plot.svelte.d.ts +15 -15
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +109 -0
- package/dist/core/Facet.svelte +59 -0
- package/dist/core/Facet.svelte.d.ts +18 -0
- package/dist/core/FacetAxes.svelte +66 -0
- package/dist/core/FacetAxes.svelte.d.ts +4 -0
- package/dist/core/FacetGrid.svelte +86 -0
- package/dist/core/FacetGrid.svelte.d.ts +13 -0
- package/dist/core/Plot.svelte +567 -0
- package/dist/core/Plot.svelte.d.ts +14 -0
- package/dist/helpers/arrowPath.d.ts +14 -0
- package/dist/helpers/arrowPath.js +129 -0
- package/dist/helpers/autoProjection.d.ts +19 -0
- package/dist/helpers/autoProjection.js +87 -0
- package/dist/helpers/autoScales.d.ts +23 -0
- package/dist/helpers/autoScales.js +203 -0
- package/dist/helpers/autoTicks.d.ts +3 -0
- package/dist/helpers/autoTicks.js +40 -0
- package/dist/helpers/autoTimeFormat.d.ts +2 -2
- package/dist/helpers/autoTimeFormat.js +34 -5
- package/dist/helpers/callWithProps.d.ts +8 -0
- package/dist/helpers/callWithProps.js +13 -0
- package/dist/helpers/colors.js +17 -2
- package/dist/helpers/curves.d.ts +3 -0
- package/dist/helpers/curves.js +42 -0
- package/dist/helpers/data.d.ts +9 -0
- package/dist/helpers/data.js +16 -0
- package/dist/helpers/facets.d.ts +12 -0
- package/dist/helpers/facets.js +49 -0
- package/dist/helpers/formats.d.ts +3 -0
- package/dist/helpers/formats.js +3 -0
- package/dist/helpers/getBaseStyles.d.ts +7 -2
- package/dist/helpers/getBaseStyles.js +34 -10
- package/dist/helpers/getLogTicks.js +5 -5
- package/dist/helpers/group.d.ts +6 -0
- package/dist/helpers/group.js +53 -0
- package/dist/helpers/index.d.ts +18 -0
- package/dist/helpers/index.js +53 -0
- package/dist/helpers/isRawValue.d.ts +2 -0
- package/dist/helpers/isRawValue.js +5 -0
- package/dist/helpers/isValid.d.ts +6 -0
- package/dist/helpers/isValid.js +6 -0
- package/dist/helpers/math.d.ts +19 -0
- package/dist/helpers/math.js +116 -0
- package/dist/helpers/mergeDeep.d.ts +1 -1
- package/dist/helpers/noise.d.ts +1 -0
- package/dist/helpers/noise.js +72 -0
- package/dist/helpers/projection.d.ts +33 -0
- package/dist/helpers/projection.js +100 -0
- package/dist/helpers/reduce.d.ts +10 -0
- package/dist/helpers/reduce.js +85 -0
- package/dist/helpers/regressionLoess.d.ts +12 -0
- package/dist/helpers/regressionLoess.js +47 -0
- package/dist/helpers/removeIdenticalLines.d.ts +8 -1
- package/dist/helpers/removeIdenticalLines.js +14 -7
- package/dist/helpers/resolve.d.ts +17 -0
- package/dist/helpers/resolve.js +152 -0
- package/dist/helpers/roundedRect.d.ts +9 -0
- package/dist/helpers/roundedRect.js +31 -0
- package/dist/helpers/scales.d.ts +42 -0
- package/dist/helpers/scales.js +309 -0
- package/dist/helpers/time.d.ts +6 -0
- package/dist/helpers/time.js +282 -0
- package/dist/helpers/typeChecks.d.ts +8 -5
- package/dist/helpers/typeChecks.js +27 -6
- package/dist/index.d.ts +49 -1
- package/dist/index.js +53 -2
- package/dist/marks/Area.svelte +146 -0
- package/dist/marks/Area.svelte.d.ts +30 -0
- package/dist/marks/AreaX.svelte +27 -0
- package/dist/marks/AreaX.svelte.d.ts +12 -0
- package/dist/marks/AreaY.svelte +38 -0
- package/dist/marks/AreaY.svelte.d.ts +19 -0
- package/dist/marks/Arrow.svelte +139 -0
- package/dist/marks/Arrow.svelte.d.ts +44 -0
- package/dist/marks/AxisX.svelte +198 -93
- package/dist/marks/AxisX.svelte.d.ts +17 -16
- package/dist/marks/AxisY.svelte +176 -62
- package/dist/marks/AxisY.svelte.d.ts +17 -14
- package/dist/marks/BarX.svelte +81 -0
- package/dist/marks/BarX.svelte.d.ts +4 -0
- package/dist/marks/BarY.svelte +95 -0
- package/dist/marks/BarY.svelte.d.ts +4 -0
- package/dist/marks/BollingerX.svelte +44 -0
- package/dist/marks/BollingerX.svelte.d.ts +18 -0
- package/dist/marks/BollingerY.svelte +39 -0
- package/dist/marks/BollingerY.svelte.d.ts +18 -0
- package/dist/marks/BoxX.svelte +89 -0
- package/dist/marks/BoxX.svelte.d.ts +4 -0
- package/dist/marks/BoxY.svelte +110 -0
- package/dist/marks/BoxY.svelte.d.ts +29 -0
- package/dist/marks/Cell.svelte +110 -0
- package/dist/marks/Cell.svelte.d.ts +16 -0
- package/dist/marks/CellX.svelte +24 -0
- package/dist/marks/CellX.svelte.d.ts +3 -0
- package/dist/marks/CellY.svelte +24 -0
- package/dist/marks/CellY.svelte.d.ts +3 -0
- package/dist/marks/ColorLegend.svelte +148 -27
- package/dist/marks/ColorLegend.svelte.d.ts +12 -13
- package/dist/marks/CustomMark.svelte +43 -0
- package/dist/marks/CustomMark.svelte.d.ts +16 -0
- package/dist/marks/CustomMarkHTML.svelte +103 -0
- package/dist/marks/CustomMarkHTML.svelte.d.ts +17 -0
- package/dist/marks/DifferenceY.svelte +144 -0
- package/dist/marks/DifferenceY.svelte.d.ts +30 -0
- package/dist/marks/Dot.svelte +128 -73
- package/dist/marks/Dot.svelte.d.ts +24 -14
- package/dist/marks/DotX.svelte +15 -3
- package/dist/marks/DotX.svelte.d.ts +8 -16
- package/dist/marks/DotY.svelte +8 -3
- package/dist/marks/DotY.svelte.d.ts +5 -17
- package/dist/marks/Frame.svelte +32 -31
- package/dist/marks/Frame.svelte.d.ts +7 -14
- package/dist/marks/Geo.svelte +102 -0
- package/dist/marks/Geo.svelte.d.ts +10 -0
- package/dist/marks/Graticule.svelte +28 -0
- package/dist/marks/Graticule.svelte.d.ts +9 -0
- package/dist/marks/GridX.svelte +67 -36
- package/dist/marks/GridX.svelte.d.ts +7 -18
- package/dist/marks/GridY.svelte +64 -25
- package/dist/marks/GridY.svelte.d.ts +7 -14
- package/dist/marks/HTMLTooltip.svelte +91 -0
- package/dist/marks/HTMLTooltip.svelte.d.ts +11 -0
- package/dist/marks/Line.svelte +219 -58
- package/dist/marks/Line.svelte.d.ts +30 -14
- package/dist/marks/LineX.svelte +8 -8
- package/dist/marks/LineX.svelte.d.ts +4 -17
- package/dist/marks/LineY.svelte +7 -8
- package/dist/marks/LineY.svelte.d.ts +4 -17
- package/dist/marks/Link.svelte +173 -0
- package/dist/marks/Link.svelte.d.ts +21 -0
- package/dist/marks/Pointer.svelte +126 -0
- package/dist/marks/Pointer.svelte.d.ts +23 -0
- package/dist/marks/Rect.svelte +103 -0
- package/dist/marks/Rect.svelte.d.ts +15 -0
- package/dist/marks/RectX.svelte +33 -0
- package/dist/marks/RectX.svelte.d.ts +15 -0
- package/dist/marks/RectY.svelte +33 -0
- package/dist/marks/RectY.svelte.d.ts +15 -0
- package/dist/marks/RegressionX.svelte +26 -0
- package/dist/marks/RegressionX.svelte.d.ts +4 -0
- package/dist/marks/RegressionY.svelte +26 -0
- package/dist/marks/RegressionY.svelte.d.ts +4 -0
- package/dist/marks/RuleX.svelte +52 -28
- package/dist/marks/RuleX.svelte.d.ts +14 -14
- package/dist/marks/RuleY.svelte +52 -28
- package/dist/marks/RuleY.svelte.d.ts +14 -14
- package/dist/marks/Sphere.svelte +8 -0
- package/dist/marks/Sphere.svelte.d.ts +51 -0
- package/dist/marks/Spike.svelte +15 -0
- package/dist/marks/Spike.svelte.d.ts +4 -0
- package/dist/marks/SymbolLegend.svelte +27 -12
- package/dist/marks/SymbolLegend.svelte.d.ts +8 -14
- package/dist/marks/Text.svelte +185 -0
- package/dist/marks/Text.svelte.d.ts +26 -0
- package/dist/marks/TickX.svelte +89 -0
- package/dist/marks/TickX.svelte.d.ts +22 -0
- package/dist/marks/TickY.svelte +90 -0
- package/dist/marks/TickY.svelte.d.ts +22 -0
- package/dist/marks/Vector.svelte +213 -0
- package/dist/marks/Vector.svelte.d.ts +31 -0
- package/dist/marks/helpers/BaseAxisX.svelte +210 -0
- package/dist/marks/helpers/BaseAxisX.svelte.d.ts +24 -0
- package/dist/marks/helpers/BaseAxisY.svelte +187 -0
- package/dist/marks/helpers/BaseAxisY.svelte.d.ts +23 -0
- package/dist/marks/helpers/CanvasLayer.svelte +38 -0
- package/dist/marks/helpers/CanvasLayer.svelte.d.ts +13 -0
- package/dist/marks/helpers/DotCanvas.svelte +184 -0
- package/dist/marks/helpers/DotCanvas.svelte.d.ts +11 -0
- package/dist/marks/helpers/GeoCanvas.svelte +165 -0
- package/dist/marks/helpers/GeoCanvas.svelte.d.ts +13 -0
- package/dist/marks/helpers/GroupMultiple.svelte +17 -0
- package/dist/marks/helpers/GroupMultiple.svelte.d.ts +9 -0
- package/dist/marks/helpers/Marker.svelte +93 -0
- package/dist/marks/helpers/Marker.svelte.d.ts +10 -0
- package/dist/marks/helpers/MarkerPath.svelte +164 -0
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +44 -0
- package/dist/marks/helpers/Regression.svelte +174 -0
- package/dist/marks/helpers/Regression.svelte.d.ts +26 -0
- package/dist/marks/helpers/events.d.ts +8 -0
- package/dist/marks/helpers/events.js +64 -0
- package/dist/transforms/bin.d.ts +51 -0
- package/dist/transforms/bin.js +171 -0
- package/dist/transforms/bollinger.d.ts +21 -0
- package/dist/transforms/bollinger.js +53 -0
- package/dist/transforms/centroid.d.ts +9 -0
- package/dist/transforms/centroid.js +13 -0
- package/dist/transforms/facet.d.ts +1 -0
- package/dist/transforms/facet.js +1 -0
- package/dist/transforms/filter.d.ts +2 -0
- package/dist/transforms/filter.js +8 -0
- package/dist/transforms/group.d.ts +66 -0
- package/dist/transforms/group.js +109 -0
- package/dist/transforms/interval.d.ts +11 -0
- package/dist/transforms/interval.js +34 -0
- package/dist/transforms/jitter.d.ts +0 -0
- package/dist/transforms/jitter.js +1 -0
- package/dist/transforms/map.d.ts +10 -0
- package/dist/transforms/map.js +89 -0
- package/dist/transforms/normalize.d.ts +9 -0
- package/dist/transforms/normalize.js +86 -0
- package/dist/transforms/recordize.d.ts +13 -0
- package/dist/transforms/recordize.js +75 -0
- package/dist/transforms/rename.d.ts +14 -0
- package/dist/transforms/rename.js +42 -0
- package/dist/transforms/select.d.ts +35 -0
- package/dist/transforms/select.js +55 -0
- package/dist/transforms/shift.d.ts +13 -0
- package/dist/transforms/shift.js +45 -0
- package/dist/transforms/sort.d.ts +28 -0
- package/dist/transforms/sort.js +61 -0
- package/dist/transforms/stack.d.ts +10 -0
- package/dist/transforms/stack.js +110 -0
- package/dist/transforms/window.d.ts +22 -0
- package/dist/transforms/window.js +73 -0
- package/dist/types.d.ts +625 -188
- package/dist/ui/Checkbox.svelte +6 -0
- package/dist/ui/Checkbox.svelte.d.ts +13 -0
- package/dist/ui/RadioInput.svelte +27 -0
- package/dist/ui/RadioInput.svelte.d.ts +9 -0
- package/dist/ui/Select.svelte +27 -0
- package/dist/ui/Select.svelte.d.ts +9 -0
- package/dist/ui/Slider.svelte +47 -0
- package/dist/ui/Slider.svelte.d.ts +11 -0
- package/dist/ui/Spiral.svelte +46 -0
- package/dist/ui/Spiral.svelte.d.ts +15 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +4 -0
- package/package.json +79 -40
- package/LICENSE +0 -11
- package/dist/classes/Channel.svelte.js +0 -74
- package/dist/classes/Mark.svelte.js +0 -17
- package/dist/classes/Plot.svelte.js +0 -98
- package/dist/contants.d.ts +0 -3
- package/dist/contants.js +0 -40
- package/dist/helpers/GroupMultiple.svelte +0 -8
- package/dist/helpers/GroupMultiple.svelte.d.ts +0 -19
- package/dist/helpers/createScale.d.ts +0 -5
- package/dist/helpers/createScale.js +0 -57
- package/dist/helpers/resolveChannel.d.ts +0 -2
- package/dist/helpers/resolveChannel.js +0 -28
- package/dist/helpers/wrapArray.d.ts +0 -2
- package/dist/helpers/wrapArray.js +0 -4
- package/dist/marks/BaseMark.svelte +0 -22
- package/dist/marks/BaseMark.svelte.d.ts +0 -19
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Cell from './Cell.svelte';
|
|
3
|
+
import { recordizeX, recordizeY } from '../index.js';
|
|
4
|
+
import type { BaseMarkProps, DataRow, RectMarkProps } from '../types.js';
|
|
5
|
+
import type { ChannelAccessor } from '../types.js';
|
|
6
|
+
|
|
7
|
+
type CellXProps = BaseMarkProps & {
|
|
8
|
+
data: DataRow[];
|
|
9
|
+
x?: ChannelAccessor;
|
|
10
|
+
fill?: ChannelAccessor;
|
|
11
|
+
stroke?: ChannelAccessor;
|
|
12
|
+
} & RectMarkProps;
|
|
13
|
+
|
|
14
|
+
let { data = [{}], ...options }: CellXProps = $props();
|
|
15
|
+
|
|
16
|
+
const args = $derived(
|
|
17
|
+
recordizeY<CellXProps>({
|
|
18
|
+
data,
|
|
19
|
+
...options
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<Cell {...args} y="0" fill={options.fill || '__value'} />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Cell from './Cell.svelte';
|
|
3
|
+
import { recordizeX } from '../index.js';
|
|
4
|
+
import type { BaseMarkProps, DataRow, RectMarkProps } from '../types.js';
|
|
5
|
+
import type { ChannelAccessor } from '../types.js';
|
|
6
|
+
|
|
7
|
+
type CellYProps = BaseMarkProps & {
|
|
8
|
+
data: DataRow[];
|
|
9
|
+
y?: ChannelAccessor;
|
|
10
|
+
fill?: ChannelAccessor;
|
|
11
|
+
stroke?: ChannelAccessor;
|
|
12
|
+
} & RectMarkProps;
|
|
13
|
+
|
|
14
|
+
let { data = [{}], ...options }: CellYProps = $props();
|
|
15
|
+
|
|
16
|
+
const args = $derived(
|
|
17
|
+
recordizeX<CellYProps>({
|
|
18
|
+
data,
|
|
19
|
+
...options
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<Cell {...args} x="0" fill={options.fill || '__value'} />
|
|
@@ -1,32 +1,150 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
import { Plot, AxisX, Frame } from '../index.js';
|
|
4
|
+
import { symbol as d3Symbol, symbol } from 'd3-shape';
|
|
5
|
+
import { range as d3Range } from 'd3-array';
|
|
6
|
+
import { maybeSymbol } from '../helpers/symbols.js';
|
|
7
|
+
|
|
8
|
+
import type { DefaultOptions, PlotContext } from '../types.js';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
width = 250,
|
|
12
|
+
tickSpacing = 30,
|
|
13
|
+
class: className = null
|
|
14
|
+
}: { width?: number; tickSpacing?: number; class?: string } = $props();
|
|
15
|
+
|
|
16
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
17
|
+
const plot = $derived(getPlotState());
|
|
18
|
+
|
|
19
|
+
const DEFAULTS = getContext<Partial<DefaultOptions>>('svelteplot/_defaults');
|
|
20
|
+
|
|
21
|
+
const legendTitle = $derived(plot.options.color.label);
|
|
22
|
+
const scaleType = $derived(plot.scales.color.type);
|
|
23
|
+
const tickFormat = $derived(
|
|
24
|
+
typeof plot.options.color?.tickFormat === 'function'
|
|
25
|
+
? plot.options.color.tickFormat
|
|
26
|
+
: Intl.NumberFormat(
|
|
27
|
+
plot.options.locale,
|
|
28
|
+
plot.options.color.tickFormat || DEFAULTS.numberFormat
|
|
29
|
+
).format
|
|
30
|
+
);
|
|
31
|
+
const randId = Math.round(Math.random() * 1e6).toFixed(32);
|
|
5
32
|
</script>
|
|
6
33
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
>
|
|
34
|
+
<!--
|
|
35
|
+
@component
|
|
36
|
+
The ColorLegend is an HTML mark that can be placed in the header, footer and overlay
|
|
37
|
+
snippets. You can activate an implicit ColorLegend above the chart using the global
|
|
38
|
+
color.legend scale option.
|
|
39
|
+
-->
|
|
40
|
+
|
|
41
|
+
{#if plot.scales.color.manualActiveMarks > 0}
|
|
42
|
+
<div class="color-legend {className || ''}">
|
|
43
|
+
{#if legendTitle}
|
|
44
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
45
|
+
<div class="title">{@html legendTitle}</div>
|
|
46
|
+
{/if}
|
|
47
|
+
{#if scaleType === 'ordinal' || scaleType === 'categorical'}
|
|
48
|
+
{#each plot.scales.color.domain as value}
|
|
49
|
+
{@const symbolV = plot.scales.symbol.fn(value)}
|
|
50
|
+
{@const symbolType = maybeSymbol(symbolV)}
|
|
51
|
+
<div class="item">
|
|
52
|
+
<div class="swatch">
|
|
53
|
+
<svg width="15" height="15"
|
|
54
|
+
>{#if plot.colorSymbolRedundant}
|
|
55
|
+
<path
|
|
56
|
+
transform="translate(7.5,7.5)"
|
|
57
|
+
style:fill={plot.hasFilledDotMarks
|
|
58
|
+
? plot.scales.color.fn(value)
|
|
59
|
+
: 'none'}
|
|
60
|
+
style:stroke={plot.hasFilledDotMarks
|
|
61
|
+
? null
|
|
62
|
+
: plot.scales.color.fn(value)}
|
|
63
|
+
d={d3Symbol(symbolType, 40)()} />
|
|
64
|
+
{:else}
|
|
65
|
+
<rect
|
|
66
|
+
style:fill={plot.scales.color.fn(value)}
|
|
67
|
+
width="15"
|
|
68
|
+
height="15" />
|
|
69
|
+
{/if}</svg>
|
|
70
|
+
</div>
|
|
71
|
+
<span class="item-label">{value}</span>
|
|
26
72
|
</div>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
73
|
+
{/each}
|
|
74
|
+
{:else if scaleType === 'quantile' || scaleType === 'quantize' || scaleType === 'threshold'}
|
|
75
|
+
{@const domain = plot.scales.color.domain}
|
|
76
|
+
{@const range = plot.scales.color.range}
|
|
77
|
+
{@const tickLabels =
|
|
78
|
+
scaleType === 'quantile'
|
|
79
|
+
? plot.scales.color.fn.quantiles()
|
|
80
|
+
: scaleType === 'quantize'
|
|
81
|
+
? plot.scales.color.fn.thresholds()
|
|
82
|
+
: plot.scales.color.fn.domain()}
|
|
83
|
+
{@const ticks = d3Range(
|
|
84
|
+
domain[0],
|
|
85
|
+
domain[1],
|
|
86
|
+
(domain[1] - domain[0]) / range.length
|
|
87
|
+
).slice(1)}
|
|
88
|
+
|
|
89
|
+
<Plot
|
|
90
|
+
maxWidth="240px"
|
|
91
|
+
margins={1}
|
|
92
|
+
marginLeft={1}
|
|
93
|
+
marginRight={1}
|
|
94
|
+
marginTop={6}
|
|
95
|
+
marginBottom={20}
|
|
96
|
+
height={38}
|
|
97
|
+
inset={0}
|
|
98
|
+
x={{ domain, ticks }}>
|
|
99
|
+
<defs>
|
|
100
|
+
<linearGradient id="gradient-{randId}" x2="1">
|
|
101
|
+
<stop offset="0%" stop-color={range[0]} />
|
|
102
|
+
{#each ticks as t, i}
|
|
103
|
+
{@const offset = (100 * (t - domain[0])) / (domain[1] - domain[0])}
|
|
104
|
+
<stop
|
|
105
|
+
offset="{offset - 0.001}%"
|
|
106
|
+
stop-color={plot.scales.color.fn(tickLabels[i] - 0.1)} />
|
|
107
|
+
<stop
|
|
108
|
+
offset="{offset}%"
|
|
109
|
+
stop-color={plot.scales.color.fn(tickLabels[i])} />
|
|
110
|
+
{/each}
|
|
111
|
+
<stop offset="100%" stop-color={range.at(-1)} />
|
|
112
|
+
</linearGradient>
|
|
113
|
+
</defs>
|
|
114
|
+
<Frame dy={-5} stroke={null} fill="url(#gradient-{randId})" />
|
|
115
|
+
<AxisX tickSize={18} dy={-17} />
|
|
116
|
+
</Plot>
|
|
117
|
+
{:else}
|
|
118
|
+
<!--- continuous -->
|
|
119
|
+
{@const domain = plot.scales.color.domain}
|
|
120
|
+
{@const ticks = new Set([
|
|
121
|
+
domain[0],
|
|
122
|
+
...(plot.scales.color?.fn?.ticks?.(Math.ceil(width / 5)) ?? []),
|
|
123
|
+
domain[1]
|
|
124
|
+
])}
|
|
125
|
+
<Plot
|
|
126
|
+
maxWidth="240px"
|
|
127
|
+
margins={1}
|
|
128
|
+
marginLeft={10}
|
|
129
|
+
marginRight={10}
|
|
130
|
+
marginTop={6}
|
|
131
|
+
marginBottom={20}
|
|
132
|
+
height={38}
|
|
133
|
+
inset={0}
|
|
134
|
+
x={{ domain, tickSpacing, tickFormat }}>
|
|
135
|
+
<defs>
|
|
136
|
+
<linearGradient id="gradient-{randId}" x2="1">
|
|
137
|
+
{#each ticks as t}
|
|
138
|
+
<stop
|
|
139
|
+
offset="{(100 * (t - domain[0])) / (domain[1] - domain[0])}%"
|
|
140
|
+
stop-color={plot.scales.color.fn(t)} />
|
|
141
|
+
{/each}
|
|
142
|
+
</linearGradient>
|
|
143
|
+
</defs>
|
|
144
|
+
<Frame dy={-5} stroke={null} fill="url(#gradient-{randId})" />
|
|
145
|
+
<AxisX tickSize={18} dy={-17} />
|
|
146
|
+
</Plot>
|
|
147
|
+
{/if}
|
|
30
148
|
</div>
|
|
31
149
|
{/if}
|
|
32
150
|
|
|
@@ -37,6 +155,9 @@ const plot = getContext("svelteplot");
|
|
|
37
155
|
display: inline-block;
|
|
38
156
|
margin-right: 2em;
|
|
39
157
|
}
|
|
158
|
+
.title {
|
|
159
|
+
font-weight: 500;
|
|
160
|
+
}
|
|
40
161
|
.item {
|
|
41
162
|
margin: 0 1em 0.5ex 0;
|
|
42
163
|
}
|
|
@@ -49,6 +170,6 @@ const plot = getContext("svelteplot");
|
|
|
49
170
|
display: inline-block;
|
|
50
171
|
}
|
|
51
172
|
.item-label {
|
|
52
|
-
vertical-align:
|
|
173
|
+
vertical-align: super;
|
|
53
174
|
}
|
|
54
175
|
</style>
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
};
|
|
7
|
-
slots: {};
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
width?: number;
|
|
3
|
+
tickSpacing?: number;
|
|
4
|
+
class?: string;
|
|
8
5
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The ColorLegend is an HTML mark that can be placed in the header, footer and overlay
|
|
8
|
+
* snippets. You can activate an implicit ColorLegend above the chart using the global
|
|
9
|
+
* color.legend scale option.
|
|
10
|
+
*/
|
|
11
|
+
declare const ColorLegend: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type ColorLegend = ReturnType<typeof ColorLegend>;
|
|
13
|
+
export default ColorLegend;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
For showing custom SVG marks positioned at x/y coordinates
|
|
4
|
+
-->
|
|
5
|
+
<script module lang="ts">
|
|
6
|
+
import type { ChannelAccessor, DataRow } from '../types.js';
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
|
|
9
|
+
export type HTMLMarkProps = {
|
|
10
|
+
data: DataRow[];
|
|
11
|
+
x?: ChannelAccessor;
|
|
12
|
+
y?: ChannelAccessor;
|
|
13
|
+
children: Snippet<{ datum: DataRow; x: number; y: number }>;
|
|
14
|
+
};
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import { getContext } from 'svelte';
|
|
19
|
+
import type { PlotContext } from '../types.js';
|
|
20
|
+
|
|
21
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
22
|
+
let plot = $derived(getPlotState());
|
|
23
|
+
|
|
24
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
25
|
+
import { projectXY } from '../helpers/scales.js';
|
|
26
|
+
import { isValid } from '../helpers/index.js';
|
|
27
|
+
import GroupMultiple from './helpers/GroupMultiple.svelte';
|
|
28
|
+
|
|
29
|
+
let { data = [{}], x, y, children, class: className = null }: HTMLMarkProps = $props();
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<GroupMultiple class="g-custom-mark {className || ''}" length={className ? 2 : data.length}>
|
|
33
|
+
{#each data as datum}
|
|
34
|
+
{@const x_ = resolveChannel('x', datum, { x, y })}
|
|
35
|
+
{@const y_ = resolveChannel('y', datum, { x, y })}
|
|
36
|
+
{#if isValid(x_) && isValid(y_)}
|
|
37
|
+
{@const [px, py] = projectXY(plot.scales, x_, y_)}
|
|
38
|
+
<g transform="translate({px}, {py})">
|
|
39
|
+
{@render children({ datum, x: px, y: py })}
|
|
40
|
+
</g>
|
|
41
|
+
{/if}
|
|
42
|
+
{/each}
|
|
43
|
+
</GroupMultiple>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ChannelAccessor, DataRow } from '../types.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export type HTMLMarkProps = {
|
|
4
|
+
data: DataRow[];
|
|
5
|
+
x?: ChannelAccessor;
|
|
6
|
+
y?: ChannelAccessor;
|
|
7
|
+
children: Snippet<{
|
|
8
|
+
datum: DataRow;
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}>;
|
|
12
|
+
};
|
|
13
|
+
/** For showing custom SVG marks positioned at x/y coordinates */
|
|
14
|
+
declare const CustomMark: import("svelte").Component<HTMLMarkProps, {}, "">;
|
|
15
|
+
type CustomMark = ReturnType<typeof CustomMark>;
|
|
16
|
+
export default CustomMark;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
For showing custom HTML tooltips positioned at x/y coordinates
|
|
4
|
+
-->
|
|
5
|
+
<script module lang="ts">
|
|
6
|
+
import type { ChannelAccessor, ConstantAccessor, DataRow } from '../types.js';
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
|
|
9
|
+
export type HTMLMarkProps = {
|
|
10
|
+
data: DataRow[];
|
|
11
|
+
x?: ChannelAccessor;
|
|
12
|
+
y?: ChannelAccessor;
|
|
13
|
+
frameAnchor?: ConstantAccessor<
|
|
14
|
+
| 'bottom'
|
|
15
|
+
| 'top'
|
|
16
|
+
| 'left'
|
|
17
|
+
| 'right'
|
|
18
|
+
| 'top-left'
|
|
19
|
+
| 'bottom-left'
|
|
20
|
+
| 'top-right'
|
|
21
|
+
| 'bottom-right'
|
|
22
|
+
| 'center'
|
|
23
|
+
>;
|
|
24
|
+
children: Snippet<{ datum: DataRow; x: number; y: number }>;
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<script lang="ts">
|
|
29
|
+
import { getContext } from 'svelte';
|
|
30
|
+
import type { PlotContext } from '../types.js';
|
|
31
|
+
|
|
32
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
33
|
+
const plot = $derived(getPlotState());
|
|
34
|
+
|
|
35
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
36
|
+
import { projectX, projectY, projectXY } from '../helpers/scales.js';
|
|
37
|
+
import { isValid } from '../helpers/index.js';
|
|
38
|
+
|
|
39
|
+
let {
|
|
40
|
+
data = [{}],
|
|
41
|
+
x,
|
|
42
|
+
y,
|
|
43
|
+
frameAnchor,
|
|
44
|
+
children,
|
|
45
|
+
class: className = null
|
|
46
|
+
}: HTMLMarkProps = $props();
|
|
47
|
+
|
|
48
|
+
function getXY(datum) {
|
|
49
|
+
const fa = frameAnchor || 'center';
|
|
50
|
+
const isLeft = fa.endsWith('left');
|
|
51
|
+
const isRight = fa.endsWith('right');
|
|
52
|
+
const isTop = fa.startsWith('top');
|
|
53
|
+
const isBottom = fa.startsWith('bottom');
|
|
54
|
+
|
|
55
|
+
if (x == null || y == null) {
|
|
56
|
+
// project x and y individually
|
|
57
|
+
const px =
|
|
58
|
+
x != null
|
|
59
|
+
? projectX('x', plot.scales, resolveChannel('x', datum, { x, y }))
|
|
60
|
+
: plot.options.marginLeft +
|
|
61
|
+
(isLeft ? 0 : isRight ? plot.width : plot.width / 2);
|
|
62
|
+
const py =
|
|
63
|
+
y != null
|
|
64
|
+
? projectY('y', plot.scales, resolveChannel('y', datum, { x, y }))
|
|
65
|
+
: plot.options.marginTop +
|
|
66
|
+
(isTop ? 0 : isBottom ? plot.height : plot.height / 2);
|
|
67
|
+
return [px, py];
|
|
68
|
+
} else {
|
|
69
|
+
// use projectXY
|
|
70
|
+
const x_ = resolveChannel('x', datum, { x, y });
|
|
71
|
+
const y_ = resolveChannel('y', datum, { x, y });
|
|
72
|
+
return projectXY(plot.scales, x_, y_);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
{#snippet customMarks()}
|
|
78
|
+
{#each data as datum}
|
|
79
|
+
{@const [px, py] = getXY(datum)}
|
|
80
|
+
{#if isValid(px) && isValid(py)}
|
|
81
|
+
<div
|
|
82
|
+
class="custom-mark-html"
|
|
83
|
+
style:left="{px.toFixed(0)}px"
|
|
84
|
+
style:top="{py.toFixed(0)}px">
|
|
85
|
+
{@render children({ datum, x: px, y: py })}
|
|
86
|
+
</div>
|
|
87
|
+
{/if}
|
|
88
|
+
{/each}
|
|
89
|
+
{/snippet}
|
|
90
|
+
|
|
91
|
+
{#if data.length > 1 || className}
|
|
92
|
+
<div class="g-custom-mark-html {className || ''}">
|
|
93
|
+
{@render customMarks()}
|
|
94
|
+
</div>
|
|
95
|
+
{:else}
|
|
96
|
+
{@render customMarks()}
|
|
97
|
+
{/if}
|
|
98
|
+
|
|
99
|
+
<style>
|
|
100
|
+
.custom-mark-html {
|
|
101
|
+
position: absolute;
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChannelAccessor, ConstantAccessor, DataRow } from '../types.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export type HTMLMarkProps = {
|
|
4
|
+
data: DataRow[];
|
|
5
|
+
x?: ChannelAccessor;
|
|
6
|
+
y?: ChannelAccessor;
|
|
7
|
+
frameAnchor?: ConstantAccessor<'bottom' | 'top' | 'left' | 'right' | 'top-left' | 'bottom-left' | 'top-right' | 'bottom-right' | 'center'>;
|
|
8
|
+
children: Snippet<{
|
|
9
|
+
datum: DataRow;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
/** For showing custom HTML tooltips positioned at x/y coordinates */
|
|
15
|
+
declare const CustomMarkHtml: import("svelte").Component<HTMLMarkProps, {}, "">;
|
|
16
|
+
type CustomMarkHtml = ReturnType<typeof CustomMarkHtml>;
|
|
17
|
+
export default CustomMarkHtml;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type {
|
|
3
|
+
BaseMarkProps,
|
|
4
|
+
ChannelAccessor,
|
|
5
|
+
ConstantAccessor,
|
|
6
|
+
CurveName,
|
|
7
|
+
DataRecord,
|
|
8
|
+
PlotContext
|
|
9
|
+
} from '../types.js';
|
|
10
|
+
import { Line, Area } from '../index.js';
|
|
11
|
+
import { randomId, coalesce } from '../helpers/index.js';
|
|
12
|
+
import { getContext } from 'svelte';
|
|
13
|
+
import { extent, max, min } from 'd3-array';
|
|
14
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
15
|
+
import type { CurveFactory } from 'd3-shape';
|
|
16
|
+
|
|
17
|
+
type DifferenceYMarkProps = {
|
|
18
|
+
data: DataRecord[];
|
|
19
|
+
/*
|
|
20
|
+
* the horizontal position of the comparison; bound to the x scale
|
|
21
|
+
*/
|
|
22
|
+
x1: ChannelAccessor;
|
|
23
|
+
/**
|
|
24
|
+
* the horizontal position of the metric; bound to the x scale
|
|
25
|
+
*/
|
|
26
|
+
x2: ChannelAccessor;
|
|
27
|
+
x: ChannelAccessor;
|
|
28
|
+
/**
|
|
29
|
+
* the vertical position of the comparison; bound to the y scale
|
|
30
|
+
*/
|
|
31
|
+
y1: ChannelAccessor;
|
|
32
|
+
/**
|
|
33
|
+
* the vertical position of the metric; bound to the y scale
|
|
34
|
+
*/
|
|
35
|
+
y2: ChannelAccessor;
|
|
36
|
+
y: ChannelAccessor;
|
|
37
|
+
positiveFill?: string;
|
|
38
|
+
positiveFillOpacity?: number;
|
|
39
|
+
negativeFill?: string;
|
|
40
|
+
negativeFillOpacity?: number;
|
|
41
|
+
stroke: boolean | ChannelAccessor;
|
|
42
|
+
curve?: CurveName | CurveFactory;
|
|
43
|
+
tension?: number;
|
|
44
|
+
} & BaseMarkProps;
|
|
45
|
+
|
|
46
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
47
|
+
let plot = $derived(getPlotState());
|
|
48
|
+
|
|
49
|
+
let { data, stroke, class: className = null, ...options }: DifferenceYMarkProps = $props();
|
|
50
|
+
let { x, x1, x2, y, y1, y2 } = $derived(options);
|
|
51
|
+
|
|
52
|
+
const x1x2Differ = $derived((x1 == null || x2 == null) && x1 !== x2);
|
|
53
|
+
|
|
54
|
+
const xExtent = $derived(
|
|
55
|
+
x1x2Differ && x != null ? extent(data, (d) => resolveChannel('x', d, options)) : null
|
|
56
|
+
);
|
|
57
|
+
const x1Extent = $derived(
|
|
58
|
+
x1x2Differ && x1 != null ? extent(data, (d) => resolveChannel('x1', d, options)) : null
|
|
59
|
+
);
|
|
60
|
+
const x2Extent = $derived(
|
|
61
|
+
x1x2Differ && x2 != null ? extent(data, (d) => resolveChannel('x2', d, options)) : null
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const maxMin = $derived(
|
|
65
|
+
max([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d[0]))
|
|
66
|
+
);
|
|
67
|
+
const minMax = $derived(
|
|
68
|
+
min([xExtent, x1Extent, x2Extent].filter((d) => d != null).map((d) => d[1]))
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const croppedX1 = $derived(
|
|
72
|
+
x1x2Differ
|
|
73
|
+
? data.filter((d) => {
|
|
74
|
+
const x1val = resolveChannel(x1 != null ? 'x1' : 'x', d, options);
|
|
75
|
+
return x1val >= maxMin && x1val <= minMax;
|
|
76
|
+
})
|
|
77
|
+
: data
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const croppedX2 = $derived(
|
|
81
|
+
x1x2Differ
|
|
82
|
+
? data.filter((d) => {
|
|
83
|
+
const x2val = resolveChannel(x2 != null ? 'x2' : 'x', d, options);
|
|
84
|
+
return x2val >= maxMin && x2val <= minMax;
|
|
85
|
+
})
|
|
86
|
+
: data
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const id = randomId();
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<g class="positive difference {className || ''}">
|
|
93
|
+
<!-- pos clips goes from bottom of plot area to the line 2 -->
|
|
94
|
+
<clipPath id="pos-clip-{id}">
|
|
95
|
+
<Area
|
|
96
|
+
data={croppedX2}
|
|
97
|
+
{...options}
|
|
98
|
+
fill={options.positiveFill || 'red'}
|
|
99
|
+
x1={coalesce(x2, x)}
|
|
100
|
+
y1={coalesce(y2, y)}
|
|
101
|
+
y2={{ scale: null, value: plot.options.marginTop + plot.facetHeight }} />
|
|
102
|
+
</clipPath>
|
|
103
|
+
<!-- pos area goes from top to line 1 -->
|
|
104
|
+
<Area
|
|
105
|
+
clipPath="url(#pos-clip-{id})"
|
|
106
|
+
data={croppedX1}
|
|
107
|
+
{...options}
|
|
108
|
+
fill={options.positiveFill || 'pink'}
|
|
109
|
+
fillOpacity={coalesce(options.positiveFillOpacity, 1)}
|
|
110
|
+
x1={coalesce(x1, x2, x)}
|
|
111
|
+
y1={{ scale: null, value: 0 }}
|
|
112
|
+
y2={coalesce(y1, x1x2Differ ? coalesce(y2, y) : 0)} />
|
|
113
|
+
</g>
|
|
114
|
+
<g class="negative difference {className || ''}">
|
|
115
|
+
<!-- neg clips goes from bottom of plot area to the line 1 -->
|
|
116
|
+
<clipPath id="neg-clip-{id}">
|
|
117
|
+
<Area
|
|
118
|
+
data={croppedX1}
|
|
119
|
+
{...options}
|
|
120
|
+
fill={options.negativeFill || 'blue'}
|
|
121
|
+
x1={coalesce(x1, x2, x)}
|
|
122
|
+
y1={coalesce(y1, x1x2Differ ? coalesce(y2, y) : 0)}
|
|
123
|
+
y2={{ scale: null, value: plot.options.marginTop + plot.facetHeight }} />
|
|
124
|
+
</clipPath>
|
|
125
|
+
<!-- neg area goes from top to line 2 -->
|
|
126
|
+
<Area
|
|
127
|
+
clipPath="url(#neg-clip-{id})"
|
|
128
|
+
data={croppedX2}
|
|
129
|
+
{...options}
|
|
130
|
+
fill={options.negativeFill || 'cyan'}
|
|
131
|
+
fillOpacity={coalesce(options.negativeFillOpacity, 1)}
|
|
132
|
+
x1={coalesce(x2, x)}
|
|
133
|
+
y1={{ scale: null, value: 0 }}
|
|
134
|
+
y2={coalesce(y2, y)} />
|
|
135
|
+
</g>
|
|
136
|
+
{#if stroke != null}
|
|
137
|
+
<!-- set stroke to false to hide the line -->
|
|
138
|
+
<Line
|
|
139
|
+
data={croppedX2}
|
|
140
|
+
{...options}
|
|
141
|
+
stroke={stroke === true ? 'currentColor' : stroke}
|
|
142
|
+
x={coalesce(x2, x)}
|
|
143
|
+
y={coalesce(y2, y)} />
|
|
144
|
+
{/if}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BaseMarkProps, ChannelAccessor, CurveName, DataRecord } from '../types.js';
|
|
2
|
+
import type { CurveFactory } from 'd3-shape';
|
|
3
|
+
type DifferenceYMarkProps = {
|
|
4
|
+
data: DataRecord[];
|
|
5
|
+
x1: ChannelAccessor;
|
|
6
|
+
/**
|
|
7
|
+
* the horizontal position of the metric; bound to the x scale
|
|
8
|
+
*/
|
|
9
|
+
x2: ChannelAccessor;
|
|
10
|
+
x: ChannelAccessor;
|
|
11
|
+
/**
|
|
12
|
+
* the vertical position of the comparison; bound to the y scale
|
|
13
|
+
*/
|
|
14
|
+
y1: ChannelAccessor;
|
|
15
|
+
/**
|
|
16
|
+
* the vertical position of the metric; bound to the y scale
|
|
17
|
+
*/
|
|
18
|
+
y2: ChannelAccessor;
|
|
19
|
+
y: ChannelAccessor;
|
|
20
|
+
positiveFill?: string;
|
|
21
|
+
positiveFillOpacity?: number;
|
|
22
|
+
negativeFill?: string;
|
|
23
|
+
negativeFillOpacity?: number;
|
|
24
|
+
stroke: boolean | ChannelAccessor;
|
|
25
|
+
curve?: CurveName | CurveFactory;
|
|
26
|
+
tension?: number;
|
|
27
|
+
} & BaseMarkProps;
|
|
28
|
+
declare const DifferenceY: import("svelte").Component<DifferenceYMarkProps, {}, "">;
|
|
29
|
+
type DifferenceY = ReturnType<typeof DifferenceY>;
|
|
30
|
+
export default DifferenceY;
|