This commit is contained in:
parent
a1e7001fb1
commit
0e984ecace
|
|
@ -11,6 +11,7 @@
|
|||
"axios": "^1.13.6",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.13.5",
|
||||
"moment": "^2.30.1",
|
||||
"vue": "^3.5.29",
|
||||
"vue-echarts": "^8.0.1",
|
||||
"vue-router": "^5.0.3"
|
||||
|
|
@ -2940,6 +2941,15 @@
|
|||
"pathe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"axios": "^1.13.6",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.13.5",
|
||||
"moment": "^2.30.1",
|
||||
"vue": "^3.5.29",
|
||||
"vue-echarts": "^8.0.1",
|
||||
"vue-router": "^5.0.3"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
<script setup>
|
||||
import {ref, computed, onMounted} from 'vue'
|
||||
import { use } from 'echarts/core'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { LineChart, BarChart } from 'echarts/charts'
|
||||
import { TooltipComponent, GridComponent, MarkAreaComponent, MarkPointComponent, LegendComponent } from 'echarts/components'
|
||||
import {use} from 'echarts/core'
|
||||
import {CanvasRenderer} from 'echarts/renderers'
|
||||
import {LineChart, BarChart} from 'echarts/charts'
|
||||
import {
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
MarkAreaComponent,
|
||||
MarkPointComponent,
|
||||
LegendComponent
|
||||
} from 'echarts/components'
|
||||
import VChart from 'vue-echarts'
|
||||
import moment from "moment";
|
||||
import imgAccidentPoint from '@/assets/images/home/sg.png'
|
||||
import imgStatusDmll from '@/assets/images/status/dmll.png'
|
||||
import imgStatusLdpjsd from '@/assets/images/status/ldpjsd.png'
|
||||
|
|
@ -27,22 +34,22 @@ use([
|
|||
const activeTrendMetric = ref('speed')
|
||||
|
||||
const statusMonitorOverviewCards = [
|
||||
{ label: '路段平均速度', value: '32', unit: '(km/h)', icon: imgStatusLdpjsd },
|
||||
{ label: '断面流量', value: '1200', unit: '(车次/h)', icon: imgStatusDmll },
|
||||
{ label: '事故点核心车速', value: '10', unit: '(km/h)', icon: imgStatusYxcs },
|
||||
{ label: '影响区车辆数', value: '580', unit: '(辆)', icon: imgStatusYxqcl },
|
||||
{label: '路段平均速度', value: '32', unit: '(km/h)', icon: imgStatusLdpjsd},
|
||||
{label: '断面流量', value: '1200', unit: '(车次/h)', icon: imgStatusDmll},
|
||||
{label: '事故点核心车速', value: '10', unit: '(km/h)', icon: imgStatusYxcs},
|
||||
{label: '影响区车辆数', value: '580', unit: '(辆)', icon: imgStatusYxqcl},
|
||||
]
|
||||
|
||||
// 事故影响下交通流变化趋势:下拉选择项(绑定图表)
|
||||
const accidentImpactSection = ref('A-001')
|
||||
const accidentImpactSectionOptions = [
|
||||
{ value: 'A-001', label: 'A-001' },
|
||||
{ value: 'A-002', label: 'A-002' },
|
||||
{value: 'A-001', label: 'A-001'},
|
||||
{value: 'A-002', label: 'A-002'},
|
||||
]
|
||||
|
||||
// 示范区域近七日交通流量对比:下拉选择(当前仅“全选”)
|
||||
const demoAreaFlowFilter = ref('all')
|
||||
const demoAreaFlowFilterOptions = [{ value: 'all', label: '全选' }]
|
||||
const demoAreaFlowFilterOptions = [{value: 'all', label: '全选'}]
|
||||
|
||||
// 示范区域历史交通流趋势:时间范围切换
|
||||
const demoAreaHistoryRange = ref('7d') // '7d' | '1d'
|
||||
|
|
@ -91,21 +98,13 @@ const congestionData = [45, 30, 75, 40, 70, 55, 35]
|
|||
const speedData = [65, 70, 45, 55, 50, 60, 68]
|
||||
|
||||
// 示范区域近七日交通流量对比(单位:pcu/h)
|
||||
const demoAreaLast7Days = [
|
||||
'03-06',
|
||||
'03-07',
|
||||
'03-08',
|
||||
'03-09',
|
||||
'03-10',
|
||||
'03-11',
|
||||
'03-12',
|
||||
]
|
||||
const demoAreaLast7Days = ref([])
|
||||
// 按截图大致还原的数据分布(早峰/晚峰/全时段)
|
||||
const demoAreaFlowData = {
|
||||
morning: [4300, 3700, 2400, 6800, 3500, 3100, 5800],
|
||||
evening: [5100, 3300, 3900, 4900, 2800, 5300, 4200],
|
||||
all: [6400, 5400, 5000, 7500, 4800, 7200, 6700],
|
||||
}
|
||||
const demoAreaFlowData = ref({
|
||||
morning: [],
|
||||
evening: [],
|
||||
all: [],
|
||||
})
|
||||
|
||||
const last7DaysFlowOption = computed(() => {
|
||||
const axisTextColor = '#64748b'
|
||||
|
|
@ -123,8 +122,8 @@ const last7DaysFlowOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: `rgba(${hexToRgb(baseColor)}, ${topAlpha})` },
|
||||
{ offset: 1, color: `rgba(${hexToRgb(baseColor)}, ${bottomAlpha})` },
|
||||
{offset: 0, color: `rgba(${hexToRgb(baseColor)}, ${topAlpha})`},
|
||||
{offset: 1, color: `rgba(${hexToRgb(baseColor)}, ${bottomAlpha})`},
|
||||
],
|
||||
})
|
||||
|
||||
|
|
@ -144,17 +143,17 @@ const last7DaysFlowOption = computed(() => {
|
|||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
axisPointer: {type: 'shadow'},
|
||||
padding: [5, 10],
|
||||
formatter: (params) => {
|
||||
if (!params?.length) return ''
|
||||
const title = params[0].axisValue
|
||||
const lines = params
|
||||
.map(p => `${p.marker}${p.seriesName}:${formatNumber(p.data)} pcu/h`)
|
||||
.join('<br/>')
|
||||
.map(p => `${p.marker}${p.seriesName}:${formatNumber(p.data)} pcu/h`)
|
||||
.join('<br/>')
|
||||
return `${title}<br/>${lines}`
|
||||
},
|
||||
textStyle: { fontSize: 11 },
|
||||
textStyle: {fontSize: 11},
|
||||
},
|
||||
grid: {
|
||||
left: 56,
|
||||
|
|
@ -164,9 +163,9 @@ const last7DaysFlowOption = computed(() => {
|
|||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: demoAreaLast7Days,
|
||||
axisLine: { lineStyle: { color: '#cbd5e1' } },
|
||||
axisTick: { show: false },
|
||||
data: demoAreaLast7Days.value,
|
||||
axisLine: {lineStyle: {color: '#cbd5e1'}},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
|
|
@ -185,8 +184,8 @@ const last7DaysFlowOption = computed(() => {
|
|||
min: 0,
|
||||
max: 8000,
|
||||
interval: 2000,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLine: {show: false},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
|
|
@ -204,7 +203,7 @@ const last7DaysFlowOption = computed(() => {
|
|||
{
|
||||
name: '早峰',
|
||||
type: 'bar',
|
||||
data: demoAreaFlowData.morning,
|
||||
data: demoAreaFlowData.value.morning,
|
||||
barWidth: 10,
|
||||
barGap: '40%',
|
||||
itemStyle: {
|
||||
|
|
@ -215,7 +214,7 @@ const last7DaysFlowOption = computed(() => {
|
|||
{
|
||||
name: '晚峰',
|
||||
type: 'bar',
|
||||
data: demoAreaFlowData.evening,
|
||||
data: demoAreaFlowData.value.evening,
|
||||
barWidth: 10,
|
||||
itemStyle: {
|
||||
color: gradient(seriesColor.evening),
|
||||
|
|
@ -225,7 +224,7 @@ const last7DaysFlowOption = computed(() => {
|
|||
{
|
||||
name: '全时段',
|
||||
type: 'bar',
|
||||
data: demoAreaFlowData.all,
|
||||
data: demoAreaFlowData.value.all,
|
||||
barWidth: 10,
|
||||
itemStyle: {
|
||||
color: gradient(seriesColor.all),
|
||||
|
|
@ -237,12 +236,12 @@ const last7DaysFlowOption = computed(() => {
|
|||
})
|
||||
|
||||
// 事故影响量化指标对比(柱状对比)
|
||||
const impactCompareAxis = ['类目一', '类目二', '类目三', '类目四']
|
||||
const impactCompareAxis = ref([])
|
||||
// 按截图大致还原的占位数据(可后续接入接口替换)
|
||||
const impactCompareData = {
|
||||
data1: [72, 92, 38, 88], // 数据一(绿色)
|
||||
data2: [86, 66, 82, 54], // 数据二(蓝色)
|
||||
}
|
||||
const impactCompareData = ref({
|
||||
data1: [0, 0, 0, 0], // 数据一(绿色)
|
||||
data2: [0, 0, 0, 0], // 数据二(蓝色)
|
||||
})
|
||||
|
||||
const accidentImpactCompareOption = computed(() => {
|
||||
const axisTextColor = '#64748b'
|
||||
|
|
@ -255,8 +254,8 @@ const accidentImpactCompareOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: `rgba(${hexToRgb(baseColor)}, ${topAlpha})` },
|
||||
{ offset: 1, color: `rgba(${hexToRgb(baseColor)}, ${bottomAlpha})` },
|
||||
{offset: 0, color: `rgba(${hexToRgb(baseColor)}, ${topAlpha})`},
|
||||
{offset: 1, color: `rgba(${hexToRgb(baseColor)}, ${bottomAlpha})`},
|
||||
],
|
||||
})
|
||||
|
||||
|
|
@ -276,7 +275,7 @@ const accidentImpactCompareOption = computed(() => {
|
|||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
axisPointer: {type: 'shadow'},
|
||||
padding: [5, 10],
|
||||
formatter: (params) => {
|
||||
if (!params?.length) return ''
|
||||
|
|
@ -284,7 +283,7 @@ const accidentImpactCompareOption = computed(() => {
|
|||
const lines = params.map(p => `${p.marker}${p.seriesName}:${p.data}`).join('<br/>')
|
||||
return `${title}<br/>${lines}`
|
||||
},
|
||||
textStyle: { fontSize: 11 },
|
||||
textStyle: {fontSize: 11},
|
||||
},
|
||||
grid: {
|
||||
left: 10,
|
||||
|
|
@ -295,9 +294,9 @@ const accidentImpactCompareOption = computed(() => {
|
|||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: impactCompareAxis,
|
||||
axisLine: { lineStyle: { color: '#cbd5e1' } },
|
||||
axisTick: { show: false },
|
||||
data: impactCompareAxis.value,
|
||||
axisLine: {lineStyle: {color: '#cbd5e1'}},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
|
|
@ -306,12 +305,9 @@ const accidentImpactCompareOption = computed(() => {
|
|||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
interval: 25,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: true },
|
||||
axisLine: {show: false},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {show: true},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
|
|
@ -324,7 +320,7 @@ const accidentImpactCompareOption = computed(() => {
|
|||
{
|
||||
name: '数据一',
|
||||
type: 'bar',
|
||||
data: impactCompareData.data1,
|
||||
data: impactCompareData.value.data1,
|
||||
barWidth: 12,
|
||||
itemStyle: {
|
||||
color: gradient('#1FEC90', 0.95, 0.15),
|
||||
|
|
@ -334,7 +330,7 @@ const accidentImpactCompareOption = computed(() => {
|
|||
{
|
||||
name: '数据二',
|
||||
type: 'bar',
|
||||
data: impactCompareData.data2,
|
||||
data: impactCompareData.value.data2,
|
||||
barWidth: 12,
|
||||
itemStyle: {
|
||||
color: gradient('#2563eb', 0.95, 0.15),
|
||||
|
|
@ -371,7 +367,7 @@ const demoAreaHistorySummary = {
|
|||
const demoAreaLast1Day = timePoints
|
||||
|
||||
const demoAreaHistoryAxis = computed(() => {
|
||||
return demoAreaHistoryRange.value === '1d' ? demoAreaLast1Day : demoAreaLast7Days
|
||||
return demoAreaHistoryRange.value === '1d' ? demoAreaLast1Day : demoAreaLast7Days.value
|
||||
})
|
||||
|
||||
// 按截图走势大致还原:左轴车流量(pcu/h) 0-5000,右轴平均车速(km/h) 0-100
|
||||
|
|
@ -410,14 +406,14 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
if (!params?.length) return ''
|
||||
const title = params[0].axisValue
|
||||
const lines = params
|
||||
.map((p) => {
|
||||
const unit = p.seriesName === '平均车速' ? ' km/h' : ' pcu/h'
|
||||
return `${p.marker}${p.seriesName}:${formatNumber(p.data)}${unit}`
|
||||
})
|
||||
.join('<br/>')
|
||||
.map((p) => {
|
||||
const unit = p.seriesName === '平均车速' ? ' km/h' : ' pcu/h'
|
||||
return `${p.marker}${p.seriesName}:${formatNumber(p.data)}${unit}`
|
||||
})
|
||||
.join('<br/>')
|
||||
return `${title}<br/>${lines}`
|
||||
},
|
||||
textStyle: { fontSize: 11 },
|
||||
textStyle: {fontSize: 11},
|
||||
},
|
||||
grid: {
|
||||
left: 56,
|
||||
|
|
@ -436,14 +432,14 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#cbd5e1' } },
|
||||
axisTick: { show: false },
|
||||
axisLine: {lineStyle: {color: '#cbd5e1'}},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
margin: 12,
|
||||
},
|
||||
splitLine: { show: false },
|
||||
splitLine: {show: false},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
|
|
@ -458,8 +454,8 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
min: 0,
|
||||
max: 5000,
|
||||
interval: 1000,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLine: {show: false},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
|
|
@ -485,13 +481,13 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
min: 0,
|
||||
max: 100,
|
||||
interval: 20,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLine: {show: false},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {
|
||||
color: axisTextColor,
|
||||
fontSize: 12,
|
||||
},
|
||||
splitLine: { show: false },
|
||||
splitLine: {show: false},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
|
|
@ -504,7 +500,7 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#2563eb', width: 2 },
|
||||
lineStyle: {color: '#2563eb', width: 2},
|
||||
},
|
||||
{
|
||||
name: '平均车速',
|
||||
|
|
@ -515,7 +511,7 @@ const demoAreaHistoryTrendOption = computed(() => {
|
|||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#22c55e', width: 2 },
|
||||
lineStyle: {color: '#22c55e', width: 2},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -619,8 +615,8 @@ const trendOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(249, 115, 22, 0.35)' },
|
||||
{ offset: 1, color: 'rgba(249, 115, 22, 0.02)' },
|
||||
{offset: 0, color: 'rgba(249, 115, 22, 0.35)'},
|
||||
{offset: 1, color: 'rgba(249, 115, 22, 0.02)'},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
@ -667,10 +663,10 @@ const accidentImpactOption = computed(() => {
|
|||
const minVal = Math.min(...baseData)
|
||||
const maxVal = Math.max(...baseData)
|
||||
const yAxisRange = (() => {
|
||||
if (metric === 'speed') return { min: 0, max: 100, interval: 25, name: '(km/h)' }
|
||||
if (metric === 'speed') return {min: 0, max: 100, interval: 25, name: '(km/h)'}
|
||||
if (metric === 'dropRate') {
|
||||
const max = Math.min(100, Math.ceil(Math.max(0, maxVal) / 10) * 10)
|
||||
return { min: 0, max: max || 10, interval: 25, name: '(%)' }
|
||||
return {min: 0, max: max || 10, interval: 25, name: '(%)'}
|
||||
}
|
||||
// diff
|
||||
const pad = 5
|
||||
|
|
@ -678,7 +674,7 @@ const accidentImpactOption = computed(() => {
|
|||
const max = Math.ceil((maxVal + pad) / 10) * 10
|
||||
const span = max - min
|
||||
const interval = span <= 20 ? 5 : span <= 50 ? 10 : 20
|
||||
return { min, max, interval, name: '(km/h)' }
|
||||
return {min, max, interval, name: '(km/h)'}
|
||||
})()
|
||||
|
||||
const accidentMarkPoint = {
|
||||
|
|
@ -687,12 +683,12 @@ const accidentImpactOption = computed(() => {
|
|||
symbolOffset: [0, -10],
|
||||
symbolKeepAspect: true,
|
||||
silent: true,
|
||||
label: { show: false },
|
||||
label: {show: false},
|
||||
data: [
|
||||
(() => {
|
||||
const idx = accidentTimeAxis.indexOf('0')
|
||||
const y = idx >= 0 ? baseData[idx] : baseData[0]
|
||||
return { name: '事故发生', xAxis: '0', yAxis: y ?? 0 }
|
||||
return {name: '事故发生', xAxis: '0', yAxis: y ?? 0}
|
||||
})(),
|
||||
],
|
||||
tooltip: {
|
||||
|
|
@ -707,12 +703,12 @@ const accidentImpactOption = computed(() => {
|
|||
if (!params || !params.length) return ''
|
||||
const time = params[0].axisValue
|
||||
const lines = params
|
||||
.map(p => `${p.marker}${p.seriesName}:${p.data} ${unit}`)
|
||||
.join('<br/>')
|
||||
.map(p => `${p.marker}${p.seriesName}:${p.data} ${unit}`)
|
||||
.join('<br/>')
|
||||
const label =
|
||||
time === '0'
|
||||
? '(事故发生时刻)'
|
||||
: (Number(time) < 0 ? '(事故前)' : '(事故后)')
|
||||
time === '0'
|
||||
? '(事故发生时刻)'
|
||||
: (Number(time) < 0 ? '(事故前)' : '(事故后)')
|
||||
return `距离事故发生 ${time} min ${label}<br/>${lines}`
|
||||
},
|
||||
axisPointer: {
|
||||
|
|
@ -832,8 +828,8 @@ const accidentImpactOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(249, 115, 22, 0.35)' },
|
||||
{ offset: 1, color: 'rgba(249, 115, 22, 0.02)' },
|
||||
{offset: 0, color: 'rgba(249, 115, 22, 0.35)'},
|
||||
{offset: 1, color: 'rgba(249, 115, 22, 0.02)'},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
@ -865,8 +861,8 @@ const accidentImpactOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(248, 113, 113, 0.35)' },
|
||||
{ offset: 1, color: 'rgba(248, 113, 113, 0.02)' },
|
||||
{offset: 0, color: 'rgba(248, 113, 113, 0.35)'},
|
||||
{offset: 1, color: 'rgba(248, 113, 113, 0.02)'},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
@ -888,7 +884,7 @@ const accidentImpactOption = computed(() => {
|
|||
padding: [-18, 0],
|
||||
},
|
||||
},
|
||||
{ xAxis: '30' },
|
||||
{xAxis: '30'},
|
||||
],
|
||||
[
|
||||
// 逐步恢复期
|
||||
|
|
@ -904,7 +900,7 @@ const accidentImpactOption = computed(() => {
|
|||
padding: [-18, 0],
|
||||
},
|
||||
},
|
||||
{ xAxis: '60' },
|
||||
{xAxis: '60'},
|
||||
],
|
||||
],
|
||||
},
|
||||
|
|
@ -934,8 +930,8 @@ const accidentImpactOption = computed(() => {
|
|||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(34, 197, 94, 0.35)' },
|
||||
{ offset: 1, color: 'rgba(34, 197, 94, 0.02)' },
|
||||
{offset: 0, color: 'rgba(34, 197, 94, 0.35)'},
|
||||
{offset: 1, color: 'rgba(34, 197, 94, 0.02)'},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
@ -949,6 +945,97 @@ const getPageData = async () => {
|
|||
const res = await api.getPageData('status')
|
||||
const data = JSON.parse(res.data)
|
||||
console.log("🚀 ~ getPageData ~ data: ", data);
|
||||
// 事故影响量化指标对比
|
||||
const dataOne = data['accident_impact_quantified_comparison']?.data_one?.items || []
|
||||
const dataTwo = data['accident_impact_quantified_comparison']?.data_two?.items || []
|
||||
const categoryOrder = []
|
||||
dataOne.forEach(item => {
|
||||
if (!categoryOrder.includes(item.project)) {
|
||||
categoryOrder.push(item.project)
|
||||
}
|
||||
})
|
||||
dataTwo.forEach(item => {
|
||||
if (!categoryOrder.includes(item.project)) {
|
||||
categoryOrder.push(item.project)
|
||||
}
|
||||
})
|
||||
impactCompareAxis.value = categoryOrder
|
||||
const categoryIndexMap = {}
|
||||
categoryOrder.forEach((cat, idx) => {
|
||||
categoryIndexMap[cat] = idx
|
||||
impactCompareData.value.data1[idx] = 0
|
||||
impactCompareData.value.data2[idx] = 0
|
||||
})
|
||||
dataOne.forEach(item => {
|
||||
const index = categoryIndexMap[item.project]
|
||||
if (index !== undefined) {
|
||||
impactCompareData.value.data1[index] = item.data ?? 0
|
||||
}
|
||||
})
|
||||
dataTwo.forEach(item => {
|
||||
const index = categoryIndexMap[item.project]
|
||||
if (index !== undefined) {
|
||||
impactCompareData.value.data2[index] = item.data ?? 0
|
||||
}
|
||||
})
|
||||
// 示范区域近七日交通流量对比
|
||||
const morningPeak = data['demo_area_7day_volume_comparison']?.morning_peak?.items || []
|
||||
const eveningPeak = data['demo_area_7day_volume_comparison']?.evening_peak?.items || []
|
||||
const allDay = data['demo_area_7day_volume_comparison']?.all_day?.items || []
|
||||
const dateOrder = []
|
||||
morningPeak.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
if (!dateOrder.includes(dateStr)) {
|
||||
dateOrder.push(dateStr)
|
||||
}
|
||||
})
|
||||
eveningPeak.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
if (!dateOrder.includes(dateStr)) {
|
||||
dateOrder.push(dateStr)
|
||||
}
|
||||
})
|
||||
allDay.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
if (!dateOrder.includes(dateStr)) {
|
||||
dateOrder.push(dateStr)
|
||||
}
|
||||
})
|
||||
demoAreaLast7Days.value = dateOrder
|
||||
const dateIndexMap = {}
|
||||
dateOrder.forEach((date, idx) => {
|
||||
dateIndexMap[date] = idx
|
||||
})
|
||||
demoAreaFlowData.value.morning = dateOrder.map(() => 0)
|
||||
demoAreaFlowData.value.evening = dateOrder.map(() => 0)
|
||||
demoAreaFlowData.value.all = dateOrder.map(() => 0)
|
||||
morningPeak.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
const index = dateIndexMap[dateStr]
|
||||
if (index !== undefined) {
|
||||
demoAreaFlowData.value.morning[index] = item.data ?? 0
|
||||
}
|
||||
})
|
||||
eveningPeak.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
const index = dateIndexMap[dateStr]
|
||||
if (index !== undefined) {
|
||||
demoAreaFlowData.value.evening[index] = item.data ?? 0
|
||||
}
|
||||
})
|
||||
allDay.forEach(item => {
|
||||
const dateStr = moment(item.project).format('MM/DD')
|
||||
const index = dateIndexMap[dateStr]
|
||||
if (index !== undefined) {
|
||||
demoAreaFlowData.value.all[index] = item.data ?? 0
|
||||
}
|
||||
})
|
||||
// 示范区域历史交通流趋势
|
||||
|
||||
// 111
|
||||
// 111
|
||||
// 111
|
||||
// 111
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -959,14 +1046,14 @@ onMounted(() => {
|
|||
<template>
|
||||
<div class="status-monitor-page">
|
||||
<div class="status-monitor-map-wrap">
|
||||
<MapPage :hide-accident-panels="true" :show-ztjc-overlays="true" :show-accident-overlays="true" />
|
||||
<MapPage :hide-accident-panels="true" :show-ztjc-overlays="true" :show-accident-overlays="true"/>
|
||||
</div>
|
||||
<div class="status-monitor-content">
|
||||
<div class="status-monitor-overview">
|
||||
<div v-for="item in statusMonitorOverviewCards" :key="item.label" class="overview-item">
|
||||
<div class="overview-icon-wrap">
|
||||
<div class="overview-icon-ring">
|
||||
<img :src="item.icon" alt="" class="overview-icon" />
|
||||
<img :src="item.icon" alt="" class="overview-icon"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview-text">
|
||||
|
|
@ -1080,18 +1167,18 @@ onMounted(() => {
|
|||
<h3>趋势统计</h3>
|
||||
<div class="trend-tabs">
|
||||
<div class="trend-tab" :class="{ 'trend-tab-active': activeTrendMetric === 'congestion' }"
|
||||
@click="activeTrendMetric = 'congestion'">
|
||||
@click="activeTrendMetric = 'congestion'">
|
||||
拥堵指数
|
||||
</div>
|
||||
<div class="trend-tab" :class="{ 'trend-tab-active': activeTrendMetric === 'speed' }"
|
||||
@click="activeTrendMetric = 'speed'">
|
||||
@click="activeTrendMetric = 'speed'">
|
||||
平均速度
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body trend-card-body">
|
||||
<div class="trend-chart-wrap">
|
||||
<v-chart class="trend-chart" :option="trendOption" autoresize />
|
||||
<v-chart class="trend-chart" :option="trendOption" autoresize/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1100,15 +1187,15 @@ onMounted(() => {
|
|||
<h3>事故影响下交通流变化趋势</h3>
|
||||
<div class="accident-impact-actions">
|
||||
<el-select v-model="accidentImpactSection" class="accident-impact-select"
|
||||
popper-class="status-monitor-select-popper" :teleported="false" style="width: 90px;">
|
||||
popper-class="status-monitor-select-popper" :teleported="false" style="width: 90px;">
|
||||
<el-option v-for="opt in accidentImpactSectionOptions" :key="opt.value" :label="opt.label"
|
||||
:value="opt.value" />
|
||||
:value="opt.value"/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body trend-card-body">
|
||||
<div class="trend-chart-wrap">
|
||||
<v-chart class="trend-chart" :option="accidentImpactOption" autoresize />
|
||||
<v-chart class="trend-chart" :option="accidentImpactOption" autoresize/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1121,15 +1208,15 @@ onMounted(() => {
|
|||
<h3>示范区域近七日交通流量对比</h3>
|
||||
<div class="demo-flow-actions">
|
||||
<el-select v-model="demoAreaFlowFilter" class="accident-impact-select demo-flow-select"
|
||||
popper-class="status-monitor-select-popper" :teleported="false" style="width: 68px;">
|
||||
popper-class="status-monitor-select-popper" :teleported="false" style="width: 68px;">
|
||||
<el-option v-for="opt in demoAreaFlowFilterOptions" :key="opt.value" :label="opt.label"
|
||||
:value="opt.value" />
|
||||
:value="opt.value"/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body chart-card-body">
|
||||
<div class="chart-wrap">
|
||||
<v-chart class="chart" :option="last7DaysFlowOption" autoresize />
|
||||
<v-chart class="chart" :option="last7DaysFlowOption" autoresize/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1139,7 +1226,7 @@ onMounted(() => {
|
|||
</div>
|
||||
<div class="card-body chart-card-body">
|
||||
<div class="chart-wrap">
|
||||
<v-chart class="chart" :option="accidentImpactCompareOption" autoresize />
|
||||
<v-chart class="chart" :option="accidentImpactCompareOption" autoresize/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1148,11 +1235,11 @@ onMounted(() => {
|
|||
<h3>示范区域历史交通流趋势</h3>
|
||||
<div class="trend-tabs">
|
||||
<div class="trend-tab" :class="{ 'trend-tab-active': demoAreaHistoryRange === '7d' }"
|
||||
@click="demoAreaHistoryRange = '7d'">
|
||||
@click="demoAreaHistoryRange = '7d'">
|
||||
近七日
|
||||
</div>
|
||||
<div class="trend-tab" :class="{ 'trend-tab-active': demoAreaHistoryRange === '1d' }"
|
||||
@click="demoAreaHistoryRange = '1d'">
|
||||
@click="demoAreaHistoryRange = '1d'">
|
||||
近一日
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1182,7 +1269,7 @@ onMounted(() => {
|
|||
</div>
|
||||
|
||||
<div class="demo-history-chart-wrap">
|
||||
<v-chart class="chart" :option="demoAreaHistoryTrendOption" autoresize />
|
||||
<v-chart class="chart" :option="demoAreaHistoryTrendOption" autoresize/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1232,7 +1319,7 @@ onMounted(() => {
|
|||
background: linear-gradient(180deg,
|
||||
rgba(185, 220, 255, 0.5) 0%,
|
||||
rgba(222, 234, 246, 0) 100%),
|
||||
#fafdff;
|
||||
#fafdff;
|
||||
box-shadow: 0 0 8px rgba(97, 112, 146, 0.6);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(45, 103, 237, 0.3);
|
||||
|
|
@ -1355,7 +1442,7 @@ onMounted(() => {
|
|||
background: linear-gradient(180deg,
|
||||
rgba(185, 220, 255, 0.5) 0%,
|
||||
rgba(222, 234, 246, 0) 100%),
|
||||
#fafdff;
|
||||
#fafdff;
|
||||
box-shadow: 0 0 8px rgba(97, 112, 146, 0.6);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(45, 103, 237, 0.3);
|
||||
|
|
@ -1387,7 +1474,6 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
|
||||
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
margin-left: 25px;
|
||||
|
|
@ -1516,7 +1602,7 @@ onMounted(() => {
|
|||
height: 56px;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(180deg, rgba(185, 220, 255, 0.65) 0%, rgba(222, 234, 246, 0) 100%),
|
||||
rgba(245, 248, 255, 0.9);
|
||||
rgba(245, 248, 255, 0.9);
|
||||
box-shadow: inset 0 0 0 1px rgba(45, 103, 237, 0.16);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -1624,7 +1710,7 @@ onMounted(() => {
|
|||
background: #2d67ed;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06),
|
||||
0 4px 8px rgba(37, 99, 235, 0.35);
|
||||
0 4px 8px rgba(37, 99, 235, 0.35);
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
|
||||
|
|
@ -1640,7 +1726,7 @@ onMounted(() => {
|
|||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.trend-tab+.trend-tab {
|
||||
.trend-tab + .trend-tab {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
|
|
@ -1648,7 +1734,7 @@ onMounted(() => {
|
|||
background: #2d67ed;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06),
|
||||
0 4px 8px rgba(37, 99, 235, 0.35);
|
||||
0 4px 8px rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
|
||||
.trend-card-body {
|
||||
|
|
@ -1708,7 +1794,7 @@ onMounted(() => {
|
|||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.overall-row+.overall-row {
|
||||
.overall-row + .overall-row {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue