Skip to content

Instantly share code, notes, and snippets.

@jcnesci
Last active June 26, 2016 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcnesci/7439277 to your computer and use it in GitHub Desktop.
Save jcnesci/7439277 to your computer and use it in GitHub Desktop.
Trying to use D3.js to create a simple line graph with a moving average using previous and next data points. View on Blocks at http://bl.ocks.org/jcnesci/7439277
{"rows":[
{"key":[4,22,23,11],"value":2},
{"key":[4,22,23,12],"value":2},
{"key":[4,22,23,13],"value":6},
{"key":[4,22,23,14],"value":3},
{"key":[4,22,23,15],"value":5},
{"key":[4,22,23,16],"value":2},
{"key":[4,22,23,17],"value":1},
{"key":[4,22,23,18],"value":5},
{"key":[4,22,23,22],"value":1},
{"key":[4,22,23,23],"value":2},
{"key":[4,22,23,24],"value":1},
{"key":[4,22,23,25],"value":8},
{"key":[4,22,23,26],"value":5},
{"key":[4,22,23,27],"value":1},
{"key":[4,22,23,28],"value":5},
{"key":[4,22,23,29],"value":2},
{"key":[4,22,23,30],"value":2},
{"key":[4,22,23,31],"value":1},
{"key":[4,22,23,32],"value":2},
{"key":[4,22,23,33],"value":4},
{"key":[4,22,23,34],"value":1},
{"key":[4,22,23,35],"value":1},
{"key":[4,22,23,36],"value":2},
{"key":[4,22,23,37],"value":4},
{"key":[4,22,23,39],"value":1},
{"key":[4,22,23,40],"value":1},
{"key":[4,22,23,41],"value":2},
{"key":[4,22,23,42],"value":2},
{"key":[4,22,23,43],"value":2},
{"key":[4,22,23,44],"value":10},
{"key":[4,22,23,45],"value":9},
{"key":[4,22,23,46],"value":7},
{"key":[4,22,23,47],"value":17},
{"key":[4,22,23,48],"value":10},
{"key":[4,22,23,49],"value":4},
{"key":[4,22,23,50],"value":4},
{"key":[4,22,23,51],"value":1},
{"key":[4,22,23,52],"value":4},
{"key":[4,22,23,53],"value":3},
{"key":[4,22,23,54],"value":1},
{"key":[4,22,23,55],"value":2},
{"key":[4,22,23,56],"value":1},
{"key":[4,22,23,57],"value":1},
{"key":[4,22,23,58],"value":4},
{"key":[4,22,23,59],"value":3},
{"key":[4,23,0,0],"value":2},
{"key":[4,23,0,1],"value":1},
{"key":[4,23,0,2],"value":3},
{"key":[4,23,0,3],"value":4},
{"key":[4,23,0,5],"value":5},
{"key":[4,23,0,6],"value":12},
{"key":[4,23,0,7],"value":5},
{"key":[4,23,0,8],"value":2},
{"key":[4,23,0,9],"value":3},
{"key":[4,23,0,11],"value":1},
{"key":[4,23,0,12],"value":2},
{"key":[4,23,0,13],"value":4},
{"key":[4,23,0,14],"value":3},
{"key":[4,23,0,15],"value":1},
{"key":[4,23,0,16],"value":3},
{"key":[4,23,0,17],"value":2},
{"key":[4,23,0,18],"value":1},
{"key":[4,23,0,19],"value":1},
{"key":[4,23,0,21],"value":1},
{"key":[4,23,0,22],"value":3},
{"key":[4,23,0,23],"value":4},
{"key":[4,23,0,24],"value":3},
{"key":[4,23,0,25],"value":1},
{"key":[4,23,0,26],"value":5},
{"key":[4,23,0,27],"value":6},
{"key":[4,23,0,28],"value":3},
{"key":[4,23,0,31],"value":1},
{"key":[4,23,0,32],"value":1},
{"key":[4,23,0,33],"value":2},
{"key":[4,23,0,34],"value":4},
{"key":[4,23,0,35],"value":1},
{"key":[4,23,0,36],"value":1},
{"key":[4,23,0,37],"value":3},
{"key":[4,23,0,38],"value":3},
{"key":[4,23,0,39],"value":2},
{"key":[4,23,0,40],"value":6},
{"key":[4,23,0,43],"value":1},
{"key":[4,23,0,44],"value":1},
{"key":[4,23,0,45],"value":3},
{"key":[4,23,0,48],"value":9},
{"key":[4,23,0,49],"value":2},
{"key":[4,23,0,50],"value":4},
{"key":[4,23,0,51],"value":1},
{"key":[4,23,0,52],"value":7},
{"key":[4,23,0,53],"value":4},
{"key":[4,23,0,54],"value":3},
{"key":[4,23,0,55],"value":2},
{"key":[4,23,0,57],"value":4},
{"key":[4,23,0,59],"value":1},
{"key":[4,23,1,0],"value":2},
{"key":[4,23,1,31],"value":3},
{"key":[4,23,1,32],"value":3},
{"key":[4,23,1,33],"value":1},
{"key":[4,23,1,35],"value":1}
]}
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<style>
body {
font: 10px sans-serif;
}
.graph_container {
position: relative;
margin: 0 auto;
width: 960px;
}
path.average {
stroke: darkviolet;
stroke-width: 1px;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.area {
fill: black;
}
#graph_container_1 .area {
fill: royalblue;
opacity: 0.2;
}
#graph_container_2 .area {
fill: crimson;
opacity: 0.2;
}
#graph_container_3 .area {
fill: gainsboro;
}
</style>
</head>
<body>
<div id="graph_container_1" class="graph_container"><p>Traffic Graph w/ Moving Average</p></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" charset="utf-8">
// Vars for graph size.
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// Our Date parsing format.
var parseDate = d3.time.format("%m,%e,%H,%M").parse;
// Setup X and Y scales.
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
// Setup X and Y axis, using the scales.
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// Setup SVG area fill displayed under a line of data.
var area = d3.svg.area()
.x(function(d) { return x(d.key); })
.y0(height)
.y1(function(d) { return y(d.value); });
// Create SVG element for the Traffic graph.
var graph1 = d3.select("#graph_container_1").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("date.json", function(error, data) {
// Setup each row of data by formatting the Date for X, and by converting to a number for Y.
data = data.rows;
data.forEach(function(d) {
d.key = parseDate(String(d.key));
d.value = +d.value;
});
x.domain(d3.extent(data, function(d) { return d.key; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
// Setup the moving average calculation.
// Currently is a hacky way of doing it by manually storing and using the previous 3 values for averaging.
// Looking for another way to address previous values so we can make the averaging window much larger (like 15 previous values).
var prevPrevVal = 0;
var prevVal = 0;
var curVal = 0
var movingAverageLine = d3.svg.line()
.x(function(d,i) { return x(d.key); })
.y(function(d,i) {
if (i == 0) {
prevPrevVal = y(d.value);
prevVal = y(d.value);
curVal = y(d.value);
} else if (i == 1) {
prevPrevVal = prevVal;
prevVal = curVal;
curVal = (prevVal + y(d.value)) / 2.0;
} else {
prevPrevVal = prevVal;
prevVal = curVal;
curVal = (prevPrevVal + prevVal + y(d.value)) / 3.0;
}
return curVal;
})
.interpolate("basis");
// Draw the moving average version of the data, as a line.
graph1.append("path")
.attr("class", "average")
.attr("d", movingAverageLine(data));
// Draw the raw data as an area.
graph1.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
// Draw the X-axis of the graph.
graph1.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Draw the Y-axis of the graph.
graph1.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Value");
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment