5.2. Eine Startseite gestalten#

Story

Nachdem Amir Weber sich die notwedigen Grundkenntnisse angeeignet hat, geht er zur Implementierung des Dashboards über.

Zweck dieser Übung

Der Aufbau eines Dashboards als Form der Visualisierung in der Verwaltungswissenschaft umfasst die Gestaltung einer übersichtlichen Startseite für ein R-Shiny-Dashboard. Diese soll zentrale Informationen klar strukturiert darstellen, den Nutzer:innen einen schnellen Überblick verschaffen und gleichzeitig als intuitiver Einstiegspunkt in die Anwendung dienen.

Die Startseite von Amirs Dashboard soll als zentrale Übersicht und Einstiegspunkt dienen. Hier werden die wichtigsten Kennzahlen für das Bundesland Berlin sofort sichtbar:

  • Anzahl der erfassten Bäume

  • Anzahl bewässerter Bäume

Damit liefert die Startseite einen kompakten, aber aussagekräftigen Überblick über das Engagement der Bürger:innen. Sie beantwortet bereits auf den ersten Blick zentrale Fragen der Analyse:

1. Wie groß ist der Bestand an erfassten Bäumen?
2. Wie viele davon wurden aktiv bewässert?

So ist die Startseite nicht nur auf den ersten Blick intuitiv und verständlich, sondern auch funktional der ideale Ausgangspunkt für die weitere Erkundung der Daten.

Für den Einstieg arbeiten Sie mit dem Datensatz „Gieß den Kiez – Bewässerungsdaten“ von GovData. Dieser Datensatz bietet detaillierte Informationen darüber, wann, wo und wieviel in Berlin gegossen wurde. Er eignet sich ideal, um erste Analysen zum Gießverhalten zu erstellen, da er sowohl zeitliche als auch räumliche Bezüge enthält und öffentlich zugänglich ist.

Ein Screenshot, der zeigt Dashboard Startseite

Abb. 5.3 Startseite des Dashboards: Auf der Startseite können ein oder mehrere Bezirke über eine Filterfunktion ausgewählt werden. Die beiden Kacheln zeigen jeweils die Anzahl der erfassten Bäume sowie die Anzahl der bereits bewässerten Bäume für die jeweilige Bezirksauswahl. Zusätzlich wird der Berliner Gesamtbestand an Bäumen als Referenz angegeben. (Quelle: eigene Ausarbeitung)#

Für die Startseite seiner Anwendung möchte Amir eine kompakte Kennzahlenübersicht erstellen. Diese soll den Nutzer:innen helfen, sofort die Größenordnung des Gießverhaltens einzuschätzen. Zum Beispiel, wie viele Bäume insgesamt erfasst sind und wie viele davon gegossen wurden. Der Mehrwert einer Startseite mit Kennzahlenkacheln umfasst also die schnellere Orientierung. Nutzer:innen erfassen auf einen Blick den aktuellen Stand der Gießaktivitäten, ohne durch die Anwendung navigieren zu müssen. Dies spart Zeit und erleichtert den Einstieg. Die Kennzahlen dienen als Ausgangspunkt: man kann von dort aus zu detaillierteren Visualisierungen und Analysen navigieren.

Zusätzlich plant er Filtermöglichkeiten nach Bezirk, um die Kennzahlen gezielt einzugrenzen und regionale Unterschiede sichtbar zu machen. Damit lassen sich die Daten auch in einer feineren Granularität, von stadtweiter Übersicht bis hin zu einzelnen Bezirken, betrachten. Die auf der Startseite dargestellten Kennzahlen werden dabei ausschließlich als absolute Werte angezeigt und nicht ins Verhältnis zueinander gesetzt, da sie zunächst eine verlässliche Datengrundlage vermitteln sollen, bevor weiterführende Analysen und Vergleiche umgesetzt werden.

Als Nächstes bauen Sie die Startseite des Dashboards mit R. Nach jedem Codeabschnitt werden kurz die verwendeten Techniken und Befehle erklärt. Dabei widmen Sie sich sowohl der Benutzeroberfläche (UI), als auch der Serverseite des R-Shiny-Dashboards.

5.2.1. Benutzeroberfläche (UI)#

Platzierung des UI Codes

Alle in diesem Abschnitt folgenden Code-Bausteine für die Benutzeroberfläche gehören in die ui-Struktur, die Sie in den Vorbereitungen definiert haben:

