roger 发表于 2020-5-24 00:14:05

Django 配合Echarts绘制图表

  在前面我总结了关于DjangoAdmin的使用技巧,利用DjangoAdmin这个后台管理功能,自己定制页面可以完成非常多的功能,下面我们将重点研究主机图形的绘制,展示和报表等功能的具体实现步骤,这里也算是个人的一点点经验。
定制查询图形功能  urls.py
from django.contrib import admin
from django.urls import path
from MyWeb import views
urlpatterns = [
    path('', admin.site.urls),
    path("grup/",views.grup)
]
  views.py
from django.shortcuts import render,HttpResponse
def grup(request):
    if request.method == "POST":
      StartData = request.POST.get("StartData")
      EndData = request.POST.get("EndData")
      sel = request.POST.get("selec")
      print(StartData,EndData,sel)

    return render(request,"grup.html")
  grup.html
{% extends "admin/base_site.html" %}
{% load i18n static %}

{% block content %}

    <form action="/grup/" method="post">
      开始时间: <input type="datetime-local" name="StartData" />
      结束时间: <input type="datetime-local" name="EndData" />

    <select name="selec">
      <option value="CPU">CPU负载</option>
      <option value="Mem">内存负载</option>
    </select>
      <input type="submit" value="查询">
    </form>
    <br>
    <div id="main" style="width: 90%; height: 300px; border: 1px solid #eecc11; padding: 40px">
    <script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
    <script>
      var mychart = echarts.init(document.getElementById("main"));
      var option = {
            xAxis: {
                type: 'category',
                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                data: ,
                type: 'line'
            }]
      };
      mychart.setOption(option)

    </script>

{% endblock %}
  更新数据 为了方便后期内容,批量填充数据.
import os,sys,sqlite3
import time,psutil,datetime
def GetCPU_Load(addr):
    dic = {}
    times = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
    cpu = psutil.cpu_percent(interval=None,percpu=True)
    dic["Address"] = addr
    dic["Times"] = times
    dic["load5"] = cpu
    dic["load10"] = cpu
    dic["load15"] = cpu
    return dic

if __name__ == "__main__":
    conn = sqlite3.connect("db.sqlite3")
    cursor = conn.cursor()
    while True:
      dic = GetCPU_Load("192.168.1.1")
      insert = 'insert into MyWeb_cpu(Address,Times,load5,load10,load15) values("{}","{}","{}","{}","{}")'.\
            format(dic["Address"],dic["Times"],dic["load5"],dic["load10"],dic["load15"])
      print(insert)
      cursor.execute(insert)
      conn.commit()
      time.sleep(1)
  来看下数据库的设计。
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
    <form action="/cpu/" method="post">
      主机地址: <input type="text" name="Address" />
      开始时间: <input type="datetime-local" name="StartData" />
      结束时间: <input type="datetime-local" name="EndData" />
    <select name="selec">
      <option value="CPU">CPU负载</option>
      <option value="Mem">内存负载</option>
    </select>
      <input type="submit" value="查询">
    </form>

    {{ time }}
    {{ load }}
from django.shortcuts import render,HttpResponse
from MyWeb importmodels
import time,datetime

def cpu(request):
    if request.method == "POST":
      times = []
      load = []
      Address = request.POST.get("Address")
      StartData = request.POST.get("StartData")
      EndData = request.POST.get("EndData")
      ret = models.CPU.objects.raw('select * from MyWeb_cpu where Times>="{}" and Times <="{}";'.
                                     format(StartData,EndData))
      for item in ret:
            times.append(item.Times.split("T"))
            load.append(item.load5)
      return render(request,"index.html",{"time":times,"load":load})
  有个问题,没有解决,可能得用json发数据。
  最后没找到解决方法,应该是要用json序列化一下就好。
<!--name: index.html-->
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
    <form action="/cpu/" method="post">
      开始时间: <input type="datetime-local" name="StartData" />
      结束时间: <input type="datetime-local" name="EndData" />
    <select name="selec">
      <option value="CPU">CPU Load5 负载</option>
    </select>
      <input type="submit" value="检索图形">
    </form>

    <div id="main" style="width: 90%; height: 300px; border: 1px solid #eecc11; padding: 40px">
    <script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
    <script>
      var mychart = echarts.init(document.getElementById("main"));
      var option = {
            grid:{
                      top:"50px",
                      left:"50px",
                      right:"15px",
                      bottom:"50px"
                  },
            xAxis: {
                type: 'category',
                data: {{ cpu_data }}
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                type: 'line',
                data: {{ cpu_data }}
            }]
      };
      mychart.setOption(option)
    </script>
{% endblock %}
  顺便加上IP查询功能,则更加完整了。
  上方form表单提交后会自动清除表单内容,如果不想清空,可以使用ajax方式提交,或使用一下方法来完成.
{% block content %}

    <form action="/fw/" method="post" target="not_iframe">
      <input type="text" name="user"/>
      <input type="submit" value="提交">
    </form>

    <iframe id="id_iframe" name="not_iframe" style="display:none;"></iframe>
{% endblock %}
本机仪表盘{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}

    <div id="cpuChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>

    <div id="memChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>

    <div id="diskChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>

    <script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
    <script>
      var cpuChart = echarts.init(document.getElementById("cpuChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 44, name: 'CPU 利用率'}]
            }
      ]
    };cpuChart.setOption(option, true);
    </script>
    <script>
      var memChart = echarts.init(document.getElementById("memChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 25, name: '内存利用率'}]
            }
      ]
    };memChart.setOption(option, true);
    </script>
    <script>
      var diskChart = echarts.init(document.getElementById("diskChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 18, name: '磁盘使用量'}]
            }
      ]
    };diskChart.setOption(option, true);
    </script>
{% endblock %}
  增加自定义页面(本机图形监控): 除了默认页面可以使用以外,还可以自己创造一个新页面.
<!--name: index.html(本机仪表盘)-->
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
    <div id="cpuChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    <div id="memChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    <div id="diskChart" style="width: 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    <script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
    <script>
      var cpuChart = echarts.init(document.getElementById("cpuChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 44, name: 'CPU 利用率'}]
            }
      ]
    };cpuChart.setOption(option, true);
    </script>
    <script>
      var memChart = echarts.init(document.getElementById("memChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 25, name: '内存利用率'}]
            }
      ]
    };memChart.setOption(option, true);
    </script>
    <script>
      var diskChart = echarts.init(document.getElementById("diskChart"));
      var option = {
      series: [
            {
                type: 'gauge',
                detail: {formatter: '{value}%'},
                data: [{value: 18, name: '磁盘使用量'}]
            }
      ]
    };diskChart.setOption(option, true);
    </script>
{% endblock %}
动态监控平台(折线图)  绘图
    <div id="echo" style="width: 100%; height: 400px;"></div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>

    <script type="text/javascript" charset="UTF-8">
      var display = function(time,cpu1,cpu5,cpu15){
var echo =echarts.init(document.getElementById("echo"));
                var option = {
                  // tooltip 鼠标放上去之后会自动出现坐标
                  tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'cross',
                            label: {
                              backgroundColor: '#6a7985'
                            }
                        }
                  },// toolbox = 菜单栏中的各种小功能
                  toolbox: {
                        feature: {
                            dataZoom: {
                              yAxisIndex: 'none'
                            },
                            restore: {},
                            saveAsImage: {}
                        }
                  },
                  legend: {
                        data: [ '1分钟负载', '5分钟负载', '15分钟负载']
                  },

                  xAxis: {
                        type: 'category',
                        data: time
                  },
                  yAxis: {
                        type: 'value'
                  },
                  series: [
                  {
                        name: "1分钟负载",
                        stack: "总量",
                        data: cpu1,
                        type: 'line'
                  },
                  {
                        name: "5分钟负载",
                        stack: "总量",
                        data: cpu5,
                        type: 'line'
                  },
                  {
                        name: "15分钟负载",
                        stack: "总量",
                        data: cpu15,
                        type: 'line'
                  }
                  ]
                };
                echo.setOption(option,true);
    };
</script>
  另一种刷新式绘图
<script type="text/javascript" src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
<div id="main" style="height:500px;width:1200px;border:1px solid #eecc11;padding:10px;"></div>
<script type="text/javascript" charset="UTF-8">
      var display = function(time,cpu){
            // 负责初始化绘图画布
            var myChart = echarts.init(document.getElementById('main'));
            myChart.setOption({
      title: {
            text: '监控系统CPU资源'
      },
      tooltip: {},
      xAxis: {
            data: []
      },
      yAxis: {},
      series: [{
            name: 'cpu',
            type: 'line',
            data: []
      }]
    });
      // 下方就是给指定字段填充数据
      myChart.setOption({
            xAxis: {
                data: time
            },
            series: [{
                name: 'cpu', // 根据名字对应到相应的系列
                data: cpu
            }]
      });
    };
    // 首次显示加载动画
    myChart.showLoading();
</script>
  数据处理
    // 负责对参数的解析
    var time =["","","","","","","","","",""];
    var cpu1 = ;
    var cpu5 = ;
    var cpu15 = ;
    var update = function(recv){
      time.push(recv.response);
      cpu1.push(parseFloat(recv.response));
      cpu5.push(parseFloat(recv.response));
      cpu15.push(parseFloat(recv.response));
      if(time.length >=10){
            time.shift();
            cpu1.shift();
            cpu5.shift();
            cpu15.shift();
            display(time,cpu1,cpu5,cpu15)
      }
    };
  图形更新
    $(
      function () {
            fetchData();
            setInterval(fetchData, 1000);
      }
    );
    function fetchData(){
      $.ajax({
            url:"/_ajax/",
            type:"GET",
            dataType: 'json',
            success:function (recv) {
                update(recv);
            }
      })
    }
  view.py
from django.shortcuts import render,HttpResponse
import os,subprocess,time,json

def index(request):
    return render(request,"index.html")

def ajax(request):
    if request.method == "GET":
      data = []
      data.append(time.strftime("%M:%S", time.localtime()))
      for key in ["system.cpu.util[,,avg1]", "system.cpu.util[,,avg5]", "system.cpu.util[,,avg15]"]:
            cmd = "C:/get.exe -s {} -p {} -k {}".format("192.168.1.20", "10050", key)
            proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
            data.append(float(proc.stdout.readlines().split()))
      return HttpResponse(json.dumps({"response":data}))
  urls.py
from django.contrib import admin
from django.urls import path
from MyWeb import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("cpu/",views.index),
    path("_ajax/",views.ajax)
]
  可能效果不是很明显,你可以稍微改一下代码。
def ajax(request):
    if request.method == "GET":
      data = []
      data.append(time.strftime("%M:%S", time.localtime()))
      data.append(random.randint(1,100))
      data.append(random.randint(100, 200))
      data.append(random.randint(23, 90))
      return HttpResponse(json.dumps({"response":data}))
    // 负责对参数的解析
    var time =["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""];
    var cpu1 = ;
    var cpu5 = ;
    var cpu15 = ;
    var update = function(recv){
      time.push(recv.response);
      cpu1.push(parseFloat(recv.response));
      cpu5.push(parseFloat(recv.response));
      cpu15.push(parseFloat(recv.response));
      if(time.length >=40){
            time.shift();
            cpu1.shift();
            cpu5.shift();
            cpu15.shift();
            display(time,cpu1,cpu5,cpu15)
      }
    };
  除了可以监控系统负载外,还可以监控网卡,监控内存等,原理都是一样的,网卡监控代码。
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block content %}
<div id="main" style="width: 100%; height: 400px;"></div>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
<script type="text/javascript" charset="UTF-8">
    var display = function(){
      var main =echarts.init(document.getElementById("main"));
      var option = {
            // tooltip 鼠标放上去之后会自动出现坐标
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                  type: 'cross',
                  label: {
                        backgroundColor: '#6a7985'
                  }
                }
            },// toolbox = 菜单栏中的各种小功能
            toolbox: {
                feature: {
                  dataZoom: {
                        yAxisIndex: 'none'
                  },
                  restore: {},
                  saveAsImage: {}
                }
            },
            legend: {
                data: [ '网卡入口流量', '网卡出口流量']
            },
            // 负责绘图的配置
            xAxis: {
                type: 'category',
                data:
            },
            yAxis: {
                type: 'value'
            },
            series: [
            {
                name: "网卡入口流量",
                stack: "总量",
                data: ,
                type: 'line',
                areaStyle: {}
            },
            {
                name: "网卡出口流量",
                stack: "总量",
                data: ,
                type: 'line',
                areaStyle: {}
            }
            ]
      };
      main.setOption(option,true);
    };
    display()
</script>
{% endblock %}
网站流量统计(折线图)  通过分析日志统计流量。
import os,sys

def log(path):
    key = []
    value = []
    for item in fp.readlines():
      date = item.split()
      HourData = date.split(":") + ":" + date.split(":")
      if item.split() != "-" and item.split() != '"-"':
            SendByte = int(item.split())
    key.append(HourData)
    value.append(SendByte)
    return dict(zip(key,value))

fp = open("c://access.log","r")
dic = log(fp)
  针对Web服务的流量统计 上面代码只能统计出所有的流量,无法叠加,可以以IP为例进行流量叠加。
import os,sys

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

if __name__ == "__main__":
    Address,OutFlow = Count_IP_And_Flow("c://access.log")
    print("地址计数:{}---> 流量计数:{}".format(Address,OutFlow))
  上面的代码,稍微修改一下就能统计时间与流量的关系。
def Count_IP_And_Flow(file):
    addr = {}# key 保存当前的IP信息
    flow = {}# value 保存当前IP流量总和
    Count= 0   # 针对IP地址的计数器
    with open(file) as f:
      contexts = f.readlines()
    for line in contexts:
      if line.split() != "-" and line.split() != '"-"':
            size = line.split()
      temp = line.split()
      ip_attr = temp.split(":") + ":" + temp.split(":")
      Count = int(size) + Count
      if ip_attr in addr.keys():
            addr = addr + 1
            flow = flow + int(size)
      else:
            addr = 1
            flow = int(size)
    return addr,flow

if __name__ == "__main__":
    Address,OutFlow = Count_IP_And_Flow("c://access.log")
    print("流量计数:{}".format(Address,OutFlow))
  接着是绘图,这里直接把代码拿出来吧。
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block content %}
<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
<div class="panel panel-primary" style="width: 100%;height: 30%; float: left">
    <div class="panel-heading">
      <h3 class="panel-title">网站流量统计</h3>
    </div>
    <div class="panel-body">
      <div id="main" style="width:100%; height: 400px"></div>
    </div>
</div>
<script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
<script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
<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);
      }

      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>
{% endblock %}
from django.shortcuts import render
import json

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

def index(request):
    OutFlow = Count_IP_And_Flow("c://access.log")
    print(OutFlow)
    return render(request,"index.html",{"data":json.dumps(OutFlow)})
  效果图如下,我这台机器访问量很小,将就着看吧。
  统计IP出现的次数。
def IP_Count(file):
    ip = {}
    with open(file) as f:
      for i in f.readlines():
            ip_attr = i.strip().split()
            if ip_attr in ip.keys():
                ip = ip + 1
            else:
                ip = 1
    print(ip)

IP_Count("c://access.log")
网站状态码统计(饼状图)  饼状图的绘制: 统计目标主机网页状态码,与个数,并绘制饼状图,饼图和其他图不太一样,绘制起来蛮烦一些。
from django.shortcuts import render
import json

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

def index(request):
    Address = Count_Flag_And_Flow("c://access.log")
    print(Address)
    return render(request,"index.html",{"data":json.dumps(Address)})

from MyWeb import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path("log/",views.index)
]
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}

{% block content %}
<div id="main" style="width:50%; height: 300px"></div>
<script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
<script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
    <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, 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>
{% endblock %}
  加上框架看效果。
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <div class="panel panel-primary" style="width: 60%;height: 50%">
<div class="panel-heading">
<h3 class="panel-title">网站访问状态统计</h3>
</div>
<div class="panel-body">
这是一个基本的面板
</div>
</div>
  来,搞事
<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
<div class="panel panel-primary" style="width: 40%;height: 30%">
    <div class="panel-heading">
      <h3 class="panel-title">网站访问状态统计</h3>
    </div>
    <div class="panel-body">
      <div id="main" style="width:100%; height: 300px"></div>
    </div>
</div>
网站访问设备统计(柱状图)  统计设备的类型,例如Windows linux 等,这里我们接着上面的做吧,先来改布局。
{% block content %}

<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
<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="main" 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="main1" style="width:100%; height: 300px"></div>
    </div>
</div>
  完整代码如下,就是拼接起来就行,没什么技术含量。
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}

{% block content %}
<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
<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="main" 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="main1" style="width:100%; height: 300px"></div>
    </div>
</div>

<script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
<script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
    <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, 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>

<script type="text/javascript" charset="UTF-8">
      var display = function() {
            var main1 = echarts.init(document.getElementById("main1"));
            var option = {
                xAxis: {
                  type: 'category',
                  data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                },
                yAxis: {
                  type: 'value'
                },
                series: [{
                  data: ,
                  type: 'bar'
                }]
            };
            main1.setOption(option,true);
      };
display();
</script>
{% endblock %}
import os,sys

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

if __name__ == "__main__":
    a = Count_Flag_And_Type("c://access.log")
    print(a)
  最终代码如下,前端第二个拼接位置需要注意。
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}

{% block content %}

<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
<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="main" 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="main1" style="width:100%; height: 300px"></div>
    </div>
</div>

<script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
<script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
    <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, 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>

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

      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>
{% endblock %}
  后端处理日志并返回结果。
from django.shortcuts import render
import json

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

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

def index(request):
    Address = Count_Flag_And_Flow("c://access.log")
    print(Address)
    Types = Count_Flag_And_Type("c://access.log")
    print(Types)
    return render(request,"index.html",{"data":json.dumps(Address),"data1":json.dumps(Types)})

def mob(request):
    return render(request,"mob.html")
  经过测试上面的代码有一定的局限性,比如下面的这两条代码,会出现异常。
  ::1 - - "OPTIONS * "
192.168.1.2 - - "-" 408 - "-" "-"
  日志统计时,应该避免出现这种无效行,该怎么做,我就不说了,正则!!
单位时间访客(访客位置)  未完待续。。。
  先来几个API查询地址。
  http://ip.ws.126.net/ipquery?ip=192.168.1.100
import os,sys
import urllib.request

def counts(file):
    Addr = []
    with open(file) as f:
      contexts = f.readlines()
    for line in contexts:
      lt = line.split()
      if lt !="::1" and lt !="127.0.0.1":
            Addr.append(lt)
    return set(Addr)

if __name__ == "__main__":
    ret = counts("C://access.log")
    for item in ret:
      url = "http://ip.ws.126.net/ipquery?ip={}".format(item)
      ret = urllib.request.urlopen(url)
      print(ret.read().decode('gbk'))
if __name__ == "__main__":
    ret = counts("C://access.log")
    for item in ret:
      url = "http://ip.ws.126.net/ipquery?ip={}".format(item)
      ret = urllib.request.urlopen(url).read().decode('gbk')
      City = ret.split().replace('province:"', '').replace('"}', "")
      print("IP:{} -----> 城市:{}".format(item,City))

页: [1]
查看完整版本: Django 配合Echarts绘制图表