Skip to content

Instantly share code, notes, and snippets.

@mph006
Last active March 2, 2016 01:53
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 mph006/5ca35dfd49822b84eee8 to your computer and use it in GitHub Desktop.
Save mph006/5ca35dfd49822b84eee8 to your computer and use it in GitHub Desktop.
Basic Updatable Timeseries
var data = {
quarterly:[{
date:"Q3 14'",
numberOfThings:2222,
percentageOfThings:20,
priceOfThings:50
},{
date:"Q4 14'",
numberOfThings:2780,
percentageOfThings:29,
priceOfThings:68
},{
date:"Q1 15'",
numberOfThings:3301,
percentageOfThings:31,
priceOfThings:69
},{
date:"Q2 15'",
numberOfThings:2700,
percentageOfThings:29,
priceOfThings:66
},{
date:"Q3 15'",
numberOfThings:2000,
percentageOfThings:19,
priceOfThings:54
},{
date:"Q4 15'",
numberOfThings:2502,
percentageOfThings:25,
priceOfThings:62
},{
date:"Q1 16'",
numberOfThings:3290,
percentageOfThings:29,
priceOfThings:70
}],
monthly:[{
date:"Sept 15'",
numberOfThings:1290,
percentageOfThings:20,
priceOfThings:18
},{
date:"Oct 15'",
numberOfThings:934,
percentageOfThings:25,
priceOfThings:19 },{
date:"Nov 15'",
numberOfThings:1054,
percentageOfThings:23,
priceOfThings:20
},{
date:"Dec 15'",
numberOfThings:500,
percentageOfThings:18,
priceOfThings:10 },{
date:"Jan 16'",
numberOfThings:1552,
percentageOfThings:33,
priceOfThings:24
},{
date:"Feb 16'",
numberOfThings:1212,
percentageOfThings:30,
priceOfThings:12
},{
date:"Mar 16'",
numberOfThings:1021,
percentageOfThings:27,
priceOfThings:14
}],
weekly:[{
date:"03/05/2016",
numberOfThings:5,
percentageOfThings:4,
priceOfThings:0.1
},{
date:"03/06/2016",
numberOfThings:2,
percentageOfThings:1,
priceOfThings:0.05},{
date:"03/07/2016",
numberOfThings:52,
percentageOfThings:20,
priceOfThings:0.69
},{
date:"03/08/2016",
numberOfThings:40,
percentageOfThings:25,
priceOfThings:0.66
},{
date:"03/09/2016",
numberOfThings:90,
percentageOfThings:33,
priceOfThings:0.70
},{
date:"03/10/2016",
numberOfThings:70,
percentageOfThings:29,
priceOfThings:0.75
},{
date:"03/11/2016",
numberOfThings:20,
percentageOfThings:15,
priceOfThings:0.5
}]
};
<!DOCTYPE html>
<html>
<head>
<title>D3 Timeseries</title>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript" src="data.js"></script>
<link rel="stylesheet" type="text/css" href="lineGraph.css"/>
</head>
<body>
<div id="graph-title">Basic Updatable D3 Timeseries</div>
<div id="graph-picklist-wrapper">
<text>View</text>
<select id="graph-picklist-y" class="graph-picklist" onchange="refreshGraph()">
<option value="numberOfThings" selected>Number of Things</option>
<option value="percentageOfThings">% Utility</option>
<option value="priceOfThings">Cost Of Things</option>
</select>
<text>By</text>
<select id="graph-picklist-x" class="graph-picklist" onchange="refreshGraph()">
<option value="weekly" selected>Week</option>
<option value="monthly">Month</option>
<option value="quarterly">Quarter</option>
</select>
</div>
<div id="graph-container"></div>
</body>
<script type="text/javascript" src="lineGraph.js"></script>
</html>
body{
font-family: Helvetica;
}
#graph-container{
position: relative;
display: block;
height: 300px;
width:90%;
margin-left: 5%;
}
#graph-picklist-wrapper{
text-align: center;
}
#graph-title{
display: block;
position: relative;
width: 70%;
margin-left: 15%;
text-align: center;
font-size: 20px;
border-bottom: thin solid black;
margin-bottom: 30px;
margin-top: 20px;
padding-bottom: 10px;
}
path.line {
fill: none;
stroke:steelblue;
stroke-width: 3px;
}
path.area {
fill:rgba(70,130,180,0.5);
opacity: 0;
}
/*.axis {
shape-rendering: crispEdges;
}
*/
.x.axis .minor {
stroke: black;
}
.x.axis path {
display: none;
stroke: none;
}
.y.axis line, .y.axis path {
fill: none;
stroke: none;
}
.y.axis line{
stroke:#d3d3d3;
stroke-width:1px;
}
.x.axis line{
stroke:#d3d3d3;
stroke-width:1px;
}
.tick text{
stroke:black;
font-size: 12px;
font-family: openSansLight;
}
.x.axis text{
margin-top: 10px;
}
#y-axis-label{
stroke:black;
font-size: 14px;
font-weight:200;
}
function fetchFacetData(d,timeScale,facet){
returnArr =[];
d.forEach(function(d){
(timeScale==="weekly")?
returnArr.push({date: new Date(d.date), value: d[facet]}) :
returnArr.push({date: d.date, value: d[facet]});
});
return returnArr;
}
function prettyPrintYAxis(facet){
switch(facet){
case "numberOfThings":
return "Number of Things"
break;
case "percentageOfThings":
return "% Utility"
break;
case "priceOfThings":
return "Cost ($M)"
break;
default:
return "Y Axis Label";
}
}
function renderLineGraph(facet,timeScale,passedData){
var animDuration = 1000;
//console.log(facet,timeScale,passedData);
var margin = {top: 8, right: 70, bottom: 35, left: 45},
width = $("#graph-container").width() - margin.left - margin.right,
height = $("#graph-container").height() - margin.top - margin.bottom;
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var yAxis = d3.svg.axis().scale(y).ticks(4).tickSize(-width).orient("right");
x.domain([new Date(passedData[0].date), new Date(passedData[passedData.length - 1].date)]);
y.domain([0, d3.max(passedData, function(d) { return d[facet]; })]).nice();
switch(timeScale){
case "weekly":
var xAxis = d3.svg.axis().scale(x).ticks(passedData.length).tickSize(-height).tickFormat(d3.time.format("%a %m/%d")).tickPadding(15);
break;
case "monthly":
x = d3.scale.ordinal().domain(["Sept 15'","Oct 15'","Nov 15'","Dec 15'","Jan 16'","Feb 16'","Mar 16'"]).rangePoints([0, width]);
var xAxis = d3.svg.axis().scale(x).ticks(passedData.length).tickSize(-height).tickPadding(15);
break;
case "quarterly":
x = d3.scale.ordinal().domain(["Q3 14'","Q4 14'","Q1 15'","Q2 15'","Q3 15'","Q4 15'","Q1 16'"]).rangePoints([0, width]);
var xAxis = d3.svg.axis().scale(x).ticks(passedData.length).tickSize(-height).tickPadding(15);
break;
default:
console.log("switch error on yAxis assignment");
var xAxis = d3.svg.axis().scale(x).ticks(passedData.length).tickSize(-height).tickFormat(d3.time.format("%a %m/%d")).tickPadding(15);
break;
}
var area = d3.svg.area()
.x(function(d) {return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.value); })
.interpolate("monotone");
// A line generator, for the dark stroke.
var line = d3.svg.line()
.x(function(d) {return x(d.date);})
.y(function(d) {return y(d.value);})
.interpolate("monotone");
// Add an SVG element with the desired dimensions and margin.
var wrapper = d3.select("#graph-container");
var svg = wrapper.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id","chart-svg-container")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis);
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (width)+ ",0)")
.call(yAxis);
svg.append('g')
.attr('transform', 'translate(' + (width+margin.right/1.5) + ', ' + (height/2) + ')')
.append('text')
.attr('text-anchor', 'middle')
.attr("id","y-axis-label")
.attr('transform', 'rotate(90)')
.text(prettyPrintYAxis(facet));
var facetData = fetchFacetData(passedData,timeScale,facet);
svg.selectAll('.line')
.data([facetData])
.enter()
.append('path')
.attr('class', 'line')
.attr("id","current-path")
.style('stroke',"steelblue")
.attr('d',function(d){return line(d);});
svg.append("path")
.data([facetData])
.attr("class", "area")
.attr("d", function(d){return area(d);});
var totalLength = d3.select("#current-path").node().getTotalLength();
d3.select("#current-path")
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(animDuration/1.5)
.ease("linear")
.attr("stroke-dashoffset", 0);
d3.selectAll(".area").transition().delay(animDuration).duration(animDuration).style("opacity",1);
}
function refreshGraph(){
$("#chart-svg-container").remove();
renderLineGraph($("#graph-picklist-y").val(),$("#graph-picklist-x").val(),data[$("#graph-picklist-x").val()]);
}
$(document).ready(function() {
renderLineGraph('numberOfThings','weekly',data.weekly);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment