diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b0b90fd94..624ed6d086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,124 @@ Year: **Current (2023)** · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) +## 0.6.12 + +[Released December 7, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.12) + +To better support dark mode, we’ve made a breaking change to default styles: the background color is now `unset` (transparent) instead of `white`. Additionally, marks that expect to use the same color as the background (for instance, the tip mark) now use the CSS custom property `--plot-background` instead of `white`. + +As since [version 0.6.6](#066), you can override Plot’s styles via the `plot-d6a7b5` class. For example, the following stylesheet applies a dark background and white foreground: + +```css +.plot-d6a7b5 { + --plot-background: #333; + background: var(--plot-background); + color: white; +} +``` + +Previously Plot forced you to choose between [rect](https://observablehq.com/plot/marks/rect), [bar](https://observablehq.com/plot/marks/bar), and [cell](https://observablehq.com/plot/marks/cell) based on whether the *x* and *y* scales were ordinal or quantitative. Rejoice: the [rect mark](https://observablehq.com/plot/marks/rect) now supports *band* scales so you can simply use rect in all cases! 🎉 (The bar and cell marks still offer conveniences for ordinal scales, so use them if you like.) + +<img src="./img/rect-band.png" width="626" alt="A bar chart showing the relative frequency of English letters."> + +```js +Plot.rectY(alphabet, {x: "letter", y: "frequency"}).plot() +``` + +Categorical color scales now default to the new *observable10* color scheme by [Jeff Pettiross](https://github.com/pettiross). These colors are intended as a drop-in replacement for *tableau10* with similar ease of discrimination and ordering, but with a slightly more saturated vibe that helps charts pop. + +<img src="./img/observable10.png" width="600" alt="Color swatches of the ten colors in the observable10 color scheme: blue, yellow, red, teal, purple, pink, brown, light blue, green, and gray."> + +```js +Plot.cellX(d3.range(10)).plot({color: {type: "categorical"}}) +``` + +The new [difference mark](https://observablehq.com/plot/marks/difference) puts a metric in context by comparing it to another metric or constant value. Like the [area mark](https://observablehq.com/plot/marks/area), the region between two lines is filled; unlike the area mark, alternating color shows when the metric is above or below the comparison. + +<img src="./img/difference-zero.png" width="630" alt="A difference chart showing a moving average of global temperature anomaly; positive anomalies are shown in green, and negative anomalies are shown in blue."> + +```js +Plot.differenceY(gistemp, Plot.windowY(28, {x: "Date", y: "Anomaly"})).plot() +``` + +The chart above shows a moving average of global temperature anomaly; above-average temperatures are shown in green and below-average temperatures are shown in blue. + +The difference mark can also compare a metric to its earlier self, showing change over time. The chart below shows the year-over-year change in Apple stock price; the gray region represents an increase over last year while the red region represents a decrease. + +<img src="./img/difference-shift.png" width="630" alt="A difference chart showing the year-over-year change in Apple stock price; the gray region represents an increase over last year, while the red region represents a decrease."> + +```js +Plot.differenceY( + aapl, + Plot.shiftX("year", { + x: "Date", + y: "Close", + positiveFillOpacity: 0.2, + positiveFill: "currentColor", + negativeFillOpacity: 0.8, + negativeFill: "red" + }) +).plot() +``` + +The chart above is constructed using the new [shift transform](https://observablehq.com/plot/transforms/shift), which derives a time-shifted copy of a metric for the given time interval, enabling year–over-year, month-over-month, or any other period-over-period comparison. + +The new [find reducer](https://observablehq.com/plot/transforms/group#find) allows you to pivot data with the [bin](https://observablehq.com/plot/transforms/bin) and [group](https://observablehq.com/plot/transforms/group) transforms, effectively turning “tall” data (with fewer columns) into “wide” data (with more columns). For example, say you have time-series data that has separate rows for observed daily temperatures in San Francisco (SF) and San Jose (SJ): + +```csv +date,station,tmax,tmin +2020-12-31,SJ,59,43 +2020-12-31,SF,60,47 +2020-12-30,SJ,58,33 +2020-12-30,SF,57,40 +2020-12-29,SJ,62,38 +2020-12-29,SF,61,41 +2020-12-28,SJ,57,43 +2020-12-28,SF,56,47 +2020-12-27,SJ,62,43 +2020-12-27,SF,57,46 +2020-12-26,SJ,60,46 +2020-12-26,SF,61,49 +``` + +To compare the average minimum temperatures of San Francisco and San Jose as another difference chart: + +<img src="./img/difference-find.png" width="630" alt="A difference chart showing moving averages of daily minimum temperatures of San Francisco and San Jose; the green region represents when San Francisco was warmer than San Jose, and the blue region when San Francisco was cooler than San Jose."> + +```js +Plot.plot({ + x: {tickFormat: "%b"}, + y: {grid: true}, + marks: [ + Plot.ruleY([32]), + Plot.differenceY( + temperature, + Plot.windowY( + 14, + Plot.groupX( + {y1: Plot.find((d) => d.station === "SJ"), y2: Plot.find((d) => d.station === "SF")}, + {x: "date", y: "tmin"} + ) + ) + ) + ] +}) +``` + +The green region above represents when San Francisco was warmer than San Jose, and the blue region when San Francisco was cooler than San Jose. + +The [tip mark](https://observablehq.com/plot/marks/tip) now supports a **preferredAnchor** option, providing greater control over tip placement: if the tip fits within the frame at the preferred anchor, this anchor will be used. (In contrast, the **anchor** option uses the specified anchor regardless of whether it will fit.) The tip mark now also prefers the *bottom* anchor by default for a more traditional, less comic-like appearance. + +The [**marker** option](https://observablehq.com/plot/features/markers) now supports new marker types: *tick*, *tick-x*, and *tick-y*. The [bin](https://observablehq.com/plot/transforms/bin) and [group](https://observablehq.com/plot/transforms/group) transforms now pass _data_ to reducers. The [group](https://observablehq.com/plot/transforms/group) and [hexbin](https://observablehq.com/plot/transforms/hexbin) transforms now support _x_ and _y_ reducers. + +This release includes several additional fixes: + +* The default axis for a *time* scale now uses local time. +* The text mark’s **lineWidth** option is now more accurate when **monospace** is true. +* The tip mark no longer truncates **title** text. +* The scale **type** option is now case-insensitive. +* Transform type definitions have correct overload precedence. + ## 0.6.11 [Released September 20, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.11) diff --git a/docs/features/markers.md b/docs/features/markers.md index d9396ac699..82f306c8c6 100644 --- a/docs/features/markers.md +++ b/docs/features/markers.md @@ -56,9 +56,9 @@ The following named markers are supported: * *dot* - a filled *circle* without a stroke and 2.5px radius * *circle*, equivalent to *circle-fill* - a filled circle with a white stroke and 3px radius * *circle-stroke* - a hollow circle with a colored stroke and a white fill and 3px radius -* *tick* - a small opposing line -* *tick-x* - a small horizontal line -* *tick-y* - a small vertical line +* *tick* <VersionBadge version="0.6.12" pr="1872" /> - a small opposing line +* *tick-x* <VersionBadge version="0.6.12" pr="1872" /> - a small horizontal line +* *tick-y* <VersionBadge version="0.6.12" pr="1872" /> - a small vertical line If **marker** is true, it defaults to *circle*. If **marker** is a function, it will be called with a given *color* and must return an [SVG marker element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/marker). diff --git a/docs/features/scales.md b/docs/features/scales.md index 52f3e2fc39..78b0da69ba 100644 --- a/docs/features/scales.md +++ b/docs/features/scales.md @@ -11,7 +11,7 @@ const align = ref(0.5); const radius = ref(8); const schemeq = ref("turbo"); const schemed = ref("rdbu"); -const schemeo = ref("Tableau10"); +const schemeo = ref("Observable10"); const interpolateq = ref("rgb"); const anomaly = gistemp.map((d) => d.Anomaly); const aapl = shallowRef([]); @@ -457,6 +457,7 @@ Plot also provides color schemes for discrete data. Use the *categorical* type f <option>Accent</option> <option>Category10</option> <option>Dark2</option> + <option>Observable10</option> <option>Paired</option> <option>Pastel1</option> <option>Pastel2</option> @@ -730,7 +731,7 @@ Plot.plot({ The normal scale types — *linear*, *sqrt*, *pow*, *log*, *symlog*, and *ordinal* — can be used to encode color. In addition, Plot supports special scale types for color: -* *categorical* - like *ordinal*, but defaults to *tableau10* +* *categorical* - like *ordinal*, but defaults to *observable10* * *sequential* - like *linear* * *cyclical* - like *linear*, but defaults to *rainbow* * *threshold* - discretizes using thresholds given as the **domain**; defaults to *rdylbu* @@ -878,6 +879,7 @@ Plot.plot({ ["Accent", d3.schemeAccent], ["Category10", d3.schemeCategory10], ["Dark2", d3.schemeDark2], + ["Observable10", Plot.scale({color: {type: "categorical"}}).range], ["Paired", d3.schemePaired], ["Pastel1", d3.schemePastel1], ["Pastel2", d3.schemePastel2], diff --git a/docs/marks/difference.md b/docs/marks/difference.md index 9480ef259b..f551e2d7ea 100644 --- a/docs/marks/difference.md +++ b/docs/marks/difference.md @@ -18,7 +18,7 @@ onMounted(() => { </script> -# Difference mark <VersionBadge pr="1896" /> +# Difference mark <VersionBadge version="0.6.12" pr="1896" /> The **difference mark** puts a metric in context by comparing it. Like the [area mark](./area.md), the region between two lines is filled; unlike the area mark, alternating color shows when the metric is above or below the comparison value. diff --git a/docs/marks/tip.md b/docs/marks/tip.md index 0079e8afb9..388d10c7de 100644 --- a/docs/marks/tip.md +++ b/docs/marks/tip.md @@ -184,7 +184,7 @@ Plot.plot({ ``` ::: -If you don’t specify an explicit **anchor**, the tip mark will choose one automatically, using the **preferredAnchor** <VersionBadge pr="1872" /> if it fits. The preferred anchor defaults to *bottom*, except when using the **tip** option and the [pointerY pointing mode](../interactions/pointer.md), in which case it defaults to *left*. In some cases, it may not be possible to fit the tip within the plot’s frame; consider setting the plot’s **style** to `overflow: visible;` to prevent the tip from being truncated. +If you don’t specify an explicit **anchor**, the tip mark will choose one automatically, using the **preferredAnchor** <VersionBadge version="0.6.12" pr="1872" /> if it fits. The preferred anchor defaults to *bottom*, except when using the **tip** option and the [pointerY pointing mode](../interactions/pointer.md), in which case it defaults to *left*. In some cases, it may not be possible to fit the tip within the plot’s frame; consider setting the plot’s **style** to `overflow: visible;` to prevent the tip from being truncated. The tip mark is compatible with transforms that derive **x** and **y** dynamically from data, such as the [centroid transform](../transforms/centroid.md) which computes polygon centroids. Below, a map of the United States shows state names. We reduce the size of the tips by setting the **textPadding** option to 3 pixels instead of the default 8. diff --git a/docs/transforms/group.md b/docs/transforms/group.md index df128f8dcc..9108d4f7d8 100644 --- a/docs/transforms/group.md +++ b/docs/transforms/group.md @@ -368,8 +368,8 @@ The following named reducers are supported: * *deviation* - the standard deviation * *variance* - the variance per [Welford’s algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) * *identity* - the array of values -* *x* - the group’s *x* value (when grouping on *x*) -* *y* - the group’s *y* value (when grouping on *y*) +* *x* <VersionBadge version="0.6.12" pr="1916" /> - the group’s *x* value (when grouping on *x*) +* *y* <VersionBadge version="0.6.12" pr="1916" /> - the group’s *y* value (when grouping on *y*) In addition, a reducer may be specified as: @@ -440,7 +440,7 @@ Plot.groupZ({x: "proportion"}, {fill: "species"}) Groups on the first channel of **z**, **fill**, or **stroke**, if any. If none of **z**, **fill**, or **stroke** are channels, then all data (within each facet) is placed into a single group. -## find(*test*) {#find} +## find(*test*) {#find} <VersionBadge version="0.6.12" pr="1914" /> ```js Plot.groupX( diff --git a/docs/transforms/hexbin.md b/docs/transforms/hexbin.md index 1ca25d311b..91198eaf64 100644 --- a/docs/transforms/hexbin.md +++ b/docs/transforms/hexbin.md @@ -197,8 +197,8 @@ The following named reducers are supported: * *variance* - the variance per [Welford’s algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) * *mode* - the value with the most occurrences * *identity* - the array of values -* *x* - the hexagon’s *x* center -* *y* - the hexagon’s *y* center +* *x* <VersionBadge version="0.6.12" pr="1916" /> - the hexagon’s *x* center +* *y* <VersionBadge version="0.6.12" pr="1916" /> - the hexagon’s *y* center In addition, a reducer may be specified as: diff --git a/docs/transforms/shift.md b/docs/transforms/shift.md index 8ab45d3a73..297dbeb8b5 100644 --- a/docs/transforms/shift.md +++ b/docs/transforms/shift.md @@ -13,7 +13,7 @@ onMounted(() => { </script> -# Shift transform <VersionBadge pr="1896" /> +# Shift transform <VersionBadge version="0.6.12" pr="1896" /> The **shift transform** is a specialized [map transform](./map.md) that derives an output **x1** channel by shifting the **x** channel; it can be used with the [difference mark](../marks/difference.md) to show change over time. For example, the chart below shows the price of Apple stock. The <span style="border-bottom: solid #01ab63 3px;">green region</span> shows when the price went up over the given interval, while the <span style="border-bottom: solid #4269d0 3px;">blue region</span> shows when the price went down. diff --git a/img/difference-find.png b/img/difference-find.png new file mode 100644 index 0000000000..06ef816340 Binary files /dev/null and b/img/difference-find.png differ diff --git a/img/difference-shift.png b/img/difference-shift.png new file mode 100644 index 0000000000..fa01ff0ba8 Binary files /dev/null and b/img/difference-shift.png differ diff --git a/img/difference-zero.png b/img/difference-zero.png new file mode 100644 index 0000000000..7cb3a5c9db Binary files /dev/null and b/img/difference-zero.png differ diff --git a/img/observable10.png b/img/observable10.png new file mode 100644 index 0000000000..284a5aacbf Binary files /dev/null and b/img/observable10.png differ diff --git a/img/rect-band.png b/img/rect-band.png new file mode 100644 index 0000000000..dd82d59dd6 Binary files /dev/null and b/img/rect-band.png differ diff --git a/package.json b/package.json index a3258edfc3..2a9dfe76dd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@observablehq/plot", "description": "A JavaScript library for exploratory data visualization.", - "version": "0.6.11", + "version": "0.6.12", "author": { "name": "Observable, Inc.", "url": "https://observablehq.com"