本文将详细介绍如何构建一个完整的数据可视化大屏项目,包含后端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

功能特性

📊 多维度数据展示

  • 实时统计卡片: 总用户数、今日新增、在线用户等

  • 全国地图分布: 各省市数据热力分布

  • 趋势分析图表: 月度数据变化趋势

  • 产品排名统计: 各产品销售排名

  • 分类占比分析: 饼图展示品类分布

  • 数据对比分析: 多维度数据对比

🔧 技术亮点

  1. 前后端分离架构: 清晰的职责分离

  2. RESTful API设计: 标准化的数据接口

  3. 跨域解决方案: 完善的CORS配置

  4. 静态文件服务: 一体化部署方案

  5. 响应式设计: 适配不同屏幕尺寸

🚀 部署方案

  • 开发环境: Flask调试模式

  • 生产环境: Gunicorn + Nginx

  • 容器化: Docker部署支持

扩展建议

  1. 数据持久化: 集成MySQL/PostgreSQL数据库

  2. 实时数据: 添加WebSocket支持实时更新

  3. 用户认证: 增加JWT身份验证

  4. 数据缓存: 使用Redis提升性能

  5. 监控告警: 集成Prometheus监控

总结

本项目提供了一个完整的数据可视化大屏解决方案,技术栈成熟稳定,架构清晰合理。通过本项目的学习,可以掌握前后端分离开发、数据可视化、API设计等核心技能。项目代码结构清晰,易于扩展和维护,适合作为企业级数据可视化项目的起点。