svelteplot 0.6.0-pr-266.0 → 0.7.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/dist/Mark.svelte +7 -0
- package/dist/Mark.svelte.d.ts +4 -5
- package/dist/Plot.svelte +10 -2
- package/dist/constants.d.ts +1 -1
- package/dist/core/FacetAxes.svelte +2 -2
- package/dist/core/Plot.svelte +7 -11
- package/dist/helpers/colors.d.ts +12 -9
- package/dist/helpers/facets.d.ts +1 -1
- package/dist/helpers/getBaseStyles.d.ts +6 -2
- package/dist/helpers/getBaseStyles.js +8 -0
- package/dist/helpers/index.d.ts +3 -3
- package/dist/helpers/reduce.d.ts +1 -1
- package/dist/helpers/removeIdenticalLines.js +3 -2
- package/dist/helpers/scales.d.ts +7 -7
- package/dist/helpers/scales.js +2 -2
- 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/helpers/wordwrap.d.ts +14 -0
- package/dist/helpers/wordwrap.js +129 -0
- package/dist/marks/Area.svelte.d.ts +4 -5
- package/dist/marks/AreaX.svelte.d.ts +5 -6
- package/dist/marks/Arrow.svelte.d.ts +4 -5
- package/dist/marks/AxisX.svelte +2 -1
- package/dist/marks/AxisX.svelte.d.ts +6 -6
- package/dist/marks/AxisY.svelte.d.ts +5 -6
- package/dist/marks/BarX.svelte.d.ts +4 -5
- package/dist/marks/BarY.svelte.d.ts +4 -5
- package/dist/marks/BollingerX.svelte.d.ts +76 -2
- package/dist/marks/BollingerY.svelte.d.ts +76 -2
- package/dist/marks/BoxY.svelte.d.ts +68 -6
- package/dist/marks/Cell.svelte.d.ts +4 -5
- package/dist/marks/CustomMark.svelte.d.ts +84 -2
- package/dist/marks/CustomMarkHTML.svelte.d.ts +1 -1
- package/dist/marks/DifferenceY.svelte.d.ts +69 -7
- package/dist/marks/Dot.svelte.d.ts +4 -5
- package/dist/marks/DotX.svelte.d.ts +5 -6
- package/dist/marks/DotY.svelte.d.ts +5 -6
- package/dist/marks/Geo.svelte.d.ts +4 -5
- package/dist/marks/GridX.svelte.d.ts +4 -5
- package/dist/marks/GridY.svelte.d.ts +4 -5
- package/dist/marks/Image.svelte.d.ts +75 -2
- package/dist/marks/Line.svelte.d.ts +5 -6
- package/dist/marks/LineX.svelte.d.ts +6 -7
- package/dist/marks/LineY.svelte.d.ts +6 -7
- package/dist/marks/Link.svelte.d.ts +4 -5
- package/dist/marks/Rect.svelte.d.ts +4 -5
- package/dist/marks/RuleX.svelte.d.ts +4 -5
- package/dist/marks/RuleY.svelte.d.ts +4 -5
- package/dist/marks/Spike.svelte.d.ts +5 -6
- package/dist/marks/Text.svelte.d.ts +5 -6
- package/dist/marks/TickX.svelte.d.ts +4 -5
- package/dist/marks/TickY.svelte.d.ts +4 -5
- package/dist/marks/Vector.svelte.d.ts +4 -5
- package/dist/marks/WaffleX.svelte +115 -0
- package/dist/marks/WaffleX.svelte.d.ts +102 -0
- package/dist/marks/WaffleY.svelte +119 -0
- package/dist/marks/WaffleY.svelte.d.ts +100 -0
- package/dist/marks/helpers/Anchor.svelte.d.ts +5 -5
- package/dist/marks/helpers/BaseAxisX.svelte +31 -3
- package/dist/marks/helpers/BaseAxisX.svelte.d.ts +2 -0
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +164 -2
- package/dist/marks/helpers/RectPath.svelte.d.ts +65 -3
- package/dist/marks/helpers/waffle.d.ts +58 -0
- package/dist/marks/helpers/waffle.js +194 -0
- package/dist/marks/index.d.ts +3 -1
- package/dist/marks/index.js +3 -1
- package/dist/transforms/bollinger.d.ts +69 -1
- package/dist/transforms/centroid.d.ts +4 -1
- package/dist/transforms/group.d.ts +12 -4
- package/dist/transforms/group.js +11 -5
- package/dist/transforms/interval.d.ts +128 -2
- package/dist/transforms/recordize.d.ts +7 -4
- package/dist/transforms/select.d.ts +448 -7
- package/dist/transforms/sort.d.ts +253 -5
- package/dist/transforms/stack.d.ts +23 -3
- package/dist/transforms/window.d.ts +134 -2
- package/dist/types/data.d.ts +1 -0
- package/dist/types/mark.d.ts +1 -1
- package/dist/types/plot.d.ts +19 -5
- package/dist/types/scale.d.ts +8 -0
- package/package.json +128 -129
|
@@ -4,7 +4,6 @@ export type ShapeRenderer = {
|
|
|
4
4
|
};
|
|
5
5
|
import type { DataRecord, ChannelAccessor } from '../types/index.js';
|
|
6
6
|
import { type Snippet } from 'svelte';
|
|
7
|
-
import { sort } from '../index.js';
|
|
8
7
|
declare class __sveltets_Render<Datum extends DataRecord> {
|
|
9
8
|
props(): Partial<{
|
|
10
9
|
filter: import("../types/index.js").ConstantAccessor<boolean, Datum>;
|
|
@@ -13,14 +12,14 @@ declare class __sveltets_Render<Datum extends DataRecord> {
|
|
|
13
12
|
fy: ChannelAccessor<Datum>;
|
|
14
13
|
dx: import("../types/index.js").ConstantAccessor<number, Datum>;
|
|
15
14
|
dy: import("../types/index.js").ConstantAccessor<number, Datum>;
|
|
16
|
-
dodgeX:
|
|
17
|
-
dodgeY:
|
|
15
|
+
dodgeX: import("../transforms/dodge.js").DodgeXOptions;
|
|
16
|
+
dodgeY: import("../transforms/dodge.js").DodgeYOptions;
|
|
18
17
|
fill: ChannelAccessor<Datum>;
|
|
19
18
|
fillOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
|
|
20
|
-
sort: {
|
|
19
|
+
sort: ((a: import("../types/data.js").RawValue, b: import("../types/data.js").RawValue) => number) | {
|
|
21
20
|
channel: string;
|
|
22
21
|
order?: "ascending" | "descending";
|
|
23
|
-
} |
|
|
22
|
+
} | import("../types/index.js").ConstantAccessor<import("../types/data.js").RawValue, Datum>;
|
|
24
23
|
stroke: ChannelAccessor<Datum>;
|
|
25
24
|
strokeWidth: import("../types/index.js").ConstantAccessor<number, Datum>;
|
|
26
25
|
strokeOpacity: import("../types/index.js").ConstantAccessor<number, Datum>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
The waffleX mark lets you create waffle charts by filling a rectangular area with small squares representing data values.
|
|
4
|
+
-->
|
|
5
|
+
<script lang="ts" generics="Datum extends DataRecord">
|
|
6
|
+
import type {
|
|
7
|
+
DataRecord,
|
|
8
|
+
BaseMarkProps,
|
|
9
|
+
ChannelAccessor,
|
|
10
|
+
LinkableMarkProps,
|
|
11
|
+
BorderRadius
|
|
12
|
+
} from '../types';
|
|
13
|
+
import { wafflePolygon, type WaffleOptions } from './helpers/waffle';
|
|
14
|
+
import { getPlotDefaults } from '../hooks/plotDefaults';
|
|
15
|
+
import { intervalX, recordizeX, sort, stackX } from '../transforms';
|
|
16
|
+
import type { StackOptions } from '../transforms/stack';
|
|
17
|
+
import Mark from '../Mark.svelte';
|
|
18
|
+
import { getContext } from 'svelte';
|
|
19
|
+
import { resolveProp, resolveStyles } from '../helpers/resolve';
|
|
20
|
+
import { roundedRect } from '../helpers/roundedRect';
|
|
21
|
+
|
|
22
|
+
interface WaffleXMarkProps
|
|
23
|
+
extends BaseMarkProps<Datum>,
|
|
24
|
+
LinkableMarkProps<Datum>,
|
|
25
|
+
WaffleOptions<Datum> {
|
|
26
|
+
data?: Datum[];
|
|
27
|
+
/**
|
|
28
|
+
* bound to a quantitative scale
|
|
29
|
+
*/
|
|
30
|
+
x?: ChannelAccessor<Datum>;
|
|
31
|
+
/**
|
|
32
|
+
* bound to a quantitative scale
|
|
33
|
+
*/
|
|
34
|
+
x1?: ChannelAccessor<Datum>;
|
|
35
|
+
/**
|
|
36
|
+
* bound to a quantitative scale
|
|
37
|
+
*/
|
|
38
|
+
x2?: ChannelAccessor<Datum>;
|
|
39
|
+
/**
|
|
40
|
+
* bound to a band scale
|
|
41
|
+
*/
|
|
42
|
+
y?: ChannelAccessor<Datum>;
|
|
43
|
+
stack?: StackOptions;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const DEFAULTS = {
|
|
47
|
+
fill: 'currentColor',
|
|
48
|
+
...getPlotDefaults().waffle,
|
|
49
|
+
...getPlotDefaults().waffleX
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
let markProps: WaffleXMarkProps = $props();
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
data = [{} as Datum],
|
|
56
|
+
class: className = null,
|
|
57
|
+
stack,
|
|
58
|
+
symbol = null,
|
|
59
|
+
unit,
|
|
60
|
+
...options
|
|
61
|
+
}: WaffleXMarkProps = $derived({ ...DEFAULTS, ...markProps });
|
|
62
|
+
|
|
63
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
64
|
+
const plot = $derived(getPlotState());
|
|
65
|
+
|
|
66
|
+
const args = $derived(
|
|
67
|
+
stackX(
|
|
68
|
+
intervalX(
|
|
69
|
+
// by default, sort by y channel (the ordinal labels)
|
|
70
|
+
sort(recordizeX({ data, ...options })),
|
|
71
|
+
{ plot }
|
|
72
|
+
),
|
|
73
|
+
stack
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<Mark
|
|
79
|
+
type="waffleX"
|
|
80
|
+
requiredScales={{ y: ['band'] }}
|
|
81
|
+
channels={['x1', 'x2', 'y', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
|
|
82
|
+
{...args}>
|
|
83
|
+
{#snippet children({ mark, usedScales, scaledData })}
|
|
84
|
+
{@const wafflePoly = wafflePolygon('x', args, plot.scales)}
|
|
85
|
+
{#each scaledData as d, i (i)}
|
|
86
|
+
{@const borderRadius = resolveProp(args.borderRadius, d?.datum, 0) as BorderRadius}
|
|
87
|
+
{@const hasBorderRadius =
|
|
88
|
+
(typeof borderRadius === 'number' && borderRadius > 0) ||
|
|
89
|
+
(typeof borderRadius === 'object' &&
|
|
90
|
+
Math.max(
|
|
91
|
+
borderRadius.topRight ?? 0,
|
|
92
|
+
borderRadius.bottomRight ?? 0,
|
|
93
|
+
borderRadius.topLeft ?? 0,
|
|
94
|
+
borderRadius.bottomLeft ?? 0
|
|
95
|
+
) > 0)}
|
|
96
|
+
{@const [style, styleClass] = resolveStyles(plot, d, options, 'fill', usedScales)}
|
|
97
|
+
{@const { pattern, rect, path } = wafflePoly(d)}
|
|
98
|
+
<g class={['waffle-x', className]}>
|
|
99
|
+
<pattern {...pattern}>
|
|
100
|
+
{#if symbol}
|
|
101
|
+
{@render symbol(rect)}
|
|
102
|
+
{:else if hasBorderRadius}
|
|
103
|
+
<path
|
|
104
|
+
d={roundedRect(rect.x, rect.y, rect.width, rect.height, borderRadius)}
|
|
105
|
+
{style}
|
|
106
|
+
class={styleClass} />
|
|
107
|
+
{:else}
|
|
108
|
+
<rect {style} class={styleClass} {...rect} />
|
|
109
|
+
{/if}
|
|
110
|
+
</pattern>
|
|
111
|
+
<path {...path} />
|
|
112
|
+
</g>
|
|
113
|
+
{/each}
|
|
114
|
+
{/snippet}
|
|
115
|
+
</Mark>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { DataRecord, ChannelAccessor, LinkableMarkProps } from '../types';
|
|
2
|
+
import { type WaffleOptions } from './helpers/waffle';
|
|
3
|
+
import type { StackOptions } from '../transforms/stack';
|
|
4
|
+
declare class __sveltets_Render<Datum extends DataRecord> {
|
|
5
|
+
props(): Partial<{
|
|
6
|
+
filter: import("../types").ConstantAccessor<boolean, Datum>;
|
|
7
|
+
facet: "auto" | "include" | "exclude";
|
|
8
|
+
fx: ChannelAccessor<Datum>;
|
|
9
|
+
fy: ChannelAccessor<Datum>;
|
|
10
|
+
dx: import("../types").ConstantAccessor<number, Datum>;
|
|
11
|
+
dy: import("../types").ConstantAccessor<number, Datum>;
|
|
12
|
+
dodgeX: import("../transforms/dodge").DodgeXOptions;
|
|
13
|
+
dodgeY: import("../transforms/dodge").DodgeYOptions;
|
|
14
|
+
fill: ChannelAccessor<Datum>;
|
|
15
|
+
fillOpacity: import("../types").ConstantAccessor<number, Datum>;
|
|
16
|
+
sort: ((a: import("../types").RawValue, b: import("../types").RawValue) => number) | {
|
|
17
|
+
channel: string;
|
|
18
|
+
order?: "ascending" | "descending";
|
|
19
|
+
} | import("../types").ConstantAccessor<import("../types").RawValue, Datum>;
|
|
20
|
+
stroke: ChannelAccessor<Datum>;
|
|
21
|
+
strokeWidth: import("../types").ConstantAccessor<number, Datum>;
|
|
22
|
+
strokeOpacity: import("../types").ConstantAccessor<number, Datum>;
|
|
23
|
+
strokeLinejoin: import("../types").ConstantAccessor<import("csstype").Property.StrokeLinejoin, Datum>;
|
|
24
|
+
strokeLinecap: import("../types").ConstantAccessor<import("csstype").Property.StrokeLinecap, Datum>;
|
|
25
|
+
strokeMiterlimit: import("../types").ConstantAccessor<number, Datum>;
|
|
26
|
+
opacity: ChannelAccessor<Datum>;
|
|
27
|
+
strokeDasharray: import("../types").ConstantAccessor<string, Datum>;
|
|
28
|
+
strokeDashoffset: import("../types").ConstantAccessor<number, Datum>;
|
|
29
|
+
mixBlendMode: import("../types").ConstantAccessor<import("csstype").Property.MixBlendMode, Datum>;
|
|
30
|
+
clipPath: string;
|
|
31
|
+
imageFilter: import("../types").ConstantAccessor<string, Datum>;
|
|
32
|
+
shapeRendering: import("../types").ConstantAccessor<import("csstype").Property.ShapeRendering, Datum>;
|
|
33
|
+
paintOrder: import("../types").ConstantAccessor<string, Datum>;
|
|
34
|
+
onclick: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
35
|
+
ondblclick: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
36
|
+
onmouseup: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
37
|
+
onmousedown: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
38
|
+
onmouseenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
39
|
+
onmousemove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
40
|
+
onmouseleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
41
|
+
onmouseout: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
42
|
+
onmouseover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
43
|
+
onpointercancel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
44
|
+
onpointerdown: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
45
|
+
onpointerup: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
46
|
+
onpointerenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
47
|
+
onpointerleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
48
|
+
onpointermove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
49
|
+
onpointerover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
50
|
+
onpointerout: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
51
|
+
ondrag: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
52
|
+
ondrop: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
53
|
+
ondragstart: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
54
|
+
ondragenter: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
55
|
+
ondragleave: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
56
|
+
ondragover: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
57
|
+
ondragend: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
58
|
+
ontouchstart: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
59
|
+
ontouchmove: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
60
|
+
ontouchend: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
61
|
+
ontouchcancel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
62
|
+
oncontextmenu: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
63
|
+
onwheel: import("svelte/elements").MouseEventHandler<SVGPathElement>;
|
|
64
|
+
class: string;
|
|
65
|
+
style: string;
|
|
66
|
+
cursor: import("../types").ConstantAccessor<import("csstype").Property.Cursor, Datum>;
|
|
67
|
+
}> & LinkableMarkProps<Datum> & WaffleOptions<Datum> & {
|
|
68
|
+
data?: Datum[] | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* bound to a quantitative scale
|
|
71
|
+
*/
|
|
72
|
+
x?: ChannelAccessor<Datum>;
|
|
73
|
+
/**
|
|
74
|
+
* bound to a quantitative scale
|
|
75
|
+
*/
|
|
76
|
+
x1?: ChannelAccessor<Datum>;
|
|
77
|
+
/**
|
|
78
|
+
* bound to a quantitative scale
|
|
79
|
+
*/
|
|
80
|
+
x2?: ChannelAccessor<Datum>;
|
|
81
|
+
/**
|
|
82
|
+
* bound to a band scale
|
|
83
|
+
*/
|
|
84
|
+
y?: ChannelAccessor<Datum>;
|
|
85
|
+
stack?: StackOptions;
|
|
86
|
+
};
|
|
87
|
+
events(): {};
|
|
88
|
+
slots(): {};
|
|
89
|
+
bindings(): "";
|
|
90
|
+
exports(): {};
|
|
91
|
+
}
|
|
92
|
+
interface $$IsomorphicComponent {
|
|
93
|
+
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']>> & {
|
|
94
|
+
$$bindings?: ReturnType<__sveltets_Render<Datum>['bindings']>;
|
|
95
|
+
} & ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
96
|
+
<Datum extends DataRecord>(internal: unknown, props: ReturnType<__sveltets_Render<Datum>['props']> & {}): ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
97
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
98
|
+
}
|
|
99
|
+
/** The waffleX mark lets you create waffle charts by filling a rectangular area with small squares representing data values. */
|
|
100
|
+
declare const WaffleX: $$IsomorphicComponent;
|
|
101
|
+
type WaffleX<Datum extends DataRecord> = InstanceType<typeof WaffleX<Datum>>;
|
|
102
|
+
export default WaffleX;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
The waffleX mark lets you create waffle charts by filling a rectangular area with small squares representing data values.
|
|
4
|
+
-->
|
|
5
|
+
<script lang="ts" generics="Datum extends DataRecord">
|
|
6
|
+
import type {
|
|
7
|
+
DataRecord,
|
|
8
|
+
ChannelAccessor,
|
|
9
|
+
BaseMarkProps,
|
|
10
|
+
LinkableMarkProps,
|
|
11
|
+
PlotContext,
|
|
12
|
+
BorderRadius
|
|
13
|
+
} from '../types';
|
|
14
|
+
import { wafflePolygon, type WaffleOptions } from './helpers/waffle';
|
|
15
|
+
import { getPlotDefaults } from '../hooks/plotDefaults';
|
|
16
|
+
import { getContext } from 'svelte';
|
|
17
|
+
import { intervalY, recordizeY, sort, stackY } from '../transforms';
|
|
18
|
+
import Mark from '../Mark.svelte';
|
|
19
|
+
import { resolveProp, resolveStyles } from '../helpers/resolve';
|
|
20
|
+
import { roundedRect } from '../helpers/roundedRect';
|
|
21
|
+
import GroupMultiple from './helpers/GroupMultiple.svelte';
|
|
22
|
+
|
|
23
|
+
interface WaffleYMarkProps
|
|
24
|
+
extends BaseMarkProps<Datum>,
|
|
25
|
+
LinkableMarkProps<Datum>,
|
|
26
|
+
WaffleOptions<Datum> {
|
|
27
|
+
data?: Datum[];
|
|
28
|
+
/**
|
|
29
|
+
* bound to a babd scale
|
|
30
|
+
*/
|
|
31
|
+
x?: ChannelAccessor<Datum>;
|
|
32
|
+
/**
|
|
33
|
+
* bound to a quantitative scale
|
|
34
|
+
*/
|
|
35
|
+
y?: ChannelAccessor<Datum>;
|
|
36
|
+
/**
|
|
37
|
+
* bound to a quantitative scale
|
|
38
|
+
*/
|
|
39
|
+
y1?: ChannelAccessor<Datum>;
|
|
40
|
+
/**
|
|
41
|
+
* bound to a quantitative scale
|
|
42
|
+
*/
|
|
43
|
+
y2?: ChannelAccessor<Datum>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const DEFAULTS = {
|
|
47
|
+
...getPlotDefaults().waffle,
|
|
48
|
+
...getPlotDefaults().waffleY
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
let markProps: WaffleYMarkProps = $props();
|
|
52
|
+
|
|
53
|
+
const {
|
|
54
|
+
data = [{} as Datum],
|
|
55
|
+
class: className = null,
|
|
56
|
+
stack,
|
|
57
|
+
symbol = null,
|
|
58
|
+
...options
|
|
59
|
+
}: WaffleYMarkProps = $derived({ ...DEFAULTS, ...markProps });
|
|
60
|
+
|
|
61
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
62
|
+
const plot = $derived(getPlotState());
|
|
63
|
+
|
|
64
|
+
const args = $derived(
|
|
65
|
+
stackY(
|
|
66
|
+
intervalY(
|
|
67
|
+
// by default, sort by y channel (the ordinal labels)
|
|
68
|
+
sort(recordizeY({ data, ...options })),
|
|
69
|
+
{ plot }
|
|
70
|
+
),
|
|
71
|
+
stack
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<Mark
|
|
77
|
+
type="waffleY"
|
|
78
|
+
requiredScales={{ x: ['band'] }}
|
|
79
|
+
channels={['y1', 'y2', 'x', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
|
|
80
|
+
{...args}>
|
|
81
|
+
{#snippet children({ mark, usedScales, scaledData })}
|
|
82
|
+
{@const wafflePoly = wafflePolygon('y', args, plot.scales)}
|
|
83
|
+
{#each scaledData as d, i (i)}
|
|
84
|
+
{@const [style, styleClass] = resolveStyles(
|
|
85
|
+
plot,
|
|
86
|
+
d,
|
|
87
|
+
args,
|
|
88
|
+
args.stroke && !args.fill ? 'stroke' : 'fill',
|
|
89
|
+
usedScales
|
|
90
|
+
)}
|
|
91
|
+
{@const borderRadius = resolveProp(args.borderRadius, d?.datum, 0) as BorderRadius}
|
|
92
|
+
{@const hasBorderRadius =
|
|
93
|
+
(typeof borderRadius === 'number' && borderRadius > 0) ||
|
|
94
|
+
(typeof borderRadius === 'object' &&
|
|
95
|
+
Math.max(
|
|
96
|
+
borderRadius.topRight ?? 0,
|
|
97
|
+
borderRadius.bottomRight ?? 0,
|
|
98
|
+
borderRadius.topLeft ?? 0,
|
|
99
|
+
borderRadius.bottomLeft ?? 0
|
|
100
|
+
) > 0)}
|
|
101
|
+
{@const { pattern, rect, path } = wafflePoly(d)}
|
|
102
|
+
<g class={['waffle-y', className]}>
|
|
103
|
+
<pattern {...pattern}>
|
|
104
|
+
{#if symbol}
|
|
105
|
+
{@render symbol({ ...rect, style, styleClass, datum: d.datum })}
|
|
106
|
+
{:else if hasBorderRadius}
|
|
107
|
+
<path
|
|
108
|
+
d={roundedRect(rect.x, rect.y, rect.width, rect.height, borderRadius)}
|
|
109
|
+
{style}
|
|
110
|
+
class={styleClass} />
|
|
111
|
+
{:else}
|
|
112
|
+
<rect {style} class={styleClass} {...rect} />
|
|
113
|
+
{/if}
|
|
114
|
+
</pattern>
|
|
115
|
+
<path {...path} />
|
|
116
|
+
</g>
|
|
117
|
+
{/each}
|
|
118
|
+
{/snippet}
|
|
119
|
+
</Mark>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { DataRecord, ChannelAccessor, LinkableMarkProps } from '../types';
|
|
2
|
+
import { type WaffleOptions } from './helpers/waffle';
|
|
3
|
+
declare class __sveltets_Render<Datum extends DataRecord> {
|
|
4
|
+
props(): Partial<{
|
|
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[] | undefined;
|
|
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
|
+
};
|
|
85
|
+
events(): {};
|
|
86
|
+
slots(): {};
|
|
87
|
+
bindings(): "";
|
|
88
|
+
exports(): {};
|
|
89
|
+
}
|
|
90
|
+
interface $$IsomorphicComponent {
|
|
91
|
+
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']>> & {
|
|
92
|
+
$$bindings?: ReturnType<__sveltets_Render<Datum>['bindings']>;
|
|
93
|
+
} & ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
94
|
+
<Datum extends DataRecord>(internal: unknown, props: ReturnType<__sveltets_Render<Datum>['props']> & {}): ReturnType<__sveltets_Render<Datum>['exports']>;
|
|
95
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
96
|
+
}
|
|
97
|
+
/** The waffleX mark lets you create waffle charts by filling a rectangular area with small squares representing data values. */
|
|
98
|
+
declare const WaffleY: $$IsomorphicComponent;
|
|
99
|
+
type WaffleY<Datum extends DataRecord> = InstanceType<typeof WaffleY<Datum>>;
|
|
100
|
+
export default WaffleY;
|
|
@@ -4,11 +4,11 @@ declare class __sveltets_Render<Datum extends Record<string, any>> {
|
|
|
4
4
|
datum?: Datum | undefined;
|
|
5
5
|
options?: {
|
|
6
6
|
[key: string]: any;
|
|
7
|
-
href?: ConstantAccessor<string,
|
|
8
|
-
target?: ConstantAccessor<string,
|
|
9
|
-
rel?: ConstantAccessor<string,
|
|
10
|
-
type?: ConstantAccessor<string,
|
|
11
|
-
download?: ConstantAccessor<string,
|
|
7
|
+
href?: ConstantAccessor<string, Datum>;
|
|
8
|
+
target?: ConstantAccessor<string, Datum>;
|
|
9
|
+
rel?: ConstantAccessor<string, Datum>;
|
|
10
|
+
type?: ConstantAccessor<string, Datum>;
|
|
11
|
+
download?: ConstantAccessor<string, Datum>;
|
|
12
12
|
} | undefined;
|
|
13
13
|
children?: (() => any) | undefined;
|
|
14
14
|
};
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { randomId, testFilter } from '../../helpers/index.js';
|
|
18
18
|
import { INDEX } from '../../constants';
|
|
19
19
|
import { RAW_VALUE } from '../../transforms/recordize';
|
|
20
|
+
import wordwrap from '../../helpers/wordwrap';
|
|
20
21
|
|
|
21
22
|
type BaseAxisXProps = {
|
|
22
23
|
scaleFn: (d: RawValue) => number;
|
|
@@ -35,7 +36,9 @@
|
|
|
35
36
|
dx: ConstantAccessor<number>;
|
|
36
37
|
dy: ConstantAccessor<number>;
|
|
37
38
|
filter: ChannelAccessor;
|
|
39
|
+
wordwrap: boolean;
|
|
38
40
|
textAnchor: ConstantAccessor<'start' | 'middle' | 'end'> | 'auto';
|
|
41
|
+
removeDuplicateTicks: boolean;
|
|
39
42
|
};
|
|
40
43
|
text: boolean;
|
|
41
44
|
plot: PlotState;
|
|
@@ -59,8 +62,21 @@
|
|
|
59
62
|
text = true
|
|
60
63
|
}: BaseAxisXProps = $props();
|
|
61
64
|
|
|
65
|
+
const isBandScale = $derived(scaleType === 'band');
|
|
66
|
+
const bandWidth = $derived(isBandScale ? scaleFn.bandwidth() : 0);
|
|
67
|
+
|
|
62
68
|
function splitTick(tick: string | string[]) {
|
|
63
|
-
return Array.isArray(tick)
|
|
69
|
+
return Array.isArray(tick)
|
|
70
|
+
? tick
|
|
71
|
+
: typeof tick === 'string' && isBandScale && options.wordwrap !== false
|
|
72
|
+
? wordwrap(
|
|
73
|
+
tick,
|
|
74
|
+
{ maxLineWidth: bandWidth * 0.9 },
|
|
75
|
+
{ minCharactersPerLine: 4 },
|
|
76
|
+
+resolveProp(tickFontSize, {}, 11),
|
|
77
|
+
false
|
|
78
|
+
)
|
|
79
|
+
: [tick];
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
let tickRotate = $derived(plot.options.x.tickRotate || 0);
|
|
@@ -72,7 +88,7 @@
|
|
|
72
88
|
// generate id used for registering margins
|
|
73
89
|
const id = randomId();
|
|
74
90
|
|
|
75
|
-
const { autoMarginTop, autoMarginBottom } =
|
|
91
|
+
const { autoMarginTop, autoMarginBottom, autoMarginLeft, autoMarginRight } =
|
|
76
92
|
getContext<AutoMarginStores>('svelteplot/autoMargins');
|
|
77
93
|
|
|
78
94
|
let tickTextElements = $state([] as SVGTextElement[]);
|
|
@@ -109,6 +125,14 @@
|
|
|
109
125
|
return tickObjects as ScaledDataRecord[];
|
|
110
126
|
});
|
|
111
127
|
|
|
128
|
+
$effect(() => {
|
|
129
|
+
// just add some minimal horizontal margins for axis ticks
|
|
130
|
+
untrack(() => $autoMarginLeft);
|
|
131
|
+
untrack(() => $autoMarginRight);
|
|
132
|
+
$autoMarginLeft.set(id, 5);
|
|
133
|
+
$autoMarginRight.set(id, 10);
|
|
134
|
+
});
|
|
135
|
+
|
|
112
136
|
$effect(() => {
|
|
113
137
|
untrack(() => [$autoMarginTop, $autoMarginBottom]);
|
|
114
138
|
if (!text) return;
|
|
@@ -147,6 +171,8 @@
|
|
|
147
171
|
return () => {
|
|
148
172
|
if ($autoMarginBottom.has(id)) $autoMarginBottom.delete(id);
|
|
149
173
|
if ($autoMarginTop.has(id)) $autoMarginTop.delete(id);
|
|
174
|
+
if ($autoMarginLeft.has(id)) $autoMarginLeft.delete(id);
|
|
175
|
+
if ($autoMarginRight.has(id)) $autoMarginRight.delete(id);
|
|
150
176
|
};
|
|
151
177
|
});
|
|
152
178
|
</script>
|
|
@@ -222,7 +248,9 @@
|
|
|
222
248
|
{:else}
|
|
223
249
|
{#each textLines as line, i (i)}
|
|
224
250
|
<tspan x="0" dy={i ? 12 : 0}
|
|
225
|
-
>{!prevTextLines ||
|
|
251
|
+
>{!prevTextLines ||
|
|
252
|
+
prevTextLines[i] !== line ||
|
|
253
|
+
options.removeDuplicateTicks === false
|
|
226
254
|
? line
|
|
227
255
|
: ''}</tspan>
|
|
228
256
|
{/each}
|
|
@@ -16,7 +16,9 @@ type BaseAxisXProps = {
|
|
|
16
16
|
dx: ConstantAccessor<number>;
|
|
17
17
|
dy: ConstantAccessor<number>;
|
|
18
18
|
filter: ChannelAccessor;
|
|
19
|
+
wordwrap: boolean;
|
|
19
20
|
textAnchor: ConstantAccessor<'start' | 'middle' | 'end'> | 'auto';
|
|
21
|
+
removeDuplicateTicks: boolean;
|
|
20
22
|
};
|
|
21
23
|
text: boolean;
|
|
22
24
|
plot: PlotState;
|