簡體   English   中英

大數據集打破 d3 桑基圖

[英]Large data set breaks d3 sankey diagram

我正在從https://bl.ocks.org/d3noob/5028304 中的示例制作 d3 Sankey 圖。 此示例適用於較小的數據集。 當我切換到使用更大的數據集時,可視化就中斷了。 看起來問題在於 dy 值變為負數。

在控制台中,錯誤是:

Error: <rect> attribute height: A negative value is not valid. ("-9.02557856272838")

它指向的代碼是:

node.append("rect")
  .attr("height", function(d) { return d.dy; })

這可能是因為情節正在離開屏幕? 我查看了使用 d3 比例,但我不確定如何實現它們。 也許是這樣的:

d3.scale.ordinal()
.domain(data.map(function(d) { return d.name; }))
.rangeRoundBands([0, height], .2);

或者也許有一種方法可以在數據集變大時縮小可視化,以便所有內容都適合容器。

這是我的代碼: https : //plnkr.co/edit/hOjEBHhS7vfajD2wb8t9?p=preview

有 945 個節點和 2463 個鏈接,這不可能適合 740 像素高的容器。 不僅如此,您還必須問自己“這個數據可視化對擁有大量信息的讀者有何用處?” . 但既然這不關我的事,你可以做幾件事:

當然,第一個是過濾您的數據。 如果這不是一個選項,您可以增加容器高度:

height = 3000 - margin.top - margin.bottom;

並減少節點的填充:

var sankey = d3.sankey()
    .nodeWidth(36)
    .nodePadding(1)
    .size([width, height]);

結果在這個plunker: https ://plnkr.co/edit/Idb6ZROhq1kuZatbGtqg ? p = preview

但是,即使這不是一個選項,您也可以更改sankey.js代碼,或者在懶惰的解決方案中,避免使用負數:

.attr("height", function(d) { return d.dy < 0 ? 0 : d.y; })

結果如下: https : //plnkr.co/edit/tpaMpK5yXwYh9MEo8hgn?p=preview

我遇到了同樣的問題。 我有包含 50 個節點和 50 個鏈接的圖表,但也有包含 1200 個節點和 1200 個鏈接的圖表。 我嘗試的第一件事是增加畫布的寬度和高度。 因此,我根據圖形深度增加了寬度,並根據節點最多的級別增加了高度。

然而,我最終得到了一些寬度過大或高度過大的邊緣情況圖。 所以我最終重新生成了圖形,直到每個節點都有一個最小高度,並且直到鏈接節點之間的空間合理。

所以這就是我所做的:

class SankeyChart {
   sankeyGenerator;
   graph;
   width = 1000;
   height = 1000;

   constructor(private nodes, private links) {
      this.sankeyGenerator = sankey()
        .extent([[10, 10], [this.width - 10, this.height - 10]])
      this.draw();
   }

 
  private draw() {
    this.graph = this.getGraph();
    this.drawLinks(this.graph.links); // method that draw the links
    this.drawNodes(this.graph.nodes); // method that draw the nodes
  }


  private getGraph() {
    const graph = this.sankeyGenerator({nodes: this.nodes, links: this.links});

    const increaseWidth = graph.links.some(l => Math.abs(l.source.y1 - l.target.y0) > 4 * Math.abs(l.source.x1 - l.target.x0));
    const increaseHeight = graph.nodes.some(n => n.y1 - n.y0 < 1);
    if (increaseHeight) {
      this.height += 1000;
    }
    if (increaseWidth) {
      this.width += 1000;
    }
    if (increaseHeight || increaseWidth) {
      this.sankeyGenerator.extent([[10, 10], [this.width - 10, this.height - 10]]);
      return this.getGraph();
    }
    return graph;
  }

}

請注意,您可能希望對graph.nodes.some(n => n.y1 - n.y0 < 1);執行額外的過濾器graph.nodes.some(n => n.y1 - n.y0 < 1); . 我有一些情況,所有節點的y1 - y0 > 1000 ,但有 2 或 3 個節點y1 - y0 < 0.00000001

另請注意,每次為大圖表調用getGraph()時,您可能會向類添加一個參數以將容器的大小增加 1000 像素以上。

暫無
暫無

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

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