# 问题处理：检测项趋势图表部分项无法正常显示

## 文档信息

- 创建时间：2026-07-22
- 问题来源：用户反馈
- 关联模块：service_monitor/statistics

---

## 1. 问题描述

### 现象

检测项趋势分析功能中，选择部分检测项后，折线图无法正常显示：

- 折线图区域空白
- 仅右侧饼图显示状态分布
- 无错误提示，但用户认为"图表没出来"

### 影响范围

经全量测试 419 个检测项：

| 类型 | 数量 | 状态 |
|------|------|------|
| 有数值数据（可画折线图） | 264 | ✅ 正常 |
| 无数值数据（折线图空白） | 140 | ❌ 问题项 |
| 状态类（值="正常"/"异常"） | 70 | 属设计限制 |
| 表格/多行类 | 3 | 数据格式特殊 |
| 其他文本类 | 67 | 值为 yes/no/路径等 |

---

## 2. 根因分析

### 2.1 数据来源

检测项的值（`value_raw`）是字符串，来自巡检脚本的输出。`statistics_service.py` 使用 `_extract_numeric()` 函数尝试提取数值：

```python
value_num, unit = _extract_numeric(value_raw)
```

### 2.2 `_extract_numeric` 的处理逻辑

该函数能提取以下格式：
- 百分比：`"92%"` → `(92.0, "%")`
- 纯数字：`"3.69"` → `(3.69, "")`
- 带单位：`"10s"`, `"500MB"`, `"1.5G"`

**无法提取的格式**：
- 状态文本：`"正常"`, `"异常"`, `"运行中"`
- 是/否：`"yes"`, `"no"`
- 多行表格数据
- 路径、命令名等

### 2.3 前端行为

当前前端 `fetchItemTrend` 函数：
- 收到 `data_points` 后，仅使用 `value_num` 绘制折线图
- 如果所有 `value_num` 都是 `null`，折线图为空
- 饼图使用 `status` 字段，正常工作

---

## 3. 问题分类

### 3.1 状态类检测项（70 个）

典型代表：`CPU_STATUS`, `MEMORY_STATUS`, `DOCKER_STATUS` 等

**值示例**：`"正常"`, `"异常"`

**预期行为**：无法画折线图，但饼图可以显示状态分布。这是合理的设计限制。

### 3.2 表格/多行类（3 个）

- `IRQ_DETAIL`：中断详情表格
- `SOFTIRQS`：软中断统计表格
- `DISK_LATENCY`：磁盘延迟表格

**值示例**：多行文本，每行是一个表格行

**预期行为**：这种数据不适合时间序列折线图。

### 3.3 其他文本类（67 个）

典型代表：
- `SSH_PERMIT_ROOT`: `"yes"` / `"no"`
- `NTP_DAEMON`: `"chronyd"`
- `SYSTEM_TIMEZONE`: `"Asia/Shanghai"`
- `CPU_PER_CORE`: `"未安装mpstat"`
- `ABNORMAL_ACCOUNTS`: `"无"`

**问题**：这些项理论上可能有数值（如异常账户数），但当前输出格式是文本。

---

## 4. 解决方案

### 方案 A：前端优化（推荐）

**改动点**：前端 `fetchItemTrend` 函数，检测到无数值数据时，显示友好提示。

```javascript
// 检测是否有数值数据
if (numeric_count === 0 && non_numeric_count > 0) {
    // 显示提示信息
    chartTrendLine.setOption({
        title: {
            text: '该检测项为非数值类型，无法绘制趋势折线',
            subtext: '请查看右侧状态分布饼图',
            left: 'center', top: 'center',
            textStyle: { color: '#6b7280', fontSize: 14 }
        }
    });
    return;  // 不渲染折线
}
```

**优点**：
- 用户明确知道为何无折线图
- 不改后端逻辑，风险低
- 状态类项的饼图仍然可用

### 方案 B：过滤非数值项（可选）

**改动点**：`get_item_keys_for_target` 函数，在填充选择器时，标记哪些项有数值数据。

**缺点**：会隐藏大量检测项，用户无法查看其状态分布。

### 方案 C：后端增强数值提取（长期）

**改动点**：扩展 `_extract_numeric` 函数，支持更多格式：
- `"yes"` → `(1, "")`, `"no"` → `(0, "")`
- `"正常"` → `(1, "")`, `"异常"` → `(0, "")`
- `"无"` → `(0, "")`

**缺点**：可能引入误判，如把路径 `"yes/bin"` 误解析。

---

## 5. 推荐方案

采用 **方案 A**，在前端添加友好提示。

### 修改文件

`skill/code/web/templates/service_monitor/statistics.html`

### 修改内容

在 `fetchItemTrend` 函数中，数据加载后检查数值情况：

1. 如果所有 `value_num` 都是 `null`，显示提示信息
2. 提示内容："该检测项为状态类或文本类，无法绘制数值趋势图"
3. 饼图正常渲染状态分布

---

## 6. 验收标准

| 标准 | 验证方法 |
|------|---------|
| 选择 `CPU_USAGE` 等数值项 | 折线图正常显示 |
| 选择 `CPU_STATUS` 等状态项 | 显示友好提示，饼图正常 |
| 选择 `IRQ_DETAIL` 等表格项 | 显示友好提示 |
| 控制台无 JS 错误 | 检查浏览器控制台 |

---

## 7. 后续建议

1. **数据输出规范化**：巡检脚本输出时，状态类项可额外输出数值版本（如 `"正常"` + `"0"` 异常数）
2. **选择器分组**：检测项选择器可按"可趋势分析"/"状态类"分组
3. **数据格式优化**：表格类数据可解析为结构化格式单独展示