赞
踩
PyEcharts 与 Flask 框架整合的前后端混合模式,其操作流程如下图所示:
图 2:前后端混合模式操作流程
创建项目环节会创建一个空白的 Flask 项目,复制模板环节会复制 PyEcharts 模板文件到 Flask 项目模板文件目录 templates,渲染图表环节通过后台程序,基于 PyEcharts 模板文件,渲染可视化图表。
我们依次来看。
创建项目的方式同普通 Flask 项目的创建一样,我们只需要创建一个空白的文件夹即可。考虑到模板的默认访问目录,我们需要在空白文件夹下,创建一个 templates 文件夹,用来存放 PyEcharts 模板文件。创建项目完成之后的文件结构如下图所示:
图 3:创建空白项目
复制模板指复制 PyEcharts 模板文件到新创建的 Flask 空白项目模板文件夹中。具体的操作方式分为 2 个步骤:
找到 PyEcharts 模板文件;
复制 PyEcharts 模板文件到 Flask 空白项目的 templates 文件夹。
查找 PyEcharts 模板文件的路径,可以通过 pip show pyecharts 指令,查询其安装位置。具体的操作指令执行界面如下图所示:
图 4:PyEcharts 安装目录查询
通过上述指令我们可以看到 PyEcharts 的安装目录位于:d:\program files\python36\lib\site-packages,我们可以通过文件管理器打开该目录。对应的模板文件如下图所示:
图 5:PyEcharts 模板文件
复制上述文件到新创建的 Flask 项目模板文件夹下,默认文件夹名称为 templates。复制后的目录结构如下图所示:
图 6:项目模板文件
前后端混合模式的图表渲染,是 Flask 应用创建过程和 PyEcharts 图表创建过程的整合。一个简单的示例程序如下:
图 7:渲染图表
上图中,首先创建了一个 Flask 应用对象,设定了默认模板目录为 templates,然后定义了一个图表生成函数,接下来通过业务响应函数 index,调用图表生成函数 bar_base(),最后通过 Flask 函数 Markup()进行图表渲染。
PyEcharts 与 Flask 整合之后的路由设置方式,完全采用的是 Flask 的路由设置方式,没有任何区别。相关内容参见“13 | Flask Web 框架基础”。
PyEcharts 与 Flask 整合之后,可以通过启动 Flask 应用程序的方式直接启动服务,然后通过浏览器进行访问。上述示例程序运行效果如下图所示:
图 8:PyEcharts 与 Flask 整合案例运行演示
通过上述内容,我们可以看到 PyEcharts 与 Flask 框架整合,影响到只是业务响应环节,在这一部分,进行 PyEcharts 图表生成,并调用 Flask 模板渲染函数进行页面渲染,其他部分相比标准得 Flask 应用程序,没有任何区别。
PyEcharts 与 Flask 框架整合的前后端分离模式,其操作流程如下图所示:
图 9:前后端分离模式
创建项目环节会创建一个空白的 Flask 项目,复制模板环节会复制 PyEcharts 模板文件到 Flask 项目模板文件目录 templates**,前端页面设计环节**设计需要展示的页面布局,图表渲染环节配置 PyEcharts 图表参数,路由设计环节设计客户端请求路由。
创建路由和复制模板环节的操作方式与前后端混合模式完全一样,我就不再赘述,接下来的介绍会从前端页面设计开始。
前端页面设计导入 Echarts 图表库文件,声明图表对象占位符,绑定页面元素,访问远程接口,完成图表对象的参数设置和渲染。一个典型的前端页面文件示例如下图所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="bar" style="width:1000px; height:600px;"></div>
<script>
$(
function () {
var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
$.ajax({
type: "GET",
url: "http://127.0.0.1:5000/barChart",
dataType: 'json',
success: function (result) {
chart.setOption(result);
}
});
}
)
</script>
</body>
</html>
服务接口设计是针对前端页面的数据请求设计,该接口请求的数据为 Echarts 的图表配置参数。具体的服务路由和响应函数如下图所示:
def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
.add_yaxis("商家 A", [randrange(0, 100) for _ in range(6)])
.add_yaxis("商家 B", [randrange(0, 100) for _ in range(6)])
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="Flask 整合:前后端分离模式"))
)
return c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
@app.route(“/barChart”)
def get_bar_chart():
c = bar_base()
return c.dump_options_with_quotes()
当浏览器页面打开地址:http://127.0.0.1:5000/ 时,页面脚本会主动调用服务器端接口: http://127.0.0.1:5000/barChart,获取图表组件配置参数,并进行页面渲染。
PyEcharts 与 Flask 整合:前后端分离模式,路由设置包括两部分:
页面路由请求;
数据路由请求。
页面路由请求完成页面内容的渲染,数据路由请求完成图表参数的传递。上述示例程序,完整的路由设置如下所示:
# 数据服务接口:图表
@app.route("/barChart")
def get_bar_chart():
c = bar_base()
return c.dump_options_with_quotes()
@app.route(“/”)
def index():
return render_template(“index.html”)
页面路由设置了页面根目录的访问方式,同时绑定了业务响应函数:index(),该函数以模板页面为参数,执行了页面渲染。数据路由设置了图表数据请求的响应接口,并绑定了业务响应函数 get_bar_chart()。
PyEcharts 与 Flask 整合之后,无论是前后端混合模式还是前后端分离模式,都可以通过启动 Flask 应用程序的方式直接启动服务,然后通过浏览器进行访问。程序运行效果如下图所示:
图 10:前后端分离模式运行演示
PyEcharts 与 Flask 整合的前后端分离模式,首先是前端页面和后台服务程序之间的解耦,彼此之间约定好数据服务接口,即可执行前后端的各自独立开发。
前后端分离的开发模式,是目前主流的开发模式,可以实现并行开发,从而加快项目的开发进展。
实际业务需求中,我们经常需要定时刷新页面数据,尤其是在一些实时监控业务场景下,定时刷新数据成为一个常规需求。
接下来,我们来看 PyEcharts 和 Flask 整合后,如何实现页面数据的刷新。
定时全量更新是前端页面发起的,周期性更新整个图表内容的刷新方式,更新的内容包括整个图表的配置参数。
实现原理是在前端页面调用 HTML 定时器函数:setInterval(),重新发起图表配置参数的接口调用。
定时全量更新模式下,后台应用程序不需要做出调整,只需要在前端页面增加基于定时器的调度函数。一个完整的前端页面示例程序如下图所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="bar" style="width:1000px; height:600px;"></div>
<script>
var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
$(
function () {
fetchData(chart);
setInterval(fetchData, 2000);
}
);
function fetchData() {
$.ajax({
type: "GET",
url: "http://127.0.0.1:5000/barChart",
dataType: 'json',
success: function (result) {
chart.setOption(result);
}
});
}
</script>
</body>
</html>
上述程序中,通过 HTML 函数 setInterval(),设置了一个定时器对象,每隔 2 秒钟,重新调用一次图表对象渲染函数 fetchData(),实现定时全量更新图表对象。
定时全量更新程序执行的效果,无法从一张图中直观体现出来,你可以自己运行程序后,看动态效果。我们通过相隔 5 秒钟的两张截图(图 12、图 13)来看:
图 11:定时全量更新图一
图 12:定时全量更新图二
通过以上示例程序,我们可以看到定时全量更新图表是通过前端页面设置定时器函数,定时重新访问图表配置参数接口实现的。
定时增量刷新是前端页面发起的、周期性更新整个图表内容的刷新方式,更新的内容只包括图表的数据部分。
实现的原理是在前端页面调用 HTML 定时器函数:setInterval(),重新发起图表配置数据项参数的接口调用。
定时增量更新模式下,需要前台页面和后台应用程序同时做出调整。一方面需要前端页面增加基于定时器的调度函数,另外一方面需要后台应用程序设置单独的增量数据服务接口。一个定时增量更新完整的前端页面示例程序如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id=“bar” style=“width:1000px; height:600px;”></div>
<script>
var chart = echarts.init(document.getElementById(‘bar’), ‘white’, {renderer: ‘canvas’});
var old_data = [];
$(
function () {
fetchData(chart);
setInterval(getDynamicData, 2000);
}
);
// 图表渲染:初始全量获取配置参数
function fetchData() {
$.ajax({
type: “GET”,
url: “http://127.0.0.1:5000/lineChart”,
dataType: “json”,
success: function (result) {
chart.setOption(result);
old_data = chart.getOption().series[0].data;
}
});
}
// 增量数据:定时重置数据属性
function getDynamicData() {
$.ajax({
type: “GET”,
url: “http://127.0.0.1:5000/lineDynamicData”,
dataType: “json”,
success: function (result) {
old_data.push([result.name, result.value]);
chart.setOption({
series: [{data: old_data}]
});
}
});
}
</script>
</body>
</html>
上述程序定义了一个 HTML定时器,每隔 2 秒钟,刷新一次。刷新的过程是:重新设置 Echarts 图表对象的数据属性,其他属性如标题、工具栏、提示框等参数维持不变。
相应的,我们需要在后台应用程序中,增加 Echarts 图表配置项的数据属性查询的数据服务接口。与上述前端页面程序相对应的,后台应用服务器程序的完整的源码结构如下所示:
# 定时增量数据更新示例
from random import randrange
from flask.json import jsonify
from flask import Flask, render_template
from pyecharts import options as opts
from pyecharts.charts import Line
# 01-创建一个 Flask 应用
app = Flask(__name__, static_folder="templates")
def line_base() -> Line:
line = (
Line()
.add_xaxis([“{}”.format(i) for i in range(10)])
.add_yaxis(
series_name=“”,
y_axis=[randrange(50, 80) for _ in range(10)],
is_smooth=True,
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title=“动态数据”),
xaxis_opts=opts.AxisOpts(type_=“value”),
yaxis_opts=opts.AxisOpts(type_=“value”),
)
)
return line
@app.route(“/”)
def index():
return render_template(“index.html”)
@app.route(“/lineChart”)
def get_line_chart():
c = line_base()
return c.dump_options_with_quotes()
idx = 9
@app.route(“/lineDynamicData”)
def update_line_data():
global idx
idx = idx + 1
return jsonify({“name”: idx, “value”: randrange(50, 80)})
if name == “main”:
app.run()
上述程序中,共声明了 3 个服务接口:页面渲染服务接口、Echarts 图表参数配置查询接口和 Echarts 图表数据项配置参数更新接口,并且绑定了对应的业务响应函数。
定时增量更新案例程序执行以后的效果,我们同样需要在页面上才可以看到动态效果。在此,我只截取一个页面,呈现具体的动态执行的效果。你可以自行执行应用程序查看。定时增量更新程序运行以后的效果如下所示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。