Skip to content

Commit 90d2238

Browse files
mbostockFil
andauthored
handle missing scales (#939)
Co-authored-by: Philippe Rivière <[email protected]> Co-authored-by: Philippe Rivière <[email protected]>
1 parent f60e7f3 commit 90d2238

File tree

9 files changed

+136
-11
lines changed

9 files changed

+136
-11
lines changed

src/marks/bar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ export class AbstractBar extends Mark {
4747
}
4848
_width({x}, {x: X}, {marginRight, marginLeft, width}) {
4949
const {insetLeft, insetRight} = this;
50-
const bandwidth = X ? x.bandwidth() : width - marginRight - marginLeft;
50+
const bandwidth = X && x ? x.bandwidth() : width - marginRight - marginLeft;
5151
return Math.max(0, bandwidth - insetLeft - insetRight);
5252
}
5353
_height({y}, {y: Y}, {marginTop, marginBottom, height}) {
5454
const {insetTop, insetBottom} = this;
55-
const bandwidth = Y ? y.bandwidth() : height - marginTop - marginBottom;
55+
const bandwidth = Y && y ? y.bandwidth() : height - marginTop - marginBottom;
5656
return Math.max(0, bandwidth - insetTop - insetBottom);
5757
}
5858
}

src/marks/tick.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ export class TickX extends AbstractTick {
6161
_x2(scales, {x: X}) {
6262
return i => X[i];
6363
}
64-
_y1(scales, {y: Y}, {marginTop}) {
64+
_y1({y}, {y: Y}, {marginTop}) {
6565
const {insetTop} = this;
66-
return Y ? i => Y[i] + insetTop : marginTop + insetTop;
66+
return Y && y ? i => Y[i] + insetTop : marginTop + insetTop;
6767
}
6868
_y2({y}, {y: Y}, {height, marginBottom}) {
6969
const {insetBottom} = this;
70-
return Y ? i => Y[i] + y.bandwidth() - insetBottom : height - marginBottom - insetBottom;
70+
return Y && y ? i => Y[i] + y.bandwidth() - insetBottom : height - marginBottom - insetBottom;
7171
}
7272
}
7373

@@ -94,13 +94,13 @@ export class TickY extends AbstractTick {
9494
_transform(selection, {y}, dx, dy) {
9595
selection.call(applyTransform, null, y, dx, offset + dy);
9696
}
97-
_x1(scales, {x: X}, {marginLeft}) {
97+
_x1({x}, {x: X}, {marginLeft}) {
9898
const {insetLeft} = this;
99-
return X ? i => X[i] + insetLeft : marginLeft + insetLeft;
99+
return X && x ? i => X[i] + insetLeft : marginLeft + insetLeft;
100100
}
101101
_x2({x}, {x: X}, {width, marginRight}) {
102102
const {insetRight} = this;
103-
return X ? i => X[i] + x.bandwidth() - insetRight : width - marginRight - insetRight;
103+
return X && x ? i => X[i] + x.bandwidth() - insetRight : width - marginRight - insetRight;
104104
}
105105
_y1(scales, {y: Y}) {
106106
return i => Y[i];

src/plot.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {Dimensions} from "./dimensions.js";
66
import {Legends, exposeLegends} from "./legends.js";
77
import {arrayify, isDomainSort, isScaleOptions, keyword, map, range, second, where, yes} from "./options.js";
88
import {Scales, ScaleFunctions, autoScaleRange, exposeScales} from "./scales.js";
9-
import {registry as scaleRegistry} from "./scales/index.js";
9+
import {position, registry as scaleRegistry} from "./scales/index.js";
1010
import {applyInlineStyles, maybeClassName, maybeClip, styles} from "./style.js";
1111
import {basic, initializer} from "./transforms/basic.js";
1212
import {maybeInterval} from "./transforms/interval.js";
@@ -113,6 +113,7 @@ export function plot(options = {}) {
113113

114114
// Reconstruct scales if new scaled channels were created during reinitialization.
115115
if (newByScale.size) {
116+
for (const key of newByScale) if (scaleRegistry.get(key) === position) throw new Error(`initializers cannot declare position scales: ${key}`);
116117
const newScaleDescriptors = Scales(addScaleChannels(new Map(), stateByMark, key => newByScale.has(key)), options);
117118
const newScales = ScaleFunctions(newScaleDescriptors);
118119
Object.assign(scaleDescriptors, newScaleDescriptors);
@@ -346,8 +347,7 @@ function inferChannelScale(channels) {
346347
switch (name) {
347348
case "fill": case "stroke": scale = "color"; break;
348349
case "fillOpacity": case "strokeOpacity": case "opacity": scale = "opacity"; break;
349-
case "r": case "length": case "symbol": scale = name; break;
350-
default: scale = null;
350+
default: scale = scaleRegistry.has(name) ? name : null; break;
351351
}
352352
channel.scale = scale;
353353
}

src/scales.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ export function scaleOrder({range, domain = range}) {
328328
// example, a rect will span the full extent of the chart along a collapsed
329329
// dimension (whereas a dot will simply be drawn in the center).
330330
export function isCollapsed(scale) {
331+
if (scale === undefined) return true; // treat missing scale as collapsed
331332
const domain = scale.domain();
332333
const value = scale(domain[0]);
333334
for (let i = 1, n = domain.length; i < n; ++i) {

test/output/dodgeRule.svg

Lines changed: 56 additions & 0 deletions
Loading

test/output/dodgeTick.svg

Lines changed: 56 additions & 0 deletions
Loading

test/plots/dodge-rule.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as Plot from "@observablehq/plot";
2+
3+
export default async function() {
4+
return Plot.ruleX([1, 2, 3], Plot.dodgeY()).plot();
5+
}

test/plots/dodge-tick.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as Plot from "@observablehq/plot";
2+
3+
export default async function() {
4+
return Plot.tickX([1, 2, 3], Plot.dodgeY()).plot();
5+
}

test/plots/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export {default as diamondsCaratPrice} from "./diamonds-carat-price.js";
5050
export {default as diamondsCaratPriceDots} from "./diamonds-carat-price-dots.js";
5151
export {default as diamondsCaratSampling} from "./diamonds-carat-sampling.js";
5252
export {default as documentationLinks} from "./documentation-links.js";
53+
export {default as dodgeRule} from "./dodge-rule.js";
5354
export {default as dodgeTextRadius} from "./dodge-text-radius.js";
55+
export {default as dodgeTick} from "./dodge-tick.js";
5456
export {default as dotSort} from "./dot-sort.js";
5557
export {default as downloads} from "./downloads.js";
5658
export {default as downloadsOrdinal} from "./downloads-ordinal.js";

0 commit comments

Comments
 (0)