Using Angular.js with Highcharts

Logo of Angular and Highcharts

 

 
AngularJS is a popular client-side framework for web applications. It provides enhanced HTML functionality, data binding, MVC pattern structure, routing support, and much more. In this article, we will go over some of the ways Highcharts can be used with AngularJS.

In its simplest form, Highcharts can be loaded and initialized in pure JavaScript from within an Angular controller or in plain JavaScript. The code below shows an example of a webpage using Highcharts (jsFiddle demo)

<!DOCTYPE html>
<html ng-app="myModule">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body ng-controller="myController">
    <div id="container">Placeholder for chart</div>
    <script>
    	angular.module('myModule', [])
    		.controller('myController', function ($scope) {
				Highcharts.chart('container', {

				    xAxis: {
				        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
				            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
				    },

				    series: [{
				        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
				    }]
				});
    		});
    </script>
</body>
</html>

The code above is not optimal since it does not separate the presentation code from logic and data. It also does not take advantage of the extra functionality provided by Angular, such as data binding, for example. One approach to optimizing the code is to write a simple custom Angular directive for Highcharts. This would allow us to follow Angular’s patterns for code separation and reuse. A generic directive might take chart options as an argument. A second approach would be to write a directive for each chart template used, providing the data as an argument. Check the following example to learn more about how to use a custom Angular directive for Highcharts (jsFiddle demo):

<!DOCTYPE html>
<html ng-app="myModule">
<head>
    <meta charset="utf-8" />
    <title> Highcharts directive demo </title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script type="text/javascript" src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body ng-controller="myController">

     <hc-chart options="chartOptions">Placeholder for generic chart</hc-chart>
     <hc-pie-chart title="Browser usage" data="pieData">Placeholder for pie chart</hc-pie-chart>

    <script>
        angular.module('myModule', [])
            // Directive for generic chart, pass in chart options
            .directive('hcChart', function () {
                return {
                    restrict: 'E',
                    template: '<div></div>',
                    scope: {
                        options: '='
                    },
                    link: function (scope, element) {
                        Highcharts.chart(element[0], scope.options);
                    }
                };
            })
            // Directive for pie charts, pass in title and data only    
            .directive('hcPieChart', function () {
                return {
                    restrict: 'E',
                    template: '<div></div>',
                    scope: {
                        title: '@',
                        data: '='
                    },
                    link: function (scope, element) {
                        Highcharts.chart(element[0], {
                            chart: {
                                type: 'pie'
                            },
                            title: {
                                text: scope.title
                            },
                            plotOptions: {
                                pie: {
                                    allowPointSelect: true,
                                    cursor: 'pointer',
                                    dataLabels: {
                                        enabled: true,
                                        format: '<b>{point.name}</b>: {point.percentage:.1f} %'
                                    }
                                }
                            },
                            series: [{
                                data: scope.data
                            }]
                        });
                    }
                };
            })
            .controller('myController', function ($scope) {
                
                // Sample options for first chart
                $scope.chartOptions = {
                    title: {
                        text: 'Temperature data'
                    },
                    xAxis: {
                        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
                    },

                    series: [{
                        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
                    }]
                };

                // Sample data for pie chart
                $scope.pieData = [{
                        name: "Microsoft Internet Explorer",
                        y: 56.33
                    }, {
                        name: "Chrome",
                        y: 24.03,
                        sliced: true,
                        selected: true
                    }, {
                        name: "Firefox",
                        y: 10.38
                    }, {
                        name: "Safari",
                        y: 4.77
                    }, {
                        name: "Opera",
                        y: 0.91
                    }, {
                        name: "Proprietary or Undetectable",
                        y: 0.2
                }]
            });
    </script>
</body>
</html>

The above example could also be expanded using Angular’s watch functionality. In combination with its data binding, this could allow changes in the underlying data to update automatically the chart.

There are several more complex open source Angular directives for Highcharts. Learn more about the most popular directive for Highcharts. This directive is not maintained or officially supported by Highcharts, but remains popular among Highcharts’ developers and users.