大屏数据可视化-疫情监控系统2-web程序开发
大屏数据可视化-疫情监控系统
3.Web程序开发
3.1.Flask快速入门
3.1.1Flask的安装与应用
- Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI(Python Web Server Gateway Interface) 工具包采用 Werkzeug ,模板引擎则使 用 Jinja2 ,是目前十分流行的 web 框架。
- 安装:
pip install flask
- 创建Flask项目:pycharm专业版新建项目-flask项目-等待相关组件加载完后,自动生成默认app.py文件-根据需求进行编辑
from flask import Flask
from flask import request
from flask import render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/abc")
def helloworld1():
id=request.values.get("id")
return f"""
<form action="/login">
账号:<input name="name" value="{id}"><br>
密码:<input name="pwd">
<input type="submit">
</form>
"""
@app.route("/login")
def helloworld2():
name=request.values.get("name")
pwd=request.values.get("pwd")
return f'name={name},pwd={pwd}'
@app.route("/tem")
def helloworld3():
#该HTML文件是在templates文件夹中创建的,body里只有一行“疫情追踪”
return render_template("index.html")
if __name__ == '__main__':
app.run()
点击提交:
3.1.2 使用Ajax局部刷新页面
-
Ajax 是 Asynchronous JavaScript and XML 的简称,通过 Ajax 向服务 器发送请求,接收服务器返回的 json 数据,然后使用 JavaScript 修改网 页的来实现页面局部数据更新
-
使用 jquery 框架可方便的编写 ajax 代码,需要 jquery.js 文件
-
…:表示上一级
-
$:表示选择事件
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../static/js/jquery-1.11.1.min.js"></script>
</head>
<body>
<h1>疫情追踪</h1>
<h3>实时报道</h3>
<button>点我有惊喜</button>
<script>
$("button").click(function () {
$.ajax({
url: "/ajax",
type: "post",
data:{"name":"张三","score":99},
success:function (d) {
$("h1").html("武汉感染人数"+d)
},error:function () {
alert("发送ajax请求失败")
}
})
})
</script>
</body>
</html>
app.py
from flask import Flask
from flask import request
from flask import render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/abc")
def helloworld1():
id=request.values.get("id")
return f"""
<form action="/login">
账号:<input name="name" value="{id}"><br>
密码:<input name="pwd">
<input type="submit">
</form>
"""
@app.route("/login")
def helloworld2():
name=request.values.get("name")
pwd=request.values.get("pwd")
return f'name={name},pwd={pwd}'
@app.route("/tem")
def helloworld3():
#该HTML文件是在templates文件夹中创建的
return render_template("index.html")
@app.route('/ajax',methods=['get','post'])
def helloworld4():
name=request.values.get("name")
score=request.values.get("score")
print(f"name:{name},score:{score}") #在控制台打印获取的name和score
return '10000'
if __name__ == '__main__':
app.run()
网页运行结果:
点击后:
3.1.2可视化大屏模板
- 模板的使用:
-
模板就是预先写好的页面,里面可以使用特殊语法引入变量
-
使用render_template返回模板页面
- 模板的制作:
-
使用绝对定位划分板块(事先规划后实现)
-
HBuilder打开Flask项目(cov)-static文件夹下建立css-css下建立css文件main.css-templates文件夹下建立main.html文件
main.ccs
body{ margin: 0; background:#333; } #title{ position: absolute; width: 40%; height: 10%; top: 0; left: 30%; color: white; font-size: 30px; /* 弹性布局,居中设置 */ display: flex; align-items: center; justify-content: center; } #time{ position: absolute; width: 20%; height: 10%; top: 0; right: 0%; background: mediumseagreen; } #c1{ position: absolute; width: 40%; height: 30%; top: 10%; left: 30%; background:darkblue; }
main.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>疫情监控</title> <link href="../static/css/main.css" rel="stylesheet"/> <style> </style> </head> <body> <div id='title'>全国疫情实时追踪</div> <div id="time">我是时间</div> <div id='l1'>我是左1</div> <div id='l2'>我是左2</div> <div id='c1'>我是中1</div> <div id='c2'>我是中2</div> <div id='r1'>我是右1</div> <div id='r2'>我是右1</div> </body> </html>
运行在谷歌浏览器中打开:
-
统计数字及时间
-
调整ccs样式
-
编辑ccs文件,调整时间显示模块样式
#time{ position: absolute; /* width: 30%; */ height: 10%; top: 5%; right: 3%; color: #FFFFFF; font-size: 20px; /* background: mediumseagreen; */ }
-
-
获取时间
-
编辑main.html网页显示时间
<script> function gettime(){ $.ajax({ url:'/time', timeout:10000,//超时时间设置为10秒; success:function(data){ $('#time').html(data) }, error:function(xhr,type,errorThrown){ } }); } // 调用gettime函数,1000毫秒即1秒执行一次 setInterval(gettime,1000) </script>
-
编辑app.py和utilis.py得到时间
app.py
@app.route('/time') def get_time(): return utilis.get_time()
utilis.py
import time def get_time(): time_str=time.strftime('%y{}%m{}%d{} %X')#年月日时分秒 return time_str.format('年','月','日')
运行得到结果:
-
-
-
确诊病例模块-统计数字
-
添加数字
/* 数字显示 */ .num{ width: 25%; float: left; display: flex; align-items: center; justify-content: center; color: gold; font-size: 20px;
-
添加文字
/*标签显示 */ .text{ width: 25%; float: left; display: flex; align-items: center; justify-content: center; font-family: '幼圆'; }
-
-
连接数据库,并从数据库获取对应数据
def get_conn(): """" 创建游标和连接 """ conn = pymysql.connect(host="localhost", user="root", password="liuhao", db="cov", charset="utf8") # 创建游标 cursor = conn.cursor() # 执行完毕返回的结果集默认以元组显示 return conn, cursor def close_conn(conn, cursor): if cursor: cursor.close()# 关闭游标 if conn: conn.close()#关闭连接 def query(sql,*args): """ 封装通用查询 :param sql: :param args: :return: 返回查询到的结果,((),())的形式 """ conn,cursor=get_conn() cursor.execute(sql,args)#查询 res=cursor.fetchall()#获取结果 close_conn(conn,cursor) return res def get_c1_data(): """ :return: 返回大屏div id=cl的数据 """ # 因为会更新多次数据,取时间戳最新的那一组 # comfirm累计的确诊、suspuct剩余疑似、heal累计治愈、dead累计死亡 sql="select sum(confirm)," \ "(select suspect from history order by ds desc limit 1)," \ "sum(heal)," \ "sum(dead) " \ "from details " \ "where update_time = (select update_time from details order by update_time desc limit 1)" res=query(sql)#输出为元祖数据 return res[0]
app.py调用
@app.route('/c1') def get_c1_data(): data=utilis.get_c1_data() return jsonify({'confirm':data[0],'suspect':data[1],'heal':data[2],'dead':data[3]})
编辑html网页文件将数据库数据连接到数字
function get_c1_data(){ $.ajax({ url:'/c1', timeout:10000,//超时时间设置为10秒; success:function(data){ // 数字模块h1下的四个分别设置相应的标签数字-即对应数据 $('.num h1').eq(0).text(data.confirm) $('.num h1').eq(1).text(data.suspect) $('.num h1').eq(2).text(data.heal) $('.num h1').eq(3).text(data.dead) }, error:function(xhr,type,errorThrown){ } }) } // 调用gettime、get_c1_data函数,1000毫秒即1秒执行一次 setInterval(gettime,1000) setInterval(get_c1_data,1000)
运行得到:
3.2echarts绘制图标
3.2.1echarts快速入门
ECharts,缩写来自 Enterprise Charts,商业级数据图表,是百度的一个开源的数据可视 化工具,提供了丰富的图表库,能够在 PC 端和移动设备上流畅运行
官网网站:
https://echarts.apache.org/zh/index.html
5分钟上手echarts:https://www.echartsjs.com/zh/tutorial.html
-
下载echart的js文件,并载入
-
准备一个固定宽高的容器
-
初始化,传入容器的实例化对象
-
在官网或者网上找到想要的形式的图标,复制对应option;修改其中的数值等参数实现更改
-
ectest.setOption(option)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../static/js/echarts.min.js"></script> </head> <body> <div id="main" style="width: 600px;height: 600px;"></div> <script> var ectest = echarts.init(document.getElementById("main"))//初始化 var option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [{ data: [123, 456, 901, 934, 1290, 1330, 1320], type: 'line' }] }; ectest.setOption(option) </script> </body> </html>
3.2.2 echarts绘制全国疫情地图
- 复制中国地图 option,导入 china.js
- 获取数据
3.3问题及解决
1.Requirement already satisfied-已满足要求
对于这样的情况,指定到提示的文件夹下安装
pip install --target= 路径 flask
2. jquery-1.11.1.min.js:4 POST http://127.0.0.1:5000/ajax 405 (METHOD NOT ALLOWED)
请求的方式不被允许,请求Ajax路由没有指定接受的请求方式,默认的方式为get
解决办法:添加post方式
@app.route('/ajax',methods=['get','post'])
- pymysql.err.ProgrammingError: (1064, “You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘from detailswhere update_time = (select update_time from details order by update’ at line 1”)
解决方法:在第四五行后加空格
应该是固定的语法, SELECT 和 FROM 都是 SQL语句的关键字,如果不打空格,就没办法正确的识别查询语句。
-
ECharts is not Loaded
用echarts.js和china.js配置地图,结果显示不正常,打开浏览器后台,显示以上报错。
原因:是在加载echarts.js前加载的china.js,这两个js文件加载顺序是需要注意的,必须先加载echarts.js才能加载其它的地图组件。
参考:
https://lfengting.gitee.io/blog/2020/03/24/python%E7%88%AC%E8%99%AB%E5%AE%9E%E6%88%98/
https://www.bilibili.com/video/BV177411j7qJ