woodywuuu / blogs

7 stars 1 forks source link

bizchart的点击事件爬坑 #7

Open woodywuuu opened 5 years ago

woodywuuu commented 5 years ago
bizchart点击事件

由于echarts没有很好的react适配,在新的项目里打算用antd官方推荐的bizcharts来做图表,发现还是有些坑会踩到。(其实有一个个人项目echarts-for-react做了不错的react适配,但是不能支持按需加载,会导致打出的包较大

需求是一个简单的折线图,按照bizcharts的官方文档,图表组件化,每个图表都是由许多组件组成的,跟echarts里由一个配置json来决定完全不同。甚至还提供了数据转换的模块@antv/data-set,不过这里不详谈,可以看官方文档。

按照官方文档配置的折线图代码简化如下:

import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';

......

onClick = (e) => {

    console.log(e);

}

<Chart height={500} data={data} scale={cols} forceFit onPointClick={this.onClick}>

  <Legend />

  <Axis name="x" />

  <Axis name="y" />

  <Tooltip crosshairs={{ type: 'y' }} title="x" />

  <Geom

    type="line"

    position="x*y"

    size={2}

    tooltip={['x*y*z', (x, y, z) => { return { name: z, title: x, value: y }; }]}

    color="z"

    shape="smooth"

  />

</Chart>

官方对于每一个元素都提供了类似Click之类的方法,详见链接,但是在使用这个函数之后,无论怎么点都无法触发。

于是我灵机一动,用了公用的触发事件onPlotClick,成功获取到了返回值,但是这个返回值里面只有横纵坐标x和y值,完全拿不到跟图形相关的参数。参考了官方的demo,我在state里存放了Chart的实例,点击后再用坐标去Chart里获取图形相关的数据。代码大致如下:

onSaveChart = (chart) => {

  this.setState({ chart });

}

onClick = (e) => {

  const point = {

    x: e.x,

    y: e.y,

  };

  const { chart } = this.state;

  const items = chart.getTooltipItems(point);

  console.log( items );

}

<Chart onGetG2Instance={this.onSaveChart} onPlotClick={this.onClick}>

......

</Chart>

这次的返回值的确有相关数据了,但是我只是点击了其中一个点,却返回了同一横坐标的所有线的数据,明显不符合我的需求。搜索了许多相关的API和Issue,都没有发现这个问题,但这种很简单的需求难道没有人用?肯定是我的打开方式不对。

于是我打开了官方折线图的DEMO,进了codepen,加上了onPointClick函数,竟然可以生效!!检查了版本之后,我细细看起了官方给的代码跟我的有什么不同,结果发现,他的代码里多了一个type为point的Geom!原来是没有点图的组件,于是没有办法监听跟点相关的点击事件。。这个设计,也是很精妙了,毕竟组件化的东西,没有加载就没有,很是合理。

最后的代码大致是这样:

import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';

......

onClick = (e) => {

    console.log(e);

}

<Chart height={500} data={data} scale={cols} forceFit onPointClick={this.onClick}>

  <Legend />

  <Axis name="x" />

  <Axis name="y" />

  <Tooltip crosshairs={{ type: 'y' }} title="x" />

  <Geom

    type="line"

    position="x*y"

    size={2}

    tooltip={['x*y*z', (x, y, z) => { return { name: z, title: x, value: y }; }]}

    color="z"

    shape="smooth"

  />

  <Geom

    type="point"

    position="x*y"

    size={2}

  />

</Chart>

虽然只是个很简单的问题,但是也花费了我好些时间去解决。搜索引擎并没有找到像我一样情况的人(也许是我关键字写得不对233333希望这篇东西能够帮到其他困惑的人。