BemsWebApplication.RealtimeEnergyConsumption = function (params, viewInfo) { "use strict"; var BUILDING_DEPTH = 1, FLOOR_DEPTH = 2, ZONE_DEPTH = 3; var CODE = $Code, FuelType = CODE.FuelType, FT = CODE.FacilityType, FC = CODE.FacilityCode, F = CODE.Formula, TIT = CODE.TimeIntervalType; var checkBox_value = true, checkBox_temperature = true, checkBox_humidity = true; // 수정 var visiblePopup = ko.observable(false); var timer; var initialized = false, shouldReload = false, dataSource; var pointHistoryGet = new BWA.Chart.PointHistoryGet(BWA.UserInfo.SiteId()), formulaGet = new BWA.Chart.FormulaGet(BWA.UserInfo.SiteId()); //var buildingDataSource = BemsWebApplication.db.createDataSource('CmBuilding', true, true), var buildingDataSource = BemsWebApplication.db.createDataSource('CmBuilding', [('SiteId', '=', BWA.UserInfo.SiteId())]), floorDataSource = BemsWebApplication.db.createDataSource('CmFloor'), zoneDataSource = BemsWebApplication.db.createDataSource('CmZone'), fuelTypesDataSource = BemsWebApplication.db.createDataSource('BemsFuelType'), //check_input = ko.observable(false), //check_input2 = ko.observable(false), buildings = ko.observableArray(), floorsForSearch = ko.observableArray(), zonesForSearch = ko.observableArray(), fuelTypesForSearch = ko.observableArray(), buildingIdForSearch = ko.observable(), buildingNameForSearch = ko.observable(), floorIdForSearch = ko.observable(), floorNameForSearch = ko.observable(), zoneIdForSearch = ko.observable(), zoneNameForSearch = ko.observable(), fuelTypeIdForSearch = ko.observable(), deferredForSearch = new $.Deferred(); var deferredForLoadData = new $.Deferred(); var chart = BWA.Chart.Instance('chartRT', 'dxChart'); var locationEnableForSearch = ko.observable(true); var chartDataArray = ko.observableArray(); var value_name; //추가 // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 // 팝업창뷰 보이기 속성 제어용 변수 선언 var DataGridPopup_Visible = ko.observable(false); // 그래프 출력 이후 엑셀출력을 위한 팝업창을 위해 임시 저장용 배열 선언 var dataArrayresult = ko.observableArray(); // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 chartDataArray([ { DateTime: new Date(2014, 11, 16, 0), OutdoorTemperature: -3.4, OutdoorHumidity: 40, Value: 30 }, { DateTime: new Date(2014, 11, 16, 0, 15), OutdoorTemperature: -1.1, OutdoorHumidity: 44, Value: 32 }, { DateTime: new Date(2014, 11, 16, 0, 30), OutdoorTemperature: 3, OutdoorHumidity: 48, Value: 33 }, { DateTime: new Date(2014, 11, 16, 0, 45), OutdoorTemperature: 4, OutdoorHumidity: 55, Value: 34 }, { DateTime: new Date(2014, 11, 16, 1), OutdoorTemperature: 8, OutdoorHumidity: 54, Value: 50 }, { DateTime: new Date(2014, 11, 16, 2), OutdoorTemperature: 10, OutdoorHumidity: 53, Value: 60 }, { DateTime: new Date(2014, 11, 16, 3), OutdoorTemperature: 11, Value: 80 }, { DateTime: new Date(2014, 11, 16, 4), OutdoorTemperature: 12, OutdoorHumidity: 48, Value: 100 }, { DateTime: new Date(2014, 11, 16, 5), OutdoorTemperature: 12, OutdoorHumidity: 40 }, { DateTime: new Date(2014, 11, 16, 6), Value: 120 } ]); var goalUpperBound = ko.observable(40); function handleClickTreeItem(element, data) { var eq = BWA.DataUtil.constructEqualFilter; var depth = data.depth; //data = data.data; switch (depth) { case BUILDING_DEPTH: // building data = data.data; buildingIdForSearch(data.BuildingId()); buildingNameForSearch(data.Name()); floorIdForSearch(null); floorNameForSearch(''); zoneIdForSearch(null); zoneNameForSearch(''); break; case FLOOR_DEPTH: // floor buildingNameForSearch(data.parentData.data.Name()); //alert(buildingIdForSearch()); data = data.data; buildingIdForSearch(data.BuildingId()); floorIdForSearch(data.FloorId()); floorNameForSearch(data.Name()); zoneIdForSearch(null); zoneNameForSearch(''); break; case ZONE_DEPTH: // zone floorNameForSearch(data.parentData.data.Name()); buildingNameForSearch(data.parentData.parentData.data.Name()); data = data.data; buildingIdForSearch(data.BuildingId()); //alert(buildingIdForSearch()); //buildingNameForSearch(data.Name()); floorIdForSearch(data.FloorId()); //alert(floorIdForSearch()); //floorNameForSearch(data.parent.data.Name()); zoneIdForSearch(data.ZoneId()); zoneNameForSearch(data.Name()); break; } } function handleSearchViewInitializeUpdate() { //alert('handleSearchViewInitializeUpdate'); $('#locationTreeViewInSearchView1').cwTreeView({ width: '40%', height: '100%', onClickTreeItem: handleClickTreeItem, delegateDataSource: BWA.DataUtil.getLocationDataSourceDelegateForTreeView( buildingDataSource, floorDataSource, zoneDataSource ) }); } function handleViewShown() { //alert('handleViewShown'); // 2 switch (fuelTypeIdForSearch()) { case $Code.FuelType.ELECTRICITY: goalUpperBound(500000); value_name = "전기";//추가 break; case $Code.FuelType.GAS: goalUpperBound(180); value_name = "가스"; break; case $Code.FuelType.WATER: goalUpperBound(40); value_name = "수도"; break; } if (initialized === false) { //alert('handleViewShown1'); // 3 chart = chart(BWA.ChartOptions.RealtimeEnergyConsumption.getChartOptions($Code.TimeType.QUARTERMIN, goalUpperBound)); //chart = chart(BWA.ChartOptions.RealtimeEnergyConsumption.getSeriesOptions($Code.TimeType.QUARTERMIN, goalUpperBound)); floorNameForSearch(''); zoneNameForSearch(''); check_button();//추가 initialized = true; } if (shouldReload) { //shouldReload = false; //dataSource.pageIndex(0); //dataSource.load(); } timer = setInterval(function () { //alert('timer'); // For Debugging var now = new Date(); if ((now.getMinutes() % 15 == 0) && (now.getSeconds() == 58)) { //alert('timer'); // For Debugging handleSearchInSearchView(); } }, 1000); } function check_button() { //추가 $("#checkBox_value").dxCheckBox({ text: (value_name == "전기") ? "전기" : ((value_name == '수도') ? "수도" : "가스"), value: true, onValueChanged: function (e) { switch (e.value) { case true: checkBox_value = true; break; case false: checkBox_value = false; break; } Data_fliter(); } }); $("#checkBox_temperature").dxCheckBox({ text: "온도", value: true, onValueChanged: function (e) { switch (e.value) { case true: checkBox_temperature = true; break; case false: checkBox_temperature = false; break; } Data_fliter(); } }); $("#checkBox_humidity").dxCheckBox({ text: "습도", value: true, onValueChanged: function (e) { switch (e.value) { case true: checkBox_humidity = true; break; case false: checkBox_humidity = false; break; } Data_fliter(); } }); } function Data_fliter() {//추가 visiblePopup(true); var dataArray = []; var commonParameters = { TimeIntervalType: $Code.TimeIntervalType.QUARTERMIN, StartDate: moment().startOf('day'), EndDate: moment() }; var pointHistoryParameters = { BuildingId: buildingIdForSearch(), FloorId: floorIdForSearch(), ZoneId: zoneIdForSearch(), FuelTypeId: fuelTypeIdForSearch() }; var temperatureParameters = { FacilityTypeId: FT.OUTDOOR, FacilityCode: FC.OUTDOOR, FormulaId: F[FT.OUTDOOR].TEMPERATURE, }; var humidityParameters = _.extend({}, temperatureParameters, { FormulaId: F[FT.OUTDOOR].HUMIDITY, }); $.when( pointHistoryGet.apiGet(_.extend(pointHistoryParameters, commonParameters)), formulaGet.apiGet(_.extend(temperatureParameters, commonParameters)), formulaGet.apiGet(_.extend(humidityParameters, commonParameters))) .done(function (values, temperatures, humidities) { var maxValue = 0; var dataArray_Temp = []; var dataArray_Temp1 = []; var dataArray_Temp2 = []; var dataArray_Temp3 = []; if (checkBox_value) {//1 if (checkBox_temperature) {//2 if (checkBox_humidity) {//5 value_input(values); temperatures_input(temperatures); humidities_input(humidities); } else { value_input(values); temperatures_input(temperatures); } } else { if (checkBox_humidity) {//1,5 value_input(values); humidities_input(humidities); } else { value_input(values); } } } else { if (checkBox_temperature) {//2 if (checkBox_humidity) {//5 temperatures_input(temperatures); humidities_input(humidities); } else { temperatures_input(temperatures); } } else { if (checkBox_humidity) {//5 humidities_input(humidities); } else { } } } function value_input(values) { _.each(values[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Value: x.Value }); }); } function temperatures_input(temperatures) { if (temperatures[0].length > 0) { // 2017 02 17 if (temperatures[0][temperatures[0].length - 1].Value == 0 && humidities[0][humidities[0].length - 1].Value == 0 && temperatures[0][temperatures[0].length - 1].DateTime == humidities[0][humidities[0].length - 1].DateTime) { temperatures[0].splice(temperatures[0].length - 1, 1); humidities[0].splice(humidities[0].length - 1, 1); } } _.each(temperatures[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Temperature: x.Value }); }); } function humidities_input(humidities) { _.each(humidities[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Humidity: x.Value }) }); } switch (fuelTypeIdForSearch()) { case $Code.FuelType.ELECTRICITY: goalUpperBound(500000); value_name = "전기"; break; case $Code.FuelType.GAS: goalUpperBound(180); value_name = "가스"; break; case $Code.FuelType.WATER: goalUpperBound(40); value_name = "수도"; break; } var options = BWA.ChartOptions.RealtimeEnergyConsumption.getSeriesOptions( fuelTypeIdForSearch(), goalUpperBound() ); options.valueAxis[1].min = -19; options.valueAxis[1].max = 39; options.valueAxis[2].max = 100; options.valueAxis[2].min = 0; options.dataSource = dataArray; chart().option(options); $('#st').text('에너지 사용량 트랜드' + " : " + buildingNameForSearch() + " - " + floorNameForSearch() + " - " + zoneNameForSearch()); visiblePopup(false); }) .fail(function (error) { visiblePopup(false); }); } function handleViewHidden() { $SearchView.visibleObservable(false); // hcLee 2015 03 23 //alert('1'); // $SearchView.hide(); // hcLee 2015 03 23 //$SearchView.toggleSearchView(); //$SearchView.toggleSearchView(); visiblePopup(false); //if ($SearchView.visibleObservable()) $SearchView.toggleSearchView(); clearInterval(timer); // hcLee 2015 06 12 //hideOverlay(); // var dataGrid = $('#gridContainer').dxDataGrid('instance'); // dataGrid.clearSelection(); } function handleViewShowing() { //alert('handleViewShowing'); // 1 $.when(fuelTypesDataSource.load(), buildingDataSource.load()).done(function (fuelTypes, dbBuildings) { //handleSearchViewInitializeUpdate(); fuelTypes = fuelTypes[0]; dbBuildings = dbBuildings[0]; fuelTypesForSearch(_.rest(fuelTypes)); deferredForSearch.resolve(); if (_.isEmpty(dbBuildings) === false) { buildingIdForSearch(dbBuildings[0].BuildingId()); buildingNameForSearch(dbBuildings[0].Name()); handleSearchInSearchView(); } }); } function refreshList() { //dataSource.pageIndex(0); //dataSource.load(); } var searchViewOptions = { searchViewItems: [ { id: 'FuelTypeId', ignoreValue: 0, defaultValue: $Code.FuelType.ELECTRICITY, value: fuelTypeIdForSearch, dataSource: fuelTypesForSearch } ], promiseDataInSearchView: deferredForSearch.promise() }; function handleSearchInSearchView() { visiblePopup(true); var dataArray = []; //document.getElementById('header').innerHTML = '기다려'; /*$("#large-indicator").dxLoadIndicator({ height: 60, width: 60 });*/ //alert('handleSearchInSearchView'); var commonParameters = { TimeIntervalType: $Code.TimeIntervalType.QUARTERMIN, StartDate: moment().startOf('day'), EndDate: moment() }; //commonParameters.EndDate._d = commonParameters.EndDate._d.getMinutes() + 1; var pointHistoryParameters = { BuildingId: buildingIdForSearch(), FloorId: floorIdForSearch(), ZoneId: zoneIdForSearch(), FuelTypeId: fuelTypeIdForSearch() }; var temperatureParameters = { FacilityTypeId: FT.OUTDOOR, FacilityCode: FC.OUTDOOR, FormulaId: F[FT.OUTDOOR].TEMPERATURE, }; var humidityParameters = _.extend({}, temperatureParameters, { FormulaId: F[FT.OUTDOOR].HUMIDITY, }); $.when( //pointHistoryGet.apiGet(_.extend(pointHistoryParameters, commonParameters))) pointHistoryGet.apiGet(_.extend(pointHistoryParameters, commonParameters)), formulaGet.apiGet(_.extend(temperatureParameters, commonParameters)), formulaGet.apiGet(_.extend(humidityParameters, commonParameters))) .done(function (values, temperatures, humidities) { var maxValue = 0; var dataArray_Temp = []; var dataArray_Temp1 = []; var dataArray_Temp2 = []; var dataArray_Temp3 = []; _.each(values[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Value: x.Value }); }); if (temperatures[0].length > 0) { // 2017 02 17 if (temperatures[0][temperatures[0].length - 1].Value == 0 && humidities[0][humidities[0].length - 1].Value == 0 && temperatures[0][temperatures[0].length - 1].DateTime == humidities[0][humidities[0].length - 1].DateTime) { temperatures[0].splice(temperatures[0].length - 1, 1); humidities[0].splice(humidities[0].length - 1, 1); } } _.each(temperatures[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Temperature: x.Value }); }); _.each(humidities[0], function (x) { dataArray.push({ DateTime: moment(x.DateTime).toDate(), Humidity: x.Value }) }); // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 _.each(values[0], function (x) { dataArray_Temp.push({ DateTime: BWA.Chart.getCustermTimeArgumentAxisString($Code.TimeType.QUARTERMIN, moment(x.DateTime).toDate()), Value: x.Value, }); }); _.each(values[0], function (x) { if (maxValue < x.Value) { maxValue = x.Value; } }); _.each(temperatures[0], function (x) { dataArray_Temp1.push({ DateTime: moment(x.DateTime).toDate(), Temperature: x.Value }); }); _.each(humidities[0], function (x) { dataArray_Temp2.push({ DateTime: moment(x.DateTime).toDate(), Humidity: x.Value }) }); // 배열을 하나로 합치자 var array_length_size = Math.max(dataArray_Temp.length, dataArray_Temp1.length, dataArray_Temp2.length); // 크기가 동일한 경우에만 허용함 (예외 방어용) if ((dataArray_Temp.length == dataArray_Temp1.length) && (dataArray_Temp.length == dataArray_Temp2.length)) { for (var i = 0; i < array_length_size; i++) { dataArray_Temp3.push( { DateTime: dataArray_Temp[i].DateTime, Value: dataArray_Temp[i].Value, Temperature: dataArray_Temp1[i].Temperature, Humidity: dataArray_Temp2[i].Humidity }); } // 만약 일렬로 병합을 원한다면 아래코드를 사용 //dataArray_Temp = dataArray_Temp1.concat(dataArray_Temp2); } dataArrayresult = dataArray_Temp3; // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 switch (fuelTypeIdForSearch()) { case $Code.FuelType.ELECTRICITY: goalUpperBound(500000); value_name = "전기"; //추가 break; case $Code.FuelType.GAS: goalUpperBound(180); value_name = "가스"; break; case $Code.FuelType.WATER: goalUpperBound(40); value_name = "수도"; break; } check_button(); //추가 var options = BWA.ChartOptions.RealtimeEnergyConsumption.getSeriesOptions( fuelTypeIdForSearch(), goalUpperBound() ); //var chart = BWA.Chart.Instance('chart', 'dxChart'); //var chart = $('#chartCoolingApproach').dxChart('instance'); //options.valueAxis[0].tickInterval = parseInt(maxValue / 19); options.valueAxis[1].min = -19; options.valueAxis[1].max = 39; options.valueAxis[2].max = 100; options.valueAxis[2].min = 0; options.dataSource = dataArray; chart().option(options); // chart().option('dataSource', dataArray); // chart().option('dataSource', chartDataArray()); // chartDataArray(values); $('#st').text('에너지 사용량 트랜드' + " : " + buildingNameForSearch() + " - " + floorNameForSearch() + " - " + zoneNameForSearch()); visiblePopup(false); }) .fail(function (error) { //alert(error); visiblePopup(false); }); //buildingNameForSearch //$SearchView.visibleObservable(false); } function handleMenuItemClick(e) { var chartIntance = chart(); var chartOptions = chartIntance._options; var series = chartIntance.getAllSeries(); var table = []; var columns = [chartOptions.argumentAxis.title]; var values = {}; _.each(chartOptions.valueAxis, function (a) { columns.push(a.title.text); }); _.each(series, function (s, i) { _.each(s.pointsByArgument, function (point, argument) { var array = values[argument]; if (_.isArray(array) === false) { array = values[argument] = []; } array[i] = point.value; }); }); var csvRows = [columns.join(',')]; _.each(values, function (values, argument) { csvRows.push([$G.dateTime(moment(Number(argument))), values.join(',')].join(',')); }); var csvContent = csvRows.join("\r\n"); var agent = navigator.userAgent.toLowerCase(); if (window.navigator.msSaveOrOpenBlob) { var fileData = ['\uFEFF' + csvContent]; var blobObject = new Blob(fileData); window.navigator.msSaveOrOpenBlob(blobObject, 'export.csv'); } else { var csvString = 'data:text/csv;utf-8,\uFEFF' + encodeURI(csvContent); var a = $('#csvExporter'); a.attr({ 'href': csvString, 'target': '_blank', 'download': 'export.csv' }); // a.trigger('click'); var aa = document.getElementById('csvExporter'); aa.click(); } } // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 function DataGridPopup_ButtonClick() { // DevExpress.ui.notify("날짜가 일치하지 않는 데이타가 존재합니다", "fail", 1000); DataGridPopup_Visible(true); } function handlePopupShown() { // 컬럼명 업데이트 var ColumnCaptionName = ""; switch (fuelTypeIdForSearch()) { case $Code.FuelType.ELECTRICITY: ColumnCaptionName = "전기"; break; case $Code.FuelType.GAS: ColumnCaptionName = "가스"; break; case $Code.FuelType.WATER: ColumnCaptionName = "수도"; break; } viewModel.RealtimeEnergyConsumptionDataGridOptions.columns[1].caption = ColumnCaptionName; // 데이타소스 업데이트 $("#RealtimeEnergyConsumptionDataGrid_Container").dxDataGrid("instance").option("dataSource", dataArrayresult); // 팝업창 갱신 DataGridPopup_Visible(true); // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 } /* check_input.subscribe(checkboxTest); check_input2.subscribe(checkboxTest); function checkboxTest() { //dayEnergyUsageChart().option('series', series); alert(check_input()); }*/ var viewModel = $.extend(BWA.CommonView.create( params, viewInfo, searchViewOptions, ko.observable(null), handleViewShown, null, handleSearchInSearchView, handleSearchViewInitializeUpdate), { refreshList: refreshList, viewShowing: handleViewShowing, viewHidden: handleViewHidden, // hcLee 2015 03 23 //viewDisposing: handleViewHidden, // hcLee 2015 03 23 locationEnableForSearch: locationEnableForSearch, handleMenuItemClick: handleMenuItemClick, menuItems: [{ text: '엑셀(csv) 내보내기' }] // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 , RealtimeEnergyConsumptionDataGridPopup_ButtonClicked: DataGridPopup_ButtonClick // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 }); // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 // 그래프 도표 팝업창 viewModel.RealtimeEnergyConsumptionDataGridPopupOptions = { width: '480px', height: '830px', // cyim 2017.05.30 : 테스트 결과 Devextreme 버그임. px 로 지정하면 초기 출력시 정확하게 가운데에 있지만, auto 설정시 화면아래에 위치하게 됨 contentTemplate: "content", showTitle: true, title: "도표", visible: DataGridPopup_Visible, dragEnabled: true, closeOnOutsideClick: true, shownAction: handlePopupShown, animation: window.utils.popup.createAnimation(), shading: false }; // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 $HourGlassPopup(viewModel, visiblePopup); //viewModel.check_input = check_input; //viewModel.check_input2 = check_input2; // 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 // 주석이 너무 없음. 나중에 변경 작업을 진행하는 누군가가 시간 소비를 하지 않기 위해...남김 // 시간 포맷은 그래프에 귀속해야 되므로 포맷은 변경하지 않는 것이 유리함 // 전기,가스,수도 와 같이 선택적으로 변경해야 된다면 아래와 같이 캡션은 고정하지 말것 viewModel.RealtimeEnergyConsumptionDataGridOptions = { dataSource: dataArrayresult, columns: [ { dataField: 'DateTime', caption: "날짜", width: '40%', alignment: 'center' },// dataType: 'date', format: 'yyyy-MM-dd HH:mm' }, { dataField: 'Value', width: '32%', alignment: 'center', format: 'fixedPoint', precision: 2 }, { dataField: 'Temperature', caption: "외기온도", width: '32%', alignment: 'center', format: 'fixedPoint', precision: 2 }, { dataField: 'Humidity', caption: "외기습도", width: '32%', alignment: 'center', format: 'fixedPoint', precision: 2 } ], // 엑셀 출력 "export": { enabled: true, fileName: '에너지 사용량 트랜드' } }; /// 2017.09.08 : 그리드 도표 작업 : 팝업창 추가 return viewModel; };