function barChart() { var key = function (d) { return d.key; }; var margin = { top: 20, right: 20, left: 20, bottom: 20 }; var width = 500; var height = 500; var xScale = d3.scale.linear(); var yScale = d3.scale.ordinal(); var yAxis = d3.svg.axis().orient('left').tickSize(0); var sort = function (a, b) { return a.count - b.count; }; var padding = 0.1; var fill = 'steelblue'; var fillOpacity = 1; var stroke = null; var strokeWidth = null; var strokeOpacity = null; function chart(selection) { selection.each(function (data, index) { data = d3.nest() .key(key) .entries(data); data = data.map(function (d) { d.count = d.values.length; return d; }) .sort(sort); width = width - margin.left - margin.right; height = height - margin.top - margin.bottom; var svg = d3.select(this).selectAll('svg').data([data]); svg.exit().remove(); svg.enter().append('svg'); svg .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); xScale .domain([0, d3.max(data, function (d) { return d.count; })]) .range([0, width]); yScale .domain(data.sort(sort).map(function (d) { return d.key; })) .rangeRoundBands([height, 0], padding, 0); var g = svg.select('g'); g.append('g') .attr('class', 'y axis') .call(yAxis.scale(yScale)); var groups = g.selectAll('g.bars').data(data); groups.exit().remove(); groups.enter().append('g'); groups.attr('class', 'bars'); groups.append('rect') .attr('x', function (d) { return xScale(0); }) .attr('y', function (d) { return yScale(d.key); }) .attr('width', function (d) { return xScale(d.count); }) .attr('height', yScale.rangeBand()) .style('fill', fill) .style('fill-opacity', fillOpacity) .style('stroke', stroke) .style('stroke-width', strokeWidth) .style('stroke-opacity', strokeOpacity); groups.append('text') .attr('class', 'bar-text') .attr('x', function (d) { return xScale(d.count) - 2; }) .attr('y', function (d) { return yScale(d.key) + ((yScale.rangeBand() / 2) / 2); }) .attr('dx', '') .attr('dy', '.71em') .attr('text-anchor', 'end') .style('fill', '#ffffff') .style('font-size', yScale.rangeBand() / 2) .text(function (d) { return d.count; }); groups.selectAll('.bars text').each(function (d) { var text = d3.select(this); var width = text.node().getBBox().width; if (width > xScale(d.count)) { text.attr('text-anchor', 'start') .style('fill', '#000000') .attr('x', function (d) { return xScale(d.count) + 5; }); } }); }); } function valuator(val) { if (typeof val === 'function') return val; if (typeof val === 'string' || typeof val === 'number') { return function (d) { return d[val]; } } throw new Error(val + ' is an unexpected type'); } // Public API chart.key = function (_) { if (!arguments.length) return key; key = valuator(_); return chart; }; chart.margin = function (_) { if (!arguments.length) return margin; margin.top = typeof _.top !== 'undefined' ? _.top : margin.top; margin.right = typeof _.right !== 'undefined' ? _.right : margin.right; margin.bottom = typeof _.bottom !== 'undefined' ? _.bottom : margin.bottom; margin.left = typeof _.left !== 'undefined' ? _.left : margin.left; return chart; }; chart.width = function (_) { if (!arguments.length) return width; width = typeof _ === 'number' ? _ : width; return chart; }; chart.height = function (_) { if (!arguments.length) return height; height = typeof _ === 'number' ? _ : height; return chart; }; chart.sort = function (_) { if (!arguments.length) return sort; sort = typeof _ === 'function' ? _ : sort; return chart; }; chart.padding = function (_) { if (!arguments.length) return padding; padding = typeof _ === 'number' ? _ : padding; return chart; }; chart.fill = function (_) { if (!arguments.length) return fill; fill = _; return chart; }; chart.fillOpacity = function (_) { if (!arguments.length) return fillOpacity; fillOpacity = _; return chart; }; chart.stroke = function (_) { if (!arguments.length) return stroke; stroke = _; return chart; }; chart.strokeWidth = function (_) { if (!arguments.length) return strokeWidth; strokeWidth = _; return chart; }; chart.strokeOpacity = function (_) { if (!arguments.length) return strokeOpacity; strokeOpacity= _; return chart; }; return chart; }