Embed Tradingview into Angular 5

前端 未结 6 1311
北荒
北荒 2021-01-12 01:04

I just copy the function in the embed script found here (https://www.tradingview.com/widget/advanced-chart/) into a component in my Angular 5 app, and include the source scr

相关标签:
6条回答
  • 2021-01-12 01:24
    1. I added widget loading scripts to index.html, after
    2. in component's template-file (html) I leaved only html tags
    3. in component's ts-file:

      declare const TradingView: any;

      and in ngAfterViewInit() I putted new TradingView.widget(...) inside setTimeout

    And that's it! It works.

    0 讨论(0)
  • 2021-01-12 01:25

    I know this is a bit old, but I am just trying out TradingView's widgets now. This helped a lot. Turns out TradingView is in the process of changing the way their widget scripts are loaded and I thought I might share the way I figured out how to make a reusable component for both their old and new loading methods. Enjoy:

    Here is the injected version (newer):

     import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
    
     @Component( {
       selector: 'rip-trading-view-fundamentals',
       template: `
           <div class="tradingview-widget-container" style="height: 300px;" #containerDiv>
               <div class="tradingview-widget-container__widget"></div>
    
           </div>
       `,
     } )
    
     export class TradingViewFundamentalsComponent implements AfterViewInit {
    
       // allows for loading with any symbol
       @Input() symbol: string = '';
       settings: any = {};
       // id for being able to check for errors using postMessage
       widgetId: string = '';
    
       // wanted to be able to hide the widget if the symbol passed in was invalid (don't love their sad cloud face)
       @ViewChild( 'containerDiv', { static: false } ) containerDiv: ElementRef;
    
       constructor( private _elRef: ElementRef ) {
       }
    
       ngAfterViewInit() {
         // need to do this in AfterViewInit because of the Input
         setTimeout( () => {
           this.widgetId = `${ this.symbol }_fundamnetals`;
    
           // postMessage listener for handling errors
           if ( window.addEventListener ) {
             window.addEventListener( 'message', ( e: any ) => {
                 if ( e && e.data ) {
                   console.log( e );
                   const payload = e.data;
                   // if the frameElementId is from this component, the symbol was no good and we should hide the widget
                   if ( payload.name === 'tv-widget-no-data' && payload.frameElementId === this.widgetId ) {
                     this.containerDiv.nativeElement.style.display = 'none';
                   }
                 }
               },
               false,
             );
           }
    
    
           this.settings = {
             symbol: this.symbol,
             colorTheme: 'light',
             isTransparent: false,
             largeChartUrl: '',
             displayMode: 'regular',
             height: 300,
             autosize: true,
             locale: 'en',
           };
           const script = document.createElement( 'script' );
           script.src = 'https://s3.tradingview.com/external-embedding/embed-widget-financials.js';
           script.async = true;
           script.id = this.widgetId;
           script.innerHTML = JSON.stringify( this.settings );
           this.containerDiv.nativeElement.appendChild( script );
           const brandingDiv = document.createElement( 'div' );
           brandingDiv.innerHTML = `
         <div class="tradingview-widget-copyright">
         <a href="https://www.tradingview.com/symbols/${ this.symbol }/" rel="noopener" target="_blank">
         <span class="blue-text">${ this.symbol } Fundamental Data</span></a>
                   by TradingView
               </div>
     `;
    
         } );
       }
    
     }
    
    

    And here is the older version, via global TradingView object used loading their library in your index.html:

    import { AfterViewInit, Component, ElementRef, HostListener, Input, ViewChild } from '@angular/core';
    import { Logger } from '../../helpers/logger.service';
    
    // declaration so Typescript knows about the TradingView object loaded in from index.html
    declare const TradingView: any;
    
    @Component( {
      selector: 'rip-trading-view-symbol-overview',
      template: `
          <div #containerDiv id="overview_{{symbol}}" class="tradingview-widget-container" style="height: 300px;"></div>
      `,
    } )
    
    export class TradingViewSymbolOverviewComponent implements AfterViewInit {
    
      chart: any;
      // allows for loading with any symbol and description
      @Input() symbol: string = '';
      @Input() description: string = '';
      // id for being able to check for errors using postMessage
      widgetId: string = '';
    
      // wanted to be able to hide the widget if the symbol passed in was invalid (don't love their sad cloud face)
      @ViewChild( 'containerDiv', { static: false } ) containerDiv: ElementRef;
    
      ngAfterViewInit() {
        // need to do this in AfterViewInit because of the Input
        setTimeout( () => {
          this.widgetId = `overview_${ this.symbol }`;
    
          // postMessage listener for handling errors
          if ( window.addEventListener ) {
            window.addEventListener( 'message', ( e: any ) => {
                if ( e && e.data ) {
                  console.log( e );
                  const payload = e.data;
                  if (
                    // if the frameElementId is from this component, the symbol was no good and we should hide the widget
                    payload.name === 'tv-widget-no-data' && payload.frameElementId === this.widgetId ) {
                    // console.log( 'No data available for the symbol profile widget' );
                    this.containerDiv.nativeElement.style.display = 'none';
                  }
                }
              },
              false,
            );
          }
    
    
          this.chart = new TradingView.MediumWidget( {
            container_id: this.widgetId,
            symbols: [
              [
                this.description,
                this.symbol,
              ],
              // could load more symbols, but we just needed the one at a time for now
              // [
              //   'Google',
              //   'GOOGL',
              // ],
              // [
              //   'Microsoft',
              //   'MSFT',
              // ],
            ],
            id: this.widgetId,
            chartOnly: false,
            // 'width': 1000,
            height: 300,
            autosize: true,
            locale: 'en',
            colorTheme: 'light',
            gridLineColor: '#F0F3FA',
            trendLineColor: '#1b66ae',
            fontColor: '#787B86',
            underLineColor: 'rgba(145,196,242,0.35)',
            isTransparent: false,
          } );
        } );
      }
    
    }
    

    If anyone has notes on how this can be further improved, I'm all ears and I hope these solutions help anyone searching for answers as there aren't alot out there and while TradingView seems to answer emails pretty quick, they don't have any docs that I could find on their site for help like this.

    0 讨论(0)
  • 2021-01-12 01:33

    Sup Guys! Other Solution if these charts are necessary for you(like in my case) you can create a simple backend side for your app using, for example, Flask:

    Create index.html (app/templates/index.html) with widget code in it, in init.py (app/init.py):

    from flask import Flask, request, render_template
    from flask_restful import Resource, Api
    from flask_cors import CORS, cross_origin
    
    app = Flask(__name__)
    app.config['DEBUG'] = True
    CORS(app)
    
    @app.route('/tradingView')
    def getChart():
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run(port=6200)
    

    then just start running server

    In your component add:

    <iframe src="http://127.0.0.1:6200/tradingView" frameborder="0"></iframe>
    

    This solution requires python and flask knowledge but its as simple as it can be, good luck!

    0 讨论(0)
  • 2021-01-12 01:34

    Works fine with my implementation https://stackblitz.com/edit/stack-48296351

    0 讨论(0)
  • 2021-01-12 01:36

    just add

    <script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script> 
    

    in index.html and it will be work perfectly.

    0 讨论(0)
  • 2021-01-12 01:38

    I found a way to solve the compile error by declaring TradingView in component:

    declare const TradingView: any;
    
    export class ChartComponent implements AfterViewInit {
    ngAfterViewInit() {
       new TradingView.widget({
          'container_id': 'technical-analysis',
          'autosize': true,
          'symbol': this.symbolPair,
          'interval': '120',
          'timezone': 'exchange',
          'theme': 'Dark',
          'style': '1',
          'toolbar_bg': '#f1f3f6',
          'withdateranges': true,
          'hide_side_toolbar': false,
          'allow_symbol_change': true,
          'save_image': false,
          'hideideas': true,
          'studies': [ 
          'MASimple@tv-basicstudies' ],
          'show_popup_button': true,
          'popup_width': '1000',
          'popup_height': '650'
        });
      }
    }
    

    View:

    <div id="technical-analysis"></div>
    
    0 讨论(0)
提交回复
热议问题