Files
sk_fems_ui/pages/ems/effc/EnrgUseTotSummPage.vue

738 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div ref="mainDiv" class="l-layout">
<CommonPageTitle />
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
:labelCols="12"
:textCols="12"
:iconShow="true"
:customClass="'select-large'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'DatePicker'"
:label="'대상연월'"
:parentPrgmId="myPrgmId"
:customClass="'datepicker-large'"
/>
</v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3" class="text-right">
<!-- <v-btn v-show="false" :ripple="false" @click="test()">TEST</v-btn> -->
<!-- <v-btn :ripple="false" @click="search()">조회</v-btn> -->
<a-button
style="margin-top: 25px; height: 40px"
icon="search"
class="search-button"
type="primary"
@click="search"
>조회</a-button
>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="overflow: auto">
<v-col>
<div v-for="(value, key, index) in contentData" :key="'key1_' + index">
<v-card-title class="d-flex align-center justify-space-between pa-3">
<span class="tit ft-size_20 ft-weight_600">{{ value.eqpmGrpNm }}</span>
</v-card-title>
<v-row>
<v-col :cols="3" v-for="(item, i) in value.chartData" :key="'key2_' + i">
<v-card>
<div
class="v-box"
style="height: 330px; position: relative"
:ref="item.eqpmGrpId + '_' + item.fabId"
@click="chartClickEvent(item, $event)"
>
<!-- Card border at the top of the title -->
<div
style="
position: absolute;
left: 0;
top: 10px;
width: 4px;
height: 50px;
background-color: #91caff;
border-radius: 2px;
"
></div>
<!-- Information area -->
<v-col :cols="5" style="height: 100%">
<div style="height: 10%">
<strong class="v-card v-card__title pa-0" >{{
item.fabNm
}}</strong>
</div>
<div style="height: 25%"></div>
<div style="height: 50%; text-align: center">
<v-row>
<!-- <v-col :cols="1"> </v-col> -->
일에너지:
</v-row>
<v-row>
<v-col :cols="12" style="text-align: left">
<span class="textInfo">
{{ item.dayVal }}
</span>
<span class="textDetail">MWh</span>
</v-col>
<!-- <v-col :cols="4" style="text-align: left"> MWh </v-col> -->
<!-- <v-col :cols="1"> </v-col> -->
</v-row>
<v-row style="margin-top: 20px">
<!-- <v-col :cols="1"> </v-col> -->
월에너지:
</v-row>
<v-row>
<v-col :cols="12" style="text-align: left">
<span class="textInfo">{{ item.mnthVal }}</span>
<span class="textDetail">MWh</span>
</v-col>
<!-- <v-col :cols="4" style="text-align: left"> MWh </v-col> -->
<!-- <v-col :cols="1"> </v-col> -->
</v-row>
</div>
<div style="height: 5%"></div>
</v-col>
<!-- Chart area -->
<v-col :cols="7" style="height: 100%">
<div style="height: 20%"></div>
<div style="text-align: center">에너지사용효율</div>
<div style="height: 70%">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'chart_' + item.eqpmGrpId + '_' + item.fabId"
:ref="'chart_' + item.eqpmGrpId + '_' + item.fabId"
/>
</div>
</v-col>
</div>
</v-card>
</v-col>
</v-row>
</div>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from "vuex";
import mixinGlobal from "@/mixin/global.js";
import { resize } from "@/mixin/resize.js";
import Utility from "~/plugins/utility";
import SelectBox from "@/components/common/select/SelectBox";
import BtnSearch from "~/components/common/button/BtnSearch";
import DatePicker from "@/components/common/Datepicker";
import Chart from "~/components/common/Chart";
import PageTitle from "~/components/common/PageTitle";
import getGaugeChartOption from "~/components/common/chartoptions/GaugeChart";
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
SelectBox,
BtnSearch,
DatePicker,
Chart,
PageTitle,
},
data() {
return {
myPrgmId: myPrgmId,
initedFlag: false,
selectValueList01: [], // 설비종류 리스트
selectValue01: null,
contentData: {},
loadChart: false,
testFlag: false,
};
},
computed: {
...mapState({
pageData: (state) => state.pageData[myPrgmId],
isDarkMode: "isDarkMode",
}),
fromDt() {
return this.pageData.fromDt;
},
},
watch: {
async selectValue01(value) {
if (this.initedFlag) {
await this.search();
}
},
async fromDt(value) {
if (this.initedFlag) {
await this.search();
}
},
isDarkMode(newVal) {
this.setChartData(this.contentData);
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch("chkOpenTabList", {
key: "create",
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: "destroy", prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: "setChartOption",
}),
async test() {
this.testFlag = !this.testFlag;
await this.search();
},
async init() {
await this.getSelectValueList01();
await this.search();
this.initedFlag = true;
},
async search() {
var enrgUseTotSummData = await this.getEnrgUseTotSummData();
var data = this.replaceUndefined(enrgUseTotSummData);
var dataGroupByEqpmGrpId = this.groupByEqpmGrpId(data);
this.contentData = dataGroupByEqpmGrpId;
this.setContent(this.contentData);
},
async getSelectValueList01() {
var res = await this.postApiReturn({
apiKey: "selectEmsEqpmKindList",
resKey: "eqpmGrpPysclQtyMngData",
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map((item) => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
async getEnrgUseTotSummData() {
var res = await this.postApiReturn({
apiKey: "selectEnrgUseTotSumm",
resKey: "data",
sendParam: {
fromDt: this.pageData.fromDt,
eqpmKind: this.selectValue01,
},
});
if (this.testFlag == true) {
res = [
{
eqpmGrpNm: "냉동기저온",
fabId: "ECC000003",
eqpmGrpId: "EQG000001",
fabNm: "삼천1공장",
dayVal: 252.55,
mnthVal: 4800.12,
planVal: 4400,
effcRt: 87.5,
},
{
eqpmGrpNm: "냉동기저온",
fabId: "ECC000008",
eqpmGrpId: "EQG000001",
fabNm: "삼천2공장",
dayVal: 353.46,
mnthVal: 2000.12,
planVal: 1800,
effcRt: 86,
},
{
eqpmGrpNm: "냉동기저온",
fabId: "ECC000009",
eqpmGrpId: "EQG000001",
fabNm: "삼천3공장",
dayVal: 353.46,
mnthVal: 2000.12,
planVal: 1800,
effcRt: 86,
},
{
eqpmGrpNm: "냉동기저온",
fabId: "ECC000010",
eqpmGrpId: "EQG000001",
fabNm: "삼천4공장",
dayVal: 553.46,
mnthVal: 3000.12,
planVal: 2800,
effcRt: 90,
},
{
eqpmGrpNm: "냉동기저온",
fabId: "ECC000011",
eqpmGrpId: "EQG000001",
fabNm: "삼천5공장",
dayVal: 453.46,
mnthVal: 3000.12,
planVal: 2800,
effcRt: 86,
},
{
eqpmGrpNm: "냉동기고온",
fabId: "ECC000008",
eqpmGrpId: "EQG000002",
fabNm: "삼천2공장",
dayVal: 444,
mnthVal: 8888.888,
planVal: 6000,
effcRt: 72.44,
},
{
eqpmGrpNm: "test1",
fabId: "ECC000008",
eqpmGrpId: "EQG000007",
fabNm: "삼천2공장",
dayVal: 455,
mnthVal: 9999.999,
planVal: 5000,
effcRt: 50.555,
},
];
}
return res;
},
groupByEqpmGrpId(data) {
var result = {};
for (var i = 0; i < data.length; i++) {
if (!result.hasOwnProperty(data[i]["eqpmGrpId"])) {
var tempObject = {};
tempObject.eqpmGrpId = data[i]["eqpmGrpId"];
tempObject.eqpmGrpNm = data[i]["eqpmGrpNm"];
tempObject.chartData = [];
tempObject.chartData.push({
...data[i],
});
result[data[i]["eqpmGrpId"]] = tempObject;
} else {
result[data[i]["eqpmGrpId"]].chartData.push({
...data[i],
});
}
}
return result;
},
replaceUndefined(data) {
var dataKeyList = ["dayVal", "mnthVal", "planVal", "effcRt"];
var replaceValList = [0, 0, 0, 0];
// var replaceValList = [666666.66, 252.35, '', 50];
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < dataKeyList.length; j++) {
if (data[i][dataKeyList[j]] == undefined) {
data[i][dataKeyList[j]] = replaceValList[j];
}
}
}
return data;
},
async setContent(data) {
this.initChart(data);
this.loadChart = false;
await this.$nextTick();
this.setChartData(data);
this.loadChart = true;
},
initChart(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
for (var i = 0; i < dataKeyList.length; i++) {
for (var j = 0; j < data[dataKeyList[i]].chartData.length; j++) {
currentChartData = data[dataKeyList[i]].chartData[j];
chartKey =
"chart_" + currentChartData["eqpmGrpId"] + "_" + currentChartData["fabId"];
this.setPageData({
[chartKey]: getGaugeChartOption({
title: chartKey,
value: 75,
isDarkMode: this.isDarkMode,
backgroundRadius: 89,
}),
});
}
}
},
async setChartData(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
var chartOption = null;
for (var i = 0; i < dataKeyList.length; i++) {
for (var j = 0; j < data[dataKeyList[i]].chartData.length; j++) {
currentChartData = data[dataKeyList[i]].chartData[j];
chartKey =
"chart_" + currentChartData["eqpmGrpId"] + "_" + currentChartData["fabId"];
chartOption = getGaugeChartOption({
title: chartKey,
value: 75,
isDarkMode: this.isDarkMode,
backgroundRadius: 89,
});
chartOption["series"][0]["data"][0].value = currentChartData["effcRt"];
this.$store.state.pageData[myPrgmId][chartKey] = chartOption;
}
}
//Mock chart
// chartKey = 'chart_test_01'
// chartOption["series"][0]["data"][0].value = 56;
// this.$store.state.pageData[myPrgmId][chartKey] = chartOption;
},
getGuageChartOption() {
// const gaugeColors = [
// [0.125, '#009245'],
// [0.25, '#39b54a'],
// [0.375, '#d9e021'],
// [0.5, '#fcee21'],
// [0.625, '#fbb03b'],
// [0.75, '#f7931e'],
// [0.875, '#f15a24'],
// [1.0, '#ed1c24']
// ];
const gaugeColors = [
[0, "#ed1c24"],
[0.6, "#ed1c24"],
[0.8, "#f7931e"],
[1.0, "#009245"],
];
var guageChartOption = {
grid: {
top: "30%",
bottom: 0,
},
series: [
{
type: "gauge",
center: ["50%", "80%"],
radius: "100%",
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
splitNumber: 10,
itemStyle: {
// color: '#FFAB91'
color: "auto",
// color:gaugeColors
},
progress: {
// show: true,
show: false,
width: 20,
},
pointer: {
// show: false
show: true,
itemStyle: {
// color: '#FFAB91',
color: "auto",
},
},
axisLine: {
lineStyle: {
width: 20,
color: gaugeColors,
},
},
axisTick: {
distance: -35,
splitNumber: 5,
lineStyle: {
width: 2,
color: "#999",
},
},
splitLine: {
distance: -42,
length: 14,
lineStyle: {
width: 3,
color: "#999",
},
},
axisLabel: {
distance: -10,
color: "#999",
fontSize: 10,
},
anchor: {
show: false,
},
title: {
show: false,
},
detail: {
valueAnimation: true,
width: "60%",
lineHeight: 25,
borderRadius: 8,
// offsetCenter: [0, '-15%'],
offsetCenter: [0, "33%"],
fontSize: 17,
fontWeight: "bolder",
formatter: "{value} %",
color: "auto",
},
data: [
{
value: NaN,
},
],
},
],
};
return guageChartOption;
},
getGuageChartOption2(chartName) {
const gaugeColors = [
[0, "#ed1c24"],
[0.6, "#ed1c24"],
[0.8, "#f7931e"],
[1.0, "#009245"],
];
const gaugeColors2 = [
[0, "#009245"],
[0.6, "#009245"],
[0.8, "#f7931e"],
[1.0, "#ed1c24"],
];
var guageChartOption = {
grid: {
// top: '-10%',
bottom: 0,
},
title: {},
graphic: [
{
type: "circle",
left: "center",
top: "center",
shape: {
r: 97, // radius of the background circle
},
style: {
fill: this.isDarkMode ? "#141415" : "#F5F5F5", // Light grey color
opacity: 0.3, // Semi-transparent
},
z: 0, // make sure it's behind the gauge
},
],
series: [
{
type: "gauge",
radius: "100%",
startAngle: 225,
endAngle: -45,
min: 0,
max: 160,
// progress: {
// show: true,
// width: 15,
// },
axisLine: {
lineStyle: {
width: 12,
color: [
[0.375, "#3CB371"], // Green (060)
[0.5, "#FFD700"], // Yellow (6080)
[0.625, "#FFA500"], // Orange (80100)
[1, "#FF4500"], // Red (100160)
],
},
},
axisTick: {
distance: -5,
length: 5,
lineStyle: {
color: "#000000",
width: 1,
},
},
splitLine: {
distance: -15,
length: 8,
lineStyle: {
color: "#000000",
width: 2,
},
},
axisLabel: {
color: this.isDarkMode ? "#fff" : "#333333",
distance: 23,
fontSize: 12,
},
pointer: {
show: true,
length: "70%",
width: 6,
itemStyle: {
color: "#FA8C16", // Set your desired pointer color here
},
},
title: {
show: false,
offsetCenter: [0, "40%"],
fontSize: 18,
},
detail: {
valueAnimation: true,
fontWeight: 500, // or "normal", "lighter", "bolder", or a number like 600
fontFamily: "Oxanium, sans-serif", // or any custom font
fontSize: 30,
lineHeight: 25,
offsetCenter: [0, "60%"],
color: this.isDarkMode ? "#fff" : "#333333",
formatter: function (value) {
return `{valueStyle|${value}}\n{percentStyle|%}`;
},
rich: {
// valueStyle: {
// fontSize: 25,
// fontWeight: "bold",
// },
percentStyle: {
fontSize: 10,
color: this.isDarkMode ? "#fff" : "#333333",
// fontWeight: "normal",
},
},
},
data: [
{
value: 16,
name: "에너지사용효율", // "Energy Usage Efficiency"
},
],
},
],
};
return guageChartOption;
},
chartClickEvent(argData, $event) {
var data = {
...argData,
fromDt: this.pageData.fromDt,
};
var key = "tick_" + Math.random();
this.$router.push({
name: "ems-effc-EqpmIndMntrPage",
query: {
prgmId: "PRG0081",
// tick:key
},
params: {
...data,
key: key,
},
});
},
},
};
const defaultData = {
cmCycle: "CYC_MONTH",
fromDt: Utility.setFormatDate(new Date(), "YYYYMM"), // 조회 시작일
};
</script>
<style lang="scss" scoped>
.textInfo {
font-family: "Oxanium", sans-serif;
font-weight: 500;
font-size: 24px;
line-height: 24px;
letter-spacing: 0;
color: #1677ff;
}
.textDetail {
// color: #000000;
font-weight: 400;
font-size: 14px;
line-height: 22px;
letter-spacing: 0;
}
</style>