Flask framework: drawing graphics with Echarts

Echarts is an open source JavaScript-based visual chart library launched by Baidu. The development library is currently developing very well, and supports the drawing of various graphics with a high degree of customization. The Echarts drawing library can also be combined with Flask, and the front desk uses the echart drawing library The graphics are generated and displayed. In the background, Flask returns a string of JSON data sets through the render_template method. After the reception is received, it is applied to the drawing library to realize the function of dynamically displaying the log status of the Web service.

In the following demo cases, we will show how to use the drawing library to draw the three most basic graphics (pie chart, column chart, line chart) interactively at the front and back ends.

Realize the drawing of a pie chart: It is used to simulate and count the log data of the Web container, and count the access status through a pie chart.

The front-end part /templates/index.html code is as follows:

<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 Website visit status statistics</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>

The backend code is as follows to return some data by mocking the render_template.

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # Configure the access url prefix of static files
            static_folder='static',      # Configure the folder for static files
            template_folder='templates') # Folder for configuration template files

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)

After running, access the custom domain name and output a pie chart with the following effect:

Realize the drawing of histogram: Count all ID addresses that have visited the site and display all the addresses whose number is greater than 2.

The front-end index.html code is as follows

<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 Website Device Type Statistics</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>

The back-end code is as follows, and the route has only one index mapping.

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # Configure the access url prefix of static files
            static_folder='static',      # Configure the folder for static files
            template_folder='templates') # Folder for configuration template files

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)

    # deduplicate and turn it into a dictionary
    list_num = set(list)
    for item in list_num:
        num = list.count(item)
        # Ignore if address is only once
        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)

The histogram drawing effect is as follows:

Realize drawing a line chart: Statistics of access traffic data within a specified time period.

The front-end index.html code is as follows

<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 Website traffic statistics</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>

The back-end code is as follows, and the route has only one index mapping.

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # Configure the access url prefix of static files
            static_folder='static',      # Configure the folder for static files
            template_folder='templates') # Folder for configuration template files

def Count_Time_And_Flow(file):
    times = {}  # key saves the current time information
    flow = {}   # value current time traffic sum
    Count= 0    # Counters for IP addresses
    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)

The rendering effect of the discount chart is as follows:

The above are the three commonly used graphics drawing methods. For other graphics, you can refer to the writing method in the above code for the same reason. We can combine these three graphics together, mainly by typesetting them at the front end.

<!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">
    <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>

    <!--Pie chart drawing method-->
    <div class="panel panel-primary" style="width: 40%;height: 30%;float: left">
        <div class="panel-heading">
            <h3 class="panel-title">Pie chart drawing</h3>
        </div>
        <div class="panel-body">
            <div id="PieChart" style="width:100%; height: 300px"></div>
        </div>
    </div>

    <!--Histogram drawing method-->
    <div class="panel panel-primary" style="width: 58%;height: 30%; float: right">
        <div class="panel-heading">
            <h3 class="panel-title">Histogram drawing</h3>
        </div>
        <div class="panel-body">
            <div id="HistogramChart" style="width:100%; height: 300px"></div>
        </div>
    </div>

    <!--Line chart drawing method-->
    <div class="panel panel-primary" style="width: 100%;height: 40%; float: left">
        <div class="panel-heading">
            <h3 class="panel-title">Line chart drawing</h3>
        </div>
        <div class="panel-body">
            <div id="Linechart" style="width:100%; height: 460px"></div>
        </div>
    </div>

    <!--Pie chart drawing method-->
    <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>

    <!--Histogram drawing method-->
    <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>

    <!--Line chart drawing method-->
    <script type="text/javascript" charset="UTF-8">

        // The function is mainly used to decompose the incoming dictionary into key,value format and return it
        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];
        }

        // Output 1 minute load
        var kv = new Array();
        kv = {{ x | safe }};
        var x = get_key_value(kv);

        // output 5 minutes load
        var kv = new Array();
        kv = {{ y | safe }};
        var y = get_key_value(kv);

        // output 15 minutes load
        var kv = new Array();
        kv = {{ z | safe }};
        var z = get_key_value(kv);

        // show utilization
        var display = function() {
            var echo = echarts.init(document.getElementById("Linechart"));
            var option = {
                title: {
                    left: 'left',
                    text: 'CPU use table',
                },
                // resize
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                // When the tooltip is placed on the mouse, the coordinates will automatically appear.
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#6a7985'
                        }
                    }
                },
            legend: {
                data: ['1 minute load', '5 minute load', '15 minute load']
            },

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

The back-end code is as follows, the parameters can be extracted from the database or read from the file.

from flask import Flask,render_template,request
import json

app = Flask(import_name=__name__,
            static_url_path='/python',   # Configure the access url prefix of static files
            static_folder='static',      # Configure the folder for static files
            template_folder='templates') # Folder for configuration template files

@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)

The output is as follows:

Tags: Python Flask echarts

Posted by CreativeWebDsign on Thu, 06 Oct 2022 16:57:05 +1030