svelteplot 0.8.1 → 0.9.0-pr-309.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/Mark.svelte +1 -1
- package/dist/Mark.svelte.d.ts +6 -4
- package/dist/constants.d.ts +3 -1
- package/dist/constants.js +11 -2
- package/dist/core/Plot.svelte +4 -4
- package/dist/helpers/autoScales.d.ts +1 -1
- package/dist/helpers/callWithProps.d.ts +1 -3
- package/dist/helpers/callWithProps.js +5 -3
- package/dist/helpers/colors.d.ts +9 -12
- package/dist/helpers/facets.d.ts +1 -1
- package/dist/helpers/getBaseStyles.d.ts +2 -4
- package/dist/helpers/index.d.ts +3 -3
- package/dist/helpers/projection.js +7 -2
- package/dist/helpers/reduce.d.ts +1 -1
- package/dist/helpers/scales.d.ts +7 -7
- package/dist/helpers/symbols.d.ts +2 -2
- package/dist/helpers/time.d.ts +3 -3
- package/dist/helpers/typeChecks.d.ts +8 -8
- package/dist/hooks/usePlot.svelte.d.ts +51 -0
- package/dist/hooks/usePlot.svelte.js +90 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/marks/Area.svelte +3 -5
- package/dist/marks/Area.svelte.d.ts +6 -4
- package/dist/marks/AreaX.svelte.d.ts +7 -5
- package/dist/marks/Arrow.svelte +3 -5
- package/dist/marks/Arrow.svelte.d.ts +6 -4
- package/dist/marks/AxisX.svelte +2 -3
- package/dist/marks/AxisX.svelte.d.ts +7 -5
- package/dist/marks/AxisY.svelte +3 -4
- package/dist/marks/AxisY.svelte.d.ts +7 -5
- package/dist/marks/BarX.svelte +2 -4
- package/dist/marks/BarX.svelte.d.ts +6 -4
- package/dist/marks/BarY.svelte +2 -4
- package/dist/marks/BarY.svelte.d.ts +6 -4
- package/dist/marks/BollingerX.svelte.d.ts +2 -76
- package/dist/marks/BollingerY.svelte.d.ts +2 -76
- package/dist/marks/BoxX.svelte +4 -138
- package/dist/marks/BoxY.svelte +20 -137
- package/dist/marks/BoxY.svelte.d.ts +6 -64
- package/dist/marks/Brush.svelte +3 -3
- package/dist/marks/Brush.svelte.d.ts +1 -63
- package/dist/marks/Cell.svelte +2 -4
- package/dist/marks/Cell.svelte.d.ts +6 -4
- package/dist/marks/ColorLegend.svelte +2 -4
- package/dist/marks/CustomMark.svelte.d.ts +2 -84
- package/dist/marks/CustomMarkHTML.svelte +5 -10
- package/dist/marks/DifferenceY.svelte +3 -5
- package/dist/marks/DifferenceY.svelte.d.ts +1 -63
- package/dist/marks/Dot.svelte +4 -5
- package/dist/marks/Dot.svelte.d.ts +6 -4
- package/dist/marks/DotX.svelte.d.ts +7 -5
- package/dist/marks/DotY.svelte.d.ts +7 -5
- package/dist/marks/Frame.svelte +3 -9
- package/dist/marks/Frame.svelte.d.ts +7 -5
- package/dist/marks/Geo.svelte +5 -5
- package/dist/marks/Geo.svelte.d.ts +7 -4
- package/dist/marks/GridX.svelte +3 -10
- package/dist/marks/GridX.svelte.d.ts +6 -4
- package/dist/marks/GridY.svelte +3 -4
- package/dist/marks/GridY.svelte.d.ts +6 -4
- package/dist/marks/HTMLTooltip.svelte +5 -5
- package/dist/marks/Image.svelte.d.ts +2 -75
- package/dist/marks/Line.svelte +7 -6
- package/dist/marks/Line.svelte.d.ts +6 -4
- package/dist/marks/LineX.svelte.d.ts +8 -6
- package/dist/marks/LineY.svelte.d.ts +8 -6
- package/dist/marks/Link.svelte +2 -4
- package/dist/marks/Link.svelte.d.ts +6 -4
- package/dist/marks/Pointer.svelte +4 -4
- package/dist/marks/Rect.svelte +2 -4
- package/dist/marks/Rect.svelte.d.ts +6 -4
- package/dist/marks/RectX.svelte +4 -4
- package/dist/marks/RectY.svelte +4 -4
- package/dist/marks/RuleX.svelte +2 -4
- package/dist/marks/RuleX.svelte.d.ts +6 -4
- package/dist/marks/RuleY.svelte +2 -4
- package/dist/marks/RuleY.svelte.d.ts +6 -4
- package/dist/marks/Spike.svelte.d.ts +7 -5
- package/dist/marks/SymbolLegend.svelte +2 -4
- package/dist/marks/SymbolLegend.svelte.d.ts +17 -2
- package/dist/marks/Text.svelte.d.ts +6 -4
- package/dist/marks/TickX.svelte +2 -3
- package/dist/marks/TickX.svelte.d.ts +6 -4
- package/dist/marks/TickY.svelte +2 -3
- package/dist/marks/TickY.svelte.d.ts +6 -4
- package/dist/marks/Trail.svelte +161 -0
- package/dist/marks/Trail.svelte.d.ts +44 -0
- package/dist/marks/Vector.svelte +3 -4
- package/dist/marks/Vector.svelte.d.ts +6 -4
- package/dist/marks/WaffleX.svelte +2 -3
- package/dist/marks/WaffleX.svelte.d.ts +2 -85
- package/dist/marks/WaffleY.svelte +2 -4
- package/dist/marks/WaffleY.svelte.d.ts +2 -83
- package/dist/marks/helpers/AreaCanvas.svelte +2 -4
- package/dist/marks/helpers/Box.svelte +271 -0
- package/dist/marks/helpers/Box.svelte.d.ts +55 -0
- package/dist/marks/helpers/CanvasLayer.svelte +2 -4
- package/dist/marks/helpers/DotCanvas.svelte +3 -5
- package/dist/marks/helpers/GeoCanvas.svelte +2 -4
- package/dist/marks/helpers/LineCanvas.svelte +2 -4
- package/dist/marks/helpers/LinearGradientX.svelte +3 -4
- package/dist/marks/helpers/LinearGradientY.svelte +3 -4
- package/dist/marks/helpers/MarkerPath.svelte +4 -5
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +2 -102
- package/dist/marks/helpers/MultilineText.svelte +4 -4
- package/dist/marks/helpers/RectPath.svelte +5 -6
- package/dist/marks/helpers/Regression.svelte +4 -8
- package/dist/marks/helpers/TrailCanvas.svelte +138 -0
- package/dist/marks/helpers/TrailCanvas.svelte.d.ts +40 -0
- package/dist/marks/helpers/events.d.ts +2 -2
- package/dist/marks/helpers/events.js +4 -4
- package/dist/marks/helpers/trail.d.ts +23 -0
- package/dist/marks/helpers/trail.js +372 -0
- package/dist/marks/index.d.ts +1 -0
- package/dist/marks/index.js +1 -0
- package/dist/transforms/bollinger.d.ts +1 -69
- package/dist/transforms/centroid.d.ts +1 -4
- package/dist/transforms/group.d.ts +4 -12
- package/dist/transforms/interval.d.ts +2 -128
- package/dist/transforms/normalize.d.ts +23 -0
- package/dist/transforms/recordize.d.ts +4 -7
- package/dist/transforms/select.d.ts +7 -448
- package/dist/transforms/sort.d.ts +5 -253
- package/dist/transforms/stack.d.ts +3 -23
- package/dist/transforms/window.d.ts +2 -134
- package/dist/types/mark.d.ts +2 -1
- package/dist/types/plot.d.ts +6 -1
- package/dist/ui/Spiral.svelte +4 -0
- package/package.json +25 -23
|
@@ -8,17 +8,16 @@
|
|
|
8
8
|
ChannelAccessor,
|
|
9
9
|
BaseMarkProps,
|
|
10
10
|
LinkableMarkProps,
|
|
11
|
-
PlotContext,
|
|
12
11
|
BorderRadius
|
|
13
12
|
} from '../types';
|
|
14
13
|
import { wafflePolygon, type WaffleOptions } from './helpers/waffle';
|
|
15
14
|
import { getPlotDefaults } from '../hooks/plotDefaults';
|
|
16
|
-
import { getContext } from 'svelte';
|
|
17
15
|
import { intervalY, recordizeY, sort, stackY } from '../transforms';
|
|
18
16
|
import Mark from '../Mark.svelte';
|
|
19
17
|
import { resolveProp, resolveStyles } from '../helpers/resolve';
|
|
20
18
|
import { roundedRect } from '../helpers/roundedRect';
|
|
21
19
|
import GroupMultiple from './helpers/GroupMultiple.svelte';
|
|
20
|
+
import { usePlot } from '../hooks/usePlot.svelte.js';
|
|
22
21
|
|
|
23
22
|
interface WaffleYMarkProps
|
|
24
23
|
extends BaseMarkProps<Datum>, LinkableMarkProps<Datum>, WaffleOptions<Datum> {
|
|
@@ -56,8 +55,7 @@
|
|
|
56
55
|
...options
|
|
57
56
|
}: WaffleYMarkProps = $derived({ ...DEFAULTS, ...markProps });
|
|
58
57
|
|
|
59
|
-
const
|
|
60
|
-
const plot = $derived(getPlotState());
|
|
58
|
+
const plot = usePlot();
|
|
61
59
|
|
|
62
60
|
const args = $derived(
|
|
63
61
|
stackY(
|
|
@@ -1,87 +1,6 @@
|
|
|
1
|
-
import type { DataRecord
|
|
2
|
-
import { type WaffleOptions } from './helpers/waffle';
|
|
1
|
+
import type { DataRecord } from '../types';
|
|
3
2
|
declare function $$render<Datum extends DataRecord>(): {
|
|
4
|
-
props:
|
|
5
|
-
filter: import("../types").ConstantAccessor<boolean, Datum>;
|
|
6
|
-
facet: "auto" | "include" | "exclude";
|
|
7
|
-
fx: ChannelAccessor<Datum>;
|
|
8
|
-
fy: ChannelAccessor<Datum>;
|
|
9
|
-
dx: import("../types").ConstantAccessor<number, Datum>;
|
|
10
|
-
dy: import("../types").ConstantAccessor<number, Datum>;
|
|
11
|
-
dodgeX: import("../transforms/dodge").DodgeXOptions;
|
|
12
|
-
dodgeY: import("../transforms/dodge").DodgeYOptions;
|
|
13
|
-
fill: ChannelAccessor<Datum>;
|
|
14
|
-
fillOpacity: import("../types").ConstantAccessor<number, Datum>;
|
|
15
|
-
sort: ((a: import("../types").RawValue, b: import("../types").RawValue) => number) | {
|
|
16
|
-
channel: string;
|
|
17
|
-
order?: "ascending" | "descending";
|
|
18
|
-
} | import("../types").ConstantAccessor<import("../types").RawValue, Datum>;
|
|
19
|
-
stroke: ChannelAccessor<Datum>;
|
|
20
|
-
strokeWidth: import("../types").ConstantAccessor<number, Datum>;
|
|
21
|
-
strokeOpacity: import("../types").ConstantAccessor<number, Datum>;
|
|
22
|
-
strokeLinejoin: import("../types").ConstantAccessor<import("csstype").Property.StrokeLinejoin, Datum>;
|
|
23
|
-
strokeLinecap: import("../types").ConstantAccessor<import("csstype").Property.StrokeLinecap, Datum>;
|
|
24
|
-
strokeMiterlimit: import("../types").ConstantAccessor<number, Datum>;
|
|
25
|
-
opacity: ChannelAccessor<Datum>;
|
|
26
|
-
strokeDasharray: import("../types").ConstantAccessor<string, Datum>;
|
|
27
|
-
strokeDashoffset: import("../types").ConstantAccessor<number, Datum>;
|
|
28
|
-
mixBlendMode: import("../types").ConstantAccessor<import("csstype").Property.MixBlendMode, Datum>;
|
|
29
|
-
clipPath: string;
|
|
30
|
-
imageFilter: import("../types").ConstantAccessor<string, Datum>;
|
|
31
|
-
shapeRendering: import("../types").ConstantAccessor<import("csstype").Property.ShapeRendering, Datum>;
|
|
32
|
-
paintOrder: import("../types").ConstantAccessor<string, Datum>;
|
|
33
|
-
onclick: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
34
|
-
ondblclick: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
35
|
-
onmouseup: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
36
|
-
onmousedown: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
37
|
-
onmouseenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
38
|
-
onmousemove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
39
|
-
onmouseleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
40
|
-
onmouseout: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
41
|
-
onmouseover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
42
|
-
onpointercancel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
43
|
-
onpointerdown: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
44
|
-
onpointerup: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
45
|
-
onpointerenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
46
|
-
onpointerleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
47
|
-
onpointermove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
48
|
-
onpointerover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
49
|
-
onpointerout: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
50
|
-
ondrag: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
51
|
-
ondrop: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
52
|
-
ondragstart: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
53
|
-
ondragenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
54
|
-
ondragleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
55
|
-
ondragover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
56
|
-
ondragend: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
57
|
-
ontouchstart: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
58
|
-
ontouchmove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
59
|
-
ontouchend: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
60
|
-
ontouchcancel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
61
|
-
oncontextmenu: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
62
|
-
onwheel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
63
|
-
class: string;
|
|
64
|
-
style: string;
|
|
65
|
-
cursor: import("../types").ConstantAccessor<import("csstype").Property.Cursor, Datum>;
|
|
66
|
-
}> & LinkableMarkProps<Datum> & WaffleOptions<Datum> & {
|
|
67
|
-
data?: Datum[];
|
|
68
|
-
/**
|
|
69
|
-
* bound to a babd scale
|
|
70
|
-
*/
|
|
71
|
-
x?: ChannelAccessor<Datum>;
|
|
72
|
-
/**
|
|
73
|
-
* bound to a quantitative scale
|
|
74
|
-
*/
|
|
75
|
-
y?: ChannelAccessor<Datum>;
|
|
76
|
-
/**
|
|
77
|
-
* bound to a quantitative scale
|
|
78
|
-
*/
|
|
79
|
-
y1?: ChannelAccessor<Datum>;
|
|
80
|
-
/**
|
|
81
|
-
* bound to a quantitative scale
|
|
82
|
-
*/
|
|
83
|
-
y2?: ChannelAccessor<Datum>;
|
|
84
|
-
};
|
|
3
|
+
props: any;
|
|
85
4
|
exports: {};
|
|
86
5
|
bindings: "";
|
|
87
6
|
slots: {};
|
|
@@ -2,17 +2,16 @@
|
|
|
2
2
|
import type {
|
|
3
3
|
Mark,
|
|
4
4
|
BaseMarkProps,
|
|
5
|
-
PlotContext,
|
|
6
5
|
ScaledDataRecord,
|
|
7
6
|
UsedScales
|
|
8
7
|
} from '../../types/index.js';
|
|
9
8
|
import { resolveProp, resolveScaledStyleProps } from '../../helpers/resolve.js';
|
|
10
|
-
import { getContext } from 'svelte';
|
|
11
9
|
import { type Area } from 'd3-shape';
|
|
12
10
|
import CanvasLayer from './CanvasLayer.svelte';
|
|
13
11
|
import type { Attachment } from 'svelte/attachments';
|
|
14
12
|
import { devicePixelRatio } from 'svelte/reactivity/window';
|
|
15
13
|
import { resolveColor } from './canvas.js';
|
|
14
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
16
15
|
|
|
17
16
|
let {
|
|
18
17
|
mark,
|
|
@@ -26,8 +25,7 @@
|
|
|
26
25
|
areaPath: Area<ScaledDataRecord>;
|
|
27
26
|
} = $props();
|
|
28
27
|
|
|
29
|
-
const
|
|
30
|
-
const plot = $derived(getPlotState());
|
|
28
|
+
const plot = usePlot();
|
|
31
29
|
|
|
32
30
|
function maybeOpacity(value: unknown) {
|
|
33
31
|
return value == null ? 1 : +value;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
Internal shared box plot implementation for BoxX and BoxY
|
|
3
|
+
-->
|
|
4
|
+
<script lang="ts" generics="Datum extends DataRecord">
|
|
5
|
+
type Orientation = 'x' | 'y';
|
|
6
|
+
|
|
7
|
+
interface BoxMarkProps extends Pick<
|
|
8
|
+
BaseMarkProps<Datum>,
|
|
9
|
+
'class' | 'fill' | 'stroke' | 'fx' | 'fy'
|
|
10
|
+
> {
|
|
11
|
+
data: Datum[];
|
|
12
|
+
x: ChannelAccessor;
|
|
13
|
+
y: ChannelAccessor;
|
|
14
|
+
/**
|
|
15
|
+
* Custom sort order for grouped box plot data
|
|
16
|
+
*/
|
|
17
|
+
sort?: 'min' | 'max' | 'median' | 'p25' | 'p75' | ((d: Datum) => RawValue);
|
|
18
|
+
/**
|
|
19
|
+
* Options for the rule marks that represent the min/max range
|
|
20
|
+
*/
|
|
21
|
+
rule: Record<string, ChannelAccessor<Datum>>;
|
|
22
|
+
/**
|
|
23
|
+
* Options for the bar marks that represent the IQR range
|
|
24
|
+
*/
|
|
25
|
+
bar: Record<string, ChannelAccessor<Datum>>;
|
|
26
|
+
/**
|
|
27
|
+
* Options for the tick marks that represent the median
|
|
28
|
+
*/
|
|
29
|
+
tickMedian: Record<string, ChannelAccessor<Datum>> | boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Options for the tick marks that represent the min/max range
|
|
32
|
+
*/
|
|
33
|
+
tickMinMax: Record<string, ChannelAccessor<Datum>> | boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Options for the dot marks that represent the outliers
|
|
36
|
+
*/
|
|
37
|
+
dot: Record<string, ChannelAccessor<Datum>>;
|
|
38
|
+
orientation: Orientation;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
import GroupMultiple from './GroupMultiple.svelte';
|
|
42
|
+
import { groupX, groupY, BarY, TickY, RuleX, BarX, TickX, RuleY, Dot } from '../../index.js';
|
|
43
|
+
import { resolveChannel } from '../../helpers/resolve.js';
|
|
44
|
+
import type { BaseMarkProps, ChannelAccessor, DataRecord, RawValue } from '../../types';
|
|
45
|
+
import { IS_SORTED } from '../../transforms/sort';
|
|
46
|
+
|
|
47
|
+
let markProps: BoxMarkProps = $props();
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
data = [{}],
|
|
51
|
+
bar,
|
|
52
|
+
rule,
|
|
53
|
+
tickMedian,
|
|
54
|
+
tickMinMax,
|
|
55
|
+
dot,
|
|
56
|
+
x,
|
|
57
|
+
y,
|
|
58
|
+
sort,
|
|
59
|
+
fx,
|
|
60
|
+
fy,
|
|
61
|
+
fill,
|
|
62
|
+
stroke,
|
|
63
|
+
orientation,
|
|
64
|
+
class: className = ''
|
|
65
|
+
}: BoxMarkProps = $derived(markProps);
|
|
66
|
+
|
|
67
|
+
const groupFn = $derived(orientation === 'y' ? groupX : groupY);
|
|
68
|
+
const BarMark = $derived(orientation === 'y' ? BarY : BarX);
|
|
69
|
+
const RuleMark = $derived(orientation === 'y' ? RuleX : RuleY);
|
|
70
|
+
const TickMark = $derived(orientation === 'y' ? TickY : TickX);
|
|
71
|
+
|
|
72
|
+
// the channels as if this would be a BoxX
|
|
73
|
+
const xChannel = $derived(orientation === 'y' ? y : x);
|
|
74
|
+
const yChannel = $derived(orientation === 'y' ? x : y);
|
|
75
|
+
const xProp = $derived(orientation === 'x' ? 'x' : 'y');
|
|
76
|
+
const x1Prop = $derived(`${xProp}1`);
|
|
77
|
+
const x2Prop = $derived(`${xProp}2`);
|
|
78
|
+
const yProp = $derived(orientation === 'x' ? 'y' : 'x');
|
|
79
|
+
|
|
80
|
+
const { data: grouped, ...groupChannels } = $derived(
|
|
81
|
+
groupFn(
|
|
82
|
+
{
|
|
83
|
+
data: data.filter((d) => resolveChannel(xProp, d, { x, y }) != null),
|
|
84
|
+
x,
|
|
85
|
+
y,
|
|
86
|
+
[x1Prop]: xChannel,
|
|
87
|
+
[x2Prop]: xChannel,
|
|
88
|
+
fx,
|
|
89
|
+
fy
|
|
90
|
+
},
|
|
91
|
+
{ [xProp]: 'median', [x1Prop]: 'p25', [x2Prop]: 'p75', fill: (rows) => rows }
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const X = Symbol('x'),
|
|
96
|
+
Y = Symbol('y'),
|
|
97
|
+
FX = Symbol('fx'),
|
|
98
|
+
FY = Symbol('fy'),
|
|
99
|
+
P25 = Symbol('p25'),
|
|
100
|
+
P75 = Symbol('p75'),
|
|
101
|
+
MEDIAN = Symbol('median'),
|
|
102
|
+
MIN = Symbol('min'),
|
|
103
|
+
MAX = Symbol('max'),
|
|
104
|
+
OUTLIERS = Symbol('outliers'),
|
|
105
|
+
SORT_REF = Symbol('sortRef');
|
|
106
|
+
|
|
107
|
+
const facets = $derived({
|
|
108
|
+
...(fx != null && { fx: FX }),
|
|
109
|
+
...(fy != null && { fy: FY })
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const sortProps = { [IS_SORTED]: true };
|
|
113
|
+
|
|
114
|
+
const compareValues = (a: RawValue, b: RawValue) =>
|
|
115
|
+
(typeof a === 'string' && typeof b === 'string'
|
|
116
|
+
? a.localeCompare(b)
|
|
117
|
+
: a > b
|
|
118
|
+
? 1
|
|
119
|
+
: a < b
|
|
120
|
+
? -1
|
|
121
|
+
: 0) || 0;
|
|
122
|
+
|
|
123
|
+
const boxData = $derived.by(() => {
|
|
124
|
+
const boxes = grouped
|
|
125
|
+
.map((row) => {
|
|
126
|
+
const medianKey = groupChannels[xProp];
|
|
127
|
+
const p25Key = groupChannels[x1Prop];
|
|
128
|
+
const p75Key = groupChannels[x2Prop];
|
|
129
|
+
const groupKey = groupChannels[yProp];
|
|
130
|
+
|
|
131
|
+
const iqr = row[p75Key] - row[p25Key];
|
|
132
|
+
const whisker = iqr * 1.5;
|
|
133
|
+
const lower = row[p25Key] - whisker;
|
|
134
|
+
const upper = row[p75Key] + whisker;
|
|
135
|
+
const data = row[groupChannels.fill].map((d) => ({
|
|
136
|
+
...d,
|
|
137
|
+
[orientation === 'y' ? Y : X]: resolveChannel(xProp, d, {
|
|
138
|
+
x,
|
|
139
|
+
y
|
|
140
|
+
})
|
|
141
|
+
}));
|
|
142
|
+
const valueSym = orientation === 'y' ? Y : X;
|
|
143
|
+
const groupSym = orientation === 'y' ? X : Y;
|
|
144
|
+
const outliers = data.filter((d) => d[valueSym] < lower || d[valueSym] > upper);
|
|
145
|
+
const inside = data
|
|
146
|
+
.filter((d) => d[valueSym] >= lower && d[valueSym] <= upper)
|
|
147
|
+
.sort((a, b) => a[valueSym] - b[valueSym]);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
...data[0],
|
|
151
|
+
[SORT_REF]: row[groupChannels.fill]?.[0],
|
|
152
|
+
[groupSym]: row[groupKey],
|
|
153
|
+
[P25]: row[p25Key],
|
|
154
|
+
[MEDIAN]: row[medianKey],
|
|
155
|
+
[P75]: row[p75Key],
|
|
156
|
+
[MIN]: inside.length ? inside[0][valueSym] : null,
|
|
157
|
+
[MAX]: inside.length ? inside.at(-1)[valueSym] : null,
|
|
158
|
+
[FX]: resolveChannel('fx', data[0], { fx }, null),
|
|
159
|
+
[FY]: resolveChannel('fy', data[0], { fy }, null),
|
|
160
|
+
[OUTLIERS]: outliers
|
|
161
|
+
};
|
|
162
|
+
})
|
|
163
|
+
.filter(Boolean);
|
|
164
|
+
|
|
165
|
+
const stripSortRef = ({ [SORT_REF]: _, ...rest }) => rest;
|
|
166
|
+
|
|
167
|
+
if (!sort) return boxes.map(stripSortRef);
|
|
168
|
+
|
|
169
|
+
const [sort_, direction] = maybeSort(sort);
|
|
170
|
+
|
|
171
|
+
const sortAccessor =
|
|
172
|
+
typeof sort === 'function'
|
|
173
|
+
? (d) => sort(d[SORT_REF])
|
|
174
|
+
: (d) => {
|
|
175
|
+
switch (sort_) {
|
|
176
|
+
case 'min':
|
|
177
|
+
return d[MIN];
|
|
178
|
+
case 'max':
|
|
179
|
+
return d[MAX];
|
|
180
|
+
case 'p25':
|
|
181
|
+
return d[P25];
|
|
182
|
+
case 'p75':
|
|
183
|
+
return d[P75];
|
|
184
|
+
case 'median':
|
|
185
|
+
default:
|
|
186
|
+
return d[MEDIAN];
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return boxes
|
|
191
|
+
.toSorted(
|
|
192
|
+
(a, b) =>
|
|
193
|
+
compareValues(sortAccessor(a), sortAccessor(b)) *
|
|
194
|
+
direction *
|
|
195
|
+
(orientation === 'x' ? -1 : 1)
|
|
196
|
+
)
|
|
197
|
+
.map(stripSortRef);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
function maybeSort(
|
|
201
|
+
sort: string | ((d: Datum) => RawValue) | undefined
|
|
202
|
+
): [string | ((d: Datum) => RawValue), 1 | -1] {
|
|
203
|
+
if (typeof sort !== 'string') return [sort, 1];
|
|
204
|
+
if (sort.startsWith('-')) {
|
|
205
|
+
return [sort.slice(1), -1];
|
|
206
|
+
}
|
|
207
|
+
return [sort, 1];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const valueSymbol = $derived(orientation === 'y' ? Y : X);
|
|
211
|
+
const groupSymbol = $derived(orientation === 'y' ? X : Y);
|
|
212
|
+
const length = $derived(className ? 2 : grouped.length);
|
|
213
|
+
const baseClass = $derived(`box-${orientation} ${className || ''}`);
|
|
214
|
+
</script>
|
|
215
|
+
|
|
216
|
+
<GroupMultiple class={baseClass} {length}>
|
|
217
|
+
<RuleMark
|
|
218
|
+
data={boxData}
|
|
219
|
+
{...{ [yProp]: groupSymbol, [x1Prop]: MIN, [x2Prop]: P25 }}
|
|
220
|
+
{stroke}
|
|
221
|
+
{...rule || {}}
|
|
222
|
+
{...facets}
|
|
223
|
+
{...sortProps} />
|
|
224
|
+
<RuleMark
|
|
225
|
+
data={boxData}
|
|
226
|
+
{...{ [yProp]: groupSymbol, [x1Prop]: P75, [x2Prop]: MAX }}
|
|
227
|
+
{stroke}
|
|
228
|
+
{...rule || {}}
|
|
229
|
+
{...facets} />
|
|
230
|
+
<BarMark
|
|
231
|
+
data={boxData}
|
|
232
|
+
{...{ [yProp]: groupSymbol, [x1Prop]: P25, [x2Prop]: P75 }}
|
|
233
|
+
{fill}
|
|
234
|
+
{stroke}
|
|
235
|
+
{...facets}
|
|
236
|
+
{...bar || {}} />
|
|
237
|
+
{#if tickMedian}
|
|
238
|
+
<TickMark
|
|
239
|
+
data={boxData}
|
|
240
|
+
{...{ [yProp]: groupSymbol, [xProp]: MEDIAN }}
|
|
241
|
+
{...facets}
|
|
242
|
+
{stroke}
|
|
243
|
+
strokeWidth={2}
|
|
244
|
+
{...typeof tickMedian === 'object' ? tickMedian : {}} />
|
|
245
|
+
{/if}
|
|
246
|
+
{#if tickMinMax}
|
|
247
|
+
<TickMark
|
|
248
|
+
data={boxData}
|
|
249
|
+
{...{ [yProp]: groupSymbol, [xProp]: MIN }}
|
|
250
|
+
{stroke}
|
|
251
|
+
{...facets}
|
|
252
|
+
inset="20%"
|
|
253
|
+
{...typeof tickMinMax === 'object' ? tickMinMax : {}} />
|
|
254
|
+
<TickMark
|
|
255
|
+
data={boxData}
|
|
256
|
+
{...{ [yProp]: groupSymbol, [xProp]: MAX }}
|
|
257
|
+
{stroke}
|
|
258
|
+
{...facets}
|
|
259
|
+
inset="20%"
|
|
260
|
+
{...typeof tickMinMax === 'object' ? tickMinMax : {}} />
|
|
261
|
+
{/if}
|
|
262
|
+
<Dot
|
|
263
|
+
data={boxData.map((d) => d[OUTLIERS]).flat()}
|
|
264
|
+
{x}
|
|
265
|
+
{y}
|
|
266
|
+
{fx}
|
|
267
|
+
{fy}
|
|
268
|
+
{fill}
|
|
269
|
+
{stroke}
|
|
270
|
+
{...dot || {}} />
|
|
271
|
+
</GroupMultiple>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ChannelAccessor, DataRecord, RawValue } from '../../types';
|
|
2
|
+
declare function $$render<Datum extends DataRecord>(): {
|
|
3
|
+
props: Pick<BaseMarkProps<Datum>, "fill" | "stroke" | "fx" | "fy" | "class"> & {
|
|
4
|
+
data: Datum[];
|
|
5
|
+
x: ChannelAccessor;
|
|
6
|
+
y: ChannelAccessor;
|
|
7
|
+
/**
|
|
8
|
+
* Custom sort order for grouped box plot data
|
|
9
|
+
*/
|
|
10
|
+
sort?: "min" | "max" | "median" | "p25" | "p75" | ((d: Datum) => RawValue);
|
|
11
|
+
/**
|
|
12
|
+
* Options for the rule marks that represent the min/max range
|
|
13
|
+
*/
|
|
14
|
+
rule: Record<string, ChannelAccessor<Datum>>;
|
|
15
|
+
/**
|
|
16
|
+
* Options for the bar marks that represent the IQR range
|
|
17
|
+
*/
|
|
18
|
+
bar: Record<string, ChannelAccessor<Datum>>;
|
|
19
|
+
/**
|
|
20
|
+
* Options for the tick marks that represent the median
|
|
21
|
+
*/
|
|
22
|
+
tickMedian: Record<string, ChannelAccessor<Datum>> | boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Options for the tick marks that represent the min/max range
|
|
25
|
+
*/
|
|
26
|
+
tickMinMax: Record<string, ChannelAccessor<Datum>> | boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Options for the dot marks that represent the outliers
|
|
29
|
+
*/
|
|
30
|
+
dot: Record<string, ChannelAccessor<Datum>>;
|
|
31
|
+
orientation: "x" | "y";
|
|
32
|
+
};
|
|
33
|
+
exports: {};
|
|
34
|
+
bindings: "";
|
|
35
|
+
slots: {};
|
|
36
|
+
events: {};
|
|
37
|
+
};
|
|
38
|
+
declare class __sveltets_Render<Datum extends DataRecord> {
|
|
39
|
+
props(): ReturnType<typeof $$render<Datum>>['props'];
|
|
40
|
+
events(): ReturnType<typeof $$render<Datum>>['events'];
|
|
41
|
+
slots(): ReturnType<typeof $$render<Datum>>['slots'];
|
|
42
|
+
bindings(): "";
|
|
43
|
+
exports(): {};
|
|
44
|
+
}
|
|
45
|
+
interface $$IsomorphicComponent {
|
|
46
|
+
new <Datum extends DataRecord>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Datum>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Datum>['props']>, ReturnType<__sveltets_Render<Datum>['events']>, ReturnType<__sveltets_Render<Datum>['slots']>> & {
|
|
47
|
+
$$bindings?: ReturnType<__sveltets_Render<Datum>['bindings']>;
|
|
48
|
+
} & ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
49
|
+
<Datum extends DataRecord>(internal: unknown, props: ReturnType<__sveltets_Render<Datum>['props']> & {}): ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
50
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
51
|
+
}
|
|
52
|
+
/** Internal shared box plot implementation for BoxX and BoxY */
|
|
53
|
+
declare const Box: $$IsomorphicComponent;
|
|
54
|
+
type Box<Datum extends DataRecord> = InstanceType<typeof Box<Datum>>;
|
|
55
|
+
export default Box;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getContext } from 'svelte';
|
|
3
|
-
import type { PlotContext } from '../../types/plot';
|
|
4
2
|
import { devicePixelRatio } from 'svelte/reactivity/window';
|
|
5
3
|
import { MediaQuery } from 'svelte/reactivity';
|
|
6
4
|
import type { Attachment } from 'svelte/attachments';
|
|
5
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
7
6
|
|
|
8
7
|
const darkMode = new MediaQuery('prefers-color-scheme: dark');
|
|
9
8
|
let colorScheme = $state();
|
|
@@ -26,8 +25,7 @@
|
|
|
26
25
|
|
|
27
26
|
let restProps: {} = $props();
|
|
28
27
|
|
|
29
|
-
const
|
|
30
|
-
const plot = $derived(getPlotState());
|
|
28
|
+
const plot = usePlot();
|
|
31
29
|
</script>
|
|
32
30
|
|
|
33
31
|
<!--
|
|
@@ -3,20 +3,18 @@
|
|
|
3
3
|
PlotState,
|
|
4
4
|
Mark,
|
|
5
5
|
BaseMarkProps,
|
|
6
|
-
ScaledDataRecord
|
|
7
|
-
PlotContext
|
|
6
|
+
ScaledDataRecord
|
|
8
7
|
} from '../../types/index.js';
|
|
9
8
|
import { resolveProp } from '../../helpers/resolve.js';
|
|
10
9
|
import { maybeSymbol } from '../../helpers/symbols.js';
|
|
11
10
|
import { symbol as d3Symbol } from 'd3-shape';
|
|
12
11
|
import type { Attachment } from 'svelte/attachments';
|
|
13
12
|
import CanvasLayer from './CanvasLayer.svelte';
|
|
14
|
-
import { getContext } from 'svelte';
|
|
15
13
|
import { devicePixelRatio } from 'svelte/reactivity/window';
|
|
16
14
|
import { resolveColor } from './canvas.js';
|
|
15
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
17
16
|
|
|
18
|
-
const
|
|
19
|
-
const plot = $derived(getPlotState());
|
|
17
|
+
const plot = usePlot();
|
|
20
18
|
|
|
21
19
|
let {
|
|
22
20
|
mark,
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
import type {
|
|
3
3
|
Mark,
|
|
4
4
|
BaseMarkProps,
|
|
5
|
-
PlotContext,
|
|
6
5
|
ScaledDataRecord,
|
|
7
6
|
UsedScales
|
|
8
7
|
} from '../../types/index.js';
|
|
9
8
|
import { CSS_VAR } from '../../constants.js';
|
|
10
9
|
import { resolveProp, resolveScaledStyleProps } from '../../helpers/resolve.js';
|
|
11
|
-
import { getContext } from 'svelte';
|
|
12
10
|
import { type GeoPath } from 'd3-geo';
|
|
13
11
|
import CanvasLayer from './CanvasLayer.svelte';
|
|
14
12
|
import type { Attachment } from 'svelte/attachments';
|
|
15
13
|
import { devicePixelRatio } from 'svelte/reactivity/window';
|
|
16
14
|
import { GEOJSON_PREFER_STROKE } from '../../helpers/index.js';
|
|
15
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
17
16
|
|
|
18
17
|
let {
|
|
19
18
|
mark,
|
|
@@ -27,8 +26,7 @@
|
|
|
27
26
|
usedScales: UsedScales;
|
|
28
27
|
} = $props();
|
|
29
28
|
|
|
30
|
-
const
|
|
31
|
-
const plot = $derived(getPlotState());
|
|
29
|
+
const plot = usePlot();
|
|
32
30
|
|
|
33
31
|
function maybeOpacity(value) {
|
|
34
32
|
return value == null ? 1 : +value;
|
|
@@ -2,17 +2,16 @@
|
|
|
2
2
|
import type {
|
|
3
3
|
Mark,
|
|
4
4
|
BaseMarkProps,
|
|
5
|
-
PlotContext,
|
|
6
5
|
ScaledDataRecord,
|
|
7
6
|
UsedScales
|
|
8
7
|
} from '../../types/index.js';
|
|
9
8
|
import { resolveProp, resolveScaledStyleProps } from '../../helpers/resolve.js';
|
|
10
|
-
import { getContext } from 'svelte';
|
|
11
9
|
import { type Line } from 'd3-shape';
|
|
12
10
|
import CanvasLayer from './CanvasLayer.svelte';
|
|
13
11
|
import type { Attachment } from 'svelte/attachments';
|
|
14
12
|
import { devicePixelRatio } from 'svelte/reactivity/window';
|
|
15
13
|
import { resolveColor } from './canvas.js';
|
|
14
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
16
15
|
|
|
17
16
|
let {
|
|
18
17
|
mark,
|
|
@@ -27,8 +26,7 @@
|
|
|
27
26
|
groupByKey?: unknown;
|
|
28
27
|
} = $props();
|
|
29
28
|
|
|
30
|
-
const
|
|
31
|
-
const plot = $derived(getPlotState());
|
|
29
|
+
const plot = usePlot();
|
|
32
30
|
|
|
33
31
|
function maybeOpacity(value: unknown) {
|
|
34
32
|
return value == null ? 1 : +value;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import type { RawValue } from '../../index.js';
|
|
3
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
id,
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
stops: { x: RawValue; color: string }[];
|
|
11
11
|
} = $props();
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
const plot = $derived(getPlotState());
|
|
13
|
+
const plot = usePlot();
|
|
15
14
|
|
|
16
15
|
const projectedStops = $derived(
|
|
17
16
|
stops
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import type { RawValue } from '../../index.js';
|
|
3
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
id,
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
stops: { y: RawValue; color: string }[];
|
|
11
11
|
} = $props();
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
const plot = $derived(getPlotState());
|
|
13
|
+
const plot = usePlot();
|
|
15
14
|
|
|
16
15
|
const projectedStops = $derived(
|
|
17
16
|
stops
|
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
ConstantAccessor,
|
|
12
12
|
DataRecord,
|
|
13
13
|
Mark,
|
|
14
|
-
PlotContext,
|
|
15
14
|
PlotScales
|
|
16
15
|
} from '../../types/index.js';
|
|
17
16
|
import { addEventHandlers } from './events.js';
|
|
18
|
-
import {
|
|
17
|
+
import { usePlot } from '../../hooks/usePlot.svelte.js';
|
|
19
18
|
|
|
20
19
|
type MarkerPathProps = BaseMarkProps<Datum> & {
|
|
21
20
|
/**
|
|
@@ -78,7 +77,7 @@
|
|
|
78
77
|
|
|
79
78
|
const id = randomId();
|
|
80
79
|
|
|
81
|
-
const
|
|
80
|
+
const plot = usePlot();
|
|
82
81
|
|
|
83
82
|
const points = $derived(text && d != null ? d.split(/[LMC]/).slice(1) : []);
|
|
84
83
|
const hasPath = $derived(points.length > 0);
|
|
@@ -96,7 +95,7 @@
|
|
|
96
95
|
class={className}
|
|
97
96
|
stroke-width={strokeWidth_}
|
|
98
97
|
{@attach addEventHandlers({
|
|
99
|
-
|
|
98
|
+
plot,
|
|
100
99
|
options: mark.options,
|
|
101
100
|
datum: datum
|
|
102
101
|
})}>
|
|
@@ -127,7 +126,7 @@
|
|
|
127
126
|
{d}
|
|
128
127
|
{style}
|
|
129
128
|
{@attach addEventHandlers({
|
|
130
|
-
|
|
129
|
+
plot,
|
|
131
130
|
options: mark.options,
|
|
132
131
|
datum: datum
|
|
133
132
|
})} />
|