当前位置: 首页 > 工具软件 > Highcharts-ng > 使用案例 >

在python下angularJS关于多图表highcharts数据处理详解

麻超
2023-12-01

 

highcharts再angularJS中生成单例图表非常容易,但是生成多图表比较困难。为此研究了很久。以下为详细说明。

准备工作:1、在directive中封装一个highcharts的指令。

app.directive('highcharts', function () {
    return {
        require: '?ngModel',
        restrict: 'EA',
        link: function (scope, element, attrs, ngModel) {
            //选项
            var opts = angular.extend({
                title: {text: '', enabled: false},
                chart: {type: 'column'},
                credits: {enabled: false},
                //显示打印
                exporting: {
                    enabled: false
                },
                xAxis: {
                    labels: {
                        y: -10,     //x轴标签位置
                        enabled: false
                    }
                },
                yAxis: {
                    allowDecimals: true,
                    title: {
                        text: ' '
                    }
                },
                series: [],
                tooltip: {}
            }, scope.$eval(attrs.highcharts));
            // var chartrsID = "#" + pagerID;

            var opt_data = opts.data;
            var new_opts = {
                title: opts.title,
                chart: opts.chart,
                credits: opts.credits,
                exporting: opts.exporting,
                xAxis: opts.xAxis,
                yAxis: opts.yAxis,
                series: [],
                tooltip: opts.tooltip,
            };

            var initChart = function () {
                new_opts.plotOptions = {
                    column: {
                        pointPadding: 0.2,
                        borderWidth: 0
                    },
                    series: {
                        cursor: 'pointer',
                        point: {
                            events: {
                                click: function (opt) {
                                    if (new_opts.series[opt.point.series.index].url != undefined)
                                        location.href = new_opts.series[opt.point.series.index].url;
                                }
                            }
                        },
                        animation: false
                    }
                };
                $(element).highcharts(new_opts)
            };

            scope.$watch(opts.data, function (a) {
                if (a != undefined && a.length != undefined) {
                    new_opts.series.splice(0, new_opts.series.length);
                    for (var i = 0; i < a.length; i++) {
                        new_opts.series.push(a[i]);
                        // new_opts.series[i].data = [a[i]];
                    }
                    initChart();
                }
            });

            // scope.$watch(opts.data + '.length', function (b) {
            //     if (b != undefined && b != 0) {
            //         new_opts.series.splice(0, new_opts.series.length);
            //         for (var i = 0; i < b; i++) {
            //             new_opts.series.push(opts.data[i]);
            //             // new_opts.series[i].data = [a[i]];
            //         }
            //         initChart();
            //     }
            // });


        }
    };
});

                  2、初始化一个highcharts并在js文件中指向它(

                       2.1  HTML

<div>highcharts="linechart" style="width:100%;height: 400px;"></div>

                       2.2 javascript

//数据源
$scope.lineList = [];

//highchair初始化
$scope.linechart = {
        data: "lineList",
        chart: {type: 'line'}, /*常用的线图为:line,柱状图为:column,横向柱状图为:bar,区域图为:area*/
        title: {text: '主机状态', enabled: true},
        xAxis: {
            categories: []
        },
        plotOptions: {
            boxplot: {
                pointPadding: 0
            }
        },
        //提示框位置和显示内容
        tooltip: {
            pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
            '<td style="padding:0"><b>{point.y:f}</b></td></tr>',
            headerFormat: ""
        }
    };

在以上工作准备完成后分析数据源格式:

首先单例情况下:

      我们看到,在初始化highchair数据时,$scope.linechart 中的data 数据源等于一个"lineList"字符串,这个字符串等价于$scope.lineList,这里我们把”lineList“看成一个指针字符,指向了$scope.lineList中的数据,在$scope.linechart中引用”lineList“实际上时引用$scope.lineList中的数据。这是angularJS的机制还是highchair的问题,我没有仔细去找答案。多图例情况的难点就是在这里,如何创建多个指针字符去指向多条数据是关键。接下来先讲单图例,然后是多图例。

单图例:

def host_perform_status(request):
    """单图例数据源"""
    line_list = [
        # 线图一个字典代表一条线,data里面的必须是数字类型或浮点数类型
        {"name": u"线1", "data": [11, 2, 13, 4, 15, 6]},
        {"name": u"线2", "data": [7, 16, 5, 14, 3, 12]},
        {"name": u"线3", "data": [7, 16, 5, 14, 3, 12]},
    ]
    # 横坐标,一般用字符串列表,列表长度和data保持一致即可
    categories = ['a', 'b', 'c', 'd', 'e', 'f']
    return render_json({'result': True, 'line_list': line_list, 'categories': categories})

后台数据源比较简单,格式处理成折线图的数据源,返回数据源和横坐标

$scope.lineList = res.line_list;
$scope.linechart.xAxis.categories = res.categories;

讲数据源给到$scope.lineList 横坐标给到$scope.linechart.xAxis.categories

<div highcharts="linechart" style="width:100%;height: 400px;"></div>

前端

以上是单一图例,接下来是多图例。

//查询多条主机的监控信息
def search_host_list(request):
    ilter_obj = json.loads(request.body)
    //是否有做查询,有则返回满足查询条件的数据,否则返回全部数据(业务)
    if filter_obj["appID"] == "":
        servers = Servers.objects.filter(is_deleted=False)
    else:
        servers = Servers.objects.filter(app_id=filter_obj["appID"],is_deleted=False)
    //是否有做查询,有则返回满足查询条件的数据,否则返回全部数据(ip,多条ip用回车分割)
    if filter_obj["ip"].strip():
        ip_list = filter_obj["ip"].split("\n")
        servers = servers.filter(ip_address__in=ip_list,is_deleted=False)
    return_data = []
    //保存多条监控数据格式k:v=={"name": u"线1", "data": [11, 2, 13, 4, 15, 6]}
    perform_obj = {}
    for i in servers:
        key = i.ip_address.replace(".", "_")
        result = get_one_server_line_chart_data(i)
        //关键1:name的值就是指针字符串
        //关键2:每个图表单独的横坐标
        one_obj = {
            "ip_address": i.ip_address,
            "name": 'performObj.ip%s' % key,
            "categories": result['categories']
        }
        //将指针字符和横坐标加入list中
        return_data.append(one_obj)
        //数据源的key='ip+key',注意,没有performObj的前缀,后在js中会说明处理原因
        perform_obj["ip" + key] = result["data"]
    return render_json({"result": True, "data": return_data, "perform_obj": perform_obj})


//单条格式处理
def get_one_server_line_chart_data(i):
    date_now = datetime.datetime.now() + datetime.timedelta(hours=-1)

    server_performs = ServerPerformance.objects.filter(server_id=i.id, when_created__gt=str(date_now).split(".")[0]).order_by("id")
    one_obj = [
        {"name": "cpu", "data": [i.cpu_usage for i in server_performs]},
        {"name": "mem", "data": [i.mem_usage for i in server_performs]},
        {"name": "disk", "data": [i.disk_usage for i in server_performs]},
    ]
    return {"categories": [i.when_created for i in server_performs], "data": one_obj}
//筛选条件
$scope.filterObj = {
        appID: "",
        ip: ""
    };

$scope.searchList = function () {
        loading.open();
        sysService.search_server_perform_list({}, $scope.filterObj, function (res) {
            loading.close();
            if (res.result) {
                $scope.is_search = true;
                $scope.serverPerforms = res.data;
                $scope.performObj = res.perform_obj;
                //对$scope.serverPerforms循环,i是每次循环一次的内容
                angular.forEach($scope.serverPerforms, function (i) {
                    //angular.extend(a,b) b属性给a 并返回a
                    //在i变量中创建一个chartOptions实例,每个实例都对应着highOption对象。i.chartOptions的值就是具体highOption的值,这里将数据源给到data,i.name等于"performObj.ip192_168_163_130",即指向了数据源$scope.performObjkey等于ip192_168_163_130的数据
                    i.chartOptions = angular.extend($scope.highOption, {
                        data: i.name,
                        xAxis: {categories: i.categories}
                    });
                    console.log(i.chartOptions)
                })
            }
        })
    };
<div style="margin-top: 5px;width:100%;overflow-y:auto">
        <div ng-if="is_search && serverPerforms.length==0" style="text-align: center">
            没有查到相关主机
        </div>
        <div ng-repeat="i in serverPerforms" style="width:50%;float: left;padding:5px;height: 380px;">
            <div style="line-height: 30px;font-size: 14px;"><span>{{ i.ip_address }}</span></div>
            <div style="width:100%;height: 320px" highcharts="i.chartOptions"></div>
        </div>
    </div>

以上就是全部的分享。

 类似资料: