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 script in angular-cli.json. However, the component returns error "Cannot find name 'TradingView'". Someone has any suggestions?
TradingView allows you to use their Charting Library on your own site, with your own source of data. There are two ways to get your Data into TradingView, the UDF API and the JS API. The JS API gives you the most control over your data, and in my opinion is much more flexible. Plus it's Javascript!
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>
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.
just add
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
in index.html and it will be work perfectly.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With