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

    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

    Reply
    1. Without error log or code how I can say whats the issue ūüôā

      Reply

Submit a Comment

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

Footer Logo

Subscribe

Select Categories