Skip to content

Instantly share code, notes, and snippets.

@kenfdev
Last active August 1, 2018 04:24
Show Gist options
  • Save kenfdev/036c9bb8c29fdae02787c12a0bafd121 to your computer and use it in GitHub Desktop.
Save kenfdev/036c9bb8c29fdae02787c12a0bafd121 to your computer and use it in GitHub Desktop.
Area Gradient fill
license: mit
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment