|
|
@@ -45,11 +45,17 @@ export default {
|
|
|
scanLineTimer: null,
|
|
|
currentViewMinX: 0,
|
|
|
currentScanX: 0,
|
|
|
- barWidth: 8,
|
|
|
- gap: 2,
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
+ barWidth() {
|
|
|
+ const scale = typeof window !== 'undefined' ? Math.max(1, window.innerWidth / 1920) : 1;
|
|
|
+ return Math.round(8 * scale);
|
|
|
+ },
|
|
|
+ gap() {
|
|
|
+ const scale = typeof window !== 'undefined' ? Math.max(1, window.innerWidth / 1920) : 1;
|
|
|
+ return Math.round(2 * scale);
|
|
|
+ },
|
|
|
intersections() {
|
|
|
let currentX = 0;
|
|
|
return this.roadSegments.map((seg, i) => {
|
|
|
@@ -95,6 +101,12 @@ export default {
|
|
|
autoScroll(val) { val ? this.startScroll() : this.stopScroll(); }
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 根据大屏宽度缩放字号/像素常量,避免大屏下文字过小
|
|
|
+ fs(px) {
|
|
|
+ const scaled = typeof px2echarts === 'function' ? px2echarts(px) : px;
|
|
|
+ return Math.max(px, scaled);
|
|
|
+ },
|
|
|
+
|
|
|
initChart() {
|
|
|
if (!this.$refs.chartRef) return;
|
|
|
this.$_chart = echarts.init(this.$refs.chartRef);
|
|
|
@@ -175,19 +187,31 @@ export default {
|
|
|
updateChart() {
|
|
|
if (!this.$_chart) return;
|
|
|
|
|
|
+ // x 轴刻度仅在红块首尾(每周期的 greenDuration 与 cycle 结束点)显示
|
|
|
+ const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
|
|
|
+ const redLen = this.cycle - this.greenDuration;
|
|
|
+ const tickInterval = redLen > 0 ? gcd(this.greenDuration, redLen) : this.greenDuration;
|
|
|
+
|
|
|
const option = {
|
|
|
backgroundColor: 'transparent',
|
|
|
animation: false,
|
|
|
tooltip: { show: false },
|
|
|
- grid: { left: 140, right: 40, top: 40, bottom: 50 },
|
|
|
+ grid: { left: this.fs(140), right: this.fs(40), top: this.fs(40), bottom: this.fs(50) },
|
|
|
xAxis: {
|
|
|
type: 'value', min: this.currentViewMinX, max: this.currentViewMinX + this.viewWindow,
|
|
|
- interval: 20, name: '时间 (秒)',
|
|
|
+ interval: tickInterval, name: '时间 (秒)',
|
|
|
nameLocation: 'end',
|
|
|
- nameTextStyle: { color: '#a0aabf', padding: [0, 0, 0, 0] },
|
|
|
+ nameTextStyle: { color: '#a0aabf', padding: [0, 0, 0, 0], fontSize: this.fs(12) },
|
|
|
axisLine: { show: true, onZero: false, lineStyle: { color: 'rgba(255,255,255,0.15)' } },
|
|
|
axisTick: { show: false },
|
|
|
- axisLabel: { color: '#a0aabf', fontSize: 10 },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#a0aabf',
|
|
|
+ fontSize: this.fs(10),
|
|
|
+ formatter: (value) => {
|
|
|
+ const mod = ((value % this.cycle) + this.cycle) % this.cycle;
|
|
|
+ return (mod === 0 || mod === this.greenDuration) ? value : '';
|
|
|
+ }
|
|
|
+ },
|
|
|
splitLine: { show: this.showYSplitLine, lineStyle: { type: 'dashed', color: 'rgba(255, 255, 255, 0.08)' } }
|
|
|
},
|
|
|
yAxis: {
|
|
|
@@ -241,7 +265,7 @@ export default {
|
|
|
const sPerpY = -sBDx / sBLen;
|
|
|
const sDot = (pT1[0] - pB1[0]) * sPerpX + (pT1[1] - pB1[1]) * sPerpY;
|
|
|
const sSign = sDot > 0 ? -1 : 1;
|
|
|
- const speedOff = 14;
|
|
|
+ const speedOff = this.fs(14);
|
|
|
const speedX = midBottomX + sSign * sPerpX * speedOff;
|
|
|
const speedY = midBottomY + sSign * sPerpY * speedOff;
|
|
|
|
|
|
@@ -251,7 +275,7 @@ export default {
|
|
|
{ type: 'polygon', shape: { points: mappedCoords }, style: { fill: item.color } },
|
|
|
...(() => {
|
|
|
// 虚线与绿波带之间留间隙,沿垂直于底线方向向外偏移
|
|
|
- const lineGap = 4;
|
|
|
+ const lineGap = this.fs(4);
|
|
|
const bDx = mappedBottom[1][0] - mappedBottom[0][0];
|
|
|
const bDy = mappedBottom[1][1] - mappedBottom[0][1];
|
|
|
const bLen = Math.sqrt(bDx * bDx + bDy * bDy) || 1;
|
|
|
@@ -268,7 +292,7 @@ export default {
|
|
|
{ type: 'polyline', shape: { points: offsetBottom }, style: { stroke: item.lineCol, lineDash: [4, 4], lineWidth: 1 } }
|
|
|
];
|
|
|
})(),
|
|
|
- { type: 'text', x: speedX, y: speedY, rotation: angle, style: { text: `${this.speedKmh}km/h`, fill: '#fff', fontSize: 11, textAlign: 'center' } },
|
|
|
+ { type: 'text', x: speedX, y: speedY, rotation: angle, style: { text: `${this.speedKmh}km/h`, fill: '#fff', fontSize: this.fs(11), textAlign: 'center' } },
|
|
|
...(() => {
|
|
|
const cxBw = (midBottomX + midTopX) / 2;
|
|
|
const cyBw = (midBottomY + midTopY) / 2;
|
|
|
@@ -277,10 +301,10 @@ export default {
|
|
|
const lenBw = Math.sqrt(dxBw * dxBw + dyBw * dyBw) || 1;
|
|
|
const uxBw = dxBw / lenBw;
|
|
|
const uyBw = dyBw / lenBw;
|
|
|
- const gapBw = 10;
|
|
|
+ const gapBw = this.fs(10);
|
|
|
return [
|
|
|
{ type: 'line', shape: { x1: midBottomX, y1: midBottomY, x2: cxBw - uxBw * gapBw, y2: cyBw - uyBw * gapBw }, style: { stroke: 'rgba(255, 255, 255, 0.4)' } },
|
|
|
- { type: 'text', x: cxBw, y: cyBw, rotation: angle, style: { text: `${this.bandwidth}s`, fill: '#fff', fontSize: 11, textAlign: 'center', textVerticalAlign: 'middle' } },
|
|
|
+ { type: 'text', x: cxBw, y: cyBw, rotation: angle, style: { text: `${this.bandwidth}s`, fill: '#fff', fontSize: this.fs(11), textAlign: 'center', textVerticalAlign: 'middle' } },
|
|
|
{ type: 'line', shape: { x1: cxBw + uxBw * gapBw, y1: cyBw + uyBw * gapBw, x2: midTopX, y2: midTopY }, style: { stroke: 'rgba(255, 255, 255, 0.4)' } }
|
|
|
];
|
|
|
})()
|
|
|
@@ -320,7 +344,9 @@ export default {
|
|
|
const intersection = this.intersections[params.dataIndex];
|
|
|
const point = api.coord([this.currentViewMinX, intersection.x]);
|
|
|
const centerYPx = point[1] + this.barWidth + this.gap / 2;
|
|
|
- const labelX = point[0] - 12;
|
|
|
+ const labelX = point[0] - this.fs(12);
|
|
|
+ const nameFs = this.fs(12);
|
|
|
+ const subFs = this.fs(11);
|
|
|
|
|
|
// 名称较长时按 "-" 拆成两行显示
|
|
|
const dashIdx = intersection.name.indexOf('-');
|
|
|
@@ -329,14 +355,14 @@ export default {
|
|
|
|
|
|
const children = [];
|
|
|
if (nameLine2) {
|
|
|
- children.push({ type: 'text', x: labelX, y: centerYPx - 15, style: { text: nameLine1, fill: '#fff', textAlign: 'right', fontSize: 12 } });
|
|
|
- children.push({ type: 'text', x: labelX, y: centerYPx - 1, style: { text: nameLine2, fill: '#fff', textAlign: 'right', fontSize: 12 } });
|
|
|
+ children.push({ type: 'text', x: labelX, y: centerYPx - this.fs(15), style: { text: nameLine1, fill: '#fff', textAlign: 'right', fontSize: nameFs } });
|
|
|
+ children.push({ type: 'text', x: labelX, y: centerYPx - this.fs(1), style: { text: nameLine2, fill: '#fff', textAlign: 'right', fontSize: nameFs } });
|
|
|
} else {
|
|
|
- children.push({ type: 'text', x: labelX, y: centerYPx - 7, style: { text: nameLine1, fill: '#fff', textAlign: 'right', fontSize: 12 } });
|
|
|
+ children.push({ type: 'text', x: labelX, y: centerYPx - this.fs(7), style: { text: nameLine1, fill: '#fff', textAlign: 'right', fontSize: nameFs } });
|
|
|
}
|
|
|
if (this.showPhaseOffset) {
|
|
|
- const offYPx = nameLine2 ? centerYPx + 14 : centerYPx + 5;
|
|
|
- children.push({ type: 'text', x: labelX, y: offYPx, style: { text: `相位差: ${intersection.offsetText}`, fill: '#a0aabf', textAlign: 'right', fontSize: 11 } });
|
|
|
+ const offYPx = nameLine2 ? centerYPx + this.fs(14) : centerYPx + this.fs(5);
|
|
|
+ children.push({ type: 'text', x: labelX, y: offYPx, style: { text: `相位差: ${intersection.offsetText}`, fill: '#a0aabf', textAlign: 'right', fontSize: subFs } });
|
|
|
}
|
|
|
|
|
|
if (intersection.distanceNext) {
|
|
|
@@ -345,9 +371,9 @@ export default {
|
|
|
const midYPx = (centerYPx + nextCenterYPx) / 2;
|
|
|
|
|
|
// 非反转 yAxis:距离越大像素 y 越小,nextCenterYPx < centerYPx
|
|
|
- const lineX = labelX - 85;
|
|
|
- children.push({ type: 'line', shape: { x1: lineX, y1: centerYPx - 36, x2: lineX, y2: nextCenterYPx + 22 }, style: { stroke: 'rgba(255,255,255,0.1)', lineDash: [2, 2] } });
|
|
|
- children.push({ type: 'text', x: lineX, y: midYPx, style: { text: `${intersection.distanceNext}m`, fill: '#a0aabf', textAlign: 'center', fontSize: 11 } });
|
|
|
+ const lineX = labelX - this.fs(10);
|
|
|
+ children.push({ type: 'line', shape: { x1: lineX, y1: centerYPx - this.fs(36), x2: lineX, y2: nextCenterYPx + this.fs(22) }, style: { stroke: 'rgba(255,255,255,0.1)', lineDash: [2, 2] } });
|
|
|
+ children.push({ type: 'text', x: lineX, y: midYPx, style: { text: `${intersection.distanceNext}m`, fill: '#a0aabf', textAlign: 'center', fontSize: subFs } });
|
|
|
}
|
|
|
return { type: 'group', children };
|
|
|
}
|
|
|
@@ -364,7 +390,7 @@ export default {
|
|
|
return {
|
|
|
type: 'line',
|
|
|
shape: { x1: top[0], y1: top[1], x2: bottom[0], y2: bottom[1] },
|
|
|
- style: { stroke: this.scanLineColor, lineWidth: 4 }
|
|
|
+ style: { stroke: this.scanLineColor, lineWidth: this.fs(4) }
|
|
|
};
|
|
|
},
|
|
|
z: 10
|