Vue + WebSocket 实时数据可视化实战:多源融合与模拟数据双模式设计

在现代交通大屏项目中,实时数据的采集和可视化尤为重要。本文结合 Vue3 和 ECharts,分享一个支持多 WebSocket 数据源实时合并、模拟数据调试、自动重连的完整设计方案,帮助你快速搭建健壮的数据可视化组件。


一、项目背景与核心需求

  • 实时接收多个 WebSocket 数据源(不同服务器或端口)

  • 设计模拟数据接口,方便本地开发调试

  • 支持数据的自动合并(如车流总量、车辆类型分布)

  • 使用 ECharts 动态展示统计数据

  • 保证 WebSocket 断线自动重连,提高稳定性


二、项目架构与核心状态管理

定义一个全局响应式对象 sources,分别存储四个数据源的数据,支持真实数据和模拟数据统一写入。


const USE_MOCK = true; // 是否启用模拟数据 
const sources = reactive({ su1: {}, su2: {}, su3: {}, su4: {}, });

三、WebSocket 连接与模拟数据设计

1. 真实 WebSocket 连接实现

使用原生 WebSocket 连接服务器,设置事件监听,支持断线自动重连。

function createRealWS(url, setTarget) {const ws = new WebSocket(url);ws.onopen = () => console.log(`🟢 WebSocket ${url} 已连接`);ws.onmessage = (event) => {const data = JSON.parse(event.data);setTarget(JSON.parse(data.data));};ws.onerror = () => console.error(`WebSocket ${url} 出错`);ws.onclose = () => {console.warn(`WebSocket ${url} 关闭,3秒后重连...`);setTimeout(() => createRealWS(url, setTarget), 3000);};
}

2. 模拟数据接口

为了方便本地开发,使用定时器生成结构一致的模拟数据,模拟数据每3秒刷新一次。

function createMockSource(setTarget) {setInterval(() => {const mock = {timestamp: Date.now(),globalTime: new Date().toLocaleString(),totalVehiCount: Math.floor(Math.random() * 1000),aveSpeed: +(30 + Math.random() * 10).toFixed(2),numVehiByType: Object.fromEntries([1, 2, 3, 7, 8, 10, 11, 15, 100].map(k => [k, Math.floor(Math.random() * 100)])),};setTarget(mock);}, 3000);
}

3. 初始化所有数据源

根据 WebSocket URL 端口号映射到对应数据源,启用模拟或真实数据。

function initAllSources() {const urls = ["ws://xx/wsStatisJd","ws://xx/wsStatisJd","ws://xx/wsStatisJd","ws://xx/wsStatisJd",];urls.forEach((url) => {const key = getSourceKeyByPort(url); // su1 su2 su3 su4const setFn = (data) => (sources[key] = data);if (USE_MOCK) {createMockSource(setFn);} else {createRealWS(url, setFn);}});
}

四、数据合并与格式化

合并车流总量

将四个数据源的车辆总数相加,确保数值准确。

function mergeTotal(...totals) {return totals.reduce((sum, val) => sum + Number(val || 0), 0);
}

合并车辆类型分布

对每种车辆类型进行累加。

格式化合并后的车辆类型数据,固定顺序输出并计算百分比

function formatVehicleTypeData(numVehiByType, total = 0) {const fixedOrder = [8, 3, 2, 1, 15, 7, 10, 11, 100];return fixedOrder.map(key => {const value = numVehiByType[key] || 0;const name = vehicleTypeMap[key] || `类型${key}`;const percent = total > 0 ? ((value / total) * 100).toFixed(1) : "0.0";return {name,value,percent: Number(percent),color: vehicleColorMap[name] || "#999999",};});
}

五、响应式数据更新与图表刷新

通过 watchEffect 监听数据变化,自动计算合并数据并刷新 ECharts 饼图。

watchEffect(() => {const { su1, su2, su3, su4 } = sources;const mergedTotal = mergeTotal(su1.totalVehiCount,su2.totalVehiCount,su3.totalVehiCount,su4.totalVehiCount);const mergedType = mergeVehicleType(su1.numVehiByType || {},su2.numVehiByType || {},su3.numVehiByType || {},su4.numVehiByType || {});chartData.value = formatVehicleTypeData(mergedType, mergedTotal);realtimeTime.value = new Date().toLocaleString();totalVehiCount.value = mergedTotal;aveSpeed.value = {su1: su1.aveSpeed || 0,su2: su2.aveSpeed || 0,su3: su3.aveSpeed || 0,su4: su4.aveSpeed || 0,};InitEchart2(chartData.value);
});

六、ECharts 饼图动态渲染

初始化并动态更新饼图,颜色对应车辆类型,关闭标签和提示框保证大屏美观。

const InitEchart2 = (data) => {const chartDom = document.getElementById("map-left-4-1-echarts");if (!chartDom) return;if (!myChart) {myChart = echarts.init(chartDom);}const colorList = data.map(item => item.color || "#ccc");myChart.setOption({color: colorList,tooltip: { show: false },series: [{name: "车辆类型占比",type: "pie",radius: ["55%", "80%"],avoidLabelOverlap: false,itemStyle: {borderRadius: 1,borderColor: "#2c3950",borderWidth: 2,},label: { show: false },emphasis: { scale: false, label: { show: false } },labelLine: { show: false },data: data.map(({ name, value }) => ({ name, value })),}],});
};

七、启动与定时刷新逻辑

在组件挂载时,初始化数据接口和数据源,并设置定时器周期刷新相关统计数据。

onMounted(() => {curDayCountData();       // 获取今日车流初始数据initAllSources();        // 启动 WebSocket / 模拟数据getDeviceOnlineData();   // 设备在线率数据curDayEventCountData();  // 今日事件统计eventHistoryCountData(); // 事件历史统计dataRefreshTimer = setInterval(() => {curDayCountData();getDeviceOnlineData();curDayEventCountData();eventHistoryCountData();}, 30000);
});onUnmounted(() => {if (dataRefreshTimer) clearInterval(dataRefreshTimer);
});

八、总结

  • 多数据源实时管理,灵活切换模拟/真实数据,提升开发效率

  • 自动重连机制,保证 WebSocket 长连接稳定可靠

  • 响应式合并处理,统一计算统计数据,确保展示准确

  • ECharts 动态刷新,实现流畅视觉效果,符合大屏需求

如果你正在做交通、工业或监控领域的实时可视化,这个方案值得借鉴。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90482.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#索引器、接口、泛型

以下是对提供的 C# 代码中涉及的核心知识点的梳理和总结,涵盖索引器、接口、泛型三大核心内容,以及相关实践要点:一、索引器(Indexer)索引器是一种允许类或结构体像数组一样通过[]语法访问成员的特殊成员,本…

界面组件DevExpress WPF中文教程:Grid - 如何过滤节点?

DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Excel——INDEX和MATCH傻傻分不清?

核心逻辑​先用 MATCH 找到目标姓名在表格中的 ​行号,再用 INDEX 根据行号 ​提取对应信息。就像查字典:先用拼音找到字的页码(MATCH 找行号)再翻到该页看具体解释(INDEX 取数据)​分步拆解(以…

制造业低代码平台实战评测:简道云、钉钉宜搭、华为云Astro、金蝶云·苍穹、斑斑低代码,谁更值得选?

上回聊了斑斑和简道云,不少同行私信问我其他几个低代码平台怎么样,今天就给大家来个"五大门派"终极对决! 一、先说痛点 制造业搞数字化最怕三件事: 1.钱花了没效果(大平台用不起,小工具不够用&…

Jenkins中HTML文件显示样式问题解决方案

Jenkins中HTML文件显示样式问题解决方案 问题描述 在Jenkins中归档的HTML文件显示格式失效,样式无法正常显示,但在本地浏览器中打开却能正常显示。 问题原因 Jenkins为了安全考虑,默认设置了严格的内容安全策略(Content Security Policy, CSP…

四、配置文件

文章目录1. 文件类型1.1 properties1.2 yaml1.2.1 简介1.2.2 基本语法1.2.3 数据类型1.2.4 示例2. 配置提示1. 文件类型 1.1 properties 同以前的properties的用法 1.2 yaml 1.2.1 简介 YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言&#x…

Python常用医疗AI库以及案例解析(场景化进阶版)

📊 框架应用拓扑图用例 #mermaid-svg-lZ1J5KCaVWBV2kAu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lZ1J5KCaVWBV2kAu .error-icon{fill:#552222;}#mermaid-svg-lZ1J5KCaVWBV2kAu .error-text{fill:#552222;st…

Python高效操作Kafka实战指南

Python操作Kafka的高效 以下是使用Python操作Kafka的高效消息发送实例,涵盖基础发送、批量处理、异步回调等场景。示例基于confluent-kafka库(推荐)和kafka-python库,代码均经过实测。 流程图 基础消息发送(同步) from confluent_kafka import Producerproducer = Pro…

离线快速处理PDF格式转化的方案

日常办公中,PDF 几乎成了我们离不开的文件格式。然而像 WPS 这样的工具,不少实用功能都需要额外付费才能解锁。它的打开方式很简单,双击桌面图标即可运行。它不会弹出主界面,而是默默驻留在系统托盘区,需要时双击图标就…

SpringMVC注解与SpringCloudOpenFeign注解对比

1. 背景知识 梳理SpringMVC和SpringCloudOpenFeign常用注解后: Spring MVC中常用注解_笔记-CSDN博客Spring Cloud OpenFeign 常用注解_笔记-CSDN博客 这里对两类注解做个对比。理解两者定位(服务端 vs 客户端)是掌握注解使用的关键&#x…

Linux 时间同步的流程

一、问题时间RTC时间、系统时间(UTC)和本地时间的关系如下:‌RTC时间‌(硬件时钟):显示为UTC时间格式:02:50:35/02:51:28由主板电池供电,独立于系统运行‌12通常存储UTC时间(Linux默认配置&…

VSCode——python选择解释器消失的解决办法

VSCode软件的左下角 设置——检查更新:

笛卡尔积规避:JOIN条件完整性检查要点

笛卡尔积是数据库查询中的高风险操作,多表JOIN时缺失有效关联条件会导致结果集指数级膨胀,引发‌性能塌方‌甚至系统崩溃‌。以下是核心检查策略及防御方案:一、笛卡尔积的致命影响‌‌性能塌方‌百万级订单表与千万级用户表缺失ON条件时&…

Vimba相机二次开发教程,基于Python

文章目录安装获取图像辅助数据Vimba 是由 Allied Vision 开发的一套软件开发套件(SDK),主要用于控制和操作其工业相机产品。它提供了一套完整的 API 和工具,支持多种操作系统和编程语言,便于开发者快速集成相机功能到应…

电子测试行业软件ATECLOUD与ETEST对比分析-纳米软件

在当今科技飞速发展的时代,电测行业对于自动化测试平台的依赖程度日益加深。高效、精准的自动化测试平台不仅能够提升测试效率,还能确保产品质量。ATECLOUD 与 ETEST 作为电测行业中颇受瞩目的自动化测试平台,各自展现出独特的优势与特点。下…

自动化测试中的常见测试方法

自动化测试中的常见测试方法在自动化测试中,除了数据驱动(Data-Driven Testing),还有多种主流方法,每种方法适用于不同场景和需求。以下是常见的自动化测试方法分类及详解:一、关键字驱动测试(K…

口语01-don‘t judge a book by its cover

Dont judge a book by its cover 不要以貌取人1 the most advanced thing2 stack3 right4 frantically5 be annoyed with sb6 Get your stuff off my desk7 But today I came to class and was running a few minutes late.8 take my seat:占我座位 / 坐我的位置9 s…

《Uniapp-Vue 3-TS 实战开发》自定义预约时间段组件

这个组件可以直接在 uniapp 项目中使用,提供了 24 小时时段选择功能,支持单选 / 多选、预设时段选择、随机选择等功能。 html版本: <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="vi…

《Uniapp-Vue 3-TS 实战开发》自定义环形进度条组件

引言 在UniApp中使用Vue3和TypeScript开发环形进度条组件,我们可以考虑三种技术:Canvas、SVG和纯HTML(利用CSS)。考虑到兼容性、实现难度和效果,SVG是较好的选择。它可以轻松实现环形进度条,支持渐变色,并且可以通过属性精确控制进度,同时在不同分辨率屏幕上清晰显示…

MybatisPlus-17.扩展功能-JSON处理器

一.JSON处理器数据库中有的字段会以JSON格式来进行存储。类型为json类型。但是在java中我们没有这样的数据类型&#xff0c;一般会以字符串接收&#xff0c;这样就会导致如果想要从数据库中获取json格式中的key和value的话会比较麻烦&#xff0c;还要进行字符串操作。那么有没有…