目录
一、定义
利用本专业核心课程《数据可视化实训项目》的知识,完成《政府大数据可视化系统》系统分析、设计、编码、测试、发布全过程项目实训。掌握利用Echarts结合常用框架及数据分析工具对大量数据进行采集、分析存储及可视化的技能,能够编写系统分析和系统设计阶段的常用文档,独立完成系统实施阶段程序设计,能够进行单元测试和集成测试,完成系统运行部署。通过较为完整的大数据分析及可视化过程,使学生具备大数据系统构建、展示的技能,培养分析问题和解决问题的能力。
二、技能标准
结合课堂讲授的知识,通过实训操作,使学生达到下列基本要求:
- 熟悉软件开发的过程。
- 熟悉《系统需求分析说明书》、《系统设计说明书》等开发文档的内容。
- 掌握大数据平台搭建、前后台软件开发环境构建以及程序调试的方法。
- 能够使用echarts实现柱状图、饼状图、线状图等图表的绘制。
- 能够对echarts对图表元素进行调整和优化。
- 能够根据需求对前台页面进行设计,并实现相关布局。
- 能够根据需求对前台页面进行美化,能够灵活使用css的相关设置。
- 能够使用java script开发前台应用,接收用户需求,发起与后台的交互,接收和解析后台返回的信息,并实现前台刷新。
- 具备基本的python编程能力。
- 能够架设flask开发环境。
- 能够在flask下接收前台请求,并对请求进行响应。
- 能够通过numpy、pandas读取大文件(csv)。
- 能够通过numpy、pandas进行数据预处理、查询和分析。
- 能够采用JSON构建前后端交互的数据结构。
- 具备开发基本的网站和前后端调试的能力。
- 编码符合规范,能够利用工具检查代码的规范程度。
- 掌握版本控制,帮助和安装制作等常用工具的使用。
- 掌握利用微信小程序官方开发文档、搜索引擎、中国知网、CSDN等网络工具获取新知识,解决实际问题的方法。
三、实训安排
实训安排
周次
时间
内容
要求
第一周
周一
项目任务布置,需求分析与系统设计。指导教师讲解项目开发的过程、需求、设计要点、讲解开发文档
学生明确实训周任务及实训目标。学生仔细研究系统需求,理解设计思路,完成需求报告。
周二
大数据平台环境的搭建
建立大数据平台环境,构建前后台软件开发环境。
周三
前端页面框架设计、页面美化
完成前端页面框架设计,实现基本页面布局。
完成前端页面的美化,确定并实现前端页面的色彩风格,优化文字、图案显示。
周四
前端完成echarts绘图测试程序的编写
能够采用测试数据显示echarts图表,完整展现前端页面。
使用svn进行软件配置管理。
周五
后端实现大文件的分片读取及数据预处理
实现大文件的分片读取,对数据进行预处理,并采用单样本、小样本测试正确性。
第二周
周一
后端实现数据分析功能
实现数据分析功能;
编写测试程序验证分析程序有效性;
采用单样本、小样本进行测试验证。
周二
实现前后端交互功能
前端实现发起请求,解析后端数据功能;
后端接收前端请求,并启动线程,完成数据分析。
周三
实现数据分析过程中的状态交互
分析过程中前端对后端进行轮询;
后端响应前端轮询信息,获取当前分析进程。
周四
完成项目开发扫尾工作
实现前端的页面、显示交互、请求及响应,后端响应请求、数据分析、分析状态获取,以上软件模块的联调,优化系统软件模块。
周五
项目总结、项目答辩
学生能够完整阐述项目完成的过程,重难点技术及解决方案,以及自己的特色。
四、前台页面展示
模板页面
五、项目架构
六、static
https://tuomasi.lanzouu.com/inNfk04van1a
提取码:0000
七、py文件
app.py
# -*- coding: utf-8 -*-
# @Time : 2022/5/8 9:12
# @Author : Tuomasi
# @File : app.py
from flask import Flask, render_template
from data import SourceDataDemo
from user_Data import userData
from data_job import JobData
from data_corp import CorpData
app = Flask(__name__)
'''
定义了3个网址,用同一套模板渲染
'''
@app.route('/')
def index():
# 新建一个实例
data = SourceDataDemo()
# 传入一个实例,和实例的标题
return render_template(' index.html', form=data, title=data.title)
@app.route('/corp')
def corp():
data = CorpData()
return render_template('index.html', form=data, title=data.title)
@app.route('/job')
def job():
data = JobData()
return render_template('index.html', form=data, title=data.title)
@app.route('/user')
def user():
data = userData()
return render_template('index.html', form=data, title=data.title)
if __name__ == "__main__":
app.run(host='127.0.0.1', debug=False)
data.py
# -*- coding: utf-8 -*-
# @Time : 2022/5/8 9:17
# @Author : Tuomasi
# @File : data.py
class SourceDataDemo:
def __init__(self):
# 默认的标题
self.title = '大数据可视化展板通用模板'
# 两个小的form看板
self.counter = {'name': '2022年总收入情况', 'value': 12345678}
self.counter2 = {'name': '2022年总支出情况', 'value': 89765497}
# 总共是6个图表,数据格式用json字符串,其中第3个图表是有3个小的图表组成的
self.echart1_data = {
'title': '行业分布',
'data': [
{"name": "商超门店", "value": 47},
{"name": "教育培训", "value": 52},
{"name": "房地产", "value": 90},
{"name": "生活服务", "value": 84},
{"name": "汽车销售", "value": 99},
{"name": "旅游酒店", "value": 37},
{"name": "五金建材", "value": 2},
]
}
self.echart2_data = {
'title': '省份分布',
'data': [
{"name": "浙江", "value": 47},
{"name": "上海", "value": 52},
{"name": "江苏", "value": 90},
{"name": "广东", "value": 84},
{"name": "北京", "value": 99},
{"name": "深圳", "value": 37},
{"name": "安徽", "value": 150},
]
}
self.echarts3_1_data = {
'title': '年龄分布',
'data': [
{"name": "0岁以下", "value": 47},
{"name": "20-29岁", "value": 52},
{"name": "30-39岁", "value": 90},
{"name": "40-49岁", "value": 84},
{"name": "50岁以上", "value": 99},
]
}
self.echarts3_2_data = {
'title': '职业分布',
'data': [
{"name": "电子商务", "value": 10},
{"name": "教育", "value": 20},
{"name": "IT/互联网", "value": 20},
{"name": "金融", "value": 30},
{"name": "学生", "value": 40},
{"name": "其他", "value": 50},
]
}
self.echarts3_3_data = {
'title': '兴趣分布',
'data': [
{"name": "汽车", "value": 4},
{"name": "旅游", "value": 5},
{"name": "财经", "value": 9},
{"name": "教育", "value": 8},
{"name": "软件", "value": 9},
{"name": "其他", "value": 9},
]
}
self.echart4_data = {
'title': '时间趋势',
'data': [
{"name": "安卓", "value": [3, 4, 3, 4, 3, 4, 3, 6, 2, 4, 2, 4, 3, 4, 3, 4, 3, 4, 3, 6, 2, 4, 4]},
{"name": "IOS", "value": [5, 3, 5, 6, 1, 5, 3, 5, 6, 4, 6, 4, 8, 3, 5, 6, 1, 5, 3, 7, 2, 5, 8]},
],
'xAxis': ['01', '02', '03', '04', '05', '06', '07', '08', '09', '11', '12', '13', '14', '15', '16', '17',
'18', '19', '20', '21', '22', '23', '24'],
}
self.echart5_data = {
'title': '省份TOP',
'data': [
{"name": "浙江", "value": 2},
{"name": "上海", "value": 3},
{"name": "江苏", "value": 3},
{"name": "广东", "value": 9},
{"name": "北京", "value": 15},
{"name": "深圳", "value": 18},
{"name": "安徽", "value": 20},
{"name": "四川", "value": 13},
]
}
# 这是一个环状图,有颜色的加上没颜色的正好等于100,半径是外圈直径和内圈直径,猜测是左闭右开
self.echart6_data = {
'title': '一线城市情况',
'data': [
{"name": "浙江", "value": 80, "value2": 20, "color": "01", "radius": ['59%', '70%']},
{"name": "上海", "value": 70, "value2": 30, "color": "02", "radius": ['49%', '60%']},
{"name": "广东", "value": 65, "value2": 35, "color": "03", "radius": ['39%', '50%']},
{"name": "北京", "value": 60, "value2": 40, "color": "04", "radius": ['29%', '40%']},
{"name": "深圳", "value": 50, "value2": 50, "color": "05", "radius": ['20%', '30%']},
]
}
# 这个在哪里用了???
self.map_1_data = {
'symbolSize': 1000,
'data': [
{'name': '海门', 'value': 239},
{'name': '鄂尔多斯', 'value': 231},
{'name': '招远', 'value': 203},
]
}
@property
def echart1(self):
data = self.echart1_data
echart = {
'title': data.get('title'),
# 第一次get获取到的是许多键值对,所以需要对每个键值对再次get
'xAxis': [i.get("name") for i in data.get('data')],
'series': [i.get("value") for i in data.get('data')]
}
# 返回的是标题和对应的数据,并没有说用什么方式展现!
return echart
@property
def echart2(self):
data = self.echart2_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'series': [i.get("value") for i in data.get('data')]
}
return echart
@property
def echarts3_1(self):
data = self.echarts3_1_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'data': data.get('data'),
}
return echart
@property
def echarts3_2(self):
data = self.echarts3_2_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'data': data.get('data'),
}
return echart
@property
def echarts3_3(self):
data = self.echarts3_3_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'data': data.get('data'),
}
return echart
@property
def echart4(self):
data = self.echart4_data
echart = {
'title': data.get('title'),
'names': [i.get("name") for i in data.get('data')],
'xAxis': data.get('xAxis'),
'data': data.get('data'),
}
return echart
@property
def echart5(self):
data = self.echart5_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'series': [i.get("value") for i in data.get('data')],
'data': data.get('data'),
}
return echart
@property
def echart6(self):
data = self.echart6_data
echart = {
'title': data.get('title'),
'xAxis': [i.get("name") for i in data.get('data')],
'data': data.get('data'),
}
return echart
@property
def map_1(self):
data = self.map_1_data
echart = {
'symbolSize': data.get('symbolSize'),
'data': data.get('data'),
}
return echart
# class SourceData(SourceDataDemo):
#
# def __init__(self):
# """
# 按照 SourceDataDemo 的格式覆盖数据即可
# """
# super().__init__()
# self.title = '大数据屏幕展示'
data_corp.py
# -*- coding: utf-8 -*-
# @Time : 2022/6/1 16:01
# @Author : Tuomasi
# @File : data_corp.py
from data import SourceDataDemo
class CorpData(SourceDataDemo):
def __init__(self):
"""
按照 SourceDataDemo 的格式覆盖数据即可
"""
super().__init__()
self.title = '全国企业大数据'
self.counter = {'name': '企业总数量(全国)', 'value': 46897675}
self.counter2 = {'name': '企业总数量(一线城市)', 'value': 6805564}
self.echart1_data = {
'title': '行业分布',
'data': [
{
"name": "批发零售业",
"value": 16881396
},
{
"name": "制造行业",
"value": 6780200
},
{
"name": "租赁商务服务",
"value": 5358030
},
{
"name": "农林牧渔业",
"value": 3335899
},
{
"name": "住宿餐饮业",
"value": 2284813
},
{
"name": "建筑业",
"value": 2267361
},
]
}
self.echart2_data = {
'title': '省份分布',
'data': [
{
"name": "广东",
"value": 5635811
},
{
"name": "山东",
"value": 3972598
},
{
"name": "江苏",
"value": 3793522
},
{
"name": "河南",
"value": 2787866
},
{
"name": "河北",
"value": 2402739
},
{
"name": "四川",
"value": 2083448
},
{
"name": "浙江",
"value": 2047431
},
{
"name": "上海",
"value": 1863549
},
{
"name": "北京",
"value": 1717739
},
{
"name": "辽宁",
"value": 1658253
}
]
}
self.echarts3_1_data = {
'title': 'IT互联网行业',
'data': [
{"name": "软件和信息技术服务", "value": 977084},
{"name": "电信、广播电视和卫星传输", "value": 106294},
{"name": "互联网和相关服务", "value": 258712},
]
}
self.echarts3_2_data = {
'title': '金融行业',
'data': [
{"name": "金融行业", "value": 45},
{"name": "资本市场", "value": 172467},
{"name": "货币金融", "value": 202444},
{"name": "其他", "value": 57077},
{"name": "保险", "value": 104538},
]
}
self.echarts3_3_data = {
'title': '运输物流仓储',
'data': [
{"name": "铁路", "value": 3331},
{"name": "邮政", "value": 118877},
{"name": "道路", "value": 564787},
{"name": "装卸搬运和运输代理", "value": 253375},
{"name": "航空", "value": 8060},
{"name": "水运", "value": 22755},
{"name": "仓储", "value": 143798},
]
}
self.echart4_data = {
'title': '新一线城市',
'data': [
{"name": "IT互联网行业", "value": [16839,22356,38262,33763,27436,20337,12178,34248,31356,50089,16040,16927,30420,7847,11937]},
{"name": "房地产", "value": [13292,7770,17510,17584,14516,14485,9193,17220,10323,19205,15400,5051,12325,8481,9617]},
],
'xAxis': ['青岛', '长沙', '重庆', '郑州', '西安', '苏州', '沈阳', '武汉', '杭州', '成都', '天津', '合肥', '南京', '佛山', '东莞'],
}
self.echart5_data = {
'title': '厦门行业分布',
'data': [
{
"name": "批发零售业",
"value": 167346
},
{
"name": "租赁商务",
"value": 55939
},
{
"name": "制造行业",
"value": 45326
},
{
"name": "科学研究",
"value": 22382
},
{
"name": "住宿餐饮",
"value": 21885
},
{
"name": "IT互联网",
"value": 18796
},
{
"name": "建筑业",
"value": 15244
},
{
"name": "居民服务",
"value": 12470
}
]
}
self.echart6_data = {
'title': '一线城市',
'data': [
{"name": "北京", "value": 1717739, "value2": 2000000 - 1717739, "color": "01", "radius": ['59%', '70%']},
{"name": "上海", "value": 1863549, "value2": 2000000 - 1863549, "color": "02", "radius": ['49%', '60%']},
{"name": "广州", "value": 1261475, "value2": 2000000 - 1261475, "color": "03", "radius": ['39%', '50%']},
{"name": "深圳", "value": 1962801, "value2": 2000000 - 1962801, "color": "05", "radius": ['30%', '40%']},
]
}
self.map_1_data = {
'symbolSize': 80000,
'data': [
{
"name": "舟山新区",
"value": 161
},
{
"name": "忻州",
"value": 70784
},
{
"name": "什邡",
"value": 3
},
{
"name": "哈密地区",
"value": 5
},
{
"name": "通辽",
"value": 85136
},
{
"name": "潍坊",
"value": 397874
},
{
"name": "保山",
"value": 48480
},
{
"name": "海宁",
"value": 1
},
{
"name": "仪征",
"value": 1
},
{
"name": "九江",
"value": 115899
},
{
"name": "耒阳",
"value": 5
},
{
"name": "景德镇",
"value": 28611
},
{
"name": "宿州",
"value": 80494
},
{
"name": "博尔塔拉蒙古自治州",
"value": 1
},
{
"name": "义马",
"value": 2
},
{
"name": "枣庄",
"value": 120614
},
{
"name": "怀化",
"value": 48647
},
{
"name": "新界",
"value": 329
},
{
"name": "阿勒泰地区",
"value": 2
},
{
"name": "自贡",
"value": 41452
},
{
"name": "营口",
"value": 108605
},
{
"name": "河源",
"value": 56177
},
{
"name": "威海",
"value": 136179
},
{
"name": "商洛",
"value": 39144
},
{
"name": "瑞丽",
"value": 1
},
{
"name": "焦作",
"value": 98645
},
{
"name": "北京",
"value": 1717739
},
{
"name": "鹤壁",
"value": 42904
},
{
"name": "宣城",
"value": 49005
},
{
"name": "淮南",
"value": 54726
},
{
"name": "昭通",
"value": 54965
},
{
"name": "万宁",
"value": 2334
},
{
"name": "铜陵",
"value": 31045
},
{
"name": "青岛莱西",
"value": 27
},
{
"name": "太仓",
"value": 15
},
{
"name": "韩城",
"value": 6
},
{
"name": "镇江",
"value": 151969
},
{
"name": "图木舒克",
"value": 869
},
{
"name": "宜昌",
"value": 106418
},
{
"name": "五指山",
"value": 757
},
{
"name": "吕梁",
"value": 85168
},
{
"name": "达州",
"value": 69415
},
{
"name": "牡丹江",
"value": 69489
},
{
"name": "溧阳",
"value": 1
},
{
"name": "黄冈",
"value": 101061
},
{
"name": "荆州",
"value": 86955
},
{
"name": "芜湖",
"value": 71639
},
{
"name": "新北",
"value": 4997
},
{
"name": "衡水",
"value": 143528
},
{
"name": "乐平",
"value": 5
},
{
"name": "和田",
"value": 46014
},
{
"name": "玉溪",
"value": 62841
},
{
"name": "吉林",
"value": 119684
},
{
"name": "晋州",
"value": 2
},
{
"name": "益阳",
"value": 67738
},
{
"name": "周口",
"value": 153687
},
{
"name": "商丘",
"value": 162361
},
{
"name": "海口",
"value": 203141
},
{
"name": "合肥",
"value": 403592
},
{
"name": "林芝",
"value": 7348
},
{
"name": "张家港",
"value": 1
},
{
"na