解决方案
简化图表逻辑,直接使用数据库中的时间戳作为横轴,不做任何时间对齐或映射处理:
```typescript
// 在 createChart 函数中
const createChart = (
canvas: HTMLCanvasElement,
label: string,
dataKey: keyof PerformanceDataPoint,
yAxisLabel: string,
range: { min: number; max: number },
formatValue?: (value: number) => string
): Chart<'line', number[], string> => {
// 直接使用数据库中的时间戳作为横轴,不做任何处理
// 按时间戳排序
const sortedData = [...performanceData.value].sort((a, b) => a.timestamp - b.timestamp);
// 生成时间标签(横轴)
const labels: string[] = sortedData.map((point) => {
const date = new Date(point.timestamp);
return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
});
// 直接使用数据值,不做任何映射或对齐
const data: number[] = sortedData.map((point) => {
let value = point[dataKey] as number;
// 对于码率稳定性,计算相对值(相对于平均值)
if (dataKey === 'bitrate') {
const avgBitrate = sortedData.reduce((sum, p) => sum + p.bitrate, 0) / sortedData.length;
const bitrateBaseline = avgBitrate > 0 ? avgBitrate : 1;
value = bitrateBaseline > 0 ? (value / bitrateBaseline) : 1;
}
return value;
});
// 创建标记线数据(合理范围)
const minLineData = new Array(sortedData.length).fill(range.min);
const maxLineData = new Array(sortedData.length).fill(range.max);
// 创建图表...
};
```
同样修改 `updateChartData` 函数:
```typescript
const updateChartData = (chart: Chart<'line', number[], string> | null, ...) => {
if (!chart) return;
// 直接使用数据库中的时间戳作为横轴,不做任何处理
const sortedData = [...performanceData.value].sort((a, b) => a.timestamp - b.timestamp);
// 生成时间标签和数据...
// 更新图表...
};
```
关键修改点:
1. **移除固定时间轴生成**:不再生成固定的时间点数组
2. **直接使用数据时间戳**:使用实际数据的时间戳作为横轴标签
3. **简化数据映射**:直接使用数据值,不做任何时间对齐或映射
4. **保持数据完整性**:显示所有数据点,按时间戳排序
背景信息
这是一个基于 Electron + Vue 3 + TypeScript 的推流监控应用。使用 Chart.js 绘制性能监控图表,显示 FPS、丢帧率、丢包率和码率稳定性等指标。
技术栈:
- **前端框架**:Vue 3 + TypeScript
- **图表库**:Chart.js
- **数据库**:SQLite (通过 sql.js)
- **数据格式**:时间序列数据,每个数据点包含时间戳和多个指标值
原始设计:
- 图表显示最近 5 分钟的数据
- 横轴固定为 300 个时间点(每秒一个点)
- 将实际数据映射到固定时间轴上
问题发现过程:
1. 数据查询成功,但图表不显示
2. 日志显示数据映射成功,但生成的图表数据都是 `null`
3. 检查时间戳发现数据时间戳与时间轴时间戳存在差异(如 588ms)
4. 尝试添加最近匹配逻辑,但问题仍然存在
5. 最终改为直接使用数据时间戳,问题解决
相关文件:
- `src/renderer/components/StreamPerformanceViewer.vue` - 图表组件
- `createChart()` 函数
- `updateChartData()` 函数