繁体   English   中英

d3 v4更新/合并分组数据

[英]d3 v4 update/merge grouped data

我想对于力模拟D3 V4,类似的数据更新这个不成功的尝试和半类似这种成功的一个 CodePen 在这里

与其加入新节点,不如将所有节点加倍(参见图片)。 似乎也无法正确刷新图表。

初始图 (初始图)

添加数据后的图形 (添加数据后)

HTML:

<button onclick="addData()">Add Data</button>
<svg width="960" height="600"></svg>

JavaScript的:

function addData() {
    graph.nodes.push({"id": "Extra1", "group": 11},{"id": "Extra2", "group": 11})
    graph.links.push({"source": "Extra1", "target": "Valjean", "strength": 1},{"source": "Extra1", "target": "Extra2", "strength": 2})
    update()
    simulation.restart()
}

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var link, linkEnter, nodeWrapper, nodeWrapperEnter;

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2))
    .on("tick", ticked);

var allLinkG = svg.append("g")
    .attr("class", "allLinkG")

var allNodeG = svg.append("g")
    .attr("class", "allNodeG")

update()
simulation.restart()

function update(){

  link = allLinkG
    .selectAll("line")
    .data(graph.links, function(d){ return d.id }) 

  link.exit().remove()

  linkEnter = link
    .enter().append("line");

  link = linkEnter.merge(link).attr("class","merged");


  nodeWrapper = allNodeG
    .selectAll("nodeWrapper")
    .data(graph.nodes, function(d) { return d.id; })

  nodeWrapper.exit().remove();

  nodeWrapperEnter = nodeWrapper.enter()
    .append("g").attr("class","nodeWrapper")
    .append("circle")
    .attr("r", 2.5)

  nodeWrapper = nodeWrapperEnter
    .merge(nodeWrapper).attr("class","merged");


  simulation
      .nodes(graph.nodes);

  simulation.force("link")
      .links(graph.links);
}

function ticked() {
    link
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    nodeWrapper
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
}

非常感谢您的帮助。

这里有几个问题:

  1. 您的selectAll是按元素类型nodeWrapper选择的,而您的选择是类.nodeWrapper
  2. 您在.merge之后将类名称更改为“ merged”,则无法执行此操作,因为它会破坏.nodeWrapper类将来的选择。
  3. 当你.merge您的选择,您合并circle以s g秒。 您应保持一致并仅在g s上操作。

快速重构:

function update() {

  link = allLinkG
    .selectAll("line")
    .data(graph.links, function(d) {
      return d.id
    })

  link.exit().remove()

  linkEnter = link
    .enter().append("line");

  link = linkEnter.merge(link).attr("class", "merged");

  nodeWrapper = allNodeG
    .selectAll(".nodeWrapper") //<-- class nodeWrapper
    .data(graph.nodes, function(d) {
      return d.id;
    })

  nodeWrapperEnter = nodeWrapper.enter()
    .append("g").attr("class", "nodeWrapper"); //<-- enter selection should be gs

  nodeWrapperEnter //<-- append  your circles
    .append("circle")
    .attr("r", 2.5)

  nodeWrapper = nodeWrapperEnter //<-- merge, don't change class
    .merge(nodeWrapper);

  nodeWrapper.exit().remove();  //<-- and the exit

  simulation
    .nodes(graph.nodes);

  simulation.force("link")
    .links(graph.links);
}

注意 ,我还修改了您的tick函数,使其在g而不是circle上进行操作:

nodeWrapper
  .attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
  });

完整的代码在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM