JS组件 + django hightcharts画折线图 饼图,柱状图

一,折线图

1.前端

<script src="{% static "plugin/highcharts/highcharts.js" %}"></script>
引用
<div class="panel panel-default">
                    <div class="panel-heading">
                        <i class="fa fa-bar-chart" aria-hidden="true"></i>
                        新增问题趋势
                    </div>
                    <div class="panel-body">
                        <div id="chart" style="100%;min-height:200px"></div>
                    </div>
                </div>
前端html展示
<script>
        var init_chart_url = "{% url "issues_chart" project_id=request.tracer.project.id %}"

        $(function () {
            initChart();
        })
        Highcharts.setOptions({global:{
            useUTC:false
            }});
        function initChart() {
            var config = {
            title: {
                text: null
            },
            subtitle: {
                text: null
            },
            yAxis: {
                title: {
                    text: '问题数量'
                }
            },
            xAxis:{
                type:"datetime",
                tickInterval:60*60*24*1000,
                labels:{
                    //轴标签格式化
                    formatter:function () {
                        return Highcharts.dateFormat("%m-%d",this.value)
                    },
                    rotation:-30 //旋转角度
                }
            },
            tooltip:{
                //鼠标悬浮后提示 (数据提示框)
                headerFormat:"<b>{point.key}</b><br>",
                pointFormat:"<span style='{series.color}'>u25CF</span> 数量:{point.y}",
                xDateFormat:"%Y-%m-%d",

            },

            legend: {
                enabled:false
            },
            credits: {
                enabled:false
            },

            plotOptions: {
                    area: {
                        stacking: 'normal',
                        lineColor: '#666666',
                        lineWidth: 1,
                        marker: {
                            lineWidth: 1,
                            lineColor: '#666666'
                        }
                    }
                },
            series: [{
                data:[]
            }],

        };
            $.get(
                init_chart_url,{},
                function (res) {
                    config.series[0].data=res.data;
                    var chart = Highcharts.chart('chart', config);
                }
            );

        }



    </script>
前端js

2.后端

def issues_chart(request,project_id):
    """ 在概览页面生成highcharts所需的数据 """

    # dict = {
    #     "2020-3-5":[153651351,0],
    #     "2020-3-5":[153651351,0],

    # }

    today = datetime.datetime.now().date()
    data_dict = {}

    for item in range(0,30):
        day = today - datetime.timedelta(days=item)
        data_dict[day.strftime("%Y-%m-%d")] = [time.mktime(day.timetuple()) * 1000,0]


    # mysql中 "DATE_FORMAT(web_transaction.create_datetime,'%%Y-%%m-%%d')"
    #sqlite中 ""strftime('%%Y-%%m-%%d',web_issues.create_datetime)""

    result = models.Issues.objects.filter(project_id=project_id,create_time__gte=today-datetime.timedelta(days=30)).extra(
        select={"ctime":"strftime('%%Y-%%m-%%d',web_issues.create_time)"}).values("ctime").annotate(ct=Count("id"))

    for i in result:
        data_dict[i["ctime"]][1] = i["ct"]
    return JsonResponse({"status":True,"data":list(data_dict.values())})
视图函数

二 饼图+柱状图

1.前端

  

<link rel="stylesheet" href="{% static 'plugin/daterangepicker/daterangepicker.css' %}">

<script src="{% static 'plugin/daterangepicker/moment.min.js' %}"></script>
<script src="{% static 'plugin/daterangepicker/daterangepicker.js' %}"></script>
    <script src="{% static 'plugin/highcharts/highcharts.js' %}"></script>
引用 
<div class="container-fluid" style="margin-top: 20px;">
    <div>
        <div class="input-group" style=" 300px;">
            <span class="input-group-addon">日期范围</span>
            <input id="rangePicker" type="text" class="form-control">
        </div>
    </div>

    <div class="row" style="margin-top: 20px;">
        <div class="col-md-8">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <i class="fa fa-bar-chart" aria-hidden="true"></i> 人员工作进度
                </div>
                <div class="panel-body">
                    <div id="projectUser" style="height: 300px;"></div>
                </div>
            </div>

        </div>
        <div class="col-md-4">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <i class="fa fa-pie-chart" aria-hidden="true"></i> 优先级统计
                </div>
                <div class="panel-body">
                    <div id="priority" style="height: 300px;"></div>
                </div>
            </div>
        </div>
    </div>
