Pārlūkot izejas kodu

SignalTimingChart新增syncScan参数支持扫描线独立/同步模式

  1. SignalTimingChart 新增 syncScan
  prop(默认false),false时每行扫描线从各自currentTime位置独立运动,true时保持原有共享定时器同步行为
  2. 列表模式下每行currentTime改为基于行索引和页码的随机偏移,避免所有行起始位置相同
画安 2 nedēļas atpakaļ
vecāks
revīzija
65f01c422f
2 mainītis faili ar 27 papildinājumiem un 11 dzēšanām
  1. 26 10
      src/components/ui/SignalTimingChart.vue
  2. 1 1
      src/mock/api.js

+ 26 - 10
src/components/ui/SignalTimingChart.vue

@@ -108,7 +108,8 @@ export default {
     showAxis: { type: Boolean, default: true },
     showScanLine: { type: Boolean, default: true },
     showScanLineLabel: { type: Boolean, default: true },
-    autoScan: { type: Boolean, default: false }
+    autoScan: { type: Boolean, default: false },
+    syncScan: { type: Boolean, default: false }
   },
   data() {
     return { scaleFactor: 1, internalTime: 0 };
@@ -138,6 +139,9 @@ export default {
     autoScan(val) {
       if (val) { this.startAutoScan(); } else { this.stopAutoScan(); }
     },
+    syncScan() {
+      if (this.autoScan) { this.startAutoScan(); }
+    },
     showScanLine(val) {
       this.updateChart();
       if (val && this.autoScan) { this.startAutoScan(); }
@@ -154,19 +158,31 @@ export default {
     },
     startAutoScan() {
       this.stopAutoScan();
-      // 统一视觉周期:所有行在 VISUAL_PERIOD 秒内完成一次扫描
       const VISUAL_PERIOD = 120;
-      this._scanListener = (elapsed) => {
-        const realMax = this.getMaxTime();
-        const offset = this.currentTime || 0; // 动态读取,不用闭包捕获
-        const ratio = ((offset + elapsed) % VISUAL_PERIOD) / VISUAL_PERIOD;
-        this.internalTime = ratio * realMax;
-        if (this.$_chart) this.updateScanLine();
-      };
-      joinSharedTimer(this._scanListener, this.currentTime || 0);
+      if (this.syncScan) {
+        // 共享定时器:所有行扫描线完全同步
+        this._scanListener = (elapsed) => {
+          const realMax = this.getMaxTime();
+          const offset = this.currentTime || 0;
+          const ratio = ((offset + elapsed) % VISUAL_PERIOD) / VISUAL_PERIOD;
+          this.internalTime = ratio * realMax;
+          if (this.$_chart) this.updateScanLine();
+        };
+        joinSharedTimer(this._scanListener, this.currentTime || 0);
+      } else {
+        // 独立定时器:每行扫描线从 currentTime 位置开始独立移动
+        this.internalTime = this.currentTime || 0;
+        this._soloTimer = setInterval(() => {
+          const realMax = this.getMaxTime();
+          this.internalTime += 1;
+          if (this.internalTime > realMax) this.internalTime = 0;
+          if (this.$_chart) this.updateScanLine();
+        }, 1000);
+      }
     },
     stopAutoScan() {
       if (this._scanListener) { leaveSharedTimer(this._scanListener); this._scanListener = null; }
+      if (this._soloTimer) { clearInterval(this._soloTimer); this._soloTimer = null; }
     },
     initChart() {
       const chartDom = this.$refs.chartRef;

+ 1 - 1
src/mock/api.js

@@ -607,7 +607,7 @@ export async function apiGetCrossingList(params = {}) {
       status: statuses[Math.floor(seededRand(i + 42) * statuses.length)],
       cycle: cycleLength,
       phaseData,
-      currentTime: pageOffset,
+      currentTime: Math.floor(seededRand(i * 31 + page * 97) * cycleLength),
     }
   })