I cannot select the (“text”) in my svg when I want to change the values

Tags: , ,



I have a problem where I can append the text into SVG but when I want it to change I can’t seem to select it to change. The code above the d3.select("button") all works as well as the bar.transition. Can someone help me figure out how to select the "text" so when I click the button it’ll use the new dataset?

var bar = svg.selectAll("rect")
  .data(dataset)
  .enter();

bar.append("rect")
  .attr("x", function(d) {
    return xScale(d[0]);
  })
  .attr("y", function(d) {
    return yScale(d[2]);
  })
  .attr("width", xScale.bandwidth())
  .attr("height", function(d) {
    return height - yScale(d[2]);
  })
  .attr("class", function(d) {
    var s = "bar ";
    if (d[2] < 50) {
      return s + "bar1";
    } else if (d[2] < 100) {
      return s + "bar2";
    } else {
      return s + "bar3";
    }
  });

bar.append("text")
  .attr("dy", "1.3em")
  .attr("x", function(d) {
    return xScale(d[0]) + xScale.bandwidth() / 2;
  })
  .attr("y", function(d) {
    return yScale(d[2]);
  })
  .attr("text-anchor", "middle")
  .attr("font-family", "sans-serif")
  .attr("font-size", "11px")
  .attr("fill", "black")
  .text(function(d) {
    return d[2];
  });

d3.select("button")
  .on("click", function() {
    var dataset = [
      ['Jun-19', 8.6, 21.7],
      ['Jul-19', 8.68, 17.98],
      ['Aug-19', 8.9, 25.38],
      ['Sep-19', 6.38, 11.6],
      ['Oct-19', 10.36, 65.08],
      ['Nov-19', 22.36, 125.72],
      ['Dec-19', 26.52, 112.22],
      ['Jan-20', 21.08, 76.1],
      ['Feb-20', 6, 44, 19.625],
      ['Mar-20', 4.68, 8.95],
      ['Apr-20', 7.4, 15.94],
      ['May-20', 7.36, 18.36]
    ];

    bar = svg.selectAll("rect")
      .data(dataset);

    bar.transition()
      .attr("x", function(d) {
        return xScale(d[0]);
      })
      .attr("y", function(d) {
        return yScale(d[2]);
      })
      .attr("width", xScale.bandwidth())
      .attr("height", function(d) {
        return height - yScale(d[2]);
      })
      .attr("class", function(d) {
        var s = "bar ";
        if (d[2] < 30) {
          return s + "bar1";
        } else if (d[2] < 60) {
          return s + "bar2";
        } else {
          return s + "bar3";
        }
      });

    svg.selectAll("text")
      .data(dataset)
      .transition()
      .attr("dy", "1.3em")
      .attr("x", function(d) {
        return xScale(d[0]) + xScale.bandwidth() / 2;
      })
      .attr("y", function(d) {
        return yScale(d[2]);
      })
      .attr("text-anchor", "middle")
      .attr("font-family", "sans-serif")
      .attr("font-size", "11px")
      .attr("fill", "black")
      .text(function(d) {
        return d[2];
      });

  });

I’ve tried using bar.selectAll("text") but it doesn’t work at all, but if I use svg.selectAll("text") it takes the ticks from my Axis.Left and moves it.

Answer

You cannot append text nodes as children of rect nodes – so the SVG probably never renders. Try using a g node per bar, and adding both the rect and the text to that. You can give it class barContainer, for example.

As for selecting the text and ignoring those from the axes, do as @Andrew Reid said in his comment and use barContainer.selectAll("text"). Alternatively, you can give all labels the class label and then use svg.selectAll(".label").



Source: stackoverflow