<template>
|
<div
|
id="chartTableContent"
|
style="width: 100%; height: 100%"
|
>
|
<div class="topSelect">
|
|
<el-input-number
|
v-model="high1"
|
:min="0"
|
:max="15000"
|
label="最低高度"
|
style="width: 130px; margin-left: 10px"
|
controls-position="right"
|
></el-input-number>
|
<el-input-number
|
v-model="high2"
|
:min="0"
|
:max="15000"
|
label="最高高度"
|
style="width: 130px; margin-left: 10px"
|
controls-position="right"
|
></el-input-number>
|
<component
|
:is="dataType"
|
ref="picker"
|
style="padding-left: 0; margin-left: 20px; width: 160px"
|
class="select11"
|
@sendPickerChild="showPickerChild"
|
|
/>
|
<!--查询按钮-->
|
<el-button
|
class="btn1"
|
@click="selectData"
|
>
|
查询
|
</el-button>
|
</div>
|
<div class="pm-profile">
|
<h2 >PM2.5 / PM10 垂直剖面动态演化图</h2>
|
<div ref="chart" class="chart-container"></div>
|
<div class="controls">
|
<p>底部时间轴可拖拽,自动播放</p>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import * as echarts from 'echarts'
|
import HourPicker from '@/components/Form/HourPicker1'
|
export default {
|
name: 'PMProfile',
|
components: {
|
HourPicker
|
},
|
props: {
|
chartData: {
|
type: Object,
|
default: null
|
}
|
},
|
data() {
|
|
return {
|
chart: null,
|
dataType: 'HourPicker',
|
defaultData: {},
|
newData: [],
|
high1: 1000,
|
high2: 7000,
|
timeList: null,
|
currentTimeIdx: 0
|
};
|
},
|
watch: {
|
select1 (nv, ov) {
|
this.unit = 'FiveMinute'
|
}
|
},
|
computed: {
|
chartDataResolved() {
|
return this.chartData || this.defaultData;
|
}
|
},
|
mounted() {
|
const now = new Date();
|
const startTime = new Date(now.getTime() - 20 * 60 * 1000);
|
const fmt = (d) => {
|
const Y = d.getFullYear();
|
const M = String(d.getMonth() + 1).padStart(2, '0');
|
const D = String(d.getDate()).padStart(2, '0');
|
const h = String(d.getHours()).padStart(2, '0');
|
const m = String(d.getMinutes()).padStart(2, '0');
|
const s = String(d.getSeconds()).padStart(2, '0');
|
return `${Y}-${M}-${D} ${h}:${m}:${s}`;
|
};
|
const defaultVal = [fmt(startTime), fmt(now)];
|
this.$refs.picker.value1 = defaultVal;
|
this.$nextTick(() => this.selectData());
|
},
|
beforeDestroy() {
|
if (this.chart) {
|
this.chart.dispose();
|
this.chart = null;
|
}
|
},
|
|
methods: {
|
initChart() {
|
const DATA = this.chartDataResolved;
|
const chartEl = this.$refs.chart;
|
if (!chartEl) return;
|
|
const chartLib = this.$echarts || echarts;
|
if (!chartLib || !chartLib.init) return;
|
|
if (this.chart) {
|
this.chart.dispose();
|
this.chart = null;
|
}
|
this.chart = chartLib.init(chartEl);
|
console.log(DATA);
|
if (!DATA || !DATA.time || !DATA.time.length) {
|
console.log(222);
|
this.chart.setOption({
|
graphic: {
|
type: 'text',
|
left: 'center',
|
top: 'center',
|
style: {
|
text: '未查询到数据',
|
fontSize: 18,
|
fill: '#909399'
|
}
|
}
|
});
|
return;
|
}
|
this.timeList = DATA.time;
|
this.currentTimeIdx = 0;
|
this.chart.setOption({
|
baseOption: {
|
timeline: {
|
axisType: 'category',
|
autoPlay: true,
|
playInterval: 1000,
|
data: DATA.time,
|
label: {
|
formatter: function (s) { return s.slice(0, 5); }
|
},
|
checkpointStyle: { borderColor: '#fff', borderWidth: 2 },
|
controlStyle: { showNextBtn: true, showPrevBtn: true }
|
},
|
title: { text: '', left: 'center', top: 0 },
|
tooltip: {
|
trigger: 'axis',
|
formatter: (params) => {
|
const time = this.timeList ? this.timeList[this.currentTimeIdx] : '';
|
var res = '时间: ' + time + '<br>';
|
params.forEach(function (p) {
|
res += '<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:' + p.color + ';margin-right:4px"></span> '
|
+ p.seriesName + ': ' + p.value[0] + ' μg/m³ @ ' + p.value[1] + 'm<br>';
|
});
|
return res;
|
}
|
},
|
legend: { data: ['PM2.5', 'PM10'], top: 35 },
|
grid: { top: 60, bottom: 100, left: 50, right: 50 },
|
xAxis: { type: 'value', name: '浓度 (μg/m³)', position: 'top', splitLine: { show: true } },
|
//yAxis: { type: 'value', name: '高度 (m)', splitLine: { show: true } },
|
yAxis: { type: 'value', name: '高度 (m)', min: this.high1, max: this.high2, splitLine: { show: true } },
|
series: [
|
{
|
name: 'PM2.5', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6,
|
lineStyle: { width: 3, color: '#ef4444' }, itemStyle: { color: '#ef4444' },
|
areaStyle: { color: 'rgba(239,68,68,0.2)' }, data: []
|
},
|
{
|
name: 'PM10', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6,
|
lineStyle: { width: 3, color: '#3b82f6' }, itemStyle: { color: '#3b82f6' },
|
areaStyle: { color: 'rgba(59,130,246,0.2)' }, data: []
|
}
|
]
|
},
|
options: DATA.time.map(function (time, idx) {
|
return {
|
title: { text: '当前时间: ' + time },
|
series: [
|
{ data: DATA.pm25[idx] },
|
{ data: DATA.pm10[idx] }
|
]
|
};
|
})
|
});
|
|
this.chart.on('timelinechanged', (params) => {
|
this.currentTimeIdx = params.currentIndex;
|
});
|
},
|
selectData () {
|
|
this.$request({
|
url: '/historyRadar/list',
|
method: 'post',
|
data: {
|
startTime: this.newData[0],
|
endTime: this.newData[1],
|
high1: this.high1,
|
high2: this.high2
|
}
|
})
|
.then((res) => {
|
|
this.defaultData = res.data
|
this.$nextTick(() => this.initChart());
|
}).catch((err) => {
|
|
})
|
},
|
showPickerChild (data) {
|
this.newData = data
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.pm-profile {
|
width: 100%;
|
background: #fff;
|
padding: 20px;
|
border-radius: 8px;
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
}
|
.pm-profile h2 {
|
text-align: center;
|
color: #303133;
|
margin: 0 0 20px 0;
|
font-size: 20px;
|
}
|
.chart-container {
|
width: 100%;
|
height: 600px;
|
}
|
.controls {
|
text-align: center;
|
margin-top: 10px;
|
color: #909399;
|
font-size: 14px;
|
}
|
.controls p {
|
margin: 0;
|
}
|
.topSelect {
|
display: flex;
|
margin-bottom: 20px;
|
padding: 20px 15px 0 15px;
|
}
|
.select11 {
|
width: 20% !important;
|
}
|
</style>
|