Spaces:
Running
Running
Update app.R
Browse files
app.R
CHANGED
|
@@ -1,141 +1,204 @@
|
|
| 1 |
library(shiny)
|
| 2 |
-
library(shinyalert)
|
| 3 |
-
library(shinythemes)
|
| 4 |
-
library(shinycssloaders)
|
| 5 |
library(shinyjs)
|
| 6 |
-
library(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
library(bslib)
|
| 8 |
-
library(thematic)
|
| 9 |
-
library(gtrendsR)
|
| 10 |
-
library(plotly)
|
| 11 |
library(dplyr)
|
| 12 |
-
library(
|
| 13 |
-
|
| 14 |
-
options(spinner.color = "lightblue",
|
| 15 |
-
spinner.color.background = "#ffffff",
|
| 16 |
-
spinner.size = 2)
|
| 17 |
|
| 18 |
my_theme <- bs_theme(
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
)
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
sidebarPanel(width = 3,actionButton("info",strong("About TrendChecker",icon("info"))),hr(),
|
| 35 |
-
hidden(tags$div(id = "about",h5("TrendChecker is a web application that enables users to monitor the search popularity of any subject of interest over time,
|
| 36 |
-
and across different countries by calling the Google trend api. Search hit of 100 is the indicator of optimum popularity, while other hits are measured relative to the optimum."))),h4(strong("Controls")),hr(),
|
| 37 |
-
textInput("text",strong("Enter Search Term")),
|
| 38 |
-
checkboxGroupInput("check",strong("Select Country(ies)"),choices = c("USA" = "US","UK" = "GB","Germany" = "DE","Netherlands" = "NL","Nigeria" = "NG","Japan" = "JP")),
|
| 39 |
-
radioButtons("radio",strong("Choose Trend Source"),choices = c("Web","News","YouTube","Images")),
|
| 40 |
-
radioButtons("time",strong("Select Time Frame"),choices = c("Last Hour","Last Four Hours","Last Day","Last Seven Days","Past 30 Days","Past 90 Days","Past 12 Months","Last Five Years")),
|
| 41 |
-
actionButton("run",strong("Run Search"),icon("caret-right"))
|
| 42 |
-
),
|
| 43 |
-
mainPanel(
|
| 44 |
-
withSpinner(plotOutput("plot", width = "113%", height = "450px"),type = 8),
|
| 45 |
-
downloadButton("plot_download","Download",icon = icon("download"))),
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
))
|
| 49 |
-
))
|
| 50 |
-
|
| 51 |
-
# Define server logic required to run query
|
| 52 |
-
|
| 53 |
-
server <- function(input, output,session) {
|
| 54 |
-
|
| 55 |
-
## APP info button toggle activation
|
| 56 |
-
|
| 57 |
-
observeEvent(input$info,{
|
| 58 |
-
toggle("about")
|
| 59 |
-
})
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
## Create reactive input switch functionality
|
| 63 |
-
|
| 64 |
-
check_input <- reactive(input$check)
|
| 65 |
-
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
"Last Four Hours" = "now 4-H",
|
| 76 |
-
"Last Day" = "now 1-d",
|
| 77 |
-
"Last Seven Days" = "now 7-d",
|
| 78 |
-
"Past 30 Days" = "today 1-m",
|
| 79 |
-
"Past 90 Days" = "today 3-m",
|
| 80 |
-
"Past 12 Months" = "today 12-m",
|
| 81 |
-
"Last Five Years" = "today+5-y"))
|
| 82 |
|
| 83 |
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
|
|
|
|
|
|
|
|
|
|
| 88 |
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
-
## Write the function
|
| 91 |
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
trend2 <- eventReactive(input$run,{
|
| 105 |
-
trend()
|
| 106 |
})
|
| 107 |
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
incProgress(1/40)
|
| 118 |
-
Sys.sleep(0.4)
|
| 119 |
-
}
|
| 120 |
-
})
|
| 121 |
-
|
| 122 |
-
req(input$run)
|
| 123 |
-
trend2()
|
| 124 |
-
|
| 125 |
-
})
|
| 126 |
|
| 127 |
-
output$
|
| 128 |
filename = function(){
|
| 129 |
-
paste("
|
| 130 |
},
|
| 131 |
content = function(file){
|
| 132 |
-
|
| 133 |
-
trend()
|
| 134 |
-
dev.off()
|
| 135 |
}
|
| 136 |
)
|
| 137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
}
|
| 139 |
|
|
|
|
|
|
|
| 140 |
# Run the application
|
| 141 |
shinyApp(ui = ui, server = server)
|
|
|
|
| 1 |
library(shiny)
|
|
|
|
|
|
|
|
|
|
| 2 |
library(shinyjs)
|
| 3 |
+
library(shinycssloaders)
|
| 4 |
+
library(shinythemes)
|
| 5 |
+
library(shinyWidgets)
|
| 6 |
+
library(shinyalert)
|
| 7 |
+
library(spsComps)
|
| 8 |
library(bslib)
|
|
|
|
|
|
|
|
|
|
| 9 |
library(dplyr)
|
| 10 |
+
library(reactable)
|
| 11 |
+
library(reactablefmtr)
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
my_theme <- bs_theme(
|
| 14 |
+
bg = "#fdfefe",
|
| 15 |
+
fg = "black",
|
| 16 |
+
primary = "red",
|
| 17 |
+
base_font = font_google("Geologica"),
|
| 18 |
+
"font-size-base" = "1.2rem",
|
| 19 |
+
version = 5,
|
| 20 |
+
"navbar-bg" = "#9f0be4"
|
| 21 |
)
|
| 22 |
|
| 23 |
+
options(
|
| 24 |
+
shiny.browser = T,
|
| 25 |
+
spinner.color = "#9f0be4",
|
| 26 |
+
spinner.color.background = "#FFFFFF",
|
| 27 |
+
spinner.size = 2
|
| 28 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
+
# options(
|
| 31 |
+
# shiny.error = function(){
|
| 32 |
+
# shinyalert(text = "An error occurred!")
|
| 33 |
+
# }
|
| 34 |
+
# )
|
| 35 |
+
#
|
| 36 |
+
# options(shiny.sanitize.errors = FALSE)
|
| 37 |
|
| 38 |
+
# import search engine function
|
| 39 |
+
#source("SearchEngine.R")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
|
| 42 |
+
# Define UI for application that fetches data from Open Alex
|
| 43 |
+
ui <- list(useShinyjs(),navbarPage(title = strong("OpenAlex For Gephi"),
|
| 44 |
+
windowTitle = "OpenAlexForGephi",
|
| 45 |
+
theme = my_theme,
|
| 46 |
+
tabPanel(title = strong("Author To Publication"),icon = icon("bar-chart"),
|
| 47 |
+
includeCSS("style.css"),includeScript("code.js"),
|
| 48 |
+
sidebarLayout(
|
| 49 |
+
sidebarPanel = "",
|
| 50 |
+
mainPanel(
|
| 51 |
+
align = "center",
|
| 52 |
+
width = 12,
|
| 53 |
+
fluidRow(column(6,actionLink("info",h6("Info", style = "color:#670e94;text-align:left;"),style = "text-decoration:none;")),
|
| 54 |
+
column(6,a(h6("Maintainer",style = "color:#670e94;text-align:right;"), style = "text-decoration:none;", target = "_blank", href = "https://github.com/Ifeanyi55"))),
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
h6(strong("Select Publication Search Window",style = "color:#670e94;")),
|
| 58 |
+
dateInput("date","From"),dateInput("date2","To"), br(),
|
| 59 |
+
textInput("text",h6(strong("Keyword Search"),style = "color:#670e94"),placeholder = "Enter keyword(s) here",width = "25%"),br(),
|
| 60 |
+
actionButton("search",strong("Search"),icon = icon("search")),
|
| 61 |
+
withSpinner(reactableOutput("table",width = "80%",height = 400),type = 1),
|
| 62 |
+
fluidRow(column(6,downloadButton("down_nodes",strong("Nodes CSV"),icon = icon("download"))),
|
| 63 |
+
column(6,downloadButton("down_edges",strong("Edges CSV"),icon = icon("download")))),
|
| 64 |
+
|
| 65 |
+
spsGoTop("up", right = "2%", bottom= "8%", icon = icon("arrow-up"), color = "purple"),
|
| 66 |
+
|
| 67 |
+
)))))
|
| 68 |
+
|
| 69 |
|
| 70 |
+
|
| 71 |
+
# Define server logic for application that fetches data from Open Alex
|
| 72 |
+
server <- function(input, output, session) {
|
| 73 |
+
|
| 74 |
+
# import nodes function
|
| 75 |
+
source("OpenAlexNodes.R")
|
| 76 |
+
|
| 77 |
+
# import edges display function
|
| 78 |
+
source("OpenAlexEdgesDisp.R")
|
| 79 |
+
|
| 80 |
+
# import edges function
|
| 81 |
+
source("OpenAlexEdges.R")
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# convert functions to a reactive objects
|
| 85 |
+
# searchEngine <- reactive({search_engine()})
|
| 86 |
+
|
| 87 |
+
# convert date inputs to a reactive object
|
| 88 |
+
fromReactive <- reactive({input$date})
|
| 89 |
+
toReactive <- reactive({input$date2})
|
| 90 |
+
|
| 91 |
+
# convert text input to a reactive object
|
| 92 |
+
textReactive <- reactive({input$text})
|
| 93 |
+
|
| 94 |
+
authorNodes <- reactive({authorPubNodes(
|
| 95 |
+
keywords = c(unlist(strsplit(textReactive(),split = ","))),
|
| 96 |
+
pub_start_date = fromReactive(),
|
| 97 |
+
pub_end_date = toReactive()
|
| 98 |
+
)})
|
| 99 |
+
authorEdgesDisp <- reactive({authorPubEdgesDisp(
|
| 100 |
+
keywords = c(unlist(strsplit(textReactive(),split = ","))),
|
| 101 |
+
pub_start_date = fromReactive(),
|
| 102 |
+
pub_end_date = toReactive()
|
| 103 |
+
)})
|
| 104 |
+
authorEdges <- reactive({authorPubEdges(
|
| 105 |
+
keywords = c(unlist(strsplit(textReactive(),split = ","))),
|
| 106 |
+
pub_start_date = fromReactive(),
|
| 107 |
+
pub_end_date = toReactive()
|
| 108 |
+
)})
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# # run the search engine
|
| 112 |
+
# searchReact <- eventReactive(input$search,{
|
| 113 |
+
# searchEngine(keywords = textReactive(),
|
| 114 |
+
# pub_start_date = fromReactive(),
|
| 115 |
+
# pub_end_date = toReactive())
|
| 116 |
+
#
|
| 117 |
+
# })
|
| 118 |
+
|
| 119 |
+
# pass search output to nodes and edges
|
| 120 |
+
nodes_df <- eventReactive(input$search,{
|
| 121 |
+
authorNodes()
|
| 122 |
+
})
|
| 123 |
|
| 124 |
+
edges_df <- eventReactive(input$search,{
|
| 125 |
+
authorEdges()
|
| 126 |
+
})
|
| 127 |
|
| 128 |
+
edges_disp <- eventReactive(input$search,{
|
| 129 |
+
authorEdgesDisp()
|
| 130 |
+
})
|
| 131 |
|
|
|
|
| 132 |
|
| 133 |
+
# render data as a reactable output
|
| 134 |
+
output$table <- renderReactable({
|
| 135 |
+
|
| 136 |
+
tryCatch(
|
| 137 |
+
{
|
| 138 |
+
reactable(edges_disp(),
|
| 139 |
+
theme = reactableTheme(highlightColor = "#b615e7",
|
| 140 |
+
borderColor = "#670e94",
|
| 141 |
+
borderWidth = 3),
|
| 142 |
+
bordered = T,
|
| 143 |
+
compact = T,
|
| 144 |
+
striped = T,
|
| 145 |
+
highlight = T,
|
| 146 |
+
searchable = T,
|
| 147 |
+
filterable = T)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
},
|
| 151 |
|
| 152 |
+
error = function(e){
|
| 153 |
+
message("An error occurred!")
|
| 154 |
+
print(e)
|
| 155 |
+
}
|
| 156 |
+
)
|
|
|
|
|
|
|
| 157 |
})
|
| 158 |
|
| 159 |
+
# activate download buttons
|
| 160 |
+
output$down_nodes <- downloadHandler(
|
| 161 |
+
filename = function(){
|
| 162 |
+
paste("Node",".csv",sep = "")
|
| 163 |
+
},
|
| 164 |
+
content = function(file){
|
| 165 |
+
write.csv(nodes_df(),file,row.names = F)
|
| 166 |
+
}
|
| 167 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
+
output$down_edges <- downloadHandler(
|
| 170 |
filename = function(){
|
| 171 |
+
paste("Edge",".csv",sep = "")
|
| 172 |
},
|
| 173 |
content = function(file){
|
| 174 |
+
write.csv(edges_df(),file,row.names = F)
|
|
|
|
|
|
|
| 175 |
}
|
| 176 |
)
|
| 177 |
+
|
| 178 |
+
# create shiny alert
|
| 179 |
+
observeEvent(input$info,{
|
| 180 |
+
shinyalert(
|
| 181 |
+
text = "Please note that the bigger the search window,
|
| 182 |
+
the more data is collected. The more data is collected,
|
| 183 |
+
the longer the runtime and the longer it takes to commence file download.",
|
| 184 |
+
title = "Info",
|
| 185 |
+
closeOnEsc = TRUE,
|
| 186 |
+
closeOnClickOutside = TRUE,
|
| 187 |
+
confirmButtonText = "OK",
|
| 188 |
+
confirmButtonCol = "#9f0be4",
|
| 189 |
+
timer = 30000,
|
| 190 |
+
showCancelButton = TRUE,
|
| 191 |
+
showConfirmButton = TRUE,
|
| 192 |
+
animation = "slide-from-top",
|
| 193 |
+
imageUrl = "info3.png"
|
| 194 |
+
|
| 195 |
+
)
|
| 196 |
+
})
|
| 197 |
+
|
| 198 |
+
|
| 199 |
}
|
| 200 |
|
| 201 |
+
|
| 202 |
+
|
| 203 |
# Run the application
|
| 204 |
shinyApp(ui = ui, server = server)
|