Skip to content

Commit

Permalink
changelog edits
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Jan 11, 2025
1 parent 60bfb7a commit 4404298
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 12 deletions.
20 changes: 9 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,26 @@ Year: **Current (2025)** · [2024](./CHANGELOG-2024.md) · [2023](./CHANGELOG-20

[Released TDB, 2025.](https://github.com/observablehq/plot/releases/tag/v0.6.17)

The **clip** option now supports GeoJSON 🌎 in addition to the usual *frame* and *sphere* options. This allows to limit the visual scope of marks that otherwise interpolate across the whole frame. For instance, we can clip this voronoi mesh of all world airports to the land feature:
The [**clip** mark option](https://observablehq.com/plot/features/marks#clip) now supports GeoJSON objects 🌎 in addition to the named *frame* and *sphere* clipping methods, allowing the visual extent of marks to be limited to arbitrary polygons. For instance, this Voronoi mesh of world airports is clipped to land boundaries:

[<img src="./img/airports-clip-land.png" width="708" alt="a map of world airports with a voronoi mesh clipped to land">](XXXXX)

```js
Plot.plot({
projection: { type: "orthographic", rotate: [110, -50] },
projection: {type: "orthographic", rotate: [110, -50]},
marks: [
Plot.dot(airports, { x: "longitude", y: "latitude", fill: "red", r: 1 }),
Plot.voronoiMesh(airports, { x: "longitude", y: "latitude", clip: land }),
Plot.dot(airports, {x: "longitude", y: "latitude", fill: "red", r: 1}),
Plot.voronoiMesh(airports, {x: "longitude", y: "latitude", clip: land}),
Plot.sphere(),
Plot.geo(land)
]
})
```

The clipping GeoJSON is rendered as a SVG [`clipPath`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath), with the same path that would be produced by the [geo](https://observablehq.com/plot/marks/geo) mark — respecting the plot’s top-level **projection** option, if any. For performance, the `clipPath` is shared across marks clipped with the same object.

For example, this combination of a [raster]() mark and a [contour]() mark shows atmospheric water vapor measurements from [NASA Earth Observations](https://neo.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_SKY_WV), across the US.
The GeoJSON object passed to the **clip** option is rendered as a [`clipPath` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath) using the same path data that a [geo mark](https://observablehq.com/plot/marks/geo) would produce, respecting the plot’s top-level **projection** option, if any. For performance, `clipPath` elements are shared by marks clipped with the same GeoJSON object. For example, the [raster mark](https://observablehq.com/plot/marks/raster) and [contour mark](https://observablehq.com/plot/marks/contour) below show atmospheric water vapor measurements across the United States from [NASA Earth Observations](https://neo.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_SKY_WV); both marks are clipped to the nation’s boundary, censoring the (absurd) values that would otherwise be interpolated between Alaska, Southern California, and Hawai’i.

[<img src="./img/vapor-clip-us.png" width="708" alt="a map of water vapor measurements">](XXXXX)

The code for this map is too long to reproduce here (click on the image above for the complete code); the crucial part is the `clip: nation` option, that allows to censor the (absurd) values that would otherwise be interpolated between Alaska, Southern California and Hawai’i.

```js
Plot.raster(vapor, {
fill: Plot.identity,
Expand All @@ -42,7 +38,9 @@ Plot.raster(vapor, {
}).plot()
```

This option is not restricted to geographic shapes. For example, to show the value of [Math.atan2](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2) over the unit circle:
[The code for the map above is too long to reproduce here completely; click on the image above for the complete code.]

The **clip** mark option can also be used to clip against arbitrary polygons, not just geographic boundaries. For example, to show the value of [Math.atan2](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2) over the unit circle:

[<img src="./img/unit-circle-atan2.png" width="332" alt="the value of Math.atan2 on the unit circle">](XXXXX)

Expand All @@ -56,7 +54,7 @@ Plot.raster({
d3.range(0, 2 * Math.PI, 0.1).map((angle) => d3.pointRadial(angle, 1))
]
}
}).plot({ width: 300, aspectRatio: 1 })
}).plot({width: 300, aspectRatio: 1})
```

The interactive **tip** associated with a [waffle mark](https://observablehq.com/plot/marks/waffle) is now anchored to the “center” of the visual representation of the associated datum. That center depends on the shape that is referenced. For fun, here’s a chart from out unit tests showing these anchoring points for various amounts of waffling. Baffling!
Expand Down
2 changes: 1 addition & 1 deletion docs/features/marks.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ All marks support the following style options:
* **clip** - whether and how to clip the mark
* **tip** - whether to generate an implicit [pointer](../interactions/pointer.md) [tip](../marks/tip.md) <VersionBadge version="0.6.7" />

If the **clip** option is *frame* (or equivalently true), the mark is clipped to the frame’s dimensions. If the **clip** option is null (or equivalently false), the mark is not clipped. If the **clip** option is *sphere*, the mark will be clipped to the projected sphere (_e.g._, the front hemisphere when using the orthographic projection); a [geographic projection](./projections.md) is required in this case. Lastly if the **clip** option is a GeoJSON object <VersionBadge pr="2243" />, the mark will be clipped to the projected geometry.
If the **clip** option<a id="clip" href="#clip" aria-label="Permalink to &quot;clip&quot;"></a> is *frame* (or equivalently true), the mark is clipped to the frame’s dimensions. If the **clip** option is null (or equivalently false), the mark is not clipped. If the **clip** option is *sphere*, the mark will be clipped to the projected sphere (_e.g._, the front hemisphere when using the orthographic projection); a [geographic projection](./projections.md) is required in this case. Lastly if the **clip** option is a GeoJSON object <VersionBadge pr="2243" />, the mark will be clipped to the projected geometry.

If the **tip** option is true, a [tip mark](../marks/tip.md) with the [pointer transform](../interactions/pointer.md) will be derived from this mark and placed atop all other marks, offering details on demand. If the **tip** option is set to an options object, these options will be passed to the derived tip mark. If the **tip** option (or, if an object, its **pointer** option) is set to *x*, *y*, or *xy*, [pointerX](../interactions/pointer.md#pointerX), [pointerY](../interactions/pointer.md#pointerY), or [pointer](../interactions/pointer.md#pointer) will be used, respectively; otherwise the pointing mode will be chosen automatically. (If the **tip** mark option is truthy, the **title** channel is no longer applied using an SVG title element as this would conflict with the tip mark.)

Expand Down

0 comments on commit 4404298

Please sign in to comment.