任务描述
知识点:
- Django
- ECharts
重 点:
- Django
- ECharts折线图
内 容:
- 绘制列表框,能够切换不同的省份
- 根据ECharts官方示例,绘制ECharts折线图
- 根据ECharts配置项手册,修改ECharts图形配置
任务指导
1、绘制列表框,能够切换不同的省份
需要绘制的图形如下:
因此需要添加一个列表框,该列表框中的选项为所有的省份,通过改变列表框中的选项,折线图能够获取到该省份的数据,然后绘制该省份的图形。
折线图在MySQL数据库中对应的表格为province_temp中的数据,其数据字段如下:
province为省份,month为月份,temp为实际平均气温,temp_forecast为预测的气温
2、根据ECharts官方示例,绘制ECharts折线图
参考示例为未来一周气温变化,如下图:
通过index.html的容器id,将该图形绘制到该div中,如下:
3、添加列表框交互,根据ECharts配置项手册,修改ECharts图形配置
- 数据更新为读取的line_data中的数据
- 图形标标题为2022年'+provinces[data_index]+'平均气温和预测情况',样式为定义的全局标题样式text_style,位置居中。
- 坐标轴分隔线取消,y轴添加坐标轴,坐标轴样式需要改变为白色,0.5宽度,坐标轴标签样式需要改变字体白色,大小6号。
- 上方的图例位置靠下,图例标签字体10号,白色
- 最大最小标记点只留下实际温度的标记点,大小30,字体8号)
任务实现
(若有时图形刷新不出来,可以尝试清除浏览器数据,之后再刷新)
1. 绘制列表框
1)增加css样式类
在index.html中,列表框对应的div容器id为list_box,高度为10%,而绘制折线图对应的id为id1,高度为90%,如下图所示:
列表框div对应的css样式为listbox和list,折线图对应的css样式为fill-h1,但是在app.css文件中并没有定义该样式类,因此需要添加,打开app.css文件
添加list样式类,主要设定列表框选项字体的颜色和大小,如下:
.list{font-size:10px;color:green;
}
添加listbox样式类,主要设定列表框的高度,如下:
.listbox {height:10%;min-height:5%;}
添加fill-h1样式类,主要设定绘制图形块的高度,如下:
.fill-h1 {height:90%;min-height:90%;}
如下:
2)添加列表框
在js文件目录下新建一个line_chart.js文件,该文件主要用来绘制列表框和折线图,先使用d3.js添加列表框,代码如下:
var myselect=d3.select('.listbox').append('select').attr('id','test').attr('height',16).style('font-size',6).on('change',select_list);
然后在index.html中引入该js文件,如下:
<script src="{% static 'js/line_chart.js' %}"></script>
保存以上文件,在浏览器中刷新网页,页面展示如下:
可以看到,页面中已经显示了列表框了,接下来需要在列表框中添加选项,选项为数据中的所有省份。
3)读取数据
打开views.py文件,读取MySQL中的province_temp数据,并将温度数据除以10,温度和预测数据四舍五入,然后取出各个省份,代码如下:
#读取折线图数据
sql=text(sql_base+table_name[1])
connect = engine.connect()
temp_province_data=pd.read_sql(sql,connect)
temp_province_data['temp']=np.round(temp_province_data['temp']/10,0)
temp_province_data['temp_forecast']=np.round(temp_province_data['temp_forecast'],0)
provinces=list(temp_province_data['province'].unique())
在视图函数中传入provinces变量给模板,如下:
'provinces': mark_safe(provinces),
保存该文件,在index.html中获取该变量,代码如下:
var provinces={{ provinces }};
4)列表框添加选项
注释掉选项改变的交互,打开line_chart.js文件,添加列表框选项代码如下:
//列表框中添加选项
var myoption=myselect.selectAll('.option').data(provinces).enter().append('option').attr('value',function(d,i){return i;}).text(function(d){return d;});
保存以上文件,为了使样式生效,可以清除一下浏览器的缓存,然后刷新网页,页面展示如下:
选项框可以进行选择,里面的选项为各个省份。
5)自定义选项改变的事件
当选项改变时,获取选项的索引值,该选项的索引值就可以用来绘制当前所选择省份的图形。继续在line_chart.js中添加如下代码:
var data_index=0;
function select_list(){data_index=this.selectedIndex;console.log(data_index);
};
然后将选项改变的交互取消注释,如下:
保存该文件,刷新浏览器网页,然后按F12(开发者工具),点击console控制台,点击列表框改变选项,查看控制台输出的当前所选择的选项索引,如下:
选择云南时,控制台输出
选择内蒙古时控制台输出
查看完成后,可以将console.log那条代码注释掉,就不会在控制台打印data_index内容了。至此,列表框即绘制完成。
2. 绘制Echarts折线图
1)参考ECharts官网示例
打开ECharts官网示例https://echarts.apache.org/examples/zh/index.html,找到折线图,然后找到未来一周气温变化,如下图:
点击进入该图的配置项
可以看到,该图形为一周的温度变化,有两条折线,刚好可以对应我们需要绘制的图形,即1-12月的气温和气温预测,因此,该配置项(option)即可作为我们绘制图形的参照,同时,该图形的两个序列数据为[10,11,......],所以我们在读取数据库表中的数据后,可以将建立一个key为省份,value为1-12月的温度/预测温度的字典(line_data),每个value值同时也是一个字典,例如:{'month':[1,2,...],'temp':[10,11...],'forecast_temp':[11,12,...]},当我们在列表框中选择了一个省份后,列表框中的交互事件中即返回了data_index,即我们所现在选项的索引值,然后通过provinces[data_index]即可获得我们所选择的省份,最后通过传入的line_data字典获得数据,即line_data[provinces[data_index]]即可获得该省份1-12月份的temp和forecast_temp数据,月份即为line_data[provinces[data_index]].month,实际温度为:line_data[provinces[data_index]].temp,预测温度为:line_data[provinces[data_index]].forecast_temp。
2)处理数据
在前面已经读取了折线图数据,然后需要对数据进行处理,处理成折线图需要的数据,然后传入到模板,打开views.py文件,添加代码如下:
line_data={}
for item in provinces:temp_dict={}temp_province=temp_province_data[temp_province_data['province']==item]temp_dict['month']=list(temp_province['month'].values)temp_dict['temp'] = list(temp_province['temp'].values)temp_dict['temp_forecast'] = list(temp_province['temp_forecast'].values)line_data[item]=temp_dict
print(line_data)
以上最外层新建了一个字典,通过省份值为key,内部的value值也是字典,形如:{'month':[1,2,...],'temp':[10,11...],'forecast_temp':[11,12,...]}
将views.py文件中之前的print()打印全部注释掉,不然控制台会输出很多数据,保存该文件,在控制台能够看到处理后的数据,如下:
查看后,可以将该打印注释掉
3)将折线图数据传入模板
继续在views.py文件中的视图函数login()中给模板传入变量,添加代码如下:
'line_data':mark_safe(line_data),
然后在index.html文件中定义变量接收该变量,代码如下:
var line_data={{ line_data }};
4)绘制折线图
在index.html中,折线图绘制在id1的div中,打开line_chart.js文件,继续在后面定义绘制折线图函数,代码如下:
function line_chart(){var myChart = echarts.init(document.getElementById('id1'));myChart.setOption(option)
}
以上代码便在id1的div中初始化了ECharts图形,并指定了配置项,因此需要在中间空白的部分添加上绘制折线图的配置项,将ECharts官网的示例配置项代码全部复制过来,粘贴到空白部分,如下:
保存该文件,然后在total_control.js文件中,添加line_chart()绘图函数,如下:
line_chart();
保存以上文件,刷新网页,展示如下:
可以看到,折线图已经嵌入到div中了,但是还存在以下问题:
- 数据需要更新为读取的line_data中的数据。
- 图形标题和样式需要改变,标题应为2022年'+provinces[data_index]+'平均气温和预测情况',样式为定义的全局标题样式text_style,位置居中。
- 坐标轴分隔线需要取消,y轴需要添加坐标轴,坐标轴样式需要改变为白色,0.5宽度,坐标轴标签样式需要改变字体白色,大小6号。
- 上方的图例样式及位置需要改变(位置靠下,图例标签字体10号,白色)。
- 最大最小标记点样式需要改变(只留下实际温度的标记点,大小30,字体8号)。
3. 修改配置项
根据上述思路,打开line_chart.js文件,参照ECharts官网配置项手册,做出如下更改:
1)在选项改变的事件,增加绘制图形函数,即当选项发生改变时,那么图形将重新绘制,在select_list()函数中添加如下代码:
line_chart();
2)修改标题,根据ECharts配置项手册,标题配置项修改为如下:
title: {text: '2022年'+provinces[data_index]+'平均气温和预测情况',textStyle:text_style,left:'center',},
3)修改图例配置项,根据ECharts配置项手册,图例配置项修改为如下:
legend: {bottom:'5%',textStyle:{color:"#FFF",fontSize: 10,},},
4)删除掉toolbox配置项,即使用默认设置
5)修改x轴标签样式、轴线样式和数据,如下:
xAxis: {type: 'category',boundaryGap: false,axisLabel:{color: 'white',fontSize: 6,formatter: '{value} 月'},axisLine:{lineStyle:{color:"#FFF",width:0.5,},},data: line_data[provinces[data_index]].month},
6)修改y轴标签样式、轴线样式和数据,如下:
yAxis: {type: 'value',splitLine:false,axisLabel:{color: 'white',fontSize: 6,formatter: '{value} °C'},axisLine:{show:true,lineStyle:{color:"#FFF",width:0.5,},},axisTick:{show:true,}},
7)修改series中的配置项,将第一个系列的name修改为'实际气温(2022)',data修改为line_data[provinces[data_index]].temp,删除掉markLine配置项,markPoint配置项中增加:
symbolSize:30,label:{fontSize:8,},
修改如下:
将第二个系列的name修改为'预测气温(2023)',data修改为line_data[provinces[data_index]].temp_forecast,markPoint和markLine配置项删除,如下:
保存以上文件,刷新网页,展示如下:
至此,大屏的折线图已经绘制完成,点击切换省份,数据会自动更新,如下: