[英]Change colour of text output as text value changes when invalidated with reactiveTimer in shiny
I am creating a dashboard for financial stocks.我正在为金融股票创建一个仪表板。 I have a box with the stock price.我有一个显示股票价格的盒子。 The stock price changes every minute.股价每分钟都在变化。 What I want is as the stock price changes, the colour should change briefly to reflect the type of change.我想要的是随着股价的变化,颜色应该短暂地变化以反映变化的类型。 For instance, if the last price is below the previous last price, I want the colour of the text to flash red as it changes, but return to the default colour, which is black.例如,如果最后一个价格低于前一个最后一个价格,我希望文本的颜色在更改时闪烁红色,但返回到默认颜色,即黑色。 This is similar to what happens on Google Finance as the price changes (see google search result for jse:npn for example)这与价格变化时 Google Finance 上发生的情况类似(例如,请参阅 jse:npn 的 google 搜索结果)
Here is the most stripped out version of my code.这是我的代码最精简的版本。
library(quantmod)
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
ui <- dashboardPage(
dashboardHeader(title = "Example"),
dashboardSidebar(
sidebarMenu(
ID = "tabs",
menuItem(text = "Naspers", tabName = "tabNaspers", icon = icon("chart-line"))
)
),
dashboardBody(
tags$head(tags$style(HTML('.fas { font-size: 36px; }
.fas {
vertical-align: middle;
}
#'
))),
tabItems(
tabItem(tabName = "tabNaspers",
fluidRow(
column(
width = 7,
boxPlus(title = span("ALL SHARE", style = "color: rgb(128,128,128); font-size: 22px"),
collapsible = TRUE,
closable = FALSE,
enable_dropdown = TRUE,
dropdown_icon = "NULL",
status = 'success',
valueBoxOutput('npn_price', 12),
valueBoxOutput('npn_day_change', 12),
width = 4
)
)
)
)
)
)
)
npn_close <- 203059.00
server <- function(input, output, session){
autoInvalidate <- reactiveTimer(intervalMs = 60000)
output$npn_price <- renderUI({
autoInvalidate()
npn_last <- getQuote("NPN.JO", what=yahooQF("Last Trade (Price Only)"))[, 2]
npn_change <- round((npn_last - npn_close) / npn_close, 4) * 100
arrow_color <- ifelse(npn_change > 0, 'rgb(15, 157, 88)' ,'rgb(226, 74, 26)')
npn_diff <- npn_last - npn_close
npn_diff <- ifelse(npn_diff < 0, paste0('-', npn_diff), paste0('+', npn_diff))
tags$div(HTML(paste0('<span style="font-size: 24px"><strong>',
npn_last, '</strong></span>', '<span style="color:', arrow_color, '; font-size: 14px">', npn_diff, '</span>')))
})
output$npn_day_change <- renderUI({
autoInvalidate()
npn_last <- getQuote("NPN.JO", what=yahooQF("Last Trade (Price Only)"))[, 2]
npn_change <- round((npn_last - npn_close) / npn_close, 4) * 100
npn_change <- paste0(npn_change, "%")
arrow_color <- ifelse(npn_change > 0, 'rgb(15, 157, 88)' ,'rgb(226, 74, 26)')
arrow_icon <- ifelse(npn_change < 0, '"fas fa-caret-down"', '"fas fa-caret-up"')
tags$div(HTML(paste0('<i class=', arrow_icon, ' style = "color:', arrow_color,
';"></i><span style="color:', arrow_color,'; font-size: 24px"><strong>',
npn_change, '</strong></span>')))
})
}
shinyApp(ui, server)
Sure.当然。 In summary we store the price, get the new price, if the price is down make the text red, then we quickly run again to produce the flash effect.综上,我们存储价格,获取新价格,如果价格下降使文字变红,然后我们快速再次运行以产生闪光效果。
For testing I added buttons to simulate the price going up and down.为了测试,我添加了按钮来模拟价格的上涨和下跌。 I also made it check for changes more frequently.我还让它更频繁地检查更改。
The flash length can be changed at this line: invalidateLater(1200)
.可以在此行更改闪存长度: invalidateLater(1200)
。
library(quantmod)
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
ui <- dashboardPage(
dashboardHeader(title = "Example"),
dashboardSidebar(
sidebarMenu(
ID = "tabs",
menuItem(text = "Naspers", tabName = "tabNaspers", icon = icon("chart-line"))
)
),
dashboardBody(
tags$head(tags$style(HTML('.fas { font-size: 36px; }.fas {vertical-align: middle;} #'))),
tabItems(
tabItem(tabName = "tabNaspers",
fluidRow(
column(
width = 7,
boxPlus(title = span("ALL SHARE", style = "color: rgb(128,128,128); font-size: 22px"),
collapsible = TRUE,
closable = FALSE,
enable_dropdown = TRUE,
dropdown_icon = "NULL",
status = 'success',
valueBoxOutput('npn_price', 12),
valueBoxOutput('npn_day_change', 12),
width = 4
)
)
),
#Buttons to simulate stock going up, so that we don't have to wait for the stock to actually go up or down
actionButton('btn_stockgoesup', 'Simulate Stock Going Up'),
actionButton('btn_stockgoesdown', 'Simulate Stock Going Down')
)
)
)
)
npn_close <- 203059.00
server <- function(input, output, session){
autoInvalidate <- reactiveTimer(intervalMs = 6000)
#Buttons to simulate stock going up, so that we don't have to wait for the stock to actually go up or down
observeEvent(input$btn_stockgoesup, {npn_last_stored <<- 0 ; print('At the next update the stock will simulate going up')})
observeEvent(input$btn_stockgoesdown, {npn_last_stored <<- Inf; print('At the next update the stock will simulate going down')})
output$npn_price <- renderUI({
autoInvalidate()
npn_last <- getQuote("NPN.JO", what=yahooQF("Last Trade (Price Only)"))[, 2]
#Handle when app first starts and there is no stored value to compare against
if(exists('npn_last_stored') == FALSE) {npn_last_stored <<- npn_last}
if(npn_last < npn_last_stored) {
#Stock went down
print('stock went down')
npn_color <- 'rgb(220, 50, 20)'
invalidateLater(1200)
} else {
#Stock went up / not changed
print('stock went up / not changed')
npn_color <- 'rgb(0, 0, 0)'
}
#Update stored value
npn_last_stored <<- npn_last
npn_change <- round((npn_last - npn_close) / npn_close, 4) * 100
arrow_color <- ifelse(npn_change > 0, 'rgb(15, 157, 88)' ,'rgb(226, 74, 26)')
npn_diff <- npn_last - npn_close
npn_diff <- ifelse(npn_diff < 0, paste0('-', npn_diff), paste0('+', npn_diff))
tags$div(HTML(paste0('<span style="color:', npn_color, '; font-size: 24px"><strong>', npn_last, '</strong></span>', '<span style="color:', arrow_color, '; font-size: 14px">', npn_diff, '</span>')))
})
output$npn_day_change <- renderUI({
autoInvalidate()
npn_last <- getQuote("NPN.JO", what=yahooQF("Last Trade (Price Only)"))[, 2]
npn_change <- round((npn_last - npn_close) / npn_close, 4) * 100
npn_change <- paste0(npn_change, "%")
arrow_color <- ifelse(npn_change > 0, 'rgb(15, 157, 88)' ,'rgb(226, 74, 26)')
arrow_icon <- ifelse(npn_change < 0, '"fas fa-caret-down"', '"fas fa-caret-up"')
tags$div(HTML(paste0('<i class=', arrow_icon, ' style = "color:', arrow_color,';"></i><span style="color:', arrow_color,'; font-size: 24px"><strong>',npn_change, '</strong></span>')))
})
}
shinyApp(ui, server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.