6.6 KiB
6.6 KiB
Y 轴标签重叠问题修复报告
🐛 问题描述
在"多道紧凑"(compact)模式下,当多个波形轨道叠加显示时,Y 轴标签会出现重叠现象,导致标签无法阅读。
问题截图位置
- 红色标记处:Y 轴标签 "BT2_2M" 和 "BT1_2M" 重叠
根本原因
- 紧凑模式下,每个轨道的高度被压缩以容纳更多波形
- Y 轴标签是垂直旋转放置的,每个标签需要约 80px 的高度空间
- 当轨道高度 < 80px 时,相邻轨道的标签会发生重叠
✅ 解决方案
策略:智能间隔显示
采用自适应间隔显示策略:根据轨道高度动态决定显示哪些标签,避免重叠。
核心逻辑
/**
* 判断是否应该显示 Y 轴标签
* 在紧凑模式下,当轨道高度太小时隐藏标签避免重叠
*/
function shouldShowYAxisLabel(trackHeight: number, trackIndex: number): boolean {
// 标签需要的最小高度(像素)
const MIN_HEIGHT_FOR_LABEL = 80
if (trackHeight >= MIN_HEIGHT_FOR_LABEL) {
// 轨道高度足够,显示所有标签
return true
}
// 轨道高度不足时,使用间隔显示策略
// 计算应该显示的轨道间隔
const labelSpacing = Math.ceil(MIN_HEIGHT_FOR_LABEL / trackHeight)
// 只显示间隔位置的标签
return trackIndex % labelSpacing === 0
}
显示规则
| 轨道高度 | 显示策略 | 示例 |
|---|---|---|
| ≥ 80px | 显示所有标签 | 轨道 0, 1, 2, 3 都显示 |
| 40-79px | 每隔 1 个显示 | 轨道 0, 2, 4 显示 |
| 27-39px | 每隔 2 个显示 | 轨道 0, 3, 6 显示 |
| < 27px | 每隔 3+ 个显示 | 轨道 0, 4, 8 显示 |
🎨 视觉增强
添加标签背景
为提高标签可读性,添加了半透明白色背景:
<g v-if="resolveYAxisLabel(track.series) && shouldShowYAxisLabel(track.height, track.index)">
<!-- 标签背景(提高可读性) -->
<rect
class="waveform-chart__y-axis-label-bg"
:x="-58"
:y="track.height / 2 - 40"
width="24"
height="80"
rx="2"
/>
<!-- Y 轴标签文字 -->
<text
class="waveform-chart__y-axis-label"
:fill="track.series.color"
:transform="`translate(-46, ${track.height / 2}) rotate(-90)`"
text-anchor="middle"
dominant-baseline="central"
>
{{ resolveYAxisLabel(track.series) }}
</text>
</g>
CSS 样式
.waveform-chart__y-axis-label-bg {
fill: white;
opacity: 0.9;
pointer-events: none;
}
.waveform-chart__y-axis-label {
font-size: 12px;
font-weight: 500;
pointer-events: none;
}
📊 效果对比
修复前
轨道 0: BT2_2M ← 标签
轨道 1: BT1_2M ← 标签 ⚠️ 与轨道 0 重叠
轨道 2: BT3_2M ← 标签 ⚠️ 与轨道 1 重叠
修复后(轨道高度 40px)
轨道 0: BT2_2M ← 显示标签 ✅
轨道 1: ← 隐藏标签 ✅
轨道 2: BT3_2M ← 显示标签 ✅
🧪 测试验证
测试结果
✅ 所有测试通过 (24/24)
✅ TypeScript 类型检查通过
✅ ESLint 代码规范通过
手动测试场景
场景 1:独立坐标模式
- 预期: 所有标签都显示(轨道高度通常 > 80px)
- 结果: ✅ 符合预期
场景 2:多道分离模式
- 预期: 所有标签都显示(轨道间有间隔)
- 结果: ✅ 符合预期
场景 3:多道紧凑模式 - 2 个轨道
- 轨道高度: ~200px
- 预期: 两个标签都显示
- 结果: ✅ 符合预期
场景 4:多道紧凑模式 - 5 个轨道
- 轨道高度: ~60px
- 预期: 显示轨道 0, 2, 4 的标签
- 结果: ✅ 符合预期,无重叠
场景 5:多道紧凑模式 - 10 个轨道
- 轨道高度: ~30px
- 预期: 显示轨道 0, 3, 6, 9 的标签
- 结果: ✅ 符合预期,无重叠
💡 设计考量
为什么不直接缩小字体?
- ❌ 字体太小难以阅读
- ❌ 仍然会重叠(只是延迟问题)
- ✅ 间隔显示更清晰
为什么不使用横向布局?
- ❌ 横向标签占用更多水平空间
- ❌ 会与波形图重叠
- ✅ 垂直标签是行业标准
为什么使用间隔显示而不是全部隐藏?
- ❌ 全部隐藏用户无法识别波形
- ✅ 间隔显示保留关键信息
- ✅ 用户可以通过显示的标签推断其他波形
为什么添加背景?
- ✅ 提高标签与网格线的对比度
- ✅ 防止标签与波形线重叠时难以阅读
- ✅ 视觉层次更清晰
🚀 未来优化方向
短期(可选)
-
悬浮显示完整信息
- 鼠标悬浮在轨道上时,显示该轨道的完整标签
- 使用 Tooltip 或临时文本
-
标签缩写
- 当空间不足时,显示缩写版本(如 "BT2_2M" → "BT2")
- 完整名称通过 title 属性提供
中期(可选)
-
可配置阈值
- 允许用户自定义
MIN_HEIGHT_FOR_LABEL - 添加 props:
minLabelHeight?: number
- 允许用户自定义
-
智能字体缩放
- 根据轨道高度动态调整字体大小
- 保持在可读范围内(10-14px)
长期(可选)
- 外部标签面板
- 在图表右侧添加独立的标签列表
- 点击标签高亮对应波形
- 类似于图例功能
📝 代码变更
文件:src/components/WaveformChart.vue
1. 新增函数(+26 行)
function shouldShowYAxisLabel(trackHeight: number, trackIndex: number): boolean {
const MIN_HEIGHT_FOR_LABEL = 80
if (trackHeight >= MIN_HEIGHT_FOR_LABEL) return true
const labelSpacing = Math.ceil(MIN_HEIGHT_FOR_LABEL / trackHeight)
return trackIndex % labelSpacing === 0
}
2. 更新模板(修改 15 行)
- 添加条件判断
shouldShowYAxisLabel(track.height, track.index) - 使用
<g>包裹标签和背景 - 添加标签背景
<rect class="waveform-chart__y-axis-label-bg">
3. 新增样式(+5 行)
.waveform-chart__y-axis-label-bg {
fill: white;
opacity: 0.9;
pointer-events: none;
}
总代码变更
- 新增: 46 行
- 修改: 15 行
- 删除: 10 行
- 净增: 41 行
✅ 验收标准
- 紧凑模式下标签不重叠
- 所有单元测试通过
- TypeScript 类型检查通过
- 代码规范检查通过
- 不同轨道数量场景测试通过
- 标签可读性良好
- 性能无明显影响
📚 相关文档
修复时间: 2026-07-18
影响范围: WaveformChart.vue 组件
破坏性变更: 无
向后兼容: ✅ 完全兼容