Skip to content

Commit cd645ec

Browse files
committed
Fix a bug in scale.invert. Add svg.mouse.
1 parent 16617a2 commit cd645ec

10 files changed

Lines changed: 205 additions & 72 deletions

File tree

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ d3.svg.js: \
5454
src/svg/svg.js \
5555
src/svg/arc.js \
5656
src/svg/line.js \
57-
src/svg/area.js
57+
src/svg/area.js \
58+
src/svg/mouse.js
5859

5960
d3.geo.js: \
6061
src/geo/geo.js \

d3.js

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
d3 = {version: "0.10.0"}; // semver
1+
d3 = {version: "0.11.0"}; // semver
22
if (!Date.now) Date.now = function() {
33
return +new Date();
44
};
@@ -705,7 +705,7 @@ function d3_selection(groups) {
705705
for (var i = 0, n = group.length; i < n; i++) {
706706
if (node = group[i]) {
707707
subgroup.push(subnode = select(node));
708-
if (subnode) subnode.__data__ = node.__data__;
708+
if (subnode && !subnode.__data__) subnode.__data__ = node.__data__;
709709
} else {
710710
subgroup.push(null);
711711
}
@@ -1392,23 +1392,25 @@ d3.scale.linear = function() {
13921392
x1 = 1,
13931393
y0 = 0,
13941394
y1 = 1,
1395-
k = 1 / (x1 - x0),
1395+
kx = 1 / (x1 - x0),
1396+
ky = (x1 - x0) / (y1 - y0),
13961397
i = d3.interpolate(y0, y1);
13971398

13981399
function scale(x) {
1399-
return i((x - x0) * k);
1400+
return i((x - x0) * kx);
14001401
}
14011402

1402-
scale.invert = function(x) {
1403-
return (x - y0) / k + x0; // TODO assumes number?
1403+
scale.invert = function(y) {
1404+
return (y - y0) * ky + x0; // TODO assumes number?
14041405
};
14051406

14061407
/** @param {*=} x */
14071408
scale.domain = function(x) {
14081409
if (!arguments.length) return [x0, x1];
14091410
x0 = x[0];
14101411
x1 = x[1];
1411-
k = 1 / (x1 - x0);
1412+
kx = 1 / (x1 - x0);
1413+
ky = (x1 - x0) / (y1 - y0);
14121414
return scale;
14131415
};
14141416

@@ -1417,6 +1419,7 @@ d3.scale.linear = function() {
14171419
if (!arguments.length) return [y0, y1];
14181420
y0 = x[0];
14191421
y1 = x[1];
1422+
ky = (x1 - x0) / (y1 - y0);
14201423
i = d3.interpolate(y0, y1); // TODO allow override?
14211424
return scale;
14221425
};
@@ -1753,6 +1756,30 @@ d3.svg.area = function() {
17531756

17541757
return area;
17551758
};
1759+
d3.svg.mouse = function(container) {
1760+
var point = (container.ownerSVGElement || container).createSVGPoint();
1761+
if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
1762+
var svg = d3.select(document.body)
1763+
.append("svg:svg")
1764+
.style("position", "absolute")
1765+
.style("top", 0)
1766+
.style("left", 0);
1767+
var ctm = svg[0][0].getScreenCTM();
1768+
d3_mouse_bug44083 = !(ctm.f || ctm.e);
1769+
svg.remove();
1770+
}
1771+
if (d3_mouse_bug44083) {
1772+
point.x = d3.event.pageX;
1773+
point.y = d3.event.pageY;
1774+
} else {
1775+
point.x = d3.event.clientX;
1776+
point.y = d3.event.clientY;
1777+
}
1778+
return point.matrixTransform(container.getScreenCTM().inverse());
1779+
};
1780+
1781+
// https://bugs.webkit.org/show_bug.cgi?id=44083
1782+
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
17561783
d3.geo = {};
17571784
// Derived from Tom Carden's Albers implementation for Protovis.
17581785
// http://gist.github.com/476238

d3.min.js

Lines changed: 53 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<li><a href="stream/stream.html">stream</a></li>
2323
<li><a href="stream/stack.html">stack</a></li>
2424
<li><a href="symbol-map/symbol-map.html">symbol-map</a></li>
25+
<li><a href="zoom/zoom.html">zoom</a></li>
2526
</ul>
2627
</body>
2728
</html>

examples/zoom/zoom.html

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
h1 = 400,
2828
h2 = 40,
2929
p = 20,
30+
x0, // start of focus region
31+
x1, // end of focus region
32+
xx, // drag state
3033
x = d3.scale.linear().range([0, w]),
3134
y1 = d3.scale.linear().range([h1 - p, 0]),
3235
y2 = d3.scale.linear().range([h2, 0]);
@@ -36,6 +39,13 @@
3639
.attr("width", w)
3740
.attr("height", h1 + h2);
3841

42+
// Focus view.
43+
var focus = svg.append("svg:g");
44+
45+
// Context view.
46+
var context = svg.append("svg:g")
47+
.attr("transform", "translate(0," + h1 + ")");
48+
3949
d3.csv("dji.csv", function(csv) {
4050
var minX = Infinity,
4151
maxX = -Infinity,
@@ -50,14 +60,12 @@
5060
if (o.y > maxY) maxY = o.y;
5161
}
5262

53-
// Update x- and y-scales. TODO y1 domain is filtered.
63+
// Update x- and y-scales.
5464
x.domain([minX, maxX]);
5565
y1.domain([0, maxY]);
5666
y2.domain([0, maxY]);
5767

5868
// Focus view.
59-
var focus = svg.append("svg:g");
60-
6169
focus.append("svg:path")
6270
.data([csv])
6371
.attr("d", d3.svg.area()
@@ -72,11 +80,17 @@
7280
.attr("y2", y1(0));
7381

7482
// Context view.
75-
var context = svg.append("svg:g")
76-
.attr("transform", "translate(0," + h1 + ")");
83+
context.append("svg:rect")
84+
.attr("width", w)
85+
.attr("height", h2)
86+
.attr("fill", "none")
87+
.attr("pointer-events", "all")
88+
.attr("cursor", "crosshair")
89+
.on("mousedown", mousedown);
7790

7891
context.append("svg:path")
7992
.data([csv])
93+
.attr("pointer-events", "none")
8094
.attr("d", d3.svg.area()
8195
.x(function(d) { return x(d.x); })
8296
.y0(y2(0))
@@ -87,8 +101,61 @@
87101
.attr("x2", w)
88102
.attr("y1", y2(0))
89103
.attr("y2", y2(0));
104+
105+
// Active focus region.
106+
active = context.append("svg:rect")
107+
.attr("pointer-events", "none")
108+
.attr("id", "active")
109+
.attr("x", x(x0 = minX))
110+
.attr("y", 0)
111+
.attr("height", h2)
112+
.attr("width", x(x1 = (minX + 1e11)) - x(x0))
113+
.attr("fill", "lightcoral")
114+
.attr("fill-opacity", .5);
90115
});
91116

117+
d3.select(window)
118+
.on("mousemove", mousemove)
119+
.on("mouseup", mouseup);
120+
121+
function mousedown() {
122+
xx = x.invert(d3.svg.mouse(this).x);
123+
}
124+
125+
function mousemove() {
126+
if (xx != null) {
127+
128+
// Compute the new focus region.
129+
var xy = x.invert(d3.svg.mouse(active[0][0]).x);
130+
if (xx < xy) { x0 = xx; x1 = xy; }
131+
else if (xx > xy) { x0 = xy; x1 = xx; }
132+
else return;
133+
134+
// Clamp the focus region.
135+
x0 = Math.max(x.domain()[0], x0);
136+
x1 = Math.min(x.domain()[1], x1);
137+
138+
// Update the display. TODO Recycle this scale?
139+
var tx = d3.scale.linear()
140+
.domain([x0, x1])
141+
.range([0, w]);
142+
143+
focus.select("path")
144+
.attr("d", d3.svg.area()
145+
.x(function(d) { return tx(d.x); })
146+
.y0(y1(0))
147+
.y1(function(d) { return y1(d.y); }));
148+
149+
active
150+
.attr("x", x(x0))
151+
.attr("width", x(x1) - x(x0));
152+
}
153+
}
154+
155+
function mouseup() {
156+
xx = null;
157+
}
158+
92159
function parseDate(d) {
93160
return Date.UTC.apply(Date, d.split("-"));
94161
}

src/core/core.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d3 = {version: "0.10.0"}; // semver
1+
d3 = {version: "0.11.0"}; // semver

src/core/selection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function d3_selection(groups) {
3333
for (var i = 0, n = group.length; i < n; i++) {
3434
if (node = group[i]) {
3535
subgroup.push(subnode = select(node));
36-
if (subnode) subnode.__data__ = node.__data__;
36+
if (subnode && !subnode.__data__) subnode.__data__ = node.__data__;
3737
} else {
3838
subgroup.push(null);
3939
}

src/externs.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ d3.svg = {
106106
line: {
107107
x: 1,
108108
y: 1
109+
},
110+
mouse: {
111+
ownerSVGElement: 1,
112+
createSVGPoint: 1,
113+
getScreenCTM: 1,
114+
e: 1,
115+
f: 1,
116+
inverse: 1,
117+
matrixTransform: 1
109118
}
110119
};
111120

src/scale/linear.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,25 @@ d3.scale.linear = function() {
33
x1 = 1,
44
y0 = 0,
55
y1 = 1,
6-
k = 1 / (x1 - x0),
6+
kx = 1 / (x1 - x0),
7+
ky = (x1 - x0) / (y1 - y0),
78
i = d3.interpolate(y0, y1);
89

910
function scale(x) {
10-
return i((x - x0) * k);
11+
return i((x - x0) * kx);
1112
}
1213

13-
scale.invert = function(x) {
14-
return (x - y0) / k + x0; // TODO assumes number?
14+
scale.invert = function(y) {
15+
return (y - y0) * ky + x0; // TODO assumes number?
1516
};
1617

1718
/** @param {*=} x */
1819
scale.domain = function(x) {
1920
if (!arguments.length) return [x0, x1];
2021
x0 = x[0];
2122
x1 = x[1];
22-
k = 1 / (x1 - x0);
23+
kx = 1 / (x1 - x0);
24+
ky = (x1 - x0) / (y1 - y0);
2325
return scale;
2426
};
2527

@@ -28,6 +30,7 @@ d3.scale.linear = function() {
2830
if (!arguments.length) return [y0, y1];
2931
y0 = x[0];
3032
y1 = x[1];
33+
ky = (x1 - x0) / (y1 - y0);
3134
i = d3.interpolate(y0, y1); // TODO allow override?
3235
return scale;
3336
};

src/svg/mouse.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
d3.svg.mouse = function(container) {
2+
var point = (container.ownerSVGElement || container).createSVGPoint();
3+
if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
4+
var svg = d3.select(document.body)
5+
.append("svg:svg")
6+
.style("position", "absolute")
7+
.style("top", 0)
8+
.style("left", 0);
9+
var ctm = svg[0][0].getScreenCTM();
10+
d3_mouse_bug44083 = !(ctm.f || ctm.e);
11+
svg.remove();
12+
}
13+
if (d3_mouse_bug44083) {
14+
point.x = d3.event.pageX;
15+
point.y = d3.event.pageY;
16+
} else {
17+
point.x = d3.event.clientX;
18+
point.y = d3.event.clientY;
19+
}
20+
return point.matrixTransform(container.getScreenCTM().inverse());
21+
};
22+
23+
// https://bugs.webkit.org/show_bug.cgi?id=44083
24+
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;

0 commit comments

Comments
 (0)