Skip to content

Commit 292d709

Browse files
authored
allow threshold swatches (#972)
1 parent 5cd0d8e commit 292d709

File tree

6 files changed

+65
-9
lines changed

6 files changed

+65
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
*Not yet released. These are forthcoming changes in the main branch.*
66

7-
Swatches legends are now rendered in SVG, supporting patterns and gradients. Swatches legends now require an ordinal color scale and will throw an error if you attempt to use them with a non-ordinal color scale (such as a linear or diverging scale).
7+
Swatches legends are now rendered in SVG, supporting patterns and gradients. Swatches legends now require an *ordinal*, *categorical*, or *threshold* color scale and will throw an error if you attempt to use them with an unsupported color scale type (such as a *linear* or *diverging* scale).
88

99
The new top-level **document** option specifies the [document](https://developer.mozilla.org/en-US/docs/Web/API/Document) used to create plot elements. It defaults to window.document, but can be changed to another document, say when using a virtual DOM library for server-side rendering in Node.
1010

src/legends/swatches.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {inferFontVariant} from "../axes.js";
33
import {maybeAutoTickFormat} from "../axis.js";
44
import {Context, create} from "../context.js";
55
import {isNoneish, maybeColorChannel, maybeNumberChannel} from "../options.js";
6-
import {isOrdinalScale} from "../scales.js";
6+
import {isOrdinalScale, isThresholdScale} from "../scales.js";
77
import {applyInlineStyles, impliedString, maybeClassName} from "../style.js";
88

99
function maybeScale(scale, key) {
@@ -14,7 +14,7 @@ function maybeScale(scale, key) {
1414
}
1515

1616
export function legendSwatches(color, options) {
17-
if (!isOrdinalScale(color)) throw new Error(`swatches legend requires ordinal color scale (not ${color.type})`);
17+
if (!isOrdinalScale(color) && !isThresholdScale(color)) throw new Error(`swatches legend requires ordinal or threshold color scale (not ${color.type})`);
1818
return legendItems(
1919
color,
2020
options,

src/scales.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ export function isOrdinalScale({type}) {
306306
return type === "ordinal" || type === "point" || type === "band" || type === ordinalImplicit;
307307
}
308308

309-
function isThresholdScale({type}) {
309+
export function isThresholdScale({type}) {
310310
return type === "threshold";
311311
}
312312

test/legends/legends-test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ it(`Plot.legend({color: {type: "identity"}}) returns undefined`, () => {
77
});
88

99
it(`Plot.legend({legend: "swatches", color: {type: "<not-ordinal>"}}) throws an error`, () => {
10-
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "linear"}}), /swatches legend requires ordinal color scale \(not linear\)/);
11-
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "diverging"}}), /swatches legend requires ordinal color scale \(not diverging\)/);
10+
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "linear"}}), /swatches legend requires ordinal/);
11+
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "linear"}}), /\(not linear\)/);
12+
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "diverging"}}), /swatches legend requires ordinal/);
13+
assert.throws(() => Plot.legend({legend: "swatches", color: {type: "diverging"}}), /\(not diverging\)/);
1214
});
1315

1416
it("Plot.legend({}) throws an error", () => {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<div class="plot" style="--swatchWidth: 15px; --swatchHeight: 15px; font-variant: tabular-nums;">
2+
<style>
3+
.plot {
4+
font-family: system-ui, sans-serif;
5+
font-size: 10px;
6+
margin-bottom: 0.5em;
7+
margin-left: 0px;
8+
}
9+
10+
.plot-swatch svg {
11+
width: var(--swatchWidth);
12+
height: var(--swatchHeight);
13+
margin-right: 0.5em;
14+
}
15+
16+
.plot {
17+
display: flex;
18+
align-items: center;
19+
min-height: 33px;
20+
flex-wrap: wrap;
21+
}
22+
23+
.plot-swatch {
24+
display: inline-flex;
25+
align-items: center;
26+
margin-right: 1em;
27+
}
28+
</style><span class="plot-swatch"><svg fill="#320a5e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
29+
<rect width="100%" height="100%"></rect>
30+
</svg>200</span><span class="plot-swatch"><svg fill="#781c6d" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
31+
<rect width="100%" height="100%"></rect>
32+
</svg>800</span><span class="plot-swatch"><svg fill="#bc3754" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
33+
<rect width="100%" height="100%"></rect>
34+
</svg>1,800</span><span class="plot-swatch"><svg fill="#ed6925" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
35+
<rect width="100%" height="100%"></rect>
36+
</svg>3,201</span><span class="plot-swatch"><svg fill="#fbb61a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
37+
<rect width="100%" height="100%"></rect>
38+
</svg>5,001</span><span class="plot-swatch"><svg fill="#fcffa4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
39+
<rect width="100%" height="100%"></rect>
40+
</svg>7,201</span>
41+
</div>

test/plots/legend-color.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export function colorLegendThresholdTickSize() {
178178
});
179179
}
180180

181-
// This quantile scale is implicitly converted to a threshold scale!
181+
// Quantile scales are implicitly converted to threshold scales.
182182
export function colorLegendQuantile() {
183183
return Plot.legend({
184184
color: {
@@ -192,7 +192,6 @@ export function colorLegendQuantile() {
192192
});
193193
}
194194

195-
// This quantile scale is implicitly converted to a threshold scale!
196195
export function colorLegendQuantileImplicit() {
197196
return Plot.plot({
198197
color: {
@@ -208,7 +207,21 @@ export function colorLegendQuantileImplicit() {
208207
}).legend("color");
209208
}
210209

211-
// Quantize scales are implicitly converted to a threshold scale
210+
export function colorLegendQuantileSwatches() {
211+
return Plot.legend({
212+
legend: "swatches",
213+
color: {
214+
type: "quantile",
215+
scheme: "inferno",
216+
domain: d3.range(100).map(i => i ** 2),
217+
n: 7,
218+
label: "Inferno"
219+
},
220+
tickFormat: ",d"
221+
});
222+
}
223+
224+
// Quantize scales are implicitly converted to threshold scales.
212225
export function colorLegendQuantize() {
213226
return Plot.legend({
214227
color: {

0 commit comments

Comments
 (0)