组件封装(不断旋转的圆形饼图:动画样式)

 组件:随便取名字吧

配置:

dealRate: '89%', // 饼图圆环中心百分比数据
dealLabel: '处置率', // 饼图圆环中心名称
PieWidth: '135', // 旋转饼图的大小
labelImgWidth: '47', // label的图形大小
incidentTop: '19', // 右边tab距离顶部的高度: incident-box的margin-top
labelSize: '14', // 右侧label字体样式的大小
labelMarginBottm: '10', // 右侧label字体距离下面字体的距离
numValue: '24', // 右侧Value字体的大小
// 右边小模块的数据数组
tabsList: [{
  label: 'XX标题',
  value: '82554',
  icon: 'home/waitIncident',//图标icon
  color: '#FFB82F'
},],
<template>
  <div class="finish-statistis-container">
    <div class="circle-box" :style="`width:` + datalist.PieWidth + `px;` + `height:` + datalist.PieWidth + `px`">
      <div class="circle-img" />
      <div class="circle-con">
        <div class="num">{{ datalist.dealRate }}</div>
        <div class="label">{{ datalist.dealLabel }}</div>
      </div>
    </div>
    <div class="incident-box" :style="`margin-top:` + datalist.incidentTop + `px`">
      <div v-for="item in datalist.tabsList" class="incident">
        <img :style="'width:' + datalist.labelImgWidth + 'px;' + 'height:' + datalist.labelImgWidth + 'px'" :src="require(`@img/` + item.icon + `.png`)">
        <div class="wait">
          <div class="label" :style="`font-size:` + datalist.labelSize + 'px;' + 'margin-bottom:' + datalist.labelMarginBottm + 'px'">{{ item.label }}</div>
          <div class="num" :style="`color:${item.color}` + ';font-size:' + datalist.numValue + 'px;'">{{ item.value }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
/**
 * @param dealRate:饼图圆环中心百分比数据;dealLabel:饼图圆环中心名称;tabsList:右边小模块的数据数组
 *
 * */
export default {
  name: 'PieRotationModel',
  props: {
    pieData: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      datalist: {
        dealRate: '89%', // 饼图圆环中心百分比数据
        dealLabel: '处置率', // 饼图圆环中心名称
        PieWidth: '135', // 旋转饼图的大小
        labelImgWidth: '47', // label的图形大小
        incidentTop: '19', // 右边tab距离顶部的高度: incident-box的margin-top
        labelSize: '14', // 右侧label字体样式的大小
        labelMarginBottm: '10', // 右侧label字体距离下面字体的距离
        numValue: '24', // 右侧Value字体的大小
        // 右边小模块的数据数组
        tabsList: [
          {
            label: 'XX事件',
            value: '82554',
            icon: 'home/waitIncident',
            color: '#FFB82F'
          },
          {
            label: 'XX事件',
            value: '12952',
            icon: 'home/finishIncident',
            color: '#5DF4E0'
          }
        ]
      }
    }
  },
  watch: {
    pieData: {
      handler(nVue) {
        this.datalist.assign(this.pieData)
      },
      deep: true
    }
  },
  mounted() {
    this.datalist = this.pieData
  }
}
</script>

<style lang="scss" scoped>
$imgPath: '~@assets/images/home/';
.finish-statistis-container {
  display: flex;
  padding: 0 20px;
  height: calc(100% - 51px);
  vertical-align: center;
  // 动图样式
  .circle-box {
    position: relative;
    margin-left: 35px;
    background: url($imgPath + 'circle-background.png') no-repeat;
    background-size: 100% 100%;
  }
  .circle-img,
  .circle-con {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .circle-img {
    z-index: 1;
    background: url($imgPath + 'circle.png') no-repeat;
    background-size: 100% 100%;
    animation: rotate 4s linear infinite;
    -webkit-animation: rotate 4s linear infinite;
  }

  .circle-con {
    z-index: 2;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;

    .num {
      font-size: 24px;
      font-weight: bold;
      color: #5df4e0;
    }

    .label {
      font-size: 14px;
    }

    @keyframes rotate {
      0% {
        transform: rotate(0deg);
      }

      100% {
        transform: rotate(360deg);
        -webkit-transform: rotate(360deg);
        -moz-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        -o-transform: rotate(360deg);
      }
    }
  }

  // 事件数量
  .incident-box {
    margin: 19px 0 0 20px;
    .incident {
      display: flex;

      img {
        width: 47px;
        height: 47px;
      }

      &:first-child {
        margin-bottom: 13px;
      }

      .finish,
      .wait {
        margin: 1px 0 0 12px;
      }

      .wait {
        font-size: 24px;
        color: #ffb82f;
        line-height: 19px;
      }

      .finish {
        font-size: 24px;
        color: #5df4e0;
        line-height: 19px;
      }

      .label {
        font-size: 14px;
        color: #fff;
        font-weight: 400;
        line-height: 19px;
        margin-bottom: 10px;
      }
    }
  }
}
</style>

另一个旋转饼图样式:

 

 options:

options = {
        color: color,
        legend: {
          right: '10%',
          top: 'center',
          icon: 'circle',
          itemWidth: 8,
          itemHeight: 8,
          itemGap: 11,
          color: color,
          textStyle: {
            color: '#ffffff',
            fontsize: 12,
            rich: {
              title: {
                fontSize: 12,
                color: 'rgba(214, 244, 255, 1)',
                width: 80
              },
              x: {
                fontSize: 12,
                color: 'rgba(214, 244, 255, 1)',
                width: 10,
                textAlign: 'right'
              },
              value0: {
                fontSize: 12,
                color: '#05A5FF',
                fontWeight: 600
              },
              value1: {
                fontSize: 12,
                color: '#44FFA5',
                fontWeight: 600
              },
              value2: {
                fontSize: 12,
                color: '#FFDD3C',
                fontWeight: 600
              },
              value3: {
                fontSize: 12,
                color: '#00FFFF',
                fontWeight: 600
              },
              value4: {
                fontSize: 12,
                color: '#FDE056',
                fontWeight: 600
              }
            }
          },
          formatter: function(name) {
            const item = legend.filter(item => item.name === name)[0]
            return '{title|' + name + '}    {value' + item.index + '|' + Utils.number.numberThousandFormat(item.nums) + '}' + '{x|' + ' 项' + '}'
          }
        },
        tooltip: {
          show: true,
          trigger: 'item',
          transitionDuration: 0 // 动画延迟
        },
        series: [
          { // 外线1
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 4,
                  cy: api.getHeight() / 1.9,
                  r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77,
                  startAngle: (0 + angle) * Math.PI / 180,
                  endAngle: (90 + angle) * Math.PI / 180
                },
                style: {
                  stroke: '#4EE9E6',
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 内线1
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 4,
                  cy: api.getHeight() / 1.9,
                  r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77,
                  startAngle: (180 + angle) * Math.PI / 180,
                  endAngle: (270 + angle) * Math.PI / 180
                },
                style: {
                  stroke: '#4EE9E6',
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 外线2
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 4.0,
                  cy: api.getHeight() / 1.9,
                  r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9,
                  startAngle: (270 + -angle) * Math.PI / 180,
                  endAngle: (40 + -angle) * Math.PI / 180
                },
                style: {
                  stroke: '#4EE9E6',
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 外线2
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 4.0,
                  cy: api.getHeight() / 1.9,
                  r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9,
                  startAngle: (90 + -angle) * Math.PI / 180,
                  endAngle: (220 + -angle) * Math.PI / 180
                },
                style: {
                  stroke: '#4EE9E6',
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 绿点1
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 4
              const y0 = api.getHeight() / 1.9
              const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9
              const point = getCirlPoint(x0, y0, r, (90 + -angle))
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 2
                },
                style: {
                  stroke: '#66FFFF', // 粉
                  fill: '#66FFFF'
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 绿点2
            name: '', // 绿点
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 4
              const y0 = api.getHeight() / 1.9
              const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9
              const point = getCirlPoint(x0, y0, r, (270 + -angle))
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 2
                },
                style: {
                  stroke: '#66FFFF', // 粉
                  fill: '#66FFFF'
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 绿点3
            name: '',
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 4
              const y0 = api.getHeight() / 1.92
              const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77
              const point = getCirlPoint(x0, y0, r, (90 + angle))
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 2
                },
                style: {
                  stroke: '#66FFFF', // 粉
                  fill: '#66FFFF'
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 绿点4
            name: '', // 绿点
            type: 'custom',
            coordinateSystem: 'none',
            animationEasing: 'cubicInOut',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 4
              const y0 = api.getHeight() / 1.92
              const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77
              const point = getCirlPoint(x0, y0, r, (270 + angle))
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 2
                },
                style: {
                  stroke: '#66FFFF', // 粉
                  fill: '#66FFFF'
                },
                silent: true
              }
            },
            data: [0]
          },
          { // 最外的圈
            name: '',
            type: 'pie',
            clockWise: false,
            animationEasing: 'cubicInOut',
            radius: ['130%', '129%'],
            hoverAnimation: false,
            center: ['25%', '55%'],
            top: 'center',
            itemStyle: {
              normal: {
                label: {
                  show: false
                }
              }
            },
            data: data
          },
          {
            type: 'pie',
            top: 'center',
            startAngle: 90,
            clockwise: false,
            animationEasing: 'cubicInOut',
            center: ['25%', '55%'],
            legendHoverLink: false,
            hoverAnimation: false,
            radius: ['129%', '55%'],
            itemStyle: {
              opacity: 0.15
            },
            label: {
              show: false,
              position: 'center'
            },
            labelLine: {
              show: false
            },
            data: data2
          },
          {
            name: '',
            type: 'pie',
            clockWise: false,
            animationEasing: 'cubicInOut',
            center: ['25%', '55%'],
            radius: ['25.5%', '26%'],
            hoverAnimation: false,
            top: 'center',
            itemStyle: {
              normal: {
                label: {
                  show: false
                }
              }
            },
            data: data
          }
        ]
      }

 值的方法:配置或者data;angle:数字,this.data:值

   var data = []
      var data2 = []
      const legend = [] // 图例
      var trafficWay = this.data
      let total = 0
      this.data.forEach(item => { total += item.nums })
      var color = ['#3cadfe', '#07fcd9', '#fff499', '#08deff', '#FDE056', '#4ED33C', '#FF8A26', '#FF5252', '#9689FF', '#CB00FF']
      trafficWay.forEach((item, index) => {
        legend.push({
          nums: item.nums,
          name: item.name,
          index: index
        })
        data.push({
          value: item.nums,
          name: item.name,
          itemStyle: {
            normal: {
              borderWidth: 5,
              shadowBlur: 10,
              borderRadius: 10,
              borderColor: color[index],
              shadowColor: color[index]
            }
          }
        }, {
          value: total * 0.02,
          name: '',
          itemStyle: {
            normal: {
              label: {
                show: false
              },
              labelLine: {
                show: false
              },
              color: 'rgba(0, 0, 0, 0)',
              borderColor: 'rgba(0, 0, 0, 0)',
              borderWidth: 0
            }
          }
        })
        data2.push({
          value: item.nums,
          name: item.name,
          index: index
        },
        {
          value: total * 0.02,
          name: '',
          itemStyle: {
            normal: {
              label: {
                show: false
              },
              labelLine: {
                show: false
              },
              color: 'rgba(0, 0, 0, 0)',
              borderColor: 'rgba(0, 0, 0, 0)',
              borderWidth: 0,
              opacity: 0.2
            }
          }
        })
      })
      // 获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度)
      const getCirlPoint = (x0, y0, r, angle) => {
        const x1 = x0 + r * Math.cos(angle * Math.PI / 180)
        const y1 = y0 + r * Math.sin(angle * Math.PI / 180)
        return {
          x: x1,
          y: y1
        }
      }

this.data举例:

 dataList: [
        { nums: 1275, name: 'XXXX况' },
        { nums: 1275, name: 'XXXX开' },
        { nums: 1275, name: 'XXXX开' },
        { nums: 1275, name: 'XXXX开' },
        { nums: 1275, name: 'XXXX开' }
      ],

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值