大屏项目_动态展示进度条,达到立体效果(4)

374 阅读2分钟

项目需求是环状进度条,在环状进度条上进行分隔,根据数据动态展示百分比

对比antd的进度条,实现起来比较麻烦,决定用echarts进行绘制

使用echarts绘制环状进度条

    import * as echarts from 'echarts';
    import { useEffect } from 'react';
    import { useSelector } from 'umi';
    import styles from './index.less';

    const PieChat = () => {
    
      // score 是后端返回的百分比
      const score = useSelector((state) => state.screen.score);
      let config = {
        color: ['#3AC5FE', '#3AC5FE'],
        
        // data里的第一项是达标,第二项则是不达标
        data: [
          {
            name: '',
            value: score,
          },
          {
            name: '',
            value: 100 - score,
          },
        ],
      };
      var modelOption = {
        // backgroundColor: '#0a1723',
        color: [
          {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 1,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: config.color[0],
              },
              {
                offset: 1,
                color: config.color[1],
              },
            ],
            global: false,
          },
          'rgba(58, 197, 254,0.5)',
        ],
        series: [
          //环形
          {
            name: '',
            type: 'pie',
            radius: ['63%', '77%'],
            center: ['50%', '50%'],
            emphasis: {
              scale: false,
              label: {
                show: false,
              },
            },
            zlevel: 1,
            labelLine: {
              show: false,
            },
            data: config.data,
          },
          //环形分割线
          {
            name: '分割线',
            type: 'gauge',
            radius: '84%', //配合splitLine里的length一起调
            clockwise: true,
            startAngle: '90',
            center: ['50%', '50%'],
            endAngle: '-269.9999',
            splitNumber: 20,
            zlevel: 2,
            detail: {
              offsetCenter: [10, 20],
              formatter: ' ',
            },
            axisLine: {
              lineStyle: {
                width: 0,
                opacity: 0,
              },
            },
            axisTick: {
              show: false,
            },
            markArea: {
              itemStyle: {
                color: '#0056FF',
              },
            },
            splitLine: {
              show: true,
              length: 21, //配合radius一起调
              padding: [0, 0, 0],
              lineStyle: {
                color: '#121d43',
                // color: '#0056FF',
                width: 5,
                opacity: 0.8,
              },
            },
            axisLabel: {
              show: false,
            },
          },
        ],
      };
      useEffect(() => {
        var modelChart = echarts.init(document.getElementById('modelPieChart'));
        modelOption && modelChart.setOption(modelOption);
        window.addEventListener('resize', () => {
          modelChart && modelChart.resize();
        });
      }, []);

      return (
        <div className={styles.pieChat}>
          <div id='modelPieChart' style={{ height: '300px' }} />
        </div>
      );
    };

    export default PieChat;

将所绘制的图形用div包裹,设置样式

     .pieChat {
        position: absolute;
        top: 30px;
        width: 100%;
        height: 300px;
        transform: rotateX(60deg);
        transform-style: preserve-3d;
        
        // 旋转效果,打开时需要将上面的注释
        // animation: rotate 10s linear 0s infinite;
      }
      
      @keyframes rotate {
          0% {
            transform: rotateX(60deg) rotateZ(0);
            transform-style: preserve-3d;
          }
          100% {
            transform: rotateX(60deg) rotateZ(360deg);
            transform-style: preserve-3d;
          }
     }
    

这里耗费了大量时间,在网上找了很多方法,开始尝试canvas,three.js。短时间内无法实现,想用transform属性,但网上的资料只有其倾斜的方法,在实际操作时,图片由于倾斜会导致变形,达不到预期的效果。 最后通过组长研究,不到一会,就实现了。transform-style: preserve-3d;这个属性很重要,需要牢记。