<script setup>
|
import FlexBox from "@/components/FlexBox.vue";
|
import ChartBox from "@/components/chartBox.vue";
|
import HdwChart from "@/components/echarts/hdwChart.vue";
|
import getNormalLine from "@/components/echarts/options/normalLine"
|
import {onMounted, ref} from "vue";
|
import getRadiusBarOption from "@/components/echarts/options/radiusBar";
|
import carInfoModule from "@/views/moudle/battShow/carInfo";
|
import battHistoryModule from "@/views/moudle/battShow/battHistory";
|
import getDataIndex from "@/util/getDataIndex";
|
import getNormalBar from "@/components/echarts/options/getNormalBar";
|
import getMin from "@/components/echarts/options/tools/getMin";
|
import getMax from "@/components/echarts/options/tools/getMax";
|
import getBarNum from "@/components/echarts/options/tools/getBarNum";
|
import * as echarts from 'echarts';
|
|
const carName = ref("");
|
const timeRange = ref("");
|
timeRange.value = [new Date("2020-01-01 00:00:00"), new Date("2023-01-01 00:00:00")];
|
const tempBar = ref(null);
|
const volBar = ref(null);
|
const alarmLine = ref(null);
|
const totalVolLine = ref(null);
|
|
const resize = ()=>{
|
tempBar.value.resize();
|
volBar.value.resize();
|
alarmLine.value.resize();
|
totalVolLine.value.resize();
|
}
|
|
const {carList, getCarNames} = carInfoModule();
|
|
const {
|
getBattHistory
|
} = battHistoryModule();
|
|
let totalData = [];
|
const searchBattHistory = async ()=> {
|
slideVal.value = 0;
|
try {
|
const rs = await getBattHistory(carName.value, timeRange.value);
|
let data = [];
|
if (rs.code !== 0) {
|
data = rs.data;
|
}
|
totalData = data;
|
slideVal.value = 100;
|
let currentDataIndex = getDataIndex(totalData.length, slideVal.value);
|
if(currentDataIndex !== -1 && totalData.length !== 0) {
|
setBarData(totalData[currentDataIndex]);
|
}else {
|
setBarData(-1)
|
}
|
|
setLineData(data);
|
}catch (e) {
|
console.log(e);
|
}
|
}
|
|
const slideVal = ref(100);
|
|
const handleSlideInput = ()=>{
|
let currentDataIndex = getDataIndex(totalData.length, slideVal.value);
|
if(currentDataIndex !== -1 && totalData.length !== 0) {
|
setBarData(totalData[currentDataIndex]);
|
}else {
|
setBarData(-1);
|
}
|
}
|
|
const formatTooltip = (val)=>{
|
let currentDataIndex = getDataIndex(totalData.length, slideVal.value);
|
let rs = val+"";
|
if(currentDataIndex !== -1 && totalData.length !== 0) {
|
let data = totalData[currentDataIndex];
|
return new Date(data.gatherTime).format("yyyy-MM-dd hh:mm:ss");
|
}
|
return rs;
|
}
|
|
const tempBarOption = getNormalBar({
|
grid: {
|
top: '15%',
|
right: '3%',
|
left: '5%',
|
bottom: '6%'
|
}
|
});
|
const volBarOption = getNormalBar({
|
minRatio: 0.999,
|
maxRatio: 1.001,
|
grid: {
|
top: '15%',
|
right: '3%',
|
left: '5%',
|
bottom: '6%'
|
}
|
});
|
const setBarData = (data)=>{
|
tempBarOption.series[0].name = "单体温度";
|
volBarOption.series[0].name = "单体电压";
|
volBarOption.series[0].label.show = false;
|
if(data !== -1) {
|
let tempData = data.monomerTemp.split(",").map((item, key) => {
|
return ["#" + (key + 1), item]
|
});
|
const tempNum = getBarNum(tempData);
|
tempBarOption.option.min = tempNum.min;
|
tempBarOption.option.max = tempNum.max;
|
tempBarOption.title.text = "最大值="+tempNum.max+"℃;最小值="+tempNum.min+"℃;平均值="+tempNum.avg+"℃";
|
tempBarOption.series[0].data = tempData;
|
|
let volData = data.monomerVol.split(",").map((item, key) => {
|
return ["#" + (key + 1), item]
|
});
|
const volNum = getBarNum(volData);
|
volBarOption.option.min = volNum.min;
|
volBarOption.option.max = volNum.max;
|
volBarOption.title.text = "最大值="+volNum.max+"V;最小值="+volNum.min+"V;平均值="+volNum.avg+"V";
|
volBarOption.series[0].type="line";
|
volBarOption.series[0].markPoint= {
|
data: [
|
{
|
type: 'max',
|
name: 'Max',
|
itemStyle: {
|
color: "#FF0000"
|
}
|
},
|
{ type: 'min', name: 'Min' }
|
]
|
};
|
volBarOption.series[0].data = volData;
|
}else {
|
tempBarOption.series[0].data = [];
|
volBarOption.series[0].data = [];
|
}
|
tempBar.value.setOption(tempBarOption);
|
volBar.value.setOption(volBarOption);
|
}
|
|
const alarmLineOption = getNormalLine({
|
minRatio: 1,
|
maxRatio: 1,
|
});
|
const totalVolLineOption = getNormalLine({
|
minRatio: 1,
|
maxRatio: 1,
|
});
|
|
let lineData = {
|
times: [],
|
vol: [],
|
temp: []
|
};
|
|
const setLineData = (data)=>{
|
// 初始化lineData
|
lineData = {
|
times: [],
|
vol: [],
|
temp: []
|
};
|
|
// 遍历数据
|
for(let i=0; i<data.length; i++) {
|
let itemData = data[i];
|
lineData.times.push(new Date(itemData.gatherTime).format("yyyy-MM-dd hh:mm:ss"));
|
// 单体温度
|
itemData.monomerTemp.split(",").map((item, key)=>{
|
if(lineData.temp[key] === undefined) {
|
lineData.temp[key] = [];
|
}
|
lineData.temp[key].push(item);
|
});
|
|
// 单体电压
|
itemData.monomerVol.split(",").map((item, key)=>{
|
if(lineData.vol[key] === undefined) {
|
lineData.vol[key] = [];
|
}
|
lineData.vol[key].push(item);
|
});
|
}
|
|
alarmLineOption.xAxis.data = lineData.times;
|
alarmLineOption.series = lineData.temp.map((item, key)=>{
|
return {
|
name: '#'+(key+1),
|
type: 'line',
|
smooth: false,
|
symbolSize: 0,
|
data: item,
|
}
|
});
|
alarmLine.value.setOption(alarmLineOption);
|
|
totalVolLineOption.xAxis.data = lineData.times;
|
totalVolLineOption.tooltip.formatter = (params)=>{
|
let res = params[0].name + '<br/>';
|
res +='<table>'
|
params.forEach((item,key) => {
|
res += "<td style='padding: 2px'>";
|
res += item.marker;
|
res += item.seriesName;
|
res += ' : ' + item.data + 'V';
|
res += "</td>";
|
if((key+1)%5 === 0) {
|
res += '<tr></tr>';
|
}
|
});
|
res +='<table>'
|
return res;
|
};
|
totalVolLineOption.series = lineData.vol.map((item, key)=>{
|
return {
|
name: '#'+(key+1),
|
type: 'line',
|
smooth: false,
|
symbolSize: 0,
|
data: item,
|
}
|
});
|
totalVolLine.value.setOption(totalVolLineOption);
|
}
|
onMounted(()=>{
|
getCarNames();
|
|
tempBar.value.setOption(tempBarOption);
|
volBar.value.setOption(volBarOption);
|
|
|
alarmLine.value.setOption(alarmLineOption);
|
totalVolLine.value.setOption(totalVolLineOption);
|
|
echarts.connect([
|
alarmLine.value.getChart(),
|
totalVolLine.value.getChart()
|
]);
|
resize();
|
});
|
</script>
|
|
<template>
|
<div class="batt-show-wrapper">
|
<div class="batt-show-layout">
|
<div class="batt-show-header">
|
<div class="input-list">
|
<div class="input-item">
|
<div class="input-wrapper">
|
<div class="input-label">车辆名称:</div>
|
<div class="input-content">
|
<el-select v-model="carName" filterable>
|
<el-option
|
v-for="(item, key) in carList" :key="'key'+key"
|
:value="item.key" :label="item.label"></el-option>
|
</el-select>
|
</div>
|
</div>
|
</div>
|
<div class="input-item">
|
<div class="input-wrapper">
|
<div class="input-label">日期选择:</div>
|
<div class="input-content">
|
<el-date-picker
|
v-model="timeRange"
|
type="datetimerange"
|
start-placeholder="开始时间"
|
end-placeholder="结束时间"
|
format="YYYY-MM-DD HH:mm:ss"
|
date-format="YYYY/MM/DD ddd"
|
time-format="A hh:mm:ss"></el-date-picker>
|
</div>
|
</div>
|
</div>
|
<div class="input-item">
|
<el-button type="primary" @click="searchBattHistory">查询</el-button>
|
</div>
|
</div>
|
</div>
|
<div class="batt-show-body">
|
<div class="batt-chart-list-wrapper">
|
<div class="batt-chart-list-content">
|
<div class="batt-chart-list top">
|
<div class="batt-chart-item left">
|
<flex-box>
|
<div class="flex-box-content">
|
<chart-box title="单体温度">
|
<hdw-chart ref="tempBar"></hdw-chart>
|
</chart-box>
|
</div>
|
</flex-box>
|
</div>
|
<div class="batt-chart-item right">
|
<flex-box>
|
<div class="flex-box-content">
|
<chart-box title="单体电压">
|
<hdw-chart ref="volBar"></hdw-chart>
|
</chart-box>
|
</div>
|
</flex-box>
|
</div>
|
</div>
|
<div class="batt-chart-list bottom">
|
<div class="batt-chart-item left">
|
<flex-box>
|
<div class="flex-box-content">
|
<chart-box title="总单体温度">
|
<hdw-chart ref="alarmLine"></hdw-chart>
|
</chart-box>
|
</div>
|
</flex-box>
|
</div>
|
<div class="batt-chart-item right">
|
<flex-box>
|
<div class="flex-box-content">
|
<chart-box title="总单体电压">
|
<hdw-chart ref="totalVolLine"></hdw-chart>
|
</chart-box>
|
</div>
|
</flex-box>
|
</div>
|
</div>
|
</div>
|
<div class="batt-chart-list-footer">
|
<el-slider
|
v-model="slideVal"
|
:format-tooltip="formatTooltip"
|
:format-value-text="formatTooltip"
|
@input="handleSlideInput"></el-slider>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<style scoped lang="less">
|
.batt-show-wrapper {
|
height: 100%;
|
background: url("@/assets/images/dw_bg.jpg") no-repeat;
|
background-size: 100% 100%;
|
.batt-show-layout {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
.batt-show-header {
|
padding: 8px 8px 4px 8px;
|
}
|
.batt-show-body {
|
flex: 1;
|
padding: 4px 8px 8px 8px;
|
}
|
}
|
}
|
.batt-chart-list-wrapper {
|
display: flex;
|
height: 100%;
|
flex-direction: column;
|
.batt-chart-list-content {
|
flex: 1;
|
.batt-chart-list {
|
display: flex;
|
height: 50%;
|
&.top {
|
padding-bottom: 4px;
|
}
|
&.bottom {
|
padding-top: 4px;
|
}
|
.batt-chart-item {
|
flex:1;
|
&.left {
|
padding-right: 4px;
|
}
|
&.right {
|
padding-left: 4px;
|
}
|
}
|
}
|
}
|
.batt-chart-list-footer {
|
padding: 4px 8px;
|
}
|
}
|
.flex-box-content {
|
height: 100%;
|
padding: 8px 0 8px 8px;
|
}
|
.input-list {
|
.input-item {
|
display: inline-block;
|
margin-left: 8px;
|
}
|
}
|
.input-wrapper {
|
display: flex;
|
.input-content {
|
min-width: 160px;
|
vertical-align: middle;
|
}
|
.input-label {
|
display: inline-block;
|
line-height: 32px;
|
color: #fff;
|
font-size: 14px;
|
margin-right: 8px;
|
vertical-align: middle;
|
}
|
}
|
</style>
|