大屏项目:react中实现3d效果的环形图包括指引线
参考链接3d环形图
3d效果的环形图
- 项目需求
- 实现方式
- 指引线(线的样式+字体颜色)
项目需求
需要在大屏上实现一个3d的环形图,并且自带指引线,指引线的颜色和每段数据的颜色一样,文本内容变成白色,数字内容变成和指引线一样的颜色
实现方式
// 返回曲面参数方程// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {// 计算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;// }isSelected = false;// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)k = typeof k !== 'undefined' ? k : 1 / 3;// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)let offsetX = isSelected ? Math.sin(midRadian) * 0.1 : 0;let offsetY = isSelected ? Math.cos(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) * h * 0.1;}return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;},};
}// 生成模拟 3D 饼图的配置项
function getPie3D(pieData, internalDiameterRatio) {let series = [];let sumValue = 0;let startValue = 0;let endValue = 0;let legendData = [];let fakeData=10;let linesSeries = []; // line3D模拟label指示线let k =typeof internalDiameterRatio !== 'undefined'? (1 - internalDiameterRatio) / (1 + internalDiameterRatio): 1 / 3;// 为每一个饼图数据,生成一个 series-surface 配置for (let i = 0; i < pieData.length; i++) {sumValue += fakeData;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: 1 / 10,},};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 + fakeData;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,fakeData);startValue = endValue;// 计算label指示线的起始和终点位置let midRadian = (series[i].pieData.endRatio + series[i].pieData.startRatio) * Math.PI;let posX = Math.cos(midRadian) * (1 + Math.cos(Math.PI / 2));let posY = Math.sin(midRadian) * (1 + Math.cos(Math.PI / 2));let posZ = Math.log(Math.abs(fakeData + 1)) * 0.1;let flag = ((midRadian >= 0 && midRadian <= Math.PI / 2) || (midRadian >= 3 * Math.PI / 2 && midRadian <= Math.PI * 2)) ? 1 : -1;let color = pieData[i].itemStyle.color;let turningPosArr = [posX * (1.8) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posY * (1.8) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posZ * (2)]let endPosArr = [posX * (1.9) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posY * (1.9) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posZ * (6)]linesSeries.push({type: 'line3D',lineStyle: {color: color,},data: [[posX, posY, posZ], turningPosArr, endPosArr]},{type: 'scatter3D',label: {show: true,distance:-10,position: 'center',textStyle: {color: 'black',backgroundColor: color,borderWidth: 2,fontSize: 16,padding: 10,borderRadius: 4,},formatter: '{b}'},symbolSize: 0,data: [{ name: series[i].name + '\n' + series[i].pieData.value, value: endPosArr }]});legendData.push(series[i].name);}series = series.concat(linesSeries) // 在这里能够将指引线与饼图进行连接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;},},});// 准备待返回的配置项,把准备好的 legendData、series 传入。let option = {//animation: false,legend: {//left: '50%',//top: 'center',textStyle: {fontSize: 18,},// icon:'diamond',data: legendData,formatter: (params) => {return params;},},tooltip: {formatter: params => {if (params.seriesName !== 'mouseoutSeries') {return `${params.seriesName}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>${option.series[params.seriesIndex].pieData.value}`;}}},xAxis3D: {},yAxis3D: {},zAxis3D: {},grid3D: {viewControl: {//3d效果可以放大、旋转等,请自己去查看官方配置projection:'perspective',autoRotateDirection: 'cw',distant: 1000,alpha: 60,beta: 40,rotateSensitivity: 1,zoomSensitivity: 1,panSensitivity: 0,autoRotate: false, //旋转属性},left: 'center',top :"middle",width: '100%',height :"100%",show: false,},series: series,};return option;
}// 传入数据生成 option
option = getPie3D([{name: '性能测试',value: 28,itemStyle: {color: '#99D3F3',},},{name: '安全',value: 56,itemStyle: {color: '#007AFF',},},{name: '功能',value: 57,itemStyle: {color: '#2acf81',},},{name: '易用性',value: 51,itemStyle: {color: '#1F9AA7',},},{name: '代码',value: 11,itemStyle: {color: '#F5B64C',},},],0.7
);
指引线(线的样式+字体颜色)
如果需要这种效果,可以按照以下方式改变formatter的属性
formatter: function (val) {return ('{name|' + val.data.name + '}:{value|' +val.data.datavalue + '}');},rich: {name: {fontSize: '0.07rem',color: '#fff',fontWeight: 600},value: {fontSize: '0.09rem',color: color,fontWeight: 600},}
相关文章:

大屏项目:react中实现3d效果的环形图包括指引线
参考链接3d环形图 3d效果的环形图 项目需求实现方式指引线(线的样式字体颜色) 项目需求 需要在大屏上实现一个3d的环形图,并且自带指引线,指引线的颜色和每段数据的颜色一样,文本内容变成白色,数字内容变…...

【STM32】STM32学习笔记-FlyMCU串口下载和STLINK Utility(30)
00. 目录 文章目录 00. 目录01. 串口简介02. 串口连接电路图03. FlyMCU软件下载程序04. 串口下载原理05. FlyMCU软件其它操作06. STLINK Utility软件07. 软件下载08. 附录 01. 串口简介 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简…...
oracle rac 12.2.0.1CPU使用率100%
oracle rac 12.2.0.1 CPU使用率100% 查看是集群的java进程"oracle.ops.opsctl.OPSCTLDriver config database"占用cpu 根据进程号查找父进程,发现是/oracle/GRID/122/perl/bin/perl /oracle/GRID/122/tfa/gcmproddb01/tfa_home/bin/tfactl.pl rediscover -mode full …...

