Echarts5.3.2可视化案例-交互篇

2022-11-12 16:40:07 浏览数 (1)

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();
      });

}

0 人点赞