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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...