Reputation: 484
I am porting some d3 graphs from another project over to a personal Vue-based project. Everything is working as expected except for attempting to center labels in the arcs of a pie chart using the arc.centroid(d) method. I keep getting two errors, which I'll explain below.
I have both my arc function and pie function in the computed hook.
My function for the labels, below, is in my methods hook:
pieLabel(width, height, margin) {
d3.select(".pie-chart-wrapper svg")
.append("g")
.attr("class", "pie-chart-labels")
.attr(
"transform",
`translate(${width / 2 + margin},${height / 2 + margin})`
)
.selectAll("text")
.data(this.pie)
.enter()
.append("text")
.style("fill", "black")
.attr("text-anchor", "middle")
.text(d => `${d3.format(",")(d.value)}`)
.each(d => {
const center = this.arc.centroid(d);
d3.select(this)
.attr("x", center[0])
.attr("y", center[1]);
});
}
The errors I keep getting are this.arc is undefined and this.setAttribute is not a function.
How do I resolve these errors?
After moving some things around, I was able to get the error for this.arc to go away. I then logged 'this' and it returned a bunch of Vue prototypes, which leads me to believe that Vue thinks I am trying to reference a Vue element that isn't there and is thus causing the error.
Anyhow, I returned the code back to how it was when it was working outside of Vue but returning the two errors when inside the Vue hook.
This is not for a specific project. I am just trying to gain an understanding for how Vue and d3.js work together.
Upvotes: 0
Views: 784
Reputation: 13129
What you're running into is the this
scoping of arrow functions. In short: they use this
from the outer scope, not their internal one. By contrast, the following should work:
.each(function(d) {
const center = this.arc.centroid(d);
d3.select(this)
.attr("x", center[0])
.attr("y", center[1]);
});
because now, this
points to the text
node, not the the Vue scope.
Upvotes: 1