2

I'm trying to write a directive for HighCharts in AngularJS which supports two way data binding as well as click events on charts.

Directive:

app.directive('highchart', function () {
    return {
        restrict: 'E',
        template: '<div></div>',
        replace: true,
        link: function (scope, element, attrs) {
             scope.$watch(scope.example_chart, function() {
             var chart = JSON.parse(attrs.chart)
             element.highcharts(chart);
             }
        }
    }
});

Now, when I write my HTML like this:

<div>            
     <highchart chart='example_chart'></highchart>
</div>

It supports the click event, but not two way data binding.

And, when it is passed as an expression:

<div>            
     <highchart chart='{{example_chart}}'></highchart>
</div>

It supports two way data binding but the function written in JSON of example_chart for click event doesn't get parsed and hence not functioning.

So, suggest a way to handle both the cases in AngularJS way.

dobydx
  • 57
  • 1
  • 2
  • 11

1 Answers1

3

highcharts-ng

You can use highcharts-ng directive, See usage here: Fiddle

Also you can use custom directive:

Custom

See demo in Fiddle

Actually there is nothing special here, pretty simple isolate scope directive with watcher on highChart configuration (defined as JSON).

I my case I used several watchers on specific fields to improve perforamnce but you can run deep watch on all config object


HTML

<high-chart config="chartConfig"> </high-chart> 

JS

myapp.directive('highChart',
   function () {
       return {
           restrict: 'E',
           replace:true,
            scope: {
            config: '='  
           },
           template: '<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
           link: function (scope, element, attrs) {

                var chart = false;

                var initChart = function() {
                  if (chart) chart.destroy();
                  var config = scope.config || {};
                  //var mergedOptions = getMergedOptions(scope, element, config);
                  chart = new Highcharts.Chart(config);

                  if(config.loading) {
                    chart.showLoading();
                  }

                };
                initChart();


       scope.$watch('config.loadRandomData', function (value) {
           if(value == false){return;}

           chart.series[0].setData(scope.config.series[0].data);          

           scope.config.loadRandomData = false;
        }, true);


        scope.$watch('config.loading', function (loading) {
          if(loading) {
            chart.showLoading();
          } else {
            chart.hideLoading();
          }
        });

       scope.$watch('config.series[0].type', function (type) {

         chart.series[0].update({type: type});        
        });

        scope.$watch('config.series[0].dataLabels.enabled', function (enableDataLabels) {          
         chart.series[0].update({dataLabels: {enabled: enableDataLabels}});        
        });                
         }//end watch           
       }
   }) ;

enter image description here

Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225