Saqib Ali Saqib Ali - 7 months ago 23
Javascript Question

How to change d3.js text entry from within that text's onclick method?

My AngularJS app uses d3.js to draw a nice chart.

While drawing this chart, it uses paints some text on the screen.
I want to change that text when someone clicks on it based on the boolean value of

myCondition
. This is how I do it:

var nodeEnter = node.enter()

var myLabel = nodeEnter.append("text")
.attr("x", 50)
.attr("dy", "3")
.text("Hello World")
.style("fill-opacity", 0)
.style("cursor", "pointer")
.on("click", function(d) {
if (myCondition)
myLabel.text("Mars");
else
myLabel.text("Venus");
}
);


It sorta works. The value of the text does indeed change from
Hello World
to
Mars
or
Venus
. But there is a problem. This code is called within a recursive function and within a loop. That recursion + loop use the same code to draw numerous such texts on the SVG Container. So when I click this label, not only does it change the text that I want. It also changes the text in other places too! I don't want that. How can I prevent it?

I really just need a way I can address
this
or
myself
from within the click function so it knows I'm talking about the object. How?

Answer

Without knowing your recursive function and the loop, I'll try two different approaches, I hope that one of them works.

The first one is using this for the click event:

var myLabel = nodeEnter.append("text")
          .attr("x", 50)
          .attr("dy", "3")
          .text("Hello World")
          .style("fill-opacity", 0)
          .style("cursor", "pointer")
          .on("click", function(d) {
              if (myCondition) 
                  d3.select(this).text("Mars");
              else
                  d3.select(this).text("Venus");
            }
          );

If this doesn't work, you can try to set a specific class to your different myLabel texts. Doing this, even if you have several myLabel in your SVG, each one has a unique class. Suppose that index is a specific value for the loop (like i). So, you can try:

var myLabel = nodeEnter.append("text")
          .attr("x", 50)
          .attr("dy", "3")
          .attr("class", "myLabel" + index)//index is any value unique for the loop
          .text("Hello World")
          .style("fill-opacity", 0)
          .style("cursor", "pointer")
          .on("click", function(d) {
              if (myCondition) 
                  d3.selectAll(".myLabel" + index).text("Mars");
              else
                  d3.selectAll(".myLabel" + index).text("Venus");
            }
          );
Comments