diff options
Diffstat (limited to 'www/js')
| -rw-r--r-- | www/js/DataModel.js | 30 | ||||
| -rw-r--r-- | www/js/EventCtrl.js | 90 | ||||
| -rw-r--r-- | www/js/EventDateTimeFilterCtrl.js | 66 | ||||
| -rw-r--r-- | www/js/EventsGraphsCtrl.js | 14 | ||||
| -rw-r--r-- | www/js/TimelineCtrl.js | 503 | ||||
| -rw-r--r-- | www/js/app.js | 68 | ||||
| -rw-r--r-- | www/js/ng.js | 14 |
7 files changed, 600 insertions, 185 deletions
diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 1954d997..695ebd18 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -359,10 +359,21 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion // All this effort because the ZM APIs return events in sorted order, oldest first. Yeesh. //----------------------------------------------------------------------------- - getEventsPages: function (monitorId) { + getEventsPages: function (monitorId,startTime, endTime) { console.log("********** INSIDE EVENTS PAGES "); var apiurl = loginData.apiurl; - var myurl = (monitorId == 0) ? apiurl + "/events.json?page=1" : apiurl + "/events/index/MonitorId:" + monitorId + ".json?page=1"; + + var myurl = apiurl + "/events/index"; + if (monitorId!=0) + myurl = myurl + "/MonitorId:" + monitorId; + if (startTime) + myurl = myurl + "/StartTime >=:"+startTime; + if (endTime) + myurl = myurl + "/EndTime <=:"+endTime; + myurl = myurl + ".json"; + console.log (">>>>>Constructed URL " + myurl); + + //var myurl = (monitorId == 0) ? apiurl + "/events.json?page=1" : apiurl + "/events/index/MonitorId:" + monitorId + ".json?page=1"; var d = $q.defer(); $http.get(myurl) .success(function (data) { @@ -388,7 +399,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion // monitorId == 0 means all monitors (ZM starts from 1) //----------------------------------------------------------------------------- - getEvents: function (monitorId, pageId, loadingStr) { + getEvents: function (monitorId, pageId, loadingStr, startTime, endTime) { console.log("ZMData getEvents called with ID=" + monitorId + "and Page=" + pageId); @@ -412,13 +423,22 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion var myevents = []; var apiurl = loginData.apiurl; - var myurl = (monitorId == 0) ? apiurl + "/events.json" : apiurl + "/events/index/MonitorId:" + monitorId + ".json"; + var myurl = apiurl + "/events/index"; + if (monitorId!=0) + myurl = myurl + "/MonitorId:" + monitorId; + if (startTime) + myurl = myurl + "/StartTime >=:"+startTime; + if (endTime) + myurl = myurl + "/EndTime <=:"+endTime; + myurl = myurl + ".json"; + + if (pageId) { myurl = myurl + "?page=" + pageId; } else { console.log("**** PAGE WAS " + pageId); } - console.log("Constructed URL is " + myurl); + console.log (">>>>>Constructed URL " + myurl); $http.get(myurl /*,{timeout:15000}*/ ) diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 7a7ce39b..761bf9ec 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -7,8 +7,10 @@ // and whether the new API has a better mechanism angular.module('zmApp.controllers') - .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', function ($scope, $rootScope, zm, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition) { + .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', function ($scope, $rootScope, zm, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover) { + // events in last 5 minutes + // TODO https://server/zm/api/events/consoleEvents/5%20minute.json //--------------------------------------------------- // Controller main @@ -30,6 +32,14 @@ angular.module('zmApp.controllers') //var segmentHandle = 0; + + +$ionicPopover.fromTemplateUrl('templates/events-popover.html', { + scope: $scope, + }).then(function(popover) { + $scope.popover = popover; + }); + // These are the commands ZM uses to move around // in ZMS var eventCommands = { @@ -103,13 +113,13 @@ angular.module('zmApp.controllers') // First get total pages and then // start from the latest. If this fails, nothing displays - ZMDataModel.getEventsPages($scope.id) + ZMDataModel.getEventsPages($scope.id, $rootScope.fromString, $rootScope.toString) .then(function (data) { eventsPage = data.pageCount; console.log("TOTAL EVENT PAGES IS " + eventsPage); pageLoaded = true; $scope.viewTitle.title = data.count; - ZMDataModel.getEvents($scope.id, eventsPage, "") + ZMDataModel.getEvents($scope.id, eventsPage, "",$rootScope.fromString, $rootScope.toString) .then(function (data) { console.log("EventCtrl Got events"); //var events = []; @@ -182,6 +192,20 @@ angular.module('zmApp.controllers') $ionicSideMenuDelegate.toggleLeft(); }; + $scope.scrollPosition= function() { + var scrl = parseFloat( $ionicScrollDelegate.$getByHandle("mainScroll").getScrollPosition().top); + var item = Math.round(scrl/200.0); + if ($scope.events[item] == undefined) + { + return ""; + } + else + { + return prettifyDate($scope.events[item].Event.StartTime); + } + //return Math.random(); + }; + //------------------------------------------------------------------------- // called when user switches to background //------------------------------------------------------------------------- @@ -912,7 +936,7 @@ angular.module('zmApp.controllers') loadingStr = "none"; } - ZMDataModel.getEvents($scope.id, eventsPage, loadingStr) + ZMDataModel.getEvents($scope.id, eventsPage, loadingStr,$rootScope.fromString, $rootScope.toString) .then(function (data) { var loginData = ZMDataModel.getLogin(); console.log("Got new page of events with Page=" + eventsPage); @@ -969,10 +993,31 @@ angular.module('zmApp.controllers') }; + + + + + + + //-------------------------------------- // formats events dates in a nice way //--------------------------------------- + $scope.prettifyDate = function (str) { + return moment(str).format('MMM Do'); + }; + + function prettifyDate (str) + { + return moment(str).format('MMM Do'); + } + + $scope.prettifyTime = function (str) { + return moment(str).format('h:mm:ssa'); + }; + + $scope.prettify = function (str) { return moment(str).format('h:mm:ssa on MMMM Do YYYY'); }; @@ -992,13 +1037,13 @@ angular.module('zmApp.controllers') console.log("***Pull to Refresh"); $scope.events = []; moreEvents = true; - ZMDataModel.getEventsPages($scope.id) + ZMDataModel.getEventsPages($scope.id, $rootScope.fromString, $rootScope.toString) .then(function (data) { eventsPage = data.pageCount; console.log("TOTAL EVENT PAGES IS " + eventsPage); pageLoaded = true; $scope.viewTitle.title = data.count; - ZMDataModel.getEvents($scope.id, eventsPage, "") + ZMDataModel.getEvents($scope.id, eventsPage, "",$rootScope.fromString, $rootScope.toString) .then(function (data) { console.log("EventCtrl Got events"); @@ -1007,10 +1052,41 @@ angular.module('zmApp.controllers') for (var i = 0; i < myevents.length; i++) { myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); - } + + // now construct base path + + var str = myevents[i].Event.StartTime; + //var yy = moment(str).format('h:mm:ssa on MMMM Do YYYY'); + var yy = moment(str).format('YY'); + var mm = moment(str).format('MM'); + var dd = moment(str).format('DD'); + var hh = moment(str).format('HH'); + var min = moment(str).format('mm'); + var sec = moment(str).format('ss'); + var loginData = ZMDataModel.getLogin(); + myevents[i].Event.BasePath = loginData.url + "/events/" + + myevents[i].Event.MonitorId + "/" + + yy + "/" + + mm + "/" + + dd + "/" + + hh + "/" + + min + "/" + + sec + "/"; + + myevents[i].Event.relativePath = + myevents[i].Event.MonitorId + "/" + + yy + "/" + + mm + "/" + + dd + "/" + + hh + "/" + + min + "/" + + sec + "/"; + myevents[i].Event.ShowScrub = false; myevents[i].Event.height = zm.eventsListDetailsHeight; + } $scope.events = myevents; + loadMore(); }); }); diff --git a/www/js/EventDateTimeFilterCtrl.js b/www/js/EventDateTimeFilterCtrl.js new file mode 100644 index 00000000..31ade8dd --- /dev/null +++ b/www/js/EventDateTimeFilterCtrl.js @@ -0,0 +1,66 @@ +/* jshint -W041 */ +/* jslint browser: true*/ +/* global cordova,StatusBar,angular,console,moment */ + + + +angular.module('zmApp.controllers') + .controller('zmApp.EventDateTimeFilterCtrl', ['$scope', '$ionicSlideBoxDelegate', '$ionicSideMenuDelegate', '$rootScope', '$ionicHistory', function ($scope, $ionicScrollDelegate,$ionicSideMenuDelegate, $rootScope, $ionicHistory) { + +$scope.removeFilters = function() +{ + $rootScope.isEventFilterOn = false; + $rootScope.fromDate = ""; + $rootScope.fromTime= ""; + $rootScope.toDate = ""; + $rootScope.toTime=""; + $rootScope.fromString=""; + $rootScope.toString=""; + $ionicHistory.goBack(); +}; + +$scope.saveFilters = function() +{ + if (!$rootScope.fromDate) + { + console.log ("RESET fromDate"); + $rootScope.fromDate = new Date(); + } + + if (!$rootScope.toDate) + { + console.log ("RESET toDate"); + $rootScope.toDate = new Date(); + } + + if (!$rootScope.fromTime) + { + console.log ("RESET fromTime"); + $rootScope.fromTime = new Date(99,5,24,0,0,0,0); //moment().format("hh:mm:ss"); + } + + + if (!$rootScope.toTime) + { + console.log ("RESET toTime"); + $rootScope.toTime =new Date(99,5,24,23,59,59,0); + //$rootScope.toTime = "01:01:02"; //moment().format("hh:mm:ss"); + } + + + $rootScope.isEventFilterOn = true; + $rootScope.fromString = moment($rootScope.fromDate).format("YYYY-MM-DD") + " " + moment($rootScope.fromTime).format ("HH:mm:ss"); + + $rootScope.toString = moment($rootScope.toDate).format("YYYY-MM-DD") + " " + moment($rootScope.toTime).format ("HH:mm:ss"); + + //console.log("CONCAT DATES " + temp); + // + // var startDate = moment(temp).format("YYYY-MM-DD hh:mm:ss"); + console.log (" DATE IS " + $rootScope.fromString + " AND " +$rootScope.toString); + $ionicHistory.goBack(); +}; + + +} + +]); diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js index 77409eba..352b9108 100644 --- a/www/js/EventsGraphsCtrl.js +++ b/www/js/EventsGraphsCtrl.js @@ -8,7 +8,7 @@ // the main function is generateChart. I call generate chart with required parameters // from the template file -angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ionicPlatform', '$scope','zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', function ($ionicPlatform, $scope, zm,ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http) { +angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ionicPlatform', '$scope','zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http',function ($ionicPlatform, $scope, zm,ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http) { console.log("Inside Graphs controller"); $scope.openMenu = function () { $ionicSideMenuDelegate.toggleLeft(); @@ -54,6 +54,18 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni }]; + var container = angular.element(document.getElementById('visualization')); + console.log (JSON.stringify(container)); + var data = [ + {id: 1, content: 'item 1', start: '2013-04-20'}, + {id: 2, content: 'item 2', start: '2013-04-14'}, + {id: 3, content: 'item 3', start: '2013-04-18'}, + {id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'}, + {id: 5, content: 'item 5', start: '2013-04-25'}, + {id: 6, content: 'item 6', start: '2013-04-27'} + ]; + var options = {}; + //var timeline = new vis.Timeline(container[0], data, options); // ------------------------------------------------- // Called when user taps on a bar diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js index adeed4a9..3562f2c7 100644 --- a/www/js/TimelineCtrl.js +++ b/www/js/TimelineCtrl.js @@ -4,11 +4,12 @@ /* jslint browser: true*/ /* global vis,cordova,StatusBar,angular,console,moment */ -// This controller generates a graph for events -// the main function is generateChart. I call generate chart with required parameters -// from the template file +// This controller creates a timeline +// It uses the visjs library, but due to performance reasons +// I've disabled pan and zoom and used buttons instead +// also limits # of items to maxItems (currently 200) -angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPlatform', '$scope', 'zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', '$q','message','$state', '$ionicLoading', '$ionicPopover', function ($ionicPlatform, $scope, zm, ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http, $q,message, $state, $ionicLoading, $ionicPopover) { +angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPlatform', '$scope', 'zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', '$q', 'message', '$state', '$ionicLoading', '$ionicPopover', '$ionicScrollDelegate', '$ionicModal', function ($ionicPlatform, $scope, zm, ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http, $q, message, $state, $ionicLoading, $ionicPopover, $ionicScrollDelegate, $ionicModal) { console.log("Inside Timeline controller"); $scope.openMenu = function () { @@ -23,10 +24,232 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla }]; $scope.prettify = function (str) { - return moment(str).format('MMMM Do YYYY, h:mm:ssa'); + return moment(str).format('MMMM Do YYYY, h:mm:ssa'); + }; + + + $scope.calcMsTimer = function (frames, len) { + var myframes, mylen; + myframes = parseFloat(frames); + mylen = parseFloat(len); + // console.log ("frames " + myframes + "length " + mylen); + // console.log ("*** MS COUNT " + (1000.0/(myframes/mylen))); + return (Math.round(1000 / (myframes / mylen))); + }; + + + $scope.move = function (percentage) { + var range = timeline.getWindow(); + var interval = range.end - range.start; + + timeline.setWindow({ + start: range.start.valueOf() - interval * percentage, + end: range.end.valueOf() - interval * percentage + }); + }; + + $scope.zoom = function (percentage) { + var range = timeline.getWindow(); + var interval = range.end - range.start; + + timeline.setWindow({ + start: range.start.valueOf() - interval * percentage, + end: range.end.valueOf() + interval * percentage + }); + }; + + + function padToN(number, digits) { + + var i; + var stringMax = ""; + var stringLeading = ""; + for (i = 1; i <= digits; i++) { + stringMax = stringMax + "9"; + if (i != digits) stringLeading = stringLeading + "0"; + } + var numMax = parseInt(stringMax); + + if (number <= numMax) { + number = (stringLeading + number).slice(-digits); + } + //console.log ("PADTON: returning " + number); + return number; + } + + + //-------------------------------------------------------- + // To show a modal dialog with the event tapped on in timeline + // FIXME : code repeat from Events + //-------------------------------------------------------- + function openModal(eid, ename, edur, eframes, basepath, relativepath) { + console.log("Open Modal with Base path " + basepath); + $scope.eventName = ename; + $scope.eventId = eid; + $scope.eFramesNum = eframes; + $scope.eventDur = Math.round(edur); + $scope.loginData = ZMDataModel.getLogin(); + $scope.eventBasePath = basepath; + $scope.relativePath = relativepath; + $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111; + + $scope.slider_modal_options = { + from: 1, + to: eframes, + realtime: true, + step: 1, + className: "mySliderClass", + callback: function (value, released) { + //console.log("CALLBACK"+value+released); + $ionicScrollDelegate.freezeScroll(!released); + + + }, + //modelLabels:function(val) {return "";}, + smooth: false, + css: { + background: { + "background-color": "silver" + }, + before: { + "background-color": "purple" + }, + default: { + "background-color": "white" + }, // default value: 1px + after: { + "background-color": "green" + }, // zone after default value + pointer: { + "background-color": "red" + }, // circle pointer + range: { + "background-color": "red" + } // use it if double value + }, + scale: [] + }; + $scope.mycarousel.index = 0; + $scope.ionRange.index = 1; + //console.log("**Resetting range"); + $scope.slides = []; + var i; + for (i = 1; i <= eframes; i++) { + var fname = padToN(i, eventImageDigits) + "-capture.jpg"; + // console.log ("Building " + fname); + $scope.slides.push({ + id: i, + img: fname + }); + } + + + // now get event details to show alarm frames + var loginData = ZMDataModel.getLogin(); + var myurl = loginData.apiurl + '/events/' + eid + ".json"; + ZMDataModel.zmLog("*** Constructed API for detailed events: " + myurl); + $http.get(myurl) + .success(function (data) { + $scope.FrameArray = data.event.Frame; + // $scope.slider_options.scale=[]; + $scope.slider_modal_options.scale = []; + //$scope.slider_options.modelLabels={2:'X'}; + //$scope.slider_options.dimension="arjun"; + var i; + for (i = 0; i < data.event.Frame.length; i++) { + if (data.event.Frame[i].Type == "Alarm") { + //⬤ + // console.log ("**ALARM AT " + i); + $scope.slider_modal_options.scale.push({ + val: i + 1, + label: ' ' + }); + } else { + //$scope.slider_options.scale.push(' '); + } + + } + + //console.log (JSON.stringify(data)); + }) + .error(function (err) { + ZMDataModel.zmLog("Error retrieving detailed frame API " + JSON.stringify(err)); + }); + + $scope.totalEventTime = Math.round(parseFloat(edur)) - 1; + $scope.currentEventTime = 0; + + ZMDataModel.setAwake(ZMDataModel.getKeepAwake()); + + $ionicModal.fromTemplateUrl('templates/events-modal.html', { + scope: $scope, + animation: 'slide-in-up' + }) + .then(function (modal) { + $scope.modal = modal; + + $ionicLoading.show({ + template: "please wait...", + noBackdrop: true, + duration: 10000 + }); + + $scope.modal.show(); + + var ld = ZMDataModel.getLogin(); + + }); + + } + + //-------------------------------------------------------- + //We need to destroy because we are instantiating + // it on open + //-------------------------------------------------------- + $scope.closeModal = function () { + // $interval.cancel(eventsInterval); + //$interval.cancel(segmentHandle); + console.log("Close & Destroy Modal"); + ZMDataModel.setAwake(false); + if ($scope.modal !== undefined) { + $scope.modal.remove(); + } + + }; + + + //-------------------------------------------------------- + // This function is called by the graph ontapped function + // which in turn calls openModal + //-------------------------------------------------------- + + function showEvent(start, mid, edur, eframes, eid, ename) { + console.log("Event STARTED WITH " + start); + var str = start; + var yy = moment(str).format('YY'); + var mm = moment(str).format('MM'); + var dd = moment(str).format('DD'); + var hh = moment(str).format('HH'); + var min = moment(str).format('mm'); + var sec = moment(str).format('ss'); + var relativepath = + mid + "/" + + yy + "/" + + mm + "/" + + dd + "/" + + hh + "/" + + min + "/" + + sec + "/"; + console.log("PATH IS " + relativepath); + + openModal(eid, ename, edur, eframes, "", relativepath); + + } + + //------------------------------------------------- // Make sure we delete the timeline // This may be redundant as the root view gets @@ -37,27 +260,32 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla //timeline.destroy(); }); + //------------------------------------------------- + // FIXME: shitty hackery -- Im using a rootScope + // to know if you just went to custom range + // and back. Fix this, really. + // So anyway, if you did select a custom range + // then we "go back" to timeline, which is when + // we come here - so make sure we update the + // graph range + //------------------------------------------------- $scope.$on('$ionicView.afterEnter', function () { - console.log ("***AFTER ENTER"); - - if ($rootScope.customTimelineRange) - { - console.log ("***** CUSTOM RANGE"); - if (moment($rootScope.fromString).isValid() && - moment($rootScope.toString).isValid()) - { - console.log ("FROM & TO IS CUSTOM"); - fromDate = $rootScope.fromString; - toDate = $rootScope.toString; - $scope.fromDate = fromDate; - $scope.toDate = toDate; - drawGraph(fromDate, toDate, maxItems); - } - else - { - console.log ("FROM & TO IS CUSTOM INVALID"); + console.log("***AFTER ENTER"); + + if ($rootScope.customTimelineRange) { + console.log("***** CUSTOM RANGE"); + if (moment($rootScope.fromString).isValid() && + moment($rootScope.toString).isValid()) { + console.log("FROM & TO IS CUSTOM"); + fromDate = $rootScope.fromString; + toDate = $rootScope.toString; + $scope.fromDate = fromDate; + $scope.toDate = toDate; + drawGraph(fromDate, toDate, maxItems); + } else { + console.log("FROM & TO IS CUSTOM INVALID"); + } } - } }); //------------------------------------------------- @@ -68,6 +296,35 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla // does not interfere with graph panning $ionicSideMenuDelegate.canDragContent(false); + // FIXME: Timeline awake to avoid graph redrawing + ZMDataModel.setAwake(ZMDataModel.getKeepAwake()); + + $scope.$watch('ionRange.index', function () { + // console.log ("***ION RANGE CHANGED"); + + $scope.mycarousel.index = parseInt($scope.ionRange.index) - 1; + }); + + $scope.$watch('mycarousel.index', function () { + + $scope.ionRange.index = ($scope.mycarousel.index + 1).toString(); + }); + + $scope.mycarousel = { + index: 0 + }; + $scope.ionRange = { + index: 1 + }; + + var eventImageDigits = 5; // failsafe + ZMDataModel.getKeyConfigParams(0) + .then(function (data) { + //console.log ("***GETKEY: " + JSON.stringify(data)); + eventImageDigits = parseInt(data); + ZMDataModel.zmLog("Image padding digits reported as " + eventImageDigits); + }); + // fromDate and toDate will be used to plot the range for the graph // We start in day mode var fromDate = moment().startOf('day').format("YYYY-MM-DD HH:mm:ss"); @@ -78,26 +335,27 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla $scope.fromDate = fromDate; $scope.toDate = toDate; - var maxItems = 200; + var maxItems = 200; // THAT magic # --> 300 and ZM on my m/c cries + $scope.maxItems = maxItems; //flat colors for graph - https://flatuicolors.com var colors = ['#3498db', '#83adb5', '#c7bbc9', '#f39c12', '#bfb5b2', '#e74c3c']; - var container ; + var container; container = angular.element(document.getElementById('visualization')); - var timeline=""; + var timeline = ""; $scope.monitors = message; $ionicPopover.fromTemplateUrl('templates/timeline-popover.html', { - scope: $scope, - }).then(function(popover) { - $scope.popover = popover; - }); + scope: $scope, + }).then(function (popover) { + $scope.popover = popover; + }); - //drawGraph(fromDate, toDate,maxItems); - dummyDrawGraph(fromDate, toDate,maxItems); + drawGraph(fromDate, toDate, maxItems); + //dummyDrawGraph(fromDate, toDate,maxItems); //------------------------------------------------- // Rest graph to sane state after you went @@ -112,42 +370,37 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla // so we can redraw the graph //------------------------------------------------- - $scope.buttonClicked = function(index) - { + $scope.buttonClicked = function (index) { //console.log (index); if (index == 0) //month { - ZMDataModel.zmLog ("Month view"); + ZMDataModel.zmLog("Month view"); $rootScope.customTimelineRange = false; toDate = moment().format("YYYY-MM-DD HH:mm:ss"); - fromDate = moment().subtract(1,'month').startOf('day').format("YYYY-MM-DD HH:mm:ss"); + fromDate = moment().subtract(1, 'month').startOf('day').format("YYYY-MM-DD HH:mm:ss"); $scope.fromDate = fromDate; $scope.toDate = toDate; - drawGraph(fromDate, toDate,maxItems); - } - else if (index == 1) //week + drawGraph(fromDate, toDate, maxItems); + } else if (index == 1) //week { $rootScope.customTimelineRange = false; ZMDataModel.zmLog("Week view"); toDate = moment().format("YYYY-MM-DD HH:mm:ss"); - fromDate = moment().subtract(1,'week').startOf('day').format("YYYY-MM-DD HH:mm:ss"); + fromDate = moment().subtract(1, 'week').startOf('day').format("YYYY-MM-DD HH:mm:ss"); $scope.fromDate = fromDate; $scope.toDate = toDate; - drawGraph(fromDate, toDate,maxItems); - } - else if (index==2) //day + drawGraph(fromDate, toDate, maxItems); + } else if (index == 2) //day { $rootScope.customTimelineRange = false; - ZMDataModel.zmLog ("Day view"); + ZMDataModel.zmLog("Day view"); toDate = moment().format("YYYY-MM-DD HH:mm:ss"); - fromDate = moment().subtract(1,'day').startOf('day').format("YYYY-MM-DD HH:mm:ss"); + fromDate = moment().subtract(1, 'day').startOf('day').format("YYYY-MM-DD HH:mm:ss"); $scope.fromDate = fromDate; $scope.toDate = toDate; - drawGraph(fromDate, toDate,maxItems); - } - - else // custom + drawGraph(fromDate, toDate, maxItems); + } else // custom { $rootScope.customTimelineRange = true; $state.go('events-date-time-filter'); @@ -155,66 +408,8 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla }; - // ------------------------------------------------------ - // Draws a random graph from Vis timeline performance - // ----------------------------------------------------- - function dummyDrawGraph(fromDate, toDate, count) - { - if (timeline) timeline.destroy(); - - var groups = new vis.DataSet([ - {id: 1, content: 'Truck 1'}, - {id: 2, content: 'Truck 2'}, - {id: 3, content: 'Truck 3'}, - {id: 4, content: 'Truck 4'} - ]); - - // create items - var items = new vis.DataSet(); - - var order = 1; - var truck = 1; - for (var j = 0; j < 4; j++) { - var date = new Date(); - for (var i = 0; i < count/4; i++) { - date.setHours(date.getHours() + 4 * (Math.random() < 0.2)); - var start = new Date(date); - - date.setHours(date.getHours() + 2 + Math.floor(Math.random()*4)); - var end = new Date(date); - - items.add({ - id: order, - group: truck, - start: start, - end: end, - content: 'Order ' + order - }); - - order++; - } - truck++; - } - - // specify options - var options = { - stack: false, - start: new Date(), - end: new Date(1000*60*60*24 + (new Date()).valueOf()), - editable: false, - margin: { - item: 10, // minimal margin between items - axis: 5 // minimal margin between items and the axis - }, - orientation: 'top' - }; - timeline = new vis.Timeline(container[0], null, options); - timeline.setGroups(groups); - timeline.setItems(items); - } - - //------------------------------------------------- + //------------------------------------------------- // This function draws the graph // So far struggling with mobile perf // Observations so far: @@ -225,17 +420,16 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla function drawGraph(fromDate, toDate, count) { - $ionicLoading.show({ - template: "Loading graph...", - animation: 'fade-in', - showBackdrop: true, - maxWidth: 200, - showDelay: 0, - duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times - }); - - if (timeline) timeline.destroy(); + $ionicLoading.show({ + template: "Loading graph...", + animation: 'fade-in', + showBackdrop: true, + maxWidth: 200, + showDelay: 0, + duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times + }); + if (timeline) timeline.destroy(); var groups = new vis.DataSet(); @@ -244,18 +438,16 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla var options = { - // autoResize: false, // true makes it much slower - //configure: true, + editable: false, - // moveable: true, - // zoomable: true, - start:fromDate, - end:toDate, + moveable: false, + zoomable: false, + selectable: true, + start: fromDate, + end: toDate, orientation: 'top', min: fromDate, max: toDate, - //width:'90%', - zoomMin: 1 * 60 * 1000, // 1 min stack: false, format: { @@ -285,14 +477,14 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla // I figure out how many items the server returns per API page // and divide the # of items I want (currently 200) with # of items per page // So iterCount is the # of HTTP calls I need to make - iterCount = Math.round(count/itemsPerPage); + iterCount = Math.round(count / itemsPerPage); console.log("I will make " + iterCount + " HTTP Requests "); // I've restructured this part. I was initially using vis DataSets // for dynamic binding which was easier, but due to performance reasons // I am waiting for the full data to load before I draw var promises = []; - while ((pages > 0) && (iterCount >0)) { + while ((pages > 0) && (iterCount > 0)) { var promise = ZMDataModel.getEvents(0, pages, "none", fromDate, toDate); promises.push(promise); pages--; @@ -304,13 +496,12 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla .then(function (data) { - // create groups - for (var g=0; g<$scope.monitors.length; g++) - { - groups.add({ - id: $scope.monitors[g].Monitor.Id, - content: ZMDataModel.getMonitorName($scope.monitors[g].Monitor.Id) - }); + // create groups + for (var g = 0; g < $scope.monitors.length; g++) { + groups.add({ + id: $scope.monitors[g].Monitor.Id, + content: ZMDataModel.getMonitorName($scope.monitors[g].Monitor.Id) + }); } for (var j = 0; j < data.length; j++) { var myevents = data[j]; @@ -320,13 +511,16 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla graphData.add({ id: graphIndex, - content: '', + content: "<span class='my-vis-font'>"+ myevents[i].Event.Notes + "</span>", start: myevents[i].Event.StartTime, end: myevents[i].Event.EndTime, group: myevents[i].Event.MonitorId, //type: "range", style: "background-color:" + colors[parseInt(myevents[i].Event.MonitorId) % colors.length] + ";border-color:" + colors[parseInt(myevents[i].Event.MonitorId) % colors.length], - // title: "Hello" + myframes: myevents[i].Event.Frames, + mydur: myevents[i].Event.Length, + myeid: myevents[i].Event.Id, + myename: myevents[i].Event.Name, }); @@ -339,21 +533,32 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla timeline.setItems(graphData); timeline.setGroups(groups); timeline.fit(); - $ionicLoading.hide(); + $ionicLoading.hide(); + timeline.on('select', function (properties) { + if (properties.items && !isNaN(properties.items[0])) { + console.log("You clicked on item " + properties.items); + var item = graphData.get(properties.items); + console.log("ITEM = " + JSON.stringify(item)); + showEvent(item[0].start, item[0].group, item[0].mydur, item[0].myframes, item[0].myeid, item[0].myename); + + + } else { + $ionicLoading.show({ + template: "Zoom in more to scrub events...", + animation: 'fade-in', + showBackdrop: true, + maxWidth: 200, + showDelay: 0, + duration: 1500, + }); + console.log("Zoomed out too far to playback events"); + } + + }); }); // get Events }); } - function arrayObjectIndexOf(myArray, searchTerm, property) { - for (var i = 0, len = myArray.length; i < len; i++) { - if (myArray[i][property] === searchTerm) return i; - } - return -1; - } - - - - }]); diff --git a/www/js/app.js b/www/js/app.js index 03ef336e..81ab5e9c 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -14,6 +14,8 @@ angular.module('zmApp', [ 'angular-carousel', 'angularAwesomeSlider' + + ]) // ------------------------------------------ @@ -164,7 +166,7 @@ angular.module('zmApp', [ // That way the user can try again, and won't get stuck // Also remember you need to add it to .config //------------------------------------------------------------------ -.factory('timeoutHttpIntercept', function ($rootScope, $q,zm, $cookieStore) { +.factory('timeoutHttpIntercept', function ($rootScope, $q,zm) { var zmCookie = ""; return { @@ -195,9 +197,12 @@ angular.module('zmApp', [ { var zmSess=cookies.match("ZMSESSID=(.*?);"); - console.log ("***RESPONSE HEADER COOKIE " + zmSess[1]); - console.log ("WHOLE STRING " + cookies); - zmCookie=zmSess[1]; + if (zmSess[1]) + { + console.log ("***RESPONSE HEADER COOKIE " + zmSess[1]); + console.log ("WHOLE STRING " + cookies); + zmCookie=zmSess[1]; + } } return response; } @@ -313,13 +318,23 @@ angular.module('zmApp', [ // First run in ionic //------------------------------------------------------------------ -.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, $fileLogger,$timeout, $ionicHistory, $window, $ionicSideMenuDelegate) +.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, $fileLogger,$timeout, $ionicHistory, $window, $ionicSideMenuDelegate) { $rootScope.zmGlobalCookie=""; + $rootScope.isEventFilterOn = false; + $rootScope.fromDate = ""; + $rootScope.fromTime= ""; + $rootScope.toDate = ""; + $rootScope.toTime=""; + $rootScope.fromString=""; + $rootScope.toString=""; ZMDataModel.init(); - + // for making sure we canuse $state.go with ng-click + // needed for views that use popovers +$rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; var loginData = ZMDataModel.getLogin(); @@ -461,9 +476,18 @@ angular.module('zmApp', [ $rootScope.rand = Math.floor((Math.random() * 100000) + 1); //$scope.rand = Math.floor((Math.random() * 100000) + 1); console.log("** generated Random of " + $rootScope.rand); - $state.go($state.current, {}, { - reload: true - }); + //console.log ("*******************************CURRENT STATE: " + JSON.stringify($state.current)); + if ($state.current.url == "/timeline") + { + ZMDataModel.zmLog("Skipping state refresh for Timeline"); + } + else + { + ZMDataModel.zmLog ("Reloading screen for state " + $state.current.url); + $state.go($state.current, {}, { + reload: true + }); + } //$window.location.reload(true); //$route.reload(); @@ -590,6 +614,16 @@ angular.module('zmApp', [ controller: 'zmApp.EventsGraphsCtrl', }) + + .state('events-date-time-filter', { + data: { + requireLogin: true + }, + url: "/events-date-time-filter", + templateUrl: "templates/events-date-time-filter.html", + controller: 'zmApp.EventDateTimeFilterCtrl', + }) + .state('state', { data: { requireLogin: true @@ -608,6 +642,22 @@ angular.module('zmApp', [ controller: 'zmApp.DevOptionsCtrl', }) + .state('timeline', { + data: { + requireLogin: true + }, + resolve: { + message: function (ZMDataModel) { + console.log("Inside app.events resolve"); + return ZMDataModel.getMonitors(0); + } + }, + url: "/timeline", + templateUrl: "templates/timeline.html", + controller: 'zmApp.TimelineCtrl', + }) + + .state('log', { data: { requireLogin: false diff --git a/www/js/ng.js b/www/js/ng.js deleted file mode 100644 index d99945b1..00000000 --- a/www/js/ng.js +++ /dev/null @@ -1,14 +0,0 @@ -/*angular.module("ng") -.factory('imageLoadingDataShare', function () { - var imageLoading = 1; // 1 = loading, -1 = error; - return { - 'set': function (val) { - imageLoading = val; - }, - 'get': function() { - return imageLoading; - } - }; - - -});*/ |
