<template>
|
<div class="per_calendar">
|
<div class="month-current">{{ getMonth }}</div>
|
<el-calendar v-model="value" @change="pick">
|
<template
|
slot="dateCell"
|
slot-scope="{date, data}"
|
>
|
<!-- 遮罩层 -->
|
<div>
|
<span v-if="(getDataValues[data.day] === undefined || getDataValues[data.day] === null)">{{ data.day.split('-').slice(2).join('-') }}</span>
|
<div
|
v-else
|
class="area_discover"
|
:class="getDataValues[data.day][sensor] < levelSensor[sensorObj[sensor]][0] ? 'green1' :
|
getDataValues[data.day][sensor] < levelSensor[sensorObj[sensor]][1] ? 'yellow1' :
|
getDataValues[data.day][sensor] < levelSensor[sensorObj[sensor]][2] ? 'orange1' :
|
getDataValues[data.day][sensor] < levelSensor[sensorObj[sensor]][3] ? 'red1' :
|
getDataValues[data.day][sensor] < levelSensor[sensorObj[sensor]][4] ? 'oRed1' : 'violet1'"
|
@mouseenter="pick(data.day, $event)"
|
@mouseleave="leave"
|
>
|
<span>{{ data.day.split('-').slice(2).join('-') }}</span>
|
<div class="details" :class="{showdetails: selectDay === data.day}" :style="{ position: 'fixed',left: dynamicLeft, top: dynamicTop}">
|
<div class="header_time"> {{ data.day }} </div>
|
<div v-for="(item, key, index) in daySensorDetail" :key="index" class="details_value">
|
<span>{{ sensorObj[key] === 'O3' ? 'O3_8H' : sensorObj[key] }}:</span>
|
<span style="word-break: break-word; color: #66b1ff">{{ key === 'primaryPollutant' ? item === '' || item === null ? '' : JSON.parse(item).join() : item }}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
</el-calendar>
|
<div class="statistics">
|
<span v-for="(item, key, index) in pollutionDays" :key="index">
|
<span class="text_right">{{ key }}: </span>
|
<span
|
class="circular_data"
|
:class="key === '优' ? 'green1' : key === '良' ? 'yellow1' : key === '轻度' ? 'orange1' : key === '中度' ? 'red1' : key === '重度' ? 'oRed1' : 'violet1'"
|
>
|
{{ item }}
|
</span></span>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
props: {
|
dateMonth: {
|
type: String,
|
default: ''
|
},
|
dataValues: {
|
type: Object,
|
default: () => {}
|
},
|
selectSensor: {
|
type: String,
|
default: ''
|
}
|
},
|
data() {
|
return {
|
value: '',
|
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
|
selectDay: '',
|
sensor: 'AQI',
|
sensorObj: {
|
CO: 'CO',
|
NO2: 'NO2',
|
O3: 'O3',
|
PM2_5: 'PM2.5',
|
PM10: 'PM10',
|
SO2: 'SO2',
|
AQI: 'AQI',
|
primaryPollutant: '首要污染物'
|
},
|
// 因子报警区间
|
levelSensor: {
|
'PM2.5': [35, 75, 115, 150, 250],
|
'PM10': [50, 150, 250, 350, 420],
|
'SO2': [50, 150, 475, 800, 1600],
|
'NO2': [40, 80, 180, 280, 565],
|
'CO': [2, 4, 14, 24, 36],
|
'O3': [100, 160, 215, 265, 800],
|
'AQI': [50, 100, 150, 200, 300]
|
},
|
// 不同因子每个月污染天数
|
pollutionDays: {},
|
// 每天的因子数据
|
daySensorDetail: {},
|
dynamicTop: 0,
|
dynamicLeft: 0
|
}
|
},
|
computed: {
|
getMonth() {
|
const date = new Date(this.value)
|
return this.months[date.getMonth()]
|
},
|
getDataValues() {
|
return this.dataValues
|
}
|
},
|
watch: {
|
dataValues() {
|
this.getDayOfSensor(this.sensor)
|
},
|
selectSensor() {
|
this.sensor = this.selectSensor
|
this.getDayOfSensor(this.sensor)
|
}
|
},
|
created() {
|
// this.getDayOfSensor('PM2_5')
|
this.getDayOfSensor(this.sensor)
|
},
|
mounted() {
|
this.value = this.dateMonth
|
},
|
methods: {
|
// 鼠标移入气泡显示并赋值数据
|
pick(day, e) {
|
// console.log(this.getDataValues)
|
// console.log(111, e)
|
this.selectDay = day
|
this.daySensorDetail = this.getDataValues[this.selectDay]
|
const sortArr = ['AQI', 'PM2_5', 'PM10', 'SO2', 'NO2', 'CO', 'O3', 'primaryPollutant']// 指定排序顺序
|
const getArr = {}// 接收新顺序
|
sortArr.forEach(item => {
|
Object.keys(this.daySensorDetail).forEach(key => {
|
if (item === key) {
|
getArr[key] = this.daySensorDetail[key]
|
}
|
})
|
})
|
this.daySensorDetail = getArr
|
// 动态改变气泡的宽度
|
const calendarMain = document.getElementsByClassName('calendar_main')[0]
|
// 获取节点距离浏览器视口的宽度
|
const left = e.target.getBoundingClientRect().left
|
const top = e.target.getBoundingClientRect().top - 136
|
const width = (calendarMain.offsetWidth + calendarMain.getBoundingClientRect().left - left - 64)
|
if (width < 196) {
|
e.target.lastChild.style.width = width + 'px'
|
}
|
this.dynamicTop = top + 'px'
|
this.dynamicLeft = (left + 40) + 'px'
|
},
|
// 鼠标移出气泡隐藏
|
leave() {
|
this.selectDay = ''
|
},
|
// 获取每个月数据优良天数
|
getDayOfSensor(sensor) {
|
const dayObj = {
|
'优': 0,
|
'良': 0,
|
'轻度': 0,
|
'中度': 0,
|
'重度': 0,
|
'严重': 0
|
}
|
for (const dataValuesKey in this.getDataValues) {
|
if (this.getDataValues[dataValuesKey] !== null) {
|
const sen = this.sensorObj[sensor]
|
if (this.getDataValues[dataValuesKey][sensor] < this.levelSensor[sen][0]) {
|
dayObj['优']++
|
} else if (this.getDataValues[dataValuesKey][sensor] < this.levelSensor[sen][1]) {
|
dayObj['良']++
|
} else if (this.getDataValues[dataValuesKey][sensor] < this.levelSensor[sen][2]) {
|
dayObj['轻度']++
|
} else if (this.getDataValues[dataValuesKey][sensor] < this.levelSensor[sen][3]) {
|
dayObj['中度']++
|
} else if (this.getDataValues[dataValuesKey][sensor] < this.levelSensor[sen][4]) {
|
dayObj['重度']++
|
} else {
|
dayObj['严重']++
|
}
|
}
|
}
|
this.pollutionDays = dayObj
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.is-selected {
|
color: #1989FA;
|
}
|
.month-current {
|
text-align: center;
|
color: grey;
|
}
|
/deep/.el-calendar__header {
|
display: none;
|
}
|
/deep/.el-calendar-table__row .prev {
|
visibility: hidden;
|
}
|
/deep/.el-calendar-table__row .prev .el-calendar-day {
|
padding: 0;
|
width: 28px;
|
height: 28px;
|
line-height: 28px;
|
text-align: center;
|
font-size: 14px;
|
}
|
/deep/.el-calendar-table__row .next {
|
visibility: hidden;
|
}
|
/deep/.el-calendar-table__row .next .el-calendar-day {
|
padding: 0;
|
width: 28px;
|
height: 28px;
|
line-height: 28px;
|
text-align: center;
|
font-size: 14px;
|
}
|
/deep/.el-calendar-table__row .current {
|
border: none;
|
}
|
/deep/.el-calendar-table__row .current .el-calendar-day{
|
padding: 0;
|
width: 28px;
|
height: 28px;
|
line-height: 28px;
|
text-align: center;
|
font-size: 14px;
|
}
|
/deep/td.is-selected {
|
background-color: white;
|
}
|
/deep/td.is-today {
|
color: black;
|
}
|
.area_discover {
|
position: relative;
|
width: 100%;
|
height: 26px;
|
font-size: 14px;
|
line-height: 28px;
|
}
|
.area_discover:hover>span {
|
color: white;
|
/*background-color: rgba(0, 0, 0, .8);*/
|
}
|
.statistics {
|
position: relative;
|
top: -36px;
|
left: 12px;
|
display: flex;
|
font-size: 14px;
|
justify-content: space-around;
|
flex-wrap: wrap;
|
}
|
.statistics > span{
|
display: inline-block;
|
width: 33.3%;
|
margin-top: 6px;
|
}
|
.details {
|
display: none;
|
/*visibility: hidden;*/
|
}
|
.showdetails {
|
display: block;
|
/*visibility: visible;*/
|
box-sizing: border-box;
|
position: fixed;
|
text-align: left;
|
width:196px;
|
/*height:260px;*/
|
background-color: #FFFFFF;
|
border: #cccccc solid 1px;
|
border-radius: 8px;
|
padding-bottom: 6px;
|
z-index: 100;
|
}
|
|
.showdetails:before{
|
box-sizing: border-box;
|
width: 0px;
|
height: 0px;
|
position: absolute;
|
top: 140px;
|
left: -16px;
|
padding:0;
|
border-right: 8px solid #FFFFFF;
|
border-top:8px solid transparent;
|
border-bottom: 8px solid transparent;
|
border-left:8px solid transparent;
|
display: block;
|
content:'';
|
z-index: 12;
|
}
|
.showdetails:after{
|
box-sizing: border-box;
|
width: 0px;
|
height: 0px;
|
position: absolute;
|
top: 139px;
|
left: -18px;
|
padding:0;
|
border-right: 9px solid #cccccc;
|
border-top:9px solid transparent;
|
border-bottom:9px solid transparent;
|
border-left:9px solid transparent;
|
display: block;
|
content:'';
|
z-index:1
|
}
|
|
.header_time {
|
position: relative;
|
margin: 0;
|
width: 100%;
|
height: 40px;
|
line-height: 40px;
|
background-color: #7AB9F9;
|
color: #fff;
|
font-size: 16px;
|
padding-left: 10px;
|
border-radius: 7px 7px 0 0;
|
text-align: left;
|
margin-bottom: 6px;
|
}
|
.details_value {
|
padding-left: 10px;
|
line-height: 20px;
|
}
|
|
.text_right {
|
display: inline-block;
|
width: 50%;
|
text-align: right;
|
}
|
.circular_data {
|
color: #fff;
|
text-shadow: 1px 1px 1px rgba(84, 84, 0, 0.6);
|
display: inline-block;
|
width: 28px;
|
height: 20px;
|
line-height: 20px;
|
border-radius: 10px;
|
text-align: center;
|
}
|
/*背景颜色*/
|
.green1{
|
background: #00e400;
|
}
|
.yellow1{
|
/*background-color: #ffff00;*/
|
background-color: #ffd304;
|
}
|
.orange1{
|
background-color: #ff7e00;
|
}
|
.red1{
|
background-color: #ff0000;
|
}
|
.oRed1{
|
background-color: #99004c;
|
}
|
.violet1{
|
background-color: #7e0023;
|
}
|
</style>
|