echarts饼图动态旋转效果

<template>
  <div class="alarmTotal" id="alarmTotal"></div>
</template>

<script>
let angle = 0; //角度,用来做简单的动画效果的
let value = 80;
var timerId;
let myChart = "";
var outerRidus1 = 0.8;
var outerRidus2 = 0.85;

//获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度)
function getCirlPoint(x0, y0, r, angle) {
  let x1 = x0 + r * Math.cos((angle * Math.PI) / 180);
  let y1 = y0 + r * Math.sin((angle * Math.PI) / 180);
  return {
    x: x1,
    y: y1,
  };
}
function draw() {
  angle = angle + 3;
}
//指示器颜色
let colorConstData = ["#FD1A0C", "#0064F9", "#FEDB65", "#7E55F3"];
//环的颜色
let colorStep = [
  [
    {
      offset: 0,
      color: "#FD1A0C", // 0% 处的颜色
    },
    {
      offset: 1,
      color: "#FF824D", // 100% 处的颜色
    },
  ],
  [
    {
      offset: 0,
      color: "#0060FF", // 0% 处的颜色
    },
    {
      offset: 1,
      color: "#00EFFE", // 100% 处的颜色
    },
  ],
  [
    {
      offset: 0,
      color: "#FFA600", // 0% 处的颜色
    },
    {
      offset: 1,
      color: "#FEDB65", // 100% 处的颜色
    },
  ],

  [
    {
      offset: 0,
      color: "#7E55F3", // 0% 处的颜色
    },
    {
      offset: 1,
      color: "#7E55F3", // 100% 处的颜色
    },
  ],
];
export default {
  name: "alarmTotal",
  props: ["alarmLevelData", "allNum"],
  data() {
    return {
      option: {},
    };
  },
  watch: {
    alarmLevelData: function (val, old) {
      this.refreshOpt();
    },
  },

  mounted() {
    myChart = this.$echarts.init(document.getElementById("alarmTotal"));
    this.resizeFn = this.debounce(
      () => {
        this.refreshOpt();
        // 通过捕获系统的onresize事件触发需要执行的事件
        myChart.resize();
      },
      1000,
      this.option
    );
    window.addEventListener("resize", this.resizeFn);
  },

  methods: {
    debounce(fn, delay, option) {
      let timer = null; //借助闭包
      return function () {
        if (timer) {
          clearTimeout(timer); //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
          timer = setTimeout(fn, delay);
        } else {
          timer = setTimeout(fn, delay); // 进入该分支说明当前并没有在计时,那么就开始一个计时
        }
      };
    },
    refreshOpt() {
      let series = this.alarmLevelData.map((item, index) => {
        return {
          value: item.count,
          name: item.value,
          itemStyle: {
            normal: {
              color: {
                // 完成的圆环的颜色
                colorStops: colorStep[index],
              },
              label: {
                textStyle: {
                  color: colorConstData[index],
                },
              },
            },
          },
          label: {
            show: true,
            position: "outside",
            formatter: `{b}:{c}个`,
            color: colorConstData[index],
          },
        };
      });
      let series2 = this.alarmLevelData.map((item, index) => {
        return {
          value: item.count,
          name: item.value,
          itemStyle: {
            normal: {
              color: {
                // 完成的圆环的颜色
                colorStops: colorStep[index],
              },
              opacity: 0.5,
            },
          },
        };
      });

      this.option = {
        legend: {
          orient: "vertical",
          show: true,
          right: "10",
          top: 30,
          y: "center",
          icon: "pin",
          itemGap: 30,
          textStyle: {
            fontSize: 12,
            lineHeight: 20,
            color: "#fft", //就是这个!超神奇
          },
        },
        tooltip: {
          show: true,
          valueFormatter: `{b}:{c}个`,
        },
        series: [
          // 最外层圆
          {
            type: "pie",
            radius: ["69%", "55%"],
            center: ["50%", "50%"],
            hoverAnimation: false,
            data: series,

            labelLine: {
              smooth: true,
              normal: {
                length: 35,
                lineStyle: {
                  width: 1,
                },
              },
            },
          },
          // 内圆 + 中间文字
          {
            type: "pie",
            radius: ["60%", "40%"],
            center: ["50%", "50%"],
            hoverAnimation: false,
            z: 10,
            label: {
              position: "center",
              formatter: () => {
                return `告警总数\r\n{total|${this.allNum}} 个`;
              },
              rich: {
                total: {
                  fontSize: 24,
                  color: "#00ffcc",
                  fontWeight: 600,
                },
              },
              color: "#FFFFFF",
              fontSize: 16,
              lineHeight: 30,
              fontWeight: 500,
            },
            data: series2,
            labelLine: {
              show: false,
            },
          },

          // 紫色线1 + 点
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              return {
                type: "arc",
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r:
                    (Math.min(api.getWidth(), api.getHeight()) / 2) *
                    outerRidus1, // 180,
                  startAngle: ((0 + angle) * Math.PI) / 180,
                  endAngle: ((90 + angle) * Math.PI) / 180,
                },
                style: {
                  stroke: "#8383FA",
                  fill: "transparent",
                  lineWidth: 1.5,
                },
                silent: true,
              };
            },
            data: [0],
          },
          // 紫色线1点
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              let x0 = api.getWidth() / 2;
              let y0 = api.getHeight() / 2;
              let r =
                (Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus1;
              let point = getCirlPoint(x0, y0, r, 0 + angle);
              return {
                type: "circle",
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4,
                },
                style: {
                  stroke: "#8450F9", //绿
                  fill: "#8450F9",
                },
                silent: true,
              };
            },
            data: [0],
          },
          // 蓝色
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              return {
                type: "arc",
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r:
                    (Math.min(api.getWidth(), api.getHeight()) / 2) *
                    outerRidus1, // 180,
                  startAngle: ((180 + angle) * Math.PI) / 180,
                  endAngle: ((270 + angle) * Math.PI) / 180,
                },
                style: {
                  stroke: "#4386FA",
                  fill: "transparent",
                  lineWidth: 1.5,
                },
                silent: true,
              };
            },
            data: [0],
          },
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              let x0 = api.getWidth() / 2;
              let y0 = api.getHeight() / 2;
              let r =
                (Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus1; // 180
              let point = getCirlPoint(x0, y0, r, 180 + angle);
              return {
                type: "circle",
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4,
                },
                style: {
                  stroke: "#4386FA", //绿
                  fill: "#4386FA",
                },
                silent: true,
              };
            },
            data: [0],
          },
          // 橘色
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              return {
                type: "arc",
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r:
                    (Math.min(api.getWidth(), api.getHeight()) / 2) *
                    outerRidus2, // 200,
                  startAngle: ((250 + -angle) * Math.PI) / 180,
                  endAngle: ((10 + -angle) * Math.PI) / 180,
                },
                style: {
                  stroke: "#0CD3DB",
                  fill: "transparent",
                  lineWidth: 1.5,
                },
                silent: true,
              };
            },
            data: [0],
          },
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              let x0 = api.getWidth() / 2;
              let y0 = api.getHeight() / 2;
              let r =
                (Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus2; // 200;
              let point = getCirlPoint(x0, y0, r, 250 + -angle);
              return {
                type: "circle",
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4,
                },
                style: {
                  stroke: "#0CD3DB", //绿
                  fill: "#0CD3DB",
                },
                silent: true,
              };
            },
            data: [0],
          },
          // 粉色
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              return {
                type: "arc",
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r:
                    (Math.min(api.getWidth(), api.getHeight()) / 2) *
                    outerRidus2, // 200,,
                  startAngle: ((70 + -angle) * Math.PI) / 180,
                  endAngle: ((200 + -angle) * Math.PI) / 180,
                },
                style: {
                  stroke: "#FF8E89",
                  fill: "transparent",
                  lineWidth: 1.5,
                },
                silent: true,
              };
            },
            data: [0],
          },
          //粉色点
          {
            type: "custom",
            coordinateSystem: "none",
            renderItem: function (params, api) {
              let x0 = api.getWidth() / 2;
              let y0 = api.getHeight() / 2;
              let r =
                (Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus2; // 200,;
              let point = getCirlPoint(x0, y0, r, 70 + -angle);
              return {
                type: "circle",
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4,
                },
                style: {
                  stroke: "#FF8E89", //粉
                  fill: "#FF8E89",
                },
                silent: true,
              };
            },
            data: [0],
          },
        ],
      };
      if (timerId) {
        clearInterval(timerId);
      }
      timerId = setInterval(() => {
        //用setInterval做动画感觉有问题
        draw();
        myChart.setOption(this.option, true);
      }, 1000);
    },
  },
};
</script>

<style lang="less" scoped>
.alarmTotal {
  width: 100%;
  height: 230px;
}
</style>

 


版权声明:本文为weixin_38233449原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。