Reputation: 4984
I have a stackblitz here - https://stackblitz.com/edit/lable-line-break-p1f9hb?file=src/app/bar-chart.ts
The x-axis have long labels that I need to split after the second word, so I have a title and sub title
When I'm creating the x-axis I'm calling a function that splits the string up and adds them as separate tspans
this.chart.append("g")
.call(this.x_axis)
.classed('x-axis', true)
.attr("transform", "translate(0," + this.height + ")")
.selectAll(".tick text")
.each(this.insertLinebreak)
private insertLinebreak (d) {
let labels = d3.select(".x-axis .tick text");
let words = d;
labels.text('');
let index = words.indexOf(' ', words.indexOf( ' ' ) + 1)
let title = words.substr(0, index)
let subtitle = words.substr(index + 1)
let tspantitle = labels.append('tspan').text(title)
let tspansubtitle = labels.append('tspan').text(subtitle)
tspantitle
.attr('x', 0)
.attr('dy', '15')
.attr('class', 'x-axis-title');
tspansubtitle
.attr('x', 0)
.attr('dy', '16')
.attr('class', 'x-axis-subtitle');
};
My probelm is its adding them in the wrong order and missing one of the titles
What I am doing wrong, is there a better way to do this.
Upvotes: 2
Views: 864
Reputation: 73731
The first line in insertLinebreak
is the source of the problem, because it retrieves all the label elements every time you want to process one of them (watch the console in this stackblitz):
private insertLinebreak(d) {
let labels = d3.select(".x-axis .tick text"); // <-- This line causes the problem
...
}
In order to select only the label that you are processing, use d3.select(this)
:
private insertLinebreak(d) {
let labels = d3.select(this);
...
}
See this stackblitz for a demo.
Upvotes: 1