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>