Angular 2 and AmCharts

10,586

Solution 1

Thanks to the help of customer support at AmCharts.

A working plunker can be found here.

The key issue was this line of code: Instead of doing this:

AmCharts.ready(function () {
    createStockChart();
});

Instead do this:

if (AmCharts.isReady) {
    createStockChart();

} else {
    AmCharts.ready(function () {
        createStockChart();
    });
}

UPDATE:

Here is the extended answer using Angular Service to get the data for the chart. Angular2 HTTP Providers, get a string from JSON for Amcharts

Solution 2

1. Installation

npm install amcharts/amcharts3-angular2 --save

2. In your HTML file, load the amCharts library using tags:

<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>

3. In your app module, import the AmChartsModule module and add it to the imports:

import { AmChartsModule } from "amcharts3-angular2";

@NgModule({
  imports: [
    AmChartsModule
  ]
})
export class AppModule {}

4. Inject the AmChartsService into your app component, create a element with an id, then use the makeChart method to create the chart:

import { AmChartsService } from "amcharts3-angular2";

@Component({
  template: `<div id="chartdiv" [style.width.%]="100" [style.height.px]="500"></div>`
})
export class AppComponent {
  private chart: any;

  constructor(private AmCharts: AmChartsService) {}

  ngOnInit() {
    this.chart = this.AmCharts.makeChart("chartdiv", {
      "type": "serial",
      "theme": "light",
      "dataProvider": []
      ...
    });
  }

  ngOnDestroy() {
    this.AmCharts.destroyChart(this.chart);
  }
}

The first argument to makeChart must be the same as the 's id. The id can be whatever you want, but if you display multiple charts each chart must have a different id

When you are finished with the chart, you must call the destroyChart method. It's good to put this inside the ngOnDestroy method.

5. If you want to change the chart after the chart has been created, you must make the changes using the updateChart method:

// This must be called when making any changes to the chart
this.AmCharts.updateChart(this.chart, () => {
  // Change whatever properties you want, add event listeners, etc.
  this.chart.dataProvider = [];

  this.chart.addListener("init", () => {
    // Do stuff after the chart is initialized
  });
});

Sample Project: https://github.com/amcharts/amcharts3-angular2

Solution 3

I'd say your selector is wrong, you use the element tag <chart></chart>, but in the directive declaration you use [chart], which selects an attribute. This will leave you with 2 possible options:

Option 1

@Directive({
   selector: 'chart', //remove the straight brackets to select a tag
   ...
})

Option 2

<div chart>...</div> <!-- now you can use the attribute selector -->
Share:
10,586
Chad
Author by

Chad

Updated on June 12, 2022

