Derick Kolln
Derick Kolln

Reputation: 633

Interaction with updated/entered elements

I wonder how to solve this problem in D3.js. This code below enters, updates or exits every 5 seconds and show up or disappear a random number of name elements that are part in the array dataset. This array also contains id elements. Now i want to click on a updated element that appears on screen, for example "foo" and want it's id (that means 1) shows up after I clicked that "foo"element. The name of the function is called testfunction, but i think something is not right with that function. The problem is, that the original name texts all disappear after click on it and the new id text appear. But i want them to be both on screen after using the clickfunction Hope some of you guys can help. Thanks

  var svg = d3.select("body").append("svg");

  var dataset = [{
  name: "foo", id: "1" 
}, {
  name: "bar",  id: "2"
}, {
  name: "baz", id: "3"
}, ];

        print(dataset);

        setInterval(() => {
          var data = dataset.slice(Math.random() * 6);
          print(data);
        }, 7000);

        function print(data) {

            var texts = svg.selectAll(".texts")
                .data(data);

            textsExit = texts.exit().remove();

            textsEnter = texts.enter()
                .append("text")
                .attr("class", "texts");

            textsUpdate = texts.merge(textsEnter)
                .attr("x", 10)
                .attr("y", (d, i) => 20 + i * 16)
                .text((d,i) => "TextNumber" + (i+1) + ", name: " + d.name)
                .on("click", testfunction);

    function testfunction(){

                    textsUpdate
                    .attr("x", 200)
                    .attr("y", function(d, i) { return (490 + i * 28)})
                    .text(function(d, i) { return "IDNumber" + (i+1) + ", Name: "+ d.id})



                    };


        }

Upvotes: 1

Views: 62

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

If I understood your problem correctly, the issue here is that you're changing your textsUpdate attributes, which will of course change textsUpdate's text positions (they don't disappear, though).

A solution is creating another text element:

var svg = d3.select("body").append("svg");

var dataset = [{
  name: "foo",
  id: "1"
}, {
  name: "bar",
  id: "2"
}, {
  name: "baz",
  id: "3"
}, ];

var testText = svg.append("text")
    .attr("x", 100)
    .attr("y", 100);

print(dataset);

setInterval(() => {
  var data = dataset.slice(Math.random() * 6);
  print(data);
}, 7000);

function print(data) {

   testText.text("");

  var texts = svg.selectAll(".texts")
    .data(data);

  textsExit = texts.exit().remove();

  textsEnter = texts.enter()
    .append("text")
    .attr("class", "texts");

  textsUpdate = texts.merge(textsEnter)
    .attr("x", 10)
    .attr("y", (d, i) => 20 + i * 16)
    .attr("cursor", "pointer")
    .text((d, i) => "TextNumber" + (i + 1) + ", name: " + d.name)
    .on("click", function(d, i) {
      testfunction(d, i);
    });

  function testfunction(data, index) {

    testText.text(function() {
        return "IDNumber" + (index + 1) + ", Name: " + data.id
      })

  };

}
<script src="https://d3js.org/d3.v4.js"></script>

Upvotes: 1

Related Questions