Reputation: 84
I have added some text nodes using d3 as below.
svg.selectAll('text.label')
.data(studentTable, d => d.name)
.enter()
.append('text')
.attrs({
class: 'label',
x: d => x(d.value),
y: d => y(d.rank),
})
Now in transition i need to access the width of the currently selected text node and set the x position according to the width. (See the comments of below code snippet).
svg.selectAll('.label').data(studentTable, d => d.name)
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attrs({
x: d => x(d.value), // Here i need to get the width of current text node to set x position
y: d => y(d.rank)
});
Any convenient way to do this ? Thanks
Upvotes: 1
Views: 636
Reputation: 102194
The method for getting the text length is getComputedTextLength()
, which you have to use with the node. To get the text node inside the arrow function, use the third and second arguments combined. So:
.attrs({
x: (d, i, n) => n[i].getComputedTextLength() + whatever,
y: d => y(d.rank)
});
Here is a demo using your code, the red line shows the end of the text:
const svg = d3.select("svg");
svg.selectAll('text.label')
.data([{
value: 100,
rank: 50
}])
.enter()
.append('text')
.attrs({
class: 'label',
x: d => d.value,
y: d => d.rank,
})
.text("Lorem ipsum dolor sit amet");
svg.append("line")
.attr("x1", 100 + svg.select(".label").node().getComputedTextLength())
.attr("x2", 100 + svg.select(".label").node().getComputedTextLength())
.attr("y1", 0)
.attr("y2", 100)
.style("stroke", "red");
svg.selectAll('.label')
.data([{
value: 100,
rank: 50
}])
.transition()
.delay(1000)
.duration(1000)
.ease(d3.easeLinear)
.attrs({
x: (d, i, n) => d.value + n[i].getComputedTextLength(),
y: d => d.rank
});
<svg width="500" height="100"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
Upvotes: 3