A question about shiny minichart

shiny

#1
library(shiny)
library(shinydashboard)
library(DT)
library(leaflet)
source("global.R")

ui <- dashboardPage(skin = "green",
                    dashboardHeader(title = 'xxx'),
                    dashboardBody(
                      tabItems(
                        # Second content
                        tabItem(tabName = "list",  
                                column(width = 9, box(width = NULL, solidHeader = TRUE, leafletOutput("map", height = 850))), 
                                column(width = 3, box(width = NULL, selectInput("type", "select", choices = c("normal","monitor"))))
                        )  
                    )))

server <- function(input, output) {
  # Initialization map
  output$map <- renderLeaflet({map %>%
      addMinicharts(cems$longitude, cems$latitude, type = 'bar',layerId = cems$towncode)})
  
  
  # Update charts each time input value changes
  observe({
    cf_data <- switch(input$type, "normal" = Filter(Negate(is.null), cems$factory),"monitor" = Filter(Negate(is.null), cems$cems))
    leafletProxy("map") %>%
      updateMinicharts(layerId = cems$towncode, chartdata = cf_data, type = 'bar', colorPalette = colors)
  })

  }

shinyApp(ui, server)

I'm a novice at shiny. I'm using minichart to show my map. But I am disturbed by three problems.

  1. The number on the map always show two set of data. But I only want one set when I select one (cems or factory).
  2. I have a lot of null in sets. I want to remove them on the map. I have added "Filter". But it doesn't work.
  3. I want to show the base map on the dashboard first. But the conde on tutorial shows chart in the beginning.
    And I don't know how to revise it.

Can someone give me some advice on the problems? Thanks


#2

@Karen Could you please provide your global.R script? I can not execute your reproduce your shiny app on my end without the information inside that script (ex: missing cems and colors). (Shiny debugging and reprex guide)


#3

@barret OK! Here are the related data and file. Thank you.
https://drive.google.com/open?id=1Lg-goPPst1b1W8fnREVmd4PzmS2qvEHF


#4

@Karen

Ok. I think I have some ideas...

  1. I think when trying to trim down your example,
  • I think you lost the sidebar code. This makes the leaflet map not show up. I've added it back.
  • I've used these variable names when using the global.R provided.
cems <- cems_factory
map <- pm25_map
colors <- mycols
  1. This is related to the filter not working. This is fixed in # 2
  2. Use dplyr::filter to subset the whole dataset, not just a particular column. Values can not be NULL in a typical data.frame, they are usually NA.
  3. Add a third option to the select input of "none" that is first. Using the value, we can check if nothing has been selected, so no values should be displayed by default.

I've made a new app.R file below using the global.R and data you've supplied. Feel free to pull it a part as necessary.

library(shiny)
library(shinydashboard)
library(DT)
library(leaflet)
source("global.R")

cems <- cems_factory
map <- pm25_map
colors <- mycols

ui <- dashboardPage(
  skin = "green",
  dashboardHeader(title = 'xxx'),
  dashboardSidebar(
    sidebarMenu(
      # Setting id makes input$tabs give the tabName of currently-selected tab
      id = "tabs",
      menuItem("Dashboard", tabName = "list", icon = icon("dashboard"))
    )
  ),
  dashboardBody(
    tabItems(
      # Second content
      tabItem(
        tabName = "list",
        column(width = 9,
          box(width = NULL, solidHeader = TRUE, leafletOutput("map", height = 850))
        ),
        column(width = 3,
          box(width = NULL,
            selectInput("type", "select", choices = c("none","normal","monitor"))
          )
        )
      )
    )
  )
)

server <- function(input, output) {
  # Initialization map
  output$map <- renderLeaflet({
    map
  })

  # Update charts each time input value changes
  observe({
    leafletProxy("map") %>%
      ### always remove the prior minichart
      removeMinicharts(cems$towncode)

    ### quit if the input type isn't none
    req(input$type != "none")

    ### Use dplyr::filter to subset the full cems data
    cf_data <- switch(
      input$type,
      "normal" = dplyr::filter(cems, !is.na(factory)),
      "monitor" = dplyr::filter(cems, !is.na(cems))
    )
    ### Add a new minichart to the leaflet map
    leafletProxy("map") %>%
      addMinicharts(cf_data$longitude, cf_data$latitude, layerId = cf_data$towncode, chartdata = cf_data, type = 'bar', colorPalette = colors)
  })

}

shinyApp(ui, server)

#5

Thank you for your reply.