Flask Echarts 實現歷史圖形查詢

来源:https://www.cnblogs.com/LyShark/archive/2023/11/27/17859533.html
-Advertisement-
Play Games

Flask前後端數據動態交互涉及用戶界面與伺服器之間的靈活數據傳遞。用戶界面使用ECharts圖形庫實時渲染數據。它提供了豐富多彩、交互性強的圖表和地圖,能夠在網頁上直觀、生動地展示數據。ECharts支持各種常見的圖表類型,包括折線圖、柱狀圖、餅圖、散點圖等,同時還支持動畫效果、數據篩選、區域縮放... ...


Flask前後端數據動態交互涉及用戶界面與伺服器之間的靈活數據傳遞。用戶界面使用ECharts圖形庫實時渲染數據。它提供了豐富多彩、交互性強的圖表和地圖,能夠在網頁上直觀、生動地展示數據。ECharts支持各種常見的圖表類型,包括折線圖、柱狀圖、餅圖、散點圖等,同時還支持動畫效果、數據篩選、區域縮放等交互功能。

Flask後端通過render_template方法將查詢得到的JSON數據傳遞至前端,使得用戶能夠查詢特定時間段內的數據。這種交互方式實現了動態圖形展示,為用戶提供了更直觀、實時的數據體驗。通過此系統,用戶可通過前端界面直接選擇時間範圍,後臺伺服器相應地返回相應的數據,實現了數據的動態交互與圖形化展示。

JQuery綁定事件

jQuery 是一個快速、輕量級、跨瀏覽器的JavaScript庫。它旨在簡化HTML文檔遍歷、事件處理、動畫操作和AJAX等常見任務,使開發者能夠更方便地處理DOM操作和前端交互。

以下這段HTML代碼實現了一個包含表單的頁面,用戶可以輸入主機地址、開始時間、結束時間以及選擇負載類型,然後通過點擊按鈕進行數據查詢。

代碼首先通過Ajax介面實現了參數傳遞,使用了jQuery中的click方法綁定了按鈕點擊事件。概述如下:

  1. 表單提交和Ajax請求:
    • 在用戶填寫完表單後,通過jQuery的click方法,給按鈕綁定了一個點擊事件。
    • 在點擊事件中,使用$.ajax函數實現了非同步的數據請求。
    • 通過$("#myForm").serialize()將表單數據序列化,然後作為請求參數發送給後端。
  2. 後端響應:
    • 請求的目標URL是根目錄("/"),這可能是Flask或其他後端框架的路由。
    • 後端處理接收到的數據,執行相應的邏輯,並返回一個JSON格式的數據。
  3. 前端處理響應數據:
    • 當Ajax請求成功時,觸發了success回調函數。
    • 在回調函數中,使用JSON.parse(data)解析後端返回的JSON字元串,得到一個包含時間、X、Y、Z數據的字典(ref_dict)。
  4. 數據展示:
    • 解析後的數據傳遞給create_graphical函數。
    • create_graphical函數負責處理這些數據,這裡是列印到控制台。

這種結構使得用戶在填寫表單並點擊按鈕後,能夠通過Ajax請求將數據發送給後端,併在後端執行相應邏輯後返回JSON格式的數據。前端接收到數據後進行解析處理,這裡簡單列印到控制台,實際應用中可以進一步用於圖表的動態更新等操作。這樣實現了前後端之間的動態數據傳遞和交互。如下index.html代碼如下所示;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <!--提交表格數據-->
    <form action="/" method="post" id="myForm">
        <p>主機地址: <input type="text" name="address" placeholder="輸入主機IP地址"></p>
        <p>開始時間: <input type="datetime-local" name="start_datetime" /></p>
        <p>結束時間: <input type="datetime-local" name="end_datetime" /></p>

        <select name="select">
            <option value="load5">五分鐘負載</option>
            <option value="load10">十分鐘負載</option>
            <option value="load15">十五分鐘負載</option>
            <option value="load_all">全部輸出</option>
        </select>

        <input name="btn" id="btn" type="button" value="查詢數據" />
    </form>

    <!-- 傳入參數列印 -->
    <script type="text/javascript" charset="UTF-8">
        var create_graphical = function(time,x,y,z)
        {
            console.log("日期: " + time);
            console.log("X: " + x);
            console.log("Y: " + y);
            console.log("Z: " + z);
        }
    </script>

    <!--點擊查詢後執行的Ajax操作-->
    <script type="text/javascript">
        $("#btn").click(function()
        {
            $.ajax({
                url: "/",
                type: "POST",
                data: $("#myForm").serialize(),
                success:function (data)
                {
                    var ref_dict = JSON.parse(data);
                    create_graphical(ref_dict.time, ref_dict.x, ref_dict.y, ref_dict.z)
                }
            })
        })
    </script>
</body>

後臺app.py則通過request.form.get方法接收用戶數據,並將收到的數據列印到後臺,將數據拼接組合成一個JSON數組並使用json.dumps()將數據返回給前端;

from flask import Flask,render_template,request
import json

app = Flask(__name__)

@app.route('/',methods=['POST','GET'])
def index():

    if request.method == "GET":
        return render_template("index.html")

    elif request.method == "POST":
            address = request.form.get("address")
            start_datetime = request.form.get("start_datetime")
            end_datetime = request.form.get("end_datetime")
            select_value = request.form.get("select")
            print(address,start_datetime,end_datetime,select_value)

            ref_time = ["11:12","11:13","11:14","11:15","11:16"]
            ref_x = [4,5,8,9,4]
            ref_y = [6,7,8,9,0]
            ref_z = [4,3,2,4,6]

            ref_dict = {"time":ref_time, "x": ref_x, "y": ref_y, "z": ref_z}
            return json.dumps(ref_dict, ensure_ascii=False)

if __name__ == '__main__':
    app.run()

運行代碼,通過填入不同的參數傳入後臺,前臺則可以看到後臺回傳參數,如下圖所示;

生成測試數據

如下提供的這段代碼的主要功能是定期獲取主機的CPU負載數據,將數據插入SQLite資料庫中。這種實時數據採集的方式可用於監控系統性能,尤其是在Web應用中,可以用於實時更新圖表或報告系統的負載情況,運行這段程式並等待5分鐘的數據採集。

以下是對該代碼的概述:

  1. 資料庫創建函數 (CreateDB):
    • 連接到SQLite資料庫(database.db)。
    • 創建了一個名為 CpuLoadDB 的表,包含主機地址 (address)、時間 (times)、5分鐘負載 (load5)、10分鐘負載 (load10)、15分鐘負載 (load15) 的欄位。
  2. 獲取CPU負載函數 (GetCPU):
    • 獲取當前時間並格式化為字元串。
    • 使用 psutil.cpu_percent 獲取實時CPU負載,返回一個包含主機地址、時間、5分鐘負載、10分鐘負載、15分鐘負載的字典。
  3. 主程式 (__main__):
    • 調用 CreateDB 函數創建資料庫表。
    • 進入一個無限迴圈,每次迴圈中獲取CPU負載數據,構建插入語句,並將數據插入資料庫中。
    • 在控制台列印插入語句,便於調試。
    • 通過 time.sleep(1) 控制每秒執行一次,模擬實時數據更新。
import sqlite3
import time,psutil,datetime

def CreateDB():
    conn = sqlite3.connect("database.db")
    cursor = conn.cursor()

    create = "create table CpuLoadDB(" \
             "address char(32) not null," \
             "times char(32) not null," \
             "load5 char(32) not null," \
             "load10 char(32) not null," \
             "load15 char(32) not null" \
             ")"
    cursor.execute(create)
    conn.commit()
    cursor.close()
    conn.close()

def GetCPU(addr):
    times = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
    cpu = psutil.cpu_percent(interval=None,percpu=True)

    dict = {'address': addr,'times': times,'load5': cpu[0],'load10': cpu[1],'load15':cpu[2]}
    return dict

if __name__ == "__main__":
    CreateDB()

    conn = sqlite3.connect("database.db")
    cursor = conn.cursor()
    while True:
        dict = GetCPU("127.0.0.1")
        insert = 'insert into CpuLoadDB(address,times,load5,load10,load15) values("{}","{}","{}","{}","{}")'.\
            format(dict["address"],dict["times"],dict["load5"],dict["load10"],dict["load15"])
        print(insert)
        cursor.execute(insert)
        conn.commit()
        time.sleep(1)

運行上述程式,開始時間2023-11-27 15:17 結束於2023-11-27 15:36,採集到的數據如下圖所示;

實現歷史查詢

通過簡潔而功能強大的前端頁面,用戶可以選擇主機、設定時間範圍,並實時查看CPU負載的變化。後端使用Flask框架搭建,藉助psutil庫獲取實時CPU負載數據,並將數據存儲在SQLite資料庫中。前端使用jQuery和ECharts庫,通過Ajax請求實現與後端的動態數據交互,併在頁面上實時繪製CPU負載的折線圖。

數據生後後,我們在原來代碼基礎之上增加echarts.js繪圖庫代碼,用戶在前臺填寫表格併發送給後端,當後端處理後輸出給前端JSON格式,前端獲取到該格式之後自動再將其繪製出來,代碼如下所示;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://www.lyshark.com/javascript/echarts/5.3.0/echarts.min.js"></script>
</head>

<body>
    <!--提交表格數據-->
    <form action="/" method="post" id="myForm">
        <!-- <p>主機地址: <input type="text" name="address" placeholder="輸入主機IP地址"></p>-->
        <p>選擇主機: <select name="address" style="width: 185px; height: 25px">
            {% for item in addr %}
                <option value="{{ item }}">{{ item }}</option>
            {% endfor %}
        </select></p>

        <p>開始時間: <input type="datetime-local" name="start_datetime" /></p>
        <p>結束時間: <input type="datetime-local" name="end_datetime" /></p>

        <p>選擇圖形: <select name="select" style="width: 185px; height: 25px">
            <option value="load5">五分鐘負載</option>
            <option value="load10">十分鐘負載</option>
            <option value="load15">十五分鐘負載</option>
        </select></p>

        <input name="btn" id="btn" type="button" value="查詢數據" />
    </form>

    <!--繪圖區域-->
    <div id="main" style="width: 100%;height:450px;border:1px solid #dddddd;float: left;margin-top: 10px;"></div>

    <!--繪圖函數實現流程-->
    <script type="text/javascript" charset="UTF-8">
        var create_graphical = function(time,cpu)
        {
            var myChart_cpu = echarts.init(document.getElementById('main'));
            myChart_cpu.setOption({
                tooltip: {},
                animation: false,
                xAxis: {
                    data: []
                },
                // 調節大小
                grid: {
                    left: '3%',
                    right: '4%',
                    top:'3%',
                    bottom: '3%',
                    containLabel: true
                },
                // tooltip 滑鼠放上去之後會自動出現坐標
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#6a7985'
                        }
                    }
                },

               // 初始化圖形
                yAxis: {},
                series: [{
                    type: 'line',
                    data: []
                }]
            });

            // 下方就是給指定欄位填充數據
            myChart_cpu.setOption({
                xAxis: {
                    data: time
                },
                series: [{
                    name: 'CPU負載率',
                    data: cpu
                }]
                });
        };
    </script>

    <!--點擊查詢後執行的Ajax操作-->
    <script type="text/javascript">
        $("#btn").click(function()
        {
            $.ajax({
                url: "/",
                type: "POST",
                dataType: "text",
                data: $("#myForm").serialize(),
                success:function (data)
                {
                    var ref_dict = JSON.parse(data);
                    create_graphical(ref_dict.time, ref_dict.cpu)
                }
            })
        })
    </script>
</body>

後端首先判斷請求來源,如果是GET方式請求,則先查詢資料庫中有哪些IP地址,並對這些地址去重後返回給前端的select組件,而如果是POST請求,則根據條件匹配記錄,並將匹配結果返回給前臺即可,後端代碼如下所示;

from flask import Flask,render_template,request
import json
import sqlite3

app = Flask(__name__)

@app.route('/',methods=['POST','GET'])
def index():
    if request.method == "GET":
        # 資料庫去重後保存
        address_set = set()

        conn = sqlite3.connect("database.db")
        cursor = conn.cursor()

        # 查詢數據中的地址,並去重
        for address_count in cursor.execute("select address from CpuLoadDB;").fetchall():
            address_set.add(address_count[0])

        return render_template("index.html",addr = list(address_set))

    elif request.method == "POST":
            address = request.form.get("address")
            start_datetime = request.form.get("start_datetime")
            end_datetime = request.form.get("end_datetime")
            select_value = request.form.get("select")

            time_ref = []
            cpu_load_ref = []

            # 查詢數據
            conn = sqlite3.connect("database.db")
            cursor = conn.cursor()

            select = "select * from CpuLoadDB where address=='{}' and times >='{}' and times <='{}'".\
                format(address,start_datetime,end_datetime)

            if select_value == "load5":
                # 查詢記錄並過濾
                for ref in cursor.execute(select).fetchall():
                    time_ref.append(ref[1].split("T")[1])
                    cpu_load_ref.append(float(ref[2]))

                ref_dict = {"time":time_ref, "cpu": cpu_load_ref}
                return json.dumps(ref_dict, ensure_ascii=False)

            if select_value == "load10":
                for ref in cursor.execute(select).fetchall():
                    time_ref.append(ref[1].split("T")[1])
                    cpu_load_ref.append(float(ref[3]))

                ref_dict = {"time":time_ref, "cpu": cpu_load_ref}
                return json.dumps(ref_dict, ensure_ascii=False)

            if select_value == "load15":
                for ref in cursor.execute(select).fetchall():
                    time_ref.append(ref[1].split("T")[1])
                    cpu_load_ref.append(float(ref[4]))

                ref_dict = {"time": time_ref, "cpu": cpu_load_ref}
                return json.dumps(ref_dict, ensure_ascii=False)

if __name__ == '__main__':
    app.run()

代碼被運行後,會首次使用GET方式獲取主機列表及負載單選框列表,此處我們查詢開始時間2023-11-27 15:20 結束於2023-11-27 15:30,這10分鐘的數據,採集到的數據如下圖所示;

文章出處:https://www.cnblogs.com/LyShark/p/17859533.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這是一本比較冷門的書《設計規則:模塊化的力量》,雖然豆瓣上只有58個評價,但是確實能學到很多東西。 這本書對我非常深遠。不是是投資,創業,還是其他領域,模塊化思想都能幫上你。這本書告訴我們生萬物的規則。 書籍電子版PDF(建議及時保存,避免被和諧):https://pan.quark.cn/s/aa ...
  • Spring Boot支持多種日誌框架,包括Logback、Log4j2和Java Util Logging(JUL)。在Spring Boot中,可以通過簡單的配置來集成這些熱門的日誌框架。 下麵將詳細說明如何集成Logback、Log4j2和Java Util Logging,並提供相應的源代碼 ...
  • Cameo項目介紹: 1、實時捕獲並顯示攝像頭幀。 2、具備截圖、保存視頻和退出三個功能鍵。 要求存在文件:manager.py 和 cameo.py 一、manager.py 兩個類:CaptureManager、WindowManager CaptureManager負責攝像頭幀的捕獲,編解碼得 ...
  • 題目 給你一個數組 nums 和一個值 val,你需要 原地 移除所有數值等於 val 的元素,並返回移除後數組的新長度。 不要使用額外的數組空間,你必須僅使用 O(1) 額外空間並 原地 修改輸入數組。 元素的順序可以改變。你不需要考慮數組中超出新長度後面的元素。 說明: 為什麼返回數值是整數,但 ...
  • Flask-SocketIO 是基於 Flask 的一個擴展,用於簡化在 Flask 應用中集成 WebSocket 功能。WebSocket 是一種在客戶端和伺服器之間實現實時雙向通信的協議,常用於實現實時性要求較高的應用,如聊天應用、實時通知等,使得開發者可以更輕鬆地構建實時性要求較高的應用。通... ...
  • keycloak可以幫助我們實現這個功能:用戶token每5分鐘失效一次,失效後通過refresh_token來換新的token,而refresh_token每30天失效一次,但如果用戶3天都沒有任何操作(就是沒有用refresh_token去換新的token),那麼3天後也讓refresh_tok ...
  • 1 簡介 Spring Data Redis是 Spring Data 系列的一部分,它提供了Spring應用程式對Redis的輕鬆配置和使用。它不僅提供了對Redis操作的高級抽象,還支持Jedis和Lettuce兩種連接方式。 可通過簡單的配置就能連接Redis,並且可以切換Jedis和Lett ...
  • PlayImage 記得一鍵三連哦 一個使用簡單的QPainter繪圖事件實現圖片播放器的簡易demo 支持圖片切換 支持多路更新,自己擴展即可 支持幻燈片播放 PlayImage自定義控制項支持復用,對外提供updateImage和updatePixmap介面,對傳入的image和pixmap進行圖 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...