integrated_traffic_vue/src/views/aggregation_management/gathering_overview/index.vue

453 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="p-20">
<el-row>
<el-col :span="24">
<el-card body-class="p-0">
<div class="tabs">
<div
v-for="(item, index) in tabsList"
:key="item.label"
:class="['tab', { active: tabIndex === index + 1 }]"
@click="fnTabsChange(item.type)"
>
{{ item.label }}
</div>
</div>
<el-form
:model="searchForm"
style="flex: 1"
class="ml-20"
@submit.prevent="fnGetData"
>
<el-row>
<el-col :span="4">
<el-form-item v-if="tabIndex === 1" prop="time">
<el-date-picker
v-model="searchForm.time"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item v-if="tabIndex === 2" prop="time">
<el-date-picker
v-model="searchForm.time"
type="week"
format="YYYY 第ww周"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item v-if="tabIndex === 3" prop="time">
<el-date-picker
v-model="searchForm.time"
type="month"
format="YYYY-MM"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit"
>搜索
</el-button>
<el-button native-type="reset" @click="fnGetData">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-col>
<el-col :span="24" class="mt-20">
<el-card>
<div class="main_title">聚集报警趋势</div>
<div id="main1"></div>
</el-card>
</el-col>
<el-col :span="24" class="mt-20">
<el-row :gutter="20">
<el-col :span="12">
<el-card>
<div class="main_title">聚集数据统计</div>
<el-scrollbar style="height: 220px">
<div class="aggregated_data_statistics">
<div
v-for="(item, index) in aggregatedDataStatistics"
:key="index"
class="item"
>
<div
class="title"
:style="{ 'background-color': item.color }"
>
{{ item.title }}
</div>
<div class="content">
<div class="value">报警数量:{{ item.num }}</div>
<el-progress
:percentage="
item.value !== 0 ? item.num / item.value : 0
"
:color="item.color"
/>
<div class="times">
<div
v-for="(item1, index1) in item.timeArr"
:key="index1"
class="time"
>
<div class="time_title">{{ item1.timeTitle }}</div>
<div class="time_value">{{ item1.timeValue }}</div>
</div>
</div>
</div>
</div>
</div>
</el-scrollbar>
</el-card>
</el-col>
<el-col :span="12">
<el-card>
<div class="main_title">聚集区域统计</div>
<el-scrollbar style="height: 220px">
<div class="aggregated-area-statistics">
<div
v-for="(item, index) in aggregatedAreaStatistics"
:key="index"
class="item"
>
<div class="value">
<div class="title">{{ item.title }}</div>
<div class="num">报警数量:{{ item.num }}</div>
</div>
<div class="alarms">
<div
v-for="(item1, index1) in item.alarmArr"
:key="index1"
class="alarm"
>
<div
class="bg"
:style="{ 'background-color': item1.color }"
/>
<div class="alarm_title">{{ item1.alarmTitle }}</div>
<div class="alarm_value">{{ item1.alarmValue }}</div>
</div>
</div>
</div>
</div>
</el-scrollbar>
</el-card>
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { onBeforeUnmount, onMounted, ref } from "vue";
import dayjs from "dayjs";
import * as echarts from "echarts";
import {
getAggregatedDataStatistics,
getAggregationAlarmTrend,
getAggregationAreaStatistics,
} from "@/request/aggregation_management.js";
let myChart1;
const tabsList = [
{ label: "每日统计", type: 1 },
{ label: "每周统计", type: 2 },
{ label: "每月统计", type: 3 },
];
const tabIndex = ref(1);
const searchForm = ref({ time: dayjs().format("YYYY-MM-DD") });
const aggregatedDataStatistics = ref([]);
const aggregatedAreaStatistics = ref([]);
const fnTabsChange = (event) => {
if (event === 1) searchForm.value.time = dayjs().format("YYYY-MM-DD");
if (event === 2) searchForm.value.time = dayjs().format("YYYY-MM-DD");
if (event === 3)
searchForm.value.time = dayjs().startOf("month").format("YYYY-MM-DD");
tabIndex.value = event;
fnGetData();
};
const fnGetData = async () => {
const aggregationAlarmTrendData = await getAggregationAlarmTrend({
type: tabIndex.value,
time: searchForm.value.time,
});
myChart1 && myChart1.dispose();
fnInitEcharts(aggregationAlarmTrendData.data);
const aggregatedDataStatisticsData = await getAggregatedDataStatistics({
type: tabIndex.value,
time: searchForm.value.time,
});
const aggregatedAreaStatisticsData = await getAggregationAreaStatistics({
type: tabIndex.value,
time: searchForm.value.time,
});
aggregatedDataStatistics.value = aggregatedDataStatisticsData.data;
aggregatedAreaStatistics.value = aggregatedAreaStatisticsData.data;
};
const fnInitEcharts = (data) => {
myChart1 = echarts.init(document.querySelector("#main1"));
const option = {
legend: {
data: ["一级聚集", "二级聚集", "三级聚集", "聚集总计"],
top: "0%",
textStyle: {
color: "#fff",
},
},
grid: {
left: "2%",
right: "2%",
bottom: "5%",
top: "13%",
containLabel: true,
},
tooltip: {
trigger: "axis",
},
xAxis: {
type: "category",
boundaryGap: false,
data: data.xdata,
axisLabel: {
color: "#fff",
},
axisLine: {
lineStyle: {
color: "#102b60",
},
},
},
yAxis: {
type: "value",
axisLabel: {
color: "#fff",
},
axisLine: {
lineStyle: {
color: "#102b60",
},
},
splitLine: {
lineStyle: {
color: "#102b60",
},
},
},
series: [
{
name: "一级聚集",
type: "line",
data: data.one,
itemStyle: {
normal: {
color: "red",
lineStyle: {
color: "red",
},
},
},
},
{
name: "二级聚集",
type: "line",
data: data.two,
itemStyle: {
normal: {
color: "orange",
lineStyle: {
color: "orange",
},
},
},
},
{
name: "三级聚集",
type: "line",
data: data.three,
itemStyle: {
normal: {
color: "#ffeb3b",
lineStyle: {
color: "#ffeb3b",
},
},
},
},
{
name: "聚集总计",
type: "line",
data: data.zong,
itemStyle: {
normal: {
color: "#0385f4",
lineStyle: {
color: "#0385f4",
},
},
},
},
],
};
myChart1.setOption(option);
};
onMounted(() => {
fnGetData();
window.onresize = function () {
myChart1 && myChart1.resize();
};
});
onBeforeUnmount(() => {
myChart1 = null;
});
</script>
<style scoped lang="scss">
:deep {
.el-card__body {
padding: 18px !important;
}
.p-0 {
padding: 0 !important;
display: flex;
align-items: center;
.el-form-item {
margin-bottom: 0;
}
}
}
.tabs {
display: flex;
.tab {
padding: 20px;
cursor: pointer;
&:hover,
&.active {
background-color: var(--el-fill-color-light);
color: var(--el-color-check);
}
}
}
.main_title {
padding: 0 18px 18px 18px;
border-bottom: 1px solid var(--el-card-border-color);
margin: 0 -18px;
}
#main1 {
width: 100%;
height: 300px;
}
.el-card {
margin: 0;
}
.aggregated_data_statistics {
font-size: 12px;
.item {
margin-top: 10px;
display: flex;
align-items: center;
.title {
width: max-content;
padding: 5px;
border-radius: 4px;
}
.content {
margin-left: 10px;
flex: 1;
.value {
text-align: right;
padding-right: 50px;
margin-bottom: 5px;
}
.times {
margin-top: 5px;
display: flex;
.time {
display: flex;
margin-right: 10px;
background-color: #b0b0b0;
border-radius: 4px;
padding: 5px;
.time_value {
font-weight: bold;
}
}
}
}
}
}
.aggregated-area-statistics {
font-size: 12px;
.item {
margin-top: 10px;
background-color: var(--el-fill-color-light);
padding: 10px;
border-radius: 4px;
.value {
display: flex;
justify-content: space-between;
.title {
margin-right: 10px;
font-weight: bold;
}
.num {
font-weight: bold;
}
}
.alarms {
display: flex;
.alarm {
margin-top: 10px;
margin-right: 10px;
display: flex;
align-items: center;
background-color: #b0b0b0;
border-radius: 4px;
padding: 5px;
.bg {
width: 10px;
height: 10px;
margin-right: 5px;
}
.alarm_title {
margin-right: 10px;
}
}
}
}
}
</style>