首页 前端知识 使用 Flask、echarts 和 jQuery 构建数据大屏

使用 Flask、echarts 和 jQuery 构建数据大屏

2025-03-08 14:03:53 前端知识 前端哥 328 129 我要收藏

使用 Flask、echarts 和 jQuery 构建数据大屏的完整指南

在当今数据驱动的世界中,构建一个直观且交互性强的大屏展示系统对于企业决策至关重要。本文将详细介绍如何使用 Flask 作为后端框架,echarts 作为前端可视化库,以及 jQuery 进行动态交互,开发一个功能强大的数据大屏。我们将通过一个实际案例,图文并茂地展示整个开发过程。

目录

  1. 项目概述
  2. 环境搭建
  3. 后端开发:Flask
  4. 前端开发:HTML、CSS、JavaScript
    • 引入必要的库
    • 布局设计
    • 使用 echarts 创建图表
    • 使用 jQuery 实现动态数据加载
  5. 整合前后端
  6. 运行与测试
  7. 完整代码示例
  8. 总结

项目概述

本项目旨在构建一个数据大屏,展示实时或定期更新的数据图表。我们将使用 Flask 作为后端服务器,提供数据接口;前端使用 HTML、CSS 进行布局设计,echarts 进行数据可视化,jQuery 进行动态数据请求和页面交互。

主要功能

  • 数据展示:通过多种图表(如柱状图、折线图、饼图等)展示数据。
  • 实时更新:定时从后端获取最新数据,动态更新图表。
  • 交互性:用户可以通过交互元素(如下拉菜单、按钮)切换不同的数据视图。

环境搭建

1. 安装 Python 和 Flask

确保已安装 Python(建议 3.6 及以上版本)。然后使用 pip 安装 Flask:

pip install Flask

2. 创建项目目录

创建一个新的项目文件夹,例如 data_dashboard,并在其中创建以下文件:

data_dashboard/
│
├── app.py
├── templates/
│   └── index.html
├── static/
│   ├── css/
│   │   └── styles.css
│   ├── js/
│   │   └── scripts.js
│   └── images/
│       └── (可选的图像文件)
└── data/
    └── (数据文件,如 JSON、CSV 等)

在这里插入图片描述

后端开发:Flask

1. 创建 Flask 应用

app.py 中编写以下代码:

from flask import Flask, render_template, jsonify
import json
import random
import time
from datetime import datetime

app = Flask(__name__)

# 示例数据生成函数
def generate_sample_data():
    timestamp = int(time.time())
    return {
        'timestamp': timestamp,
        'value': random.randint(10, 100)
    }

# 数据接口
@app.route('/api/data')
def get_data():
    data = generate_sample_data()
    return jsonify(data)

# 首页路由
@app.route('/')
def index():
    return render_template('index.html')

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

2. 解释

  • 路由 /api/data:提供一个简单的 API 接口,返回一个包含时间戳和随机值的 JSON 对象。这模拟了从数据库或外部数据源获取数据的过程。
  • 路由 /:渲染前端页面 index.html

在这里插入图片描述

前端开发:HTML、CSS、JavaScript

1. 引入必要的库

templates/index.html 中引入 Bootstrap(用于快速布局)、jQuery、echarts 以及自定义的 CSS 和 JavaScript 文件:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>数据大屏</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
    <!-- 引入 echarts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div class="container-fluid">
        <h1 class="text-center my-4">数据大屏展示</h1>
        <div class="row">
            <!-- 柱状图 -->
            <div class="col-md-6">
                <div class="card mb-4">
                    <div class="card-header">月度销售数据</div>
                    <div class="card-body">
                        <div id="barChart" style="width: 100%; height: 400px;"></div>
                    </div>
                </div>
            </div>
            <!-- 折线图 -->
            <div class="col-md-6">
                <div class="card mb-4">
                    <div class="card-header">网站访问趋势</div>
                    <div class="card-body">
                        <div id="lineChart" style="width: 100%; height: 400px;"></div>
                    </div>
                </div>
            </div>
            <!-- 饼图 -->
            <div class="col-md-4">
                <div class="card mb-4">
                    <div class="card-header">用户分布</div>
                    <div class="card-body">
                        <div id="pieChart" style="width: 100%; height: 300px;"></div>
                    </div>
                </div>
            </div>
            <!-- 实时数据展示 -->
            <div class="col-md-8">
                <div class="card mb-4">
                    <div class="card-header">实时数据</div>
                    <div class="card-body">
                        <table class="table table-striped">
                            <thead>
                                <tr>
                                    <th>时间</th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tbody id="dataTableBody">
                                <!-- 动态填充数据 -->
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 引入 jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- 引入自定义脚本 -->
    <script src="{{ url_for('static', filename='js/scripts.js') }}"></script>
</body>
</html>

2. 布局设计

上述 HTML 使用 Bootstrap 的网格系统将页面分为多个部分:

  • 柱状图:展示月度销售数据。
  • 折线图:展示网站访问趋势。
  • 饼图:展示用户分布。
  • 实时数据展示:以表格形式展示最新的数据记录。

在这里插入图片描述

3. 使用 echarts 创建图表

static/js/scripts.js 中编写以下代码:

$(document).ready(function() {
    // 初始化柱状图
    var barChart = echarts.init(document.getElementById('barChart'));
    var barOption = {
        title: {
            text: '月度销售数据'
        },
        tooltip: {},
        xAxis: {
            type: 'category',
            data: ['一月','二月','三月','四月','五月','六月']
        },
        yAxis: {
            type: 'value'
        },
        series: [{
            name: '销售额',
            type: 'bar',
            data: [120, 200, 150, 80, 70, 110],
            itemStyle: {
                color: '#5470C6'
            }
        }]
    };
    barChart.setOption(barOption);

    // 初始化折线图
    var lineChart = echarts.init(document.getElementById('lineChart'));
    var lineOption = {
        title: {
            text: '网站访问趋势'
        },
        tooltip: {},
        xAxis: {
            type: 'category',
            data: ['周一','周二','周三','周四','周五','周六','周日']
        },
        yAxis: {
            type: 'value'
        },
        series: [{
            name: '访问量',
            type: 'line',
            data: [150, 230, 224, 218, 135, 147, 260],
            itemStyle: {
                color: '#91CC75'
            }
        }]
    };
    lineChart.setOption(lineOption);

    // 初始化饼图
    var pieChart = echarts.init(document.getElementById('pieChart'));
    var pieOption = {
        title: {
            text: '用户分布'
        },
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: '5%',
            left: 'center'
        },
        series: [{
            name: '访问来源',
            type: 'pie',
            radius: '50%',
            data: [
                {value: 1048, name: '搜索引擎'},
                {value: 735, name: '直接访问'},
                {value: 580, name: '邮件营销'},
                {value: 484, name: '联盟广告'},
                {value: 300, name: '视频广告'}
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            },
            label: {
                formatter: '{b}: {c} ({d}%)'
            }
        }]
    };
    pieChart.setOption(pieOption);

    // 实时数据更新
    function fetchData() {
        $.ajax({
            url: '/api/data',
            method: 'GET',
            success: function(response) {
                var data = response;
                // 更新表格
                var tableRow = '<tr><td>' + datetimeConverter(data.timestamp) + '</td><td>' + data.value + '</td></tr>';
                $('#dataTableBody').prepend(tableRow);

                // 保持表格最多显示10条记录
                if ($('#dataTableBody tr').length > 10) {
                    $('#dataTableBody tr').last().remove();
                }

                // 更新柱状图
                barOption.xAxis.data.push(datetimeConverter(data.timestamp).split(' ')[1]);
                barOption.series[0].data.push(data.value);
                barChart.setOption(barOption);

                // 更新折线图
                lineOption.xAxis.data.push(datetimeConverter(data.timestamp).split(' ')[1]);
                lineOption.series[0].data.push(data.value);
                lineChart.setOption(lineOption);

                // 更新饼图(示例中不涉及动态更新)
            },
            error: function(error) {
                console.error('数据获取失败:', error);
            }
        });
    }

    // 转换时间戳为可读的日期时间格式
    function datetimeConverter(timestamp) {
        var date = new Date(timestamp * 1000);
        var year = date.getFullYear();
        var month = ('0' + (date.getMonth() + 1)).slice(-2);
        var day = ('0' + date.getDate()).slice(-2);
        var hours = ('0' + date.getHours()).slice(-2);
        var minutes = ('0' + date.getMinutes()).slice(-2);
        var seconds = ('0' + date.getSeconds()).slice(-2);
        return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
    }

    // 每隔5秒获取一次数据
    setInterval(fetchData, 5000);

    // 初始获取数据
    fetchData();
});

4. 解释

  • 初始化图表:使用 echarts 初始化三个图表(柱状图、折线图、饼图),并设置初始数据。
  • 实时数据更新
    • 使用 setInterval 每隔 5 秒调用 fetchData 函数,从后端获取最新数据。
    • 更新表格中的数据记录。
    • 将新数据添加到柱状图和折线图的系列数据中,并刷新图表。
    • 表格最多显示 10 条记录,超过则删除最早的记录。

在这里插入图片描述

整合前后端

1. 静态文件引用

templates/index.html 中通过 {{ url_for('static', filename='路径') }} 引用静态文件(如 CSS 和 JS)。

2. 启动静态文件夹

确保 Flask 应用能够访问静态文件夹。在 app.py 中已经通过 render_template 函数指定了模板路径。


在这里插入图片描述

运行与测试

1. 启动 Flask 应用

在项目根目录下运行:

python app.py

2. 访问应用

打开浏览器,访问 http://127.0.0.1:5000/,即可看到数据大屏展示。

3. 效果展示

以下是数据大屏的预期效果:

在这里插入图片描述


完整代码示例

1. app.py

from flask import Flask, render_template, jsonify
import json
import random
import time
from datetime import datetime

app = Flask(__name__)

# 示例数据生成函数
def generate_sample_data():
    timestamp = int(time.time())
    return {
        'timestamp': timestamp,
        'value': random.randint(10, 100)
    }

# 数据接口
@app.route('/api/data')
def get_data():
    data = generate_sample_data()
    return jsonify(data)

# 首页路由
@app.route('/')
def index():
    return render_template('index.html')

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

2. templates/index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>数据大屏</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
    <!-- 引入 echarts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div class="container-fluid">
        <h1 class="text-center my-4">数据大屏展示</h1>
        <div class="row">
            <!-- 柱状图 -->
            <div class="col-md-6">
                <div class="card mb-4">
                    <div class="card-header">月度销售数据</div>
                    <div class="card-body">
                        <div id="barChart" style="width: 100%; height: 400px;"></div>
                    </div>
                </div>
            </div>
            <!-- 折线图 -->
            <div class="col-md-6">
                <div class="card mb-4">
                    <div class="card-header">网站访问趋势</div>
                    <div class="card-body">
                        <div id="lineChart" style="width: 100%; height: 400px;"></div>
                    </div>
                </div>
            </div>
            <!-- 饼图 -->
            <div class="col-md-4">
                <div class="card mb-4">
                    <div class="card-header">用户分布</div>
                    <div class="card-body">
                        <div id="pieChart" style="width: 100%; height: 300px;"></div>
                    </div>
                </div>
            </div>
            <!-- 实时数据展示 -->
            <div class="col-md-8">
                <div class="card mb-4">
                    <div class="card-header">实时数据</div>
                    <div class="card-body">
                        <table class="table table-striped">
                            <thead>
                                <tr>
                                    <th>时间</th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tbody id="dataTableBody">
                                <!-- 动态填充数据 -->
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 引入 jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- 引入自定义脚本 -->
    <script src="{{ url_for('static', filename='js/scripts.js') }}"></script>
</body>
</html>

3. static/css/styles.css

body {
    background-color: #f8f9fa;
}

.card {
    background-color: #ffffff;
}

.card-header {
    background-color: #007bff;
    color: #ffffff;
    font-weight: bold;
}

4. static/js/scripts.js

$(document).ready(function() {
    // 初始化柱状图
    var barChart = echarts.init(document.getElementById('barChart');
    var barOption = {
        title: {
            text: '月度销售数据'
        },
        tooltip: {},
        xAxis: {
            type: 'category',
            data: ['一月','二月','三月','四月','五月','六月']
        },
        yAxis: {
            type: 'value'
        },
        series: [{
            name: '销售额',
            type: 'bar',
            data: [120, 200, 150, 80, 70, 110],
            itemStyle: {
                color: '#5470C6'
            }
        }]
    };
    barChart.setOption(barOption);

    // 初始化折线图
    var lineChart = echarts.init(document.getElementById('lineChart');
    var lineOption = {
        title: {
            text: '网站访问趋势'
        },
        tooltip: {},
        xAxis: {
            type: 'category',
            data: ['周一','周二','周三','周四','周五','周六','周日']
        },
        yAxis: {
            type: 'value'
        },
    series: [{
        name: '访问量',
        type: 'line',
        data: [150, 230, 224, 218, 135, 147, 260],
        itemStyle: {
            color: '#91CC75'
        }
    }]
    };
    lineChart.setOption(lineOption);

    // 初始化饼图
    var pieChart = echarts.init(document.getElementById('pieChart');
    var pieOption = {
        title: {
            text: '用户分布'
        },
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: '5%',
            left: 'center'
        },
        series: [{
            name: '访问来源',
            type: 'pie',
            radius: '50%',
            data: [
                {value: 1048, name: '搜索引擎'},
                {value: 735, name: '直接访问'},
                {value: 580, name: '邮件营销'},
                {value: 484, name: '联盟广告'},
                {value: 300, name: '视频广告'}
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            },
            label: {
                formatter: '{b}: {c} ({d}%)'
            }
        }]
    };
    pieChart.setOption(pieOption);

    // 实时数据更新
    function fetchData() {
        $.ajax({
            url: '/api/data',
            method: 'GET',
            success: function(response) {
                var data = response;
                // 更新表格
                var tableRow = '<tr><td>' + datetimeConverter(data.timestamp) + '</td><td>' + data.value + '</td></tr>';
                $('#dataTableBody').prepend(tableRow);

                // 保持表格最多显示10条记录
                if ($('#dataTableBody tr').length > 10) {
                    $('#dataTableBody tr').last().remove();
                }

                // 更新柱状图
                barOption.xAxis.data.push(datetimeConverter(data.timestamp).split(' ')[1]);
                barOption.series[0].data.push(data.value);
                barChart.setOption(barOption);

                // 更新折线图
                lineOption.xAxis.data.push(datetimeConverter(data.timestamp).split(' ')[1]);
                lineOption.series[0].data.push(data.value);
                lineChart.setOption(lineOption);

                // 更新饼图(示例中不涉及动态更新)
            },
            error: function(error) {
                console.error('数据获取失败:', error);
            }
        });
    }

    // 转换时间戳为可读的日期时间格式
    function datetimeConverter(timestamp) {
        var date = new Date(timestamp * 1000);
        var year = date.getFullYear();
        var month = ('0' + (date.getMonth() + 1)).slice(-2);
        var day = ('0' + date.getDate()).slice(-2);
        var hours = ('0' + date.getHours()).slice(-2);
        var minutes = ('0' + date.getMinutes()).slice(-2);
        var seconds = ('0' + date.getSeconds()).slice(-2);
        return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
    }

    // 每隔5秒获取一次数据
    setInterval(fetchData, 5000);

    // 初始获取数据
    fetchData();
});

总结

通过本文,我们详细介绍了如何使用 Flask、echarts 和 jQuery 构建一个数据大屏。整个过程包括环境搭建、后端开发、前端设计以及前后端整合。通过实际代码示例和图文说明,展示了如何实现实时数据展示和动态图表更新。希望本文能为您的数据可视化项目提供有益的参考。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/22935.html
标签
评论
发布的文章

Lua与Unity交互

2025-03-08 14:03:36

Pygame介绍与游戏开发

2025-03-08 14:03:36

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!