2016-08-08 8 views
1

D3 v4では、this unsuccessful attemptと似ており、準類似のthis successful oneに類似したデータを強制的に更新しようとしています。 CodePen hered3 v4グループ化されたデータを更新/マージ

新しいノードに参加する代わりに、すべてのノードが倍増しているようです(写真参照)。グラフも正しくリフレッシュされていないようです。

initial graph (初期グラフ)

graph after adding data (データを追加した後)

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; }); 
} 

どうもありがとうございました。ここ

答えて

2

いくつかの問題:

  1. あなたselectAllは、クラス.nodeWrapperの意味要素型nodeWrapper、によって選択されます。
  2. .mergeの後にクラス名を "merged"に変更すると、将来の選択が.nodeWrapperクラスで破られるため、これを行うことはできません。
  3. .mergeを選択すると、circlegにマージします。一貫性を保ち、gでのみ動作する必要があります。

クイックリファクタリング:

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); 
} 

、私はまたcircleの代わりにg上で動作させるために、あなたのtick機能を変更:

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

完全なコードはhereです。

+0

ありがとう、本当に役に立ちます。 '.attr(" class "、" merged ")'はクラスを置き換える代わりにクラスを追加すると仮定していました。 '.classed(" merged "、true)'は私が代わりに使うべきだったものです。 – ropeladder

関連する問題