<template>
|
<div class="home-contain">
|
<!-- 左 -->
|
<div class="main-item">
|
<!-- 上 -->
|
<div class="row-1">
|
<card class="card row-1" title="基础资源信息" content-class="base-card">
|
<total-data
|
class="row-item"
|
:type="0"
|
:value="base.stationNum | toLarge"
|
></total-data>
|
<total-data
|
class="row-item"
|
:type="1"
|
:value="base.powerNum | toLarge"
|
></total-data>
|
<total-data
|
class="row-item"
|
:type="2"
|
:value="base.battGroupCount | toLarge"
|
></total-data>
|
<total-data
|
class="row-item"
|
:type="3"
|
:value="base.hrDisNum | toLarge"
|
></total-data>
|
</card>
|
</div>
|
<!-- 中 -->
|
<div class="sub-item row-2">
|
<card class="card" title="站点信息" content-class="station">
|
<template #tools>
|
<el-radio-group
|
size="mini"
|
@input="stationLevelChange"
|
:disabled="!chartData.station.length"
|
v-model="stationLevel"
|
>
|
<el-radio-button :label="0">按电压等级</el-radio-button>
|
<el-radio-button :label="1">按类型</el-radio-button>
|
</el-radio-group>
|
<el-tag class="cur-point mrl8" effect="dark" size="mini" type="success" @click="goToStationInfo">更多>></el-tag>
|
</template>
|
<!-- <bar-chart ref="station"></bar-chart> -->
|
<bar3d3 ref="station"></bar3d3>
|
</card>
|
<card class="card" title="电池信息">
|
<template #tools>
|
<el-radio-group
|
size="mini"
|
:disabled="!chartData.batt.length"
|
@input="battLevelChange"
|
v-model="battLevel"
|
>
|
<el-radio-button :label="0">按品牌</el-radio-button>
|
<el-radio-button :label="1">按电压类型</el-radio-button>
|
</el-radio-group>
|
<el-tag class="cur-point mrl8" effect="dark" size="mini" type="success" @click="goToBattInfo">更多>></el-tag>
|
</template>
|
<!-- <pie-chart ref="battInfo"></pie-chart> -->
|
<pie3d ref="battInfo"></pie3d>
|
</card>
|
</div>
|
<!-- 下 -->
|
<div class="sub-item row-3">
|
<card class="card" title="电源信息">
|
<template #tools>
|
<el-tag class="cur-point mrl8" effect="dark" size="mini" type="success" @click="goToPowerInfo">更多>></el-tag>
|
</template>
|
<!-- <power-chart ref="powerChart"></power-chart> -->
|
<pie3d ref="powerChart" :theme-idx="1"></pie3d>
|
</card>
|
<card class="card" title="测试信息" content-class="test">
|
<template #tools>
|
<el-radio-group
|
size="mini"
|
:disabled="!chartData.test.length"
|
@input="testLevelChange"
|
v-model="testLevel"
|
>
|
<el-radio-button :label="0">本月</el-radio-button>
|
<el-radio-button :label="1">本季度</el-radio-button>
|
<el-radio-button :label="2">本年</el-radio-button>
|
</el-radio-group>
|
</template>
|
<bar3d ref="bar3d"></bar3d>
|
</card>
|
</div>
|
</div>
|
<!-- 右 -->
|
<div class="main-item">
|
<!-- 上 -->
|
<div class="row-1">
|
<card class="card" title="蓄电池优劣分析" content-class="base-card">
|
<batt-card
|
class="row-item"
|
:type="0"
|
:value="batt.groupNum | toLarge"
|
></batt-card>
|
<batt-card
|
class="row-item"
|
:type="1"
|
:value="batt.goodSum | toLarge"
|
></batt-card>
|
<batt-card
|
class="row-item"
|
:type="2"
|
:value="batt.alarmNum | toLarge"
|
></batt-card>
|
<batt-card
|
class="row-item"
|
:type="3"
|
:value="batt.changeNum | toLarge"
|
></batt-card>
|
</card>
|
</div>
|
<!-- 中 -->
|
<div class="row-2">
|
<card class="card" title="同一投运时间不同品牌电池性能分析">
|
<template #tools>
|
<el-tag class="cur-point mrl8" effect="dark" size="mini" type="success" @click="goToBattInfo">更多>></el-tag>
|
</template>
|
<div class="card-contain">
|
<div class="batt-chart">
|
<div class="pos-full">
|
<batt-chart ref="battChart"></batt-chart>
|
</div>
|
</div>
|
<div class="panel0">
|
<panel title="请选择投运年限">
|
<div class="content">
|
<el-select
|
v-model="year0"
|
@change="year0Change"
|
:disabled="!chartData.analysis.length"
|
size="mini"
|
>
|
<el-option
|
v-for="(item, idx) in years"
|
:key="'year0_' + idx"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
<div class="wrap">
|
<!-- 损坏数量最多品牌 -->
|
<div class="batt-data break">
|
<div class="label">损坏数量<br />最多品牌</div>
|
<div class="value" v-if="listChange.length <= 1">
|
{{ changeProd }}
|
</div>
|
<el-tooltip
|
class="item"
|
v-else
|
effect="dark"
|
content="changeProd1"
|
placement="top-end"
|
>
|
<div class="value">{{ changeProd }}</div>
|
</el-tooltip>
|
</div>
|
<!-- 劣化数量最多品牌 -->
|
<div class="batt-data">
|
<div class="label">劣化数量<br />最多品牌</div>
|
<div class="value" v-if="listAlarm.length <= 1">
|
{{ alarmProd }}
|
</div>
|
<el-tooltip
|
class="item"
|
effect="dark"
|
v-else
|
content="alarmProd1"
|
placement="top-end"
|
>
|
<div class="value">{{ alarmProd }}</div>
|
</el-tooltip>
|
</div>
|
</div>
|
</div>
|
</panel>
|
</div>
|
</div>
|
</card>
|
</div>
|
<!-- 下 -->
|
<div class="row-3">
|
<card class="card" title="同一投运时间相同品牌电池性能分析">
|
<template #tools>
|
<el-tag class="cur-point mrl8" effect="dark" size="mini" type="success" @click="goToBattInfo">更多>></el-tag>
|
</template>
|
<div class="card-contain">
|
<div class="chart">
|
<div class="pos-full inner">
|
<!-- <bar-chart ref="analysis1" :bar-width="80"></bar-chart> -->
|
<bar3d2 ref="analysis1"></bar3d2>
|
</div>
|
</div>
|
<!-- 中 -->
|
<div class="selector">
|
<panel class="big" title="请选择投运年限">
|
<div class="content">
|
<el-select
|
v-model="year1"
|
@change="updateAnalysis1"
|
:disabled="!chartData.analysis1.length"
|
size="mini"
|
>
|
<el-option
|
v-for="(item, idx) in years"
|
:key="'year1_' + idx"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
</div>
|
</panel>
|
<panel class="small" title="请选择电池品牌">
|
<div class="content">
|
<el-select
|
v-model="battProd"
|
@change="updateAnalysis1"
|
:disabled="!prodList.length"
|
size="mini"
|
>
|
<el-option
|
v-for="(item, idx) in prodList"
|
:key="'prod_' + idx"
|
:label="item"
|
:value="item"
|
>
|
</el-option>
|
</el-select>
|
</div>
|
</panel>
|
</div>
|
<!-- 右 -->
|
<div class="card-info">
|
<div class="item">
|
<div class="icon break"></div>
|
<div class="info">损坏数量: {{ changeCount }}</div>
|
</div>
|
<div class="item">
|
<div class="icon bad"></div>
|
<div class="info">劣化数量: {{ alarmCount }}</div>
|
</div>
|
</div>
|
</div>
|
</card>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import Card from "@/components/bigScreenPage/big_screen_card";
|
import totalData from "./components/total-data";
|
import battCard from "./components/batt-card";
|
import barChart from "./components/bar-chart";
|
import pieChart from "./components/pie-chart";
|
import pie3d from "./components/pie3d";
|
import panel from "./components/panel";
|
import bar3d from "./components/bar-3d";
|
import bar3d3 from "./components/bar-3d3";
|
import bar3d2 from "./components/bar-3d2";
|
import powerChart from "./components/power-chart";
|
import battChart from "./components/batt-chart";
|
|
import noRepeat from "@/assets/js/tools/noRepeat";
|
|
import createWs from "@/assets/js/websocket";
|
const WSMixin = createWs("homeAdmin");
|
|
export default {
|
name: "",
|
mixins: [WSMixin],
|
data() {
|
return {
|
updateFlag: false,
|
years: [
|
{
|
value: 0,
|
label: "一年以内",
|
},
|
{
|
value: 1,
|
label: "两年以内",
|
},
|
{
|
value: 2,
|
label: "三年以内",
|
},
|
],
|
stationLevel: 0,
|
battLevel: 0,
|
testLevel: 0,
|
changeCount: "--",
|
alarmCount: "--",
|
year0: 0,
|
year1: 0,
|
base: {
|
stationNum: 0,
|
powerNum: 0,
|
battGroupCount: 0,
|
hrDisNum: 0,
|
},
|
batt: {
|
groupNum: 0,
|
goodSum: 0,
|
alarmNum: 0,
|
changeNum: 0,
|
},
|
battProd: "",
|
prodList: [],
|
chartData: {
|
station: [],
|
batt: [],
|
test: [],
|
analysis: [],
|
analysis1: [],
|
},
|
listChange: [],
|
listAlarm: [],
|
};
|
},
|
components: {
|
Card,
|
totalData,
|
battCard,
|
barChart,
|
panel,
|
pieChart,
|
pie3d,
|
bar3d,
|
bar3d3,
|
bar3d2,
|
powerChart,
|
battChart,
|
},
|
computed: {
|
changeProd() {
|
if (1 == this.listChange.length) {
|
return this.listChange[0];
|
} else if (this.listChange.length > 1) {
|
return this.listChange[0] + " 等";
|
} else {
|
return "无";
|
}
|
},
|
alarmProd() {
|
if (1 == this.listAlarm.length) {
|
return this.listAlarm[0];
|
} else if (this.listAlarm.length > 1) {
|
return this.listAlarm[0] + " 等";
|
} else {
|
return "无";
|
}
|
},
|
changeProd1() {
|
if (this.listChange.length > 1) {
|
return this.listChange.join("、");
|
} else {
|
return "";
|
}
|
},
|
alarmProd1() {
|
if (this.listAlarm.length > 1) {
|
return this.listAlarm.join("、");
|
} else {
|
return "";
|
}
|
},
|
},
|
filters: {
|
toLarge(input) {
|
if (undefined == input) {
|
return "";
|
} else {
|
if (input > 999) {
|
return "999+";
|
} else {
|
return input;
|
}
|
}
|
},
|
},
|
methods: {
|
goToStationInfo() {
|
this.$router.push("/dataMager/totalStation");
|
},
|
goToBattInfo() {
|
this.$router.push("/dataMager/produceTotal");
|
},
|
goToPowerInfo() {
|
this.$router.push("/dataMager/powerMager");
|
},
|
onWSMessage(res) {
|
res = JSON.parse(res.data);
|
console.log(res, "=====111data");
|
let { resGroupAnalysis, resBattInfoAnalysis } = res.data;
|
this.base = resBattInfoAnalysis.data2;
|
this.batt = resGroupAnalysis.data2;
|
this.updateCharts(res.data);
|
},
|
updateCharts(data) {
|
let {
|
resStationAnalysis: {
|
data2: { node, stationType },
|
},
|
resProductQuaAnalysis: {
|
data: { oneYear, twoYear, threeYear },
|
},
|
resPwrdevInfAnalysis: { data2: power },
|
battGroupInfo: {
|
data2: { monVol, producer },
|
},
|
resTestdataInfAnalysis: {
|
data2: { month, year, quarter },
|
},
|
} = data;
|
let station = [];
|
[stationType, node].forEach((item, idx) => {
|
let res = {
|
xLabel: [],
|
sData: [],
|
colorList: [
|
["#d3c209", "#e29300"],
|
["#02ddff", "#0082ff"],
|
],
|
};
|
Object.keys(item).forEach((v) => {
|
if (0 == idx) {
|
if (0 != v) {
|
res.xLabel.push(v);
|
res.sData.push(item[v]);
|
}
|
} else {
|
res.xLabel.push(["非节点站", "节点站"][v]);
|
res.sData.push(item[v]);
|
}
|
});
|
station.push(res);
|
});
|
this.chartData.station = station;
|
// 站点
|
this.$refs.station.setData(station[this.stationLevel]);
|
|
let batt = [];
|
[producer, monVol].forEach((item, idx) => {
|
batt.push(this.formatBattData(item, idx));
|
});
|
this.chartData.batt = batt;
|
// 电池
|
this.$refs.battInfo.setData(batt[this.battLevel]);
|
|
let powerChart = (() => {
|
let res = { sData: [] };
|
|
let arr = Object.keys(power)
|
.map((v) => ({ name: v, value: power[v] }))
|
.sort((a, b) => {
|
return b.value - a.value;
|
});
|
if (arr.length <= 5) {
|
res.sData = arr;
|
} else {
|
let name = "其他";
|
let value = 0;
|
arr.splice(4).forEach((v) => {
|
value += v.value * 1;
|
});
|
res.sData = arr;
|
res.sData.push({ name, value });
|
}
|
return res;
|
})();
|
// 电源
|
this.$refs.powerChart.setData(powerChart);
|
|
let test = [];
|
[month, quarter, year].forEach((item) => {
|
// test.push({
|
// xLabel: ["核容放电", "核容充电", "监测放电", "监测充电"],
|
// sData: [item.hrdisNum, item.hrchNum, item.jcdisNum, item.jcchNum],
|
// });
|
test.push({
|
xLabel: ["核容放电", "核容充电"],
|
sData: [item.hrdisNum, item.hrchNum],
|
});
|
});
|
this.chartData.test = test;
|
// 测试
|
this.$refs.bar3d.setData(test[this.testLevel]);
|
|
let analysis = [],
|
analysis1 = [];
|
let prodList = [];
|
[oneYear, twoYear, threeYear].forEach((item) => {
|
analysis.push(this.formatTestData(item));
|
analysis1.push(Object.keys(item).map((v) => ({ name: v, ...item[v] })));
|
prodList.push(...Object.keys(item));
|
});
|
|
this.chartData.analysis = analysis;
|
this.chartData.analysis1 = analysis1;
|
this.prodList = noRepeat(prodList);
|
if (!this.battProd) {
|
this.battProd = this.prodList[0] || "";
|
this.updateAnalysis1();
|
}
|
// this.battProd = this.prodList[0] || '';
|
// 性能1
|
this.$refs.battChart.setData(analysis[this.year0]);
|
this.year0Change(this.year0);
|
|
let { getTestData, year1, battProd } = this;
|
// 性能2
|
this.$refs.analysis1.setData(getTestData(year1, battProd));
|
if (!this.updateFlag) {
|
this.updateFlag = true;
|
this.resizeChart();
|
}
|
},
|
resizeChart() {
|
this.$refs.station?.resize();
|
this.$refs.battInfo?.resize();
|
this.$refs.powerChart?.resize();
|
this.$refs.bar3d?.resize();
|
this.$refs.battChart?.resize();
|
this.$refs.analysis1?.resize();
|
},
|
formatTestData(data) {
|
let sData = [[], []];
|
let xLabel = [];
|
let arr = Object.keys(data)
|
.map((v) => ({ name: v, ...data[v] }))
|
.sort((a, b) => {
|
if (a.change != b.change) {
|
return b.change - a.change;
|
} else {
|
return b.alarm - a.alarm;
|
}
|
});
|
if (arr.length <= 5) {
|
arr.forEach((v) => {
|
sData[0].push(v.alarm);
|
sData[1].push(v.change);
|
xLabel.push(v.name);
|
});
|
} else {
|
let label = "其他";
|
let alarm = 0,
|
change = 0;
|
arr.splice(4).forEach((v) => {
|
alarm += v.alarm * 1;
|
change += v.change * 1;
|
});
|
arr.forEach((v) => {
|
sData[0].push(v.alarm);
|
sData[1].push(v.change);
|
xLabel.push(v.name);
|
});
|
xLabel.push(label);
|
sData[0].push(alarm);
|
sData[1].push(change);
|
}
|
return { xLabel, sData };
|
},
|
formatBattData(data, idx) {
|
let res = { sData: [] };
|
|
let arr = Object.keys(data)
|
.map((v) => ({ name: idx ? v * 1 + "伏" : v, value: data[v] }))
|
.sort((a, b) => {
|
return b.value - a.value;
|
});
|
if (arr.length <= 5) {
|
res.sData = arr;
|
} else {
|
let name = "其他";
|
let value = 0;
|
arr.splice(4).forEach((v) => {
|
value += v.value * 1;
|
});
|
res.sData = arr;
|
res.sData.push({ name, value });
|
}
|
return res;
|
},
|
getTestData(year, prod) {
|
let data = this.chartData.analysis1;
|
let arr = data[year];
|
let Ores = arr.filter((v) => v.name == prod)[0];
|
return {
|
xLabel: ["劣化", "损坏"],
|
sData: [Ores.alarm, Ores.change],
|
colorList: [
|
["#f8f38d", "#23b5f5"],
|
["#51eab2", "#23b5f5"],
|
],
|
};
|
},
|
// 获取最多损坏 最多劣化
|
getMax(arr) {
|
let OChange = {};
|
let OAlarm = {};
|
arr.forEach((v) => {
|
// 劣化数量 v.alarm
|
OAlarm[v.alarm] = OAlarm[v.alarm] || [];
|
OAlarm[v.alarm].push(v.name);
|
OChange[v.change] = OChange[v.change] || [];
|
OChange[v.change].push(v.name);
|
});
|
// console.log(OChange, OAlarm);
|
// 劣化最多的品牌
|
let listA = [];
|
let listC = [];
|
// 劣化最多的数量
|
let NumA = Object.keys(OAlarm).sort((a, b) => b - a)[0];
|
let NumC = Object.keys(OChange).sort((a, b) => b - a)[0];
|
if (NumA > 0) {
|
listA = OAlarm[NumA];
|
}
|
if (NumC > 0) {
|
listC = OChange[NumC];
|
}
|
return { listA, listC };
|
},
|
stationLevelChange(value) {
|
// console.log('station change', value);
|
this.$refs.station.setData(this.chartData.station[value]);
|
},
|
battLevelChange(value) {
|
this.$refs.battInfo.setData(this.chartData.batt[value]);
|
},
|
testLevelChange(value) {
|
this.$refs.bar3d.setData(this.chartData.test[value]);
|
},
|
year0Change(value) {
|
// console.log(value, 'year0');
|
this.$refs.battChart.setData(this.chartData.analysis[value]);
|
// 更新统计
|
let { listA, listC } = this.getMax(this.chartData.analysis1[value]);
|
this.listChange = listC;
|
this.listAlarm = listA;
|
},
|
updateAnalysis1() {
|
let { getTestData, year1, battProd } = this;
|
let data = getTestData(year1, battProd);
|
// 性能2
|
this.$refs.analysis1.setData(data);
|
// 更新统计
|
let {
|
sData: [alarmCount, changeCount],
|
} = data;
|
this.changeCount = changeCount;
|
this.alarmCount = alarmCount;
|
},
|
},
|
|
mounted() {},
|
};
|
</script>
|
|
<style scoped lang="less">
|
.home-contain {
|
height: 100%;
|
display: flex;
|
padding: 0 8px;
|
}
|
|
.card {
|
flex: 1;
|
}
|
|
.row-1 {
|
height: 270px;
|
}
|
|
/deep/ .base-card {
|
display: flex;
|
flex-direction: row;
|
justify-content: space-around;
|
/* justify-content: space-between; */
|
padding: 0 28px;
|
}
|
|
.row-2,
|
.row-3 {
|
flex: 1.2;
|
}
|
|
.main-item {
|
flex: 1;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.sub-item {
|
display: flex;
|
}
|
|
.pos-full {
|
position: absolute;
|
left: 0;
|
right: 0;
|
top: 0;
|
bottom: 0;
|
}
|
|
.card-contain {
|
height: 100%;
|
padding: 8px;
|
box-sizing: border-box;
|
display: flex;
|
|
.batt-chart,
|
.chart {
|
flex: 1;
|
position: relative;
|
|
.inner {
|
padding: 0 30px 4px;
|
}
|
}
|
|
.panel0 {
|
height: 100%;
|
margin-left: 2em;
|
|
.content {
|
height: 100%;
|
padding: 10px;
|
box-sizing: border-box;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
}
|
|
.batt-data {
|
font-size: 14px;
|
font-weight: bold;
|
color: #00fefe;
|
background: #01354c;
|
border: 1px #016273 solid;
|
border-radius: 6px;
|
display: flex;
|
margin-top: 4px;
|
height: 40px;
|
line-height: 1;
|
|
&.break {
|
color: #f2a23b;
|
}
|
|
.value,
|
.label {
|
flex: 1;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
.value {
|
border-left: 1px #016273 solid;
|
}
|
}
|
}
|
|
.selector {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
margin-left: 1em;
|
|
.big {
|
flex: 1.2;
|
}
|
|
.small {
|
flex: 1;
|
}
|
|
.content {
|
padding: 6px;
|
}
|
}
|
}
|
|
.sub-item .card {
|
flex: 1;
|
|
&:not(:first-child) {
|
margin-left: 10px;
|
}
|
}
|
|
.main-item ~ .main-item {
|
margin-left: 10px;
|
}
|
|
/deep/ .test,
|
/deep/ .station {
|
padding: 0 40px 8px;
|
}
|
|
/deep/ .el-radio-button--mini .el-radio-button__inner {
|
padding: 0.28rem 0.7rem;
|
font-size: 0.6rem;
|
border-radius: 0;
|
border: 0 none;
|
background: #00bbc3;
|
color: #022c44;
|
}
|
|
/deep/ :not(:first-child) > .el-radio-button__inner {
|
border-left: 1px solid #0096a3;
|
}
|
|
/deep/ .el-radio-button__orig-radio:checked + .el-radio-button__inner {
|
box-shadow: none;
|
}
|
|
/deep/ .el-radio-button__orig-radio:checked + .el-radio-button__inner {
|
background-color: #2982f6;
|
color: #fff;
|
}
|
|
.card-info {
|
width: 152px;
|
padding: 4px 0;
|
border: 2px #00fefe solid;
|
margin-left: 0.4em;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-around;
|
|
.item {
|
// flex: 1;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
|
.icon {
|
width: 70px;
|
height: 70px;
|
|
&.bad {
|
background: url("./images/batt_bad.png") center center / contain
|
no-repeat;
|
}
|
|
&.break {
|
background: url("./images/batt_break.png") center center / contain
|
no-repeat;
|
}
|
}
|
|
.info {
|
font-size: 16px;
|
color: #ffff00;
|
font-weight: bold;
|
}
|
}
|
}
|
.cur-point {
|
cursor: pointer;
|
}
|
.mrl8 {
|
margin-left: 8px;
|
}
|
</style>
|