Skip to content

Instantly share code, notes, and snippets.

@LemoNode
Created October 4, 2018 20:25
Show Gist options
  • Save LemoNode/704c604c3e5cc87f15f03e508307c475 to your computer and use it in GitHub Desktop.
Save LemoNode/704c604c3e5cc87f15f03e508307c475 to your computer and use it in GitHub Desktop.
Line chart
license: gpl-3.0
date apples oranges
2011-10-01 63.4 62.7
2011-10-02 58.0 59.9
2011-10-03 53.3 59.1
2011-10-04 55.7 58.8
2011-10-05 64.2 58.7
2011-10-06 58.8 57.0
2011-10-07 57.9 56.7
2011-10-08 61.8 56.8
2011-10-09 69.3 56.7
2011-10-10 71.2 60.1
2011-10-11 68.7 61.1
2011-10-12 61.8 61.5
2011-10-13 63.0 64.3
2011-10-14 66.9 67.1
2011-10-15 61.7 64.6
2011-10-16 61.8 61.6
2011-10-17 62.8 61.1
2011-10-18 60.8 59.2
2011-10-19 62.1 58.9
2011-10-20 65.1 57.2
2011-10-21 55.6 56.4
2011-10-22 54.4 60.7
2011-10-23 54.4 65.1
2011-10-24 54.8 60.9
2011-10-25 57.9 56.1
2011-10-26 54.6 54.6
2011-10-27 54.4 56.1
2011-10-28 42.5 58.1
2011-10-29 40.9 57.5
2011-10-30 38.6 57.7
2011-10-31 44.2 55.1
2011-11-01 49.6 57.9
2011-11-02 47.2 64.6
2011-11-03 50.1 56.2
2011-11-04 50.1 50.5
2011-11-05 43.5 51.3
2011-11-06 43.8 52.6
2011-11-07 48.9 51.4
2011-11-08 55.5 50.6
2011-11-09 53.7 54.6
2011-11-10 57.7 55.6
2011-11-11 48.5 53.9
2011-11-12 46.8 54.0
2011-11-13 51.1 53.8
2011-11-14 56.8 53.5
2011-11-15 59.7 53.4
2011-11-16 56.5 52.2
2011-11-17 49.6 52.7
2011-11-18 41.5 53.1
2011-11-19 44.3 49.0
2011-11-20 54.0 50.4
2011-11-21 54.1 51.1
2011-11-22 49.4 52.3
2011-11-23 50.0 54.6
2011-11-24 44.0 55.1
2011-11-25 50.3 51.5
2011-11-26 52.1 53.6
2011-11-27 49.6 52.3
2011-11-28 57.2 51.0
2011-11-29 59.1 49.5
2011-11-30 50.6 49.8
2011-12-01 44.3 60.4
2011-12-02 43.9 62.2
2011-12-03 42.1 58.3
2011-12-04 43.9 52.7
2011-12-05 50.2 51.5
2011-12-06 54.2 49.9
2011-12-07 54.6 48.6
2011-12-08 43.4 46.4
2011-12-09 27.4 49.8
2011-12-10 25.0 52.1
2011-12-11 39.4 48.8
2011-12-12 48.7 47.4
2011-12-13 43.0 47.2
2011-12-14 38.3 46.1
2011-12-15 27.4 48.8
2011-12-16 25.0 47.9
2011-12-17 33.1 49.8
2011-12-18 39.6 49.1
2011-12-19 42.3 48.3
2011-12-20 39.7 49.3
2011-12-21 46.0 48.4
2011-12-22 41.2 53.3
2011-12-23 39.8 47.5
2011-12-24 38.1 47.9
2011-12-25 37.1 48.9
2011-12-26 45.5 45.9
2011-12-27 50.6 47.2
2011-12-28 42.7 48.9
2011-12-29 42.6 50.9
2011-12-30 36.9 52.9
2011-12-31 27.4 50.1
2012-01-01 25.0 53.9
2012-01-02 39.4 53.1
2012-01-03 48.7 49.7
2012-01-04 43.0 52.7
2012-01-05 37.1 52.6
2012-01-06 48.2 49.0
2012-01-07 43.7 51.0
2012-01-08 40.1 56.8
2012-01-09 38.0 52.3
2012-01-10 43.5 51.6
2012-01-11 50.4 49.8
2012-01-12 45.8 51.9
2012-01-13 37.5 53.7
2012-01-14 40.8 52.9
2012-01-15 36.5 49.7
2012-01-16 39.1 45.3
2012-01-17 43.2 43.6
2012-01-18 36.5 45.0
2012-01-19 36.5 47.3
2012-01-20 38.3 51.4
2012-01-21 27.4 53.7
2012-01-22 25.0 48.3
2012-01-23 39.4 52.9
2012-01-24 48.7 49.1
2012-01-25 43.0 52.1
2012-01-26 37.1 53.6
2012-01-27 48.2 50.4
2012-01-28 43.7 50.3
2012-01-29 40.1 53.8
2012-01-30 38.0 51.9
2012-01-31 43.5 50.0
2012-02-01 50.4 50.0
2012-02-02 45.8 51.3
2012-02-03 37.5 51.5
2012-02-04 40.8 52.0
2012-02-05 36.5 53.8
2012-02-06 39.1 54.6
2012-02-07 43.2 54.3
2012-02-08 36.5 51.9
2012-02-09 36.5 53.8
2012-02-10 38.3 53.9
2012-02-11 36.9 52.3
2012-02-12 29.7 50.1
2012-02-13 33.1 49.5
2012-02-14 39.6 48.6
2012-02-15 42.3 49.9
2012-02-16 39.7 52.4
2012-02-17 46.0 49.9
2012-02-18 41.2 51.6
2012-02-19 39.8 47.8
2012-02-20 38.1 48.7
2012-02-21 37.1 49.7
2012-02-22 45.5 53.4
2012-02-23 50.6 54.1
2012-02-24 42.7 55.9
2012-02-25 42.6 51.7
2012-02-26 36.9 47.7
2012-02-27 40.9 45.4
2012-02-28 45.9 47.0
2012-02-29 40.7 49.8
2012-03-01 41.3 48.9
2012-03-02 36.8 48.1
2012-03-03 47.6 50.7
2012-03-04 44.2 55.0
2012-03-05 38.5 48.8
2012-03-06 32.9 48.4
2012-03-07 43.3 49.9
2012-03-08 51.2 49.2
2012-03-09 47.8 51.7
2012-03-10 37.2 49.3
2012-03-11 42.9 50.0
2012-03-12 48.8 48.6
2012-03-13 52.6 53.9
2012-03-14 60.5 55.2
2012-03-15 47.2 55.9
2012-03-16 44.7 54.6
2012-03-17 48.2 48.2
2012-03-18 48.2 47.1
2012-03-19 53.1 45.8
2012-03-20 57.8 49.7
2012-03-21 57.5 51.4
2012-03-22 57.3 51.4
2012-03-23 61.7 48.4
2012-03-24 55.8 49.0
2012-03-25 48.4 46.4
2012-03-26 49.8 49.7
2012-03-27 39.6 54.1
2012-03-28 49.7 54.6
2012-03-29 56.8 52.3
2012-03-30 46.5 54.5
2012-03-31 42.2 56.2
2012-04-01 45.3 51.1
2012-04-02 48.1 50.5
2012-04-03 51.2 52.2
2012-04-04 61.0 50.6
2012-04-05 50.7 47.9
2012-04-06 48.0 47.4
2012-04-07 51.1 49.4
2012-04-08 55.7 50.0
2012-04-09 58.3 51.3
2012-04-10 55.0 53.8
2012-04-11 49.0 52.9
2012-04-12 51.7 53.9
2012-04-13 53.1 50.2
2012-04-14 55.2 50.9
2012-04-15 62.3 51.5
2012-04-16 62.9 51.9
2012-04-17 69.3 53.2
2012-04-18 59.0 53.0
2012-04-19 54.1 55.1
2012-04-20 56.5 55.8
2012-04-21 58.2 58.0
2012-04-22 52.4 52.8
2012-04-23 51.6 55.1
2012-04-24 49.3 57.9
2012-04-25 52.5 57.5
2012-04-26 50.5 55.3
2012-04-27 51.9 53.5
2012-04-28 47.4 54.7
2012-04-29 54.1 54.0
2012-04-30 51.9 53.4
2012-05-01 57.4 52.7
2012-05-02 53.7 50.7
2012-05-03 53.1 52.6
2012-05-04 57.2 53.4
2012-05-05 57.0 53.1
2012-05-06 56.6 56.5
2012-05-07 54.6 55.3
2012-05-08 57.9 52.0
2012-05-09 59.2 52.4
2012-05-10 61.1 53.4
2012-05-11 59.7 53.1
2012-05-12 64.1 49.9
2012-05-13 65.3 52.0
2012-05-14 64.2 56.0
2012-05-15 62.0 53.0
2012-05-16 63.8 51.0
2012-05-17 64.5 51.4
2012-05-18 61.0 52.2
2012-05-19 62.6 52.4
2012-05-20 66.2 54.5
2012-05-21 62.7 52.8
2012-05-22 63.7 53.9
2012-05-23 66.4 56.5
2012-05-24 64.5 54.7
2012-05-25 65.4 52.5
2012-05-26 69.4 52.1
2012-05-27 71.9 52.2
2012-05-28 74.4 52.9
2012-05-29 75.9 52.1
2012-05-30 72.9 52.1
2012-05-31 72.5 53.3
2012-06-01 67.2 54.8
2012-06-02 68.3 54.0
2012-06-03 67.7 52.3
2012-06-04 61.9 55.3
2012-06-05 58.3 53.5
2012-06-06 61.7 54.1
2012-06-07 66.7 53.9
2012-06-08 68.7 54.4
2012-06-09 72.2 55.0
2012-06-10 72.6 60.0
2012-06-11 69.2 57.2
2012-06-12 66.9 55.1
2012-06-13 66.7 53.3
2012-06-14 67.7 53.4
2012-06-15 68.5 54.6
2012-06-16 67.5 57.0
2012-06-17 64.2 55.6
2012-06-18 61.7 52.5
2012-06-19 66.4 53.9
2012-06-20 77.9 55.3
2012-06-21 88.3 53.3
2012-06-22 82.2 54.1
2012-06-23 77.0 55.2
2012-06-24 75.4 55.8
2012-06-25 70.9 56.8
2012-06-26 65.9 57.5
2012-06-27 73.5 57.7
2012-06-28 77.4 56.6
2012-06-29 79.6 56.4
2012-06-30 84.2 58.4
2012-07-01 81.8 58.8
2012-07-02 82.5 56.4
2012-07-03 80.2 56.5
2012-07-04 77.8 55.8
2012-07-05 86.1 54.8
2012-07-06 79.9 54.9
2012-07-07 83.5 54.7
2012-07-08 81.5 52.8
2012-07-09 77.8 53.7
2012-07-10 76.1 53.1
2012-07-11 76.3 52.7
2012-07-12 75.8 52.0
2012-07-13 77.2 53.4
2012-07-14 79.3 54.0
2012-07-15 78.9 54.0
2012-07-16 79.6 54.5
2012-07-17 83.3 56.7
2012-07-18 84.3 57.5
2012-07-19 75.1 57.1
2012-07-20 68.4 58.1
2012-07-21 68.4 57.6
2012-07-22 72.2 56.0
2012-07-23 75.6 56.6
2012-07-24 82.6 57.8
2012-07-25 78.4 57.5
2012-07-26 77.0 56.4
2012-07-27 79.4 55.3
2012-07-28 77.4 55.0
2012-07-29 72.5 55.6
2012-07-30 72.9 55.6
2012-07-31 73.6 55.9
2012-08-01 75.0 55.4
2012-08-02 77.7 54.4
2012-08-03 79.7 53.7
2012-08-04 79.6 54.1
2012-08-05 81.5 57.8
2012-08-06 80.0 58.2
2012-08-07 75.7 58.0
2012-08-08 77.8 57.0
2012-08-09 78.6 55.0
2012-08-10 77.8 54.8
2012-08-11 78.5 53.0
2012-08-12 78.8 52.5
2012-08-13 78.6 53.3
2012-08-14 76.8 53.9
2012-08-15 76.7 56.2
2012-08-16 75.9 57.1
2012-08-17 77.6 55.3
2012-08-18 72.6 56.2
2012-08-19 70.4 54.3
2012-08-20 71.8 53.1
2012-08-21 73.6 53.4
2012-08-22 74.7 54.5
2012-08-23 74.6 55.7
2012-08-24 76.0 54.8
2012-08-25 76.2 53.8
2012-08-26 73.4 56.5
2012-08-27 74.6 58.3
2012-08-28 79.4 58.7
2012-08-29 74.7 57.5
2012-08-30 73.5 55.9
2012-08-31 77.9 55.4
2012-09-01 80.7 55.7
2012-09-02 75.1 53.1
2012-09-03 73.5 53.5
2012-09-04 73.5 52.5
2012-09-05 77.7 54.5
2012-09-06 74.2 56.3
2012-09-07 76.0 56.4
2012-09-08 77.1 56.5
2012-09-09 69.7 56.4
2012-09-10 67.8 55.4
2012-09-11 64.0 56.2
2012-09-12 68.1 55.7
2012-09-13 69.3 54.3
2012-09-14 70.0 55.2
2012-09-15 69.3 54.3
2012-09-16 66.3 52.9
2012-09-17 67.0 54.8
2012-09-18 72.8 54.8
2012-09-19 67.2 56.8
2012-09-20 62.1 55.4
2012-09-21 64.0 55.8
2012-09-22 65.5 55.9
2012-09-23 65.7 52.8
2012-09-24 60.4 54.5
2012-09-25 63.2 53.3
2012-09-26 68.5 53.6
2012-09-27 69.2 52.1
2012-09-28 68.7 52.6
2012-09-29 62.5 53.9
2012-09-30 62.3 55.1
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
body {
margin: auto;
width: 650px;
font: 14px Consolas;
}
.overlay {
fill: none;
pointer-events: all;
}
.x-axis text {
font-size: 12px;
color: white;
text-shadow:
2px 2px 0 #000,
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
}
.x-axis .tick:first-of-type text {
display: none;
}
.y-axis path {
display: none;
}
.y-axis line {
opacity: .15;
}
</style>
</head>
<body>
<svg id="chart" width="650" height="420"></svg>
Choose Category:
<select id="options"></select>
<font style="float: right;" id="min"></font><br>
<font style="float: right;" id="max"></font>
<script>
d3.csv("data.csv").then(d => chart(d))
function chart(data) {
var parse = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%Y-%m-%d"),
percent = d3.format("+.0%"),
format = x => percent(x - 1);
data.forEach(d => d.date = parse(d.date));
var keys = data.columns.slice(1);
var options = d3.select("#options").selectAll("option")
.data(keys)
.enter().append("option")
.text(d => d)
var svg = d3.select("#chart"),
margin = {top: 25, right: 10, bottom: 10, left: 25},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right])
var y = d3.scaleLinear()
.range([height - margin.bottom, margin.top])
var xAxis = svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.attr("class", "x-axis")
var yAxis = svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.attr("class", "y-axis")
var area = d3.area()
.x(d => x(d.date))
.y1(d => y(d.percent))
var defs = svg.append("defs");
var clipAbove = defs.append("clipPath").attr("id", "clip-above")
.append("rect")
.attr("width", width)
.attr("height", 0);
var clipBelow = defs.append("clipPath").attr("id", "clip-below")
.append("rect")
.attr("y", 0)
.attr("width", width)
.attr("height", 0);
update(d3.select("#options").property("value"), 0)
function update(input, speed) {
draw(input, speed)
hover(input)
text(input, speed)
}
function draw(input, speed) {
data.forEach(d => d.percent = +d[input] / +data[0][input]);
var mapped = [{ values: data.map(function(d) {
return {date: d.date, percent: d.percent}
})}]
y.domain(d3.extent(data, d => d.percent)).nice()
yAxis.transition().duration(speed)
.call(d3.axisLeft(y)
.tickFormat(format)
.tickSize(-width + margin.right + margin.left))
xAxis.transition().duration(speed)
.attr("transform", "translate(0," + y(1) + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b")));
area.y0(y(1))
clipAbove.transition().duration(speed)
.attr("height", y(1));
clipBelow.transition().duration(speed)
.attr("y", y(1))
.attr("height", height - y(1));
var above = svg.selectAll(".above")
.data(mapped)
above.exit().remove()
above.enter().append("path")
.attr("class", "above")
.attr("fill", "#7fbc41")
.merge(above)
.transition().duration(speed)
.attr("clip-path", "url(#clip-above)")
.attr("d", d => area(d.values))
var below = svg.selectAll(".below")
.data(mapped)
below.exit().remove()
below.enter().insert("g", ".x-axis").append("path")
.attr("class", "below")
.attr("fill", "#EB6161")
.merge(below)
.transition().duration(speed)
.attr("clip-path", "url(#clip-below)")
.attr("d", d => area(d.values))
}
function hover(input) {
var bisect = d3.bisector(d => d.date).left,
format = d3.format("+.0%");
var focus = svg.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("circle")
.attr("r", 2.5)
.attr("stroke", "#000")
.attr("fill", "#fff");
focus.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em");
focus.append("line")
.attr("stroke", "#666")
.attr("stroke-width", 2)
.attr("y1", -height + margin.top)
.attr("y2", -margin.bottom);
var overlay = svg.append("rect")
.attr("class", "overlay")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width - margin.right - margin.left - 1)
.attr("height", height - margin.bottom - margin.top)
.on("mouseover", () => focus.style("display", null))
.on("mouseout", () => focus.style("display", "none"))
.on("mousemove", mousemove);
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisect(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.select("circle")
.attr("transform",
"translate(" + x(d.date) + "," + y(d.percent) + ")");
focus.select("line")
.attr("transform",
"translate(" + x(d.date) + "," + height + ")");
focus.select("text")
.attr("transform",
"translate(" + x(d.date) + "," + height + ")")
.text(input + ": " + d[input]);
}
}
function text(input, speed) {
var text = svg.selectAll(".text")
.data([data[data.length - 1]])
text.enter().append("text")
.attr("class", "text")
.attr("x", width - margin.left - margin.right)
.attr("dx", margin.right + margin.left)
.merge(text)
.transition().duration(speed)
.attr("y", d => y(d.percent))
.text(d => d[input])
var maxValue = d3.max(data, d => d[input]),
max = data.filter(f => f[input] === maxValue)[0]
var minValue = d3.min(data, d => d[input]),
min = data.filter(f => f[input] === minValue)[0]
var maxText = d3.select("#max")
.style("margin-left", "15px")
.html("Max value: <b>"
+ max[input]
+ "</b> Date: <b>"
+ formatDate(max.date)
+ "</b>")
var minText = d3.select("#min")
.html("Min value: <b>"
+ min[input]
+ "</b> Date: <b>"
+ formatDate(min.date)
+ "</b>")
}
var select = d3.select("#options")
.style("border-radius", "3px")
.style("padding", "1px 3px 1px 3px")
.on("change", function() {
update(this.value, 750)
})
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment