586 lines
14 KiB
Vue
586 lines
14 KiB
Vue
<template>
|
||
<div class="l-layout">
|
||
<CommonPageTitle />
|
||
<v-row ref="searchFilter">
|
||
<v-col :cols="12">
|
||
<v-card class="searchFilter">
|
||
<v-row align="end" no-gutters>
|
||
<v-col :cols="3">
|
||
<!-- 차트목록 -->
|
||
<component :is="'SelectBox'" ref="SelectBox" :propsValue="selectValue01" :itemList="selectValueList01"
|
||
:label="'차트'" @update:propsValue="selectValue01 = $event" :textCols="12" customClass="select-large" />
|
||
</v-col>
|
||
<v-col :cols="3">
|
||
<!-- 대상일 -->
|
||
<component :is="'Datepicker'" :parentPrgmId="myPrgmId" :label="'대상일'" :labelCols="3" customClass="datepicker-large" />
|
||
</v-col>
|
||
<v-col :cols="6" class="text-right">
|
||
<!-- 조회버튼 -->
|
||
<BtnSearch @click="search" size="large" />
|
||
</v-col>
|
||
</v-row>
|
||
</v-card>
|
||
</v-col>
|
||
</v-row>
|
||
<v-row ref="contents">
|
||
<v-col :cols="12" style="min-height: 50vh">
|
||
<v-card class="pb-5">
|
||
<div class="d-flex align-center justify-space-between pa-5">
|
||
<v-card-title class="pa-0">에너지 현황</v-card-title>
|
||
</div>
|
||
<v-row align="center" class="mx-2">
|
||
<v-col class="d-flex align-center">
|
||
<span class="arrowText">
|
||
<v-btn class="" outlined fab x-small color="#E6F4FF">
|
||
<v-icon>check</v-icon>
|
||
</v-btn>
|
||
고압반
|
||
</span>
|
||
<div class="col arrow-right mx-2 pa-0"></div>
|
||
<span class="arrowText">
|
||
분전반
|
||
<v-btn class="" outlined fab x-small color="#E6F4FF">
|
||
<v-icon>check</v-icon>
|
||
</v-btn>
|
||
</span>
|
||
</v-col>
|
||
</v-row>
|
||
<div class="px-5" style="height: 80%">
|
||
<div ref="chartParent" class="w100 h100">
|
||
<component
|
||
:ref="chartName"
|
||
class="w100 h100"
|
||
:is="loadChart ? 'Chart' : null"
|
||
:parentPrgmId="myPrgmId"
|
||
:chartName="chartName"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</v-card>
|
||
</v-col>
|
||
</v-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import mixinGlobal from '@/mixin/global.js';
|
||
import { resize } from '@/mixin/resize.js';
|
||
import Datepicker from '~/components/common/Datepicker';
|
||
import { mapState, mapActions, mapMutations } from 'vuex';
|
||
import BtnSearch from '~/components/common/button/BtnSearch';
|
||
import Utility from '~/plugins/utility';
|
||
import SelectBox from '@/components/common/select/SelectBox';
|
||
import DateUtility from '~/plugins/dateUtility';
|
||
import Chart from '~/components/common/Chart';
|
||
|
||
import getSankeyChartOption from "~/components/common/chartoptions/sankeyChart";
|
||
|
||
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: {
|
||
Datepicker,
|
||
BtnSearch,
|
||
Utility,
|
||
DateUtility,
|
||
Chart,
|
||
SelectBox,
|
||
},
|
||
data() {
|
||
return {
|
||
myPrgmId: myPrgmId,
|
||
selectValueList01: [],
|
||
selectValue01: null,
|
||
loadChart: false,
|
||
chartName: 'sankeyChart',
|
||
sankeyChartData: [],
|
||
sankeyChartLinks: []
|
||
};
|
||
},
|
||
computed: {
|
||
...mapState({
|
||
isDarkMode: state => state.isDarkMode,
|
||
}),
|
||
chkIsFind() {
|
||
// 조회 플래그
|
||
return this.pageData.isFind;
|
||
},
|
||
chkToDt() {
|
||
return this.pageData.toDt;
|
||
},
|
||
chkFromDt() {
|
||
return this.pageData.fromDt;
|
||
},
|
||
},
|
||
watch: {
|
||
chkIsFind(val) {
|
||
if (val) this.search();
|
||
},
|
||
chkToDt(val) {
|
||
var diff = DateUtility.diff(
|
||
Utility.setFormatDate(new Date(), 'YYYY-MM-DD'),
|
||
this.pageData.toDt,
|
||
'd',
|
||
);
|
||
if (diff > 0) {
|
||
this.setPageData({
|
||
toDt: new Date(),
|
||
isCheck: true,
|
||
});
|
||
}
|
||
},
|
||
chkFromDt(val) {
|
||
var diff = DateUtility.diff(
|
||
Utility.setFormatDate(new Date(), 'YYYY-MM-DD'),
|
||
this.pageData.fromDt,
|
||
'd',
|
||
);
|
||
if (diff > 0) {
|
||
this.setPageData({
|
||
fromDt: new Date(),
|
||
isCheck: true,
|
||
});
|
||
}
|
||
},
|
||
isDarkMode(newVal) {
|
||
this.setChartOption({
|
||
chartKey: this.chartName,
|
||
value: getSankeyChartOption({
|
||
isDarkMode: newVal,
|
||
data: this.sankeyChartData,
|
||
links: this.sankeyChartLinks
|
||
})
|
||
});
|
||
},
|
||
},
|
||
async beforeCreate() {
|
||
myPrgmId = this.$route.query.prgmId;
|
||
await this.$store.dispatch('chkOpenTabList', {
|
||
key: 'create',
|
||
prgmId: myPrgmId,
|
||
defaultData: defaultData,
|
||
});
|
||
},
|
||
async created() { },
|
||
async mounted() {
|
||
this.init();
|
||
// document.querySelector('.icon_arrow').style.width = document.querySelector('.iconArrowCols').clientWidth-20 + "px";
|
||
},
|
||
beforeDestroy() {
|
||
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
|
||
},
|
||
methods: {
|
||
...mapMutations({
|
||
setChartOption: 'setChartOption',
|
||
setPageData: 'setPageData',
|
||
}),
|
||
...mapActions({
|
||
getCodeList: 'modules/search/getCodeList',
|
||
}),
|
||
initTestChart() {
|
||
const randomNumber = n => Math.floor(Math.random() * n) + 1;
|
||
const makeData = [
|
||
{ name: 'A' },
|
||
{ name: 'B' },
|
||
{ name: 'B2' },
|
||
{ name: 'C1' },
|
||
{ name: 'C2' },
|
||
{ name: 'C3' },
|
||
// { name: 'D' }
|
||
];
|
||
const makeLinks = [
|
||
{ source: 'A', target: 'B', value: 100 },
|
||
{ source: 'A', target: 'B2', value: 50 },
|
||
{ source: 'B', target: 'C1', value: 50 },
|
||
{ source: 'B', target: 'C2', value: 50 },
|
||
{ source: 'B2', target: 'C3', value: 50 },
|
||
];
|
||
for (let index = 0; index < 10; index++) {
|
||
makeData.push(...[
|
||
{ name: 'D' + index },
|
||
]);
|
||
makeLinks.push(...[
|
||
{ source: 'C' + randomNumber(3), target: 'D' + index, value: randomNumber(50) },
|
||
]);
|
||
}
|
||
|
||
this.sankeyChartData = makeData;
|
||
this.sankeyChartLinks = makeLinks;
|
||
const chartOption = getSankeyChartOption({
|
||
isDarkMode: this.isDarkMode,
|
||
data: makeData,
|
||
links: makeLinks
|
||
});
|
||
this.setChartOption({ chartKey: this.chartName, value: chartOption });
|
||
this.$nextTick(() => {
|
||
this.loadChart = true;
|
||
});
|
||
},
|
||
async init() {
|
||
await this.getEnrgMapChartList();
|
||
this.setFromDt();
|
||
},
|
||
async search() {
|
||
try{
|
||
await this.getChartData();
|
||
}catch(err){
|
||
this.initTestChart();
|
||
}
|
||
this.setPageData({
|
||
isFind: false,
|
||
});
|
||
},
|
||
setFromDt() {
|
||
this.pageData.fromDt = Utility.setBeforetDate(
|
||
this.pageData,
|
||
this.pageData.toDt,
|
||
'YYYYMMDD',
|
||
);
|
||
},
|
||
async getEnrgMapChartList() {
|
||
let res = await this.postApiReturn({
|
||
apiKey: 'selectEnrgMapChartList',
|
||
resKey: 'enrgMapChartList',
|
||
sendParam: {},
|
||
});
|
||
if (res.length > 0) {
|
||
this.selectValueList01 = await res.map(item => {
|
||
return {
|
||
text: item.sankeyChartNm,
|
||
value: item.sankeyChartSno.toString(),
|
||
};
|
||
});
|
||
this.selectValue01 = this.selectValueList01[0].value;
|
||
} else {
|
||
this.selectValueList01 = [];
|
||
this.selectValue01 = null;
|
||
}
|
||
this.setPageData({
|
||
sankeyChartList: this.selectValueList01,
|
||
sankeyChartSno: this.selectValue01,
|
||
});
|
||
},
|
||
async getChartData() {
|
||
let res = await this.postApiReturn({
|
||
apiKey: 'selectChartNode',
|
||
resKey: 'enrgMapChartNodeList',
|
||
sendParam: {
|
||
sankeyChartSno: this.selectValue01,
|
||
},
|
||
});
|
||
|
||
let res2 = await this.postApiReturn({
|
||
apiKey: 'selectSankeyTag',
|
||
resKey: 'sankeyTagList',
|
||
sendParam: {
|
||
sankeyChartSno: this.selectValue01,
|
||
},
|
||
});
|
||
|
||
var taglist = res2.map(item => {
|
||
return item['hmiTagNm'];
|
||
});
|
||
|
||
var tempSObj = {};
|
||
var tempEObj = {};
|
||
tempSObj['eterm'] = Utility.setFormatDate(
|
||
this.pageData.fromDt,
|
||
'YYYY-MM-DD 00:29:59',
|
||
);
|
||
tempSObj['sterm'] = Utility.setFormatDate(
|
||
DateUtility.addDate(-1, 'YYYY/MM/DD', this.pageData.fromDt),
|
||
'YYYY-MM-DD 23:59:59',
|
||
);
|
||
tempSObj['interval'] = '1';
|
||
tempSObj['vals'] = ['MIN'];
|
||
tempSObj['t'] = '2022-06-03 05:22:50';
|
||
tempSObj['term'] = 'MIN10';
|
||
tempSObj['tags'] = taglist;
|
||
tempSObj['url'] = 'http://58.232.11.31:1567/RTDBweapi/aggdata2.do';
|
||
|
||
var today = Utility.setFormatDate(new Date(), 'YYYYMMDD');
|
||
var eterm = Utility.setFormatDate(this.pageData.toDt, 'YYYYMMDD');
|
||
tempEObj['eterm'] = Utility.setFormatDate(
|
||
this.pageData.toDt,
|
||
'YYYY-MM-DD 23:59:59',
|
||
);
|
||
tempEObj['sterm'] =
|
||
today == eterm
|
||
? Utility.setFormatDate(this.pageData.toDt, 'YYYY-MM-DD 00:00:00')
|
||
: Utility.setFormatDate(this.pageData.toDt, 'YYYY-MM-DD 23:29:59');
|
||
tempEObj['interval'] = '1';
|
||
tempEObj['vals'] = ['MIN'];
|
||
tempEObj['t'] = '2022-06-03 05:22:50';
|
||
tempEObj['term'] = 'MIN10';
|
||
tempEObj['tags'] = taglist;
|
||
tempEObj['url'] = 'http://58.232.11.31:1567/RTDBweapi/aggdata2.do';
|
||
|
||
var startRes = await this.postApiReturn({
|
||
apiKey: 'selectEnrgMapInfo',
|
||
resKey: 'enrgMapInfoData',
|
||
sendParam: tempSObj,
|
||
});
|
||
|
||
var endRes = await this.postApiReturn({
|
||
apiKey: 'selectEnrgMapInfo',
|
||
resKey: 'enrgMapInfoData',
|
||
sendParam: tempEObj,
|
||
});
|
||
|
||
var resultRes = [];
|
||
var tempTags = [];
|
||
var allResCheck = false;
|
||
for (var i = 0; i < taglist.length; i++) {
|
||
if (
|
||
startRes.tags[i]['d'].length > 0 &&
|
||
endRes.tags[i]['d'].length > 0
|
||
) {
|
||
resultRes.push(
|
||
Utility.setFormatDecimal(
|
||
endRes.tags[i]['M'] - startRes.tags[i]['N'],
|
||
2,
|
||
),
|
||
);
|
||
} else {
|
||
resultRes.push(0);
|
||
tempTags.push({ index: i, tag: startRes.tags[i].tag });
|
||
}
|
||
}
|
||
if (tempTags.length > 0) {
|
||
allResCheck = true;
|
||
console.log('allResCheck... true');
|
||
}
|
||
if (allResCheck) {
|
||
tempSObj['tags'] = tempTags.map(item => {
|
||
return item.tag;
|
||
});
|
||
tempSObj['sterm'] = Utility.setFormatDate(
|
||
DateUtility.addDate(-1, 'YYYY/MM/DD', this.pageData.fromDt),
|
||
'YYYY-MM-DD 23:59:59',
|
||
);
|
||
tempSObj['eterm'] = Utility.setFormatDate(
|
||
this.pageData.toDt,
|
||
'YYYY-MM-DD 23:29:59',
|
||
);
|
||
var allRes = await this.postApiReturn({
|
||
apiKey: 'selectEnrgMapInfo',
|
||
resKey: 'enrgMapInfoData',
|
||
sendParam: tempSObj,
|
||
});
|
||
var cnt = 0;
|
||
allRes.tags.map(item => {
|
||
resultRes[tempTags[cnt++].index] = Utility.setFormatDecimal(
|
||
item['M'] - item['N'],
|
||
2,
|
||
);
|
||
});
|
||
}
|
||
|
||
this.setChartData(res, res2, resultRes);
|
||
},
|
||
async setChartData(nodeList, data, value) {
|
||
this.loadChart = false;
|
||
let makeData = [];
|
||
let makeLinks = [];
|
||
|
||
this.makeDataAndLink(nodeList, data, value, makeLinks, makeData);
|
||
|
||
//label에서 보여줄 total 값
|
||
var totalVal = 0;
|
||
makeLinks.map(item => {
|
||
if (item.source == makeData[0].name) {
|
||
totalVal += item.value;
|
||
}
|
||
});
|
||
|
||
//label , tooltip 셋팅
|
||
for (var i = 0; i < makeData.length; i++) {
|
||
makeData[i]['label'] = {
|
||
show: true,
|
||
formatter: function (obj) {
|
||
var retVal = makeLinks.filter(n => {
|
||
return n.target == obj.name;
|
||
});
|
||
return (
|
||
obj.name +
|
||
'\n' +
|
||
(obj.name == makeData[0].name
|
||
? Utility.setFormatIntDecimal(totalVal, 2)
|
||
: Utility.setFormatIntDecimal(retVal[0].value, 2))
|
||
);
|
||
},
|
||
};
|
||
makeData[i]['tooltip'] = {
|
||
formatter: function (obj) {
|
||
var retVal = makeLinks.filter(n => {
|
||
return n.target == obj.name;
|
||
});
|
||
return (
|
||
obj.name +
|
||
'\n' +
|
||
(obj.name == makeData[0].name
|
||
? Utility.setFormatIntDecimal(totalVal, 2)
|
||
: Utility.setFormatIntDecimal(retVal[0].value, 2)
|
||
)
|
||
.toString()
|
||
.bold()
|
||
);
|
||
},
|
||
};
|
||
}
|
||
|
||
this.sankeyChartData = makeData;
|
||
this.sankeyChartLinks = makeLinks;
|
||
const chartOption = getSankeyChartOption({
|
||
isDarkMode: this.isDarkMode,
|
||
data: makeData,
|
||
links: makeLinks
|
||
});
|
||
|
||
this.setChartOption({ chartKey: this.chartName, value: chartOption });
|
||
|
||
this.loadChart = true;
|
||
},
|
||
makeDataAndLink(nodeList, data, value, makeLinks, makeData) {
|
||
var makeTempData = [];
|
||
var tempMakeLinks = [];
|
||
nodeList.map(item => {
|
||
makeTempData.push({
|
||
name: item.nodeName,
|
||
});
|
||
});
|
||
var cnt = 0;
|
||
data.map(item => {
|
||
tempMakeLinks.push({
|
||
source: item.sourceName,
|
||
target: item.tartgetName,
|
||
value: parseFloat(value[cnt++]),
|
||
});
|
||
});
|
||
|
||
// var resultArr = parentList.filter((item, index)=>{
|
||
// console.log("index :",parentList.indexOf(item))
|
||
// console.log("##",parentList.indexOf(item) === index)
|
||
// return parentList.indexOf(item) === index;
|
||
// });
|
||
|
||
//1차 정렬
|
||
tempMakeLinks.sort(function (a, b) {
|
||
if (a.source == b.source) {
|
||
return b.value - a.value;
|
||
}
|
||
});
|
||
|
||
tempMakeLinks.filter(item => {
|
||
if (item.source == makeTempData[0].name) {
|
||
makeLinks.push(item);
|
||
}
|
||
});
|
||
|
||
//2차 정렬
|
||
makeSort(makeLinks, tempMakeLinks);
|
||
|
||
makeLinks.map(item => {
|
||
makeData.push({ name: item.target });
|
||
});
|
||
|
||
makeData.unshift(makeTempData[0]);
|
||
|
||
//
|
||
function makeSort(list, b) {
|
||
for (var i = 0; i < list.length; i++) {
|
||
b.filter(item => {
|
||
if (item.source == list[i].target) {
|
||
makeLinks.push(item);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
},
|
||
};
|
||
|
||
const defaultData = {
|
||
isFind: false,
|
||
cmCycle: 'CYC_DAY', // 주기
|
||
defaultRange: {
|
||
CYC_DAY: 30,
|
||
},
|
||
fromDt: '',
|
||
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||
sankeyChartList: [],
|
||
sankeyChartSno: null,
|
||
sankeyChart: {
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
confine: true,
|
||
axisPointer: {
|
||
type: 'shadow',
|
||
},
|
||
},
|
||
grid: {
|
||
left: '0',
|
||
right: '0',
|
||
top: '0',
|
||
},
|
||
legend: null,
|
||
series: [],
|
||
title: {},
|
||
backgroundColor: '',
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
@each $theme in dark, light {
|
||
.v-application.#{$theme}-mode {
|
||
.arrowText {
|
||
.v-btn {
|
||
background-color: map-deep-get($config, #{$theme}, "arow-line-btn-bg-color"); // #E6F4FF;
|
||
border: none;
|
||
|
||
.v-icon {
|
||
color: map-deep-get($config, #{$theme}, "arow-line-color"); // #1677FF;
|
||
}
|
||
}
|
||
}
|
||
|
||
.arrow-right {
|
||
width: 100%;
|
||
height: 1px;
|
||
display: flex;
|
||
background-color: map-deep-get($config, #{$theme}, "arow-line-color"); //#1677FF;
|
||
}
|
||
}
|
||
}
|
||
|
||
// .arrow-right:before {
|
||
// // content: '';
|
||
// background: #594dff;
|
||
// width: 100%;
|
||
// clip-path: polygon(
|
||
// 0 10px,
|
||
// calc(100% - 15px) 10px,
|
||
// calc(100% - 15px) 0,
|
||
// 100% 50%,
|
||
// calc(100% - 15px) 100%,
|
||
// calc(100% - 15px) calc(100% - 10px),
|
||
// 0 calc(100% - 10px)
|
||
// );
|
||
// }
|
||
</style>
|