本文将详细介绍如何构建一个完整的数据可视化大屏项目,包含后端API服务和前端可视化展示。
相关服务:台湾站群服务器租用
效果展示!
地图数据分布
项目概述
这是一个基于Flask后端和Vue.js前端的数据可视化大屏应用,能够实时展示各类业务数据,包括地图分布、趋势分析、排名统计等多种可视化图表
技术架构
后端技术栈
-
Flask: Python轻量级Web框架
-
Flask-CORS: 处理跨域请求
-
RESTful API: 提供数据接口服务
前端技术栈
-
Vue.js 3: 前端框架
-
Vite: 构建工具
-
Tailwind CSS: 样式框架
-
ECharts: 数据可视化库
项目结构解析
data-visualization-app/
├── backend/ # 后端服务
│ ├── app.py # Flask主应用
│ └── requirements.txt # Python依赖
├── frontend/ # 前端项目
│ ├── src/
│ │ ├── components/ # Vue组件
│ │ │ ├── MapComponent.vue # 地图组件
│ │ │ ├── TrendChart.vue # 趋势图组件
│ │ │ ├── PieChart.vue # 饼图组件
│ │ │ ├── RankingChart.vue # 排名组件
│ │ │ └── ComparisonChart.vue # 对比组件
│ │ ├── views/
│ │ │ └── App.vue # 主应用组件
│ │ ├── assets/
│ │ │ └── styles/
│ │ │ └── index.css # 全局样式
│ │ └── main.ts # 应用入口
│ ├── package.json # 前端依赖
│ ├── tailwind.config.js # Tailwind配置
│ └── vite.config.ts # Vite配置
├── run.py # 项目启动脚本
└── start.bat # Windows启动脚本
核心代码详解
后端API服务 (app.py)
from flask import Flask, jsonify, send_from_directory
from flask_cors import CORS
import random
import time
from datetime import datetime
import os
app = Flask(__name__)
CORS(app) # 允许跨域请求
# 获取前端dist目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
frontend_dist_dir = os.path.join(current_dir, '..', 'frontend', 'dist')
print(f"前端静态文件目录: {frontend_dist_dir}")
# 模拟数据生成
def generate_stats_data():
"""生成统计数据"""
return [
{"value": random.randint(1000, 5000), "label": "总用户数"},
{"value": random.randint(500, 2000), "label": "今日新增"},
{"value": random.randint(50, 200), "label": "在线用户"},
{"value": random.randint(100, 500), "label": "订单数量"},
{"value": f"¥{random.randint(10000, 50000)}", "label": "总收入"},
{"value": f"{random.randint(80, 99)}%", "label": "完成率"}
]
def generate_map_data():
"""生成地图数据"""
provinces = ["北京", "天津", "上海", "重庆", "河北", "山西", "辽宁", "吉林", "黑龙江",
"江苏", "浙江", "安徽", "福建", "江西", "山东", "河南", "湖北", "湖南",
"广东", "海南", "四川", "贵州", "云南", "陕西", "甘肃", "青海", "台湾",
"内蒙古", "广西", "西藏", "宁夏", "新疆", "香港", "澳门"]
return [{"name": province, "value": random.randint(100, 10000)} for province in provinces]
def generate_pie_data():
"""生成饼图数据"""
categories = ["电子产品", "服装鞋帽", "食品饮料", "家居用品", "美妆护肤", "其他"]
return [{"name": category, "value": random.randint(100, 1000)} for category in categories]
def generate_ranking_data():
"""生成排名数据"""
items = ["产品A", "产品B", "产品C", "产品D", "产品E", "产品F", "产品G", "产品H"]
return [{"name": item, "value": random.randint(500, 2000)} for item in items]
def generate_trend_data():
"""生成趋势数据"""
months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
return {
"xAxis": months,
"series": [random.randint(100, 1000) for _ in months]
}
def generate_comparison_data():
"""生成对比数据"""
categories = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6']
return {
"xAxis": categories,
"series": [random.randint(100, 800) for _ in categories]
}
# API路由
@app.route('/api/stats')
def get_stats():
return jsonify(generate_stats_data())
@app.route('/api/map-data')
def get_map_data():
return jsonify(generate_map_data())
@app.route('/api/pie-data')
def get_pie_data():
return jsonify(generate_pie_data())
@app.route('/api/ranking-data')
def get_ranking_data():
return jsonify(generate_ranking_data())
@app.route('/api/trend-data')
def get_trend_data():
return jsonify(generate_trend_data())
@app.route('/api/comparison-data')
def get_comparison_data():
return jsonify(generate_comparison_data())
@app.route('/api/time')
def get_current_time():
return jsonify({
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"date": datetime.now().strftime("%Y年%m月%d日")
})
# 静态文件服务
@app.route('/')
def serve_index():
return send_from_directory(frontend_dist_dir, 'index.html')
@app.route('/<path:path>')
def serve_static(path):
return send_from_directory(frontend_dist_dir, path)
if __name__ == '__main__':
# 检查前端文件是否存在
index_path = os.path.join(frontend_dist_dir, 'index.html')
if os.path.exists(index_path):
print("✅ 找到前端文件,服务器准备启动...")
else:
print("❌ 警告: 未找到前端文件,请先构建前端")
app.run(debug=True, host='0.0.0.0', port=5000)
前端组件示例 (MapComponent.vue)
<template>
<div class="map-container">
<div class="chart-title">全国数据分布</div>
<div ref="chart" class="chart"></div>
</div>
</template>
<script setup>
import { onMounted, ref, onUnmounted } from 'vue'
import * as echarts from 'echarts'
const chart = ref(null)
let chartInstance = null
const initChart = async () => {
// 初始化ECharts实例
chartInstance = echarts.init(chart.value)
// 获取地图数据
const response = await fetch('/api/map-data')
const mapData = await response.json()
const option = {
tooltip: {
trigger: 'item'
},
visualMap: {
min: 0,
max: 10000,
text: ['高', '低'],
calculable: true
},
series: [{
name: '数据量',
type: 'map',
map: 'china',
data: mapData,
label: {
show: true
},
emphasis: {
label: {
show: true
}
}
}]
}
chartInstance.setOption(option)
}
onMounted(() => {
initChart()
})
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose()
}
})
</script>
<style scoped>
.map-container {
width: 100%;
height: 400px;
background: #fff;
border-radius: 8px;
padding: 16px;
}
.chart-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 12px;
}
.chart {
width: 100%;
height: 350px;
}
</style>
项目启动步骤
1. 后端环境配置
cd backend
pip install -r requirements.txt
2. 前端环境配置
cd frontend
npm install
npm run build
3. 启动项目
# 方法一:使用Python脚本
python run.py
# 方法二:直接运行Flask应用
python backend/app.py
# 方法三:Windows系统使用批处理文件
start.bat
功能特性
📊 多维度数据展示
-
实时统计卡片: 总用户数、今日新增、在线用户等
-
全国地图分布: 各省市数据热力分布
-
趋势分析图表: 月度数据变化趋势
-
产品排名统计: 各产品销售排名
-
分类占比分析: 饼图展示品类分布
-
数据对比分析: 多维度数据对比
🔧 技术亮点
-
前后端分离架构: 清晰的职责分离
-
RESTful API设计: 标准化的数据接口
-
跨域解决方案: 完善的CORS配置
-
静态文件服务: 一体化部署方案
-
响应式设计: 适配不同屏幕尺寸
🚀 部署方案
-
开发环境: Flask调试模式
-
生产环境: Gunicorn + Nginx
-
容器化: Docker部署支持
扩展建议
-
数据持久化: 集成MySQL/PostgreSQL数据库
-
实时数据: 添加WebSocket支持实时更新
-
用户认证: 增加JWT身份验证
-
数据缓存: 使用Redis提升性能
-
监控告警: 集成Prometheus监控
总结
本项目提供了一个完整的数据可视化大屏解决方案,技术栈成熟稳定,架构清晰合理。通过本项目的学习,可以掌握前后端分离开发、数据可视化、API设计等核心技能。项目代码结构清晰,易于扩展和维护,适合作为企业级数据可视化项目的起点。