Skip to content

Instantly share code, notes, and snippets.

@davidrapin
Last active October 12, 2017 17:00
Show Gist options
  • Save davidrapin/69afce17c7618aca71086e8425293d73 to your computer and use it in GitHub Desktop.
Save davidrapin/69afce17c7618aca71086e8425293d73 to your computer and use it in GitHub Desktop.
Simple D3 histogram
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
border: 1px solid red;
}
</style>
<svg id="b1" ></svg>
<svg id="b2" ></svg>
<svg id="b3" ></svg>
<svg id="b4" ></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
function Histogram(svgId, width, height) {
var margin = {top: 20, right: 15, bottom: 20, left: 15};
width = width || 180;
height = height || 100;
this.barColor = "steelblue";
this.highlightColor = "red"
this.highlightValue = null;
this.values = [];
this.bars = 5;
this.height = height - margin.top - margin.bottom;
this.width = width - margin.left - margin.right;
var svg = d3
.select("body svg#" + svgId)
.attr("width", width)
.attr("height", height)
this.g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}
function log() {
console.log.apply(console, arguments)
}
Histogram.prototype.highlight = function(value) {
var self = this;
self.highlightValue = value;
self.g
.selectAll(".bar rect")
.style('fill', function(d) {
return self.highlightValue !== null && d.x0 <= self.highlightValue && self.highlightValue < d.x1
? self.highlightColor
: self.barColor
});
}
Histogram.prototype.render = function(values) {
this.values = values;
this._render();
}
Histogram.prototype._render = function() {
var self = this;
var formatCount = d3.format(",.0f");
// x scale
var x = d3.scaleLinear()
.domain([d3.min(self.values), d3.max(self.values)])
.rangeRound([0, self.width])
.nice(self.bars);
var bins = d3.histogram()
.domain(x.domain())
.thresholds(x.ticks(self.bars))
(self.values);
// y scale
var y = d3.scaleLinear()
.domain([0, d3.max(bins, function(d) { return d.length; })])
.range([self.height, 0]);
var bar = self.g.selectAll(".bar")
.data(bins)
.enter()
.append("g")
.attr("class", "bar")
.attr("transform", function(d) {
return "translate(" + x(d.x0) + "," + y(d.length) + ")";
});
bar.exit().remove();
bar.append("rect")
.attr("x", 1)
.style("fill", self.barColor)
.attr("width", x(bins[0].x1) - x(bins[0].x0) - 1)
.attr("height", function(d) { return self.height - y(d.length); });
bar.append("text")
.attr("dy", ".5em")
.attr("y", -6)
.style("visibility", function(d) { return d.length > 0 ? "visible" : "hidden"; })
.style("fill", "#222")
.style("font", "10px sans-serif")
.attr("x", (x(bins[0].x1) - x(bins[0].x0)) / 2)
.attr("text-anchor", "middle")
.text(function(d) { return formatCount(d.length); });
self.g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + self.height + ")")
.call(d3.axisBottom(x).ticks(self.bars));
}
var h1 = new Histogram("b1");
h1.render(d3.range(1000).map(d3.randomBates(5)));
h1.highlight(0.4)
var h2 = new Histogram("b2");
h2.render(d3.range(1000).map(d3.randomBates(7)).map(function(x) {return x + 10}));
h2.highlight(10.3)
h2.highlight(10.7)
var h3 = new Histogram("b3");
h3.render(d3.range(1000).map(d3.randomUniform(7)).map(function(x) {return x + 5}));
h3.highlight(9)
var h4 = new Histogram("b4");
h4.render(d3.range(1000).map(d3.randomExponential(7)).map(function(x) {return x + 10}));
h4.highlight(10.3)
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment