ramnathv / rMaps

Interactive Maps from R
http://rmaps.github.io
389 stars 194 forks source link

Using hover events as Shiny inputs #48

Open justmytwospence opened 10 years ago

justmytwospence commented 10 years ago

The title pretty much says it all, is there a way to communicate hover events back to Shiny? In particular I'd like to subset a dataset when a particular state is hovered over.

ramnathv commented 10 years ago

It is not possible currently. One would have to write Shiny bindings to allow two way communication between the client and the server. If all you are looking to do is subset data, it is easily done on the client side, using some custom javascript, which might be simpler than writing a Shiny binding.

If you have data, some code and an idea of what you want to happen on hover, post it here and I can try and help with the custom javascript snippet that would do what you are looking for.

justmytwospence commented 10 years ago

Thanks for the speedy response, Ramnath. I actually want to use the hover info to adjust the way I am drawing a few other plots. Is a binding required for this? I actually just got a custom binding to work for rendering a D3 SVG, so although its still a little mystifying to me, the concept isn't completely alien to me.

ramnathv commented 10 years ago

Actually, there may not be a need to write an explicit binding. Shiny has mechanisms that allow messages to be passed between the client and the server. So in this case, all that might be required is to trigger a message on hover, that communicates to the server some information about the object being hovered upon.

Now, which of the libraries in rMaps were you looking to use. If you were planning to use Leaflet, I would recommend looking at Leaflet Shiny by @jcheng5 that might be more amenable to what you are looking for.

If you have some working code and described in more detail what you were trying to accomplish, I can help you with the rMaps side of things.

justmytwospence commented 10 years ago

I am using DataMaps. What I have so far is here: https://github.com/justmytwospence/msan622/tree/master/homework3

and viewable here: https://justmytwospence.shinyapps.io/homework3

Eventually the map and the plot will be on the same page obviously, and I'd like to highlight the corresponding path on the parallel coordinates plot when a particular state is hovered over (as well as several other things eventually). To do so, I will need some sort of message from RMaps to indicate the relevant state.

ramnathv commented 10 years ago

As I suspected, it is possible to pass data on which state is being hovered upon using Shiny.onInputChange. Here is an example based on your application. Let me explain what is happening here.

Datamaps has a popupTemplate option that allows you to pass a javascript function to customize the output displayed on hover. We take advantage of this and sneakily insert a Shiny.onInputChange line that passes the state being hovered upon, given by geography.properties.name to the variable state. This variable is now accessible to shiny as input$state.

As a simple test, I am using input$state to drive a text output mystate. So if you now add a verbatimTextOutput("mystate") line to your map tab, you will see its value changes to the state being hovered upon.

Clearly you can do more with input$state.

output$myplot = rCharts::renderChart2({
  ichoropleth(
    Crime ~ State, 
    data = subset(violent_crime, Year == 2010),
    geographyConfig = list(
      popupTemplate = "#! function(geography, data){
        Shiny.onInputChange('state', geography.properties.name)
        return '<div class=hoverinfo><strong>' + geography.properties.name + '</strong></div>';
      } !#"
    )
  )
})

output$mystate <- renderText({
    input$state
})

Let me know if this is clear and satisfies what you were looking for.

timelyportfolio commented 10 years ago

Here is a similar example (now messed up for some reason; don't have time to inspect) with parallel coordinates and map interacting on the JS side. Unless Shiny is required, this can serve as a good example of avoiding the burden and overhead of maintaining a connection with R.

I will try to plug into Datamaps if you don't since I think this is very nice functionality, especially to solve the problem mentioned here.

ramnathv commented 10 years ago

I agree with @timelyportfolio. rCharts actually has a parallel coords binding and I am now thinking that it may not be that difficult to create a page with two plots that can talk to each other. It will still involve some custom javascript, but nothing too scary IMHO.

Shiny does give you some advantages, but there is the overhead of maintaining a persistent R session. Let me know if you think this might be interesting and we could try to put together a minimal working example.

justmytwospence commented 10 years ago

That sounds appealing. Both the source code and the deployed app are updated slightly. I still haven't done the piece that updates the parallel coordinates (I'm working on this in my spare minuets between classes right now), but it will probably be easier to do it in pure JS as you suggest.

The one other thing I wanted to include is a scatterplot matrix (linked if possible). I wasn't aware that rCharts has specific bindings, getting a minimal working example of either/both of those would be great.

ramnathv commented 10 years ago

Here is the rCharts Parallel Coordinates example

http://rcharts.io/parcoords/

A scatterplot matrix binding for rCharts was recently implemented as can be seen here

http://rcharts.io/viewer/?9907415

It does not have linked brushing, but should not be very hard to add.

justmytwospence commented 10 years ago

Thanks for pointing these out to me! I have some serious grokking to do on rChart's internals before these make sense to me.

timsterc commented 10 years ago

@ramnathv - is it possible to use rCharts via Shiny to generate a Parallel Coordinates plot in a Shiny UI ? Have been trying for hours - but seem to be missing the obvious ...

Thanks !