Node 端渲染 F2

虽然 F2 默认基于 Html5 Canvas 进行图表绘制,但是对于当前运行时环境来说,只要能够提供和 Html5 Canvas 上下文环境一样的上下文接口,一样也能使用 F2 进行图表绘制。

下面的表格给出了各个运行环境下可使用的 F2 的功能对比:

Html5 Node 小程序(微信&&小程序)
图表绘制 ✔︎ ✔︎ ✔︎
Legend 组件 ✔︎ ✔︎ ✔︎
Tooltip 组件 ✔︎ ✔︎
事件(Tooltip、Legend 上的事件交互) ✔︎ ✔︎
动画 ✔︎ ✔︎

Node 端渲染说明

将 F2 运行于 node 的后台服务上,可以提供强大的服务端渲染可视化图表的能力,这种能力可以应用于生成离线报表、图文 pdf 等场景。

目前 F2 在 node 环境中能够提供完整的图表绘制能力,但无法提供事件、交互以及动画功能(所以在试验官网 demo 时请删除 chart.tooltip() 以及 .animate() 相关的代码哦)。具体的使用方法如下:

  • 首先安装模块node-canvas 该模块提供了在 node 中实现 canvas 渲染的能力,结合该模块,就可以实现 F2 在 node 端的图表渲染了
  1. npm install canvas
  • 引入 F2,这里需要说明的是:node 端不支持动画、事件以及 Tooltip,所以在引入 F2 时请选择按需引入以避免上述模块的引入,这样也能够使得 F2 的代码体量更小巧。为了使用更便利,建议将以下代码封装成通用模块。
  1. const F2 = require('@antv/f2/lib/core'); // 引入核心包
  2.  
  3. require('@antv/f2/lib/geom/'); // 几何标记对象
  4. require('@antv/f2/lib/geom/adjust/'); // 数据调整
  5.  
  6. require('@antv/f2/lib/coord/polar'); // 极坐标系
  7. require('@antv/f2/lib/component/axis/circle'); // 极坐标系下的弧长坐标轴
  8.  
  9. require('@antv/f2/lib/scale/time-cat'); // timeCat 类型的度量
  10.  
  11. require('@antv/f2/lib/component/guide'); // 加载 guide 组件
  12. const Guide = require('@antv/f2/lib/plugin/guide'); // Guide 插件
  13. const Legend = require('@antv/f2/lib/plugin/legend'); // Legend 插件
  14. F2.Chart.plugins.register([ Legend, Guide ]); // 注册以上插件
  • 创建一个 canvas 对象

const Canvas = require('canvas');
const canvas = Canvas.createCanvas(400, 267);

  • 使用 F2 绘制图表,需要注意的是在创建 Chart 对象时传入的属性,下面两种方式 widthheight 属性都是必须设置的
  1. // 第一种方式直接传入 canvas
  2. const chart = new F2.Chart({
  3. el: canvas, // 将第三步创建的 canvas 对象传入
  4. width: 400, // 必选,图表宽度,同 canvas 的宽度相同
  5. height: 267 // 必选,图表高度,同 canvas 的高度相同
  6. });
  7.  
  8. // 第二种方式传入上下文环境
  9. const chart = new F2.Chart({
  10. context: canvas.getContext('2d'), // 将第三步创建的 canvas 对象的上下文传入
  11. width: 400, // 必选,图表宽度,同 canvas 的宽度相同
  12. height: 267 // 必选,图表高度,同 canvas 的高度相同
  13. });

下面是 F2 在 node 端绘制饼图的完整代码:

pie.png | left | 375x260

  1. const fs = require('fs');
  2. const path = require('path');
  3.  
  4. const Canvas = require('canvas'); // 引入 node canvas
  5.  
  6. // 引入 F2: start
  7. const F2 = require('@antv/f2/lib/core'); // 引入核心包
  8. require('@antv/f2/lib/geom/'); // 几何标记对象
  9. require('@antv/f2/lib/geom/adjust/'); // 数据调整
  10. require('@antv/f2/lib/coord/polar'); // 极坐标系
  11. require('@antv/f2/lib/component/axis/circle'); // 极坐标系下的弧长坐标轴
  12. require('@antv/f2/lib/scale/time-cat'); // timeCat 类型的度量
  13. require('@antv/f2/lib/component/guide'); // 加载 guide 组件
  14. const Guide = require('@antv/f2/lib/plugin/guide'); // Guide 插件
  15. const Legend = require('@antv/f2/lib/plugin/legend'); // Legend 插件
  16. F2.Chart.plugins.register([ Legend, Guide ]); // 注册以上插件
  17. // 引入 F2: end
  18.  
  19. const canvas = Canvas.createCanvas(375, 260); // 创建 canvas 对象
  20.  
  21. // 使用 F2 绘制饼图
  22. function drawPie() {
  23. const data = [
  24. { name: '芳华', percent: 0.4, a: '1' },
  25. { name: '妖猫传', percent: 0.2, a: '1' },
  26. { name: '机器之血', percent: 0.18, a: '1' },
  27. { name: '心理罪', percent: 0.15, a: '1' },
  28. { name: '寻梦环游记', percent: 0.05, a: '1' },
  29. { name: '其他', percent: 0.02, a: '1' }
  30. ];
  31. const chart = new F2.Chart({
  32. el: canvas,
  33. width: 375,
  34. height: 260,
  35. padding: [ 45, 'auto', 'auto' ]
  36. });
  37. chart.source(data, {
  38. percent: {
  39. formatter(val) {
  40. return val * 100 + '%';
  41. }
  42. }
  43. });
  44. chart.legend({
  45. position: 'right'
  46. });
  47. chart.coord('polar', {
  48. transposed: true,
  49. radius: 0.85
  50. });
  51. chart.axis(false);
  52. chart.interval()
  53. .position('a*percent')
  54. .color('name', [ '#1890FF', '#13C2C2', '#2FC25B', '#FACC14', '#F04864', '#8543E0' ])
  55. .adjust('stack')
  56. .style({
  57. lineWidth: 1,
  58. stroke: '#fff',
  59. lineJoin: 'round',
  60. lineCap: 'round'
  61. });
  62.  
  63. chart.render();
  64.  
  65. }
  66.  
  67. drawPie();
  68.  
  69. canvas.createPNGStream().pipe(fs.createWriteStream(path.join(__dirname, 'pie.png'))) // 导出图片

不同设备分辨率适配方案

适配方案很简单,假设当前设备的像素比为 2,那么在创建 F2 图表的时候,设置下 pixelRatio 属性即可:

  1. const chart = new F2.Chart({
  2. el: canvas,
  3. width: 375,
  4. height: 260,
  5. padding: [ 45, 'auto', 'auto' ],
  6. pixelRatio: 2
  7. });

这里我们设置的画布宽高为 375 260,在设置了 pixelRatio: 2 后生成的图表宽高会相应放大 2 倍,尺寸为 750 520,这个时候在显示图片时,将图片的实际显示大小设置为 375 * 260,就可以保证图片的清晰显示了,如下图所示:

  • 屏幕分辨率: 2
  • 图片实际大小:750 * 520
  • 图片的样式(显示大小): style="width: 375px;height: 260px;"Node 端渲染 F2 - 图2

原文: https://antv.alipay.com/zh-cn/f2/3.x/tutorial/node-env.html