Skip to content

Commit

Permalink
Rule.stroke
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Nov 17, 2020
1 parent 5ff0356 commit 0b4285b
Show file tree
Hide file tree
Showing 6 changed files with 1,581 additions and 41 deletions.
11 changes: 0 additions & 11 deletions src/mark.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@ export class Mark {
Object.entries(channels).filter(([, channel]) => channel),
([name, channel]) => [name, Channel(data, channel)]
));

// Enforce that all present channels have the same length.
for (const key in channels) {
const {value: {length}} = channels[key];
for (const otherKey in channels) {
if (key === otherKey) continue;
const {value: {length: otherLength}} = channels[otherKey];
if (otherLength !== length) throw new Error("inconsistent channel length");
}
break;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/marks/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class BarX extends Bar {
{
x: {value: x, scale: "x"},
y: {value: y, scale: "y", type: "band"},
x0: {value: [0], scale: "x"} // ensure the x-domain includes zero
_: {value: [0], scale: "x"} // ensure the x-domain includes zero
},
style
);
Expand Down Expand Up @@ -100,7 +100,7 @@ export class BarY extends Bar {
{
x: {value: x, scale: "x", type: "band"},
y: {value: y, scale: "y"},
y0: {value: [0], scale: "y"} // ensure the y-domain includes zero
_: {value: [0], scale: "y"} // ensure the y-domain includes zero
},
style
);
Expand Down
100 changes: 73 additions & 27 deletions src/marks/rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,62 @@ export class RuleX extends Mark {
constructor(
data,
{
x = identity
x = identity,
y1,
y2,
stroke
} = {},
{
stroke = "currentColor",
stroke: fixedStroke = stroke === undefined ? "currentColor" : undefined,
strokeWidth,
strokeOpacity,
strokeOpacity
} = {}
) {
super(data, {x: {value: x, scale: "x"}});
this.stroke = stroke;
super(
data,
{
x: {value: x, scale: "x"},
y1: y1 && {value: y1, scale: "y"},
y2: y2 && {value: y2, scale: "y"},
stroke: stroke && {value: stroke, scale: "color"}
}
);
this.stroke = fixedStroke;
this.strokeWidth = strokeWidth;
this.strokeOpacity = strokeOpacity;
}
render(I, {x: {scale: x}}, {marginTop, height, marginBottom}) {
render(
I,
{
x: {scale: x},
y: {scale: y} = {},
color: {scale: color} = {}
},
{marginTop, height, marginBottom}
) {
const {
stroke,
strokeWidth,
strokeOpacity,
channels: {
x: {value: X}
x: {value: X},
y1: {value: Y1} = {},
y2: {value: Y2} = {},
stroke: {value: S} = {}
}
} = this;
return create("svg:g")
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth)
.attr("stroke-opacity", strokeOpacity)
.call(g => g.selectAll("line")
.data(I)
.join("line")
.attr("x1", i => Math.round(x(X[i])) + 0.5) // TODO round
.attr("x2", i => Math.round(x(X[i])) + 0.5) // TODO round
.attr("y1", marginTop)
.attr("y2", height - marginBottom))
.call(g => g.selectAll("line")
.data(I)
.join("line")
.attr("stroke", S && (i => color(S[i])))
.attr("x1", i => Math.round(x(X[i])) + 0.5) // TODO round
.attr("x2", i => Math.round(x(X[i])) + 0.5) // TODO round
.attr("y1", Y1 ? i => y(Y1[i]) : marginTop)
.attr("y2", Y2 ? i => y(Y2[i]) : height - marginBottom))
.node();
}
}
Expand All @@ -47,39 +70,62 @@ export class RuleY extends Mark {
constructor(
data,
{
y = identity
x1,
x2,
y = identity,
stroke
} = {},
{
stroke = "currentColor",
stroke: fixedStroke = stroke === undefined ? "currentColor" : undefined,
strokeWidth,
strokeOpacity
} = {}
) {
super(data, {y: {value: y, scale: "y"}});
this.stroke = stroke;
super(
data,
{
x1: x1 && {value: x1, scale: "x"},
x2: x2 && {value: x2, scale: "x"},
y: {value: y, scale: "y"},
stroke: stroke && {value: stroke, scale: "color"}
}
);
this.stroke = fixedStroke;
this.strokeWidth = strokeWidth;
this.strokeOpacity = strokeOpacity;
}
render(I, {y: {scale: y}}, {width, marginLeft, marginRight}) {
render(
I,
{
x: {scale: x} = {},
y: {scale: y},
color: {scale: color} = {}
},
{width, marginLeft, marginRight}
) {
const {
stroke,
strokeWidth,
strokeOpacity,
channels: {
y: {value: Y}
x1: {value: X1} = {},
x2: {value: X2} = {},
y: {value: Y},
stroke: {value: S} = {}
}
} = this;
return create("svg:g")
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth)
.attr("stroke-opacity", strokeOpacity)
.call(g => g.selectAll("line")
.data(I)
.join("line")
.attr("x1", marginLeft)
.attr("x2", width - marginRight)
.attr("y1", i => Math.round(y(Y[i])) + 0.5) // TODO round?
.attr("y2", i => Math.round(y(Y[i])) + 0.5)) // TODO round?
.call(g => g.selectAll("line")
.data(I)
.join("line")
.attr("stroke", S && (i => color(S[i])))
.attr("x1", X1 ? i => x(X1[i]) : marginLeft)
.attr("x2", X2 ? i => x(X2[i]) : width - marginRight)
.attr("y1", i => Math.round(y(Y[i])) + 0.5) // TODO round?
.attr("y2", i => Math.round(y(Y[i])) + 0.5)) // TODO round?
.node();
}
}
9 changes: 8 additions & 1 deletion src/scales/quantitative.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ function constant(x) {
return () => x;
}

function flip(i) {
return t => i(1 - t);
}

export function ScaleQ(key, scale, encodings, {
nice,
domain = (key === "r" ? inferRadialDomain : inferDomain)(encodings),
Expand All @@ -24,7 +28,10 @@ export function ScaleQ(key, scale, encodings, {
// to interpolate two colors in Lab color space. Other times the interpolate
// function is a “fixed” interpolator independent of the range, as when a
// color scheme such as interpolateRdBu is used.
if (interpolate.length === 1) interpolate = constant(interpolate);
if (interpolate.length === 1) {
if (invert) interpolate = flip(interpolate);
interpolate = constant(interpolate);
}
scale.interpolate(interpolate);
}
if (range !== undefined) scale.range(range);
Expand Down
Loading

0 comments on commit 0b4285b

Please sign in to comment.