echarts双环形图制作

先看最终效果

在这里插入图片描述
/**

  • 双环形图绘制原理:
    1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠
    1. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图
    1. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染

*/

代码块

<template>
   <div ref="target" class="w-full h-full"></div>
</template>

<script setup>
import { onMounted, ref, watch } from "vue";
import * as echarts from "echarts";

const props = defineProps({
  data: {
    type: Object,
    required: true,
  },
});

const target = ref(null);
let mChart = null;
onMounted(() => {
  mChart = echarts.init(target.value);
  renderChart();
});

/**
 * 双环形图绘制原理:
 * 1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠
 * 2. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图
 * 3. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染
 */
const getSeriesData = () => {
  const series = [];

  props.data.abnormals.forEach((item, index) => {
    // 上层环形绘制
    series.push({
      name: item.name,
      // 使用饼图绘制,减少饼图宽度即为环形图
      type: "pie",
      // 逆时针排布
      clockWise: false,
      // 不展示鼠标移入动画
      hoverAnimation: false,
      // 半径位置,需要依次递减,否则会重复在一处进行展示
      radius: [73 - index * 15 + "%", 68 - index * 15 + "%"],
      // 中心点
      center: ["55%", "55%"],
      // 不展示 label
      label: { show: false },
      // 数据配置
      data: [
        // 设置数据与名称
        { value: item.value, name: item.name },
        // 最大数据,展示比例
        {
          value: 1000,
          name: "",
          itemStyle: { color: "rgba(0,0,0,0)", borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false,
        },
      ],
    });

    // 底层图
    series.push({
      name: item.name,
      type: "pie",
      // 图形不响应事件
      silent: true,
      // z-index: 置于底层
      z: 1,
      // 逆时针排布
      clockWise: false,
      // 不展示鼠标移入动画
      hoverAnimation: false,
      // 半径位置,需要依次递减,否则会重复在一处进行展示
      radius: [73 - index * 15 + "%", 68 - index * 15 + "%"],
      // 中心点
      center: ["55%", "55%"],
      // 不展示 label
      label: { show: false },
      // 数据
      data: [
        // 绘制底线 75%
        {
          value: 7.5,
          itemStyle: { color: "rgb(3, 31, 62)", borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false,
        },
        // 绘制底线 25% 透明区域
        {
          value: 2.5,
          name: "",
          itemStyle: { color: "rgba(0,0,0,0)", borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false,
        },
      ],
    });
  });

  return series;
};

const renderChart = () => {
  const options = {
    // 图例配置
    legend: {
      show: true,
      // 图例色块
      icon: "circle",
      // 位置
      top: "14%",
      left: "60%",
      // 展示数据
      data: props.data.abnormals.map((item) => item.name),
      // 总宽度(一列)
      width: -5,
      // 每个色块的宽
      itemWidth: 10,
      // 每个色块的高度
      itemHeight: 10,
      // item 间距
      itemGap: 6,
      // 展示内容
      formatter: function (name) {
        return "{title|" + name + "}";
      },
      // 字体配置
      textStyle: {
        rich: {
          title: {
            fontSize: 12,
            lineHeight: 5,
            color: "rgba(255,255,255,0.8)",
          },
        },
      },
    },
    // 提示层
    tooltip: {
      show: true,
      trigger: "item",
      formatter: "{a}<br>{b}:{c}({d}%)",
    },
    // Y 轴展示选项
    yAxis: [
      {
        type: "category",
        // 反向展示
        inverse: true,
        // 不展示轴线
        axisLine: {
          show: false,
        },
        // 不展示刻度
        axisTick: {
          show: false,
        },
      },
    ],
    // X 轴不展示
    xAxis: [
      {
        show: false,
      },
    ],
    // 每两个标记一条线
    series: getSeriesData(),
  };

  mChart.setOption(options);
};

// 监听数据的变化,重新渲染图表
watch(
  () => props.data,
  () => {
    renderChart();
  }
);
</script>

<style lang="scss" scoped></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值