python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Flask Echarts绘制图形

Flask框架利用Echarts实现绘制图形

作者:lyshark

echarts是百度推出的一款开源的基于JavaScript的可视化图表库,该开发库目前发展非常不错,且支持各类图形的绘制可定制程度高。如下演示案例中,将分别展示运用该绘图库如何前后端交互绘制(饼状图,柱状图,折线图)这三种最基本的图形,需要的可以参考一下

echarts是百度推出的一款开源的基于JavaScript的可视化图表库,该开发库目前发展非常不错,且支持各类图形的绘制可定制程度高,Echarts绘图库同样可以与Flask结合,前台使用echart绘图库进行图形的生成与展示,后台则是Flask通过render_template方法返回一串JSON数据集,前台收到后将其应用到绘图库上,实现动态展示Web服务日志状态功能。

如下演示案例中,将分别展示运用该绘图库如何前后端交互绘制(饼状图,柱状图,折线图)这三种最基本的图形。

实现绘制饼状图

用于模拟统计Web容器的日志数据,通过饼状图将访问状态统计出来。

前端部分/templates/index.html代码如下:

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

	<body>
		<div class="panel panel-primary" style="width: 40%;height: 30%; float: left">
		<div class="panel-heading">
			<h3 class="panel-title">LyShark 网站访问状态统计</h3>
		</div>
		<div class="panel-body">
			<div id="main" style="width:100%; height: 300px"></div>
		</div>
		</div>
	</body>

	<script type="text/javascript" charset="UTF-8">
		var kv = new Array();
		kv = {{ data | safe }}
		var test = new Array();
		for(var logkey in kv){
			test.push( {value:kv[logkey], name:logkey} )
		}
		var display = function(){
			var main = echarts.init(document.getElementById("main"));
			var option = {
				legend: {
					orient: 'vertical',
					left: 'left',
				},
				series: [
					{
						type: 'pie',
						radius: '70%',
						center: ['50%', '50%'],
						detail: {formatter:'{value}'},
						data: test
					}
				]
			};
			main.setOption(option,true);
		};
		display();
	</script>
</html>

后端代码如下通过模拟render_template返回一些数据。

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # 配置静态文件的访问url前缀
            static_folder='static',      # 配置静态文件的文件夹
            template_folder='templates') # 配置模板文件的文件夹

def Count_Flag_And_Flow(file):
    list = []
    flag = {}
    with open(file) as f:
        contexts = f.readlines()
    for line in contexts:
        it = line.split()[8]
        list.append(it)
    list_num = set(list)
    for item in list_num:
        num = list.count(item)
        flag[item] = num
    return flag

@app.route('/', methods=["GET"])
def index():
    Address = {'226': 4, '404': 12, '200': 159, '400': 25, '102': 117, '302': 1625}
    # Address = Count_Flag_And_Flow("d://access_log")
    return render_template("index.html",data = json.dumps(Address))

if __name__ == '__main__':
    app.run(host="127.0.0.1", port=80, debug=False)

运行后访问自定义域名,输出如下效果的饼状图:

实现绘制柱状图

统计访问了本站的所有ID地址并将地址数大于2的全部显示出来.

前端index.html代码如下

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

	<body>
		<div class="panel panel-primary" style="width: 58%;height: 30%; float: left">
			<div class="panel-heading">
				<h3 class="panel-title">LyShark 网站设备类型统计</h3>
			</div>
			<div class="panel-body">
				<div id="main1" style="width:100%; height: 300px"></div>
			</div>
		</div>
	</body>

	<script type="text/javascript" charset="UTF-8">
			var kv = new Array();
			var keys = new Array();
			var values = new Array();
			kv = {{ data | safe }}

			for(var logkey in kv){
				keys.push(logkey);
				values.push(kv[logkey]);
			}
			var display = function() {
				var main1 = echarts.init(document.getElementById("main1"));
				var option = {
					xAxis: {
						type: 'category',
						data: keys
					},
					yAxis: {
						type: 'value'
					},
					series: [{
						data: values,
						type: 'bar'
					}]
				};
				main1.setOption(option,true);
			};
		display();
	</script>
</html>

后端代码如下,路由曾则只保留一个index映射

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # 配置静态文件的访问url前缀
            static_folder='static',      # 配置静态文件的文件夹
            template_folder='templates') # 配置模板文件的文件夹

def Count_Flag_And_Type(file):
    list = []
    flag = {}
    with open(file) as f:
        contexts = f.readlines()
    for line in contexts:
        addr = line.split()[0].replace("(","").replace(")","")
        if addr != "::1":
            list.append(addr)

    # 去重并将其转为字典
    list_num = set(list)
    for item in list_num:
        num = list.count(item)
        # 如果地址只有一次则忽略
        if num > 1:
            flag[item] = num
    return flag

@app.route('/', methods=["GET"])
def index():
    Types = {'Linux': 23, 'studies': 57, 'Windows': 87, 'compatible': 44, 'web': 32, 'X11': 78}
    # Types = Count_Flag_And_Type("d://access_log")
    return render_template("index.html",data = json.dumps(Types))

if __name__ == '__main__':
    app.run(host="127.0.0.1", port=80, debug=False)

柱状图绘制效果如下:

实现绘制折线图

统计指定的时间段内的访问流量数据.

前端index.html代码如下

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

	<body>
		<div class="panel panel-primary" style="width: 100%;height: 30%; float: left">
			<div class="panel-heading">
				<h3 class="panel-title">LyShark 网站流量统计</h3>
			</div>
			<div class="panel-body">
				<div id="main" style="width:100%; height: 400px"></div>
			</div>
		</div>
	</body>

	<script type="text/javascript" charset="UTF-8">
			var kv = new Array();
			var keys = new Array();
			var values = new Array();
			kv = {{ data | safe }};
			for(var logkey in kv){
				keys.push(logkey);
				values.push(kv[logkey]);
			}

			var display = function() {
				var main = echarts.init(document.getElementById("main"));
				var option = {
					xAxis: {
						type: 'category',
						boundaryGap: false,
						data: keys
					},
					yAxis: {
						type: 'value'
					},
					series: [{
						data: values,
						type: 'line',
						areaStyle: {},
					}]
				};
				main.setOption(option,true);
			};
		display();
	</script>
</html>

后端代码如下,路由曾则只保留一个index映射

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # 配置静态文件的访问url前缀
            static_folder='static',      # 配置静态文件的文件夹
            template_folder='templates') # 配置模板文件的文件夹

def Count_Time_And_Flow(file):
    times = {}  # key 保存当前时间信息
    flow = {}   # value 当前时间流量总和
    Count= 0    # 针对IP地址的计数器
    with open(file) as f:
        contexts = f.readlines()
    for line in contexts:
        if line.split()[9] != "-" and line.split()[9] != '"-"':
            size = line.split()[9]
        temp = line.split()[3]
        ip_attr = temp.split(":")[1] + ":" + temp.split(":")[2]
        Count = int(size) + Count
        if ip_attr in times.keys():
            flow[ip_attr] = flow[ip_attr] + int(size)
        else:
            times[ip_attr] = 1
            flow[ip_attr] = int(size)
    return flow

@app.route('/', methods=["GET"])
def index():
    OutFlow = {'03:30': 12, '03:48': 25, '04:15': 47, '04:28': 89, '04:42': 66, '04:51': 54}
    # OutFlow = Count_Time_And_Flow("d://access_log")
    return render_template("index.html",data = json.dumps(OutFlow))

if __name__ == '__main__':
    app.run(host="127.0.0.1", port=80, debug=False)

折现图绘制效果如下:

如上是三种常用图形的绘制方式,其他图形同理可以参考如上方代码中的写法,我们可以将这三个图形合并在一起,主要是前端对其进行排版即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdn.lyshark.com/javascript/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" >
    <script type="text/javascript" src="https://cdn.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://cdn.lyshark.com/javascript/echarts/5.0.0/echarts.min.js"></script>
