Skip to content

Commit 36a873c

Browse files
authored
fix for null scales (#759)
1 parent 4663ef3 commit 36a873c

File tree

6 files changed

+53
-6
lines changed

6 files changed

+53
-6
lines changed

src/legends.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {rgb} from "d3";
2-
import {isObject} from "./options.js";
2+
import {isScaleOptions} from "./options.js";
33
import {normalizeScale} from "./scales.js";
44
import {legendRamp} from "./legends/ramp.js";
55
import {legendSwatches, legendSymbols} from "./legends/swatches.js";
@@ -13,17 +13,17 @@ const legendRegistry = new Map([
1313
export function legend(options = {}) {
1414
for (const [key, value] of legendRegistry) {
1515
const scale = options[key];
16-
if (isObject(scale)) { // e.g., ignore {color: "red"}
16+
if (isScaleOptions(scale)) { // e.g., ignore {color: "red"}
1717
let hint;
1818
// For symbol legends, pass a hint to the symbol scale.
1919
if (key === "symbol") {
20-
const {fill, stroke = fill === undefined && isObject(options.color) ? "color" : undefined} = options;
20+
const {fill, stroke = fill === undefined && isScaleOptions(options.color) ? "color" : undefined} = options;
2121
hint = {fill, stroke};
2222
}
2323
return value(
2424
normalizeScale(key, scale, hint),
2525
legendOptions(scale, options),
26-
key => isObject(options[key]) ? normalizeScale(key, options[key]) : null
26+
key => isScaleOptions(options[key]) ? normalizeScale(key, options[key]) : null
2727
);
2828
}
2929
}
@@ -75,7 +75,7 @@ export function Legends(scales, options) {
7575
const legends = [];
7676
for (const [key, value] of legendRegistry) {
7777
const o = options[key];
78-
if (o && o.legend) {
78+
if (o?.legend && (key in scales)) {
7979
const legend = value(scales[key], legendOptions(scales[key], o), key => scales[key]);
8080
if (legend != null) legends.push(legend);
8181
}

src/options.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,16 @@ export function arrayify(data, type) {
7474

7575
// Disambiguates an options object (e.g., {y: "x2"}) from a primitive value.
7676
export function isObject(option) {
77-
return option && option.toString === objectToString;
77+
return option?.toString === objectToString;
78+
}
79+
80+
// Disambiguates a scale options object (e.g., {color: {type: "linear"}}) from
81+
// some other option (e.g., {color: "red"}). When creating standalone legends,
82+
// this is used to test whether a scale is defined; this should be consistent
83+
// with inferScaleType when there are no channels associated with the scale, and
84+
// if this returns true, then normalizeScale must return non-null.
85+
export function isScaleOptions(option) {
86+
return isObject(option) && (option.type !== undefined || option.domain !== undefined);
7887
}
7988

8089
// Disambiguates an options object (e.g., {y: "x2"}) from a channel value

test/legends/legends-test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ it("Plot.legend({color: {type:'identity'}}) returns undefined", () => {
55
const l = Plot.legend({color: {type: "identity"}});
66
assert.strictEqual(l, undefined);
77
});
8+
9+
it("Plot.legend({}) throws an error", () => {
10+
assert.throws(() => Plot.legend({}), /unknown legend type/);
11+
});
12+
13+
it("Plot.legend({color: {}}) throws an error", () => {
14+
assert.throws(() => Plot.legend({color: {}}), /unknown legend type/);
15+
});

test/output/emptyLegend.svg

Lines changed: 17 additions & 0 deletions
Loading

test/plots/empty-legend.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as Plot from "@observablehq/plot";
2+
3+
export default async function() {
4+
return Plot.plot({
5+
color: {
6+
legend: true // ignored because no color scale
7+
},
8+
marks: [
9+
Plot.frame()
10+
]
11+
});
12+
}

test/plots/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export {default as diamondsCaratPrice} from "./diamonds-carat-price.js";
4040
export {default as diamondsCaratPriceDots} from "./diamonds-carat-price-dots.js";
4141
export {default as documentationLinks} from "./documentation-links.js";
4242
export {default as empty} from "./empty.js";
43+
export {default as emptyLegend} from "./empty-legend.js";
4344
export {default as emptyX} from "./empty-x.js";
4445
export {default as figcaption} from "./figcaption.js";
4546
export {default as figcaptionHtml} from "./figcaption-html.js";

0 commit comments

Comments
 (0)