首页> 前端开发> AngularJs 封装使用highchart

[文章]AngularJs 封装使用highchart

收藏
0 23 0

前言

最近项目中AngularJs 需要用到highchart 插件,遇到了不少问题。但是因为AngularJs已经不维护了,资料很少,踩了不少坑,借此记录一下使用心得。

1. 封装成指令

AngularJs用到插件的话,一般都会将插件封装成一个可配置的指令,这样有利于复用。

以下是highchart的指令封装,一些指令常识和逻辑解释都放在代码的注释中:

```js

//使用驼峰法来命名一个指令

app.directive('myChart', function () {

    return {

        restrict: 'AE',//A:作为属性使用,E:作为元素名使用

        replace: true,//是否采用HTML模板替换原有的元素

        template: '<div></div>',//与指令关联的HTML模板

        link: function (scope, element, attrs) {

            var defaultOptions = {

                chart: {

                    type: 'line'

                },

                title: {text: '', enabled: false},

                credits: {enabled: false},

                //显示打印

                exporting: {

                    enabled: false

                },

                xAxis: {

                    labels: {

                        y: -10,     //x轴标签位置

                        enabled: false

                    }

                },

                yAxis: {

                    allowDecimals: true,

                    title: {

                        text: ' '

                    }

                },

                legend: {},

                series: [],

                tooltip: {},

                drilldown: {},

                plotOptions: {

                    column: {

                        pointPadding: 0,

                        borderWidth: 0

                    },

                    series: {

                        cursor: 'pointer',

                        marker: {

                            enabled: false, /*数据点是否显示*/

                            radius: 3,  /*数据点大小px*/

                            //fillColor:'#ff3300'         /*数据点颜色*/

                        },

                        borderWidth: 0,

                        dataLabels: {

                            enabled: false

                        }

                    }

 

                }

            };

 

            var options = angular.extend(defaultOptions, scope.$eval(attrs.myChart));

            console.log("attrs", attrs);

            console.log("config", scope.$eval(attrs.myChart));

 

            var process = function (opt) {

                $(element).highcharts(opt);//生成图形

            };

 

            var opts = angular.copy(options);//深度拷贝

 

            /**

             * 1、经过测试,发现如果改变对象里面的值,有时候$watch也观测不到变,

             * 即使$watch的第三个参数是true也不行。

             * 2highchart的配置参数中,必须都是api里有的参数。

             * 如果配置参数中存在api没有的参数,highchart会报错

             */

            scope.$watch(options.watchData, function (seriesData) {

                // console.log(seriesData);

                if (seriesData != undefined) {

                    if (seriesData.tickInterval) {

                        opts.xAxis.tickInterval = seriesData.tickInterval;

                    }

                    if (seriesData.categories) {

                        opts.xAxis.categories = seriesData.categories;

                    }

                    if (seriesData.series) {

                        opts.series = seriesData.series;

                    }

                    process(opts);

                }

            }, true);

        }

    };

});

```

遇到的坑:

1、经过测试,发现如果改变对象里面的值,有时候 $watch也观测不到变, 即使$watch的第三个参数是true也不行。

2highchart的配置参数中,必须都是api里有的参数。 如果配置参数中存在api没有的参数,highchart会报错

 

记录所用知识:

深拷贝:在堆中重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响;angularJs实现深拷贝的方法是angular.copy(args)

 

之所以要用到深拷贝,是因为highchart的特性有关(不知道是不是因为版本问题),如果highchart配置中没有这个参数,强加进去会报错。但是又需要一个参数(可以自行设置,比如watchData)来检测变化的数据,所以就需要保留原有的参数不变,重新设立一个参数opts。如果简单的进行‘=’赋值,就会是浅拷贝,就没有了意义。

 

$eval服务:$eval是一个作用域scope中的方法,它将会在当前作用域中执行一个表达式并返回结果.

 

scope.$eval(attrs.myChart),这里用到$eval是因为可以解析属性中myChart这个对象里面表达式watchData的值。因为{watchData: “data”}data 值来自$scope.data={}

 

2.使用

<div my-chart="cpu_rate" style="width:100%;height: 90%"></div>

$scope.cpu_rate={

   chart: {type: 'line'},

            yAxis: {

                labels: {

                    format: '{value}%'

                }

            },

            xAxis: {

                type: 'datetime',

                dateTimeLabelFormats: {

                    second: '%M:%S',

                    minute: '%M:%S',

                    hour: '%H:%M:%S',

                    day: '%Y-%m-%d'

                },

                //1 * 3600 * 1000 x轴间隔为小时

                //24 * 3600 * 1000  x轴间隔为天

                tickInterval: 1 * 3600 * 1000

            },

            //提示框位置和显示内容

            tooltip: {

                crosshairs: [{

                    width: 1,

                    color: 'red'

                }],

                xDateFormat: '%m-%d %H:%M:%S',

                shared: true,

            },

            legend: {

                layout: 'horizontal',

                align: 'center',

                verticalAlign: 'bottom',

                borderWidth: 0

            },

            series: [],

            watchData: "data"

}

注意: 这里的时间戳为毫秒级别,记得*1000当采用时间为x轴间距时,hightcharts会有8小时的误差显示,解决办法就是 +8*3600*1000。时间戳一定得是数字类型,不能是字符串类型,否则会报错。

前端开发
最近热帖
{{item.Title}} {{item.ViewCount}}
近期热议
{{item.Title}} {{item.PostCount}}