echarts、higncharts折线图或柱状图显示数据为0的点

echarts、higncharts折线图或柱状图只需要后端传到前端一段json数据,接送数据的x轴与y周有对应数据,折线图或柱状图就会渲染出这数据。

比如,x轴表示美每天日期,y轴表示数量。他们的数据都在数据库里存着。如下图:

它们的数据存放数据库中,x轴为每周的周一,并且代表当前周的违规次数或人数。由于3月25日到3月31日那周和4月8日到4月14日那周都没人违规,所以数据库中并没有这两周的任何数据,所以后端从数据库拿到数据并传到前端,渲染出来的图就如上两图了。

若要那两周就算没数据也想展示到图里面,如下两张图:

解决办法如下:

后端:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import web
import json
import time
import datetime
from common.util.login_required import login_required
from common.config.DatabaseConfig import mysql_db

# 
urls = (
    "/visualviolationno***", "VisualViolat***",  # 可视化页面
    "/visualviolationno***", "VisualViolat***",  # 柱状图1数据处理
    "/visualviolationno***", "VisualViolat***",  # 折线图2数据处理
    "/visualviolationno***", "VisualViolat***",  # 饼状图3数据处理
    "/visualviolationno***", "VisualViolat***",  # 柱状图4数据处理
)

render = web.template.render('templates')
app = web.application(urls, globals())


# 可视化页面
class VisualViolationNotification(object):
    def GET(self):
        render = web.template.render('templates')
        return render.violationnotification()


# 柱状图1数据处理
class VisualViolationNot***(object):
    def GET(self):
        data_web = web.input()
        data_name = data_web.i1.encode("gbk")
        date_min = data_web.get('i2')
        date_max = data_web.get('i3')
        if len(date_min) == 7 and len(date_max) == 7:

            sql = "select count(*) count,division from week_violation where substring(date_min,1,7) <= '" + date_max + "' and substring(date_min,1,7) >= '" + date_min + "' group by division"
        else:
            sql = "select count(*) count,division from week_violation where date_min >= '" + date_min + "' and date_max <= '" + date_max + "'  group by division"


        ret = mysql_db.query(sql)
        ret = list(ret)
        list_out = []
        list_count = []
        list_division = []
        for i in ret:
            count = i.get("count")
            list_count.append(count)
            division = i.get("division")
            list_division.append(division)
        list_out.append(list_division)
        list_out.append(list_count)
        return json.dumps(list_out)


# 折线图2数据处理
class VisualViolationNotificationData2(object):
    def GET(self):
        data_web = web.input()
        data_name = data_web.i1.encode("gbk")
        date_min = data_web.get('i2')
        date_max = data_web.get('i3')
        if len(date_min) == 7 and len(date_max) == 7:
            flag = ''
            sql = "select count(*) count,month_min date_min from week_violation where substring(date_min,1,7) <= '" + date_max + "' and substring(date_min,1,7) >= '" + date_min + "' group by month_min"
            ret = mysql_db.query(sql)
            ret = list(ret)
            list1 = []
            total_x = []
            total_y = []
            for tot in ret:
                total_x.append(str(tot.get("date_min")))
                total_y.append(tot.get("count"))
            list1.append(total_x)
            list1.append(total_y)
            list1.append(flag)
            list1 = json.dumps(list1)

        else:
            flag = ''
            sql = "select count(*) count,date_min from week_violation where date_min >= '" + date_min + "' and date_max <= '" + date_max + "' group by date_min"
            ret = mysql_db.query(sql)
            ret = list(ret)
            list1 = []
            total_x = []
            total_y = []
            for tot in ret:
                total_x.append(str(tot.get("date_min")))
                total_y.append(tot.get("count"))
            list1.append(total_x)
            list1.append(total_y)
            list1.append(flag)

            date_min = date_min.encode("utf-8")
            date_min = datetime.datetime.strptime(date_min, "%Y-%m-%d")
            date_max = datetime.datetime.strptime(date_max, "%Y-%m-%d")


            work = workDays(date_min, date_max)
            ret = list(work.workDays())
            l1 = []
            for i in range(len(ret)):
                if i % 2 == 0:
                    l1.append(ret[i].strftime("%Y-%m-%d"))

            for i in l1:
                if i not in list1[0]:
                    list1[1].insert(l1.index(i), 0)
            list1[0] = l1
            list1 = json.dumps(list1)

        return list1


# 饼状图3数据处理
class VisualViolationNotificationData3(object):
    def GET(self):
        data_web = web.input()
        data_name = data_web.i1.encode("gbk")
        date_min = data_web.get('i2')
        date_max = data_web.get('i3')
        if len(date_min) == 7 and len(date_max) == 7:
            sql = "select count(*) count,division from week_violation where substring(date_min,1,7) <= '" + date_max + "' and substring(date_min,1,7) >= '" + date_min + "' group by division"

        else:
            sql = "select count(*) count,division from week_violation where date_min >= '" + date_min + "' and date_max <= '" + date_max + "' group by division"

        ret = mysql_db.query(sql)
        ret = list(ret)

        list1 = []
        for i in ret:
            dict = {}
            dict['y'] = i.get("count")
            dict['name'] = i.get("division")
            list1.append(dict)
        return json.dumps(list1)


# 柱状图4数据处理
class VisualViolationNotificationData4(object):
    def GET(self):

        data_web = web.input()
        data_name = data_web.i1.encode("gbk")
        #date_min = data_web.i2.encode("gbk")
        #date_max = data_web.i3.encode("gbk")
        date_min = data_web.get('i2')
        date_max = data_web.get('i3')

        if len(date_min) == 7 and len(date_max) == 7:
            flag = ''
            sql = "select count(distinct num) count,month_min date_min from week_violation where substring(date_min,1,7) <= '" + date_max + "' and substring(date_min,1,7) >= '" + date_min + "' group by month_min"
            with mysql_db.transaction():
                ret = mysql_db.query(sql)
            ret = list(ret)
            list_out = []
            list_count = []
            list_division = []
            for i in ret:
                count = i.get("count")
                list_count.append(count)
                date_min = i.get("date_min")
                list_division.append(str(date_min))

            list_out.append(list_division)
            list_out.append(list_count)
            list_out.append(flag)
        else:
            flag = ''
            sql = "select count(distinct num) count,date_min from week_violation where date_min >= '" +date_min + "' and date_max <= '" + date_max + "' group by date_min"
            with mysql_db.transaction():
                ret = mysql_db.query(sql)
            ret = list(ret)
            list_out = []
            list_count = []
            list_division = []
            for i in ret:
                count = i.get("count")
                list_count.append(count)
                date_min1 = i.get("date_min")
                list_division.append(str(date_min1))

            list_out.append(list_division)
            list_out.append(list_count)
            list_out.append(flag)

            date_min = date_min.encode("utf-8")
            date_min = datetime.datetime.strptime(date_min, "%Y-%m-%d")
            date_max = datetime.datetime.strptime(date_max, "%Y-%m-%d")

            work = workDays(date_min, date_max)
            ret = list(work.workDays())
            l1 = []
            for i in range(len(ret)):
                if i % 2 == 0:
                    l1.append(ret[i].strftime("%Y-%m-%d"))
            for i in l1:
                if i not in list_out[0]:
                    list_out[1].insert(l1.index(i), 0)
            list_out[0] = l1

        return json.dumps(list_out)


# 计算两个日期之间的周
class workDays():
    def __init__(self, start_date, end_date, days_off=None):
        """days_off:休息日,默认周六日, 以0(星期一)开始,到6(星期天)结束, 传入tupple
        没有包含法定节假日,
        """
        self.start_date = start_date
        self.end_date = end_date
        self.days_off = days_off
        if self.start_date > self.end_date:
            self.start_date, self.end_date = self.end_date, self.start_date
        if days_off is None:
            self.days_off = 1,2,3,4,5
        # 每周工作日列表
        self.days_work = [x for x in range(7) if x not in self.days_off]

    def workDays(self):
        """实现工作日的 iter, 从start_date 到 end_date , 如果在工作日内,yield 日期
        """
        # 还没排除法定节假日
        tag_date = self.start_date
        while True:
            if tag_date > self.end_date:
                break
            if tag_date.weekday() in self.days_work:
                yield tag_date
            tag_date += datetime.timedelta(days=1)

    def daysCount(self):
        """工作日统计,返回数字"""
        return len(list(self.workDays()))

    def weeksCount(self, day_start=0):
        """统计所有跨越的周数,返回数字
        默认周从星期一开始计算
        """
        day_nextweek = self.start_date
        while True:
            if day_nextweek.weekday() == day_start:
                break
            day_nextweek += datetime.timedelta(days=1)
        # 区间在一周内
        if day_nextweek > self.end_date:
            return 1
        weeks = ((self.end_date - day_nextweek).days + 1) / 7
        weeks = int(weeks)
        if ((self.end_date - day_nextweek).days + 1) % 7:
            weeks += 1
        if self.start_date < day_nextweek:
            weeks += 1
        return weeks
#
# date_min = datetime.datetime(2019,1,7)
# date_max = datetime.datetime(2019,2,18)
#
# work = workDays(date_min,date_max)
#
# ret = list(work.workDays())
# # print ret
# l1 = []
# l2 = []
# for i in range(len(ret)):
#     if i % 2 == 0:
#         l1.append(ret[i].strftime("%Y-%m-%d"))
#
# b = ['2019-01-07', '2019-01-21', '2019-01-28', '2019-02-11']
# c = [1,2,3,4]
# print b
# print l1
# for i in l1:
#     if i not in b:
#         c.insert(l1.index(i),0)
# print c

前端

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
    <meta http-equiv="Cache-Control" content="no-siteapp"/>
    <!--[if lt IE 9]>
    <script type="text/javascript" src="../static/ui/lib/html5shiv.js"></script>
    <script type="text/javascript" src="../static/ui/lib/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="../static/ui/static/h-ui/css/H-ui.min.css"/>
    <link rel="stylesheet" type="text/css" href="../static/ui/static/h-ui.admin/css/H-ui.admin.css"/>
    <link rel="stylesheet" type="text/css" href="../static/ui/lib/Hui-iconfont/1.0.8/iconfont.css"/>
    <link rel="stylesheet" type="text/css" href="../static/ui/static/h-ui.admin/skin/default/skin.css" id="skin"/>
    <link rel="stylesheet" type="text/css" href="../static/ui/static/h-ui.admin/css/style.css"/>
    <!--[if IE 6]>
    <script type="text/javascript" src="../static/ui/lib/DD_belatedPNG_0.0.8a-min.js"></script>
    <script>DD_belatedPNG.fix('*');</script>
    <![endif]-->
    <title></title>
</head>
<body>

<div>
<span class="" id="month" style="margin-left: 500px; margin-top: 20px;">
    日期范围
    <input type="text" id="datemin" class="Wdate startTime input-text" name="startTime" style="width:120px;"
           value="2018-01"
           onfocus="WdatePicker({dateFmt:'yyyy-MM',isShowClear:false,isShowToday:false,isShowOK:false,readOnly:true,maxDate:'#F{$$dp.$$D(\'datemax\')}',onpicked:pickedSdate})"/>
    -
    <input type="text" id="datemax" class="Wdate endTime input-text" name="endTime" style="width:120px;"
           value="2018-12"
           onfocus="WdatePicker({dateFmt:'yyyy-MM',isShowClear:false,isShowToday:false,isShowOK:false,readOnly:true,minDate:'#F{$$dp.$$D(\'datemin\')}',startDate:'#F{$$dp.$$D(\'datemin\',{d:+1})}',onpicked:pickedSdate})"/>
    <span id="data-name" class="hide"></span>

    <button type="button" class="btn btn-success radius" id="tijiao" name=""><i class="Hui-iconfont">&#xe665;</i> 搜索
    </button>
</span>


    <span class="text-c hide" id="week" style="margin-left: 500px; margin-top: 20px;">
       日期范围
        <input type="text"
               onfocus="WdatePicker({ maxDate:'#F{$$dp.$$D(\'datemax1\')||\'%y-%M-%d\'}',disabledDays:[0,2,3,4,5,6]})"
               id="datemin1"
               class="input-text Wdate" style="width:120px;">
        -
        <input type="text"
               onfocus="WdatePicker({ minDate:'#F{$$dp.$$D(\'datemin1\')}',maxDate:'%y-%M-%d',disabledDays:[1,2,3,4,5,6]})"
               id="datemax1"
               class="input-text Wdate" style="width:120px;">

        <button type="button" class="btn btn-success radius" id="tijiao1" name=""><i class="Hui-iconfont">&#xe665;</i> 搜索
        </button>
</span>

    <span style="margin-top: 20px;">
    <button id="flag" value="month"></button>
    <a href="javascript: void month()" id="button_month" class="">
    <button class="btn btn-success radius" type="button">月查询</button></a>
        <a href="javascript: void week()" id="button_week" class="hide">
    <button class="btn btn-success radius" type="button">周查询</button></a>
</span>

</div>
<!--视图-->
<div class="page-container">
    <div id="container1" style="width: 50%; float: left"></div>
    <div id="container2" style="width: 50%; float: left;"></div>
    <div id="container3" style="width: 50%; float: left;"></div>
    <div id="container4" style="width: 50%; float: left;"></div>
</div>
<!--_footer 作为公共模版分离出去-->
<script type="text/javascript" src="../static/ui/lib/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="../static/ui/lib/layer/2.4/layer.js"></script>
<script type="text/javascript" src="../static/ui/static/h-ui/js/H-ui.min.js"></script>
<script type="text/javascript" src="../static/ui/static/h-ui.admin/js/H-ui.admin.js"></script>
<!--/_footer 作为公共模版分离出去-->

