效果图:
- 安装
pnpm i echarts
- 公共模块组件
<div
class="pie"
ref="percent"
style="width: 100%; height: calc(100% - 48px)"
></div>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
const props = defineProps<{
titlecolor: any // 中间百分比数字文字的颜色
value: any // 值百分之多少
valuesize: any // 值的大小
color: any // 圆环颜色数组 渐变
}>()
let percent = ref<any>('')
// ---------------------------------
const Pie = () => {
let dataArr = []
for (var i = 0; i < 100; i++) {
if (i % 10 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: 40,
itemStyle: {
// 外圈的点点颜色
normal: {
color: props.color[1],
borderWidth: 0,
// borderColor: '#00ff00'
},
},
})
} else {
dataArr.push({
name: (i + 1).toString(),
value: 100,
itemStyle: {
normal: {
color: 'rgba(0,0,0,0)',
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
}
}
return dataArr
}
const Pie1 = () => {
let dataArr = []
for (var i = 0; i < 100; i++) {
if (i % 5 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: 20,
itemStyle: {
normal: {
color: props.color[1],
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
} else {
dataArr.push({
name: (i + 1).toString(),
value: 100,
itemStyle: {
normal: {
color: 'rgba(0,0,0,0)',
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
}
}
return dataArr
}
const Pie2 = () => {
let dataArr = []
for (var i = 0; i < 100; i++) {
if (i % 5 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: 20,
itemStyle: {
normal: {
color: props.color[1],
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
} else {
dataArr.push({
name: (i + 1).toString(),
value: 100,
itemStyle: {
normal: {
color: 'rgba(0,0,0,0)',
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
}
}
return dataArr
}
const Pie3 = () => {
let dataArr = []
for (var i = 0; i < 100; i++) {
if (i % 10 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: 30,
itemStyle: {
normal: {
color: props.color[1],
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
} else {
dataArr.push({
name: (i + 1).toString(),
value: 100,
itemStyle: {
normal: {
color: 'rgba(0,0,0,0)',
borderWidth: 0,
borderColor: 'rgba(0,0,0,0)',
},
},
})
}
}
return dataArr
}
// ---------------------------------
const markChart = () => {
// 初始化
let Mychart = echarts.init(percent.value)
// 配置项
// 带分割线的圆环配置 start ------------------------------
var labelData: any = []
var labelData1: any = []
for (var i = 0; i < 150; ++i) {
labelData.push({
value: 1,
name: i,
itemStyle: {
normal: {
color: '#696969',
},
},
})
}
for (var i = 0; i < labelData.length; ++i) {
if (labelData[i].name < 50) {
labelData[i].itemStyle = {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: props.color[0],
},
{
offset: 1,
color: props.color[0],
},
]),
},
}
}
}
// ------------------------------
let option = {
// -- start 中间 百分比值样式属性
title: [
{
text: props.value + '%', //动态传递
x: '50%',
y: '45%',
textAlign: 'center',
textStyle: {
fontSize: props.valuesize,
fontWeight: '700',
color: props.titlecolor,
textAlign: 'center',
},
},
],
// -- end
polar: {
center: ['50%', '50%'], //极坐标系的中心(圆心)坐标
radius: ['75%', '85%'], // 极坐标系的半径,第一个为 内半径,第二个外半径标识可视区域
},
angleAxis: {
// 角度轴
max: 100, // 设置角度轴刻度的最大值
show: false, // 是否显示
startAngle: 0, // 设置角度轴起始刻度的角度 默认90度 即圆心正上方;0度为圆心的正右方
},
radiusAxis: {
//径向轴
type: 'category', // 类型:类目轴 必须通过data设置类目数据
show: true,
},
series: [
{
name: '',
type: 'bar',
roundCap: true, // 是否在环形柱条两端显示成圆形
barWidth: 40, //最外圈圆环宽度
showBackground: true, // 是否显示环形柱条背景色
backgroundStyle: {
color: '#464451', // 环形柱条背景颜色
},
data: [props.value],
coordinateSystem: 'polar', // 使用坐标系类型:[cartesian2d - 二维直角坐标系] [polar - 极坐标系]
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{
offset: 0.6,
color: props.color[1],
},
{
offset: 1,
color: props.color[2],
},
]),
},
},
},
{
hoverAnimation: false,
type: 'pie',
z: 2,
data: labelData,
radius: ['52%', '59%'],
zlevel: -2,
itemStyle: {
normal: {
borderColor: '#1f1e26',
borderWidth: 4,
},
},
label: {
normal: {
position: 'inside',
show: false,
},
},
},
{
hoverAnimation: false,
type: 'pie',
z: 1,
data: labelData1,
radius: ['52%', '59%'],
zlevel: -2,
itemStyle: {
normal: {
borderColor: '#1f1e26',
borderWidth: 4,
},
},
label: {
normal: {
position: 'inside',
show: false,
},
},
},
{
type: 'pie',
radius: ['42%', '45%'],
center: ['50%', '50%'],
data: [
{
hoverOffset: 1,
value: props.value, //最内圈圆环
name: '',
itemStyle: {
color: props.color[1],
},
label: {
show: false,
},
labelLine: {
normal: {
smooth: true,
lineStyle: {
width: 10,
},
},
},
hoverAnimation: false,
},
{
label: {
show: false,
},
labelLine: {
normal: {
smooth: true,
lineStyle: {
width: 0,
},
},
},
value: 100 - props.value, //动态传递
hoverAnimation: false,
itemStyle: {
color: '#3c3a48',
},
},
],
},
{
type: 'pie',
zlevel: 0,
silent: true,
radius: ['67%', '65.5%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie(),
},
{
type: 'pie',
zlevel: 0,
silent: true,
startAngle: -150,
radius: ['65%', '63.5%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie3(),
},
{
type: 'pie',
zlevel: 0,
silent: true,
startAngle: -140,
radius: ['68%', '66.5%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie(),
},
{
type: 'pie',
zlevel: 0,
silent: true,
radius: ['61%', '60%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie1(),
},
{
type: 'pie',
zlevel: 0,
silent: true,
startAngle: -140,
radius: ['61%', '60%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie2(),
},
{
type: 'pie',
zlevel: 0,
silent: true,
startAngle: -147.5,
radius: ['61%', '60%'],
z: 1,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie2(),
},
],
}
// ------------------------------
// 生成图表
Mychart.setOption(option)
window.onresize = function () {
Mychart.resize()
}
}
// -------------------------------
onMounted(() => {
setTimeout(() => {
markChart()
}, 8)
})