Files
Situation-Awareness-Platfor…/docs/ECharts多维度数据分析与展示实现详解.md
cfy666 c1e9a4be83 chore: sync local changes and add documentation
- Update yarn.lock
- Add project implementation docs in docs/
- Add personal internship experience notes in 实习讲解/
2026-06-29 19:47:30 +08:00

279 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ECharts 多维度数据分析与展示 — 面试版
> 简历原话:**"集成 ECharts 实现多维度数据分析和展示"**
>
> 这篇文档帮你理解这句话背后到底做了什么,以及面试时怎么讲。
---
## 一、先搞清楚:这句话到底是什么意思?
拆成三部分理解:
| 关键词 | 含义 | 项目中对应 |
|--------|------|------------|
| **集成 ECharts** | 把 ECharts 图表库引入项目,让它能画图 | 安装 echarts 6.x在 Vue3 组件中调用 `echarts.init()` 创建图表 |
| **多维度** | 不是只画一种图、看一组数据,而是从多个角度分析数据 | 3 大业务模块、10+ 种图表类型、覆盖时间/空间/语言/行业等多个角度 |
| **数据分析和展示** | 不是简单的数据罗列,而是通过图表帮助用户发现规律、做出判断 | 四象限风险定位、趋势预测、热力分布等,让数据"说话" |
**一句话概括**:我在平台的 3 个核心模块中,用 ECharts 画了 20 多个图表,从安全漏洞、开源生态、社区发展等多个角度把后端数据可视化出来。
---
## 二、画了哪些图?按模块讲
### 模块 1安全态势最核心面试重点
这个模块帮用户**看懂开源项目的安全风险**
```
安全态势 = 哪里有危险 × 什么漏洞 × 哪些组件有风险
```
| 看什么 | 用什么图 | 怎么理解 |
|--------|----------|----------|
| 全球哪里有攻击 | 世界地图 + 涟漪动画 | 地图上每个国家颜色深浅表示威胁程度,关键位置有闪烁的光点 |
| 中国各省安全情况 | 中国地图热力图 | 像天气预报的温度图,颜色越深=威胁越大 |
| CVE 漏洞数量变化 | 柱状图 + 折线图 | 柱子=每月漏洞数量,折线=增长还是下降,还能切换"全球/国内"视角 |
| 漏洞严重程度 | 堆叠柱状图 | 每根柱子分红(高危)黄(中危)绿(低危)三段,一眼看出哪个季度最严重 |
| 哪种编程语言漏洞多 | 四象限气泡图 | X轴=活跃度Y轴=漏洞密度,气泡大小=漏洞总数,颜色=风险等级 |
| 哪些开源组件最危险 | 水平柱状图 | Log4j2、Spring 等组件的危险程度排名 |
### 模块 2开源生态
帮用户了解**开源世界的整体发展状况**
| 看什么 | 用什么图 | 怎么理解 |
|--------|----------|----------|
| 各省有多少开源人才 | 中国地图散点 | 地图上标出各省人才密度,旁边显示 Top5 排名 |
| 开发者数量变化 | 面积折线图 | 像山丘一样的增长曲线,能看出增长趋势 |
| 基础设施覆盖情况 | 多层环形图 | 三层圆环,分别代表镜像站、代码托管、构建平台的覆盖率 |
| GitHub vs GitCode 对比 | 分组柱状图 | 6 个指标PR合并率、响应速度等两边对比 |
| 编程语言谁强谁弱 | 南丁格尔玫瑰图 | 扇形面积越大=市场份额越大 |
### 模块 3社区分析
帮用户了解**开源社区在各城市的发展**
| 看什么 | 用什么图 |
|--------|----------|
| 各城市项目/人才/社区数量 | 柱状图(多个) |
| 高校俱乐部增长趋势 | 折线图 |
| 各省政策发布数量 | 柱状图 |
| 鸿蒙生态分布 | 多图表组合 |
---
## 三、怎么实现的?(面试核心)
### 3.1 一个图表从无到有的完整流程
用最简单的语言描述:
```
第1步后端给数据API请求
第2步拿到数据存到 Vue 的 ref 里(响应式状态)
第3步等页面渲染好nextTick用 echarts.init() 创建图表
第4步把数据塞进 ECharts 的配置项setOption
第5步页面关闭时销毁图表dispose防止内存泄漏
```
用代码简单表示:
```typescript
// 1. 请求数据
const response = await cveDataGlobalPage1();
// 2. 存到 ref
cveData.value = response.data;
// 3. 等 DOM 好了再画图
nextTick(() => {
const chart = echarts.init(document.getElementById('chart'));
// 4. 配置图表
chart.setOption({
xAxis: { data: ['1月', '2月', '3月'...] },
series: [{ type: 'bar', data: cveData.value }]
});
});
// 5. 组件销毁时清理
onUnmounted(() => chart.dispose());
```
### 3.2 面试必讲的 5 个技术点
#### 技术点 1图表生命周期管理防内存泄漏
**问题**ECharts 每次 `init()` 都会创建一个实例,如果不销毁,页面会越来越卡。
**解决方案**:每次画新图之前,先把旧的 `dispose()` 掉。
```typescript
// 存储图表实例
const chartInstances = ref({});
// 画图前:先销毁旧的,再创建新的
const initChart = () => {
if (chartInstances.value.myChart) {
chartInstances.value.myChart.dispose(); // 销毁旧的
}
const chart = echarts.init(el); // 创建新的
chartInstances.value.myChart = chart;
};
// 组件卸载时也要销毁
onUnmounted(() => {
chartInstances.value.myChart?.dispose();
});
```
**面试话术**
> "我在每个图表组件中都用了 ref 存储 ECharts 实例,每次重绘前先 dispose 旧实例再 init 新实例,组件卸载时也会销毁,避免内存泄漏。"
---
#### 技术点 2地图三级容错加载
**问题**ECharts 画地图需要先注册 GeoJSON 数据。如果数据加载失败,地图就是白的。
**解决方案**:准备三套数据源,依次尝试:
```
本地文件(最快) → CDN远程加载备用 → 手写简化版(兜底)
```
**面试话术**
> "地图数据加载我做了三级容错:先加载本地预编译的地图文件,失败了从阿里 DataV CDN 拉取,再失败用手写的简化 GeoJSON 兜底,保证地图永远不会白屏。"
---
#### 技术点 3一个图表达 4 个维度(气泡散点图)
**问题**:普通的柱状图只能表达 2 个维度X 轴 + Y 轴),怎么在一个图里塞更多信息?
**解决方案**用气泡散点图4 种方式编码 4 个维度:
| 编码方式 | 代表的维度 | 例子 |
|----------|-----------|------|
| X 轴位置 | 代码活跃度 | JavaScript 在右边活跃Rust 在左边 |
| Y 轴位置 | 漏洞密度 | Java 在上面漏洞多Go 在下面 |
| 气泡大小 | 漏洞总数 | JavaScript 气泡最大 |
| 气泡颜色 | 风险等级 | 红色=高风险,蓝色=健康 |
**面试话术**
> "编程语言安全态势图我用了四象限气泡散点图X 轴是代码活跃度Y 轴是漏洞密度,气泡大小代表漏洞总数,颜色代表风险象限。一个图表同时展示了 4 个数据维度,用户可以直观看出哪些语言'又活跃又危险'。"
---
#### 技术点 4兜底数据策略
**问题**:如果后端挂了,页面上 20 多个图表全部空白,看起来像 bug。
**解决方案**:每个图表都准备一套硬编码的"假数据"API 失败时用假数据渲染:
```typescript
try {
const data = await api.getData();
chartData.value = data;
} catch (error) {
// API 失败,用默认数据
chartData.value = [
{ name: 'JavaScript', value: 95 },
{ name: 'Python', value: 90 },
// ... 预设的示例数据
];
}
```
**面试话术**
> "数据展示型产品最怕图表空白所以我给每个图表都加了兜底数据。API 正常就用真实数据,失败了用硬编码的示例数据渲染,保证页面始终有内容。"
---
#### 技术点 5响应式自适应
**问题**:浏览器窗口大小变了,图表不会自动调整。
**解决方案**:监听窗口变化,触发图表重绘:
```typescript
// 监听窗口 resize
window.addEventListener('resize', () => {
chart.resize(); // ECharts 自带的调整大小方法
});
// 更进一步:宽度类型变了(比如从桌面切到平板),重新画图
// 因为小屏可能需要调整字号、隐藏部分标签等
watch(widthType, () => {
initChart(); // 重新初始化,而不是简单的 resize
});
```
**面试话术**
> "我用了自定义的 usePageResize Hook 检测视口变化。简单变化用 ECharts 自带的 resize(),但宽度类型变化时(比如桌面切到移动端)会重新初始化图表,调整 grid、字号、标签等配置。"
---
## 四、整体架构一句话总结
```
后端 API → Axios 请求 → Vue ref 存数据 → ECharts 渲染图表
↓ (失败)
兜底默认数据 → 也能渲染
```
技术栈:**Vue3** 的 Composition API 管理状态和生命周期 + **ECharts 6.x** 负责所有图表渲染 + **自定义工具类**管理地图数据加载。
---
## 五、面试问答准备
### Q1"集成 ECharts 实现多维度数据分析和展示"具体做了什么?
> 我在态势感知平台的安全态势、开源生态、社区分析三大模块中,用 ECharts 实现了 20 多个图表组件。涵盖了 10 种以上的图表类型——柱状图、折线图、饼图、散点气泡图、世界地图、中国地图、堆叠图、环形图、玫瑰图等。从时间、空间、编程语言、行业、组件等多个维度对开源安全和生态数据进行可视化分析。
### Q2遇到的技术难点是什么
> 主要有三个:
> 1. **地图加载**ECharts 画地图需要 GeoJSON 数据加载可能失败。我做了三级容错本地→CDN→兜底保证地图不白屏。
> 2. **性能**20 多个图表如果同时初始化会卡。我用 nextTick 确保 DOM 就绪再画图,组件销毁时及时 dispose 释放内存。
> 3. **数据可靠性**:后端 API 可能失败。我给每个图表加了兜底默认数据,保证页面始终有内容。
### Q3多维度体现在哪里
> 以编程语言安全态势的气泡图为例,一个图表编码了 4 个维度X 轴是代码活跃度Y 轴是漏洞密度,气泡大小是漏洞总数,颜色代表风险等级。从整体项目来看,我们从时间维度(月度/季度趋势)、空间维度(世界地图/中国地图)、语言维度、行业维度、组件维度等多个角度分析数据。
### Q4ECharts 实例的生命周期怎么管理?
> 每个图表组件用 ref 存储 ECharts 实例引用。每次重绘前先 dispose 旧实例再 init 新实例,避免内存泄漏。组件 onUnmounted 时也会销毁。窗口 resize 时调用 ECharts 的 resize() 方法自适应。
### Q5为什么不直接用 vue-echarts 这种封装库?
> 项目中简单图表用了 vue-devui 的 DChart 组件。但复杂图表(比如地图、气泡散点图、混合图表)需要深度自定义配置,直接用 echarts.init() 更灵活,能精确控制每个细节。
---
## 六、关键数字(面试时用)
| 数据 | 数字 |
|------|------|
| 图表组件数量 | 20+ 个 |
| 图表类型 | 10+ 种 |
| 业务模块 | 3 个(安全/生态/社区) |
| 可视化数据维度 | 时间、空间、语言、行业、组件、人才等 6+ 个 |
| 地图容错级别 | 3 级本地→CDN→兜底 |
| ECharts 版本 | 6.x |
---
## 七、涉及的源码文件(需要看的时候查)
| 做什么 | 文件在哪 |
|--------|----------|
| 地图加载工具 | `src/utils/mapLoader.js` |
| API 接口定义 | `src/api/jyh/situation.ts` |
| 安全模块(最复杂) | `src/views/Jyh/security/` 目录下所有组件 |
| 生态模块 | `src/views/Jyh/ecosystem/` 目录下所有组件 |
| 社区模块 | `src/views/Jyh/Community/` 目录下所有组件 |