ui <- dashboardPage(
  dashboardHeader(...),
  dashboardSidebar(
    # ... Hier kommt der Code für die Seitenleiste hin ...
  ),
  dashboardBody(
    # ... Hier kommt der Code für den Inhaltsbereich hin ...
  )
)

Das System Ihrer Benutzeroberfläche wird aus zwei Teilen bestehen:

  • einer Seitenleiste (sidebarMenu) mit der Navigation

  • einem Inhaltsbereich (tabItem) mit:

    • sog. ValueBoxen für wichtige Kennzahlen

    • Dropdowns zur Auswahl des Zeitraums und des Bezirks

Somit können Sie eine übersichtliche Navigationsstruktur etablieren.

Seitenleiste mit der Navigation (sidebarMenu)#

Die Seitenleiste enthält Menüpunkte, die jeweils einen Namen und ein Symbol zur besseren Orientierung bekommen. Hier können Sie zwischen verschiedenen Dashboard-Bereichen wechseln (etwa von der Startseite zur Kartenansicht oder zur Bewässerungsanalyse).

Code
dashboardSidebar(
  sidebarMenu( id = "sidebarMenu",
    menuItem("Startseite", tabName = "start", icon = icon("home"))
  )
)

Inhaltsbereich#

Auf der Startseite des Dashboards visualisieren Sie die beiden zentralen Kennzahlen: die Gesamtzahl der Bäume sowie die Anzahl der bewässerten Bäume. Über einen integrierten Filter kann die Anzeige zudem auf spezifische Bezirke eingegrenzt werden.

Code
tabItems(
      tabItem(
        tabName = "start",
        fluidRow(
          box(width = 12,
              # Label: Einfacher Text, Zahl hervorgehoben
              div(style = "padding: 10px 15px 0 15px;",
                  p(style = "font-size: 15px; margin-bottom: 2px;",
                    "Gesamter Baumbestand in Berlin:"),
                  span(style = "font-size: 28px; font-weight: bold; color: #3C6E97; margin-top: 0;",
                    textOutput("total_trees_label"))
              ),
          
              # Dropdown-Filter in voller Breite darüber
              fluidRow(
                column(width = 12,
                       div(style = "padding: 10px 15px;", 
                           selectInput("bezirk", "Bezirk auswählen (Mehrfachauswahl möglich):", 
                                       choices = c("Alle Bezirke", sort(na.omit(unique(df_merged$bezirk)))), 
                                       selected = "Alle Bezirke", multiple = TRUE)
                       )
                )
              ),
            
              # Zwei dynamische Kacheln nebeneinander
              fluidRow(
                valueBoxOutput("total_trees_filtered", width = 6),
                valueBoxOutput("total_tree_watered", width = 6)
              )
          )
        )
      )
    )

Mit diesem Aufbau haben Sie die Struktur seiner Startseite definiert:

  • Eine klare Navigation über die Seitenleiste

  • Zwei zentrale Kennzahlen in prominenter Position

  • Ein Filter zur Eingrenzung nach Bezirken

Was noch fehlt, ist die Intelligenz: Die tatsächliche Berechnung der Kennzahlen und die Reaktion auf Nutzer:inneneingaben. Dafür ist der Server zuständig.

5.2.2. Server – Die Logik hinter dem Dashboard#

Platzierung des Server Codes

Alle in diesem Abschnitt folgenden Code-Bausteine für den Server gehören in die server-Funktion, die Sie in den Vorbereitungen definiert haben:

server <- function(input, output) { 
  # Hier folgt der R-Code zur Datenverarbeitung...
}

In Shiny beobachtet der Server kontinuierlich die Eingabefelder (input$...) und aktualisiert automatisch alle Ausgaben (output$...), die von diesen Eingaben abhängen.

Für Ihr Dashboard bedeutet das konkret:

  • Sobald Nutzer:innen einen anderen Bezirk auswählen, wird der Datensatz im Hintergrund neu gefiltert

  • Die Kennzahlen werden neu berechnet und sofort in den ValueBoxen angezeigt

  • Alles geschieht ohne Verzögerung, ohne manuelles Nachladen

Daten filtern mit reaktiven Funktionen#

Amir beginnt mit der zentralen Aufgabe: Die Daten müssen je nach Auswahl der Nutzer:innen gefiltert werden. Dafür erstellt er eine reaktive Funktion, die immer dann neu ausgeführt wird, wenn sich die Eingaben ändern.

Code
filteredData <- reactive({
  req(input$bezirk)
  
  df <- df_merged 
  df_filtered <- df
  
  # Filter nach Bezirk
  if (!("Alle Bezirke" %in% input$bezirk)) {
    df_filtered <- df_filtered %>% filter(bezirk %in% input$bezirk)
  }
  
  df_filtered
})

Praktisches Beispiel für das Dashboard#

Code
output$dynamic_tree_box <- renderUI({
  if ("Baumbestand Stand 2025" %in% input$start_year) {
    valueBoxOutput("total_trees")
  } else {
    valueBoxOutput("total_tree_watered")
  }
})

ValueBoxes: Kennzahlen anzeigen#

Nun können Sie die Kennzahlen mit Inhalten füllen. In der UI wurden diese bereits als Label textOutput("total_trees_label") und zwei Kacheln valueBoxOutput("total_trees_filtered") und valueBoxOutput("total_tree_watered") angelegt. Nun definieren Sie, was darin erscheinen soll.

Alle Bäume
output$total_trees_label <- renderText({
  formatC(n_distinct(df_merged$gisid), format = "d", big.mark = ".")
})

output$total_trees_filtered <- renderValueBox({
  valueBox(
    formatC(n_distinct(filteredData()$gisid), format = "d", big.mark = "."),
    "erfasste Bäume (Bezirksauswahl)",
    icon = icon("tree"),
    color = "olive" 
  )
})
Gegossene Bäume
output$total_tree_watered <- renderValueBox({
  valueBox(
    formatC(n_distinct(filteredData()$gisid[!is.na(filteredData()$timestamp)]), 
            format = "d", big.mark = "."),
    "bewässerte Bäume (Bezirksauswahl)",
    icon = icon("tint"),
    color = "blue"
  )
})
Automatisches Abwählen von Bezirken
prev_bezirk <- reactiveVal("Alle Bezirke")
  
  observeEvent(input$bezirk, {
    if (is.null(input$bezirk)) {
      updateSelectInput(session, "bezirk", selected = "Alle Bezirke")
      prev_bezirk("Alle Bezirke")
      return()
    }
    
    curr_bezirk <- input$bezirk
    prev <- prev_bezirk()
    
    if ("Alle Bezirke" %in% curr_bezirk && !("Alle Bezirke" %in% prev)) {
      updateSelectInput(session, "bezirk", selected = "Alle Bezirke")
      prev_bezirk("Alle Bezirke")
    } else if ("Alle Bezirke" %in% curr_bezirk && length(curr_bezirk) > 1) {
      new_selection <- curr_bezirk[curr_bezirk != "Alle Bezirke"]
      updateSelectInput(session, "bezirk", selected = new_selection)
      prev_bezirk(new_selection)
    } else {
      prev_bezirk(curr_bezirk)
    }
  }, ignoreNULL = FALSE, ignoreInit = TRUE)

Das Dashboard ist nun funktionsfähig: Nutzer:innen können Bezirke auswählen und sehen sofort, wie viele Bäume in diesen Bezirken, im Verhältnis zum Gesamtbestand, gegossen wurden. Die Trennung von UI und Server ermöglicht es Amir, später weitere Analysen hinzuzufügen, ohne die bestehende Struktur grundlegend ändern zu müssen.

Überblick der Funktionen/Operatoren

Funktion/Operator

Bedeutung

<-

weist einer Variable einen Wert zu

if (...) / else

Bedingte Ausführung

%in%

prüft, ob ein Wert in einer Liste ist

filter()

filtert Zeilen in einem Datensatz

is.na()

prüft auf fehlende Werte

%>%

Pipe-Operator: leitet Ergebnis einer Funktion weiter

reactive({})

erstellt einen reaktiven Ausdruck im Server

req()

stellt sicher, dass ein Eingabewert vorhanden ist

renderValueBox()

rendert eine valueBox reaktiv im Server

valueBox()

erstellt eine farbige Kennzahlen-Box in der UI

valueBoxOutput()

Platzhalter in der UI für eine reaktive valueBox

icon()

bindet ein Font-Awesome-Icon ein

selectInput()

erstellt ein Dropdown-Auswahlmenü

fluidRow()

erstellt eine responsive Zeile im Grid-Layout

column()

definiert eine Spaltenbreite innerhalb einer fluidRow

