vue+echarts封装一个可配置的环形图

效果展示

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

组件代码

<template>
  <div class="donut-chart">
    <div ref="chart" class="chart"></div>
  </div>
</template>

<script>
const OVERVIEW_COLOR_LIST = [
  '#6F9CF9',
  '#65DCAC',
  '#A486D5',
  '#F7C739',
  '#EB7F65',
  '#5DD4F7',
  '#43AFE8',
  '#FFAC68',
  '#4CBEBE',
  '#F697C1',
];
export default {
  name: 'DonutChart',
  props: {
    chartInfo: {
      type: Object,
      default: () => ({})
    },
  },
  data() {
    return {
      OVERVIEW_COLOR_LIST,
      chartColorList: [],
      chartVariable: {}, //不同标签个数对应变量
    };
  },
  watch: {
    chartInfo() {
      this.init();
    },
  },
  methods: {
    // 初始化数据
    init() {
      if (this.chartInfo.chartData) {
        const chartLen = this.chartInfo.chartData.length;
        if (!this.chartInfo.isChartData) {
          this.chartColorList = ['#ccc'];
        } else {
          if (this.chartInfo.colorList) {
            this.chartColorList = this.chartInfo.colorList;
          } else {
            this.chartColorList = OVERVIEW_COLOR_LIST;
          }
        }
        // 是否截断
        if (chartLen > 8) {
          this.chartVariable = {
            width: '350px',
            itemGap: 15,
            isLegendTooltip: true,
            formatter: (name) => {
              if (name.length > 5) {
                name = name.slice(0, 4) + '...';
              }
              const arr = ['{item|' + name + '}'];
              return arr.join('\n');
            },
          };
        } else {
          this.chartVariable = {
            width: '300px',
            itemGap: 20,
            isLegendTooltip: false,
            formatter: (name) => {
              const arr = ['{item|' + name + '}'];
              return arr.join('\n');
            },
          };
        }
        // 图形大小
        if (this.chartInfo.size === 'large') {
          this.chartVariable.center = ['20%', '45%'];
          this.chartVariable.radius = ['60%', '75%'];
          this.chartVariable.titleTop = '30%';
          this.chartVariable.titleFontSize = {
            val: 24,
            name: 16,
          };
          this.chartVariable.legendTop = chartLen > 18 ? '10%' : '25%';
        } else {
          this.chartVariable.center = ['20%', '35%'];
          this.chartVariable.radius = ['50%', '65%'];
          this.chartVariable.titleTop = '20%';
          this.chartVariable.titleFontSize = {
            val: 20,
            name: 12,
          };
          this.chartVariable.legendTop = '15%';
        }
        this.paintChart();
      }
    },
    // 绘制图表
    paintChart() {
      const chartDom = this.$echarts.init(this.$refs.chart);
      if (chartDom) {
        const option = {
          color: this.chartColorList,
          tooltip: {
            show: true,
          },
          title: [
            {
              text:
                '{val|' +
                this.chartInfo.chartCount.toLocaleString() +
                '}\n{name|' +
                this.chartInfo.chartName +
                '}',
              top: this.chartVariable.titleTop,
              left: '19.5%',
              textAlign: 'center',
              textStyle: {
                rich: {
                  name: {
                    fontSize: this.chartVariable.titleFontSize.name,
                    color: '#6E7784',
                    align: 'center',
                    padding: [10, 0],
                  },
                  val: {
                    fontSize: this.chartVariable.titleFontSize.val,
                    fontWeight: 'bold',
                    color: '#151631',
                    align: 'center',
                    padding: [10, 0],
                  },
                },
              },
            },
          ],
          legend: {
            icon: 'circle',
            y: 'center',
            x: 'right',
            width: this.chartVariable.width,
            left: '43%',
            top: this.chartVariable.legendTop,
            itemWidth: 8,
            itemHeight: 8,
            itemGap: this.chartVariable.itemGap,
            formatter: this.chartVariable.formatter,
            tooltip: {
              show: this.chartVariable.isLegendTooltip,
            },
            textStyle: {
              color: '#6E7784',
              rich: {
                item: {
                  backgroundColor: '#fff',
                  width: 80,
                },
              },
            },
          },
          series: [
            {
              name: this.chartInfo.chartName,
              type: 'pie',
              radius: this.chartVariable.radius,
              center: this.chartVariable.center,
              tooltip: {
                trigger: 'item',
                borderWidth: 2,
                borderColor: '#ECECEE',
                backgroundColor: '#fff',
                textStyle: {
                  color: '#666666',
                },
                position: 'right',
                padding: 20,
                formatter: (params) => {
                  const res = `${params.data.name}<br />占比:${this.chartInfo.chartCount
                    ? Number(
                      (params.data.value / this.chartInfo.chartCount) * 100
                    ).toFixed(2)
                    : 100}%`;
                  return res;
                },
              },
              emphasis: {
                focus: 'self',
              },
              itemStyle: {
                borderWidth: 1,
                borderColor: '#fff',
              },
              avoidLabelOverlap: false,
              label: {
                show: false,
              },
              data: this.chartInfo.chartData,
            },
          ],
        };
        chartDom && chartDom.setOption(option);
        chartDom.on('click', (param) => {
          this.chartInfo.chartClickFunc(param);
        });
        const sizeFun = () => {
          chartDom.resize();
        };
        window.addEventListener('resize', sizeFun);
        this.$once('hook:beforeDestroy', function () {
          this.$echarts.dispose(chartDom);
        });
      }
    },
  },
};
</script>

<style lang="less">
.donut-chart {
  height: 320px;
  width: 100%;
  & .chart {
    height: 320px;
    width: 100%;
    min-width: 600px;
  }
}
</style>

使用方式

<template>
  <div>
    <donut-chart :chartInfo="normalInfo"/>
  </div>
</template>

<script>
export default {
  data(){
    return{
      normalInfo:{},
    }
  },
  mounted(){
    let chartData = [];
      let eventCount = 11288;
      let isChartData = true;
      let dataList=[
        {
          "name": "互联网",
          "count": 11078,
        },
        {
          "name": "境外互联网",
          "count": 5604,
        },
        {
          "name": "境内互联网",
          "count": 1049,
        },
        {
          "name": "互联网-境内",
          "count": 523,
        },
        {
          "name": "局域网-生产网",
          "count": 1049,
        },
        {
          "name": "局域网-测试网",
          "count": 523,
        }
      ];
      dataList.forEach(item=>{
        chartData.push({
          value: item.count,
          name: item.name,
        });
      })
      this.normalInfo = {
        chartName: "API个数",
        chartData: chartData,
        chartCount: eventCount,
        isChartData: isChartData,
        size: "large",
        chartClickFunc: (params) => {},
      };
  },
}
</script>

属性说明

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值