cytoscape / cyjShiny

An R/shiny widget for cytoscape.js
Other
92 stars 28 forks source link

Set Node size / color / shape #17

Open paul-shannon opened 5 years ago

paul-shannon commented 5 years ago

@alptaciroglu posted an issue to paul-shannon/cyjShiny (just now belatedly archived, made read-only) about "bypass" methods for controlling node color and size.

In response, I offer a new example tinyApp.R image

and these words of explanation:

cyjShiny uses the classic Cytoscape approach to control node and edge color, shape and size. Rather than set them directly you

The benefit of this approach is that, just once in the style.js file, you specify how you want node and edge visual attributes to be calculated from node and edge data attributes. It asks a little more of you to set things up, but subsequent new renderings, reflecting subsequent new data, happens automatically.

You can see this in action in cyjShiny/inst/unitTests/cyjShinyDemo.R . New node attributes (node data) is sent to cytoscape.js in the browser with this callback:

    observeEvent(input$setNodeAttributes, ignoreInit=TRUE, {
       attribute <- "lfc"
       expression.vector <- switch(input$setNodeAttributes,
                                   "gal1RGexp" = tbl.mrna$gal1RGexp,
                                   "gal4RGexp" = tbl.mrna$gal4RGexp,
                                   "gal80Rexp" = tbl.mrna$gal80Rexp)
       setNodeAttributes(session, attributeName=attribute, nodes=yeastGalactodeNodeIDs, values=expression.vector)
       })
alptaciroglu commented 5 years ago

Thanks a lot Paul! This looks very good indeed. I wanted to play around with the script, change stuff and see how it works. One question though: where do you get dataFramesToJSON() function in the tinyApp.R example you created? I could not find the related documentation. Thanks again!

erickfvelasquez commented 5 years ago

I found the dataFramesToJSON() function in the man directory. Should be installed when you install the package with devtools::install(). Afterwards you can just access the documentation through ?dataFramesToJSON. Hope this helps!

paul-shannon commented 5 years ago

thanks, eric, for picking up this thread. I had let it slip.

Actually an R package's man directory is for documentation - dataFramesToJSON is described there, as you found. The actual source code is here, the package’s R directory:

https://github.com/cytoscape/cyjShiny/tree/master/R/graphsToJSON.R

On Mar 11, 2019, at 7:29 PM, erickfvelasquez notifications@github.com wrote:

I found the dataFramesToJSON() function in the man directory. Should be installed when you install the package with devtools::install(). Afterwards you can just access the documentation through ?dataFramesToJSON. Hope this helps!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

erickfvelasquez commented 5 years ago

Thanks for clarifying! I'm wondering why your sort nodes in graphsToJSON?

nodes <- sort(unique(c(tbl.edges$source, tbl.edges$target, tbl.nodes$id)))

It's giving me problems when I define attributes to certain nodes in a dataframe format, since it reorders the IDs in alphabetical order. For example, let's say I created the following dataframe

      id type lfc
1    BUB1 bait   2
2   BUB1B bait   2
3    BUB3 bait   2
4  MAD1L1 bait   2
5  MAD2L2 bait   2
6   AHCTF1 hits   1 

it would be reorder like this:

       id type lfc
1    AHCTF1 bait   2
2    BUB1 bait   2
3   BUB1B bait   2
4    BUB3 bait   2
5  MAD1L1 bait   2
6  MAD2L2 hits   1

Messing up the assigned attributes of the data frame. Thank you for your help in advance!

alptaciroglu commented 5 years ago

Hello again,

So I was trying to implement the example you worked on @paul-shannon

On loading the biologicalStyle, I get

biologicalStyle.jsWarning: Error in parse_con: lexical error: invalid char in json text. <!DOCTYPE html> <html lang="en" (right here) ------^

