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,165 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { PlotState, Mark, DataRecord, BaseMarkProps } from '../../types.js';
|
|
3
|
+
import { CSS_VAR } from '../../constants.js';
|
|
4
|
+
import { testFilter } from '../../helpers/index.js';
|
|
5
|
+
import { resolveProp, resolveScaledStyleProps } from '../../helpers/resolve.js';
|
|
6
|
+
import { untrack } from 'svelte';
|
|
7
|
+
import { isEqual } from 'es-toolkit';
|
|
8
|
+
import { type GeoPath } from 'd3-geo';
|
|
9
|
+
|
|
10
|
+
let canvas: HTMLCanvasElement | undefined = $state();
|
|
11
|
+
let devicePixelRatio = $state(1);
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
mark,
|
|
15
|
+
plot,
|
|
16
|
+
data,
|
|
17
|
+
testFacet,
|
|
18
|
+
usedScales,
|
|
19
|
+
path
|
|
20
|
+
}: {
|
|
21
|
+
mark: Mark<BaseMarkProps>;
|
|
22
|
+
plot: PlotState;
|
|
23
|
+
data: DataRecord[];
|
|
24
|
+
testFacet: any;
|
|
25
|
+
usedScales: any;
|
|
26
|
+
path: GeoPath;
|
|
27
|
+
} = $props();
|
|
28
|
+
|
|
29
|
+
function scaleHash(scale) {
|
|
30
|
+
return { domain: scale.domain, type: scale.type, range: scale.range };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let _plotSize = $state([plot.width, plot.height]);
|
|
34
|
+
let _usedScales = $state(usedScales);
|
|
35
|
+
let _markOptions = $state(mark.options);
|
|
36
|
+
|
|
37
|
+
const filteredData = $derived(
|
|
38
|
+
data.filter((datum) => testFilter(datum, _markOptions) && testFacet(datum, _markOptions))
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
let _filteredData: DataRecord[] = $state([]);
|
|
42
|
+
|
|
43
|
+
$effect(() => {
|
|
44
|
+
// update _usedScales only if changed
|
|
45
|
+
if (!isEqual(usedScales, _usedScales)) _usedScales = usedScales;
|
|
46
|
+
if (!isEqual(mark.options, _markOptions)) _markOptions = mark.options;
|
|
47
|
+
|
|
48
|
+
const plotSize = [plot.width, plot.height];
|
|
49
|
+
if (!isEqual(plotSize, _plotSize)) _plotSize = plotSize;
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
_markOptions.filter
|
|
53
|
+
? !isEqual(filteredData, _filteredData)
|
|
54
|
+
: filteredData.length !== _filteredData.length
|
|
55
|
+
) {
|
|
56
|
+
_filteredData = filteredData;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
$effect(() => {
|
|
61
|
+
// track plot size, since we're untracking the scales
|
|
62
|
+
_plotSize;
|
|
63
|
+
_markOptions;
|
|
64
|
+
|
|
65
|
+
const plotScales = untrack(() => plot.scales);
|
|
66
|
+
const context = canvas.getContext('2d');
|
|
67
|
+
if (context === null) return;
|
|
68
|
+
// this will re-run whenever `color` or `size` change
|
|
69
|
+
context.resetTransform();
|
|
70
|
+
context.scale(devicePixelRatio, devicePixelRatio);
|
|
71
|
+
|
|
72
|
+
let currentColor;
|
|
73
|
+
|
|
74
|
+
path.context(context);
|
|
75
|
+
|
|
76
|
+
const plot_ = untrack(() => plot);
|
|
77
|
+
|
|
78
|
+
for (const datum of _filteredData) {
|
|
79
|
+
// untrack the filter test to avoid redrawing when not necessary
|
|
80
|
+
let { stroke, fill, opacity, ...restStyles } = resolveScaledStyleProps(
|
|
81
|
+
datum,
|
|
82
|
+
_markOptions,
|
|
83
|
+
_usedScales,
|
|
84
|
+
plot_,
|
|
85
|
+
'fill'
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const fillOpacity = restStyles['fill-opacity'];
|
|
89
|
+
const strokeOpacity = restStyles['stroke-opacity'];
|
|
90
|
+
|
|
91
|
+
if (`${fill}`.toLowerCase() === 'currentcolor')
|
|
92
|
+
fill =
|
|
93
|
+
currentColor ||
|
|
94
|
+
(currentColor = getComputedStyle(
|
|
95
|
+
canvas?.parentElement?.parentElement
|
|
96
|
+
).getPropertyValue('color'));
|
|
97
|
+
if (`${stroke}`.toLowerCase() === 'currentcolor')
|
|
98
|
+
stroke =
|
|
99
|
+
currentColor ||
|
|
100
|
+
(currentColor = getComputedStyle(
|
|
101
|
+
canvas?.parentElement?.parentElement
|
|
102
|
+
).getPropertyValue('color'));
|
|
103
|
+
if (CSS_VAR.test(fill))
|
|
104
|
+
fill = getComputedStyle(canvas).getPropertyValue(fill.slice(4, -1));
|
|
105
|
+
if (CSS_VAR.test(stroke))
|
|
106
|
+
stroke = getComputedStyle(canvas).getPropertyValue(stroke.slice(4, -1));
|
|
107
|
+
|
|
108
|
+
if (stroke && stroke !== 'none') {
|
|
109
|
+
const strokeWidth = resolveProp(_markOptions.strokeWidth, datum, 1.6);
|
|
110
|
+
context.lineWidth = strokeWidth;
|
|
111
|
+
}
|
|
112
|
+
context.fillStyle = fill ? fill : 'none';
|
|
113
|
+
context.strokeStyle = stroke ? stroke : 'none';
|
|
114
|
+
|
|
115
|
+
context.beginPath();
|
|
116
|
+
path(datum);
|
|
117
|
+
context.closePath();
|
|
118
|
+
|
|
119
|
+
if (opacity != null) context.globalAlpha = opacity ?? 1;
|
|
120
|
+
if (fillOpacity != null) context.globalAlpha = (opacity ?? 1) * fillOpacity;
|
|
121
|
+
|
|
122
|
+
if (fill && fill !== 'none') context.fill();
|
|
123
|
+
if (strokeOpacity != null) context.globalAlpha = (opacity ?? 1) * strokeOpacity;
|
|
124
|
+
if (stroke && stroke !== 'none') context.stroke();
|
|
125
|
+
}
|
|
126
|
+
return () => {
|
|
127
|
+
canvas?.getContext('2d')?.clearRect(0, 0, canvas?.width, canvas?.height);
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// code from https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
|
|
132
|
+
let remove: null | (() => void) = null;
|
|
133
|
+
|
|
134
|
+
function updatePixelRatio() {
|
|
135
|
+
if (remove != null) {
|
|
136
|
+
remove();
|
|
137
|
+
}
|
|
138
|
+
const mqString = `(resolution: ${window.devicePixelRatio}dppx)`;
|
|
139
|
+
const media = matchMedia(mqString);
|
|
140
|
+
media.addEventListener('change', updatePixelRatio);
|
|
141
|
+
remove = () => {
|
|
142
|
+
media.removeEventListener('change', updatePixelRatio);
|
|
143
|
+
};
|
|
144
|
+
devicePixelRatio = window.devicePixelRatio;
|
|
145
|
+
}
|
|
146
|
+
$effect(() => {
|
|
147
|
+
updatePixelRatio();
|
|
148
|
+
});
|
|
149
|
+
</script>
|
|
150
|
+
|
|
151
|
+
<foreignObject x="0" y="0" width={plot.width} height={plot.height}>
|
|
152
|
+
<canvas
|
|
153
|
+
xmlns="http://www.w3.org/1999/xhtml"
|
|
154
|
+
bind:this={canvas}
|
|
155
|
+
width={plot.width * devicePixelRatio}
|
|
156
|
+
height={plot.height * devicePixelRatio}
|
|
157
|
+
style="width: {plot.width}px; height: {plot.height}px;"></canvas>
|
|
158
|
+
</foreignObject>
|
|
159
|
+
|
|
160
|
+
<style>
|
|
161
|
+
foreignObject,
|
|
162
|
+
canvas {
|
|
163
|
+
color: currentColor;
|
|
164
|
+
}
|
|
165
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PlotState, Mark, DataRecord, BaseMarkProps } from '../../types.js';
|
|
2
|
+
import { type GeoPath } from 'd3-geo';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
mark: Mark<BaseMarkProps>;
|
|
5
|
+
plot: PlotState;
|
|
6
|
+
data: DataRecord[];
|
|
7
|
+
testFacet: any;
|
|
8
|
+
usedScales: any;
|
|
9
|
+
path: GeoPath;
|
|
10
|
+
};
|
|
11
|
+
declare const GeoCanvas: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type GeoCanvas = ReturnType<typeof GeoCanvas>;
|
|
13
|
+
export default GeoCanvas;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
let {
|
|
4
|
+
length = 1,
|
|
5
|
+
children,
|
|
6
|
+
class: className = null,
|
|
7
|
+
...groupProps
|
|
8
|
+
}: { children: Snippet; length?: number; class?: string | null } = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
{#if length > 1 || className}
|
|
12
|
+
<g class={className} {...groupProps}>
|
|
13
|
+
{@render children()}
|
|
14
|
+
</g>
|
|
15
|
+
{:else}
|
|
16
|
+
{@render children()}
|
|
17
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
children: Snippet;
|
|
4
|
+
length?: number;
|
|
5
|
+
class?: string | null;
|
|
6
|
+
};
|
|
7
|
+
declare const GroupMultiple: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type GroupMultiple = ReturnType<typeof GroupMultiple>;
|
|
9
|
+
export default GroupMultiple;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export type MarkerShape =
|
|
3
|
+
| 'dot'
|
|
4
|
+
| 'circle'
|
|
5
|
+
| 'circle-stroke'
|
|
6
|
+
| 'arrow'
|
|
7
|
+
| 'arrow-reverse'
|
|
8
|
+
| 'tick'
|
|
9
|
+
| 'tick-x'
|
|
10
|
+
| 'tick-y';
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
@component Marker is a helper component that creates a marker for use in a line or path.
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import { getContext } from 'svelte';
|
|
19
|
+
|
|
20
|
+
type MarkerProps = {
|
|
21
|
+
id: string;
|
|
22
|
+
shape: MarkerShape;
|
|
23
|
+
color: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let { id, shape, color }: MarkerProps = $props();
|
|
27
|
+
|
|
28
|
+
const tickMarker = (orient: number | 'auto') => ({
|
|
29
|
+
viewBox: '-3 -3 6 6',
|
|
30
|
+
path: 'M0,-3v6',
|
|
31
|
+
width: 6,
|
|
32
|
+
height: 6,
|
|
33
|
+
orient,
|
|
34
|
+
color: 'stroke'
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const MARKERS: Record<
|
|
38
|
+
MarkerShape,
|
|
39
|
+
{
|
|
40
|
+
path?: string;
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
orient: number | 'auto';
|
|
44
|
+
color: 'fill' | 'stroke';
|
|
45
|
+
bg?: 'fill' | 'stroke';
|
|
46
|
+
viewBox?: string;
|
|
47
|
+
}
|
|
48
|
+
> = {
|
|
49
|
+
circle: { width: 6.67, height: 6.67, orient: 0, color: 'fill', bg: 'stroke' },
|
|
50
|
+
dot: { width: 6.67, height: 6.67, orient: 0, color: 'fill' },
|
|
51
|
+
'circle-stroke': { width: 6.67, height: 6.67, orient: 0, color: 'stroke', bg: 'fill' },
|
|
52
|
+
tick: tickMarker('auto'),
|
|
53
|
+
'tick-x': tickMarker(90),
|
|
54
|
+
'tick-y': tickMarker(0),
|
|
55
|
+
arrow: {
|
|
56
|
+
path: 'M-1.5,-3l3,3l-3,3',
|
|
57
|
+
width: 6.67,
|
|
58
|
+
height: 6.67,
|
|
59
|
+
orient: 'auto',
|
|
60
|
+
color: 'stroke'
|
|
61
|
+
},
|
|
62
|
+
'arrow-reverse': {
|
|
63
|
+
path: 'M1.5,-3l-3,3l3,3',
|
|
64
|
+
width: 6.67,
|
|
65
|
+
height: 6.67,
|
|
66
|
+
orient: 'auto',
|
|
67
|
+
color: 'stroke'
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const defaultDotRadius = getContext('svelteplot/_defaults').markerDotRadius;
|
|
72
|
+
|
|
73
|
+
const markerColors = $derived({
|
|
74
|
+
fill: 'none',
|
|
75
|
+
[MARKERS[shape].color]: color,
|
|
76
|
+
...(MARKERS[shape].bg ? { [MARKERS[shape].bg as string]: 'var(--svelteplot-bg)' } : {})
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<marker
|
|
81
|
+
{id}
|
|
82
|
+
viewBox={MARKERS[shape].viewBox || '-5 -5 10 10'}
|
|
83
|
+
markerWidth={MARKERS[shape].width}
|
|
84
|
+
orient={MARKERS[shape].orient}
|
|
85
|
+
markerHeight={MARKERS[shape].height}
|
|
86
|
+
stroke-width="1.5"
|
|
87
|
+
{...markerColors}>
|
|
88
|
+
{#if shape === 'dot' || shape === 'circle' || shape === 'circle-stroke'}
|
|
89
|
+
<circle r={defaultDotRadius} />
|
|
90
|
+
{:else}
|
|
91
|
+
<path d={MARKERS[shape].path} />
|
|
92
|
+
{/if}
|
|
93
|
+
</marker>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type MarkerShape = 'dot' | 'circle' | 'circle-stroke' | 'arrow' | 'arrow-reverse' | 'tick' | 'tick-x' | 'tick-y';
|
|
2
|
+
type MarkerProps = {
|
|
3
|
+
id: string;
|
|
4
|
+
shape: MarkerShape;
|
|
5
|
+
color: string;
|
|
6
|
+
};
|
|
7
|
+
/** Marker is a helper component that creates a marker for use in a line or path. */
|
|
8
|
+
declare const Marker: import("svelte").Component<MarkerProps, {}, "">;
|
|
9
|
+
type Marker = ReturnType<typeof Marker>;
|
|
10
|
+
export default Marker;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
Helper component for paths with markers and optional text along the path.
|
|
4
|
+
-->
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import Marker, { type MarkerShape } from './Marker.svelte';
|
|
7
|
+
import { isSnippet, randomId } from '../../helpers/index.js';
|
|
8
|
+
import { resolveProp } from '../../helpers/resolve.js';
|
|
9
|
+
import type {
|
|
10
|
+
BaseMarkProps,
|
|
11
|
+
ConstantAccessor,
|
|
12
|
+
DataRecord,
|
|
13
|
+
Mark,
|
|
14
|
+
PlotContext,
|
|
15
|
+
PlotScales
|
|
16
|
+
} from '../../types.js';
|
|
17
|
+
import { addEventHandlers } from './events.js';
|
|
18
|
+
import { getContext } from 'svelte';
|
|
19
|
+
|
|
20
|
+
type MarkerPathProps = BaseMarkProps & {
|
|
21
|
+
/**
|
|
22
|
+
* the datum associated with this path, usually the first
|
|
23
|
+
* element of the data array group
|
|
24
|
+
*/
|
|
25
|
+
datum: DataRecord;
|
|
26
|
+
/**
|
|
27
|
+
* the marker shape to use at the start of the path, defaults to
|
|
28
|
+
* cirlce
|
|
29
|
+
*/
|
|
30
|
+
markerStart?: boolean | MarkerShape;
|
|
31
|
+
/**
|
|
32
|
+
* the marker shape to use at the middle of the path, defaults to circle
|
|
33
|
+
*/
|
|
34
|
+
markerMid?: boolean | MarkerShape;
|
|
35
|
+
/**
|
|
36
|
+
* the marker shape to use at the end of the path, defaults to circle
|
|
37
|
+
*/
|
|
38
|
+
markerEnd?: boolean | MarkerShape;
|
|
39
|
+
/**
|
|
40
|
+
* shorthand for setting all markers
|
|
41
|
+
*/
|
|
42
|
+
marker?: boolean | MarkerShape;
|
|
43
|
+
/**
|
|
44
|
+
* path string
|
|
45
|
+
*/
|
|
46
|
+
d: string;
|
|
47
|
+
style: string;
|
|
48
|
+
startOffset: string;
|
|
49
|
+
textStyle: string;
|
|
50
|
+
textStyleClass?: string | null;
|
|
51
|
+
text: string;
|
|
52
|
+
transform: string;
|
|
53
|
+
color: string;
|
|
54
|
+
strokeWidth: ConstantAccessor<number>;
|
|
55
|
+
mark: Mark<BaseMarkProps>;
|
|
56
|
+
scales: PlotScales;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let {
|
|
60
|
+
datum,
|
|
61
|
+
markerStart,
|
|
62
|
+
markerMid,
|
|
63
|
+
markerEnd,
|
|
64
|
+
marker,
|
|
65
|
+
d,
|
|
66
|
+
style,
|
|
67
|
+
class: className = null,
|
|
68
|
+
textStyleClass = null,
|
|
69
|
+
startOffset,
|
|
70
|
+
textStyle,
|
|
71
|
+
text,
|
|
72
|
+
transform,
|
|
73
|
+
color,
|
|
74
|
+
strokeWidth,
|
|
75
|
+
mark
|
|
76
|
+
}: MarkerPathProps = $props();
|
|
77
|
+
|
|
78
|
+
const id = randomId();
|
|
79
|
+
|
|
80
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
81
|
+
|
|
82
|
+
const points = $derived(text && d != null ? d.split(/[LMC]/).slice(1) : []);
|
|
83
|
+
const hasPath = $derived(points.length > 0);
|
|
84
|
+
const firstPt = $derived(text && hasPath ? points.at(0).split(',').map(Number) : []);
|
|
85
|
+
const lastPt = $derived(text && hasPath ? points.at(-1).split(',').map(Number) : []);
|
|
86
|
+
const leftToRight = $derived(text && hasPath ? firstPt[0] < lastPt.at(-2) : true);
|
|
87
|
+
const pathIsCurve = $derived(text && hasPath ? d.includes('C') : false);
|
|
88
|
+
// this rather complicated code "reverses" the path to ensure that the text
|
|
89
|
+
// is not turned upside down
|
|
90
|
+
const textPath = $derived(
|
|
91
|
+
!text || leftToRight
|
|
92
|
+
? hasPath
|
|
93
|
+
: pathIsCurve
|
|
94
|
+
? [
|
|
95
|
+
'M',
|
|
96
|
+
points.at(-1).split(',').slice(-2).join(','),
|
|
97
|
+
'C',
|
|
98
|
+
points.at(-1).split(',').slice(2, 4).join(','),
|
|
99
|
+
',',
|
|
100
|
+
points.at(-1).split(',').slice(0, 2).join(','),
|
|
101
|
+
',',
|
|
102
|
+
points[0]
|
|
103
|
+
].join('')
|
|
104
|
+
: [
|
|
105
|
+
'M',
|
|
106
|
+
points.at(-1),
|
|
107
|
+
...points
|
|
108
|
+
.toReversed()
|
|
109
|
+
.slice(1)
|
|
110
|
+
.map((pt) => `L${pt}`)
|
|
111
|
+
].join('')
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const strokeWidth_ = $derived(resolveProp(strokeWidth, datum, 1.4));
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<g
|
|
118
|
+
{transform}
|
|
119
|
+
class={className}
|
|
120
|
+
stroke-width={strokeWidth_}
|
|
121
|
+
use:addEventHandlers={{ getPlotState, options: mark.options, datum }}>
|
|
122
|
+
{#each Object.entries( { start: markerStart, mid: markerMid, end: markerEnd, all: marker } ) as [key, marker]}
|
|
123
|
+
{@const markerId = `marker-${key === 'all' ? '' : `${key}-`}${id}`}
|
|
124
|
+
{#if isSnippet(marker)}
|
|
125
|
+
{@render marker(markerId, color)}
|
|
126
|
+
{:else if marker}
|
|
127
|
+
<Marker
|
|
128
|
+
id={markerId}
|
|
129
|
+
shape={marker === true ? 'circle' : resolveProp(marker, datum)}
|
|
130
|
+
{color} />
|
|
131
|
+
{/if}
|
|
132
|
+
{/each}
|
|
133
|
+
{#if mark.options.onmouseenter || mark.options.onclick}
|
|
134
|
+
<!-- add invisible path in bg for easier mouse access -->
|
|
135
|
+
<path
|
|
136
|
+
{d}
|
|
137
|
+
style="fill:none;stroke-width: {(strokeWidth || 1) +
|
|
138
|
+
10}; stroke: transparent; stroke-opacity:0" />
|
|
139
|
+
{/if}
|
|
140
|
+
<path
|
|
141
|
+
marker-start={markerStart || marker
|
|
142
|
+
? `url(#marker-${markerStart ? 'start-' : ''}${id})`
|
|
143
|
+
: null}
|
|
144
|
+
marker-mid={markerMid || marker ? `url(#marker-${markerMid ? 'mid-' : ''}${id})` : null}
|
|
145
|
+
marker-end={markerEnd || marker ? `url(#marker-${markerEnd ? 'end-' : ''}${id})` : null}
|
|
146
|
+
{d}
|
|
147
|
+
{style}
|
|
148
|
+
use:addEventHandlers={{ getPlotState, options: mark.options, datum }} />
|
|
149
|
+
{#if text}
|
|
150
|
+
<!-- since textPath.side is not yet supported, we have to use an invisible
|
|
151
|
+
path in order to keep the text from turning upside down -->
|
|
152
|
+
<path d={textPath} {id} stroke="none" fill="none" />
|
|
153
|
+
<text dy="-3" style={textStyle} class={textStyleClass}>
|
|
154
|
+
<textPath {startOffset} href="#{id}">{text}</textPath>
|
|
155
|
+
</text>
|
|
156
|
+
{/if}
|
|
157
|
+
</g>
|
|
158
|
+
|
|
159
|
+
<style>
|
|
160
|
+
text {
|
|
161
|
+
font-size: 12px;
|
|
162
|
+
paint-order: stroke fill;
|
|
163
|
+
}
|
|
164
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type MarkerShape } from './Marker.svelte';
|
|
2
|
+
import type { BaseMarkProps, ConstantAccessor, DataRecord, Mark, PlotScales } from '../../types.js';
|
|
3
|
+
type MarkerPathProps = BaseMarkProps & {
|
|
4
|
+
/**
|
|
5
|
+
* the datum associated with this path, usually the first
|
|
6
|
+
* element of the data array group
|
|
7
|
+
*/
|
|
8
|
+
datum: DataRecord;
|
|
9
|
+
/**
|
|
10
|
+
* the marker shape to use at the start of the path, defaults to
|
|
11
|
+
* cirlce
|
|
12
|
+
*/
|
|
13
|
+
markerStart?: boolean | MarkerShape;
|
|
14
|
+
/**
|
|
15
|
+
* the marker shape to use at the middle of the path, defaults to circle
|
|
16
|
+
*/
|
|
17
|
+
markerMid?: boolean | MarkerShape;
|
|
18
|
+
/**
|
|
19
|
+
* the marker shape to use at the end of the path, defaults to circle
|
|
20
|
+
*/
|
|
21
|
+
markerEnd?: boolean | MarkerShape;
|
|
22
|
+
/**
|
|
23
|
+
* shorthand for setting all markers
|
|
24
|
+
*/
|
|
25
|
+
marker?: boolean | MarkerShape;
|
|
26
|
+
/**
|
|
27
|
+
* path string
|
|
28
|
+
*/
|
|
29
|
+
d: string;
|
|
30
|
+
style: string;
|
|
31
|
+
startOffset: string;
|
|
32
|
+
textStyle: string;
|
|
33
|
+
textStyleClass?: string | null;
|
|
34
|
+
text: string;
|
|
35
|
+
transform: string;
|
|
36
|
+
color: string;
|
|
37
|
+
strokeWidth: ConstantAccessor<number>;
|
|
38
|
+
mark: Mark<BaseMarkProps>;
|
|
39
|
+
scales: PlotScales;
|
|
40
|
+
};
|
|
41
|
+
/** Helper component for paths with markers and optional text along the path. */
|
|
42
|
+
declare const MarkerPath: import("svelte").Component<MarkerPathProps, {}, "">;
|
|
43
|
+
type MarkerPath = ReturnType<typeof MarkerPath>;
|
|
44
|
+
export default MarkerPath;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import type { BaseMarkProps, ChannelAccessor, FacetContext, PlotContext } from '../../types.js';
|
|
3
|
+
|
|
4
|
+
type RegressionType = 'linear' | 'quad' | 'poly' | 'exp' | 'log' | 'pow' | 'loess';
|
|
5
|
+
|
|
6
|
+
export type RegressionMarkProps = BaseMarkProps & {
|
|
7
|
+
x: ChannelAccessor;
|
|
8
|
+
y: ChannelAccessor;
|
|
9
|
+
type: RegressionType;
|
|
10
|
+
/**
|
|
11
|
+
* If order is specified, sets the regression's order to the specified number.
|
|
12
|
+
* For example, if order is set to 4, the regression generator will perform a
|
|
13
|
+
* fourth-degree polynomial regression. Likewise, if order is set to 2, the
|
|
14
|
+
* regression generator will perform a quadratic regression. Be careful about
|
|
15
|
+
* attempting to fit your data with higher order polynomials; though the
|
|
16
|
+
* regression line will fit your data with a high determination coefficient,
|
|
17
|
+
* it may have little predictive power for data outside of your domain.
|
|
18
|
+
*/
|
|
19
|
+
order: number;
|
|
20
|
+
// for log
|
|
21
|
+
base: number;
|
|
22
|
+
// for loess
|
|
23
|
+
span: number;
|
|
24
|
+
// for confidence bands
|
|
25
|
+
confidence: number;
|
|
26
|
+
};
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<script lang="ts">
|
|
30
|
+
import { getContext } from 'svelte';
|
|
31
|
+
import { Line, Area } from '../../index.js';
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
regressionLinear,
|
|
35
|
+
regressionQuad,
|
|
36
|
+
regressionPoly,
|
|
37
|
+
regressionExp,
|
|
38
|
+
regressionLog,
|
|
39
|
+
regressionPow,
|
|
40
|
+
regressionLoess
|
|
41
|
+
} from 'd3-regression/dist/d3-regression.esm.js';
|
|
42
|
+
import { resolveChannel } from '../../helpers/resolve.js';
|
|
43
|
+
import { confidenceInterval } from '../../helpers/math.js';
|
|
44
|
+
import callWithProps from '../../helpers/callWithProps.js';
|
|
45
|
+
import { isDate } from '../../helpers/typeChecks';
|
|
46
|
+
|
|
47
|
+
const regressions = new Map<RegressionType, typeof regressionLinear>([
|
|
48
|
+
['linear', regressionLinear],
|
|
49
|
+
['quad', regressionQuad],
|
|
50
|
+
['poly', regressionPoly],
|
|
51
|
+
['exp', regressionExp],
|
|
52
|
+
['log', regressionLog],
|
|
53
|
+
['pow', regressionPow],
|
|
54
|
+
['loess', regressionLoess]
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
function maybeRegression(name: string) {
|
|
58
|
+
name = `${name}`.toLowerCase();
|
|
59
|
+
if (regressions.has(name)) return regressions.get(name);
|
|
60
|
+
throw new Error('unknown regression ' + name);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
64
|
+
let plot = $derived(getPlotState());
|
|
65
|
+
|
|
66
|
+
let {
|
|
67
|
+
data,
|
|
68
|
+
dependent,
|
|
69
|
+
type = 'linear',
|
|
70
|
+
order = 3,
|
|
71
|
+
base = 2.71828,
|
|
72
|
+
span = 0.3,
|
|
73
|
+
confidence = 0.99,
|
|
74
|
+
class: className = null,
|
|
75
|
+
...options
|
|
76
|
+
}: RegressionMarkProps & { dependent: 'x' | 'y' } = $props();
|
|
77
|
+
|
|
78
|
+
const { getTestFacet } = getContext<FacetContext>('svelteplot/facet');
|
|
79
|
+
let testFacet = $derived(getTestFacet());
|
|
80
|
+
|
|
81
|
+
let filteredData = $derived(data.filter((d) => testFacet(d, options)));
|
|
82
|
+
|
|
83
|
+
let independent: 'x' | 'y' = $derived(dependent === 'x' ? 'y' : 'x');
|
|
84
|
+
|
|
85
|
+
let regressionFn = $derived(maybeRegression(type));
|
|
86
|
+
|
|
87
|
+
let regression = $derived(
|
|
88
|
+
callWithProps(regressionFn, [], {
|
|
89
|
+
x: (d) => resolveChannel(independent, d, options),
|
|
90
|
+
y: (d) => resolveChannel(dependent, d, options),
|
|
91
|
+
...(type === 'poly' ? { order } : {}),
|
|
92
|
+
...(type === 'log' ? { base } : {}),
|
|
93
|
+
...(!type.startsWith('loess') ? { domain: plot.scales[independent].domain } : {}),
|
|
94
|
+
...(type === 'loess' ? { bandwidth: span } : {})
|
|
95
|
+
})(filteredData)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
let regrPoints = $derived([
|
|
99
|
+
...new Set([
|
|
100
|
+
plot.scales[independent].domain[0],
|
|
101
|
+
...plot.scales[independent].fn.ticks(40),
|
|
102
|
+
plot.scales[independent].domain[1]
|
|
103
|
+
])
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
let regrData = $derived(
|
|
107
|
+
regression.predictMany
|
|
108
|
+
? regression.predictMany(regrPoints).map((__y, i) => ({ __x: regrPoints[i], __y }))
|
|
109
|
+
: regression.predict
|
|
110
|
+
? regrPoints.map((__x) => {
|
|
111
|
+
// const __x = x;
|
|
112
|
+
const __y = regression.predict(__x);
|
|
113
|
+
return { __x, __y };
|
|
114
|
+
})
|
|
115
|
+
: regression.map(([__x, __y]) => ({
|
|
116
|
+
__x: plot.scales[independent].type === 'time' ? new Date(__x) : __x,
|
|
117
|
+
__y
|
|
118
|
+
}))
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
let stroke = $derived(
|
|
122
|
+
options.stroke != null ? resolveChannel('stroke', filteredData[0], options) : null
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
let confBandGen = $derived(
|
|
126
|
+
confidence !== false
|
|
127
|
+
? confidenceInterval(
|
|
128
|
+
data
|
|
129
|
+
.map((d) => ({
|
|
130
|
+
x: resolveChannel(independent, d, options),
|
|
131
|
+
y: resolveChannel(dependent, d, options)
|
|
132
|
+
}))
|
|
133
|
+
.filter(
|
|
134
|
+
({ x, y }) => (Number.isFinite(x) || isDate(x)) && Number.isFinite(y)
|
|
135
|
+
),
|
|
136
|
+
regression.predict,
|
|
137
|
+
1 - confidence
|
|
138
|
+
)
|
|
139
|
+
: null
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
let confBandData = $derived(
|
|
143
|
+
confidence !== false && regression.predict
|
|
144
|
+
? regrPoints.map((x) => {
|
|
145
|
+
const { x: __x, left, right } = confBandGen(x);
|
|
146
|
+
return { __x, __y1: left, __y2: right };
|
|
147
|
+
})
|
|
148
|
+
: []
|
|
149
|
+
);
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
{#if filteredData.length}
|
|
153
|
+
<g class="regression-{independent} {className || ''}">
|
|
154
|
+
<Line
|
|
155
|
+
data={regrData}
|
|
156
|
+
{...{
|
|
157
|
+
...options,
|
|
158
|
+
fx: null,
|
|
159
|
+
fy: null,
|
|
160
|
+
stroke,
|
|
161
|
+
x: dependent === 'y' ? '__x' : '__y',
|
|
162
|
+
y: dependent === 'y' ? '__y' : '__x'
|
|
163
|
+
}} />
|
|
164
|
+
{#if confBandData.length}
|
|
165
|
+
<Area
|
|
166
|
+
data={confBandData}
|
|
167
|
+
{...dependent === 'y'
|
|
168
|
+
? { x1: '__x', y1: '__y1', y2: '__y2' }
|
|
169
|
+
: { y1: '__x', x1: '__y1', x2: '__y2' }}
|
|
170
|
+
fill={stroke || 'currentColor'}
|
|
171
|
+
opacity={0.15} />
|
|
172
|
+
{/if}
|
|
173
|
+
</g>
|
|
174
|
+
{/if}
|