轉載請注明出處,謝謝
最近在開發”面向領導編程”的電子大屏項目,使用到了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 }