开篇先介绍一下,鄙人有幸在毕业设计时使用过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。