diff d3s_examples/python-neo4jrestclient/static/platin/js/Time/SimileTimeplotModify.js @ 8:18ef6948d689

new d3s examples
author Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de>
date Thu, 01 Oct 2015 17:17:27 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/d3s_examples/python-neo4jrestclient/static/platin/js/Time/SimileTimeplotModify.js	Thu Oct 01 17:17:27 2015 +0200
@@ -0,0 +1,1140 @@
+/*
+* SimileTimeplotModify.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * Modified (overwritten) Simile Timeplot Functions
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+SimileAjax.DateTime.MILLISECOND = 0;
+SimileAjax.DateTime.SECOND = 1;
+SimileAjax.DateTime.MINUTE = 2;
+SimileAjax.DateTime.HOUR = 3;
+SimileAjax.DateTime.DAY = 4;
+SimileAjax.DateTime.WEEK = 5;
+SimileAjax.DateTime.MONTH = 6;
+SimileAjax.DateTime.QUARTER = 7;
+SimileAjax.DateTime.SEMESTER = 8;
+SimileAjax.DateTime.YEAR = 9;
+SimileAjax.DateTime.LUSTRUM = 10;
+SimileAjax.DateTime.DECADE = 11;
+SimileAjax.DateTime.HALFCENTURY = 12;
+SimileAjax.DateTime.CENTURY = 13;
+SimileAjax.DateTime.HALFMILLENNIUM = 14;
+SimileAjax.DateTime.MILLENNIUM = 15;
+
+SimileAjax.DateTime.Strings = {
+	"en" : ["milliseconds", "seconds", "minutes", "hours", "days", "weeks", "months", "quarters", "semester", "years", "5 years", "decades", "50 years", "centuries", "500 years", "millenniums"],
+	"de" : ["Millisekunden", "Sekunden", "Minuten", "Stunden", "Tage", "Wochen", "Monate", "Quartale", "Semester", "Jahre", "5 Jahre", "Dekaden", "50 Jahre", "Jahrhunderte", "500 Jahre", "Jahrtausende"]
+};
+
+SimileAjax.DateTime.gregorianUnitLengths = [];
+(function() {
+	var d = SimileAjax.DateTime;
+	var a = d.gregorianUnitLengths;
+
+	a[d.MILLISECOND] = 1;
+	a[d.SECOND] = 1000;
+	a[d.MINUTE] = a[d.SECOND] * 60;
+	a[d.HOUR] = a[d.MINUTE] * 60;
+	a[d.DAY] = a[d.HOUR] * 24;
+	a[d.WEEK] = a[d.DAY] * 7;
+	a[d.MONTH] = a[d.DAY] * 31;
+	a[d.QUARTER] = a[d.DAY] * 91;
+	a[d.SEMESTER] = a[d.DAY] * 182;
+	a[d.YEAR] = a[d.DAY] * 365;
+	a[d.LUSTRUM] = a[d.YEAR] * 5;
+	a[d.DECADE] = a[d.YEAR] * 10;
+	a[d.HALFCENTURY] = a[d.YEAR] * 50;
+	a[d.CENTURY] = a[d.YEAR] * 100;
+	a[d.HALFMILLENNIUM] = a[d.YEAR] * 500;
+	a[d.MILLENNIUM] = a[d.YEAR] * 1000;
+})();
+
+SimileAjax.DateTime.roundDownToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) {
+	timeZone = ( typeof timeZone == 'undefined') ? 0 : timeZone;
+	var timeShift = timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+	var date2 = new Date(date.getTime() + timeShift);
+	var clearInDay = function(d) {
+		d.setUTCMilliseconds(0);
+		d.setUTCSeconds(0);
+		d.setUTCMinutes(0);
+		d.setUTCHours(0);
+	};
+	var clearInWeek = function(d) {
+		clearInDay(d);
+		var day = d.getDay();
+		var millies = d.getTime();
+		millies -= day * 1000 * 60 * 60 * 24;
+		d.setTime(millies);
+	};
+	var clearInYear = function(d) {
+		clearInDay(d);
+		d.setUTCDate(1);
+		d.setUTCMonth(0);
+	};
+
+	switch (intervalUnit) {
+		case SimileAjax.DateTime.MILLISECOND:
+			var x = date2.getUTCMilliseconds();
+			date2.setUTCMilliseconds(x - (x % multiple));
+			break;
+		case SimileAjax.DateTime.SECOND:
+			date2.setUTCMilliseconds(0);
+			var x = date2.getUTCSeconds();
+			date2.setUTCSeconds(x - (x % multiple));
+			break;
+		case SimileAjax.DateTime.MINUTE:
+			date2.setUTCMilliseconds(0);
+			date2.setUTCSeconds(0);
+			var x = date2.getUTCMinutes();
+			date2.setTime(date2.getTime() - (x % multiple) * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+			break;
+		case SimileAjax.DateTime.HOUR:
+			date2.setUTCMilliseconds(0);
+			date2.setUTCSeconds(0);
+			date2.setUTCMinutes(0);
+			var x = date2.getUTCHours();
+			date2.setUTCHours(x - (x % multiple));
+			break;
+		case SimileAjax.DateTime.DAY:
+			clearInDay(date2);
+			break;
+		case SimileAjax.DateTime.WEEK:
+			clearInWeek(date2);
+			break;
+		case SimileAjax.DateTime.MONTH:
+			clearInDay(date2);
+			date2.setUTCDate(1);
+			var x = date2.getUTCMonth();
+			date2.setUTCMonth(x - (x % multiple));
+			break;
+		case SimileAjax.DateTime.QUARTER:
+			clearInDay(date2);
+			date2.setUTCDate(1);
+			var x = date2.getUTCMonth();
+			date2.setUTCMonth(x - (x % 3));
+			break;
+		case SimileAjax.DateTime.SEMESTER:
+			clearInDay(date2);
+			date2.setUTCDate(1);
+			var x = date2.getUTCMonth();
+			date2.setUTCMonth(x - (x % 6));
+			break;
+		case SimileAjax.DateTime.YEAR:
+			clearInYear(date2);
+			var x = date2.getUTCFullYear();
+			date2.setUTCFullYear(x - (x % multiple));
+			break;
+		case SimileAjax.DateTime.LUSTRUM:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 5) * 5);
+			break;
+		case SimileAjax.DateTime.DECADE:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 10) * 10);
+			break;
+		case SimileAjax.DateTime.HALFCENTURY:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 50) * 50);
+			break;
+		case SimileAjax.DateTime.CENTURY:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 100) * 100);
+			break;
+		case SimileAjax.DateTime.HALFMILLENNIUM:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 500) * 500);
+			break;
+		case SimileAjax.DateTime.MILLENNIUM:
+			clearInYear(date2);
+			date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 1000) * 1000);
+			break;
+	}
+
+	date.setTime(date2.getTime() - timeShift);
+};
+
+SimileAjax.DateTime.incrementByInterval = function(date, intervalUnit, timeZone) {
+	timeZone = ( typeof timeZone == 'undefined') ? 0 : timeZone;
+
+	var timeShift = timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+	var date2 = new Date(date.getTime() + timeShift);
+
+	switch (intervalUnit) {
+		case SimileAjax.DateTime.MILLISECOND:
+			date2.setTime(date2.getTime() + 1)
+			break;
+		case SimileAjax.DateTime.SECOND:
+			date2.setTime(date2.getTime() + 1000);
+			break;
+		case SimileAjax.DateTime.MINUTE:
+			date2.setTime(date2.getTime() + SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+			break;
+		case SimileAjax.DateTime.HOUR:
+			date2.setTime(date2.getTime() + SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+			break;
+		case SimileAjax.DateTime.DAY:
+			date2.setUTCDate(date2.getUTCDate() + 1);
+			break;
+		case SimileAjax.DateTime.WEEK:
+			date2.setUTCDate(date2.getUTCDate() + 7);
+			break;
+		case SimileAjax.DateTime.MONTH:
+			date2.setUTCMonth(date2.getUTCMonth() + 1);
+			break;
+		case SimileAjax.DateTime.QUARTER:
+			date2.setUTCMonth(date2.getUTCMonth() + 3);
+			break;
+		case SimileAjax.DateTime.SEMESTER:
+			date2.setUTCMonth(date2.getUTCMonth() + 6);
+			break;
+		case SimileAjax.DateTime.YEAR:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 1);
+			break;
+		case SimileAjax.DateTime.LUSTRUM:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 5);
+			break;
+		case SimileAjax.DateTime.DECADE:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 10);
+			break;
+		case SimileAjax.DateTime.HALFCENTURY:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 50);
+			break;
+		case SimileAjax.DateTime.CENTURY:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 100);
+			break;
+		case SimileAjax.DateTime.HALFMILLENNIUM:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 500);
+			break;
+		case SimileAjax.DateTime.MILLENNIUM:
+			date2.setUTCFullYear(date2.getUTCFullYear() + 1000);
+			break;
+	}
+	date.setTime(date2.getTime() - timeShift);
+};
+
+SimileAjax.DateTime.getTimeLabel = function(unit, t) {
+	var time = SimileAjax.DateTime;
+	var second = t.getUTCSeconds();
+	var minute = t.getUTCMinutes();
+	var hour = t.getUTCHours();
+	var day = t.getUTCDate();
+	var month = t.getUTCMonth() + 1;
+	var year = t.getUTCFullYear();
+	switch(unit) {
+		case time.SECOND:
+			return hour + ":" + ((minute < 10) ? "0" : "") + minute + ":" + ((second < 10) ? "0" : "") + second;
+		case time.MINUTE:
+			return hour + ":" + ((minute < 10) ? "0" : "") + minute;
+		case time.HOUR:
+			return hour + ":00";
+		case time.DAY:
+		case time.WEEK:
+		case time.MONTH:
+		case time.QUARTER:
+		case time.SEMESTER:
+			return year + "-" + ((month < 10) ? "0" : "") + month + "-" + ((day < 10) ? "0" : "") + day;
+		case time.YEAR:
+		case time.LUSTRUM:
+		case time.DECADE:
+		case time.HALFCENTURY:
+		case time.CENTURY:
+		case time.HALFMILLENNIUM:
+		case time.MILLENNIUM:
+			return year;
+	}
+};
+
+SimileAjax.DateTime.getTimeString = function(unit, t) {
+	var time = SimileAjax.DateTime;
+	switch(unit) {
+		case time.MILLISECOND:
+		case time.SECOND:
+		case time.MINUTE:
+		case time.HOUR:
+			var m = t.getUTCMonth() + 1;
+			var d = t.getUTCDate();
+			var h = t.getUTCHours();
+			var min = t.getUTCMinutes();
+			var s = t.getUTCSeconds();
+			return t.getUTCFullYear() + "-" + ((m < 10) ? "0" : "") + m + "-" + ((d < 10) ? "0" : "") + d + " " + ((h < 10) ? "0" : "") + h + ":" + ((min < 10) ? "0" : "") + min + ":" + ((s < 10) ? "0" : "") + s;
+		case time.DAY:
+		case time.WEEK:
+		case time.MONTH:
+		case time.QUARTER:
+		case time.SEMESTER:
+			var m = t.getUTCMonth() + 1;
+			var d = t.getUTCDate();
+			return t.getUTCFullYear() + "-" + ((m < 10) ? "0" : "") + m + "-" + ((d < 10) ? "0" : "") + d;
+		case time.YEAR:
+		case time.LUSTRUM:
+		case time.DECADE:
+		case time.HALFCENTURY:
+		case time.CENTURY:
+		case time.HALFMILLENNIUM:
+		case time.MILLENNIUM:
+			return t.getUTCFullYear();
+	}
+};
+
+Timeplot.DefaultEventSource.prototype.loadData = function(events) {
+
+	this._events.maxValues = new Array();
+	this._events.removeAll();
+	for (var i = 0; i < events.length; i++) {
+		var event = events[i];
+		var numericEvent = new Timeplot.DefaultEventSource.NumericEvent(event.date, event.value);
+		this._events.add(numericEvent);
+	}
+	this._fire("onAddMany", []);
+
+};
+
+Timeplot._Impl.prototype.resetPlots = function(plotInfos) {
+
+	this._plotInfos = plotInfos;
+	this._painters = {
+		background : [],
+		foreground : []
+	};
+	this._painter = null;
+
+	var timeplot = this;
+	var painter = {
+		onAddMany : function() {
+			timeplot.update();
+		},
+		onClear : function() {
+			timeplot.update();
+		}
+	}
+
+	for ( i = this._plots.length; i > 0; i--) {
+		this._plots[i - 1].opacityPlot.removeChild(this._plots[i - 1]._opacityCanvas);
+		this._plots[i - 1].dispose();
+		if (document.addEventListener) {
+			this._containerDiv.removeEventListener("mousemove", this._plots[i - 1].mousemove, false);
+			this._containerDiv.removeEventListener("mouseover", this._plots[i - 1].mouseover, false);
+		} else if (document.attachEvent) {
+			this._containerDiv.detachEvent("onmousemove", this._plots[i - 1].mousemove);
+			this._containerDiv.detachEvent("onmouseover", this._plots[i - 1].mouseover);
+		}
+		delete this._plots[i - 1];
+	}
+
+	this._plots = [];
+
+	for ( i = 0; i < this._plotInfos.length; i++) {
+		var plot = new Timeplot.Plot(this, this._plotInfos[i]);
+		var dataSource = plot.getDataSource();
+		if (dataSource) {
+			dataSource.addListener(painter);
+		}
+		this.addPainter("background", {
+			context : plot.getTimeGeometry(),
+			action : plot.getTimeGeometry().paint
+		});
+		this.addPainter("background", {
+			context : plot.getValueGeometry(),
+			action : plot.getValueGeometry().paint
+		});
+		this.addPainter("foreground", {
+			context : plot,
+			action : plot.paint
+		});
+		this._plots.push(plot);
+		plot.initialize();
+	}
+
+};
+
+Timeplot.DefaultTimeGeometry.prototype._calculateGrid = function() {
+	var grid = [];
+
+	var time = SimileAjax.DateTime;
+	var u = this._unit;
+	var p = this._period;
+
+	if (p == 0)
+		return grid;
+
+	var periodUnit = -1;
+	do {
+		periodUnit++;
+	} while (time.gregorianUnitLengths[periodUnit] < p);
+
+	periodUnit--;
+
+	var unit;
+	if (periodUnit < time.DAY) {
+		unit = time.HOUR;
+	} else if (periodUnit < time.WEEK) {
+		unit = time.DAY;
+	} else if (periodUnit < time.QUARTER) {
+		unit = time.WEEK;
+	} else if (periodUnit < time.YEAR) {
+		unit = time.MONTH;
+	} else if (periodUnit < time.DECADE) {
+		unit = time.YEAR;
+	} else if (periodUnit < time.CENTURY) {
+		unit = time.DECADE;
+	} else if (periodUnit < time.HALFMILLENNIUM) {
+		unit = time.CENTURY;
+	} else if (periodUnit < time.MILLENNIUM) {
+		unit = time.HALFMILLENNIUM;
+	} else {
+		unit = time.MILLENNIUM;
+	}
+
+	if (unit < this._granularity) {
+		unit = this._granularity;
+	}
+
+	var t = u.cloneValue(this._earliestDate);
+	var timeZone;
+	do {
+		time.roundDownToInterval(t, unit, timeZone, 1, 0);
+		var x = this.toScreen(u.toNumber(t));
+		var l = SimileAjax.DateTime.getTimeLabel(unit, t);
+		if (x > 0) {
+			grid.push({
+				x : x,
+				label : l
+			});
+		}
+		time.incrementByInterval(t, unit, timeZone);
+	} while (t.getTime() < this._latestDate.getTime());
+
+	return grid;
+
+};
+
+//modified function to prevent from drawing left and right axis
+Timeplot.DefaultValueGeometry.prototype.paint = function() {
+	if (this._timeplot) {
+		var ctx = this._canvas.getContext('2d');
+
+		ctx.lineJoin = 'miter';
+
+		// paint grid
+		if (this._gridColor) {
+			var gridGradient = ctx.createLinearGradient(0, 0, 0, this._canvas.height);
+			gridGradient.addColorStop(0, this._gridColor.toHexString());
+			gridGradient.addColorStop(0.3, this._gridColor.toHexString());
+			gridGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+			ctx.lineWidth = this._gridLineWidth;
+			ctx.strokeStyle = gridGradient;
+
+			for (var i = 0; i < this._grid.length; i++) {
+				var tick = this._grid[i];
+				var y = Math.floor(tick.y) + 0.5;
+				if ( typeof tick.label != "undefined") {
+					if (this._axisLabelsPlacement == "left") {
+						var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label", {
+							left : 4,
+							bottom : y + 2,
+							color : this._gridColor.toHexString(),
+							visibility : "hidden"
+						});
+						this._labels.push(div);
+					} else if (this._axisLabelsPlacement == "right") {
+						var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label", {
+							right : 4,
+							bottom : y + 2,
+							color : this._gridColor.toHexString(),
+							visibility : "hidden"
+						});
+						this._labels.push(div);
+					}
+					if (y + div.clientHeight < this._canvas.height + 10) {
+						div.style.visibility = "visible";
+						// avoid the labels that would overflow
+					}
+				}
+
+				// draw grid
+				ctx.beginPath();
+				if (this._gridType == "long" || tick.label == 0) {
+					ctx.moveTo(0, y);
+					ctx.lineTo(this._canvas.width, y);
+				} else if (this._gridType == "short") {
+					if (this._axisLabelsPlacement == "left") {
+						ctx.moveTo(0, y);
+						ctx.lineTo(this._gridShortSize, y);
+					} else if (this._axisLabelsPlacement == "right") {
+						ctx.moveTo(this._canvas.width, y);
+						ctx.lineTo(this._canvas.width - this._gridShortSize, y);
+					}
+				}
+				ctx.stroke();
+			}
+		}
+	}
+};
+
+//modified function to prevent from drawing hidden labels
+Timeplot.DefaultTimeGeometry.prototype.paint = function() {
+	if (this._canvas) {
+		var unit = this._unit;
+		var ctx = this._canvas.getContext('2d');
+
+		var gradient = ctx.createLinearGradient(0, 0, 0, this._canvas.height);
+
+		ctx.strokeStyle = gradient;
+		ctx.lineWidth = this._gridLineWidth;
+		ctx.lineJoin = 'miter';
+
+		// paint grid
+		if (this._gridColor) {
+			gradient.addColorStop(0, this._gridColor.toString());
+			gradient.addColorStop(1, "rgba(255,255,255,0.9)");
+			for (var i = 0; i < this._grid.length; i++) {
+				var tick = this._grid[i];
+				var x = Math.floor(tick.x) + 0.5;
+				if (this._axisLabelsPlacement == "top") {
+					var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label", {
+						left : x + 4,
+						top : 2,
+						visibility : "hidden"
+					});
+					this._labels.push(div);
+				} else if (this._axisLabelsPlacement == "bottom") {
+					var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label", {
+						left : x + 4,
+						bottom : 2,
+						visibility : "hidden"
+					});
+					this._labels.push(div);
+				}
+				if (!this._hideLabels && x + div.clientWidth < this._canvas.width + 10) {
+					div.style.visibility = "visible";
+					// avoid the labels that would overflow
+				}
+
+				// draw separator
+				ctx.beginPath();
+				ctx.moveTo(x, 0);
+				ctx.lineTo(x, this._canvas.height);
+				ctx.stroke();
+			}
+		}
+	}
+};
+
+Timeplot.Plot.prototype.getSliceNumber = function() {
+	return this._dataSource.getData().times.length;
+};
+
+Timeplot.Plot.prototype.getSliceId = function(time) {
+	var data = this._dataSource.getData();
+	for (var k = 0; k < data.times.length; k++) {
+		if (data.times[k].getTime() == time.getTime()) {
+			return k;
+		}
+	}
+	return null;
+};
+
+Timeplot.Plot.prototype.getSliceTime = function(index) {
+	var data = this._dataSource.getData();
+	if (0 <= index && index < data.times.length) {
+		return data.times[index];
+	}
+	return null;
+};
+
+Timeplot.Plot.prototype.initialize = function() {
+	if (this._dataSource && this._dataSource.getValue) {
+		this._timeFlag = this._timeplot.putDiv("timeflag", "timeplot-timeflag");
+		this._valueFlag = this._timeplot.putDiv(this._id + "valueflag", "timeplot-valueflag");
+		this._pinValueFlag = this._timeplot.putDiv(this._id + "pinvalueflag", "timeplot-valueflag");
+		var pin = document.getElementById(this._timeplot._id + "-" + this._id + "pinvalueflag");
+		if (SimileAjax.Platform.browser.isIE && SimileAjax.Platform.browser.majorVersion < 9) {
+			var cssText = "border: 1px solid " + this._plotInfo.lineColor.toString() + "; background-color: " + this._plotInfo.fillColor.toString() + ";";
+			cssText = cssText.replace(/rgba\((\s*\d{1,3}),(\s*\d{1,3}),(\s*\d{1,3}),(\s*\d{1}|\s*\d{1}\.\d+)\)/g, 'rgb($1,$2,$3)');
+			pin.style.setAttribute("cssText", cssText);
+		} else {
+			pin.style.border = "1px solid " + this._plotInfo.lineColor.toString();
+			pin.style.backgroundColor = this._plotInfo.fillColor.toString();
+		}
+		this._valueFlagLineLeft = this._timeplot.putDiv(this._id + "valueflagLineLeft", "timeplot-valueflag-line");
+		this._valueFlagLineRight = this._timeplot.putDiv(this._id + "valueflagLineRight", "timeplot-valueflag-line");
+		this._pinValueFlagLineLeft = this._timeplot.putDiv(this._id + "pinValueflagLineLeft", "timeplot-valueflag-line");
+		this._pinValueFlagLineRight = this._timeplot.putDiv(this._id + "pinValueflagLineRight", "timeplot-valueflag-line");
+		if (!this._valueFlagLineLeft.firstChild) {
+			this._valueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_left.png"));
+			this._valueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_right.png"));
+		}
+		if (!this._pinValueFlagLineLeft.firstChild) {
+			this._pinValueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(GeoTemConfig.path + "plot-line_left.png"));
+			this._pinValueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(GeoTemConfig.path + "plot-line_right.png"));
+		}
+		this._valueFlagPole = this._timeplot.putDiv(this._id + "valuepole", "timeplot-valueflag-pole");
+
+		var opacity = this._plotInfo.valuesOpacity;
+
+		SimileAjax.Graphics.setOpacity(this._timeFlag, opacity);
+		SimileAjax.Graphics.setOpacity(this._valueFlag, opacity);
+		SimileAjax.Graphics.setOpacity(this._pinValueFlag, opacity);
+		SimileAjax.Graphics.setOpacity(this._valueFlagLineLeft, opacity);
+		SimileAjax.Graphics.setOpacity(this._valueFlagLineRight, opacity);
+		SimileAjax.Graphics.setOpacity(this._pinValueFlagLineLeft, opacity);
+		SimileAjax.Graphics.setOpacity(this._pinValueFlagLineRight, opacity);
+		SimileAjax.Graphics.setOpacity(this._valueFlagPole, opacity);
+
+		var plot = this;
+
+		var mouseOverHandler = function(elmt, evt, target) {
+			plot._timeFlag.style.visibility = "visible";
+			plot._valueFlag.style.visibility = "visible";
+			plot._pinValueFlag.style.visibility = "visible";
+			plot._valueFlagLineLeft.style.visibility = "visible";
+			plot._valueFlagLineRight.style.visibility = "visible";
+			plot._pinValueFlagLineLeft.style.visibility = "visible";
+			plot._pinValueFlagLineRight.style.visibility = "visible";
+			plot._valueFlagPole.style.visibility = "visible";
+			if (plot._plotInfo.showValues) {
+				plot._valueFlag.style.display = "block";
+				mouseMoveHandler(elmt, evt, target);
+			}
+		}
+		var mouseOutHandler = function(elmt, evt, target) {
+			plot._timeFlag.style.visibility = "hidden";
+			plot._valueFlag.style.visibility = "hidden";
+			plot._pinValueFlag.style.visibility = "hidden";
+			plot._valueFlagLineLeft.style.visibility = "hidden";
+			plot._valueFlagLineRight.style.visibility = "hidden";
+			plot._pinValueFlagLineLeft.style.visibility = "hidden";
+			plot._pinValueFlagLineRight.style.visibility = "hidden";
+			plot._valueFlagPole.style.visibility = "hidden";
+		}
+		var day = 24 * 60 * 60 * 1000;
+		var month = 30 * day;
+
+		var mouseMoveHandler = function(elmt, evt, target) {
+			if ( typeof SimileAjax != "undefined" && plot._plotInfo.showValues) {
+				var c = plot._canvas;
+				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot._canvas).x);
+				if (x > c.width)
+					x = c.width;
+				if (isNaN(x) || x < 0)
+					x = 0;
+				var t = plot._timeGeometry.fromScreen(x);
+				if (t == 0) {// something is wrong
+					plot._valueFlag.style.display = "none";
+					return;
+				}
+
+				var v, validTime;
+				if (plot.style == 'bars') {
+					var time1 = plot._dataSource.getClosestValidTime(t);
+					var x1 = plot._timeGeometry.toScreen(time1);
+					var index_x1 = plot.getSliceId(time1);
+					var time2;
+					if (x < x1 && index_x1 > 0 || x >= x1 && index_x1 == plot.getSliceNumber() - 1) {
+						time2 = plot.getSliceTime(index_x1 - 1);
+					} else {
+						time2 = plot.getSliceTime(index_x1 + 1);
+					}
+					var x2 = plot._timeGeometry.toScreen(time2);
+
+					var t1 = new Date(time1);
+					var t2 = new Date(time2);
+					var unit = plot._timeGeometry.extendedDataSource.unit;
+					var l;
+					if (x1 < x2) {
+						l = SimileAjax.DateTime.getTimeLabel(unit, t1) + '-' + SimileAjax.DateTime.getTimeLabel(unit, t2);
+						validTime = time1;
+					} else {
+						l = SimileAjax.DateTime.getTimeLabel(unit, t2) + '-' + SimileAjax.DateTime.getTimeLabel(unit, t1);
+						validTime = time2;
+					}
+					v = plot._dataSource.getValue(validTime);
+					if (plot._plotInfo.roundValues)
+						v = Math.round(v);
+					plot._valueFlag.innerHTML = v;
+					plot._timeFlag.innerHTML = l;
+					x = (x1 + x2 ) / 2;
+				} else if (plot.style == 'graph') {
+					validTime = plot._dataSource.getClosestValidTime(t);
+					x = plot._timeGeometry.toScreen(validTime);
+					v = plot._dataSource.getValue(validTime);
+					if (plot._plotInfo.roundValues)
+						v = Math.round(v);
+					plot._valueFlag.innerHTML = v;
+					var t = new Date(validTime);
+					var unit = plot._timeGeometry.extendedDataSource.unit;
+					var l = SimileAjax.DateTime.getTimeLabel(unit, t);
+					plot._timeFlag.innerHTML = l;
+				}
+
+				var tw = plot._timeFlag.clientWidth;
+				var th = plot._timeFlag.clientHeight;
+				var tdw = Math.round(tw / 2);
+				var vw = plot._valueFlag.clientWidth;
+				var vh = plot._valueFlag.clientHeight;
+				var y = plot._valueGeometry.toScreen(v);
+
+				if (x + tdw > c.width) {
+					var tx = c.width - tdw;
+				} else if (x - tdw < 0) {
+					var tx = tdw;
+				} else {
+					var tx = x;
+				}
+
+				plot._timeplot.placeDiv(plot._valueFlagPole, {
+					left : x,
+					top : 0,
+					height : c.height,
+					display : "block"
+				});
+				plot._timeplot.placeDiv(plot._timeFlag, {
+					left : tx - tdw,
+					top : 0,
+					display : "block"
+				});
+
+				var sliceId = plot.getSliceId(validTime);
+				var pvw, pvh = 0, pinY;
+				if (plot.pins[sliceId].count > 0) {
+					plot._pinValueFlag.innerHTML = plot.pins[sliceId].count;
+					pvw = plot._pinValueFlag.clientWidth;
+					pvh = plot._pinValueFlag.clientHeight;
+					pinY = plot.pins[sliceId].height;
+				}
+				var rightOverflow = x + vw + 14 > c.width;
+				var leftOverflow = false;
+				if (plot.pins[sliceId].count > 0) {
+					if (x - pvw - 14 < 0) {
+						leftOverflow = true;
+					}
+				}
+				var shiftV, shiftP;
+				if (plot.pins[sliceId].count > 0) {
+					var cut = y - pinY < vh / 2 + pvh / 2;
+					if ((leftOverflow || rightOverflow ) && cut) {
+						shiftV = 0;
+						shiftP = pvh;
+					} else {
+						shiftV = vh / 2;
+						shiftP = pvh / 2;
+					}
+				} else {
+					shiftV = vh / 2;
+				}
+
+				if (x + vw + 14 > c.width && y + vh / 2 + 4 > c.height) {
+					plot._valueFlagLineLeft.style.display = "none";
+					plot._timeplot.placeDiv(plot._valueFlagLineRight, {
+						left : x - 14,
+						bottom : y - 14,
+						display : "block"
+					});
+					plot._timeplot.placeDiv(plot._valueFlag, {
+						left : x - vw - 13,
+						bottom : y - 13 - shiftV,
+						display : "block"
+					});
+				} else if (x + vw + 14 > c.width && y + vh / 2 + 4 < c.height) {
+					plot._valueFlagLineRight.style.display = "none";
+					plot._timeplot.placeDiv(plot._valueFlagLineLeft, {
+						left : x - 14,
+						bottom : y,
+						display : "block"
+					});
+					plot._timeplot.placeDiv(plot._valueFlag, {
+						left : x - vw - 13,
+						bottom : y + 13 - shiftV,
+						display : "block"
+					});
+				} else if (x + vw + 14 < c.width && y + vh / 2 + 4 > c.height) {
+					plot._valueFlagLineRight.style.display = "none";
+					plot._timeplot.placeDiv(plot._valueFlagLineLeft, {
+						left : x,
+						bottom : y - 13,
+						display : "block"
+					});
+					plot._timeplot.placeDiv(plot._valueFlag, {
+						left : x + 13,
+						bottom : y - 13 - shiftV,
+						display : "block"
+					});
+				} else {
+					plot._valueFlagLineLeft.style.display = "none";
+					plot._timeplot.placeDiv(plot._valueFlagLineRight, {
+						left : x,
+						bottom : y,
+						display : "block"
+					});
+					plot._timeplot.placeDiv(plot._valueFlag, {
+						left : x + 13,
+						bottom : y + 13 - shiftV,
+						display : "block"
+					});
+				}
+
+				if (plot.pins[sliceId].count > 0) {
+					if (x - pvw - 14 < 0 && pinY + pvh + 4 > c.height) {
+						plot._pinValueFlagLineLeft.style.display = "none";
+						plot._timeplot.placeDiv(plot._pinValueFlagLineRight, {
+							left : x,
+							bottom : pinY,
+							display : "block"
+						});
+						plot._timeplot.placeDiv(plot._pinValueFlag, {
+							left : x + 13,
+							bottom : pinY - 13 - shiftP,
+							display : "block"
+						});
+					} else if (x - pvw - 14 < 0 && pinY + pvh + 4 < c.height) {
+						plot._pinValueFlagLineLeft.style.display = "none";
+						plot._timeplot.placeDiv(plot._pinValueFlagLineRight, {
+							left : x,
+							bottom : pinY,
+							display : "block"
+						});
+						plot._timeplot.placeDiv(plot._pinValueFlag, {
+							left : x + 13,
+							bottom : pinY + 13 - shiftP,
+							display : "block"
+						});
+					} else if (x - pvw - 14 >= 0 && pinY + pvh + 4 > c.height) {
+						plot._pinValueFlagLineLeft.style.display = "none";
+						plot._timeplot.placeDiv(plot._pinValueFlagLineRight, {
+							left : x - 13,
+							bottom : pinY - 13,
+							display : "block"
+						});
+						plot._timeplot.placeDiv(plot._pinValueFlag, {
+							left : x - 15 - pvw,
+							bottom : pinY - 13 - shiftP,
+							display : "block"
+						});
+					} else {
+						plot._pinValueFlagLineRight.style.display = "none";
+						plot._timeplot.placeDiv(plot._pinValueFlagLineLeft, {
+							left : x - 14,
+							bottom : pinY,
+							display : "block"
+						});
+						plot._timeplot.placeDiv(plot._pinValueFlag, {
+							left : x - pvw - 15,
+							bottom : pinY + 13 - shiftP,
+							display : "block"
+						});
+					}
+				} else {
+					plot._pinValueFlagLineLeft.style.display = "none";
+					plot._pinValueFlagLineRight.style.display = "none";
+					plot._pinValueFlag.style.display = "none";
+				}
+
+			}
+
+		}
+		var timeplotElement = this._timeplot.getElement();
+		this.mouseover = SimileAjax.DOM.registerPlotEvent(timeplotElement, "mouseover", mouseOverHandler);
+		this.mouseout = SimileAjax.DOM.registerPlotEvent(timeplotElement, "mouseout", mouseOutHandler);
+		this.mousemove = SimileAjax.DOM.registerPlotEvent(timeplotElement, "mousemove", mouseMoveHandler);
+
+		this.opacityPlot = this._timeplot.putDiv("opacityPlot" + this._timeplot._plots.length, "opacityPlot");
+		SimileAjax.Graphics.setOpacity(this.opacityPlot, 50);
+		//		this.opacityPlot.style.zIndex = this._timeplot._plots.length;
+		this._timeplot.placeDiv(this.opacityPlot, {
+			left : 0,
+			bottom : 0,
+			width : this._canvas.width,
+			height : this._canvas.height
+		});
+		this._opacityCanvas = document.createElement("canvas");
+		this.opacityPlot.appendChild(this._opacityCanvas);
+		if (!this._opacityCanvas.getContext && G_vmlCanvasManager)
+			this._opacityCanvas = G_vmlCanvasManager.initElement(this._opacityCanvas);
+		this._opacityCanvas.width = this._canvas.width;
+		this._opacityCanvas.height = this._canvas.height;
+		this._opacityCanvas.style.position = 'absolute';
+		this._opacityCanvas.style.left = '0px';
+		this.opacityPlot.style.visibility = "hidden";
+
+	}
+};
+
+SimileAjax.DOM.registerPlotEvent = function(elmt, eventName, handler) {
+	var handler2 = function(evt) {
+		evt = (evt) ? evt : ((event) ? event : null);
+		if (evt) {
+			var target = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
+			if (target) {
+				target = (target.nodeType == 1 || target.nodeType == 9) ? target : target.parentNode;
+			}
+
+			return handler(elmt, evt, target);
+		}
+		return true;
+	}
+	if (SimileAjax.Platform.browser.isIE) {
+		elmt.attachEvent("on" + eventName, handler2);
+	} else {
+		elmt.addEventListener(eventName, handler2, false);
+	}
+
+	return handler2;
+};
+
+SimileAjax.DOM.getEventRelativeCoordinates = function(evt, elmt) {
+	if (SimileAjax.Platform.browser.isIE) {
+		var coords = SimileAjax.DOM.getPageCoordinates(elmt);
+		return {
+			x : evt.clientX - coords.left,
+			y : evt.clientY - coords.top
+		};
+	} else {
+		var coords = SimileAjax.DOM.getPageCoordinates(elmt);
+
+		if ((evt.type == "DOMMouseScroll") && SimileAjax.Platform.browser.isFirefox && (SimileAjax.Platform.browser.majorVersion == 2)) {
+			// Due to: https://bugzilla.mozilla.org/show_bug.cgi?id=352179
+
+			return {
+				x : evt.screenX - coords.left,
+				y : evt.screenY - coords.top
+			};
+		} else {
+			return {
+				x : evt.pageX - coords.left,
+				y : evt.pageY - coords.top
+			};
+		}
+	}
+};
+
+SimileAjax.Graphics.setOpacity = function(elmt, opacity) {
+	if (SimileAjax.Platform.browser.isIE) {
+		elmt.style.filter = "alpha(opacity = " + opacity + ")";
+	} else {
+		var o = (opacity / 100).toString();
+		elmt.style.opacity = o;
+		elmt.style.MozOpacity = o;
+	}
+};
+
+Timeplot.Plot.prototype.fullOpacityPlot = function(left, right, lp, rp, c) {
+
+	var ctx = this._opacityCanvas.getContext('2d');
+
+	ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
+	ctx.lineWidth = this._plotInfo.lineWidth;
+	ctx.lineJoin = 'miter';
+
+	var h = this._canvas.height;
+	ctx.fillStyle = this._plotInfo.lineColor.toString();
+
+	var data = this._dataSource.getData();
+	var times = data.times;
+	var values = data.values;
+
+	var first = true;
+	ctx.beginPath();
+	ctx.fillStyle = this._plotInfo.lineColor.toString();
+	var lastX = 0, lastY = 0;
+	for (var t = 0; t < times.length; t++) {
+		if (!(times[t].getTime() < left.getTime() || times[t].getTime() > right.getTime())) {
+			var x = this._timeGeometry.toScreen(times[t]);
+			var y = this._valueGeometry.toScreen(values[t]);
+			if (first) {
+				ctx.moveTo(x, h);
+				first = false;
+			}
+			if (this.style == 'bars') {
+				ctx.lineTo(x, h - lastY);
+			}
+			ctx.lineTo(x, h - y);
+			if (times[t].getTime() == right.getTime() || t == times.length - 1)
+				ctx.lineTo(x, h);
+			lastX = x;
+			lastY = y;
+		}
+	}
+	ctx.fill();
+
+};
+
+Timeplot._Impl.prototype.regularGrid = function() {
+
+	var canvas = this.getCanvas();
+	var ctx = canvas.getContext('2d');
+	var gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
+	gradient.addColorStop(0, "rgb(0,0,0)");
+	gradient.addColorStop(1, "rgba(255,255,255,0.9)");
+	ctx.strokeStyle = gradient;
+	ctx.lineWidth = 0.5;
+	ctx.lineJoin = 'miter';
+
+	var xDist = canvas.width / 9;
+	var positions = [];
+	for (var i = 1; i < 9; i++) {
+		var x = i * xDist;
+		ctx.beginPath();
+		ctx.moveTo(x, 0);
+		ctx.lineTo(x, canvas.height);
+
+		ctx.stroke();
+		positions.push({
+			label : '',
+			x : x
+		});
+	}
+	return positions;
+
+};
+
+Timeplot.Plot.prototype._plot = function() {
+	var ctx = this._canvas.getContext('2d');
+	var data = this._dataSource.getData();
+	if (data) {
+		var times = data.times;
+		var values = data.values;
+		var T = times.length;
+		ctx.moveTo(0, 0);
+		var lastX = 0, lastY = 0;
+		for (var t = 0; t < T; t++) {
+			var x = this._timeGeometry.toScreen(times[t]);
+			var y = this._valueGeometry.toScreen(values[t]);
+			if (t > 0 && (values[t - 1] > 0 || values[t] > 0 )) {
+				if (this.style == 'graph') {
+					ctx.lineTo(x, y);
+				}
+				if (this.style == 'bars') {
+					if (values[t - 1] > 0) {
+						ctx.lineTo(x, lastY);
+					} else {
+						ctx.moveTo(x, lastY);
+					}
+					ctx.lineTo(x, y);
+				}
+			} else {
+				ctx.moveTo(x, y);
+			}
+			lastX = x;
+			lastY = y;
+		}
+	}
+};
+
+SimileAjax.DOM.registerEvent = function(elmt, eventName, handler) {
+	var handler2 = function(evt) {
+		evt = (evt) ? evt : ((event) ? event : null);
+		if (evt) {
+			var target = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
+			if (target) {
+				target = (target.nodeType == 1 || target.nodeType == 9) ? target : target.parentNode;
+			}
+
+			return handler(elmt, evt, target);
+		}
+		return true;
+	}
+	if (SimileAjax.Platform.browser.isIE) {
+		elmt.attachEvent("on" + eventName, handler2);
+	} else {
+		if (eventName == "mousewheel") {
+			eventName = "DOMMouseScroll";
+		}
+		elmt.addEventListener(eventName, handler2, false);
+	}
+};
+
+Timeplot._Impl.prototype._setUpright = function(ctx, canvas) {
+	// excanvas+IE requires this to be done only once, ever; actual canvas
+	// implementations reset and require this for each call to re-layout
+	// modified: problem does not exist for IE9
+	if (!SimileAjax.Platform.browser.isIE)
+		this._upright = false;
+	else if (SimileAjax.Platform.browser.majorVersion > 8)
+		this._upright = false;
+	if (!this._upright) {
+		this._upright = true;
+		ctx.translate(0, canvas.height);
+		ctx.scale(1, -1);
+	}
+};
+
+Timeplot._Impl.prototype._resizeCanvas = function() {
+	var canvas = this.getCanvas();
+	if (canvas.firstChild) {
+		canvas.firstChild.style.width = canvas.clientWidth + 'px';
+		canvas.firstChild.style.height = canvas.clientHeight + 'px';
+	}
+	for (var i = 0; i < this._plots.length; i++) {
+		var opacityCanvas = this._plots[i]._opacityCanvas;
+		if (opacityCanvas.firstChild) {
+			opacityCanvas.firstChild.style.width = opacityCanvas.clientWidth + 'px';
+			opacityCanvas.firstChild.style.height = opacityCanvas.clientHeight + 'px';
+		}
+	}
+};
+
+Timeplot._Impl.prototype.getWidth = function() {
+	var canvas = this.getCanvas();
+	if ( typeof canvas.width != 'undefined' && this._containerDiv.clientWidth == 0) {
+		return canvas.width;
+	}
+	return this._containerDiv.clientWidth;
+};
+
+Timeplot._Impl.prototype.getHeight = function() {
+	var canvas = this.getCanvas();
+	if ( typeof canvas.height != 'undefined' && this._containerDiv.clientHeight == 0) {
+		return canvas.height;
+	}
+	return this._containerDiv.clientHeight;
+};
+
+Timeplot._Impl.prototype._prepareCanvas = function() {
+	var canvas = this.getCanvas();
+
+	// using jQuery. note we calculate the average padding; if your
+	// padding settings are not symmetrical, the labels will be off
+	// since they expect to be centered on the canvas.
+	var con = SimileAjax.jQuery(this._containerDiv);
+	this._paddingX = (parseInt(con.css('paddingLeft')) + parseInt(con.css('paddingRight'))) / 2;
+	this._paddingY = (parseInt(con.css('paddingTop')) + parseInt(con.css('paddingBottom'))) / 2;
+
+	if (isNaN(this._paddingX)) {
+		this._paddingX = 0;
+	}
+	if (isNaN(this._paddingY)) {
+		this._paddingY = 0;
+	}
+
+	canvas.width = this.getWidth() - (this._paddingX * 2);
+	canvas.height = this.getHeight() - (this._paddingY * 2);
+
+	var ctx = canvas.getContext('2d');
+	this._setUpright(ctx, canvas);
+	ctx.globalCompositeOperation = 'source-over';
+};