841be49c45197447aa4dae1bb1093673a9b04860.svn-base 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. Partials.Boiler = function (params) {
  2. var dateBoxValue = ko.observable(new Date((new Date).getTime() + (24 * 60 * 60 * 1000)));
  3. var initialized = false;
  4. var dataSource;
  5. var rawData = ko.observable();
  6. function createDataSource() {
  7. return new DevExpress.data.DataSource({
  8. store: Partials.db.BemsDeviceRunHourly,
  9. paginate: false,
  10. select: ['RunDate', 'Temperature', 'Loads', 'BemsDeviceRunHourlyCombine', 'BemsDeviceRunHourlyCost'],
  11. expand: ['BemsDeviceRunHourlyCombine', 'BemsDeviceRunHourlyCost', 'BemsDeviceRunHourlyCombine/BemsDevice', 'BemsDeviceRunHourlyCombine/BemsDevice/BemsDeviceType'],
  12. map: function (item) {
  13. item.Hour = moment(item.RunDate).format("H");
  14. item.Loads = parseInt(item.Loads);
  15. /**
  16. * 시설가동 및 온도 그래프를 위해
  17. */
  18. item.Boiler = item.BemsDeviceRunHourlyCombine.reduce(function (p, c) { return (c.BemsDevice.DeviceTypeId == 5) ? (c.BemsDevice.Calorie * c.BemsDevice.Capacity) + p : p; }, 0);
  19. /**
  20. * 생산열량 및 사용금액 그래프를 위해
  21. */
  22. item.Calories = item.Boiler;
  23. item.Electricity = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 1) ? parseInt(c.Cost) + p : p; }, 0);
  24. item.Gas = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 2) ? parseInt(c.Cost) + p : p; }, 0);
  25. item.Water = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 3) ? parseInt(c.Cost) + p : p; }, 0);
  26. item.Chemical = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 4) ? parseInt(c.Cost) + p : p; }, 0);
  27. return item;
  28. },
  29. filter: [
  30. ["SiteId", "=", 1],
  31. ["BuildingId", "=", 1],
  32. ["ServiceTypeId", "=", 2],
  33. ["year(RunDate)", "=", dateBoxValue().getFullYear()],
  34. ["month(RunDate)", "=", dateBoxValue().getMonth() + 1],
  35. ["day(RunDate)", "=", dateBoxValue().getDate()],
  36. ]
  37. });
  38. }
  39. dateBoxValue.subscribe(function (e) {
  40. dataSource = createDataSource();
  41. handleViewShown();
  42. });
  43. function Temperature(result, initial) {
  44. $.extend(initial, {
  45. cellTemplate: function (e, v) {
  46. $("<div />").text(v.text).appendTo(e);
  47. }
  48. });
  49. return result.reduce(function (p, c) {
  50. var o = new Object();
  51. o[c.Hour] = c.Temperature.toFixed(1);
  52. $.extend(p, o);
  53. return p;
  54. }, initial);
  55. }
  56. function Loads(result, initial) {
  57. $.extend(initial, {
  58. cellTemplate: function (e, v) {
  59. $("<div />").text(v.text).appendTo(e);
  60. }
  61. });
  62. return result.reduce(function (p, c) {
  63. var o = new Object();
  64. o[c.Hour] = c.Loads;
  65. $.extend(p, o);
  66. return p;
  67. }, initial);
  68. }
  69. function Devices(index, result, initial) {
  70. $.extend(initial, {
  71. cellTemplate: function (e, v) {
  72. if (v.value) {
  73. $("<div style='float:left; clear:both' />").text(v.value.BemsDevice.BemsDeviceType.Name).appendTo(e);
  74. $("<div style='float:left;clear:both' />").text(v.value.BemsDevice.Name).appendTo(e);
  75. $("<div style='float:right' />").text(Globalize.format(v.value.BemsDevice.Calorie * v.value.BemsDevice.Capacity, "n0")).appendTo(e);
  76. } else {
  77. $("<div style='height:38px' />").appendTo(e);
  78. }
  79. }
  80. });
  81. return result.reduce(function (p, c) {
  82. if (c.BemsDeviceRunHourlyCombine[0]) {
  83. var o = new Object();
  84. o[c.Hour] = c.BemsDeviceRunHourlyCombine[index];
  85. $.extend(p, o);
  86. }
  87. return p;
  88. }, initial);
  89. }
  90. function DevicesSummary(result, initial) {
  91. $.extend(initial, {
  92. cellTemplate: function (e, v) {
  93. if (v.value) {
  94. var sum = v.value.reduce(function(prev ,current) {
  95. return (current.BemsDevice.Calorie * current.BemsDevice.Capacity) + prev;
  96. }, 0 );
  97. $("<div />").text(Globalize.format(sum)).appendTo(e);
  98. }
  99. }
  100. });
  101. return result.reduce(function (p, c) {
  102. if (c.BemsDeviceRunHourlyCombine) {
  103. var o = new Object();
  104. o[c.Hour] = c.BemsDeviceRunHourlyCombine;
  105. $.extend(p, o);
  106. }
  107. return p;
  108. }, initial);
  109. }
  110. function Cost(fuelTypeId, result, initial) {
  111. $.extend(initial, {
  112. cellTemplate: function (e, v) {
  113. if (v.value) {
  114. $("<div style='width:100%;text-align:right' />").text(Globalize.format(parseInt(v.value.Consume))).appendTo(e);
  115. $("<div style='width:100%;text-align:right' />").text(Globalize.format(parseInt(v.value.Cost), 'c')).appendTo(e);
  116. } else {
  117. $("<div style='height:38px' />").appendTo(e);
  118. }
  119. }
  120. });
  121. return result.reduce(function (p, c) {
  122. if (c.BemsDeviceRunHourlyCost) {
  123. var cost = c.BemsDeviceRunHourlyCost.filter(function (v) { return v.FuelTypeId === fuelTypeId; })[0];
  124. if (cost) {
  125. var o = new Object();
  126. o[c.Hour] = cost;
  127. $.extend(p, o);
  128. }
  129. }
  130. return p;
  131. }, initial);
  132. }
  133. function load(result) {
  134. rawData(result);
  135. var data = new Array();
  136. data.push(Temperature(result, { Group: 0, Item: '온도(℃)' }));
  137. data.push(Loads(result, { Group: 0, Item: '부하량(cal)' }));
  138. data.push(Devices(0, result, { Group: 1, Item: '1' }));
  139. data.push(Devices(1, result, { Group: 1, Item: '2' }));
  140. data.push(Devices(2, result, { Group: 1, Item: '3' }));
  141. data.push(Devices(3, result, { Group: 1, Item: '4' }));
  142. data.push(DevicesSummary(result, { Group: 1, Item: '합계(cal)' }));
  143. data.push(Cost(1, result, { Group: 2, Item: '전기 (kWh)' }));
  144. data.push(Cost(2, result, { Group: 2, Item: '가스 (㎥/h)' }));
  145. data.push(Cost(3, result, { Group: 2, Item: '수도 (㎥/h)' }));
  146. data.push(Cost(4, result, { Group: 2, Item: '약품 (ℓ)' }));
  147. $("#gridContainer").dxDataGrid({
  148. dataSource: data,
  149. showBorders: true,
  150. showRowLines: true,
  151. columnFixing: {
  152. enabled: true
  153. },
  154. columns: [
  155. {
  156. dataField: "Group", caption: '', groupIndex: 0, customizeText: function (cellinfo) {
  157. if (cellinfo.value === 0) return '예측';
  158. if (cellinfo.value === 1) return '가동설비 및 생산열량 (cal)';
  159. if (cellinfo.value === 2) return '에너지 사용량 및 비용';
  160. return '';
  161. }
  162. },
  163. { dataField: 'Item', caption: '시간', width: 110, alignment: 'center', fixed: true },
  164. { dataField: '0', caption: '00시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  165. { dataField: '1', caption: '01시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  166. { dataField: '2', caption: '02시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  167. { dataField: '3', caption: '03시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  168. { dataField: '4', caption: '04시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  169. { dataField: '5', caption: '05시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  170. { dataField: '6', caption: '06시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  171. { dataField: '7', caption: '07시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  172. { dataField: '8', caption: '08시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  173. { dataField: '9', caption: '09시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  174. { dataField: '10', caption: '10시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  175. { dataField: '11', caption: '11시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  176. { dataField: '12', caption: '12시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  177. { dataField: '13', caption: '13시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  178. { dataField: '14', caption: '14시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  179. { dataField: '15', caption: '15시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  180. { dataField: '16', caption: '16시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  181. { dataField: '17', caption: '17시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  182. { dataField: '18', caption: '18시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  183. { dataField: '19', caption: '19시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  184. { dataField: '20', caption: '20시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  185. { dataField: '21', caption: '21시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  186. { dataField: '22', caption: '22시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  187. { dataField: '23', caption: '23시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },
  188. ]
  189. });
  190. }
  191. var devicesChartOption = {
  192. dataSource: rawData,
  193. commonSeriesSettings: {
  194. argumentField: "Hour",
  195. type: "Bar",
  196. hoverMode: "allArgumentPoints",
  197. selectionMode: "allArgumentPoints",
  198. },
  199. argumentAxis: {
  200. label: {
  201. customizeText: function () {
  202. return this.value + '시';
  203. }
  204. }
  205. },
  206. valueAxis: [
  207. {
  208. name: 'valueAxis',
  209. label: {
  210. format: 'fixedPoint millions',
  211. customizeText: function () {
  212. return this.valueText + ' cal';
  213. }
  214. }
  215. }, {
  216. name: 'tempAxis',
  217. position: 'right',
  218. label: {
  219. precision: 0,
  220. customizeText: function () {
  221. return this.value + ' ℃';
  222. },
  223. },
  224. maxValueMargin: 0.1,
  225. minValueMargin: 0.1,
  226. min: -10,
  227. max: 30
  228. }
  229. ],
  230. series: [
  231. { name: "보일러", color: "#c0222f", valueField: "Boiler" },
  232. { name: "온도", type: "spline", color: "#9dD5ad", valueField: "Temperature", axis: 'tempAxis' },
  233. ],
  234. legend: {
  235. verticalAlignment: "top",
  236. horizontalAlignment: "right",
  237. position: "inside",
  238. border: { visible: true }
  239. },
  240. onPointClick: function (e) {
  241. e.target.select();
  242. },
  243. tooltip: {
  244. enabled: true,
  245. location: "edge",
  246. format: 'fixedPoint',
  247. customizeTooltip: function (point) {
  248. return point.seriesName + " : " + point.valueText;
  249. }
  250. }
  251. };
  252. var pricesChartOption = {
  253. dataSource: rawData,
  254. commonSeriesSettings: {
  255. argumentField: "Hour",
  256. type: "Bar",
  257. hoverMode: "allArgumentPoints",
  258. selectionMode: "allArgumentPoints",
  259. },
  260. argumentAxis: {
  261. label: {
  262. customizeText: function () {
  263. return this.value + '시';
  264. }
  265. }
  266. },
  267. valueAxis: [
  268. {
  269. name: 'valueAxis',
  270. label: {
  271. format: 'currency',
  272. customizeText: function () {
  273. return this.valueText;
  274. }
  275. }
  276. }, {
  277. name: 'caloriesAxis',
  278. position: 'right',
  279. label: {
  280. precision: 0,
  281. format: 'fixedPoint millions',
  282. customizeText: function () {
  283. return this.valueText + 'cal';
  284. },
  285. },
  286. maxValueMargin: 0.1,
  287. minValueMargin: 1,
  288. }
  289. ],
  290. series: [
  291. { name: "전기", color: "#70cbed", valueField: "Electricity" },
  292. { name: "가스", color: "#bad5a4", valueField: "Gas" },
  293. { name: "수도", color: "#c0222f", valueField: "Water" },
  294. { name: "약품", color: "#f2c899", valueField: "Chemical" },
  295. { name: "생산열량", type: "line", color: "#9da5ad", valueField: "Calories", axis: 'caloriesAxis' },
  296. ],
  297. legend: {
  298. verticalAlignment: "top",
  299. horizontalAlignment: "right",
  300. position: "inside",
  301. border: { visible: true }
  302. },
  303. onPointClick: function (e) {
  304. e.target.select();
  305. },
  306. tooltip: {
  307. enabled: true,
  308. location: "edge",
  309. format: 'fixedPoint',
  310. customizeTooltip: function (point) {
  311. return point.seriesName + " : " + point.valueText;
  312. }
  313. }
  314. };
  315. var operateGridOption = {
  316. dataSource: new DevExpress.data.DataSource({
  317. store: Partials.db.BemsDevice,
  318. select: ['SiteId', 'BuildingId', 'DeviceId', 'Name', 'BemsDeviceType/Name', 'BemsZone/Name', 'Capacity', 'Calorie', 'IsUse'],
  319. expand: ['BemsDeviceType', 'BemsZone'],
  320. map: function (item) {
  321. return item;
  322. },
  323. filter: [
  324. ["SiteId", "=", 1],
  325. ["BuildingId", "=", 1],
  326. ["DeviceTypeId", "=", 5],
  327. ]
  328. }),
  329. paging: { enabled: false },
  330. showColumnLines: false,
  331. showRowLines: true,
  332. hoverStateEnabled: true,
  333. editing: { editMode: 'batch', editEnabled: true, },
  334. rowUpdating: function (rowInfo) {
  335. Partials.db.BemsDevice.update(rowInfo.key, rowInfo.newData);
  336. },
  337. columns: [
  338. { dataField: 'Name', caption: '설비명칭', alignment:'right', allowEditing:false, },
  339. { dataField: 'BemsDeviceType.Name', caption: '방식', width: 100, alignment: 'right', allowEditing: false },
  340. { dataField: 'BemsZone.Name', caption: '장소', width: 220, alignment: 'right', allowEditing: false },
  341. { dataField: 'Capacity', caption: '용량(RT)', format: 'fixedPoint', allowEditing: false },
  342. { dataField: 'Calorie', caption: '열량(cal)', format: 'fixedPoint', allowEditing: false },
  343. { dataField: 'IsUse', caption: '사용', alignment: 'center', },
  344. ]
  345. };
  346. var graphViewPopup = {
  347. width: 1200,
  348. height: 600,
  349. showTitle: true,
  350. title: ko.computed({
  351. read: function () {
  352. return moment(dateBoxValue()).format("YYYY년 MM월 D일");
  353. }
  354. }),
  355. visible: ko.observable(false),
  356. dragEnabled: false,
  357. closeOnOutsideClick: false,
  358. show: function () {
  359. graphViewPopup.visible(true);
  360. },
  361. shownAction: function () {
  362. }
  363. };
  364. var predictPopup = {
  365. width: 800,
  366. height: 'auto',
  367. showTitle: true,
  368. weatherDataSource: ko.observable(),
  369. zoneDataSource: ko.observable(),
  370. buttons: [
  371. {
  372. toolbar: 'bottom', location: 'after', widget: 'button', options: {
  373. text: '예측', clickAction: function () {
  374. var tomorrow = new Date();
  375. tomorrow.setDate(tomorrow.getDate() + 1);
  376. if (moment(tomorrow).format('YYYYMMDD') === moment(dateBoxValue()).format('YYYYMMDD')) {
  377. Partials.api.post('ExecuteLoadsHourly', { SiteId: 1, ServiceTypeId: 2, CreatedDate: dateBoxValue() }).done(function (result) {
  378. viewModel.predictPopup.visible(false);
  379. viewModel.viewShown();
  380. });
  381. } else {
  382. DevExpress.ui.dialog.alert('익일 부하예측만 가능합니다.', '알림');
  383. }
  384. }
  385. }
  386. }
  387. ],
  388. title: ko.computed({
  389. read: function () {
  390. return moment(dateBoxValue()).format("YYYY년 MM월 D일");
  391. }
  392. }),
  393. visible: ko.observable(false),
  394. dragEnabled: false,
  395. closeOnOutsideClick: false,
  396. show: function () {
  397. predictPopup.visible(true);
  398. },
  399. showingAction: function () {
  400. predictPopup.weatherDataSource = new DevExpress.data.DataSource({
  401. store: Partials.db.BemsWeatherHourly,
  402. paginate: false,
  403. map: function (item) {
  404. return item;
  405. },
  406. filter: [
  407. ["SiteId", "=", 1],
  408. ["year(CreatedDate)", "=", dateBoxValue().getFullYear()],
  409. ["month(CreatedDate)", "=", dateBoxValue().getMonth() + 1],
  410. ["day(CreatedDate)", "=", dateBoxValue().getDate()],
  411. ]
  412. });
  413. predictPopup.zoneDataSource = new DevExpress.data.DataSource({
  414. store: Partials.db.BemsZoneActivateDaily,
  415. expand: ['BemsZoneActivate', 'BemsZoneActivate/BemsZone'],
  416. paginate: false,
  417. map: function (item) {
  418. return item;
  419. },
  420. filter: [
  421. ["SiteId", "=", 1],
  422. ["BuildingId", "=", 1],
  423. ["ServiceTypeId", "=", 2],
  424. ["year(CreatedDate)", "=", dateBoxValue().getFullYear()],
  425. ["month(CreatedDate)", "=", dateBoxValue().getMonth() + 1],
  426. ["day(CreatedDate)", "=", dateBoxValue().getDate()],
  427. ]
  428. });
  429. },
  430. shownAction: function () {
  431. predictPopup.weatherDataSource.load().done(function (result) {
  432. var dataGrid = $("#weatherGrid").dxDataGrid("instance");
  433. dataGrid.option({
  434. dataSource: result,
  435. editing: { editMode: 'batch', editEnabled: true, },
  436. rowUpdating: function (rowInfo) {
  437. var key = new Partials.BemsWeatherHourlyViewModel(rowInfo.key);
  438. Partials.db.BemsWeatherHourly.update(key.toJS(), rowInfo.newData);
  439. },
  440. columns: [
  441. {
  442. dataField: 'CreatedDate', caption: '시간', width: '10%', alignment: 'right', allowEditing: false, customizeText: function (cellInfo) {
  443. return moment(cellInfo.value).format("H");
  444. }
  445. },
  446. { dataField: 'Temperature', caption: '온도(℃)', format: 'fixedPoint', precision: 1, },
  447. { dataField: 'Humidity', caption: '습도(%)', format: 'fixedPoint', precision: 0, },
  448. { dataField: 'Wind', caption: '풍속(m/s)', format: 'fixedPoint', precision: 2, },
  449. { dataField: 'Rainfall', caption: '강수량(mm)', format: 'fixedPoint', precision: 2, },
  450. ]
  451. });
  452. });
  453. predictPopup.zoneDataSource.load().done(function (result) {
  454. var dataGrid = $("#zoneGrid").dxDataGrid("instance");
  455. dataGrid.option({
  456. dataSource: result,
  457. editing: { editMode: 'batch', editEnabled: true, },
  458. columnFixing: {
  459. enabled: true
  460. },
  461. rowUpdating: function (rowInfo) {
  462. Partials.db.BemsZoneActivateDaily.update(rowInfo.key, rowInfo.newData);
  463. },
  464. columns: [
  465. { dataField: 'BemsZoneActivate.BemsZone.Name', caption: '시설명', fixed: true, width: 150, allowEditing: false },
  466. { dataField: 'BemsZoneActivate.Loads', caption: '부하(cal)', fixed: true, format: 'fixedPoint', width: 110, alignment: 'right', allowEditing: false },
  467. { dataField: 'BemsZoneActivate.RateOfWork', caption: '가동율(%)', fixed: true, format: 'fixedPoint', precision: 2, width: 100, alignment: 'right', allowEditing: false },
  468. { dataField: 'H00', caption: '00시', width: 50, alignment: 'center', dataType: 'boolean', },
  469. { dataField: 'H01', caption: '01시', width: 50, alignment: 'center', dataType: 'boolean', },
  470. { dataField: 'H02', caption: '02시', width: 50, alignment: 'center', dataType: 'boolean', },
  471. { dataField: 'H03', caption: '03시', width: 50, alignment: 'center', dataType: 'boolean', },
  472. { dataField: 'H04', caption: '04시', width: 50, alignment: 'center', dataType: 'boolean', },
  473. { dataField: 'H05', caption: '05시', width: 50, alignment: 'center', dataType: 'boolean', },
  474. { dataField: 'H06', caption: '06시', width: 50, alignment: 'center', dataType: 'boolean', },
  475. { dataField: 'H07', caption: '07시', width: 50, alignment: 'center', dataType: 'boolean', },
  476. { dataField: 'H08', caption: '08시', width: 50, alignment: 'center', dataType: 'boolean', },
  477. { dataField: 'H09', caption: '09시', width: 50, alignment: 'center', dataType: 'boolean', },
  478. { dataField: 'H10', caption: '10시', width: 50, alignment: 'center', dataType: 'boolean', },
  479. { dataField: 'H11', caption: '11시', width: 50, alignment: 'center', dataType: 'boolean', },
  480. { dataField: 'H12', caption: '12시', width: 50, alignment: 'center', dataType: 'boolean', },
  481. { dataField: 'H13', caption: '13시', width: 50, alignment: 'center', dataType: 'boolean', },
  482. { dataField: 'H14', caption: '14시', width: 50, alignment: 'center', dataType: 'boolean', },
  483. { dataField: 'H15', caption: '15시', width: 50, alignment: 'center', dataType: 'boolean', },
  484. { dataField: 'H16', caption: '16시', width: 50, alignment: 'center', dataType: 'boolean', },
  485. { dataField: 'H17', caption: '17시', width: 50, alignment: 'center', dataType: 'boolean', },
  486. { dataField: 'H18', caption: '18시', width: 50, alignment: 'center', dataType: 'boolean', },
  487. { dataField: 'H19', caption: '19시', width: 50, alignment: 'center', dataType: 'boolean', },
  488. { dataField: 'H20', caption: '20시', width: 50, alignment: 'center', dataType: 'boolean', },
  489. { dataField: 'H21', caption: '21시', width: 50, alignment: 'center', dataType: 'boolean', },
  490. { dataField: 'H22', caption: '22시', width: 50, alignment: 'center', dataType: 'boolean', },
  491. { dataField: 'H23', caption: '23시', width: 50, alignment: 'center', dataType: 'boolean', },
  492. ]
  493. });
  494. });
  495. }
  496. };
  497. var operatePopup = {
  498. width: 700,
  499. height: 'auto',
  500. showTitle: true,
  501. title: ko.computed({
  502. read: function () {
  503. return moment(dateBoxValue()).format("YYYY년 MM월 D일");
  504. }
  505. }),
  506. visible: ko.observable(false),
  507. dragEnabled: false,
  508. closeOnOutsideClick: false,
  509. buttons: [
  510. {
  511. toolbar: 'bottom', location: 'after', widget: 'button', options: {
  512. text: '산출하기', clickAction: function () {
  513. var tomorrow = new Date();
  514. tomorrow.setDate(tomorrow.getDate() + 1);
  515. if (moment(tomorrow).format('YYYYMMDD') === moment(dateBoxValue()).format('YYYYMMDD')) {
  516. Partials.api.post('OptimalDeviceRunHourly', { SiteId: 1, BuildingId: 1, ServiceTypeId: 2, RunDate: dateBoxValue() }).done(function (result) {
  517. viewModel.operatePopup.visible(false);
  518. viewModel.viewShown();
  519. });
  520. } else {
  521. DevExpress.ui.dialog.alert('익일 최적운전 산출이 가능합니다.', '알림');
  522. }
  523. }
  524. }
  525. }
  526. ],
  527. show: function () {
  528. operatePopup.visible(true);
  529. },
  530. shownAction: function () {
  531. $("#operateGrid").dxDataGrid("instance").dataSource.load();
  532. }
  533. };
  534. var handleViewShown = function () {
  535. if (initialized == false) {
  536. initialized = true;
  537. dataSource = createDataSource();
  538. }
  539. dataSource.load().done(function (result) {
  540. load(result);
  541. });
  542. };
  543. var viewModel = {
  544. dateBoxValue: dateBoxValue,
  545. devicesChartOption: devicesChartOption,
  546. pricesChartOption: pricesChartOption,
  547. operateGridOption: operateGridOption,
  548. viewShown: handleViewShown,
  549. graphViewPopup: graphViewPopup,
  550. operatePopup: operatePopup,
  551. predictPopup: predictPopup,
  552. onPrevious: function (e) {
  553. var date = new Date(dateBoxValue());
  554. date.setDate(date.getDate() - 1);
  555. dateBoxValue(date);
  556. },
  557. onNext: function (e) {
  558. var date = new Date(dateBoxValue());
  559. date.setDate(date.getDate() + 1)
  560. dateBoxValue(date);
  561. }
  562. };
  563. return viewModel;
  564. };