</div>
前端html展示
<script>
        priority_api = "{% url "statistics_priority" project_id=request.tracer.project.id %}"
        projectUser_api = "{% url "statistics_projectUser" project_id=request.tracer.project.id %}"

        $(function () {
            initDateRangePicker();
            priority(moment().format('YYYY-MM-DD'),moment().add(1,"days").format("YYYY-MM-DD"));
            projectUser(moment().format('YYYY-MM-DD'),moment().add(1,"days").format("YYYY-MM-DD"));
        })
        function initDateRangePicker(){
            var options = {
                maxDate: moment(),
                alwaysShowCalendars: true,
                showWeekNumbers: true,
                ranges: {
                    '今天': [moment(), moment()],
                    '昨天': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                    '最近7天': [moment().subtract(6, 'days'), moment()],
                    '最近30天': [moment().subtract(29, 'days'), moment()],
                    '本月': [moment().startOf('month'), moment().endOf('month')]
                },
                locale: {
                    format: 'YYYY-MM-DD',
                    separator: '',
                    applyLabel: '确定',
                    cancelLabel: '取消',
                    fromLabel: '开始',
                    toLabel: '结束',
                    customRangeLabel: '自定义',
                    weekLabel: 'W',
                    daysOfWeek: ['', '', '', '', '', '', ''],
                    monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
                    firstDay: 1
                }
            };
            $('#rangePicker').daterangepicker(options, function (start, end, label) {
                // 选择了时间之后,函数自动被触发。
                priority(start.format('YYYY-MM-DD'), end.add(1, 'days').format('YYYY-MM-DD'));
                projectUser(start.format('YYYY-MM-DD'), end.add(1, 'days').format('YYYY-MM-DD'));
            });
        }

        function priority(start,end) {
            var config = {
                chart: {

                    type: 'pie'
                },
                title: {
                    text: null
                },
                tooltip: {
                    pointFormat: '{series.name}: <b>{point.y}</b>'
                },
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            //关闭数据 折线标签
                            enabled: false,
                        },
                        showInLegend: true  //显示下方图例
                    }
                },
                credits:{
                    enabled:false
                },
                series: [{
                    name: '优先级',
                    colorByPoint: true,

                    data: []
                }]
            }
            var chart = Highcharts.chart("priority",config);
            $.get(priority_api,{start:start,end:end},function (res) {
                config.series[0].data = res.data;
                Highcharts.chart("priority",config);
            })


        }

        function projectUser(start,end) {
            var config =  {
                chart: {
                    type: 'column'
                },
                title: {
                    text: null
                },
                credits:{
                    enabled:false
                },
                xAxis: {
                    categories: ['小张', '132', 'oo']
                },
               yAxis: {
                    min: 0,
                    title: {
                        text: '问题数量'
                    },
                    stackLabels: {  // 堆叠数据标签
                        enabled: true,
                        style: {
                            fontWeight: 'bold',
                            color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
                        }
                    }
                },
                legend: {
                    align: 'center',
                    verticalAlign: 'top'

                },
                tooltip: {
                    formatter: function () {
                        return '<b>' + this.x + '</b><br/>' +
                            this.series.name + ': ' + this.y + '<br/>' +
                            '总量: ' + this.point.stackTotal;
                    }
                },
                plotOptions: {
                    column: {
                        stacking: 'normal',
                        dataLabels: {
                            enabled:false
                        }
                    }
                },
                series: [
                    {
                    name: '新建',
                    data: [5, 3, 4]
                },
                    {name: '处理中',
                    data: [2, 9, 3,]
                },
                ]
            };
            $.get(projectUser_api,{start:start,end:end},function (res) {
                config.series = res.data.data;
                config.xAxis.categories = res.data.categories;
                Highcharts.chart("projectUser",config);
            })
        }

    </script>
