【Web开发】Python实现Web图表功能(ECharts.js,Flask,axios+fetch)
  I6bYKJOwynuQ 2023年11月02日 73 0

在这里插入图片描述

1、简介

官网地址: https://echarts.apache.org/zh/index.html 在这里插入图片描述

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

在这里插入图片描述

  • 可视化类型

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

2、Flask + echarts.js(axios例子)

  • test_flask.py:
import json
from flask import Flask, request, jsonify,render_template
app = Flask(__name__)


@app.route('/test')
def hello_world():
    return 'Hello World,爱看书的小沐!'

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

@app.route('/getdata_bar')
def getdata_bar():
    language = ['python', 'java', 'c', 'c++', 'c#', 'php']
    value = ['100', '150', '100', '90', '80', '90']
    return json.dumps({'language':language,'value':value},ensure_ascii=False) 

@app.route('/getdata_pie')
def getdata_pie():
    data = [
        {"value": 235, "name": '视频广告'},
        {"value": 274, "name": '联盟广告'},
        {"value": 310, "name": '邮件营销'},
        {"value": 335, "name": '直接访问'},
        {"value": 400, "name": '搜索引擎'},
        {"value": 90, "name": '其他'},
    ],

    return json.dumps({'data':data},ensure_ascii=False) 

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8080)

2.1 异步请求axios.js(axios.get)

jQuery 的默认 Content-Type 请求头是:Content-Type: application/x-www-form-urlencoded axios 默认的 Content-Type 请求头是:Content-Type: application/json Ajax 请求不来源于 form 提交,flask 的 request.form 是拿不到数据的。 如果项目是从 jQuery 转到 axios 上,需要在 axios 上做 Content-Type 的处理:

axios.post({
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function (response) {
    console.log(response);
})

axio.get的几种写法:

axios.get('/page?ID=123')
    .then(function (response) {
        // handle success
        console.log(response);
    })
    .catch(function (error) {
        // handle error
        console.log(error);
    })
    .then(function () {
        // always executed
    });
  
// or
  
axios.get('/page', {
    params: {
    ID: 123
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
})
.then(function () {
    // always executed
});

如果请求的是图片流,如下:

axios({
    method:'get',
    url:'page/img',
    responseType:'stream'
})
.then(function (response) {
    response.data.pipe(fs.createWriteStream('detail.jpg'))
});

axios.js库的简单示例如下:

<html>
	<head>
		<meta charset="UTF-8">
		<title>LyShark</title>
		<script src="https://cdn.lyshark.com/javascript/axios/0.26.0/axios.min.js"></script>
	</head>

	<body>
		<input type="text" name="name" id="name" />
		<input type="text" name="age" id="age" />
		<button onclick="saveHanderPost()" >提交</button>
	</body>
	
	<!-- 第一种发送方法 -->
	<script type="text/javascript">
		function saveHanderPost()
		{
			let name = document.getElementById("name").value;
			let age = document.getElementById("age").value;

			axios.post("/",{
				name:name,
				age:age
			})
			.then(function(response){
				console.log(response);
				console.log(response.data.username);
				console.log(response.data.message);
			})

			.catch(function(error){
				console.log(error);
			})
		}
	</script>
	
	<!-- 第二种发送方法 -->
	<script type="text/javascript">
	    function saveHanderPostB()
		{
			let name = document.getElementById("name").value;
			let age = document.getElementById("age").value;
			
			axios({
				url: "/",
				method: "post",
				data: {
					name: name,
					age:age
				},
				responseType: "text/json",
			})
			.then(function(response){
				console.log(response);
				console.log(response.data.username);
				console.log(response.data.message);
			})
			.catch(function(error){
				console.log(error);
			})
		}
	</script>
</html>

服务端代码app.py同上。

  • index.html
<!DOCTYPE html>
<html style="height: 100%" lang="en">

<head>
    <meta charset="utf-8">
    <title>My Finance</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script>
    <script src="https://cdn.lyshark.com/javascript/axios/0.26.0/axios.min.js"></script>
</head>

<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width:1000px;height:300px;"></div>

    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            title: {
                text: 'axios.get异步数据加载示例(爱看书的小沐)'
            },
            tooltip: {},
            legend: {
                data: ['1月销量', '2月销量']
            },
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: '1月销量',
                type: 'bar',
                data: []
            },{
                name: '2月销量',
                type: 'bar',
                data: []
            }]
        });

        axios.get('/echarts').then(res => {
        // axios({
        //     method: 'get', 
        //     url: '/echarts',
        //     params: {}
        // }).then((res) => {
            console.log(res);
            myChart.setOption({
                xAxis: {
                    data: res.data.categories
                },
                axisLabel: {
                    show: true,
                    interval: 0,
                    rotate: 40,
                    textStyle: {
                        color: '#333'
                    }
                },
                series: [
                    {
                        name: '1月销量',
                        data: res.data.data
                    },
                    {
                        name: '2月销量',
                        data: res.data.data2
                    }
                ]
            });
        })
    </script>
</body>
</html>

在这里插入图片描述

2.2 异步请求axios.js(axios.post)

服务端代码app.py同上。

  • index.html
<!DOCTYPE html>
<html style="height: 100%" lang="en">

<head>
    <meta charset="utf-8">
    <title>My Finance</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script>
    <script src="https://cdn.lyshark.com/javascript/axios/0.26.0/axios.min.js"></script>
</head>

<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width:1000px;height:300px;"></div>

    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            title: {
                text: 'axios.post异步数据加载示例(爱看书的小沐)'
            },
            tooltip: {},
            legend: {
                data: ['1月销量', '2月销量']
            },
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: '1月销量',
                type: 'bar',
                data: []
            },{
                name: '2月销量',
                type: 'bar',
                data: []
            }]
        });

        axios.post('/echarts', {
            name: 'alma',
            edu: {shcool: 'MIT', age: '20'},
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
        // axios({
        //     url: "/echarts",
        //     method: "post",
        //     data: {
        //         name: 111,
        //         age: 222
        //     },
        //     responseType: "json",
        // })
        .then(function(res){
            // console.log(res);
            // console.log(res.data.username);
            // console.log(res.data.message);
            console.log(res);
            myChart.setOption({
                xAxis: {
                    data: res.data.categories
                },
                axisLabel: {
                    show: true,
                    interval: 0,
                    rotate: 40,
                    textStyle: {
                        color: '#333'
                    }
                },
                series: [
                    {
                        name: '1月销量',
                        data: res.data.data
                    },
                    {
                        name: '2月销量',
                        data: res.data.data2
                    }
                ]
            });
        })
        .catch(function(error){
            console.log(error);
        })
       
    </script>
</body>
</html>

在这里插入图片描述

3、Flask + echarts.js(fetch例子)

Fetch API 提供了一个获取资源的接口(包括跨网络通信)。对于任何使用过 XMLHttpRequest 的人都能轻松上手,而且新的 API 提供了更强大和灵活的功能集。

Fetch 提供了对 Request 和 Response(以及其它与网络请求有关的)对象的通用定义。这将在未来更多需要它们的地方使用它们,无论是 service worker、Cache API,又或者是其它处理请求和响应的方式,甚至是任何一种需要你自己在程序中生成响应的方式(即使用计算机程序或者个人编程指令)。

发送请求或者获取资源,请使用 fetch() 方法。它在很多接口中都被实现了,更具体地说,是在 Window 和 WorkerGlobalScope 接口上。因此在几乎所有环境中都可以用这个方法获取资源。

fetch 规范主要在三个方面与 jQuery.ajax() 不同:

  • 从 fetch() 返回的 Promise 不会因 HTTP 的错误状态而被拒绝,即使响应是 HTTP 404 或 500。相反,它将正常兑现(ok 状态会被设置为 false),并且只有在网络故障或者有任何阻止请求完成时,才拒绝。
  • 除非你在 init 对象中设置(去包含)credentials,否则 fetch() 将不会发送跨源 cookie。

3.1 异步请求fetch(fetch+get)

服务端代码app.py同上。

  • index.html
<!DOCTYPE html>
<html style="height: 100%" lang="en">

<head>
    <meta charset="utf-8">
    <title>My ECharts</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script>
    <!-- 引入 vintage 主题 -->
</head>

<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width:1000px;height:300px;"></div>

    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            title: {
                text: 'fetch+get异步数据加载示例(爱看书的小沐)'
            },
            tooltip: {},
            legend: {
                data: ['1月销量', '2月销量']
            },
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: '1月销量',
                type: 'bar',
                data: []
            },{
                name: '2月销量',
                type: 'bar',
                data: []
            }]
        });
		
		<!-- //(1) -->
		<!-- fetch("/echarts").then(res=>res.json()).then(res=>{ -->
			<!-- console.log(res); -->
		<!-- }) -->

		<!-- //(2) -->
		<!-- fetch("/echarts") -->
		<!-- .then(res=>{ -->
			<!-- console.log(res.status); // 200 -->
			<!-- console.log(res.statusText); // ok -->
		<!-- }) -->

		//(3)
		fetch("/echarts").then(response=>{
		<!-- fetch("/echarts").then(function(response){ -->
			<!-- return response.blob(); -->
			<!-- return response.text(); -->
			return response.json();
		}).then(function(data){
			console.log(data);
			myChart.setOption({
                xAxis: {
                    data: data.categories
                },
                axisLabel: {
                    show: true,
                    interval: 0,
                    rotate: 40,
                    textStyle: {
                        color: '#333'
                    }
                },
                series: [
                    {
                        name: '1月销量',
                        data: data.data
                    },
                    {
                        name: '2月销量',
                        data: data.data2
                    }
                ]
            });
			alert("ok");
		});
		

    </script>
</body>
</html>

在这里插入图片描述

3.2 异步请求fetch(fetch+post)

 let payload = 'foo=bar&name=tomcat';
    let paramHeaders = new Headers({
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    });
    fetch('/send-params', {
      method: 'POST',   // 发送请求体时必须使用一种HTTP方法
      body: payload,
      headers: paramHeaders
    });

服务端代码app.py同上。

  • index.html
<!DOCTYPE html>
<html style="height: 100%" lang="en">

<head>
    <meta charset="utf-8">
    <title>My ECharts</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script>
    <!-- 引入 vintage 主题 -->
</head>

<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width:1000px;height:300px;"></div>

    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            title: {
                text: 'fetch + post异步数据加载示例(爱看书的小沐)'
            },
            tooltip: {},
            legend: {
                data: ['1月销量', '2月销量']
            },
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: '1月销量',
                type: 'bar',
                data: []
            },{
                name: '2月销量',
                type: 'bar',
                data: []
            }]
        });
		
		<!-- fetch("http://127.0.0.1:3000/books", { -->
		fetch("/echarts", {
			method: "post",
			<!-- body: "uname=lisi&pwd=123", -->
			body: "",
			header: {
				"Content-Type": "application/x-www-form-urlencoded"
			}
		}).then(function(response){
			return response.json();
		}).then(function(response){
			console.log(response);
			myChart.setOption({
                xAxis: {
                    data: response.categories
                },
                axisLabel: {
                    show: true,
                    interval: 0,
                    rotate: 40,
                    textStyle: {
                        color: '#333'
                    }
                },
                series: [
                    {
                        name: '1月销量',
                        data: response.data
                    },
                    {
                        name: '2月销量',
                        data: response.data2
                    }
                ]
            });
			alert("ok");
		})

    </script>
</body>
</html>

在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡) 感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

在这里插入图片描述

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  1BVmdlLr07sm   2023年11月30日   71   0   0 HTMLcss
I6bYKJOwynuQ
最新推荐 更多