- Size and scale SVG elements based on their containers.
- Reset scales when the window sizes.
- Re-size all the things.
Size and scale SVG elements based on their containers.
var margin = {top: 30, right: 10, bottom: 30, left: 10}
, width = parseInt(d3.select('#chart').style('width'), 10)
, width = width - margin.left - margin.right
, 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
// ordinal scales are easier for uniform bar heights
// I'll set domain and rangeBands after data loads
var y = d3.scale.ordinal();
var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(percent);
Reset scales when the window sizes
We can catch the resize event on window and running a function:
d3.select(window).on('resize', resize);
function resize() {
// update width
width = parseInt(d3.select('#chart').style('width'), 10);
width = width - margin.left - margin.right;
// reset x range
x.range([0, width]);
// do the actual resize...
}
Resize All Things
Here’s the list again:
- top axis
- bottom axis
- background bars
- foreground (data) bars
- labels (maybe)
- median ticks
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'));
}
