Financial application with amCharts on Angular

Jakub Jóźwicki
3 min readFeb 9, 2019

In a financial world you need pretty charts. Angular is a standard for 4 tier architecture with Single Page Application consuming microservices. For Angular there are amCharts.

PieChart3D with Material buttons

Smart application should be interactive. We can attach click event handler to data series. We can retrieve from the event a reference to exact data item which triggered event emission.

series.slices.template.events.on("hit", function(event) {
let symbol = data[event.target.dataItem.index].symbol;
if (AppComponent.selectedModelProduct.has(symbol))
AppComponent.selectedModelProduct.delete(symbol);
else
AppComponent.selectedModelProduct.add(symbol);
});

We can wrap access to microservices providing data using Service component with static methods. For then we need static HttpClient:

import { HttpClientModule, HttpClient, HttpHandler, HttpXhrBackend, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injector} from '@angular/core';
export class CustomerDataService {
private static injector = Injector.create({
providers: [
{ provide: HttpClient, deps: [HttpHandler] },
{ provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest }) },
],
});
private static http: HttpClient = CustomerDataService.injector.get(HttpClient);
...
}

Then we can do:

public static getStockData(symbol: string, points: number) : Observable<any> {
let payload = CustomerDataService.http.get('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol='+symbol+'&outputSize='+points+'&apikey='+CustomerDataService.API_KEY).pipe(
map(root => CustomerDataService.dailyStocksTransform(root["Time Series (Daily)"], symbol))
);
return payload;
}
In case of exotic data stuctures we need to use Object properties

HttpClient in Angular parses JSON transparently and we receive Object with properties. To perform mapping we need to use Object.defineProperty. Dynamic properties cannot be copied between objects with Object.assign or spread operator instanceC = {…instanceA, …instanceB}. These 2 patterns work only with default static properties.

We can execute HTTP GET requests in parallel

In case we need execute many HTTP calls we can do then in parallel with rxjs. We gather Observables from HttpClient.get and merge all responses with

merge(...httpGets).pipe(mergeAll())

then get flat array via

merge(...httpGets).pipe(mergeAll()).pipe(toArray).subscribe((data: any[]) => { /* operate on data */ }

We can focus user on newly populated chart with:

document.getElementById('valueChart').scrollIntoView();

Any other nice tricks?

Yes, modern fonts:

constructor(private zone: NgZone, @Inject(DOCUMENT) private document: any, private renderer: Renderer) {}private addGoogleFont(name: string) {
const elem = this.renderer.createElement(this.document.head, 'link');
this.renderer.setElementProperty(elem, 'href', 'https://fonts.googleapis.com/css?family='+name.replace(' ','+'));
this.renderer.setElementProperty(elem, 'rel', 'stylesheet');
}
private enableRwd() {
const elem = this.renderer.createElement(this.document.head, 'meta');
this.renderer.setElementProperty(elem, 'content', 'width=device-width, initial-scale=1');
this.renderer.setElementProperty(elem, 'name', 'viewport');
}
ngAfterViewInit() {
this.enableRwd();
this.addGoogleFont('Archivo');
this.addGoogleFont('Lato');
this.addGoogleFont('Material Icons');
}

Yes, column layout:

<div class="row">
<div class="column">
<div id="chartPortfolioReal" style="width: 500px;"></div>
</div>
<div class="column">
<div id="chartPortfolioModel" style="width: 500px;"></div>
</div>
</div>
* { box-sizing: border-box; }
.column { float: left; width: 50%; padding: 10px; }
.row:after { content: ""; display: table; clear: both; }
@media screen and (max-width: 800px) {
.column { width: 100%; }
}

Enjoy Angular and amCharts!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Jakub Jóźwicki
Jakub Jóźwicki

No responses yet