【问题标题】:How can I avoid links not fully or properly connecting to nodes in sankeyNetwork?如何避免链接未完全或正确连接到 sankeyNetwork 中的节点?
【发布时间】:2020-08-10 18:36:41
【问题描述】:

我在一个 Shiny 应用程序内有一个来自 networkd3 渲染的 Sankey 网络,显示一年内的转换,用户可以使用各种选项来过滤数据。我遇到了链接没有与节点完全连接并运行到其他链接的问题,特别是当用户选择一小部分组时,导致绘图水平方向比垂直方向长(即,每年显示的年份多于组- 见下面的例子)。

我在 Stack Overflow 上找不到修复程序。我相信问题可能出在底层的 Javascript 中,所以我已经超出了我的深度。任何帮助将不胜感激。谢谢!代表如下。

## Create links dataframe 
# Note that the 0 count links are for displaying nodes in the proper year
links <- data.frame(
  from = c(
    "A 2015", "A 2016", "A 2017", "A 2018", "A 2019",
    "A 2015", "A 2016", "A 2017", "A 2018"
  ),
  to = c(
    "B 2016", "B 2017", "B 2018", "B 2019", "B 2020",
    "A 2016", "A 2017", "A 2018", "A 2019"
  ),
  count = c(48, 36, 31, 46, 24, 0, 0, 0, 0)
)

## Create node dataframe
nodes <- data.frame(
  name = unique(
    c(
      as.character(links$from), 
      as.character(links$to)
    )
  )
)

## Add node indices to link data (zero-indexed)
links$source = match(links$from, nodes$name)-1
links$target = match(links$to, nodes$name)-1

## Render Sankey
library(networkD3)
sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "source",
  Target = "target",
  Value = "count",
  NodeID = "name",
  iterations = 0, 
  sinksRight = FALSE
)

【问题讨论】:

    标签: javascript r d3.js htmlwidgets networkd3


    【解决方案1】:

    D3 的 sankey 模块创建的链接是带有贝塞尔曲线的 SVG 路径。在您的示例中,浏览器的 SVG 引擎试图在非常紧凑的水平空间内创建一条曲线路径,路径非常粗(笔划宽度)。例如比较以下两个 SVG(唯一的区别是笔画宽度)...

    <svg style="width: 100%; height: 100%;">
    
        <path d="M 0 50 C 25,50 25,100 50,100" style="stroke-width: 10px; fill: none; stroke: rgb(0, 0, 0); stroke-opacity: 0.2;"></path>
        
        <g transform="translate(100,0)">
        
            <path d="M 0 50 C 25,50 25,100 50,100" style="stroke-width: 80px; fill: none; stroke: rgb(0, 0, 0); stroke-opacity: 0.2;"></path>
        
        </g>
        
    </svg>

    默认情况下,networkD3 的 sankey plot 尝试使用其容器允许的尽可能多的水平和垂直空间,在您的情况下,这会导致高宽比不是最佳,这使得节点之间的水平距离相对较小,并且节点的高度(以及因此链接的厚度)相对较大。

    您可以通过更改容器的大小并刷新(即调整浏览器窗口的大小,或更改容器的 HTML/CSS 属性)或通过指定宽度和高度以使比例适用于例如,您拥有的数据...

    sankeyNetwork(
      Links = links,
      Nodes = nodes,
      Source = "source",
      Target = "target",
      Value = "count",
      NodeID = "name",
      iterations = 0, 
      sinksRight = FALSE,
      height = 250,
      width = 1000
    )
    

    【讨论】:

    • 谢谢你,非常清楚和有帮助的答案。因此,我认为在交互式 Shiny 应用程序中实现此解决方案的最佳方法(默认值通常工作良好,除非在这种情况下,当用户显示很多年并过滤掉节点中显示的大多数组时)按组(高度)将宽度和高度编程为年份(宽度)的函数。这有意义还是有更好的方法?
    • 是的,如果可行的话,这对我来说是个不错的策略。
    猜你喜欢
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2019-10-12
    • 2020-03-25
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    相关资源
    最近更新 更多