本文适合刚入门flask框架用来熟悉项目的开发人员,关于flask框架的组成概念一些用法请参考下面的文章
https://blog.csdn.net/qq_47452807/article/details/122289200
本文主要给出一个可视化sqlite数据库数据的demo,先展示一下效果:
主要的代码如下
(1)app.py文件
from flask import Flask, jsonify, render_template
import sqlite3
# 创建一个Flask应用实例
app = Flask(__name__)
# 定义SQLite数据库的路径
DATABASE_PATH = r'E:\qt_data\sensordata.db'
# 获取数据库连接的函数
def get_db_connection():
# 连接到SQLite数据库
conn = sqlite3.connect(DATABASE_PATH)
# 将数据库查询结果设置为字典格式,便于通过列名访问数据
conn.row_factory = sqlite3.Row
return conn
# 定义根路由(主页)的处理函数
@app.route('/')
def index():
# 渲染index.html模板
return render_template('index.html')
# 定义/data路由的处理函数,返回JSON格式的传感器数据
@app.route('/data')
def data():
# 获取数据库连接
conn = get_db_connection()
# 创建游标对象,用于执行SQL查询
cursor = conn.cursor()
# 执行SQL查询,获取最新的20条环境数据记录,按时间戳降序排列
cursor.execute("SELECT * FROM env_data ORDER BY timestamp DESC LIMIT 20")
# 获取查询结果的所有行
rows = cursor.fetchall()
# 关闭数据库连接
conn.close()
# 构建一个字典,将查询结果中的每列数据提取到对应的列表中
data = {
"timestamp": [row["timestamp"] for row in rows], # 时间戳
"co2": [row["co2"] for row in rows], # 二氧化碳浓度
"ch2o": [row["ch2o"] for row in rows], # 甲醛浓度
"tvoc": [row["tvoc"] for row in rows], # 总挥发性有机化合物浓度
"pm2_5": [row["pm2_5"] for row in rows], # PM2.5浓度
"pm10": [row["pm10"] for row in rows], # PM10浓度
"temp": [row["temp"] for row in rows], # 温度
"hum": [row["hum"] for row in rows], # 湿度
}
# 将数据字典转换为JSON格式并返回
return jsonify(data)
# 主函数,启动Flask应用
if __name__ == '__main__':
app.run(debug=True) # debug模式运行应用,方便开发调试
(2)index.html文件
Environmental Data Visualization
(3)script.js文件
// 异步函数fetchData,用于从服务器获取传感器数据
async function fetchData() {
// 发送HTTP GET请求到服务器的'/data'路由,并等待响应
const response = await fetch('/data');
// 将响应转换为JSON格式的数据
const data = await response.json();
// 返回获取到的数据
return data;
}
// 函数createChart,用于根据传感器数据创建并初始化折线图
function createChart(data) {
// 获取页面中ID为'lineChart'的canvas元素,并获取其2D绘图上下文
const ctx = document.getElementById('lineChart').getContext('2d');
// 使用Chart.js库创建一个折线图
const chart = new Chart(ctx, {
type: 'line', // 图表类型为折线图
data: {
// 设置X轴的标签为时间戳(数据需要反转以使最新数据在最右侧)
labels: data.timestamp.reverse(),
// 定义多条数据集,每个数据集代表一种传感器数据
datasets: [
{
label: 'CO2', // 数据集标签为'CO2'
data: data.co2.reverse(), // 数据为CO2的浓度值(反转顺序)
borderColor: 'rgb(255, 99, 132)', // 设置线条颜色为红色
fill: false // 不填充曲线下方区域
},
{
label: 'CH2O', // 数据集标签为'CH2O'
data: data.ch2o.reverse(), // 数据为CH2O的浓度值(反转顺序)
borderColor: 'rgb(54, 162, 235)', // 设置线条颜色为蓝色
fill: false // 不填充曲线下方区域
},
{
label: 'TVOC', // 数据集标签为'TVOC'
data: data.tvoc.reverse(), // 数据为TVOC的浓度值(反转顺序)
borderColor: 'rgb(75, 192, 192)', // 设置线条颜色为青色
fill: false // 不填充曲线下方区域
},
{
label: 'PM2.5', // 数据集标签为'PM2.5'
data: data.pm2_5.reverse(), // 数据为PM2.5的浓度值(反转顺序)
borderColor: 'rgb(153, 102, 255)', // 设置线条颜色为紫色
fill: false // 不填充曲线下方区域
},
{
label: 'PM10', // 数据集标签为'PM10'
data: data.pm10.reverse(), // 数据为PM10的浓度值(反转顺序)
borderColor: 'rgb(255, 159, 64)', // 设置线条颜色为橙色
fill: false // 不填充曲线下方区域
},
{
label: 'Temperature', // 数据集标签为'温度'
data: data.temp.reverse(), // 数据为温度值(反转顺序)
borderColor: 'rgb(255, 205, 86)', // 设置线条颜色为黄色
fill: false // 不填充曲线下方区域
},
{
label: 'Humidity', // 数据集标签为'湿度'
data: data.hum.reverse(), // 数据为湿度值(反转顺序)
borderColor: 'rgb(201, 203, 207)', // 设置线条颜色为灰色
fill: false // 不填充曲线下方区域
}
]
},
options: {
// 使图表自适应容器大小
responsive: true,
scales: {
x: {
display: true, // 显示X轴
title: {
display: true, // 显示X轴的标题
text: 'Timestamp' // 设置X轴标题为'时间戳'
}
},
y: {
display: true, // 显示Y轴
title: {
display: true, // 显示Y轴的标题
text: 'Value' // 设置Y轴标题为'数值'
}
}
}
}
});
// 返回创建的图表对象
return chart;
}
// 异步函数updateChart,用于更新图表数据
async function updateChart(chart) {
// 获取最新的数据
const data = await fetchData();
// 更新图表的X轴标签(时间戳),并反转顺序
chart.data.labels = data.timestamp.reverse();
// 更新各个数据集的数据,并反转顺序
chart.data.datasets[0].data = data.co2.reverse();
chart.data.datasets[1].data = data.ch2o.reverse();
chart.data.datasets[2].data = data.tvoc.reverse();
chart.data.datasets[3].data = data.pm2_5.reverse();
chart.data.datasets[4].data = data.pm10.reverse();
chart.data.datasets[5].data = data.temp.reverse();
chart.data.datasets[6].data = data.hum.reverse();
// 更新图表显示
chart.update();
}
// 在DOM完全加载后执行的事件监听器函数
document.addEventListener('DOMContentLoaded', async function () {
// 获取初始数据
const data = await fetchData();
// 创建并渲染图表
const chart = createChart(data);
// 每隔1秒更新一次图表数据
setInterval(async function () {
await updateChart(chart);
}, 1000); // 1000毫秒 = 1秒
});
sensordata.db文件放在本文顶部了有需要自取哦