前端js

2.后端

from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
from web import models
from django.db.models import Count

def statistics(request,project_id):
    return render(request,"statistics.html")

def statistics_priority(request,project_id):
    ''' 优先级数据处理'''
    '''  数据类型:第一种:data = [{name: '高', y: 0,}, ]
    
    第二种:data = [
        danger:{name:"高",y:0}
        warning:{name:"中",y:0}
    ]
    '''
    start = request.GET.get("start")
    end = request.GET.get("end")

    data = {}
    for key,value in models.Issues.priority_choices:
        data[key] = {"name":value,"y":0}

    result = models.Issues.objects.filter(project_id=project_id,create_time__gte=start,create_time__lte=end).values("priority").annotate(ct=Count("id"))
    for item in result:
        data[item["priority"]]["y"] = item["ct"]
    return JsonResponse({"status":True,"data":list(data.values()) })

def statistics_projectUser(request,project_id):
    '''

    :param request:
    :param project_id:
    :return:
    需要返回的数据:
    1.
    categories: ['小张', '132', 'oo']


    2:
    {
    name: '新建',
    data: [5, 3, 4]
    },
    {
    name: '处理中',
    data: [2, 9, 3,]
    },

    构造data字典:
    第一步:info = {
        1:{
            name:"武沛齐",
            status:{
                1:0,
                2:1,
                3:0,
                4:0,
                5:0,
                6:0,
                7:0,
            }
        },
    None:{
            name:"未指派",
            status:{
                1:0,
                2:0,
                3:1,
                4:0,
                5:0,
                6:0,
                7:0,
            }
        }
    }
    第二部:data_result_dict = {
        1:{name:新建,data:[0,0]},
        2:{name:处理中,data:[1,0]},
        3:{name:已解决,data:[0,1]},
        4:{name:已忽略,data:[]},
        5:{name:待反馈,data:[]},
        6:{name:已关闭,data:[]},
        7:{name:重新打开,data:[]},
    }
    '''
    start = request.GET.get("start")
    end = request.GET.get("end")
    # 1.所有项目成员 及 未指派
    all_user_dict = {}

    # 未指派
    all_user_dict[None] = {
        "name": "未指派",
        "status": {k: 0 for k, v in models.Issues.status_choices}
    }
    # 创建者
    all_user_dict[request.tracer.project.creater.id] = {
        "name":request.tracer.project.creater.username,
        "status":{ k:0 for k,v in models.Issues.status_choices}
    }

    #参与者
    project_user_list = models.ProjectUser.objects.filter(project_id=project_id)
    for item in project_user_list:
        all_user_dict[item.user.id] = {
            "name":item.user.username,
            "status":{k:0 for k,v in models.Issues.status_choices}
        }
    # 2、获取所有问题
    issues_list = models.Issues.objects.filter(project_id=project_id,create_time__gte=start,create_time__lte=end)
    for item in issues_list:
        if item.assign:
            all_user_dict[item.assign_id]["status"][item.status] += 1
        else:
            all_user_dict[None]["status"][item.status] += 1

    # 3.获取所有成员列表 构造categories
    categories = [item["name"] for item in all_user_dict.values()]

    # 4 构造dict字典并返回
    dict = {}
    # 4.1 构造一个符合结构的空字典
    for k,v in models.Issues.status_choices:
        dict[k] = {
            "name":v,
            "data":[]
        }

    #4.2 填入数据
    for k,v in models.Issues.status_choices:
        for item in all_user_dict.values():
            dict[k]["data"].append(item["status"][k])


    #返回数据 注意字典的values方法要用list()改成列表
    content = {
        "categories":categories,
        "data":list(dict.values()),
    }
    return JsonResponse({"status": True, "data": content})
视图函数
原文地址:https://www.cnblogs.com/hude/p/12849059.html