Skip to content

Instantly share code, notes, and snippets.

@LemoNode
Last active October 3, 2018 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LemoNode/73dbb9d6a144476565386f48a2df2e3b to your computer and use it in GitHub Desktop.
Save LemoNode/73dbb9d6a144476565386f48a2df2e3b to your computer and use it in GitHub Desktop.
Bar chart
license: gpl-3.0

A bar chart

date value
2018-jan 95
2018-feb 75
2018-mar 45
2018-apr 65
2018-may 88
2018-jun 78
2018-jul 70
2018-aug 33
2018-sep 43
2018-okt 53
2018-nov 31
2018-dec 79
2019-jan 21
2019-feb 43
2019-mar 55
2019-apr 33
2019-may 65
2019-jun 12
2019-jul 32
2019-aug 76
2019-sep 56
2019-okt 78
2019-nov 77
2019-dec 57
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
body {
padding-top: 25px;
margin: auto;
width: 650px;
font: 18px arial;
}
</style>
</head>
<body>
<b>Dynamic bar-chart example.</b>
<svg id="chart" width="650" height="420"></svg>
Choose year:
<select id="year"></select>
<input type="checkbox" id="sort">
Toggle sort
<script>
d3.csv("data.csv").then(d => chart(d));
function chart(csv) {
csv.forEach(function(d) {
var dates = d.date.split("-");
d.year = dates[0]; d.month = dates[1];
d.value = +d.value;
return d;
})
var months = [...new Set(csv.map(d => d.month))],
years = [...new Set(csv.map(d => d.year))];
var options = d3.select("#year").selectAll("option")
.data(years)
.enter().append("option")
.text(d => d)
var svg = d3.select("#chart"),
margin = {top: 25, bottom: 10, left: 25, right: 25},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand()
.range([margin.left, width - margin.right])
.padding(0.1)
.paddingOuter(0.2)
var y = d3.scaleLinear()
.range([height - margin.bottom, margin.top])
var xAxis = g => g
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(d3.axisBottom(x).tickSizeOuter(0))
var yAxis = g => g
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y))
svg.append("g")
.attr("class", "x-axis")
svg.append("g")
.attr("class", "y-axis")
update(d3.select("#year").property("value"), 0)
function update(year, speed) {
var data = csv.filter(f => f.year == year)
y.domain([0, d3.max(data, d => d.value)]).nice()
svg.selectAll(".y-axis").transition().duration(speed)
.call(yAxis);
data.sort(d3.select("#sort").property("checked")
? (a, b) => b.value - a.value
: (a, b) => months.indexOf(a.month) - months.indexOf(b.month))
x.domain(data.map(d => d.month))
svg.selectAll(".x-axis").transition().duration(speed)
.call(xAxis)
var bar = svg.selectAll(".bar")
.data(data, d => d.month)
bar.exit().remove();
bar.enter().append("rect")
.attr("class", "bar")
.attr("fill", "steelblue")
.attr("width", x.bandwidth())
.merge(bar)
.transition().duration(speed)
.attr("x", d => x(d.month))
.attr("y", d => y(d.value))
.attr("height", d => y(0) - y(d.value))
}
chart.update = update;
}
var select = d3.select("#year")
.style("border-radius", "5px")
.on("change", function() {
chart.update(this.value, 750)
})
var checkbox = d3.select("#sort")
.style("margin-left", "45%")
.on("click", function() {
chart.update(select.property("value"), 750)
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment