vlambda博客
学习文章列表

Flask 结合 Highcharts 实现动态渲染图表

最近动态图表可以说火爆全网,我们当然可以通过很多第三方工具来实现该功能,既方便又美观。可是作为折腾不止的我们来说,有没有办法自己手动实现一个简易版的呢,答案当然是肯定的,今天我们就先来看一看如何基于 highcharts 完成上面的需求。

我们先来看看最终的效果

动态曲线图

Flask 结合 Highcharts 实现动态渲染图表

动态条形图

Flask 结合 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

Flask 结合 Highcharts 实现动态渲染图表

可以看到,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>

至此,我们简易版的动态图表就制作完成了,感兴趣的你要不要来尝试一下呢

近期文章