# 数学公式与可视化图表


KaTeX 公式、Mermaid 流程与时序图、ECharts 柱状图与折线图及环形图。

本篇属于 [Markdown 语法手册](/collections/markdown/)。按章内目录跳转，代码块提供可复制源码，其后的正文和组件展示实际效果。

<!--more-->

## 行内与块级公式

```latex
圆的面积为 $A = \pi r^2$。

$$
\sum_{k=1}^{n} k = \frac{n(n+1)}{2}
$$
```

圆的面积为 $A = \pi r^2$。

$$
\sum_{k=1}^{n} k = \frac{n(n+1)}{2}
$$

单个美元符号包裹行内公式，双美元符号包裹独立公式。本站继承主题的 Goldmark passthrough，并使用 v1 的 `math.enable` 和 `math.type: katex`，公式在构建时渲染。不要使用旧版 `params.page.math`。

```yaml
math:
  enable: true
  type: katex
```

上面是页面 front matter 的覆盖写法。本站还启用了 `params.math.katex.throw_on_error`，公式语法错误会使构建失败，方便发布前发现问题。

## 分式、根号与下标

```latex
$$
f(x) = \frac{x^2 + 1}{\sqrt{x + 2}}, \qquad x > -2
$$

平均值为 $\bar{x} = \frac{1}{n}\sum_{i=1}^{n}x_i$。
```

$$
f(x) = \frac{x^2 + 1}{\sqrt{x + 2}}, \qquad x > -2
$$

平均值为 $\bar{x} = \frac{1}{n}\sum_{i=1}^{n}x_i$。

`\frac` 接收分子和分母，`\sqrt` 表示平方根，`_` 和 `^` 分别表示下标和上标。超过一个字符的内容要用花括号分组，例如 `x_{i+1}`，否则通常只有紧接着的一个字符属于下标。

## 多行推导与对齐

```latex
$$
\begin{aligned}
(a+b)^2 &= (a+b)(a+b) \\
        &= a^2 + 2ab + b^2
\end{aligned}
$$
```

$$
\begin{aligned}
(a+b)^2 &= (a+b)(a+b) \\
        &= a^2 + 2ab + b^2
\end{aligned}
$$

`aligned` 环境用于对齐推导，`&` 指定对齐位置，两个反斜杠表示换行。正文直接写 LaTeX 时不需要像 JSON 字符串一样把所有反斜杠再次转义。

## 分段函数与矩阵

```latex
$$
|x| = \begin{cases}
x, & x \ge 0 \\
-x, & x < 0
\end{cases}
\qquad
A = \begin{bmatrix}1 & 2 \\ 3 & 4\end{bmatrix}
$$
```

$$
|x| = \begin{cases}
x, & x \ge 0 \\
-x, & x < 0
\end{cases}
\qquad
A = \begin{bmatrix}1 & 2 \\ 3 & 4\end{bmatrix}
$$

`cases` 提供左大括号，`bmatrix` 提供方括号。矩阵中的 `&` 分隔列，两个反斜杠分隔行。手机上特别长的公式应拆分，避免为了保持一行而把文字缩到难以阅读。

## 公式排查清单

| 现象 | 优先检查 |
| --- | --- |
| 公式原样显示 | `math.enable` 和 passthrough 配置 |
| 下标只包含一个字符 | 是否使用花括号分组 |
| 构建报告 KaTeX 错误 | 命令拼写、括号闭合、环境名称 |
| 公式太宽 | 改用多行推导或拆成多个块 |
| 普通金额被识别为数学内容 | 对字面美元符号使用反斜杠转义 |

不要把完整 LaTeX 文档的 `documentclass` 等命令复制到公式块。网页公式渲染支持的是数学表达式，不能把它当成完整的 TeX 排版系统。

## Mermaid 流程图

```text
{{</* mermaid */>}}
flowchart LR
  A[写 Markdown] --> B[本地预览]
  B --> C{检查通过?}
  C -->|是| D[生产构建]
  C -->|否| A
{{</* /mermaid */>}}
```

{{< mermaid >}}
flowchart LR
  A[写 Markdown] --> B[本地预览]
  B --> C{检查通过?}
  C -->|是| D[生产构建]
  C -->|否| A
{{< /mermaid >}}

`flowchart LR` 表示从左到右，改为 `TD` 则从上到下。节点 ID 用简短英文，方括号内显示中文。短代码可设置 `wrapper=false` 关闭图表工具栏；默认继承站点配置。

也可使用 Mermaid 代码块：

````markdown
```mermaid
sequenceDiagram
  participant A as 作者
  participant H as Hugo
  A->>H: 保存文章
  H-->>A: 更新预览
```
````

```mermaid
sequenceDiagram
  participant A as 作者
  participant H as Hugo
  A->>H: 保存文章
  H-->>A: 更新预览
```

Mermaid 在浏览器中运行，首次打开需要访问配置中的 jsDelivr 模块。没有网络时，仍可阅读相邻的图表源码和文字说明。

## 时序图中的成功与失败分支

````markdown
```mermaid
sequenceDiagram
  participant W as 作者
  participant H as Hugo
  W->>H: 提交待构建的 Markdown
  alt 语法检查通过
    H-->>W: 生成静态页面
  else 存在错误
    H-->>W: 返回文件位置和错误说明
  end
```
````

```mermaid
sequenceDiagram
  participant W as 作者
  participant H as Hugo
  W->>H: 提交待构建的 Markdown
  alt 语法检查通过
    H-->>W: 生成静态页面
  else 存在错误
    H-->>W: 返回文件位置和错误说明
  end
```

`participant` 定义参与者，英文 ID 用来连接，`as` 后显示中文名称。`alt`、`else`、`end` 描述互斥分支。实线和虚线箭头可以区分请求与响应，但这种约定应在图附近说明。

## 流程图分组

````markdown
```mermaid
flowchart TD
  subgraph Draft[写作阶段]
    A[记录想法] --> B[整理结构]
    B --> C[补齐示例]
  end
  subgraph Review[检查阶段]
    D[本地预览] --> E[检查链接]
    E --> F[生产构建]
  end
  C --> D
```
````

```mermaid
flowchart TD
  subgraph Draft[写作阶段]
    A[记录想法] --> B[整理结构]
    B --> C[补齐示例]
  end
  subgraph Review[检查阶段]
    D[本地预览] --> E[检查链接]
    E --> F[生产构建]
  end
  C --> D
```

`subgraph` 把相关步骤归成一组。纵向 `TD` 通常更适合手机，横向 `LR` 适合节点较少的流程。长说明放在正文，节点里只保留简短动作。

## 图表写作建议

- 一张图回答一个问题，避免把所有细节塞进同一张图。
- 节点 ID 使用稳定英文，显示文字可以改为中文。
- 图后补一两句话解释结论，便于读屏和无网络时阅读。
- 不依赖颜色作为唯一标识，同时写出节点名称和分支文字。
- 本主题会在图进入视口后延迟绘制，刚打开页面时未绘制的图不一定代表错误。

## ECharts 柱状图

```text
{{</* echarts width="100%" height="360px" */>}}
{
  "tooltip": {"trigger": "axis"},
  "legend": {"data": ["示例数"], "top": 12},
  "grid": {"left": 45, "right": 20, "bottom": 45},
  "xAxis": {"type": "category", "data": ["基础", "扩展", "短代码", "图片", "图表"]},
  "yAxis": {"type": "value", "minInterval": 1},
  "series": [{"name": "示例数", "type": "bar", "data": [6, 6, 4, 5, 4]}]
}
{{</* /echarts */>}}
```

{{< echarts width="100%" height="360px" >}}
{
  "tooltip": {"trigger": "axis"},
  "legend": {"data": ["示例数"], "top": 12},
  "grid": {"left": 45, "right": 20, "bottom": 45},
  "xAxis": {"type": "category", "data": ["基础", "扩展", "短代码", "图片", "图表"]},
  "yAxis": {"type": "value", "minInterval": 1},
  "series": [{"name": "示例数", "type": "bar", "data": [6, 6, 4, 5, 4]}]
}
{{< /echarts >}}

数据仅用于演示。`width="100%"` 适配容器，`height` 必须提供适合阅读的高度。默认内容为严格 JSON：键名和字符串使用双引号，不能加注释和尾随逗号。

`xAxis` 定义横轴，`yAxis` 定义纵轴，`series` 定义数据系列。将 `type` 从 `bar` 改成 `line` 可得到折线图。主题会根据深浅色模式初始化配色，并在尺寸变化时调整图表。

## 折线图：观察变化

```text
{{</* echarts width="100%" height="340px" */>}}
{
  "tooltip": {"trigger": "axis"},
  "grid": {"left": 45, "right": 20, "top": 30, "bottom": 45},
  "xAxis": {"type": "category", "boundaryGap": false, "data": ["周一", "周二", "周三", "周四", "周五"]},
  "yAxis": {"type": "value", "name": "字数"},
  "series": [{"name": "写作字数", "type": "line", "data": [300, 600, 450, 900, 750], "smooth": false}]
}
{{</* /echarts */>}}
```

{{< echarts width="100%" height="340px" >}}
{
  "tooltip": {"trigger": "axis"},
  "grid": {"left": 45, "right": 20, "top": 30, "bottom": 45},
  "xAxis": {"type": "category", "boundaryGap": false, "data": ["周一", "周二", "周三", "周四", "周五"]},
  "yAxis": {"type": "value", "name": "字数"},
  "series": [{"name": "写作字数", "type": "line", "data": [300, 600, 450, 900, 750], "smooth": false}]
}
{{< /echarts >}}

这组数据只是示例。`boundaryGap=false` 让折线两端贴近坐标区边界，`smooth=false` 用直线连接观测点，避免平滑曲线让读者误以为中间过程也经过测量。为纵轴标明单位，比只显示一列数字更清楚。

## 环形图：展示组成

```text
{{</* echarts width="100%" height="360px" */>}}
{
  "tooltip": {"trigger": "item"},
  "legend": {"bottom": 8},
  "series": [{
    "name": "时间分配",
    "type": "pie",
    "radius": ["38%", "64%"],
    "center": ["50%", "43%"],
    "label": {"show": false},
    "data": [
      {"name": "写作", "value": 50},
      {"name": "校对", "value": 30},
      {"name": "整理", "value": 20}
    ]
  }]
}
{{</* /echarts */>}}
```

{{< echarts width="100%" height="360px" >}}
{
  "tooltip": {"trigger": "item"},
  "legend": {"bottom": 8},
  "series": [{
    "name": "时间分配",
    "type": "pie",
    "radius": ["38%", "64%"],
    "center": ["50%", "43%"],
    "label": {"show": false},
    "data": [
      {"name": "写作", "value": 50},
      {"name": "校对", "value": 30},
      {"name": "整理", "value": 20}
    ]
  }]
}
{{< /echarts >}}

`radius` 的两个值分别是内、外半径；内半径大于零时形成环形图。示例隐藏外侧标签以适配小屏，通过图例和提示框读取类别。为了让不操作图表的读者也能获得数据，正文再给出一份表格：

| 活动 | 示例占比 |
| --- | ---: |
| 写作 | 50% |
| 校对 | 30% |
| 整理 | 20% |

## 参数与排查

| 参数或现象 | 说明 |
| --- | --- |
| `tooltip.trigger` | `axis` 适合坐标轴图；`item` 适合扇区等独立图形 |
| `grid` | 控制坐标区域的留白，避免刻度被裁剪 |
| `legend` | 展示系列或类别名称，可用于切换显示 |
| 图表空白 | 检查浏览器脚本是否加载，以及 JSON 是否有效 |
| 图表高度为零 | 给短代码设置明确的 `height` |
| 标签挤在一起 | 缩短标签、减少刻度或调整布局 |

这三个示例都使用主题本地 ECharts 资源，不需要额外启用旧版 `params.page` 配置。图表内部颜色承担数据区分作用，与站点正文颜色不必完全相同；仍应检查深浅模式下的对比度。

## Markmap：用 Markdown 写思维导图

Markmap 适合把标题和列表转换成可展开的知识结构。本站已安装官方 `cmpt-markmap` 组件，普通文章使用 `markmap` 代码围栏即可，不需要更改文章布局。

可复制源码：

````markdown
```markmap {height="360px"}
# Markdown 写作
## 组织内容
- 标题与段落
- 列表与引用
## 丰富表达
- 图片与链接
- 代码与公式
## 发布检查
- 本地预览
- 链接与移动端
```
````

实际效果：

```markmap {height="360px"}
# Markdown 写作
## 组织内容
- 标题与段落
- 列表与引用
## 丰富表达
- 图片与链接
- 代码与公式
## 发布检查
- 本地预览
- 链接与移动端
```

标题构成主分支，列表构成子节点；点击节点圆点可以折叠或展开，工具栏支持缩放、适配视口与全屏。上图把写作分成组织内容、丰富表达、发布检查三部分。

| 配置 | 说明 |
| --- | --- |
| 围栏语言 `markmap` | 将代码块渲染成思维导图 |
| `height="360px"` | 图表区域高度，省略时为 `24rem` |
| 页面 `layout: markmap` | 可选的全文分栏导图布局；普通文章无需设置 |
| `params.markmap` 或页面 `markmap` | 配置键使用 `snake_case`，如 `color_freeze_level` |
| 围栏内 YAML 的 `markmap` | 使用 Markmap 原生 `camelCase`，如 `colorFreezeLevel` |

组件根据内容渲染标记加载资源；首页处理含导图文章的摘要时也可能加载 Markmap 资源。导图运行时会从 CDN 获取依赖，需要网络；因此保留上方源码和文字说明，便于复制与阅读。


---

> 作者: [yuehei](/authors/yuehei/)  
> URL: https://33.ax/wiki/math-and-diagrams/  