box()

erstellt eine umrahmende Inhaltsbox in der UI

tabItems() / tabItem()

strukturiert Inhalte in Tab-Bereiche

dashboardBody()

definiert den Hauptinhaltsbereich des Dashboards

dashboardSidebar()

definiert die Seitenleiste

sidebarMenu() / menuItem()

erstellt ein Navigationsmenü in der Seitenleiste

dashboardHeader()

definiert den Kopfbereich mit Titel

dashboardPage()

erstellt das Grundlayout der Shiny-Dashboard-Seite

shinyApp()

startet die Shiny-Anwendung mit UI und Server

5.2.3. Was muss Amir beim Bau eines Dashboards beachten?#

Bei der Gestaltung der Startseite sollten Sie darauf achten, dass die wichtigsten Informationen klar, gut lesbar und ohne unnötige Ablenkungen präsentiert werden. Besonders für einen ersten Überblick gilt: Weniger ist oft mehr.

Für die Startseite heißt das vor allem:

  • Klarheit: Keine überladene Darstellung, eindeutige Beschriftungen, selbsterklärende Kennzahlen.

  • Lesbarkeit: Vermeidung von 3D-Elementen oder komplexen Grafiken, wenn ein einfacher Indikator genügt.

  • Fokus: Nur die wirklich zentralen Kennzahlen aufnehmen, um den Blick nicht zu zerstreuen.

  • Konsistenz: Einheitliche Farb- und Formatwahl, damit Nutzer:innen sich sofort orientieren können.

  • Kontext: Kurze Hinweise oder Legenden, damit die Zahlen richtig interpretiert werden können.

5.2.4. Reflexion#

Die zentrale Leitfrage der Fallstudie lautet: Wo lassen sich die höchsten Ausprägungen des Engagements von Bürger:innen bei der Bewässerung städtischer Bäume in Berlin feststellen?

Die Startseite des Dashboards ermöglicht einen ersten Überblick darüber, in welchen Bezirken es wieviele Bäume gibt und wieviele davon gegossen wurden. In absoluten Zahlen zeigt sich dabei das höchste Engagement bei den Bürger:innen in Mitte, gefolgt von Tempelhof-Schöneberg und Friedrichshain-Kreuzberg.

Ein Screenshot, der zeigt Dashboard Startseite mit Bezirk, wo absolut die meisten Bäume gegossen werden

Abb. 5.4 Startseite, jedoch ist nur der Bezirk Mitte ausgewählt (dort wurde in absoluten Zahlen die meisten Bäume gegossen) (Quelle: eigene Ausarbeitung)#

Für eine abschließende Beantwortung der Leitfrage reicht diese Betrachtung jedoch nicht aus, da ohne Normalisierung – etwa durch das Verhältnis gegossener Bäume zur Gesamtbaumzahl je Bezirk – keine validen Vergleiche zwischen den Bezirken gezogen werden können. Fahren Sie daher mit der folgenden Übung fort.

Übung#

Berechnen Sie nun für jeden Berliner Bezirk das relative Bürger:innenengagement, indem Sie die Anzahl der gegossenen Bäume zur Gesamtbaumzahl des jeweiligen Bezirks ins Verhältnis setzen.

An dieser Stelle können Sie Ihre bisher erlernten R-Fähigkeiten anwenden. Anstatt sich die Kennzahlen aus dem Dashboard rauszuschreiben und die Berechnungen mit einem Taschenrechner oder Excel durchzuführen, schreiben Sie doch ein kleines R-Script, welches diese Aufgabe erledigt. Sobald Sie das richtige Ergebnis berechnet haben, können Sie es unten im Quiz auswählen. Vergessen Sie hierbei nicht, wie bereits in vorherigen Kapiteln gezeigt, das Arbeitsverzeichnis korrekt zu setzen und die bereinigten Daten aus dem Datenverzeichnis auszulesen.

Durch die Berechnung der relativen Zahlen konnte die zentrale Leitfrage dieser Fallstudie nun sinnvoll beantwortet werden, wo sich die höchsten Ausprägungen des Engagements von Bürger:innen in Berlin feststellen lässt.

Im nächsten Abschnitt werden Sie aufbauend auf diesen Ergebnissen eine weitere Visualisierung in Form einer Karte erstellen, die nochmal räumlich abbildet, in welchem Berliner Bezirk wieviel gegossen wurde.