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

在第一次输入时,我将数据绑定到 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.

我做错了什么还是这是预期的行为?任何帮助将非常感激!


杨魅力
浏览 122回答 1
1回答

繁花如伊

当您设置.attr("id"一个函数时,该函数会立即执行,并且仅执行一次。这意味着当您将新值插入数据数组时,您还需要重新计算该属性。如果您移动.attr("id"到之后.merge,一切都会按预期进行:var windowWidth = window.innerWidth;var storyline = d3.select(".Storyline").append("svg");function update(dateData, rawData) {&nbsp; console.log(dateData)&nbsp; var x = d3.scaleLinear()&nbsp; &nbsp; .domain([0, (dateData.length - 1)])&nbsp; &nbsp; .range(["10%", "80%"]);&nbsp; storyline&nbsp; &nbsp; .transition()&nbsp; &nbsp; .duration(500)&nbsp; &nbsp; .delay(50)&nbsp; &nbsp; .attr("width", (dateData.length * 20) + "%")&nbsp; &nbsp; .attr("height", "100%")&nbsp; var dateFlags = storyline.selectAll("g.dateflag")&nbsp; &nbsp; .data(dateData, function(d, i) {&nbsp; &nbsp; &nbsp; return d&nbsp; &nbsp; });&nbsp; //ENTER&nbsp; var dateFlagsEnter = dateFlags.enter()&nbsp; &nbsp; .append("g")&nbsp; &nbsp; .attr("class", "dateflag");&nbsp; dateFlagsEnter.append("foreignObject")&nbsp; &nbsp; .attr("class", "timePoints")&nbsp; &nbsp; .attr("width", "130px")&nbsp; &nbsp; .attr("height", "100%")&nbsp; &nbsp; .attr("x", function(d, i) {&nbsp; &nbsp; &nbsp; return x(i);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("y", function(d, i) {&nbsp; &nbsp; &nbsp; var topBottom;&nbsp; &nbsp; &nbsp; if ((i % 2) == 1) {&nbsp; &nbsp; &nbsp; &nbsp; topBottom = "35%";&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; topBottom = "40%";&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return topBottom;&nbsp; &nbsp; })&nbsp; &nbsp; .attr("opacity", "0%");&nbsp; dateFlagsEnter.select(".timePoints").append("xhtml:div")&nbsp; &nbsp; .attr("class", "tpGroup")&nbsp; dateFlagsEnter.select(".tpGroup").append("xhtml:div")&nbsp; &nbsp; .attr("id", "dateLabel")&nbsp; &nbsp; .append("xhtml:div")&nbsp; &nbsp; .html(function(d, i) {&nbsp; &nbsp; &nbsp; return d + " index= " + i;&nbsp; &nbsp; })&nbsp; &nbsp; .attr("id", "dateLabelText")&nbsp; &nbsp; .on("click", function(d, i) {&nbsp; &nbsp; &nbsp; var clickIndex = i&nbsp; &nbsp; &nbsp; console.log("clickedID: " + clickIndex)&nbsp; &nbsp; &nbsp; expand(dateData, clickIndex);&nbsp; &nbsp; });&nbsp; //UPDATE&nbsp; dateFlags.merge(dateFlagsEnter)&nbsp; &nbsp; .attr("id", function(d, i) {&nbsp; &nbsp; &nbsp; console.log("ContainerID: " + i)&nbsp; &nbsp; &nbsp; return i&nbsp; &nbsp; })&nbsp; &nbsp; .select(".timePoints")&nbsp; &nbsp; .transition()&nbsp; &nbsp; .duration(500)&nbsp; &nbsp; .delay(50)&nbsp; &nbsp; .attr("x", function(d, i) {&nbsp; &nbsp; &nbsp; return x(i);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("opacity", "100%");&nbsp; dateFlags.merge(dateFlagsEnter).select("#dateLabelText")&nbsp; &nbsp; .html(function(d) {&nbsp; &nbsp; &nbsp; return d;&nbsp; &nbsp; });&nbsp; //EXIT&nbsp; dateFlags.exit().remove();};function expand(dateData, clickIndex) {&nbsp; var lineIndex = clickIndex&nbsp; dateData.splice((lineIndex + 1), 0, "Day1.1", "Day1.2")&nbsp; update(dateData);};function getDateData() {&nbsp; var dateData = ["Day1", "Day2", "Day3", "Day4", "Day5", ]&nbsp; update(dateData);};getDateData();<div class="Storyline"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript