javascript - 更改 TabsetPanel 中的选项卡后, Shiny 的 renderUI 不会显示不同的 D3 图

标签 javascript r d3.js shiny networkd3

我想做什么

我正在尝试构建一个 Shiny 的应用程序,它使用选项卡面板显示不同的交互式 HTML 绘图。它们都应该出现在 renderUI 的同一个调用中。如下我的示例所示,我的绘图基于 d3框架(如包 networkD3processanimateR )。

问题

不幸的是,renderUI 仅显示生成的第一个图。 。更改选项卡后,第二个图就不会显示。 processanimateR给我错误 Failed to render the graph. It is probably too large. Original error: TypeError: d3.create is not a function at PATokens.insertTokens (<anonymous>:185:25) at <anonymous>:52:33 at <anonymous>:105:9 。当然,该图不会太大而无法显示(数据方面),因为更改制表符序列可以完美地生成它。 此行为与首先显示哪个图无关。在下面的示例中,我标记了可用于交换 tab01 的行。和tab02看看会发生什么。

我尝试过的

通过提出尽可能小的例子,我可能排除了很多错误来源。 此外,我尝试使用多个 uiOutput (每个选项卡一个)没有成功。问题仍然存在。正如这个最小的示例所示,这可能是 d3 的问题。在后台运行。也许有一些图形引擎在选项卡更改或其他情况下不会关闭js相关。

我的问题

有没有办法显示多个d3在 Shiny 的应用程序中绘图,使它们全部按预期显示?

提前谢谢您!

我的例子

#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Settings
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Packages
sapply(c("shiny","processanimateR","bupaR","networkD3"),require,character.only=T)

# data
x <- structure(list(
    activity = c(
        "action 1", "action 2", "action 3", 
        "action 5", "action 2", "action 3", "action 25", "action 26", 
        "action 2", "action 3", "action 1", "action 2", "action 3", "action 1", 
        "action 2", "action 3", "action 1", "action 2", "action 3", "action 5", 
        "action 2", "action 3", "action 25", "action 26", "action 2", 
        "action 3", "action 1", "action 2", "action 3", "action 1", "action 2", 
        "action 3"),
    id = c(494.18, 494.18, 494.18, 485.56, 485.56, 485.56, 
           413.99, 413.99, 413.99, 413.99, 439.49, 439.49, 439.49, 466.38, 
           466.38, 466.38, 494.18, 494.18, 494.18, 485.56, 485.56, 485.56, 
           413.99, 413.99, 413.99, 413.99, 439.49, 439.49, 439.49, 466.38, 
           466.38, 466.38), .order = 1:32,
    activity_instance_id_by_bupar = c(1L, 
                                      2L, 3L, 16L, 17L, 18L, 50L, 51L, 52L, 53L, 60L, 61L, 62L, 71L, 
                                      72L, 73L, 1L, 2L, 3L, 16L, 17L, 18L, 50L, 51L, 52L, 53L, 60L, 
                                      61L, 62L, 71L, 72L, 73L),
    lifecycle_id = c("start", "start", 
                     "start", "start", "start", "start", "start", "start", "start", 
                     "start", "start", "start", "start", "start", "start", "start", 
                     "complete", "complete", "complete", "complete", "complete", "complete", 
                     "complete", "complete", "complete", "complete", "complete", "complete", 
                     "complete", "complete", "complete", "complete"),
    timestamp = structure(c(1424304001, 
                            1377475201, 1516579201, 1384128001, 1375401601, 1397952001, 1328486401, 
                            1364688001, 1318032001, 1384905601, 1348099201, 1342483201, 1366416001, 
                            1361404801, 1358726401, 1384905601, 1425168001, 1378339201, 1517443201, 
                            1384992001, 1376265601, 1398816001, 1329350401, 1365552001, 1318896001, 
                            1385769601, 1348963201, 1343347201, 1367280001, 1362268801, 1359590401, 
                            1385769601),
                          tzone = "UTC", class = c("POSIXct", "POSIXt")), 
    trace = c("action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 5,action 3", 
              "action 2,action 5,action 3", "action 2,action 5,action 3", 
              "action 2,action 25,action 26,action 3", "action 2,action 25,action 26,action 3", 
              "action 2,action 25,action 26,action 3", "action 2,action 25,action 26,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 5,action 3", 
              "action 2,action 5,action 3", "action 2,action 5,action 3", 
              "action 2,action 25,action 26,action 3", "action 2,action 25,action 26,action 3", 
              "action 2,action 25,action 26,action 3", "action 2,action 25,action 26,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3", 
              "action 2,action 1,action 3", "action 2,action 1,action 3"
    ),
    n = c(3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 
          3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3),
    absolute_frequency = c(3L, 
                           3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 
                           3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 
                           3L),
    relative_frequency = c(0.272727272727273, 0.272727272727273, 
                           0.272727272727273, 0.0909090909090909, 0.0909090909090909, 
                           0.0909090909090909, 0.0909090909090909, 0.0909090909090909, 
                           0.0909090909090909, 0.0909090909090909, 0.272727272727273, 
                           0.272727272727273, 0.272727272727273, 0.272727272727273, 
                           0.272727272727273, 0.272727272727273, 0.272727272727273, 
                           0.272727272727273, 0.272727272727273, 0.0909090909090909, 
                           0.0909090909090909, 0.0909090909090909, 0.0909090909090909, 
                           0.0909090909090909, 0.0909090909090909, 0.0909090909090909, 
                           0.272727272727273, 0.272727272727273, 0.272727272727273, 
                           0.272727272727273, 0.272727272727273, 0.272727272727273)),
    row.names = c(NA, 
                  -32L),
    class = c("eventlog", "log", "tbl_df", "tbl", "data.frame"
    ),
    case_id = "id", activity_id = "activity", activity_instance_id = "activity_instance_id_by_bupar",
    lifecycle_id = "lifecycle_id",
    resource_id = "id",
    timestamp = "timestamp")
