【问题标题】:mindmap-like layout using visNetwork R package (network visualization using vis.js javascript library)使用 visNetwork R 包的类似思维导图的布局(使用 vis.js javascript 库的网络可视化)
【发布时间】:2016-09-18 16:47:16
【问题描述】:

是否可以调整 visNetwork 的选项(例如 visLayout、visOptions 或 visPhysics)以获得类似于思维导图的网络可视化?

我想获得这样的东西:

这是我在R 中使用visNetwork 绘制相同数据的可重现示例:

nodes <- structure(list(id = 1:22, label = structure(c(14L, 20L, 19L, 
                                                       16L, 12L, 18L, 2L, 17L, 22L, 8L, 13L, 3L, 4L, 5L, 6L, 7L, 21L, 
                                                       15L, 9L, 1L, 10L, 11L), .Label = c("A seemengly impossible mission\n", 
                                                                                       "Another \n", "Detail 1\n", "Detail 2\n", "Detail 3\n", "Detail 4\n", 
                                                                                       "Detail 5\n", "Do you know where is Dover?\n", "Dover Castle\n", 
                                                                                       "Finally, I'm the fifth\n", "I'm alone", "I'm relatively short\n", 
                                                                                       "Let's say there is a third one\n", "Main topic\n", "Operation Dynamo\n", 
                                                                                       "or, I'm even longer and perhaps I need some more space\n", "Running out of imagination\n", 
                                                                                       "Shorter\n", "Some longer text goes here\n", "Thing 1\n", "Thing number 4\n", 
                                                                                       "What can happen?\n"), class = "factor"), shape = structure(c(1L, 
                                                                                                                                                  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                                                                                                                                  1L, 1L, 1L, 1L, 1L), class = "factor", .Label = "box")), .Names = c("id", 
                                                                                                                                                                                                                    "label", "shape"), row.names = c(NA, -22L), class = "data.frame")

edges <- structure(list(from = c(1L, 2L, 2L, 2L, 2L, 1L, 7L, 7L, 7L, 1L, 
                                 11L, 11L, 11L, 11L, 11L, 1L, 17L, 17L, 17L, 1L, 21L), to = 2:22, 
                        arrows = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                             1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "to", class = "factor")), .Names = c("from", 
                                                                                                                                           "to", "arrows"), row.names = c(NA, 21L), class = "data.frame")
library(visNetwork)
visNetwork(nodes, edges) %>%
    visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
    visLayout(randomSeed = 1)

这段代码产生了这个可视化:

所以你可以看到第一个图更干净,更容易阅读和使用。是否可以调整visNetwork参数(vis.js参数),使结果与这里的第一个图比较相似?

基本上,它就像有一个中心主题,然后是围绕主题呈放射状排列的下一个级别主题,并且进一步的级别相互关联(类似于列表)。

【问题讨论】:

  • 也许看看radialNetwork() 来自networkD3

标签: r vis.js


【解决方案1】:

您可以将坐标传递给节点 data.frame,然后禁用物理。

您可以将节点放置在您想要的位置并使用闪亮的应用程序获取坐标,然后在您的网络中使用它,例如:

mynetwork <- visNetwork(nodes, edges) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
  visLayout(randomSeed = 1) %>%
  visPhysics(enabled = FALSE) # disable physics to move nodes

require(shiny)
server <- function(input, output) {
  output$network <- renderVisNetwork({
    mynetwork
  })

  vals <- reactiveValues(coords=NULL)

  output$view <- renderPrint({
    write.table(vals$coords, file = "save_coordinates.csv", sep = ";")
    vals$coords
  })

  observe({
    input$getcoord
    visNetworkProxy("network") %>% visGetPositions()
    vals$coords <- if (!is.null(input$network_positions)) 
      do.call(rbind, input$network_positions)
  })
}

ui <- fluidPage(
  visNetworkOutput("network", height = "800px"),
  actionButton("getcoord", "View & Save Coordinates"),
  verbatimTextOutput("view")
)

shinyApp(ui = ui, server = server)


# and after, put coordinnates into nodes data.frame and use visNodes(fixed = TRUE) 
# if you want

coord <- read.csv("save_coordinates.csv", sep = ";")
nodes <- cbind(nodes, coord)

visNetwork(nodes, edges) %>%
  visNodes(fixed = T) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
  visLayout(randomSeed = 1) %>%
  visPhysics(enabled = FALSE) 

你也可以玩levelvisHierarchicalLayout

nodes <- data.frame(id = 1:9, level = c(1,1,2,3,3, 4, 4, 4, 4))
edges <- data.frame(from = c(3, 3, 3, 3, 4, 4, 5, 5), 
                    to = c(1, 2, 4, 5, 6, 7, 8, 9))


visNetwork(nodes, edges) %>%
  visHierarchicalLayout(direction = "LR")

【讨论】:

  • 谢谢!这是一个不错的解决方案。但是(必须有一个但是)对于一次性计时器和一个特定网络来说,这是一个很好的解决方案。实际上,我一直在寻找更“自动”的东西,以思维导图的方式巧妙地为任何网络安排节点。正如@Steven Beaupré 所建议的那样,我发现的最接近的是networkD3 包中的radialNetwork(),但它就像径向排列所有网络一样。我想要的东西更像是第一层的径向排列,然后是第二层的垂直排列
  • 也可以使用 levelvisHierarchicalLayout。在我的回答中举个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
  • 2018-12-27
  • 2019-11-08
  • 2018-04-19
  • 2021-03-17
  • 1970-01-01
相关资源
最近更新 更多