之前写了一个echarts实现多条进度条,并定时翻页的组件,现在用vue+gulp重构了一下,稍后会贴出源码地址,很抱歉,之前没有贴出css,让某些伙伴不知所措。
如果需要源码:https://github.com/liuxin00020/test
或者在本人的资源里面下载
效果图如下:
1、实现的方式
一样的json数据列表首先构成左右两边的数据显示,中间用echarts柱状图,绝对定位实现,只支持IE9+
2、html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>echarts 实现多条进度条</title>
<link rel="stylesheet" href="css/processbar.css">
</head>
<body>
<div id="app" class="screen">
<!-- **** 标题 **** -->
<div class="screen-title">区域分布</div>
<!-- **** 内容 **** -->
<div class="screen-content">
<!-- ** 方格标注 ** -->
<div class="icon-box">
<span class="icon-item">警察</span>
<span class="icon-item">罪犯</span>
</div>
<!-- ** 列表 ** -->
<div class="region-distribution-list">
<div class="list-item" v-for="(item,index) in newList" :key="index">
<span class="region">{{item.region}}</span>
<div class="bg-bar"><span></span><span></span></div>
<div class="num-box">
<span class="policeNum">{{item.policeNum}}</span>
|
<span class="criminalNum">{{item.criminalNum}}</span>
</div>
</div>
<!-- ** 柱状图 ** -->
<div class="bar-graph">
<div id="regionBar"></div>
</div>
</div>
</div>
</div>
<script src="js/EchartsProcessBar.js"></script>
</body>
</html>
3、js代码
import Vue from 'vue/dist/vue.js'
import echarts from 'echarts';
import {list} from '../asset/list.json'
Vue.prototype.$echarts = echarts;
let app = new Vue({
el: '#app',
data: {
list: list, // 模拟数据
newList: [], // 用于分页显示数据
pageCount: 8, // 每页显示的个数
},
created() {
this.newList = this.list.slice(0, this.pageCount); // 初始化第一页数据
},
mounted() {
this.loadBar(this.newList); // 加载echarts
this.autoPlay(); // 自动翻页
},
methods: {
// echarts柱状图加载
loadBar(list) {
let regions = [], policeNums = [], criminalNums = [];
// 遍历数据列表,封装echarts的数据格式
list.map((item) => {
regions.unshift(item.region); // 地区
policeNums.unshift(item.policeNum); // 警察人数
criminalNums.unshift(item.criminalNum); // 罪犯人数
});
// 若末尾页不足8条,则填充0,防止样式错乱
let len = regions.length;
for (let i = 0; i < 8 - len; i++) {
regions.unshift(0);
policeNums.unshift(0);
criminalNums.unshift(0);
}
// echarts数据绑定开始
let chartDom = this.$echarts.init(document.getElementById("regionBar"));
chartDom.setOption({
color: ["#f5a623", "#fff"],
grid: [{//外框
top: '6.2%',
left: '0',
right: '0',
bottom: '6.4%',
containLabel: false,
}],
calculable: true,
tooltip: {
trigger: 'axis'
},
xAxis: [{
type: 'value',
splitLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false},//不显示刻度
axisLine: {show: false},
boundaryGap: false,//座标轴两边留白策略
}],
yAxis: [{
type: 'category',
boundaryGap: false,
position: 'top',
data: regions,
splitLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false},//不显示刻度
axisLine: {show: false},
}],
series: [
{
type: 'bar',
data: policeNums,
barWidth: 2,
},
{
type: 'bar',
data: criminalNums,
barWidth: 2,
barGap: '6px' // 两个数据之间,间隔5px
}
]
});
},
// 自动翻页
autoPlay() {
let playTime = 2000, // 播放间隔事件
timer = null,
page = 1,
totalPage = this.list.length % this.pageCount == 0 ? this.list.length / this.pageCount : parseInt(this.list.length / this.pageCount) + 1; // 总页数,每页显示8条
// 播放函数
const play = () => {
page++;
if (page > totalPage) {
page = 1;
}
this.newList = this.list.slice((page - 1) * this.pageCount, page * this.pageCount); // 截取数组,用于展示当前页的数据
this.loadBar(this.newList); // 重新加载柱状图
}
// 定时任务,翻页
timer = setInterval(play, playTime);
// 鼠标悬浮事件,移上去,暂停定时任务
this.$el.onmouseover = (event) => {
clearInterval(timer);
};
// 鼠标移开,播放继续
this.$el.onmouseleave = (event) => {
timer = setInterval(play, playTime);
}
},
}
});
4、scss代码
* {
padding: 0;
border: 0;
margin: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
border: 0;
padding: 0;
margin: 0;
font-size: 16px;
font-family: '微软雅黑 Light'
}
.screen {
width: 100%;
height: 100%;
background-color: rgb(4, 24, 70);
color: #fff;
border: 2px solid rgb(24, 59, 137);
padding: 20px;
}
.screen-title {
width: 100%;
height: 10%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.4rem;
position: relative;
&:after {
content: '';
width: 100%;
height: 1px;
background: linear-gradient(to right, transparent, rgb(31, 70, 161), transparent);
position: absolute;
bottom: 0;
left: 0;
}
}
.screen-content {
width: 100%;
height: 90%;
}
.icon-box {
width: 100%;
height: 50px;
line-height: 50px;
text-align: right;
}
.icon-item {
margin-left: 10px;
display: inline-flex;
align-items: center;
text-indent: 5px;
&:before {
content: '';
width: 8px;
height: 8px;
background-color: #fff;
}
&:first-child::before {
background-color: rgb(245, 167, 30);
}
}
.region-distribution-list {
width: 100%;
height: calc(100% - 50px);
display: flex;
flex-direction: column;
position: relative;
}
.list-item {
width: 100%;
height: 12.5%;
display: flex;
align-items: center;
justify-content: space-between;
}
.region {
width: 100px;
}
.bg-bar {
flex: 1;
span {
width: 100%;
height: 6px;
display: block;
background-color: rgb(1, 13, 48);
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
.num-box {
width: 100px;
display: flex;
justify-content: center;
}
.policeNum {
padding-right: 10px;
color: rgb(245, 167, 30);
width: 50%;
text-align: right;
}
.criminalNum {
padding-left: 10px;
width: 50%;
}
.bar-graph {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
padding: 0 100px;
#regionBar {
width: 100%;
height: 100%;
}
}