Echarts5.3.2可视化案例-交互篇
- Echarts简介
- 官网介绍
- Echarts案例
- Echarts 前后端交互
- 1. 安装flask
- 2. 创建appweb.py
- 3. flask返回json数据 中文显示
- 4. flask读取数据库返回json数据
- 5. flask返回pandas读取的数据
- 6. flask解决CORS跨域问题
- 7. 轮询实现 显示加载动画 图表大小调整
- 8.切换标签实现图标切换
Echarts简介
官网介绍
1.官网地址:
https://echarts.apache.org/en/index.html https://echarts.apache.org/zh/index.html
2.介绍下官网:
看文档 知道如何下载 通过github下载 在dist目录下 echarts.js 示例 https://echarts.apache.org/examples/zh/index.html gallery资源 https://www.makeapie.com/explore.html#s
Echarts案例
https://echarts.apache.org/zh/tutorial.html 1.下载echarts.js到本地 2.然后在html文件中通过如下引入
代码语言:javascript复制<script src="echarts.min.js"></script>
或通过cdn免下载引入
代码语言:javascript复制<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.js"></script>
3.使用 初始化一个具有宽和高的容器
代码语言:javascript复制<div id="main" style="width: 600px ;height:600px;"></div>
在script中进行如下操作 初始化e’charts,绑定容器
代码语言:javascript复制<script>
// init echarts
var myid = document.getElementById("main");
var myecharts = echarts.init(myid);
// define option
// invoking function
</script>
设置option,这里包括我们想要绘制的图形类型,数据,x,y轴信息等 在官网示例中找
代码语言:javascript复制 // define option
var option = {
title:{
text:"echarts 标题"
},
xAxis:{
data:['food','digital','dress','bags']
},
yAxis:{
},
series:{
type:"bar",
data:[100,120,90,150]
},
}
将option传给myecharts实例就可以了
代码语言:javascript复制 //Call the function and pass the arguments
myecharts.setOption(option);
展示如图
Echarts 前后端交互
1. 安装flask
代码语言:javascript复制pip install flask==2.0.3
2. 创建appweb.py
并初始化appweb.py
代码语言:javascript复制from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
@app.route('/hello')
def hello():
return 'Hello2'
# app.run(host, port, debug, options)
app.run("0.0.0.0",5000,debug=True,)
必须在项目中导入Flask模块。 Flask类的一个对象是我们的WSGI应用程序。 Flask构造函数使用当前模块(__name __)的名称作为参数。 Flask类的route()函数是一个装饰器,它告诉应用程序哪个URL应该调用相关的函数。
测试 http://localhost:5000/hello http://localhost:5000/hello
3. flask返回json数据 中文显示
代码语言:javascript复制app.config['JSON_AS_ASCII'] = False
# 随便定义个json字典
dic={"a":1,"b":2,"c":"你好"}
@app.route('/jsonify')
def jsonifys():
# Content-Type: application/json
return jsonify(dic)
@app.route('/jsondumps')
def jsondumps():
# Content-Type: text/html; charset=utf-8
return json.dumps(dic,ensure_ascii=False)
测试: http://localhost:5000/jsonify http://localhost:5000/jsondumps
使用jsonify方法是需要添加一句 app.config[‘JSON_AS_ASCII’] = False 而json.dumps方法需要添加参数 ensure_ascii=False 这样做可以避免显示中文乱码。
4. flask读取数据库返回json数据
SQL文件:
代码语言:javascript复制/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50723
Source Host : localhost:3306
Source Schema : weblogs
Target Server Type : MySQL
Target Server Version : 50723
File Encoding : 65001
Date: 14/04/2022 12:54:40
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dw_pvs_everyhour_oneday
-- ----------------------------
DROP TABLE IF EXISTS `dw_pvs_everyhour_oneday`;
CREATE TABLE `dw_pvs_everyhour_oneday` (
`month` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '月份',
`day` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '日期',
`hour` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '小时',
`pvs` int(11) NULL DEFAULT NULL COMMENT '每天浏览量'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dw_pvs_everyhour_oneday
-- ----------------------------
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 07', 13);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 08', 11);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 09', 14);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 10', 3);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 11', 2);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 12', 4);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 13', 5);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 14', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 15', 2);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 16', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 17', 4);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 19', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 22', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '18', ' 23', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '19', ' 00', 4);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '19', ' 02', 2);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '19', ' 03', 5);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '19', ' 04', 1);
INSERT INTO `dw_pvs_everyhour_oneday` VALUES ('09', '19', ' 05', 1);
Python web代码: 在工程目录下创建static和templates目录,如下:
在工程目录下创建webapp.py文件,内容如下:
代码语言:javascript复制from flask import Flask,render_template,url_for
import pymysql
import json
#生成Flask实例
app=Flask(__name__)
@app.route("/")
def hello():
return render_template('my_template.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)
if __name__ == '__main__':
app.run(debug=True)
测试: http://localhost:5000/test
在templates文件夹下创建my_template.html,代码如下:
代码语言:javascript复制<!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>
<!--引入jquery.js-->
<script src="../static/js/jquery.js"></script>
<!--引入echarts.js-->
<script src="../static/js/echarts.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var app = {
xday:[],
yvalue:[]
};
// 发送ajax请求,从后台获取json数据
$(document).ready(function () {
getData();
console.log(app.xday);
console.log(app.yvalue)
});
function getData() {
$.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
}]
})
},
error:function (msg) {
console.log(msg);
alert('系统发生错误');
}
})
};
</script>
<body>
</body>
</html>
测试: 打开http://localhost:5000/ 返回截图如下:
5. flask返回pandas读取的数据
数据样例:
后端代码:
代码语言:javascript复制import pandas as pd
df = pd.read_csv("DataAnalyst.csv")
@app.route('/detail')
def get_detail():
# 省略df的创建过程
jdata = df.to_json(orient='records', force_ascii=False)
# 返回值为一个字符串
return jdata
@app.route('/detailjson')
def get_detail_json():
# 省略df的创建过程
jdata = df.to_json(orient='records', force_ascii=False)
# 返回值为json数据
return jsonify(json.loads(jdata))
前端代码:
代码语言:javascript复制<div id="main2" style="width: 800px;height:500px;margin: 0 auto;"></div>
<script type="text/javascript">
var myChart2 = echarts.init(document.getElementById('main2'));
var app2 = {
xday:[],
yvalue:[]
};
// 发送ajax请求,从后台获取json数据
$(document).ready(function () {
getData();
console.log(app.xday);
console.log(app.yvalue);
getDfData();
});
var city_list = [];
var city_company_list = [];
var dict1 = {};
function getDfData() {
$.ajax({
//url:'http://localhost:5000/detail',
url:'http://localhost:5000/detailjson',
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;
}
});
for(var key in dict1){
city_list.push(key)
city_company_list.push(dict1[key])
}
app2.xday = city_list;
app2.yvalue = city_company_list;
console.log(app2)
myChart2.setOption({
title: {
text: '异步数据加载示例'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: app2.xday
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: app2.yvalue
}]
})
},
error:function (msg) {
console.log(msg);
alert('系统发生错误');
}
})
};
</script>
6. flask解决CORS跨域问题
如果前端代码不在flask工程下,或是直接打开html,会出现无法前端无法获得数据的情况,这时可以配置跨域请求 什么是跨域?
后端跨域配置 安装flask_cors
代码语言:javascript复制pip install flask_cors
后端代码实现跨域
代码语言:javascript复制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
代码语言:javascript复制<!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代码如下:
代码语言:javascript复制// 渲染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不需要修改,但也粘贴如下:
代码语言:javascript复制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文件中添加
代码语言:javascript复制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中添加如下容器
代码语言:javascript复制<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代码:
代码语言:javascript复制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();
});
}