D3.js结合Angular.js制作图表

Angular中使用D3制作图表,我们可以根据图表的种类创建不同的指令和对应的服务。比如创建一个柱状图时,我们在模块下创建一个barChart指令:

myComponents.directive('barChart', function($compile) {
    'use strict';

    return {
        restrict: 'AE',
        scope: {
            chartTitle: "@",        //图表标题
            series: "=",            //图标的数据
            height: "=?height"      //图表的高度
        },
        controller: function(initBarChart, $scope, $element, $attrs) {
            $scope.height = $scope.height || 200;   //如果高度未定义,则使用默认值200

            var _chart = initBarChart($scope);      //使用服务

            var _chartBody = $element.find(".chart-body");  //获取图表的容器
            _chartBody.height($scope.height);       //设置容器的高度

            _chart.generate($element.find(".chart-body"), $scope.series, {      //使用服务提供的方法生成图表
                height: $scope.height,
            });

            //Do something here...
            
        },
        template: '
' + '
' + '

{{chartTitle}}

' + '
' + '
' + '
' + '
', replace: true }; });

对应的initBarChart服务:

myComponents.service('initBarChart', function() {
    'use strict';

    var charts = function($scope) {
        return {
            generate: function(ele, series, config) {
                ele = $(ele);
                series = series || [];
                config = config || {};
                
                 d3.select(id).selectAll('.svg_barchart').remove();
                //添加svg元素
                var svg = d3.select(id).append("svg")
                    .attr('class', 'svg_barchart')
                //Do something here...
            },
        };
    return charts;
});

我们只需要把D3制作柱状图的关键代码放到generate方法中就可以了。

在页面中使用这个指令:

然后在作用范围包含这个节点的$scope中定义变量operationSeries,用于传递图表中要显示的数据或者配置参数。

监听图表数据的变化

使用Ajax获取数据并进行处理后,发现图表显示不出来。在Chrome的ng-inspect插件中看到$scope.series是有数据的,但是图表中获取不到这个series的值。后来想到可能是图表绘制的时候,series的数据还没有处理好。

于是决定在指令对应的控制器中,使用$watch监听series变量的变化:

//检测数据变化,更新图表 
$scope.$watch('series', function(newData, oldData){
    if(!angular.equals(newData,oldData)){
       _chart.generate($element.find(".chart-body"), newData, {
            height: $scope.height,
        });
    }
}, true); 

你可能感兴趣的:(D3.js结合Angular.js制作图表)