Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cytoscape filtering #5

Open
kyleweise opened this issue Jul 19, 2018 · 9 comments
Open

Implement cytoscape filtering #5

kyleweise opened this issue Jul 19, 2018 · 9 comments
Labels
enhancement New feature or request

Comments

@kyleweise
Copy link

I think another main action that other users and myself would like to be able to do is filter nodes/edges(i.e. this ), where the usage would be something like

cytoscape(...) %>% nodes() %>% filter('[weight > 50]')

or
cytoscape(...) %>% filter_nodes('[weight > 50]')

The first more closely matches the example given by cytoscape.js in the link. Again, my JavaScript is not so good and I'm relatively new to package development in R, but I'm hoping contributing to this repo with aid in both of those areas.

Thanks,

-Kyle

@mrjoh3
Copy link
Owner

mrjoh3 commented Jul 20, 2018

for this one I think you need to think some more about how it is implemented and what the use case is. filter('[weight > 50]') is simply filtering the data so you could more easily do:

data %>% filter() %>% cytoscape() ...

Now I suspect that you are wanting to interact with the chart after it has rendered. In this case you will need some sort of js UI element to manage the interaction. This could more easily be done in R (likely shiny) with a slider element. The filter() would observe the slider and reapply when necessary. This would be much easier than implementing in JS.

Have a think and let me know.

Matt

@kyleweise
Copy link
Author

In the case where you have nice and neat dataframes of nodes and edges to pass to cytoscape(...), I can see using filter(...) beforehand would be easier. In my case, I am building the graph from pre-generated JSON files with cytoscape(json = my_json_string). While I assume doing this kind of filtering/preprocessing with the JSON objects as R lists is not impossible, it's rather difficult. Ergo, this feature request.

My actual use case is a Shiny app where the graph is built off these pre-generated JSON files. Then, I need to have couple groups of checkbox inputs, which basically toggle showing different nodes/edges. So in my server.R of the app, I'm a bit stuck between trying to do something like this, where I handle it all in R:

observeEvent(input$checkboxGroup_1, {
#filter by values in checkboxGroup_1
cytoscape() %>% filter(...)
})

or something like this, where I handle it in JavaScript:

observeEvent(input$checkboxGroup_1, {
message <- as.list(input$checkboxGroup_1)
session$sendCustomMessage("checkboxGroup_1_handler", message)
})

@mrjoh3 mrjoh3 added the enhancement New feature or request label Jul 22, 2018
@kyleweise
Copy link
Author

Any thoughts on how I might go about this? I'm at a loss for ideas.
I'm not even sure the second option is viable because that involves a custom .js file associated with my app, and not the cytoscape.js file of the package. So they would not have access to the same cy = cytoscape(...) object.
Let me know your thoughts.

@mrjoh3
Copy link
Owner

mrjoh3 commented Jul 26, 2018 via email

@kyleweise
Copy link
Author

Yes, I am able to do that. However, using jsonlite::fromJSON on my data results in a super complex dataframe, and loses much of the structure of the JSON that I would then have to reconstruct manually. This is what I was referring to when I said that "filtering/preprocessing with the JSON objects as R lists is not impossible, it's rather difficult" in a previous comment.

Also, have a look at this blog post by Dean Attali, in particular tip 8. I think it might be useful to reconstruct this package a bit to mimic the structure he describes, although I'm not sure exactly how it would work in regards to the many many methods that cytoscape.js has for both the "core" and "collections".

mrjoh3 added a commit that referenced this issue Jul 30, 2018
@mrjoh3
Copy link
Owner

mrjoh3 commented Jul 30, 2018

Hi Kyle,

have a look at the latest commit it is a very basic implementation based on the link you mentioned above. I have not tested that it works only that nothing else broke. Try to incorporate it into a shiny example (it will only work in shiny).

When you define the widget make sure you define the elementId you will need it to apply the filter. You can pass a character filter such as '[weight > 50]'. Let me know if it work and we can start to make it a bit more complex.

Matt

@kyleweise
Copy link
Author

kyleweise commented Jul 30, 2018

Just tried testing this by making some changes to the minimum_shiny app. I added some test weights to the nodes:

 nodes <- data.frame(id = unique(c(df$reporter, df$partner)), stringsAsFactors = FALSE,
                         weight = sample(x = c(1:100), 71))

and added the cy_filter() to the network pipe:

cytoscape(nodes = nodes, edges = edges) %>%
       layout('breadthfirst', directed = TRUE) %>%
       panzoom() %>%
       cy_filter("[weight > 25]")

and although it doesn't throw any errors (in R or JavaScript), the graph does not appear. My first thought is because the functionality for the piping is not set up properly / at all?

@mrjoh3
Copy link
Owner

mrjoh3 commented Jul 30, 2018

ah of course. this won't work with the pipe as the output is a message and not the entire widget. In shiny you will have to apply the function from inside an observe. The observe can relate to anything, even the loading of the app.

So something like:

cytoscape(nodes = nodes, edges = edges, elementId = 'myWidget')

# call filter here
observeEvent(input$..., {
    cy_filter('myWidget', "[weight > 25]")
})


@kyleweise
Copy link
Author

Hey Matt,

see my most recent PR, I've gotten the cy_filter() function to work (somewhat). See if you can't help me figure out the bug I have and if you have any tips for getting my custom function to work.

Thanks,

-Kyle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants