django Highcharts製作圖表–顯示CPU使用率

  • 2019 年 10 月 6 日
  • 筆記

Highcharts 是一個用純JavaScript編寫的一個圖表庫。

Highcharts 能夠很簡單便捷的在web網站或是web應用程式添加有交互性的圖表

Highcharts 免費提供給個人學習、個人網站和非商業用途使用。

訪問官網:

https://www.hcharts.cn/

進入下載頁面:

https://www.hcharts.cn/download

下載6.10版本

解壓Highcharts-6.1.0.zip文件,訪問裡面的index.htm文件。

點擊Time series, zoomable

頁面效果如下:

這個,就是接下來django需要用的模板。

它在目錄Highcharts-6.1.0examplesline-time-series裡面,編輯line-time-series目錄下的index.htm文件

注意這一行:

'https://cdn.rawgit.com/highcharts/highcharts/057b672172ccc6c08fe7dbb27fc17ebca3f5b770/samples/data/usdeur.json',

它是圖表需要的json數據,打開這個json鏈接,將網頁內容複製,使用json格式化工具處理,效果如下:

如果Google瀏覽器,安裝插件JSON Formatter,就可以得到上面的效果。

它的數據格式一個大的列表,裡面每一個元素都是小列表。

列表第一個值,是一個時間戳,第二個是具體的值。打開站長工具的時間戳轉換,鏈接如下:

https://tool.lu/timestamp/

輸入數值1167609600000,點擊轉換

很明顯,時間不對。為什麼呢?因為它是毫秒

選擇毫秒,再次點擊轉換,時間就對了。

那麼django需要輸出,指定格式的json數據,才能展示正確的圖表。

數據從何而來呢?自己造唄!

下面將演示,如何展示一個CPU使用率的圖表。

在項目根目錄創建文件monit_system.py,它能統計系統的CPU使用率,記憶體使用情況。

統計完成之後,將對應的數值插入到MySQL中。它會插入30條記錄,每隔10秒採集一次。

程式碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import pymysqlimport geventimport timeimport psutil#解決wind10錯誤OSError: raw write() returned invalid lengthimport win_unicode_console  win_unicode_console.enable()class MyPyMysql:    def __init__(self, host, port, username, password, db, charset='utf8'):        self.host = host  # mysql主機地址        self.port = port  # mysql埠        self.username = username  # mysql遠程連接用戶名        self.password = password  # mysql遠程連接密碼        self.db = db  # mysql使用的資料庫名        self.charset = charset  # mysql使用的字元編碼,默認為utf8        self.pymysql_connect()  # __init__初始化之後,執行的函數    def pymysql_connect(self):        # pymysql連接mysql資料庫        # 需要的參數host,port,user,password,db,charset        self.conn = pymysql.connect(host=self.host,                                      port=self.port,                                      user=self.username,                                      password=self.password,                                      db=self.db,                                      charset=self.charset                                      )          # 連接mysql後執行的函數        self.asynchronous()    def getCPUstate(self,interval=1):        cpu = psutil.cpu_percent(interval)          return cpu    def getMemorystate(self):        phymem = psutil.virtual_memory()          cur_mem = phymem.percent          mem_rate = int(phymem.used / 1024 / 1024)          mem_all = int(phymem.total / 1024 / 1024)        line = {              'cur_mem': cur_mem,              'mem_rate': mem_rate,              'mem_all': mem_all,          }        return line    def run(self):        # 創建游標        self.cur = self.conn.cursor()          # 定義sql語句        sql = "insert into blog_system_monit(cpu,cur_mem,mem_rate,mem_all,create_time,time_stamp) values (%s,%s,%s,%s,%s,%s)"        print(sql)        # 定義數據        cpu = self.getCPUstate()  # cpu使用率        mem = self.getMemorystate()  # 記憶體info資訊        mem_rate = mem['mem_rate']  # 記憶體使用率        cur_mem = mem['cur_mem']  # 當前使用記憶體        mem_all = mem['mem_all']  # 總記憶體        struct_time = time.localtime()          create_time = time.strftime("%Y-%m-%d %H:%M:%S", struct_time)  # 轉換為標準時間        t = time.time()  # 當前時間戳        time_stamp = int(round(t * 1000))  # 轉換為毫秒的時間戳        print((cpu, cur_mem,mem_rate, mem_all,create_time,time_stamp))        # 執行插入一行數據,如果插入多行,使用executemany(sql語句,數據(需一個元組類型))        content = self.cur.execute(sql,(cpu,cur_mem,mem_rate,mem_all,create_time,time_stamp))          if content:              print('插入ok')        # 提交數據,必須提交,不然數據不會保存        self.conn.commit()    def asynchronous(self):        #執行30次協程任務        for i in range(0,30):              time.sleep(10)  # 等待10秒            gevent.spawn(self.run())  # 執行方法        self.cur.close()  # 關閉游標        self.conn.close()  # 關閉pymysql連接if __name__ == '__main__':      start_time = time.time()  # 計算程式開始時間    st = MyPyMysql('127.0.0.1', 3306, 'root', '', 'db2')  # 實例化類,傳入必要參數    print('程式耗時{:.2f}'.format(time.time() - start_time))  # 計算程式總耗時

創建表blog_system_monit

進入django項目,修改blog目錄下的models.py,內容如下:

from django.db import models# Create your models here.#必須要繼承models.Model類,這個固定寫法。# 這裡表示創建表blog_system_monit,blog是應用名,它會自動加上的。class system_monit(models.Model):    #id自增,類型為bigint。設置為主鍵    id = models.BigAutoField(primary_key=True)      #類型為decimal(10,2),長度為10,小數點保留2位    cpu = models.DecimalField(max_digits=10, decimal_places=2)      #類型為int(11),11是默認長度    cur_mem = models.IntegerField()      mem_rate = models.DecimalField(max_digits=10, decimal_places=2)      mem_all = models.IntegerField()      #類型為datetime    create_time = models.DateTimeField()      #由於毫秒的時間戳超過了timestamp的長度,所以只能設置bigint了。    time_stamp = models.BigIntegerField()

在Pycharm的Terminal窗口中,輸入以下命令

python manage.py makemigrations

python manage.py migrate

執行完成之後,它會自動創建表blog_system_monit

使用pycharm執行腳本monit_system.py,等待5分鐘,就會插入30條數據。

如果腳本沒有報錯,查看錶記錄,會有30條記錄

編輯文件views.py,增加2個視圖函數

def chart(request):    #顯示html文件    return render(request, "chart.html")def chart_json(request):    #讀取表所有記錄    system_monit = models.system_monit.objects.all()      data = []  # 創建一個空列表    for i in system_monit:  # 遍歷,拼橫縱坐標        #橫坐標為時間戳,縱坐標為cpu使用率。注意,必須轉換類型,否則數據不對。        data.append([int(i.time_stamp),float('%.2f' % i.cpu)])        print(data)    isdict = json.dumps(data)  # json序列化列表    return HttpResponse(isdict, content_type="application/json")  # 執行類型為json

修改mysite下的urls.py,新增2個路徑

urlpatterns = [      path('admin/', admin.site.urls),      path('chart/', views.chart),      path('chart_json/', views.chart_json),  ]

訪問json的url

http://127.0.0.1:8000/chart_json/

必須保證格式,和上面cdn.rawgit.com鏈接的json格式一樣。

上的圖片是用了JSON Formatter插件展示json數據的效果。

否則下面的步驟不用做了!!!

將line-time-series目錄下的index.htm文件複製到django項目的templates目錄下,重命名為chart.html

在django項目的static文件夾下,創建目錄Highcharts-6.1.0

將Highcharts-6.1.0解壓目錄中的3個文件,複製到此目錄

修改部分程式碼,大家可以和index.htm對比一下,就知道修改的部分了。完整程式碼如下:

<!DOCTYPE HTML>  <html>  <head>      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">      <meta name="viewport" content="width=device-width, initial-scale=1">      <title>Highcharts Example</title>    <style type="text/css">    </style>      {#配置favicon.ico,解決警告Not Found: /favicon.ico#}    {% load staticfiles %}      <link REL="SHORTCUT ICON" HREF="{% static "images/favicon.ico" %}"/>  </head>  <body>  <script src="../static/js/jquery-3.3.1.min.js"></script>  <script src="../static/Highcharts-6.1.0/highcharts.js"></script>  <script src="../static/Highcharts-6.1.0/modules/exporting.js"></script>  <script src="../static/Highcharts-6.1.0/modules/export-data.js"></script><div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div><script type="text/javascript">      {#解決顯示時間少8小時問題#}    Highcharts.setOptions({global: {useUTC: false}});    $.getJSON(          {#'https://cdn.rawgit.com/highcharts/highcharts/057b672172ccc6c08fe7dbb27fc17ebca3f5b770/samples/data/usdeur.json',#}        '/chart_json/',          function (data) {            Highcharts.chart('container', {                  chart: {                      zoomType: 'x'                },                  title: {                      text: 'cpu使用率'                },                  subtitle: {                      text: document.ontouchstart === undefined ?                          '單擊並拖動繪圖區域以放大' : '捏合圖表放大'                },                  xAxis: {                      type: 'datetime',                },                  {#自定義x坐標資訊顯示,return部分是用js拼接的,內容可以自己定義。#}                tooltip: {                      formatter: function () {                          return '<strong>' + this.series.name + ':' + this.y + '%<br/></strong>' +                              Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);                      }                  },                  yAxis: {                      title: {                          text: '使用率'                    }                  },                  legend: {                      enabled: false                  },                  plotOptions: {                      area: {                          fillColor: {                              linearGradient: {                                  x1: 0,                                  y1: 0,                                  x2: 0,                                  y2: 1                            },                              stops: [                                  [0, Highcharts.getOptions().colors[0]],                                  [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]                              ]                          },                          marker: {                              radius: 2                        },                          lineWidth: 1,                          states: {                              hover: {                                  lineWidth: 1                            }                          },                          threshold: null                      }                  },                series: [{                      type: 'area',                      name: '百分比',                      data: data                  }]              });          }      );  </script>  </body>  </html>

項目文件結構如下:

mysite/  ├── blog  │   ├── admin.py  │   ├── apps.py  │   ├── __init__.py  │   ├── models.py  │   └── views.py  ├── manage.py  ├── monit_system.py  ├── mysite  │   ├── __init__.py  │   ├── settings.py  │   ├── urls.py  │   └── wsgi.py  ├── static  │   ├── css  │   ├── Highcharts-6.1.0│   │   ├── highcharts.js  │   │   └── modules  │   │       ├── export-data.js  │   │       └── exporting.js  │   ├── images  │   │   └── favicon.ico  │   └── js  │       └── jquery-3.3.1.min.js  └── templates      ├── chart.html      ├── cur_time.html      ├── detail.html      └── index.html

使用pycharm啟動django項目,訪問url

http://127.0.0.1:8000/chart/

頁面效果如下:

圖標支援放大和縮小,可以看到秒級的數據,比如

增加黑色主題

打開解壓路徑,進入目錄Highcharts-6.1.0codethemes,裡面有一個dark-unica.js文件

在staticHighcharts-6.1.0目錄下創建目錄themes,將dark-unica.js文件複製到此目錄

修改char.html文件,在

<script src="../static/Highcharts-6.1.0/modules/export-data.js"></script>

下面一行添加如下程式碼,導入主題js

{#黑色主題#}<script src="../static/Highcharts-6.1.0/themes/dark-unica.js"></script>

再次訪問網頁,效果如下:

我的部落格即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=vcus7uflzabs

本文載自: http://www.py3study.com/Article/details/id/317.html