在現代交通大屏項目中,實時數據的采集和可視化尤為重要。本文結合 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 動態刷新,實現流暢視覺效果,符合大屏需求
如果你正在做交通、工業或監控領域的實時可視化,這個方案值得借鑒。