Skip to content

Instantly share code, notes, and snippets.

@eyeseast
Created September 1, 2013 21:01
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save eyeseast/6407300 to your computer and use it in GitHub Desktop.
Save eyeseast/6407300 to your computer and use it in GitHub Desktop.
Code from my post on responsive bar charts.
<div id="chart">
<h4>Percent of adults over 25 with at least a bachelor's degree:</h4>
<p><strong>Median:</strong> <span class="median"></span></p>
<small>Source: <cite><a href="http://census.gov">U.S. Census Bureau</a></cite>, via <cite><a href="http://beta.censusreporter.org/compare/01000US/040/table/?release=acs2011_1yr&table=B15003">Census Reporter</a></cite></small>
</div>
var url = "/visible-data/data/census/bachelors-degrees.csv"
, margin = {top: 30, right: 10, bottom: 30, left: 10}
, width = parseInt(d3.select('#chart').style('width'), 10)
, width = width - margin.left - margin.right
, height = 200 // placeholder
, barHeight = 20
, spacing = 3
, percent = d3.format('%');
// scales and axes
var x = d3.scale.linear()
.range([0, width])
.domain([0, .4]); // hard-coding this because I know the data
var y = d3.scale.ordinal();
var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(percent);
// create the chart
var chart = d3.select('#chart').append('svg')
.style('width', (width + margin.left + margin.right) + 'px')
.append('g')
.attr('transform', 'translate(' + [margin.left, margin.top] + ')');
d3.csv(url).row(function(d) {
d.Total = +d.Total;
d["Bachelor's degree"] = +d["Bachelor's degree"];
d.percent = d["Bachelor's degree"] / d.Total;
return d;
}).get(function(err, data) {
// sort
data = _.sortBy(data, 'percent').reverse();
// set y domain
y.domain(d3.range(data.length))
.rangeBands([0, data.length * barHeight]);
// set height based on data
height = y.rangeExtent()[1];
d3.select(chart.node().parentNode)
.style('height', (height + margin.top + margin.bottom) + 'px')
// render the chart
// add top and bottom axes
chart.append('g')
.attr('class', 'x axis top')
.call(xAxis.orient('top'));
chart.append('g')
.attr('class', 'x axis bottom')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis.orient('bottom'));
var bars = chart.selectAll('.bar')
.data(data)
.enter().append('g')
.attr('class', 'bar')
.attr('transform', function(d, i) { return 'translate(0,' + y(i) + ')'; });
bars.append('rect')
.attr('class', 'background')
.attr('height', y.rangeBand())
.attr('width', width);
bars.append('rect')
.attr('class', 'percent')
.attr('height', y.rangeBand())
.attr('width', function(d) { return x(d.percent); })
bars.append('text')
.text(function(d) { return d.Name; })
.attr('class', 'name')
.attr('y', y.rangeBand() - 5)
.attr('x', spacing);
// add median ticks
var median = d3.median(data, function(d) { return d.percent; });
d3.select('span.median').text(percent(median));
bars.append('line')
.attr('class', 'median')
.attr('x1', x(median))
.attr('x2', x(median))
.attr('y1', 1)
.attr('y2', y.rangeBand() - 1);
});
// resize
d3.select(window).on('resize', resize);
function resize() {
// update width
width = parseInt(d3.select('#chart').style('width'), 10);
width = width - margin.left - margin.right;
// resize the chart
x.range([0, width]);
d3.select(chart.node().parentNode)
.style('height', (y.rangeExtent()[1] + margin.top + margin.bottom) + 'px')
.style('width', (width + margin.left + margin.right) + 'px');
chart.selectAll('rect.background')
.attr('width', width);
chart.selectAll('rect.percent')
.attr('width', function(d) { return x(d.percent); });
// update median ticks
var median = d3.median(chart.selectAll('.bar').data(),
function(d) { return d.percent; });
chart.selectAll('line.median')
.attr('x1', x(median))
.attr('x2', x(median));
// update axes
chart.select('.x.axis.top').call(xAxis.orient('top'));
chart.select('.x.axis.bottom').call(xAxis.orient('bottom'));
}
// highlight code blocks
hljs.initHighlighting();
.bar rect {
stroke: #fff;
shape-rendering: crispEdges;
}
.bar rect.background {
fill: #eee;
}
.bar rect.percent {
fill: #74c476;
}
.bar:hover rect.percent {
fill: #a1d99b;
}
.bar text {
font-size: 12px;
fill: #333;
}
.axis line {
stroke: #ccc;
stroke-width: 1;
}
line.median {
stroke: #777;
stroke-width: 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment