实现卫星信息监控页面的显示
parent
d6afa63135
commit
a800048b5a
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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">
|
||||
<div class="main-content flex flex-1">
|
||||
<div class="w-1/4 px-2 flex flex-col">
|
||||
<border-box-3>
|
||||
<ScrollBoardTable ref="BDScrollBoardTable" />
|
||||
<ScrollBoardTable title="北 斗" 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>
|
||||
<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'
|
||||
|
|
Loading…
Reference in New Issue