83: parse_con 82: parseJSON 81: parse_and_simplify 80: fromJSON 77: loadStyleFile 76: observeEventHandler [tinyApp.R#86] 5: runApp

############################################################ The changes I made;

I added:

source('graphsToJSON.R', local=TRUE) to tinyApp.R file

I added:

selectInput("doLayout", "Select Layout:", choices=c("cose", "cola", "circle", "concentric", "breadthfirst", "grid", "random", "dagre", "cose-bilkent"), selected = 'cose'),

To server.R file and changed server.R output$cyjShiny part with :

cyjShiny(graph=rv$graph)

Else I would get:

cyjShiny: unused arguments (layoutName = "cola", style_file = "basicStyle.js") error.

I was unable to run the code with biologicalStyle unfortunately ... Could you let me know if I am doing something wrong?

##############################################################

Here is the full tinyApp.R file incase you might need it. I have graphsToJSON.R and two style files in the same directory as well.

library(shiny)
library(cyjShiny)
library(htmlwidgets)
library(R.utils)

source('graphsToJSON.R', local=TRUE)

ui = shinyUI(fluidPage(

  sidebarLayout(
     sidebarPanel(
        actionButton('generateSample', 'Generate!'),
        hr(),
        selectInput("doLayout", "Select Layout:",
                    choices=c("cose",
                              "cola",
                              "circle",
                              "concentric",
                              "breadthfirst",
                              "grid",
                              "random",
                              "dagre",
                              "cose-bilkent"),
                    selected = 'cose'),
        hr(),
        actionButton("selectRandomNodeButton", "Select random node"),
        hr(),
        selectInput("visualStyleSelector", "Select Visual Style",
                    choices=c("Default" = "basicStyle.js", "Biological"="biologicalStyle.js")),
        h6("Send random node 'lfc' attributes (visible only with Biological Style, mapped to color):"),
        actionButton("randomNodeAttributes", "Send"),
        width=3
        ),
     mainPanel(
        cyjShinyOutput('cyjShiny'),
        width=9
        )
     ) # sidebarLayout
))
#----------------------------------------------------------------------------------------------------
server = function(input, output, session) {

  rv <- reactiveValues(graph=FALSE)
 observeEvent(input$generateSample, ignoreInit=TRUE,{
     tbl.nodes <- data.frame(id=c("A", "B", "C"),
                             type=c("kinase", "TF", "glycoprotein"),
                             lfc=c(-3, 1, 1),
                             count=c(0, 0, 0),
                             stringsAsFactors=FALSE)

     tbl.edges <- data.frame(source=c("A", "B", "C"),
                             target=c("B", "C", "A"),
                             interaction=c("phosphorylates", "synthetic lethal", "unknown"),
                             stringsAsFactors=FALSE)

     graph.json <- dataFramesToJSON(tbl.edges, tbl.nodes)

     strategy <- input$doLayout
     printf("about to sendCustomMessage, doLayout: %s", strategy)
     doLayout(session, strategy)
     rv$graph <- graph.json
   })

   observeEvent(input$doLayout,  ignoreInit=TRUE,{
     strategy <- input$doLayout
     printf("about to sendCustomMessage, doLayout: %s", strategy)
     doLayout(session, strategy)
     #session$sendCustomMessage(type="doLayout", message=list(input$doLayout))
   })

   observeEvent(input$selectRandomNodeButton, ignoreInit=TRUE, {
      session$sendCustomMessage(type="clearSelection", message=list())
      ## selectNodes(session, tbl.nodes$id[sample(1:3, 1)])  ## Changed or I would get Error in selectNodes: could not find function "selectNodes"
      session$sendCustomMessage(type="selectNodes", message=list(tbl.nodes$id[sample(1:3, 1)]))
      })

   observeEvent(input$visualStyleSelector, ignoreInit=TRUE, {
      newStyleFile <- input$visualStyleSelector
      printf("newStyle: %s", newStyleFile)
      loadStyleFile(newStyleFile)
      })

   observeEvent(input$randomNodeAttributes, ignoreInit=TRUE, {
      nodeNames <- tbl.nodes$id
      newValues <- runif(n=3, min=-3, max=3)
      setNodeAttributes(session, attributeName="lfc", nodes=nodeNames, newValues)
      })

  output$value <- renderPrint({ input$action })
  output$cyjShiny <- renderCyjShiny(
    cyjShiny(graph=rv$graph)
    )

} # server
#----------------------------------------------------------------------------------------------------
runApp(shinyApp(ui=ui,server=server))
`

Also the sessionInfo()

R version 3.5.2 (2018-12-20) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 18.04.1 LTS

Matrix products: default BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1 LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8
[6] LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages: [1] stats graphics grDevices utils datasets methods base

other attached packages: [1] R.utils_2.8.0 R.oo_1.22.0 R.methodsS3_1.7.1 cyjShiny_0.99.8 jsonlite_1.6 htmlwidgets_1.3 shiny_1.2.0

loaded via a namespace (and not attached): [1] graph_1.58.2 Rcpp_1.0.0 rstudioapi_0.9.0 magrittr_1.5 BiocGenerics_0.26.0 xtable_1.8-3
[7] R6_2.4.0 rlang_0.3.1 tools_3.5.2 DT_0.5.2 parallel_3.5.2 shinyjs_1.0
[13] htmltools_0.3.6 yaml_2.2.0 digest_0.6.18 crayon_1.3.4 later_0.8.0 promises_1.0.1
[19] rsconnect_0.8.13 mime_0.6 compiler_3.5.2 stats4_3.5.2 httpuv_1.4.5.1