LeetCode、2542. 最大子序列的分数【中等,排序+小顶堆】
文章目录 前言LeetCode、2542. 最大子序列的分数【中等,排序小顶堆】题目及类型思路及代码实现 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领…...

Linux_Docker图形化工具Portainer如何安装并结合内网穿透实现远程访问
文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…...
【Spring Boot 3】【Redis】集成Jedis
【Spring Boot 3】【Redis】集成Jedis 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费…...

C++设计模式(李建忠)笔记3
C设计模式(李建忠) 本文是学习笔记,如有侵权,请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT:https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 文章目录 C设计模…...
计算机考研408的准备
计算机考研408的准备 一:专硕和学硕 计算机的学硕叫做计算机科学与技术,而计算机的专硕叫计算机技术。这么区分的意义就在于我们的就业形势和科研形式。 二:就业形势 由于本科的严重扩招以及课程设置的问题,相当大量的人在毕业…...

2.【Linux】(进程的状态||深入理解fork||底层剖析||task_struct||进程优先级||并行和并发||详解环境变量)
一.进程 1.进程调度 Linux把所有进程通过双向链表的方式连接起来组成任务队列,操作系统和cpu通过选择一个task_struct执行其代码来调度进程。 2.进程的状态 1.运行态:pcb结构体在运行或在运行队列中排队。 2.阻塞态:等待非cpu资源就绪&am…...
【管理篇 / 升级】❀ 13. FortiOS 7.4固件升级新规则 ❀ FortiGate 防火墙
【简介】飞塔防火墙的固件升级一直是所有厂家中最好的。只要有注册官方帐号,有注册设备,并且只要有一台设备在服务期内,即可下载所有型号的所有版本的固件。即使其它设备服务期已过,也可以通过固件文件手动升级,避免防…...

【前端】vue.js从入门到项目实战笔记
文章目录 第三章3.1 插值绑定({{}}, v-html)3.1.1 文本插值3.1.2 HTML插值 3.2 属性绑定 v-bind3.2.1 指令v-bind3.2.3 类名和样式绑定 【前端目录贴】 第三章 3.1 插值绑定({{}}, v-html) 文本插值中的代…...

flex布局(3)
九、骰子 *{margin:0;padding: 0;box-sizing: border-box; } .flex{display: flex;flex-flow: row wrap;justify-content: space-between;align-items: center;align-content: space-between;padding:20px; } .touzi{width: 120px;height: 120px;background-color: aliceblue;…...

JVM知识总结
1.概述 JVM指的是Java虚拟机,本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件,作用是为了支持跨平台特性。 功能: 装载字节码,解释/编译为机器码 管理数据存储和垃圾回收 优化热点代码提升效率 …...

读书笔记-《数据结构与算法》-摘要8[桶排序]
桶排序和归并排序有那么点点类似,也使用了归并的思想。大致步骤如下: 设置一个定量的数组当作空桶。Divide - 从待排序数组中取出元素,将元素按照一定的规则塞进对应的桶子去。对每个非空桶进行排序,通常可在塞元素入桶时进行插入…...

【STM32调试】寄存器调试不良问题记录持续版
STM32寄存器调试不良问题记录 NVIC(内嵌的中断向量控制器)EXTI(外部中断/事件) 记录一些stm32调试过程中:不易被理解、存在使用误区、不清不楚、是坑、使用常识等方面的一些记录。本记录只包含stm32的内核以及外设等寄…...

centos7 arm服务器编译升级安装动态库libstdc++.so.6,解决GLIBC和CXXABI版本低的问题
前言 由于centos7内置的libstdc.so.6版本太低,导致安装第三方包的时候,会报“CXXABI_1.3.8”不存在等问题。 自带的打印如下: strings /usr/lib64/libstdc.so.6 | grep GLIBC strings /usr/lib64/libstdc.so.6 | grep CXXABI 如图 升级 注…...

自动驾驶轨迹规划之碰撞检测(三)
欢迎大家关注我的B站: 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.基于圆覆盖 2.BVH 3.MATLAB自动驾驶工具箱 4 ROS内置的模型 自动驾驶轨迹规划之碰撞检测(一)-CSDN博客 自动驾…...
如何用pandas处理财报数据删除金融行业数据
要删除财报数据中的金融行业数据,您可以按照以下步骤使用pandas进行处理: 导入pandas库: import pandas as pd读取财报数据文件: df pd.read_csv(财报数据.csv)查看数据中的行业分类列: print(df[行业分类])确定金…...
oracle 19c容器数据库data dump数据泵传输数据(4)---网络传输
Transporting a Database Over the Network: Example 这个的方式导入可以不需要传输dmp文件,我原本是想从11g导入到pdb2的,但是因为版本的原因,就直接实验从pdb1导入到pdb2吧。 这种方式和前面完全传输的方式类似,不需要事先在目…...
IP 网络分为接入网、城域网和骨干网
根据前述的IP 网络设计思想,结合算力网络对 正网络的需求分析,卫网络的具体实现可以从架构设计利网络技术两个方面进行总体设计。 首先从架构设计上考虑,架构应尽量简化,做到“以简应繁”。因此,整体网络架构不宜设计…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

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、一个结构体实现多…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...