后端跨域配置
安装flask_cors
pip install flask_cors
后端代码实现跨域
from flask_cors import CORS from flask_cors import cross_origin # CORS(app, supports_credentials=True) # 配置全局跨域 @app.route('/detail') @cross_origin(supports_credentials=True) # 配置单路由跨域 def get_detail(): # 省略df的创建过程 jdata = df.to_json(orient='records', force_ascii=False) return jdata
7. 轮询实现+显示加载动画+图表大小调整
在templates目录下创建my_template.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>炫酷的ECharts</title> </head> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width: 800px;height:500px;margin: 0 auto;"></div> <div id="main2" style="width: 800px;height:500px;margin: 0 auto;"></div> <!--引入jquery.js--> <script src="../static/js/jquery.js"></script> <!--引入echarts.js--> <script src="../static/js/echarts.js"></script> <script src="../static/js/my_template.js"></script> <body> </body> </html>
在js目录下创建my_template1.js文件
my_template1.js代码如下:
// 渲染left_up的图表 function echarts_left_up() { // 初始化echarts var myChart = echarts.init(document.getElementById('main')); // 显示加载页面 myChart.showLoading(); var app = { xday: [], yvalue: [] }; // 发送ajax请求 $.ajax({ url: 'http://localhost:5000/test', data: {}, type: 'GET', async: false, dataType: 'json', success: function (data) { app.xday = data.xdays; app.yvalue = data.yvalues; myChart.setOption({ title: { text: '异步数据加载示例' }, tooltip: {}, legend: { data: ['销量'] }, xAxis: { data: app.xday }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: app.yvalue }] }) // 关闭加载动画 myChart.hideLoading(); }, error: function (msg) { console.log(msg); alert('系统发生错误'); } }) // 监听窗口,动态调整echarts大小 window.addEventListener("resize", function () { myChart.resize(); }); } // 用于渲染left_down的图表 function echarts_left_down() { // 初始化echarts var myChart2 = echarts.init(document.getElementById('main2')); // 显示加载动画 myChart2.showLoading() var app2 = { xday: [], yvalue: [] }; var city_list = []; var city_company_list = []; var dict1 = {}; // 发送ajax请求 $.ajax({ url: 'http://localhost:5000/detailjson', // url:'http://localhost:5000/detail', data: {}, type: 'GET', async: false, dataType: 'json', success: function (data) { // 遍历数据 data.forEach((item, index) => { // 进行城市的数量统计 if (dict1.hasOwnProperty(item.城市)) { dict1[item.城市] += 1; } else { dict1[item.城市] = 1; } }); // 获取字典中的key和value值,并生成两个list for (var key in dict1) { city_list.push(key) city_company_list.push(dict1[key]) } app2.xday = city_list; app2.yvalue = city_company_list; // 设置option myChart2.setOption({ title: { text: '异步数据加载示例' }, tooltip: {}, legend: { data: ['销量'] }, xAxis: { data: app2.xday }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: app2.yvalue }] }) // 隐藏加载动画 myChart2.hideLoading() }, error: function (msg) { console.log(msg); alert('系统发生错误'); } }) // 动态调整图表大小 window.addEventListener("resize", function () { myChart2.resize(); }); } // 发送ajax请求,从后台获取json数据 $(document).ready(function () { echarts_left_up(); echarts_left_down(); }); // 加载时调用一次 echarts_left_up() echarts_left_down() // 定期调用 有些占用性能,可以设置单击刷新 var echarts_left_up_id=setInterval(echarts_left_up, 1000 * 10) var echarts_left_down_id=setInterval(echarts_left_down, 1000 * 10) // 清楚定时调用 // window.clearInterval(echarts_left_up_id); // window.clearInterval(echarts_left_down_id);
后端代码webapp.py不需要修改,但也粘贴如下:
from flask import Flask,render_template,jsonify import pymysql import json #生成Flask实例 app=Flask(__name__) from flask_cors import CORS from flask_cors import cross_origin CORS(app, supports_credentials=True) @app.route("/") def hello(): return render_template('my_template.html') @app.route("/template1") def hello1(): return render_template('my_template1.html') #/test路由 接收前端的Ajax请求 @app.route('/test',methods=['POST','GET']) def my_echart(): #连接数据库 conn=pymysql.connect(host='127.0.0.1',user='root',password='111111',db='weblogs') cur=conn.cursor() sql='SELECT t.hour,t.pvs from dw_pvs_everyhour_oneday t' cur.execute(sql) u=cur.fetchall() #转换成json格式 jsonData={} xhour=[] ypvs=[] for data in u: xhour.append(data[0]) ypvs.append(data[1]) print(xhour) print(ypvs) jsonData['xdays']=xhour jsonData['yvalues']=ypvs #json.dumps()用于将dict类型的数据转换成str,因为如果直接将dict类型的数据写入json会报错,因此将数据写入时需要用到此函数 j=json.dumps(jsonData) cur.close() conn.close() #在浏览器上渲染my_template.html模板(为了查看输出数据) return (j) import pandas as pd df = pd.read_csv("DataAnalyst.csv") @app.route('/detail') # @cross_origin(supports_credentials=True) def get_detail(): # 省略df的创建过程 jdata = df.to_json(orient='records', force_ascii=False) return jdata @app.route('/detailjson') # @cross_origin(supports_credentials=True) def get_detail_json(): # 省略df的创建过程 jdata = df.to_json(orient='records', force_ascii=False) return jsonify(json.loads(jdata)) if __name__ == '__main__': app.run(debug=True)
测试:
http://127.0.0.1:5000/template1
8.切换标签实现图标切换
flask代码
在webapp.py文件中添加
from flask import request app.config['JSON_AS_ASCII'] = False @app.route('/switch_echarts') @cross_origin(supports_credentials=True) def switch_bar(): data = request.values.get("type",default=2019) print("="*20) print("datashuju: ",data) year = request.values.get("year",default=2019) print(year) bar_data = {"categories": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], "data": [5, 20, 36, 10, 10, 20]} if year=="2019": bar_data = {"categories": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], "data": [5, 10, 10, 20, 10, 20]} elif year=="2020": bar_data = {"categories": ["第1", "第2", "第3", "第4", "第5", "第6"], "data": [5, 20, 36, 10, 10, 20]} else: bar_data = {"categories": ["第1", "第2", "第3", "第4", "第5", "第6"], "data": [0, 0, 0, 0, 0, 0]} print("****",bar_data) # return json.dumps(bar_data,ensure_ascii=False) return jsonify(bar_data)
html代码
在my_template1.html中添加如下容器
<div class="panel bar"> <h2> 柱状图显示 <!-- 用于显示2019年的数据 this表示当前元素 --> <a onclick="bar_year(this)" type="2019">2019</a> <!-- 用于显示2020年的数据 this表示当前元素--> <a onclick="bar_year(this)" type="2020">2020</a> </h2> <div id="switch_echarts" style="width: 600px;height:600px;"> </div> </div>
js代码:
var switch_echarts_init // 初始化 标签跳转的函数 function switch_echarts_bar(){ if (switch_echarts_init != null && switch_echarts_init != "" && switch_echarts_init != undefined) { switch_echarts_init.dispose();//销毁 } var switch_echarts_init = echarts.init(document.getElementById("switch_echarts")); switch_echarts_init.showLoading(); var option; option={ title: { text: '异步数据加载示例11' }, tooltip: {}, legend: { data:['销量'] }, xAxis: { data: [] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [] }] } // $(selector).get(url,data,success(response,status,xhr),dataType) // 默认读取2019年的数据 $.get('http://127.0.0.1:5000/switch_echarts?year=2019',{data:1},"json").done(function (data) { console.log(data.data) console.log(data.categories) option.series[0].data = data.data option.xAxis.data = data.categories switch_echarts_init.setOption(option); switch_echarts_init.hideLoading(); }); // myChart.hideLoading(); // switch_echarts_init.setOption(option); window.addEventListener("resize", function () { switch_echarts_init.resize(); }); } var time_bar = window.setTimeout(switch_echarts_bar(),5000) // bar choice change function bar_choice_by_year(data){ var type = data.type if (switch_echarts_init != null && switch_echarts_init != "" && switch_echarts_init != undefined) { switch_echarts_init.dispose();//销毁 } var switch_echarts_init = echarts.init(document.getElementById("switch_echarts")); switch_echarts_init.showLoading(); var option; option={ title: { text: type+'异步数据加载示例-切换为' }, tooltip: {}, legend: { data:['销量'] }, xAxis: { data: [] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [] }] } $.get('http://127.0.0.1:5000/switch_echarts?year='+type,{data:1},"json").done(function (data) { option.series[0].data = data.data option.xAxis.data = data.categories switch_echarts_init.setOption(option); switch_echarts_init.hideLoading(); }); window.addEventListener("resize", function () { switch_echarts_init.resize(); }); }