Created
September 10, 2012 11:55
-
-
Save drsm79/3690530 to your computer and use it in GitHub Desktop.
d3 with CouchDB using views
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
import requests | |
import json | |
import time | |
reader = csv.DictReader(open('_attachments/sp500.csv', 'rb')) | |
database = "http://127.0.0.1:5984/d3apps4" | |
to_upload = {"docs": []} | |
for row in reader: | |
# Convert the date into something more suitable for CouchDB | |
row['date'] = 1000 * time.mktime(time.strptime(row['date'], "%b %Y")) | |
to_upload['docs'].append(row) | |
print requests.post("%s/_bulk_docs" % database, | |
headers={'content-type': 'application/json'}, | |
data=json.dumps(to_upload)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="http://mbostock.github.com/d3/d3.js?2.7.2"></script> | |
<style> | |
svg { | |
font: 10px sans-serif; | |
} | |
path { | |
fill: steelblue; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.brush .extent { | |
stroke: #fff; | |
fill-opacity: .125; | |
shape-rendering: crispEdges; | |
} | |
</style> | |
<body> | |
<script> | |
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 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 + ")"); | |
var context = svg.append("g") | |
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); | |
function sortOnDate(a, b){ | |
if (a.date > b.date) return 1; | |
if (a.date < b.date) return -1; | |
return 0; | |
} | |
d3.json("_view/pricetimeseries", function(viewdata) { | |
// We just want rows from the view in the visualisation | |
data = viewdata["rows"]; | |
data.forEach(function(d) { | |
// the key holds the date, in seconds | |
d.date = new Date(d.key); | |
d.price = +d.value; | |
}); | |
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.append("path") | |
.data([data]) | |
.attr("clip-path", "url(#clip)") | |
.attr("d", area); | |
focus.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
focus.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
context.append("path") | |
.data([data]) | |
.attr("d", area2); | |
context.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height2 + ")") | |
.call(xAxis2); | |
context.append("g") | |
.attr("class", "x brush") | |
.call(brush) | |
.selectAll("rect") | |
.attr("y", -6) | |
.attr("height", height2 + 7); | |
}); | |
function brush() { | |
x.domain(brush.empty() ? x2.domain() : brush.extent()); | |
focus.select("path").attr("d", area); | |
focus.select(".x.axis").call(xAxis); | |
} | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function(doc) { | |
if (doc.date && doc.price){ | |
emit(doc.date, doc.price); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment