echarts绘制有立体感的饼状图

echarts yekong

echarts在绘制饼状图的时候,为了让饼状图能够多样性,会设计出多种不同样式的饼状图,今天的饼状图是有一种立体感的饼状图,效果如下:

echarts绘制有立体感的饼状图

这里的饼状图分为两层,我们让两层饼状图稍微错位一点再给一个深浅不同的颜色就实现了我们想要的效果。

实例代码

<template>
  <div class="echartsBody">
    <div class="echartsBody1" ref="echarts1"></div>
    <div class="echartsBg">
      <div class="echartsBgInner"></div>
    </div>
  </div>
</template>

<script>
import * as echarts from "echarts"

export default {
  name: 'echarts1',
  components: {},
  data() {
    return {}
  },
  props: {
    list: {
      type: Array,
      default() {
        return [];
      }
    },
    shadowColor: {
      type: String,
      default() {
        return 'rgba(254, 175, 87, 0.5)';
      }
    },
    title: {
      type: String,
      default() {
        return '各班组效率';
      }
    },
    total: {
      type: String,
      default() {
        return 0;
      }
    },
  },
  mounted() {
    var that = this;
    const viewElem = document.body;
    // 监听窗口变化,重绘echarts
    const resizeObserver = new ResizeObserver(() => {
      setTimeout(() => {
        that.drawEcharts();
      }, 300)
    });
    resizeObserver.observe(viewElem);
  },
  computed: {
    colorList: function () {
      var that = this;
      var colorList = []
      that.list.forEach((type) => {
            if (type.checked) {
              var color = new echarts.graphic.LinearGradient(0, 0, 1, 1, [{
                offset: 0,
                color: type.color1
              }, {
                offset: 1,
                color: type.color2
              }])
              colorList.push(color)
            }
          }
      );
      return colorList
    }
  },
  methods: {
    drawEcharts() {
      var that = this
      let myChart = echarts.init(this.$refs.echarts1)
      var colors = this.colorList
      var data = []
      var data2 = []
      that.list.forEach((type) => {
        if (type.checked) {
          var datas = {
            ...type,
            itemStyle: {
              normal: {
                color: new echarts.graphic.LinearGradient(0, 0, 1, 1, [{
                  offset: 0,
                  color: type.color1
                }, {
                  offset: 1,
                  color: type.color2
                }]),
                shadowColor: that.shadowColor
              }
            }
          }
          data.push(datas)
        }
      });
      that.list.forEach((type) => {
        if (type.checked) {
          var datas = {
            ...type,
            itemStyle: {
              normal: {
                color: new echarts.graphic.LinearGradient(0, 0, 1, 1, [{
                  offset: 0,
                  color: type.color1.replace('1)', '0.5)')
                }, {
                  offset: 1,
                  color: type.color2.replace('1)', '0.5)')
                }]),
              }
            }
          }
          data2.push(datas)
        }
      });
      var option = {
        // color: colors,
        tooltip: {
          trigger: 'item',
          // formatter: '{a} {b} : {c} ({d}%)'
        },
        series: [
          {
            type: 'pie',
            center: ['50%', '50%'],
            radius: ['55%', '75%'],
            labelLine: {
              normal: {
                length: 20
              }
            },
            z: 1,
            label: {
              show: true,
              formatter: function (params) {
                return `{a|${params.name}}\n{b|${params.percent}%}`
              },
              rich: {
                a: {
                  fontSize: 14,
                  fontFamily: 'MiSans',
                  fontWeight: 400,
                  color: '#D4F2F1'
                },
                b: {
                  fontSize: 16,
                  fontFamily: 'MiSans',
                  fontWeight: 600,
                  color: '#FFFFFF'
                }
              },
            },
            itemStyle: {
              normal: {
                borderColor: '#142b47',
                borderWidth: 1
              }
            },
            data: data
          },
          {
            z: 0,
            type: 'pie',
            center: ['50%', '48.5%'],
            radius: ['55%', '75%'],
            labelLine: {
              normal: {
                length: 20
              }
            },
            label: {
              show: false,
              position: 'inside',
              formatter: '{d}%',
              color: '#fff',
              fontSize: 16
            },
            itemStyle: {
              normal: {
                borderColor: '#142b47',
                borderWidth: 1
              }
            },
            data: data2
          },
        ]
      }
      myChart.clear()
      myChart.resize()
      myChart.setOption(option)
    },
  }
}
</script>

<style lang="scss" scoped>
.echartsBody {
  position: relative;
  width: 100%;
  height: calc(100% - 0px);


  .echartsBody1 {
    position: relative;
    width: 100%;
    height: calc(100% - 0px);
  }

  .echartsBody2 {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: calc(100% - 0px);
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: column;
    align-content: flex-start;
    pointer-events: none;

    .echartsTitle {
      font-size: 30px;
      font-family: DIN;
      font-weight: normal;
      color: #FFFFFF;
      text-shadow: 0 0 10px rgba(120, 168, 238, 1.00);
    }

    .echartsDesc {
      font-size: 14px;
      font-family: MicrosoftYaHei;
      font-weight: 400;
      color: #9DB9E9;
    }
  }

  .echartsBg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;

    .echartsBgInner {
      width: 100%;
      height: 100%;
      background: url("./assets/echartsbg.png") center center no-repeat;
      background-size: contain;
      scale: 0.9;
      animation: rotate 3s linear infinite;
    }
  }
}

@keyframes rotate {
  0% {
    transform: rotateZ(0deg); /*从0度开始*/
  }
  100% {
    transform: rotateZ(360deg); /*360度结束*/
  }
}
</style>

传值

<template>
  <div class="echartsBodys">
    <div class="echartsTop">
      <echarts1 title="立体饼状图" :total="total" :list="list" ref="echarts"></echarts1>
    </div>
    <div class="list">
      <div class="listItem cur" @click="getChecked(index)" v-for="(item,index) in list" :key="index">
        <div class="listIteml">
          <div class="dot" :class="{disabled:!item.checked}"
               :style="'background: linear-gradient(0deg,'+item.color1+' 0%, '+item.color2+' 100%);'"></div>
          <span :class="{disabled:!item.checked}">{{ item.name }}</span>
        </div>
        <div class="num"
             v-if="item.checked">
          {{ item.percentage }}%
        </div>
      </div>
    </div>
  </div>
</template>

<script>

import echarts1 from "./echarts/echarts.vue";

export default {
  name: "title",
  data() {
    return {
      // 颜色格式要用rgba格式,以便于echarts根据颜色设置透明度为0.8的背景形成立体饼状图
      list: [
        {
          name: '类型1',
          value: 100,
          checked: true,
          color1: 'rgba(254, 246, 71, 1)',
          color2: 'rgba(254, 246, 71, 1)',
          percentage: 0
        },
        {
          name: '类型2',
          value: 100,
          checked: true,
          color1: 'rgba(74, 231, 230, 1)',
          color2: 'rgba(74, 231, 230, 1)',
          percentage: 0
        },
        {
          name: '类型3',
          value: 100,
          checked: true,
          color1: 'rgba(252, 108, 126, 1)',
          color2: 'rgba(252, 108, 126, 1)',
          percentage: 0
        },
        {
          name: '类型4',
          value: 100,
          checked: true,
          color1: 'rgba(101, 252, 125, 1)',
          color2: 'rgba(101, 252, 125, 1)',
          percentage: 0
        },
        {
          name: '类型5',
          value: 100,
          checked: true,
          color1: 'rgba(252, 168, 108, 1)',
          color2: 'rgba(252, 168, 108, 1)',
          percentage: 0
        },
        {
          name: '类型6',
          value: 100,
          checked: true,
          color1: 'rgba(16, 173, 255, 1)',
          color2: 'rgba(16, 173, 255, 1)',
          percentage: 0
        },
      ]
    }
  },
  computed: {
    total: function () {
      var total = 0
      this.list.forEach((type) => {
        total += type.value
      });
      return total
    },
  },
  watch: {
    total: function (newTotal, oldTotal) {
      this.list.forEach((type) => {
        type.percentage = Math.floor((type.value / this.total) * 100);
      });
    }
  },
  components: {echarts1},
  mounted() {
    this.list.forEach((type) => {
      type.percentage = Math.floor((type.value / this.total) * 100);
    });
  },
  methods: {
    getChecked(index) {
      this.list[index].checked = !this.list[index].checked
      this.$refs.echarts.drawEcharts()
    },
  },

}
</script>

<style lang="scss" scoped>


.echartsBodys {
  width: 100%;
  position: relative;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: column;
  align-content: flex-start;

  .list {
    position: relative;
    width: 100%;
    height: 100px;
    //background: url("./assets/jiaobiaobg.png") no-repeat;
    //background-size: 100% 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    flex-direction: row;
    align-content: flex-start;
    margin-top: 20px;

    .listItem {
      font-size: 14px;
      display: flex;
      height: 50%;
      width: calc(33.33% - 20px);
      margin: 0 auto;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;

      .listIteml {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
        font-size: 14px;
        font-family: MicrosoftYaHei;
        font-weight: 400;
        color: #FFFFFF;
        width: 340px;
      }

      span {
        font-size: 14px;
        font-family: MiSans;
        font-weight: 400;
        color: #D4F2F1;
      }

      .dot {
        width: 4px;
        height: 14px;
        background: #FEF647;
        border-radius: 2px;
        margin-right: 10px;
      }

      .dot.disabled {
        background: rgba(#999, 0.8) !important;
      }

      span.disabled {
        color: rgba(#999, 0.8) !important;
      }

      .num {
        font-size: 14px;
        font-family: MiSans;
        font-weight: 400;
        color: #FFFFFF;
      }
    }
  }

  .echartsTop {
    position: relative;
    width: 100%;
    height: calc(100% - 100px);
  }
}

</style>

项目应用

人工智能人才需求数据可视化

更多饼状图效果

echarts 饼状图效果实例汇总

喜欢