Flask 结合 Highcharts 实现动态渲染图表
最近动态图表可以说火爆全网,我们当然可以通过很多第三方工具来实现该功能,既方便又美观。可是作为折腾不止的我们来说,有没有办法自己手动实现一个简易版的呢,答案当然是肯定的,今天我们就先来看一看如何基于 highcharts 完成上面的需求。
我们先来看看最终的效果
动态曲线图
动态条形图
看起来效果还是不错的,下面我们就一起来看看具体的实现吧。
Highcharts 简介
Highcharts 系列软件包含 Highcharts JS,Highstock JS,Highmaps JS 共三款软件,均为纯 JavaScript 编写的 HTML5 图表库,是一个非常完善的图表库。我们可能对于 ECharts 比较熟悉,而 Highcharts 则是一个可以与之比肩的项目。
文档
https://www.highcharts.com.cn/docs
API 文档
https://api.highcharts.com.cn/highcharts
Highcharts 有着非常完善的文档资料,且其 API 也更为丰富,这就大大降低了我们实现功能的难度。
今天我们要用到的功能主要有两个,分别是 series 的 addPoint 和 数据点(Point)的 update
addPoint
可以看到,addPoint 函数可以在图表渲染完成之后,再进行新增点的操作,通过该函数,我们可以完成曲线图的动态展示效果。
update
update 函数可以不断的更新数据点,从而实现条形图的变化效果。
动态曲线图
我们创建一个 js 文件,就命名为 a.js 吧,然后先定义两个全局变量,并通过 ajax 来获取后台数据
var chart = null; // 定义全局变量
var data = {};
$(document).ready(function () {
$.get({
url: '/get_data/',
'success': function (point) {
data = point;
},
});
chart = chartfunc();
chart.credits.update({
text: 'Power by zhouluobo',
href: 'https://www.luobodazahui.top/',
});
return data;
});
而上面函数中的函数 chartfunc 就是具体的图表配置信息,如下
function chartfunc(){
chart = Highcharts.chart('container', {
chart: {
type: 'spline',
},
title: {
text: '新型冠状病毒肺炎走势'
},
xAxis: {
type: 'category',
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: '确诊人数',
margin: 80
}
},
series: [{
name: '每日新增',
data: []
},
{
name: '累计确诊',
data: []
}]
});
return chart;
}
图表的配置信息都是最为基本的,根据官方文档完全可以搞定。
接下来,我们编写新增数据点的函数
$('#button').click(function () {
var req_data = data;
//具体的参数详见:https://api.hcharts.cn/highcharts#Series.addPoint
var index=0;
var handler = setInterval(function () {
funt();
},500);
function funt() {
if(index<req_data['today'].length){
index++;
if(index>=req_data['today'].length){
clearInterval(handler); //关闭定时
}
chart.series[0].addPoint(req_data['today'][index]);
chart.series[1].addPoint(req_data['total'][index]);
}
}
});
我们在按钮 button 上绑定了 click 事件,在事件中,我们根据后台数据的长度来决定新增数据点的数量。这样,每隔500毫秒,就会新增一个数据点,从而得到动态曲线图的效果。
动态条形图
动态条形图其实也是类似的,在 b.js 文件中,前两段代码一样,对于动态更新数据部分,我们采用 update 函数来实现
$('#button').click(function () {
var req_data = data;
var index=0;
var handler = setInterval(function () {
funt();
},500);
function funt() {
if(index<req_data['total'].length){
if(index>=req_data['total'].length){
clearInterval(handler); //关闭定时
}
chart.series[0].data[0].update({
y: req_data['today'][index]['y']
});
chart.series[1].data[0].update({
y: req_data['total'][index]['y']
});
index++;
}
}
});
下面就是 Flask 和 数据获取的代码了
Flask 与数据获取
我们先定义好路由
from flask import Flask, render_template,jsonify
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/bar/')
def bar_chart():
return render_template('bar.html')
接下来,还是通过如下接口来获取疫情数据
https://c.m.163.com/ug/api/wuhan/app/data/list-total
这个接口在前面的文章中已经讲解过了,这里直接给出解析代码
import requests
@app.route('/get_data/')
def get_data():
total_list = []
today_list = []
ncov_data = {}
headers = {
'user-agent': '',
'accept': ''
}
url = 'https://c.m.163.com/ug/api/wuhan/app/data/list-total'
res = requests.get(url, headers=headers)
data = res.json()['data']['chinaDayList']
for i in data:
date = i['date']
today = i['today']['confirm']
total = i['total']['confirm']
today_list.append({'name': date, 'y': today})
total_list.append({'name': date, 'y': total})
ncov_data['today'] = today_list
ncov_data['total'] = total_list
return jsonify(ncov_data)
最后我们来看看 HTML 文件的代码,其实就是引入 jquery 和 highcharts,然后再创建一个图表容器即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spline Chart</title>
<!-- 引入 jquery.js -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
<!-- 引入 highcharts.js -->
<script src="http://cdn.highcharts.com.cn/highcharts/highcharts.js"></script>
</head>
<body>
<!-- 图表容器 DOM -->
<div id="container" style="min-width:500px;height:500px"></div>
<button id="button" class="autocompare">START</button>
<script src="/static/a.js"></script>
</body>
</html>
至此,我们简易版的动态图表就制作完成了,感兴趣的你要不要来尝试一下呢