blog icon indicating copy to clipboard operation
blog copied to clipboard

将 echarts 跑在 Node.js 服务器上

Open lmk123 opened this issue 6 years ago • 1 comments

最近有个需求,想把 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,但果然是不会有人理我的 😂

所以,我暂时通过给每个文本设定 paddingoffset 这种方式将字体位置再调整回来,但这样做非常繁琐,也不具有通用性。后来我看到有一个非官方的项目 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

后面如果再遇到其它的坑就再更新吧。

lmk123 avatar Mar 24 '18 05:03 lmk123

linux : yum -y groupinstall Fonts mac os : ??

JieChang avatar Jun 27 '18 03:06 JieChang