這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 記錄一下在公司遇到的一些功能,以及相關實現 以上的內容我花了一周時間去實現的,自己也覺得時間很長,但主要因為很少使用ECharts,導致使用的過程中大部分的時間都在查文檔。 對於上面的這些功能點,其實算是寫了兩遍吧,這周一開了個Code ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
記錄一下在公司遇到的一些功能,以及相關實現
以上的內容我花了一周時間去實現的,自己也覺得時間很長,但主要因為很少使用ECharts,導致使用的過程中大部分的時間都在查文檔。
對於上面的這些功能點,其實算是寫了兩遍吧,這周一開了個Code Review,因為涉及到公共組件了,所以得想辦法遷移出去,導致得重新改善一下代碼;另一方面的話,主要是我把每一個功能其實都拓展成一個圖表了(也就是說包括主圖表、內環圖表、外環圖表、環形文字圖表),會導致渲染消耗太大,所以得進行細分,也就是加入到series里即可。
接下來我們來說說各個功能點如何實現吧
內環
效果如下
簡單說就是在餅圖內部實現一個圓環的旋轉效果,因為長度、顏色的相關聯,
所以我的思路就是再畫一個餅圖圖表去實現它,然後刪除lengend、tooltip等相關提示。
一開始想多添加一個series解決的,但是因為需要旋轉效果,不好獲取這個元素,所以就把它抽離出來,單獨實現一個了
刪除圖表相關提示信息的代碼
option = { backgroundColor: 'transparent', tooltip: { show: false }, legend: { show: false }, series: [ { silent: true, // 禁用圖標中的點擊和觸摸事件 left: 0, label: { show: false }, itemStyle: borderWidth: 0, borderRadius: 0, } } ] }
漸變色效果
主要就是通過線性漸變去實現的,還看了幾個不錯的文章,只是實現比較複雜,但效果更好一點
color: props.option.color.map(color => { return { type: 'linear', x: 0, y: 0, x2: 1, y2: 1, colorStops: [ { offset: 0, color: 'rgba(0,180,255,.05)' // 0% 處的顏色 }, { offset: 1, color: color // 100% 處的顏色 } ] } })最終實現效果
外環
效果如下
簡單說就是在餅圖外部實現一個圓環的擴展弧度
因為我們的圖表可能存在多個series,即多個環形圖,所以我們需要找到最外部的最大環半徑,從它開始向外擴展(這個可以擴展到series上,無需再添加一個圖表)
實現上和內環其實一樣的,只要修改一個radius的顯示位置即可,從最大環半徑開始向外拓展。
最終實現效果
環形間隔
效果如下
這個網上例子其實挺多的,主要的方式就是拓展data數據,然後設置itemStyle
的color
為透明色即可,看起來很簡單;但是在我們的項目里會有一定難度,因為我們的data
處理被封裝到內部公共組件去處理了,所以沒辦法去直接修改data
這裡的思路(組長提供的),傳一個方法到內部去,然後獲取到其更新data
後的option,併在更新前進行處理
所以我的方式是設置了一個方法 handleOptionBeforeUpdate
,接收instance、option兩個參數,instace後面的輪播動畫會使用到,現在只需要使用option,我們對其進行修改,再返回一個新的option回去,讓它進行更新即可
插入間隙
// 計算間隙(根據比例判斷間隙需要多大) const sum = option.series[0].data.reduce((sum, d) => sum + +d.value, 0) const val = (sum * props.borderGap) / 10 for (const series of option.series) { series.data = series.data.reduce( (sum, d) => [ ...sum, d, { name: '', value: val, itemStyle: { color: 'transparent' } } ], [] ) }最終實現效果
輪播動畫
效果如下
這個看著很難,但是網上例子挺多的,隨便找找就有好幾個
主要就是通過定時器和 ECharts實例 去用代碼觸發action
dispatchAction
instance.dispatchAction({ type: 'downplay', seriesIndex: 0, // 系列 dataIndex: 0 // 具體index })
type類型
- highlight —— 高亮
- downplay —— 取消高亮
- showTip —— 顯示Tooltip
- hideTip —— 隱藏Tooltip
- select —— 選中
- unselect —— 取消選中
- …
我們後面討論決定選擇使用highlight和downplay兩種
不使用select的原因,主要是因為selct選中在項目里有問題,會存在選中多個的情況,無法取消選中,通過的方式是重新渲染圖表,但是太消耗性能了,而且選中會導致居中文字偏移,所以放棄了這種方式
接下來,看一下具體的定時器方法
const timer = useRef<NodeJS.Timer>() const currentIndex = useRef<number>(0) const resetSelect = () => { eChartInstance.current?.dispatchAction({ type: 'downplay', seriesIndex: 0 }) } const selectSector = () => { eChartInstance.current?.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: currentIndex.current }) } // 輪播動畫 const rotatingAnimation = () => { if (props.rotatingAnimation.isActive) { clearInterval(timer.current) timer.current = setInterval(() => { const dataLen = eChartOption.current?.series[0].data.length ?? 0 currentIndex.current = (currentIndex.current + 2) % dataLen resetSelect() selectSector() }, props.rotatingAnimation.duration * 1000) } else { resetSelect() } } useEffect(() => { rotatingAnimation() return () => { clearInterval(timer.current) } }, [props.rotatingAnimation])
主要就是定時器這一塊,其實挺簡單的
最終實現效果
環形文字
效果如下
這個文字效果我找了很久也沒看到完美的實現方案,目前有兩種比較可行的方案,一種是根據位置旋轉每一個文字(不大現實),另一種就是通過旭日圖去顯示了,旭日圖的文字是支持這種方式的。
const textSeries = { type: 'sunburst', sort: null, silent: true, // 禁用圖標中的點擊和觸摸事 nodeClick: false, label: { show: true, position: 'outside', rotate: 'tangential', // 實現!!! align: 'right', distance: 10, padding: [0, -15] // 進行偏移 }, itemStyle: { borderWidth: 0, borderRadius: 0, color: 'transparent' } }
其他圖表的文字也能實現
tangential
,但是無法進行偏移
最終實現效果