事故快检UI页面布局画完
This commit is contained in:
parent
5a2ebb1d32
commit
4e976a5593
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup>
|
<script setup >
|
||||||
import { ref, computed,onMounted } from 'vue'
|
import { ref, computed,onMounted,onUnmounted } from 'vue'
|
||||||
import { use } from 'echarts/core'
|
import { use } from 'echarts/core'
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
import { PieChart, BarChart } from 'echarts/charts'
|
import { BarChart } from 'echarts/charts'
|
||||||
import { TooltipComponent, TitleComponent, GridComponent } from 'echarts/components'
|
import { TooltipComponent, TitleComponent, GridComponent } from 'echarts/components'
|
||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import imgAccuracy from '@/assets/images/home/recognitionAcc.png'
|
import imgAccuracy from '@/assets/images/home/recognitionAcc.png'
|
||||||
|
|
@ -10,9 +10,85 @@ import imgDelay from '@/assets/images/home/detectionAvg.png'
|
||||||
import MapPage from '@/views/map/index.vue'
|
import MapPage from '@/views/map/index.vue'
|
||||||
import Timeline from '@/components/TimelineView/TimelinePag.vue'
|
import Timeline from '@/components/TimelineView/TimelinePag.vue'
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
const chartRef = ref(null);
|
|
||||||
|
|
||||||
use([CanvasRenderer, PieChart, BarChart, TooltipComponent, TitleComponent, GridComponent])
|
const chartRef = ref(null); //第2个图表
|
||||||
|
const chartRefThree = ref(null);//第3个图表
|
||||||
|
const chartRefFre = ref(null);//第4个图表
|
||||||
|
let myChartOne = null;
|
||||||
|
|
||||||
|
// 模拟图表数据 [处理时间, 严重程度]
|
||||||
|
const data = [
|
||||||
|
[1, 12], [1, 18], [2, 16], [4, 18], [5, 15], [6, 31], [7, 10], [7, 36],
|
||||||
|
[1.5, 48], [1.8, 80], [4.2, 40], [6.5, 108], [8.5, 72], [9.2, 63],
|
||||||
|
[10.8, 58], [10.8, 91], [11.2, 98], [12.5, 68], [12.5, 71], [15, 78],
|
||||||
|
[16.8, 75], [19.2, 72], [19.8, 95], [20.2, 48], [20.8, 50], [21, 71],
|
||||||
|
[21, 79], [23, 67], [23.2, 102], [32, 95]
|
||||||
|
];
|
||||||
|
|
||||||
|
const initChart = () => {
|
||||||
|
if (chartRefFre.value) {
|
||||||
|
myChartOne = echarts.init(chartRefFre.value);
|
||||||
|
|
||||||
|
const optionFor = {
|
||||||
|
grid: {
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '10%',
|
||||||
|
top: '10%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
name: '处理时间(分钟)',
|
||||||
|
nameLocation: 'center',
|
||||||
|
nameGap: 30,
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: 40,
|
||||||
|
interval: 10,
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#E0E0E0' } },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: { color: '#666', fontSize: 14 },
|
||||||
|
splitLine: { show: false } // 隐藏纵向网格线
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
name: '(严重程度)',
|
||||||
|
nameLocation: 'start',
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: 120,
|
||||||
|
interval: 20,
|
||||||
|
axisLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: { color: '#666', fontSize: 14 },
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: { type: 'dashed', color: '#E0E0E0' } // 横向虚线网格
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: data,
|
||||||
|
type: 'scatter',
|
||||||
|
symbolSize: 10,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#2ECC71', // 对应图中的绿色
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
myChartOne.setOption(optionFor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 响应式监听窗口变化
|
||||||
|
const handleResize = () => {
|
||||||
|
myChartOne && myChartOne.resize();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 注册 ECharts 必须的组件
|
||||||
|
use([CanvasRenderer, BarChart, TooltipComponent, TitleComponent, GridComponent])
|
||||||
|
|
||||||
// 交通事故快速检测 - 动态数据
|
// 交通事故快速检测 - 动态数据
|
||||||
const accidentQuickDetect = ref({
|
const accidentQuickDetect = ref({
|
||||||
|
|
@ -77,7 +153,166 @@ const carList = ref([
|
||||||
{ name: '建设路', time: '11:12', img: 'xxx.jpg' },
|
{ name: '建设路', time: '11:12', img: 'xxx.jpg' },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
// ----------底部第二个图标---------------------------------------------------------
|
||||||
|
// 1. 原始数据定义
|
||||||
|
const rawData = [
|
||||||
|
{ time: '06:00-07:00', blue: 3.0, cyan: 0 },
|
||||||
|
{ time: '08:00-09:00', blue: 11.6, cyan: 0 },
|
||||||
|
{ time: '10:00-11:00', blue: 0, cyan: 16.2 },
|
||||||
|
{ time: '12:00-13:00', blue: 8.9, cyan: 0 },
|
||||||
|
{ time: '14:00-15:00', blue: 6.9, cyan: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 2. 提取X轴和Y轴数据
|
||||||
|
const xAxisData = computed(() => rawData.map(item => item.time));
|
||||||
|
const blueData = computed(() => rawData.map(item => item.blue));
|
||||||
|
const cyanData = computed(() => rawData.map(item => item.cyan));
|
||||||
|
|
||||||
|
// 3. ECharts 配置项
|
||||||
|
const optionNew = computed(() => {
|
||||||
|
// 定义通用标签样式 (用于柱状图顶部的数值)
|
||||||
|
const labelStyle = {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
fontSize: 12,
|
||||||
|
offset: [0, -5], // 向上偏移,匹配图片
|
||||||
|
formatter: (params) => {
|
||||||
|
// 只有当数值大于 0 时才显示标签
|
||||||
|
return params.value > 0 ? params.value.toFixed(1) : '';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
// 设置基础颜色
|
||||||
|
color: ['#4A7CFF', '#00E8FF'], // [深蓝, 青色]
|
||||||
|
|
||||||
|
// 图表布局,留出显示标签和坐标轴的空间
|
||||||
|
grid: {
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
top: '15%',
|
||||||
|
bottom: '10%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 图例配置 (右上角)
|
||||||
|
legend: {
|
||||||
|
data: ['数据', '数据一'],
|
||||||
|
right: 10,
|
||||||
|
top: 0,
|
||||||
|
icon: 'rect', // 图例图标为矩形
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 提示框 (可选,增强交互)
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// X 轴配置
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData.value,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#E0E0E0', // X轴线颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false, // 隐藏刻度线
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#666',
|
||||||
|
fontSize: 11,
|
||||||
|
interval: 0, // 强制显示所有标签
|
||||||
|
rotate: 0,
|
||||||
|
margin: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Y 轴配置
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: 25, // 根据图片设置最大值
|
||||||
|
interval: 5, // 刻度间隔为 5
|
||||||
|
axisLine: {
|
||||||
|
show: false, // 隐藏Y轴线
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false, // 隐藏刻度线
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#666',
|
||||||
|
fontSize: 11,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#E0E0E0',
|
||||||
|
type: 'dashed', // 设置为虚线
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 系列配置 (柱状图)
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '数据', // 匹配图例
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: 15, // 柱子宽度
|
||||||
|
barGap: '-100%', // 核心配置:使两个系列在同一个X轴位置重合
|
||||||
|
data: blueData.value,
|
||||||
|
label: {
|
||||||
|
...labelStyle,
|
||||||
|
color: '#4A7CFF', // 蓝组标签颜色
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [2, 2, 0, 0], // 顶部微小圆角
|
||||||
|
color: (params) => {
|
||||||
|
// 只有当数值大于 0 时才渲染颜色
|
||||||
|
return params.value > 0 ? '#4A7CFF' : 'rgba(0,0,0,0)';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '数据一', // 匹配图例
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: 15,
|
||||||
|
data: cyanData.value,
|
||||||
|
label: {
|
||||||
|
...labelStyle,
|
||||||
|
color: '#00E8FF', // 青组标签颜色
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [2, 2, 0, 0],
|
||||||
|
color: (params) => {
|
||||||
|
// 只有当数值大于 0 时才渲染颜色
|
||||||
|
return params.value > 0 ? '#00E8FF' : 'rgba(0,0,0,0)';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
|
// -----------底部第四个图表-------------------------------------------------------------
|
||||||
|
initChart();
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
|
||||||
|
// -----------底部第一个图表-------------------------------------------------------------
|
||||||
const chart = echarts.init(chartRef.value);
|
const chart = echarts.init(chartRef.value);
|
||||||
const option = {
|
const option = {
|
||||||
title: {
|
title: {
|
||||||
|
|
@ -137,14 +372,98 @@ onMounted(() => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
chart.setOption(option);
|
chart.setOption(option);
|
||||||
|
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener("resize", () => {
|
||||||
chart.resize();
|
chart.resize();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// ------------底部图表第三个--------------------------------------------------------------------
|
||||||
|
const myChart = echarts.init(chartRefThree.value);
|
||||||
|
const data = [15, 18, 22, 31, 33];
|
||||||
|
const categories = ['和平路', '文化路', '解放路', '人民路', '建设路'];
|
||||||
|
|
||||||
|
const optionThree = {
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '10%',
|
||||||
|
bottom: '10%',
|
||||||
|
top: '5%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
max: 40, // 对应图中最大刻度
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#E0E0E0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
color: '#666',
|
||||||
|
margin: 15
|
||||||
|
},
|
||||||
|
name: '(事故人数)',
|
||||||
|
nameLocation: 'middle',
|
||||||
|
nameGap: 30
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: categories,
|
||||||
|
axisLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
color: '#666',
|
||||||
|
fontSize: 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '人数',
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: 12, // 条形图宽度
|
||||||
|
showBackground: true,
|
||||||
|
backgroundStyle: {
|
||||||
|
color: '#EDEDED',
|
||||||
|
borderRadius: 10
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 10,
|
||||||
|
// 设置水平线性渐变 (左浅蓝到右深蓝)
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
|
{ offset: 0, color: '#A5C1FF' },
|
||||||
|
{ offset: 1, color: '#4D73FF' }
|
||||||
|
])
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top', // 标签放在条形上方
|
||||||
|
distance: 5,
|
||||||
|
color: '#4D73FF',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
formatter: '{c}'
|
||||||
|
},
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
myChart.setOption(optionThree);
|
||||||
|
// 响应式处理
|
||||||
|
window.addEventListener('resize', () => myChart.resize());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
myChartOne && myChartOne.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// 根据总数计算事故类型占比
|
// 根据总数计算事故类型占比
|
||||||
const accidentTypesWithPercent = computed(() => {
|
const accidentTypesWithPercent = computed(() => {
|
||||||
const total = accidentQuickDetect.value.totalToday
|
const total = accidentQuickDetect.value.totalToday
|
||||||
|
|
@ -540,18 +859,34 @@ const accidentList = ref([
|
||||||
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
||||||
事故高发时段
|
事故高发时段
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<v-chart class="chart" :option="optionNew" autoresize />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="impact-item3">
|
<div class="impact-item3">
|
||||||
<div class="title-Bottoms">
|
<div class="title-Bottoms">
|
||||||
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
||||||
事故高发路段TOP5
|
事故高发路段TOP5
|
||||||
</div>
|
</div>
|
||||||
|
<div class="earchartconter">
|
||||||
|
<div ref="chartRefThree" class="earcsslThree"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="impact-item4">
|
<div class="impact-item4">
|
||||||
<div class="title-Bottoms">
|
<div class="title-Bottoms">
|
||||||
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
<img class="img-jt" src="@/assets/images/erjititle.png" alt="区域交通概况" srcset="">
|
||||||
处理时间与严重程度分析
|
处理时间与严重程度分析
|
||||||
</div>
|
</div>
|
||||||
|
<div class="earchartconter">
|
||||||
|
<!-- <div class="chart-header">
|
||||||
|
<div class="header-right">
|
||||||
|
平均处理时长:<span class="avg-value">25</span> 分钟
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div ref="chartRefFre" class="earcsslThree"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -741,6 +1076,13 @@ const accidentList = ref([
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 图表 2--------------------------------- */
|
||||||
|
.chart {
|
||||||
|
width: 400px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.type-percent {
|
.type-percent {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
|
|
@ -910,6 +1252,12 @@ const accidentList = ref([
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.earcsslThree{
|
||||||
|
width: 500px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
.titlnew{
|
.titlnew{
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
|
@ -1751,4 +2099,50 @@ img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left .icon {
|
||||||
|
color: #4A90E2;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px;
|
||||||
|
letter-spacing: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left .title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avg-value {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #4A90E2;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue