实现卫星信息监控页面的显示

master
叶志超 2021-11-24 19:37:16 +08:00
parent d6afa63135
commit a800048b5a
5 changed files with 315 additions and 31 deletions

View File

@ -1,40 +1,143 @@
<template>
<div class="center-cmp">
<div class="cc-header">
<dv-decoration-1 style="width:200px;height:50px;" />
<div>机电设备总数</div>
<dv-decoration-1 style="width:200px;height:50px;" />
<Decoration1 style="width:200px;height:50px;" />
<div>监测到卫星总数</div>
<Decoration1 style="width:200px;height:50px;" />
</div>
<div class="cc-details">
<div class="card">2</div>
<div class="card">1</div>
<div class="card">3</div>
<div class="card">5</div>
<div class="card">7</div>
</div>
<div class="cc-main-container">
<div class="ccmc-left">
<div class="station-info">
收费站<span>1315</span>
  <span>15</span>
</div>
<div class="station-info">
监控中心<span>415</span>
<span>15</span>
</div>
</div>
<dv-active-ring-chart class="ccmc-middle" :config="config" />
<div class="ccmc-middle">
<Ring />
</div>
<div class="ccmc-right">
<div class="station-info">
<span>90</span>道路外场
<span>10</span>G P S
</div>
<div class="station-info">
<span>317</span>其他
<span>17</span>格洛纳斯
</div>
</div>
<LabelTag :config="labelConfig" />
</div>
</div>
</template>
<script lang="ts" setup>
import Ring from './Ring.vue'
import Decoration1 from './Layout/Decoration1.vue'
import Decoration5 from './Layout/Decoration5.vue'
</script>
<style scoped>
.center-cmp {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
display: flex;
flex-direction: column;
}
.cc-header {
height: 125px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30px;
}
.cc-details {
height: 120px;
display: flex;
justify-content: center;
font-size: 32px;
align-items: center;
}
.cc-details .card {
background-color: rgba(4,49,128,.6);
color: #08e5ff;
height: 100px;
width: 100px;
font-size: 65px;
font-weight: bold;
line-height: 100px;
text-align: center;
margin: 10px;
}
.cc-main-container {
position: relative;
flex: 1;
display: flex;
}
.ccmc-middle {
width: 50%;
}
.active-ring-name {
font-size: 20px !important;
}
.ccmc-left, .ccmc-right {
width: 25%;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 24px;
}
.ccmc-left span, .ccmc-right span {
font-size: 30px;
font-weight: bold;
}
.ccmc-left .station-info, .ccmc-right .station-info {
height: 80px;
display: flex;
align-items: center;
}
.ccmc-left {
align-items: flex-end;
}
.ccmc-left span {
margin-left: 10px;
}
.ccmc-right {
align-items: flex-start;
}
.ccmc-right span {
margin-right: 10px;
}
.label-tag {
position: absolute;
width: 500px;
height: 30px;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
</style>

View File

@ -8,7 +8,7 @@
<rect
v-if="Math.random() > 0.6"
:key="i"
:fill="mergedColor[0]"
:fill="defaultColor[0]"
:x="point[0] - halfPointSideLength"
:y="point[1] - halfPointSideLength"
:width="pointSideLength"
@ -17,7 +17,7 @@
<animate
v-if="Math.random() > 0.6"
attributeName="fill"
:values="`${mergedColor[0]};transparent`"
:values="`${defaultColor[0]};transparent`"
dur="1s"
:begin="Math.random() * 2"
repeatCount="indefinite"
@ -27,7 +27,7 @@
<rect
v-if="rects[0]"
:fill="mergedColor[1]"
:fill="defaultColor[1]"
:x="rects[0][0] - pointSideLength"
:y="rects[0][1] - pointSideLength"
:width="pointSideLength * 2"
@ -61,7 +61,7 @@
<rect
v-if="rects[1]"
:fill="mergedColor[1]"
:fill="defaultColor[1]"
:x="rects[1][0] - 40"
:y="rects[1][1] - pointSideLength"
:width="40"
@ -85,10 +85,67 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ref, onMounted, reactive } from 'vue'
const dom = ref(null)
const width = ref(0)
const height = ref(0)
const svgWH = [200, 50]
const rowNum = 4
const rowPoints = 20
const defaultColor = ['#fff', '#0de7c2']
const pointSideLength = 2.5
const halfPointSideLength = pointSideLength / 2
let rects = reactive([])
let points = reactive([])
let svgScale = reactive([1, 1])
const calcPointsPosition = () => {
const [w, h] = svgWH
const horizontalGap = w / (rowPoints + 1)
const verticalGap = h / (rowNum + 1)
let pointArr = new Array(rowNum).fill(0).map((foo, i) =>
new Array(rowPoints).fill(0).map((foo, j) => [
horizontalGap * (j + 1), verticalGap * (i + 1)
])
)
points = pointArr.reduce((all, item) => [...all, ...item], [])
}
const calcRectsPosition = () => {
const rect1 = points[rowPoints * 2 - 1]
const rect2 = points[rowPoints * 2 - 3]
rects = [rect1, rect2]
}
const calcSVGData = () => {
calcPointsPosition()
calcRectsPosition()
calcScale()
}
const calcScale = () => {
const [w, h] = svgWH
svgScale = [width.value / w, height.value / h]
}
onMounted(() => {
width.value = dom.value.clientWidth
height.value = dom.value.clientHeight
calcSVGData()
})
</script>
<style>

View File

@ -0,0 +1,90 @@
<template>
<v-chart ref="ring" :option="option" />
</template>
<script lang="ts" setup>
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { LegendComponent } from "echarts/components";
import { PieChart } from "echarts/charts";
import VChart from "vue-echarts";
import { ref, reactive, onMounted } from "vue";
use([
CanvasRenderer,
LegendComponent,
PieChart
]);
const option = reactive({
legend: {
bottom: '5%',
left: 'center',
selectedMode: false,
itemGap: 15,
itemWidth: 35,
itemHeight: 20,
textStyle: {
color: 'white',
fontSize: 16
}
},
series: [
{
type: 'pie',
radius: ['40%', '70%'],
startAngle: 180,
label: {
show: false,
position: 'center'
},
emphasis: {
scaleSize: 25,
label: {
show: true,
color: 'white',
fontSize: '28',
fontWeight: 'bold',
formatter: '{c}\n\n{b}'
}
},
labelLine: {
show: false
},
data: [
{ value: 15, name: '北 斗' },
{ value: 10, name: 'G P S' },
{ value: 15, name: '格洛纳斯' },
{ value: 17, name: '伽 利 略' }
]
}
]
});
let highlightIndex = -1
const ring = ref(null)
const COUNT = option.series[0].data.length
const highlight = () => {
ring.value.dispatchAction({
type: 'downplay',
dataIndex: highlightIndex
})
highlightIndex++
if (highlightIndex >= COUNT) highlightIndex = 0
ring.value.dispatchAction({
type: 'highlight',
dataIndex: highlightIndex
})
}
onMounted(() => {
setInterval(highlight, 3000)
})
const update = console.log
defineExpose({ update })
</script>

View File

@ -1,5 +1,7 @@
<template>
<div class="satellite-table overflow-hidden">
<div class="satellite-table h-full flex flex-col">
<div class="text-center text-3xl my-2">{{ title }}</div>
<div class="table-header flex">
<div
class="table-header-item leading-10 flex-1"
@ -9,13 +11,12 @@
/>
</div>
<div class="table-body flex flex-col overflow-hidden">
<div class="table-body flex-grow bg-red-100">
<div
class="row-item flex"
v-for="(row, ri) in data.satellites"
:key="`${row.toString()}`"
:style="`
line-height: 40px;
background-color: ${ri % 2 === 0 ? evenRowBGC : oddRowBGC};
`"
>
@ -33,12 +34,26 @@
<script lang="ts" setup>
import { reactive } from 'vue'
defineProps({
title: String
})
const oddRowBGC = '#003B51'
const evenRowBGC = '#0A2732'
const header = ['卫星编号', '仰角', '方位角', '载噪比']
const data = reactive({
satellites: [{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25}]
satellites: [
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
{id: "20", elevationDeg: 68, azimuthTrue: 322, SNRdB: 25},
]
})
const update = (GSVArr: Array<any>) => {
@ -59,4 +74,8 @@ defineExpose({ update })
.table-header {
background-color: rgb(25, 129, 246);
}
.row-item {
line-height: 38px;
}
</style>

View File

@ -2,14 +2,28 @@
<full-screen-container>
<TheHeader title="卫星信息监控平台" />
<div class="main-content flex-1 grid grid-cols-3 grid-rows-2 grid-flow-col gap-4">
<border-box-3>
<ScrollBoardTable ref="BDScrollBoardTable" />
</border-box-3>
<border-box-3></border-box-3>
<border-box-3 class="row-span-2"></border-box-3>
<border-box-3></border-box-3>
<border-box-3></border-box-3>
<div class="main-content flex flex-1">
<div class="w-1/4 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable title="北  斗" ref="BDScrollBoardTable" />
</border-box-3>
<border-box-3>
<ScrollBoardTable title="伽 利 略" ref="GAScrollBoardTable" />
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp />
</border-box-3>
</div>
<div class="w-1/4 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable title="G P S" ref="GPScrollBoardTable" />
</border-box-3>
<border-box-3>
<ScrollBoardTable title="格洛纳斯" ref="GLScrollBoardTable" />
</border-box-3>
</div>
</div>
</full-screen-container>
</template>
@ -18,6 +32,7 @@
import FullScreenContainer from '../components/Layout/FullScreenContainer.vue'
import TheHeader from '../components/Layout/TheHeader.vue'
import BorderBox3 from '../components/Layout/BorderBox3.vue'
import CenterCmp from '../components/CenterCmp.vue'
import ScrollBoardTable from '../components/ScrollBoardTable.vue'
import { ref, onMounted } from 'vue'