Upload app.R
Browse files
app.R
CHANGED
@@ -16,15 +16,6 @@ orderInputPanel <- function() {
|
|
16 |
)
|
17 |
}
|
18 |
|
19 |
-
textInputPanel <- function() {
|
20 |
-
conditionalPanel(
|
21 |
-
condition = "output.showTextInput",
|
22 |
-
textInput("related_captions_input", "Enter related captions (comma separated):"),
|
23 |
-
actionButton("confirm_text", "Confirm Order"),
|
24 |
-
actionButton("cancel_text", "Cancel")
|
25 |
-
)
|
26 |
-
}
|
27 |
-
|
28 |
# キャプションの並び替え関数
|
29 |
sort_captions_by_search <- function(data, search_term) {
|
30 |
if (is.null(search_term) || search_term == "") {
|
@@ -64,14 +55,16 @@ ui <- fluidPage(
|
|
64 |
tags$script(HTML("
|
65 |
function handleCaptionClick(caption, source) {
|
66 |
var operationModeElement = document.getElementById('operation_mode_UI');
|
67 |
-
if (
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
73 |
} else if (operationModeElement && operationModeElement.innerText === 'Database Making') {
|
74 |
-
|
75 |
} else {
|
76 |
copyToClipboard(caption);
|
77 |
}
|
@@ -106,7 +99,7 @@ ui <- fluidPage(
|
|
106 |
tags$br(),
|
107 |
|
108 |
# Direct Removerモード
|
109 |
-
actionButton("direct_remover", "Direct Remover"),
|
110 |
conditionalPanel(
|
111 |
condition = "output.operation_mode_UI === 'direct remove'",
|
112 |
actionButton("exit_direct_remover", "Exit Direct Remover")
|
@@ -134,6 +127,8 @@ ui <- fluidPage(
|
|
134 |
actionButton("aggregate_single", "Aggregation Single"),
|
135 |
actionButton("aggregate_all", "Aggregation All")
|
136 |
),
|
|
|
|
|
137 |
|
138 |
conditionalPanel(
|
139 |
condition = "output.operation_mode_UI !== 'direct remove' && output.operation_mode_UI !== 'Database Making'",
|
@@ -156,10 +151,10 @@ ui <- fluidPage(
|
|
156 |
actionButton("move_caption", "Move Single"),
|
157 |
actionButton("move_caption_all", "Move All"),
|
158 |
tags$br(),
|
159 |
-
actionButton("remove_related_single", "Remove Related Single"),
|
160 |
-
actionButton("remove_related_all", "Remove Related All"),
|
161 |
orderInputPanel(),
|
162 |
-
textInputPanel(), # ここで関数を呼び出しています
|
163 |
tags$br(),
|
164 |
),
|
165 |
tags$br(),
|
@@ -182,10 +177,12 @@ ui <- fluidPage(
|
|
182 |
textInput("search_caption", "Search Caption:", ""),
|
183 |
actionButton("search_button", "Search"),
|
184 |
actionButton("clear_search", "Clear"),
|
|
|
|
|
185 |
fluidRow(
|
186 |
column(4, tableOutput("selected_image_captions")),
|
187 |
column(4, tableOutput("caption_frequency_table_with_links")),
|
188 |
-
column(4, tableOutput("
|
189 |
)
|
190 |
)
|
191 |
)
|
@@ -357,13 +354,15 @@ server <- function(input, output, session) {
|
|
357 |
# 選択されている画像のcaptionを別変数に保存
|
358 |
captions_for_selected_image <- updated_data$caption[updated_data$image_path == input$selected_image]
|
359 |
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
|
|
|
|
367 |
}
|
368 |
}
|
369 |
|
@@ -379,17 +378,19 @@ server <- function(input, output, session) {
|
|
379 |
observeEvent(input$aggregate_all, {
|
380 |
updated_data <- captions_data()
|
381 |
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
for (i in 1:nrow(relation_database())) {
|
387 |
-
parent <- relation_database()$parent_caption[i]
|
388 |
-
child <- relation_database()$child_caption[i]
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
|
|
|
|
|
|
|
|
|
|
393 |
}
|
394 |
}
|
395 |
}
|
@@ -403,6 +404,20 @@ server <- function(input, output, session) {
|
|
403 |
update_log("Captions aggregated for all images.")
|
404 |
})
|
405 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
# Relation Databaseをセーブ
|
407 |
output$save_relation_database <- downloadHandler(
|
408 |
filename = function() {
|
@@ -592,36 +607,6 @@ server <- function(input, output, session) {
|
|
592 |
update_log("MOVE CAPTION ALL MODE.")
|
593 |
})
|
594 |
|
595 |
-
observeEvent(input$remove_related_single, {
|
596 |
-
if (operation_mode() != "Normal") {
|
597 |
-
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
598 |
-
return()
|
599 |
-
}
|
600 |
-
if (!is.null(captions_data())) {
|
601 |
-
selected_image_path <- input$selected_image
|
602 |
-
target_caption <- input$edit_caption
|
603 |
-
|
604 |
-
# target_captionが選択された画像に紐づいているか確認
|
605 |
-
if (any(captions_data()$image_path == selected_image_path & captions_data()$caption == target_caption)) {
|
606 |
-
operation_mode("remove_related_single")
|
607 |
-
showTextInput(TRUE)
|
608 |
-
update_log("RELATIVE REMOVE SINGLE MODE.")
|
609 |
-
} else {
|
610 |
-
showNotification("Error: Caption not found in the selected image.", type = "error")
|
611 |
-
}
|
612 |
-
}
|
613 |
-
})
|
614 |
-
|
615 |
-
observeEvent(input$remove_related_all, {
|
616 |
-
if (operation_mode() != "Normal") {
|
617 |
-
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
618 |
-
return()
|
619 |
-
}
|
620 |
-
operation_mode("remove_related_all")
|
621 |
-
showTextInput(TRUE)
|
622 |
-
update_log("RELATIVE REMOVE ALL MODE.")
|
623 |
-
})
|
624 |
-
|
625 |
observeEvent(input$confirm_order, {
|
626 |
switch(operation_mode(),
|
627 |
"add_single" = {
|
@@ -672,46 +657,6 @@ server <- function(input, output, session) {
|
|
672 |
showOrderInput(FALSE)
|
673 |
})
|
674 |
|
675 |
-
|
676 |
-
observeEvent(input$confirm_text, {
|
677 |
-
switch(operation_mode(),
|
678 |
-
"remove_related_single" = {
|
679 |
-
# Remove Related captions of Singleの処理
|
680 |
-
related_captions <- unlist(strsplit(input$related_captions_input, ","))
|
681 |
-
related_captions <- trimws(related_captions) # スペースを削除
|
682 |
-
representative_caption <- input$edit_caption
|
683 |
-
|
684 |
-
updated_data <- remove_related_captions_except_representative(captions_data(), related_captions, representative_caption, input$selected_image)
|
685 |
-
captions_data(updated_data)
|
686 |
-
update_log("Relative captions were removed from this image.")
|
687 |
-
},
|
688 |
-
"remove_related_all" = {
|
689 |
-
# Remove Related captions from All Imagesの処理
|
690 |
-
related_captions <- unlist(strsplit(input$related_captions_input, ","))
|
691 |
-
related_captions <- trimws(related_captions) # スペースを削除
|
692 |
-
representative_caption <- input$edit_caption
|
693 |
-
|
694 |
-
updated_data <- captions_data()
|
695 |
-
# representative_captionを持つすべての画像を検索
|
696 |
-
images_with_rep_caption <- unique(updated_data$image_path[updated_data$caption == representative_caption])
|
697 |
-
|
698 |
-
for (image_path in images_with_rep_caption) {
|
699 |
-
updated_data <- remove_related_captions_except_representative(updated_data, related_captions, representative_caption, image_path)
|
700 |
-
}
|
701 |
-
|
702 |
-
captions_data(updated_data)
|
703 |
-
update_log("Relative captions were removed from all images.")
|
704 |
-
}
|
705 |
-
)
|
706 |
-
|
707 |
-
# キャプションの頻度を更新
|
708 |
-
updated_caption_frequency <- get_caption_frequency(captions_data())
|
709 |
-
caption_frequency(updated_caption_frequency)
|
710 |
-
operation_mode("Normal")
|
711 |
-
showTextInput(FALSE)
|
712 |
-
})
|
713 |
-
|
714 |
-
|
715 |
observeEvent(input$cancel_order, {
|
716 |
operation_mode("Normal")
|
717 |
showOrderInput(FALSE)
|
@@ -902,9 +847,17 @@ server <- function(input, output, session) {
|
|
902 |
}
|
903 |
}, sanitize.text.function = function(x) x)
|
904 |
|
905 |
-
output$
|
906 |
-
relation_database()
|
907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
}
|
909 |
|
910 |
# アプリを実行
|
|
|
16 |
)
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
# キャプションの並び替え関数
|
20 |
sort_captions_by_search <- function(data, search_term) {
|
21 |
if (is.null(search_term) || search_term == "") {
|
|
|
55 |
tags$script(HTML("
|
56 |
function handleCaptionClick(caption, source) {
|
57 |
var operationModeElement = document.getElementById('operation_mode_UI');
|
58 |
+
if (source === 'remove_RDB') {
|
59 |
+
Shiny.setInputValue('remove_relation_index', caption, {priority: 'event'});
|
60 |
+
} else if (operationModeElement && operationModeElement.innerText === 'direct remove') {
|
61 |
+
if (source === 'frequency') {
|
62 |
+
Shiny.setInputValue('clicked_caption_frequency', caption, {priority: 'event'});
|
63 |
+
} else {
|
64 |
+
Shiny.setInputValue('clicked_caption', caption, {priority: 'event'});
|
65 |
+
}
|
66 |
} else if (operationModeElement && operationModeElement.innerText === 'Database Making') {
|
67 |
+
Shiny.setInputValue('clicked_caption_RDB', caption, {priority: 'event'});
|
68 |
} else {
|
69 |
copyToClipboard(caption);
|
70 |
}
|
|
|
99 |
tags$br(),
|
100 |
|
101 |
# Direct Removerモード
|
102 |
+
actionButton("direct_remover", "Enter Direct Remover Mode"),
|
103 |
conditionalPanel(
|
104 |
condition = "output.operation_mode_UI === 'direct remove'",
|
105 |
actionButton("exit_direct_remover", "Exit Direct Remover")
|
|
|
127 |
actionButton("aggregate_single", "Aggregation Single"),
|
128 |
actionButton("aggregate_all", "Aggregation All")
|
129 |
),
|
130 |
+
tags$br(),
|
131 |
+
tags$br(),
|
132 |
|
133 |
conditionalPanel(
|
134 |
condition = "output.operation_mode_UI !== 'direct remove' && output.operation_mode_UI !== 'Database Making'",
|
|
|
151 |
actionButton("move_caption", "Move Single"),
|
152 |
actionButton("move_caption_all", "Move All"),
|
153 |
tags$br(),
|
154 |
+
# actionButton("remove_related_single", "Remove Related Single"),
|
155 |
+
# actionButton("remove_related_all", "Remove Related All"),
|
156 |
orderInputPanel(),
|
157 |
+
# textInputPanel(), # ここで関数を呼び出しています
|
158 |
tags$br(),
|
159 |
),
|
160 |
tags$br(),
|
|
|
177 |
textInput("search_caption", "Search Caption:", ""),
|
178 |
actionButton("search_button", "Search"),
|
179 |
actionButton("clear_search", "Clear"),
|
180 |
+
tags$br(),
|
181 |
+
tags$br(),
|
182 |
fluidRow(
|
183 |
column(4, tableOutput("selected_image_captions")),
|
184 |
column(4, tableOutput("caption_frequency_table_with_links")),
|
185 |
+
column(4, tableOutput("relation_database_display"))
|
186 |
)
|
187 |
)
|
188 |
)
|
|
|
354 |
# 選択されている画像のcaptionを別変数に保存
|
355 |
captions_for_selected_image <- updated_data$caption[updated_data$image_path == input$selected_image]
|
356 |
|
357 |
+
if (nrow(relation_database()) > 0) {
|
358 |
+
for (i in 1:nrow(relation_database())) {
|
359 |
+
parent <- relation_database()$parent_caption[i]
|
360 |
+
child <- relation_database()$child_caption[i]
|
361 |
+
|
362 |
+
# parent_captionの存在確認を行い、存在する場合remove_caption_and_adjust_orderを実行
|
363 |
+
if (parent %in% captions_for_selected_image) {
|
364 |
+
updated_data <- remove_caption_and_adjust_order(updated_data, input$selected_image, child)
|
365 |
+
}
|
366 |
}
|
367 |
}
|
368 |
|
|
|
378 |
observeEvent(input$aggregate_all, {
|
379 |
updated_data <- captions_data()
|
380 |
|
381 |
+
if (nrow(relation_database()) > 0) {
|
382 |
+
for (image_path in unique(updated_data$image_path)) {
|
383 |
+
# 各画像のcaptionを別変数に保存
|
384 |
+
captions_for_image <- updated_data$caption[updated_data$image_path == image_path]
|
|
|
|
|
|
|
385 |
|
386 |
+
for (i in 1:nrow(relation_database())) {
|
387 |
+
parent <- relation_database()$parent_caption[i]
|
388 |
+
child <- relation_database()$child_caption[i]
|
389 |
+
|
390 |
+
# parent_captionの存在確認を行い、存在する場合remove_caption_and_adjust_orderを実行
|
391 |
+
if (parent %in% captions_for_image) {
|
392 |
+
updated_data <- remove_caption_and_adjust_order(updated_data, image_path, child)
|
393 |
+
}
|
394 |
}
|
395 |
}
|
396 |
}
|
|
|
404 |
update_log("Captions aggregated for all images.")
|
405 |
})
|
406 |
|
407 |
+
observeEvent(input$remove_relation_index, {
|
408 |
+
index_to_remove <- as.numeric(input$remove_relation_index)
|
409 |
+
|
410 |
+
# 削除する関係の情報を保存
|
411 |
+
parent_to_remove <- relation_database()$parent_caption[index_to_remove]
|
412 |
+
child_to_remove <- relation_database()$child_caption[index_to_remove]
|
413 |
+
|
414 |
+
# 関係を削除
|
415 |
+
relation_database(relation_database()[-index_to_remove, ])
|
416 |
+
|
417 |
+
# ログを更新
|
418 |
+
update_log(paste("Removed relation:", parent_to_remove, "->", child_to_remove))
|
419 |
+
})
|
420 |
+
|
421 |
# Relation Databaseをセーブ
|
422 |
output$save_relation_database <- downloadHandler(
|
423 |
filename = function() {
|
|
|
607 |
update_log("MOVE CAPTION ALL MODE.")
|
608 |
})
|
609 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
610 |
observeEvent(input$confirm_order, {
|
611 |
switch(operation_mode(),
|
612 |
"add_single" = {
|
|
|
657 |
showOrderInput(FALSE)
|
658 |
})
|
659 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
observeEvent(input$cancel_order, {
|
661 |
operation_mode("Normal")
|
662 |
showOrderInput(FALSE)
|
|
|
847 |
}
|
848 |
}, sanitize.text.function = function(x) x)
|
849 |
|
850 |
+
output$relation_database_display <- renderTable({
|
851 |
+
db <- relation_database()
|
852 |
+
|
853 |
+
# relation_databaseが空でない場合のみリンクを作成
|
854 |
+
if (nrow(db) > 0) {
|
855 |
+
db$remove <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"remove_RDB\");'>Remove</a>", 1:nrow(db))
|
856 |
+
}
|
857 |
+
|
858 |
+
db
|
859 |
+
}, sanitize.text.function = function(x) x) # HTMLをエスケープしないようにする
|
860 |
+
|
861 |
}
|
862 |
|
863 |
# アプリを実行
|