1.需求
如图,需要做个以上x轴为日期,y轴为时间点的散点图,以此来统计用户七天内用户每天的上线下线在线时长数据,如果到了小时了就显示多少小时,如果在一小时之内就显示多少分钟
思路:都是登录,退出,登录,退出,而且退出的时间比登录的大,直接判断它的状态是退出还是登录,如果当前状态退出,下个数据状态是登录,那么当前日期时间减去下个数据的日期时间就可以了
折线的一般的都是数值型,且一根线上x轴与y轴就一个点,像这种一根线上有多个点的需要用到散点图,但是这个需求又不是一般的散点图啊,他不是数值型的,x轴和y轴都是字符串的,这就需要考虑到要把每个一天中每个时分秒都加到y轴里去,再通过间隔隔开,一天有多少秒y轴就有多少个刻度,246060 就是一天多少秒
灵感来源于官方散点图实例
2.实现
(1.)先在此项目中下载echarts
npm install echarts --save
// 在初始化echarts的时候,具体看下面setGraphical()初始化echarts图表的方法,引入就好了,无需去main.js中声明import使用use()
(2.)在template中
<div class="icore-graphical-index">
<div class="icore-graphical-area" ref="graphical-area"> // 这个ref有用的,后面会用到
</div>
</div>
</template>
(3.)script中
<script>
export default {
name: 'echartsData',
data () {
return {
// option: {
// title: {
// text: '用户行为统计图'
// },
// tooltip : {
// trigger: 'item',
// axisPointer: {
// type: 'cross'
// }
// // formatter: function (params) {
// // console.log(params, 'pars')
// // }
// },
// legend: {
// data:['登录','退出','在线时长']
// },
// xAxis: {
// type: 'category',
// data: ['2020-3-7', '2020-3-8', '2020-3-9', '2020-3-10', '2020-3-11', '2020-3-12', '2020-3-13']
// },
// yAxis: {
// type: 'value'
// },
// series: [
// {
// name: '登录',
// data: [['2020-03-07',5.0000], ['2020-03-07',6.0000], ['2020-03-08',7.0000], ['2020-03-09',8.0000], ['2020-03-10',9.0000], ['2020-03-11',10.0000], ['2020-03-12',12.0000], ['2020-03-12',14.0000],['2020-03-13',5.0000]],
// type: 'line'
// },
// {
// name: '退出',
// data: [['2020-03-07',7.0000], ['2020-03-08',9.0000], ['2020-03-09',10.0000], ['2020-03-09',19.0000], ['2020-03-10',18.3800], ['2020-03-11',20.2200], ['2020-03-12',23.0000], ['2020-03-12',19.0800],['2020-03-13',17.2200]],
// type: 'line'
// },
// {
// name: '在线时长',
// data: [['2020-03-07',2], ['2020-03-08',2], ['2020-03-09',2], ['2020-03-10',9.38], ['2020-03-11',10.22], ['2020-03-12',11],['2020-03-13',12.2200]],
// type: 'line'
// }
// ],
// },
// 上面代码是三条折线图的,现在不用这玩意
option: {
title: {
text: '用户行为统计图'
},
tooltip: {
position: 'top',
trigger: 'item',
// 自己定义显示的值,就是鼠标放在点上,显示的东西
formatter: function (params) {
let status = ''
let value = ''
if (params.value[2] === 1) {
status = ' 退出'
} else if (params.value[2] === 0) {
status = ' 登录'
}
if (params.value[3] > 0) {
if (params.value[3] > 1) {
value = Number(params.value[3]).toFixed(1) + '小时'
} else if (params.value[3] > 0) {
value = Math.ceil(params.value[3] * 60) + '分钟'
}
return params.value[0] + ' ' + params.value[1] + status + '</br>' + '在线时长: ' + value;
} else {
return params.value[0] + ' ' + params.value[1] + status;
}
}
},
xAxis: {
type: 'category',
data: ['2020-03-08', '2020-03-09', '2020-03-10', '2020-03-11', '2020-03-12', '2020-03-13', '2020-03-14'],
boundaryGap: false,
splitLine: {
show: true,
lineStyle: {
color: '#999',
type: 'dashed'
}
},
axisLine: {
show: false
}
},
yAxis: {
type: 'category',
axisLine: {
show: false
},
splitLine: {
lineStyle: {
type: 'dashed'
}
},
axisTick: {
interval: 14400
// length: 6
}, // 这个感觉没用,但是如果不加,整个散点图都不见了。
// 重点是下面这个axisLabel,这个是用来控制y轴间隔的,因为24小时,时分秒,一天有86400个值,我这让他四个小时一个刻度
axisLabel:{
// y轴刻度配置,我这是设置了4小时一个刻度间隔,如果想隔6小时就6*3600 - 1就好了
interval: 14399 // 0:表示全部显示不间隔;auto:表示自动根据刻度个数和宽度自动设置间隔个数
},
// interval: 14399, // 每次增加几个
data: ['00:00:00', '04:00:00', '08:00:00', '12:00:00', '16:00:00']
},
series: [{
type: 'scatter',
data: [['2020-03-09', '04:00:00'], ['2020-03-09', '05:00:00'], ["2020-03-11", "16:22:49"]]
}]
},
myChart: ''
};
},
mounted () {
this.setGraphical();
this.getUserBehavior()
// height = document.getElementById('userInfo_div1').offsetHeight;
},
methods: {
/**
* 根据参数生成不同类型的图形化控件
* 这是个初始化echarts的方法
*/
setGraphical: function () {
let that = this;
// 引入 ECharts 主模块,在这里引入就好了,无需去main.js中声明import使用use()
let echarts = require('echarts');
require('echarts-gl')
// 基于准备好的dom,初始化echarts实例,将echarts实例记录在data中后面会调用的,that.$refs['graphical-area']就这是盒子的ref
that.myChart = echarts.init(that.$refs['graphical-area']);
// 以下开始计算y轴刻度
var hours = 0 // 时
var minute = 0 // 分
var second = 0 // 秒
var s = 0 // 总共的
var yAxis = []
yAxis.push('00:00:00') // 从00:00:00开始,否则就会第一个刻度将会是数组的第一个,00:00:01
for (var i = 1; i <= 86400; i++) {
// 一分钟以内
if (i < 60) {
if (i < 10) {
s = '00:00:0' + i
} else {
s = '00:00:' + i
}
} else if (i < 3600) {
// 一小时以内
minute = parseInt(i / 60) < 10 ? '0' + parseInt(i / 60) : parseInt(i / 60)
second = (i % 60) < 10 ? '0' + i % 60 : i % 60
s = '00' + ':' + minute + ':' + second
} else {
// 超过一小时以后
hours = parseInt(i / 3600) < 10 ? '0' + parseInt(i / 3600) : parseInt(i / 3600)
minute = (parseInt(i % 3600 / 60)) < 10 ? '0' + parseInt(i % 3600 / 60) : parseInt(i % 3600 / 60)
second = (i % 60) < 10 ? '0' + i % 60 : i % 60
s = hours + ':' + minute + ':' + second
}
yAxis.push(s)
}
// 将这个数组赋值给y轴
that.option.yAxis.data = yAxis
// 绘制图表,只要是给option赋了值,就要重新绘制图表,否则修改没有效果
that.myChart.setOption(that.option);
},
// 获取数组的接口
getUserBehavior () {
let _this = this
// 获取当前时间, 时分秒,因为我是要获取今天到前6天一周的数据,所以x轴日期是变化的
var now = new Date();
var year = now.getFullYear(); // 得到年份
var month = now.getMonth(); // 得到月份
var date = now.getDate(); // 得到日期
// var day = now.getDay(); // 得到周几
var hour = now.getHours(); // 得到小时
var minu = now.getMinutes(); // 得到分钟
var sec = now.getSeconds(); // 得到秒
month = month + 1;
if (month < 10) month = '0' + month;
if (date < 10) date = '0' + date;
if (hour < 10) hour = '0' + hour;
if (minu < 10) minu = '0' + minu;
if (sec < 10) sec = '0' + sec;
var time = year + '-' + month + '-' + date + ' ' + hour + ':' + minu + ':' + sec;
var date1 = 0
var date2 = 0
var arr1 = []
var arr2 = []
var xAxis = []
var d = date
var day1 = ''
var day2 = ''
var value = 0
_this.axios.get('pass/v1/sysauthbehaviors/getUserBehavior?day=7').then((res) => {
if (res.code === '0') {
let resultArray = res.data
resultArray.forEach(item => {
for (var i = 0; i < item.sysAuthBehaviors.length; i++) {
// day1 = item.sysAuthBehaviors[i].crtDate.substring(8, 10)
day1 = item.sysAuthBehaviors[i].crtDate.substring(0, 10) // 取到日期: 2020-03-16
day2 = item.sysAuthBehaviors[i].crtDate.substring(11, 19) // 取到时间: 17:22:22
// 这里是用来获取今天最近的一点登录点在目前的在线时间,刚开始我以为需求是要计算一天的总在线时长,暂时先不考虑这个
// if (date === day1 && item.sysAuthBehaviors[0].status === 0) {
// date1 = new Date(time).getTime()
// date2 = new Date(item.sysAuthBehaviors[i].crtDate).getTime()
// value = value + ((date1 - date2) / 1000 / 60 / 60)
// }
item.sysAuthBehaviors[i].value = 0 // 这个用来存放登录时长,如果登录就让他为0,退出就计算他在线时长
// 状态0是登录,1是退出,如果当前不等于最后一项时,就拿当前项与下一项做对比
if (i !== item.sysAuthBehaviors.length - 1 && item.sysAuthBehaviors[i].status === 1 && item.sysAuthBehaviors[i + 1].status === 0) {
date1 = new Date(item.sysAuthBehaviors[i].crtDate).getTime()
date2 = new Date(item.sysAuthBehaviors[i + 1].crtDate).getTime()
item.sysAuthBehaviors[i].value = (date1 - date2) / 1000 / 60 / 60 // 获取的是小时,在线几小时,上面option中的tooltip会显示与转换
}
arr2.unshift([day1, day2, item.sysAuthBehaviors[i].status, item.sysAuthBehaviors[i].value])
}
// 记录x轴的日期
xAxis.unshift(d < 10 ? year + '-' + month + '-' + '0' + d : year + '-' + month + '-' + d)
d--
})
_this.option.xAxis.data = xAxis
// _this.option.series[0].data = arr1
_this.option.series[0].data = arr2
_this.myChart.setOption(_this.option); // 重新渲染此图表,否则赋值的没用
} else {
this.$message.error(res.message);
}
}).catch((err) => {
})
}
}
};
</script>
获取的数据就是一个数组中有七个对象,七天数据,所以对象中又有数组,因为数据是今天、昨天、前天、钱两天…的形式的,所以需要unshift()往数组前追加,今天的数据才能与x轴的数据对称
还有获取到的数据形式是[[‘2020-03-16’, ‘17:36:42’, ‘xx’, ‘xx’], [‘2020-03-16’, ‘17:55:33’, ‘xx’, ‘xx’],[‘2020-03-16’, ‘17:56:56’, ‘xx’, ‘xx’]],第一项对应x轴坐标,第二项对应y轴坐标,这两个就是直角坐标轴上的某个点,后面的就是会在tooltip里面的,你要哪些数据就保存哪些就好了,我保存的就是登陆退出状态和在线时长
(4.)style中
<style lang="scss" scoped>
.icore-graphical-index {
display: inline-block;
height: inherit;
width: inherit;
.icore-graphical-area {
height: 100%;
width: 100%;
}
}
</style>
要注意两点很重要,标题上也写了
1.装图表的盒子必须要有宽高,宽可以为100%,高必须是个确定值;否则图表出不来,因为没给它设置宽高2.修改赋值了option中某个属性必须重新绘制图表:图表实例化.setOption(),否则赋值修改的数据没有效果