|
@@ -8,47 +8,49 @@
|
|
|
import * as echarts from "echarts";
|
|
|
require('echarts/theme/macarons') // echarts theme
|
|
|
import resize from '@/utils/resize'
|
|
|
+import { getConfig } from '@/api/site/site'
|
|
|
import { getSiteSection } from '@/api/site/berthing'
|
|
|
-import { getCarLocation } from '@/api/analysis/achievement'
|
|
|
+import { getCarLocation, getWaterLevel } from '@/api/analysis/achievement'
|
|
|
import CarSvg from '@/assets/images/car.svg'
|
|
|
import BarSvg from '@/assets/images/bar.svg'
|
|
|
|
|
|
export default {
|
|
|
mixins: [resize],
|
|
|
props: {
|
|
|
- siteId: Number,
|
|
|
+ siteId: Number | String,
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
sections: [],
|
|
|
+ config: {},
|
|
|
location: 0,
|
|
|
+ waterlevel: 0,
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
this.loadSection();
|
|
|
+ this.loadSiteConfig();
|
|
|
this.loadCarLocation();
|
|
|
+ this.timer1 = setInterval(() => this.loadCarLocation(), 5e3)
|
|
|
+ this.loadWaterLevel();
|
|
|
+ this.timer2 = setInterval(() => this.loadWaterLevel(), 5e3)
|
|
|
this.$nextTick(() => {
|
|
|
this.chart = echarts.init(this.$refs.chart, 'macarons');
|
|
|
})
|
|
|
},
|
|
|
beforeDestroy() {
|
|
|
- if (this.timer1) {
|
|
|
- clearTimeout(this.timer1);
|
|
|
+ if (this.timer1) clearTimeout(this.timer1);
|
|
|
+ if (this.timer2) clearTimeout(this.timer2);
|
|
|
+ if (this.chart) {
|
|
|
+ this.chart.dispose()
|
|
|
+ this.chart = null
|
|
|
}
|
|
|
-
|
|
|
- if (!this.chart) {
|
|
|
- return
|
|
|
- }
|
|
|
- this.chart.dispose()
|
|
|
- this.chart = null
|
|
|
},
|
|
|
methods: {
|
|
|
loadCarLocation() {
|
|
|
getCarLocation(this.siteId).then((res) => {
|
|
|
this.location = res.data?.position || 0;
|
|
|
this.setOptions();
|
|
|
- }).finally(() => {
|
|
|
- this.timer1 = setTimeout(() => this.loadCarLocation(), 5e3)
|
|
|
})
|
|
|
},
|
|
|
loadSection() {
|
|
@@ -57,136 +59,144 @@ export default {
|
|
|
this.setOptions();
|
|
|
})
|
|
|
},
|
|
|
+ loadWaterLevel() {
|
|
|
+ getWaterLevel(this.siteId).then((res) => {
|
|
|
+ this.waterlevel = res.data.waterlevel || 0;
|
|
|
+ this.setOptions();
|
|
|
+ })
|
|
|
+ },
|
|
|
+ loadSiteConfig() {
|
|
|
+ getConfig(this.siteId).then((res) => {
|
|
|
+ this.config = res.data || {};
|
|
|
+ this.setOptions();
|
|
|
+ })
|
|
|
+ },
|
|
|
setOptions() {
|
|
|
- if (!this.chart) {
|
|
|
+ if (!this.chart || !this.config || this.sections.length === 0) {
|
|
|
return;
|
|
|
}
|
|
|
- const xAxisData = this.sections.map(({ x }) => x);
|
|
|
- const seriesData = this.sections.map(({ y }) => y);
|
|
|
- const waterData = this.sections.map(() => 405);
|
|
|
- const locationData = this.sections.map(() => 420);
|
|
|
- const topData = this.sections.map(() => 430);
|
|
|
|
|
|
- console.log(Math.min(...xAxisData), Math.max(...xAxisData))
|
|
|
+ const carWidth = 50; // 小车宽度
|
|
|
+ const carHeight = 32; // 小车高度
|
|
|
+ const gap = carWidth / 2; // 断面左右留的边距,方便绘制立柱
|
|
|
+ const barWidth = 18; // 立柱宽度
|
|
|
+
|
|
|
+ const waterlevel = this.waterlevel;
|
|
|
+ const start = this.config.offset;
|
|
|
+ const location = this.location;
|
|
|
+
|
|
|
+ const sections = [
|
|
|
+ [this.sections[0].x - gap, this.sections[0].y],
|
|
|
+ ...this.sections.map(({x, y}) => [x, y]),
|
|
|
+ [this.sections[this.sections.length - 1].x + gap, this.sections[this.sections.length - 1].y],
|
|
|
+ ];
|
|
|
+
|
|
|
+ const x = sections.map(([x]) => x);
|
|
|
+ const maxX = Math.max(...x);
|
|
|
+ const minX = Math.min(...x);
|
|
|
+ const bar1X = start - (carWidth - barWidth) / 2; // 左侧立柱x坐标
|
|
|
+ const bar2X = maxX - (start - minX) + (carWidth - barWidth) / 2; // 右侧立柱x坐标
|
|
|
+ const boxWidth = (carWidth - barWidth) * 2; // 小车充电盒子宽度
|
|
|
+
|
|
|
+ const y = sections.map(([,y]) => y);
|
|
|
+ const maxY = Math.max(...y);
|
|
|
+ const minY = Math.min(...y);
|
|
|
+ const disY = maxY - minY;
|
|
|
+ const barY = maxY + disY * 1.2;
|
|
|
+ const lineY = maxY + disY * 0.8;
|
|
|
|
|
|
const options = {
|
|
|
- xAxis: [
|
|
|
- {
|
|
|
- data: xAxisData,
|
|
|
- boundaryGap: false,
|
|
|
- show: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: 'value',
|
|
|
- min: Math.min(...xAxisData),
|
|
|
- max: Math.max(...xAxisData),
|
|
|
- show: false,
|
|
|
- }
|
|
|
- ],
|
|
|
- yAxis: [
|
|
|
- {
|
|
|
- name: '高程',
|
|
|
- show: false,
|
|
|
- min: 'dataMin',
|
|
|
- max: 'dataMax',
|
|
|
- },
|
|
|
- ],
|
|
|
grid: {
|
|
|
+ top: 0,
|
|
|
left: 0,
|
|
|
right: 0,
|
|
|
bottom: 0,
|
|
|
- top: 0,
|
|
|
- containLabel: true
|
|
|
+ show: false,
|
|
|
},
|
|
|
- tooltip: {
|
|
|
+ xAxis: {
|
|
|
+ type: 'value',
|
|
|
+ min: minX,
|
|
|
+ max: maxX,
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ min: minY - disY * 0.1,
|
|
|
+ max: maxY + disY * 1.5,
|
|
|
+ type: 'value',
|
|
|
show: false,
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
- name: '水位',
|
|
|
+ data: sections,
|
|
|
type: 'line',
|
|
|
- silent: true,
|
|
|
- data: waterData,
|
|
|
- symbol: 'none',
|
|
|
+ // symbol: 'none',
|
|
|
+ animation: false,
|
|
|
+ z: 10,
|
|
|
lineStyle: {
|
|
|
- normal: {
|
|
|
- width: 0
|
|
|
- }
|
|
|
+ width: 1,
|
|
|
+ color: '#FF8500',
|
|
|
},
|
|
|
areaStyle: {
|
|
|
- normal: {
|
|
|
- color: '#adcef8',
|
|
|
- }
|
|
|
- },
|
|
|
- z: 1,
|
|
|
- },
|
|
|
- {
|
|
|
- name: '小车',
|
|
|
- type: 'scatter',
|
|
|
- data: [[this.location, 420]],
|
|
|
- symbol: `image://${CarSvg}`,
|
|
|
- symbolSize: [50, 30],
|
|
|
- xAxisIndex: 1,
|
|
|
- itemStyle: {
|
|
|
- normal: {
|
|
|
- color: '#ff5722',
|
|
|
- shadowColor: '#ff5722',
|
|
|
- shadowBlur: 100
|
|
|
- }
|
|
|
- },
|
|
|
- silent: true,
|
|
|
- z: 3
|
|
|
- },
|
|
|
- {
|
|
|
- name: '柱子',
|
|
|
- type: 'scatter',
|
|
|
- data: [[40, 420]],
|
|
|
- symbol: `image://${BarSvg}`,
|
|
|
- symbolSize: [20, 500],
|
|
|
- symbolOffset: [0, '50%'],
|
|
|
- xAxisIndex: 1,
|
|
|
- itemStyle: {
|
|
|
- normal: {
|
|
|
- color: '#ff5722',
|
|
|
- shadowColor: '#ff5722',
|
|
|
- shadowBlur: 100
|
|
|
- }
|
|
|
- },
|
|
|
- silent: true,
|
|
|
- z: 3
|
|
|
+ opacity: 1,
|
|
|
+ color: '#ffc27f',
|
|
|
+ }
|
|
|
},
|
|
|
{
|
|
|
- name: '小车',
|
|
|
+ data: [[minX, waterlevel],[maxX, waterlevel]],
|
|
|
type: 'line',
|
|
|
- data: topData,
|
|
|
symbol: 'none',
|
|
|
+ z: 0,
|
|
|
lineStyle: {
|
|
|
- normal: {
|
|
|
- width: 0
|
|
|
- }
|
|
|
+ width: 0,
|
|
|
},
|
|
|
areaStyle: {
|
|
|
- normal: {
|
|
|
- color: 'transparent',
|
|
|
- }
|
|
|
- },
|
|
|
- z: 0,
|
|
|
+ opacity: 1,
|
|
|
+ color: '#a5cdf7',
|
|
|
+ }
|
|
|
},
|
|
|
{
|
|
|
- name: '高程',
|
|
|
+ data: [[bar1X, lineY],[bar2X, lineY]],
|
|
|
type: 'line',
|
|
|
- symbol: false,
|
|
|
- smooth: false,
|
|
|
- data: seriesData,
|
|
|
+ symbol: 'none',
|
|
|
+ z: 2,
|
|
|
lineStyle: {
|
|
|
- color: '#FF8500',
|
|
|
- },
|
|
|
- areaStyle: {
|
|
|
- normal: {
|
|
|
- color: '#f6c27d',
|
|
|
- }
|
|
|
+ width: 2,
|
|
|
+ color: '#54606C',
|
|
|
},
|
|
|
- z: 10,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ data: [[bar1X, barY],[bar2X, barY]],
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: barWidth,
|
|
|
+ z: 3,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#A6B7C7'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ data: [[location, lineY]],
|
|
|
+ type: 'scatter',
|
|
|
+ symbol: `image://${CarSvg}`,
|
|
|
+ symbolSize: [carWidth, carHeight],
|
|
|
+ symbolOffset: [0, -6],
|
|
|
+ silent: true,
|
|
|
+ z: 3,
|
|
|
+ itemStyle: {
|
|
|
+ opacity: 1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ data: [[start, lineY]],
|
|
|
+ type: 'scatter',
|
|
|
+ symbol: 'rect',
|
|
|
+ symbolSize: [boxWidth, 30],
|
|
|
+ symbolOffset: [0, '-50%'],
|
|
|
+ silent: true,
|
|
|
+ z: 4,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#778CB2',
|
|
|
+ opacity: 0.5
|
|
|
+ }
|
|
|
},
|
|
|
]
|
|
|
};
|