Skip to content

Commit 949167d

Browse files
committed
docs: add more examples
1 parent 3cbbb5d commit 949167d

30 files changed

+273
-82
lines changed

config/sidebar.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ export default {
1111
{
1212
title: 'Why SveltePlot?',
1313
to: '/why-svelteplot'
14+
},
15+
{
16+
title: 'Examples',
17+
to: '/examples'
1418
}
15-
// {
16-
// title: 'Introduction',
17-
// to: '/introduction'
18-
// }
1919
]
2020
},
2121
{
@@ -119,10 +119,6 @@ export default {
119119
{
120120
title: 'Gradients',
121121
to: '/features/gradients'
122-
},
123-
{
124-
title: 'Examples',
125-
to: '/examples'
126122
}
127123
]
128124
}

screenshot-examples.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ 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('.svelteplot', { timeout: 10000 });
97+
await page.waitForSelector('.content > figure.svelteplot', { timeout: 10000 });
9898

9999
// Toggle dark mode if needed
100100
if (isDarkMode) {
@@ -112,7 +112,7 @@ const takeScreenshot = async (page, urlPath, outputPath, isDarkMode = false) =>
112112

113113
// Get the Plot SVG element
114114
const elementHandle = await page.evaluateHandle(() =>
115-
document.querySelector('.svelteplot svg')
115+
document.querySelector('.content > figure.svelteplot > .plot-body > svg')
116116
);
117117

118118
// Take a screenshot of the element

src/lib/ui/ExamplesGrid.svelte

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<script>
2+
let { examples } = $props();
3+
</script>
4+
5+
<div class="list">
6+
{#each examples as page, i (i)}
7+
<a href={page.url}>
8+
<div>
9+
{#if page.screenshot}
10+
<img src={page.screenshot} alt={page.title} />{/if}
11+
</div>
12+
<h4>
13+
{page.title}
14+
</h4>
15+
</a>
16+
{/each}
17+
</div>
18+
19+
<style>
20+
.list {
21+
display: grid;
22+
grid-template-columns: repeat(3, 1fr);
23+
gap: 1rem;
24+
width: 100%;
25+
margin: 2rem 0;
26+
}
27+
28+
.list > a {
29+
display: flex;
30+
flex-direction: column;
31+
align-items: left;
32+
row-gap: 0.3rem;
33+
text-decoration: none;
34+
35+
> div {
36+
border: 1px solid #88888822;
37+
border-radius: 2px;
38+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
39+
padding: 1.5ex;
40+
}
41+
42+
&:hover {
43+
text-decoration: underline;
44+
color: var(--svp-text);
45+
> div {
46+
border: 1px solid var(--svp-text);
47+
}
48+
}
49+
}
50+
51+
.list img {
52+
width: 100%;
53+
box-sizing: border-box;
54+
border-radius: 3px;
55+
transition: transform 0.2s ease-in-out;
56+
}
57+
58+
.list h4 {
59+
margin: 0rem;
60+
font-weight: normal;
61+
font-size: 13px;
62+
line-height: 1;
63+
}
64+
</style>

src/routes/examples/+layout.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const load: PageLoad = async ({ fetch }) => {
77
return {
88
data: {
99
world: await loadJSON(fetch, 'countries-110m'),
10+
us: await loadJSON(fetch, 'us-counties-10m'),
1011
...(await loadDatasets(
1112
[
1213
'aapl',
@@ -20,6 +21,7 @@ export const load: PageLoad = async ({ fetch }) => {
2021
'tdf',
2122
'rightwing',
2223
'stocks',
24+
'unemployment',
2325
'sftemp'
2426
],
2527
fetch

src/routes/examples/+page.svelte

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
11
<script module>
22
export const frontmatter = {
3-
title: 'Example plots',
3+
title: 'Examples',
44
description: 'Some description'
55
};
6+
7+
// list of maybe 9 nice examples showcases
8+
const showcase = ['line/gradient-line', 'geo/us-choropleth', 'axis/datawrapper-ticks'];
69
</script>
710

811
<script>
912
import { groupBy } from 'es-toolkit';
13+
import { SVELTEPRESS_CONTEXT_KEY } from '@sveltepress/theme-default/context';
14+
import { getContext } from 'svelte';
15+
import ExamplesGrid from 'svelteplot/ui/ExamplesGrid.svelte';
16+
const { isDark } = getContext(SVELTEPRESS_CONTEXT_KEY);
1017
1118
const pages = import.meta.glob('./**/*.svelte', { eager: true });
19+
1220
const paths = groupBy(
1321
Object.keys(pages).filter((d) => !d.startsWith('./[group]')),
1422
(d) => d.split('/')[1]
1523
);
24+
25+
const screenshots = import.meta.glob('/static/examples/**/*.png', {
26+
eager: true,
27+
import: 'default',
28+
query: '?url'
29+
});
30+
31+
const examples = $derived(
32+
showcase
33+
.map((url) => Object.keys(pages).find((p) => p === `./${url}.svelte`))
34+
.map((page) => ({
35+
page,
36+
title: pages[page].title,
37+
url: `/examples/${page.replace(/^..\//, './').replace('.svelte', '')}`,
38+
screenshot: screenshots[
39+
page
40+
.replace(/^.\//, '/static/examples/')
41+
.replace('.svelte', $isDark ? '.dark.png' : '.png')
42+
]?.replace('/static', '')
43+
}))
44+
);
1645
</script>
1746
47+
<p>Sometimes it's easiest to learn a new framework by digging into examples.</p>
48+
49+
<ExamplesGrid {examples} />
50+
1851
<div class="column-container">
1952
{#each Object.entries(paths) as [group, groupPages] (group)}
2053
<div>
@@ -39,6 +72,7 @@
3972
> div {
4073
padding-top: 1em;
4174
break-before: column;
75+
break-inside: avoid-column;
4276
}
4377
h3 {
4478
break-before: avoid-column;

src/routes/examples/[group]/+layout.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
<script lang="ts">
2+
import '../../../app.scss';
3+
</script>
4+
15
<div class="theme-default--page-layout">
26
<div class="content">
37
<slot />
@@ -8,5 +12,14 @@
812
.content {
913
margin-left: auto;
1014
margin-right: auto;
15+
16+
:global {
17+
a {
18+
transition: color 0.2s ease-out;
19+
}
20+
a:hover {
21+
color: var(--svp-accent);
22+
}
23+
}
1124
}
1225
</style>

src/routes/examples/[group]/+page.svelte

Lines changed: 17 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const { isDark } = getContext(SVELTEPRESS_CONTEXT_KEY);
66
77
import { getContext } from 'svelte';
8+
import ExamplesGrid from 'svelteplot/ui/ExamplesGrid.svelte';
89
910
const pages = import.meta.glob('../**/*.svelte', { eager: true });
1011
@@ -24,84 +25,30 @@
2425
const subPages = $derived(
2526
Object.keys(pages).filter((d) => d.replace(/^..\//, '').startsWith(`${page.params.group}/`))
2627
);
28+
29+
const examples = $derived(
30+
subPages
31+
.filter((page) => !page.endsWith('/_index.svelte'))
32+
.map((page) => ({
33+
page,
34+
title: pages[page].title,
35+
url: `/examples/${page.replace(/^..\//, './').replace('.svelte', '')}`,
36+
screenshot: screenshots[
37+
page
38+
.replace(/^..\//, '/static/examples/')
39+
.replace('.svelte', $isDark ? '.dark.png' : '.png')
40+
]?.replace('/static', '')
41+
}))
42+
);
2743
</script>
2844
2945
{#if subPages.length}
3046
{#if indexKey}
3147
<a href="/examples">Examples</a>
3248
<indexMod.default />
3349
34-
<div class="list">
35-
{#each subPages as page, i (i)}
36-
{#if !page.endsWith('/_index.svelte')}
37-
{@const url = `/examples/${page.replace(/^..\//, './').replace('.svelte', '')}`}
38-
{@const screenshotUrl = page
39-
.replace(/^..\//, '/static/examples/')
40-
.replace('.svelte', $isDark ? '.dark.png' : '.png')}
41-
<div>
42-
{#if screenshots[screenshotUrl]}
43-
<a href={url}
44-
><img
45-
src={screenshots[screenshotUrl].replace('/static', '')}
46-
alt={pages[page].title} /></a
47-
>{/if}
48-
<h4>
49-
<a href={url}>{pages[page].title}</a>
50-
</h4>
51-
</div>
52-
{/if}
53-
{/each}
54-
</div>
50+
<ExamplesGrid {examples} />
5551
{/if}
5652
{:else}
5753
<h2>Not found</h2>
5854
{/if}
59-
60-
<style>
61-
.list {
62-
display: grid;
63-
grid-template-columns: repeat(3, 1fr);
64-
gap: 1rem;
65-
width: 100%;
66-
margin: 2rem 0;
67-
}
68-
69-
.list > div {
70-
display: flex;
71-
flex-direction: column;
72-
align-items: left;
73-
row-gap: 0.3rem;
74-
75-
> a {
76-
border: 1px solid #88888822;
77-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
78-
padding: 1.5ex;
79-
}
80-
81-
&:hover {
82-
> a {
83-
border: 1px solid currentColor;
84-
}
85-
h4 a {
86-
text-decoration: underline;
87-
}
88-
}
89-
}
90-
91-
.list img {
92-
width: 100%;
93-
box-sizing: border-box;
94-
border-radius: 3px;
95-
transition: transform 0.2s ease-in-out;
96-
}
97-
98-
.list h4 {
99-
margin: 0rem;
100-
font-weight: normal;
101-
font-size: 13px;
102-
line-height: 1;
103-
> a {
104-
text-decoration: none;
105-
}
106-
}
107-
</style>

src/routes/examples/geo/_index.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script module>
2+
export const title = 'Geo';
3+
</script>
4+
5+
<h1>Geo examples</h1>
6+
7+
<p>You can use the <a href="/marks/geo">Geo</a> mark for creating maps in SveltePlot.</p>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script module>
2+
export const title = 'US choropleth map (canvas)';
3+
export const description = 'See also the <a href="/examples/geo/us-choropleth">SVG version</a>';
4+
</script>
5+
6+
<script>
7+
import { Plot } from 'svelteplot';
8+
import Geo from 'svelteplot/marks/Geo.svelte';
9+
import * as topojson from 'topojson-client';
10+
import { page } from '$app/state';
11+
12+
const { us, unemployment } = $derived(page.data.data);
13+
const rateMap = $derived(new Map(unemployment.map((d) => [d.id, +d.rate])));
14+
const counties = $derived(
15+
topojson.feature(us, us.objects.counties).features.map((feat) => {
16+
return {
17+
...feat,
18+
properties: {
19+
...feat.properties,
20+
unemployment: rateMap.get(+feat.id)
21+
}
22+
};
23+
})
24+
);
25+
</script>
26+
27+
<Plot
28+
projection="albers-usa"
29+
color={{
30+
scheme: 'blues',
31+
label: 'Unemployment (%)',
32+
legend: true,
33+
n: 5,
34+
type: 'quantile'
35+
}}>
36+
<Geo canvas data={counties} fill={(d) => d.properties.unemployment} />
37+
</Plot>

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