Related
I am trying to plot a dygraph in my Shiny App but I can't seem to get the output working. I would like to do it using modules.
Comprar = purchase and Alquiler = Rental.
I randomly create some price data and some dates
Generate some summary statistics for the average price and number of observations in the data comprar_stats and alquiler_stats
I store some metrics in a list that I would like to call throughout the App.
Then in ui_dygraph I try to generate the dropdown module for each option on my data comprar_main, alquiler_main and price_to_rent. I am able to generate a dropdown but not an output of the dygraph...
How I can I obtain the output of the dygraph? - This code is a mix of some Shiny code I took from the Appsilon "Enterprice Shiny" App - I would like to try and modularise my Apps.
Expected Output: Obtain the dygraph outputs depending on the dropdown.
Shiny App:
library(bslib)
library(shiny)
library(tidyverse)
library(dygraphs)
library(zoo)
################################################################################
startDate <- as.Date("2023-01-01")
endDate <- as.Date("2023-06-01")
dates <- rep(dates, each = 10)
propertyPrices <- round(rnorm(length(dates), mean = 100000, sd = 20000), 2)
comprar_main <- data.frame(collectionDate = dates, price = propertyPrices)
propertyRentals <- round(rnorm(length(dates), mean = 1000, sd = 200), 2)
alquiler_main <- data.frame(collectionDate = dates, price = propertyRentals)
################################################################################
################################################################################
comprar_stats = comprar_main %>%
filter(collectionDate > as.Date("2022-09-27")) %>% # accidently have rental data before this date
filter(price < 1000000) %>%
filter(price > 100000) %>%
group_by(collectionDate) %>%
summarise(
mean_price = mean(price),
mean_price = round(mean_price, 0),
propertiesListed = n()
) %>%
ungroup() %>%
mutate(
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0)
) %>%
add_column(
type = "comprar_main"
)
alquiler_stats = alquiler_main %>%
filter(collectionDate > as.Date("2022-09-27")) %>%
filter(price < 2500) %>%
filter(price > 200) %>%
group_by(collectionDate) %>%
summarise(
mean_price = mean(price),
mean_price = round(mean_price, 0),
propertiesListed = n()
) %>%
ungroup() %>%
mutate(
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0)
) %>%
add_column(
type = "alquiler_main"
)
stats = bind_rows(comprar_stats, alquiler_stats)
stats_price_to_rent = full_join(comprar_stats, alquiler_stats, by = "collectionDate") %>%
mutate(
mean_price = mean_price.x / (mean_price.y * 12), # annualise the rent
mean_price = round(mean_price),
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0),
propertiesListed = propertiesListed.y / propertiesListed.x,
propertiesListed = round(propertiesListed, 2)
) %>%
add_column(type = "price_to_rent_main") %>%
select(c(collectionDate, mean_price, propertiesListed, rolling_average, type))
################################################################################
metrics_list <- list(
comprar_main = list(
id = "comprar_main",
title = "Comprar (All Spain)",
currency = "€",
category = "comprar",
legend = "Purchase Spain",
legend2 = "# of properties"
),
alquiler_main = list(
id = "alquiler_main",
title = "Alquiler (All Spain)",
currency = "€",
category = "alquiler",
legend = "Rental Spain",
legend2 = "# of properties"
),
price_to_rent_main = list(
id = "price_to_rent_main",
title = "Price to Rent (All Spain)",
currency = "€",
category = "misc",
legend = "Price To Rent",
legend2 = "# of rentals / # of purchases",
caption = "Some info here"
)
)
################################################################################
################################################################################
########################### User interfaces ####################################
ui_dygraph <- function(id) {
ns <- NS(id)
# Add all available metrics to dygraph chart
choices <- names(metrics_list)
tagList(
tags$div(
class = "panel-header",
selectInput(
ns("metric"), "Select metric for the time chart",
choices,
width = NULL,
selectize = TRUE,
selected = choices[[1]]
)
),
tags$div(
class = "chart-time-container",
dygraphOutput(ns("dygraph"), height = "240px")
)
)
}
################################################################################
ui <- navbarPage(
fluidPage(
theme = bs_theme(bootswatch = "minty"),
title = "hi",
ui_dygraph("dygraph"),
renderUI(output$dygraph)
)
)
server <- function(input, output, session, df) {
metric <- reactive({ metrics_list[[input$metric]] })
output$dygraph <- renderDygraph({
data = df
metric_suffix <- ifelse(!is.null(metric()$currency), glue::glue(" ({metric()$currency})"), "")
metric_legend <- paste0(metric()$legend, metric_suffix)
metric_legend2 <- paste0(metric()$legend2)
if(metric()$id == "comprar_main") {
dyAxisValueRange = c(220000, 310000)
dy2AxisValueRange = c(0, 15000)
} else if (metric()$id == "alquiler_main") {
dyAxisValueRange = c(0, 2700)
dy2AxisValueRange = c(0, 4000)
} else { # price_to_rent_main axis
dyAxisValueRange = c(15, 35)
dy2AxisValueRange = c(0, 3.5)
}
if (metric()$id == "comprar_main") {
data = stats
} else if (metric()$id == "alquiler_main") {
data = stats
} else {
data = stats_price_to_rent
}
data %>%
filter(type == metric()$id) %>%
select(-c(type)) %>%
column_to_rownames("collectionDate") %>%
as.xts() %>%
# as.xts(order.by = .$collectionDate)
dygraph(main = glue::glue("{metric()$title}")) %>%
dySeries("mean_price", label = metric_legend, drawPoints = FALSE, color = "#0099F9") %>%
dySeries("rolling_average", label = "Rolling Average (14 days)", drawPoints = FALSE, color = "#15354A") %>%
dyAxis("y", label = "Price", valueRange = dyAxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dyAxis("y2", label = metric_legend2, valueRange = dy2AxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dySeries("propertiesListed", label = metric_legend2, stepPlot = TRUE, fillGraph = TRUE, color = "#bdc2c6", axis=('y2')) %>%
dyOptions(
includeZero = FALSE,
axisLineColor = "#585858",
gridLineColor = "#bdc2c6",
axisLabelFontSize = 12,
axisLabelColor = "#585858",
disableZoom = TRUE
)
})
}
shinyApp(ui = ui, server = server)
As mentioned by #YBS in the comments the issue is that your digraph module misses a moduleServer. Moving you code from the main server to a module server will fix your issue:
library(xts)
library(bslib)
library(shiny)
library(tidyverse)
library(dygraphs)
ui_dygraph <- function(id) {
ns <- NS(id)
choices <- names(metrics_list)
tagList(
tags$div(
class = "panel-header",
selectInput(
ns("metric"), "Select metric for the time chart",
choices,
width = NULL,
selectize = TRUE,
selected = choices[[1]]
)
),
tags$div(
class = "chart-time-container",
dygraphOutput(ns("dygraph"), height = "240px")
)
)
}
server_dygraph <- function(id) {
moduleServer(id, function(input, output, session) {
metric <- reactive({
metrics_list[[input$metric]]
})
output$dygraph <- renderDygraph({
data <- df
metric_suffix <- ifelse(!is.null(metric()$currency), glue::glue(" ({metric()$currency})"), "")
metric_legend <- paste0(metric()$legend, metric_suffix)
metric_legend2 <- paste0(metric()$legend2)
if (metric()$id == "comprar_main") {
dyAxisValueRange <- c(220000, 310000)
dy2AxisValueRange <- c(0, 15000)
} else if (metric()$id == "alquiler_main") {
dyAxisValueRange <- c(0, 2700)
dy2AxisValueRange <- c(0, 4000)
} else {
dyAxisValueRange <- c(15, 35)
dy2AxisValueRange <- c(0, 3.5)
}
if (metric()$id == "comprar_main") {
data <- stats
} else if (metric()$id == "alquiler_main") {
data <- stats
} else {
data <- stats_price_to_rent
}
data %>%
filter(type == metric()$id) %>%
select(-c(type)) %>%
column_to_rownames("collectionDate") %>%
as.xts() %>%
dygraph(main = glue::glue("{metric()$title}")) %>%
dySeries("mean_price", label = metric_legend, drawPoints = FALSE, color = "#0099F9") %>%
dySeries("rolling_average", label = "Rolling Average (14 days)", drawPoints = FALSE, color = "#15354A") %>%
dyAxis("y",
label = "Price", valueRange = dyAxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dyAxis("y2",
label = metric_legend2, valueRange = dy2AxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dySeries("propertiesListed", label = metric_legend2, stepPlot = TRUE, fillGraph = TRUE, color = "#bdc2c6", axis = ("y2")) %>%
dyOptions(
includeZero = FALSE,
axisLineColor = "#585858",
gridLineColor = "#bdc2c6",
axisLabelFontSize = 12,
axisLabelColor = "#585858",
disableZoom = TRUE
)
})
})
}
ui <- navbarPage(
fluidPage(
theme = bs_theme(bootswatch = "minty"),
title = "hi",
ui_dygraph("dygraph")
)
)
server <- function(input, output, session, df) {
server_dygraph("dygraph")
}
shinyApp(ui = ui, server = server)
I am new to shiny and trying to change chart variable based on toggle switch input but getting error.
I have used the toggleid inside the observe({}) but not sure if that's how it is done.
Based on condition I have stored the required variable name in Case_selected which I have tried to use with !!Case_selected to get the variable name out from it.
ui code:
fluidRow(
style = "border: 1px solid gray;",
h3("Top Countries with Confirmed Cases"),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmedtotal",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_total", height = "650px")),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmeddaily",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_daily", height = "650px")),
column(6,
h4("Latest 1 week Top Countries by Daily Confirmed Cases"),
plotOutput("lastweek_confirmed_daily", height = "650px")
)
),
server code:
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (is.null(x))
Case_selected <- "Confirmed"
else
Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = !! Case_selected, n = 10) %>% # Confirmed
ggplot(aes( x = !! Case_selected, y = reorder(Country.Region, !! Case_selected),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
#scale_fill_tableau(palette = "Tableau 20")
})
Error: object 'Case_selected' not found
I have also tried with !! rlang::sym() but not sure why none of this is working.
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = !! rlang::sym(Case_selected) , n = 10) %>% # Confirmed
ggplot(aes( x = !! rlang::sym(Case_selected), y = reorder(Country.Region, !! rlang::sym(Case_selected)),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
Original Code that works without using any variable toggle option:
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = Confirmed, n = 10) %>%
ggplot(aes( x = Confirmed, y = reorder(Country.Region, Confirmed),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
#scale_fill_tableau(palette = "Tableau 20")
})
Update ts_all_long
Update for reproduce able example:
library(tidyverse)
library(lubridate)
file_url1 <- "https://raw.githubusercontent.com/johnsnow09/covid19-df_stack-code/main/ts_all_long4.csv"
ts_all_long <- read.csv(url(file_url1))
ts_all_long <- ts_all_long %>%
mutate(date = as.Date(date))
ui.R
library(shiny)
library(shinydashboard)
library(shinythemes)
library(shinyWidgets)
library(highcharter)
shinyUI(fluidPage(
theme=shinytheme("lumen"),
themeSelector(),
navbarPage(
title = "Covid19 Dashboard",
id = "Covid19_Dashboard",
tabPanel("By Confirmed Cases",
# Application title
titlePanel("Global level"),
# fluidRow(h5("(this Page may take some time, kindly wait to load!!)",
# col = "gray30", align = "center")),
fluidRow(
style = "border: 1px solid gray;",
h3("Top Countries with Confirmed Cases"),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmedtotal",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_total", height = "650px")
)
)
)))
server.R
library(shiny)
library(tidyverse)
library(ggthemes)
library(covid19.analytics)
library(tidytext)
library(scales)
library(lubridate)
library(glue)
library(highcharter)
library(shinyWidgets)
shinyServer(function(input, output) {
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (is.null(x))
Case_selected <- "Confirmed"
else
Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = .data[[Case_selected]], n = 10) %>% # Confirmed
ggplot(aes( x = .data[[Case_selected]],
y = reorder(Country.Region, .data[[Case_selected]]),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
})
You need to define Case_selected as reactive so that you can use it throughout the app. Also use .data to refer to column name.
shinyServer(function(input, output) {
rv <- reactiveValues()
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (!x) rv$Case_selected <- "Confirmed"
else rv$Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = .data[[rv$Case_selected]], n = 10) %>% # Confirmed
ggplot(aes( x = .data[[rv$Case_selected]],
y = reorder(Country.Region, .data[[rv$Case_selected]]),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
})
I've just created my first Shiny app and published to the Internet - https://craycrayjodie.shinyapps.io/MapApp/
When launching the app and viewing in Chrome and I.E the default page ('Map' tab) loads as expected - with the "March" data displayed on the map. This is specified in the sliderTextInput for the page.
However, when I load the app and view in Firefox (i.e. the 'Map' tab), the "March" data is not displayed on the map when the app loads by default in Firefox. I need to move the sliderTextInput, then the data loads on the map in the Browser.
This is only an issue for Firefox, the other browsers (i.e. Chrome and IE) are fine and have the March data loaded and displayed on the map when the default 'Map' page loads.
I have published my files up to GitHub - https://github.com/craycrayjodie/DataVis
Also, my app.R logic is as follows:
library(dplyr)
library(lubridate)
library(sf)
library(leaflet)
library(shinythemes)
library(RColorBrewer)
library(shinyWidgets)
library(rmapshaper)
library(rsconnect)
library(shiny)
library(ggplot2)
library(highcharter)
library(magrittr)
library(htmlwidgets)
library(RColorBrewer)
library(shinycssloaders)
###################################################################################################
myAusdata_by_month_sf = readRDS("myAusdata_by_month.rds") #load previously saved datafile
myAusdata_by_month_5 = readRDS("myAusdata_by_month_5.rds") #load previously saved datafile
areas_by_weeks = readRDS("areas_by_weeks.rds") #load previously saved datafile
# Options for Spinner
options(spinner.color="pink", spinner.type = 7, spinner.color.background="#ffffff", spinner.size=1)
ui <- shinyUI(
navbarPage(
title = "Australians Mobility Changes During COVID",
theme = shinytheme("yeti"),
tabPanel("Map",
div(class = "outer",
tags$head(
includeCSS("styles.css")
),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 30, left = 250, draggable = TRUE,
# slider title, step increments
sliderTextInput("choices", "Select month:", choices = unique(myAusdata_by_month_sf$month),
animate = animationOptions(interval = 1500, loop = FALSE), grid = TRUE, selected = "March", width = 400))
),
tags$div(id = "cite",
'Data downloaded from Facebook for Good by Jodie Anderson (2020).'
)
),
tabPanel("Story",
highchartOutput("timeline", height = "800px" ) %>% withSpinner(),
includeMarkdown("analysis.md"),
br()
),
tabPanel("Heatmap",
highchartOutput("heatmap", height = "100%") %>% withSpinner(),
br()
),
tabPanel("About",
includeMarkdown("about.md"),
br()
)
)
)
# Define server logic
server <- function(input, output, session) {
filteredData <- reactive({
myAusdata_by_month_sf %>%
filter(month %in% input$choices)
})
popup <- reactive({
sprintf("%s: %.1f%%", filteredData()$polygon_name, filteredData()$AvRelChange*100)
})
output$map <- renderLeaflet({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leaflet(myAusdata_by_month_sf) %>%
setView(134, -29, 4) %>%
addProviderTiles("Esri.WorldGrayCanvas") %>%
addLegend(pal=mypalette, values=~AvRelChange, opacity=1, title = "Mobility Change (%)", position = "bottomleft",
labFormat = labelFormat(prefix = "(", suffix = ")", between = ", ",
transform = function(x) 100 * x))
})
observe({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leafletProxy("map", data = filteredData()) %>%
clearShapes() %>%
addPolygons(fillColor = ~mypalette(AvRelChange),
stroke=TRUE,
fillOpacity = 1,
color = "grey",
weight = 0.3,
label = popup(), labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "2px 2px"),
textsize = "13px",
direction = "auto", offset = c(20, -25)))
})
output$timeline <- renderHighchart ({
hc <- myAusdata_by_month_5 %>%
hchart ('spline', hcaes(x= date, y=AvRelChange, group=NAME_1)) %>%
hc_colors(brewer.pal(8, "Dark2")) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"),
align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_xAxis(title = list(text=NULL), plotBands = list(list(label = list(text = "Australia<br>in<br>lockdown"), color = "rgba(100, 0, 0, 0.1)",from = datetime_to_timestamp(as.Date('2020-03-16', tz = 'UTC')),
to = datetime_to_timestamp(as.Date('2020-03-31', tz = 'UTC'))))) %>%
hc_yAxis(title=list(text = "Mobility Change (%)"), showLastLabel = FALSE, labels = list(format = "{value}%")) %>%
hc_caption(text = "The Change in Mobility metric looks at how much people are moving around and compares it to a baseline period that predates most social distancing measures.<br>
The baseline period for this dataset is the four weeks of February 2020 (i.e. from the 2nd to the 29th).", useHTML = TRUE)%>%
hc_credits(text = "www.highcharts.com", href = "www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_tooltip(crosshairs = TRUE, borderWidth = 2, valueSuffix = "%") %>%
hc_navigator(enabled = TRUE) %>%
hc_rangeSelector(enabled = TRUE) %>%
hc_plotOptions(series = list(marker = list(enabled = FALSE), lineWidth = 4)) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-13', tz = 'UTC')),y = 7),shape = "rect", text = "10th July: QLD opens borders", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-20', tz = 'UTC')),y = -22),shape = "rect", text = "30th June: Vic in lockdown", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-08-20', tz = 'UTC')),y = -30),shape = "rect", text = "2nd Aug: Vic restrictions ease", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-11-14', tz = 'UTC')),y = -41),shape = "rect", text = "16th Nov: SA restrictions in place<br>21st Nov: SA restrictions lifted", useHTML = TRUE)))
hc
})
output$heatmap <- renderHighchart ({
hc1 <- areas_by_weeks %>%
hchart(type = "heatmap", hcaes(x = date, y = polygon_name, value = AvRelChange)) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"), align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_boost(useGPUTranslations = TRUE) %>%
hc_size(height = 5000, width = 550) %>%
hc_colorAxis(labels = list(format = '{value}%'), stops = color_stops(10, rev(brewer.pal(10, "RdBu")))) %>%
hc_legend(itemMarginTop = 75, layout = "vertical", verticalAlign = "top", align = "right", valueDecimals = 0) %>%
hc_xAxis(labels = list(enabled = FALSE), tickInterval = 5, title = NULL, lineWidth = 0, tickLength = 20) %>%
hc_yAxis(title=list(text = ""), reversed = TRUE, gridLineWidth = 0) %>%
hc_tooltip(pointFormat = '{point.date} <br> {point.polygon_name}: <b>{point.value} %') %>%
hc_credits(position = list(align = 'center', x = 135, y = -4), text = "www.highcharts.com", href = "http://www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_caption(align = 'center', text = "The white coloured boxes in the heatmap represent gaps in data.", useHTML = TRUE)
hc1
})
}
# Run the application
shinyApp(ui = ui, server = server)
If a clever cookie can please advise on what changes I need to make to get the app working when the page loads with Firefox, that would be fabulous :)
Attempting to build off of Stack Exchange Question:
R Highcharter: tooltip customization
Have a R module (below). That ingests some data and provides the UI including highcharter visualizations.
consolidatedlogModuleUI <- function(id){
ns <- NS(id)
tagList(
fluidRow(
bs4Card(highchartOutput(ns("fundedbydayChart")),
width = 12,
collapsible = TRUE)
),
fluidRow(
bs4TabCard(title = "Consolidated Log",
elevation = 2,
width = 12,
bs4TabPanel(
tabName = "tab1",
active = TRUE,
DT::dataTableOutput(ns("consolidatedlogTable"))
),
bs4TabPanel(
tabName = "tab2",
active = FALSE,
DT::dataTableOutput(ns("daysummaryTable"))
)
)
)
)
}
#######
# Consolidated Log Server Module
#######
consolidatedlogModule <- function(input,output,session,data){
ns <- session$ns
data$HasGap <- ifelse(data$GAPGrossRevenue > 0, 1, 0)
data$HasESC <- ifelse(data$ESCGrossRevenue > 0, 1, 0)
consolidatedLogVariables <- c("AcctID", "FSR", "DocSentDate", "DocsToLenderDate",
"FundedDate", "HasGap", "HasESC", "LoanRevenue")
logSummary <- data %>%
group_by(FundedMonthGroup) %>%
summarise(TotalCount = n()
, TotalAmount = sum(LoanRevenue)
, TotalGAP = sum(HasGap)
, TotalESC = sum(HasESC))
daySummary <- data %>%
group_by(FundedDayGroup) %>%
summarise(TotalCount = n()
,TotalAmount = sum(LoanRevenue))
### Consolidated Log Table
output$consolidatedlogTable = DT::renderDataTable({
data[consolidatedLogVariables]
}, extensions = "Responsive", rownames = FALSE,
caption = "Current Consolidated Log",
filter = "bottom"
)
output$daysummaryTable = DT::renderDataTable({
daySummary
}, extensions = "Responsive", rownames = FALSE,
caption = "Current Consolidated Log",
filter = "bottom"
)
### Charts
#Fundedbyday Chart
output$fundedbydayChart = renderHighchart({
highchart() %>%
hc_add_theme(hc_theme_ffx()) %>%
hc_title(text = "Loans Funded By Day") %>%
hc_add_series(data = daySummary, mapping = hcaes(x=FundedDayGroup, y=TotalAmount), type = "column", name = "Daily Loan Revenue",
tooltip = list(pointFormat = "Daily Revenue ${point.TotalAmount} across {point.TotalCount} deals")) %>%
hc_tooltip(crosshairs = TRUE)
# highchart() %>%
# hc_add_theme(hc_theme_ffx()) %>%
# hc_title(text = "Loans Funded By Day") %>%
# hc_add_series(daySummary$TotalAmount, type = "column", name = "Daily Loan Revenue",
# tooltip = list(pointFormat = "Daily Revenue ${point.TotalAmount} across {point.TotalCount} deals")) %>%
# hc_tooltip()
#hchart(daySummary, "column", hcaes(daySummary$FundedDayGroup, daySummary$TotalAmount))
})
}
The highChart function that is commented out works correctly in displaying the columns wanted. The Axis is incorrect and the tooltips is unformatted but the data displays.
Using the Non-commented highchart with the HCAES call and other items, the plot is displayed without any data.
Below is code to reproduce the test data set for the daySummary, the dataframe in question.
FundedDayGroup <- as.Date(c('2019-02-01', '2019-02-4', '2019-02-05'))
TotalCount <- c(1,13,18)
TotalAmount <- c(0, 13166, 15625)
daySummary <- data.frame(FundedDayGroup, TotalCount, TotalAmount)
The issue ended up being Highcharter not interpreting the POSIXct format of the dates and needing to cast the date variable using as.Date. Additionally added some logic to handle the xAxis and setting the datetime. Code below
highchart() %>%
hc_add_theme(hc_theme_ffx()) %>%
hc_title(text = "Loans Funded By Day") %>%
hc_add_series(data = daySummary, mapping = hcaes(x=as.Date(FundedDayGroup), y=TotalAmount), type = "column", name = "Daily Loan Revenue",
tooltip = list(pointFormat = "Daily Revenue ${point.TotalAmount} across {point.TotalCount} deals")) %>%
hc_xAxis(type = "datetime", labels=list(rotation = -45, y = 40) ) %>%
hc_yAxis(title=list(text = "Revenue")) %>%
hc_tooltip(crosshairs = TRUE)
I would like to create a plotly plot where the fill under each line is toggled upon mouseover/hover. The closest that I've come is using a combination of plotly and Shiny in the code below. Basically, I use the function event_data("plotly_hover") with a call to add_trace, which generates the fill for the line. However, when the mouse is moved away from the line, or unhovered, I get an error message: Error: incorrect length (0), expecting: 2366. In addition, the hoverinfo text no longer appears, or only briefly before the fill appears.
I'm not sure what the program is looking for when unhovering, so am not sure why I'm getting this error. Or perhaps there is different and simpler way to toggle the fill for plotly graphs?
ui.R
shinyUI(fluidPage(
titlePanel("Snow Weather Stations"),
mainPanel(
plotlyOutput("testplot", height = "500px")
)
)
)
server.R
library(shiny)
library(plotly)
library(dplyr)
library(tidyr)
csvf <- read.csv(file = "http://bcrfc.env.gov.bc.ca/data/asp/realtime/data/SW.csv",
check.names = FALSE, stringsAsFactors = FALSE)
swe <- csvf %>%
gather(STATION, SWE, -1) %>%
separate(`DATE (UTC)`, c('DATE', 'TIME'), sep = " ") %>%
filter(TIME == "15:00:00") %>%
select(-TIME) %>%
filter(substr(STATION,1,2) == "1A")
swe$DATE <- as.Date(swe$DATE)
swe$HOVERTEXT <- paste(swe$STATION, paste0(swe$SWE, " mm"), sep = "<br>")
xmin <- as.numeric(as.Date("2015-10-01")) * 24 * 60 * 60 * 1000
xmax <- as.numeric(as.Date("2016-09-30")) * 24 * 60 * 60 * 1000
shinyServer(function(input, output) {
output$testplot <- renderPlotly({
plot_ly(swe, x = DATE, y = SWE, group = STATION,
line = list(color = '#CCCCCC'),
text = HOVERTEXT, hoverinfo = "text+x",
hoveron = "points",
key = STATION) %>%
layout(showlegend = FALSE,
hovermode = 'closest',
xaxis = list(title = "",
showgrid = FALSE, showline = TRUE,
mirror = "ticks", ticks = "inside", tickformat = "%b",
hoverformat = "%b %-d",
range = c(xmin, xmax)),
yaxis = list(title = "Snow Water Equivalent (mm)",
showgrid = FALSE, showline = TRUE,
mirror = "ticks", ticks = "inside",
rangemode = "tozero")) %>%
config(displayModeBar = FALSE)
d <- event_data("plotly_hover")
if (is.null(d)) {
stn <- "1A01P Yellowhead Lake"
} else {
stn <- d$key[1]
}
add_trace(filter(swe, STATION == stn), x = DATE, y = SWE,
line = list(color = "404040"), fill = "tozeroy")
})
})