Skip to content

Commit

Permalink
Fix a bug in area step interpolation.
Browse files Browse the repository at this point in the history
When computing the reversed baseline, we need to switch between step-before and
step-after, since the points are in reverse order. Otherwise, we're effectively
filling the gap between step-before and step-after.
  • Loading branch information
mbostock committed Oct 7, 2011
1 parent fe61281 commit 4d1de5e
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 22 deletions.
17 changes: 11 additions & 6 deletions d3.js
Original file line number Diff line number Diff line change
Expand Up @@ -3149,16 +3149,17 @@ function d3_svg_area(projection) {
x1 = d3_svg_lineX,
y0 = 0,
y1 = d3_svg_lineY,
interpolate = "linear",
interpolator = d3_svg_lineInterpolators[interpolate],
interpolate,
i0,
i1,
tension = .7;

function area(d) {
if (d.length < 1) return null;
var points0 = d3_svg_linePoints(this, d, x0, y0),
points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
return "M" + interpolator(projection(points1), tension)
+ "L" + interpolator(projection(points0.reverse()), tension)
return "M" + i0(projection(points1), tension)
+ "L" + i1(projection(points0.reverse()), tension)
+ "Z";
}

Expand Down Expand Up @@ -3200,7 +3201,8 @@ function d3_svg_area(projection) {

area.interpolate = function(x) {
if (!arguments.length) return interpolate;
interpolator = d3_svg_lineInterpolators[interpolate = x];
i0 = d3_svg_lineInterpolators[interpolate = x];
i1 = i0.reverse || i0;
return area;
};

Expand All @@ -3210,9 +3212,12 @@ function d3_svg_area(projection) {
return area;
};

return area;
return area.interpolate("linear");
}

d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;

d3.svg.area = function() {
return d3_svg_area(Object);
};
Expand Down
4 changes: 2 additions & 2 deletions d3.min.js

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions src/svg/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ function d3_svg_area(projection) {
x1 = d3_svg_lineX,
y0 = 0,
y1 = d3_svg_lineY,
interpolate = "linear",
interpolator = d3_svg_lineInterpolators[interpolate],
interpolate,
i0,
i1,
tension = .7;

function area(d) {
if (d.length < 1) return null;
var points0 = d3_svg_linePoints(this, d, x0, y0),
points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
return "M" + interpolator(projection(points1), tension)
+ "L" + interpolator(projection(points0.reverse()), tension)
return "M" + i0(projection(points1), tension)
+ "L" + i1(projection(points0.reverse()), tension)
+ "Z";
}

Expand Down Expand Up @@ -54,7 +55,8 @@ function d3_svg_area(projection) {

area.interpolate = function(x) {
if (!arguments.length) return interpolate;
interpolator = d3_svg_lineInterpolators[interpolate = x];
i0 = d3_svg_lineInterpolators[interpolate = x];
i1 = i0.reverse || i0;
return area;
};

Expand All @@ -64,9 +66,12 @@ function d3_svg_area(projection) {
return area;
};

return area;
return area.interpolate("linear");
}

d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;

d3.svg.area = function() {
return d3_svg_area(Object);
};
Expand Down
2 changes: 1 addition & 1 deletion test/svg/area-radial-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ suite.addBatch({
},
"interpolate can be defined as a constant": function(area) {
var a = area().interpolate("step-before");
assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V-0.540302H0.841471L0,-1V0H0Z");
assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V-0.540302H0.841471L0,-1H0V0Z");
assert.equal(a.interpolate(), "step-before");
},

Expand Down
15 changes: 8 additions & 7 deletions test/svg/area-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ suite.addBatch({
},
"interpolate can be defined as a constant": function(area) {
var a = area().interpolate("step-before");
assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V1H1L1,0V0H0Z");
assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V1H1L1,0H0V0Z");
assert.equal(a.interpolate(), "step-before");
},

Expand All @@ -157,8 +157,8 @@ suite.addBatch({
},

"interpolate(step)": {
"supports step-before interpolation": testInterpolation("step-before"),
"supports step-after interpolation": testInterpolation("step-after")
"supports step-before interpolation": testInterpolation("step-before", "step-after"),
"supports step-after interpolation": testInterpolation("step-after", "step-before")
},

"interpolate(basis)": {
Expand All @@ -178,12 +178,13 @@ suite.addBatch({
});

// An area is just two lines, with one reversed.
function testInterpolation(interpolate) {
function testInterpolation(i0, i1) {
if (arguments.length < 2) i1 = i0;
return function(area) {
var a = area().interpolate(interpolate),
var a = area().interpolate(i0),
d = [[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]],
l0 = d3.svg.line().interpolate(interpolate).x(a.x0()).y(a.y0()),
l1 = d3.svg.line().interpolate(interpolate).x(a.x1()).y(a.y1());
l0 = d3.svg.line().interpolate(i1).x(a.x0()).y(a.y0()),
l1 = d3.svg.line().interpolate(i0).x(a.x1()).y(a.y1());
assert.pathEqual(a(d), l1(d) + "L" + l0(d.reverse()).substring(1) + "Z");
};
}
Expand Down

0 comments on commit 4d1de5e

Please sign in to comment.