django Echarts画柱状推移图
1. 首先确定要画什么样的图,在Echarts官网找好案例
2.根据图确认需要准备的数据,从后台准备数据传递给模板
3.模板渲染,使用Echarts组件功能完成自己想要的内容
中间遇到几个坑:
1. by月份统计客户来访次数,数据库中存入的是Date格式,如何转换月份? XXX.strftime("%Y") 这样就可以以单独获取年月日
2.如何从数据库中By月份拿数据? 参考下面这一句,先mapping年,再来是月,再来是你想要做的事
models.VisitCusInfo.objects.filter(auditDate__year=row[0:4],auditDate__month=row[5:7],visitCompany__companyName=com).values("visitCompany__companyName").count()
3.后台写好数据传入前台js时报错,是因为模板渲染了,需要加入 {{ |safe }}
OK,先看结果:
后台代码,里面有很详细的注释:
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)
return render(request,"charts/visitChart.html",{"series":series,"x_data":x_data,"legend_data":legend_data})
再上前台代码:
{#<!DOCTYPE html>#}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>visitCharts</title>
<script src="/static/js/echarts.js"></script>
<style>
#chart1{
width: 1000px;
height: 400px;
}
</style>
</head>
<body>
<div id="chart1"></div>
</body>
<script>
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('chart1'));
//app.title = '堆叠柱状图';
option = {
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>