Skip to content

Instantly share code, notes, and snippets.

@soooh
Last active November 13, 2016 20:30
Show Gist options
  • Save soooh/41a11d5f99e43ac0f845f65d0ededa1b to your computer and use it in GitHub Desktop.
Save soooh/41a11d5f99e43ac0f845f65d0ededa1b to your computer and use it in GitHub Desktop.
basic line projection with interval
<!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