0

Please spare me if this is a beginner type of question. I'm playing Highcharts.js with Angular.js, but it's seems like directive scope is not binding to value. Below are my codes.

HTML - but it's working inside this expressions {{xaxis}} {{seriesdata}}

<div class="container" ng-controller='chartController'>
        <div class="row">
            <div class="col-md-6">
                <line-chart xaxis='xaxis' seriesdata='seriesdata'></line-chart>
                {{xaxis}}
                {{seriesdata}}
            </div>
            <div class="col-md-6">
                <bar-chart options='pieOptions'></bar-chart>
            </div>
        </div>
    </div>

directive.js

(function() {
    'use strict';

    angular
        .module('chart')
        .directive('lineChart', lineChartDirective);

    /* @ngInject */
    function lineChartDirective() {
        return {
            restrict: 'E',
            replace: true,
            template: '<div></div>',
            scope: {
                xaxis: '=xaxis',
                seriesdata: '=seriesdata'
            },
            link: function(scope, element) {
                Highcharts.chart(element[0], {
                    chart: {
                        type: 'spline',
                        zoomType: 'x'
                    },
                    plotOptions: {
                        line: {
                            dataLabels: {
                                enabled: true
                            }
                        }
                    },
                    title: {
                        text: 'Profit Ratio by Month'
                    },
                    xAxis: {
                        categories: scope.xaxis
                    },
                    yAxis: {
                        title: {
                            text: 'Profit %'
                        }
                    },
                    series: [
                        {
                            name: 'Total',
                            data: scope.seriesdata
                        }
                    ]
                });
            }
        }
    }
})();

service.js

(function() {
    'use strict';

    angular
        .module('chart')
        .factory('chartData', chartDataFactory);

    chartDataFactory.$inject = ['$http'];

    /* @ngInject */
    function chartDataFactory($http) {
        function getData() {
            return $http.get('../../data/sampleData.json').then(function(result) {
                return result.data;
            })
        }

        return {
            getData: getData
        }
    }
})();

controller.js

(function() {
    'use strict';

    angular
        .module('chart')
        .controller('chartController', chartController);

    chartController.$inject = ['$scope', 'chartData', 'lodash'];

    /* @ngInject */
    function chartController($scope, chartData, lodash) {
        var vm = this;
        chartData.getData().then(function(data) {
            $scope.chartData = data;
            $scope.xaxis = data.SEO[0]["SEO-MOD-001"]["SEO-END-001"];
            $scope.seriesdata = data.SEO[0]["SEO-MOD-001"]["SEO-END-002"];
            console.log($scope.xaxis);
            console.log($scope.seriesdata);
        });

        $scope.pieOptions = {
            chart: {
                type: 'column'
            },
            title: {
                text: 'Projects'
            },
            xAxis: {
                categories: ['Noreil', 'Ken', 'Alfie', 'Francis']
            },
            yAxis: {
                title: {
                    text: 'Completed Projects'
                }
            },
            series: [
                {
                    name: 'Quarter 1',
                    data: [23, 11, 34, 26]
                },
                {
                    name: 'Quarter 2',
                    data: [14, 20, 26, 30]
                }
            ]
        }
    }
})();
5
  • 1
    <line-chart xaxis='{{xaxis}}' seriesdata='{{seriesdata}}'></line-chart> Commented Feb 24, 2016 at 9:02
  • Try to create your directive variables on the scope before your make ajax, maybe it is the problem Commented Feb 24, 2016 at 9:05
  • @vidriduch - I did that too but it's returning parse error. Commented Feb 24, 2016 at 9:06
  • @ioganegambaputifonguser - do you have sample code snippet for that? Commented Feb 24, 2016 at 9:08
  • In case you're interested, there is already an angular module that integrates highcharts: github.com/pablojim/highcharts-ng Might be easier than doing it all from scratch. Commented Feb 24, 2016 at 9:30

1 Answer 1

1

When the directive link function gets executed, you don't have data yet. So try following in link function:

var unwatch = scope.$watch('[xaxis, seriesdata]', function (results) {
    if (results[0] && results[1]) {
        init();
        unwatch();
    }
}, true);

function init() {
    // Highcharts.chart(element[0], { ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

I'm having injection error on $scope, even if its already injected.
question, should I always use this kind of approach if I'm using ajax calls?
@freeman29 I prefer using ui-router or ng-router and resolve data before controller is loaded, so in directive you will already have data. Another option is to use ng-if on directive's element, so it does not get compiled before data is accessible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.