Search code examples
javascriptangularjshighchartshighcharts-ng

Creating Highcharts with Angular using Highcharts >= 5.0.0 and highcharts-ng >= 1.0.0 using a ChartFactory


I would like to make the transition from pre-version 5.0.0 Highcharts and highcharts-ng version 0.0.12 to the latest versions.

I know there are some critical changes in the chart object, as well as with how highcharts-ng works in the latest versions. I have been searching for an example on how to set my Angular environment up using these latest versions, but it seems there is a great shortage on resources using these versions.

I was hoping you could help me with setting this up.

I have tried numerous changes myself, but I keep getting errors I did not get with the older versions of the scripts. Errors such as:

  1. "Unable to get property of 'series' of undefined or null reference (at $doCheck (http://localhost:50262/app/vendorScripts/highcharts-ng.js:51:16))",
  2. "Cannot set property 'getChartObj' of undefined" (at HighChartNGController.$onInit (highcharts-ng.js:36)),
  3. "Multiple definitions of a property not allowed in strict mode (ChartFactory)"

This is my working solution pre-latest versions:

Here is my ChartFactory:

'use strict';

angular.module('portalDashboardApp')
  .factory('ChartFactory', function () {

      return {
          getChartConfig: function () {
              return {
                  options: {
                      chart: {
                          type: 'bar',
                          height: 400,
                          spacingTop: 30,
                          spacingBottom: 10,
                          spacingLeft: 10,
                          spacingRight: 50,
                          zoomType: 'x',
                          backgroundColor: false,
                          resetZoomButton: {
                              position: {
                                  x: 0,
                                  y: 40
                              }
                          }
                      },
                      credits: {
                          enabled: false
                      },
                      navigation: {
                          buttonOptions: {
                              y: -30
                          }
                      },
                      tooltip: {
                          formatter: function () {
                              return '<b>' + this.y + ' ' + this.series.name + '</b>';
                          }
                      },
                      plotOptions: {
                          column: {
                              stacking: ''
                          },
                          pie: {
                              allowPointSelect: true,
                              cursor: 'pointer',
                              dataLabels: {
                                  enabled: true,
                              },
                              showInLegend: true
                          },
                          series: {
                              animation: true,
                              point: {
                                  events: {
                                      click: function () {

                                      }
                                  }
                              },
                              dataLabels: {
                                  enabled: true,
                                  format: ''
                              }
                          }
                      },
                      exporting: {
                          sourceWidth: 1600,
                          sourceHeight: 800,
                          // scale: 2 (default)
                          chartOptions: {
                              subtitle: null
                          },
                          buttons: {
                              contextButton: {
                                  text: 'Export Chart'
                              }
                          }
                      }
                  },
                  title: {
                      text: false
                  },
                  xAxis: {
                      type: 'category'
                  },
                  yAxis: {
                      gridLineWidth: 1,
                      title: {
                          text: 'Count'
                      },
                      labels:
                      {
                          enabled: true,
                          format: '{value}'
                      }
                  },
                  legend: {
                      layout: 'vertical',
                      floating: true,
                      backgroundColor: '#FFFFFF',
                      align: 'right',
                      verticalAlign: 'top',
                      y: 60,
                      x: -60
                  },
                  series: [{}],
                  loading: false
              };
          }
      };
  });

This is how I would create a chart in my Angular controller:

  1. I would inject my ChartFactory
  2. Get my data from mt API call

And then set up, customize and apply my data for my chart using these methods:

function volumeGraphConfig(timeline_data, time_trend) {
    $scope.VolumeGraphChartConfig = ChartFactory.getChartConfig();
    $scope.VolumeGraphChartConfig.chart.type = 'column';
}

function populateVolumeData(timeline_data, time_trend) {

    $scope.VolumeGraphChartConfig.xAxis.categories = timeline_data;

    $scope.VolumeGraphChartConfig.series = [{
        name: 'Twitter',
        data: time_trend.Twitter,
        color: twitterColor
    }, {
        name: 'Instagram',
        data: time_trend.Instagram,
        color: instagramColor
    }, {
        name: 'Youtube',
        data: time_trend.Youtube,
        color: youtubeColor
    }];

    $scope.VolumeGraphChartConfig.tooltip = {
        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <strong>{point.y}</strong> mentions<br/>',
        shared: false
    };
}

I would then display my chart using this HTML div:

<highchart id="FacebookVolume" config="volumeGraphChartConfig"></highchart>

How can I change this to work with the latest versions? Thank you!


Solution

  • The first two errors:

    Cannot set property 'getChartObj' of undefined

    Unable to get property of 'series' of undefined or null reference

    happen when your config object is undefined.


    For your case, you need to use the same variable you declared on your $scope

    <highchart id="FacebookVolume" config="VolumeGraphChartConfig"></highchart>
    

    (capital V)