Skip to content

Commit 9b0267d

Browse files
committed
feat: New GeoClipPath component for clipping content to GeoJSON boundaries in both SVG and Canvas modes
1 parent 83aa90f commit 9b0267d

13 files changed

Lines changed: 212 additions & 25 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'layerchart': minor
3+
---
4+
5+
feat: New `GeoClipPath` component for clipping content to GeoJSON boundaries in both SVG and Canvas modes

docs/src/content/components/CircleClipPath.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
description: Clipping component which conditionally applies a circular clip region to its child elements based on the rendering context and provided properties.
33
category: clipping
44
layers: [svg]
5-
related: []
5+
related: [ClipPath, GeoClipPath, RectClipPath]
66
---

docs/src/content/components/ClipPath.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
description: Clipping component which defines a clipping region to constrain the rendering of chart elements within a specified shape or boundary.
33
category: clipping
44
layers: [svg]
5-
related:
6-
[
7-
components/ChartClipPath,
8-
components/CircleClipPath,
9-
components/RectClipPath,
10-
components/Threshold
11-
]
5+
related: [ChartClipPath, CircleClipPath, GeoClipPath, RectClipPath, Threshold]
126
order: 1
137
---
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
description: Clipping component which defines a GeoJSON-based clip region to constrain the rendering of chart elements within geographic boundaries. Supports both SVG and Canvas rendering.
3+
category: clipping
4+
layers: [svg, canvas]
5+
related: [ClipPath, ChartClipPath, CircleClipPath, RectClipPath, GeoPath]
6+
---