y <- jsonlite::fromJSON(paste0('https://cdn.rawgit.com/christophergandrud/networkD3/','master/JSONdata/energy.json'))

#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Shiny-App UI ----
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ui <- shinyUI(fluidPage(
    title="shiny example",
    sidebarLayout(
        position="left",
        sidebarPanel(),
        mainPanel(
            tags$div(
                do.call(
                    tabsetPanel,
                    c(id='tabs',
                      lapply(1:2,function(y){
                          tabPanel(id=paste0("tab0",y),value=paste0("tab0",y),title=strong(paste0("This is tab0",y),align="left",style="black"),selected=1)
                      })
                    )
                ),
                uiOutput("out_ui")
            )
        )
    ),
    style=paste0("font-family: Arial;")
))

#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Shiny-App Server ----
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
server <- function(input,output,session){
    output$out_ui <- renderUI({
        
        # X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
        # >>>> Problem Segment <<<< ----
        # X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
        # Try: Chance this to "tab01"
        if(input$tabs=="tab02"){
            
            # Process
            animate_process(
                x,
                processmap=process_map(
                    x,
                    type=frequency("absolute",color_scale="Paired",color_edges="Greys"),
                    rankdir="TB",render=F,fixed_edge_with=T,
                    layout=layout_pm(
                        edge_weight=F,
                        edge_cutoff=0)),
                mapping=token_aes(
                    size=token_scale(8),
                    color=token_scale(
                        range="black",
                        scale="ordinal"
                    ),
                    opacity=token_scale(100)
                ),
                duration=60,mode="absolute",timeline=T,jitter=10,initial_time=0,
                repeat_count=10,repeat_delay=2,width=1200,height=900,
                sizingPolicy=htmlwidgets::sizingPolicy(
                    browser.fill=T,viewer.fill=F,
                    knitr.figure=F,knitr.defaultWidth="100%",knitr.defaultHeight="1000")
            )
            
        # X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
        # >>>> Problem Segment <<<< ----
        # X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
        # Try: Chance this to "tab02"
        }else if(input$tabs=="tab01"){
            
            # Sankey
            sankeyNetwork(
                Links=y$links,Nodes=y$nodes,Source='source',
                Target='target',Value='value',NodeID='name',
                units='TWh',fontSize=12,nodeWidth=30
            )
        }
    })
}
shinyApp(ui=ui,server=server)

#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

最佳答案

我可以告诉你为什么它不起作用。 processAninmateR 使用 D3 5.7。 networkD3 使用 D3 4.5。我检查以确保我的包裹是最新的;没有这样的运气。这些软件包似乎也不存在匹配的版本。

这是一个解决方法。这会让您保存 Sankey,但您也可以保存过程动画(使用 saveWidget)。当您保存此文件时,它需要位于您的shiny.R文件的目录中或该文件的子目录中。如果您使用此处显示的代码,它会自动将其保存在正确的位置。

您的代码中发生了一些奇怪的事情,但我会进行大胆的猜测,并说这是因为您可能已经尝试了一百万零一种方法来完成这项工作。

您可以将 else if 调用的信息替换为以下内容:

# save to an object
sn <- sankeyNetwork(Links = y$links, Nodes = y$nodes, Source = 'source',
                    Target = 'target', Value = 'value', NodeID = 'name',
                    units = 'TWh', fontSize = 12, nodeWidth = 30)
saveNetwork(sn, "sankey.html")               # save in local folder
addResourcePath("tmp", getwd())              # connect with file 
tags$iframe(src = "tmp/sankey.html", width = "100%",  # show plot in page
            frameBorder = "0", height = "500px")

关于javascript - 更改 TabsetPanel 中的选项卡后, Shiny 的 renderUI 不会显示不同的 D3 图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74139117/

相关文章:

javascript - 我是否必须在单独的文件中定义不同的 mongodb 模型?

javascript推送返回数字而不是对象

r - 获取特定包中的数据集列表

r - 按因子级别对数据框进行子集化

r - 如何在 R 中求和或平均小时数

d3.js - parseDate = d3.time.format ("%Y") 不工作

javascript - 如何修复返回编码的 Youtube API 结果标题

javascript - 折叠卡打开然后立即再次关闭

javascript - javascript d3 和 dc 的概率密度函数

javascript - 如何根据D3中的数据创建元素?