Dynamic Am-Charts In Angular 8

Here, we will learn about creating dynamic AM-Charts in Angular 8. Charts are very useful for showing data and people understand the data very easily. So we will use am-charts for creating dynamic charts in Angular-8.

We will use the dummy API for it.

https://api.myjson.com/bins/zg8of

So, create a new project in Angular 8 using your favorite code editor.

After creating it, open the project and open app.component.html file and add the code in it.

<div id="chartdiv" style="width: 100%; height: 500px">
</div>
<div id="l-0"></div>

Open the app.component.ts file and add the code in it.

import { Component, NgZone } from "@angular/core";
import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";
import { HttpClient } from '@angular/common/http';

am4core.useTheme(am4themes_animated);

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  private chart: am4charts.XYChart;
  tempData: any;
  dates = [];
  newData = [];
  gr = [];
  data = [];
  constructor(private _zone: NgZone, private _http: HttpClient) { this.getApiData(); }

  getApiData() {
    this._http.get("https://api.myjson.com/bins/zg8of").subscribe(res => {
      this.tempData = res;
      this.tempData.forEach(values => {
        this.data.push(values);
      });
      console.log(this.data);
      this._zone.runOutsideAngular(() => {
        var result = this.groupBy(this.data, function (item) {
          return ([item.Name]);
        });

        result.forEach(b => {
          var d1 = b.map(function (i) {
            return i.Month;
          });
          Object.assign(this.dates, d1);
        });

        this.dates.forEach(b => {
          var item = { sales_figure: b };
          var i = 0;
          result.forEach(c => {
            var el = c.filter(function (e) {
              return e.Month == b;
            });
            if (el && el.length > 0) {
              item[c[i].Name.toUpperCase()] = el[0].Sales_Figure;
              if (this.gr.filter(function (g) {
                return g == c[i].Name.toUpperCase();
              }).length <= 0) {
                this.gr.push(c[i].Name.toUpperCase());
              }
            }
            i++;
          });

          if (Object.keys(item).length > 1)
            this.newData.push(item);
        });
        let chart = am4core.create("chartdiv", am4charts.XYChart);
        am4core.options.minPolylineStep = Math.ceil(this.newData.length / 50);
        am4core.options.commercialLicense = true;
        chart.paddingRight = 20;
        chart.data = this.newData;

        var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
        categoryAxis.dataFields.category = "sales_figure";
        categoryAxis.renderer.minGridDistance = 70;
        categoryAxis.fontSize = 12;

        var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
        valueAxis.fontSize = 12;
        valueAxis.title.text = "Sales Figure";

        chart.legend = new am4charts.Legend();
        chart.legend.position = "top";
        chart.legend.fontSize = 12;

        var markerTemplate = chart.legend.markers.template;
        markerTemplate.width = 10;
        markerTemplate.height = 10;

        var legendContainer = am4core.create("l-0", am4core.Container);
        legendContainer.width = am4core.percent(100);
        chart.legend.parent = legendContainer;

        var legendDiv = document.getElementById("l-0");
        function resizeLegendDiv() {
          legendDiv.style.height = chart.legend.measuredHeight + "px";
          legendDiv.style.overflow = "hidden";
        }

        chart.legend.events.on('inited', resizeLegendDiv);
        chart.colors.list = [am4core.color("#0D8ECF"), am4core.color("#FF6600"), am4core.color("#FCD202"), am4core.color("#B0DE09"), am4core.color("#2A0CD0"), am4core.color("#CD0D74"), am4core.color("#CC0000"), am4core.color("#00CC00"), am4core.color('#ffd8b1'), am4core.color("#990000"), am4core.color('#4363d8'), am4core.color('#e6194b'), am4core.color('#3cb44b'), am4core.color('#ffe119'), am4core.color('#f58231'), am4core.color('#911eb4'), am4core.color('#46f0f0'), am4core.color('#f032e6'), am4core.color('#bcf60c'), am4core.color('#fabebe'), am4core.color('#008080'), am4core.color('#e6beff'), am4core.color('#9a6324'), am4core.color('#fffac8'), am4core.color('#800000'), am4core.color('#aaffc3'), am4core.color('#808000'), am4core.color('#ffd8b1'), am4core.color('#000075')];
        this.gr.forEach(d => {

          var series = chart.series.push(new am4charts.LineSeries());
          series.dataFields.valueY = d;
          series.name = d;
          series.dataFields.categoryX = "sales_figure";
          series.tooltipText = "{name}: [bold]{valueY}[/]";
          series.strokeWidth = 2;
          series.minBulletDistance = 30;
          series.tensionX = 0.7;
          series.legendSettings.labelText = "[bold]" + "{name}";

          var bullet = series.bullets.push(new am4charts.CircleBullet());
          bullet.circle.strokeWidth = 2;
          bullet.circle.radius = 3;
          bullet.circle.fill = am4core.color("#fff");

          var bullethover = bullet.states.create("hover");
          bullethover.properties.scale = 1.2;
          chart.cursor = new am4charts.XYCursor();
          chart.cursor.behavior = "panXY";
          chart.cursor.snapToSeries = series;
        });

        chart.scrollbarX = new am4core.Scrollbar();
        chart.scrollbarX.parent = chart.bottomAxesContainer;

        this.chart = chart;
      });
    });
  }

  groupBy(array, f) {
    var groups = {};
    array.forEach(function (o) {
      var group = JSON.stringify(f(o));
      groups[group] = groups[group] || [];
      groups[group].push(o);
    });
    return Object.keys(groups).map(function (group) {
      return groups[group];
    })
  }

  ngOnDestroy() {
    this._zone.runOutsideAngular(() => {
      if (this.chart) {
        this.chart.dispose();
      }
    });
  }

}

