1. 程式人生 > >django Highcharts製作圖表--顯示CPU使用率

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

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

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

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

 

訪問官網:

https://www.hcharts.cn/

進入下載頁面:

https://www.hcharts.cn/download

下載6.10版本

blob.png

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

點選Time series, zoomable

blob.png

頁面效果如下:

blob.png

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

它在目錄Highcharts-6.1.0\examples\line-time-series裡面,編輯line-time-series目錄下的index.htm檔案

注意這一行:

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

它是圖表需要的json資料,開啟這個json連結,將網頁內容複製,使用json格式化工具處理,效果如下:

blob.png

如果谷歌瀏覽器,安裝外掛JSON Formatter,就可以得到上面的效果。

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

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

https://tool.lu/timestamp/

輸入數值1167609600000,點選轉換

blob.png

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

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

blob.png

 

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

 

資料從何而來呢?自己造唄!

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

在專案根目錄建立檔案monit_system.py,它能統計系統的CPU使用率,記憶體使用情況。

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

程式碼如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pymysql
import gevent
import time
import psutil

#解決wind10錯誤OSError: raw write() returned invalid length
import 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條記錄

blob.png

編輯檔案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/

 

blob.png

必須保證格式,和上面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/

頁面效果如下:

blob.png

 

圖示支援放大和縮小,可以看到秒級的資料,比如

 

blob.png

增加黑色主題

開啟解壓路徑,進入目錄Highcharts-6.1.0\code\themes,裡面有一個dark-unica.js檔案

在static\Highcharts-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>

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

blob.png

 

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

 

轉載出處: 
http://www.py3study.com/Article/details/id/317.html