I'm building a Shiny app displaying interactive networks with visNetwork
and I'd like to give users the option to choose between two igraph
layouts. The problem is the additional argument required for one layout is an unused argument for the other and I can't seem to get rid of it conditionally.
library(igraph)
library(shiny)
library(visNetwork)
# generate data
iGr <- make_graph("Meredith")
visGr <- toVisNetworkData(iGr)
# ui
ui <- fluidPage(
# layout options
radioButtons(
inputId="grLayout",
label="View in:",
choices=list(
"Graph layout"="layout_with_graphopt",
"Ellipse layout"="layout_in_circle"
),
selected="layout_with_graphopt"
),
visNetworkOutput("netPlot")
)
# server
server <- function(input, output){
output$netPlot <- renderVisNetwork({
visNetwork(visGr$nodes, visGr$edges) %>%
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout,
charge=0.1 # <- here's my problem
)
})
}
shinyApp(ui=ui, server=server)
I need the charge
argument for the layout_with_graphopt
option with my real data to make the the visualization readable, but it throws an "unused argument (charge = 0.1)" error with the layout_in_circle
option. I've tried the two variations without success.
This one won't run at all and throws an 'argument "graph" is missing, with no default' error:
output$netPlot <- renderVisNetwork({
visNetwork(visGr$nodes, visGr$edges) %>%
{if (input$grLayout=="layout_with_graphopt") {
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout,
charge=0.1)
} else {
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout)
}}
})
This one throws an "unused argument (charge = NULL)" error for the layout_in_circle
option. (I get something similar if I try NA
):
output$netPlot <- renderVisNetwork({
chargeVal <- if (input$grLayout=="layout_with_graphopt") {0.1} else {NULL}
visNetwork(visGr$nodes, visGr$edges) %>%
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout,
charge=chargeVal)
})
I'd rather not do an if else
on the whole renderVisNetwork
block because the real one is quite lengthy with a fair number of bells and whistles, and the charge
argument would be the only difference between them.
I figured it out. The trick is to stick everything except the visIgraphLayout
lines into a visNetwork
object, then pipe conditional versions of visIgraphLayout
onto the back of it:
output$netPlot <- renderVisNetwork({
plot1 <- visNetwork(visGr$nodes, visGr$edges)
# can add whatever other bells and whistles needed before if/else if
# conditional layout:
if (input$grLayout=="layout_with_graphopt"){
plot2 <- plot1 %>%
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout,
charge=0.1)
} else if (input$grLayout=="layout_in_circle") {
plot2 <- plot1 %>%
visIgraphLayout(physics=FALSE, type="square", layout=input$grLayout)
}
return(plot2)
})