London-35
London-35

Reputation: 85

How to update labels using selection.join in D3?

I have a horizontal bar chart that gets updated when one of the radio buttons clicked. The bars get updated fine, however, the old labels seem not to be removed every time the labels get updated. Am I missing something here? it seems that the exit function is not working. I couldn't find examples that deal with labels.

enter image description here


    svg_bar.selectAll(".text-bar")
    .data(dataSet)
    .join(
    enter => enter
        .append("text")
        .attr('text-anchor', 'middle')
        .attr('font-size', '16px')
        .attr('font-family', 'sans-serif')
        .attr('fill', 'white')
      .call(enter => enter.transition()
        .duration(1000)
        .attr('y', (d) => yScale_h(d.clean_test) + yScale_h.bandwidth() / 2)
        .attr('x', (d) => xScale_h(d.Award) - 14)
        .text(function (d) {
          return `${d.Award} `;
        })
       ),
    update => update 
      .call(update => update.transition()
        .duration(1000)
        .text(function (d) {
          return `${d.Award} `;
        })
        .attr('y', (d) => yScale_h(d.clean_test) + yScale_h.bandwidth() / 2)
        .attr('x', (d) => xScale_h(d.Award) - 14)
       ),
    exit => exit
      .call(exit => exit.transition()
        .duration(1000)
        .remove()
       )
    );

Upvotes: 1

Views: 142

Answers (1)

Rodrigo Divino
Rodrigo Divino

Reputation: 1931

If you use svg_bar.selectAll(".text-bar"), the selection is always empty and d3 will always add new elements.

If you use svg_bar.selectAll("text"), the selection will include all text elements of the svg, and it will change other text elements such as the y-axis and title.

One approach to select only the texts of the bars is to select with a class, such as svg_bar.selectAll("text.bar"). For this to work, the appended bars need to be assigned to the 'bar' class with .classed('bar', true), so they selected in the next render.

svg_bar.selectAll("text.bar") // Selects the texts of class "bar"
    .data(dataSet)
    .join(
    enter => enter
        .append("text")
        .classed("bar", true) // Create texts with class "bar"
        .attr('text-anchor', 'middle')

...

Upvotes: 1

Related Questions