基于Vue的3D饼图
先看效果:
再看代码:
<template><div class="container"><div style="height: 100%;width: 100%;" id="bingtu3D"></div></div></template>
<script>
import "echarts-liquidfill";
import 'echarts-gl';
import * as echarts from "echarts";export default {mounted () {this.BingTu3D()},methods: {BingTu3D(){const myCharts = echarts.init(document.getElementById('bingtu3D'));function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k,height) {// 计算let midRatio = (startRatio + endRatio) / 2;let startRadian = startRatio * Math.PI * 2;let endRadian = endRatio * Math.PI * 2;let midRadian = midRatio * Math.PI * 2;// 如果只有一个扇形,则不实现选中效果。if (startRatio === 0 && endRatio === 1) {isSelected = false;}// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)k = typeof k !== 'undefined' ? k : 1 / 3 ;// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;// 计算高亮效果的放大比例(未高亮,则比例为 1)let 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);}return Math.sin(v) > 0 ? 1*height : -1;}};}// 生成模拟 3D 饼图的配置项function getPie3D(pieData, internalDiameterRatio) {let series = [];let sumValue = 0;let startValue = 0;let endValue = 0;let legendData = [];let k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio): 1 / 3;// 为每一个饼图数据,生成一个 series-surface 配置for (let i = 0; i < pieData.length; i++) {sumValue += pieData[i].value;let 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}};if (typeof pieData[i].itemStyle != 'undefined') {let itemStyle = {};typeof pieData[i].itemStyle.color != 'undefined' ? itemStyle.color = pieData[i].itemStyle.color : null;typeof pieData[i].itemStyle.opacity != 'undefined' ? itemStyle.opacity = pieData[i].itemStyle.opacity : null;seriesItem.itemStyle = itemStyle;}series.push(seriesItem);}// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。for (let i = 0; i < series.length; i++) {endValue = startValue + series[i].pieData.value;console.log(series[i]);series[i].pieData.startRatio = startValue / sumValue;series[i].pieData.endRatio = endValue / sumValue;series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio, false, false, k,series[i].pieData.value);startValue = endValue;legendData.push(series[i].name);}// // 补充一个透明的圆环,用于支撑高亮功能的近似实现。series.push({name: 'mouseoutSeries',type: 'surface',parametric: true,wireframe: {show: false,},itemStyle: {opacity: 0.1,color: '#E1E8EC',},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},v: {min: 0,max: Math.PI,step: Math.PI / 20,},x: function (u, v) {return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2;},y: function (u, v) {return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2;},z: function (u, v) {return Math.cos(v) > 0 ? -0.5 : -5;},},});// 补充一个透明的圆环,用于支撑高亮功能的近似实现。series.push({name: 'mouseoutSeries',type: 'surface',parametric: true,wireframe: {show: false,},itemStyle: {opacity: 0.1,color: '#E1E8EC',},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},v: {min: 0,max: Math.PI,step: Math.PI / 20,},x: function (u, v) {return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2;},y: function (u, v) {return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2;},z: function (u, v) {return Math.cos(v) > 0 ? -5 : -7;},},});series.push({name: 'mouseoutSeries',type: 'surface',parametric: true,wireframe: {show: false,},itemStyle: {opacity: 0.1,color: '#E1E8EC',},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},v: {min: 0,max: Math.PI,step: Math.PI / 20,},x: function (u, v) {return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2.2;},y: function (u, v) {return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2.2;},z: function (u, v) {return Math.cos(v) > 0 ? -7 : -7;},},});return series;}// 传入数据生成 optionconst optionsData = [{name: 'name1',value: 95,itemStyle: {// opacity: 0.5,color: '#dc3545',},},{name: 'name2',value: 5,itemStyle: {// opacity: 0.5,color: '#efb72c',},},{name: 'name3',value: 60,itemStyle: {// opacity: 0.5,color: '#00b2ff',},},];const series = getPie3D(optionsData, 0.8, 240, 28, 26, 0.5);series.push({name: 'pie2d',type: 'pie',label: {show:true,opacity: 1,lineHeight: 20,textStyle: {fontSize: 16,color:'#fff'},},labelLine: {length: 30,length2: 60,},startAngle: -30, //起始角度,支持范围[0, 360]。clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式radius: ['20%', '50%'],center: ['50%', '50%'],data: optionsData,itemStyle: {opacity: 0,},});// 准备待返回的配置项,把准备好的 legendData、series 传入。const option = {legend: {tooltip: {show: true,},data: ['name1', 'name2', 'name3'],bottom: '1%',right:'10%',textStyle: {color: '#fff',fontSize: 16,},},animation: true,// tooltip: {// formatter: params => {// if (params.seriesName !== 'mouseoutSeries' && params.seriesName !== 'pie2d') {// return `${params.seriesName}<br/><span style="display:inline-block;margin-right:5px;border-radius:5px;width:10px;height:10px;background-color:${params.color};"></span>${option.series[params.seriesIndex].pieData.value }`;// }// },// textStyle : {// fontSize : 16// },// },title: {x: 'center',top: '20',},// backgroundColor: '#333',label: {show: true,position: 'outside',formatter: '{b} \n{c} {d}%',},xAxis3D: {min: -1,max: 1,},yAxis3D: {min: -1,max: 1,},zAxis3D: {min: -1,max: 1,},grid3D: {show: false,boxHeight: 0.5,bottom: '50%',viewControl:{distance:180,alpha:25,beta:60,autoRotate: false, // 自动旋转},},series: series,};// 绘制图表myCharts.setOption(option)//自适应大小window.onresize = () => {myCharts.resize()}},}
}
</script>
<style lang="less" scoped>
/*正文开始*/
.container{width:1920px;height:900px;background-color: #5b81ee;
}
body {width: 1920px;overflow: hidden;height: 1080px;
}
</style>
相关文章:

基于Vue的3D饼图
先看效果: 再看代码: <template><div class"container"><div style"height: 100%;width: 100%;" id"bingtu3D"></div></div></template> <script> import "echarts-liqu…...

Gateway简述
前言 在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端调用多个微服务接口的地址。另外微服务架构的请求中,90%的都携带认证信息/用户登录信息,都需要做相关的限制管理,API网关由此应允而生。 这样的架构会存…...

Midjourney API 的对接和使用
“ 阅读本文大概需要 4 分钟。 ” 在人工智能绘图领域,想必大家听说过 Midjourney 的大名吧。 Midjourney 以其出色的绘图能力在业界独树一帜。无需过多复杂的操作,只要简单输入绘图指令,这个神奇的工具就能在瞬间为我们呈现出对应的图像。无…...
01 消息引擎系统
本文是Kafka 核心技术与实战学习笔记 kafka的作用 kafka最经常被提到的作用是是削峰填谷,即解决上下游TPS的错配以及瞬时峰值流量,如果没有消息引擎系统的保护,下游系统的崩溃可能会导致全链路的崩溃。还有一个好处是发送方和接收方的松耦合…...

npm 卸载 vuecli后还是存在
运行了npm uninstall vue-cli -g,之后是up to date in,然后vue -V,版本号一直都在,说明没有卸载掉 1、执行全局卸载命令 npm uninstall vue-cli -g 2、删除vue原始文件 查看文件位置,找到文件删掉 where vue 3、再…...

Unity 之利用 localEulerAngle与EulerAngle 控制物体旋转
文章目录 概念讲解localEulerAngle与EulerAngle的区别 概念讲解 欧拉角(Euler Angles)是一种常用于描述物体在三维空间中旋转的方法。它使用三个角度来表示旋转,分别绕物体的三个坐标轴(通常是X、Y和Z轴)进行旋转。这…...
从零学算法 (剑指 Offer 13)
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如&am…...
854之数据结构
一.线性表 1.顺序表 #include <iostream> #include<stdlib.h> using namespace std; #define max 100 typedef struct {int element[max];int last; } List; typedef int position ; void Insert(int x, position p, List &L) {position q;if (L.last > ma…...

Redis从基础到进阶篇(二)----内存模型与内存优化
目录 一、缓存通识 1.1 ⽆处不在的缓存 1.2 多级缓存 (重点) 二、Redis简介 2.1 什么是Redis 2.2 Redis的应用场景 三、Redis数据存储的细节 3.1 Redis数据类型 3.2 内存结构 3.3 内存分配器 3.4 redisObject 3.4.1 type 3.4.2 encoding 3…...

DBO优化SVM的电力负荷预测,附MATLAB代码
今天为大家带来一期基于DBO-SVM的电力负荷预测。 原理详解 文章对支持向量机(SVM)的两个参数进行优化,分别是:惩罚系数c和 gamma。 其中,惩罚系数c表示对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。c越小࿰…...
第一百二十五回 dart中List和Map的常见用法
文章目录 概念介绍使用方法初始化相互转换元素操作 经验分享 我们在上一章回中介绍了Flexible组件相关的内容,本章回中将介绍 dart中的List和Map.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里介绍的List也叫列表,它表示一组相…...

小白到运维工程师自学之路 第七十九集 (基于Jenkins自动打包并部署Tomcat环境)2
紧接上文 4、新建Maven项目 clean package -Dmaven.test.skiptrue 用于构建项目并跳过执行测试 拉到最后选择构建后操作 SSH server webExec command scp 192.168.77.18:/root/.jenkins/workspace/probe/psi-probe-web/target/probe.war /usr/local/tomcat/webapps/ /usr/loca…...

林【2021】
三、应用 1.字符串abaaabaabaa,用KMP改进算法求出next和nextval的值 2.三元组矩阵 4.二叉树变森林 四、代码(单链表递增排序,二叉树查找x,快速排序)...

c语言练习题30:判断一个数是否为2^n
判断一个数是否为2^n 思路:2^n中只有一个1故可以通过n&(n-1)是否为0来判断。 代码:...

VX小程序 实现区域转图片预览
图例 方法一 1、安装插件 wxml2canvas npm install --save wxml2canvas git地址参照:https://github.com/wg-front/wxml2canvas 2、类型 // 小程序页面 let data{list:[{type:wxml,class:.test_center .draw_canvas,limit:.test_center,x:0,y:0}] } 3、数据结…...

HTML5-1-标签及属性
文章目录 语法规范标签规范标签列表通用属性基本布局 页面的组成: HTML(HyperText Markup Language,超文本标记语言)是用来描述网页的一种语言,它不是一种编程语言,而是一种标记语言。 HTML5 是下一代 HTM…...
5017. 垦田计划
Powered by:NEFU AB-IN Link 文章目录 5017. 垦田计划题意思路代码 5017. 垦田计划 题意 略 思路 二分最小需要几天即可 注意: 天数不能低于k二分时,若耗时天数小于mid,直接continue 代码 /* * Author: NEFU AB-IN * Date: 2023-08-26 22:4…...

【校招VIP】产品思维分析之面试新的功能点设计
考点介绍: 这种题型是面试里出现频度最高,也是难度最大的一种,需要面试者对产品本身的功能、扩展性以及行业都有一定的了解。而且分析时间较短,需要一定的产品能力和回答技巧。 『产品思维分析之面试新的功能点设计』相关题目及解…...
indexDB vue 创建数据库 创建表 添加对象数据
1 .open(dbName,1) 版本号可以省略 let dbName hist-data-1dconst request indexedDB.open(dbName); // 如果你不知道数据库的版本号,可以省略第二个参数,这样 indexedDB 会默认为你打开最新版本的数据库,因为版本号总是自增长的 2 第一次…...

Django基础1——项目实现流程
文章目录 一、前提了解二、准备开发环境2.1 创建项目2.1.1 pycharm创建2.1.2 命令创建 2.2 创建应用 例1:效果实现例2:网页展示日志文件 一、前提了解 基本了解: 官网Django是Python的一个主流Web框架,提供一站式解决方案…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...