vue3 + echarts 二次开发百分比饼图

效果图:

  • 安装  
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)
})

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大大大大白呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值