TransFlow/src/components/sensorFusion/echartsLine.vue

643 lines
28 KiB
Vue

<template>
<div :id="echartsRef" ref="echartsLine"></div>
</template>
<script>
import { getNameFromTargetType } from '@/utils/targetType';
export default {
name: 'echartsLine', //折线图组件
props: {
itemData: {
type: Object,
default() {
return {};
}
},
intersectionName: {
type: Array,
default() {
return [];
}
},
chatShowType: {
type: String
},
echartsRef: {
type: String
},
//时间模式
timeMode: {
type: String
},
componentType: {
type: String
}, //组件类型
dataList: {
type: Array,
default() {
return [];
}
}, //表格数据
flowType: {
type: String
} //流量类型
},
data() {
return {
chart: null,
chartData: {
yData: [],
xData: []
}, //表格数据
seriesList: [], //类型数组
typeData: [],
title: '',
num: 1
};
},
created() {},
methods: {
//传值对应字段返回相应字段数组
extractKeyValues(arr, key) {
return arr.map((item) => {
if (key == 'speed' && item[key]) {
return Math.abs(item[key]);
}
if ((key == 'ave_headway' || key == 'headway') && item[key]) {
if (item[key] == -1) {
return '-';
}
}
return item[key];
});
},
//过滤重复的 time 字段,保留每个 time 最后一个对象
filteredArrayFun(originalArray, targetTime) {
// 过滤重复的 time 字段
let uniqueArray = originalArray.reduce((accumulator, currentValue) => {
const existingItemIndex = accumulator.findIndex((item) => item.time === currentValue.time);
if (existingItemIndex === -1) {
accumulator.push(currentValue);
}
return accumulator;
}, []);
// 确保 targetTime 是有效的日期字符串
const targetDate = targetTime ? new Date(targetTime) : null;
// 过滤比目标时间小的对象
if (targetDate) {
uniqueArray = uniqueArray.filter((item) => new Date(item.time) > targetDate);
}
// 按照时间从小到大排序
const sortedArray = uniqueArray.sort((a, b) => {
const dateA = new Date(a.time);
const dateB = new Date(b.time);
return dateA - dateB;
});
return sortedArray;
},
//数据判断处理
dataProcessing(val) {
if (val && val.length > 10) {
val = val.slice(-10);
// this.typeData = this.typeData.slice(-10);
}
if (val != null) {
let xData = [],
yData = [];
let targetTime = '';
if (this.chartData.xData.length > 0) {
targetTime = this.chartData.xData[this.chartData.xData.length - 1];
}
if (this.componentType != '类型') {
//类型种类特殊不能去除时间重复项,不走下面去重逻辑
val = this.filteredArrayFun(val, targetTime);
}
if (this.timeMode == '实时触发') {
if (this.componentType == '车头时距') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'headway');
} else if (this.componentType == '流量') {
if (this.flowType == '入流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'in_flow');
} else if (this.flowType == '出流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'out_flow');
}
} else if (this.componentType == '速度') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'speed');
} else if (this.componentType == '类型') {
// console.log('实时触发-类型-', val);
xData = this.extractKeyValues(val, 'time');
let seriesArr = this.extractKeyValues(val, 'type_data');
const transformedData = [];
if (seriesArr && seriesArr.length > 0) {
const firstLevel = seriesArr.find((i) => i && i.length > 0);
if (firstLevel && firstLevel.length > 0) {
for (let i = 0; i < firstLevel.length; i++) {
const item = firstLevel[i];
if (item) {
const valueList = seriesArr.map((arr) => {
if (arr) {
let t = arr[i] && arr[i].value;
if (arr[i] && (arr[i].quantity || arr[i].quantity === 0)) {
t = arr[i].quantity;
}
return t;
}
return 0;
});
transformedData.push({
name: getNameFromTargetType(item.name),
value: valueList
});
}
}
}
}
let totalCountList = 0;
if (transformedData.length > 0 && transformedData[0].value) {
totalCountList = transformedData[0].value.map((_, i) => {
return transformedData.reduce((sum, curr) => sum + curr.value[i], 0);
});
}
transformedData.push({
name: '总数',
value: totalCountList
});
this.seriesList = this.seriesList.concat(transformedData).slice(-10);
} else if (this.componentType == '检测数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'n_stay');
} else if (this.componentType == '排队数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'n_queue');
}
} else if (this.timeMode == '固定时刻') {
if (this.componentType == '车头时距') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'headway');
} else if (this.componentType == '流量') {
if (this.flowType == '入流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'in_flow');
} else if (this.flowType == '出流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'out_flow');
}
} else if (this.componentType == '速度') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'speed');
} else if (this.componentType == '类型') {
// this.chartData.xData = this.extractKeyValues(val, 'time');
xData = this.extractKeyValues(val, 'time');
let seriesArr = this.extractKeyValues(val, 'type_data');
// console.log('seriesArr-固定时刻', seriesArr);
const transformedData = [];
if (seriesArr && seriesArr.length > 0) {
const firstLevel = seriesArr.find((i) => i && i.length > 0);
if (firstLevel && firstLevel.length > 0) {
for (let i = 0; i < firstLevel.length; i++) {
const item = firstLevel[i];
if (item) {
const valueList = seriesArr.map((arr) => {
if (arr) {
let t = arr[i] && arr[i].value;
if (arr[i] && (arr[i].quantity || arr[i].quantity === 0)) {
t = arr[i].quantity;
}
return t;
}
return 0;
});
transformedData.push({
name: getNameFromTargetType(item.name),
value: valueList
});
}
}
}
}
// console.log('transformedData-1',transformedData)
let totalCountList = 0;
if (transformedData.length > 0 && transformedData[0].value) {
totalCountList = transformedData[0].value.map((_, i) => {
return transformedData.reduce((sum, curr) => sum + curr.value[i], 0);
});
}
transformedData.push({
name: '总数',
value: totalCountList
});
this.seriesList = this.seriesList.concat(transformedData).slice(-10);
} else if (this.componentType == '检测数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'n_stay');
} else if (this.componentType == '排队数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'n_queue');
}
} else if (this.timeMode == '固定间隔') {
if (this.componentType == '车头时距') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'ave_headway');
} else if (this.componentType == '流量') {
if (this.flowType == '入流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'in_flow');
} else if (this.flowType == '出流') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'out_flow');
}
} else if (this.componentType == '速度') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'speed');
} else if (this.componentType == '类型') {
xData = this.extractKeyValues(val, 'time');
// console.log('固定间隔-类型-val-', val);
let seriesArr = this.extractKeyValues(val, 'type_data');
// console.log('固定间隔-类型-seriesArr-', seriesArr);
// console.log('固定间隔-类型-xData-', this.chartData.xData);
const transformedData = [];
if (seriesArr && seriesArr.length > 0) {
const firstLevel = seriesArr.find((i) => i && i.length > 0);
if (firstLevel && firstLevel.length > 0) {
for (let i = 0; i < firstLevel.length; i++) {
const item = firstLevel[i];
if (item) {
const valueList = seriesArr.map((arr) => {
if (arr) {
let t = arr[i] && arr[i].value;
if (arr[i] && (arr[i].quantity || arr[i].quantity === 0)) {
t = arr[i].quantity;
}
return t;
}
return 0;
});
transformedData.push({
name: getNameFromTargetType(item.name),
value: valueList
});
}
}
}
}
// console.log('固定间隔-类型-transformedData-1', transformedData);
let totalCountList = 0;
if (transformedData.length > 0 && transformedData[0].value) {
totalCountList = transformedData[0].value.map((_, i) => {
return transformedData.reduce((sum, curr) => sum + curr.value[i], 0);
});
}
transformedData.push({
name: '总数',
value: totalCountList
});
this.seriesList = this.seriesList.concat(transformedData).slice(-10);
// console.log('固定间隔-类型-transformedData-2', transformedData);
} else if (this.componentType == '延误') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'ave_delay');
} else if (this.componentType == '检测数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'ave_stay');
} else if (this.componentType == '排队数') {
xData = this.extractKeyValues(val, 'time');
yData = this.extractKeyValues(val, 'ave_queue');
}
}
this.chartData.xData = this.chartData.xData.concat(xData).slice(-10);
if (this.componentType != '类型') {
//类型是特殊的不走这边处理
this.chartData.yData = this.chartData.yData.concat(yData).slice(-10);
}
} else {
return false;
}
},
//初始化表格
initEcharts() {
if (this.componentType == '流量') {
this.title = '辆';
if (this.timeMode != '实时触发') {
this.title = `辆/${this.itemData.cycleInterval}${this.itemData.unit}`;
}
} else if (this.componentType == '速度') {
if (this.dataList.length > 0) {
// console.log(this.dataList[0].originalSpeed,'速度速度速度速度')
if (this.dataList[0].originalSpeed && this.dataList[0].originalSpeed >= 0) {
this.title = 'km/h';
} else {
this.title = 'pix/s';
}
}
} else if (this.componentType == '排队数') {
this.title = '辆';
if (this.timeMode != '实时触发') {
this.title = `辆/${this.itemData.cycleInterval}${this.itemData.unit}`;
}
} else if (this.componentType == '检测数') {
this.title = '辆';
if (this.timeMode != '实时触发') {
this.title = `辆/${this.itemData.cycleInterval}${this.itemData.unit}`;
}
} else if (this.componentType == '延误') {
this.title = '秒';
} else if (this.componentType == '拥堵') {
this.title = '秒';
} else if (this.componentType == '车头时距') {
this.title = '秒';
} else {
this.title = '';
}
// let slicedData = [];
// if (data != undefined && data.length > 5) {
// slicedData =data.slice(-5); // 保留最后的 10 条数据
// } else {
// slicedData = data; // 如果数据不足 10 条,则保留全部数据
// }
if (this.componentType == '类型') {
// console.log('类型-dataList', this.dataList);
if (this.dataList.length > 0 && this.num == 1) {
// this.typeData.push({ type_data: this.dataList[0].type_data, time: this.dataList[0].time });
this.dataList.sort((a, b) => {
const timeA = new Date(a.time);
const timeB = new Date(b.time);
return timeA - timeB;
});
for (const item of this.dataList) {
this.typeData.push({ type_data: item.type_data, time: item.time });
}
this.num++;
} else {
this.typeData.push({ type_data: this.dataList[0].type_data, time: this.dataList[0].time });
}
// console.log('类型-typeData', this.typeData);
this.dataProcessing(this.typeData);
} else {
this.dataProcessing(this.dataList);
}
// let myChart = this.$echarts.getInstanceByDom(document.getElementById(this.echartsRef));
// if (myChart == null) {
// myChart = this.$echarts.init(document.getElementById(this.echartsRef));
// }
let myChart = this.chart;
// let myChart = this.$echarts.init(document.getElementById('echartsLine'));
var seriesList = [];
var color = ['#0CD2E6', '#3751E6', '#FFC722', 'rgb(255,115,38)'];
if (this.componentType == '类型') {
// console.log('类型-seriesList', this.seriesList);
if (this.seriesList.length > 0) {
for (let i = 0; i < this.seriesList.length; i++) {
seriesList.push({
name: this.seriesList[i].name,
type: 'line',
data: this.seriesList[i].value,
symbolSize: 8, //标记的大小
lineStyle: {
color: color[i],
width: 3,
shadowColor: 'rgba(255,115,38,0.17)', //设置折线阴影
shadowBlur: 5,
shadowOffsetY: 9
},
itemStyle: {
//折线拐点标志的样式
color: color[i],
borderColor: color[i],
borderWidth: 2
},
smooth: 0.4,
emphasis: {
scale: 1.5
}
});
}
}
} else {
seriesList = [
{
// name: '流量_1-zone2-曲线图-实时触发',
type: 'line',
// data: this.chartData.yData.reverse(),
data: this.chartData.yData,
symbolSize: 8, //标记的大小
lineStyle: {
color: 'rgb(255,115,38)',
width: 3,
shadowColor: 'rgba(255,115,38,0.17)', //设置折线阴影
shadowBlur: 5,
shadowOffsetY: 9
},
itemStyle: {
//折线拐点标志的样式
color: 'rgb(255,115,38)',
borderColor: 'rgb(255,115,38)',
borderWidth: 2
},
smooth: 0.4,
emphasis: {
scale: 1.5
}
}
];
}
let option = {
grid: {
top: '25%',
left: '5%',
right: '5%',
bottom: '8%',
containLabel: true
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(1, 13, 19, 0.5)',
borderWidth: 1,
axisPointer: {
type: 'shadow'
// label: {
// show: true,
// },
},
textStyle: {
color: 'rgba(212, 232, 254, 1)'
// fontSize: fontChart(0.24),
},
extraCssText: 'z-index:2'
},
legend: {
// 图例过多时滚动
type: 'scroll',
left: 'center',
top: 0,
left: '10%',
// itemWidth: 15,
// itemHeight: 10,
// itemGap: 15,
// borderRadius: 4,
textStyle: {
color: '#000',
fontSize: 14,
fontWeight: 400
}
// data: [
// {
// name: '流量_1-zone2-曲线图-实时触发',
// icon: 'circle'
// }
// ]
},
xAxis: {
type: 'category',
// data: this.chartData.xData.reverse(),
data: this.chartData.xData,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#393939' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: this.title,
nameTextStyle: {
color: '#000',
fontFamily: 'Alibaba PuHuiTi',
fontSize: 14,
fontWeight: 600
// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离
},
nameGap: 30, // 表现为上下位置
axisLine: {
show: true,
lineStyle: {
color: '#eeeeee'
}
},
axisTick: {
show: false
},
axisLabel: {
color: '#393939',
fontSize: 14
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(131,101,101,0.2)',
type: 'dashed'
}
}
}
],
series: seriesList
};
if (myChart) {
myChart.setOption(option);
window.onresize = () => {
myChart.resize();
};
}
}
},
mounted() {
let that = this;
const $dom = document.getElementById(this.echartsRef);
$dom.style.width = '440px';
$dom.style.height = '260px';
setTimeout(() => {
this.chart = this.$echarts.getInstanceByDom(document.getElementById(this.echartsRef));
if (this.chart == null) {
this.chart = this.$echarts.init(document.getElementById(this.echartsRef));
}
that.$nextTick(() => {
that.initEcharts();
});
}, 300);
},
watch: {
intersectionName: {
handler: function (oldValues, newValues) {
this.$nextTick(() => {
this.initEcharts();
});
}
},
chatShowType: {
handler: function (oldValues, newValues) {}
},
componentType: {
handler: function (oldValues, newValues) {}
},
dataList: {
handler: function (oldValues, newValues) {
this.$nextTick(() => {
this.chart = this.$echarts.getInstanceByDom(document.getElementById(this.echartsRef));
if (this.chart == null) {
this.chart = this.$echarts.init(document.getElementById(this.echartsRef));
}
this.initEcharts();
});
}
},
echartsRef: {
handler: function (oldValues, newValues) {
// console.log('old', oldValues);
// console.log('newV', newValues);
let that = this;
setTimeout(() => {
that.$nextTick(() => {
this.chart = this.$echarts.getInstanceByDom(document.getElementById(this.echartsRef));
if (this.chart == null) {
this.chart = this.$echarts.init(document.getElementById(this.echartsRef));
}
that.initEcharts();
});
}, 300);
}
}
}
};
</script>
<style lang="less" scoped>
#echartsLine {
width: 100%;
height: 100%;
}
</style>