D3.js 中的标签过渡:在更改时重命名标签名称并顺利过渡

Transition of labels in D3.js: Rename label names on change and transition smoothly

我是 d3 的初学者,我正在使用 D3.js 创建一个不断变化的条形图。我到目前为止可以创建条形图,单击单选按钮时更改数据集,并更改轴。

现在我没有开始工作的是更改 x 和 y 轴上标签的名称。我也无法正常工作,因为我的标签刻度线会随着我的条形图平滑过渡,它们只是突然改变。

对于我的标签名称,我试图删除这些名称,然后将其再次添加到我的更改功能中。但这只会从一开始就显示新文本:

附加到 svg:

 //y-axis
    svg.append("text")
        .attr("class", "y label")
        .attr("text-anchor", "end")
        .attr("y", -20)
        .attr("dy", ".75em")
        .attr("transform", "rotate(0)")
        .text("Crazy label name for axis");

然后删除它并在我的更改函数中重新添加它:

 svg.select(".y.label").remove();

         svg.append("text")
        .attr("class", "y label")
        .attr("text-anchor", "end")
        .attr("y", -20)
        .attr("dy", ".75em")
        .attr("transform", "rotate(0)")
        .text("new crazy text");

我也无法让我的刻度名称(或每个条的标签名称)与我的条平滑过渡。

谁能帮帮我?非常感谢!

这是完整的代码和示例数据:


 d3.selectAll("input").on("change", function(d) {
      selectDataset.call(this, d);
    });

    function selectDataset(d) {
      let value = this.value;
      if (value === "heat") {
        change(datasetTotal, value, "Default text");
      } else if (value === "cool") {
        change(datasetOption1, value, "Text 2");
      } else if (value === "area") {
        change(datasetOption2, value, "Text 3");
      }
}

    var margin = {
            top: (parseInt(d3.select('.area-heat-cool').style('height'), 10) / 20),
            right: (parseInt(d3.select('.area-heat-cool').style('width'), 10) / 20),
            bottom: (parseInt(d3.select('.area-heat-cool').style('height'), 10) / 20),
            left: (parseInt(d3.select('.area-heat-cool').style('width'), 10) / 5)
        },
        width = parseInt(d3.select('.area-heat-cool').style('width'), 10) - margin.left - margin.right,
        height = parseInt(d3.select('.area-heat-cool').style('height'), 10) - margin.top - margin.bottom;

    var div = d3.select(".area-heat-cool").append("div").attr("class", "toolTip");

    var y = d3.scaleBand()
        .rangeRound([height, 0], .2, 0.5)
        .paddingInner(0.1);

    var x = d3.scaleLinear()
        .range([0, width]);

    var xAxis = d3.axisBottom()
        .scale(x);

    var yAxis = d3.axisLeft()
        .scale(y);

    var svg = d3.select(".area-heat-cool").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    //x-axis
    svg.append("text")
          .attr("class", "x label")
          .attr("data-default", "text2_contact2")
          .attr("text-anchor", "end")
          .attr("x", width)
          .attr("y", height - 6)
          .text("Default text");

    //y-axis
    svg.append("text")
        .attr("class", "y label")
        .attr("text-anchor", "end")
        .attr("y", -20)
        .attr("dy", ".75em")
        .attr("transform", "rotate(0)")
        .text("Text of y Axis");


    d3.select("input[value=\"heat\"]").property("checked", true);
    change(datasetTotal);

    function change(dataset, optionSelect, textselect) {

        y.domain(dataset.map(function(d) {
            return d.label;
        }));
        x.domain([0, d3.max(dataset, function(d) {
            return d.value;
        })]);

        svg.select(".y.axis").remove();
        svg.select(".x.axis").remove();
        // svg.select(".y.label").remove();

        d3.select(".x.label").text(textselect).transition().duration(1000) ;

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(0)")
            .attr("x", 50)
            .attr("dx", ".1em")
            .style("text-anchor", "end")
            .text("Option %");


        var bar = svg.selectAll(".bar")
            .data(dataset, function(d) {
                return d.label;
            });

        var barExit = bar.exit().remove();

        var barEnter = bar.enter()
                        .append("g")
                        .attr("class", "bar");

        var barRects = barEnter.append("rect")
            .attr("x", function(d) {
            return x(0);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.bandwidth());

        var barTexts = barEnter.append("text")
            .attr("x", function(d) {
                return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });


        barRectUpdate = bar.select("rect")
                  .transition()
                  .duration(3050)
                  .attr("x", function(d) {
                    return x(0);
                  })
                  .attr("y", function(d) {
                    return y(d.label);
                  })
                  .attr("width", function(d) {
                    return x(d.value);
                  })
                  .attr("height", y.bandwidth())
                  .style('fill', function () {
                    if (optionSelect === "heat") {
                      return '#A12D24'
                    } else if (optionSelect === "cool") {
                      return '#668BA4'
                    } else if (optionSelect === "area") {
                      return 'lightgrey'
                    }
                  });

        var barTextsUpdate = bar.select("text")
              .transition()
              .duration(3050)
              .attr("x", function(d) {
              return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });

    }


数据看起来像

data1 = [{label: "example 1", value: 156}
{label: "example 2", value: 189}
{label: "example 3", value: 234}
{label: "example 4", value: 345}
{label: "example 5", value: 346}
{label: "example 6", value: 456}
{label: "example 7", value: 489}
{label: "example 8", value: 567}]; 


data2 = [{label: "example 1", value: 23}
{label: "example 2", value: 211}
{label: "example 3", value: 45}
{label: "example 4", value: 64}
{label: "example 5", value: 95}
{label: "example 6", value: 32}
{label: "example 7", value: 0}
{label: "example 8", value: 234}]; 

问题是您要删除文本的 DOM 元素而不更新它们。如果需要删除它们,那么您可以淡出文本并在最后删除它们 d3.select("text").transition().duration(300).style("opacity","0").on("end", () => { d3.select("text").removeAll() });

但我建议您重复使用标签并使用相同的d3.select("").transition().duration(300)方式更新它们的内容