chartjs-node-canvas服务端生成Chart.js图表时标签显示为方框如何解决
问题原因
使用chartjs-node-canvas服务端渲染图表时文字全部显示为方框,核心原因是字体缺失/加载异常,具体场景包括:
chartjs-node-canvas底层依赖node-canvas实现画布渲染,本身不会捆绑操作系统级别的字体文件,所有文字渲染所需的字体都需要从运行环境的系统字体目录读取。- 绝大多数Linux服务端系统、Docker基础镜像默认仅预装极少量基础英文字体,不会携带中文字体、甚至缺少常规西文无衬线字体。当Chart.js配置的默认字体(如Arial、微软雅黑、默认sans-serif fallback链)在系统中找不到匹配字体文件时,canvas无法解析文字字形,就会渲染为方框。
- 若代码中使用了自定义第三方字体,但没有提前向
node-canvas注册字体就触发渲染,也会因为字体未加载完成出现方框问题。
修复方案
按照以下步骤操作即可解决:
- 给服务端运行环境安装必需的基础字体
- Debian/Ubuntu 系列系统执行以下命令安装开源中文字体与字体管理工具:
apt update && apt install -y fonts-wqy-zenhei fonts-wqy-microhei fonts-noto-cjk fontconfig fc-cache -fv - CentOS/RHEL/Rocky Linux 系列系统执行:
yum install -y wqy-zenhei-fonts wqy-microhei-fonts noto-cjk-fonts fontconfig fc-cache -fv
fc-list :lang=zh命令,确认中文字体已经被系统正常识别。 - Debian/Ubuntu 系列系统执行以下命令安装开源中文字体与字体管理工具:
- 显式指定Chart.js全局字体配置,不要依赖系统默认字体 fallback 逻辑,示例代码:
const { ChartJSNodeCanvas } = require('chartjs-node-canvas'); const chartCallback = (ChartJS) => { // 明确指定前面安装的系统字体作为渲染字体 ChartJS.defaults.font.family = '"WenQuanYi Micro Hei", "Noto Sans CJK SC", sans-serif'; ChartJS.defaults.font.size = 12; }; const canvas = new ChartJSNodeCanvas({ width: 800, height: 600, chartCallback }); - 如果需要使用自定义第三方字体,必须提前通过
node-canvas的registerFont方法注册字体,再执行渲染逻辑,示例:const { ChartJSNodeCanvas } = require('chartjs-node-canvas'); const { registerFont } = require('canvas'); // 提前加载注册本地字体文件 registerFont('./fonts/your-custom-font.ttf', { family: 'CustomChartFont' }); const canvas = new ChartJSNodeCanvas({ width: 800, height: 600, chartCallback: (ChartJS) => { ChartJS.defaults.font.family = 'CustomChartFont'; } });
如果是Docker容器部署,必须把字体安装命令写到Dockerfile构建步骤中,不能依赖基础镜像自带字体,否则容器重建后问题会复现。
内容的提问来源于stack exchange,提问作者Neeta Asodekar
相关产品推荐
相关产品推荐

