为了账号安全,请及时绑定邮箱和手机立即绑定

如何更新 d3 中绑定数据的索引 (i)?

如何更新 d3 中绑定数据的索引 (i)?

杨魅力 2023-07-14 15:44:27
在第一次输入时,我将数据绑定到 svg,如下所示:var dateContainer = svg.selectAll("g.dateContainerClass")    .data(dateData, function(d) {       return d.id    });var dateContainerEnter = dateContainer.enter()    .append("g")    .attr("class", "dateContainerClass");此时,绑定数据由一个包含 5 个条目的数组组成。从第一个到最后一个也是i0 到 4。现在数组已更新:两个新条目拼接在 0 和 1 之间。dateData.splice((i + 1), 0, rawData[(rawIndex + 1)], rawData[(rawIndex + 2)])之后,新的dateData将再次绑定到选择,如上所示。我期待发生的是这样的:i=0 (old)i=1 (new)i=2 (new)i=3 (old)i=4 (old)etc.实际发生的情况是这样的:i=0 (old)i=1 (new)i=2 (new)i=1 (old)i=2 (old)etc.我做错了什么还是这是预期的行为?任何帮助将非常感激!
查看完整描述

1 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

当您设置.attr("id"一个函数时,该函数会立即执行,并且仅执行一次。这意味着当您将新值插入数据数组时,您还需要重新计算该属性。如果您移动.attr("id"到之后.merge,一切都会按预期进行:


var windowWidth = window.innerWidth;

var storyline = d3.select(".Storyline").append("svg");


function update(dateData, rawData) {

  console.log(dateData)

  var x = d3.scaleLinear()

    .domain([0, (dateData.length - 1)])

    .range(["10%", "80%"]);


  storyline

    .transition()

    .duration(500)

    .delay(50)

    .attr("width", (dateData.length * 20) + "%")

    .attr("height", "100%")


  var dateFlags = storyline.selectAll("g.dateflag")

    .data(dateData, function(d, i) {

      return d

    });


  //ENTER


  var dateFlagsEnter = dateFlags.enter()

    .append("g")

    .attr("class", "dateflag");


  dateFlagsEnter.append("foreignObject")

    .attr("class", "timePoints")

    .attr("width", "130px")

    .attr("height", "100%")

    .attr("x", function(d, i) {

      return x(i);

    })

    .attr("y", function(d, i) {

      var topBottom;

      if ((i % 2) == 1) {

        topBottom = "35%";

      } else {

        topBottom = "40%";

      }

      return topBottom;

    })

    .attr("opacity", "0%");


  dateFlagsEnter.select(".timePoints").append("xhtml:div")

    .attr("class", "tpGroup")


  dateFlagsEnter.select(".tpGroup").append("xhtml:div")

    .attr("id", "dateLabel")

    .append("xhtml:div")

    .html(function(d, i) {

      return d + " index= " + i;

    })

    .attr("id", "dateLabelText")

    .on("click", function(d, i) {

      var clickIndex = i

      console.log("clickedID: " + clickIndex)

      expand(dateData, clickIndex);

    });


  //UPDATE


  dateFlags.merge(dateFlagsEnter)

    .attr("id", function(d, i) {

      console.log("ContainerID: " + i)

      return i

    })

    .select(".timePoints")

    .transition()

    .duration(500)

    .delay(50)

    .attr("x", function(d, i) {

      return x(i);

    })

    .attr("opacity", "100%");


  dateFlags.merge(dateFlagsEnter).select("#dateLabelText")

    .html(function(d) {

      return d;

    });


  //EXIT


  dateFlags.exit().remove();


};


function expand(dateData, clickIndex) {

  var lineIndex = clickIndex


  dateData.splice((lineIndex + 1), 0, "Day1.1", "Day1.2")

  update(dateData);

};


function getDateData() {

  var dateData = ["Day1", "Day2", "Day3", "Day4", "Day5", ]

  update(dateData);

};


getDateData();

<div class="Storyline"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


查看完整回答
反对 回复 2023-07-14
  • 1 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信