D3更新父元素上的数据不会反映在子元素上

时间:2018-11-18 15:46:46

标签: d3.js

让我们考虑一下,我需要用<g>元素包裹一圈圆圈,并将数据绑定到该父对象。(initialNodes

当我按下更新按钮时,update函数将接收新数据(newNodes),并且我希望圆的x / y位置会得到更新,但是如您在控制台中所见,尽管d.x / d.y的打印正确,但是return d.x中并未考虑到它,因此仅将Enter组添加到画布。

我在做什么错?如何在父元素<g>和子元素上反映更新的数据?

var color = d3.schemeCategory10;

var initialNodes = [
    {"id": 0, "x": 50,  "y": 50},
    {"id": 1, "x": 100, "y": 100},
];

var vis = d3.select("body").append("svg").attr("width", 200).attr("height", 200);

update(initialNodes);

function update(data) {
    // DATA JOIN
    // Join new data with old elements, if any.
    var circlesGroup = vis.selectAll("g.stop").data(data, function(d){return d.id});
    var circlesEnter = circlesGroup.enter().append("g").attr("class", "stop");
    var circlesExit  = circlesGroup.exit().remove();


    // ENTER
    // Create new elements as needed.
    circlesEnter
        .append("circle")
        .attr("r", 15)
        .transition().duration(750)
        .attr("cx", function (d) {
          console.log('ENTERING: id:'+d.id+' position:'+d.x+','+d.y);
          return d.x;
          })
        .attr("cy", function (d) {return d.y;})
        .style("fill", 'red');

    // UPDATE
    // Update old elements as needed.
    circlesGroup
        .transition().duration(750)
        .attr("cx", function (d) {
          console.log('ENTERING: id:'+d.id+' position:'+d.x+','+d.y);
          return d.x;})
        .attr("cy", function (d) {return d.y;});

    // EXIT
    // Remove old elements as needed.
    circlesExit
        .remove();
}

var newNodes = [
                {"id": 0, "x": 50, "y": 100}, 
                {"id": 1, "x": 50, "y": 30},
                {"id": 2, "x": 100, "y": 50}
            ];

var updateNodes = function() {
    update(newNodes);
}

// Add the onclick callback to the button
d3.select("#updatebutton").on("click", updateNodes);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button id="updatebutton">Update</button>

1 个答案:

答案 0 :(得分:1)

circleGroupg元素的选择。没必要为cx元素设置cyg

创建新节点后,选择所有g.stop ,然后。为什么?阅读d3选择文档。

没有理由添加第二个remove()

var color = d3.schemeCategory10;

var initialNodes = [
    {"id": 0, "x": 50,  "y": 50},
    {"id": 1, "x": 100, "y": 100},
];

var vis = d3.select("body").append("svg").attr("width", 200).attr("height", 200);

update(initialNodes);

function update(data) {
    // DATA JOIN
    // Join new data with old elements, if any.
    var circlesGroup = vis.selectAll("g.stop").data(data, function(d){return d.id});
    var circlesEnter = circlesGroup.enter().append("g").attr("class", "stop");
    var circlesExit  = circlesGroup.exit().remove();


    // ENTER
    // Create new elements as needed.
    circlesEnter
        .append("circle")
        .attr("r", 15)
        .style("fill", 'red');
    vis.selectAll("g.stop").select("circle")
        .transition().duration(750)
        .attr("cx", function (d) {
          console.log('ENTERING2: id:'+d.id+' position:'+d.x+','+d.y);
          return d.x;})
        .attr("cy", function (d) {return d.y;});
}

var newNodes = [
                {"id": 0, "x": 50, "y": 100}, 
                {"id": 1, "x": 50, "y": 30},
                {"id": 2, "x": 100, "y": 50}
            ];

var updateNodes = function() {
    update(newNodes);
}

// Add the onclick callback to the button
d3.select("#updatebutton").on("click", updateNodes);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div><button id="updatebutton">Update</button></div>