Finally, add the reference for HttpClientModule in the app.module.ts file and that’s it.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Output:

output

3 Comments

  1. Jawwad

    Assalam o Alaikum. I’m trying to implement these concept about amCharts in my angular9 project but getting these errors. How can I resolve them. Kindly Help me out.

    Humbly Thanks……..! 🙂

    Angular is running in the development mode. Call enableProdMode() to enable the production mode.
    client:52 [WDS] Live Reloading enabled.
    zone-evergreen.js:2845 GET https://api.myjson.com/bins/zg8of net::ERR_CONNECTION_TIMED_OUT
    scheduleTask @ zone-evergreen.js:2845
    scheduleTask @ zone-evergreen.js:385
    onScheduleTask @ zone-evergreen.js:272
    scheduleTask @ zone-evergreen.js:378
    scheduleTask @ zone-evergreen.js:210
    scheduleMacroTask @ zone-evergreen.js:233
    scheduleMacroTaskWithCurrentZone @ zone-evergreen.js:1134
    (anonymous) @ zone-evergreen.js:2878
    proto. @ zone-evergreen.js:1449
    (anonymous) @ http.js:2637
    _trySubscribe @ Observable.js:42
    subscribe @ Observable.js:28
    subscribeToResult @ subscribeToResult.js:9
    _innerSub @ mergeMap.js:59
    _tryNext @ mergeMap.js:53
    _next @ mergeMap.js:36
    next @ Subscriber.js:49
    (anonymous) @ subscribeToArray.js:3
    _trySubscribe @ Observable.js:42
    subscribe @ Observable.js:28
    call @ mergeMap.js:21
    subscribe @ Observable.js:23
    call @ filter.js:13
    subscribe @ Observable.js:23
    call @ map.js:16
    subscribe @ Observable.js:23
    getApiData @ app.component.ts:24
    AppComponent @ app.component.ts:22
    AppComponent_Factory @ app.component.ts:132
    getNodeInjectable @ core.js:5993
    instantiateRootComponent @ core.js:12832
    createRootComponent @ core.js:26488
    create @ core.js:34110
    bootstrap @ core.js:43108
    (anonymous) @ core.js:42696
    _moduleDoBootstrap @ core.js:42692
    (anonymous) @ core.js:42647
    invoke @ zone-evergreen.js:364
    onInvoke @ core.js:41667
    invoke @ zone-evergreen.js:363
    run @ zone-evergreen.js:123
    (anonymous) @ zone-evergreen.js:857
    invokeTask @ zone-evergreen.js:399
    onInvokeTask @ core.js:41645
    invokeTask @ zone-evergreen.js:398
    runTask @ zone-evergreen.js:167
    drainMicroTaskQueue @ zone-evergreen.js:569
    Promise.then (async)
    scheduleMicroTask @ zone-evergreen.js:552
    scheduleTask @ zone-evergreen.js:388
    scheduleTask @ zone-evergreen.js:210
    scheduleMicroTask @ zone-evergreen.js:230
    scheduleResolveOrReject @ zone-evergreen.js:847
    then @ zone-evergreen.js:979
    bootstrapModule @ core.js:42677
    ./src/main.ts @ main.ts:11
    __webpack_require__ @ bootstrap:83
    0 @ main.ts:12
    __webpack_require__ @ bootstrap:83
    checkDeferredModules @ bootstrap:44
    webpackJsonpCallback @ bootstrap:31
    (anonymous) @ main.js:1
    Show 17 more frames
    core.js:6241 ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: “Unknown Error”, url: “https://api.myjson.com/bins/zg8of”, ok: false, …}error: ProgressEvent {isTrusted: true, lengthComputable: false, loaded: 0, total: 0, type: “error”, …}bubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: “https://api.myjson.com/bins/zg8of”, __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}defaultPrevented: falseeventPhase: 0isTrusted: truelengthComputable: falseloaded: 0path: []returnValue: truesrcElement: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: “https://api.myjson.com/bins/zg8of”, __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}target: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: “https://api.myjson.com/bins/zg8of”, __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}timeStamp: 28933.13500000113total: 0type: “error”__proto__: ProgressEventheaders: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}headers: Map(0) {}lazyUpdate: nullnormalizedNames: Map(0) {}__proto__: Objectmessage: “Http failure response for https://api.myjson.com/bins/zg8of: 0 Unknown Error”name: “HttpErrorResponse”ok: falsestatus: 0statusText: “Unknown Error”url: “https://api.myjson.com/bins/zg8of”__proto__: HttpResponseBase
    defaultErrorLogger @ core.js:6241
    handleError @ core.js:6294
    next @ core.js:42627
    schedulerFn @ core.js:37132
    __tryOrUnsub @ Subscriber.js:183
    next @ Subscriber.js:122
    _next @ Subscriber.js:72
    next @ Subscriber.js:49
    next @ Subject.js:39
    emit @ core.js:37092
    (anonymous) @ core.js:41707
    invoke @ zone-evergreen.js:364
    run @ zone-evergreen.js:123
    runOutsideAngular @ core.js:41501
    onHandleError @ core.js:41704
    handleError @ zone-evergreen.js:368
    runTask @ zone-evergreen.js:170
    invokeTask @ zone-evergreen.js:480
    ZoneTask.invoke @ zone-evergreen.js:469
    timer @ zone-evergreen.js:2552
    setTimeout (async)
    scheduleTask @ zone-evergreen.js:2573
    scheduleTask @ zone-evergreen.js:385
    onScheduleTask @ zone-evergreen.js:272
    scheduleTask @ zone-evergreen.js:378
    scheduleTask @ zone-evergreen.js:210
    scheduleMacroTask @ zone-evergreen.js:233
    scheduleMacroTaskWithCurrentZone @ zone-evergreen.js:1134
    (anonymous) @ zone-evergreen.js:2586
    proto. @ zone-evergreen.js:1449
    hostReportError @ hostReportError.js:2
    error @ Subscriber.js:156
    _error @ Subscriber.js:75
    error @ Subscriber.js:55
    _error @ Subscriber.js:75
    error @ Subscriber.js:55
    _error @ Subscriber.js:75
    error @ Subscriber.js:55
    notifyError @ OuterSubscriber.js:7
    _error @ InnerSubscriber.js:14
    error @ Subscriber.js:55
    onError @ http.js:2560
    invokeTask @ zone-evergreen.js:399
    onInvokeTask @ core.js:41645
    invokeTask @ zone-evergreen.js:398
    runTask @ zone-evergreen.js:167
    invokeTask @ zone-evergreen.js:480
    invokeTask @ zone-evergreen.js:1621
    globalZoneAwareCallback @ zone-evergreen.js:1647
    error (async)
    customScheduleGlobal @ zone-evergreen.js:1773
    scheduleTask @ zone-evergreen.js:385
    onScheduleTask @ zone-evergreen.js:272
    scheduleTask @ zone-evergreen.js:378
    scheduleTask @ zone-evergreen.js:210
    scheduleEventTask @ zone-evergreen.js:236
    (anonymous) @ zone-evergreen.js:1928
    (anonymous) @ http.js:2626
    _trySubscribe @ Observable.js:42
    subscribe @ Observable.js:28
    subscribeToResult @ subscribeToResult.js:9
    _innerSub @ mergeMap.js:59
    _tryNext @ mergeMap.js:53
    _next @ mergeMap.js:36
    next @ Subscriber.js:49
    (anonymous) @ subscribeToArray.js:3
    _trySubscribe @ Observable.js:42
    subscribe @ Observable.js:28
    call @ mergeMap.js:21
    subscribe @ Observable.js:23
    call @ filter.js:13
    subscribe @ Observable.js:23
    call @ map.js:16
    subscribe @ Observable.js:23
    getApiData @ app.component.ts:24
    AppComponent @ app.component.ts:22
    AppComponent_Factory @ app.component.ts:132
    getNodeInjectable @ core.js:5993
    instantiateRootComponent @ core.js:12832
    createRootComponent @ core.js:26488
    create @ core.js:34110
    bootstrap @ core.js:43108
    (anonymous) @ core.js:42696
    _moduleDoBootstrap @ core.js:42692
    (anonymous) @ core.js:42647
    invoke @ zone-evergreen.js:364
    onInvoke @ core.js:41667
    invoke @ zone-evergreen.js:363
    run @ zone-evergreen.js:123
    (anonymous) @ zone-evergreen.js:857
    invokeTask @ zone-evergreen.js:399
    onInvokeTask @ core.js:41645
    invokeTask @ zone-evergreen.js:398
    runTask @ zone-evergreen.js:167
    drainMicroTaskQueue @ zone-evergreen.js:569
    Promise.then (async)
    scheduleMicroTask @ zone-evergreen.js:552
    scheduleTask @ zone-evergreen.js:388
    scheduleTask @ zone-evergreen.js:210
    scheduleMicroTask @ zone-evergreen.js:230
    scheduleResolveOrReject @ zone-evergreen.js:847
    then @ zone-evergreen.js:979
    bootstrapModule @ core.js:42677
    ./src/main.ts @ main.ts:11
    __webpack_require__ @ bootstrap:83
    0 @ main.ts:12
    __webpack_require__ @ bootstrap:83
    checkDeferredModules @ bootstrap:44
    webpackJsonpCallback @ bootstrap:31
    (anonymous) @ main.js:1
    Show 45 more frames
    zone-evergreen.js:2550 [Violation] ‘setTimeout’ handler took 97ms

    0
    0
    Reply
  2. darek

    Hello Faisal,

    I tried to implement this code in a local instance of angular but it does not work for me. Any ideas why? no errors being reported in the console. Thank you

    0
    0
    Reply
    1. Without error log or code how I can say whats the issue 🙂

      0
      0
      Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories