Spaces:
Sleeping
Sleeping
Upload app.R
Browse files
app.R
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
# app.R - 警備マッチング可視化アプリ(日付×contract_idベースマッチング対応版)
|
| 2 |
# 要件: 充足率表示、日付期間選択、要営業強化エリア識別
|
| 3 |
# 修正: ac_date_xxx.csv対応、日付とcontract_idの組み合わせでマッチング
|
| 4 |
-
# 追加:
|
| 5 |
|
| 6 |
library(shiny)
|
| 7 |
library(dplyr)
|
|
@@ -170,8 +170,8 @@ ui <- fluidPage(
|
|
| 170 |
),
|
| 171 |
hr(),
|
| 172 |
h4("🗺️ 表示設定"),
|
| 173 |
-
checkboxInput("show_available", "
|
| 174 |
-
checkboxInput("show_non_available", "
|
| 175 |
radioButtons(
|
| 176 |
"match_mode",
|
| 177 |
"追加マッチング方法(未割当隊員の参考)",
|
|
@@ -200,11 +200,11 @@ ui <- fluidPage(
|
|
| 200 |
),
|
| 201 |
tags$div(class = "legend-item",
|
| 202 |
tags$div(class = "legend-color", style = "background-color: #3498db;"),
|
| 203 |
-
tags$span("
|
| 204 |
),
|
| 205 |
tags$div(class = "legend-item",
|
| 206 |
tags$div(class = "legend-color", style = "background-color: #95a5a6;"),
|
| 207 |
-
tags$span("
|
| 208 |
)
|
| 209 |
),
|
| 210 |
hr(),
|
|
@@ -245,13 +245,13 @@ ui <- fluidPage(
|
|
| 245 |
fluidRow(
|
| 246 |
column(6,
|
| 247 |
tags$div(class = "summary-header",
|
| 248 |
-
h5("
|
| 249 |
textOutput("stat_available_guards", inline = TRUE)
|
| 250 |
)
|
| 251 |
),
|
| 252 |
column(6,
|
| 253 |
tags$div(class = "summary-header",
|
| 254 |
-
h5("
|
| 255 |
textOutput("stat_non_available_guards", inline = TRUE)
|
| 256 |
)
|
| 257 |
)
|
|
@@ -297,7 +297,7 @@ server <- function(input, output, session) {
|
|
| 297 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 298 |
filter(available_flag == 1L, !is.na(担当予定contract_id))
|
| 299 |
|
| 300 |
-
#
|
| 301 |
available_guards_avail <- avail %>%
|
| 302 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 303 |
filter(available_flag == 1L) %>%
|
|
@@ -306,7 +306,7 @@ server <- function(input, output, session) {
|
|
| 306 |
available_guards <- available_guards_avail %>%
|
| 307 |
inner_join(guard, by = "ユーザー番号")
|
| 308 |
|
| 309 |
-
#
|
| 310 |
non_available_guards_avail <- avail %>%
|
| 311 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 312 |
filter(available_flag == 0L) %>%
|
|
@@ -433,7 +433,7 @@ server <- function(input, output, session) {
|
|
| 433 |
addTiles() %>%
|
| 434 |
setView(lng = center_lng, lat = center_lat, zoom = 9) %>%
|
| 435 |
addLayersControl(
|
| 436 |
-
overlayGroups = c("現場(充足率)", "
|
| 437 |
options = layersControlOptions(collapsed = FALSE)
|
| 438 |
)
|
| 439 |
})
|
|
@@ -448,8 +448,8 @@ server <- function(input, output, session) {
|
|
| 448 |
proxy <- leafletProxy("map")
|
| 449 |
proxy %>%
|
| 450 |
clearGroup("現場(充足率)") %>%
|
| 451 |
-
clearGroup("
|
| 452 |
-
clearGroup("
|
| 453 |
|
| 454 |
# 現場マーカー(充足率付き)- 地理的にユニークな場所ごとに集約
|
| 455 |
if (!("メッセージ" %in% colnames(sites_data)) && nrow(sites_data) > 0) {
|
|
@@ -515,7 +515,7 @@ server <- function(input, output, session) {
|
|
| 515 |
}
|
| 516 |
}
|
| 517 |
|
| 518 |
-
#
|
| 519 |
if (isTRUE(input$show_available) && nrow(available_gds) > 0) {
|
| 520 |
gds_unique <- available_gds %>%
|
| 521 |
filter(!is.na(home_lat), !is.na(home_lng)) %>%
|
|
@@ -531,13 +531,13 @@ server <- function(input, output, session) {
|
|
| 531 |
fillColor = "#3498db",
|
| 532 |
fillOpacity = 0.7,
|
| 533 |
weight = 1,
|
| 534 |
-
label = ~paste0("【
|
| 535 |
-
group = "
|
| 536 |
)
|
| 537 |
}
|
| 538 |
}
|
| 539 |
|
| 540 |
-
#
|
| 541 |
if (isTRUE(input$show_non_available) && nrow(non_available_gds) > 0) {
|
| 542 |
gds_unique <- non_available_gds %>%
|
| 543 |
filter(!is.na(home_lat), !is.na(home_lng)) %>%
|
|
@@ -553,8 +553,8 @@ server <- function(input, output, session) {
|
|
| 553 |
fillColor = "#95a5a6",
|
| 554 |
fillOpacity = 0.7,
|
| 555 |
weight = 1,
|
| 556 |
-
label = ~paste0("【
|
| 557 |
-
group = "
|
| 558 |
)
|
| 559 |
}
|
| 560 |
}
|
|
|
|
| 1 |
# app.R - 警備マッチング可視化アプリ(日付×contract_idベースマッチング対応版)
|
| 2 |
# 要件: 充足率表示、日付期間選択、要営業強化エリア識別
|
| 3 |
# 修正: ac_date_xxx.csv対応、日付とcontract_idの組み合わせでマッチング
|
| 4 |
+
# 追加: 割当済隊員/未割当隊員の表示切替
|
| 5 |
|
| 6 |
library(shiny)
|
| 7 |
library(dplyr)
|
|
|
|
| 170 |
),
|
| 171 |
hr(),
|
| 172 |
h4("🗺️ 表示設定"),
|
| 173 |
+
checkboxInput("show_available", "割当済隊員を表示(対応可否=1)", TRUE),
|
| 174 |
+
checkboxInput("show_non_available", "未割当隊員を表示(対応可否=0)", TRUE),
|
| 175 |
radioButtons(
|
| 176 |
"match_mode",
|
| 177 |
"追加マッチング方法(未割当隊員の参考)",
|
|
|
|
| 200 |
),
|
| 201 |
tags$div(class = "legend-item",
|
| 202 |
tags$div(class = "legend-color", style = "background-color: #3498db;"),
|
| 203 |
+
tags$span("割当済隊員(対応可否=1)")
|
| 204 |
),
|
| 205 |
tags$div(class = "legend-item",
|
| 206 |
tags$div(class = "legend-color", style = "background-color: #95a5a6;"),
|
| 207 |
+
tags$span("未割当隊員(対応可否=0)")
|
| 208 |
)
|
| 209 |
),
|
| 210 |
hr(),
|
|
|
|
| 245 |
fluidRow(
|
| 246 |
column(6,
|
| 247 |
tags$div(class = "summary-header",
|
| 248 |
+
h5("割当済隊員数(期間内)"),
|
| 249 |
textOutput("stat_available_guards", inline = TRUE)
|
| 250 |
)
|
| 251 |
),
|
| 252 |
column(6,
|
| 253 |
tags$div(class = "summary-header",
|
| 254 |
+
h5("未割当隊員数(期間内)"),
|
| 255 |
textOutput("stat_non_available_guards", inline = TRUE)
|
| 256 |
)
|
| 257 |
)
|
|
|
|
| 297 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 298 |
filter(available_flag == 1L, !is.na(担当予定contract_id))
|
| 299 |
|
| 300 |
+
# 割当済隊員(対応可否=1)
|
| 301 |
available_guards_avail <- avail %>%
|
| 302 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 303 |
filter(available_flag == 1L) %>%
|
|
|
|
| 306 |
available_guards <- available_guards_avail %>%
|
| 307 |
inner_join(guard, by = "ユーザー番号")
|
| 308 |
|
| 309 |
+
# 未割当隊員(対応可否=0)
|
| 310 |
non_available_guards_avail <- avail %>%
|
| 311 |
filter(!is.na(日付), 日付 >= d_start, 日付 <= d_end) %>%
|
| 312 |
filter(available_flag == 0L) %>%
|
|
|
|
| 433 |
addTiles() %>%
|
| 434 |
setView(lng = center_lng, lat = center_lat, zoom = 9) %>%
|
| 435 |
addLayersControl(
|
| 436 |
+
overlayGroups = c("現場(充足率)", "割当済隊員", "未割当隊員"),
|
| 437 |
options = layersControlOptions(collapsed = FALSE)
|
| 438 |
)
|
| 439 |
})
|
|
|
|
| 448 |
proxy <- leafletProxy("map")
|
| 449 |
proxy %>%
|
| 450 |
clearGroup("現場(充足率)") %>%
|
| 451 |
+
clearGroup("割当済隊員") %>%
|
| 452 |
+
clearGroup("未割当隊員")
|
| 453 |
|
| 454 |
# 現場マーカー(充足率付き)- 地理的にユニークな場所ごとに集約
|
| 455 |
if (!("メッセージ" %in% colnames(sites_data)) && nrow(sites_data) > 0) {
|
|
|
|
| 515 |
}
|
| 516 |
}
|
| 517 |
|
| 518 |
+
# 割当済隊員マーカー(青)
|
| 519 |
if (isTRUE(input$show_available) && nrow(available_gds) > 0) {
|
| 520 |
gds_unique <- available_gds %>%
|
| 521 |
filter(!is.na(home_lat), !is.na(home_lng)) %>%
|
|
|
|
| 531 |
fillColor = "#3498db",
|
| 532 |
fillOpacity = 0.7,
|
| 533 |
weight = 1,
|
| 534 |
+
label = ~paste0("【割当済】ユーザー番号: ", ユーザー番号, " | ", 苗字, " ", 名前, " | ", guard_city),
|
| 535 |
+
group = "割当済隊員"
|
| 536 |
)
|
| 537 |
}
|
| 538 |
}
|
| 539 |
|
| 540 |
+
# 未割当隊員マーカー(グレー)
|
| 541 |
if (isTRUE(input$show_non_available) && nrow(non_available_gds) > 0) {
|
| 542 |
gds_unique <- non_available_gds %>%
|
| 543 |
filter(!is.na(home_lat), !is.na(home_lng)) %>%
|
|
|
|
| 553 |
fillColor = "#95a5a6",
|
| 554 |
fillOpacity = 0.7,
|
| 555 |
weight = 1,
|
| 556 |
+
label = ~paste0("【未割当】ユーザー番号: ", ユーザー番号, " | ", 苗字, " ", 名前, " | ", guard_city),
|
| 557 |
+
group = "未割当隊員"
|
| 558 |
)
|
| 559 |
}
|
| 560 |
}
|