I would like to integrate a JS code to a Shiny application to load a TradingView JS widget.
The problem is when the app is loading, the selector input disappears and the TradingView widget replaces the whole UI, I do not know why.
library(shiny)
library(shinyjs)
jsCode <- 'shinyjs.pageCol = function(para){new TradingView.widget( {"width": 640,"height": 400,"symbol": para,"interval": "D","timezone": "Etc/UTC","theme": "light", "style": "1",
"locale": "en", "toolbar_bg": "#f1f3f6","enable_publishing": false, "allow_symbol_change": true,"container_id": "tradingview_e9634"} );}'
shinyApp(
ui = fluidPage(
div(selectInput("ticker", "Ticker:",
c('NASDAQ:AMD', 'NASDAQ:TSLA', 'NASDAQ:GE'))),
tags$head(HTML('<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>')) ,
useShinyjs(),
div(extendShinyjs(text = jsCode, functions = c("pageCol")))
),
server = function(input, output) {
observeEvent(input$ticker, {
js$pageCol(input$ticker)
})
}
)
There are two ways of making it work, as described in this other post (related only to Javascript): TradingView widget replacing entire HTML body.
Either give the ID attribute name you chose in your jsCode to the div tag:
div(id="tradingview_e9634", extendShinyjs(text = jsCode, functions = c("pageCol")))
Or use an iframe: place the following chart.html file in a www subfolder of your app folder.
<html>
<head>
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
<script>
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
var para = getParameterByName('value');
console.log(para);
var fxWidget = new TradingView.widget({
"width": 640,
"height": 400,
"symbol": para,
"interval": "1",
"timezone": "Etc/UTC",
"theme": "light",
"style": "1",
"locale": "en",
"toolbar_bg": "#f1f3f6",
"enable_publishing": false,
"allow_symbol_change": true,
"container_id": "tradingview_e9634"
});
</script>
</head>
<body>
</body>
</html>
and use this app.R (simpler than the other version, no need for shinyjs):
library(shiny)
shinyApp(
ui = fluidPage(
div(selectInput("ticker", "Ticker:",
c('NASDAQ:AMD', 'NASDAQ:TSLA', 'NYSE:GE'))),
htmlOutput("frame")
),
server = function(input, output) {
observeEvent(input$ticker, {
query <- paste0("chart.html?value=", input$ticker)
output$frame <- renderUI({
tags$iframe(src=query, width=660, height=450)
})
})
})