From f5624d6a7ad32ee475e00edbad26bc98ea4629e1 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期五, 10 五月 2024 17:35:54 +0800 Subject: [PATCH] 实时走航模块 --- src/assets/common-style.css | 11 + src/utils/chart/chart-option.js | 79 +++++++++++ src/components/monitor/VehicleData.vue | 44 ++++++ src/components/monitor/WeatherData.vue | 80 +++++++++++ src/components.d.ts | 3 src/components/mission/MissionManage.vue | 2 src/views/realtimemode/RealtimeMode.vue | 68 +++++++++ src/views/realtimemode/component/DashBoard.vue | 32 ++++ src/styles/elementUI.scss | 4 src/components/monitor/GaugeChart.vue | 45 ++++++ 10 files changed, 359 insertions(+), 9 deletions(-) diff --git a/src/assets/common-style.css b/src/assets/common-style.css index a0c5d3e..83a6e27 100644 --- a/src/assets/common-style.css +++ b/src/assets/common-style.css @@ -216,6 +216,7 @@ border: 1px solid white; border-radius: 2px; -moz-border-radius: 25px; + width: 120px; /* Old Firefox */ } @@ -291,11 +292,13 @@ text-align: center; overflow-y: scroll; } + table.easy-table th { background-color: var(--bg-color-2); border: 1px solid #ffffffce; white-space: nowrap; } + table.easy-table td { cursor: pointer; min-width: 50px; @@ -334,6 +337,7 @@ /* overflow: scroll; */ /* overflow-y: scroll; */ } + table.border-table th { cursor: pointer; background-color: var(--bg-color-2); @@ -341,6 +345,7 @@ /* box-shadow: 0px 1.1px 2.5px #888888; */ white-space: nowrap; } + table.border-table td { cursor: pointer; min-width: 60px; @@ -437,7 +442,7 @@ /* line-height: 20px; */ } -div.refresh-btn{ +div.refresh-btn { padding: 0px 6px; text-align: right; } @@ -469,11 +474,11 @@ line-height: 12px } -div.info-middle .text-table td.last-col{ +div.info-middle .text-table td.last-col { text-align: left; } -div.info-middle .text-table tr.divide{ +div.info-middle .text-table tr.divide { /* line-height: 16px; */ border-bottom: 1px dashed #ffffff93; } diff --git a/src/components.d.ts b/src/components.d.ts index 6880056..1c2f542 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -41,6 +41,7 @@ FactorCheckbox: typeof import('./components/monitor/FactorCheckbox.vue')['default'] FactorLegend: typeof import('./components/monitor/FactorLegend.vue')['default'] FactorRadio: typeof import('./components/monitor/FactorRadio.vue')['default'] + GaugeChart: typeof import('./components/monitor/GaugeChart.vue')['default'] HistoricalTrajectory: typeof import('./components/animation/HistoricalTrajectory.vue')['default'] LineChart: typeof import('./components/monitor/LineChart.vue')['default'] MapToolbox: typeof import('./components/map/MapToolbox.vue')['default'] @@ -56,6 +57,8 @@ SearchBar: typeof import('./components/search/SearchBar.vue')['default'] SliderBar: typeof import('./components/SliderBar.vue')['default'] TrajectoryState: typeof import('./components/animation/TrajectoryState.vue')['default'] + VehicleData: typeof import('./components/monitor/VehicleData.vue')['default'] + WeatherData: typeof import('./components/monitor/WeatherData.vue')['default'] } export interface ComponentCustomProperties { vLoading: typeof import('element-plus/es')['ElLoadingDirective'] diff --git a/src/components/mission/MissionManage.vue b/src/components/mission/MissionManage.vue index 124400a..ba24f8f 100644 --- a/src/components/mission/MissionManage.vue +++ b/src/components/mission/MissionManage.vue @@ -111,7 +111,7 @@ }; }, computed: { - ...mapState(useMissionStore, ['missionList']) + ...mapState(useMissionStore, ['missionLi1st']) }, methods: { createMission() {}, diff --git a/src/components/monitor/GaugeChart.vue b/src/components/monitor/GaugeChart.vue new file mode 100644 index 0000000..592f4b2 --- /dev/null +++ b/src/components/monitor/GaugeChart.vue @@ -0,0 +1,45 @@ +<template> + <div ref="gaugeChart" class="gauge-chart"></div> +</template> +<script> +import * as echarts from 'echarts'; +import { gaugeOption } from '@/utils/chart/chart-option'; + +export default { + props: { + name: String, + value: Number + }, + data() { + return { + option: null + }; + }, + watch: { + value(nV) { + this.refreshChart(nV); + } + }, + methods: { + initChart() { + this.option = gaugeOption(this.name, this.value); + this.gaugeChart.setOption(this.option); + }, + refreshChart(e) { + this.option.data[0].value = e; + this.gaugeChart.setOption(this.option); + } + }, + mounted() { + this.gaugeChart = echarts.init(this.$refs.gaugeChart); + this.initChart(); + } +}; +</script> +<style scoped> +.gauge-chart { + height: 280px; + width: 260px; + /* background-color: aliceblue; */ +} +</style> diff --git a/src/components/monitor/VehicleData.vue b/src/components/monitor/VehicleData.vue new file mode 100644 index 0000000..6121556 --- /dev/null +++ b/src/components/monitor/VehicleData.vue @@ -0,0 +1,44 @@ +<template> + <el-row class="wrap"> + <el-form :inline="true"> + <el-form-item label="杞﹂�燂細" class="tag-2"> + {{ speed }} + </el-form-item> + </el-form> + <GaugeChart name="杞﹂��" :speed="speed"></GaugeChart> + </el-row> +</template> +<script> +import { FactorDatas } from '@/model/FactorDatas'; + +export default { + props: { + loading: Boolean, + factorDatas: FactorDatas + }, + data() { + return { + speed: '--km/h' + }; + }, + watch: { + factorDatas: { + handler(nV) { + this.speed = this.lastOne(nV, '14') + 'km/h'; + }, + deep: true + } + }, + methods: { + lastOne(factorDatas, key) { + const f = factorDatas.factor[key]; + if (f) { + const lastIndex = f.datas.length - 1; + return factorDatas.factor[key].datas[lastIndex].factorData; + } else { + return '--'; + } + } + } +}; +</script> diff --git a/src/components/monitor/WeatherData.vue b/src/components/monitor/WeatherData.vue new file mode 100644 index 0000000..7d6ab88 --- /dev/null +++ b/src/components/monitor/WeatherData.vue @@ -0,0 +1,80 @@ +<template> + <el-row class="wrap"> + <el-form :inline="true"> + <el-form-item label="娓╁害锛�" class="tag-2"> + {{ temprature }} + </el-form-item> + <el-form-item label="婀垮害锛�" class="tag-2"> + {{ humidity }} + </el-form-item> + </el-form> + <!-- <div class="tag-2">{{ temprature }}</div> + <div class="tag-2">{{ humidity }}</div> --> + </el-row> + <el-row class="wrap"> + <el-form :inline="true"> + <el-form-item label="椋庡悜锛�" class="tag-2"> + {{ windDirection }} + </el-form-item> + <el-form-item label="椋庨�燂細" class="tag-2"> + {{ windSpeed }} + </el-form-item> + </el-form> + <!-- <div class="tag-2">{{ windDirection }}</div> + <div class="tag-2">{{ windSpeed }}</div> --> + </el-row> +</template> +<script> +import { FactorDatas } from '@/model/FactorDatas'; + +export default { + props: { + loading: Boolean, + factorDatas: FactorDatas + }, + data() { + return { + temprature: '--鈩�', + humidity: '--%', + windDirection: '--', + windSpeed: '--m/s' + }; + }, + watch: { + factorDatas: { + handler(nV) { + this.temprature = this.lastOne(nV, '8') + '鈩�'; + this.humidity = this.lastOne(nV, '9') + '%'; + this.windDirection = this.lastOne(nV, '17'); + this.windSpeed = this.lastOne(nV, '16') + 'm/s'; + }, + deep: true + } + }, + // computed: { + // temprature() { + // return `${this.lastOne('TEMPERATURE')}鈩僠; + // }, + // humidity() { + // return `${this.lastOne('HUMIDITY')}%`; + // }, + // windDirection() { + // return `${this.lastOne('WIND_DIRECTION')}`; + // }, + // windSpeed() { + // return `${this.lastOne('WIND_SPEED')}m/s`; + // } + // }, + methods: { + lastOne(factorDatas, key) { + const f = factorDatas.factor[key]; + if (f) { + const lastIndex = f.datas.length - 1; + return factorDatas.factor[key].datas[lastIndex].factorData; + } else { + return '--'; + } + } + } +}; +</script> diff --git a/src/styles/elementUI.scss b/src/styles/elementUI.scss index 813ba05..8464ecc 100644 --- a/src/styles/elementUI.scss +++ b/src/styles/elementUI.scss @@ -7,7 +7,7 @@ } .el-form-item__label { - color: white; + color: white !important; } // .el-radio { @@ -24,4 +24,4 @@ .el-button-custom:focus-visible { outline: 0px solid var(--el-button-outline-color); -} \ No newline at end of file +} diff --git a/src/utils/chart/chart-option.js b/src/utils/chart/chart-option.js index 250e550..556a0bb 100644 --- a/src/utils/chart/chart-option.js +++ b/src/utils/chart/chart-option.js @@ -14,6 +14,7 @@ return fontSize; } +// 鎶樼嚎鍥� function factorLineOption(_xAxis, _series, legends) { var fontSize = fGetChartFontSize(); return { @@ -104,4 +105,80 @@ }; } -export { factorLineOption }; +// 浠〃鐩� +function gaugeOption(name, value) { + var fontSize = fGetChartFontSize(); + var option = { + title: { + text: name, + textStyle: { + color: 'white', + fontSize: fontSize + }, + left: 'center' + }, + textStyle: { + color: '#ffffff', + fontSize: 10 + }, + tooltip: { + formatter: '{a} <br/>{b} : {c}%' + }, + toolbox: { + // feature: { + // restore: {}, + // saveAsImage: {} + // } + }, + series: [ + { + name: name, + type: 'gauge', + detail: { + color: 'white', + formatter: '{value}', + textStyle: { + fontSize: fontSize + } + }, + splitLine: { + lineStyle: { + color: 'white' + } + }, + axisTick: { + lineStyle: { + color: 'white' + } + }, + axisLabel: { + color: 'white', + fontSize: 10 + }, + axisLine: { + lineStyle: { + color: [ + [0.2, '#2afd2a'], + [0.8, '#f1e74d'], + [1, '#c23531'] + ] + } + }, + itemStyle: { + color: 'white' + }, + data: [ + { + value: value, + name: '' + } + ], + min: 0, + max: 200 + } + ] + }; + return option; +} + +export { factorLineOption, gaugeOption }; diff --git a/src/views/realtimemode/RealtimeMode.vue b/src/views/realtimemode/RealtimeMode.vue index b991977..f1e9bf0 100644 --- a/src/views/realtimemode/RealtimeMode.vue +++ b/src/views/realtimemode/RealtimeMode.vue @@ -1,9 +1,73 @@ <template> - <div>RealtimeMode</div> + <div class="p-events-none m-t-2"> + <el-row justify="center" align="middle" class="top-wrap"> </el-row> + <el-row class="m-t-2"> + <FactorRadio + :device-type="deviceType" + @change="(e) => (factorType = e)" + ></FactorRadio> + </el-row> + <el-row class="m-t-2"> + <FactorLegend + class="m-t-2" + :factor="factorDatas.factor[factorType]" + ></FactorLegend> + </el-row> + <el-row class="m-t-2" justify="start"> + <DashBoard :factor-datas="factorDatas"></DashBoard> + </el-row> + </div> </template> <script> +import { useFetchData } from '@/composables/fetchData'; +import { TYPE0 } from '@/constant/device-type'; +import { FactorDatas } from '@/model/FactorDatas'; +import monitorDataApi from '@/api/monitorDataApi'; +import DashBoard from './component/DashBoard.vue'; + export default { - name: 'HistoryPage' + components: { DashBoard }, + setup() { + const { loading, fetchData } = useFetchData(10000); + return { loading, fetchData }; + }, + data() { + return { + // 鐩戞祴璁惧绫诲瀷 + deviceType: TYPE0, + // 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙� + factorType: '1', + // 鐩戞祴鏁版嵁 + factorDatas: new FactorDatas() + }; + }, + methods: { + onFetchData(type, data) { + // todo 鏍规嵁璁惧绫诲瀷鍒囨崲鍦板浘鐩戞祴鍥犲瓙灞曠ず鍗曢�夋銆佹姌绾垮浘澶嶉�夋銆佹暟鎹〃鏍煎閫夋鐨勫洜瀛愮被鍨� + this.deviceType = type; + this.factorDatas.setData(data, this.drawMode, () => { + this.factorDatas.refreshHeight(this.factorType); + // this.draw(); + }); + }, + fetchRealTimeData() { + // fixme 2024.5.3 姝ゅ鍒濆鑾峰彇鐨勬暟鎹紝鍙傛暟搴旇鐢眘earchbar鍐冲畾锛屽悗缁慨鏀� + this.fetchData((page) => { + return monitorDataApi + .fetchHistroyData({ + deviceCode: '0a0000000001', + page, + perPage: 100 + }) + .then((res) => { + this.onFetchData(TYPE0, res.data); + }); + }); + } + }, + mounted() { + this.fetchRealTimeData(); + } }; </script> diff --git a/src/views/realtimemode/component/DashBoard.vue b/src/views/realtimemode/component/DashBoard.vue new file mode 100644 index 0000000..13df5ad --- /dev/null +++ b/src/views/realtimemode/component/DashBoard.vue @@ -0,0 +1,32 @@ +<template> + <el-row class="wrap"> + <el-col v-show="show" span="10"> + <BaseCard> + <template #content> + <WeatherData :factor-datas="factorDatas"></WeatherData> + <VehicleData :factor-datas="factorDatas"></VehicleData> + </template> + </BaseCard> + </el-col> + <el-col span="2"> + <CardButton name="瀹炴椂鐩戞祴" @click="() => (show = !show)"></CardButton> + </el-col> + </el-row> +</template> +<script> +import { FactorDatas } from '@/model/FactorDatas'; + +export default { + props: { + deviceType: { + type: String + }, + factorDatas: FactorDatas + }, + data() { + return { + show: true + }; + } +}; +</script> -- Gitblit v1.9.3