<!--请在下方写此页面业务相关的脚本-->
<script type="text/javascript" src="../static/ui/lib/hcharts/Highcharts/5.0.6/js/highcharts.js"></script>
<script type="text/javascript" src="../static/ui/lib/hcharts/Highcharts/5.0.6/js/modules/exporting.js"></script>
<script type="text/javascript" src="../static/ui/lib/hcharts/Highcharts/5.0.6/js/highcharts-3d.js"></script>
<script type="text/javascript" src="../static/ui/lib/My97DatePicker/4.8/WdatePicker.js"></script>
<script type="text/javascript" src="../static/ui/lib/datatables/1.10.0/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="../static/ui/lib/jquery.contextmenu/jquery.contextmenu.r2.js"></script>
<script type="text/javascript" src="../static/ui/lib/laypage/1.2/laypage.js"></script>
<script type="text/javascript">

    function month() {
        $$("#month").toggleClass("hide");
        $$("#week").toggleClass("hide");
        $$("#button_month").toggleClass("hide");
        $$("#button_week").toggleClass("hide");
        $$("#flag").val("week");
    }

    function week() {
        $$("#month").toggleClass("hide");
        $$("#week").toggleClass("hide");
        $$("#button_month").toggleClass("hide");
        $$("#button_week").toggleClass("hide");
        $$("#flag").val("month");
    }


    // 只让日期插件显示年和月份
    $$(function () {
        //日期显示当月
        (function () {
            var date = new Date();
            date.setMonth(date.getMonth() - 6);
            var date_zero = date.toLocaleDateString().split("/");
            console.log(date_zero);
            var mydate_min = (date_zero[0] < 10 ? "0" + date_zero[0] : date_zero[0]).toString() + "-" + (date_zero[1] < 10 ? "0" + date_zero[1] : date_zero[1]).toString();

            date.setMonth(date.getMonth() + 5);
            var date_none = date.toLocaleDateString().split("/");
            var mydate_max = (date_none[0] < 10 ? "0" + date_none[0] : date_none[0]).toString() + "-" + (date_none[1] < 10 ? "0" + date_none[1] : date_none[1]).toString();
            console.log(mydate_max);

            // var year_min = "2018";
            // var year_max = "2018";
            // // var month = date.getMonth() + 1;
            // var month_min = "1";
            // var month_max = "12";
            // month_min = (month_min < 10 ? "0" + month_min : month_min);
            // month_max = (month_max < 10 ? "0" + month_max : month_max);
            // var mydate_min = (year_min.toString() + '-' + month_min.toString());
            // var mydate_max = (year_max.toString() + '-' + month_max.toString());
            $$('.startTime').val(mydate_min);
            $$('.endTime').val(mydate_max);


            // 当前库的名称
            var data_name = "******";


            // 处罚搜索框时间
            $$('#tijiao').click(function () {

                // 重新加载
                func1();

            });
            // 处罚搜索框时间
            $$('#tijiao1').click(function () {

                // 重新加载
                func1();

            });


            // 视图函数
            $$(
                func1()
            );


            function func1() {
                // 获取当前日期搜索框日期
                var data_min = $$("#datemin").val();
                var data_max = $$("#datemax").val();


                if ($$("#flag").val() == "month") {
                    data_min = $$("#datemin").val();
                    data_max = $$("#datemax").val();


                }

                if ($$("#flag").val() == "week") {
                    data_min = $$("#datemin1").val();
                    data_max = $$("#datemax1").val();
                }


                // 次数-部门 柱状图
                $$.ajax({
                    url: "***",
                    type: "GET",
                    data: {"i1": data_name, "i2": data_min, "i3": data_max},
                    success: function (data) {
                        var data = JSON.parse(data);
                        var data_x = data[0];
                        var data_y = data[1];
                        // Set up the chart
                        $$('#container1').highcharts({
                            chart: {
                                type: 'column'
                            },
                            title: {
                                text: data_min + '' + data_max + ' 各部门违规人次'
                            },
                            subtitle: {
                                text: '人次/部门'
                            },
                            xAxis: {
                                categories: data_x
                            },
                            yAxis: {
                                min: 0,
                                title: {
                                    text: '违规人次'
                                }
                            },
                            tooltip: {
                                headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                                pointFormat: '<tr><td style="color:{series.color};padding:0">共有</td>' +
                                    '<td style="padding:0"><b>{point.y:.1f} 次</b></td></tr>',
                                footerFormat: '</table>',
                                shared: true,
                                useHTML: true
                            },
                            plotOptions: {
                                column: {
                                    pointPadding: 0.2,
                                    borderWidth: 0,
                                    dataLabels: {enabled: true}
                                }
                            },
                            series: [{
                                name: '各部门',
                                data: data_y

                            }]
                        });


                    }
                });

                // 次数-部门 饼状图
                $$.ajax({
                    url: "***",
                    type: "GET",
                    data: {"i1": data_name, "i2": data_min, "i3": data_max},
                    success: function (data) {
                        var data = JSON.parse(data);
                        $$('#container2').highcharts({
                            chart: {
                                plotBackgroundColor: null,
                                plotBorderWidth: null,
                                plotShadow: false
                            },
                            title: {
                                text: data_min + '' + data_max + ' 各部门违规人次占比'
                            },
                            tooltip: {
                                pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
                            },
                            plotOptions: {
                                pie: {
                                    allowPointSelect: true,
                                    cursor: 'pointer',
                                    dataLabels: {
                                        enabled: true,
                                        color: '#000000',
                                        connectorColor: '#000000',
                                        format: '<b>{point.name}</b>: {point.percentage:.1f} %'
                                    }
                                }
                            },
                            series: [{
                                type: 'pie',
                                name: '占比',
                                data: data
                            }]
                        });


                    }
                });


                // 次数-月份 折线图
                $$.ajax({
                    url: "***",
                    type: "GET",
                    data: {"i1": data_name, "i2": data_min, "i3": data_max},
                    success: function (data) {
                        var data = JSON.parse(data);
                        var data_x = data[0];
                        var data_y = data[1];
                        var date_type = data[2];
                        $$('#container3').highcharts({
                            chart: {
                                zoomType: 'xy',
                                spacingRight: 20
                            },
                            title: {
                                text: data_min + '' + data_max + ' 各个' + date_type + '违规人次'
                            },
                            subtitle: {
                                text: document.ontouchstart === undefined ?
                                    '人次/' + date_type :
                                    '人次/' + date_type
                            },
                            xAxis: {
                                type: 'linear',
                                categories: data_x,
                                title: {
                                    text: '' + date_type
                                }
                            },
                            yAxis: {
                                title: {
                                    text: '违规人次'
                                }
                            },
                            tooltip: {
                                shared: true
                            },
                            legend: {
                                enabled: false,
                                align: 'center',
                                verticalAlign: 'middle'
                            },
                            plotOptions: {
                                line: {
                                    dataLabels: {
                                        enabled: true
                                    }
                                },
                                area: {
                                    fillColor: {
                                        linearGradient: {x1: 0, y1: 0, x2: 0, y2: 1},
                                        stops: [
                                            [0, Highcharts.getOptions().colors[0]],
                                            [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
                                        ]
                                    },
                                    lineWidth: 1,
                                    marker: {
                                        enabled: false
                                    },
                                    shadow: false,
                                    states: {
                                        hover: {
                                            lineWidth: 1
                                        }
                                    },
                                    threshold: null
                                },

                            },
                            series: [{
                                name: "人次",
                                data: data_y
                            }]
                        });
                    }
                });

                // 人数-月份 柱状
                $$.ajax({
                    url: "***",
                    type: "GET",
                    data: {"i1": data_name, "i2": data_min, "i3": data_max},
                    success: function (data) {
                        var data = JSON.parse(data);
                        var data_x = data[0];
                        var data_y = data[1];
                        var date_type = data[2];

                        // Set up the chart
                        $$('#container4').highcharts({
                            chart: {
                                type: 'column'
                            },
                            title: {
                                text: data_min + '' + data_max + ' 各个' + date_type + '违规人数'
                            },
                            subtitle: {
                                text: '人数/' + date_type
                            },
                            xAxis: {
                                categories: data_x
                            },
                            yAxis: {
                                min: 0,
                                title: {
                                    text: '违规人数'
                                }
                            },
                            tooltip: {
                                headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                                pointFormat: '<tr><td style="color:{series.color};padding:0">本' + date_type + '共</td>' +
                                    '<td style="padding:0"><b>{point.y:.1f} 次</b></td></tr>',
                                footerFormat: '</table>',
                                shared: true,
                                useHTML: true
                            },
                            plotOptions: {
                                column: {
                                    pointPadding: 0.2,
                                    borderWidth: 0,
                                    dataLabels: {enabled: true}
                                }
                            },
                            series: [{
                                name: '' + date_type,
                                data: data_y

                            }]
                        });


                    }
                });


            }
        })();
    });

    //获取选中的值
    function pickedSdate() {
        var _val = this.value,
            _name = this.name;
        if (_name == 'startTime') {
            $$('.sTime').text(_val);
        } else if (_name == 'endTime') {
            $$('.eTime').text(_val);
        }
        //执行统一搜索
    }

</script>
</body>
</html>

注意:以上后端使用web.py框架和前端使用H-ui框架,认真看并不难

数据库类型如下:

id      名字    账户           违规内容             所属周周一        所属周周日           部门             所属月份
1540 张* ****** 内勤请假登陆堡垒机 2019-02-25 2019-03-03 核心系统开发部 2019-02
1541    李*    ******    堡垒机违规操作          2019-03-11       2019-03-17        核心系统开发部      2019-03

 

猜你喜欢

转载自www.cnblogs.com/aaronthon/p/10716862.html
0条评论
添加一条新回复