4. MultiQC 报告结构解析:HTML 报告的文件组织、模块、样品、表格、图表等元素
打开一份 MultiQC 生成的 HTML 报告,你看到的绝不只是静态页面。它背后有一套清晰的文件组织,以及模块、样品、表格、图表的协作逻辑。今天,我们就一层层剖开它。
4.1 文件组织:报告输出目录里有什么
运行 multiqc . 后,默认生成 multiqc_report 文件夹。我个人习惯用 --outdir 指定路径,避免污染工作区。
multiqc_report/
├── index.html # 主报告页面
├── multiqc_data/ # 原始数据(JSON / TSV)
│ ├── multiqc_general_stats.json
│ ├── multiqc_fastqc.txt
│ └── ...
└── multiqc_plots/ # 嵌入式图表(PNG / SVG / Plotly JSON)
├── fastqc_per_base_sequence_quality.png
└── ...
你想想看,multiqc_data/ 里的 JSON 其实就是报告的数据源,后续自定义模板时,我们就是从这里拉取数据。我曾接手一个项目,同事直接把 multiqc_general_stats.json 当 API 用,写了个内部监控看板——嗯,这思路挺野,但也说明它的结构化程度很高。
--data-only,只输出 multiqc_data/ 目录。
4.2 模块:报告的心脏
MultiQC 的每个“模块”对应一种质控工具的输出解析器。比如 FastQC、Cutadapt、STAR、Qualimap 等。报告左侧的导航栏就是模块列表,点击可跳转。
模块在报告里表现为一个 section,内部包含:
- 样品选择器(可勾选过滤样品)
- General Statistics 表格(每个样品一行)
- 专有图表(如 FastQC 的碱基质量箱线图、Cutadapt 的剪接长度分布)
- 详细数据表格(可排序、搜索)
我记得有一次,用户报告说某个模块的图表显示不全。查了半天,原来是自定义模板里漏写了对应模块的 module_js() 调用。所以,搞清楚每个模块的固定内容结构很重要。
4.3 样品:行的逻辑
在 MultiQC 的语境下,“样品”就是你在命令行传入的各个质控报告的原始样本名。报告中几乎所有表格都是以样品为行。举个例子,General Statistics 表:
| Sample | % Dups | % GC | Length | M Seqs |
|---|---|---|---|---|
| sample_1 | 24.5 | 48.2 | 147 | 18.3 |
| sample_2 | 31.7 | 51.0 | 150 | 22.1 |
| sample_3 | 19.8 | 49.6 | 145 | 16.7 |
表格的排序、搜索、导出都是 JavaScript 控制的。自定义模板时,你可能会想调整列的显示顺序,或者增加自定义指标列。说白了,就是操作 table_config 对象。
4.4 表格:不只是普通 HTML 表格
MultiQC 里的表格用 datatable 库增强,支持:
- 列排序(单击表头)
- 列搜索(输入关键词)
- 行选择(勾选样品,联动图表)
- 导出为 CSV
报告的表格结构其实藏在 multiqc_data/ 的 JSON 里。举个例子,General Statistics 的数据结构长这样:
{
"sample_1": {
"fastqc": {
"percent_duplicates": 24.5,
"percent_gc": 48.2,
"avg_sequence_length": 147,
"total_sequences": 18300000
},
"cutadapt": { ... }
}
}
模板引擎拿到这个 JSON,用 Jinja2 循环渲染成 <table>。我曾踩过坑:在自定义模板里想给某列加条件格式,但忘了引入 datatables 的初始化脚本,结果用户只能在浏览器看到纯 HTML 表格——没有排序功能,体验差很多。所以,记得在你的自定义模板里包含 multiqc_js() 和 multiqc_css()。
4.5 图表:静态与动态的权衡
MultiQC 支持三种图表渲染方式:
- Flat(静态 PNG):加载快,但无法交互。适合批量打印。
- Plotly(交互式 HTML):缩放、悬停提示、导出数据。报告中默认使用。
- SVG(静态矢量):保真度高,可直接在 Illustrator 中编辑。
如果报告里的图表数量多,文件体积会很大。我建议:
- 对外交付的报告用
--flat参数生成静态 PNG,体积小,兼容老浏览器。 - 内部探索分析时保留 Plotly 交互图,方便数据深挖。
图表的数据通常作为 JSON 嵌入在 <script> 标签中。比如一个 Plotly 图表的数据:
<div id="fastqc-per-base-plot"></div>
<script>
var data = [{"x": [1,2,3,...], "y": [40,38,39,...], "type": "box"}];
var layout = {"title": "Per Base Sequence Quality"};
Plotly.newPlot('fastqc-per-base-plot', data, layout);
</script>
自定义模板时,你可以选择只渲染表格而不显示图表,或者替换成你自己用 D3.js 画的图。这需要修改模块的 generator 逻辑,不过那是后面章节的事了。
4.6 交互与联动:样品勾选如何影响全局
报告里有一个全局的“样品选择器”。当你勾选或取消某个样品时,所有模块的表格行和图表数据都会同步过滤。这个机制是靠发布-订阅模式实现的。核心 JS 对象是 multiqc_samples,它管理所有样品的选中状态。
我曾经在自定义模板里想添加一个“全选/反选”按钮,结果发现 multiqc_samples.toggle_all() 方法早就内置了。很多时候,你需要的功能 MultiQC 已经提供了,只是文档里没写全。建议大家多翻翻 multiqc/multiqc.js 的源码。
multiqc.js 或 multiqc.css,必须确保新文件仍然包含样品的联动逻辑。否则报告会失去交互能力。
4.7 从报告结构到自定义模板入口
理解报告的结构,就等于拿到了自定义模板的“地图”。你需要修改的文件主要有:
report_content.html— 整个报告的外壳general_stats.html— General Statistics 表格plotly_box.html— Plotly 图表容器datatable_table.html— 其他数据表格nav.html— 左侧导航栏
这些模板默认存放在 multiqtemplates/default/ 路径下。你可以复制到自定义目录,然后修改。嗯,从下一节开始,我们就要动手改真正的模板了,不过先别急,先把今天的结构图刻在脑子里。