Commit cb366e3e authored by ninglx's avatar ninglx

wj-smartcity title背景动画 数据查询&态势监测页面开发接口联调 数据聚合展示

parent 5b912e2f
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
::v-deep .el-table .cell{ ::v-deep .el-table .cell{
line-height: 33px; line-height: 33px;
cursor: pointer; cursor: pointer;
color: white;
} }
::v-deep .custom-table-header-cell { ::v-deep .custom-table-header-cell {
...@@ -71,7 +72,7 @@ ...@@ -71,7 +72,7 @@
} }
::v-deep .el-table { ::v-deep .el-table {
background: #0f2645; background: #030b19;
} }
::v-deep .row-deep { ::v-deep .row-deep {
...@@ -86,6 +87,18 @@ ...@@ -86,6 +87,18 @@
} }
} }
::v-deep .row-even {
td {
background-color: #030d1e;
}
}
::v-deep .row-odd {
td {
background-color: #0b1933;
}
}
::v-deep .row-deep.hover-row { ::v-deep .row-deep.hover-row {
td { td {
background-color: #171f34; background-color: #171f34;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<img alt="" src="../../assets/images/holo/logo.svg"/> <img alt="" src="../../assets/images/holo/logo.svg"/>
{{ title }} {{ title }}
</div> </div>
<div class="move-light"></div>
<!-- <div class="user">--> <!-- <div class="user">-->
<!-- <div class="user-icon"></div>--> <!-- <div class="user-icon"></div>-->
<!-- <div class="user-text">{{ userInfo.name }}</div>--> <!-- <div class="user-text">{{ userInfo.name }}</div>-->
...@@ -347,7 +348,7 @@ export default { ...@@ -347,7 +348,7 @@ export default {
height: 82px; height: 82px;
display: unset; display: unset;
background:transparent; background:transparent;
background-image: url("../../assets/images/holo/topIndex1.png"); background-image: url("../../assets/images/holo/topIndex2.png");
background-size: 100% auto; background-size: 100% auto;
background-clip: border-box; background-clip: border-box;
position: relative; position: relative;
...@@ -366,6 +367,28 @@ export default { ...@@ -366,6 +367,28 @@ export default {
height: 47px; height: 47px;
} }
} }
.move-light{
position: absolute;
top: 61px;
height: 7px;
width: 120px;
background: radial-gradient(rgb(192, 238, 249), rgba(77, 217, 248, 0.5), rgba(19, 159, 250,0.2), transparent);
animation: moveToRight 15s linear infinite;
@keyframes moveToRight {
0%{
left: -120px;
opacity: 1;
}
75%{
opacity: 1;
}
100%{
left: 300px;
opacity: 0;
}
}
}
} }
.el-menu.el-menu--horizontal { .el-menu.el-menu--horizontal {
......
...@@ -12,4 +12,8 @@ export default [ ...@@ -12,4 +12,8 @@ export default [
path: "/signalEvaluation", path: "/signalEvaluation",
component: (resolve) => require(["@/views/signalEvaluation/index.vue"], resolve), component: (resolve) => require(["@/views/signalEvaluation/index.vue"], resolve),
}, },
{
path: "/dataQueries",
component: (resolve) => require(["@/views/dataQueries/index.vue"], resolve),
},
]; ];
...@@ -46,3 +46,28 @@ export const getCrossStatusTimeRate = (data) => request({ ...@@ -46,3 +46,28 @@ export const getCrossStatusTimeRate = (data) => request({
method:'post', method:'post',
data: data data: data
}) })
// 数据查询 车道交通指标
export const getLaneTrafficIndex = (data) => request({
url:`${baseUrl}/trend/laneTrafficIndex`,
method:'post',
data: data
})
// 态势监测 底部路口级交通事件列表
export const getHoloEventList = (data) =>request({
url:`${baseUrl}/trend/holoEventList`,
method:'post',
data: data
})
// 转向级
export const getLanePeriodTurnData = (data) => request({
url:`${baseUrl}/trend/lanePeriodTurnData`,
method:'post',
data: data
})
// 数据查询 车道快照指标
export const getLaneSnapshotIndex = (data) => request({
url:`${baseUrl}/trend/laneSnapshotIndex`,
method:'post',
data: data
})
\ No newline at end of file
/** // 判空占位
* Created by jiachenpan on 16/11/18. export function occupancyValue(value) {
*/ if (value || value === 0) {
return value
}
return '--'
}
export function parseTime(time) { export function parseTime(time) {
if (time) { if (time) {
......
...@@ -645,6 +645,31 @@ export function addOrUpdateEventPoint(map, geo, callback) { ...@@ -645,6 +645,31 @@ export function addOrUpdateEventPoint(map, geo, callback) {
} }
} }
export function addOrUpdateEventPoint1(map, geo, callback) {
if (!map.getSource("eventPoint1")) {
map.addSource("eventPoint1", {
type: "geojson",
data: geo,
});
} else {
map.getSource("eventPoint1").setData(geo);
}
if (!map.getLayer("eventPoint1")) {
map.addLayer({
id: "eventPoint1",
type: "symbol",
source: "eventPoint1",
layout: {
"icon-allow-overlap": true,
"icon-ignore-placement": true,
"icon-image": "event",
"icon-size": 1,
"icon-offset": [0, -10],
},
});
}
}
// 相机设备 // 相机设备
export function addOrUpdateEquipCamera(map, geo, callback) { export function addOrUpdateEquipCamera(map, geo, callback) {
if (!map.getSource("camera")) { if (!map.getSource("camera")) {
......
<template>
<div class="full-w-h dataQueries">
<left-list @crossChange="crossChange" class="leftPart"/>
<div class="rightPart">
<right-form ref="rightForm" :crossData="crossData"/>
</div>
</div>
</template>
<script>
import LeftList from "@/views/dataQueries/leftLists/index.vue";
import RightForm from "@/views/dataQueries/rightForm/index.vue";
export default {
components: {RightForm, LeftList},
data(){
return{
crossData:null
}
},
methods:{
crossChange(crossData){
this.crossData = crossData
console.log('cross',crossData)
setTimeout(()=>{
this.$refs.rightForm.getData()
},0)
}
}
}
</script>
<style lang="less" scoped>
.dataQueries{
display: flex;
justify-content: space-between;
.leftPart{
width: 400px;
}
.rightPart{
width: calc(100% - 420px);
}
}
</style>
\ No newline at end of file
<template>
<div class="full-w-h lists">
<msg-card title="路口列表">
<div class="msg_card_inner">
<el-input
class="s_input"
style="background-color: transparent"
placeholder="请输入路口名称"
@input="filterCrossTable"
v-model="crossName"
:maxlength='64'
>
<template slot="prepend"><i class="el-icon-search"></i></template>
</el-input>
<div class="left_table">
<el-table
:current-row-key="currentRowKey"
:row-key="getRowKey"
@row-click="rowClick"
style="width: 100%;"
height="100%"
highlight-current-row
v-loading="tableLoading"
element-loading-text="数据加载中..."
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.4)"
ref="multipleTable"
:row-class-name="getRowClassName"
:data="tableData"
class="track-result-table"
cell-class-name="custom-table-cell"
header-row-class-name="custom-table-header"
header-cell-class-name="custom-table-header-cell"
>
<el-table-column
align="center"
width="100"
label="排名"
sortable
prop="index"
>
</el-table-column>
<el-table-column
width="auto"
align="center"
:show-overflow-tooltip="true"
prop="crossName"
label="路口名称"
>
</el-table-column>
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="congestionIndex"-->
<!-- width="100"-->
<!-- label="拥堵指数"-->
<!-- >-->
<!-- </el-table-column>-->
</el-table>
</div>
<w-map :mapId="'dataQueries-map'" ref="wMap"/>
</div>
</msg-card>
</div>
</template>
<script>
import * as mapTool from '@/utils/mapboxTools'
import WMap from "@/components/Standard/mapMapbox.vue";
import {allCamera, crossList} from "@/common/api/signalEvaluation";
import mapAssets from "@/config/holo/mapAssets";
import MsgCard from "@/components/Standard/msg-card.vue";
let map = null
export default {
name: 'leftList',
components: {MsgCard, WMap},
data(){
return{
currentRowKey:'',
crossName:'',
tableLoading: true,
tableData: [],
fullData: [],
}
},
mounted(){
map = this.$refs.wMap.initMap({zoom: 17.8,pitch:0})
map.on('style.load',()=>{
this.getList()
})
},
methods:{
getRowClassName(e) {
if (e.rowIndex % 2 !== 0) {
if (e.row.isSignal && e.row.isSignal.toString().includes("select")) {
return "row-deep-select";
} else {
return "row-deep";
}
} else {
if (e.row.isSignal && e.row.isSignal.toString().includes("select")) {
return "row-not-select";
} else {
return "row-not";
}
}
},
getList() {
crossList({}).then(res => {
this.tableLoading = false;
this.fullData = res.data.content.sort((a,b)=>{
return b.congestionIndex - a.congestionIndex
}).map((item, index) => {
return {isSignal:'1',index: index + 1, ...item}
})
this.tableData = JSON.parse(JSON.stringify(this.fullData))
this.rowClick(this.tableData[0])
this.currentRowKey = this.tableData[0].crossId
})
},
getRowKey(row){
return row.crossId
},
filterCrossTable(e) {
this.tableData = this.fullData.filter((item) => {
return item.crossName.includes(e);
});
},
rowClick(row) {
// this.lastCheck = row;
// this.updateLayer(row);
map?.flyTo({
center: [row.longitude,row.latitude],
duration: 1500
});
this.$emit("crossChange", row);
},
}
}
</script>
<style lang="less" scoped>
@import url("../../../assets/less/elementTable.less");
.s_input {
margin-bottom: 15px;
}
::v-deep .el-input-group__prepend {
background-color: transparent;
border: 1px solid rgba(25, 58, 110, 1);
}
::v-deep .el-input__inner {
background-color: transparent;
border: 1px solid rgba(25, 58, 110, 1);
border-left: none;
color: white;
font-size: 16px;
font-weight: 500;
}
.msg_card_inner {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-bottom: 10px;
.left_table {
overflow: hidden;
height: 700px;
margin-bottom: 20px;
}
}
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<div class="full-w-h" style="display: flex;flex-direction: column">
<div class="custom-tab-header">
<div @click="clickTab(item)" class="c-tab-item"
:class="`${activeTab===Object.keys(item)[0]?'active':''}`" v-for="item of tabs">{{
item[Object.keys(item)[0]]
}}
</div>
</div>
<div class="custom-tab-content">
<div class="tab-item" v-if="activeTab==='1'">
<cycle-data ref="tab1" :crossData="crossData"/>
</div>
<div class="tab-item" v-if="activeTab==='2'">
<snapshot-data ref="tab2" :crossData="crossData"/>
</div>
<div class="tab-item" v-if="activeTab==='3'">
</div>
</div>
</div>
</template>
<script>
import {getLanePeriodTurnData, getLaneTrafficIndex} from "@/dao/optApi";
import {noDataTitle} from "@/utils/chartStyle";
import {getFontSize} from "@/config/holo/fontSize";
import CycleData from "@/views/dataQueries/rightForm/cycleData.vue";
import SnapshotData from "@/views/dataQueries/rightForm/snapshotData.vue";
export default {
name: 'rightForm',
components: {SnapshotData, CycleData},
props: ['crossData'],
data() {
return {
activeTab: '1',
tabs: [
{'1': '周期数据'},
{'2': '快照数据'},
{'3': '事件数据'},
],
}
},
computed: {},
mounted() {
},
methods: {
clickTab(item){
if(Object.keys(item)[0]==='3') return
this.activeTab=Object.keys(item)[0]
},
getData() {
let queue = [];
let needDicts = [
'Direction'
];
for (let item of needDicts) {
queue.push(
this.$store.dispatch("QUERY_DICT", {
type: item,
})
);
}
Promise.all(queue).then(() => {
this.$refs[`tab${this.activeTab}`].getData()
})
},
}
}
</script>
<style lang="less" scoped>
@import url("../../../assets/less/elementTable.less");
::v-deep .el-input__inner, ::v-deep .el-range-input {
color: white;
background-color: transparent;
}
.custom-tab-header {
height: 45px;
display: flex;
width: 100%;
justify-content: space-between;
.c-tab-item {
width: 45%;
cursor: pointer;
background-color: #1a68af;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
}
.c-tab-item:last-child{
cursor: not-allowed;
}
.active {
background-color: #207dd2;
}
}
.custom-tab-content {
height: calc(100% - 45px);
.tab-item {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
}
</style>
\ No newline at end of file
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<wMap :mapId="'situation-map'" ref="wMap"/> <wMap :mapId="'situation-map'" ref="wMap"/>
<msgs :clickCrossData="clickCrossData" :isCrossDetail="isCrossDetail" v-if="!loading" @showCrossStatus="showCrossStatus" @openCrossIndexDetail="openCrossIndexDetail" <msgs :clickCrossData="clickCrossData" :isCrossDetail="isCrossDetail" v-if="!loading" @showCrossStatus="showCrossStatus" @openCrossIndexDetail="openCrossIndexDetail"
@showPolygon="showPolygon" @showPolygon="showPolygon"
@openGreenWaveDialog="openGreenWaveDialog" :show="boxesShow"></msgs> @openGreenWaveDialog="openGreenWaveDialog" :show="boxesShow" @showEventPoint="showEventPoint"></msgs>
<div :class="boxesShow ? '' : 'hideBackToMain'" @click="backToMain" v-if="isCrossDetail" class="backToMain"></div> <div :class="boxesShow ? '' : 'hideBackToMain'" @click="backToMain" v-if="isCrossDetail" class="backToMain"></div>
<!--切换图层 收起放开侧边栏--> <!--切换图层 收起放开侧边栏-->
<layers-switch <layers-switch
...@@ -34,6 +34,7 @@ import * as mapTool from '@/utils/mapboxTools' ...@@ -34,6 +34,7 @@ import * as mapTool from '@/utils/mapboxTools'
import {initWs} from "@/config/holo/websocket"; import {initWs} from "@/config/holo/websocket";
import dict from "../../config/holo/dictionary"; import dict from "../../config/holo/dictionary";
import vehicleDetail from "./mapPopup/vehicleDetail.vue"; import vehicleDetail from "./mapPopup/vehicleDetail.vue";
import {addOrUpdateEventPoint1} from "@/utils/mapboxTools";
const VehiclePopup = Vue.extend(vehicleDetail); const VehiclePopup = Vue.extend(vehicleDetail);
let map = null; let map = null;
...@@ -166,10 +167,12 @@ export default { ...@@ -166,10 +167,12 @@ export default {
map.on('dblclick',()=>{ map.on('dblclick',()=>{
console.log('center '+map.getCenter()+' pitch '+map.getPitch()+' bearing '+map.getBearing()+' zoom '+map.getZoom()) console.log('center '+map.getCenter()+' pitch '+map.getPitch()+' bearing '+map.getBearing()+' zoom '+map.getZoom())
}) })
window.map = map
map.on('zoomend',()=>{ map.on('zoomend',()=>{
this.mapZoomEnd() this.mapZoomEnd()
if(map.getZoom() < 16.5){ if(map.getZoom() < 16.5){
this.isCrossDetail = false this.isCrossDetail = false
this.removeLayers('eventPoint1')
} }
}) })
map.on('moveend',()=>{ map.on('moveend',()=>{
...@@ -191,9 +194,25 @@ export default { ...@@ -191,9 +194,25 @@ export default {
}); });
}, },
methods: { methods: {
showEventPoint(events){
let features = []
for(let item of events){
if(item.lng && item.lat){
features.push(turf.point([item.lng,item.lat],item))
}
}
// features.push(turf.point([map.getCenter().lng,map.getCenter().lat],{a:1}))
let geo = turf.featureCollection(features)
mapTool.addOrUpdateEventPoint1(map,geo)
map.on('click','eventPoint1',this.eventPointClick)
},
eventPointClick(e){
console.log('e.features[0].properties',e.features[0].properties)
},
backToMain(){ backToMain(){
this.isCrossDetail = false this.isCrossDetail = false
this.boxesShow = true this.boxesShow = true
this.removeLayers('eventPoint1')
map?.flyTo({ map?.flyTo({
duration: 1000, duration: 1000,
essential: true, essential: true,
......
<template> <template>
<div id="e_popup"> <div id="e_popup">
<div class="header">事件详情</div> <div class="header">{{ model.eventTypeName }}</div>
<div class="main"> <div class="main">
<div class="detail_item" v-for="(item,index) of eventDetails" :key="index"> <div class="detail_item" v-for="(item,index) of eventDetails" :key="index">
<div class="detail_item_label">{{ item.label }}</div> <div class="detail_item_label">{{ item.label }}</div>
...@@ -11,11 +11,12 @@ ...@@ -11,11 +11,12 @@
</template> </template>
<script> <script>
import {occupancyValue} from "@/utils";
export default { export default {
name: "eventPopup", name: "eventPopup",
props: ["model"], props: ["model"],
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
...@@ -26,11 +27,11 @@ export default { ...@@ -26,11 +27,11 @@ export default {
computed: { computed: {
eventDetails() { eventDetails() {
return [ return [
{ label: "事件类型:", value: this.model.eventType }, { label: "时间:", value: this.model.startTime },
{ label: "车牌号码:", value: this.model.plateNo }, { label: "事件编号:", value: occupancyValue(this.model.eventId) },
{ label: "参与者类别:", value: this.model.objectType }, { label: "停车状态:", value: '--' },
{ label: "检测时间:", value: this.model.detectTime }, { label: "车辆类型:", value: occupancyValue(this.model.objectType) },
{ label: "事件位置:", value: this.model.placeDesc }, { label: "车辆号码:", value: occupancyValue(this.model.plateNo) },
]; ];
}, },
}, },
......
<template>
<div class="full-w-h" style="display: flex;flex-direction: column">
<div class="custom-form">
<label class="custom-form-label">事件类型: </label>
<el-select highlight-current-row style="width: 120px;margin-right: 10px" @change="filterDataByType"
v-model="value"
placeholder="请选择">
<el-option
v-for="item in options"
:key="item"
:label="$store.state.dicts.EventType.find((it) => {
return it.code == item;
})?.name || item"
:value="item">
</el-option>
</el-select>
<label class="custom-form-label">时段选择: </label>
<el-date-picker
@change="getData"
v-model="dateTimeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
<el-table
element-loading-spinner="el-icon-loading"
element-loading-text="数据加载中..."
element-loading-background="rgba(3, 11, 25, 0.8)"
v-loading="loading"
header-row-class-name="custom-table-header"
header-cell-class-name="custom-table-header-cell"
@row-click="rowClick"
:data="listDataCopy"
:row-class-name="getRowClassName"
style="width: 100%;flex:1"
height="100%">
<el-table-column
show-overflow-tooltip
align="center"
label="事件编号">
<template slot-scope="scope">{{ occupancyValue(scope.row.eventId) }}</template>
</el-table-column>
<el-table-column
prop="eventTypeName"
align="center"
label="事件类型"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="startTime"
align="center"
label="时间"
show-overflow-tooltip>
</el-table-column>
<el-table-column
align="center"
label="位置"
show-overflow-tooltip>
<template slot-scope="scope">{{ occupancyValue(scope.row.placeDesc) }}</template>
</el-table-column>
<el-table-column
align="center"
label="备注"
show-overflow-tooltip>
<template slot-scope="scope">{{ occupancyValue(scope.row.remark) }}</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import Vue from "vue";
import {getHoloEventList} from "@/dao/optApi";
import {occupancyValue} from "@/utils";
import eventPopupVue from "../../mapPopup/eventPopup.vue";
const EventPopupVue = Vue.extend(eventPopupVue);
let eventPopup = null
export default {
name: 'eventComp',
props: ['crossData'],
data() {
return {
options: [],
value: '',
dateTimeRange: [],
tableData: [],
listDataCopy: [],
loading: true,
}
},
mounted() {
this.dateTimeRange = [
new Date(
new Date().setTime(new Date().getTime() - 3600 * 1000 * 24)
),
new Date()
];
this.getData()
},
methods: {
occupancyValue,
filterDataByType() {
this.listDataCopy = this.tableData.filter(item => {
return this.value === item.eventType
})
},
getData() {
this.loading = true
getHoloEventList({
crossId: this.crossData.id,
"end": this.dateTimeRange[1].toLocaleString().replaceAll('/', '-'),
"start": this.dateTimeRange[0].toLocaleString().replaceAll('/', '-'),
}).then(res => {
this.loading = false
this.$emit('showEventPoint', res.content)
this.tableData = res.content.map(item => {
item.eventTypeName = this.$store.state.dicts.EventType.find((dict) => {
return dict.code == item.eventType;
})?.name || item.eventType
return item
})
this.listDataCopy = JSON.parse(JSON.stringify(this.tableData))
this.options = res.content.reduce((a, b) => {
if (!a.includes(b.eventType)) {
a.push(b.eventType)
}
return a
}, [])
})
},
rowClick(row) {
eventPopup?.remove()
// if(!row.lng){
// row = {
// lng: window.map.getCenter().lng,
// lat: window.map.getCenter().lat
// }
// }
if (row.lng && row.lat) {
// 添加弹窗
eventPopup = new mapboxgl.Popup({
closeButton: true,
anchor: "bottom",
offset: [0, -20],
});
eventPopup.setLngLat([row.lng, row.lat])
.setHTML(`<div id="event_popup_smartcity"></div>`)
.addTo(window.map)
.addClassName("eventPopup");
new EventPopupVue({
propsData: {
model: row,
},
}).$mount(
`#event_popup_smartcity`
);
}else{
this.$message('选中事件无经纬度信息')
}
},
getRowClassName(e) {
if (e.rowIndex % 2 !== 0) {
return "row-even";
} else {
return "row-odd";
}
},
}
}
</script>
<style lang="less" scoped>
.custom-form {
height: 40px;
display: flex;
align-items: center;
}
::v-deep .el-range-input, ::v-deep .el-input__inner {
background-color: transparent;
color: white;
}
@import url("../../../../assets/less/elementTable.less");
::v-deep .el-input__inner {
color: white;
}
</style>
\ No newline at end of file
<template>
<div class="full-w-h" style="display: flex;flex-direction: column; position: relative">
<div class="custom-form">
<label class="custom-form-label">指标选择: </label>
<el-select @change="renderTargetIndex" style="width: 120px;margin-right: 10px" v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.prop"
:label="item.label"
:value="item.prop">
</el-option>
</el-select>
<label class="custom-form-label">时段选择: </label>
<el-date-picker
:clearable="false"
style="width:360px"
@change="getData"
v-model="dateTimeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
<v-chart :option="option" autoresize style="flex: 1"></v-chart>
</div>
</template>
<script>
import {noDataTitle} from "@/utils/chartStyle";
import {getFontSize} from "@/config/holo/fontSize";
import {getLaneTrafficIndex, getSingalFlow} from "@/dao/optApi";
export default {
name: 'trafficIndexComp',
props: ['crossData'],
data() {
return {
loading: true,
options: [{label: '时间', prop: 'time'},
{label: '方向', prop: 'dir'},
{label: '车道号', prop: 'laneSort'},
{label: '总流量', prop: 'allFlow'},
{label: '行人流量', prop: 'pedFlow'},
{label: '非机动车流量', prop: 'nonMotorFlow'},
{label: '小车流量', prop: 'trafficFlowA'},
{label: '中车流量', prop: 'trafficFlowB'},
{label: '大车流量', prop: 'trafficFlowC'},
{label: '平均速度', prop: 'speed'},
{label: '时间占有率', prop: 'timeOccupancy'},
{label: '平均车头时距', prop: 'vehheadTime'},
{label: '平均车身间距', prop: 'vehheadDist'},
{label: '85位速度', prop: 'v85'},
{label: '车辆总和', prop: 'allVehiceleFlow'},
{label: '平均空间占有率', prop: 'vehicleNumsRatioMean'},
{label: '最大排队长度', prop: 'queueLength'},
{label: '平均停车次数', prop: 'stopTimes'},
{label: '平均延误', prop: 'delayTime'},],
value: 'allFlow',
dateTimeRange: [],
xData: [],
yDatas: [],
}
},
computed: {
option() {
let title = {
show: false
}
if (!this.xData.length) {
title = noDataTitle
}
let series = []
for (let [i, item] of this.yDatas.entries()) {
// let nameReal = this.$store.state.dicts.Direction.find((item) => {
// return item.code == key;
// }).name
let nameReal = item.name;
series.push({
name: nameReal,
type: "line",
symbol: 'none',
smooth: true,
// areaStyle: {
// color: new echarts.graphic.LinearGradient(
// 0,
// 1,
// 0,
// 0,
// [
// {
// offset: 0,
// color: "rgba(62, 170, 247, 0)", // 100% 处的颜色
// },
// {
// offset: 1,
// color: this.colors[i], // 0% 处的颜色
// },
// ],
// false
// ),
// },
label: {
show: false,
},
emphasis: {
focus: "series",
},
data: item.list,
})
}
return {
title,
// dataZoom: {
// type: "inside",
// startValue: this.xData.length - 6,
// endValue: this.xData.length - 1,
// },
// color: this.colors,
tooltip: {
enterable: true,
trigger: "axis",
axisPointer: {
type: "shadow",
},
textStyle: {
fontSize: getFontSize(12),
},
confine: true,
},
legend: {
left: 0,
itemGap: getFontSize(16),
itemWidth: getFontSize(12),
itemHeight: getFontSize(12),
textStyle: {
color: "rgba(126, 139, 166, 1)",
fontSize: getFontSize(12),
lineHeight: 16,
},
pageTextStyle: {
color: "rgba(126, 139, 166, 1)",
fontSize: getFontSize(12),
},
pageIconColor: "white",
pageIconSize: getFontSize(12),
pageIconInactiveColor: "rgba(153, 153, 153, 1)",
type: "scroll",
},
grid: {
left: 0,
right: getFontSize(15),
bottom: 0,
top: "22%",
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
data: this.xData,
axisLabel: {
fontSize: getFontSize(12),
color: "rgba(126, 139, 166, 1)",
},
},
yAxis: {
axisTick: {
show: false,
},
axisLine: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "rgba(255, 255, 255, 0.2)",
},
},
type: "value",
axisLabel: {
fontSize: getFontSize(12),
color: "rgba(126, 139, 166, 1)",
},
},
series: series,
}
}
},
mounted() {
this.dateTimeRange = [
new Date(
new Date().setTime(new Date().getTime() - 3600 * 1000 * 24)
),
new Date()
];
this.getData()
},
methods: {
getData() {
this.loading = true;
getLaneTrafficIndex({
"crossId": this.crossData.id,
"end": this.dateTimeRange[1].toLocaleString().replaceAll('/', '-'),
"start": this.dateTimeRange[0].toLocaleString().replaceAll('/', '-'),
"granularity": "1h"
}).then(res => {
this.allData = res.content
this.renderTargetIndex()
})
},
renderTargetIndex(){
console.log('value',this.value)
this.xData = this.allData.reduce((a, b) => {
if(!a.includes(b.time)){
a.push(b.time)
}
return a
}, [])
this.yDatas = []
let yObj = this.allData.reduce((a, b) => {
let dir = this.$store.state.dicts.Direction.find((item) => {
return item.code == b.dir;
})?.name
if(a[`${dir}-${b.laneSort}`]){
a[`${dir}-${b.laneSort}`].push(b[this.value])
}else{
a[`${dir}-${b.laneSort}`] = [b[this.value]]
}
return a
}, {})
for(let key in yObj){
this.yDatas.push({name: key, list: yObj[key]})
}
}
}
}
</script>
<style lang="less" scoped>
.custom-form {
z-index: 2;
//position: absolute;
//right: 0;
//top: 0;
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: flex-end;
}
::v-deep .el-range-input, ::v-deep .el-input__inner{
background-color: transparent;
color: white;
}
</style>
\ No newline at end of file
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
<warning-msg style="height: 33%"/> <warning-msg style="height: 33%"/>
</div> </div>
</div> </div>
<div v-if="!isCrossDetail" class="button_flow" :class="[{ hide_bottom: !show }]"> <div class="button_flow" :class="[{ hide_bottom: !show }]">
<traffic-flow style="height: 100%;"/> <traffic-flow @showEventPoint="showEventPoint" :crossData="clickCrossData" :key="bottomChartKey" :isCrossDetail="isCrossDetail" style="height: 100%;"/>
</div> </div>
</div> </div>
</template> </template>
...@@ -43,6 +43,9 @@ export default { ...@@ -43,6 +43,9 @@ export default {
return {}; return {};
}, },
computed: { computed: {
bottomChartKey(){
return `bottomChart${this.isCrossDetail}${this.clickCrossData.id}`
},
detailKey() { detailKey() {
return `detailKey${this.isCrossDetail}${this.clickCrossData.id}` return `detailKey${this.isCrossDetail}${this.clickCrossData.id}`
} }
...@@ -52,6 +55,9 @@ export default { ...@@ -52,6 +55,9 @@ export default {
mounted() { mounted() {
}, },
methods: { methods: {
showEventPoint(events){
this.$emit('showEventPoint',events)
},
showCrossStatus(data) { showCrossStatus(data) {
this.$emit('showCrossStatus', data) this.$emit('showCrossStatus', data)
}, },
......
...@@ -66,8 +66,7 @@ ...@@ -66,8 +66,7 @@
<el-table-column <el-table-column
align="center" align="center"
prop="name" prop="name"
label="路口名称" label="路口名称">
width="160">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="congestionIndex" prop="congestionIndex"
...@@ -77,15 +76,13 @@ ...@@ -77,15 +76,13 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
label="同比" label="同比">
width="60">
<template slot-scope="scope"> <template slot-scope="scope">
{{ Math.abs(scope.row.lastPeriodIndex) }}% <img :src="getDownUpImg(scope.row.lastPeriodIndex)" alt=""/> {{ Math.abs(scope.row.lastPeriodIndex) }}% <img :src="getDownUpImg(scope.row.lastPeriodIndex)" alt=""/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="环比" label="环比"
width="60"
align="center" align="center"
> >
<template slot-scope="scope"> <template slot-scope="scope">
...@@ -377,11 +374,22 @@ export default { ...@@ -377,11 +374,22 @@ export default {
::v-deep .el-table__empty-text { ::v-deep .el-table__empty-text {
color: #ccc; color: #ccc;
} }
::v-deep .row-even {
td {
background-color: #030d1e;
}
}
.item-cross { ::v-deep .row-odd {
::v-deep .el-input__inner { td {
color: white; background-color: #0b1933;
} }
}
::v-deep .el-input__inner {
color: white;
}
.item-cross {
.list_control { .list_control {
display: flex; display: flex;
...@@ -527,16 +535,6 @@ export default { ...@@ -527,16 +535,6 @@ export default {
} }
} }
} }
::v-deep .row-even {
td {
background-color: #030d1e;
}
}
::v-deep .row-odd {
td {
background-color: #0b1933;
}
}
} }
</style> </style>
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
import {getFontSize} from "../../../../config/holo/fontSize"; import {getFontSize} from "../../../../config/holo/fontSize";
import msgCard from "../../../../components/Standard/msg-card.vue"; import msgCard from "../../../../components/Standard/msg-card.vue";
import {getKeyCross} from "@/dao/optApi"; import {getKeyCross} from "@/dao/optApi";
import {noDataTitle} from "@/utils/chartStyle";
let timer = null; let timer = null;
...@@ -29,7 +30,14 @@ export default { ...@@ -29,7 +30,14 @@ export default {
}, },
computed:{ computed:{
option(){ option(){
let title = {
show: false
}
if(!this.xData.length){
title = noDataTitle
}
return { return {
title,
dataZoom: { dataZoom: {
type: "inside", type: "inside",
startValue: Object.keys(this.chartResult).length - 6, startValue: Object.keys(this.chartResult).length - 6,
......
...@@ -182,9 +182,7 @@ export default { ...@@ -182,9 +182,7 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
@import url("../../../../assets/less/elementTable.less"); @import url("../../../../assets/less/elementTable.less");
.s_input {
margin-bottom: 15px;
}
::v-deep .el-input-group__prepend { ::v-deep .el-input-group__prepend {
background-color: transparent; background-color: transparent;
...@@ -199,9 +197,9 @@ export default { ...@@ -199,9 +197,9 @@ export default {
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
} }
//::v-deep .el-table__body tr.current-row>td.el-table__cell, .el-table__body tr.selection-row>td.el-table__cell { .s_input {
// background-color: #04386e; margin-bottom: 15px;
//} }
.msg_card_inner { .msg_card_inner {
height: 100%; height: 100%;
display: flex; display: flex;
......
...@@ -321,6 +321,11 @@ export default { ...@@ -321,6 +321,11 @@ export default {
stopTimesList: '非协调停车次数', stopTimesList: '非协调停车次数',
twoStopRateList: '非协调二次停车率(%)' twoStopRateList: '非协调二次停车率(%)'
} }
let colors = {
queueList: '#00933a',
stopTimesList: '#ff8200',
twoStopRateList: '#ffd145'
};
let seriesData = [] let seriesData = []
let xData = [] let xData = []
if(targetCrossData){ if(targetCrossData){
...@@ -339,7 +344,29 @@ export default { ...@@ -339,7 +344,29 @@ export default {
data: targetCrossData[key].map(item => { data: targetCrossData[key].map(item => {
return item.value return item.value
}), }),
yAxisIndex: indexes[key].includes('') ? 1 : 0 itemStyle:{
color: colors[key]
},
yAxisIndex: indexes[key].includes('') ? 1 : 0,
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: "rgba(62, 170, 247, 0)", // 100% 处的颜色
},
{
offset: 1,
color: colors[key] , // 0% 处的颜色
},
],
false
),
},
} }
) )
} }
...@@ -347,6 +374,11 @@ export default { ...@@ -347,6 +374,11 @@ export default {
} }
} }
return { return {
dataZoom: {
type: "inside",
startValue: xData.length - 6,
endValue: xData.length - 1,
},
tooltip: { tooltip: {
trigger: 'axis' trigger: 'axis'
}, },
...@@ -822,6 +854,9 @@ export default { ...@@ -822,6 +854,9 @@ export default {
width: 70px; width: 70px;
text-align: right; text-align: right;
} }
label{
margin-bottom: 0;
}
.custom-form-input{ .custom-form-input{
width: 150px width: 150px
} }
......
...@@ -286,7 +286,8 @@ export default { ...@@ -286,7 +286,8 @@ export default {
objData[item.scopeName].push(item.value || 0); objData[item.scopeName].push(item.value || 0);
}); });
const seriesData = []; const seriesData = [];
legendData.forEach((item) => { let colors = ['#00933a','#ff8200','#c0cfc5','#3e5df5','#ffd145']
legendData.forEach((item,index) => {
seriesData.push({ seriesData.push({
yAxisIndex: 0, yAxisIndex: 0,
name: item, name: item,
...@@ -296,13 +297,34 @@ export default { ...@@ -296,13 +297,34 @@ export default {
showSymbol: false, showSymbol: false,
lineStyle: { lineStyle: {
width: 2, width: 2,
color: colors[index]
// color: obj[item].color, // color: obj[item].color,
}, },
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: "rgba(62, 170, 247, 0)", // 100% 处的颜色
},
{
offset: 1,
color: colors[index] , // 0% 处的颜色
},
],
false
),
},
data: objData[item], data: objData[item],
}); });
}); });
let myChart = echarts.init(this.$refs.chartLine); let myChart = echarts.init(this.$refs.chartLine);
let option = { let option = {
color: colors,
// color: colorList, // color: colorList,
legend: { legend: {
right: 0, right: 0,
...@@ -320,9 +342,9 @@ export default { ...@@ -320,9 +342,9 @@ export default {
}, },
tooltip: { tooltip: {
trigger: "axis", trigger: "axis",
formatter: (params) => { // formatter: (params) => {
return `${this.indexModel} : ${params[0].value}`; // return `${this.indexModel} : ${params[0].value}`;
}, // },
// axisPointer: { // axisPointer: {
// type: "cross", // type: "cross",
// }, // },
......
...@@ -40,13 +40,51 @@ export default { ...@@ -40,13 +40,51 @@ export default {
xAxisIndex: 0, xAxisIndex: 0,
itemStyle:{ itemStyle:{
color:'#178fff', color:'#178fff',
} },
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: "rgba(62, 170, 247, 0)", // 100% 处的颜色
},
{
offset: 1,
color: 'rgba(23, 143, 255,0.7)' , // 0% 处的颜色
},
],
false
),
},
}, { }, {
smooth: true, smooth: true,
symbol:'none', symbol:'none',
itemStyle:{ itemStyle:{
color:'#ff8101', color:'#ff8101',
}, },
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: "rgba(62, 170, 247, 0)", // 100% 处的颜色
},
{
offset: 1,
color: 'rgba(255, 129, 1,0.7)' , // 0% 处的颜色
},
],
false
),
},
name: '对比时段', name: '对比时段',
type: 'line', type: 'line',
data: seriesData1, data: seriesData1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment