效果图

使用npm下载或cdn引入echarts,echarts-gl,

版本:“echarts”: “^5.1.2”
“echarts-gl”: “^2.0.8”

新建一个js文件pieChart.js,以便于调用

const getPie3D = (pieData,internalDiameterRatio,distance,alpha,pieHeight,opacity = 1
) => {const series = []let sumValue = 0let startValue = 0let endValue = 0let legendData = ['一般事故','一般事故','特大事故','轻微事故']let legendBfb = []const k = 1 - internalDiameterRatiopieData.sort((a, b) => {return b.value - a.value})// 为每一个饼图数据,生成一个 series-surface 配置for (let i = 0; i < pieData.length; i++) {sumValue += pieData[i].valueconst seriesItem = {name:typeof pieData[i].name === 'undefined'? `series${i}`: pieData[i].name,type: 'surface',parametric: true,wireframe: {show: false,},pieData: pieData[i],pieStatus: {selected: false,hovered: false,k: k,},center: ['10%', '50%'],}if (typeof pieData[i].itemStyle !== 'undefined') {const itemStyle = {}itemStyle.color =typeof pieData[i].itemStyle.color !== 'undefined'? pieData[i].itemStyle.color: opacityitemStyle.opacity =typeof pieData[i].itemStyle.opacity !== 'undefined'? pieData[i].itemStyle.opacity: opacityseriesItem.itemStyle = itemStyle}series.push(seriesItem)}// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。legendData = ['一般事故','一般事故','特大事故','轻微事故']legendBfb = []for (let i = 0; i < series.length; i++) {endValue = startValue + series[i].pieData.valueseries[i].pieData.startRatio = startValue / sumValueseries[i].pieData.endRatio = endValue / sumValueseries[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio,series[i].pieData.endRatio,false,false,k,series[i].pieData.value)startValue = endValueconst bfb = fomatFloat(series[i].pieData.value / sumValue, 4)legendData.push({name: series[i].name,value: bfb,})legendBfb.push({name: series[i].name,value: bfb,})}const boxHeight = getHeight3D(series, pieHeight) // 通过pieHeight设定3d饼/环的高度,单位是px// 准备待返回的配置项,把准备好的 legendData、series 传入。const option = {title: {text: '等级分布',// padding: [30, 0, 0, 40],top:'4.5%',left:'8.1%',textStyle: {// 文字颜色color: '#ffffff',// 字体风格,'normal','italic','oblique'fontStyle: 'normal',// 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...fontWeight: 'bold',// 字体系列fontFamily: 'sans-serif',fontSize: '2.2rem',},},legend: {y: '85%', //延Y轴居中x: '5%',itemWidth: 12, // 设置宽度itemHeight: 12, // 设置高度textStyle: {color: '#ffffff',fontSize: 12,},data: legendData,orient: 'vertical',itemGap: 30,textStyle: {color: '#A1E2FF',},formatter: function (param) {const item = legendBfb.filter((item) => item.name === param)[0]const bfs = fomatFloat(item.value * 100, 2) + '%'return `${item.name}`// return `${item.name}  ${bfs}`},},labelLine: {show: true,lineStyle: {color: 'rgba(0,0,0,0)',},},label: {show: true,position: [10,10],formatter: '{d}%',fontSize: 16,},tooltip: {backgroundColor: '#033b77',borderColor: '#21f2c4',textStyle: {color: '#fff',fontSize: 13,},formatter: (params) => {// if (//     params.seriesName !== 'mouseoutSeries' &&//     params.seriesName !== 'pie2d'// ) {//     const bfb = (//         (option.series[params.seriesIndex].pieData.endRatio -//             option.series[params.seriesIndex].pieData//                 .startRatio) *//         100//     ).toFixed(2)//     return (//         `${params.seriesName}<br/>` +//         `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>` +//         `${bfb}%`//     )// }},},xAxis3D: {min: -1,max: 1,},yAxis3D: {min: -1,max: 1,},zAxis3D: {min: -1,max: 1,},grid3D: {show: false,boxHeight: boxHeight, // 圆环的高度viewControl: {// 3d效果可以放大、旋转等,请自己去查看官方配置alpha, // 角度distance, // 调整视角到主体的距离,类似调整zoomrotateSensitivity: 0, // 设置为0无法旋转zoomSensitivity: 0, // 设置为0无法缩放panSensitivity: 0, // 设置为0无法平移autoRotate: false, // 自动旋转},},series: series,}return option
}/*** 生成扇形的曲面参数方程,用于 series-surface.parametricEquation*/
const getParametricEquation = (startRatio,endRatio,isSelected,isHovered,k,h
) => {// 计算const midRatio = (startRatio + endRatio) / 2const startRadian = startRatio * Math.PI * 2const endRadian = endRatio * Math.PI * 2const midRadian = midRatio * Math.PI * 2// 如果只有一个扇形,则不实现选中效果。if (startRatio === 0 && endRatio === 1) {// eslint-disable-next-line no-param-reassignisSelected = false}// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)// eslint-disable-next-line no-param-reassignk = typeof k !== 'undefined' ? k : 1 / 3// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0// 计算高亮效果的放大比例(未高亮,则比例为 1)const hoverRate = isHovered ? 1.05 : 1// 返回曲面参数方程return {u: {min: -Math.PI,max: Math.PI * 3,step: Math.PI / 32,},v: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},x: function (u, v) {if (u < startRadian) {return (offsetX +Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate)}if (u > endRadian) {return (offsetX +Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate)}return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate},y: function (u, v) {if (u < startRadian) {return (offsetY +Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate)}if (u > endRadian) {return (offsetY +Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate)}return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate},z: function (u, v) {if (u < -Math.PI * 0.5) {return Math.sin(u)}if (u > Math.PI * 2.5) {return Math.sin(u) * h * 0.1}return Math.sin(v) > 0 ? 1 * h * 0.1 : -1},}
}/*** 获取3d丙图的最高扇区的高度*/
const getHeight3D = (series, height) => {series.sort((a, b) => {return b.pieData.value - a.pieData.value})return (height * 25) / series[0].pieData.value
}/*** 格式化浮点数*/
const fomatFloat = (num, n) => {let f = parseFloat(num)if (isNaN(f)) {return false}f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n) // n 幂let s = f.toString()let rs = s.indexOf('.')// 判定如果是整数,增加小数点再补0if (rs < 0) {rs = s.lengths += '.'}while (s.length <= rs + n) {s += '0'}return s
}export { getPie3D, getParametricEquation }

在html页面写一个盒子

 <div style="width: 42rem;height: 43.5rem;" id="pieChartMap"></div>

使用时,需要引入pieChart.js里的getPie3D, getParametricEquation

// 图表初始化initChart() {this.statusChart = echarts.init(document.getElementById('pieChartMap'))// 传入数据生成 option, 构建3d饼状图, 参数工具文件已经备注的很详细this.option = getPie3D(this.optionData, 0.8, 240, 28, 26, 1)this.statusChart.setOption(this.option)// 是否需要label指引线,如果要就添加一个透明的2d饼状图并调整角度使得labelLine和3d的饼状图对齐,并再次setOptionthis.option.series.push({name: 'pie2d', // 自己根据场景修改backgroundColor: 'transparent',type: 'pie',label: {opacity: 1,fontSize: 13,lineHeight: 20,},startAngle: -40, // 起始角度,支持范围[0, 360]。clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式radius: ['20%', '50%'],center: ['50%', '50%'],data: this.optionData,itemStyle: {opacity: 0, // 这里必须是0,不然2d的图会覆盖在表面},})this.statusChart.setOption(this.option)this.bindListen(this.statusChart)},bindListen(myChart, optionName = 'option') {let selectedIndex = ''let hoveredIndex = ''// 监听点击事件,实现选中效果(单选)myChart.on('click', (params) => {// 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。const isSelected =!this[optionName].series[params.seriesIndex].pieStatus.selectedconst isHovered =this[optionName].series[params.seriesIndex].pieStatus.hoveredconst k =this[optionName].series[params.seriesIndex].pieStatus.kconst startRatio =this[optionName].series[params.seriesIndex].pieData.startRatioconst endRatio =this[optionName].series[params.seriesIndex].pieData.endRatio// 如果之前选中过其他扇形,将其取消选中(对 option 更新)if (selectedIndex !== '' &&selectedIndex !== params.seriesIndex) {this[optionName].series[selectedIndex].parametricEquation =getParametricEquation(this[optionName].series[selectedIndex].pieData.startRatio,this[optionName].series[selectedIndex].pieData.endRatio,false,false,k,this[optionName].series[selectedIndex].pieData.value)this[optionName].series[selectedIndex].pieStatus.selected = false}// 对当前点击的扇形,执行选中/取消选中操作(对 option 更新)this[optionName].series[params.seriesIndex].parametricEquation =getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,this[optionName].series[params.seriesIndex].pieData.value)this[optionName].series[params.seriesIndex].pieStatus.selected =isSelected// 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndexselectedIndex = isSelected ? params.seriesIndex : null// 使用更新后的 option,渲染图表myChart.setOption(this[optionName])})// 监听 mouseover,近似实现高亮(放大)效果myChart.on('mouseover', (params) => {// 准备重新渲染扇形所需的参数let isSelectedlet isHoveredlet startRatiolet endRatiolet k// 如果触发 mouseover 的扇形当前已高亮,则不做操作if (hoveredIndex === params.seriesIndex) {// 否则进行高亮及必要的取消高亮操作} else {// 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)if (hoveredIndex !== '') {// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。isSelected =this[optionName].series[hoveredIndex].pieStatus.selectedisHovered = falsestartRatio =this[optionName].series[hoveredIndex].pieData.startRatioendRatio =this[optionName].series[hoveredIndex].pieData.endRatiok = this[optionName].series[hoveredIndex].pieStatus.k// 对当前点击的扇形,执行取消高亮操作(对 option 更新)this[optionName].series[hoveredIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,this[optionName].series[hoveredIndex].pieData.value)this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空hoveredIndex = ''}// 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)if (params.seriesName !== 'mouseoutSeries' &&params.seriesName !== 'pie2d') {// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。isSelected =this[optionName].series[params.seriesIndex].pieStatus.selectedisHovered = truestartRatio =this[optionName].series[params.seriesIndex].pieData.startRatioendRatio =this[optionName].series[params.seriesIndex].pieData.endRatiok =this[optionName].series[params.seriesIndex].pieStatus.k// 对当前点击的扇形,执行高亮操作(对 option 更新)this[optionName].series[params.seriesIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,this[optionName].series[params.seriesIndex].pieData.value + 60)this[optionName].series[params.seriesIndex].pieStatus.hovered = isHovered// 记录上次高亮的扇形对应的系列号 seriesIndexhoveredIndex = params.seriesIndex}// 使用更新后的 option,渲染图表myChart.setOption(this[optionName])}})// 修正取消高亮失败的 bugmyChart.on('globalout', (params) => {// 准备重新渲染扇形所需的参数let isSelectedlet isHoveredlet startRatiolet endRatiolet kif (hoveredIndex !== '') {// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。isSelected =this[optionName].series[hoveredIndex].pieStatus.selectedisHovered = falsek = this[optionName].series[hoveredIndex].pieStatus.kstartRatio =this[optionName].series[hoveredIndex].pieData.startRatioendRatio =this[optionName].series[hoveredIndex].pieData.endRatio// 对当前点击的扇形,执行取消高亮操作(对 option 更新)this[optionName].series[hoveredIndex].parametricEquation =getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,this[optionName].series[hoveredIndex].pieData.value)this[optionName].series[hoveredIndex].pieStatus.hovered =isHovered// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空hoveredIndex = ''}// 使用更新后的 option,渲染图表myChart.setOption(this[optionName])})},

在mounted里调用this.leftChart()即可
echarts社区地址:http://www.ppchart.com/#/
https://www.makeapie.cn/echarts
在此原文章更改:link

echarts3d饼图相关推荐

  1. vue3+heightchart实现3D饼图,echarts3D饼图,3D饼图引导线实现

    附上 heightcharts 官网地址 Highcharts 演示 | Highchartshttps://www.hcharts.cn/demo/highcharts 首先需要下载一下 heigh ...

  2. echarts3d饼图,环形图(包含透明效果)

    效果图: 饼图: 环形图: 带透明度的环形图: 安装echarts "echarts":"^5.1.2" "echarts-gl":&quo ...

  3. Echarts 图表一些细节设置 lenged 双Y轴等

    echarts 示例 Echarts图表效果图(Make A Pie替代) Make A Pie 是由社区贡献者维护的用于 Apache ECharts 作品分享的第三方非官方社区.平时做Echart ...

  4. VML 画统计 柱状、饼图、折线

    <!-- --> <!-- 涉及文件 alt.js / function.asp--> <!-- 必须包含页面所有代码 --> <!-- 高度定义有待改进 c ...

  5. html使用highcharts绘制饼图,html js highcharts绘制圆饼图表

    jquery实现饼状图效果 - 站长素材 var chart; $(function () { var totalMoney=999 var zccw=178 var sycw=821 $(docum ...

  6. vue饼图统计_做可交互的统计图表,这套图形语法不容错过

    选好可视化 "一图胜千言",是最直观的数据可视化魅力.以图表来传达和沟通信息,其效率远超枯燥乏味的数据表达. 有需求就有市场.数据可视化崭露头角后,各个厂商出备的产品.解决方案,开 ...

  7. selenium+python自动化81-html报告优化(饼图+失败重跑+兼容python23)

    优化html报告 为了满足小伙伴的各种变态需求,为了装逼提升逼格,为了让报告更加高大上,测试报告做了以下优化: 测试报告中文显示,优化一些断言失败正文乱码问题 新增错误和失败截图,展示到html报告里 ...

  8. Matplotlib常见图形绘制(折线图、散点图、柱状图、直方图、饼图)

    Matplotlib能够绘制折线图.散点图.柱状图.直方图.饼图. 我们需要知道不同的统计图的意义,以此来决定选择哪种统计图来呈现我们的数据. 1 常见图形种类及意义 折线图:以折线的上升或下降来表示 ...

  9. zabbix3.4.7版本饼图显示问题

    问题描述 最近使用zabbix3.4.7版本,发现监控Linux的主机关联系统自带的Template OS Linux模版之后,磁盘空间饼图显示有问题,出现空白,如图所示 查看之后,确定为自带的Lem ...

最新文章

  1. Struts2工作原理详解
  2. 下载Android源码流程(完整版)
  3. python字符串讲解
  4. LNMP Nginx 499 问题 第三方回调异常
  5. Shell编程进阶 1.3data命令
  6. idea2020代码el组件红色波浪线_Android实现炫酷的ViewPager3D组件
  7. webservice wsdl 生成服务
  8. mysql 大小限制_MYSQL 表大小限制
  9. 3S基础知识:MapInfo教程--二次开发入门
  10. 影视后期制作(Pr)
  11. android dropbox目录,通过Android上传文件到Dropbox文件夹
  12. 2021年全球与中国孕妇防辐射服行业市场规模及发展前景分析
  13. python二进制写入文件_python读写二进制文件的方法
  14. Ubuntu1804 使用mondorescue 进行系统备份iso制作
  15. POE交换机供电知识
  16. golang学习之negroni对于第三方中间件的使用分析
  17. STM32 BLDC电机驱动开发板资料 反电动势B-EMF过零检测
  18. 2019计算机学院年会主持稿,2019年会的主持词
  19. Uiautomator2命令
  20. 基于自定义注解校验入参Model中的必传字段

热门文章

  1. linux绝育玩客云_玩客云绝育,不影响下载功能
  2. apktool工具在kali中的安装步骤
  3. 基于STM32F407的人脸追踪
  4. matlab如何绘制相关系数热力图,相关系数矩阵与热力图heatmap
  5. 手机芯片基带芯片及服务器芯片有什么区别,手机射频电路知识干货,射频芯片和基带芯片又是什么关系?...
  6. 弘辽科技:淘宝开店审核不通过怎么办?认证复核不通过怎么办?
  7. 荧光发射和荧光寿命 [Lifetime] 的工作原理
  8. maven下载jar包, 反复出现lastUpdated文件
  9. MPC (c++) 和 udacity模拟器仿真
  10. blast2go centos mysql 5.7++ 安装报错ERROR 1819 (HY000) at line 4