Better zoom example using d3.svg.brush.

This commit is contained in:
Mike Bostock 2012-01-23 18:15:52 -08:00
Родитель 3e8e4e30eb
Коммит 8b8e31b33a
3 изменённых файлов: 224 добавлений и 5362 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

124
examples/zoom/sp500.csv Normal file
Просмотреть файл

@ -0,0 +1,124 @@
date,price
Jan 2000,1394.46
Feb 2000,1366.42
Mar 2000,1498.58
Apr 2000,1452.43
May 2000,1420.6
Jun 2000,1454.6
Jul 2000,1430.83
Aug 2000,1517.68
Sep 2000,1436.51
Oct 2000,1429.4
Nov 2000,1314.95
Dec 2000,1320.28
Jan 2001,1366.01
Feb 2001,1239.94
Mar 2001,1160.33
Apr 2001,1249.46
May 2001,1255.82
Jun 2001,1224.38
Jul 2001,1211.23
Aug 2001,1133.58
Sep 2001,1040.94
Oct 2001,1059.78
Nov 2001,1139.45
Dec 2001,1148.08
Jan 2002,1130.2
Feb 2002,1106.73
Mar 2002,1147.39
Apr 2002,1076.92
May 2002,1067.14
Jun 2002,989.82
Jul 2002,911.62
Aug 2002,916.07
Sep 2002,815.28
Oct 2002,885.76
Nov 2002,936.31
Dec 2002,879.82
Jan 2003,855.7
Feb 2003,841.15
Mar 2003,848.18
Apr 2003,916.92
May 2003,963.59
Jun 2003,974.5
Jul 2003,990.31
Aug 2003,1008.01
Sep 2003,995.97
Oct 2003,1050.71
Nov 2003,1058.2
Dec 2003,1111.92
Jan 2004,1131.13
Feb 2004,1144.94
Mar 2004,1126.21
Apr 2004,1107.3
May 2004,1120.68
Jun 2004,1140.84
Jul 2004,1101.72
Aug 2004,1104.24
Sep 2004,1114.58
Oct 2004,1130.2
Nov 2004,1173.82
Dec 2004,1211.92
Jan 2005,1181.27
Feb 2005,1203.6
Mar 2005,1180.59
Apr 2005,1156.85
May 2005,1191.5
Jun 2005,1191.33
Jul 2005,1234.18
Aug 2005,1220.33
Sep 2005,1228.81
Oct 2005,1207.01
Nov 2005,1249.48
Dec 2005,1248.29
Jan 2006,1280.08
Feb 2006,1280.66
Mar 2006,1294.87
Apr 2006,1310.61
May 2006,1270.09
Jun 2006,1270.2
Jul 2006,1276.66
Aug 2006,1303.82
Sep 2006,1335.85
Oct 2006,1377.94
Nov 2006,1400.63
Dec 2006,1418.3
Jan 2007,1438.24
Feb 2007,1406.82
Mar 2007,1420.86
Apr 2007,1482.37
May 2007,1530.62
Jun 2007,1503.35
Jul 2007,1455.27
Aug 2007,1473.99
Sep 2007,1526.75
Oct 2007,1549.38
Nov 2007,1481.14
Dec 2007,1468.36
Jan 2008,1378.55
Feb 2008,1330.63
Mar 2008,1322.7
Apr 2008,1385.59
May 2008,1400.38
Jun 2008,1280
Jul 2008,1267.38
Aug 2008,1282.83
Sep 2008,1166.36
Oct 2008,968.75
Nov 2008,896.24
Dec 2008,903.25
Jan 2009,825.88
Feb 2009,735.09
Mar 2009,797.87
Apr 2009,872.81
May 2009,919.14
Jun 2009,919.32
Jul 2009,987.48
Aug 2009,1020.62
Sep 2009,1057.08
Oct 2009,1036.19
Nov 2009,1095.63
Dec 2009,1115.1
Jan 2010,1073.87
Feb 2010,1104.49
Mar 2010,1140.45
1 date price
2 Jan 2000 1394.46
3 Feb 2000 1366.42
4 Mar 2000 1498.58
5 Apr 2000 1452.43
6 May 2000 1420.6
7 Jun 2000 1454.6
8 Jul 2000 1430.83
9 Aug 2000 1517.68
10 Sep 2000 1436.51
11 Oct 2000 1429.4
12 Nov 2000 1314.95
13 Dec 2000 1320.28
14 Jan 2001 1366.01
15 Feb 2001 1239.94
16 Mar 2001 1160.33
17 Apr 2001 1249.46
18 May 2001 1255.82
19 Jun 2001 1224.38
20 Jul 2001 1211.23
21 Aug 2001 1133.58
22 Sep 2001 1040.94
23 Oct 2001 1059.78
24 Nov 2001 1139.45
25 Dec 2001 1148.08
26 Jan 2002 1130.2
27 Feb 2002 1106.73
28 Mar 2002 1147.39
29 Apr 2002 1076.92
30 May 2002 1067.14
31 Jun 2002 989.82
32 Jul 2002 911.62
33 Aug 2002 916.07
34 Sep 2002 815.28
35 Oct 2002 885.76
36 Nov 2002 936.31
37 Dec 2002 879.82
38 Jan 2003 855.7
39 Feb 2003 841.15
40 Mar 2003 848.18
41 Apr 2003 916.92
42 May 2003 963.59
43 Jun 2003 974.5
44 Jul 2003 990.31
45 Aug 2003 1008.01
46 Sep 2003 995.97
47 Oct 2003 1050.71
48 Nov 2003 1058.2
49 Dec 2003 1111.92
50 Jan 2004 1131.13
51 Feb 2004 1144.94
52 Mar 2004 1126.21
53 Apr 2004 1107.3
54 May 2004 1120.68
55 Jun 2004 1140.84
56 Jul 2004 1101.72
57 Aug 2004 1104.24
58 Sep 2004 1114.58
59 Oct 2004 1130.2
60 Nov 2004 1173.82
61 Dec 2004 1211.92
62 Jan 2005 1181.27
63 Feb 2005 1203.6
64 Mar 2005 1180.59
65 Apr 2005 1156.85
66 May 2005 1191.5
67 Jun 2005 1191.33
68 Jul 2005 1234.18
69 Aug 2005 1220.33
70 Sep 2005 1228.81
71 Oct 2005 1207.01
72 Nov 2005 1249.48
73 Dec 2005 1248.29
74 Jan 2006 1280.08
75 Feb 2006 1280.66
76 Mar 2006 1294.87
77 Apr 2006 1310.61
78 May 2006 1270.09
79 Jun 2006 1270.2
80 Jul 2006 1276.66
81 Aug 2006 1303.82
82 Sep 2006 1335.85
83 Oct 2006 1377.94
84 Nov 2006 1400.63
85 Dec 2006 1418.3
86 Jan 2007 1438.24
87 Feb 2007 1406.82
88 Mar 2007 1420.86
89 Apr 2007 1482.37
90 May 2007 1530.62
91 Jun 2007 1503.35
92 Jul 2007 1455.27
93 Aug 2007 1473.99
94 Sep 2007 1526.75
95 Oct 2007 1549.38
96 Nov 2007 1481.14
97 Dec 2007 1468.36
98 Jan 2008 1378.55
99 Feb 2008 1330.63
100 Mar 2008 1322.7
101 Apr 2008 1385.59
102 May 2008 1400.38
103 Jun 2008 1280
104 Jul 2008 1267.38
105 Aug 2008 1282.83
106 Sep 2008 1166.36
107 Oct 2008 968.75
108 Nov 2008 896.24
109 Dec 2008 903.25
110 Jan 2009 825.88
111 Feb 2009 735.09
112 Mar 2009 797.87
113 Apr 2009 872.81
114 May 2009 919.14
115 Jun 2009 919.32
116 Jul 2009 987.48
117 Aug 2009 1020.62
118 Sep 2009 1057.08
119 Oct 2009 1036.19
120 Nov 2009 1095.63
121 Dec 2009 1115.1
122 Jan 2010 1073.87
123 Feb 2010 1104.49
124 Mar 2010 1140.45

