赞
踩
npm i echarts-gl echarts
2、导入,并进行配置。
<template> <div ref="echart" class="echartDiv"></div> </template> <script setup> import * as echarts from "echarts"; import "echarts-gl"; import { onMounted, toRefs, ref, reactive } from "vue"; import textBg from "../assets/full-screen.svg" // 传入数据生成 option const optionsData = [ { name: "待办", value: 26, itemStyle: { color: "#2A71FF", }, }, { name: "已办", value: 56, itemStyle: { color: "#00EDFE", }, }, { name: "未处理", value: 18, itemStyle: { color: "#FEDB4B", }, }, { name: "忽略", value: 98, itemStyle: { color: "#FE7C2F", }, }, ]; //挂载 onMounted(() => { echartInit(); }); const echart = ref(null); const echartInit = () => { const myChart = echarts.init(echart.value); const series = getPie3D(optionsData, 0.8); series.push({ name: "pie2d", type: "pie", label: { opacity: 1, fontSize: 14, lineHeight: 20, backgroundColor: { image: textBg, }, padding: [40, 40, 40, 40],//内边距属性 textStyle: { fontSize: 14, color: "#0CF", }, }, labelLine: { length: 60, length2: 30, }, startAngle: -30, //起始角度,支持范围[0, 360]。 clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式 radius: ["40%", "60%"], center: ["50%", "50%"], data: optionsData, itemStyle: { opacity: 0, }, }); // 准备待返回的配置项,把准备好的 legendData、series 传入。 let option = { legend: { show: true, tooltip: { show: true, }, orient: "vertical", data: ["待办", "已办", "未处理", "忽略"], top: "center", itemGap: 14, itemHeight: 8, itemWidth: 17, right: "2%", textStyle: { color: "#fff", fontSize: 12, }, }, animation: false, 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: 14, }, }, title: { x: "center", top: "20", textStyle: { color: "#fff", fontSize: 22, }, }, backgroundColor: "#0E3567", labelLine: { show: true, lineStyle: { color: "#7BC0CB", }, normal: { show: true, length: 10, length2: 10, }, }, label: { show: true, 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.5, // 设置立体柱状图的高度 boxWidth: 100, bottom: "50%", // environment: "rgba(255,255,255,0)", viewControl: { distance: 180, alpha: 25, // 倾斜角度 beta: 155, // 旋转角度 autoRotate: false, // 自动旋转 rotateSensitivity: 0, // 禁止旋转 zoomSensitivity: 0, // 禁止缩放 }, }, series: series, }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); }; function getParametricEquation( startRatio, endRatio, isSelected, isHovered, k, height ) { console.log("222222222222222222"); // 计算 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 饼图的配置项 internalDiameterRatio直径比例 透明的空心占比 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); } return series; } </script> <style lang="scss" scoped> .echartDiv { width: 800px; height: 400px; img: { width: 120px!important; height: 120px!important; } } </style>
3、实现效果图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。