【Python】Flask + echart 绘制多Y轴多折线图(数据视图导出excel)

【Python】Flask + echart 绘制多Y轴多折线图(数据视图导出excel)

项目任务:

最近在实习过程中,要写一个flask+echart实现画图表的任务。效果如图;【Python】Flask + echart 绘制多Y轴多折线图(数据视图导出excel)_第1张图片
【Python】Flask + echart 绘制多Y轴多折线图(数据视图导出excel)_第2张图片
【Python】Flask + echart 绘制多Y轴多折线图(数据视图导出excel)_第3张图片


代码整体逻辑:

1、 flask后端代码:flask代码有两个任务,1)定义一个函数,连接mysql数据库,从数据库中查询获取想要的数据并返回。2)路由接收前端ajax传来的用户输入,并传递后端函数数据处理后的json数据
2、 html代码:书写网页格式,并用echart进行画图
3、 echart内置各类属性设置编写


后端代码:

from flask import Flask,render_template
from flask import Flask
from pyecharts import options as opts
from pyecharts.charts import Bar, Grid, Line
from sqlalchemy import Table, MetaData, create_engine
from sqlalchemy.orm import Session
import pandas as pd
import pdfkit
import pymysql
from jinja2 import Markup
from flask import Flask, Response,make_response, jsonify, request, json, render_template
from flask import make_response # 导入make_response模块

conn = pymysql.connect(host = "127.0.0.1",user = 'root', password='777777',database='runoob',charset='utf8',cursorclass=pymysql.cursors.DictCursor)
cur = conn.cursor()
app = Flask(__name__)
#查询获取数据
def getColumnsdatas(sql):
    #游标执行sql,返回数据
    cur.execute(sql)
    #获取第一行,并把光标指到第二行,字典形式数据,json格式
    result = cur.fetchone()

    data = []

    while result:
        data.append(result)
        result = cur.fetchone()

    #最终返回列表嵌套字典形式数据    [{},{},{}..........],
    return data

#连接数据库,执行sql语句,getColumnsdatas方法查找数据
#创建空字典,空列表,
def getDatafromUTModelParam(castno, sn):
    sqltext = "SELECT CASTLEN,CASTSPEED,TDWEIGHT,STOPPERPOSITION,ARPRESS,UPPERE FROM sheet1 where CASTNO = '{}' and strandno='{}'".format(castno,sn)
    result = getColumnsdatas(sqltext)   # [{},{},{}..........],
    #创建空字典,用来保存列表数据
    data_final = {}
    #空列表用来保存CASTLEN数据
    data2_x = []
    for i in range(len(result)):
        a = float(result[i]['CASTLEN'])
        data2_x.append(a)

    data2_y1 = []
    for i in range(len(result)):
        b = float(result[i]['CASTSPEED'])
        data2_y1.append(b)

    data2_y2 = []
    for i in range(len(result)):
        c = float(result[i]['TDWEIGHT'])
        data2_y2.append(c)

    data2_y3 = []
    for i in range(len(result)):
        d = float(result[i]['STOPPERPOSITION'])
        data2_y3.append(d)

    data2_y4 = []
    for i in range(len(result)):
        e = float(result[i]['ARPRESS'])
        data2_y4.append(e)

    data2_y5 = []
    for i in range(len(result)):
        f = float(result[i]['UPPERE'])
        data2_y5.append(f)

    #字典嵌套列表,{‘x':[],'y1':[],'y2':[]......}
    data_final['x'] = data2_x
    data_final['y1'] = data2_y1
    data_final['y2'] = data2_y2
    data_final['y3'] = data2_y3
    data_final['y4'] = data2_y4
    data_final['y5'] = data2_y5

    return data_final
#{'铸坯长度': array([1.0, 1.07, 1.129999, ..., 353.160003, 353.320007, 353.440002],
#      dtype=object), '拉速': array([0.4, 0.4, 0.4, ..., 0.569999, 0.409999, 0.2], dtype=object)}

@app.route("/")
def index():
    return render_template("index.html")

#用来加载时传输38307,5的数据,显示此图
@app.route("/datasend",methods=["POST"])
def data_show():
    #加载时的浇次、流号是个定值,在前端写死’CASTNO‘,'STRANDNO'
    data = json.loads(request.form.get('data'))

    CASTNO_to_load = data['CASTNO']
    STRANDNO_to_load = data['STRANDNO']
    #print(type(x))
    #print(y)
    data_show_first = getDatafromUTModelParam(CASTNO_to_load,STRANDNO_to_load)
    return jsonify(data_show_first)

#接收用户输入值,在后端处理数据后传值给前端echart,显示图表
@app.route("/dataset",methods=["GET","POST"])
def dataset():

    #获取前端input输入值
    num1 = request.form.get("num1")
    num2 = request.form.get("num2")
    data_list = getDatafromUTModelParam(int(num1), int(num2))
    # print(num1)
    # print(num2)
    # print(data_list)
    return jsonify(data_list)
#dataset()

if __name__ == '__main__':
    app.run()

解释:我在上面写了两个函数,主要用来从数据库取数据,并转为列表形式利于传递,echart画图时传递数据格式为列表形式。

前端主要代码:

<form id="demo_form">
    请输入浇次号:<input type="text" name="num1" id="num1">
    请输入流号:<input type="text" name="num2" id="num2">
    <button name="button" type="button" onclick="btnn()">查询button>
form>
{# echart的div,同时margin:0 auto使div网页居中 #}
<div id="main" style="width: 1000px; height: 600px;margin: 0 auto" >div>

解释:前端利用了form表单,form表单中有两个用户输入input。form表单用于后面的ajax值的传递。

 function btnn() {
        //ajax提交,$('#demo_form').serialize(),将input数据转格式,用ajax传入后端处理,然后echart画图
        post_data = $('#demo_form').serialize();
        $.ajax({
            url: "/dataset",
            type: 'POST',
            data: post_data,
            success: function (data, status, request) {
                console.log(data)
                //json_data=JSON.parse(data)

                //var jsonData = JSON.parse(data);
                if (data) {
                    //alert("liuliu")
                    console.log(data);
                    var myChart2 = echarts.init(document.getElementById("main"));
                    x = data['x'];
                    y1 = data['y1'];
                    y2 = data['y2'];
                    y3 = data['y3'];
                    y4 = data['y4'];
                    y5 = data['y5'];
                    plot_line(myChart2, x, y1, y2,y3,y4,y5);
                }
            },
            error: function () {
                console.log("ERROR");
            }
        });
    }

解释:此function响应上面的btnn按钮,实现用户输入值传递给后端,然后后端处理完数据返回给
success(data)里面的data,然后echart定位div并赋值x,y1,y2,y3,y4,y5。最后再写一个画图函数,将
值代入并画图成功。

画图主要代码:

 // 工具栏
            toolbox: {
                show: true,
                // 布局朝向(水平, 垂直) ['horizontal', 'vertical']
                orient: 'horizontal',
                // 各工具配置项
                feature: {
                    // 数据视图工具
                    dataView: {
                        readOnly: false,
                        title: '表格数据',
                        lang: ['表格数据:', '关闭', '导出Excel'],    // 按钮
                        //下载js插件jquery.table2excel.js,用于table转excel      引入,$("#tempChart")是Echarts容器,#tempChart定义table的id,将图表导出
                        contentToOption: function (opts) {
                            $("#tempChart").table2excel({
                                exclude: ".noExl", //过滤位置的 css 类名, 有class = “noExl” 的行不被导出

                                filename: "EXCEL:", // 文件名称
                                name: "Excel Document Name.xls",
                                exclude_img: true,
                                exclude_links: true,
                                exclude_inputs: true
                            });
                        },

                        //视图中显示table形式数据,将折线图数据视图转为table形式
                        optionToContent: function (opt) {
                            let axisData = opt.xAxis[0].data; //坐标数据
                            let series = opt.series; //折线图数据
                            let tdHeads = '<td  style="padding: 0 10px">铸坯长度td>'; //表头
                            let tdBodys = ''; //数据
                            series.forEach(function (item) {
                                //组装表头
                                tdHeads += `<td style="padding: 0 10px">${item.name}td>`;
                            });
                            //下面table的id即为上面 $("#tempChart").table2excel 指定的table转excel的id


                            let table = `<table id='tempChart' border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center"><tbody><tr>${tdHeads} tr>`;
                            for (let i = 0, l = axisData.length; i < l; i++) {
                                for (let j = 0; j < series.length; j++) {
                                    //组装表数据
                                    tdBodys += `<td>${series[j].data[i]}td>`;
                                }
                                table += `<tr><td style="padding: 0 10px">${axisData[i]}td>${tdBodys}tr>`;
                                tdBodys = '';
                            }
                            table += 'tbody>table>';
                            return table;
                        }
                    },
                    // 配置项还原
                    restore: {},
                    // 保存为图片
                    saveAsImage: {}
                }
            },

解释:此段代码根据echart官方修改,最关键点在于toolbox数据视图的设置,需要将数据视图的数据显示在table表中,并可以将table表保存为excel格式保存在本地。
代码关键点在于保存excel时,用到了table2excel.js的插件,可以直接将table表保存为excel,$("#tempChart").table2excel的tempChart是下面转为table格式时table的id为tempChart

总结:

做这个任务,实现网页显示图表并将数据保存为excel的关键点在于,ajax要接收传递怎样形式的数据,弄清楚echart表是如何使用,然后echart画折线图需要设置哪些属性,数据视图如何设置为table形式,又怎么保存为excel,遇见问题多看博客如何解决,结合自己实现形式做小改动。第一次写博客,潦草一写,希望这个博客可以帮到你,开源帮助你我。

你可能感兴趣的:(flask,python,echarts)