【问题标题】:Transition of labels in D3.js: Rename label names on change and transition smoothlyD3.js 中标签的转换:在更改和平滑转换时重命名标签名称
【发布时间】:2019-12-26 16:06:52
【问题描述】:

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

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

对于我的标签名称,我试图删除名称,然后在我的 on change 函数中再次添加它。但这只会从一开始就显示新文本:

附加到 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}]; 

【问题讨论】:

    标签: javascript d3.js transition


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢康奈尔!明天我回到我的电脑前我会试试这个,让你知道!
    • 抱歉回复晚了,我周末没在电脑上。在 Cornel 的帮助下,我现在设法像这样转换文本标签:d3.select(".x.label").text(textselect).transition().duration(1000) ; 我在函数中传递了 textvalue。我现在的问题是默认值没有显示。它仅在我单击单选按钮时显示,而不是在开始时显示。 (我更新了代码)。你知道为什么会这样吗?再次感谢您
    • 我会在 else 分支上默认显示,而不是 let value = this.value; if (value === "cool") { change(datasetOption1, value, "Text 2"); } else if (value === "area") { change(datasetOption2, value, "Text 3"); } else { change(datasetTotal, value, "Default text"); }
    • 谢谢!!不幸的是,它仍然没有向我显示这样的默认值....我也认为它没有显示很奇怪,因为我在调用函数之前附加了它,对吧?!如果没有该功能,它将显示默认值
    • 刚刚注意到 - selectDataset 是在 d3.selectAll("input").on("change", function(d) { 侦听器函数中定义的。尝试将其提取到函数之外并默认调用它。在监听器中使用它只会在值更改时执行,而不是默认情况下
    猜你喜欢
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    相关资源
    最近更新 更多