updating data in a d3 histogram
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
width:100%; height: 100%;
margin: 0; padding: 0;
}
.graph, .graph2 {
margin: 20px;
}
button {
margin-left: 20px;
}
.bar rect {
fill: #FF6BB5;
shape-rendering: crispEdges;
}
.bar text {
fill: #fff;
}
.graph text, .graph2 text {
fill: #999;
}
.axis path, .axis line {
fill: none;
stroke: #999;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<div class="graph"></div>
<div class="graph2"></div>
<button>Update</button>
<script src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
var count = 0;
var csvFiles = ['nyc_flips_pluto_150712_sample1.csv', 'nyc_flips_pluto_150712_sample2.csv', 'nyc_flips_pluto_150712_sample3.csv'];
var formatDate = d3.time.format("%Y-%m-%d");
// variables for d3 histogram set up
var binsize = 1,
minbin = 2003,
maxbin = 2015
numbins = (maxbin - minbin) / binsize;
var binmargin = 0.2,
margin = {top: 10, right: 30, bottom: 40, left: 80},
width = 500 - margin.left - margin.right,
height = 225 - margin.top - margin.bottom;
var xmin = minbin - 1,
xmax = maxbin + 1;
var dataStore;
// object to store graph properites
function Params(container, key, label) {
this.container = container;
this.key = key;
this.label = label;
this.x = null;
this.x2 = null;
this.xAxis = null;
this.yAxis = null;
this.svg = null;
this.bar = null;
this.made = false;
};
// graphs one and two
var a = new Params('.graph', 'numFlips', 'Frequency of Transactions'),
b = new Params('.graph2', 'totalProfit', 'Profit in U.S. dollars');
// var x, x2, y, xAxis, yAxis, svg, bar;
// loads data from a csv file
function getData() {
d3.csv('./' + csvFiles[count], function(err, d){
if (err) {
console.log("error loading csv: ", err);
return;
}
dataStore = d;
if (a.made && b.made) {
// if the graph exists then update its data
updateGraph(d, a);
updateGraph(d, b);
} else {
// otherwise create the graph
makeGraph(d, a);
makeGraph(d, b);
}
});
if (count === 2) {
count = 0;
} else {
count += 1;
}
}
// groups the data into bins for the d3 histogram
function makeHistData(data) {
// helper function to grab date object from date string
var formatDate = d3.time.format("%Y-%m-%d");
// create an array to store our histogram's data
histdata = new Array(numbins);
for (var i = 0; i < numbins; i++) {
histdata[i] = { numFlips: 0, totalProfit: 0 };
}
// group our data into bins, one for each year
data.forEach(function(d){
// get integer year of d
var year = formatDate.parse(d.date).getFullYear();
// put into appropriate position in array for corresponding bin
var bin = year - minbin;
// make sure profit is a number type
d.profit = +d.profit;
if ((bin.toString() !== "NaN") && (bin < histdata.length)) {
histdata[bin].numFlips += 1;
histdata[bin].totalProfit += d.profit;
}
});
return histdata;
};
// creates the histogram
function makeGraph(data, graph) {
var histdata = makeHistData(data);
// var x, x2, y, xAxis, yAxis, svg, bar;
console.log(histdata);
graph.x = d3.scale.linear()
.domain([0, (xmax - xmin)])
.range([0, width]);
graph.x2 = d3.scale.linear()
.domain([xmin, xmax])
.range([0, width]);
graph.y = d3.scale.linear()
.domain([0, d3.max(histdata, function(d){
return d[graph.key];
})])
.range([height, 0]);
graph.xAxis = d3.svg.axis()
.scale(graph.x2)
.tickFormat(function(d) {
return d.toString();
})
.orient("bottom");
graph.yAxis = d3.svg.axis()
.scale(graph.y)
.ticks(8)
.orient("left");
graph.svg = d3.select(graph.container).append("svg")
.attr("position", "relative")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
graph.bar = graph.svg.selectAll(".bar")
.data(histdata)
.enter()
.append("g")
.attr("class", "bar")
.attr("transform", function(d,i) {
return "translate(" + graph.x2(i * binsize + minbin) + "," + graph.y(d[graph.key]) + ")";
});
graph.bar.append("rect")
.attr("x", graph.x(binmargin))
.attr("width", graph.x(binsize - 2 * binmargin))
.attr("height", function(d) { return height - graph.y(d[graph.key]); });
// x-axis & labels
graph.svg.append("g")
.attr("class", "x axis " + graph.key)
.attr("transform", "translate(0," + height + ")")
.call(graph.xAxis);
graph.svg.append("text")
.attr("class", "xlabel")
.attr("text-anchor", "middle")
.attr("x", width / 2)
.attr("y", height + margin.bottom - 5)
.text("year");
// y-axis & labels
graph.svg.append("g")
.attr("class", "y axis " + graph.key)
.attr("transform", "translate(0,0)")
.call(graph.yAxis);
graph.svg.append("text")
.attr("class", "ylabel")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height/2))
.attr("dy", "1em")
.attr("transform", "rotate(-90)")
.style("text-anchor", "middle")
.text(graph.label);
graph.made = true;
}
// updates the data in the graph
function updateGraph(data, graph) {
// group the data into new bins
var newhistdata = makeHistData(data);
graph.y.domain([0, d3.max(newhistdata, function(d){
return d[graph.key];
})]);
graph.yAxis = d3.svg.axis()
.scale(graph.y)
.ticks(8)
.orient("left");
graph.bar.data(newhistdata)
.transition()
.duration(1000)
.attr("transform", function(d,i) {
return "translate(" + graph.x2(i * binsize + minbin) + "," + graph.y(d[graph.key]) + ")";
})
.select("rect")
.attr("x", graph.x(binmargin))
.attr("width", graph.x(binsize - 2 * binmargin))
.attr("height", function(d) { return height - graph.y(d[graph.key]); });
d3.select('g.x.axis ' + graph.key).call(graph.xAxis);
d3.select('g.y.axis ' + graph.key).call(graph.yAxis);
}
getData();
d3.select('button').on('click', function(){
getData();
});
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js