Built with blockbuilder.org
A little change from the previous one:
-
Adding grids
-
Path animated by transition, not the css opacity attribute.
license: mit |
Built with blockbuilder.org
A little change from the previous one:
Adding grids
Path animated by transition, not the css opacity attribute.
date | europe | asia | america | |
---|---|---|---|---|
12-Feb-12 | 52 | 40 | 65 | |
27-Feb-12 | 56 | 35 | 70 | |
02-Mar-12 | 51 | 45 | 62 | |
14-Mar-12 | 63 | 44 | 82 | |
30-Mar-12 | 64 | 54 | 85 | |
07-Apr-12 | 70 | 34 | 72 | |
18-Apr-12 | 65 | 36 | 69 | |
02-May-12 | 56 | 40 | 71 | |
19-May-12 | 71 | 55 | 75 | |
28-May-12 | 45 | 32 | 68 | |
03-Jun-12 | 64 | 44 | 75 | |
18-Jun-12 | 53 | 36 | 78 | |
29-Jun-12 | 59 | 42 | 79 |
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v3.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
.tick line, | |
path.domain | |
{stroke: black;stroke-width: 1;fill: none;} | |
.invisided{opacity: 0;} | |
form{margin: 10px;padding: 5px;} | |
label{display: inline-block;min-width: 80px;cursor:pointer;} | |
.grid line{ stroke: #ccc;stroke-dasharray: 8, 8;} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<div> | |
<form> | |
<label><input name='country' type="radio" value="europe">Europe</label> | |
<label><input name='country' type="radio" value="asia">Asia</label> | |
<label><input name='country' type="radio" value="america">America</label> | |
</form> | |
</div> | |
</div> | |
<script> | |
var margin = {top: 40, bottom: 40, left: 40, right: 40}, | |
svgHeight = 400, svgWidth = 500, | |
Height = svgHeight - margin.top - margin.bottom, | |
Width = svgWidth - margin.left - margin.right; | |
var dateParse = d3.time.format('%d-%b-%y').parse; | |
var xScale = d3.time.scale().range([0, Width]).nice(), | |
yScale = d3.scale.linear().range([Height, 0]).nice(), | |
xAxis = d3.svg.axis().orient('bottom') | |
.scale(xScale) | |
.ticks(5) | |
.tickFormat(d3.time.format('%b-%y')), | |
yAxis = d3.svg.axis().orient('left') | |
.scale(yScale).ticks(8), | |
colors = d3.scale.category10(), | |
xGrid = d3.svg.axis().orient('bottom') | |
.scale(xScale) | |
.ticks(5) | |
.tickSize(-Height, 0) | |
.tickFormat(''), | |
yGrid = d3.svg.axis().orient('left') | |
.scale(yScale) | |
.ticks(8) | |
.tickSize(-Width, 0) | |
.tickFormat(''); | |
var line = d3.svg.line() | |
// .interpolate('basis') | |
.x(function(d){return xScale(d.date);}) | |
.y(function(d){return yScale(d.value);}); | |
var svg = d3.select('#container') | |
.append('svg') | |
.attr('width', svgWidth) | |
.attr('height', svgHeight); | |
// radio inputs and events | |
var inputs = d3.select('#container').selectAll('input') | |
inputs.on('change', function(){ | |
var radioValue = document.forms[0]['country'].value; | |
updata(radioValue); | |
}); | |
var url = 'data.tsv'; | |
var nestData, continents; | |
d3.tsv(url, function(error, data){ | |
// data proccessing | |
continents = d3.keys(data[0]) | |
.filter(function(d){return d !== 'date'}); | |
var valExtent = []; | |
data.forEach(function(d){ | |
d.date = dateParse(d.date); | |
d.europe = +d.europe; | |
d.asia = +d.asia; | |
d.america = +d.america; | |
valExtent = d3.extent([valExtent[0], valExtent[1], | |
d.europe, d.asia, d.america]); | |
}); | |
// nestData is global decleared | |
nestData = continents.map(function(name){ | |
return { | |
key: name, | |
values: data.map(function(d){ | |
return { date: d.date, value: d[name] }; | |
}), | |
}; | |
}); | |
// scale domain | |
xScale.domain(d3.extent(data, function(d){return d.date;})); | |
yScale.domain([valExtent[0] * 0.8, valExtent[1] * 1.1]); | |
// draw grids | |
svg.append('g') | |
.attr('class', 'grid') | |
.attr('transform', 'translate(' + | |
[margin.left, margin.top + Height] + ')') | |
.call(xGrid); | |
svg.append('g') | |
.attr('class', 'grid') | |
.attr('transform', 'translate(' + | |
[margin.left, margin.top] + ')') | |
.call(yGrid); | |
// draw axises | |
svg.append('g') | |
.attr('transform', 'translate(' + | |
[margin.left, margin.top] + ')') | |
.call(yAxis); | |
svg.append('g') | |
.attr('transform', 'translate(' + | |
[margin.left, margin.top + Height] + ')') | |
.call(xAxis); | |
// Main Line chart | |
svg.append('g') | |
.attr('transform', 'translate(' + | |
[margin.left, margin.top] + ')') | |
.attr('class', 'graph'); | |
// initial canvas | |
// select the first input and set it checked | |
d3.select('#container').select('input').property('checked', true); | |
updata(document.forms[0]['country'].value); | |
}) | |
// drawing path funciton | |
function updata(index){ | |
// get the data from index parameter | |
var data = nestData[continents.indexOf(index)].values; | |
var ele = d3.select('svg .graph') | |
.selectAll('path') | |
.data(data); | |
// update path according to new data | |
ele | |
.transition() | |
.duration(300) | |
.attr('d', line(data)) | |
.attr('stroke', colors(index)); | |
// if path is not exist, create a new one | |
ele | |
.enter() | |
.append('path') | |
.attr('d', line(data)) | |
.attr('fill', 'none') | |
.attr('stroke-width', 3) | |
.attr('stroke', colors(index)); | |
// if there is more tags then the data, kill the extra tags | |
ele | |
.exit() | |
.remove(); | |
} | |
</script> | |
</body> |