Dynamic loading of Data
Nobody has claimed this yet.
- Dominant language
- R
- Stars
- 739
- Forks
- 153
- Avg merge
- 1h 29m
- Merged PRs (30d)
- 1
Description
Hi,
I am using your package for the first time and since it is relatively new in the market, I am posing my problem here.
Objective: I want the highstockcharts to render fast. Today a 10 year data for 2-3 stocks (candlestick) takes ~ 3-5 seconds. I can optimize this by first loading only the weekly data. But if a user chooses to zoom-in (zoom period <365 days), the script should load the daily data for that zoomed in period + the original weekly data. Loading of the weekly data along with the zoomed in period daily data is necessary. Now when the chart redraws with the new data, it should zoom into the users extreme points. I have done this with amCharts but am struggling with Highcharts because the series of methods that gets triggered in case of HighCharts i s a little different.
In HighCharts, when we initialize the chart for the first time, the redraw event gets triggered followed by afterSetExtremes event and again finally the redraw event.
Redraw--> afterSetExtremes --> Redraw --> Stop
We can always use these events to build a logic to achieve the above objective but I am failing to trigger the Highcharts.charts[0].xAxis[0].setExtremes(start,end) statement. in my code below, when the user zooms-in <365 days, a r-script gets triggered which loads the new data. This is working fine but when it redraws the chart, it is not able to set the zoom periods to what the user had used. I am not sure if this is the right forum but any help will be appreciated.
PS: Highstock scores above amCharts in terms of performance and hence this feature is critical.
library(highcharter)
library(quantmod)
library(shinyBS)
library(shiny)
library(shinyjs)
shinyUI(fluidPage(
bsButton("demobtn",type="action", label = NULL,class="btn-group btn-group-xs",icon=icon("plus")),
column(3,HTML('
column(3,HTML('
column(3,HTML('
column(3,HTML('
highchartOutput("hcontainer",height = "800px")
))
server = function(input, output, session) {
values <- reactiveValues()
values$Validate=0
onclick("demobtn",values$Validate <- runif(1, 1, 10000))
SPY <- getSymbols("SPY", from="2006-01-01", auto.assign=FALSE)
SPY <- adjustOHLC(SPY)
SPY.SMA.10 <- SMA(Cl(SPY), n=10)
SPY.SMA.200 <- SMA(Cl(SPY), n=200)
SPY.RSI.14 <- RSI(Cl(SPY), n=14)
SPY.RSI.SellLevel <- xts(rep(70, NROW(SPY)), index(SPY))
SPY.RSI.BuyLevel <- xts(rep(30, NROW(SPY)), index(SPY))
indx <- as.Date(as.integer(apply.monthly(SPY,function(x)index(first(x[as.POSIXlt(index(x))$mday>=10],"day")))))
indx1 <- as.Date(as.integer(apply.monthly(SPY,function(x)index(first(x[as.POSIXlt(index(x))$mday>=15],"day")))))
indx2 <- as.Date(as.integer(apply.monthly(SPY,function(x)index(first(x[as.POSIXlt(index(x))$mday>=20],"day")))))
SPY<-c(SPY[.indexmday(SPY)==1],SPY[index<-indx],SPY[index<-indx1],SPY[index<-indx2])
SPY.SMA.10<-c(SPY.SMA.10[.indexmday(SPY.SMA.10)==1],SPY.SMA.10[index<-indx],SPY.SMA.10[index<-indx1],SPY.SMA.10[index<-indx2])
SPY.SMA.200<-c(SPY.SMA.200[.indexmday(SPY.SMA.200)==1],SPY.SMA.200[index<-indx],SPY.SMA.200[index<-indx1],SPY.SMA.200[index<-indx2])
SPY.RSI.14<-na.omit(c(SPY.RSI.14[.indexmday(SPY.RSI.14)==1],SPY.RSI.14[index<-indx],SPY.RSI.14[index<-indx1],SPY.RSI.14[index<-indx2]))
SPY.RSI.SellLevel<-na.omit(c(SPY.RSI.SellLevel[.indexmday(SPY.RSI.SellLevel)==1],SPY.RSI.SellLevel[index<-indx],SPY.RSI.SellLevel[index<-indx1],SPY.RSI.SellLevel[index<-indx2]))
SPY.RSI.BuyLevel<-na.omit(c(SPY.RSI.BuyLevel[.indexmday(SPY.RSI.BuyLevel)==1],SPY.RSI.BuyLevel[index<-indx],SPY.RSI.BuyLevel[index<-indx1],SPY.RSI.BuyLevel[index<-indx2]))
observeEvent(input$zoomstart,{
check<<-"Pakad"
if (is.null(input$zoomend)==FALSE){
enddt<<-input$zoomend
startdt<<-input$zoomstart
SPY <<- getSymbols("SPY", from="2006-01-01", auto.assign=FALSE)
SPY <<- adjustOHLC(SPY)
```
SPY.SMA.10 <<- SMA(Cl(SPY), n=10)
SPY.SMA.200 <<- SMA(Cl(SPY), n=200)
SPY.RSI.14 <<- RSI(Cl(SPY), n=14)
SPY.RSI.SellLevel <<- xts(rep(70, NROW(SPY)), index(SPY))
SPY.RSI.BuyLevel <<- xts(rep(30, NROW(SPY)), index(SPY))
}
values$Validate <- runif(1, 1, 10000)
```
})
output$hcontainer <- renderHighchart({
values$Validate
```
# if (values$Validate==0)
# return()
highchart() %>%
# create axis :)
hc_yAxis_multiples(
list(title = list(text = NULL), height = "65%", top = "0%"),
list(title = list(text = NULL), height = "10%", top = "72.5%", opposite = TRUE),
list(title = list(text = NULL), height = "15%", top = "85%")
) %>%
# series :D
hc_add_series_ohlc(SPY, yAxis = 0, name = "SPY",smoothed=TRUE,forced=TRUE,groupPixelWidth=240) %>%
# hc_add_series_xts(SPY.SMA.10, yAxis = 0, name = "Fast MA",forced=TRUE,groupPixelWidth=240) %>%
# hc_add_series_xts(SPY.SMA.200, yAxis = 0, name = "Slow MA",forced=TRUE,groupPixelWidth=240) %>%
hc_add_series_xts(SPY$SPY.Volume, color = "gray", yAxis = 1, name = "Volume", type = "column",forced=TRUE,groupPixelWidth=240) %>%
hc_add_series_xts(SPY.RSI.14, yAxis = 2, name = "Osciallator",forced=TRUE,groupPixelWidth=240) %>%
hc_add_series_xts(SPY.RSI.SellLevel, color = "red", yAxis = 2, name = "Sell level", enableMouseTracking = FALSE,forced=TRUE,groupPixelWidth=240) %>%
hc_add_series_xts(SPY.RSI.BuyLevel, color = "blue", yAxis = 2, name = "Buy level", enableMouseTracking = FALSE,forced=TRUE,groupPixelWidth=240) %>%
# I <3 themes
hc_add_theme(hc_theme_538())%>%
hc_chart(zoomType = "xy") %>%
hc_xAxis(
events = list(
setExtremes = JS('function(event){
document.getElementById("ZoomFlag").innerHTML = "Yes";
}'),
afterSetExtremes = JS('function(event){
if (document.getElementById("ZoomST").innerHTML!="-") {
var start = document.getElementById("ZoomST").innerHTML;
var end = document.getElementById("ZoomEND").innerHTML;
} else {
var start = this.getExtremes()["min"];
var end = this.getExtremes()["max"];
}
var timeDiff = Math.abs(parseInt(end) - parseInt(start));
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
if (document.getElementById("ZoomFlag").innerHTML=="Yes" && diffDays<365) {
if (document.getElementById("DataPull").innerHTML=="-"){
alert("Hello");
document.getElementById("DataPull").innerHTML="PullIt";
//document.getElementById("ZoomFlag").innerHTML = "-";
alert(document.getElementById("DataPull").innerHTML);
document.getElementById("ZoomST").innerHTML= this.getExtremes()["min"];
document.getElementById("ZoomEND").innerHTML= this.getExtremes()["max"];
alert(document.getElementById("ZoomST").innerHTML);
clearTimeout();
setTimeout(function(){
Shiny.onInputChange("zoomstart", start)
Shiny.onInputChange("zoomend", end)
}, 1);
} else { clearTimeout();
document.getElementById("ZoomFlag").innerHTML = "-";
document.getElementById("ZoomST").innerHTML= "-";
document.getElementById("ZoomEND").innerHTML = "-";
alert(document.getElementById("ZoomFlag").innerHTML);
alert("This is when we need to chart to set extremes");
setTimeout(function(){
Highcharts.charts[0].xAxis[0].setExtremes(start,end);
}, 1);
}
} else {
alert(document.getElementById("ZoomFlag").innerHTML);
}
}')
)
)%>%
hc_chart(
events = list(
redraw = JS('function(event){
}')
))%>%
hc_rangeSelector(buttons=list(
list(type= 'month',count= 1,text= '1m'),
list(type= 'month',count= 3,text= '3m'),
list(type= 'month',count= 6,text= '6m'),
list(type= 'ytd', text= 'YTD'),
list(type= 'year',count= 1,text= '1Y'),
list(type= 'year',count= 3,text= '3Y'),
list(type= 'year',count= 5,text= '5Y'),
list(type= 'year',count= 7,text= '7Y'),
list(type= 'all',text= 'All')
))
})
```
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Shiny observeEvent(input$zoomstart) handler and the hc_xAxis afterSetExtremes event in the example. Reproduce a zoom under 365 days and trace the redraw, data reload, and setExtremes sequence. Done means the additional data loads while preserving the user's zoom range without a redraw loop.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, r
- Domain
- data-visualization
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100