300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > echarts实现复合饼图

echarts实现复合饼图

时间:2019-04-19 11:10:58

相关推荐

echarts实现复合饼图

Echart 复合饼图

要实现如Excel中一样的复合饼图,但发现echarts中并没有相关样例,故根据配置项自行实现

实现思路

利用echarts中的嵌套环形图进行修改

1.1. 将中间内圆进行平移,构成复合饼图的详细子图,通过media属性实现

media: [{query: {minAspectRatio: 1 },option: {series: [{center: ['70%', '50%'] },{center: ['30%', '50%'] },]}}],

实现效果:

2. 接下来就是要为右边的圆以及左边对应的扇形增加连线,这里用到的markline属性,可以在图中增加自定义的线条.

线的起点在左边扇形边界,线的终点在圆的边上。

因为比较懒,懒得计算,所以右边圆上的终点直接写死了。

所以接下来的重点在于获取到左边扇形的上下边界坐标点:

首先需要获取到环形图的属性,需要在图初次完成渲染时获取到图的信息,找到环形图的_itemLayouts属性,该属性拥有每个扇形圆心坐标,半径值,开始角度,结束角度根据获得的圆心坐标(cx,cy),半径值(r),开始角度(startAngle),结束角度 (endAngle)计算扇形的边界坐标,然后更新markLine的起始点就可以得到从扇形到圆的连线 计算方式:开始边界x坐标(x1)= 圆心x坐标 + cos(开始角度) * 半径值开始边界y坐标(y1)= 圆心y坐标 + sin(开始角度) * 半径值结束边界x坐标(x2)= 圆心x坐标 + cos(结束角度) * 半径值结束边界y坐标(y2)= 圆心y坐标 + sin(结束角度) * 半径值得到(x1, y1),(x2, y2)之后,将值以及之前定好的终点圆的边界坐标写到配置项markLine中,就可以得到复合饼图 最终效果

代码(可复制到codeSandbox中运行)

import "./styles.css";import React, {useRef, useMemo, useEffect, useState} from 'react';import ReactEcharts from 'echarts-for-react';export default function App() {const [chartView, setChartView] = useState(null);const myCharts = useRef(null);useEffect(()=>{window.addEventListener('resize', chartResize);return () =>{window.removeEventListener('resize', chartResize);}}, [])const chartResize = () => {setChartView(null);myCharts && myCharts.current.getEchartsInstance().resize();}const chartOptions = useMemo(() => {console.log('111',chartView)let changePos = false;let pos = {};if (chartView) {changePos = true;let tmp = chartView[1]._data._itemLayouts[0];pos.startTop = {x: tmp.cx + Math.cos(tmp.startAngle) * tmp.r, y: tmp.cy + Math.sin(tmp.startAngle) * tmp.r}pos.startBootom = {x: tmp.cx + Math.cos(tmp.endAngle) * tmp.r, y: tmp.cy + Math.sin(tmp.endAngle) * tmp.r} }return {tooltip: {trigger: 'item',formatter: '{a} <br/>{b}: {c} ({d}%)'},legend: {data: ['Direct','Marketing','Search Engine','Email','Baidu',]},series: [{name: 'Access From',type: 'pie',selectedMode: 'single',radius: [0, '30%'],label: {show: false,position: 'inner',fontSize: 14},labelLine: {show: false},data: [{value: 1548, name: 'Search Engine' },{value: 775, name: 'Direct' },{value: 679, name: 'Marketing' }]},{name: 'Access From',type: 'pie',radius: ['45%', '60%'],label: {show: false},labelLine: {length: 30},startAngle: 60,data: [{value: 1048, name: 'Baidu' },{value: 2046, name: 'Email' },],markLine:{silent: true,symbol: 'none',data: [[{x: changePos ? pos.startTop.x : '30%', y: changePos ? pos.startTop.y :47},{x: '70%', y: 84}],[{x: changePos ? pos.startBootom.x :'30%', y: changePos ? pos.startBootom.y :193},{x: '70%', y: 157}]]}}],media: [{query: {minAspectRatio: 1 },option: {series: [{center: ['70%', '50%'] }, {center: ['30%', '50%'] }]}}]}}, [chartView])const onChartReady = ($event) => {console.log($event._chartsViews)if (!chartView) {setChartView($event._chartsViews)}}return (<div className="App"><ReactEcharts ref={myCharts}style={{height: 240, width: '100%'}} opts={{renderer: 'svg'}} option={chartOptions} onChartReady={(event)=>{onChartReady(event)}}// 需要加onEvents,不然onChartReady不生效onEvents={{resize: ()=>{console.log('resize')}}}/></div>);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。