There and Back Again competition entry https://shiny.petras.space/commute/
rstats
rshiny
census
competition
leaflet
javascript
stats-nz

app.R 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. library(shiny)
  2. library(shinyjs)
  3. library(leaflet)
  4. library(rgdal)
  5. library(dplyr)
  6. library(leaflet.extras)
  7. # work_travel <- read_csv("../travel-work.csv")
  8. load(file="datasets.RData")
  9. shpf <- readOGR(dsn="../shapefiles/sa20025WGSfilcth")
  10. sa.in.dest <- shpf@data$SA22018_V1 %in% work_to$work_code
  11. sa.in.home <- shpf@data$SA22018_V1 %in% work_from$res_code
  12. transport.t <- c("Work at home", "Private car", "Company car",
  13. "Carpool", "Bus", "Train", "Bicycle", "Walk",
  14. "Ferry", "Other", "None")
  15. cols.labs <- c(transport.t[1:10], "Total")
  16. codelist <- shpf@data %>%
  17. mutate(sa2_code = as.numeric(as.character(SA22018_V1))) %>%
  18. select(sa2_code)
  19. startcols <- codelist %>% left_join(work_from, by = c("sa2_code" = "res_code"))
  20. startcols <- tencols[startcols$MAX]
  21. startcols <- ifelse(is.na(startcols), "#808080", startcols)
  22. # Define UI
  23. ui <- fluidPage(
  24. useShinyjs(),
  25. tags$style(type = "text/css",
  26. "html, body {
  27. width:100%;
  28. height:100%
  29. }
  30. #map {
  31. height: 100% !important;
  32. position: absolute !important;
  33. top: 0;
  34. left: 0;
  35. }
  36. #loading {
  37. cursor: progress !important;
  38. }
  39. #loading p {
  40. border-radius: 25px;
  41. background: #FFFFFF;
  42. padding: 10px;
  43. border: 2px solid #000000;
  44. font-size: 1.5em;
  45. font-weight: bold;
  46. }
  47. #mapcontrol {
  48. background-color: rgba(255, 255, 255, 0.8);
  49. border-radius: 5px;
  50. box-shadow: 0 0 15px rgba(0,0,0,0.2);
  51. padding: 6px 8px;
  52. font: 14px/16px Arial, Helvetica, sans-serif;
  53. }
  54. #lochtml ul {
  55. padding-left: 15px;
  56. }"),
  57. leafletOutput("map"),
  58. absolutePanel(top = 10, right = 10, id="mapcontrol",
  59. radioButtons("radioinout", label=NULL,
  60. choices = c(
  61. "Work in" = "work",
  62. "Live in" = "res"
  63. ),
  64. inline = TRUE),
  65. div(id="locinfo",
  66. htmlOutput("lochtml"))),
  67. absolutePanel(bottom = 30, left = 30, id="loading",
  68. p("Loading..."))
  69. )
  70. # Define server logic
  71. server <- function(input, output) {
  72. sel.SA2.code <- reactiveVal(0)
  73. p.layers <- c("polya", "polyb")
  74. output$map <- renderLeaflet({
  75. leaf <- leaflet(shpf, options = leafletOptions(minZoom = 3, maxZoom = 13)) %>%
  76. addPolygons(group = p.layers[1] ,color="#000", opacity = 1, weight=1,
  77. fillColor = startcols,
  78. label = shpf@data$SA22018__1,
  79. fillOpacity = 1) %>%
  80. setView(174, -41, 5) %>%
  81. addResetMapButton() %>%
  82. addLegend(position = "topleft",
  83. colors = c(tencols, "#808080"),
  84. labels = transport.t, opacity = 1)
  85. shinyjs::hideElement(selector="#loading p", asis = TRUE,
  86. anim=TRUE, animType = "slide", time=7)
  87. leaf
  88. })
  89. updateMap <- function() {
  90. shinyjs::showElement(selector="#loading p", asis = TRUE,
  91. anim=TRUE, animType = "slide")
  92. fcols <- startcols
  93. if (sel.SA2.code() != 0) {
  94. codvs <- work_simp %>% filter(work_code == sel.SA2.code())
  95. codvs <- codelist %>% left_join(codvs, by=c("sa2_code" = "res_code"))
  96. codvs <- tencols[codvs$MAX]
  97. fcols <- ifelse(is.na(codvs), "#808080", codvs)
  98. }
  99. leafletProxy("map", data = shpf) %>%
  100. addPolygons(group = p.layers[2] ,color="#000", opacity = 1, weight=1,
  101. fillColor = fcols,
  102. label = shpf@data$SA22018__1,
  103. fillOpacity = 1) %>%
  104. clearGroup(p.layers[1])
  105. p.layers <<- rev(p.layers)
  106. shinyjs::hideElement(selector="#loading p", asis=TRUE,
  107. anim=TRUE, animType = "slide", time = 7)
  108. }
  109. observeEvent(input$map_shape_click, {
  110. p <- input$map_shape_click
  111. pdat <- data.frame(Longitude = p$lng,
  112. Latitude =p$lat)
  113. coordinates(pdat) <- ~ Longitude + Latitude
  114. proj4string(pdat) <- proj4string(shpf)
  115. ppoly <- over(pdat, shpf)
  116. codetmp <- as.numeric(as.character(ppoly[1,"SA22018_V1"]))
  117. sel.SA2.code(ifelse(sel.SA2.code() == codetmp, 0, codetmp))
  118. updateMap()
  119. })
  120. output$lochtml <- renderUI({
  121. seled <- sel.SA2.code()
  122. if (seled == 0) {
  123. HTML("")
  124. } else {
  125. str <- sprintf("<hr style='border-top: 1px solid #000;'/><h4>%s</h4>",
  126. shpf@data$SA22018__1[shpf@data$SA22018_V1 == seled])
  127. if (input$radioinout == "work") {
  128. vals <- as.numeric(work_to[work_to$work_code == seled, 5:15])
  129. vals <- ifelse(is.na(vals), 0, vals)
  130. vals <- ifelse(vals < 0, "~0", as.character(vals))
  131. listi <- paste0(sprintf("<li>%s: %s</li>", cols.labs,
  132. vals),
  133. collapse="")
  134. str <- paste0(str, "<ul>", listi, "</ul>")
  135. } else {
  136. vals <- as.numeric(work_from[work_from$res_code == seled, 5:15])
  137. vals <- ifelse(is.na(vals), 0, vals)
  138. vals <- ifelse(vals < 0, "~0", as.character(vals))
  139. listi <- paste0(sprintf("<li>%s: %s</li>", cols.labs,
  140. vals),
  141. collapse="")
  142. str <- paste0(str, "<ul>", listi, "</ul>")
  143. }
  144. HTML(str)
  145. }
  146. })
  147. }
  148. # Run the application
  149. shinyApp(ui = ui, server = server)