<template>
|
<div>
|
<el-dialog
|
:title="title"
|
:visible.sync="visible"
|
top="30px"
|
width="1000px"
|
center
|
:before-close="close"
|
@closed="close"
|
>
|
<div>
|
<el-form
|
:inline="true"
|
style="text-align: center;"
|
:model="formInline"
|
>
|
<el-form-item>
|
<el-radio-group
|
v-model="time"
|
@change="changeDay"
|
>
|
<el-radio-button label="天" />
|
<el-radio-button label="小时" />
|
<el-radio-button label="分钟" />
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item label="时间:">
|
<el-date-picker
|
v-model="selectTime"
|
type="datetimerange"
|
range-separator="至"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
value-format="yyyy-MM-dd HH:mm"
|
:default-date="[macDate.startTime, macDate.endTime]"
|
:picker-options="pickerOptions"
|
align="right"
|
@change="changeDay"
|
/>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div>
|
<div class="tit">
|
<p style="font-size:16px">
|
共<span class="greenClor">{{ sum }}</span>{{ time }},在线 <span class="greenClor">{{ macOnlineDetailData.pieChart2 }}</span>{{ time }},在线率<span :class=" onlineRate<90 ?'redClor':'greenClor'">{{ onlineRate.toFixed(2) }}%</span>
|
</p>
|
<div id="myPieChart" />
|
</div>
|
|
<div class="echartsBox">
|
<div class="myLineChartBox">
|
<div id="myLineChart" />
|
<div class="backIcon">
|
<img
|
v-if="lineType==='minute'"
|
src="../../assets/icon/back.png"
|
@click="renderBack"
|
>
|
</div>
|
</div>
|
</div>
|
<p style="margin-top: 0px;">
|
注:折线图最小单位为小时,可支持下钻
|
</p>
|
<div>
|
<p style="font-size:16px">
|
日志
|
</p>
|
<el-table
|
:data="tableData"
|
border
|
max-height="200"
|
style="width: 100%"
|
>
|
<el-table-column
|
type="index"
|
label="序号"
|
width="60"
|
align="center"
|
label-class-name="itemSpan"
|
/>
|
|
<el-table-column
|
prop="endTime"
|
label="离线日期"
|
align="center"
|
label-class-name="itemSpan"
|
/>
|
<el-table-column
|
prop="startTime"
|
label="上线日期"
|
align="center"
|
label-class-name="itemSpan"
|
/>
|
<el-table-column
|
prop="mun"
|
label="离线时长"
|
align="center"
|
label-class-name="itemSpan"
|
>
|
<template slot-scope="scope">
|
<span v-if="scope.row.mun!=='-'">{{ scope.row.mun }}{{ time }}</span>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import * as echarts from 'echarts'
|
import dayjs from 'dayjs'
|
export default {
|
props: {
|
visible: { type: Boolean, required: true },
|
macDate: { type: Object, required: true }
|
},
|
data () {
|
return {
|
title: '详情',
|
sum: '',
|
formInline: {},
|
macOnlineDetailData: {},
|
time: '小时',
|
selectTime: [],
|
startTime: '',
|
endTime: '',
|
tableData: [],
|
choiceDate: null,
|
chart: null,
|
pieChart: null,
|
type: 'hour',
|
lineType: 'hour',
|
// 重点
|
|
pickerOptions: {
|
shortcuts: [{
|
text: '今天',
|
onClick (picker) {
|
const end = dayjs()
|
const start = new Date(dayjs().startOf('day'))
|
picker.$emit('pick', [new Date(start), new Date(end)])
|
}
|
}, {
|
text: '近1天',
|
onClick (picker) {
|
const end = dayjs()
|
const start = dayjs().subtract(1, 'day')
|
picker.$emit('pick', [new Date(start), new Date(end)])
|
}
|
}, {
|
text: '近3天',
|
onClick (picker) {
|
const end = dayjs()
|
const start = dayjs().subtract(3, 'day')
|
picker.$emit('pick', [new Date(start), new Date(end)])
|
}
|
}, {
|
text: '近5天',
|
onClick (picker) {
|
const end = dayjs()
|
const start = dayjs().subtract(5, 'day')
|
picker.$emit('pick', [new Date(start), new Date(end)])
|
}
|
}, {
|
text: '近7天',
|
onClick (picker) {
|
const end = dayjs()
|
const start = dayjs().subtract(7, 'day')
|
picker.$emit('pick', [new Date(start), new Date(end)])
|
}
|
}],
|
onPick: ({ maxDate, minDate }) => {
|
// 把选择的第一个日期赋值给一个变量。
|
this.choiceDate = minDate.getTime()
|
// 如何你选择了两个日期了,就把那个变量置空
|
if (maxDate) this.choiceDate = ''
|
},
|
disabledDate: time => {
|
// 如何选择了一个日期
|
if (this.choiceDate) {
|
// 7天的时间戳
|
const one = 6 * 24 * 3600 * 1000
|
// 当前日期 - one = 6天之前
|
const minTime = this.choiceDate - one
|
// 当前日期 + one = 6天之后
|
const maxTime = this.choiceDate + one
|
return (
|
time.getTime() < minTime ||
|
time.getTime() > maxTime ||
|
// 限制不能选择今天及以后
|
time.getTime() > Date.now()
|
)
|
} else {
|
// 如果没有选择日期,就要限制不能选择今天及以后
|
return time.getTime() > Date.now()
|
}
|
}
|
}
|
}
|
},
|
computed: {
|
onlineRate () {
|
return (this.macOnlineDetailData.pieChart2 / this.sum) * 100 || 0
|
}
|
},
|
watch: {
|
time (newValue, oldValue) {
|
if (newValue === '天') {
|
this.type = 'day'
|
this.lineType = 'day'
|
} else if (newValue === '小时') {
|
this.type = 'hour'
|
this.lineType = 'hour'
|
} else if (newValue === '分钟') {
|
this.type = 'minute'
|
}
|
}
|
},
|
mounted () {
|
this.title = `${this.macDate.name}详情`
|
this.startTime = dayjs(this.macDate.startTime).format('YYYY-MM-DD HH:mm')
|
this.endTime = dayjs(this.macDate.endTime).format('YYYY-MM-DD HH:mm')
|
this.$set(this.selectTime, 0, new Date(this.macDate.startTime))
|
this.$set(this.selectTime, 1, new Date(this.macDate.endTime))
|
this.getLineData()
|
this.getMacDetail()
|
},
|
beforeDestroy () {
|
if (!this.chart) {
|
return
|
}
|
this.chart.dispose()
|
this.myPieChart.dispose()
|
this.chart = null
|
this.myPieChart = null
|
},
|
methods: {
|
changeDay () {
|
this.startTime = !this.selectTime ? '' : dayjs(this.selectTime[0]).format('YYYY-MM-DD HH:mm')
|
this.endTime = !this.selectTime ? '' : dayjs(this.selectTime[1]).format('YYYY-MM-DD HH:mm')
|
this.getMacDetail()
|
if (this.type === 'minute') {
|
this.lineType = 'hour'
|
this.getLineData(this.startTime, this.endTime, 'hour')
|
} else {
|
this.lineType = this.type
|
this.getLineData(this.startTime, this.endTime, this.type)
|
}
|
},
|
initPieChart (pieChartData) {
|
let that = this
|
let percent = null
|
let labelData = {
|
show: true,
|
position: 'right',
|
alignTo: 'edge',
|
margin: 0,
|
normal: {
|
formatter: function (params) {
|
percent = params.percent
|
let onlineType = params.dataIndex === 0 ? '离线' : '在线'
|
return `${onlineType}{a|${params.value}}${that.time}:{b|${params.percent}%}`
|
},
|
fontSize: 14, // 标签字体大小
|
fontStyle: 'italic', // 标签字体斜体
|
rich: { // 在rich中对两个标识进行样式修改
|
a: {
|
fontSize: 14,
|
fontStyle: 'italic',
|
color: '#67c23a'
|
},
|
b: {
|
fontSize: 14,
|
fontStyle: 'italic',
|
color: percent !== 0 ? '#67c23a' : 'red'
|
},
|
}
|
},
|
}
|
let dom = document.getElementById('myPieChart')
|
let myChart = echarts.init(dom)
|
this.myPieChart = myChart
|
this.myPieChart.setOption({
|
grid: {
|
left: '40px', // 左侧内边距
|
right: '5px', // 右侧内边距
|
},
|
tooltip: {
|
trigger: 'item',
|
formatter: function (params) {
|
var value = params.value
|
let tip = params.dataIndex === 1 ? '在线: ' + value : '离线: ' + value
|
return tip
|
},
|
},
|
series: [
|
{
|
radius: 30,
|
center: ['50%', '50%'],
|
type: 'pie',
|
data: pieChartData,
|
label: labelData,
|
labelLayout: {
|
hideOverlap: false
|
}
|
},
|
],
|
}, true)
|
},
|
initChart (myChart, option, dom) {
|
myChart.setOption(option)
|
myChart.on('click', (params) => {
|
if (this.lineType === 'hour') {
|
this.lineType = 'minute'
|
echarts.dispose(dom)
|
var myChart = echarts.init(dom)
|
let starTiem = params.data[0]
|
let data = dayjs(starTiem).add(1, 'hour')
|
let endTiem = dayjs(data).isAfter(dayjs()) ? dayjs() : data
|
console.log('.isAfter(now)', dayjs(endTiem).isAfter(dayjs()))
|
this.getLineData(dayjs(starTiem).format('YYYY-MM-DD HH:mm:ss'), dayjs(endTiem).format('YYYY-MM-DD HH:mm:ss'), 'minute')
|
myChart.setOption(option, true)
|
}
|
})
|
},
|
renderBack () {
|
this.lineType = 'hour'
|
let dom = document.getElementById('myLineChart')
|
echarts.dispose(dom)
|
this.getLineData(this.startTime, this.endTime, this.lineType)
|
},
|
renderLine () {
|
let dom = document.getElementById('myLineChart')
|
let myChart = echarts.init(dom)
|
let option = this.getOption(
|
this.xData,
|
this.sData
|
)
|
this.initChart(myChart, option, dom)
|
},
|
getOption (xData, sData) {
|
let option = null
|
let interval = 3600 * 1000
|
if (this.type === 'minute') {
|
interval = 60 * 1000
|
}
|
option = {
|
grid: {
|
left: '40px', // 左侧内边距
|
right: '5px', // 右侧内边距
|
},
|
xAxis: {
|
type: 'time',
|
interval: interval,
|
axisTick: { show: false },
|
splitLine: { show: false },
|
axisLine: {
|
lineStyle: { width: 0 }
|
},
|
axisLabel: {
|
interval: interval,
|
interale: 0,
|
}
|
},
|
tooltip: {
|
trigger: 'item',
|
formatter: function (params) {
|
var value = params.data[0]
|
let tip = params.value[1] === 1 ? '在线: ' + value : '离线: ' + value
|
return tip
|
},
|
},
|
yAxis: {
|
axisLine: {show: true},
|
axisTick: {show: true},
|
splitLine: {show: true},
|
axisLabel: {
|
formatter: function (value) {
|
var texts = []
|
if (value === 0) {
|
texts.push('离线')
|
} else if (value === 1) {
|
texts.push('在线')
|
}
|
return texts
|
},
|
},
|
splitArea: {show: true},
|
show: true,
|
type: 'value',
|
splitNumber: 1,
|
min: 0,
|
max: 1,
|
},
|
dataZoom: [
|
{
|
height: 20, // 时间滚动条的高度
|
type: 'slider', // type的作用是指定数据缩放的类型,slider表示使用滑动条进行缩放,inside表示使用鼠标滚轮进行缩放。
|
xAxisIndex: 0, // 作用在x轴的下标(因为x轴可以有多个)
|
filterMode: 'weakFilter', // 间滚动条的过滤模式,'filter'表示滑动时间条时会直接过滤掉不在时间范围内的数据,'weakFilter'表示滑动时间条时会逐渐过滤掉不在时间范围内的数据。
|
start: 0, // 默认开始位置(百分比)
|
end: 100, // 默认结束位置(百分比)
|
},
|
{
|
type: 'inside',
|
xAxisIndex: 0,
|
filterMode: 'filter',
|
start: 0,
|
end: 100,
|
},
|
],
|
series: [
|
{
|
data: sData,
|
type: 'line'
|
}
|
]
|
}
|
return option
|
},
|
getLineData (startTime = this.startTime, endTime = this.endTime, type = this.type) {
|
this.$request({
|
url: '/onlineRate/detail',
|
method: 'get',
|
params: {
|
mac: this.macDate.mac,
|
startTime: startTime,
|
endTime: endTime,
|
type: type
|
}
|
})
|
.then(res => {
|
this.xData = res.data.lineChart1.map(item => {
|
return dayjs(item).format('YYYY-MM-DD HH:mm:ss')
|
})
|
let data = res.data.lineChart2
|
this.sData = data.map((item, index) => {
|
return [ this.xData[index], item ]
|
})
|
this.$nextTick(() => {
|
this.renderLine()
|
})
|
})
|
.catch(err => {
|
console.log(err)
|
})
|
},
|
getMacDetail () {
|
this.$request({
|
url: '/onlineRate/detail',
|
method: 'get',
|
params: {
|
mac: this.macDate.mac,
|
startTime: this.startTime,
|
endTime: this.endTime,
|
type: this.type
|
}
|
})
|
.then(res => {
|
this.macOnlineDetailData = res.data
|
this.sum = res.data.sum
|
this.tableData = res.data.tabulation
|
let pieChartData = [this.macOnlineDetailData.pieChart1, this.macOnlineDetailData.pieChart2]
|
this.initPieChart(pieChartData)
|
})
|
.catch(err => {
|
console.log(err)
|
})
|
},
|
close () {
|
this.$emit('update:visible', false)
|
}
|
}
|
}
|
</script>
|
|
<style scoped lang="scss">
|
.echartsBox{
|
// display: flex;
|
height: 360px;
|
|
.myLineChartBox {
|
width: 100%;
|
position: relative;
|
#myLineChart{
|
width: 100%!important;
|
height:360px;
|
left: -10px;
|
canvas {
|
width: 100%!important;
|
}
|
}
|
}
|
}
|
#myPieChart {
|
height: 120px;
|
width: 600px!important;
|
canvas {
|
width: 100%!important;
|
}
|
}
|
.backIcon{
|
position: absolute;
|
top: -10px;
|
right: 80px;
|
cursor: pointer;
|
img{
|
height: 40px;
|
}
|
}
|
.tit{
|
position: relative;
|
#myPieChart{
|
float: right;
|
position: absolute;
|
left: 322px;
|
top: -40px;
|
}
|
}
|
.redClor{
|
color: red;
|
}
|
.greenClor{
|
color:#67c23a;
|
}
|
</style>
|