362 lines
8.1 KiB
Vue
362 lines
8.1 KiB
Vue
<template>
|
|
<div class="l-layout">
|
|
<v-row ref="rowParent">
|
|
<v-col :cols="12">
|
|
<v-card class="pa-3 widget-card">
|
|
<div class="d-flex align-center justify-space-between">
|
|
<v-card-title class="pa-0">전력피크 트랜드</v-card-title>
|
|
<v-card-subtitle class="mt-0 pa-0">
|
|
<v-icon
|
|
v-show="widgetPrgmId"
|
|
class="mr-1"
|
|
size="25"
|
|
@click="btnAction('widgetCallPage')"
|
|
>mdi-note-search</v-icon
|
|
>
|
|
<v-icon
|
|
v-show="widgetPopFg"
|
|
size="25"
|
|
@click="btnAction('popWidget')"
|
|
>mdi-plus-box-multiple</v-icon
|
|
>
|
|
</v-card-subtitle>
|
|
</div>
|
|
<div class="mt-1" align="right">
|
|
현재 피크 : {{ nowPeakVal }}kW ({{ peakRto }}%) / 요금적용전력 :
|
|
{{ chargedPower }}kW
|
|
</div>
|
|
<div class="d-flex align-center justify-space-between">
|
|
<div :style="{ width: '100%', height: '200px' }">
|
|
<component
|
|
class="w100 h100"
|
|
:is="loadChart_01 ? 'Chart' : null"
|
|
:parentPrgmId="parentPrgmId"
|
|
:widgetId="'PeakTrndWidget'"
|
|
:widgetData="'PeakTrndWidgetData'"
|
|
:chartName="chart_01"
|
|
ref="chart_01"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
|
import Vue from 'vue';
|
|
import DateUtility from '~/plugins/dateUtility';
|
|
import Utility from '~/plugins/utility';
|
|
import Chart from '~/components/common/Chart';
|
|
|
|
export default {
|
|
props: {
|
|
parentPrgmId: {
|
|
type: String,
|
|
require: true,
|
|
},
|
|
widgetId: {
|
|
type: String,
|
|
require: true,
|
|
},
|
|
widgetPrgmId: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
widgetPopFg: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
widgetReflashMm: {
|
|
type: Number,
|
|
require: true,
|
|
},
|
|
},
|
|
components: {
|
|
DateUtility,
|
|
Chart,
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
searchParam(state) {
|
|
return state.pageData[this.parentPrgmId];
|
|
},
|
|
isDarkMode: 'isDarkMode',
|
|
}),
|
|
},
|
|
watch: {},
|
|
beforeCreate() {
|
|
this.$store.commit('setWidgetPageData', {
|
|
prgmId: this.$route.query.prgmId,
|
|
PeakTrndWidget: { PeakTrndWidgetData },
|
|
});
|
|
},
|
|
async created() {
|
|
this.search();
|
|
this.timer = setInterval(this.search, this.widgetReflashMm);
|
|
},
|
|
beforeDestroy() {
|
|
window.clearTimeout(this.timer);
|
|
},
|
|
mounted() {},
|
|
data() {
|
|
return {
|
|
blocNm: '',
|
|
//차트
|
|
chart_01: 'peakUsage',
|
|
loadChart_01: false,
|
|
//바인딩
|
|
rdbElecQual: 'Kw',
|
|
chargedPower: 0,
|
|
nowPeakVal: 0,
|
|
peakRto: 0,
|
|
dtToday: Utility.setFormatDate(new Date(), 'YYYY/MM/DD HH'),
|
|
};
|
|
},
|
|
methods: {
|
|
...mapMutations({
|
|
setPageData: 'setPageData',
|
|
setWidgetChartOption: 'setWidgetChartOption',
|
|
openDashboardWidget: 'openDashboardWidget',
|
|
}),
|
|
...mapActions({
|
|
postApi: 'modules/list/postApi',
|
|
postApiReturn: 'modules/list/postApiReturn',
|
|
getEnergyList: 'modules/search/getEnergyList',
|
|
}),
|
|
setBlocNm() {
|
|
this.blocNm = this.$store.state.userInfo.blocNm;
|
|
if (this.blocNm != '') {
|
|
this.blocNm = '[' + this.blocNm + ']';
|
|
}
|
|
},
|
|
async search() {
|
|
this.setBlocNm();
|
|
await this.getPeakUsage();
|
|
},
|
|
async getPeakUsage() {
|
|
this.loadChart_01 = false;
|
|
let markAreaData = [];
|
|
let markColor = {
|
|
MAX: 'rgba(238, 102, 102, 0.1)',
|
|
MID: 'rgba(250, 200, 88, 0.1)',
|
|
MIN: 'rgba(145, 204, 117, 0.1)',
|
|
};
|
|
|
|
// 부하시간 가져오기
|
|
let res3 = [];
|
|
res3 = await this.postApiReturn({
|
|
apiKey: 'selectPeakKine',
|
|
resKey: 'peakData',
|
|
sendParam: {
|
|
readObjId: 'ROI000001',
|
|
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
|
},
|
|
});
|
|
|
|
markAreaData = res3.map(item => [
|
|
{
|
|
name: item.commCdNm,
|
|
xAxis:
|
|
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
|
? 0
|
|
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
|
itemStyle: {
|
|
color: markColor[item.peakKine],
|
|
},
|
|
label: {
|
|
distance: [0],
|
|
fontSize: 9,
|
|
fontWeight: 'lighter',
|
|
color: '#fff',
|
|
},
|
|
},
|
|
{
|
|
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
|
},
|
|
]);
|
|
//전력 조회
|
|
let res = await this.postApiReturn({
|
|
apiKey: 'selectPeakTrnd',
|
|
resKey: 'peakTrndData',
|
|
sendParam: {
|
|
blocId: this.$store.state.userInfo.blocId,
|
|
readObjId: 'ROI000001',
|
|
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
|
},
|
|
});
|
|
|
|
this.$nextTick(() => {
|
|
this.setChart01Data(res, markAreaData);
|
|
});
|
|
|
|
// 상단에 표시할 요금전용전력, 현재피크
|
|
this.sendParamData = {
|
|
readObjId: 'ROI000001',
|
|
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
|
cmCycle: 'CYC_HOUR',
|
|
blocId: this.$store.state.userInfo.blocId,
|
|
};
|
|
|
|
this.getPeakPowTitle();
|
|
},
|
|
async getPeakPowTitle() {
|
|
if (this.sendParamData != undefined) {
|
|
let res3 = [];
|
|
res3 = await this.postApiReturn({
|
|
apiKey: 'selectPeakPowAndChargedPower',
|
|
resKey: 'peakData',
|
|
// sendParam: {dateType: this.pageData.cmCycle, date: this.pageData.dtToday}
|
|
sendParam: this.sendParamData,
|
|
});
|
|
|
|
let res4 = [];
|
|
res4 = await this.postApiReturn({
|
|
apiKey: 'selectUseWithPeak',
|
|
resKey: 'peakData',
|
|
sendParam: {},
|
|
});
|
|
|
|
res3.forEach(item => {
|
|
this.chargedPower =
|
|
item.peakVal == 0 ? 0 : Utility.setFormatInt(item.peakVal);
|
|
});
|
|
|
|
res4.forEach((item, idx) => {
|
|
this.nowPeakVal =
|
|
item.curPeakVal == 0 ? 0 : Utility.setFormatInt(item.curPeakVal);
|
|
this.peakRto =
|
|
item.peakRto == 0 ? 0 : Utility.setFormatDecimal(item.peakRto, 0);
|
|
});
|
|
}
|
|
},
|
|
|
|
//차트Setting
|
|
async setChart01Data(data, markAreaData) {
|
|
this.loadChart_01 = false;
|
|
|
|
this.$store.state.pageData[
|
|
this.parentPrgmId
|
|
].PeakTrndWidget.PeakTrndWidgetData.series = [];
|
|
if (!data.length) {
|
|
return;
|
|
}
|
|
|
|
let xAxisData = [];
|
|
let legendData = [];
|
|
|
|
// chart color 집합
|
|
let colorPalette = {
|
|
PLCPEAK: '#D73964',
|
|
PLCMAX: 'rgba(252,151,175,0.7)',
|
|
};
|
|
|
|
let seriesDataList = [];
|
|
|
|
let myKey = Object.keys(data[0]);
|
|
myKey = myKey.filter(v => {
|
|
return v.search('qty') != -1;
|
|
});
|
|
myKey.sort();
|
|
|
|
for (var i = 0; i < 24; i++) {
|
|
xAxisData.push(i + '시');
|
|
}
|
|
|
|
seriesDataList = data.map(item => ({
|
|
name: item.plcNm,
|
|
type: item.plcCd == 'PLCMAX' ? 'bar' : 'line',
|
|
color:
|
|
item.plcCd == 'PLCPEAK'
|
|
? colorPalette[item.plcCd]
|
|
: item.plcCd == 'PLCMAX'
|
|
? colorPalette[item.plcCd]
|
|
: colorPalette[item.readObjId],
|
|
symbol: item.plcCd == 'PLCPEAK' ? 'none' : 'circle',
|
|
data: myKey.map(key => item[key] || 0),
|
|
yAxisIndex:
|
|
item.readObjId == 'ROI000013' || item.readObjId == 'ROI000014'
|
|
? 1
|
|
: 0,
|
|
markArea: item.plcCd == 'PLCMAX' ? { data: markAreaData } : 'none',
|
|
}));
|
|
|
|
var chartOption = {
|
|
series: seriesDataList,
|
|
grid: {
|
|
left: '1%',
|
|
right: '2%',
|
|
top: '15%',
|
|
bottom: '15%',
|
|
containLabel: true,
|
|
},
|
|
legend: {
|
|
bottom: 'bottom',
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
//boundaryGap: false,
|
|
splitLine: false,
|
|
data: xAxisData,
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
name: 'kWh',
|
|
splitLine: {
|
|
show: false,
|
|
},
|
|
axisLabel: {
|
|
color: '#767D83',
|
|
fontSize: 9,
|
|
formatter: '{value}',
|
|
},
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
},
|
|
};
|
|
|
|
this.setWidgetChartOption({
|
|
prgmId: this.$route.query.prgmId,
|
|
widgetKey: 'PeakTrndWidget',
|
|
widgetData: 'PeakTrndWidgetData',
|
|
chartKey: 'peakUsage',
|
|
value: chartOption,
|
|
});
|
|
|
|
this.loadChart_01 = true;
|
|
},
|
|
btnAction(action) {
|
|
switch (action) {
|
|
case 'popWidget':
|
|
this.openDashboardWidget({
|
|
prgmId: this.$route.query.prgmId,
|
|
widgetId: this.widgetId,
|
|
});
|
|
break;
|
|
case 'widgetCallPage':
|
|
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
|
break;
|
|
}
|
|
},
|
|
},
|
|
};
|
|
const PeakTrndWidgetData = {
|
|
peakUsage: Utility.defaultChartOption(true),
|
|
sendParamData: { readObjId: '' },
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.v-avatar {
|
|
border-radius: 21px;
|
|
font-size: 1.75rem;
|
|
}
|
|
.v-virtual-scroll-wrapper {
|
|
overflow-y: auto;
|
|
max-height: 210px;
|
|
}
|
|
</style>
|