Ifeanyi commited on
Commit
5f02390
1 Parent(s): e9e3678

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +575 -37
app.R CHANGED
@@ -1,51 +1,589 @@
1
  library(shiny)
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  library(bslib)
3
  library(dplyr)
4
- library(ggplot2)
5
-
6
- df <- readr::read_csv("penguins.csv")
7
- # Find subset of columns that are suitable for scatter plot
8
- df_num <- df |> select(where(is.numeric), -Year)
9
-
10
- ui <- page_fillable(theme = bs_theme(bootswatch = "minty"),
11
- layout_sidebar(fillable = TRUE,
12
- sidebar(
13
- varSelectInput("xvar", "X variable", df_num, selected = "Bill Length (mm)"),
14
- varSelectInput("yvar", "Y variable", df_num, selected = "Bill Depth (mm)"),
15
- checkboxGroupInput("species", "Filter by species",
16
- choices = unique(df$Species), selected = unique(df$Species)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  ),
18
- hr(), # Add a horizontal rule
19
- checkboxInput("by_species", "Show species", TRUE),
20
- checkboxInput("show_margins", "Show marginal plots", TRUE),
21
- checkboxInput("smooth", "Add smoother"),
22
- ),
23
- plotOutput("scatter")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  )
25
- )
26
 
 
 
