Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

将 echarts 跑在 Node.js 服务器上 #61

Open
lmk123 opened this issue Mar 24, 2018 · 1 comment
Open

将 echarts 跑在 Node.js 服务器上 #61

lmk123 opened this issue Mar 24, 2018 · 1 comment

Comments

@lmk123
Copy link
Owner

lmk123 commented Mar 24, 2018

最近有个需求,想把 echarts 跑在服务端生成图表图片。echarts 支持一个没有公开的方法,可以把 node-canvas 作为浏览器端 Canvas 对象的替代:

// 这里用的是 node-canvas@1.6.9,不是 node-canvas@2.0.0
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——但抱着死马当作活马医的心态,我试了一下,将 canvas@1.6.9 换成了 canvas-prebuilt@1.6.0,奇怪的是,现在 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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants