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

目录

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)

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

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

实现绘制柱状图

统计访问了本站的所有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)

柱状图绘制效果如下:

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

实现绘制折线图

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

前端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)

折现图绘制效果如下:

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

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

<!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实现绘制图形

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容