最近在实习过程中,要写一个flask+echart实现画图表的任务。效果如图;
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,遇见问题多看博客如何解决,结合自己实现形式做小改动。第一次写博客,潦草一写,希望这个博客可以帮到你,开源帮助你我。