summaryrefslogtreecommitdiff
path: root/www/js
diff options
context:
space:
mode:
authorPliablePixels <pliablepixels@gmail.com>2015-08-05 17:59:26 -0400
committerPliablePixels <pliablepixels@gmail.com>2015-08-05 17:59:26 -0400
commit10f5788d747d2f96027c0591fe332b74f9b9aac7 (patch)
tree1f0162ff7fd69338eba5eea78cc09fc1f5affd33 /www/js
parent67b5040175a6c282be515dfb61e30540f22d0333 (diff)
Timeline feature (Experimental)
Diffstat (limited to 'www/js')
-rw-r--r--www/js/DataModel.js30
-rw-r--r--www/js/EventCtrl.js90
-rw-r--r--www/js/EventDateTimeFilterCtrl.js66
-rw-r--r--www/js/EventsGraphsCtrl.js14
-rw-r--r--www/js/TimelineCtrl.js503
-rw-r--r--www/js/app.js68
-rw-r--r--www/js/ng.js14
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&nbsp;1'},
- {id: 2, content: 'Truck&nbsp;2'},
- {id: 3, content: 'Truck&nbsp;3'},
- {id: 4, content: 'Truck&nbsp;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;
- }
- };
-
-
-});*/