| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 | Partials.Boiler = function (params) {    var dateBoxValue = ko.observable(new Date((new Date).getTime() + (24 * 60 * 60 * 1000)));    var initialized = false;    var dataSource;    var rawData = ko.observable();    function createDataSource() {        return new DevExpress.data.DataSource({            store: Partials.db.BemsDeviceRunHourly,            paginate: false,            select: ['RunDate', 'Temperature', 'Loads', 'BemsDeviceRunHourlyCombine', 'BemsDeviceRunHourlyCost'],            expand: ['BemsDeviceRunHourlyCombine', 'BemsDeviceRunHourlyCost', 'BemsDeviceRunHourlyCombine/BemsDevice', 'BemsDeviceRunHourlyCombine/BemsDevice/BemsDeviceType'],            map: function (item) {                item.Hour = moment(item.RunDate).format("H");                item.Loads = parseInt(item.Loads);                /**                 * 시설가동 및 온도 그래프를 위해                 */                item.Boiler = item.BemsDeviceRunHourlyCombine.reduce(function (p, c) { return (c.BemsDevice.DeviceTypeId == 5) ? (c.BemsDevice.Calorie * c.BemsDevice.Capacity) + p : p; }, 0);                /**                 * 생산열량 및 사용금액 그래프를 위해                 */                item.Calories = item.Boiler;                item.Electricity = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 1) ? parseInt(c.Cost) + p : p; }, 0);                item.Gas = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 2) ? parseInt(c.Cost) + p : p; }, 0);                item.Water = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 3) ? parseInt(c.Cost) + p : p; }, 0);                item.Chemical = item.BemsDeviceRunHourlyCost.reduce(function (p, c) { return (c.FuelTypeId === 4) ? parseInt(c.Cost) + p : p; }, 0);                return item;            },            filter: [                ["SiteId", "=", 1],                ["BuildingId", "=", 1],                ["ServiceTypeId", "=", 2],                ["year(RunDate)", "=", dateBoxValue().getFullYear()],                ["month(RunDate)", "=", dateBoxValue().getMonth() + 1],                ["day(RunDate)", "=", dateBoxValue().getDate()],            ]        });    }    dateBoxValue.subscribe(function (e) {        dataSource = createDataSource();        handleViewShown();    });    function Temperature(result, initial) {        $.extend(initial, {            cellTemplate: function (e, v) {                $("<div />").text(v.text).appendTo(e);            }        });        return result.reduce(function (p, c) {            var o = new Object();            o[c.Hour] = c.Temperature.toFixed(1);            $.extend(p, o);            return p;        }, initial);    }    function Loads(result, initial) {        $.extend(initial, {            cellTemplate: function (e, v) {                $("<div />").text(v.text).appendTo(e);            }        });        return result.reduce(function (p, c) {            var o = new Object();            o[c.Hour] = c.Loads;            $.extend(p, o);            return p;        }, initial);    }    function Devices(index, result, initial) {        $.extend(initial, {            cellTemplate: function (e, v) {                if (v.value) {                    $("<div style='float:left; clear:both' />").text(v.value.BemsDevice.BemsDeviceType.Name).appendTo(e);                    $("<div style='float:left;clear:both' />").text(v.value.BemsDevice.Name).appendTo(e);                    $("<div style='float:right' />").text(Globalize.format(v.value.BemsDevice.Calorie * v.value.BemsDevice.Capacity, "n0")).appendTo(e);                } else {                    $("<div style='height:38px' />").appendTo(e);                }            }        });        return result.reduce(function (p, c) {            if (c.BemsDeviceRunHourlyCombine[0]) {                var o = new Object();                o[c.Hour] = c.BemsDeviceRunHourlyCombine[index];                $.extend(p, o);            }            return p;        }, initial);    }    function DevicesSummary(result, initial) {        $.extend(initial, {            cellTemplate: function (e, v) {                if (v.value) {                    var sum = v.value.reduce(function(prev ,current) {                        return  (current.BemsDevice.Calorie * current.BemsDevice.Capacity) + prev;                    }, 0 );                    $("<div />").text(Globalize.format(sum)).appendTo(e);                }            }        });        return result.reduce(function (p, c) {            if (c.BemsDeviceRunHourlyCombine) {                var o = new Object();                o[c.Hour] = c.BemsDeviceRunHourlyCombine;                $.extend(p, o);            }            return p;        }, initial);    }    function Cost(fuelTypeId, result, initial) {        $.extend(initial, {            cellTemplate: function (e, v) {                if (v.value) {                    $("<div style='width:100%;text-align:right' />").text(Globalize.format(parseInt(v.value.Consume))).appendTo(e);                    $("<div style='width:100%;text-align:right' />").text(Globalize.format(parseInt(v.value.Cost), 'c')).appendTo(e);                } else {                    $("<div style='height:38px' />").appendTo(e);                }            }        });        return result.reduce(function (p, c) {            if (c.BemsDeviceRunHourlyCost) {                var cost = c.BemsDeviceRunHourlyCost.filter(function (v) { return v.FuelTypeId === fuelTypeId; })[0];                 if (cost) {                    var o = new Object();                    o[c.Hour] = cost;                    $.extend(p, o);                }            }            return p;        }, initial);    }    function load(result) {        rawData(result);        var data = new Array();        data.push(Temperature(result, { Group: 0, Item: '온도(℃)' }));        data.push(Loads(result, { Group: 0, Item: '부하량(cal)' }));        data.push(Devices(0, result, { Group: 1, Item: '1' }));        data.push(Devices(1, result, { Group: 1, Item: '2' }));        data.push(Devices(2, result, { Group: 1, Item: '3' }));        data.push(Devices(3, result, { Group: 1, Item: '4' }));        data.push(DevicesSummary(result, { Group: 1, Item: '합계(cal)' }));        data.push(Cost(1, result, { Group: 2, Item: '전기 (kWh)' }));        data.push(Cost(2, result, { Group: 2, Item: '가스 (㎥/h)' }));        data.push(Cost(3, result, { Group: 2, Item: '수도 (㎥/h)' }));        data.push(Cost(4, result, { Group: 2, Item: '약품 (ℓ)' }));        $("#gridContainer").dxDataGrid({            dataSource: data,            showBorders: true,            showRowLines: true,            columnFixing: {                enabled: true            },            columns: [                {                    dataField: "Group", caption: '', groupIndex: 0, customizeText: function (cellinfo) {                        if (cellinfo.value === 0) return '예측';                        if (cellinfo.value === 1) return '가동설비 및 생산열량 (cal)';                        if (cellinfo.value === 2) return '에너지 사용량 및 비용';                        return '';                    }                },                { dataField: 'Item', caption: '시간', width: 110, alignment: 'center', fixed: true },                { dataField: '0', caption: '00시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v);  }  },                { dataField: '1', caption: '01시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '2', caption: '02시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '3', caption: '03시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '4', caption: '04시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '5', caption: '05시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '6', caption: '06시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '7', caption: '07시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '8', caption: '08시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '9', caption: '09시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '10', caption: '10시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '11', caption: '11시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '12', caption: '12시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '13', caption: '13시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '14', caption: '14시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '15', caption: '15시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '16', caption: '16시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '17', caption: '17시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '18', caption: '18시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '19', caption: '19시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '20', caption: '20시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '21', caption: '21시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '22', caption: '22시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },                { dataField: '23', caption: '23시', width: 140, alignment: 'center', format: 'fixedPoint', cellTemplate: function (e, v) { v.data.cellTemplate(e, v); } },            ]        });    }    var devicesChartOption = {        dataSource: rawData,        commonSeriesSettings: {            argumentField: "Hour",            type: "Bar",            hoverMode: "allArgumentPoints",            selectionMode: "allArgumentPoints",        },        argumentAxis: {            label: {                customizeText: function () {                    return this.value + '시';                }            }        },        valueAxis: [            {                name: 'valueAxis',                label: {                    format: 'fixedPoint millions',                    customizeText: function () {                        return this.valueText + ' cal';                    }                }            }, {                name: 'tempAxis',                position: 'right',                label: {                    precision: 0,                    customizeText: function () {                        return this.value + ' ℃';                    },                },                maxValueMargin: 0.1,                minValueMargin: 0.1,                min: -10,                max: 30            }        ],        series: [            { name: "보일러", color: "#c0222f", valueField: "Boiler" },            { name: "온도", type: "spline", color: "#9dD5ad", valueField: "Temperature", axis: 'tempAxis' },        ],        legend: {            verticalAlignment: "top",            horizontalAlignment: "right",            position: "inside",            border: { visible: true }        },        onPointClick: function (e) {            e.target.select();        },        tooltip: {            enabled: true,            location: "edge",            format: 'fixedPoint',            customizeTooltip: function (point) {                return point.seriesName + " : " + point.valueText;            }        }    };    var pricesChartOption = {        dataSource: rawData,        commonSeriesSettings: {            argumentField: "Hour",            type: "Bar",            hoverMode: "allArgumentPoints",            selectionMode: "allArgumentPoints",        },        argumentAxis: {            label: {                customizeText: function () {                    return this.value + '시';                }            }        },        valueAxis: [            {                name: 'valueAxis',                label: {                    format: 'currency',                    customizeText: function () {                        return this.valueText;                    }                }            }, {                name: 'caloriesAxis',                position: 'right',                label: {                    precision: 0,                    format: 'fixedPoint millions',                    customizeText: function () {                        return this.valueText + 'cal';                    },                },                maxValueMargin: 0.1,                minValueMargin: 1,            }        ],        series: [            { name: "전기", color: "#70cbed", valueField: "Electricity" },            { name: "가스", color: "#bad5a4", valueField: "Gas" },            { name: "수도", color: "#c0222f", valueField: "Water" },            { name: "약품", color: "#f2c899", valueField: "Chemical" },            { name: "생산열량", type: "line", color: "#9da5ad", valueField: "Calories", axis: 'caloriesAxis' },        ],        legend: {            verticalAlignment: "top",            horizontalAlignment: "right",            position: "inside",            border: { visible: true }        },        onPointClick: function (e) {            e.target.select();        },        tooltip: {            enabled: true,            location: "edge",            format: 'fixedPoint',            customizeTooltip: function (point) {                return point.seriesName + " : " + point.valueText;            }        }    };    var operateGridOption = {        dataSource: new DevExpress.data.DataSource({            store: Partials.db.BemsDevice,            select: ['SiteId', 'BuildingId', 'DeviceId', 'Name', 'BemsDeviceType/Name', 'BemsZone/Name', 'Capacity', 'Calorie', 'IsUse'],            expand: ['BemsDeviceType', 'BemsZone'],            map: function (item) {                return item;            },            filter: [                ["SiteId", "=", 1],                ["BuildingId", "=", 1],                ["DeviceTypeId", "=", 5],            ]        }),        paging: { enabled: false },        showColumnLines: false,        showRowLines: true,        hoverStateEnabled: true,        editing: { editMode: 'batch', editEnabled: true, },        rowUpdating: function (rowInfo) {            Partials.db.BemsDevice.update(rowInfo.key, rowInfo.newData);        },        columns: [            { dataField: 'Name', caption: '설비명칭', alignment:'right', allowEditing:false, },            { dataField: 'BemsDeviceType.Name', caption: '방식', width: 100, alignment: 'right', allowEditing: false },            { dataField: 'BemsZone.Name', caption: '장소', width: 220, alignment: 'right', allowEditing: false },            { dataField: 'Capacity', caption: '용량(RT)', format: 'fixedPoint', allowEditing: false },            { dataField: 'Calorie', caption: '열량(cal)', format: 'fixedPoint', allowEditing: false },            { dataField: 'IsUse', caption: '사용', alignment: 'center', },        ]    };    var graphViewPopup = {        width: 1200,        height: 600,        showTitle: true,        title: ko.computed({            read: function () {                return moment(dateBoxValue()).format("YYYY년 MM월 D일");            }        }),        visible: ko.observable(false),        dragEnabled: false,        closeOnOutsideClick: false,        show: function () {            graphViewPopup.visible(true);        },        shownAction: function () {        }    };    var predictPopup = {        width: 800,        height: 'auto',        showTitle: true,        weatherDataSource: ko.observable(),        zoneDataSource: ko.observable(),        buttons: [            {                toolbar: 'bottom', location: 'after', widget: 'button', options: {                    text: '예측', clickAction: function () {                        var tomorrow = new Date();                        tomorrow.setDate(tomorrow.getDate() + 1);                        if (moment(tomorrow).format('YYYYMMDD') === moment(dateBoxValue()).format('YYYYMMDD')) {                            Partials.api.post('ExecuteLoadsHourly', { SiteId: 1, ServiceTypeId: 2, CreatedDate: dateBoxValue() }).done(function (result) {                                viewModel.predictPopup.visible(false);                                viewModel.viewShown();                            });                        } else {                            DevExpress.ui.dialog.alert('익일 부하예측만 가능합니다.', '알림');                        }                    }                }            }        ],        title: ko.computed({            read: function () {                return moment(dateBoxValue()).format("YYYY년 MM월 D일");            }        }),        visible: ko.observable(false),        dragEnabled: false,        closeOnOutsideClick: false,        show: function () {            predictPopup.visible(true);        },        showingAction: function () {            predictPopup.weatherDataSource = new DevExpress.data.DataSource({                store: Partials.db.BemsWeatherHourly,                paginate: false,                map: function (item) {                    return item;                },                filter: [                    ["SiteId", "=", 1],                    ["year(CreatedDate)", "=", dateBoxValue().getFullYear()],                    ["month(CreatedDate)", "=", dateBoxValue().getMonth() + 1],                    ["day(CreatedDate)", "=", dateBoxValue().getDate()],                ]            });            predictPopup.zoneDataSource = new DevExpress.data.DataSource({                store: Partials.db.BemsZoneActivateDaily,                expand: ['BemsZoneActivate', 'BemsZoneActivate/BemsZone'],                paginate: false,                map: function (item) {                    return item;                },                filter: [                    ["SiteId", "=", 1],                    ["BuildingId", "=", 1],                    ["ServiceTypeId", "=", 2],                    ["year(CreatedDate)", "=", dateBoxValue().getFullYear()],                    ["month(CreatedDate)", "=", dateBoxValue().getMonth() + 1],                    ["day(CreatedDate)", "=", dateBoxValue().getDate()],                ]            });        },        shownAction: function () {            predictPopup.weatherDataSource.load().done(function (result) {                var dataGrid = $("#weatherGrid").dxDataGrid("instance");                dataGrid.option({                    dataSource: result,                    editing: { editMode: 'batch', editEnabled: true, },                    rowUpdating: function (rowInfo) {                        var key = new Partials.BemsWeatherHourlyViewModel(rowInfo.key);                        Partials.db.BemsWeatherHourly.update(key.toJS(), rowInfo.newData);                    },                    columns: [                        {                            dataField: 'CreatedDate', caption: '시간', width: '10%', alignment: 'right', allowEditing: false, customizeText: function (cellInfo) {                                return moment(cellInfo.value).format("H");                            }                        },                        { dataField: 'Temperature', caption: '온도(℃)', format: 'fixedPoint', precision: 1, },                        { dataField: 'Humidity', caption: '습도(%)', format: 'fixedPoint', precision: 0, },                        { dataField: 'Wind', caption: '풍속(m/s)', format: 'fixedPoint', precision: 2, },                        { dataField: 'Rainfall', caption: '강수량(mm)', format: 'fixedPoint', precision: 2, },                    ]                });            });            predictPopup.zoneDataSource.load().done(function (result) {                var dataGrid = $("#zoneGrid").dxDataGrid("instance");                dataGrid.option({                    dataSource: result,                    editing: { editMode: 'batch', editEnabled: true, },                    columnFixing: {                        enabled: true                    },                    rowUpdating: function (rowInfo) {                        Partials.db.BemsZoneActivateDaily.update(rowInfo.key, rowInfo.newData);                    },                    columns: [                        { dataField: 'BemsZoneActivate.BemsZone.Name', caption: '시설명', fixed: true, width: 150, allowEditing: false },                        { dataField: 'BemsZoneActivate.Loads', caption: '부하(cal)', fixed: true, format: 'fixedPoint', width: 110, alignment: 'right', allowEditing: false },                        { dataField: 'BemsZoneActivate.RateOfWork', caption: '가동율(%)', fixed: true, format: 'fixedPoint', precision: 2, width: 100, alignment: 'right', allowEditing: false },                        { dataField: 'H00', caption: '00시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H01', caption: '01시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H02', caption: '02시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H03', caption: '03시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H04', caption: '04시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H05', caption: '05시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H06', caption: '06시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H07', caption: '07시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H08', caption: '08시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H09', caption: '09시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H10', caption: '10시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H11', caption: '11시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H12', caption: '12시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H13', caption: '13시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H14', caption: '14시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H15', caption: '15시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H16', caption: '16시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H17', caption: '17시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H18', caption: '18시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H19', caption: '19시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H20', caption: '20시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H21', caption: '21시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H22', caption: '22시', width: 50, alignment: 'center', dataType: 'boolean', },                        { dataField: 'H23', caption: '23시', width: 50, alignment: 'center', dataType: 'boolean', },                    ]                });            });        }    };    var operatePopup = {        width: 700,        height: 'auto',        showTitle: true,        title: ko.computed({            read: function () {                return moment(dateBoxValue()).format("YYYY년 MM월 D일");            }        }),        visible: ko.observable(false),        dragEnabled: false,        closeOnOutsideClick: false,        buttons: [            {                toolbar: 'bottom', location: 'after', widget: 'button', options: {                    text: '산출하기', clickAction: function () {                        var tomorrow = new Date();                        tomorrow.setDate(tomorrow.getDate() + 1);                        if (moment(tomorrow).format('YYYYMMDD') === moment(dateBoxValue()).format('YYYYMMDD')) {                            Partials.api.post('OptimalDeviceRunHourly', { SiteId: 1, BuildingId: 1, ServiceTypeId: 2, RunDate: dateBoxValue() }).done(function (result) {                                viewModel.operatePopup.visible(false);                                viewModel.viewShown();                            });                        } else {                            DevExpress.ui.dialog.alert('익일 최적운전 산출이 가능합니다.', '알림');                        }                    }                }            }        ],        show: function () {            operatePopup.visible(true);        },        shownAction: function () {            $("#operateGrid").dxDataGrid("instance").dataSource.load();        }    };    var handleViewShown = function () {        if (initialized == false) {            initialized = true;            dataSource = createDataSource();        }        dataSource.load().done(function (result) {            load(result);        });    };    var viewModel = {        dateBoxValue: dateBoxValue,        devicesChartOption: devicesChartOption,        pricesChartOption: pricesChartOption,        operateGridOption: operateGridOption,        viewShown: handleViewShown,        graphViewPopup: graphViewPopup,        operatePopup: operatePopup,        predictPopup: predictPopup,        onPrevious: function (e) {            var date = new Date(dateBoxValue());            date.setDate(date.getDate() - 1);            dateBoxValue(date);        },        onNext: function (e) {            var date = new Date(dateBoxValue());            date.setDate(date.getDate() + 1)            dateBoxValue(date);        }    };    return viewModel;};
 |