刚开始看到ui的设计图时,我就一直在想怎么可以用柱状图堆叠的形式来呈现这种效果。直到我看到了这个官方实例自定义系列,跟我要实现的效果非常相似了。这是echarts的自定义系列图表,type: 'custom'
。
所以我就直接把这个实例给改改,改成自己要实现的效果。
直接上代码吧。
1、写一个dom用来画echarts
<div class="chart-box" ref="onlineScatterChart" autoresize id="onlineScatterChart"></div>
2、基本的配置项
scatterChartOption:{
color:['#1ca3ff','rgba(0,0,0,0.3)'],
legend: {
top: 0,
right:0,
selectedMode:false,
data: ['在线','离线']
},
grid: {
left: '10px',
right: '10px',
bottom: '30px',
top:'40px',
containLabel: true
},
xAxis: {
type:'time',
splitNumber:13,
axisLabel: {
formatter: function (timestamp) { //秒级时间戳转换成YYYY-MM-DD hh:mm:ss并设置换行
timestamp = timestamp*1000
let date = new Date(timestamp);
let YY = date.getFullYear() + '-';
let MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
let hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
let mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
let ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
return YY + MM + DD +'\n'+hh + mm + ss;
}
}
},
yAxis: [
{
name:'车辆',
data:[],
nameTextStyle:{
color: 'transparent'
}
},
{
name:'rate',
data:[],
axisLabel:{
formatter:function(rate){
return rate + '%'
}
},
nameTextStyle:{
color: 'transparent'
}
}
],
series: [{
type: 'custom',
name:'在线',
renderItem: this.renderItem,
itemStyle: {
opacity: 1
},
encode: {
x: [1, 2],
y: 0
},
data:[]
}]
},
renderItem
需要重点关注,这是用来画自定义系列图表的函数。请看看renderItem
函数里写了啥,我这里是直接把官方实例里面的方法平移过来,只做了些改动。
renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
/* var height = api.size([0, 1])[1] * 0.6; */
var height = 30; //改成每个横向条高为30
var rectShape = echarts.graphic.clipRectByRect({
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
}, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
});
return rectShape && {
type: 'rect',
shape: rectShape,
style: api.style()
};
},
3、初始化charts
initChart(){
let chart = document.getElementById('onlineScatterChart');
this.onlineScatterChart = echarts.init(chart);
this.onlineScatterChart.setOption(this.scatterChartOption);
}
4、请求数据
getScatterData(){
this.myaxios({
url: "/api/getOnlineData?"+str,
method: "post",
data: {vehicleList:vehList}
}).then(res => {
console.log(res)
let data = res.data;
if(data.code == 1){
for(let i = 0;i<data.msg.list.length;i++){
this.createData(data.msg.list[i].vehicleNum,data.msg.list[i].onlineHistory,i);
this.categ.push(data.msg.list[i].vehicleNum); //车牌list
}
this.setChartData();
this.listTotal = this.vehicleList.length
this.onlineScatterChart.resize();
}
else{
this.$message.error('加载异常');
}
});
}
createData(categ,data,index){
let start = Date.parse(new Date(this.timePicker[0]))/1000; //x轴的开始时间
let end = Date.parse(new Date(this.timePicker[1]))/1000; //x轴的结束时间
let curOnlineTotal = 0;
this.datalist.push({ //给每一项填充一个从start到end的灰色背景条,当做离线时间
name: '离线',
value: [
index,
start,
end,
end-start
],
itemStyle: {
normal: {
color: 'rgba(0,0,0,0.1)'
}
},
silent:true,
tooltip : null
});
for (var i = 0; i < data.length; i++) {
curOnlineTotal += (data[i].offlineTime - data[i].onlineTime);
this.datalist.push({
name: categ,
value: [
index,
data[i].onlineTime,
data[i].offlineTime,
data[i].offlineTime-data[i].onlineTime
],
itemStyle: {
normal: {
color: this.colorGroup
}
}
});
}
let onlineRate = parseInt((curOnlineTotal /(end - start))*100) //计算机器的在线率
this.rateList.push(onlineRate)
}
value: [index,data[i].onlineTime,data[i].offlineTime,data[i].offlineTime-data[i].onlineTime]
中index是指类目的下标,start是机器的上线时间,end是机器的下线时间,end-start是本次在线的持续在线时长。
5、接下来就是把整理好的数据setOption到echarts实例里面。
setChartData(){
let that = this;
let xMin = Date.parse(new Date(that.timePicker[0]))/1000;
let xmax = Date.parse(new Date(that.timePicker[1]))/1000;
this.onlineScatterChart.setOption({
tooltip: {
formatter: function (params) {
if(params.name != '离线'){
return params.name + '<br>' +
'在线时长:' + that.showDuration(params.value[3]) + '<br>'+
'起始时间:' + that.timestampToDate(params.value[1]) + '<br>'+
'结束时间:' + that.timestampToDate(params.value[2]);
}
}
},
xAxis:{
min:xMin, //x轴最小值为统计的起始时间
max:xmax //x轴最大值为统计的开始时间
},
yAxis:[
{
data:this.categ
},
{
data:this.rateList,
axisLabel:{
textStyle:{
color:function(val,idx){
if(val < that.onlineScatterRate)
return 'red'
else
return '#000'
}
}
}
}
],
series:[{
type: 'custom',
data:this.datalist
}]
});
this.onlineScatterChart.resize(); //重新resize大小
}