vue3.0 使用echarts与echarts-gl 实现3D饼图

embedded/2024/9/22 18:55:20/

效果

安装echarts

npm install echarts
npm install echarts-gl

3d饼图组件:

<template><div style="width: 100%; height: 100%" ref="echart"></div>
</template><script setup>
import { reactive, ref, onMounted, watch } from 'vue'
import * as echarts from 'echarts'
import 'echarts-gl'const boxHeight = ref([])
const legendData = ref([])
const echart = ref()const props = defineProps({optionsData: []
})const echartInit = () => {var myChart = echarts.init(echart.value)const series = getPie3D(props.optionsData, 0.7)series.push({center: ['10%', '90%'],name: 'pie2d',type: 'pie',label: {show: false,opacity: 1,fontSize: 12,lineHeight: 10,textStyle: {fontSize: 12,color: '#fff',},},labelLine: {length: 30,length2: 30,},startAngle: -30, //起始角度,支持范围[0, 360]。clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式radius: ['40%', '60%'],//data: props.optionsData,data: props.optionsData.map(item => {item.itemStyle.opacity = 0return item}),itemStyle: {opacity: 0,}})// 准备待返回的配置项,把准备好的 legendData、series 传入。let option = {legend: {show: true,tooltip: {show: true,},orient: 'vertical',//data: ['待办', '已办', '未处理'],data: legendData.value,top: 'center',// 设置图例为矩形itemWidth: 14,   // 图例标记的宽度,默认为14itemHeight: 14,  // 图例标记的高度,默认为12itemStyle: {// 设置边框圆角,可以设置为 0 实现正方形borderRadius: 5},itemGap: 12,right: '2%',textStyle: {color: '#fff',fontSize: 12,},formatter: (param)=> {let item = legendData.value.filter(item => item.name == param)[0];let bfs = fomatFloat(item.value * 100, 2) + "%";let v = item.value2;//return `${item.name}  ${bfs}`;return `${item.name}  ${v}`;}},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:10px;width:10px;height:10px;background-color:${params.color};"></span>${option.series[params.seriesIndex].pieData.value + '台'}`}},textStyle: {fontSize: 12,},},title: {x: 'center',top: '20',textStyle: {color: '#fff',fontSize: 12,},},// backgroundColor: '#FFF',labelLine: {show: false,lineStyle: {color: '#7BC0CB',},normal: {show: false,length: 10,length2: 10,},},label: {show: false,position: 'outside',formatter: '{b} \n{d}%',textStyle: {color: '#fff',fontSize: '14px',},},xAxis3D: {min: -1,max: 1,},yAxis3D: {min: -1,max: 1,},zAxis3D: {min: -1,max: 1,},grid3D: {show: false,//boxHeight: 0.01,boxHeight: boxHeight.value,//top: '30%',bottom: '50%',left: '-18%',// environment: "rgba(255,255,255,0)",viewControl: {distance: 180,//这个数值越大图就越小alpha: 25,//倾斜角度beta: 60,//起始渲染角度autoRotate: false, // 自动旋转rotateSensitivity: 1,//旋转灵敏度,鼠标按住不放可进行角度偏移zoomSensitivity: 1,//缩放灵敏度,鼠标滚轮可修改大小panSensitivity: 0,// 平移操作的灵敏度,值越大越灵敏。默认为1,设置为0后无法平移。支持使用数组分别设置横向和纵向的平移灵敏度},},series: series,}// 使用刚指定的配置项和数据显示图表。myChart.setOption(option)}function fomatFloat(num, n) {var f = parseFloat(num);if (isNaN(f)) {return false;}f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 幂   var s = f.toString();var rs = s.indexOf('.');//判定如果是整数,增加小数点再补0if (rs < 0) {rs = s.length;s += '.';}while (s.length <= rs + n) {s += '0';}return s;
}// 获取3d饼图的最高扇区的高度
function getHeight3D(series, height) {series.sort((a, b) => {return (b.pieData.value - a.pieData.value);})return height * 25 / series[0].pieData.value;
}
function getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,height,
) {// 计算let midRatio = (startRatio + endRatio) / 2let startRadian = startRatio * Math.PI * 2let endRadian = endRatio * Math.PI * 2let 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 : 0let 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 = 0let startValue = 0let endValue = 0//let legendData = []let k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3pieData.sort((a, b) => {return (b.value - a.value);});// 为每一个饼图数据,生成一个 series-surface 配置for (let i = 0; i < pieData.length; i++) {sumValue += pieData[i].valuelet 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) : nulltypeof pieData[i].itemStyle.opacity != 'undefined' ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : nullseriesItem.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.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,)boxHeight.value = getHeight3D(series, 2);//通过传参设定3d饼/环的高度,26代表26pxstartValue = endValue//legendData.value.push(series[i].name)let bfb = fomatFloat(series[i].pieData.value / sumValue, 4);legendData.value.push({name: series[i].name,value: bfb,value2: series[i].pieData.value});}return series}watch(() => [props.optionsData],() => {echartInit()}
)onMounted(() => {echartInit()
})</script>

vue中的使用:

<My3DPie :optionsData="optionsData" />

vue的js引入组件

// 传入数据生成 optionconst optionsData = ref([{name: '饮料',value: 36,itemStyle: {opacity: 0.8,color: '#14EC92',},},{name: '小食品',value: 29,itemStyle: {opacity: 0.8,color: '#42A2D8',},}])


http://www.ppmy.cn/embedded/112253.html

相关文章

集成与扩展:将Python办公自动化脚本集成到更大的工作流中

目录 一、引言 二、Python在办公自动化中的基础应用 2.1 数据处理与Excel操作 2.2 报告生成 三、Python与数据库的集成 3.1 连接到数据库 3.2 执行SQL查询 四、Python与Web服务的集成 4.1 使用Flask开发Web服务 五、Python与其他应用程序的集成 5.1 命令行调用 5.2…

windows通过wsl2安装linux系统之Ubuntu,傻瓜式安装

期望通过每一次分享&#xff0c;让技术的门槛变低&#xff0c;落地更容易。 —— around 目录 1.基础环境和要求2.安装wsl23.安装linux系统4.迁移linux系统挂载5.配置linux账号密码6.配置ssh登录方式待续… 前言 为什么要在windows上安装linux&#xff0c;这个问题当你是研发…

Blender怎么给物体添加遮罩

Blender中&#xff0c;你可以在雕刻模式下给物体添加遮罩&#xff0c;以保护某些部分不被修改或雕刻。以下是如何在Blender中添加遮罩的步骤&#xff1a; 1. 进入雕刻模式 首先&#xff0c;选择你的模型&#xff0c;然后按 Tab 键进入 雕刻模式。 2. 选择遮罩工具 在雕刻模…

docker-01 创建一个自己的镜像并运行容器

docker-01 创建一个自己的镜像并运行容器 前言 我们都知道使用Docker的镜像可以快速创建和部署应用&#xff0c;大大的节约了部署的时间。并且Docker 的镜像提供了除内核外完整的运行时环境&#xff0c;确保代码的环境一致性&#xff0c;从而不会在出现这段代码在我机器上没问…

MySQL——数据库的高级操作(二)用户管理(5)如何解决 root 用户密码丢失

大家都知道 root 用户是超级管理员&#xff0c;具有很多的权限&#xff0c;因此该用户的密码一旦丢失就会造成很大的麻烦&#xff0c;针对这种情况&#xff0c;MySQL提供了对应的处理机制&#xff0c;可以通过特殊方法登录到 MySQL 服务器&#xff0c;然后重新为 root 用户设置…

【YashanDB知识库】YAS-02025 no free space in virtual memory pool

本文转自YashanDB官网&#xff0c;具体内容请见YAS-02025 no free space in virtual memory pool 【标题】YAS-02025 no free space in virtual memory pool 【问题分类】业务SQL执行 【关键字】YAS-02025 【问题描述】在崖山环境查询数据提示报错 YAS-02025 no free space…

低代码门户技术:构建灵活、高效的企业门户解决方案

正文&#xff1a; 在当今快节奏的商业环境中&#xff0c;企业门户网站已经成为连接内部员工、外部客户以及合作伙伴的关键平台。为了应对日益增长的业务需求和技术挑战&#xff0c;低代码门户技术应运而生&#xff0c;它提供了一种更加灵活、高效的方式来构建和管理企业门户。…

胤娲科技:解锁AI奥秘——产品经理的智能进化之旅

当AI不再是遥不可及的科幻 想象一下&#xff0c;你走进一家未来感十足的咖啡厅&#xff0c;无需言语&#xff0c;智能咖啡机就能根据你的偏好调制出一杯完美的拿铁&#xff1b; 打开手机&#xff0c;AI助手不仅提醒你今天有雨&#xff0c;还贴心推荐了最适合雨中漫步的音乐列表…