Skip to content

Commit 165603a

Browse files
authored
Merge pull request #110 from svelteplot/feat/mark-defaults
feature: apply mark defaults
2 parents 72e14f1 + c934743 commit 165603a

File tree

121 files changed

+1262
-284
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+1262
-284
lines changed

pnpm-workspace.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
onlyBuiltDependencies:
2+
- puppeteer

screenshot-examples.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ const takeScreenshot = async (page, urlPath, outputPath, isDarkMode = false) =>
9494
const finalOutputPath = outputPath.replace('.png', `${themeSuffix}.png`);
9595

9696
// Wait for the Plot component to be rendered
97-
await page.waitForSelector('.content > figure.svelteplot', { timeout: 10000 });
97+
await page.waitForSelector('.content figure.svelteplot ', {
98+
timeout: 10000
99+
});
98100

99101
// Toggle dark mode if needed
100102
if (isDarkMode) {
@@ -112,7 +114,7 @@ const takeScreenshot = async (page, urlPath, outputPath, isDarkMode = false) =>
112114

113115
// Get the Plot SVG element
114116
const elementHandle = await page.evaluateHandle(() =>
115-
document.querySelector('.content > figure.svelteplot > .plot-body > svg')
117+
document.querySelector('.content .screenshot')
116118
);
117119

118120
// Take a screenshot of the element

src/lib/Plot.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<script lang="ts">
1313
import Plot from './core/Plot.svelte';
1414
15-
import type { PlotOptions } from './types.js';
15+
import type { PlotDefaults, PlotOptions } from './types.js';
1616
1717
// implicit marks
1818
import AxisX from './marks/AxisX.svelte';
@@ -28,6 +28,7 @@
2828
import { autoScale, autoScaleColor } from './helpers/autoScales.js';
2929
import { namedProjection } from './helpers/autoProjection.js';
3030
import { isObject } from './helpers/index.js';
31+
import { getContext } from 'svelte';
3132
3233
let {
3334
header: userHeader,

src/lib/core/Plot.svelte

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,17 @@
5151
const maxMarginBottom = $derived(Math.max(...$autoMarginBottom.values()));
5252
const maxMarginTop = $derived(Math.max(...$autoMarginTop.values()));
5353
54+
const USER_DEFAULTS = getContext<Partial<PlotDefaults>>('svelteplot/defaults') || {};
55+
5456
// default settings in the plot and marks can be overwritten by
5557
// defining the svelteplot/defaults context outside of Plot
5658
const DEFAULTS: PlotDefaults = {
57-
axisXAnchor: 'bottom',
58-
axisYAnchor: 'left',
59-
xTickSpacing: 80,
60-
yTickSpacing: 50,
6159
height: 350,
6260
initialWidth: 500,
6361
inset: 0,
6462
colorScheme: 'turbo',
6563
unknown: '#cccccc99',
66-
dotRadius: 3,
67-
frame: false,
68-
axes: true,
69-
grid: false,
64+
7065
categoricalColorScheme: 'observable10',
7166
pointScaleHeight: 18,
7267
bandScaleHeight: 30,
@@ -77,7 +72,29 @@
7772
compactDisplay: 'short'
7873
},
7974
markerDotRadius: 3,
80-
...getContext<Partial<PlotDefaults>>('svelteplot/defaults')
75+
...USER_DEFAULTS,
76+
axisX: {
77+
anchor: 'bottom',
78+
implicit: true,
79+
...USER_DEFAULTS.axis,
80+
...USER_DEFAULTS.axisX
81+
},
82+
axisY: {
83+
anchor: 'left',
84+
implicit: true,
85+
...USER_DEFAULTS.axis,
86+
...USER_DEFAULTS.axisY
87+
},
88+
gridX: {
89+
implicit: false,
90+
...USER_DEFAULTS.grid,
91+
...USER_DEFAULTS.gridX
92+
},
93+
gridY: {
94+
implicit: false,
95+
...USER_DEFAULTS.grid,
96+
...USER_DEFAULTS.gridY
97+
}
8198
};
8299
83100
let {
@@ -390,16 +407,16 @@
390407
? margins
391408
: Math.max(5, maxMarginBottom),
392409
inset: isOneDimensional ? 10 : DEFAULTS.inset,
393-
grid: DEFAULTS.grid,
394-
axes: DEFAULTS.axes,
395-
frame: DEFAULTS.frame,
410+
grid: (DEFAULTS.gridX?.implicit ?? false) && (DEFAULTS.gridY?.implicit ?? false),
411+
axes: (DEFAULTS.axisX?.implicit ?? false) && (DEFAULTS.axisY?.implicit ?? false),
412+
frame: DEFAULTS.frame?.implicit ?? false,
396413
projection: null,
397414
aspectRatio: null,
398415
facet: {},
399416
padding: 0.1,
400417
x: {
401418
type: 'auto',
402-
axis: autoXAxis ? DEFAULTS.axisXAnchor : false,
419+
axis: DEFAULTS.axisX.implicit && autoXAxis ? DEFAULTS.axisX.anchor : false,
403420
labelAnchor: 'auto',
404421
reverse: false,
405422
clamp: false,
@@ -408,13 +425,13 @@
408425
round: false,
409426
percent: false,
410427
align: 0.5,
411-
tickSpacing: DEFAULTS.xTickSpacing,
428+
tickSpacing: DEFAULTS.axisX.tickSpacing ?? 80,
412429
tickFormat: 'auto',
413-
grid: false
430+
grid: DEFAULTS.gridX.implicit ?? false
414431
},
415432
y: {
416433
type: 'auto',
417-
axis: autoYAxis ? DEFAULTS.axisYAnchor : false,
434+
axis: DEFAULTS.axisY.implicit && autoYAxis ? DEFAULTS.axisY.anchor : false,
418435
labelAnchor: 'auto',
419436
reverse: false,
420437
clamp: false,
@@ -423,9 +440,9 @@
423440
round: false,
424441
percent: false,
425442
align: 0.5,
426-
tickSpacing: DEFAULTS.yTickSpacing,
443+
tickSpacing: DEFAULTS.axisY.tickSpacing ?? 50,
427444
tickFormat: 'auto',
428-
grid: false
445+
grid: DEFAULTS.gridY.implicit ?? false
429446
},
430447
opacity: {
431448
type: 'linear',

src/lib/marks/Area.svelte

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,30 @@
3939
ConstantAccessor,
4040
ChannelAccessor,
4141
ScaledDataRecord,
42-
LinkableMarkProps
42+
LinkableMarkProps,
43+
PlotDefaults
4344
} from '../types.js';
4445
import type { RawValue } from '$lib/types.js';
4546
import type { StackOptions } from '$lib/transforms/stack.js';
4647
47-
let {
48+
let markProps: AreaMarkProps = $props();
49+
50+
const DEFAULTS = {
51+
fill: 'currentColor',
52+
curve: 'linear',
53+
tension: 0,
54+
...getContext<PlotDefaults>('svelteplot/_defaults').area
55+
};
56+
57+
const {
4858
data,
4959
/** the curve */
5060
curve = 'linear',
5161
tension = 0,
5262
class: className = '',
5363
canvas = false,
5464
...options
55-
}: AreaMarkProps = $props();
65+
}: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
5666
5767
const { getPlotState } = getContext<PlotContext>('svelteplot');
5868
const plot = $derived(getPlotState());

src/lib/marks/AreaX.svelte

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77
import { renameChannels } from '$lib/transforms/rename.js';
88
import { stackX } from '$lib/transforms/stack.js';
99
import { recordizeX } from '$lib/transforms/recordize.js';
10-
import type { ChannelAccessor } from '../types.js';
10+
import type { ChannelAccessor, PlotDefaults } from '../types.js';
11+
import { getContext } from 'svelte';
1112
1213
type AreaXProps = Omit<AreaMarkProps, 'y1' | 'y2'> & {
1314
x?: ChannelAccessor;
1415
y?: ChannelAccessor;
1516
};
1617
17-
// we're discarding y1 and y2 props since they are not
18-
let { data, stack, ...options }: AreaXProps = $props();
18+
let markProps: AreaMarkProps = $props();
19+
20+
const DEFAULTS = getContext<PlotDefaults>('svelteplot/_defaults').areaX;
21+
22+
const { data, stack, ...options }: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
1923
2024
const args = $derived(
2125
renameChannels<AreaXProps>(

src/lib/marks/AreaY.svelte

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import { renameChannels } from '$lib/transforms/rename.js';
88
import { stackY } from '$lib/transforms/stack.js';
99
import { recordizeY } from '$lib/transforms/recordize.js';
10-
import type { ChannelAccessor } from '../types.js';
10+
import type { ChannelAccessor, PlotDefaults } from '../types.js';
11+
import { getContext } from 'svelte';
1112
1213
/**
1314
* AreaY mark foo
@@ -17,7 +18,11 @@
1718
y?: ChannelAccessor;
1819
};
1920
20-
let { data, stack, ...options }: AreaYProps = $props();
21+
let markProps: AreaMarkProps = $props();
22+
23+
const DEFAULTS = getContext<PlotDefaults>('svelteplot/_defaults').areaY;
24+
25+
const { data, stack, ...options }: AreaMarkProps = $derived({ ...DEFAULTS, ...markProps });
2126
2227
const args = $derived(
2328
renameChannels<AreaYProps>(

src/lib/marks/Arrow.svelte

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@
3838
</script>
3939

4040
<script lang="ts">
41-
import { getContext, type Snippet } from 'svelte';
41+
import { getContext } from 'svelte';
4242
import type {
4343
PlotContext,
4444
DataRecord,
4545
BaseMarkProps,
4646
ConstantAccessor,
4747
ChannelAccessor,
48-
RawValue
48+
RawValue,
49+
PlotDefaults
4950
} from '../types.js';
5051
import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
5152
import { coalesce, maybeData, maybeNumber } from '../helpers/index.js';
@@ -55,7 +56,23 @@
5556
import { addEventHandlers } from './helpers/events.js';
5657
import GroupMultiple from './helpers/GroupMultiple.svelte';
5758
58-
let { data = [{}], class: className = null, ...options }: ArrowMarkProps = $props();
59+
let markProps: ArrowMarkProps = $props();
60+
61+
const DEFAULTS = {
62+
headAngle: 60,
63+
headLength: 8,
64+
inset: 0,
65+
...getContext<PlotDefaults>('svelteplot/_defaults').arrow
66+
};
67+
68+
const {
69+
data = [{}],
70+
class: className = '',
71+
...options
72+
}: ArrowMarkProps = $derived({
73+
...DEFAULTS,
74+
...markProps
75+
});
5976
6077
const { getPlotState } = getContext<PlotContext>('svelteplot');
6178
const plot = $derived(getPlotState());
@@ -68,7 +85,7 @@
6885
: maybeData(data)
6986
);
7087
71-
const args: ArrowProps = $derived(
88+
const args: ArrowMarkProps = $derived(
7289
replaceChannels({ data: sorted, ...options }, { y: ['y1', 'y2'], x: ['x1', 'x2'] })
7390
);
7491
</script>
@@ -78,16 +95,16 @@
7895
required={['x1', 'x2', 'y1', 'y2']}
7996
channels={['x1', 'y1', 'x2', 'y2', 'opacity', 'stroke', 'strokeOpacity']}
8097
{...args}>
81-
{#snippet children({ mark, usedScales, scaledData })}
98+
{#snippet children({ usedScales, scaledData })}
8299
{@const sweep = maybeSweep(args.sweep)}
83100
<GroupMultiple class="arrow" length={scaledData.length}>
84101
{#each scaledData as d, i (i)}
85102
{#if d.valid}
86103
{@const inset = resolveProp(args.inset, d.datum, 0)}
87104
{@const insetStart = resolveProp(args.insetStart, d.datum)}
88105
{@const insetEnd = resolveProp(args.insetEnd, d.datum)}
89-
{@const headAngle = resolveProp(args.headAngle, d.datum, 60)}
90-
{@const headLength = resolveProp(args.headLength, d.datum, 8)}
106+
{@const headAngle = resolveProp(args.headAngle, d.datum)}
107+
{@const headLength = resolveProp(args.headLength, d.datum)}
91108
{@const bend = resolveProp(args.bend, d.datum, 0)}
92109
{@const strokeWidth = resolveProp(args.strokeWidth, d.datum, 1)}
93110
{@const arrPath = arrowPath(

src/lib/marks/AxisX.svelte

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,11 @@
2727
ticks?: number | string | RawValue[];
2828
/** set to false or null to disable tick labels */
2929
text: boolean | null;
30-
} & XOR<
31-
{
32-
/** approximate number of ticks to be generated */
33-
tickCount?: number;
34-
},
35-
{
36-
/** approximate number of pixels between generated ticks */
37-
tickSpacing?: number;
38-
}
39-
>;
30+
/** approximate number of ticks to be generated */
31+
tickCount?: number;
32+
/** approximate number of pixels between generated ticks */
33+
tickSpacing?: number;
34+
};
4035
</script>
4136

4237
<script lang="ts">
@@ -49,32 +44,36 @@
4944
RawValue,
5045
ConstantAccessor,
5146
FacetContext,
52-
DefaultOptions
47+
PlotDefaults,
48+
ChannelName
5349
} from '../types.js';
5450
import autoTimeFormat from '$lib/helpers/autoTimeFormat.js';
5551
import { derived } from 'svelte/store';
5652
import { autoTicks } from '$lib/helpers/autoTicks.js';
5753
import { resolveScaledStyles } from '$lib/helpers/resolve.js';
5854
59-
const DEFAULTS = {
55+
let markProps: AxisXMarkProps = $props();
56+
57+
const DEFAULTS: Omit<AxisXMarkProps, 'data' | ChannelName> = {
6058
tickSize: 6,
6159
tickPadding: 3,
6260
tickFontSize: 11,
63-
axisXAnchor: 'bottom',
64-
...getContext<Partial<DefaultOptions>>('svelteplot/_defaults')
61+
anchor: 'bottom',
62+
...getContext<PlotDefaults>('svelteplot/_defaults').axis,
63+
...getContext<PlotDefaults>('svelteplot/_defaults').axisX
6564
};
6665
67-
let {
66+
const {
6867
ticks: magicTicks,
6968
data = Array.isArray(magicTicks) ? magicTicks : [],
7069
automatic = false,
7170
title,
72-
anchor = DEFAULTS.axisXAnchor as 'top' | 'bottom',
71+
anchor,
7372
facetAnchor = 'auto',
7473
interval = typeof magicTicks === 'string' ? magicTicks : undefined,
75-
tickSize = DEFAULTS.tickSize,
76-
tickFontSize = DEFAULTS.tickFontSize,
77-
tickPadding = DEFAULTS.tickPadding,
74+
tickSize,
75+
tickFontSize,
76+
tickPadding,
7877
labelAnchor,
7978
tickFormat,
8079
tickClass,
@@ -83,7 +82,7 @@
8382
tickSpacing,
8483
text = true,
8584
...options
86-
}: AxisXMarkProps = $props();
85+
}: AxisXMarkProps = $derived({ ...DEFAULTS, ...markProps });
8786
8887
const { getPlotState } = getContext<PlotContext>('svelteplot');
8988
const plot = $derived(getPlotState());

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy