You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

235 lines
7.2 KiB

<template>
<div class="chart" :class="className" :style="{ height: height, width: width }" />
</template>
<script>
import resize from './mixins/resize'
import cloneDeep from 'lodash/cloneDeep'
import { getAllDateMonthList, formatDate } from '@/utils'
const colors = ['#4d9bf9', '#FF7F00', '#6A3D9A', '#6af1b0', '#4d9bf9']
export default {
mixins: [resize],
props: {
className: { type: String, default: '' },
width: { type: String, default: '100%' },
height: { type: String, default: '200px' },
chartData: { type: Array, default: () => [] },
title: { type: String, default: '' }
},
data() {
return {
chart: null,
disabled: false,
data: []
}
},
watch: {
chartData: {
deep: true,
handler(newVal, oldVal) {
this.initChart()
},
immediate: true
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) { return }
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
if (this.$el) {
this.chart = this.$echarts.init(this.$el)
this.data = cloneDeep(this.chartData) || []
this.setOptions()
}
},
resize() {
this.$_resizeHandler()
},
setOptions() {
let xDateStart = null
let xDateEnd = null
let dateMonthList = []
let xArrayDataValue = []
const legendData = [`${this.title}`, `OD`, `OS`] // series无对应数据时,不显示
const mapLegend = { noEye: `${this.title}`, od: `OD`, os: `OS` }
const seriesData = { noEye: [], od: [], os: [] }
const series = [] // 对象数组,含seriesData
// data 数据处理:排序、转换、x轴数据组织
if (this.data && this.data.length > 0) {
this.disabled = false
this.data.sort((a, b) => {
return new Date(a.examTime) - new Date(b.examTime)
})
this.data = this.data.map(item => {
return { ...item, examDate: formatDate(item.examTime, 'yyyy-MM-dd') }
})
xDateStart = this.data[0].examDate
xDateEnd = this.data[this.data.length - 1 || 0].examDate
dateMonthList = getAllDateMonthList(xDateStart, xDateEnd)
xArrayDataValue = [...new Set(this.data.map(item => item.examDate))]
} else {
this.disabled = true
}
// seriesData 数据填充
this.data.forEach(item => {
if (item.both) {
seriesData.noEye.push({
name: item.examDate,
value: [item.examDate, item.both]
})
}
if (item.od) {
seriesData.od.push({
name: item.examDate,
value: [item.examDate, item.od]
})
}
if (item.os) {
seriesData.os.push({
name: item.examDate,
value: [item.examDate, item.os]
})
}
})
// series 数据组织
Object.keys(seriesData).forEach((key, index) => {
if (seriesData[key] && seriesData[key].length > 0) {
series.push({
name: mapLegend[key],
type: 'line',
data: seriesData[key],
showAllSymbol: true,
smooth: true,
itemStyle: { color: colors[index] },
symbolSize: 10
})
}
})
const thatData = this.data
this.chart.setOption({
title: { text: this.title },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'line' },
confine: true,
formatter: function(params, ticket, callback) {
const thisDate = params[0].data.name
let result = `日期:${thisDate} <br/>`
const dateDataList = thatData.filter(item => {
return String(item.examDate) === String(thisDate)
})
if (dateDataList.find(item => item.both != null)) {
// 无眼别
const tabelBorderStyle = 'border-right:1px solid #fff;border-bottom:1px solid #fff;'
const tdStyle = 'border-left:1px solid #fff;border-top:1px solid #fff;width:60px;text-align:center;'
result += `<table border="0" cellspacing="0" cellpadding="0" style="${tabelBorderStyle}" >
<tr>
<td style="${tdStyle}">数值</td>
<td style="${tdStyle}">检查时间</td>
<td style="${tdStyle}">设备</td>
</tr>`
let trStr = ''
dateDataList.forEach(item => {
trStr += `<tr>
<td style="${tdStyle}">${item.both || '-'}</td>
<td style="${tdStyle} width:100px;">${formatDate(item.examTime, 'hh:mm:ss')}</td>
<td style="${tdStyle}">\xa0${item.deviceName || '-'}\xa0</td>
</tr>`
})
result += `${trStr}</table>`
} else {
// 有眼别
const tabelBorderStyle = 'border-right:1px solid #fff;border-bottom:1px solid #fff;'
const tdStyle = 'border-left:1px solid #fff;border-top:1px solid #fff;width:60px;text-align:center;'
result += `<table border="0" cellspacing="0" cellpadding="0" style="${tabelBorderStyle}" >
<tr>
<td style="${tdStyle}">OD</td>
<td style="${tdStyle}">OS</td>
<td style="${tdStyle}">检查时间</td>
<td style="${tdStyle}">设备</td>
</tr>`
let trStr = ''
dateDataList.forEach(item => {
trStr += `<tr>
<td style="${tdStyle}">${item.od || '-'}</td>
<td style="${tdStyle}">${item.os || '-'}</td>
<td style="${tdStyle} width:100px;text-align:left;padding:0 5px;">
${formatDate(item.examTime, 'hh:mm:ss')}
</td>
<td style="${tdStyle} width:100px;">
${item.deviceName || '-'}
</td>
</tr>`
})
result += `${trStr}</table>`
}
return result
}
},
legend: {
data: legendData,
icon: 'pin'
},
dataZoom: [{
type: 'inside',
disabled: this.disabled,
start: 0,
end: 100
}],
grid: {
top: 45,
left: 50,
right: 50,
bottom: 30,
containLabel: false
},
xAxis: [{
type: 'time',
min: xDateStart,
max: xDateEnd,
data: xArrayDataValue,
splitLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false }
}, {
type: 'category',
position: 'bottom',
data: dateMonthList,
axisPointer: {
triggerTooltip: false,
show: false
},
axisTick: { show: true }
}],
yAxis: { type: 'value' },
series: series
})
}
}
}
</script>
<style scoped>
.chart{
padding: 0 20px;
}
</style>