更改使用 AngularJS 呈现 HighChart 的指令

Changing Directive that renders HighChart using AngularJS

我正在使用 Angular 指令来呈现 Highcharts 视觉效果,并试图根据用户输入更改所使用的指令。为了测试,尝试在折线图和柱形图之间切换。 指令是:

myApp.directive('columnChart', function () {
return function (scope, element, attrs) {
    initChart();
    function initChart() {
        var chartConfig = {
            chart: {
                type: 'column',
                zoomType: 'xy'
            },
            title: {
                text: ''
            },
            xAxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            },
            yAxis: [{
                min: 0,
                title: {
                    text: 'Y Axis Label'
                    },
            }],
                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]
                }]
        };
        var chart = $(element).highcharts(chartConfig);
    }
};
});

myApp.directive('lineChart', function () {
return function (scope, element, attrs) {
     initChart();

 function initChart() {
        var chartConfig = {
            chart: {
                type: 'line',
                zoomType: 'xy'
            },
            title: {
                text: ''
            },
            xAxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            },
            yAxis: [{
                min: 0,
                //max:200,
                title: {
                    text: 'Y Axis Label'
                    },
            }],
                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]
                }]
        };
        var chart = $(element).highcharts(chartConfig);
    }
};
});

我有一个简单的测试页面,其中包含更改指令的按钮:

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div ng-controller="MyCtrl">
    <button ng-click="setLineChart()">Set Line Chart</button>
    <button ng-click="setColumnChart()">Set Column Chart</button>
    <div id="container" column-Chart style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</div>

和设置指令的代码:

$scope.setLineChart = function() {
    var docElement = document.getElementById("container");
    var scope = angular.element(docElement).scope();
    var element = angular.element(docElement);
    element.html('<div id="chartContainer" line-Chart style="min-width: 400px; height: 400px; margin: 0 auto"></div>');
    console.log("element: " , element);
    $compile(element)(scope);
};

单击“设置折线图”按钮会导致调用折线图指令,但图表仍解析为柱形图。

这是 jsfiddle:https://jsfiddle.net/MFRTest/xsadzv4f/12/

感谢任何对我遗漏的见解

使用 AngularJS 框架,避免在控制器中操作 DOM。使应用程序更易于理解、调试、测试和维护的框架 separates concerns

取而代之的是根据控制器提供的模型创建 highcharts 的指令:

app.directive("highchart", function() {
  return {
    link: postLink
  }
  function postLink(scope, elem, attrs) {
    scope.$watch(attrs.highchart, function (chartConfig) {
      elem.highcharts(chartConfig);
    }, true)
  }
})

用法:

<button ng-click="$ctrl.chart = $ctrl.lineChart">Set Line Chart</button>
<button ng-click="$ctrl.chart = $ctrl.colChart">Set Column Chart</button>

<div highchart="$ctrl.chart" 
     style="min-width: 300px; height: 300px; margin: 0 auto">
</div>

The DEMO

angular.module("app",[])

.directive("highchart", function() {
  return {
    link: postLink
  }
  function postLink(scope, elem, attrs) {
    scope.$watch(attrs.highchart, function (chartConfig) {
      elem.highcharts(chartConfig);
    })
  }
})

.controller("ctrl", function() {
  this.colChart = {
        chart: {
          type: 'column',
          zoomType: 'xy'
        },
        title: {
          text: ''
        },
        xAxis: {
          categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
          ]
        },
        yAxis: [{
          min: 0,
          //max:200,
          title: {
            text: 'Y Axis Label'
          },
        }],
        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]
        }]
      };
  this.lineChart = {
            chart: {
                type: 'line',
                zoomType: 'xy'
            },
            title: {
                text: ''
            },
            xAxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            },
            yAxis: [{
                min: 0,
                //max:200,
                title: {
                    text: 'Y Axis Label'
                    },
            }],
                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 src="//unpkg.com/jquery"></script>
    <script src="//unpkg.com/highcharts"></script>
    <script src="//unpkg.com/angular/angular.js"></script>
    
  <body ng-app="app" ng-controller="ctrl as $ctrl">
    <h3>Highchart Directive DEMO</h3>
    <button ng-click="$ctrl.chart = $ctrl.lineChart">
      Set Line Chart
    </button>
    <button ng-click="$ctrl.chart = $ctrl.colChart">
      Set Column Chart
    </button>
    <div highchart="$ctrl.chart" 
         style="min-width: 300px; height: 180px; margin: 0 auto">
    </div>
  </body>