如何自定义G2Plot图表

1,084 阅读4分钟

G2Plot 内置的是业务中使用量占比超过 90% 的常规统计图表,但而对于业务产品来说,定制不可避免。所以G2Plot开放了基于G2开发的 Adaptor 模式供用户自定义图表,让用户在使用方便的内置图表的同时,又能利用G2的强大功能自由定义满足自己业务的图表,让我们一起来了解下如何自定义图表吧。

一个简单的例子

我们都知道柱状图(Column)的每根柱子是长方形的,有天产品突然说长方形没什么特色,想换成三角形。。。听到这里你也不需要紧张,G2Plot实现它so easy! 先看一下效果 在线Demo

使用自定义图表

// 引用自定义扩展图入口
import { P } from '@antv/g2plot';

const id = 'container';
const options = {
   data:[
  	{ genre: 'Sports', sold: 275 },
  	{ genre: 'Strategy', sold: 115 },
  	{ genre: 'Action', sold: 120 },
  	{ genre: 'Shooter', sold: 350 },
  	{ genre: 'Other', sold: 150 },
	];
    xField: 'genre',
    yField: 'sold',
 },

// 使用自定义扩展图
const hill = new P(
  id,
  options,
  adaptor,
  defaultOptions
); 

hill.render();

在自定义图表前,我们先看一下如何使用自定义图表。从上面代码我们知道P有四个参数:

  • id:创建图表id
  • options:图表配置参数,继承于G2的 ChartCfg
  • adaptor:适配器
  • defaultOptions:默认配置参数

其中options与defaultOptions区别是,defaultOptions是默认配置,写死在自定义组件内部,options是每次创建图表初始化配置,同时自定义属性对象。

自定义Adaptor

import { G2 } from '@antv/g2plot';

// 自定义图形
G2.registerShape('interval', 'hill', {
  draw(info, container) {
    const { points, defaultStyle = {} } = info;
    let path = [
      ['M', points[0].x, points[0].y],
      ['L', (points[1].x + points[2].x) / 2, points[1].y],
      ['L', points[3].x, points[3].y],
      ['Z'],
    ];
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: {
        path,
        ...defaultStyle,
      },
    });
  },
});

// 1. 定义默认配置
const defaultOptions = {
  autoFit:false,
  width:400
};

// 2. adaptor 实现
function adaptor(params) {
  const { chart, options } = params;
  const { data, xField, yField } = options;

  // 数据
  chart.data(data);

  // 几何图形
  chart
    .interval()
    .position(`${xField}*${yField}`)
    .shape('hill')
   
  return params;
}


adaptor的入参parmas由chart和options构成并返回params,其中chart即是G2中的Chart对象,因此我们可以通过定义options属性,然后在adaptor作为中转站,重新实现我们想要的样式效果。

我们可以看到上面代码中chart干了两件事情:

  1. 通过chart.data设置数据源
  2. 通过chart.interval设置几何图形。其中我们定义xField,yField属性,通过重写chart的poistion来绑定x,y轴跟数据源data的映射关系,通过设置shape来自定义几何图形。

因为我们可以通过chart在adaptor作为中转站重写Axis坐标轴,Theme主题等等G2支持的所有操作来实现我们想要的效果。

自定义图形registerShape

import { G2 } from '@antv/g2plot';

// 自定义图形
G2.registerShape('interval', 'hill', {
  draw(info, container) {
    const { points, defaultStyle = {} } = info;
    let path = [
      ['M', points[0].x, points[0].y],
      ['L', (points[1].x + points[2].x) / 2, points[1].y],
      ['L', points[3].x, points[3].y],
      ['Z'],
    ];
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: {
        path,
        ...defaultStyle,
      },
    });
  },
});

// 1. 定义默认配置
const defaultOptions = {
  autoFit:false,
  width:400
};

// 2. adaptor 实现
function adaptor(params) {
  const { chart, options } = params;
  const { data, xField, yField } = options;

  // 数据
  chart.data(data);

  // 几何图形
  chart
    .interval()
    .position(`${xField}*${yField}`)
    .shape('hill')
   
  return params;
}


通过registerShape自定义图形是自定义图表最重要和常见的操作参考文档

上面的代码只用到registerShape的一个绘制方法draw,draw返回container.addShape其实就是shape对象,然后这个shape对象我们可以设置path和style。

  • path:路径,基于G开发的,采用SVG path标准。
  • style:绘图属性,比如设置填充色、border等等,参考文档

draw其实还可以返回group对象,用来绘制多个shape组合,参考addGroup文档

image.png

如上图所示:本身柱状是由红色的4个点通过path路径绘制出来的,现在想要变成三角形,其实我们只要重写path数组,通过points获取最上面那个绿色点的位置(points[1].x + points[2].x) / 2,points[1].y。下面绿色和红色重叠的点代表不需要改变,所以上面的代码直接取points[0].x,points[0].y和points[3].x,point[3].y,这样按照path的语法把三个点按顺序构成path数组赋值给shape就可以了。

总结

通过上面的实践不难发现,G2Plot通过开放P对象和Adaptor模式就可以让用户直接使用到强大又灵活的G2特性,因此想自定义图表我们必须了解G2的api和基本原理,以及SVG,Canvas等绘图知识。

更多