</head>
<body>

    <!--饼状图绘制方法-->
    <div class="panel panel-primary" style="width: 40%;height: 30%;float: left">
        <div class="panel-heading">
            <h3 class="panel-title">饼状图绘制</h3>
        </div>
        <div class="panel-body">
            <div id="PieChart" style="width:100%; height: 300px"></div>
        </div>
    </div>

    <!--柱状图绘制方法-->
    <div class="panel panel-primary" style="width: 58%;height: 30%; float: right">
        <div class="panel-heading">
            <h3 class="panel-title">柱状图绘制</h3>
        </div>
        <div class="panel-body">
            <div id="HistogramChart" style="width:100%; height: 300px"></div>
        </div>
    </div>

    <!--折线图绘制方法-->
    <div class="panel panel-primary" style="width: 100%;height: 40%; float: left">
        <div class="panel-heading">
            <h3 class="panel-title">折线图绘制</h3>
        </div>
        <div class="panel-body">
            <div id="Linechart" style="width:100%; height: 460px"></div>
        </div>
    </div>

    <!--饼状图绘制方法-->
    <script type="text/javascript" charset="UTF-8">
        var kv = new Array();
        kv = {{ Address | safe }}
        var test = new Array();
        for(var logkey in kv){
            test.push( {value:kv[logkey], name:logkey} )
        }
        var display = function(){
            var echo = echarts.init(document.getElementById("PieChart"));
            var option = {
                legend: {
                    orient: 'vertical',
                    left: 'left',
                },
                series: [
                    {
                        type: 'pie',
                        radius: '70%',
                        center: ['50%', '50%'],
                        detail: {formatter:'{value}'},
                        data: test
                    }
                ]
            };
            echo.setOption(option,true);
        };
        display();
    </script>

    <!--柱状图绘制方法-->
    <script type="text/javascript" charset="UTF-8">
        var kv = new Array();
        var keys = new Array();
        var values = new Array();
        kv = {{ Types | safe }}

        for(var logkey in kv){
            keys.push(logkey);
            values.push(kv[logkey]);
        }
        var display = function() {
            var echo = echarts.init(document.getElementById("HistogramChart"));
            var option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                      type: 'shadow'
                    }
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: keys
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    data: values,
                    type: 'bar'
                }]
            };
            echo.setOption(option,true);
        };
        display();
    </script>

    <!--折线图绘制方法-->
    <script type="text/javascript" charset="UTF-8">

        // 函数主要用于将传入的字典分解成key,value格式并返回
        var get_key_value = function(kv)
        {
            var keys = new Array();
            var values = new Array();

            for(var logkey in kv)
            {
                keys.push(logkey);
                values.push(kv[logkey]);
            }
            return [keys,values];
        }

        // 输出1分钟负载
        var kv = new Array();
        kv = {{ x | safe }};
        var x = get_key_value(kv);

        // 输出5分钟负载
        var kv = new Array();
        kv = {{ y | safe }};
        var y = get_key_value(kv);

        // 输出15分钟负载
        var kv = new Array();
        kv = {{ z | safe }};
        var z = get_key_value(kv);

        // 显示利用率
        var display = function() {
            var echo = echarts.init(document.getElementById("Linechart"));
            var option = {
                title: {
                    left: 'left',
                    text: 'CPU 利用表',
                },
                // 调节大小
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                // tooltip 鼠标放上去之后会自动出现坐标
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#6a7985'
                        }
                    }
                },
            legend: {
                data: ['1分钟负载', '5分钟负载', '15分钟负载']
            },

            xAxis: {
                type: 'category',
                // data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                data: x[0]
            },
            yAxis: {
                type: 'value'
            },
            series:
            [
                {
                    name: "1分钟负载",
                    stack: "总量",
                    //data: [10, 25, 99, 87, 54, 66, 2],
                    data: x[1],
                    type: 'line'
                },
                {
                    name: "5分钟负载",
                    stack: "总量",
                    //data: [89, 57, 85, 44, 25, 4, 54],
                    data: y[1],
                    type: 'line'
                },
                {
                    name: "15分钟负载",
                    stack: "总量",
                    //data: [1, 43, 2, 12, 5, 4, 7],
                    data: z[1],
                    type: 'line'
                }
            ]
            };
            echo.setOption(option,true);
        };
        display();
    </script>
</body>

后端代码如下,其中的参数可以从数据库内提取也可以从文件中读入。

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # 配置静态文件的访问url前缀
            static_folder='static',      # 配置静态文件的文件夹
            template_folder='templates') # 配置模板文件的文件夹

@app.route('/', methods=["GET"])
def index():
    Address = {'226': 4, '404': 12, '200': 159, '400': 25, '102': 117, '302': 1625}
    Types = {'Linux': 23, 'studies': 57, 'Windows': 87, 'compatible': 44, 'web': 32, 'X11': 78}
    x = {'03:30': 12, '03:48': 25, '04:15': 47, '04:28': 89, '04:42': 66, '04:51': 54}
    y = {'05:22': 55, '07:48': 29, '07:15': 98, '08:54': 11, '08:41': 61, '06:51': 5}
    z = {'07:30': 1, '09:48': 5, '06:15': 24, '08:28': 59, '2:42': 11, '08:51': 22}
    
    return render_template("index.html",Address = json.dumps(Address), Types= json.dumps(Types), x = json.dumps(x), y = json.dumps(y), z = json.dumps(z))

if __name__ == '__main__':
    app.run(host="127.0.0.1", port=80, debug=False)

输出效果如下:

到此这篇关于Flask框架利用Echarts实现绘制图形的文章就介绍到这了,更多相关Flask Echarts绘制图形内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文