2017-03-09 19 views
2

マウスクリックに基づいてノードを折りたたんだ/展開する方法を知りたい。Collapsible Sankey Diagram - D3

私の図はこれです:たとえばhttps://bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22

、私はノード「PAGOU」をクリックし、その後のリンクとノード(右側)のすべてが削除されます。 私はそれをVasco Asturiano(readme.md上のリファレンス)アライメントオプションに基づいて作成しました。

答えて

3

私はここで私の前の回答から以下のコードを適応:私は、彼らが崩壊しているかどうかを追跡するためにノードにプロパティを追加https://jsfiddle.net/sheilak/jfwkx4f3/

とどのように多く: Collapsible D3 force directed graph with non-tree data

ここフィドルで完全なコードそれらの親ノードのノードは崩壊する。また、リンクが折りたたまれているかどうかにかかわらず、リンクがないグラフがライブラリに表示されないため、ソースノードを折りたたむことはできません。

graph.nodes.forEach(function (d, i) { 
    graph.nodes[i] = { "name": d }; 
    graph.nodes[i].collapsing = 0; // count of collapsed parent nodes 
    graph.nodes[i].collapsed = false; 
    graph.nodes[i].collapsible = false; 
}); 

我々は、フィルタリングのためのソースノードを必要とするので、私は、全体のソースまたはターゲット・ノードではなくインデックスを指すようにリンクするためのコードを変更しました。私はまた、すべてのターゲットノードを折りたたみ可能に設定します。

graph.links.forEach(function(e) { 
    e.source = graph.nodes.filter(function(n) { 
     return n.name === e.source; 
     })[0], 
    e.target = graph.nodes.filter(function(n) { 
     return n.name === e.target; 
     })[0]; 
    e.target.collapsible = true; 
}); 

レイアウトコードを関数にプルして、ノードをクリックするたびに呼び出すことができます。また、グラフのノードとリンクをフィルタリングするコードを追加し、そのノードとその親が折りたたまれているかどうかに基づいてリンクを作成しました。

update(); 

var nodes, links; 

function update() { 
    nodes = graph.nodes.filter(function(d) { 
    // return nodes with no collapsed parent nodes 
    return d.collapsing == 0; 
    }); 

    links = graph.links.filter(function(d) { 
    // return only links where source and target are visible 
    return d.source.collapsing == 0 && d.target.collapsing == 0; 
    }); 

    // Sankey properties 
    sankey 
    .nodes(nodes) 
    .links(links) 
    .layout(32); 

    // I need to call the function that renders the sakey, remove and call it again, or the gradient coloring doesn't apply (I don't know why) 
    sankeyGen(); 
    svg.selectAll("g").remove(); 
    sankey.align("left").layout(32); 
    sankeyGen(); 
} 

この行は、クリックハンドラに干渉していたためコメントアウトする必要がありましたが、私はそこで何が変更されたのか分かりません。

.on("start", function() { 
    //this.parentNode.appendChild(this); 
}) 

折りたたみを実行するためのクリックハンドラが追加されました。

node.on('click', click); 
function click(d) { 
    if (d3.event.defaultPrevented) return; 
    if (d.collapsible) { 
    // If it was visible, it will become collapsed so we should decrement child nodes count 
    // If it was collapsed, it will become visible so we should increment child nodes count 
    var inc = d.collapsed ? -1 : 1; 
    recurse(d); 

    function recurse(sourceNode){ 
     //check if link is from this node, and if so, collapse 
     graph.links.forEach(function(l) { 
     if (l.source.name === sourceNode.name){ 
      l.target.collapsing += inc; 
      recurse(l.target); 
     } 
     }); 
    } 
    d.collapsed = !d.collapsed; // toggle state of node 
    }  
    update(); 
} 
+1

私は十分にあなたに感謝できる方法がないので、私はそう感じる!私は本当にこれに答える仕事に感謝します。私は試しましたが、私はそれをすることができませんでした、あなたの答えは私には巨大な学びです!ありがとうございました。 – TheBiro

0

上記のフィドルは、各子が単一の親を持つ標準的なツリーに適しています。しかし、伝統的なサニーがユニークに適合する複数の親子関係( 'ラティス')シナリオでは、この折りたたみ可能な表現はおそらくあまり単純ではない。たとえば、ノードAを拡張して子を表示するとき、Aの子に拡張されていない他の親がある場合、親は自動的に展開されます。これはおそらくあなたが望むものです。なぜなら部分的な親子関係は誤解を招きかねませんが、とにかく少しでも驚いています。失見当は、ノードを再センタリングしないことによって緩和することができます。特に高度に格子状のデータ構造の場合、意図しない組み合わせ拡張効果が存在する可能性があります。

関連する問題