Skip to content

Commit a76aed5

Browse files
committed
Merge remote-tracking branch 'origin/fix-clip-extent' into 3.3.6
2 parents 0bf3fc1 + ba48daa commit a76aed5

5 files changed

Lines changed: 76 additions & 26 deletions

File tree

d3.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,19 +3046,24 @@ d3 = function() {
30463046
},
30473047
polygonEnd: function() {
30483048
listener = listener_;
3049-
if ((segments = d3.merge(segments)).length) {
3049+
segments = d3.merge(segments);
3050+
var inside = clean && insidePolygon([ x0, y0 ]), visible = segments.length;
3051+
if (inside || visible) {
30503052
listener.polygonStart();
3051-
d3_geo_clipPolygon(segments, compare, inside, interpolate, listener);
3053+
if (inside) {
3054+
listener.lineStart();
3055+
interpolate(null, null, 1, listener);
3056+
listener.lineEnd();
3057+
}
3058+
if (visible) {
3059+
d3_geo_clipPolygon(segments, compare, pointInside, interpolate, listener);
3060+
}
30523061
listener.polygonEnd();
3053-
} else if (insidePolygon([ x0, y0 ])) {
3054-
listener.polygonStart(), listener.lineStart();
3055-
interpolate(null, null, 1, listener);
3056-
listener.lineEnd(), listener.polygonEnd();
30573062
}
30583063
segments = polygon = ring = null;
30593064
}
30603065
};
3061-
function inside(point) {
3066+
function pointInside(point) {
30623067
var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]);
30633068
return i;
30643069
}
@@ -3090,17 +3095,17 @@ d3 = function() {
30903095
listener.point(to[0], to[1]);
30913096
}
30923097
}
3093-
function visible(x, y) {
3098+
function pointVisible(x, y) {
30943099
return x0 <= x && x <= x1 && y0 <= y && y <= y1;
30953100
}
30963101
function point(x, y) {
3097-
if (visible(x, y)) listener.point(x, y);
3102+
if (pointVisible(x, y)) listener.point(x, y);
30983103
}
3099-
var x__, y__, v__, x_, y_, v_, first;
3104+
var x__, y__, v__, x_, y_, v_, first, clean;
31003105
function lineStart() {
31013106
clip.point = linePoint;
31023107
if (polygon) polygon.push(ring = []);
3103-
first = true;
3108+
first = clean = true;
31043109
v_ = false;
31053110
x_ = y_ = NaN;
31063111
}
@@ -3116,7 +3121,7 @@ d3 = function() {
31163121
function linePoint(x, y) {
31173122
x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
31183123
y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
3119-
var v = visible(x, y);
3124+
var v = pointVisible(x, y);
31203125
if (polygon) ring.push([ x, y ]);
31213126
if (first) {
31223127
x__ = x, y__ = y, v__ = v;
@@ -3135,9 +3140,11 @@ d3 = function() {
31353140
}
31363141
listener.point(b[0], b[1]);
31373142
if (!v) listener.lineEnd();
3143+
clean = false;
31383144
} else if (v) {
31393145
listener.lineStart();
31403146
listener.point(x, y);
3147+
clean = false;
31413148
}
31423149
}
31433150
}

d3.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geo/clip-extent.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,26 @@ function d3_geo_clipExtent(x0, y0, x1, y1) {
4646
},
4747
polygonEnd: function() {
4848
listener = listener_;
49-
if ((segments = d3.merge(segments)).length) {
49+
segments = d3.merge(segments);
50+
var inside = clean && insidePolygon([x0, y0]),
51+
visible = segments.length;
52+
if (inside || visible) {
5053
listener.polygonStart();
51-
d3_geo_clipPolygon(segments, compare, inside, interpolate, listener);
54+
if (inside) {
55+
listener.lineStart();
56+
interpolate(null, null, 1, listener);
57+
listener.lineEnd();
58+
}
59+
if (visible) {
60+
d3_geo_clipPolygon(segments, compare, pointInside, interpolate, listener);
61+
}
5262
listener.polygonEnd();
53-
} else if (insidePolygon([x0, y0])) {
54-
listener.polygonStart(), listener.lineStart();
55-
interpolate(null, null, 1, listener);
56-
listener.lineEnd(), listener.polygonEnd();
5763
}
5864
segments = polygon = ring = null;
5965
}
6066
};
6167

62-
function inside(point) {
68+
function pointInside(point) {
6369
var a = corner(point, -1),
6470
i = insidePolygon([a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0]);
6571
return i;
@@ -101,22 +107,23 @@ function d3_geo_clipExtent(x0, y0, x1, y1) {
101107
}
102108
}
103109

104-
function visible(x, y) {
110+
function pointVisible(x, y) {
105111
return x0 <= x && x <= x1 && y0 <= y && y <= y1;
106112
}
107113

108114
function point(x, y) {
109-
if (visible(x, y)) listener.point(x, y);
115+
if (pointVisible(x, y)) listener.point(x, y);
110116
}
111117

112118
var x__, y__, v__, // first point
113119
x_, y_, v_, // previous point
114-
first;
120+
first,
121+
clean;
115122

116123
function lineStart() {
117124
clip.point = linePoint;
118125
if (polygon) polygon.push(ring = []);
119-
first = true;
126+
first = clean = true;
120127
v_ = false;
121128
x_ = y_ = NaN;
122129
}
@@ -137,7 +144,7 @@ function d3_geo_clipExtent(x0, y0, x1, y1) {
137144
function linePoint(x, y) {
138145
x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
139146
y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
140-
var v = visible(x, y);
147+
var v = pointVisible(x, y);
141148
if (polygon) ring.push([x, y]);
142149
if (first) {
143150
x__ = x, y__ = y, v__ = v;
@@ -158,9 +165,11 @@ function d3_geo_clipExtent(x0, y0, x1, y1) {
158165
}
159166
listener.point(b[0], b[1]);
160167
if (!v) listener.lineEnd();
168+
clean = false;
161169
} else if (v) {
162170
listener.lineStart();
163171
listener.point(x, y);
172+
clean = false;
164173
}
165174
}
166175
}

test/geo/clip-extent-test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,40 @@ suite.addBatch({
109109
assert.isTrue(stream.valid);
110110
clip.extent([[0, 0], [960, 500]]);
111111
assert.isFalse(stream.valid);
112+
},
113+
"a polygon that encloses the extent, with a hole": function(d3) {
114+
var clip = d3.geo.clipExtent().extent([[1, 1], [9, 9]]),
115+
stream = clip.stream(testContext);
116+
stream.polygonStart();
117+
stream.lineStart();
118+
stream.point(0, 0);
119+
stream.point(10, 0);
120+
stream.point(10, 10);
121+
stream.point(0, 10);
122+
stream.lineEnd();
123+
stream.lineStart();
124+
stream.point(4, 4);
125+
stream.point(4, 6);
126+
stream.point(6, 6);
127+
stream.point(6, 4);
128+
stream.lineEnd();
129+
stream.polygonEnd();
130+
assert.deepEqual(testContext.buffer(), [
131+
{type: "polygonStart"},
132+
{type: "lineStart"},
133+
{type: "point", x: 1, y: 1},
134+
{type: "point", x: 9, y: 1},
135+
{type: "point", x: 9, y: 9},
136+
{type: "point", x: 1, y: 9},
137+
{type: "lineEnd"},
138+
{type: "lineStart"},
139+
{type: "point", x: 4, y: 4},
140+
{type: "point", x: 4, y: 6},
141+
{type: "point", x: 6, y: 6},
142+
{type: "point", x: 6, y: 4},
143+
{type: "lineEnd"},
144+
{type: "polygonEnd"}
145+
]);
112146
}
113147
}
114148
}

test/geo/path-benchmark

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var fs = require("fs"),
44
d3 = require("../../");
55

66
var formatNumber = d3.format(",.02r"),
7-
projection = d3.geo.stereographic().clipAngle(150),
7+
projection = d3.geo.stereographic().clipAngle(150).clipExtent([[0, 0], [960, 500]]),
88
path = d3.geo.path().projection(projection),
99
graticule = d3.geo.graticule().step([1, 1]),
1010
circle = d3.geo.circle().angle(30),

0 commit comments

Comments
 (0)