簡體   English   中英

可折疊Sankey圖-D3

[英]Collapsible Sankey Diagram - D3

我想知道如何基於鼠標單擊使sankey圖折疊/展開節點。

我的圖是這樣的: https : //bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22

例如,我想單擊節點“ PAGOU”,然后刪除所有后續鏈接和節點(在右側)。 我是根據Vasco Asturiano(在readme.md上參考)的配售選項制成的。

我從這里以前的回答中改編了以下代碼: 具有非樹數據的可折疊D3力定向圖

我向節點添加了屬性,以跟蹤它們是否折疊以及折疊了多少個父節點。 同樣,它們是否可折疊-源節點也不應可折疊,因為庫似乎不喜歡沒有鏈接的圖。

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

cirofdo的Gist中的完整代碼

上面的小提琴非常適合每個孩子都有一個父母的標准樹。 但是,對於傳統sankey非常適合的多親子關系(“格子”)方案; 這種可折疊的表示可能不太直接。 例如,當擴展節點A以顯示其子代時,如果任何A的子代都有未擴展的其他父代,則父代會自動得到擴展。 這可能就是您想要的,因為僅顯示部分父母身份會產生誤導,但無論如何確實會讓您有些意外。 可以通過不重新居中節點來緩解迷失方向。 可能會有意想不到的組合擴展效果,尤其是對於高度網格化的數據結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM