Flask前後端數據動態交互涉及用戶界面與伺服器之間的靈活數據傳遞。用戶界面使用ECharts圖形庫實時渲染數據。它提供了豐富多彩、交互性強的圖表和地圖,能夠在網頁上直觀、生動地展示數據。ECharts支持各種常見的圖表類型,包括折線圖、柱狀圖、餅圖、散點圖等,同時還支持動畫效果、數據篩選、區域縮放... ...
Flask前後端數據動態交互涉及用戶界面與伺服器之間的靈活數據傳遞。用戶界面使用ECharts圖形庫實時渲染數據。它提供了豐富多彩、交互性強的圖表和地圖,能夠在網頁上直觀、生動地展示數據。ECharts支持各種常見的圖表類型,包括折線圖、柱狀圖、餅圖、散點圖等,同時還支持動畫效果、數據篩選、區域縮放等交互功能。
Flask後端通過render_template方法將查詢得到的JSON數據傳遞至前端,使得用戶能夠查詢特定時間段內的數據。這種交互方式實現了動態圖形展示,為用戶提供了更直觀、實時的數據體驗。通過此系統,用戶可通過前端界面直接選擇時間範圍,後臺伺服器相應地返回相應的數據,實現了數據的動態交互與圖形化展示。
JQuery綁定事件
jQuery 是一個快速、輕量級、跨瀏覽器的JavaScript庫。它旨在簡化HTML文檔遍歷、事件處理、動畫操作和AJAX等常見任務,使開發者能夠更方便地處理DOM操作和前端交互。
以下這段HTML代碼實現了一個包含表單的頁面,用戶可以輸入主機地址、開始時間、結束時間以及選擇負載類型,然後通過點擊按鈕進行數據查詢。
代碼首先通過Ajax介面實現了參數傳遞,使用了jQuery中的click
方法綁定了按鈕點擊事件。概述如下:
- 表單提交和Ajax請求:
- 在用戶填寫完表單後,通過jQuery的
click
方法,給按鈕綁定了一個點擊事件。 - 在點擊事件中,使用
$.ajax
函數實現了非同步的數據請求。 - 通過
$("#myForm").serialize()
將表單數據序列化,然後作為請求參數發送給後端。
- 在用戶填寫完表單後,通過jQuery的
- 後端響應:
- 請求的目標URL是根目錄("/"),這可能是Flask或其他後端框架的路由。
- 後端處理接收到的數據,執行相應的邏輯,並返回一個JSON格式的數據。
- 前端處理響應數據:
- 當Ajax請求成功時,觸發了
success
回調函數。 - 在回調函數中,使用
JSON.parse(data)
解析後端返回的JSON字元串,得到一個包含時間、X、Y、Z數據的字典(ref_dict
)。
- 當Ajax請求成功時,觸發了
- 數據展示:
- 解析後的數據傳遞給
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分鐘的數據採集。
以下是對該代碼的概述:
- 資料庫創建函數 (
CreateDB
):- 連接到SQLite資料庫(
database.db
)。 - 創建了一個名為
CpuLoadDB
的表,包含主機地址 (address
)、時間 (times
)、5分鐘負載 (load5
)、10分鐘負載 (load10
)、15分鐘負載 (load15
) 的欄位。
- 連接到SQLite資料庫(
- 獲取CPU負載函數 (
GetCPU
):- 獲取當前時間並格式化為字元串。
- 使用
psutil.cpu_percent
獲取實時CPU負載,返回一個包含主機地址、時間、5分鐘負載、10分鐘負載、15分鐘負載的字典。
- 主程式 (
__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分鐘的數據,採集到的數據如下圖所示;
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!