6af3dc0ab85bd4ffb610d9ee8809c8bf5a40cb40.svn-base 29 KB

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