docs/src/content/components/RectClipPath.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
description: Clipping component which defines a rectangular clip region to constrain the rendering of chart elements within a specified shape or boundary.
33
category: clipping
44
layers: [svg]
5-
related: [ChartClipPath]
5+
related: [ChartClipPath, ClipPath, GeoClipPath]
66
---
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"component": "GeoClipPath",
3+
"examples": [
4+
{
5+
"name": "basic",
6+
"title": "basic",
7+
"path": "/docs/components/GeoClipPath/basic",
8+
"components": [
9+
{
10+
"component": "Chart",
11+
"lineNumber": 15,
12+
"line": "<Chart"
13+
},
14+
{
15+
"component": "Layer",
16+
"lineNumber": 22,
17+
"line": "<Layer>"
18+
},
19+
{
20+
"component": "GeoClipPath",
21+
"lineNumber": 23,
22+
"line": "<GeoClipPath geojson={nation}>"
23+
},
24+
{
25+
"component": "Graticule",
26+
"lineNumber": 24,
27+
"line": "<Graticule class=\"stroke-primary/30\" />"
28+
},
29+
{
30+
"component": "GeoPath",
31+
"lineNumber": 28,
32+
"line": "<GeoPath geojson={feature} class=\"fill-none stroke-surface-content/20\" />"
33+
}
34+
]
35+
}
36+
],
37+
"usage": [
38+
{
39+
"example": "basic",
40+
"component": "GeoClipPath",
41+
"path": "/docs/components/GeoClipPath/basic",
42+
"lineNumber": 23,
43+
"line": "<GeoClipPath geojson={nation}>"
44+
},
45+
{
46+
"example": "timezones",
47+
"component": "GeoPath",
48+
"path": "/docs/components/GeoPath/timezones",
49+
"lineNumber": 116,
50+
"line": "<GeoClipPath geojson={countriesGeojson} disabled={!enableClip}>"
51+
},
52+
{
53+
"example": "clipped",
54+
"component": "GeoTile",
55+
"path": "/docs/components/GeoTile/clipped",
56+
"lineNumber": 44,
57+
"line": "<GeoClipPath geojson={selectedFeature}>"
58+
},
59+
{
60+
"example": "us-water-vapor",
61+
"component": "Raster",
62+
"path": "/docs/components/Raster/us-water-vapor",
63+
"lineNumber": 37,
64+
"line": "<GeoClipPath geojson={nation}>"
65+
}
66+
],
67+
"updatedAt": "2026-04-12T22:40:49.420Z"
68+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script module lang="ts">
2+
import { getUsStatesTopology } from '$lib/geo.remote.js';
3+
const topology = await getUsStatesTopology();
4+
</script>
5+
6+
<script lang="ts">
7+
import { geoAlbersUsa } from 'd3-geo';
8+
import { feature } from 'topojson-client';
9+
import { Chart, GeoClipPath, GeoPath, Graticule, Layer } from 'layerchart';
10+
11+
const nation = feature(topology as any, (topology as any).objects.nation);
12+
const states = feature(topology, topology.objects.states);
13+
</script>
14+
15+
<Chart
16+
geo={{
17+
projection: geoAlbersUsa,
18+
fitGeojson: states
19+
}}
20+
height={400}
21+
>
22+
<Layer>
23+
<GeoClipPath geojson={nation}>
24+
<Graticule class="stroke-primary/30" />
25+
</GeoClipPath>
26+
27+
{#each states.features as feature (feature.id)}
28+
<GeoPath geojson={feature} class="fill-none stroke-surface-content/20" />
29+
{/each}
30+
31+
<GeoPath geojson={nation} class="fill-none stroke-surface-content" />
32+
</Layer>
33+
</Chart>

docs/src/examples/components/GeoPath/timezones.svelte

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@
2222
// @ts-expect-error
2323
import { century, equationOfTime, declination } from 'solar-calculator';
2424
25-
import { Blur, Chart, ClipPath, GeoCircle, GeoPath, Layer, Tooltip, antipode } from 'layerchart';
25+
import {
26+
Blur,
27+
Chart,
28+
ClipPath,
29+
GeoCircle,
30+
GeoClipPath,
31+
GeoPath,
32+
Layer,
33+
Tooltip,
34+
antipode
35+
} from 'layerchart';
2636
import TimezonesControls from '$lib/components/controls/GeoPathTimezonesControls.svelte';
2737
import { TimerState } from '@layerstack/svelte-state';
2838
@@ -103,8 +113,7 @@
103113
<Layer>
104114
<GeoPath geojson={{ type: 'Sphere' }} class="stroke-surface-content/30" id="globe" />
105115

106-
<GeoPath geojson={countriesGeojson} id="clip" />
107-
<ClipPath useId="clip" disabled={!enableClip}>
116+
<GeoClipPath geojson={countriesGeojson} disabled={!enableClip}>
108117
{#each timezoneGeojson.features as feature}
109118
<GeoPath
110119
geojson={feature}
@@ -113,7 +122,7 @@
113122
class="stroke-gray-900/50 hover:brightness-110"
114123
/>
115124
{/each}
116-
</ClipPath>
125+
</GeoClipPath>
117126

118127
{#each countriesGeojson.features as feature}
119128
<GeoPath geojson={feature} class="stroke-gray-900/10 fill-gray-900/20 pointer-events-none" />

docs/src/examples/components/GeoTile/clipped.svelte

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { geoMercator } from 'd3-geo';
99
import { feature } from 'topojson-client';
1010
11-
import { ClipPath, Chart, GeoPath, GeoTile, Layer, Tooltip } from 'layerchart';
11+
import { Chart, GeoClipPath, GeoPath, GeoTile, Layer, Tooltip } from 'layerchart';
1212
import GeoTileControls from '$lib/components/controls/GeoTileControls.svelte';
1313
const states = feature(topology, topology.objects.states);
1414
@@ -41,10 +41,9 @@
4141
>
4242
{#snippet children({ context })}
4343
<Layer>
44-
<ClipPath useId="clip">
44+
<GeoClipPath geojson={selectedFeature}>
4545
<GeoTile url={serviceUrl} {zoomDelta} />
46-
</ClipPath>
47-
<GeoPath geojson={selectedFeature} id="clip" class="stroke-none" />
46+
</GeoClipPath>
4847
{#each filteredStates.features as feature}
4948
<GeoPath
5049
geojson={feature}

docs/src/examples/components/Raster/us-water-vapor.svelte

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { interpolateRdYlBu } from 'd3-scale-chromatic';
44
import { geoAlbersUsa } from 'd3-geo';
55
import { feature } from 'topojson-client';
6-
import { Chart, ClipPath, Contour, GeoPath, Layer, Legend, Raster } from 'layerchart';
6+
import { Chart, Contour, GeoClipPath, GeoPath, Layer, Legend, Raster } from 'layerchart';
77
88
import { getWaterVapor } from '$lib/data.remote.js';
99
import { getUsCountiesTopology } from '$lib/geo.remote.js';
@@ -34,11 +34,7 @@
3434
/>
3535

3636
<Layer>
37-
<ClipPath>
38-
{#snippet clip()}
39-
<GeoPath geojson={nation} class="stroke-none" />
40-
{/snippet}
41-
37+
<GeoClipPath geojson={nation}>
4238
<Raster
4339
data={waterVapor.values}
4440
width={waterVapor.width}
@@ -64,7 +60,7 @@
6460
thresholds={40}
6561
blur={10}
6662
/>
67-
</ClipPath>
63+
</GeoClipPath>
6864

6965
<GeoPath geojson={nation} class="fill-none stroke-[#2f2f2f]" strokeWidth={1.25} />
7066
</Layer>

0 commit comments

Comments
 (0)