|
|
@@ -73,10 +73,10 @@
|
|
|
<div class="donut-title">实时方案(执行方案3)</div>
|
|
|
<PlanDonutChart
|
|
|
:chartData="realtimeDonutData"
|
|
|
- centerValue="94"
|
|
|
+ :centerValue="String(realtimeRemaining)"
|
|
|
centerLabel="剩余时长"
|
|
|
:showTotal="true"
|
|
|
- :totalValue="180"
|
|
|
+ :totalValue="cycleLength"
|
|
|
:scale="panelScale"
|
|
|
/>
|
|
|
</div>
|
|
|
@@ -84,7 +84,7 @@
|
|
|
<div class="donut-title">下周期方案</div>
|
|
|
<PlanDonutChart
|
|
|
:chartData="nextCycleDonutData"
|
|
|
- centerValue="98"
|
|
|
+ :centerValue="String(cycleLength)"
|
|
|
centerLabel="总时长"
|
|
|
:showTotal="false"
|
|
|
:scale="panelScale"
|
|
|
@@ -176,19 +176,14 @@ export default {
|
|
|
currentMethod: 'temp',
|
|
|
currentScheme: 'early_peak',
|
|
|
schemeOptions: [],
|
|
|
- // 实时方案圆饼图数据
|
|
|
- realtimeDonutData: [
|
|
|
- { label: '已走时长', value: 86, color: '#8892a0' },
|
|
|
- { label: '1-西单面', value: 0, color: '#3b82f6' },
|
|
|
- { label: '2-东西直行', value: 43, color: '#a855f7' },
|
|
|
- { label: '3-北左转', value: 51, color: '#14b8a6' }
|
|
|
- ],
|
|
|
+ // 实时方案圆饼图数据(从 phaseData 动态生成)
|
|
|
+ realtimeDonutData: [],
|
|
|
// 下周期方案圆饼图数据
|
|
|
- nextCycleDonutData: [
|
|
|
- { label: '1-西单面', value: 23, color: '#3b82f6' },
|
|
|
- { label: '2-东西直行', value: 51, color: '#a855f7' },
|
|
|
- { label: '3-北左转', value: 24, color: '#14b8a6' }
|
|
|
- ],
|
|
|
+ nextCycleDonutData: [],
|
|
|
+ // 实时方案剩余时长
|
|
|
+ realtimeRemaining: 0,
|
|
|
+ // 各阶段基础数据(从 phaseData 解析)
|
|
|
+ phaseStages: [],
|
|
|
currentLocktime: 50,
|
|
|
locktimeOptions: [],
|
|
|
currentStage: '1',
|
|
|
@@ -266,6 +261,63 @@ export default {
|
|
|
activeArrowTypes: ewGreen ? activeArrowTypes : []
|
|
|
}
|
|
|
});
|
|
|
+
|
|
|
+ // 更新实时方案圆饼图的已走时长
|
|
|
+ this.updateRealtimeDonut(activeTime);
|
|
|
+ },
|
|
|
+ // 从 phaseData 解析4个阶段的绿灯时长,构建圆饼图数据
|
|
|
+ buildDonutFromPhaseData() {
|
|
|
+ const phaseData = this.mockPhaseData || [];
|
|
|
+ const stageColors = ['#3b82f6', '#a855f7', '#14b8a6', '#f59e0b'];
|
|
|
+ const stageLabels = ['1-南北直行', '2-南北左转', '3-东西直行', '4-东西左转'];
|
|
|
+
|
|
|
+ // 提取 track 0 的绿灯相位(每阶段的第一个 green)
|
|
|
+ const greenPhases = phaseData.filter(p => p[0] === 0 && p[5] === 'green');
|
|
|
+ const stages = greenPhases.slice(0, 4).map((p, i) => ({
|
|
|
+ label: stageLabels[i] || `阶段${i + 1}`,
|
|
|
+ value: p[4], // 绿灯时长
|
|
|
+ start: p[1], // 阶段开始时间
|
|
|
+ end: p[2], // 绿灯结束时间
|
|
|
+ color: stageColors[i]
|
|
|
+ }));
|
|
|
+ this.phaseStages = stages;
|
|
|
+
|
|
|
+ // 实时方案:已走时长 + 4个阶段
|
|
|
+ this.realtimeDonutData = [
|
|
|
+ { label: '已走时长', value: 0, color: '#8892a0' },
|
|
|
+ ...stages.map(s => ({ label: s.label, value: s.value, color: s.color }))
|
|
|
+ ];
|
|
|
+ this.realtimeRemaining = this.cycleLength;
|
|
|
+
|
|
|
+ // 下周期方案:4个阶段,时长随机微调 ±3s
|
|
|
+ this.nextCycleDonutData = stages.map(s => ({
|
|
|
+ label: s.label,
|
|
|
+ value: Math.max(10, s.value + Math.floor(Math.random() * 7) - 3),
|
|
|
+ color: s.color
|
|
|
+ }));
|
|
|
+ },
|
|
|
+ // 根据扫描线时间更新实时方案圆饼图
|
|
|
+ updateRealtimeDonut(activeTime) {
|
|
|
+ if (this.phaseStages.length === 0) return;
|
|
|
+ const elapsed = Math.round(activeTime);
|
|
|
+ const remaining = Math.max(0, this.cycleLength - elapsed);
|
|
|
+ this.realtimeRemaining = remaining;
|
|
|
+
|
|
|
+ // 计算各阶段的剩余时长
|
|
|
+ const stageValues = this.phaseStages.map(s => {
|
|
|
+ if (activeTime >= s.end) return 0; // 阶段已完成
|
|
|
+ if (activeTime < s.start) return s.value; // 阶段未开始
|
|
|
+ return Math.max(0, Math.round(s.end - activeTime)); // 阶段进行中
|
|
|
+ });
|
|
|
+
|
|
|
+ this.realtimeDonutData = [
|
|
|
+ { label: '已走时长', value: elapsed, color: '#8892a0' },
|
|
|
+ ...this.phaseStages.map((s, i) => ({
|
|
|
+ label: s.label,
|
|
|
+ value: stageValues[i],
|
|
|
+ color: s.color
|
|
|
+ }))
|
|
|
+ ];
|
|
|
},
|
|
|
initScaleObserver() {
|
|
|
const ro = new ResizeObserver(entries => {
|
|
|
@@ -293,6 +345,7 @@ export default {
|
|
|
this.phaseDiff = data.phaseDiff || 0;
|
|
|
this.coordTime = data.coordTime || 0;
|
|
|
this.currentStageList = data.stageList || [];
|
|
|
+ this.buildDonutFromPhaseData();
|
|
|
this.$nextTick(() => {
|
|
|
this.dataReady = true;
|
|
|
});
|