echarts 水波图

参考链接:https://blog.csdn.net/weixin_42146585/article/details/121180829

首先得首先,先下载水波球插件依赖

npm install echarts-liquidfill

然后引用 import 'echarts-liquidfill'

 

首先每个水波图都是联调接口后,遍历渲染出来的。

由于大屏区域限制,只能容下四个的位置,所以又做了一个自动轮播。

颜色是指定了六个颜色,根据数据长度循环出来的。

 

使用:

 <echartWave ref="waveEchat" :waveList="waveList"></echartWave>
   api(id).then(res => {
        if (res.data.code == 200) {
          res.data.data.address.map((val, index) => {
            val.id = index;
          });//要给每一个id,很重要
          this.waveList = res.data.data.address;
          this.$nextTick(() => {
            this.$refs.waveEchat.getData();
          });
        }
      });
 
引用:
import echartWave from './components/echartWave.vue'; //水波图组件

 

 

<!--
 * @Description:领导驾驶舱-新版-水波图组件
 * @Author: 
 * @LastEditTime: 2023-05-20 15:41:35

 // https://www.jianshu.com/p/85774c1a67d5 轮播参考
-->
<template>
  <div
    class="wave-wrap"
    @mouseover="changeInterval(true)"
    @mouseleave="changeInterval(false)"
    ref="wave"
  >
    <div
      class="wave-top-wrap"
      :style="'left: -' + left + 'px;width:' + width * box.length + 'px;'"
    >
      <div
        class="wave-top"
        v-for="(item, index) in box"
        :key="index"
        :style="'width:' + width + 'px;'"
      >
        <div class="wave-item" v-for="(val, i) in item" :key="i">
          <!-- 好坑爹啊,用class类名显示出来了八个,原来是因为获取了页面上所有相同类名的元素,换个特殊一点的就好了 -->
          <div
            class="mYecharts"
            :id="'mYecharts' + val.id"
            :ref="'mYecharts' + val.id"
          ></div>
        </div>
      </div>
    </div>
    <div class="wave-bottom">
      <div class="wave-btn">
        <span
          class="btn"
          @click="changeImg(index)"
          v-for="(item, index) in box.length"
          :key="index"
          :class="index === currentIndex ? 'active' : ''"
        ></span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'echartWave',
  components: {},
  props: {
    waveList: {
      type: Array
    }
  },
  data() {
    return {
      color: [
        ['#FF5E49', '#FFCF71'],
        ['#3f00ff', '#E100FF'],
        ['#7F4EED', '#B6B9FF'],
        ['#00C6FF', '#0072FF'],
        ['#FFE466', '#F2C94C'],
        ['#11998E', '#38EF7D']
      ],
      colorList: [],
      num: 0,
      box: [], //处理后的数组
      currentIndex: 0, //当前所在图片下标
      left: 0,
      width: 0,
      screenWidth: null,
      timer: null //定时轮询
    };
  },
  mounted() {
    this.$nextTick(() => {
      // this.play(); // 初始的时候加载
      this.startInterval();
    });
    window.onresize = () => {
      //屏幕尺寸变化
      return (() => {
        this.screenWidth = document.body.clientWidth;
        this.width = this.$refs.wave.offsetWidth;
        this.left = this.$refs.wave.offsetWidth * this.currentIndex;
      })();
    };
  },
  methods: {
    //开启定时器
    startInterval() {
      // 事件里定时器应该先清除在设置,防止多次点击直接生成多个定时器
      clearInterval(this.timer);
      this.timer = setInterval(() => {
        this.currentIndex++;
        this.left = this.$refs.wave.offsetWidth * this.currentIndex;
        if (this.currentIndex > this.box.length - 1) {
          this.currentIndex = 0;
          this.left = 0;
        }
      }, 3000);
    },
    // 点击控制圆点
    changeImg(index) {
      this.currentIndex = index;
      this.left = this.$refs.wave.offsetWidth * this.currentIndex;
    },
    //鼠标移入移出控制
    changeInterval(val) {
      if (val) {
        clearInterval(this.timer);
      } else {
        this.startInterval();
      }
    },
    //处理数据
    myData() {
      //创建二维数组
      this.box = split_array(this.waveList, 4);
      function split_array(arr, len) {
        var a_len = arr.length;
        var result = [];
        for (var i = 0; i < a_len; i += len) {
          result.push(arr.slice(i, i + len));
        }
        return result;
      }
      //设置颜色
      let i = 0;
      this.colorList = [];
      for (let a = 0; a < this.waveList.length; a++) {
        if (i == 6) {
          i = 0;
        }
        this.colorList.push(this.color[i]);
        i++;
      }
      this.width = this.$refs.wave.offsetWidth;
    },
    getData() {
      this.myData(); //处理数据
      // var myEchart = document.getElementsByClassName('mYecharts'); //获取类名
      this.waveList.forEach((val, index) => {
        setTimeout(_ => {
          //好坑爹啊,只有用id获取元素遍历才行,ref创建时机不对
          let chart = document.getElementById('mYecharts' + val.id);
          let myChart = this.$echarts.init(chart);
          myChart.resize();
          myChart.setOption({
            title: {
              text: val.adress,
              left: 'center',
              bottom: '-2%',
              textStyle: {
                color: '#fff',
                fontSize: 16
              }
            },
            backgroundColor: 'transparent', // 画布背景色
            series: [
              {
                value: 100, //  内容 配合formatter
                type: 'liquidFill',
                radius: '64%', // 控制中间圆球的尺寸(此处可以理解为距离外圈圆的距离控制)
                center: ['50%', '42%'],
                data: [
                  val.total / 100, //一定要小数!不然都是满的!
                  {
                    value: val.total / 100,
                    direction: 'left' //波浪方向
                  }
                ], // data个数代表波浪数
                backgroundStyle: {
                  borderWidth: 1,
                  color: '#031445' // 球体背景色
                },
                amplitude: '6%', //波浪的振幅
                // 修改波浪颜色
                // color: ['#0286ea', 'l#0b99ff'], // 每个波浪不同颜色,颜色数组长度为对应的波浪个数
                color: [
                  {
                    type: 'linear',
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                      {
                        offset: 1,
                        color: this.colorList[index][0]
                      },
                      {
                        offset: 0,
                        color: this.colorList[index][1]
                      }
                    ],
                    globalCoord: false
                  }
                ],
                label: {
                  // formatter: 0.87 * 100 + '\n%',
                  formatter: val.total + '\n{d|%}',
                  rich: {
                    d: {
                      fontSize: 20
                    }
                  },
                  textStyle: {
                    fontSize: '2.2rem',
                    color: '#fff'
                  }
                },
                outline: {
                  show: false
                }
              },
              {
                type: 'pie',
                z: 1,
                center: ['50%', '42%'],
                radius: ['66%', '71%'], // 控制外圈圆的粗细
                // hoverAnimation: false,
                data: [
                  {
                    name: '',
                    value: 500,
                    labelLine: {
                      show: false
                    },
                    itemStyle: {
                      color: '#02336A'
                    }
                    // emphasis: {
                    //   labelLine: {
                    //     show: false
                    //   },
                    //   itemStyle: {
                    //     color: '#00AFFF'
                    //   }
                    // }
                  }
                ]
              },
              // 虚点
              {
                type: 'pie',
                zlevel: 0,
                silent: true,
                center: ['50%', '42%'],
                radius: ['80%', '87%'],
                z: 1,
                label: {
                  show: false
                },
                labelLine: {
                  show: false
                },
                data: this.Pie()
              }
            ]
          });
          window.addEventListener('resize', () => {
            myChart.resize();
          });
        }, 100);
      });
    },
    //外层虚线颜色
    Pie() {
      let dataArr = [];
      for (var i = 0; i < 150; i++) {
        if (i % 2 === 0) {
          dataArr.push({
            name: (i + 1).toString(),
            value: 50,
            itemStyle: {
              color: '#00AFFF',
              borderWidth: 0,
              borderColor: 'rgba(0,0,0,0)'
            }
          });
        } else {
          dataArr.push({
            name: (i + 1).toString(),
            value: 100,
            itemStyle: {
              color: 'rgba(0,0,0,0)',
              borderWidth: 0,
              borderColor: 'rgba(0,0,0,0)'
            }
          });
        }
      }
      return dataArr;
    }
  },
  destroyed() {
    clearInterval(this.timer);
  }
};
</script>
<style lang="scss" scoped>
.wave-wrap {
  width: 100%;
  height: 100%;
  padding: 0 20px;
  box-sizing: border-box;
  position: relative;
  .wave-top-wrap {
    height: calc(100% - 30px);
    width: auto;
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    justify-content: space-between;
    transition: left 0.4s ease;
  }
  .wave-top {
    width: 100%;
    height: 100%;
    padding: 0 20px;
    display: inline-block;
    // position: absolute;
    // top: 0;
    // left: 0;
    .wave-item {
      width: 50%;
      height: 50%;
      display: inline-block;
      padding: 10px 40px;
      box-sizing: border-box;
      .mYecharts {
        width: 100%;
        height: 100%;
      }
    }
  }
  .wave-bottom {
    width: 100%;
    height: 30px;
    line-height: 30px;
    position: absolute;
    bottom: 0px;
    .wave-btn {
      text-align: center;
      .btn {
        border: 1px solid #fff;
        border-radius: 50%;
        margin: 0 5px;
      }
      .active {
        background: #fff;
      }
    }
  }
}
</style>

 

posted @ 2023-05-19 19:13  如意酱  阅读(966)  评论(0编辑  收藏  举报