I am trying to transition only the textpath on which I am mousehovering but both textpaths in the example below get transitioned. Is there a way to only transition the one when hovering?
For the code below I modified this example and I am using version 5 of D3.js.
Here is the script:
<script>
//Create the SVG
var svg = d3.select("body").append("svg")
.attr("width", 900)
.attr("height", 900);
class graph {
constructor(opts){
this.x = opts.x;
this.y = opts.y;
this.container = svg.append('g')
.attr('class', 'country-wrapper')
.attr('transform', 'translate(' + this.x + ',' + this.y + ')')
.on('mouseover', this.handleMouseOver);
this.background = this.container.append('g')
.attr('class', 'background-viz')
this.appendText();
}
appendText(){
var d = "M0,300 A200,200 0 0,1 400,300";
console.log(d);
var path = this.background.append("path")
.attr("id", "wavy")
.attr("d", d)
.style("fill", "none")
.style("stroke", "#AAAAAA")
.style("stroke-dasharray", "5,5");
var textArc = this.background.append("text")
.style("text-anchor","middle")
.append("textPath")
.attr("xlink:href", "#wavy")
.attr("startOffset", "50%")
.text("placeholder for text here");
}
handleMouseOver(){
var d = "M75,300 A125,125 0 0,1 325,300";
console.log('new ', d);
d3.select(this).select('.background-viz').selectAll('path')
.transition()
.attr("d", "M75,300 A125,125 0 0,1 325,300");
}
}
for (var i = 0; i < 2; i++){
new graph({
x: i * 900/2,
y: 0
});
}
</script>
The issue is with the following line:
textPath.attr("xlink:href", "#wavy")
as both path have the same IDs and as you hover onto one, you see both the textPaths transitioning. You have to differentiate the IDs based on some value. Best solution would be to pass an ID and use it:
Here's how:
Pass ID while creating the paths, texts i.e. to every instance
new graph({
x: i * 900/2,
y: 0,
id: i
});
Use it/apply it to the paths and textPaths:
var path = this.background.append("path")
.attr("id", "wavy-"+this.id)
....
.append("textPath")
.attr("xlink:href", "#wavy-"+this.id)
Using the above changes, here's a code snippet:
//Create the SVG
var svg = d3.select("body").append("svg")
.attr("width", 900)
.attr("height", 900);
class graph {
constructor(opts){
this.x = opts.x;
this.y = opts.y;
this.id = opts.id;
this.container = svg.append('g')
.attr('class', 'country-wrapper')
.attr('transform', 'translate(' + this.x + ',' + this.y + ')')
.on('mouseover', this.handleMouseOver);
this.background = this.container.append('g')
.attr('class', 'background-viz')
this.appendText();
}
appendText(){
var d = "M0,300 A200,200 0 0,1 400,300";
var path = this.background.append("path")
.attr("id", "wavy-"+this.id)
.attr("d", d)
.style("fill", "none")
.style("stroke", "#AAAAAA")
.style("stroke-dasharray", "5,5");
var textArc = this.background.append("text")
.style("text-anchor","middle")
.append("textPath")
.attr("xlink:href", "#wavy-"+this.id)
.attr("startOffset", "50%")
.text("placeholder for text here");
}
handleMouseOver(){
var d = "M75,300 A125,125 0 0,1 325,300";
//console.log('new ', d);
d3.select(this).select('.background-viz').selectAll('path')
.transition()
.attr("d", "M75,300 A125,125 0 0,1 325,300");
}
}
for (var i = 0; i < 2; i++){
new graph({
x: i * 900/2,
y: 0,
id: i
});
}
<script src="https://d3js.org/d3.v5.min.js"></script>
Hope this helps.