This example, using satirical data from The Onion, demonstrates how to wrap long axis labels to fit on multiple lines.
Note: The second point is not recommended practice but serves to ilustrate the variable wrap feature!
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Wrapping Long Labels</title>
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.title {
font: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var margin = {top: 80, right: 180, bottom: 80, left: 180},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var padding = 0.1, outerPadding = 0.3,
x = d3.scale.ordinal()
.rangeRoundBands([0, width], padding, outerPadding);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(8, "%");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.tsv("data.tsv", type, function (error, data) {
var a = alpha(data, v), //scale factor between value and bar width
mid = Midi(data, v, a), //mid-point displacement of bar i
w = Wi(data, v, a); //width of bar i
x.range(data.map(mid)); //force irregular intervals based on value
x.domain(data.map(function (d) {
return d.name;
}));
y.domain([0, d3.max(data, v)]);
svg.append("text")
.attr("class", "title")
.attr("x", x(data[0].name))
.attr("y", -26)
.attr("shape-rendering", "crispEdges")
.text("Why Are We Leaving Facebook?");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll(".tick text")
.call(wrap, function (d, i) {
return w(i);
});
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d, i) {
return x(d.name) - a * d.value/2; //center the bar on the tick
})
//using x.range sets x.rangeBands to zero, compute width as a function of value
.attr("width", x.rangeBand() || function (d) {
return a * d.value; //`a` already accounts for both types of padding
})
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
});
});
function wrap(text, width) {
text.each(function (d, i) {
var text = d3.select(this),
words = text.html(d).text().split(/\s+/).reverse(), //reset html to clear any tspans added before
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"),
//[edit]add dWidth
dWidth = typeof width === "function" ? width(d, i) : width;
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > dWidth/*[edit]*/) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
function type(d) {
d.value = +d.value;
return d;
}
function v(d) {
return +d.value;
}
function alpha(values, value) {
var n = values.length, total = d3.sum(values, value);
return (width - (n - 1) * padding * width / n - 2 * outerPadding * width / n) / total
}
function Wi(values, value, alpha) {
return function (i) {
return value(values[i]) * alpha
}
}
function Midi(values, value, alpha) {
var w = Wi(values, value, alpha), n = values.length;
return function (_, i) {
var op = outerPadding * width / n, p = padding * width / n;
return op + d3.sum(values.slice(0, i), value) * alpha + i * p + w(i) / 2;
}
}
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js