2016-06-24 22 views
2

Probleme beim Synchronisieren von zwei Prospekte auf verschiedenen Registerkarten.Synchronisieren Sie zwei Leaflet Maps auf verschiedenen Tabs in RMarkdown mit Shiny

Nach dem Lesen der vorherigen Einträge (Synchronizing two leaflet maps in R/Rmarkdown) funktioniert die von @TimSalabim bereitgestellte Lösung nicht, da sich die Karten auf verschiedenen Registerkarten befinden.

ist hier ein MWE RMarkdown Beispiel:

--- 
title: "QuestionforStackOverflow" 
output: 
flexdashboard::flex_dashboard: 
runtime: shiny 
--- 

```{r setup, include=FALSE} 
library(flexdashboard) 
library(shiny) 
library(leaflet) 
``` 

Tab One 
====================================================================== 
```{r tab1} 
output$map1 <- 
    renderLeaflet(
    leaflet() %>% 
     addProviderTiles("CartoDB.Positron") %>% 
     setView(-93.65, 42.0285, zoom = 4) 
) 

leafletOutput("map1") 

``` 
Tab Two 
====================================================================== 
```{r tab2} 

output$map2 <- 
    renderLeaflet(
    leaflet() %>% 
     addProviderTiles("CartoDB.Positron") %>% 
     setView(-93.65, 42.0285, zoom = 4) 
) 

leafletOutput("map2") 
``` 

Ich möchte einen Zweiweg ändern. Jede Ansicht ändert sich in map1 - ändert map2 ODER Änderungen an map2 ändern map1.

Ideal: Wenn Sie in St. Louis auf map1 scrollen, wird map2 die gleiche Zoomstufe auf St. Louis haben.

Momentan gibt es keine Interaktivität zwischen den beiden Karten. Gibt es eine Möglichkeit, sie zu synchronisieren?

Antwort

1

Sie können die leafletProxy() für diesen Einsatz: die Hilfe Siehe hier: https://rstudio.github.io/leaflet/shiny.html

Für Ihr spezielles Problem, hier ist eine Idee:

--- 
    title: "QuestionforStackOverflow" 
    output: 
    flexdashboard::flex_dashboard: 
    runtime: shiny 
--- 

```{r setup, include=FALSE} 
    library(flexdashboard) 
    library(shiny) 
    library(leaflet) 
``` 

Tab One 
====================================================================== 

```{r tab1} 
output$map1 <- 
    renderLeaflet(
    leaflet() %>% 
     addProviderTiles("CartoDB.Positron") %>% 
     setView(-93.65, 42.0285, zoom = 4) 
) 

actionButton("syncMap1", "Fit to map2 bounds") 
leafletOutput("map1") 

observeEvent(input$syncMap1,{ 
    map2coords <- input$map2_bounds 
    map1Proxy <- leafletProxy("map1") 
    map1Proxy %>% fitBounds(lng1 = map2coords$east, 
          lat1 = map2coords$north, 
          lng2 = map2coords$west, 
          lat2 = map2coords$south) 
}) 
``` 

Tab Two 
====================================================================== 

```{r tab2} 

output$map2 <- 
    renderLeaflet(
    leaflet() %>% 
     addProviderTiles("CartoDB.Positron") %>% 
     setView(-93.65, 42.0285, zoom = 4) 
) 
actionButton("syncMap2", "Fit to map1 bounds") 
leafletOutput("map2") 

observeEvent(input$syncMap2,{ 
    map1coords <- input$map1_bounds 
    map2Proxy <- leafletProxy("map2") 
    map2Proxy %>% fitBounds(lng1 = map1coords$east, 
          lat1 = map1coords$north, 
          lng2 = map1coords$west, 
          lat2 = map1coords$south) 
}) 
``` 

Die Idee ist, die Koordinaten der anderen Karte abrufen wenn Sie auf die Schaltflächen klicken und die Ansicht dann synchronisieren.

Geringes Problem: Die Ansicht ist nicht so gut synchronisiert: könnte besser sein, den Schwerpunkt der angezeigten Karte zu finden und setView() mit input$map1_zoom zu verwenden.

Hauptproblem: Dies bedeutet die Verwendung von Tasten, was nicht so benutzerfreundlich ist. Theoretisch könnten Sie einen observe() Block verwenden, um die Koordinaten jeder Karte zum anderen zu reflektieren. Versuchte es und es ist ziemlich fehlerhaft, wahrscheinlich wegen einer "unendlichen" Schleife, da es Mikrovariationen in den Koordinaten gibt.

+0

Für die automatische Synchronisierung könnten Sie die @Jieter-Idee der Tab-Change-Erkennung verwenden. Aber so weit ich es versucht habe, ist es mit flexdashboard nicht möglich: Sie können dem Registerkartencontainer keine ID geben, und daher können Sie nicht jedes Mal, wenn eine andere Registerkarte ausgewählt wird, eine Eingabe ändern. Mit glänzend wäre dies viel einfacher. – RobinCura

+0

Ordentlich arbeiten. Ist es möglich, ein Ereignis zu erstellen, wenn der Benutzer zwischen Tabs wechselt? Das könnte das Problem der Endlosschleife lösen. Nach einem schnellen Blick scheint es in js möglich zu sein, aber vielleicht nicht in R. –

0

Keine Ahnung, wie das mit R funktionieren würde, aber mit einfachem JavaScript könnten Sie Leaflet.Sync verwenden, um zwei Karten zu synchronisieren.

Wenn Sie zwei Registerkarten haben, von denen nur eine zu der Zeit sichtbar ist, können Sie auch einfach auf Tab-Schalter synchronisieren, was viel einfacher zu implementieren ist.

+0

(http://stackoverflow.com/questions/23599268/include-a-javascript-file-in-shiny-app) Ich werde versuchen, diese Dokumentation zu folgen. Für den JS-Code hinzufügen ... –

+0

* Wie für den JS-Code, nicht sicher, wo in RMarkdown zu bearbeiten. –