Просмотреть файл

@ -1,160 +1,131 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Zoom</title>
<script type="text/javascript" src="../../d3.js"></script>
<script type="text/javascript" src="../../d3.csv.js"></script>
<script type="text/javascript" src="../../d3.time.js"></script>
<style type="text/css">
<meta charset="utf-8">
<script src="../../d3.js"></script>
<script src="../../d3.csv.js"></script>
<script src="../../d3.time.js"></script>
<style>
svg {
font: 10px sans-serif;
}
path {
fill: steelblue;
}
line {
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script type="text/javascript">
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
var w = 960,
h1 = 400,
h2 = 40,
p = 20,
x0, // start of focus region
x1, // end of focus region
xx, // drag state
time = d3.time.format("%Y-%m-%d"),
x = d3.scale.linear().range([0, w]),
y1 = d3.scale.linear().range([h1 - p, 0]),
y2 = d3.scale.linear().range([h2, 0]);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h1 + h2);
</style>
<body>
<script>
// Focus view.
var focus = svg.append("g");
var margin = {top: 10, right: 10, bottom: 100, left: 40},
margin2 = {top: 430, right: 10, bottom: 20, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var formatDate = d3.time.format("%b %Y");
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brush);
var area = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var area2 = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x2(d.date); })
.y0(height2)
.y1(function(d) { return y2(d.price); });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Context view.
var context = svg.append("g")
.attr("transform", "translate(0," + h1 + ")");
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
d3.csv("dji.csv", function(csv) {
var minX,
maxX,
maxY = -Infinity;
d3.csv("sp500.csv", function(data) {
// Compute x- and y-extent.
csv.reverse();
for (var i = 0, n = csv.length, o; i < n; i++) {
o = csv[i];
o = csv[i] = {x: +time.parse(o.Date), y: +o.Close};
if (o.y > maxY) maxY = o.y;
}
minX = csv[0].x;
maxX = csv[n - 1].x;
data.forEach(function(d) {
d.date = formatDate.parse(d.date);
d.price = +d.price;
});
// Update x- and y-scales.
x.domain([minX, maxX]);
y1.domain([0, maxY]);
y2.domain([0, maxY]);
x.domain(d3.extent(data.map(function(d) { return d.date; })));
y.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
x2.domain(x.domain());
y2.domain(y.domain());
// Focus view.
focus.append("path")
.data([csv])
.attr("d", d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(y1(0))
.y1(function(d) { return y1(d.y); }));
.data([data])
.attr("clip-path", "url(#clip)")
.attr("d", area);
focus.append("line")
.attr("x1", 0)
.attr("x2", w)
.attr("y1", y1(0))
.attr("y2", y1(0));
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Context view.
context.append("rect")
.attr("width", w)
.attr("height", h2)
.attr("fill", "none")
.attr("pointer-events", "all")
.attr("cursor", "crosshair")
.on("mousedown", mousedown);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
context.append("path")
.data([csv])
.attr("pointer-events", "none")
.attr("d", d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(y2(0))
.y1(function(d) { return y2(d.y); }));
.data([data])
.attr("d", area2);
context.append("line")
.attr("x1", 0)
.attr("x2", w)
.attr("y1", y2(0))
.attr("y2", y2(0));
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
// Active focus region.
active = context.append("rect")
.attr("pointer-events", "none")
.attr("id", "active")
.attr("x", x(x0 = minX))
.attr("y", 0)
.attr("height", h2)
.attr("width", x(x1 = (minX + 1e11)) - x(x0))
.attr("fill", "lightcoral")
.attr("fill-opacity", .5);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
});
d3.select(window)
.on("mousemove", mousemove)
.on("mouseup", mouseup);
function mousedown() {
xx = x.invert(d3.svg.mouse(this)[0]);
}
function mousemove() {
if (xx != null) {
// Compute the new (clamped) focus region.
var xy = x.invert(d3.svg.mouse(active[0][0])[0]);
if (xx < xy) { x0 = xx; x1 = xy; }
else if (xx > xy) { x0 = xy; x1 = xx; }
else return;
x0 = Math.max(x.domain()[0], x0);
x1 = Math.min(x.domain()[1], x1);
// Update the x-scale. TODO Recycle this scale?
var tx = d3.scale.linear()
.domain([x0, x1])
.range([0, w]);
// Recompute the focus path.
focus.select("path")
.attr("d", d3.svg.area()
.x(function(d) { return tx(d.x); })
.y0(y1(0))
.y1(function(d) { return y1(d.y); }));
// Reposition the active region rect.
active
.attr("x", x(x0))
.attr("width", x(x1) - x(x0));
}
}
function mouseup() {
xx = null;
function brush() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select("path").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
</script>