Skip to content

Instantly share code, notes, and snippets.

@pbogden
Last active February 2, 2017 16:16
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 pbogden/31bcf52ccf0174e08c6c to your computer and use it in GitHub Desktop.
Save pbogden/31bcf52ccf0174e08c6c to your computer and use it in GitHub Desktop.
Reusable bar chart
d3.barChart = function() {
var width = 960,
height = 500,
xValue = function(d) { return d[0]; },
yValue = function(d) { return d[1]; },
extent = null;
var margin = {top: 30, right: 30, bottom: 30, left: 30},
xScale = d3.scaleBand(),
yScale = d3.scaleLinear(),
xAxis = d3.axisBottom(),
yAxis = d3.axisLeft();
function chart(selection) {
selection.each(function(data) {
// Convert to standard data representation greedily;
// this is needed for nondeterministic accessors.
data = data.map(function(d, i) {
return [ xValue.call(data, d, i), yValue.call(data, d, i) ];
});
var g = d3.select(this).append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
xScale
.range([0, width - margin.left - margin.right])
.padding(.1)
.domain(data.map(function(d) { return d[0]; }));
extent = extent || d3.extent(data, function(d) { return d[1]; });
extent[0] = Math.min(0, extent[0]);
yScale
.range([height - margin.top - margin.bottom, 0])
.domain(extent);
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale)
.ticks(8, "%");
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + yScale.range()[0] + ")")
.call(xAxis);
g.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("fill", "black")
.text("Frequency");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d[0]); })
.attr("width", xScale.bandwidth())
.attr("y", function(d) { return ( yScale(0) - yScale(d[1]) ) > 0 ? yScale(d[1]) : yScale(0); })
.attr("height", function(d) { return Math.abs( yScale(0) - yScale(d[1]) ) });
g.append("path")
.datum([ [d3.min(xScale.range()), yScale(0)], [d3.max(xScale.range()), yScale(0)] ])
.attr("d", d3.line())
.style("stroke", "#333")
.style("stroke-width", "1")
});
}
chart.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
return chart;
};
chart.width = function(_) {
if (!arguments.length) return width;
width = _;
return chart;
};
chart.height = function(_) {
if (!arguments.length) return height;
height = _;
return chart;
};
chart.x = function(_) {
if (!arguments.length) return xValue;
xValue = _;
return chart;
};
chart.y = function(_) {
if (!arguments.length) return yValue;
yValue = _;
return chart;
};
chart.xScale = function(_) {
if (!arguments.length) return xScale;
xScale = _;
return chart;
};
chart.yScale = function(_) {
if (!arguments.length) return yScale;
yScale = _;
return chart;
};
chart.extent = function(_) {
if (!arguments.length) return extent;
extent = _;
return chart;
};
return chart;
}
letter frequency
A -.08167
B .01492
C .02782
D .04253
E .12702
F .02288
G .02015
H .06094
I .06966
J .00153
K .00772
L .04025
M .02406
N .06749
O .07507
P .01929
Q .00095
R .05987
S .06327
T .09056
U .02758
V .00978
W .02360
X .00150
Y .01974
Z .00074
<!DOCTYPE html>
<meta charset="utf-8">
<title>bar</title>
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
#container {
position: relative;
width: 100%;
max-width: 960px;
margin: auto;
}
svg {
position: absolute;
top: 0;
left: 0;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="d3.barChart.js"></script>
<script>
var width = 960,
height = 500,
margin = { top: 50, left: 50, bottom: 50, right: 50 };
var container = d3.select("body").append("div")
.attr("id", "container")
var g = container.append("svg")
.attr('viewBox', "0, 0, " + width + ", " + height)
.attr('preserveAspectRatio', "xMinYMid")
.append("g")
g.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "#ccc")
setContainerHeight(); // initial load
d3.select(window).on('resize', setContainerHeight);
d3.tsv("data.tsv", function(error, data) {
if (error) throw error;
var chart = d3.barChart()
.x(function(d) { return d.letter; })
.y(function(d) { return +d.frequency; })
.margin(margin)
.width(width)
.height(height)
.extent([-.085, .13]); // optional
g.datum(data)
.call(chart);
});
function setContainerHeight() {
var w = parseInt( container.style("width"), 10);
var a = width / height;
container.style('height', w / a + 'px');
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment