转载请注明出处,谢谢
最近在开发”面向领导编程”的电子大屏项目,使用到了react+bizCharts,发现网上除了官网之外文档真的是挺少的(官网地址:https://bizcharts.net/product/bizcharts/category/7/page/12),现在介绍一下我是怎么实现tooltip轮播的
<Chart />中 onGetG2Instance 的方法,官网API中是这样介绍的(获取G2图表实例,当配置化不能满足要求,需要实现一些自定义程度较高的操作,可以通过G2图表实例,调用g2底层的方法),对,就是通过这个方法获取到了很多g2里面写的chart的很多属性的,记得自定义方法的时候要把图表的数据一起传进去,后面有用。
通过onGetG2Instance方法我们可以获取到了chart,g2的 chart.showTooltip(pos) 方法可以控制tooltip的展示。
但是对应的点的坐标是个问题,一开始看g2的源码找到了鼠标移动时的 getSnapRecords(pos) 方法,这个方法主要是用于鼠标移动到转折点附近的时候,通过当前鼠标的位置,找到离得最近的转折点的准确坐标,展示tooltip,这个方法可以结合定时器控制鼠标的xy值的变化来进行tooltip轮播,不过这种方式并不是很友好的处理
后来发现还有一个chart.getXY(itemData)方法,这个方法获取某一项的数据,从而或者这条数据对应的转折点,开辟了新思路
tooltip的自动滚动实现了,剩下的就是控制鼠标移入的时候滚动停止将控制权交出去,鼠标移开的时候重新获取控制权,使用的是 onPlotMove 和 onPlotLeave 两个方法
调用后台接口异步获取数据时需要注意,因为异步的原因,会导致数据还没回来,但是onGetG2Instance已经执行过去了导致tooltip轮播直接不开始,这个需要在展示chart时加数据有无的控制
// 以下是代码逻辑
{ !!data && data.length > 0 ? <Chart height={400} data={data} scale={cols} forceFit onGetG2Instance={(chart, data) => this.onGetG2InstanceTooltips(chart, data)} onPlotMove={(ev) => this.onPlotMoveTooltips(ev)} onPlotLeave={(ev) => this.onPlotLeaveTooltips(ev)}> <Axis name="year" /> <Axis name="value" /> <Tooltip crosshairs={{ type: "y" }} /> <Geom type="line" position="year*value" size={2} /> <Geom type="point" position="year*value" size={4} shape={"circle"} style={{ stroke: "#fff", lineWidth: 1 }} /> </Chart> : null } onGetG2InstanceTooltips = (chart, data) => { let innerPoint = [] data.map(item => { innerPoint = [...innerPoint, JSON.stringify(chart.getXY(item))] }) const pointList = Array.from(new Set(innerPoint)).map(item => { return JSON.parse(item) }) this.setState({ tooltipStuff: true }, () => { this.onPointInterval(pointList, chart) }) } onPointInterval = (pointList, chart) => { let i = 0 this.interval = setInterval(() => { !!this.state.tooltipStuff ? (++i, i > pointList.length - 1 ? i = -1 : chart.showTooltip(pointList[i])) : null }, 1000 * 3); } // 鼠标移入 onPlotMoveTooltips = (ev) => { this.setState({ tooltipStuff: false }) } // 鼠标移出 onPlotLeaveTooltips = (ev) => { this.setState({ tooltipStuff: true }) } // 数据的控制 { !!data && data.length > 0 ? <Chart>....</Chart> : null }