1

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)
    })
  }
)
julien.leroux5
  • 969
  • 7
  • 17

1 Answers1

1

There are two ways of making it work, as described in this other post (related only to Javascript): TradingView widget replacing entire HTML body.

  1. 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")))
    
  2. 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)
           })
         })
       })
    
julien.leroux5
  • 969
  • 7
  • 17