This variation of a line chart is taken from the example demonstrated by Mike Bostock where the gradient for the line varied. In this example the gradient is applied to the area fill instead.
forked from d3noob's block: Area Gradient fill
license: mit |
This variation of a line chart is taken from the example demonstrated by Mike Bostock where the gradient for the line varied. In this example the gradient is applied to the area fill instead.
forked from d3noob's block: Area Gradient fill
date | temperature | |
---|---|---|
20111001 | 62.7 | |
20111002 | 59.9 | |
20111003 | 59.1 | |
20111004 | 58.8 | |
20111005 | 58.7 | |
20111006 | 57.0 | |
20111007 | 56.7 | |
20111008 | 56.8 | |
20111009 | 56.7 | |
20111010 | 60.1 | |
20111011 | 61.1 | |
20111012 | 61.5 | |
20111013 | 64.3 | |
20111014 | 67.1 | |
20111015 | 64.6 | |
20111016 | 61.6 | |
20111017 | 61.1 | |
20111018 | 59.2 | |
20111019 | 58.9 | |
20111020 | 57.2 | |
20111021 | 56.4 | |
20111022 | 60.7 | |
20111023 | 65.1 | |
20111024 | 60.9 | |
20111025 | 56.1 | |
20111026 | 54.6 | |
20111027 | 56.1 | |
20111028 | 58.1 | |
20111029 | 57.5 | |
20111030 | 57.7 | |
20111031 | 55.1 |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
margin: auto; | |
width: 960px; | |
} | |
text { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.x.axis path { | |
/* display: none; */ | |
} | |
.area { | |
fill: url(#temperature-gradient); | |
stroke-width: 05px; | |
} | |
.grid { | |
opacity: 0.15 | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v4.js"></script> | |
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script> | |
<script> | |
var margin = {top: 20, right: 20, bottom: 30, left: 50}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var parseDate = d3.timeParse("%Y%m%d"); | |
const bisectDate = d3.bisector(d => d.date).left; | |
var x = d3.scaleTime() | |
.range([0, width]); | |
var y = d3.scaleLinear() | |
.range([height, 0]); | |
var area = d3.area() | |
.x(function(d) { return x(d.date); }) | |
.y0(height) | |
.y1(function(d) { return y(d.temperature); }); | |
var svg = d3.select("body").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.csv("data.csv", function(error, data) { | |
data.forEach(function(d) { | |
d.date = parseDate(d.date); | |
d.temperature = +d.temperature; | |
}); | |
x.domain([data[0].date, data[data.length - 1].date]); | |
y.domain(d3.extent(data, function(d) { return d.temperature; })); | |
svg.append("linearGradient") | |
.attr("id", "temperature-gradient") | |
.attr("gradientUnits", "userSpaceOnUse") | |
.attr("x1", 0).attr("y1", y(50)) | |
.attr("x2", 0).attr("y2", y(60)) | |
.selectAll("stop") | |
.data([ | |
{offset: "0%", color: "steelblue"}, | |
{offset: "50%", color: "gray"}, | |
{offset: "100%", color: "red"} | |
]) | |
.enter().append("stop") | |
.attr("offset", function(d) { return d.offset; }) | |
.attr("stop-color", function(d) { return d.color; }); | |
// add the X gridlines | |
svg.append("g") | |
.attr("class", "grid") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x) | |
.ticks(10) | |
.tickSize(-height) | |
.tickFormat("") | |
) | |
// add the Y gridlines | |
svg.append("g") | |
.attr("class", "grid") | |
.call(d3.axisLeft(y) | |
.ticks(10) | |
.tickSize(-width) | |
.tickFormat("") | |
) | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x)); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(d3.axisLeft(y)) | |
.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("Temperature (ºF)"); | |
svg.append("path") | |
.datum(data) | |
.attr("class", "area") | |
.attr("d", area); | |
const focus = svg.append('g') | |
.attr('class', 'focus') | |
.style('display', 'none'); | |
// focus.append('circle') | |
// .attr('r', 4.5); | |
focus.append('line') | |
.classed('y', true); | |
const target = svg.append('g') | |
.attr('class', 'target') | |
.style('display', 'none'); | |
target.append('circle') | |
.attr('r', 4.5); | |
target.append('line') | |
.classed('target-y', true); | |
svg.append('rect') | |
.attr('class', 'overlay') | |
.attr('width', width) | |
.attr('height', height) | |
.on('mouseover', () => focus.style('display', null)) | |
.on('mouseout', () => focus.style('display', 'none')) | |
.on('mousemove', mousemove) | |
.on('click', mouseclick); | |
d3.select('.overlay') | |
.styles({ | |
fill: 'none', | |
'pointer-events': 'all' | |
}); | |
d3.selectAll('.focus') | |
.style('opacity', 0.2); | |
d3.selectAll('.focus line') | |
.styles({ | |
fill: 'none', | |
'stroke': 'black', | |
'stroke-width': '1.5px', | |
// 'stroke-dasharray': '3 3' | |
}); | |
d3.selectAll('.target') | |
.style('opacity', 0.7); | |
d3.selectAll('.target line') | |
.styles({ | |
fill: 'none', | |
'stroke': 'blue', | |
'stroke-width': '1.5px' | |
}); | |
d3.selectAll('.target circle') | |
.styles({ | |
fill: 'blue', | |
stroke: 'blue' | |
}); | |
function mousemove() { | |
const x0 = x.invert(d3.mouse(this)[0]); | |
const i = bisectDate(data, x0, 1); | |
const d0 = data[i - 1]; | |
const d1 = data[i]; | |
const d = x0 - d0.date > d1.date - x0 ? d1 : d0; | |
focus.attr('transform', `translate(${x(d.date)}, 0)`); | |
focus.select('line.y') | |
.attr('x1', 0) | |
.attr('x2', 0) | |
.attr('y1', 0) | |
.attr('y2', height); | |
} | |
function mouseclick() { | |
const x0 = x.invert(d3.mouse(this)[0]); | |
const i = bisectDate(data, x0, 1); | |
const d0 = data[i - 1]; | |
const d1 = data[i]; | |
const d = x0 - d0.date > d1.date - x0 ? d1 : d0; | |
target.attr('transform', `translate(${x(d.date)}, 0)`); | |
target.style('display', null); | |
target.select('line.target-y') | |
.attr('x1', 0) | |
.attr('x2', 0) | |
.attr('y1', 0) | |
.attr('y2', height); | |
} | |
}); | |
</script> |