Reputation: 473
I've drawn a bar chart based on array of objects like this:
var arr = [
{first: "a", second: "middle1", third: "firstVeryVeryVeryVeryLong", value: 20},
{first: "secondVeryVeryVeryVeryLong", second: "b", third: "middle2", value: 40},
{first: "middle3", second: "thirdVeryVeryVeryVeryLong", third: "c", value: 51}
]
I want all three parameters (first, second and third) in the axis labels on my bars, but the "first" and "second" have to be in the first row and the "third" in the second one. I've tried to use the wrap function http://bl.ocks.org/mbostock/7555321 but it wraps labels using their length, as I need wrap them by quantity of words
Here is my fiddle: https://jsfiddle.net/anton9ov/pqhuuk12/
Upvotes: 0
Views: 96
Reputation: 1410
wrap
function from https://bl.ocks.org/mbostock/7555321 can be adopted:
svg.append("g")
.attr("transform", "translate(" + labelLength + ", 0)")
.call(yAxis)
.selectAll('text')
.call(wrap, yScale.bandwidth());
function wrap(text, height) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
//start the text from bar top
y = text.attr("y") - (barHeight/2),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > height) {
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);
}
}
});
}
Here is your updated fiddle: https://jsfiddle.net/pqhuuk12/8/
Upvotes: 0