feat:完善功能

This commit is contained in:
zjc
2025-01-16 12:37:23 +08:00
parent ef5cb642ca
commit 2a11f91d36
43 changed files with 2644 additions and 3108 deletions

View File

@@ -0,0 +1,86 @@
<template>
<div class="alarm">
<p class="alarm-title">异常点位告警排名</p>
<ul class="alarm-list">
<li class="alarm-item" v-for="(item, index) in 10" :key="index">
<div class="alarm-item__rank">{{ index + 1 }}</div>
<p class="alarm-item__label">核心监控点1</p>
</li>
</ul>
</div>
</template>
<script setup></script>
<style scoped lang="scss">
.alarm {
&-title {
padding-bottom: vh(10);
font-weight: bold;
font-size: vw(14);
color: #37d8fc;
}
&-list {
width: vw(140);
height: vh(160);
overflow-y: auto;
&::-webkit-scrollbar {
width: vw(4); /* 滚动条的宽度 */
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background: 'transparent'; /* 轨道的背景色 */
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
}
&-item {
margin-bottom: vh(10);
display: flex;
align-items: center;
background: linear-gradient(90deg, #1b5ec7 0%, rgba(27, 94, 199, 0) 100%);
&:nth-child(1) {
background: linear-gradient(90deg, #ffc10b 0%, rgba(255, 209, 44, 0) 100%);
.alarm-item__rank {
background-image: url('@/assets/images/rk-1.png');
background-size: 100% 100%;
}
}
&:nth-child(2) {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.alarm-item__rank {
background-image: url('@/assets/images/rk-2.png');
background-size: 100% 100%;
}
}
&:nth-child(3) {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.alarm-item__rank {
background-image: url('@/assets/images/rk-3.png');
background-size: 100% 100%;
}
}
}
&-item__rank {
width: vw(24);
height: vw(24);
font-weight: bold;
font-size: vw(14);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-image: url('@/assets/images/rk-4.png');
background-size: 100% 100%;
}
&-item__label {
font-weight: 400;
font-size: vw(14);
color: #ffffff;
}
}
</style>

View File

@@ -0,0 +1,106 @@
<template>
<div class="alarmRate" :id="id" />
</template>
<script setup>
import { fitChartSize } from '@/utils/dataUtil'
import { useEchart } from '@/hooks/echart'
const props = defineProps({
config: {
type: Object,
default: () => {
return {}
}
},
dataList: {
type: Array,
default: () => []
},
total: {
type: Number,
default: () => 123456
},
colors: {
type: Array,
default: () => ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA']
}
})
const { id, setOption } = useEchart()
var defaultCofig = {
color: [],
legend: {
orient: 'vertical',
bottom: 'center',
left: '50%',
itemWidth: fitChartSize(12),
itemHeight: fitChartSize(12),
itemGap: fitChartSize(10),
textStyle: {
color: '#ffffff',
fontSize: fitChartSize(16)
}
},
series: [
{
type: 'pie',
center: ['30%', '50%'],
radius: ['30%', '40%'],
itemStyle: {
borderWidth: fitChartSize(4),
borderColor: '#093672'
},
label: {
show: true,
position: 'center',
fontWeight: 'bold',
rich: {
value: {
color: '#fff',
fontSize: fitChartSize(16),
fontWeight: 'bold',
padding: [0, 0, 5, 0]
},
name: {
color: '#7894A8',
fontSize: fitChartSize(12)
}
}
},
labelLine: {
show: false
},
data: []
}
]
}
watch(
() => props.dataList,
(newVal) => {
if (newVal.length > 0) {
nextTick(() => {
defaultCofig.color = props.colors
defaultCofig.series[0].data = props.dataList
defaultCofig.series[0].label.formatter = () => {
return `{value|${props.total}}` + '\n' + `{name|工单总数}`
}
setOption({
...defaultCofig,
...props.config
})
})
}
},
{ immediate: true }
)
</script>
<style scoped lang="scss">
.alarmRate {
width: vw(240);
height: vh(200);
}
</style>

View File

@@ -0,0 +1,161 @@
<template>
<div class="alarmToday" :id="id" />
</template>
<script setup>
import { fitChartSize } from '@/utils/dataUtil'
import { useEchart } from '@/hooks/echart'
const props = defineProps({
config: {
type: Object,
default: () => {
return {}
}
},
dataList: {
type: Array,
default: () => []
},
total: {
type: Number,
default: () => 123456
},
colors: {
type: Array,
default: () => ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA']
}
})
const { id, setOption } = useEchart()
const color = ['#409eff', '#29c9c8', '#f6b936']
var params = {
color: ['#70bfe5', '#eb6a6c', '#f9c942', '#91c974', '#5a6ac0'],
// legend: {
// data: ['1月', '2月', '3月', '4月', '5月'],
// itemGap: 15,
// itemWidth: 10, // 设置宽度
// itemHeight: 10,
// top: '40',
// right: '30',
// textStyle: {
// color: '#595959'
// }
// },
grid: {
left: '4%',
right: '4%',
bottom: '5%',
top: '12%',
containLabel: true
},
xAxis: [
{
name: '月份',
type: 'category',
axisTick: {
alignWithLabel: false
},
axisLabel: {
padding: [25, 0, 0, 0]
},
data: ['1月', '2月', '3月', '4月', '5月']
}
],
yAxis: [
{
type: 'value',
axisLabel: {
formatter: function (params) {
return params
}
}
}
],
series: []
}
var datas = [
[
[10, 1, 1, 2, 3],
[2, 11, 7, 1, 1],
[5, 7, 5, 1, 1]
],
[
[1, 1, 1, 2, 3],
[2, 5, 7, 1, 1],
[5, 7, 5, 1, 1]
],
[
[1, 1, 1, 2, 3],
[2, 5, 7, 1, 1],
[5, 7, 5, 1, 1]
]
]
// 变量和循环处理
var categories = ['1月', '2月', '3月']
var years = ['应完成xxx']
for (var i = 0; i < years.length; i++) {
var yearData = datas[i] // 获取对应年份的数据
var seriesData = [] // 用于存储每个年份对应的系列数据
for (var j = 0; j < categories.length; j++) {
var itemData = []
for (var k = 0; k < yearData[j].length; k++) {
itemData.push(yearData[j][k])
}
seriesData.push({
type: 'bar',
stack: 'stack' + (i + 1),
barGap: 0.5,
barWidth: 20,
label: {
show: true,
// position: 'insideTop',
align: 'center',
formatter: function (param) {
return param.value
}
},
data: itemData,
name: categories[j]
})
}
Array.prototype.push.apply(params.series, seriesData)
}
const init = () => {
setOption(params)
}
// watch(
// () => props.dataList,
// (newVal) => {
// if (newVal.length > 0) {
// nextTick(() => {
// defaultCofig.color = props.colors
// defaultCofig.series[0].data = props.dataList
// defaultCofig.series[0].label.formatter = () => {
// return `{value|${props.total}}` + '\n' + `{name|工单总数}`
// }
// setOption({
// ...defaultCofig,
// ...props.config
// })
// })
// }
// },
// { immediate: true }
// )
onMounted(() => {
init()
})
</script>
<style scoped lang="scss">
.alarmToday {
width: vw(400);
height: vh(200);
}
</style>

View File

@@ -0,0 +1,193 @@
<template>
<!-- 安全检测 -->
<div class="box-1">
<div class="detection-top">
<img class="map-img" src="@/assets/images/map-img-1.jpg" />
</div>
<div class="flex">
<div class="monitor">
<div class="t-title">
<span>监控点位统计</span>
</div>
<div class="monitor-statistics">
<img class="monitor-statistics-icon" src="@/assets/images/t-ico-0.png" />
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">监控点位</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">核心点位</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">拥堵次数</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
</div>
<div class="bg">
<Title3 title="今日安全告警" />
<alarmToday />
</div>
</div>
<div class="traffic">
<div class="t-title">
<span>交通信息</span>
</div>
<div class="traffic-statistics">
<img class="traffic-statistics-icon" src="@/assets/images/t-ico-2.png" />
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">当前告警总数</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">安全告警总数</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">已解除告警数</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
</div>
<div class="bg">
<Title3 title="异常告警占比" />
<div class="flex">
<alarmRate :dataList="dataList" />
<alarmList />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import countup from 'vue-countup-v3'
import alarmRate from './alarmRate'
import alarmList from './alarmList'
import alarmToday from './alarmToday'
const dataList = ref([
{
name: '云阳',
value: 20
},
{
name: '奉节',
value: 10
},
{
name: '巫山',
value: 70
}
])
onMounted(() => {})
</script>
<style lang="scss" scoped>
.box-1 {
margin-top: vh(120);
width: vw(820);
height: vh(950);
background: linear-gradient(321deg, #0b2f64 0%, #062b57 91%, rgba(5, 40, 79, 0) 100%);
border-radius: 0px 0px 0px 0px;
.detection-top {
width: 100%;
height: vh(580);
background-color: #fff;
.map-img {
width: 100%;
height: 100%;
}
}
.monitor {
width: vw(405);
margin-right: vw(8);
&-statistics {
height: vh(70);
display: flex;
align-items: center;
justify-content: space-evenly;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
}
&-statistics-icon {
width: vw(45);
height: vw(48);
}
&-statistics-item {
&__label {
font-weight: 400;
font-size: vw(14);
color: #fff;
}
&__value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #ffffff;
}
&:nth-child(4) {
.monitor-statistics-item__value {
color: #e21b1b;
}
}
}
}
.traffic {
width: vw(405);
&-statistics {
height: vh(70);
display: flex;
align-items: center;
justify-content: space-evenly;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
}
&-statistics-icon {
width: vw(45);
height: vw(48);
}
&-statistics-item {
&__label {
font-weight: 400;
font-size: vw(14);
color: #fff;
}
&__value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #e21b1b;
text-align: center;
}
&:nth-child(4) {
.traffic-statistics-item__value {
color: rgba(167, 0, 0, 0.6);
}
}
}
}
.bg {
padding: vw(5);
margin-top: vh(8);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
}
.t-title {
margin: vh(10) auto;
width: 100%;
height: vh(32);
font-weight: 800;
font-size: vw(16);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-image: url('@/assets/images/title-4.png');
background-size: 100% 100%;
}
}
</style>

View File

@@ -1,628 +1,19 @@
<template>
<!-- 安全检测 -->
<div class="box-detection">
<!-- 地图 -->
<div class="detection-top">
<Map />
</div>
<div class="detection-bom flex">
<!-- 数据 -->
<div class="d-left">
<div class="t-title">
<span>监控点位统计</span>
</div>
<div class="t-census flex">
<img class="t-icon" src="@/assets/images/t-ico-0.png" alt="" />
<div class="item">
监控点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
核心点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
拥堵次数 <div class="color2"><countup endVal="895" /></div>
</div>
</div>
<div class="box">
<div class="title-3"><span>异常告警占比</span></div>
<div class="pt-20 h-flex">
<div class="left">
<v-chart class="chart" :option="option1" autoresize />
</div>
<!-- <div class="right">
<div class="li li-1"><span class="rk-img" >1</span> 核心监控1</div>
<div class="li li-2"><span class="rk-img" >1</span>核心监控1</div>
<div class="li li-3"><span class="rk-img" >1</span>核心监控1</div>
<div class="li"><span class="rk-img" >1</span>核心监控1</div>
<div class="li"><span class="rk-img" >1</span>核心监控1</div>
<div class="li"><span class="rk-img" >1</span>核心监控</div>
</div> -->
</div>
</div>
</div>
<div class="d-right">
<div class="t-title">
<span>交通信息</span>
</div>
<div class="t-census flex">
<img class="t-icon" src="@/assets/images/t-ico-1.png" alt="" />
<div class="item">
监控点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
核心点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
拥堵次数 <div class="color1"><countup endVal="895" /></div>
</div>
</div>
<div class="box">
<div class="title-3"><span>异常告警占比</span></div>
<div class="pt-20 chart-p">
<div class="check-label">
<span class="active">平均</span>
<span>最大</span>
<span>最小</span>
</div>
<!-- <div class="check-box">
<el-select v-model="selectSpot" slot="prepend" placeholder="选择景区">
<el-option label="餐厅名" value="1"></el-option>
<el-option label="订单号" value="2"></el-option>
<el-option label="用户电话" value="3"></el-option>
</el-select>
</div> -->
<v-chart class="line-chart" :option="optionLine" autoresize />
</div>
</div>
</div>
</div>
<div class="box-2">
<Nav />
<Monitor />
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import countup from 'vue-countup-v3'
import { fitChartSize } from '@/utils/dataUtil'
import Map from '@/components/Map/marker.vue'
import VChart, { THEME_KEY } from 'vue-echarts'
import { ref, provide } from 'vue'
provide(THEME_KEY, 'dark')
const option1 = ref({
backgroundColor: 'transparent',
tooltip: {
trigger: 'item'
},
legend: {
type: 'scroll',
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
itemWidth: 5,
itemHeight: 5,
textStyle: {
fontSize: fitChartSize(14)
}
},
series: [
{
name: 'Access From',
type: 'pie',
left: -30,
top: -50,
width: fitChartSize(350),
height: fitChartSize(350),
// width:200,
// height:200,
radius: ['40%', '50%'],
avoidLabelOverlap: false,
padAngle: 5,
itemStyle: {
borderRadius: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: fitChartSize(10),
fontWeight: 'bold',
color: '#fff'
}
},
labelLine: {
show: true
},
data: [
{ value: 200, name: '异常状况1' },
{ value: 500, name: '异常状况2' },
{ value: 234, name: '异常状况3' },
{ value: 135, name: '异常状况4' },
{ value: 100, name: '异常状况5' },
{ value: 777, name: '异常状况6' },
{ value: 777, name: '其他' }
]
}
]
})
const optionLine = ref({
backgroundColor: 'transparent',
grid: {
top: '50',
bottom: '50',
left: '4%',
containLabel: true
},
xAxis: {
nameLocation: 'middle',
type: 'category',
boundaryGap: false,
axisLabel: {
fontSize: 10,
interval: 0, // 显示所有标签
rotate: 0 // 旋转标签45度
},
data: ['10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00'],
axisTisk: {
show: true,
// 设置刻度长度
length: 1,
lineStyle: {
type: 'dashed', // 设置为虚线
width: 0
}
},
axisLine: {
lineStyle: {
color: '#0096FF' // 设置横线颜色
}
}
},
yAxis: {
type: 'value',
min: 0,
max: 45,
interval: 15,
axisLabel: {
fontSize: fitChartSize(12), // 设置Y轴刻度字体大小
color: 'rgba(255,255,255,0.9)'
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: '#00D0FF'
}
}
},
series: [
{
data: [0, 23, 30, 24, 40, 30, 45, 26],
type: 'line',
smooth: true,
label: {
show: false //隐藏坐标点
},
itemStyle: {
color: 'transparent'
},
markLine: {
symbol: ['none', 'none'],
label: { show: false }
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: '#7DE7FF'
},
{
offset: 0.5,
color: '#02F9FA'
},
{
offset: 1,
color: '#009DFF'
}
]),
width: 3
}
}
]
})
const optionBar = ref({
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
// type: 'scroll',
// orient: 'vertical',
right: 0,
top: 0,
bottom: 20,
itemWidth: 5,
itemHeight: 5
},
grid: {
left: '3%',
right: '4%',
bottom: '20%',
containLabel: true,
show: false
},
xAxis: [
{
nameLocation: 'middle',
type: 'category',
boundaryGap: true,
axisLabel: {
fontSize: fitChartSize(10),
interval: 0, // 显示所有标签
rotate: 0 // 旋转标签45度
},
minorTisk: {
show: false
},
data: ['10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00'],
axisTisk: {
alignWithLabel: true,
show: false,
// 设置刻度长度
length: 0,
lineStyle: {
type: 'dashed', // 设置为虚线
width: 0
}
}
}
],
yAxis: [
{
type: 'value',
min: 0,
max: 45,
interval: 15,
axisLabel: {
fontSize: fitChartSize(12), // 设置Y轴刻度字体大小
color: 'rgba(255,255,255,0.9)',
offset: 10
},
splitLine: {
show: false,
lineStyle: {
type: 'dashed',
color: '#00D0FF'
}
}
}
],
series: [
{
itemStyle: {
// 设置柱状图颜色
color: '#0D53FF'
},
name: '三峡之巅',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: [10, 0, 16, 10, 22, 11, 9, 30],
barWidth: '45%' // 设置柱体粗细,可以是百分比或者像素值
},
{
name: '白帝城',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
itemStyle: {
// 设置柱状图颜色
color: '#05FFB9'
},
data: [20, 5, 14, 14, 0, 20, 11, 2]
},
{
name: '龙河桥',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
itemStyle: {
// 设置柱状图颜色
color: '#FFCB39'
},
data: [15, 20, 8, 19, 20, 5, 22, 13]
}
]
})
onMounted(() => {})
import Nav from '@/components/Nav/index.vue'
import Monitor from '@/components/Monitor/index.vue'
</script>
<style lang="scss" scoped>
.line-chart {
width: 100%;
height: vh(240);
}
.chart-p {
position: relative;
.check-label {
position: absolute;
right: vw(20);
top: vh(15);
span {
min-width: vw(55);
padding: vw(5);
background: linear-gradient(270deg, rgba(8, 41, 86, 0.16) 0%, #0b61b4 100%);
border-radius: vw(50);
// border: 1px solid rgba(0,114,220,0.3);
margin-left: vw(5);
display: inline-block;
font-weight: 400;
font-size: vw(13);
color: #0084ff;
text-align: center;
font-style: normal;
text-transform: none;
}
.active {
background: linear-gradient(270deg, #37d8fc 0%, #0084ff 100%);
border-radius: vw(50);
border: 1px solid rgba(0, 114, 220, 0.3);
color: #fff;
}
}
}
.box-detection {
.box-2 {
margin-top: vh(120);
width: vw(820);
height: vh(950);
background: linear-gradient(321deg, #0b2f64 0%, #062b57 91%, rgba(5, 40, 79, 0) 100%);
border-radius: 0px 0px 0px 0px;
.detection-top {
width: 100%;
height: vh(580);
background-color: #fff;
.map-img {
width: 100%;
height: 100%;
}
}
.detection-bom {
justify-content: space-between;
.d-left {
width: vw(405);
.left {
width: 100%;
height: vh(240);
}
}
.d-right {
width: vw(405);
}
.box {
width: 100%;
padding: vw(5);
margin-top: vh(5);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
.title-2 {
width: vw(253);
height: vh(28);
display: flex;
align-items: center;
background-image: url('@/assets/images/title-5.png');
background-size: 100% 100%;
& > span {
padding-left: vw(22);
font-weight: bold;
font-size: vw(15);
background-image: linear-gradient(to bottom, #ffffff 0%, #75c1ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
color: transparent; /* 兼容其他浏览器 */
}
}
.statistic {
display: flex;
margin-top: vh(12);
width: 100%;
height: vh(88);
background-image: url('@/assets/images/bg-4.png');
background-size: 100% 100%;
&-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
&-title {
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
}
&-value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #02f9fa;
}
.count {
font-weight: bold;
font-size: vw(28);
color: #ff4400 !important;
}
.prefix,
.suffix {
color: #ff4400;
font-size: vw(12);
}
}
.title-3 {
position: relative;
width: vw(344);
height: vh(12);
margin-top: vh(20);
background-image: url('@/assets/images/title-6.png');
background-size: 100% 100%;
& > span {
position: absolute;
bottom: vh(4);
left: vw(20);
font-size: vw(15);
font-weight: bold;
background-image: linear-gradient(to bottom, #ffffff 0%, #0096ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
color: transparent; /* 兼容其他浏览器 */
}
}
}
.t-title {
margin: vh(10) auto;
width: 100%;
height: vh(32);
font-weight: 800;
font-size: vw(16);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-image: url('@/assets/images/title-4.png');
background-size: 100% 100%;
}
.t-census {
justify-content: center;
align-items: center;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
padding: vw(10);
.t-icon {
width: vw(45);
height: vh(48);
}
.item {
flex: 1;
font-weight: 400;
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
line-height: vh(16);
text-align: center;
font-style: normal;
text-transform: none;
.color1 {
display: block;
font-weight: bold;
font-size: vw(24);
color: #ffffff;
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
}
.color2 {
display: block;
font-weight: bold;
font-size: vw(24);
color: #f15a25;
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
}
.color3 {
display: block;
font-weight: bold;
font-size: vw(24);
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
color: #a70000;
}
}
}
}
}
.h-flex {
width: vw(2353);
height: vh(964);
display: flex;
justify-content: space-between;
.left {
flex: 1;
width: vw(260);
}
.right {
margin-left: vw(20);
width: vw(120);
.li {
position: relative;
font-weight: 400;
font-size: vw(14);
color: #ffffff;
line-height: 16px;
text-align: left;
font-style: normal;
text-transform: none;
position: relative;
padding-left: vw(30);
padding: 0 vw(10);
padding-left: vw(15);
background: linear-gradient(90deg, #1b5ec7 0%, rgba(27, 94, 199, 0) 100%);
border-radius: 0px 0px 0px 0px;
height: vh(24);
line-height: vh(24);
margin-bottom: vh(8);
// opacity: 0.4;
.rk-img {
position: absolute;
width: vw(24);
height: vh(24);
line-height: vh(24);
left: vw(-12);
top: 50%;
display: block;
background-image: url('/src/assets/images/rk-4.png');
background-size: 100% 100%;
transform: translateY(-50%);
text-align: center;
}
}
.li-1 {
background: linear-gradient(90deg, #ffc10b 0%, rgba(255, 209, 44, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-1.png');
}
}
.li-2 {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-2.png');
}
}
.li-3 {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-3.png');
}
}
}
}
</style>

View File

@@ -1,25 +1,210 @@
<template>
<!-- 视频 -->
<div class="box-3-content">
<navLeft></navLeft>
<!-- 视频 -->
<monitor></monitor>
</div>
<!-- 安全检测 -->
<div class="box-detection">
<!-- 地图 -->
<div class="detection-top">
<!-- <Map /> -->
</div>
<div class="detection-bom flex">
<!-- 数据 -->
<div class="monitor">
<div class="t-title">
<span>监控点位统计</span>
</div>
<div class="monitor-statistics">
<img class="monitor-statistics-icon" src="@/assets/images/t-ico-0.png" />
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">监控点位</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">核心点位</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
<div class="monitor-statistics-item">
<span class="monitor-statistics-item__label">拥堵次数</span>
<countup class="monitor-statistics-item__value" end-val="895" />
</div>
</div>
<div class="bg">
<Title3 title="核心点位拥堵次数" />
<alarmRate />
</div>
</div>
<div class="traffic">
<div class="t-title">
<span>交通信息</span>
</div>
<div class="traffic-statistics">
<img class="traffic-statistics-icon" src="@/assets/images/t-ico-2.png" />
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">当前拥堵节点</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">最大车流量</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
<div class="traffic-statistics-item">
<span class="traffic-statistics-item__label">最大车速</span>
<countup class="traffic-statistics-item__value" end-val="895" />
</div>
</div>
<div class="bg">
<Title3 title="车流量" />
<div class="pt-20 chart-p">
<div class="check-label">
<span class="active">平均</span>
<span>最大</span>
<span>最小</span>
</div>
<Line />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import navLeft from '@/components/navLeft/index.vue'
import monitor from '@/components/monitor/index.vue'
import alarmRate from './alarmRate.vue'
import countup from 'vue-countup-v3'
onMounted(() => {})
</script>
<style lang="scss" scoped>
.box-3-content{
width:vw(2353);
height:vh(964);
// background-image: url('/src/assets/images/monotir-bg-1.png');
background-size: 100% 100%;
margin-top: vh(120);
display: flex;
}
</style>
.chart-p {
position: relative;
.check-label {
position: absolute;
right: vw(20);
top: vh(15);
span {
min-width: vw(55);
padding: vw(5);
background: linear-gradient(270deg, rgba(8, 41, 86, 0.16) 0%, #0b61b4 100%);
border-radius: vw(50);
margin-left: vw(5);
display: inline-block;
font-weight: 400;
font-size: vw(13);
color: #0084ff;
text-align: center;
font-style: normal;
text-transform: none;
}
.active {
background: linear-gradient(270deg, #37d8fc 0%, #0084ff 100%);
border-radius: vw(50);
border: 1px solid rgba(0, 114, 220, 0.3);
color: #fff;
}
}
}
.box-detection {
margin-top: vh(120);
width: vw(820);
height: vh(950);
background: linear-gradient(321deg, #0b2f64 0%, #062b57 91%, rgba(5, 40, 79, 0) 100%);
border-radius: 0px 0px 0px 0px;
.detection-top {
width: 100%;
height: vh(580);
background-color: #fff;
.map-img {
width: 100%;
height: 100%;
}
}
.monitor {
width: vw(405);
margin-right: vw(8);
&-statistics {
height: vh(70);
display: flex;
align-items: center;
justify-content: space-evenly;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
}
&-statistics-icon {
width: vw(45);
height: vw(48);
}
&-statistics-item {
&__label {
font-weight: 400;
font-size: vw(14);
color: #fff;
}
&__value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #ffffff;
}
&:nth-child(4) {
.monitor-statistics-item__value {
color: #e21b1b;
}
}
}
}
.traffic {
width: vw(405);
&-statistics {
height: vh(70);
display: flex;
align-items: center;
justify-content: space-evenly;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
}
&-statistics-icon {
width: vw(45);
height: vw(48);
}
&-statistics-item {
&__label {
font-weight: 400;
font-size: vw(14);
color: #fff;
}
&__value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #e21b1b;
text-align: center;
}
&:nth-child(4) {
.traffic-statistics-item__value {
color: rgba(167, 0, 0, 0.6);
}
}
}
}
.bg {
padding: vw(5);
margin-top: vh(8);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
}
.t-title {
margin: vh(10) auto;
width: 100%;
height: vh(32);
font-weight: 800;
font-size: vw(16);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-image: url('@/assets/images/title-4.png');
background-size: 100% 100%;
}
}
</style>

View File

@@ -1,592 +0,0 @@
<template>
<!-- 安全检测 -->
<div class="box-detection">
<!-- 地图 -->
<div class="detection-top">
<img class="map-img" src="@/assets/images/map-img-1.jpg" alt="" />
<!-- <Map /> -->
</div>
<div class="detection-bom flex">
<!-- 数据 -->
<div class="d-left">
<div class="t-title">
<span>监控点位统计</span>
</div>
<div class="t-census flex">
<img class="t-icon" src="@/assets/images/t-ico-0.png" alt="" />
<div class="item">
监控点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
核心点位 <div class="color1"><countup endVal="895" /></div>
</div>
<div class="item">
拥堵次数 <div class="color2"><countup endVal="895" /></div>
</div>
</div>
<div class="box">
<div class="title-3"><span>异常告警占比</span></div>
<div class="pt-20 h-flex">
<div class="left">
<v-chart class="chart" :option="optionBar" autoresize />
<!-- <v-chart class="chart" :option="option1" autoresize /> -->
</div>
</div>
</div>
</div>
<div class="d-right">
<div class="t-title">
<span>交通信息</span>
</div>
<div class="t-census flex">
<img class="t-icon" src="@/assets/images/t-ico-2.png" alt="" />
<div class="item">
监控点位 <div class="color1 color2"><countup endVal="895" /></div>
</div>
<div class="item">
核心点位 <div class="color1 color2"><countup endVal="895" /></div>
</div>
<div class="item">
拥堵次数 <div class="color1 color3"><countup endVal="895" /></div>
</div>
</div>
<div class="box">
<div class="title-3"><span>异常告警占比</span></div>
<div class="pt-20 h-flex">
<div class="left">
<v-chart class="chart" :option="option1" autoresize />
</div>
<div class="right">
<div class="li li-1"><span class="rk-img">1</span> 核心监控1</div>
<div class="li li-2"><span class="rk-img">1</span>核心监控1</div>
<div class="li li-3"><span class="rk-img">1</span>核心监控1</div>
<div class="li"><span class="rk-img">1</span>核心监控1</div>
<div class="li"><span class="rk-img">1</span>核心监控1</div>
<div class="li"><span class="rk-img">1</span>核心监控</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import countup from 'vue-countup-v3'
import { fitChartSize } from '@/utils/dataUtil'
import Map from '@/components/Map/marker.vue'
import VChart, { THEME_KEY } from 'vue-echarts'
import { ref, provide } from 'vue'
provide(THEME_KEY, 'dark')
const option1 = ref({
backgroundColor: 'transparent',
tooltip: {
trigger: 'item'
},
legend: {
type: 'scroll',
orient: 'vertical',
right: -10,
top: 0,
bottom: 20,
itemWidth: 5,
itemHeight: 5,
textStyle: {
fontSize: fitChartSize(12)
}
},
series: [
{
name: 'Access From',
type: 'pie',
left: -25,
top: 0,
width: fitChartSize(250),
height: fitChartSize(250),
radius: ['40%', '50%'],
avoidLabelOverlap: false,
padAngle: 5,
itemStyle: {
borderRadius: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: fitChartSize(10),
fontWeight: 'bold',
color: '#fff'
}
},
labelLine: {
show: true
},
data: [
{ value: 200, name: '异常状况1' },
{ value: 500, name: '异常状况2' },
{ value: 234, name: '异常状况3' },
{ value: 135, name: '异常状况4' },
{ value: 100, name: '异常状况5' },
{ value: 777, name: '异常状况6' },
{ value: 777, name: '其他' }
]
}
]
})
const optionLine = ref({
backgroundColor: 'transparent',
grid: {
top: '50',
bottom: '50',
left: '4%',
containLabel: true
},
xAxis: {
nameLocation: 'middle',
type: 'category',
boundaryGap: false,
axisLabel: {
fontSize: 10,
interval: 0, // 显示所有标签
rotate: 0 // 旋转标签45度
},
data: ['10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00'],
axisTisk: {
show: true,
// 设置刻度长度
length: 1,
lineStyle: {
type: 'dashed', // 设置为虚线
width: 0
}
},
axisLine: {
lineStyle: {
color: '#0096FF' // 设置横线颜色
}
}
},
yAxis: {
type: 'value',
min: 0,
max: 45,
interval: 15,
axisLabel: {
fontSize: fitChartSize(12), // 设置Y轴刻度字体大小
color: 'rgba(255,255,255,0.9)'
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: '#00D0FF'
}
}
},
series: [
{
data: [0, 23, 30, 24, 40, 30, 45, 26],
type: 'line',
smooth: true,
label: {
show: false //隐藏坐标点
},
itemStyle: {
color: 'transparent'
},
markLine: {
symbol: ['none', 'none'],
label: { show: false }
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: '#7DE7FF'
},
{
offset: 0.5,
color: '#02F9FA'
},
{
offset: 1,
color: '#009DFF'
}
]),
width: 3
}
}
]
})
const optionBar = ref({
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
// type: 'scroll',
// orient: 'vertical',
right: 0,
top: 0,
bottom: 20,
itemWidth: 5,
itemHeight: 5,
textStyle: {
fontSize: fitChartSize(12)
}
},
grid: {
left: '3%',
right: '4%',
bottom: '20%',
containLabel: true,
show: false
},
xAxis: [
{
nameLocation: 'middle',
type: 'category',
boundaryGap: true,
axisLabel: {
fontSize: fitChartSize(10),
interval: 0, // 显示所有标签
rotate: 0 // 旋转标签45度
},
minorTisk: {
show: false
},
data: ['10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00', '10:00'],
axisTisk: {
alignWithLabel: true,
show: false,
// 设置刻度长度
length: 0,
lineStyle: {
type: 'dashed', // 设置为虚线
width: 0
}
}
}
],
yAxis: [
{
type: 'value',
min: 0,
max: 45,
interval: 15,
axisLabel: {
fontSize: fitChartSize(12), // 设置Y轴刻度字体大小
color: 'rgba(255,255,255,0.9)',
offset: 10
},
splitLine: {
show: false,
lineStyle: {
type: 'dashed',
color: '#00D0FF'
}
}
}
],
series: [
{
itemStyle: {
// 设置柱状图颜色
color: '#0D53FF'
},
name: '三峡之巅',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: [10, 0, 16, 10, 22, 11, 9, 30],
barWidth: '45%' // 设置柱体粗细,可以是百分比或者像素值
},
{
name: '白帝城',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
itemStyle: {
// 设置柱状图颜色
color: '#05FFB9'
},
data: [20, 5, 14, 14, 0, 20, 11, 2]
},
{
name: '龙河桥',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
itemStyle: {
// 设置柱状图颜色
color: '#FFCB39'
},
data: [15, 20, 8, 19, 20, 5, 22, 13]
}
]
})
onMounted(() => {})
</script>
<style lang="scss" scoped>
.line-chart {
width: 100%;
height: vh(240);
}
.box-detection {
margin-top: vh(120);
width: vw(820);
height: vh(950);
background: linear-gradient(321deg, #0b2f64 0%, #062b57 91%, rgba(5, 40, 79, 0) 100%);
border-radius: 0px 0px 0px 0px;
.detection-top {
width: 100%;
height: vh(580);
background-color: #fff;
.map-img {
width: 100%;
height: 100%;
}
}
.detection-bom {
justify-content: space-between;
.d-left {
width: vw(405);
.left {
width: 100%;
height: vh(240);
}
}
.d-right {
width: vw(405);
}
.box {
width: 100%;
padding: vw(5);
margin-top: vh(5);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
.title-2 {
width: vw(253);
height: vh(28);
display: flex;
align-items: center;
background-image: url('@/assets/images/title-5.png');
background-size: 100% 100%;
& > span {
padding-left: vw(22);
font-weight: bold;
font-size: vw(15);
background-image: linear-gradient(to bottom, #ffffff 0%, #75c1ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
color: transparent; /* 兼容其他浏览器 */
}
}
.statistic {
display: flex;
margin-top: vh(12);
width: 100%;
height: vh(88);
background-image: url('@/assets/images/bg-4.png');
background-size: 100% 100%;
&-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
&-title {
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
}
&-value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(24);
color: #02f9fa;
}
.count {
font-weight: bold;
font-size: vw(28);
color: #ff4400 !important;
}
.prefix,
.suffix {
color: #ff4400;
font-size: vw(12);
}
}
.title-3 {
position: relative;
width: vw(344);
height: vh(12);
margin-top: vh(20);
background-image: url('@/assets/images/title-6.png');
background-size: 100% 100%;
& > span {
position: absolute;
bottom: vh(4);
left: vw(20);
font-size: vw(15);
font-weight: bold;
background-image: linear-gradient(to bottom, #ffffff 0%, #0096ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
color: transparent; /* 兼容其他浏览器 */
}
}
}
.t-title {
margin: vh(10) auto;
width: 100%;
height: vh(32);
font-weight: 800;
font-size: vw(16);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-image: url('@/assets/images/title-4.png');
background-size: 100% 100%;
}
.t-census {
justify-content: center;
align-items: center;
background-image: url('@/assets/images/i-data-bg-1.png');
background-size: 100% 100%;
padding: vw(10);
.t-icon {
width: vw(45);
height: vh(48);
}
.item {
flex: 1;
font-weight: 400;
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
line-height: vh(16);
text-align: center;
font-style: normal;
text-transform: none;
.color1 {
display: block;
font-weight: bold;
font-size: vw(24);
color: #ffffff;
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
}
.color2 {
display: block;
font-weight: bold;
font-size: vw(24);
color: #f15a25;
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
}
.color3 {
display: block;
font-weight: bold;
font-size: vw(24);
line-height: 28px;
text-align: center;
font-style: normal;
text-transform: none;
color: #a70000;
}
}
}
}
}
.h-flex {
display: flex;
justify-content: space-between;
.left {
flex: 1;
width: vw(260);
}
.right {
margin-left: vw(20);
width: vw(120);
.li {
position: relative;
font-weight: 400;
font-size: vw(14);
color: #ffffff;
line-height: 16px;
text-align: left;
font-style: normal;
text-transform: none;
position: relative;
padding-left: vw(30);
padding: 0 vw(10);
padding-left: vw(15);
background: linear-gradient(90deg, #1b5ec7 0%, rgba(27, 94, 199, 0) 100%);
border-radius: 0px 0px 0px 0px;
height: vh(24);
line-height: vh(24);
margin-bottom: vh(8);
// opacity: 0.4;
.rk-img {
position: absolute;
width: vw(24);
height: vh(24);
line-height: vh(24);
left: vw(-12);
top: 50%;
display: block;
background-image: url('/src/assets/images/rk-4.png');
background-size: 100% 100%;
transform: translateY(-50%);
text-align: center;
}
}
.li-1 {
background: linear-gradient(90deg, #ffc10b 0%, rgba(255, 209, 44, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-1.png');
}
}
.li-2 {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-2.png');
}
}
.li-3 {
background: linear-gradient(90deg, #919191 0%, rgba(175, 175, 175, 0) 100%);
.rk-img {
background-image: url('/src/assets/images/rk-3.png');
}
}
}
}
</style>