先看最终画面:
后台代码:
from django.shortcuts import render,HttpResponse
from app1 import models
from datetime import datetime,date,timedelta
def columnsChart(request):
#统计所有来访公司来访次数的by month推移图(柱状堆叠图)
#要画图第一步,获取行名和列名
#列名: 获取visitCus中 所有来访公司的名字
#行名: 获取所有数据库中的月份
#数据:获取所有来访公司在数据库表中的count
#首先获取列名:所有公司名称
companys = models.VisitCusInfo.objects.values("visitCompany__companyName").distinct()
cols=[]
for company in companys:
if company["visitCompany__companyName"] not in cols:
cols.append(company["visitCompany__companyName"])
print(cols)
#再来获取行名及数据
dates = models.VisitCusInfo.objects.values("auditDate") #by客户稽核时间
#对获取到的时间格式整理成by month,只获取月份
rows = []
for row in dates:
month = row['auditDate'].strftime("%Y-%m")
if month not in rows:
rows.append(month)
rows.sort()
print(rows)
#by月份 by公司获取每个公司访问次数
#Echarts官网source参考: 获取legend
# legend: {
# data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎','百度','谷歌','必应','其他']
# },
legend_data=cols
#获取x轴数据,Echarts官网示例
# xAxis : [
# {
# type : 'category',
# data : ['周一','周二','周三','周四','周五','周六','周日']
# }
x_data = rows
#获取数据内容,Echarts官网示例:
# series : [
# {
# name:'直接访问',
# type:'bar',
# stack: '广告',
# data:[320, 332, 301, 334, 390, 330, 320]
# },
# {
# name:'邮件营销',
# type:'bar',
# stack: '广告',
# data:[120, 132, 101, 134, 90, 230, 210]
# },
series=[]
#rows存的是日期,cols存的是公司名
for com in cols:
serie = {"name":com,"type":"bar","stack":"访问次数","data":None}
series_data = []
for row in rows:
cnt = models.VisitCusInfo.objects.filter(auditDate__year=row[0:4],auditDate__month=row[5:7],visitCompany__companyName=com).values("visitCompany__companyName").count()
series_data.append(cnt)
serie["data"]=series_data
series.append(serie)
#柱子宽度可以在这里设置,注意必须加在最后一个 'bar' 系列上才会生效,并且是对此坐标系中所有 'bar' 系列生效。
series[-1]['barWidth']="40%"
print(series)
#最新访客信息
visits = models.VisitCusInfo.objects.all().order_by("-auditDate")\
.values_list("auditDate","visitCompany__companyName","visitTopic","visitPerson")[0:6]
#画饼图:最近12个月客户稽核次数 by 客户名
#需要获取两个数据 1 公司名:legend_data 2 每个公司稽核次数series_data
companyNames = cols.copy()
series_data = []
#print(companyNames)
for name in companyNames:
thisDate = datetime.date(datetime.now())
deltMonth = thisDate+timedelta(days=-365)
print(deltMonth)
cnt = models.VisitCusInfo.objects.filter(visitCompany__companyName=name,
auditDate__gt=deltMonth).values_list("visitCompany__companyName").count()
series_data.append({"name":name,"value":cnt})
print(companyNames)
print(series_data)
return render(request,"charts/visitChart.html",{
"series":series,
"x_data":x_data,
"legend_data":legend_data,
"visits":visits,
"companyNames":companyNames,
"series_data":series_data
})
前台HTML JS代码:
{#<!DOCTYPE html>#}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>visitCharts</title>
<script src="/static/js/echarts.js"></script>
<link rel="stylesheet" href="../static/css/amazeui.min.css" />
<link rel="stylesheet" href="../static/css/admin.css" />
<style>
table{
font-size: 14px;
}
#chart1{
width: 1000px;
height: 400px;
}
.top_div{
width: 50%;
height: 400px;
float: left;
}
#news{
padding: 3%;
}
a:hover{
color: blue;
}
a{
color: black;
}
</style>
</head>
<body>
<div style="width: 1000px;height: 300px">
<div id = "news" class="top_div">
<table class="am-table am-table-striped am-table-hover am-nbfc">
<thead>
{# <tr>最新客户来访信息</tr>#}
<tr>
<td>CTC客户最新来访信息</td>
{# <td>Topic</td>#}
{# <td>QS</td>#}
</tr>
</thead>
<tbody>
{% for visit in visits %}
<tr style="text-align: left">
<td>
<a href="/visitCus.html/">{{ visit.0 |date:"Y-m-d"}}
 
{{ visit.1 }}
|  {{ visit.2 }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div id = "chart2" class="top_div">
<span>asdfasdf</span>
</div>
</div>
<div id="chart1"></div>
</body>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('chart2'));
option = {
title : {
//text: 'CTC客户稽核',
subtext: 'CTC各客户稽核占比',
x:'left'
},
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)" //鼠标悬停显示百分比
//formatter: '{b}:{c}<br/>{b}:{c}'
},
legend: {
type: 'scroll',
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
data: {{ companyNames|safe }}
//selected: data.selected
},
series : [
{
name: '客户稽核次数',
type: 'pie',
radius : '55%',
center: ['40%', '50%'],
data: {{ series_data|safe }},
// formatter: '{b}\n{c}%', //显示百分比
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
normal:{
label:{
show: true,
position: 'top',
formatter: '{b} \n({c},{d}%)'
}
}
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
<script>
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('chart1'));
//app.title = '堆叠柱状图';
option = {
title: {
subtext: 'CTC客户稽核统计'
},
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
//data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎','百度','谷歌','必应','其他']
data:{{ legend_data|safe }}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis : [
{
type : 'category',
data:{{ x_data|safe }}
//data : ['周一','周二','周三','周四','周五','周六','周日']
}
],
yAxis : [
{
type : 'value',
max: 5
}
],
series:{{ series|safe }},
dataZoom: [
{ // 这个dataZoom组件,默认控制x轴。
type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
start: 20, // 左边在 10% 的位置。
end: 100 // 右边在 60% 的位置。
},
{ // 这个dataZoom组件,默认控制x轴。
type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
start: 20, // 左边在 10% 的位置。
end: 100 // 右边在 60% 的位置。
}
],
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</html>
url:
"""ctcqs URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app1.views import views
from app1.views import cusLinkbook,visitCustomers,fileDownload,issueViews,cusSopViews
from app1.views import qsMemberViews,cusInfo,issueNameViews,issueDeptViews,csvdownload,csvupload
from app1.views.charts import issueChart,visitChart
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('visitCus.html/', visitCustomers.auditCus),
path('cusLinkbook.html/', cusLinkbook.index),
path('addCus.html/', cusLinkbook.addCus),
path('editCus.html/', cusLinkbook.editCus),
path('delCus.html/', cusLinkbook.delCus),
path('seleCus.html/', cusLinkbook.seleCus),
path('addVisitCus.html/', visitCustomers.addVisitCus),
path('fileDownload/', fileDownload.fileDown),
path('editVisitCus.html/', visitCustomers.editVisitCus),
path('delVisitCus.html/', visitCustomers.delVisitCus),
path('seleVisitCus.html/', visitCustomers.seleVisitCus),
path('seleVisitCus.html/', visitCustomers.seleVisitCus),
path('issueIndex.html/', issueViews.issueIndex),
path('addIssue.html/', issueViews.addIssue),
path('editIssue.html/', issueViews.editIssue),
path('seleIssue.html/', issueViews.seleIssue),
path('delIssue.html/', issueViews.delIssue),
path('fileDownloadIssue/', fileDownload.fileDownloadIssue),
path('cusSopIndex.html/', cusSopViews.cusSopIndex),
path('addCusSop.html/', cusSopViews.addCusSop),
path('editCusSop.html/', cusSopViews.editCusSop),
path('seleCusSop.html/', cusSopViews.seleCusSop),
path('delCusSop.html/', cusSopViews.delCusSop),
path('fileDownloadSop/', fileDownload.fileDownloadSop),
path('addQsMember.html/', qsMemberViews.addQsMember),
path('qsMemberIndex.html/', qsMemberViews.qsMemberIndex),
path('delQsMember.html/', qsMemberViews.delQsMember),
path('editQsMember.html/', qsMemberViews.editQsMember),
path('addCusInfo.html/', cusInfo.addCusInfo),
path('cusInfoIndex.html/', cusInfo.cusInfoIndex),
path('editCusInfo.html/', cusInfo.editCusInfo),
path('delCusInfo.html/', cusInfo.delCusInfo),
path('issueNameIndex.html/', issueNameViews.issueNameIndex),
path('addIssueName.html/', issueNameViews.addIssueName),
path('editIssueName.html/', issueNameViews.editIssueName),
path('delIssueName.html/', issueNameViews.delIssueName),
path('addIssueDept.html/', issueDeptViews.addIssueDept),
path('editIssueDept.html/', issueDeptViews.editIssueDept),
path('delIssueDept.html/', issueDeptViews.delIssueDept),
path('issueDeptIndex.html/', issueDeptViews.IssueDeptIndex),
path('downloadSopCsv/', csvdownload.downloadSopCsv),
path('downloadQs/', csvdownload.downloadQs),
path('downloadVisitCus/', csvdownload.downloadVisitCus),
path('downloadIssue/', csvdownload.downloadIssue),
path('downloadCusLinkbook/', csvdownload.downloadCusLinkbook),
path('uploadIssue/', csvupload.uploadIssue),
path('downloadIssueFormat/', csvdownload.downloadIssueFormat),
path('chart.html/', views.chart),
path('visitChart.html/', visitChart.columnsChart),
path('issueChart.html/', issueChart.chart1),
]