动态饼图

ECharts 上有很多精美的图表,但它们大部分都是静态的,而且官方也没有提供做动态效果的 API,所以我们需要通过使用官方已经提供的功能再加上一些逻辑操作做出动态效果。

自动逐条滚动并且显示标题的饼图

本教程基于 ECharts v5.3.2 版本, 使用定时器依次将拼图里的各个块做高亮显示以实现自动轮播的效果。

<script>
import Vue from "vue";
import * as echarts from 'echarts'

export default {
  data() {
    return {
      pieChart: {},
      pieOption: {
        series: [
          {
            type: "pie",
            legendHoverLink: false,
            roseType: false,
            selectedMode: false,
            clockwise: false,
            // minAngle: 30,
            left: 0,
            top: 0,
            right: 0,
            bottom: 0,
            // radius: '60%',
            radius: ["40%", "80%"],
            silent: false,
            data: [
              {
                value: 10,
                name: "10",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#3BF6DE", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#0588B6", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 20,
                name: "20",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#2442FF", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#4B7BFF", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 30,
                name: "30",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#9A50FF", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#5E4EEB", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 40,
                name: "40",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#006BE3", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#003E8A", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 50,
                name: "50",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#00B0FF", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#1784D9", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 60,
                name: "60",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#5396FF", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#7CBEFF", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 70,
                name: "70",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#D93A7B", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#9A34AE", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 80,
                name: "80",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#FEDB64", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#FA6B14", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 90,
                name: "90",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#D29C0F", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#FFE272", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
              {
                value: 100,
                name: "100",
                itemStyle: {
                  color: {
                    type: "radial",
                    x: 1,
                    y: 1,
                    r: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: "#390FD2", // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: "#72B7FF", // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
            ],
            label: {
              color: "#FFFFFF",
              show: false,
              position: "center",
              bleedMargin: 0,
              align: "right",
              fontFamily: "PingFangSC-Regular, PingFang SC",
              padding: 0,
              fontSize: 16,
              // formatter: '{per|{d}%}\n{hr|}\n{a|}\n{b|{b}}'
              formatter: "{b}\n\n{d}%",
            },
            labelLine: {
              smooth: false,
              lineStyle: {
                color: "#566DEA",
              },
            },
            animationType: "expansion",
            animationEasing: "linear",
            emphasis: {
              label: {
                show: true,
                fontSize: 16 * 1.5,
                fontWeight: "bold",
              },
            },
          },
        ],
      },
      pieTimer: undefined,
      pieDataLen: 0,
      pieCurrentIndex: 0,
      piePrevIndex: 0,
    };
  },
  mounted() {
    this.pieChart = echarts.init(this.$refs.main, "", { renderer: "svg" });
    window.onresize = () => {
      this.pieChart.resize();
    };

    this.pieChart.setOption(this.pieOption);
    if (this.pieOption.series !== undefined) {
      this.pieDataLen = this.pieOption.series[0].data?.length - 1;
    }
    Vue.nextTick(() => {
      clearTimeout(this.pieTimer);
      this.pieToolTipLoop(true);
    });
  },
  beforeDesotry() {
    clearTimeout(this.pieTimer);
  },
  methods: {
    pieToolTipLoop(isInit) {
      // 切换饼图上现实的Tip
      this.pieTimer = setTimeout(() => {
        if (isInit) {
          this.pieChart.dispatchAction({
            type: "highlight",
            seriesIndex: 0,
            dataIndex: this.pieCurrentIndex,
          });
        } else {
          if (this.pieCurrentIndex >= this.pieDataLen) {
            this.piePrevIndex = this.pieDataLen;
            this.pieCurrentIndex = 0;
          } else {
            this.piePrevIndex = this.pieCurrentIndex;
            this.pieCurrentIndex++;
          }
          this.pieChart.dispatchAction({
            type: "highlight",
            seriesIndex: 0,
            dataIndex: this.pieCurrentIndex,
          });
          this.pieChart.dispatchAction({
            type: "downplay",
            seriesIndex: 0,
            dataIndex: this.piePrevIndex,
          });
        }

        this.pieToolTipLoop(false);
      }, (1000 / 60) * 120);
    },
  },
};
</script>