Comments

  • Chad
    Chad almost 2 years

    Does anybody have any idea on how to implement Amcharts into Angular2 (BETA)?

    I was trying to follow the path/pattern of this question however, I was pretty successful with charts.js, but unfortunately, I can't use charts.js,for my charting program. Since it seems like everything in Angular2 Beta is uncharted territory, I don't have a clue where to start? I mimicked the charts.js example above with no luck, no error.

    /// <reference path="../DefinitelyTyped/amcharts/AmCharts.d.ts" />
    

    There is a DefinitelyTyped library for amcharts (not one for plot.ly yet).

    UPDATE: Here is the directive:

    /// <reference path="../DefinitelyTyped/amcharts/AmCharts.d.ts" />
    
    
    
    import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
    
    @Directive({
    selector: '[chart]',
    })
    
    export class amChartDirective  {
              var chartData = [{date: new Date(2015,2,31,0, 0,      0,      0),value:372.10,volume:2506100},{date: new Date(2015,3,1,0, 0, 0, 0),value:370.26,volume:2458100},{date: new Date(2015,3,2,0, 0, 0, 0),value:372.25,volume:1875300},{date: new Date(2015,3,6,0, 0, 0, 0),value:377.04,volume:3050700}];
              var chart;
              AmCharts.ready(function () {
                  createStockChart();
              });
              function createStockChart() {
                  chart = new AmCharts.AmStockChart();
                  chart.dataDateFormat = "M-D-YY";
                  chart.pathToImages = "http://www.strategic-options.com/trade/3_party/amcharts/images/";
                  var dataSet = new AmCharts.DataSet();
                  dataSet.dataProvider = chartData;
                  dataSet.fieldMappings = [{
                          fromField: "value",
                          toField: "value"
                      }, {
                          fromField: "volume",
                          toField: "volume"
                      }];
                  dataSet.categoryField = "date";
                  chart.dataSets = [dataSet];
                  // PANELS ///////////////////////////////////////////
                  // first stock panel
                  var stockPanel1 = new AmCharts.StockPanel();
                  stockPanel1.showCategoryAxis = false;
                  stockPanel1.title = "Value";
                  stockPanel1.percentHeight = 70;
                  // graph of first stock panel
                  var graph1 = new AmCharts.StockGraph();
                  graph1.valueField = "value";
                  stockPanel1.addStockGraph(graph1);
                  // create stock legend
                  var stockLegend1 = new AmCharts.StockLegend();
                  stockLegend1.valueTextRegular = " ";
                  stockLegend1.markerType = "none";
                  stockPanel1.stockLegend = stockLegend1;
                  // second stock panel
                  var stockPanel2 = new AmCharts.StockPanel();
                  stockPanel2.title = "Volume";
                  stockPanel2.percentHeight = 30;
                  var graph2 = new AmCharts.StockGraph();
                  graph2.valueField = "volume";
                  graph2.type = "column";
                  graph2.fillAlphas = 1;
                  stockPanel2.addStockGraph(graph2);
                  // create stock legend
                  var stockLegend2 = new AmCharts.StockLegend();
                  stockLegend2.valueTextRegular = " ";
                  stockLegend2.markerType = "none";
                  stockPanel2.stockLegend = stockLegend2;
                  // set panels to the chart
                  chart.panels = [stockPanel1, stockPanel2];
    
                  // PERIOD SELECTOR ///////////////////////////////////
                  var periodSelector = new AmCharts.PeriodSelector();
                  periodSelector.periods = [{
    
                          period: "DD",
                          count: 10,
                          label: "10 days"
                      }, {
                          period: "MM",
                          count: 1,
                          label: "1 month"
                      }, {
                          period: "YYYY",
                          count: 1,
                          label: "1 year"
                      }, {
    
                          period: "YTD",
                          label: "YTD"
                      }, {
                          selected: true,
                          period: "MAX",
                          label: "MAX"
                      }];
                  periodSelector.selectFromStart = true;
                  chart.periodSelector = periodSelector;
    
    
                  var panelsSettings = new AmCharts.PanelsSettings();
                  panelsSettings.usePrefixes = true;
                  chart.panelsSettings = panelsSettings;
    
                  //Cursor Settings
                  var cursorSettings = new AmCharts.ChartCursorSettings();
                  cursorSettings.valueBalloonsEnabled = true;
                  cursorSettings.graphBulletSize = 1;
                  chart.chartCursorSettings = cursorSettings;
    
                  // EVENTS
    
                  var e0 = {date: new Date(2016,0,7), type: "arrowDown", backgroundColor: "#FF0707", graph: graph1, text: "Sell Short", description: "Sell Short equity here"};
                  dataSet.stockEvents = [e0];
                  chart.write("chartdiv");
              }
              function hideStockEvents() {
                  window.console.log('woop');
                  chart.hideStockEvents();
              }
              function showStockEvents() {
                  window.console.log('woop');
                  chart.showStockEvents();
              }
    }
    }
    

    Then here is the template.html, from the app.component.ts

    <chart>helllo from AmCharts part 2<divid="chartdiv"  style="width:100%; height:600px;"></div></chart>
    

    The javascript / amcharts code above works in on my php site. W

    When I run the code I don't get any errors.

    I suspect it's one of two things?

    Something is wrong with my Selector or the html get rendered but the JavaScript doesn't "write the chart".

    chart.write("chartdiv");
    

    Finally, it's not throwing any errors in the console, which is really weird because this Angular2 Beta throws errors all the time.

  • Chad
    Chad over 8 years
    Thanks, I don't think that is the the problem, because that's the same way '[chart]' to load the chart.js and it worked for me before I started AmCharts. In addition the amcharts div tags is working on the html, but no charts are populating in div tag. So I'm starting to think it is a loading / write chart. The directive hits the page before html is in the browser.
  • AngularM
    AngularM over 8 years
    I can't get this working: I've followed the plunker and I get this error: "Cannot find name 'AmCharts'. I've added the libs as well"
  • Chad
    Chad over 8 years
    Make sure you are following the answer on I submitted on 2/1/16 and that has the green check by it. That one is working. (I just checked.) I need to remove this answer.
  • AngularM
    AngularM over 8 years
    I get a typescript compiler error saying cannot find name "am charts". This is for when I write: AmCharts.ready(function () { createStockChart(); });
  • Chad
    Chad over 8 years
    Only 3 things I can think of: Your are using the if statements to see if Amcharts is ready? The second is do you have DefinitelyTyped library loaded? Finally you have all the amCharts scripits loaded on the index.html page?
  • AngularM
    AngularM over 8 years
    I load the am scripts on index, where they meant to be?
  • AngularM
    AngularM over 8 years
    It seems it's not sure what am charts are
  • AngularM
    AngularM over 8 years
    It all works fine but the typescript compiler complains that it cannot find name am charts ? Does it need to be imported?
  • Chad
    Chad about 8 years
    I have the same problem with the complier, I just ignored it. (please check the answer if this resolved your problem, thanks.)
  • Aetherix
    Aetherix almost 8 years
    For me it seems like the chartdiv doesn't exist yet when the chart.write function is called. So I run the logic in ngAfterViewInit.
  • heart hacker
    heart hacker almost 7 years
    please provide a working example for amcharts3-angular2 as don't know how to pass data into dataprovider !