diff war/scripts/sti/ExtendedDataSource.js @ 3:cf06b77a8bbd

Committed branch of the e4D repos sti-gwt branch 16384. git-svn-id: http://dev.dariah.eu/svn/repos/eu.dariah.de/ap1/sti-gwt-dariah-geobrowser@36 f2b5be40-def6-11e0-8a09-b3c1cc336c6b
author StefanFunk <StefanFunk@f2b5be40-def6-11e0-8a09-b3c1cc336c6b>
date Tue, 17 Jul 2012 13:34:40 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/war/scripts/sti/ExtendedDataSource.js	Tue Jul 17 13:34:40 2012 +0000
@@ -0,0 +1,301 @@
+/**
+ * small class that represents a time slice of the actual timeplot.
+ * it has a specific date and contains its corrsponding data objects as well
+ * @param {Date} date the date of the timeslice
+ * 
+ * @constructor
+*/
+function TimeSlice(date){
+
+    this.date = date;
+    this.elements = [];
+	this.selected = false;
+    
+};
+
+/**
+ * data source to allow dynamic and manual creation of time slices, which will be used as input for the Simile Timeplot.
+ * at the end we will get around 200 time slices, which units are depending on the time range of the input data
+ * 
+ * @constructor
+*/
+function ExtendedDataSource(){
+
+    this.timeSlices;
+	this.unit;
+	this.minDate;
+	this.maxDate;
+	this.eventSources;
+	this.events;
+	this.leftSlice;
+	this.rightSlice;
+    
+};
+
+ExtendedDataSource.prototype = {
+
+	/**
+ 	* initializes the ExtendedDataSource
+ 	* @param {Timeplot.ColumnSource[]} dataSources the column sources corresponding to the data sets
+ 	* @param {Timeplot.DefaultEventSource[]} eventSources the event sources corresponding to the column sources
+ 	* @param {Array} dataSets all data sets
+ 	* @param {SimileAjax.DateTime} granularity the time granularity of the given data
+	*/
+	initialize: function( dataSources, eventSources, dataSets, granularity ){
+		        
+		this.minDate = undefined;
+		this.maxDate = undefined;
+		        
+        for (var i = 0; i < dataSets.length; i++) {
+            for (var j = 0; j < dataSets[i].objects.length; j++) {
+                var o = dataSets[i].objects[j];
+                var timeMin = o.timeStamp;
+                var timeMax = o.timeStamp;
+                if( o.timeStamp == undefined ){
+                	timeMin = o.timeSpan.start;
+                	timeMax = o.timeSpan.end;
+                }
+                if (this.minDate == undefined || timeMin.getTime() < this.minDate.getTime()) 
+                    this.minDate = timeMin;
+                if (this.maxDate == undefined || timeMax.getTime() > this.maxDate.getTime()) 
+                    this.maxDate = timeMax;
+            }
+        }
+        this.timeSlices = [];
+        
+        var time = SimileAjax.DateTime;
+        var u = SimileAjax.NativeDateUnit;
+        var p = this.maxDate - this.minDate;
+		
+		var periodUnit = -1;
+		do {
+			periodUnit++;
+		}
+		while( time.gregorianUnitLengths[periodUnit] < p );
+
+		switch (granularity){
+			case time.MILLISECOND:
+			case time.SECOND:
+				if( periodUnit > time.QUARTER )
+					this.unit = periodUnit - 7;
+				else if( periodUnit > time.TWOWEEKS )
+					this.unit = time.DAY;
+				else if( periodUnit > time.HOUR )
+					this.unit = periodUnit - 5;
+				else if( periodUnit > time.HALFMINUTE )					
+					this.unit = periodUnit - 4;
+				else
+					this.unit = time.SECOND;
+				break;
+			case time.DAY:
+				if( periodUnit > time.QUARTER )
+					this.unit = periodUnit - 7;
+				else 
+					this.unit = time.DAY;
+				break;
+			case time.MONTH:
+				if( periodUnit > time.DECADE )
+					this.unit = periodUnit - 7;
+				else 
+					this.unit = time.MONTH;
+				break;
+			case time.YEAR:
+				if( periodUnit > time.CENTURY )
+					this.unit = periodUnit - 7;
+				else 
+					this.unit = time.YEAR;
+				break;
+		}
+
+        var timeZone;
+        var t = new Date(this.minDate.getTime() - 0.9 * time.gregorianUnitLengths[this.unit]);
+        do {
+            time.roundDownToInterval(t, this.unit, timeZone, 1, 0);
+            var slice = new TimeSlice(u.cloneValue(t));
+            this.timeSlices.push(slice);
+            time.incrementByInterval(t, this.unit, timeZone);
+        }
+        while (t.getTime() <= this.maxDate.getTime() + 1.1 * time.gregorianUnitLengths[this.unit]);
+        
+        for (var i = 0; i < dataSources.length; i++) 
+            for (var j = 0; j < this.timeSlices.length; j++) 
+                this.timeSlices[j].elements.push([]);
+	
+		for(var i=0; i<dataSets.length; i++ ){
+			if( !dataSets[i].hidden ){
+			for(var j=0; j<dataSets[i].objects.length; j++ ){
+				var o = dataSets[i].objects[j];
+                var timeMin = o.timeStamp;
+                var timeMax = o.timeStamp;
+                if( o.timeStamp == undefined ){
+                	timeMin = o.timeSpan.start;
+                	timeMax = o.timeSpan.end;
+                }
+				for( var k=0; k<this.timeSlices.length-1; k++ ){
+					var t1 = this.timeSlices[k].date.getTime();
+					var t2 = this.timeSlices[k+1].date.getTime();
+					if( ( timeMin >= t1 && timeMin < t2 ) || ( timeMax >= t1 && timeMax < t2 ) || ( timeMin <= t1 && timeMax >= t2 ) ){
+						this.timeSlices[k].elements[i].push(o);
+					}
+					if( k == this.timeSlices.length-2 && ( timeMin >= t2 || timeMax >= t2 ) ){
+						this.timeSlices[k+1].elements[i].push(o);
+					}
+				}
+			}
+			}
+		}
+
+		this.events = [];
+		for(var i=0; i<eventSources.length; i++ ){
+			var eventSet = [];
+			for(var j=0; j<this.timeSlices.length; j++ ){
+				var value = new Array( ""+this.timeSlices[j].elements[i].length );
+				eventSet.push( { date: this.timeSlices[j].date, value: value } );
+			}
+			eventSources[i].loadData( eventSet );
+			this.events.push(eventSet);
+		}
+		
+		this.eventSources = eventSources;
+		
+		this.leftSlice = 0;
+		this.rightSlice = this.timeSlices.length - 1;
+		
+		setZoomLevels(Math.round( (this.timeSlices.length-3)/2 ));
+
+	},
+	
+	/**
+ 	* computes the slice index corresponding to a given time
+ 	* @param {Date} time the given time
+ 	* @return the corresponding slice index
+	*/
+	getSliceIndex: function( time ){
+		for(var i=0; i<this.timeSlices.length; i++ ){
+			if( time == this.timeSlices[i].date ){
+				return i;
+			}
+		}
+	},
+	
+	/**
+ 	* returns the time of a specific time slice
+ 	* @param {int} time the given slice index
+ 	* @return the corresponding slice date
+	*/
+	getSliceTime: function( index ){
+		return this.timeSlices[index].date;
+	},
+
+	/**
+ 	* shifts the actual zoomed range
+ 	* @param {int} delta the value to shift (negative for left shift, positive for right shift)
+ 	* @return boolean value, if the range could be shifted
+	*/
+	setShift: function( delta ){
+		if( delta == 1 && this.leftSlice != 0 ){
+			this.leftSlice--;
+			this.rightSlice--;
+			return true;
+		}	
+		else if( delta == -1 && this.rightSlice != this.timeSlices.length-1 ){
+			this.leftSlice++;
+			this.rightSlice++;
+			return true;
+		}	
+		else {
+			return false;
+		}
+	},
+	
+	/**
+ 	* zooms the actual range
+ 	* @param {int} delta the value to zoom (negative for zoom out, positive for zoom in)
+ 	* @param {Date} time the corresponding time of the actual mouse position on the plot
+ 	* @param {Date} leftTime the time of the left border of a selected timerange or null
+ 	* @param {Date} rightTime the time of the right border of a selected timerange or null
+ 	* @return boolean value, if the range could be zoomed
+	*/
+	setZoom: function( delta, time, leftTime, rightTime ){
+		var n1 = 0;
+		var n2 = 0;
+		var m = -1;
+		if( delta > 0 ){
+			m = 1;
+			if( leftTime != null ){
+				n1 = this.getSliceIndex(leftTime) - this.leftSlice;
+				n2 = this.rightSlice - this.getSliceIndex(rightTime);
+			}
+			else {
+				slice = this.getSliceIndex(time);
+				if( slice == this.leftSlice || slice == this.rightSlice ){
+					return;
+				}
+				n1 = slice - 1 - this.leftSlice;
+				n2 = this.rightSlice - slice - 1;
+			}
+		}
+		else if( delta < 0 ){
+			n1 = this.leftSlice;
+			n2 = this.timeSlices.length - 1 -this.rightSlice;
+		}
+				
+		var zoomSlices = 2*delta;
+		if( Math.abs(n1 + n2) < Math.abs(zoomSlices) ){
+			zoomSlices = n1 + n2;
+		}
+
+		if( n1 + n2 == 0 ){
+			return false;
+		}
+
+		var m1 = Math.round( n1 / (n1 + n2) * zoomSlices );
+		var m2 = zoomSlices - m1;
+
+		this.leftSlice += m1;
+		this.rightSlice -= m2;
+		 
+		return true;
+	},
+	
+	/**
+ 	* resets the plots by loading data of actual zoomed range
+	*/
+	reset: function( timeGeometry ){
+		for(var i=0; i<this.eventSources.length; i++ ){
+			this.eventSources[i].loadData( this.events[i].slice( this.leftSlice, this.rightSlice + 1) );
+			if( i+1 < this.eventSources.length ){
+				timeGeometry._earliestDate = null;
+				timeGeometry._latestDate = null;
+			}
+		}
+	},
+	
+	/**
+ 	* Getter for actual zoom
+ 	* @return actual zoom value
+	*/
+	getZoom: function(){
+		if( this.timeSlices == undefined ){
+			return 0;
+		}
+		return Math.round((this.timeSlices.length-3)/2 ) - Math.round((this.rightSlice-this.leftSlice-2)/2); 
+	},
+	
+	/**
+ 	* Getter for date of the first timeslice
+ 	* @return date of the first timeslice
+	*/
+	earliest: function(){
+		return this.timeSlices[0].date;
+	},
+	
+	/**
+ 	* Getter for date of the last timeslice
+ 	* @return date of the last timeslice
+	*/
+	latest: function(){
+		return this.timeSlices[ this.timeSlices.length - 1 ].date;
+	}
+			
+};