sugitora commited on
Commit
f41e850
·
verified ·
1 Parent(s): d4de2b2

Upload 2 files

Browse files
Files changed (2) hide show
  1. Dockerfile +5 -31
  2. app.R +45 -40
Dockerfile CHANGED
@@ -1,44 +1,18 @@
1
- # Dockerfile for Hugging Face Spaces - R Shiny App
2
- # Risk Monitoring Dashboard
3
 
4
  FROM rocker/r-ver:4.3.2
5
 
6
- # Install system dependencies for leaflet and other packages
7
  RUN apt-get update && apt-get install -y --no-install-recommends \
8
  libcurl4-openssl-dev \
9
  libssl-dev \
10
  libxml2-dev \
11
- libfontconfig1-dev \
12
- libfreetype6-dev \
13
- libpng-dev \
14
- libtiff5-dev \
15
- libjpeg-dev \
16
- libharfbuzz-dev \
17
- libfribidi-dev \
18
- libgdal-dev \
19
- libgeos-dev \
20
- libproj-dev \
21
- libudunits2-dev \
22
- libsqlite3-dev \
23
- libv8-dev \
24
  pandoc \
25
- make \
26
- g++ \
27
  && rm -rf /var/lib/apt/lists/*
28
 
29
- # Install R packages one by one for better error handling
30
- RUN R -e "install.packages('shiny', repos='https://cloud.r-project.org/')"
31
- RUN R -e "install.packages('bslib', repos='https://cloud.r-project.org/')"
32
- RUN R -e "install.packages('htmltools', repos='https://cloud.r-project.org/')"
33
- RUN R -e "install.packages('htmlwidgets', repos='https://cloud.r-project.org/')"
34
- RUN R -e "install.packages('leaflet', repos='https://cloud.r-project.org/')"
35
- RUN R -e "install.packages('plotly', repos='https://cloud.r-project.org/')"
36
- RUN R -e "install.packages('DT', repos='https://cloud.r-project.org/')"
37
- RUN R -e "install.packages('dplyr', repos='https://cloud.r-project.org/')"
38
- RUN R -e "install.packages('lubridate', repos='https://cloud.r-project.org/')"
39
-
40
- # Verify leaflet is installed
41
- RUN R -e "library(leaflet); cat('leaflet installed successfully\n')"
42
 
43
  # Create app directory
44
  WORKDIR /app
 
1
+ # Dockerfile for Hugging Face Spaces - R Shiny App (Lightweight version)
2
+ # Risk Monitoring Dashboard - No leaflet dependency
3
 
4
  FROM rocker/r-ver:4.3.2
5
 
6
+ # Install minimal system dependencies
7
  RUN apt-get update && apt-get install -y --no-install-recommends \
8
  libcurl4-openssl-dev \
9
  libssl-dev \
10
  libxml2-dev \
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  pandoc \
 
 
12
  && rm -rf /var/lib/apt/lists/*
13
 
14
+ # Install R packages
15
+ RUN R -e "install.packages(c('shiny', 'bslib', 'plotly', 'DT', 'dplyr', 'lubridate'), repos='https://cloud.r-project.org/')"
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  # Create app directory
18
  WORKDIR /app
app.R CHANGED
@@ -5,7 +5,7 @@
5
 
6
  library(shiny)
7
  library(bslib)
8
- library(leaflet)
9
  library(plotly)
10
  library(DT)
11
  library(dplyr)
@@ -354,7 +354,7 @@ ui <- page_navbar(
354
  border-radius: 2px;
355
  }
356
 
357
- .leaflet-container {
358
  border-radius: 8px;
359
  }
360
 
@@ -425,7 +425,7 @@ ui <- page_navbar(
425
  col_widths = c(8, 4),
426
  card(
427
  card_header("世界リスクマップ"),
428
- leafletOutput("risk_map", height = "350px")
429
  ),
430
  layout_columns(
431
  col_widths = 12,
@@ -682,48 +682,53 @@ server <- function(input, output, session) {
682
  })
683
 
684
  # ----- リスクマップ -----
685
- output$risk_map <- renderLeaflet({
686
- leaflet(country_data) %>%
687
- addProviderTiles(providers$CartoDB.Positron) %>%
688
- setView(lng = 20, lat = 20, zoom = 2) %>%
689
- addCircleMarkers(
690
- ~lng, ~lat,
691
- radius = ~sqrt(risk_score) * 1.5,
692
- color = ~ifelse(risk_score >= 70, "#E53E3E",
693
- ifelse(risk_score >= 40, "#DD6B20", "#38A169")),
694
- fillOpacity = 0.7,
695
- stroke = TRUE,
696
- weight = 2,
697
- popup = ~paste0(
698
- "<strong>", country_jp, "</strong><br>",
699
- "リスクスコア: <span style='color:",
700
- ifelse(risk_score >= 70, "#E53E3E",
701
- ifelse(risk_score >= 40, "#DD6B20", "#38A169")),
702
- "; font-weight: bold;'>", risk_score, "</span><br>",
703
  "地域: ", region
 
 
 
 
 
 
 
704
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705
  )
706
  })
707
 
708
- # マップの選択国ハイライト
709
- observe({
710
- current <- selected_country()
711
- current_data <- country_data %>% filter(country == current)
712
-
713
- leafletProxy("risk_map") %>%
714
- clearGroup("highlight") %>%
715
- addCircleMarkers(
716
- data = current_data,
717
- ~lng, ~lat,
718
- radius = 20,
719
- color = "#FF6B35",
720
- fillOpacity = 0,
721
- stroke = TRUE,
722
- weight = 3,
723
- group = "highlight"
724
- )
725
- })
726
-
727
  # ----- メトリクス -----
728
  output$high_risk_count <- renderText({
729
  sum(country_data$risk_score >= 70)
 
5
 
6
  library(shiny)
7
  library(bslib)
8
+ # library(leaflet) # Replaced with plotly geo
9
  library(plotly)
10
  library(DT)
11
  library(dplyr)
 
354
  border-radius: 2px;
355
  }
356
 
357
+ .plotly-container {
358
  border-radius: 8px;
359
  }
360
 
 
425
  col_widths = c(8, 4),
426
  card(
427
  card_header("世界リスクマップ"),
428
+ plotlyOutput("risk_map", height = "350px")
429
  ),
430
  layout_columns(
431
  col_widths = 12,
 
682
  })
683
 
684
  # ----- リスクマップ -----
685
+ output$risk_map <- renderPlotly({
686
+ # Color based on risk score
687
+ colors <- sapply(country_data$risk_score, function(s) {
688
+ if (s >= 70) "#E53E3E"
689
+ else if (s >= 40) "#DD6B20"
690
+ else "#38A169"
691
+ })
692
+
693
+ plot_geo(country_data, locationmode = 'world') %>%
694
+ add_markers(
695
+ x = ~lng,
696
+ y = ~lat,
697
+ size = ~risk_score,
698
+ color = I(colors),
699
+ text = ~paste0(
700
+ "<b>", country_jp, "</b><br>",
701
+ "リスクスコア: ", risk_score, "<br>",
 
702
  "地域: ", region
703
+ ),
704
+ hoverinfo = "text",
705
+ marker = list(
706
+ sizemode = 'diameter',
707
+ sizeref = 2,
708
+ opacity = 0.7,
709
+ line = list(width = 1, color = 'white')
710
  )
711
+ ) %>%
712
+ layout(
713
+ geo = list(
714
+ scope = 'world',
715
+ projection = list(type = 'natural earth'),
716
+ showland = TRUE,
717
+ landcolor = toRGB("gray95"),
718
+ showocean = TRUE,
719
+ oceancolor = toRGB("lightblue"),
720
+ showcountries = TRUE,
721
+ countrycolor = toRGB("gray80"),
722
+ showframe = FALSE
723
+ ),
724
+ margin = list(l = 0, r = 0, t = 0, b = 0)
725
  )
726
  })
727
 
728
+ # マップの選択国ハイライト(plotlyでは動的ハイライトを簡略化)
729
+ # Note: plotlyでは leafletProxy のような動的更新が異なるため、
730
+ # 選択国のハイライトはクリックイベントで対応
731
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
732
  # ----- メトリクス -----
733
  output$high_risk_count <- renderText({
734
  sum(country_data$risk_score >= 70)