基于Vue框架的云南省教育扶贫可视化系统设计与实现
作者: 吕维广,申浩如,孙定蜜,杨延仁,胡正南,黎谍,饶肖
摘要:通过对云南省教育扶贫阶段性成果进行分析,确定数据、名言、模范、地图、政策、学术6个典型展示维度,采用前后端分离开发模式和增量软件开发模型,基于Vue、ECharts、Maven、MySQL工具,设计开发该信息可视化系统。将云南省教育扶贫积累的异构、多源、空间相关数据进行表征,以数字化动态交互形式展现出来,为云南省教育精准扶贫提供直观的可视化分析手段,形成窗口宣传效应。
关键词:云南省;教育扶贫;可视化系统;Vue;ECharts
中图分类号:TP311.52 文献标识码:A
文章编号:1009-3044(2022)32-0034-04
1 概述
教育扶贫是赢得中国脱贫攻坚全面胜利的重要一役。由于云南省的地理复杂性和民族多样性,使云南教育扶贫更具挑战性。本文基于数据统计原理,综合使用Vue、ECharts、Maven等工具对云南省相关教育扶贫数据进行可视化表征,从地理空间和非地理空间维度直观展现这些海量、异构、多源数据,为政府职能部门、教育行政主管部门、学术研究群体提供有价值的可视化结果,助推云南省教育扶贫精准施策,实现贫困人口“脱真贫、真脱贫”[1]的愿景。
2 云南省教育扶贫可视化系统总体设计
2.1 系统架构设计
教育扶贫可视化系统采用B/S体系结构,前端使用Vue框架,它是一个扩展性和复用性较强的轻量级渐进式JavaScript框架,基于数据驱动、交互展示和视图组件化构建前端页面[2]。后端服务程序使用Maven项目管理工具创建,自动管理依赖包和版本配置,通过IDEA一键发布调试,大幅降低包的版本依赖问题[3]。最终将负责业务逻辑的后端工程打包通过阿里云Tomcat服务器发布。
前后端数据交互使用axios进行异步请求同步化处理,减轻后端数据处理压力[4]。前后端分离开发,前端代码由阿里云的对象存储OSS服务托管,降低服务器带宽压力[5]。此外,为解决前后端分离开发导致的跨域请求问题,项目使用Filter过滤器对请求进行过滤处理[6]。底层数据存管采用MySQL数据库。系统架构如图1所示。
系统选用增量软件开发模型。原因有三:1)开发时人员可灵活分配,能在较短时间内向甲方提交部分可操作产品,有效解决了参与系统开发的学生成员因学业导致频繁换人的客观实际。2)采用“分而治之”思想,把问题分解成可控的子模块,先完成需求稳定的核心构件,避免团队因长时间需求任务而感到沮丧。3)增量模型并非一步跨到未来,让开发者逐步适应全栈开发技术,符合在校学生软件开发训练的普遍规律。
系统架构设计必须注意:1)增量开发模型最大特点是具有较好的扩展性,在开发过程中必须注意接口定义。2)由于系统各个模块之间耦合度较低,导致代码的审查难度增加,容易出现代码冗余情况,所以必须定义好一个可行的开发过程。3)由于各个组件是逐步并入软件体系架构中,系统内核是十分关键的部分,内核不精简将会使增量模型退化成边做边改模型[7]。
项目开发中的依赖库如表1所示。
2.2 功能模块设计
系统有6个模块:教育扶贫里程碑、每日扶贫金句、教育扶贫先锋模范、地图可视化综合交互展示、教育扶贫政策方针、教育扶贫学术研究。根据不同数据属性将这些数据分别通过柱状图、曲线图、堆叠图、矢量地图、轮播图、主题词云等多种可视化形式进行表征,详见表2。
2.3 后台数据库设计
后端资源通过MySQL存储,使用JDBC连接池工具进行数据库连接管理,优点是无须手动管理数据库连接对象,按需取用,使用结束释放回连接池即可,避免数据库未被释放带来的风险。根据系统功能描述,设计数据库表,其中下划线字段为表主键:
1)城市:city (ID, 城市名, 所属县名, 扶贫举措)。进库记录88条。
2)金句:famous_remarks (ID, 发布时间, 内容, 发言人) 。进库记录12条。
3)人物:people (ID, 姓名, 身份、事迹简介) 。进库记录27条。
4)政策:policy (ID, 政策名称, 发布机构, 官方URL) 。进库记录42条。
5)词云:word_cloud (ID, 关键词, 引用次数) 。进库记录1000条。
3 云南省教育扶贫可视化系统核心功能实现
3.1 系统界面
图2给出了云南省教育扶贫可视化系统界面设计,界面以深红主调为背景,嵌入了省会昆明市的传统地标“金马碧鸡”牌坊和新建地标高度407米的“春之眼”,以及滇西重镇大理市的苍山元素,寓意近年云南省扶贫取得的丰硕成果。
3.2 图文信息展示模块
教育扶贫里程碑、每日扶贫金句、教育扶贫模范这三个模块主要使用Element UI组件划分页面框架,并利用CSS渲染文字,同时还使用JavaScript结合@keyframes实现图片和文字的滚动播放效果。
3.3 基于ECharts和地理信息标注的可视化模块
针对项目开发难度较大的地图综合展示模块,该模块采用ECharts的map类型地图图表,将具有空间地理特征的信息可视表征。首先,地图绘制是通过阿里云提供的数据可视化平台http://datav.aliyun.com获取云南省地理数据结构编码JSON文件,在渲染前将文件通过GET或POST方法获得地理结构数据,之后使用echarts.registerMap('yunnan', geoJson)方法注册地图,然后对地图进行相关配置。在配置项中,data是该图表渲染数据的接口,其中包括城市名和权值(决定地图块着色深浅),渲染时可根据城市名和权值进行自动关联,权值越高的城市区域显示颜色越深。城市颜色渲染梯度是通过配置视觉映射组件visualMap控制。代码如下:
geo:{ //地理坐标系组件,支持地理坐标上绘制散点、线集
type:'map', //指定图表类型为地图
map:'yunnan', //自定义扩展图表类型,参数使用注册时的变量名
roam:true, //关闭移动漫游
zoom:1.2, //设置初始化地图缩放比例
selectedMode:false, //设为不可移动地图
data:mapData, //地图渲染数据包括:mapData{[name:’城市名’,value:权值]}
label: {
show: false, //不显示标签
fontSize: '50px' //设置标签显示字体大小
},
}
visualMap: [{ //视觉映射组件配置
bottom: '45%', //组件离容器底部位置
left:'5%', //组件离容器左边位置
text: ['High', 'Low'], //两端的文字
realtime: true, //拖拽时实时更新渲染
calculable: true, //显示拖拽手柄,手柄能拖拽调整选中范围
}]
同时在地图上标注“州市”散点图,在上述geo地理坐标系统进行叠加渲染,配置时data是散点图渲染的数据接口,数据结构包括必选项散点geo坐标位置和附加描述信息项,并指明该散点图是基于何种坐标系渲染。默认情况下鼠标移动到散点上浮动提示框只显示诸如经纬度和地名等默认信息,如要显示指定描述信息需通过配置浮动提示框tooltip实现,如要实现根据点击对象判断显示指定信息,则需配置formatter。formatter既可接收一段静态html格式代码也可接收一个匿名函数function(param),函数被调用时传入参数param标识了被点击的唯一元素,即被点击元素类型和对应geo坐标及附加描述信息,通过对点元素的判断来选择显示内容,代码如下:
series: [ //散点图配置
{
data: scatterdata, //散点坐标数据data:[“value”:[经度,纬度],”name”:”地名”,”text”:”描述信息”]
type: 'scatter', //设置图表类型为散点图
coordinateSystem:'geo', //设置散点使用的坐标系统
symbolSize: 20, //散点大小
color:'red' //散点颜色
}
]
tooltip:{ //浮动提示框配置
show:true,
backgroundColor: "rgba(203,203,203,0.8)", //设置背景图片RGBA格式
borderWidth: 0, //边框宽度设置1
borderColor: "aqua", //设置边框颜色
padding:0, //边框宽度
textStyle:{ //配置提示框文本格式
fontSize:'40px',
color:'rgba(254,255,86)'
},
triggger:'item', //触发类型
formatter:function(param){ //函数方式返回提示框信息
return '<div >'+param.data.name+'<div >'; //显示点击元素数据中变量name的数据
}
}
}
由于地图和今昔对比图展示于同一“<div></div>”标签中,在ECharts作图时需将两图配置信息写入配置数组。同时两张图表均按用户交互需求通过POST方法从服务器动态更新数据,这使得配置项中的数据部分不会被固定,而是留下一个数据接口,随用户点击动态调用,并同步刷新图表Vue地图组件。同理,今昔校园对比照片也跟随用户点击动态从服务器拉取图片,通过监听click事件向服务器发送POST请求报文刷新图片。代码如下:
mapChart.on('click', function (params) { //监听点击事件
if(params.componentSubType=='map'){ //判断是否点击了地图组件
City(params.name).then(data => { //通过axios获取数据
var testdata=[] //设置空变量
for(var i in data){ //遍历数据
testdata.push(data[i]) //在空变量中填充要渲染的数据
}
citydata.value=testdata //把最新数据同步给数据接口
})
landname.value=params.name //同步点击的州市名
//根据点击的州市名用require方法获取对应今夕对比图片
imgland1.value =require('@/assets/land/'+params.name+'1.jpg')
imgland2.value =require('@/assets/land/'+params.name+'2.jpg')