<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>
    <script src="http://code.highcharts.com/modules/exporting.js"></script>
    <!--script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script-->
    <script src="http://cdn.staticfile.org/angular.js/1.2.6/angular.js"></script>
    <script src="highcharts-ng.js"></script>
    <script src="script.js"></script>
  </head>

<body>
	<div ng-controller="MyController">
		<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
		<hr />
		<highchart config="chartConfig" class="span10"></highchart>
	</div>
</body>

</html>
var myApp = angular.module('myApp', ['highcharts-ng']);
myApp.controller('MyController', ['$scope', function($scope) {
	var chartConfig = {
          chart: {
              type: 'column'
          },
          title: {
              text: 'Stacked column chart'
          },
          xAxis: {
              categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
          },
          yAxis: {
              min: 0,
              title: {
                  text: 'Total fruit consumption'
              },
              stackLabels: {
                  enabled: true,
                  style: {
                      fontWeight: 'bold',
                      color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
                  }
              }
          },
          legend: {
              align: 'right',
              x: -70,
              verticalAlign: 'top',
              y: 20,
              floating: true,
              backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
              borderColor: '#CCC',
              borderWidth: 1,
              shadow: false
          },
          tooltip: {
              formatter: function() {
                  return '<b>'+ this.x +'</b><br/>'+
                      this.series.name +': '+ this.y +'<br/>'+
                      'Total: '+ this.point.stackTotal;
              }
          },
          plotOptions: {
              column: {
                  stacking: 'normal',
                  dataLabels: {
                      enabled: true,
                      color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
                      style: {
                          textShadow: '0 0 3px black, 0 0 3px black'
                      }
                  }
              }
          },
          series: [{
              name: 'John',
              data: [5, 3, 4, 7, 2]
          }, {
              name: 'Jane',
              data: [2, 2, 3, 2, 1]
          }, {
              name: 'Joe',
              data: [3, 4, 4, 2, 5]
          }]
      };
	$scope.chartConfig = chartConfig;
	
	$('#container').highcharts(chartConfig);
}]);
/* Styles go here */

//https://github.com/pablojim/highcharts-ng

'use strict';

angular.module('highcharts-ng', [])
  .directive('highchart', function () {

    function prependMethod(obj, method, func) {
      var original = obj[method];
      obj[method] = function () {
        var args = Array.prototype.slice.call(arguments);
        func.apply(this, args);
        if(original) {
          return original.apply(this, args);
        }  else {
          return;
        }

      };
    }

    function deepExtend(destination, source) {
      for (var property in source) {
        if (source[property] && source[property].constructor &&
            source[property].constructor === Object) {
          destination[property] = destination[property] || {};
          deepExtend(destination[property], source[property]);
        } else {
          destination[property] = source[property];
        }
      }
      return destination;
    }

    var seriesId = 0;
    var ensureIds = function (series) {
      series.forEach(function (s) {
        if (!angular.isDefined(s.id)) {
          s.id = "series-" + seriesId++;
        }
      });
    }

    var defaultOptions = {
      chart: {
        events: {}
      },
      title: {},
      series: [],
      navigator: {enabled: false}
    }

    var getMergedOptions = function (scope, element, config) {
      var mergedOptions = {}
      if (config.options) {
        mergedOptions = deepExtend(defaultOptions, config.options);
      } else {
        mergedOptions = defaultOptions;
      }
      mergedOptions.chart.renderTo = element[0];
      if(config.xAxis) {
        prependMethod(mergedOptions.chart.events, 'selection', function(e){
          var thisChart = this;
          if(e.xAxis) {
            scope.$apply(function () {
              scope.config.xAxis.currentMin = e.xAxis[0].min;
              scope.config.xAxis.currentMax = e.xAxis[0].max;
            });
          } else {
            //handle reset button - zoom out to all
            scope.$apply(function () {
              scope.config.xAxis.currentMin = thisChart.xAxis[0].dataMin;
              scope.config.xAxis.currentMax = thisChart.xAxis[0].dataMax;
            });
          }
        });

        prependMethod(mergedOptions.chart.events, 'addSeries', function(e){
            scope.config.xAxis.currentMin = this.xAxis[0].min || scope.config.xAxis.currentMin;
            scope.config.xAxis.currentMax = this.xAxis[0].max || scope.config.xAxis.currentMax;
        });
      }

      if(config.xAxis) {
        mergedOptions.xAxis = angular.copy(config.xAxis)
      }
      if(config.title) {
        mergedOptions.title = config.title
      }
      return mergedOptions
    }

    var updateZoom = function (axis, modelAxis) {
      var extremes = axis.getExtremes();
      if(modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) {
        axis.setExtremes(modelAxis.currentMin, modelAxis.currentMax, false);
      }
    }

    var processExtremes = function(chart, axis) {
      if(axis.currentMin || axis.currentMax) {
        chart.xAxis[0].setExtremes(axis.currentMin, axis.currentMax, true);
      }
    }

    var processSeries = function(chart, series) {
      var ids = []
      if(series) {
        ensureIds(series);

        //Find series to add or update
        series.forEach(function (s) {
          ids.push(s.id)
          var chartSeries = chart.get(s.id);
          if (chartSeries) {
            chartSeries.update(angular.copy(s), false);
          } else {
            chart.addSeries(angular.copy(s), false)
          }
        });
      }

      //Now remove any missing series
      for(var i = chart.series.length - 1; i >= 0; i--) {
        var s = chart.series[i];
        if (ids.indexOf(s.options.id) < 0) {
          s.remove(false);
        }
      };

    }

    var initialiseChart = function(scope, element, config) {
      config || (config = {});
      var mergedOptions = getMergedOptions(scope, element, config);
      var chart = config.useHighStocks ? new Highcharts.StockChart(mergedOptions) : new Highcharts.Chart(mergedOptions);
      if(config.xAxis) {
        processExtremes(chart, config.xAxis);
      }
      processSeries(chart, config.series);
      if(config.loading) {
        chart.showLoading()
      }
      chart.redraw();
      return chart;
    }


    return {
      restrict: 'EAC',
      replace: true,
      template: '<div></div>',
      scope: {
        config: '='
      },
      link: function (scope, element, attrs) {

        var chart = initialiseChart(scope, element, scope.config);

        scope.$watch("config.series", function (newSeries, oldSeries) {
          //do nothing when called on registration
          if (newSeries === oldSeries) return;
          processSeries(chart, newSeries);
          chart.redraw();
        }, true);

        scope.$watch("config.title", function (newTitle) {
          chart.setTitle(newTitle, true);
        }, true);

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

        scope.$watch("config.useHighStocks", function (useHighStocks) {
          chart.destroy();
          chart = initialiseChart(scope, element, scope.config);
        });

        scope.$watch("config.xAxis", function (newAxes, oldAxes) {
          if (newAxes === oldAxes) return;
          if(newAxes) {
            chart.xAxis[0].update(newAxes);
            updateZoom(chart.xAxis[0], angular.copy(newAxes));
            chart.redraw();
          }
        }, true);
        scope.$watch("config.options", function (newOptions, oldOptions, scope) {
          //do nothing when called on registration
          if (newOptions === oldOptions) return;
          chart.destroy();
          chart = initialiseChart(scope, element, scope.config);

        }, true);
      }
    }
  });