简体   繁体   中英

Dynamically add rectangles on click event

I'm trying to add rectangles dynamically on-click event. The goal is once i click on a rectangle, additional rows with text will be added.

I have tried to use the script below:

svg.append("rect")
 .attr("x", 0)
 .attr("y", 31)
 .attr("width", 250)
 .attr("height", 30)
 .attr("fill", "rgb(82,82,82)")
 .attr("stroke-width", 0)
 .on("click",function ()
 {
      MyDataSource= dataset.filter(function(d) {
        return d.Topic== "MyTopic";
                  });
    console.log("Button clicked");
    var topics = svg.selectAll("g")
    .data(MyDataSource)
    .enter()
    .append("g")
    .attr("class","bar");

      var rects = topics.append("rect")
    .attr("y", function(d, i) {
      return (i+2) * 31;
    })
    .attr("x", 0)
    .attr("width", 250)
    .attr("height",30) 
    .attr("fill", "rgb(8,81,156)") 
     .attr("stroke-width",0)
     .append("title")
     .text(function(d) {
          return d.Topics;
     });


      var recttext = topics.append("text")
    .attr("y", function(d,i) {
      return (i+2)*31+20;
    })
    .attr("x", 150)
    .text(function(d) {
      return d.Topics;
    })  ;                  
 });

Once i click on that rectangle, the console would have "Button clicked" but nothing will happen on the page.

If i take away the script in the Onclick function and add it to the page default code, the rows would be added successfully when the page first loads.

How can I set this code to work correctly on the On-click event?

Thanks in advance

If you want to add new rectangles on every click, make sure you also add new data to MyDataSource . With the selection.data().enter().append() pattern, d3 compares the argument passed to data against whatever data is exists on selection. New elements are appended for all new data. Right now, the data is the same on every click (except the first), so d3 decides there is nothing to update. Thus, topics refers to an empty selection and your subsequent calls to append to it will not render anything.

However, if MyDataSource is not changing at all, you'd just end up with a long array that contains many copies of your data set. A better choice in this case is to use .datum() instead of .data() , which allows you to bind many elements to the same single datum. If that datum is an array, you can then iterate through it to create new elements and achieve the same end as .data() but a cleaner underlying data structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM