Ant Design Charts中如何为图表中的元素绑定事件

        开篇先介绍一下,鄙人有幸在毕业设计时使用过Ant Design Pro做了一个可视化的网站,可视化部分主要借助了Ant Design Charts提供的图表组件,在此期间,有些使用的经验可以分享一下。

        在Ant Design Charts教程中关于图表绑定事件的介绍很短,实际上官方已经介绍过了,Ant Design Charts是AntV的一个扩展产品,是AntV的React版本,故Ant Design Charts的教程也只是添加了一些和AntV不同的地方。而Ant Design Charts中的图表大多是AntV中的G2系列,故可以参照以下两个教程来学习图表元素事件绑定。

G2plot图表事件https://g2plot.antv.antgroup.com/api/options/eventsG2事件https://g2.antv.antgroup.com/manual/event

        接着以一个例子来讲解如何为图表元素绑定事件。首先介绍一下需要实现的效果,在气泡图中实现点击一个气泡为气泡改变颜色,效果如下

        首先肯定是从ant design charts中复制一个气泡图案例,我们在这个基础上改,这里选择的是气泡图 | Ant Design Charts。配置好之后,假定数据类型是对象,从Dva的Model里获取,(Dva是Ant Design Pro的一个插件(包),专门用于管理数据,实现了组件之间的数据上提和共享,解决了Ant Design Pro中不同路由组件之间数据流通的问题。)代码如下:

  const { topicForColorAndText, dispatch } = props;
  const { topics, Type, color } = topicForColorAndText;

        props是函数式组件的一个参数,数据类型为JavaScript中的对象,用于接收数据。topicForColorAndText就是Model的名称,dispatch为后续修改Model中的数据所需的方法。topics,Type,color就是Model里存储的数据。格式为:

        color为事先定义的颜色数组(之后以编号从该数组里取颜色),Type相当于一个全局变量,用于存储下一个气泡的颜色编号,topics实际上是后端应用算法处理过后得到的文章的主题数组,但这里把它抽象为气泡以进行可视化。

        topics中的一个元素实际上就是气泡图中的一个气泡,type属性规定了气泡是什么颜色。

        数据有了,接着来为图表绑定事件,这里采用挂载到 ref 上的方式,代码如下:

  const plotRef = useRef();
  useEffect(() => {
    const plot = plotRef.current.getChart();
    plot.on('element:click', (evt) => {
     //这里写对元素的属性进行改变的代码
    });
  }, []);

        首先定义了plotRef ,它是一个引用对象,用于引用图表的 DOM 元素,之后还要把它定义为气泡图组件中属性ref的值,这样在每次挂载组件时, 通过getCharts()方法获取的图表实例plot才会指代气泡图。plot.on()第一个参数element:click表示监听气泡(泛化为元素,比如柱形图的柱子也是元素)被点击一次的事件,第二个参数是一个回调函数,这个回调函数的参数就是触发这个事件的事件对象,关于evt,只需知道evt.data.data获取的数据就是每个气泡的数据,依靠这个数据在model里找到对应的气泡(主题),改变其type值即可达到改变颜色的效果。

        最后附上完整代码,但不包括Model里的数据更新代码,因为仅仅为了实现这个点击改变颜色就使用Dva来管理数据太繁琐了,完全可以改为简单的方式(用useState),笔主用dva是因为想在其它组件共用model里的数据。

import React, { useRef, useEffect } from 'react';
import { Scatter } from '@ant-design/plots';
import { connect } from 'umi';

const Bubble = (props) => {
  const { topicForColorAndText, dispatch } = props;
  const { topics, Type, color } = topicForColorAndText;
  // console.log('topics[0]',topics[0]);
  const plotRef = useRef();
  useEffect(() => {
    const plot = plotRef.current.getChart();
    //console.log(plot.options.data);
    //开始绑定事件
    //因为绑定事件后,事件内获取不到Type的最新值,故在这进行模拟
    let i = 1
    plot.on('element:click', (evt) => {
      // console.log(evt.data.data);
      // evt.data.color = `r(0.4, 0.3, 0.7) 0:rgba(255,255,255,0.5) 1:${color[type+1]}`;
      if (evt.data.data.type != 0) {
        dispatch({
          type: 'topicForColorAndText/updateTopics2',
          payload:evt.data.data,
        });
      } else {
        if(i>9){
          i=1
        }
        dispatch({
          type: 'topicForColorAndText/isUpdateType',
          payload: Type + i,
        });
        dispatch({
          type: 'topicForColorAndText/updateTopics',
          payload: evt.data.data,
        });
        i++
      }
    });
  }, []);
  const newTopics = topics.map((i)=>{
    return{...i,type:''+i.type}
  })
  const colors = color.map((i) => {
    return 'r(0.4, 0.3, 0.6) 0:rgba(255,255,255,0.5) 1:' + i;
  })
  const config =
    Type > 0
      ? {
          appendPadding: 30,
          data: newTopics,
          xField: 'x',
          yField: 'y',
          colorField:'type',
          color:({type})=>{
            // console.log(typeof(type))
            return colors[parseInt(type)]
          } ,
          sizeField: 'size',
          size: [5, 20],
          shape: 'circle',
          yAxis: {
            nice: true,
            line: {
              style: {
                stroke: '#eee',
              },
            },
          },
          xAxis: {
            grid: {
              line: {
                style: {
                  stroke: '#eee',
                },
              },
            },
            line: {
              style: {
                stroke: '#eee',
              },
            },
          },
          interactions: [{ type: 'element-active' }],
        }
      : {
          appendPadding: 30,
          data: topics,
          xField: 'x',
          yField: 'y',
          color: "r(0.4, 0.3, 0.7) 0:rgba(255,255,255,0.5) 1:#5B8FF9",
          sizeField: 'size',
          size: [5, 20],
          shape: 'circle',
          yAxis: {
            nice: true,
            line: {
              style: {
                stroke: '#eee',
              },
            },
          },
          xAxis: {
            grid: {
              line: {
                style: {
                  stroke: '#eee',
                },
              },
            },
            line: {
              style: {
                stroke: '#eee',
              },
            },
          },
          interactions: [{ type: 'element-active' }],
        };

  return <Scatter {...config} ref={plotRef} />;
};

export default connect(({ topicForColorAndText }) => ({ topicForColorAndText }))(Bubble);

        值得一提的是,在<Scatter>这个官方提供的组件中,colorField:'type',表示按照数据中的属性type来为元素指定颜色,但type的值必须是字符串类型,故使用newTopics方法来转换一下。

        这篇文章主要基于现有的代码来书写,所以有一些跟实现效果不相关的部分,比如数据的定义、采用Dva来管理数据。如果读者对Dva的使用有疑问可以联系我,后续会出一篇文章来讲解Dva。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值