欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Vue+WebSocket實現(xiàn)實時數(shù)據(jù)可視化的實戰(zhàn)指南

 更新時間:2025年07月31日 10:05:35   作者:saadiya~  
在現(xiàn)代交通大屏項目中,實時數(shù)據(jù)的采集和可視化尤為重要,本文結(jié)合 Vue3 和 ECharts,分享一個支持多 WebSocket 數(shù)據(jù)源實時合并、模擬數(shù)據(jù)調(diào)試、自動重連的完整設(shè)計方案,幫助你快速搭建健壯的數(shù)據(jù)可視化組件,需要的朋友可以參考下

一、項目背景與核心需求

  • 實時接收多個 WebSocket 數(shù)據(jù)源(不同服務(wù)器或端口)
  • 設(shè)計模擬數(shù)據(jù)接口,方便本地開發(fā)調(diào)試
  • 支持數(shù)據(jù)的自動合并(如車流總量、車輛類型分布)
  • 使用 ECharts 動態(tài)展示統(tǒng)計數(shù)據(jù)
  • 保證 WebSocket 斷線自動重連,提高穩(wěn)定性

二、項目架構(gòu)與核心狀態(tài)管理

定義一個全局響應(yīng)式對象 sources,分別存儲四個數(shù)據(jù)源的數(shù)據(jù),支持真實數(shù)據(jù)和模擬數(shù)據(jù)統(tǒng)一寫入。

const USE_MOCK = true; // 是否啟用模擬數(shù)據(jù) 
const sources = reactive({ su1: {}, su2: {}, su3: {}, su4: {}, });

三、WebSocket 連接與模擬數(shù)據(jù)設(shè)計

1. 真實 WebSocket 連接實現(xiàn)

使用原生 WebSocket 連接服務(wù)器,設(shè)置事件監(jiān)聽,支持斷線自動重連。

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} 關(guān)閉,3秒后重連...`);
    setTimeout(() => createRealWS(url, setTarget), 3000);
  };
}

2. 模擬數(shù)據(jù)接口

為了方便本地開發(fā),使用定時器生成結(jié)構(gòu)一致的模擬數(shù)據(jù),模擬數(shù)據(jù)每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. 初始化所有數(shù)據(jù)源

根據(jù) WebSocket URL 端口號映射到對應(yīng)數(shù)據(jù)源,啟用模擬或真實數(shù)據(jù)。

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 su4
    const setFn = (data) => (sources[key] = data);
 
    if (USE_MOCK) {
      createMockSource(setFn);
    } else {
      createRealWS(url, setFn);
    }
  });
}

四、數(shù)據(jù)合并與格式化

合并車流總量

將四個數(shù)據(jù)源的車輛總數(shù)相加,確保數(shù)值準確。

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

合并車輛類型分布

對每種車輛類型進行累加。

格式化合并后的車輛類型數(shù)據(jù),固定順序輸出并計算百分比

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",
    };
  });
}

五、響應(yīng)式數(shù)據(jù)更新與圖表刷新

通過 watchEffect 監(jiān)聽數(shù)據(jù)變化,自動計算合并數(shù)據(jù)并刷新 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 餅圖動態(tài)渲染

初始化并動態(tài)更新餅圖,顏色對應(yīng)車輛類型,關(guān)閉標簽和提示框保證大屏美觀。

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 })),
    }],
  });
};

七、啟動與定時刷新邏輯

在組件掛載時,初始化數(shù)據(jù)接口和數(shù)據(jù)源,并設(shè)置定時器周期刷新相關(guān)統(tǒng)計數(shù)據(jù)。

onMounted(() => {
  curDayCountData();       // 獲取今日車流初始數(shù)據(jù)
  initAllSources();        // 啟動 WebSocket / 模擬數(shù)據(jù)
  getDeviceOnlineData();   // 設(shè)備在線率數(shù)據(jù)
  curDayEventCountData();  // 今日事件統(tǒng)計
  eventHistoryCountData(); // 事件歷史統(tǒng)計
 
  dataRefreshTimer = setInterval(() => {
    curDayCountData();
    getDeviceOnlineData();
    curDayEventCountData();
    eventHistoryCountData();
  }, 30000);
});
 
onUnmounted(() => {
  if (dataRefreshTimer) clearInterval(dataRefreshTimer);
});

八、總結(jié)

  • 多數(shù)據(jù)源實時管理,靈活切換模擬/真實數(shù)據(jù),提升開發(fā)效率
  • 自動重連機制,保證 WebSocket 長連接穩(wěn)定可靠
  • 響應(yīng)式合并處理,統(tǒng)一計算統(tǒng)計數(shù)據(jù),確保展示準確
  • ECharts 動態(tài)刷新,實現(xiàn)流暢視覺效果,符合大屏需求

如果你正在做交通、工業(yè)或監(jiān)控領(lǐng)域的實時可視化,這個方案值得借鑒。

以上就是基于Vue+WebSocket實現(xiàn)實時數(shù)據(jù)可視化的實戰(zhàn)指南的詳細內(nèi)容,更多關(guān)于Vue WebSocket實時數(shù)據(jù)可視化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論