Last active
November 13, 2016 20:30
-
-
Save soooh/41a11d5f99e43ac0f845f65d0ededa1b to your computer and use it in GitHub Desktop.
basic line projection with interval
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'> | |
<svg width='960' height='500'></svg> | |
<script src='https://d3js.org/d3.v4.min.js'></script> | |
<script> | |
var parseYear = d3.timeParse('%Y'); | |
var currentYear = new Date().getFullYear(); | |
// generate random data with d3 range and map | |
var data = d3.range(41).map(function(i) { | |
return { | |
x: parseYear(currentYear - i), | |
y: d3.randomUniform(40, 60)(), | |
e: d3.randomUniform(1, 5)() | |
}; | |
}); | |
data = data.sort(function(a, b) { return a.x - b.x }); | |
// generate future data | |
var projection = d3.range(10).map(function(i) { | |
return { | |
x: parseYear(currentYear + i + 1), | |
y: d3.randomUniform(40, 60)(), | |
e: d3.randomUniform(5, 10)() | |
}; | |
}); | |
// the first data point of projection shd be the last point of data | |
projection.splice(0, 0, data[data.length - 1]); | |
// | |
// `data` and `projection` are both randomly generated datatsets. | |
// my assumption is that you will structure your data with | |
// some kind of confidence, error, standard deviation, etc. | |
// to display whatever uncertainty you'd like to show. | |
// | |
var svg = d3.select('svg'), | |
margin = {top: 20, right: 20, bottom: 30, left: 50}, | |
width = +svg.attr('width') - margin.left - margin.right, | |
height = +svg.attr('height') - margin.top - margin.bottom, | |
g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
var x = d3.scaleTime() | |
.rangeRound([0, width]) | |
.domain([ parseYear(currentYear - 40), parseYear(currentYear + 10) ]); | |
var y = d3.scaleLinear() | |
.range([height, 0]) | |
.domain([0, 100]); | |
var interval = d3.area() | |
.x(function(d) { return x(d.x); }) | |
.y0(function(d) { | |
return y(d.y - d.e); | |
}) | |
.y1(function(d) { | |
return y(d.y + d.e); | |
}); | |
var line = d3.line() | |
.x(function(d) { return x(d.x); }) | |
.y(function(d) { return y(d.y); }); | |
// shaded future | |
g.append('rect') | |
.attr('class', 'future') | |
.attr('x', x( parseYear(currentYear) )) | |
.attr('y', 0) | |
.attr('width', x( parseYear(currentYear + 10) ) - x( parseYear(currentYear))) | |
.attr('height', height) | |
// shaded interval | |
g.append('path') | |
.datum(data) | |
.attr('class', 'interval') | |
.attr('d', interval); | |
// line | |
g.append('path') | |
.datum(data) | |
.attr('class', 'line') | |
.attr('d', line); | |
// shaded projection interval | |
g.append('path') | |
.datum(projection) | |
.attr('class', 'projected-interval') | |
.attr('d', interval); | |
// projected line | |
g.append('path') | |
.datum(projection) | |
.attr('class', 'projected-line') | |
.attr('d', line); | |
// axes | |
g.append('g') | |
.attr('transform', 'translate(0,' + height + ')') | |
.call( d3.axisBottom(x) ); | |
g.append('g') | |
.call( d3.axisLeft(y) ) | |
</script> | |
<style> | |
.interval { | |
fill: gainsboro; | |
} | |
.line { | |
fill: none; | |
stroke: black; | |
stroke-width: 1px; | |
} | |
.future { | |
fill: rgba(0, 0, 0, 0.05); | |
} | |
.projected-interval { | |
fill: rgba(0, 0, 0, 0.15); | |
} | |
.projected-line { | |
fill: none; | |
stroke: black; | |
stroke-width: 1px; | |
stroke-dasharray: 2,2; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment