blog
blog copied to clipboard
将 echarts 跑在 Node.js 服务器上
最近有个需求,想把 echarts 跑在服务端生成图表图片。echarts 支持一个没有公开的方法,可以把 node-canvas 作为浏览器端 Canvas
对象的替代:
// 这里用的是 [email protected],不是 [email protected]
const Canvas = require('canvas')
const echarts = require('echarts')
echarts.setCanvasCreator(() => new Canvas(32, 32))
至此,echarts 的相关配置就完成了,但是接下来就会遇到 node-canvas 相关的各种问题。
一、中文不显示
在 macOS 中开发时是能正常显示中文的,但放到服务器上(我用的是 CentOS 7)就会发现中文不渲染了。在网上搜索了一番,得知是因为服务器上没有中文字体导致的。
让 node-canvas 显示中文有两种方式:
- 使用 node-canvas@2 的
.registerFont()
方法注册中文字体 - 在服务器上安装中文字体
第一种方式要使用目前还处于 alpha 阶段的新版 node-canvas,但为了保险起见,我想用更稳定的 node-canvas@1 版本,所以我放弃了这个方案。
第二个方式也不难,网上有详细的教程教你如何在服务器上安装中文字体,但我觉得能直接用 yum
安装中文字体是最方便的,在网上搜了一大圈后,发现大部分的中文字体包在 CentOS 7 中已经没有了,不过经过不懈的搜索,最终还是找到了在 CentOS 7 中的字体包名称:
yum -y groupinstall Fonts
第二种方式也有它的弊端,那就是 node-canvas 使用的其实是系统字体,这样的话,在不同的系统中渲染出来的图的字体就不一样,例如在 macOS 中用的是苹方,在 CentOS 7 中用的是文泉驿简体(似乎是叫这个名字)。后面我打算在 node-canvas@2 发布稳定版之后用第一种方式注册字体,不过如果你想在 node-canvas@1 中自定义字体也是可以做到的,这里推荐一篇文章:Fonts in node-canvas。
二、文字向上偏移
echarts 默认生成的图片在 macOS 这种高清屏里看的时候会显得很模糊,解决办法就是生成图片时指定 devicePixelRatio
为 2:
const Canvas = require('canvas')
const echarts = require('echarts')
echarts.setCanvasCreator(() => new Canvas(32, 32))
const chart = echarts.init(new Canvas(100, 100), null, {
devicePixelRatio: 2 // <- 这里
})
这样生成出来的图片大小其实是两倍于指定的宽高的,然后在使用时将宽高缩回来,在高清屏里就不会模糊了。但我在实际生成图片之后,发现这种情况下文字都往上偏了。
而且在 macOS 里,汉字的位置是对的,数字和英文是偏的;在 CentOS 7 里,所有文字都会往上偏。也因此,我一开始以为是字体的问题,但在将电脑里的苹方简体放到 CentOS 7 里后,生成的图片所有文字仍然是偏的。
之后在尝试各种方式不成功后,我给 echarts 提了一个 bug,但果然是不会有人理我的 😂
所以,我暂时通过给每个文本设定 padding
或 offset
这种方式将字体位置再调整回来,但这样做非常繁琐,也不具有通用性。后来我看到有一个非官方的项目 node-gfx/node-canvas-prebuilt,它把编译好的原生模块放在 GitHub 里,在安装时寻找对应平台的原生模块直接下载下来,这样就不需要在本地自己编译 node-canvas 了。
虽然我觉得这个问题应该是 echarts 的 bug——但抱着死马当作活马医的心态,我试了一下,将 [email protected]
换成了 [email protected]
,奇怪的是,现在 macOS 上汉字往下偏了,但数字和英文的位置是正确的,但是在 CentOS 7 中,所有文字的位置都正确了!
emmmmm....
不管怎样,在服务器里正常就好 😂
另外,使用 canvas-prebuilt
的时候虽然不需要安装编译 canvas
所需的 yum 包,但推荐安装下面这两个包:
yum -y install libpng12 fontconfig
libpng12
是为了解决在使用 canvas-prebuilt
时报 libpng12.so.0 not found
的错误,安装 fontconfig
一是为了防止报 no default font config
的提示,二是方便以后自定义字体。
总结
所以一路的坑踩下来,这里提供一份能运行 echarts 的 Dockerfile :
FROM centos:7.3.1611
# 安装 node v8.x
RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash - \
&& yum -y install nodejs gcc-c++ make fontconfig libpng12 \
# 安装字体
&& yum -y groupinstall Fonts
后面如果再遇到其它的坑就再更新吧。
linux : yum -y groupinstall Fonts mac os : ??