27
  server <- function(input, output, session) {
28
- subsetted <- reactive({
29
- req(input$species)
30
- df |> filter(Species %in% input$species)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  })
 
32
 
33
- output$scatter <- renderPlot({
34
- p <- ggplot(subsetted(), aes(!!input$xvar, !!input$yvar)) + list(
35
- theme(legend.position = "bottom"),
36
- if (input$by_species) aes(color=Species),
37
- geom_point(),
38
- if (input$smooth) geom_smooth()
39
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- if (input$show_margins) {
42
- margin_type <- if (input$by_species) "density" else "histogram"
43
- p <- p |> ggExtra::ggMarginal(type = margin_type, margins = "both",
44
- size = 8, groupColour = input$by_species, groupFill = input$by_species)
 
 
 
 
45
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- p
48
- }, res = 100)
49
  }
50
 
51
- shinyApp(ui, server)
 
 
 
 
1
  library(shiny)
2
+ library(shinyalert)
3
+ library(shinythemes)
4
+ library(shinydisconnect)
5
+ library(shinycssloaders)
6
+ library(shinyWidgets)
7
+ library(shiny.telemetry)
8
+ library(spotifyr)
9
+ library(SpotifyNetwork)
10
+ library(spsComps)
11
+ library(searcher)
12
+ library(reactable)
13
+ library(visNetwork)
14
+ library(plotly)
15
  library(bslib)
16
  library(dplyr)
17
+ library(igraph)
18
+
19
+ # set global options
20
+ options(
21
+ shiny.browser = T,
22
+ spinner.color = "#16F529",
23
+ spinner.color.background = "#FFFFFF",
24
+ spinner.size = 2
25
+ )
26
+
27
+ # create theme
28
+ my_theme <- bs_theme(
29
+ bg = "#fdfefe",
30
+ fg = "black",
31
+ primary = "red",
32
+ base_font = font_google("Michroma"),
33
+ "font-size-base" = "0.75rem",
34
+ version = 5,
35
+ "navbar-bg" = "#16F529"
36
+ )
37
+
38
+ # initialize telemetry
39
+ telemetry <- Telemetry$new()
40
+
41
+
42
+ # define UI for application that gets Spotify network data
43
+ ui <- navbarPage(
44
+ title = strong("Spotify Data Importer"), id = "navbar",
45
+ # useShinyalert(),
46
+ windowTitle = "Spotify Data Importer",
47
+
48
+ # add telemetry javascript elements
49
+ header = use_telemetry(),
50
+
51
+ footer = h5(strong(tagList(h5(span("Spotify Data Importer for",style="color:green"), a("NodeXL", href = "https://www.nodexl.com/"))))),
52
+ theme = my_theme, collapsible = T, setBackgroundImage(src = "music.jpg"),
53
+ # add marquee visual element
54
+ tags$html(HTML("<marquee direction = right scrollamount = '12' style = 'color:green; font-size:17px;'><strong>Spotify Data Importer For <span style='color:red'>NodeXL</span></strong></marquee>"),
55
+ ),
56
+ # Add social media icons to navbar
57
+ tags$style(".navbar-nav.socialmedia { display: flex; justify-content: right; flex-direction:row; padding: 5px; font-size: 20px; }"),
58
+ tags$div(class = "navbar-nav socialmedia",
59
+ tags$a(href = "https://www.github.com/Ifeanyi55", target = "_blank", icon("github", lib = "font-awesome"))),
60
+
61
+ tabPanel(
62
+ id = "tabOne", value = "oneTab", title = strong("Home"), icon = icon("home"),
63
+ sidebarLayout(
64
+ sidebarPanel(
65
+ id = "side", width = 3, h4(strong("Credentials")), hr(),
66
+ textInput("client_id", strong("Enter Client ID")),
67
+ textInput("client_secret", strong("Enter Client SECRET")), br(),
68
+ actionButton("validate", strong("Authenticate"), icon = icon("caret-right")), br(),hr(),
69
+ textOutput("valout")
70
  ),
71
+ mainPanel(
72
+ id = "main", width = 8,
73
+ span(style = "color:blue;",h5(strong(p(id = "dateclock")))),br(),
74
+ h2(strong("Welcome to the NodeXL Spotify Data Importer!")),
75
+ p(h5(strong("Before you begin scraping data, you will need to complete the steps below:"))), hr(),
76
+ p(h5(strong(tagList("STEP 1: Go to", a("https://developer.spotify.com/dashboard/", href = "https://developer.spotify.com/dashboard/"), "and login with your credentials")))), br(),
77
+ p(h5(strong("STEP 2: Create an app, and give it a name and a description"))), br(),
78
+ p(h5(strong("STEP 3: Get the generated client ID and client Secret, and return here"))), br(),
79
+ p(h5(strong("STEP 4: Enter the client ID and client Secret in the 'Credentials' box"))), br(),
80
+ p(h5(strong("STEP 5: Click the 'Authenticate' button"))), br(),
81
+ p(h5(strong("STEP 6: Wait for the system to authenticate your credentials and print out a reference ID"))), br(),
82
+ p(h5(strong("Great! You can now proceed to scraping network data via the Spotify API."))),
83
+ actionButton("nextTab", strong("Proceed")), hr()
84
+ )
85
+ )
86
+ ),
87
+ tabPanel(
88
+ id = "tabA", value = "Atab", title = strong("Network Data"), icon = icon("table"),
89
+
90
+ # load and run the CSS script
91
+ includeCSS("style.css"),
92
+ # load and run the javascript script
93
+ includeScript("JSCode.js"),
94
+ sidebarLayout(
95
+ sidebarPanel(
96
+ width = 2, id = "sidebar",
97
+ actionButton("info", strong("Info"), icon = icon("info")), br(), br(), br(), tags$a(img(src = "spotify.png"), href = "https://open.spotify.com/"), br(), hr(),
98
+ textInput("id", strong("Enter Artist's Spotify Id")),
99
+ actionButton("run", strong("Related Data"), icon = icon("caret-right")),br(),hr(),br(),
100
+ h5(strong("Collaborators Data")),
101
+ actionButton("fetch", strong("Collab Data"), icon = icon("caret-right")),hr()
102
+ ),
103
+
104
+ mainPanel(
105
+ # go to top button
106
+ spsGoTop(id = "up",right = "3%",bottom = "10%",icon = icon("arrow-up",color = "green")),
107
+ textInput("search", span(strong("Search Box"),style = "color:white;"), placeholder = "Search Google", width = "150px"),actionButton("search_bttn", strong("Search")),hr(),
108
+ fluidRow(column(12, h3(strong(span(style = "color:white;text-align:center;",h4("Related Artists Network Data")))))),
109
+ fluidRow(
110
+ column(12, withSpinner(reactableOutput("network_data",width = 1000,height = 400), type = 1)),
111
+ ),
112
+ fluidRow(
113
+ column(6, downloadButton("down_csv", strong("Download CSV"), icon = icon("download"))),
114
+ column(6, downloadButton("down_graphml", strong("Download GraphML"), icon = icon("download")))
115
+ ),br(),br(),br(),
116
+ fluidRow(column(12, h3(strong(span(style = "color:white;text-align:center;",h4("Artists Collaboration Network Data")))))),
117
+ fluidRow(
118
+ column(12,withSpinner(reactableOutput("collabs_data", width = 1000, height = 400),type = 1))
119
+ ),
120
+ downloadButton("down_flat",strong("Download CSV"),icon = icon("download")),
121
+ br(), hr(), uiOutput("out")
122
+ )
123
+ )
124
+ ),
125
+ tabPanel(
126
+ id = "tabB", value = "Btab", title = strong("80s Hits"), icon = icon("music"),
127
+ sidebarLayout(sidebarPanel = "", mainPanel(tags$iframe(
128
+ style = "border-radius:12px",
129
+ src = "https://open.spotify.com/embed/playlist/37i9dQZF1DXb57FjYWz00c?utm_source=generator",
130
+ width = "1350px",
131
+ height = "550px",
132
+ frameBorder = "0",
133
+ allowfullscreen = "",
134
+ allow = "autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture",
135
+ loading = "lazy"
136
+ )))
137
+ ),
138
+ tabPanel(
139
+ id = "tabD", strong("NodeXL YouTube"), icon = icon("youtube"),
140
+ sidebarLayout(sidebarPanel(id = ""), mainPanel(
141
+ tags$iframe(
142
+ width = "620",
143
+ height = "350",
144
+ src = "https://www.youtube.com/embed/xKhYGRpbwOc",
145
+ title = "YouTube video player",
146
+ frameborder = "0",
147
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
148
+ allowfullscreen = T
149
+ ), hr(),
150
+ tags$iframe(
151
+ width = "620",
152
+ height = "350",
153
+ src = "https://www.youtube.com/embed/Gs4NPuKIXdo",
154
+ title = "YouTube video player",
155
+ frameborder = "0",
156
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
157
+ allowfullscreen = T
158
+ ), hr(),
159
+ tags$iframe(
160
+ width = "620",
161
+ height = "350",
162
+ src = "https://www.youtube.com/embed/J1W5uqAyHTg",
163
+ title = "YouTube video player",
164
+ frameborder = "0",
165
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
166
+ allowfullscreen = T
167
+ ), hr(),
168
+ tags$iframe(
169
+ width = "620",
170
+ height = "350",
171
+ src = "https://www.youtube.com/embed/zEgrruOITHw",
172
+ title = "YouTube video player",
173
+ frameborder = "0",
174
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
175
+ allowfullscreen = T
176
+ ), hr(),
177
+ tags$iframe(
178
+ width = "620",
179
+ height = "350",
180
+ src = "https://www.youtube.com/embed/pwsImFyc0lE",
181
+ title = "YouTube video player",
182
+ frameborder = "0",
183
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
184
+ allowfullscreen = T
185
+ ), hr(),
186
+ tags$iframe(
187
+ width = "620",
188
+ height = "350",
189
+ src = "https://www.youtube.com/embed/mjAq8eA7uOM",
190
+ title = "YouTube video player",
191
+ frameborder = "0",
192
+ allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
193
+ allowfullscreen = T
194
+ )
195
+ ))
196
+ )
197
  )
 
198
 
199
+
200
+ # define server logic required to get Spotify's network data
201
  server <- function(input, output, session) {
202
+ # track events
203
+ telemetry$start_session()
204
+
205
+ # set up Spotify API credentials environment
206
+ authentication <- function(id, secret) {
207
+ client_ID <- id
208
+ client_secret <- secret
209
+
210
+ # authenticate the spotify client side
211
+ Sys.setenv(SPOTIFY_CLIENT_ID = client_ID)
212
+ Sys.setenv(SPOTIFY_CLIENT_SECRET = client_secret)
213
+
214
+ access_token <- get_spotify_access_token()
215
+ }
216
+
217
+ client_id <- reactive(as.character(input$client_id))
218
+ client_secret <- reactive(as.character(input$client_secret))
219
+ authenticate <- reactive(authentication(
220
+ client_id(),
221
+ client_secret()
222
+ ))
223
+ validation <- eventReactive(input$validate, {
224
+ authenticate()
225
+ })
226
+
227
+ output$valout <- renderText({
228
+ validation()
229
+ })
230
+
231
+ # update nav bar page using the value of the tabPanel
232
+ # (i.e. value = "Atab")
233
+ observeEvent(input$nextTab, {
234
+ updateNavbarPage(session, inputId = "navbar", selected = "Atab")
235
  })
236
+
237
 
238
+
239
+ # activate the search box
240
+ search_input <- reactive(input$search)
241
+
242
+ searchGoogle <- reactive(search_google(search_input(), rlang = F))
243
+
244
+ search_result <- eventReactive(input$search_bttn, {
245
+ searchGoogle()
246
+ })
247
+
248
+ output$out <- renderUI({
249
+ search_result()
250
+ })
251
+
252
+ # render spotify
253
+ # renderUI({
254
+ # tags$iframe(src = "https://open.spotify.com/")
255
+ # })
256
+
257
+
258
+ # turn text input into a reactive object
259
+ id_input <- reactive({
260
+ as.character(input$id)
261
+ })
262
+
263
+ # wrap SpotifyNetwork functions in reactive wrappers
264
+ # related_network <- reactive({
265
+ # related_artists_network(id_input())
266
+ # })
267
+ # artist_plot <- reactive({
268
+ # artists_popularity(id_input())
269
+ # })
270
+ nodes_table <- reactive({
271
+ related_artists_nodes(id_input())
272
+ })
273
+ edges_table <- reactive({
274
+ related_artists_edges(id_input())
275
+ })
276
+
277
+ # create event reactive element for each output
278
+ # network_react <- eventReactive(input$run, {
279
+ # related_network()
280
+ # })
281
+ # artist_react <- eventReactive(input$run, {
282
+ # artist_plot()
283
+ # })
284
+ nodes_react <- eventReactive(input$run, {
285
+ nodes_table()
286
+ })
287
+ edges_react <- eventReactive(input$run, {
288
+ edges_table()
289
+ })
290
+
291
+ # function to wrangle nodes & edges data into a NodeXL flat file
292
+ create_flatTabler <- function(dfN,dfE){
293
+
294
+
295
+ # scrape data from Vertex1
296
+ # as.vector(data,mode) converts the returned list into a vector
297
+ popularity <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex1"]])[[3]])
298
+ popularity <- as.vector(popularity,"numeric")
299
+
300
+
301
+ followers <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex1"]])[[4]])
302
+ followers <- as.vector(followers,"numeric")
303
+
304
+
305
+ profile <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex1"]])[[5]])
306
+ profile <- as.vector(profile,"character")
307
+
308
+
309
+ images <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex1"]])[[6]])
310
+ images <- as.vector(images,"character")
311
+
312
+
313
+ genre <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex1"]])[[7]])
314
+ genre <- as.vector(genre,"character")
315
+
316
+
317
+ # scrape data from Vertex2
318
+ # as.vector(data,mode) converts the returned list into a vector
319
+ popularityB <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex2"]])[[3]])
320
+ popularityB <- as.vector(popularityB,"numeric")
321
+
322
+
323
+ followersB <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex2"]])[[4]])
324
+ followersB <- as.vector(followersB,"numeric")
325
+
326
+
327
+ profileB <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex2"]])[[5]])
328
+ profileB <- as.vector(profileB,"character")
329
+
330
+
331
+ imagesB <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex2"]])[[6]])
332
+ imagesB <- as.vector(imagesB,"character")
333
+
334
+
335
+ genreB <- apply(dfE,1,function(df) subset(dfN,dfN$name == df[["Vertex2"]])[[7]])
336
+ genreB <- as.vector(genreB,"character")
337
+
338
+
339
+ # assign scraped data for Vertex1 to new columns
340
+ dfE$`Vertex1 popularity` <- popularity
341
+ dfE$`Vertex1 followers` <- followers
342
+ dfE$`Vertex1 profile` <- profile
343
+ dfE$`Vertex1 images` <- images
344
+ dfE$`Vertex1 genre` <- genre
345
+
346
+ # assign scraped data for Vertex2 to new columns
347
+ dfE$`Vertex2 popularity` <- popularityB
348
+ dfE$`Vertex2 followers` <- followersB
349
+ dfE$`Vertex2 profile` <- profileB
350
+ dfE$`Vertex2 images` <- imagesB
351
+ dfE$`Vertex2 genre` <- genreB
352
+
353
+ dfE$`Edge Weight` <- round(dfE$`Vertex1 popularity`/dfE$`Vertex2 popularity`,2)
354
+
355
+ dfE <- dfE |> relocate(`Edge Weight`,.after = Vertex2)
356
+
357
+ return(dfE)
358
+
359
+
360
+ }
361
+
362
+
363
+ # parse edges_react to function
364
+ flat_file <- reactive({create_flatTabler(nodes_react(),edges_react())})
365
+
366
+ # add edge metadata
367
+ # flat_file()["Edge Weight"] <- reactive({round(flat_file()$`Vertex1 popularity`/flat_file()$`Vertex2 popularity`,2)})
368
+ #
369
+ # flat_file() <- flat_file() |>
370
+ # reactive({relocate(`Edge Weight`,.after = Vertex2)})
371
+
372
+ # create flat file event reactive object
373
+ flat_react <- eventReactive(input$run,{
374
+ flat_file()
375
+ })
376
+
377
+ # # render outputs
378
+ # output$network <- renderVisNetwork({
379
+ # network_react()
380
+ # })
381
+ #
382
+ # output$plot <- renderPlotly({
383
+ # artist_react()
384
+ # })
385
+
386
+ # function to download nodes data file
387
+ output$down_csv <- downloadHandler(
388
+ filename = function() {
389
+ paste("Related_artists", ".csv", sep = "")
390
+ },
391
+ content = function(file) {
392
+ write.csv(flat_react(), file)
393
+ }
394
+ )
395
+
396
+ output$network_data <- renderReactable({
397
+
398
+ tryCatch(
399
+ {
400
+ reactable(flat_react(),
401
+ theme = reactableTheme(
402
+ highlightColor = "#00e600",
403
+ borderColor = "#00e600",
404
+ borderWidth = 3
405
+ ),
406
+ outlined = T,
407
+ bordered = T,
408
+ filterable = T,
409
+ striped = T,
410
+ compact = T,
411
+ highlight = T,
412
+ defaultColDef = colDef(
413
+ align = "center",
414
+ headerStyle = list(background = "#00e600")
415
+ ),
416
+ paginationType = "simple"
417
+ )
418
+
419
+ },
420
+ error = function(e){
421
+ message("There was an error!")
422
+ print(e)
423
+ }
424
+ )
425
+ })
426
+
427
+ # function to generate GraphML file
428
+ create_graphml <- function(nodes,edges){
429
+
430
+ # create new graph object
431
+ graph <- graph_from_data_frame(edges)
432
+
433
+
434
+ # add attributes to graph nodes
435
+ {
436
+ V(graph)$Name <- nodes$name
437
+ V(graph)$Popularity <- nodes$popularity
438
+ V(graph)$Followers <- nodes$followers
439
+ V(graph)$Profile <- nodes$profile
440
+ V(graph)$Images <- nodes$images
441
+ V(graph)$Genre <- nodes$genre
442
+ }
443
+
444
+ return(graph)
445
+
446
+ }
447
+
448
+ # make function reactive
449
+ graphml_react <- reactive({
450
+ create_graphml(nodes_react(),
451
+ edges_react())})
452
+
453
+ # make function event reactive so that it is triggered
454
+ # by run action button
455
+ graphmlReact <- eventReactive(input$run,{
456
+ graphml_react()
457
+ })
458
 
459
+
460
+ # write GraphML download function
461
+ output$down_graphml <- downloadHandler(
462
+ filename = function(){
463
+ paste("Related_artists",".graphml",sep = "")
464
+ },
465
+ content = function(file){
466
+ write_graph(graphmlReact(),file,format = "graphml")
467
  }
468
+ )
469
+
470
+ # import get_artists_collaborators() function
471
+ source("Collaborators.R")
472
+
473
+ # wrap in reactive wrappers
474
+ artists_collaborations <- reactive({get_artists_collaborators(id_input())})
475
+
476
+ # make event reactive
477
+ collabs_react <- eventReactive(input$fetch,{artists_collaborations()})
478
+
479
+ output$collabs_data <- renderReactable({
480
+ tryCatch(
481
+ {
482
+ reactable(collabs_react(),
483
+ theme = reactableTheme(
484
+ highlightColor = "#3498DA",
485
+ borderColor = "#3498DA",
486
+ borderWidth = 3
487
+ ),
488
+ outlined = T,
489
+ bordered = T,
490
+ filterable = T,
491
+ striped = T,
492
+ compact = T,
493
+ highlight = T,
494
+ defaultColDef = colDef(
495
+ align = "center",
496
+ headerStyle = list(background = "#3498DA")
497
+ ),
498
+ paginationType = "simple"
499
+ )
500
+ },
501
+ error = function(e){
502
+ message("There was an error!")
503
+ print(e)
504
+ }
505
+ )
506
+ })
507
+
508
+ # activate download button
509
+ output$down_flat <- downloadHandler(
510
+ filename = function(){
511
+ paste("CollabData",".csv",sep = "")
512
+ },
513
+ content = function(file){
514
+ write.csv(collabs_react(),file)
515
+ }
516
+ )
517
+
518
+ # function to download edges data file
519
+ # output$down_edges <- downloadHandler(
520
+ # filename = function() {
521
+ # paste("Edges", ".csv", sep = "")
522
+ # },
523
+ # content = function(file) {
524
+ # write.csv(edges_react(), file)
525
+ # }
526
+ # )
527
+
528
+
529
+ # output$edges <- renderReactable({
530
+ # reactable(edges_react(),
531
+ # theme = reactableTheme(
532
+ # highlightColor = "#00FFAB",
533
+ # borderColor = "#00FFAB"
534
+ # ),
535
+ # outlined = T,
536
+ # bordered = T,
537
+ # filterable = T,
538
+ # striped = T,
539
+ # compact = T,
540
+ # highlight = T,
541
+ # defaultColDef = colDef(
542
+ # align = "center",
543
+ # headerStyle = list(background = "#00FFAB")
544
+ # ),
545
+ # paginationType = "simple"
546
+ # )
547
+ # })
548
+
549
+ observeEvent(input$info, {
550
+ shinyalert(
551
+ title = "About Software", closeOnEsc = T, confirmButtonCol = "#006400",
552
+ imageUrl = "spotify.png",
553
+ closeOnClickOutside = T,
554
+ confirmButtonText = "Got It", showConfirmButton = T,
555
+ animation = "pop", timer = 20000,
556
+ text = "The Spotify Data Importer allows a user to
557
+ query the Spotify API and get network data
558
+ of artists that are related to a particular artist. You can also get data of artists that have collaborated together.
559
+
560
+ It typically takes between 16 and 20
561
+ seconds to get a response from the Spotify server for related
562
+ artists network data and more than that for artists collaboration
563
+ network data."
564
+ )
565
+ })
566
+
567
+
568
+ observeEvent(input$fetch,{
569
+ shinyalert(
570
+ closeOnEsc = T,
571
+ confirmButtonText = "Got It!",
572
+ confirmButtonCol = "#3498DA",
573
+ closeOnClickOutside = T,
574
+ showConfirmButton = T,
575
+ animation = "slide-from-top",
576
+ cancelButtonText = T,
577
+ timer = 10000,
578
+ text = "This may take a while to run, sorry!"
579
+
580
+ )
581
+ })
582
 
583
+
 
584
  }
585
 
586
+
587
+
588
+ # Run the application
589
+ shinyApp(ui = ui, server = server)