You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ca...@apache.org on 2007/01/11 23:36:18 UTC

svn commit: r495409 [6/47] - in /myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource: ./ src/ src/animation/ src/cal/ src/charting/ src/charting/svg/ src/charting/vml/ src/collections/ src/crypto/ src/data/ src/data/c...

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/iCalendar.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/iCalendar.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/iCalendar.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/iCalendar.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,815 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.cal.iCalendar");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.cal.textDirectory");
+dojo.require("dojo.date.common");
+dojo.require("dojo.date.serialize");
+
+
+dojo.cal.iCalendar.fromText =  function (/* string */text) {
+	// summary
+	// Parse text of an iCalendar and return an array of iCalendar objects
+
+	var properties = dojo.cal.textDirectory.tokenise(text);
+	var calendars = [];
+
+	//dojo.debug("Parsing iCal String");
+	for (var i = 0, begun = false; i < properties.length; i++) {
+		var prop = properties[i];
+		if (!begun) {
+			if (prop.name == 'BEGIN' && prop.value == 'VCALENDAR') {
+				begun = true;
+				var calbody = [];
+			}
+		} else if (prop.name == 'END' && prop.value == 'VCALENDAR') {
+			calendars.push(new dojo.cal.iCalendar.VCalendar(calbody));
+			begun = false;
+		} else {
+			calbody.push(prop);
+		}
+	}
+	return /* array */calendars;
+}
+
+
+dojo.cal.iCalendar.Component = function (/* string */ body ) {
+	// summary
+	// A component is the basic container of all this stuff. 
+
+	if (!this.name) {
+		this.name = "COMPONENT"
+	}
+
+	this.properties = [];
+	this.components = [];
+
+	if (body) {
+		for (var i = 0, context = ''; i < body.length; i++) {
+			if (context == '') {
+				if (body[i].name == 'BEGIN') {
+					context = body[i].value;
+					var childprops = [];
+				} else {
+					this.addProperty(new dojo.cal.iCalendar.Property(body[i]));
+				}
+			} else if (body[i].name == 'END' && body[i].value == context) {
+				if (context=="VEVENT") {
+					this.addComponent(new dojo.cal.iCalendar.VEvent(childprops));
+				} else if (context=="VTIMEZONE") {
+					this.addComponent(new dojo.cal.iCalendar.VTimeZone(childprops));
+				} else if (context=="VTODO") {
+					this.addComponent(new dojo.cal.iCalendar.VTodo(childprops));
+				} else if (context=="VJOURNAL") {
+					this.addComponent(new dojo.cal.iCalendar.VJournal(childprops));
+				} else if (context=="VFREEBUSY") {
+					this.addComponent(new dojo.cal.iCalendar.VFreeBusy(childprops));
+				} else if (context=="STANDARD") {
+					this.addComponent(new dojo.cal.iCalendar.Standard(childprops));
+				} else if (context=="DAYLIGHT") {
+					this.addComponent(new dojo.cal.iCalendar.Daylight(childprops));
+				} else if (context=="VALARM") {
+					this.addComponent(new dojo.cal.iCalendar.VAlarm(childprops));
+				}else {
+					dojo.unimplemented("dojo.cal.iCalendar." + context);
+				}
+				context = '';
+			} else {
+				childprops.push(body[i]);
+			}
+		}
+
+		if (this._ValidProperties) {
+			this.postCreate();
+		}
+	}
+}
+
+dojo.extend(dojo.cal.iCalendar.Component, {
+
+	addProperty: function (prop) {
+		// summary
+		// push a new property onto a component.
+		this.properties.push(prop);
+		this[prop.name.toLowerCase()] = prop;
+	},
+
+	addComponent: function (prop) {
+		// summary
+		// add a component to this components list of children.
+		this.components.push(prop);
+	},
+
+	postCreate: function() {
+		for (var x=0; x<this._ValidProperties.length; x++) {
+			var evtProperty = this._ValidProperties[x];
+			var found = false;
+	
+			for (var y=0; y<this.properties.length; y++) {	
+				var prop = this.properties[y];
+				var propName = prop.name.toLowerCase();
+				if (dojo.lang.isArray(evtProperty)) {
+
+					var alreadySet = false;
+					for (var z=0; z<evtProperty.length; z++) {
+						var evtPropertyName = evtProperty[z].name.toLowerCase();
+						if((this[evtPropertyName])  && (evtPropertyName != propName )) {
+							alreadySet=true;
+						} 
+					}
+					if (!alreadySet) {
+						this[propName] = prop;
+					}
+				} else {
+					if (propName == evtProperty.name.toLowerCase()) {
+						found = true;
+						if (evtProperty.occurance == 1){
+							this[propName] = prop;
+						} else {
+							found = true;
+							if (!dojo.lang.isArray(this[propName])) {
+							 	this[propName] = [];
+							}
+							this[propName].push(prop);
+						}
+					}
+				}
+			}
+
+			if (evtProperty.required && !found) {	
+				dojo.debug("iCalendar - " + this.name + ": Required Property not found: " + evtProperty.name);
+			}
+		}
+
+		// parse any rrules		
+		if (dojo.lang.isArray(this.rrule)) {
+			for(var x=0; x<this.rrule.length; x++) {
+				var rule = this.rrule[x].value;
+
+				//add a place to cache dates we have checked for recurrance
+				this.rrule[x].cache = function() {};
+				
+				var temp = rule.split(";");
+				for (var y=0; y<temp.length; y++) {
+					var pair = temp[y].split("=");
+					var key = pair[0].toLowerCase();
+					var val = pair[1];
+
+					if ((key == "freq") || (key=="interval") || (key=="until")) {
+						this.rrule[x][key]= val;
+					} else {
+						var valArray = val.split(",");
+						this.rrule[x][key] = valArray; 
+					}
+				}	
+			}
+			this.recurring = true;
+		}
+
+	}, 
+
+	toString: function () {
+		// summary
+		// output a string representation of this component.
+		return "[iCalendar.Component; " + this.name + ", " + this.properties.length +
+			" properties, " + this.components.length + " components]";
+	}
+});
+
+dojo.cal.iCalendar.Property = function (prop) {
+	// summary
+	// A single property of a component.
+
+	// unpack the values
+	this.name = prop.name;
+	this.group = prop.group;
+	this.params = prop.params;
+	this.value = prop.value;
+
+}
+
+dojo.extend(dojo.cal.iCalendar.Property, {
+	toString: function () {	
+		// summary
+		// output a string reprensentation of this component.
+		return "[iCalenday.Property; " + this.name + ": " + this.value + "]";
+	}
+});
+
+// This is just a little helper function for the Component Properties
+var _P = function (n, oc, req) {
+	return {name: n, required: (req) ? true : false,
+		occurance: (oc == '*' || !oc) ? -1 : oc}
+}
+
+/*
+ * VCALENDAR
+ */
+
+dojo.cal.iCalendar.VCalendar = function (/* string */ calbody) {
+	// summary
+	// VCALENDAR Component
+
+	this.name = "VCALENDAR";
+	this.recurring = [];
+	this.nonRecurringEvents = function(){};
+	dojo.cal.iCalendar.Component.call(this, calbody);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VCalendar, dojo.cal.iCalendar.Component);
+
+dojo.extend(dojo.cal.iCalendar.VCalendar, {
+
+	addComponent: function (prop) {
+		// summary
+		// add component to the calenadar that makes it easy to pull them out again later.
+		this.components.push(prop);
+		if (prop.name.toLowerCase() == "vevent") {
+			if (prop.rrule) {
+				this.recurring.push(prop);
+			} else {
+				var startDate = prop.getDate();
+				var month = startDate.getMonth() + 1;
+				var dateString= month + "-" + startDate.getDate() + "-" + startDate.getFullYear();
+				if (!dojo.lang.isArray(this[dateString])) {
+					this.nonRecurringEvents[dateString] = [];
+				}
+				this.nonRecurringEvents[dateString].push(prop);
+			}
+		}
+	},
+
+	preComputeRecurringEvents: function(until) {
+		var calculatedEvents = function(){};
+
+		for(var x=0; x<this.recurring.length; x++) {
+			var dates = this.recurring[x].getDates(until);
+			for (var y=0; y<dates.length;y++) {
+				var month = dates[y].getMonth() + 1;
+				var dateStr = month + "-" + dates[y].getDate() + "-" + dates[y].getFullYear();
+				if (!dojo.lang.isArray(calculatedEvents[dateStr])) {
+					calculatedEvents[dateStr] = [];
+				}
+
+				if (!dojo.lang.inArray(calculatedEvents[dateStr], this.recurring[x])) { 
+					calculatedEvents[dateStr].push(this.recurring[x]);
+				} 
+			}
+		}
+		this.recurringEvents = calculatedEvents;
+	
+	},
+
+	getEvents: function(/* Date */ date) {
+		// summary
+		// Gets all events occuring on a particular date
+		var events = [];
+		var recur = [];
+		var nonRecur = [];
+		var month = date.getMonth() + 1;
+		var dateStr= month + "-" + date.getDate() + "-" + date.getFullYear();
+		if (dojo.lang.isArray(this.nonRecurringEvents[dateStr])) {
+			nonRecur= this.nonRecurringEvents[dateStr];
+			dojo.debug("Number of nonRecurring Events: " + nonRecur.length);
+		} 
+		
+
+		if (dojo.lang.isArray(this.recurringEvents[dateStr])) {
+			recur= this.recurringEvents[dateStr];
+		} 
+
+		events = recur.concat(nonRecur);
+
+		if (events.length > 0) {
+			return events;
+		} 
+
+		return null;			
+	}
+});
+
+/*
+ * STANDARD
+ */
+
+var StandardProperties = [
+	_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true),
+	_P("comment"), _P("rdate"), _P("rrule"), _P("tzname")
+];
+
+
+dojo.cal.iCalendar.Standard = function (/* string */ body) {
+	// summary
+	// STANDARD Component
+
+	this.name = "STANDARD";
+	this._ValidProperties = StandardProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.Standard, dojo.cal.iCalendar.Component);
+
+/*
+ * DAYLIGHT
+ */
+
+var DaylightProperties = [
+	_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true),
+	_P("comment"), _P("rdate"), _P("rrule"), _P("tzname")
+];
+
+dojo.cal.iCalendar.Daylight = function (/* string */ body) {
+	// summary
+	// Daylight Component
+	this.name = "DAYLIGHT";
+	this._ValidProperties = DaylightProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.Daylight, dojo.cal.iCalendar.Component);
+
+/*
+ * VEVENT
+ */
+
+var VEventProperties = [
+	// these can occur once only
+	_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1),
+	_P("geo", 1), _P("last-mod", 1), _P("location", 1), _P("organizer", 1),
+	_P("priority", 1), _P("dtstamp", 1), _P("seq", 1), _P("status", 1),
+	_P("summary", 1), _P("transp", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1),
+	// these two are exclusive
+	[_P("dtend", 1), _P("duration", 1)],
+	// these can occur many times over
+	_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
+	_P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"),
+	_P("rdate"), _P("rrule")
+];
+
+dojo.cal.iCalendar.VEvent = function (/* string */ body) {
+	// summary 
+	// VEVENT Component
+	this._ValidProperties = VEventProperties;
+	this.name = "VEVENT";
+	dojo.cal.iCalendar.Component.call(this, body);
+	this.recurring = false;
+	this.startDate = dojo.date.fromIso8601(this.dtstart.value);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VEvent, dojo.cal.iCalendar.Component);
+
+dojo.extend(dojo.cal.iCalendar.VEvent, {
+		getDates: function(until) {
+			var dtstart = this.getDate();
+
+			var recurranceSet = [];
+			var weekdays=["su","mo","tu","we","th","fr","sa"];
+			var order = { 
+				"daily": 1, "weekly": 2, "monthly": 3, "yearly": 4,
+				"byday": 1, "bymonthday": 1, "byweekno": 2, "bymonth": 3, "byyearday": 4};
+
+			// expand rrules into the recurrance 
+			for (var x=0; x<this.rrule.length; x++) {
+				var rrule = this.rrule[x];
+				var freq = rrule.freq.toLowerCase();
+				var interval = 1;
+
+				if (rrule.interval > interval) {
+					interval = rrule.interval;
+				}
+
+				var set = [];
+				var freqInt = order[freq];
+
+				if (rrule.until) {
+					var tmpUntil = dojo.date.fromIso8601(rrule.until);
+				} else {
+					var tmpUntil = until
+				}
+
+				if (tmpUntil > until) {
+					tmpUntil = until
+				}
+
+
+				if (dtstart<tmpUntil) {
+
+					var expandingRules = function(){};
+					var cullingRules = function(){};
+					expandingRules.length=0;
+					cullingRules.length =0;
+
+					switch(freq) {
+						case "yearly":
+							var nextDate = new Date(dtstart);
+							set.push(nextDate);
+							while(nextDate < tmpUntil) {
+								nextDate.setYear(nextDate.getFullYear()+interval);
+								tmpDate = new Date(nextDate);
+								if(tmpDate < tmpUntil) {
+									set.push(tmpDate);
+								}
+							}
+							break;
+						case "monthly":
+							nextDate = new Date(dtstart);
+							set.push(nextDate);
+							while(nextDate < tmpUntil) {
+								nextDate.setMonth(nextDate.getMonth()+interval);
+								var tmpDate = new Date(nextDate);
+								if (tmpDate < tmpUntil) {
+									set.push(tmpDate);
+								}
+							}
+							break;
+						case "weekly":
+							nextDate = new Date(dtstart);
+							set.push(nextDate);
+							while(nextDate < tmpUntil) {
+								nextDate.setDate(nextDate.getDate()+(7*interval));
+								var tmpDate = new Date(nextDate);
+								if (tmpDate < tmpUntil) {
+									set.push(tmpDate);
+								}
+							}
+							break;	
+						case "daily":
+							nextDate = new Date(dtstart);
+							set.push(nextDate);
+							while(nextDate < tmpUntil) {
+								nextDate.setDate(nextDate.getDate()+interval);
+								var tmpDate = new Date(nextDate);
+								if (tmpDate < tmpUntil) {
+									set.push(tmpDate);
+								}
+							}
+							break;
+	
+					}
+
+					if ((rrule["bymonth"]) && (order["bymonth"]<freqInt))	{
+						for (var z=0; z<rrule["bymonth"].length; z++) {
+							if (z==0) {
+								for (var zz=0; zz < set.length; zz++) {
+									set[zz].setMonth(rrule["bymonth"][z]-1);
+								}
+							} else {
+								var subset=[];
+								for (var zz=0; zz < set.length; zz++) {
+									var newDate = new Date(set[zz]);
+									newDate.setMonth(rrule[z]);
+									subset.push(newDate);
+								}
+								tmp = set.concat(subset);
+								set = tmp;
+							}
+						}
+					}
+
+					
+					// while the spec doesn't prohibit it, it makes no sense to have a bymonth and a byweekno at the same time
+					// and if i'm wrong then i don't know how to apply that rule.  This is also documented elsewhere on the web
+					if (rrule["byweekno"] && !rrule["bymonth"]) {	
+						dojo.debug("TODO: no support for byweekno yet");
+					}
+
+
+					// while the spec doesn't prohibit it, it makes no sense to have a bymonth and a byweekno at the same time
+					// and if i'm wrong then i don't know how to apply that rule.  This is also documented elsewhere on the web
+					if (rrule["byyearday"] && !rrule["bymonth"] && !rrule["byweekno"] ) {	
+						if (rrule["byyearday"].length > 1) {
+							var regex = "([+-]?)([0-9]{1,3})";
+							for (var z=1; x<rrule["byyearday"].length; z++) {
+								var regexResult = rrule["byyearday"][z].match(regex);
+								if (z==1) {
+									for (var zz=0; zz < set.length; zz++) {
+										if (regexResult[1] == "-") {
+											dojo.date.setDayOfYear(set[zz],366-regexResult[2]);
+										} else {
+											dojo.date.setDayOfYear(set[zz],regexResult[2]);
+										}
+									}
+								}	else {
+									var subset=[];
+									for (var zz=0; zz < set.length; zz++) {
+										var newDate = new Date(set[zz]);
+										if (regexResult[1] == "-") {
+											dojo.date.setDayOfYear(newDate,366-regexResult[2]);
+										} else {
+											dojo.date.setDayOfYear(newDate,regexResult[2]);
+										}
+										subset.push(newDate);
+									}
+									tmp = set.concat(subset);
+									set = tmp;
+								}
+							}
+						}
+					}
+
+					if (rrule["bymonthday"]  && (order["bymonthday"]<freqInt)) {	
+						if (rrule["bymonthday"].length > 0) {
+							var regex = "([+-]?)([0-9]{1,3})";
+							for (var z=0; z<rrule["bymonthday"].length; z++) {
+								var regexResult = rrule["bymonthday"][z].match(regex);
+								if (z==0) {
+									for (var zz=0; zz < set.length; zz++) {
+										if (regexResult[1] == "-") {
+											if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+												set[zz].setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
+											}
+										} else {
+											if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+												set[zz].setDate(regexResult[2]);
+											}
+										}
+									}
+								}	else {
+									var subset=[];
+									for (var zz=0; zz < set.length; zz++) {
+										var newDate = new Date(set[zz]);
+										if (regexResult[1] == "-") {
+											if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+												newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
+											}
+										} else {
+											if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+												newDate.setDate(regexResult[2]);
+											}
+										}
+										subset.push(newDate);
+									}
+									tmp = set.concat(subset);
+									set = tmp;
+								}
+							}
+						}
+					}
+
+					if (rrule["byday"]  && (order["byday"]<freqInt)) {	
+						if (rrule["bymonth"]) {
+							if (rrule["byday"].length > 0) {
+								var regex = "([+-]?)([0-9]{0,1}?)([A-Za-z]{1,2})";
+								for (var z=0; z<rrule["byday"].length; z++) {
+									var regexResult = rrule["byday"][z].match(regex);
+									var occurance = regexResult[2];
+									var day = regexResult[3].toLowerCase();
+
+
+									if (z==0) {
+										for (var zz=0; zz < set.length; zz++) {
+											if (regexResult[1] == "-") {
+												//find the nth to last occurance of date 
+												var numDaysFound = 0;
+												var lastDayOfMonth = dojo.date.getDaysInMonth(set[zz]);
+												var daysToSubtract = 1;
+												set[zz].setDate(lastDayOfMonth); 
+												if (weekdays[set[zz].getDay()] == day) {
+													numDaysFound++;
+													daysToSubtract=7;
+												}
+												daysToSubtract = 1;
+												while (numDaysFound < occurance) {
+													set[zz].setDate(set[zz].getDate()-daysToSubtract);	
+													if (weekdays[set[zz].getDay()] == day) {
+														numDaysFound++;
+														daysToSubtract=7;	
+													}
+												}
+											} else {
+												if (occurance) {
+													var numDaysFound=0;
+													set[zz].setDate(1);
+													var daysToAdd=1;
+
+													if(weekdays[set[zz].getDay()] == day) {
+														numDaysFound++;
+														daysToAdd=7;
+													}
+
+													while(numDaysFound < occurance) {
+														set[zz].setDate(set[zz].getDate()+daysToAdd);
+														if(weekdays[set[zz].getDay()] == day) {
+															numDaysFound++;
+															daysToAdd=7;
+														}
+													}
+												} else {
+													//we're gonna expand here to add a date for each of the specified days for each month
+													var numDaysFound=0;
+													var subset = [];
+
+													lastDayOfMonth = new Date(set[zz]);
+													var daysInMonth = dojo.date.getDaysInMonth(set[zz]);
+													lastDayOfMonth.setDate(daysInMonth);
+
+													set[zz].setDate(1);
+												
+													if (weekdays[set[zz].getDay()] == day) {
+														numDaysFound++;
+													}
+													var tmpDate = new Date(set[zz]);
+													daysToAdd = 1;
+													while(tmpDate.getDate() < lastDayOfMonth) {
+														if (weekdays[tmpDate.getDay()] == day) {
+															numDaysFound++;
+															if (numDaysFound==1) {
+																set[zz] = tmpDate;
+															} else {
+																subset.push(tmpDate);
+																tmpDate = new Date(tmpDate);
+																daysToAdd=7;	
+																tmpDate.setDate(tmpDate.getDate() + daysToAdd);
+															}
+														} else {
+															tmpDate.setDate(tmpDate.getDate() + daysToAdd);
+														}
+													}
+													var t = set.concat(subset);
+													set = t; 
+												}
+											}
+										}
+									}	else {
+										var subset=[];
+										for (var zz=0; zz < set.length; zz++) {
+											var newDate = new Date(set[zz]);
+											if (regexResult[1] == "-") {
+												if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+													newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
+												}
+											} else {
+												if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
+													newDate.setDate(regexResult[2]);
+												}
+											}
+											subset.push(newDate);
+										}
+										tmp = set.concat(subset);
+										set = tmp;
+									}
+								}
+							}
+						} else {
+							dojo.debug("TODO: byday within a yearly rule without a bymonth");
+						}
+					}
+
+					dojo.debug("TODO: Process BYrules for units larger than frequency");
+			
+					//add this set of events to the complete recurranceSet	
+					var tmp = recurranceSet.concat(set);
+					recurranceSet = tmp;
+				}
+			}
+
+			// TODO: add rdates to the recurrance set here
+
+			// TODO: subtract exdates from the recurrance set here
+
+			//TODO:  subtract dates generated by exrules from recurranceSet here
+
+			recurranceSet.push(dtstart);
+			return recurranceSet;
+		},
+
+		getDate: function() {
+			return dojo.date.fromIso8601(this.dtstart.value);
+		}
+});
+
+/*
+ * VTIMEZONE
+ */
+
+var VTimeZoneProperties = [
+	_P("tzid", 1, true), _P("last-mod", 1), _P("tzurl", 1)
+
+	// one of 'standardc' or 'daylightc' must occur
+	// and each may occur more than once.
+];
+
+dojo.cal.iCalendar.VTimeZone = function (/* string */ body) {
+	// summary
+	// VTIMEZONE Component
+	this.name = "VTIMEZONE";
+	this._ValidProperties = VTimeZoneProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VTimeZone, dojo.cal.iCalendar.Component);
+
+/*
+ * VTODO
+ */
+
+var VTodoProperties = [
+	// these can occur once only
+	_P("class", 1), _P("completed", 1), _P("created", 1), _P("description", 1),
+	_P("dtstart", 1), _P("geo", 1), _P("last-mod", 1), _P("location", 1),
+	_P("organizer", 1), _P("percent", 1), _P("priority", 1), _P("dtstamp", 1),
+	_P("seq", 1), _P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1),
+	_P("recurid", 1),
+	// these two are exclusive
+	[_P("due", 1), _P("duration", 1)],
+	// these can occur many times over
+	_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
+	_P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"),
+	_P("rdate"), _P("rrule")
+];
+
+dojo.cal.iCalendar.VTodo= function (/* string */ body) {
+	// summary
+	// VTODO Componenet
+	this.name = "VTODO";
+	this._ValidProperties = VTodoProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VTodo, dojo.cal.iCalendar.Component);
+
+/*
+ * VJOURNAL
+ */
+
+var VJournalProperties = [
+	// these can occur once only
+	_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1),
+	_P("last-mod", 1), _P("organizer", 1), _P("dtstamp", 1), _P("seq", 1),
+	_P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1),
+	// these can occur many times over
+	_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
+	_P("exdate"), _P("exrule"), _P("related"), _P("rstatus"), _P("rdate"), _P("rrule")
+];
+
+dojo.cal.iCalendar.VJournal= function (/* string */ body) {
+	// summary
+	// VJOURNAL Component
+	this.name = "VJOURNAL";
+	this._ValidProperties = VJournalProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VJournal, dojo.cal.iCalendar.Component);
+
+/*
+ * VFREEBUSY
+ */
+
+var VFreeBusyProperties = [
+	// these can occur once only
+	_P("contact"), _P("dtstart", 1), _P("dtend"), _P("duration"),
+	_P("organizer", 1), _P("dtstamp", 1), _P("uid", 1), _P("url", 1),
+	// these can occur many times over
+	_P("attendee"), _P("comment"), _P("freebusy"), _P("rstatus")
+];
+
+dojo.cal.iCalendar.VFreeBusy= function (/* string */ body) {
+	// summary
+	// VFREEBUSY Component
+	this.name = "VFREEBUSY";
+	this._ValidProperties = VFreeBusyProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VFreeBusy, dojo.cal.iCalendar.Component);
+
+/*
+ * VALARM
+ */
+
+var VAlarmProperties = [
+	[_P("action", 1, true), _P("trigger", 1, true), [_P("duration", 1), _P("repeat", 1)],
+	_P("attach", 1)],
+
+	[_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true),
+	[_P("duration", 1), _P("repeat", 1)]],
+
+	[_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true),
+	_P("summary", 1, true), _P("attendee", "*", true),
+	[_P("duration", 1), _P("repeat", 1)],
+	_P("attach", 1)],
+
+	[_P("action", 1, true), _P("attach", 1, true), _P("trigger", 1, true),
+	[_P("duration", 1), _P("repeat", 1)],
+	_P("description", 1)]
+];
+
+dojo.cal.iCalendar.VAlarm= function (/* string */ body) {
+	// summary
+	// VALARM Component
+	this.name = "VALARM";
+	this._ValidProperties = VAlarmProperties;
+	dojo.cal.iCalendar.Component.call(this, body);
+}
+
+dojo.inherits(dojo.cal.iCalendar.VAlarm, dojo.cal.iCalendar.Component);
+

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/textDirectory.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/textDirectory.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/textDirectory.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/cal/textDirectory.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.cal.textDirectory");
+dojo.require("dojo.string");
+
+dojo.cal.textDirectory.Property = function(/*String*/line){
+// summary: parses a single line from an iCalendar text/directory file
+// and creates an object with four named values; name, group, params
+// and value. name, group and value are strings containing the original
+// tokens unaltered and values is an array containing name/value pairs
+// or a single name token packed into arrays.
+
+	// split into name/value pair
+	var left = dojo.string.trim(line.substring(0, line.indexOf(':')));
+	var right = dojo.string.trim(line.substr(line.indexOf(':') + 1));
+
+	// separate name and paramters	
+	var parameters = dojo.string.splitEscaped(left,';');
+	this.name = parameters[0];
+	parameters.splice(0, 1);
+
+	// parse paramters
+	this.params = [];
+	var arr;
+	for(var i = 0; i < parameters.length; i++){
+		arr = parameters[i].split("=");
+		var key = dojo.string.trim(arr[0].toUpperCase());
+
+		if(arr.length == 1){ this.params.push([key]); continue; }
+
+		var values = dojo.string.splitEscaped(arr[1],',');
+		for(var j = 0; j < values.length; j++){
+			if(dojo.string.trim(values[j]) != ''){
+				this.params.push([key, dojo.string.trim(values[j])]);
+			}
+		}
+	}
+
+	// separate group
+	if(this.name.indexOf('.') > 0){
+		arr = this.name.split('.');
+		this.group = arr[0];
+		this.name = arr[1];
+	}
+
+	// don't do any parsing, leave to implementation
+	this.value = right;
+}
+
+
+dojo.cal.textDirectory.tokenise = function(/*String*/text){
+// summary: parses text into an array of properties.
+
+	// normlize to one property per line and parse
+	var nText = dojo.string.normalizeNewlines(text,"\n").
+		replace(/\n[ \t]/g, '').
+		replace(/\x00/g, '');
+
+	var lines = nText.split("\n");
+	var properties = [];
+
+	for(var i = 0; i < lines.length; i++){
+		if(dojo.string.trim(lines[i]) == ''){ continue; }
+		var prop = new dojo.cal.textDirectory.Property(lines[i]);
+		properties.push(prop);
+	}
+	return properties; // Array
+}

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Axis.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Axis.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Axis.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Axis.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,146 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.Axis");
+dojo.require("dojo.lang.common");
+
+dojo.charting.Axis = function(/* string? */label, /* string? */scale, /* array? */labels){
+	var id = "dojo-charting-axis-"+dojo.charting.Axis.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.scale = scale || "linear";		//	linear || log
+	this.label = label || "";
+	this.showLabel = true;		//	show axis label.
+	this.showLabels = true;		//	show interval ticks.
+	this.showLines = false;		//	if you want lines over the range of the plot area
+	this.showTicks = false;		//	if you want tick marks on the axis.
+	this.range = { upper : 0, lower : 0 };	//	range of individual axis.
+	this.origin = "min"; 			//	this can be any number, "min" or "max". min/max is translated on init.
+
+	this.labels = labels || [];
+	this._labels = [];	//	what we really use to draw things.
+	this.nodes={ main: null, axis: null, label: null, labels: null, lines: null, ticks: null };
+};
+dojo.charting.Axis.count = 0;
+
+dojo.extend(dojo.charting.Axis, {
+	//	TODO: implement log scaling.
+	getCoord: function(
+		/* float */val, 
+		/* dojo.charting.PlotArea */plotArea, 
+		/* dojo.charting.Plot */plot
+	){
+		//	summary
+		//	returns the coordinate of val based on this axis range, plot area and plot.
+		val = parseFloat(val, 10);
+		var area = plotArea.getArea();
+		if(plot.axisX == this){
+			var offset = 0 - this.range.lower;
+			var min = this.range.lower + offset;	//	FIXME: check this.
+			var max = this.range.upper + offset;
+			val += offset;
+			return (val*((area.right-area.left)/max))+area.left;	//	float
+		} else {
+			var max = this.range.upper;
+			var min = this.range.lower;
+			var offset = 0;
+			if(min<0){
+				offset += Math.abs(min);
+			}
+			max += offset; min += offset; val += offset;
+			var pmin = area.bottom;
+			var pmax = area.top;
+			return (((pmin-pmax)/(max-min))*(max-val))+pmax;
+		}
+	},
+	initializeOrigin: function(drawAgainst, plane){
+		//	figure out the origin value.
+		if(isNaN(this.origin)){
+			if(this.origin.toLowerCase() == "max"){ 
+				this.origin = drawAgainst.range[(plane=="y")?"upper":"lower"]; 
+			}
+			else if (this.origin.toLowerCase() == "min"){ 
+				this.origin = drawAgainst.range[(plane=="y")?"lower":"upper"]; 
+			}
+			else { this.origin=0; }
+		}
+	},
+	initializeLabels: function(){
+		//	Translate the labels if needed.
+		if(this.labels.length == 0){
+			this.showLabels = false;
+			this.showLines = false;
+			this.showTicks = false;
+		} else {
+			if(this.labels[0].label && this.labels[0].value != null){
+				for(var i=0; i<this.labels.length; i++){
+					this._labels.push(this.labels[i]);
+				}
+			}
+			else if(!isNaN(this.labels[0])){
+				for(var i=0; i<this.labels.length; i++){
+					this._labels.push({ label: this.labels[i], value: this.labels[i] });
+				}
+			}
+			else {
+				// clone me
+				var a = [];
+				for(var i=0; i<this.labels.length; i++){
+					a.push(this.labels[i]);
+				}
+
+				//	do the bottom one.
+				var s=a.shift();
+				this._labels.push({ label: s, value: this.range.lower });
+
+				//	do the top one.
+				if(a.length>0){
+					var s=a.pop();
+					this._labels.push({ label: s, value: this.range.upper });
+				}
+				//	do the rest.
+				if(a.length>0){
+					var range = this.range.upper - this.range.lower;
+					var step = range / (this.labels.length-1);
+					for(var i=1; i<=a.length; i++){
+						this._labels.push({
+							label: a[i-1],
+							value: this.range.lower+(step*i)
+						});
+					}
+				}
+			}
+		}
+	},
+	initialize: function(plotArea, plot, drawAgainst, plane){
+		//	summary
+		//	Initialize the passed axis descriptor.  Note that this should always
+		//	be the result of plotArea.getAxes, and not the axis directly!
+		this.destroy();
+		this.initializeOrigin(drawAgainst, plane);
+		this.initializeLabels();
+		var node = this.render(plotArea, plot, drawAgainst, plane);
+		return node;
+	},
+	destroy: function(){
+		for(var p in this.nodes){
+			while(this.nodes[p] && this.nodes[p].childNodes.length > 0){
+				this.nodes[p].removeChild(this.nodes[p].childNodes[0]);
+			}
+			if(this.nodes[p] && this.nodes[p].parentNode){
+				this.nodes[p].parentNode.removeChild(this.nodes[p]);
+			}
+			this.nodes[p] = null;
+		}
+	}
+});
+
+dojo.requireIf(dojo.render.svg.capable, "dojo.charting.svg.Axis");
+dojo.requireIf(dojo.render.vml.capable, "dojo.charting.vml.Axis");

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Chart.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Chart.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Chart.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Chart.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,85 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.Chart");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.charting.PlotArea");
+
+dojo.charting.Chart = function(
+	/* HTMLElement? */node, 
+	/* string? */title, 
+	/* string? */description
+){
+	//	summary
+	//	Create the basic Chart object.
+	this.node = node || null;
+	this.title = title || "Chart";			//	pure string.
+	this.description = description || "";	//	HTML is allowed.
+	this.plotAreas = [];
+};
+
+dojo.extend(dojo.charting.Chart, {
+	//	methods
+	addPlotArea: function(/* object */obj, /* bool? */doRender){
+		//	summary
+		//	Add a PlotArea to this chart; object should be in the
+		//	form of: { plotArea, (x, y) or (top, left) }
+		if(obj.x!=null && obj.left==null){ obj.left = obj.x; }
+		if(obj.y!=null && obj.top==null){ obj.top = obj.y; }
+		this.plotAreas.push(obj);
+		if(doRender){ this.render(); }
+	},
+	
+	//	events
+	onInitialize:function(chart){ },
+	onRender:function(chart){ },
+	onDestroy:function(chart){ },
+
+	//	standard build methods
+	initialize: function(){
+		//	summary
+		//	Initialize the Chart by rendering it.
+		if(!this.node){ 
+			dojo.raise("dojo.charting.Chart.initialize: there must be a root node defined for the Chart."); 
+		}
+		this.destroy();
+		this.render();
+		this.onInitialize(this);
+	},
+	render:function(){
+		//	summary
+		//	Render the chart in its entirety.
+		if(this.node.style.position != "absolute"){
+			this.node.style.position = "relative";
+		}
+		for(var i=0; i<this.plotAreas.length; i++){
+			var area = this.plotAreas[i].plotArea;
+			var node = area.initialize();
+			node.style.position = "absolute";
+			node.style.top = this.plotAreas[i].top + "px";
+			node.style.left = this.plotAreas[i].left + "px";
+			this.node.appendChild(node);
+			area.render();
+		}
+	},
+	destroy: function(){
+		//	summary
+		//	Destroy any nodes that have maintained references.
+
+		//	kill any existing plotAreas
+		for(var i=0; i<this.plotAreas.length; i++){
+			this.plotAreas[i].plotArea.destroy();
+		};
+		//	clean out any child nodes.
+		while(this.node && this.node.childNodes && this.node.childNodes.length > 0){ 
+			this.node.removeChild(this.node.childNodes[0]); 
+		}
+	}
+});

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plot.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plot.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plot.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plot.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,103 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.Plot");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.charting.Axis");
+dojo.require("dojo.charting.Series");
+
+dojo.charting.RenderPlotSeries = { Singly:"single", Grouped:"grouped" };
+
+dojo.charting.Plot = function(
+	/* dojo.charting.Axis? */xaxis, 
+	/* dojo.charting.Axis? */yaxis, 
+	/* dojo.charting.Series[]? */series
+){
+	//	summary
+	//	Creates a new instance of a Plot (X/Y Axis + n Series).
+	var id = "dojo-charting-plot-"+dojo.charting.Plot.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.axisX = null;
+	this.axisY = null;
+	this.series = [];
+	this.dataNode = null;
+
+	//	for bar charts, pie charts and stacked charts, change to Grouped.
+	this.renderType = dojo.charting.RenderPlotSeries.Singly;
+	if(xaxis){
+		this.setAxis(xaxis,"x");
+	}
+	if(yaxis){
+		this.setAxis(yaxis,"y");
+	}
+	if(series){
+		for(var i=0; i<series.length; i++){ this.addSeries(series[i]); }
+	}
+}
+dojo.charting.Plot.count=0;
+
+dojo.extend(dojo.charting.Plot, {
+	addSeries: function(
+		/* dojo.charting.Series || object */series,
+		/* function? */plotter
+	){
+		//	summary
+		//	Add a new Series to this plot.  Can take the form of a Series, or an object
+		//	of the form { series, plotter }
+		if(series.plotter){
+			this.series.push(series);
+		} else {
+			this.series.push({
+				data: series,
+				plotter: plotter || dojo.charting.Plotters["Default"]
+			});
+		}
+	},
+	setAxis: function(/* dojo.charting.Axis */axis, /* string */which){
+		//	summary
+		//	Set the axis on which plane.
+		if(which.toLowerCase()=="x"){ this.axisX = axis; }
+		else if(which.toLowerCase()=="y"){ this.axisY = axis; }
+	},
+	getRanges: function(){
+		//	summary
+		//	set the ranges on these axes.
+		var xmin, xmax, ymin, ymax;
+		xmin=ymin=Number.MAX_VALUE;
+		xmax=ymax=Number.MIN_VALUE;
+		for(var i=0; i<this.series.length; i++){
+			var values = this.series[i].data.evaluate();	//	full data range.
+			for(var j=0; j<values.length; j++){
+				var comp=values[j];
+				xmin=Math.min(comp.x, xmin);
+				ymin=Math.min(comp.y, ymin);
+				xmax=Math.max(comp.x, xmax);
+				ymax=Math.max(comp.y, ymax);
+			}
+		}
+		return {
+			x:{ upper: xmax, lower:xmin },
+			y:{ upper: ymax, lower:ymin },
+			toString:function(){
+				return "[ x:"+xmax+" - "+xmin+", y:"+ymax+" - "+ymin+"]";
+			}
+		};	//	object
+	},
+	destroy: function(){
+		//	summary
+		//	Clean out any existing DOM node references.
+		var node=this.dataNode;
+		while(node && node.childNodes && node.childNodes.length > 0){
+			node.removeChild(node.childNodes[0]);
+		}
+		this.dataNode=null;
+	}
+});

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/PlotArea.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/PlotArea.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/PlotArea.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/PlotArea.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,195 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.PlotArea");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.gfx.color");
+dojo.require("dojo.gfx.color.hsl");
+dojo.require("dojo.charting.Plot");
+
+dojo.charting.PlotArea = function(){
+	//	summary
+	//	Creates a new PlotArea for drawing onto a Chart.
+	var id="dojo-charting-plotarea-"+dojo.charting.PlotArea.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.areaType = "standard"; 	//	standard || radar
+	this.plots = [];	//	plots that will be drawn on this area
+
+	this.size={ width:600, height:400 };
+	this.padding={ top:10, right:10, bottom:20, left:20 };
+
+	//	drawing node references.
+	this.nodes = {
+		main:null,
+		area:null,
+		background: null,
+		axes: null,
+		plots: null
+	};
+
+	//	this is preset for a limited color range (green to purple), 
+	//	anticipating a max of 32 series on this plot area.
+	//	if you need more flexibility, override these numbers.
+	this._color = { h: 140, s: 120, l: 120, step: 27 };
+};
+dojo.charting.PlotArea.count = 0;
+
+dojo.extend(dojo.charting.PlotArea, {
+	nextColor: function(){
+		//	summary
+		//	Advances the internal HSV cursor and returns the next generated color.
+		var rgb=dojo.gfx.color.hsl2rgb(this._color.h, this._color.s, this._color.l);
+		this._color.h = (this._color.h + this._color.step)%360;
+		while(this._color.h < 140){ 
+			this._color.h += this._color.step; 
+		}
+		return dojo.gfx.color.rgb2hex(rgb[0], rgb[1], rgb[2]);	//	string
+	},
+	getArea:function(){
+		//	summary
+		//	Return an object describing the coordinates of the available area to plot on.
+		return {
+			left: this.padding.left,
+			right: this.size.width - this.padding.right,
+			top: this.padding.top,
+			bottom: this.size.height - this.padding.bottom,
+			toString:function(){ 
+				var a=[ this.top, this.right, this.bottom, this.left ];
+				return "["+a.join()+"]";
+			}
+		};	//	object
+	},
+	getAxes: function(){
+		//	summary
+		//	get the unique axes for this plot area.
+		var axes={};
+		for(var i=0; i<this.plots.length; i++){
+			var plot=this.plots[i];
+			axes[plot.axisX.getId()] = {
+				axis: plot.axisX,
+				drawAgainst: plot.axisY,
+				plot: plot,
+				plane: "x"
+			};
+			axes[plot.axisY.getId()] = {
+				axis: plot.axisY,
+				drawAgainst: plot.axisX,
+				plot: plot,
+				plane: "y"
+			};
+		}
+		return axes;	//	object 
+	},
+	getLegendInfo: function(){
+		//	summary
+		//	return an array describing all data series on this plot area.
+		var a=[];
+		for(var i=0; i<this.plots.length; i++){
+			for(var j=0; j<this.plots[i].series.length; j++){
+				var data = this.plots[i].series[j].data;
+				a.push({ label:data.label, color:data.color });
+			}
+		}
+		return a;	//	array
+	},
+	setAxesRanges: function(){
+		//	summary
+		//	Find and set the ranges on all axes on this plotArea.
+		//	We do this because plots may have axes in common; if you
+		//	want to use this, make sure you do it *before* initialization.
+		var ranges={};
+		var axes={};
+		for(var i=0; i<this.plots.length; i++){
+			var plot = this.plots[i];
+			var ranges=plot.getRanges();
+			var x=ranges.x;
+			var y=ranges.y;
+			var ax, ay;
+			if(!axes[plot.axisX.getId()]){
+				axes[plot.axisX.getId()]=plot.axisX;
+				ranges[plot.axisX.getId()]={upper: x.upper, lower:x.lower};
+			}
+			ax=ranges[plot.axisX.getId()];
+			ax.upper=Math.max(ax.upper, x.upper);
+			ax.lower=Math.min(ax.lower, x.lower);
+
+			if(!axes[plot.axisY.getId()]){
+				axes[plot.axisY.getId()]=plot.axisY;
+				ranges[plot.axisY.getId()]={upper: y.upper, lower:y.lower};
+			}
+			ay=ranges[plot.axisY.getId()];
+			ay.upper=Math.max(ay.upper, y.upper);
+			ay.lower=Math.min(ay.lower, y.lower);
+		}
+		
+		//	now that we have all the max/min ranges, set the axes
+		for(var p in axes){
+			axes[p].range=ranges[p];
+		}
+	},
+
+	render: function(/* object? */kwArgs, /* function? */applyToData){
+		//	summary
+		//	Render this plotArea.  Optional kwArgs are the same as that taken for Series.evaluate;
+		//	applyToData is a callback function used by plotters for customization.
+		if(!this.nodes.main
+			|| !this.nodes.area 
+			|| !this.nodes.background 
+			|| !this.nodes.plots 
+			|| !this.nodes.axes
+		){ this.initialize(); }
+
+		//	plot it.
+		for(var i=0; i<this.plots.length; i++){
+			var plot=this.plots[i];
+			this.nodes.plots.removeChild(plot.dataNode);
+			var target = this.initializePlot(plot);
+			switch(plot.renderType){
+				case dojo.charting.RenderPlotSeries.Grouped:	{
+					// ALWAYS plot using the first plotter, ignore any others.
+					if(plot.series[0]){
+						target.appendChild(plot.series[0].plotter(this, plot, kwArgs, applyToData));
+					}
+					break;
+				}
+				case dojo.charting.RenderPlotSeries.Singly:
+				default: {
+					for(var j=0; j<plot.series.length; j++){
+						var series = plot.series[j];
+						var data = series.data.evaluate(kwArgs);
+						target.appendChild(series.plotter(data, this, plot, applyToData));
+					}
+				}
+			}
+			this.nodes.plots.appendChild(target);
+		}
+	},
+	destroy: function(){
+		//	summary
+		//	Clean out any existing DOM references.
+		for(var i=0; i<this.plots.length; i++){
+			this.plots[i].destroy();
+		};
+		//	clean out any child nodes.
+		for(var p in this.nodes){
+			var node=this.nodes[p];
+			if(!node) continue;
+			if(!node.childNodes) continue;
+			while(node.childNodes.length > 0){ 
+				node.removeChild(node.childNodes[0]); 
+			}
+			this.nodes[p]=null;
+		}
+	}
+});
+
+dojo.requireIf(dojo.render.svg.capable, "dojo.charting.svg.PlotArea");
+dojo.requireIf(dojo.render.vml.capable, "dojo.charting.vml.PlotArea");

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plotters.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plotters.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plotters.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Plotters.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.Plotters");
+
+/*	
+ *	Plotters is the placeholder; what will happen is that the proper renderer types
+ *	will be mixed into this object (as opposed to creating a new one).
+ */
+
+dojo.requireIf(dojo.render.svg.capable, "dojo.charting.svg.Plotters");
+dojo.requireIf(dojo.render.vml.capable, "dojo.charting.vml.Plotters");

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/README.txt
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/README.txt?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/README.txt (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/README.txt Thu Jan 11 14:35:53 2007
@@ -0,0 +1,46 @@
+Dojo Charting Engine
+=========================================================================
+The Dojo Charting Engine is a (fairly) complex object structure, designed
+to provide as much flexibility as possible in terms of chart construction.
+To this end, the engine details the following structure:
+
+Chart
+---PlotArea[]
+------Plot[]
+---------Axis (axisX)
+---------Axis (axisY)
+---------Series[]
+
+
+A Chart object is the main entity; it is the entire graphic.  A Chart may
+have any number of PlotArea objects, which are the basic canvas against 
+which data is plotted.  A PlotArea may have any number of Plot objects,
+which is a container representing up to 2 axes and any number of series
+to be plotted against those axes; a Series represents a binding against
+two fields from a data source (initial rev, this data source is always of
+type dojo.collections.Store but this will probably change once dojo.data
+is in production).
+
+The point of this structure is to allow for as much flexibility as possible
+in terms of what kinds of charts can be represented by the engine.  The
+current plan is to accomodate up to analytical financial charts, which tend
+to have 3 plot areas and any number of different types of axes on each one.
+
+The main exception to this is the pie chart, which will have it's own
+custom codebase.  Also, 3D charts are not accounted for at this time,
+although the only thing that will probably need to be altered to make
+that work would be Plot and Series (to accomodate the additional Z axis).
+
+Finally, a Plot will render its series[] through the use of Plotters, which
+are custom methods to render specific types of charts.
+-------------------------------------------------------------------------
+In terms of widgets, the basic concept is that there is a central, super-
+flexible Chart widget (Chart, oddly enough), and then any number of preset
+chart type widgets, that are basically built to serve a simple, easy 
+purpose.  For instance, if someone just needs to plot a series of lines,
+they would be better off using the LineChart widget; but if someone needed
+to plot a combo chart, that has 2 Y Axes (one linear, one log) against the
+same X Axis, using lines and areas, then they will want to use a Chart widget.
+Note also that unlike other widgets, the Charting engine *can* be called
+directly from script *without* the need for the actual widget engine to be
+loaded; the Chart widgets are thin wrappers around the charting engine.
\ No newline at end of file

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Series.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Series.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Series.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/Series.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,215 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.Series");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.charting.Plotters");
+
+dojo.charting.Series = function(/* object? */kwArgs){
+	//	summary
+	//	Create an instance of data series for plotting.
+	var args = kwArgs || { length:1 };
+	this.dataSource = args.dataSource || null;
+	this.bindings = { };
+	this.color = args.color;
+	this.label = args.label;
+
+	if(args.bindings){
+		for(var p in args.bindings){
+			this.addBinding(p, args.bindings[p]);
+		}
+	}
+};
+
+dojo.extend(dojo.charting.Series, {
+	bind:function(/* dojo.collections.Store */src, /* object */bindings){
+		//	summary
+		//	Bind this series to src, with bindings.
+		this.dataSource = src;
+		this.bindings = bindings;
+	},
+	addBinding:function(/* string */name, /* string */binding){
+		//	summary
+		//	Bind to field "binding" using "name".
+		this.bindings[name] = binding;
+	},
+	evaluate:function(/* object? */kwArgs){
+		//	summary
+		//	Evaluate all bindings and return an array of objects describing the bind.
+		var ret = [];
+		var a = this.dataSource.getData();
+		var l = a.length;
+		var start = 0;
+		var end = l;
+		
+		/*	Allow for ranges.  Can be done in one of two ways:
+		 *	1. { from, to } as 0-based indices
+		 *	2. { length } as num of data points to get; a negative
+		 *		value will start from the end of the data set.
+		 *	No kwArg object means the full data set will be evaluated
+		 *		and returned.
+		 */
+		if(kwArgs){
+			if(kwArgs.from){ 
+				start = Math.max(kwArgs.from,0);
+				if(kwArgs.to){ 
+					end = Math.min(kwArgs.to, end);
+				}
+			}
+			else if(kwArgs.length){
+				if(kwArgs.length < 0){
+					//	length points from end
+					start = Math.max((end + length),0);
+				} else {
+					end = Math.min((start + length), end);
+				}
+			}
+		}
+
+		for(var i=start; i<end; i++){
+			var o = { src: a[i], series: this };
+			for(var p in this.bindings){
+				o[p] = this.dataSource.getField(a[i], this.bindings[p]);
+			}
+			ret.push(o);
+		}
+
+		//	sort by the x axis, if available.
+		if(typeof(ret[0].x) != "undefined"){
+			ret.sort(function(a,b){
+				if(a.x > b.x) return 1;
+				if(a.x < b.x) return -1;
+				return 0;
+			});
+		}
+		return ret;	//	array
+	},
+
+	//	trends
+	trends:{
+		createRange: function(/* array */values, /* int */len){
+			//	summary
+			//	Creates the data range used for all trends.
+			var idx = values.length-1;
+			var length = (len||values.length);
+			return { "index": idx, "length": length, "start":Math.max(idx-length,0) };	//	object
+		},
+
+		mean: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the mean or average over the set of values.
+			var range = this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var total = 0;
+			var count = 0;
+			for(var i=range.index; i>=range.start; i--){
+				total += values[i].y; 
+				count++;
+			}
+			total /= Math.max(count,1);
+			return total;	//	float
+		},
+
+		variance: function(/* array */values,/* int */len){
+			//	summary
+			//	Returns the variance of the set of values.
+			var range = this.createRange(values,len);
+			if(range.index < 0){ return 0; }
+			var total = 0;
+			var square = 0;
+			var count = 0;
+			for(var i=range.index; i>=range.start; i--){
+				total += values[i].y;
+				square += Math.pow(values[i].y, 2);
+				count++;
+			}
+			return (square/count)-Math.pow(total/count,2);	//	float
+		},
+
+		standardDeviation: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the standard deviation of the set of values.
+			return Math.sqrt(this.getVariance(values, len));	//	float
+		},
+
+		max: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the max number in the set of values.
+			var range = this.createRange(values, len);
+			if(range.index < 0){ return 0; }
+			var max = Number.MIN_VALUE;
+			for (var i=range.index; i>=range.start; i--){
+				max = Math.max(values[i].y,max);
+			}
+			return max;	//	float
+		},
+
+		min: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the lowest number in the set of values.
+			var range=this.createRange(values, len);
+			if(range.index < 0){ return 0; }
+			var min = Number.MAX_VALUE;
+			for(var i=range.index; i>=range.start; i--){
+				min = Math.min(values[i].y, min);
+			}
+			return min;	//	float
+		},
+
+		median: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the median in the set of values (number closest to the middle of a sorted set).
+			var range = this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var a = [];
+			for (var i=range.index; i>=range.start; i--){
+				var b=false;
+				for(var j=0; j<a.length; j++){
+					if(values[i].y == a[j]){
+						b = true;
+						break;
+					}
+				}
+				if(!b){ 
+					a.push(values[i].y); 
+				}
+			}
+			a.sort();
+			if(a.length > 0){ 
+				return a[Math.ceil(a.length / 2)]; 	//	float
+			}
+			return 0;	//	float
+		},
+
+		mode: function(/* array */values, /* int */len){
+			//	summary
+			//	Returns the mode in the set of values
+			var range=this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var o = {};
+			var ret = 0
+			var median = Number.MIN_VALUE;
+			for(var i=range.index; i>=range.start; i--){
+				if (!o[values[i].y]){
+					o[values[i].y] = 1;
+				} else { 
+					o[values[i].y]++;
+				}
+			}
+			for(var p in o){
+				if(median < o[p]){ 
+					median = o[p]; 
+					ret=p; 
+				}
+			}
+			return ret;
+		}
+	}
+});

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/__package__.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/__package__.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/__package__.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/__package__.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,11 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.*");

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/Axis.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/Axis.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/Axis.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/Axis.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,226 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.svg.Axis");
+dojo.require("dojo.lang.common");
+
+if(dojo.render.svg.capable){
+	dojo.extend(dojo.charting.Axis, {
+		renderLines: function(
+			/* dojo.charting.PlotArea */plotArea, 
+			/* dojo.charting.Plot */plot, 
+			/* string */plane
+		){
+			//	summary
+			//	Renders any reference lines for this axis.
+			if(this.nodes.lines){
+				while(this.nodes.lines.childNodes.length > 0){
+					this.nodes.lines.removeChild(this.nodes.lines.childNodes[0]);
+				}
+				if(this.nodes.lines.parentNode){
+					this.nodes.lines.parentNode.removeChild(this.nodes.lines);
+					this.nodes.lines = null;
+				}
+			}
+			
+			var area = plotArea.getArea();
+			var g = this.nodes.lines = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			g.setAttribute("id", this.getId()+"-lines");
+			for(var i=0; i<this._labels.length; i++){
+				if (this._labels[i].value == this.origin){ continue; }
+
+				var v = this.getCoord(this._labels[i].value, plotArea, plot);
+				var l=document.createElementNS(dojo.svg.xmlns.svg, "line");
+				l.setAttribute("style","stroke:#999;stroke-width:1px;stroke-dasharray:1,4;");
+				if(plane == "x"){
+					l.setAttribute("y1",area.top);
+					l.setAttribute("y2",area.bottom);
+					l.setAttribute("x1",v);
+					l.setAttribute("x2",v);
+				}
+				else if (plane == "y"){
+					l.setAttribute("y1",v);
+					l.setAttribute("y2",v);
+					l.setAttribute("x1",area.left);
+					l.setAttribute("x2",area.right);
+				}
+				g.appendChild(l);
+			}
+			return g;	//	SVGGElement
+		},
+		renderTicks: function(
+			/* dojo.charting.PlotArea */plotArea, 
+			/* dojo.charting.Plot */plot, 
+			/* string */plane,
+			/* float */coord
+		){
+			//	summary
+			//	Renders any tick lines for this axis.
+			if(this.nodes.ticks){
+				while(this.nodes.ticks.childNodes.length > 0){
+					this.nodes.ticks.removeChild(this.nodes.ticks.childNodes[0]);
+				}
+				if(this.nodes.ticks.parentNode){
+					this.nodes.ticks.parentNode.removeChild(this.nodes.ticks);
+					this.nodes.ticks = null;
+				}
+			}
+			
+			var g = this.nodes.ticks = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			g.setAttribute("id", this.getId()+"-ticks");
+			for(var i=0; i<this._labels.length; i++){
+				var v = this.getCoord(this._labels[i].value, plotArea, plot);
+
+				var l=document.createElementNS(dojo.svg.xmlns.svg, "line");
+				l.setAttribute("style","stroke:#000;stroke-width:1pt;");
+				if(plane == "x"){
+					l.setAttribute("y1",coord);
+					l.setAttribute("y2",coord+3);
+					l.setAttribute("x1",v);
+					l.setAttribute("x2",v);
+				}
+				else if (plane == "y"){
+					l.setAttribute("y1",v);
+					l.setAttribute("y2",v);
+					l.setAttribute("x1",coord-2);
+					l.setAttribute("x2",coord+2);
+				}
+				g.appendChild(l);
+			}
+			return g;	//	SVGGElement
+		},
+		renderLabels: function(
+			/* dojo.charting.PlotArea */plotArea, 
+			/* dojo.charting.Plot */plot, 
+			/* string */plane,
+			/* float */coord,
+			/* int */textSize,
+			/* string */anchor
+		){
+			//	summary
+			//	Render all labels for this axis.
+			function createLabel(label, x, y, textSize, anchor){
+				var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+				text.setAttribute("x", x);
+				text.setAttribute("y", (plane=="x"?y:y+2));
+				text.setAttribute("style", "text-anchor:"+anchor+";font-family:sans-serif;font-size:"+textSize+"px;fill:#000;");
+				text.appendChild(document.createTextNode(label));
+				return text;
+			};
+
+			//	wipe if needed
+			if(this.nodes.labels){
+				while(this.nodes.labels.childNodes.length > 0){
+					this.nodes.labels.removeChild(this.nodes.labels.childNodes[0]);
+				}
+				if(this.nodes.labels.parentNode){
+					this.nodes.labels.parentNode.removeChild(this.nodes.labels);
+					this.nodes.labels = null;
+				}
+			}
+			var g = this.nodes.labels = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			g.setAttribute("id", this.getId()+"-labels");
+
+			for(var i=0; i<this._labels.length; i++){
+				var v = this.getCoord(this._labels[i].value, plotArea, plot);
+				if(plane == "x"){
+					g.appendChild(createLabel(this._labels[i].label, v, coord, textSize, anchor));
+				}
+				else if (plane == "y"){
+					g.appendChild(createLabel(this._labels[i].label, coord, v, textSize, anchor));
+				}
+			}
+			return g;	//	SVGGelement
+		},
+		render: function(
+			/* dojo.charting.PlotArea */plotArea, 
+			/* dojo.charting.Plot */plot,
+			/* dojo.charting.Axis */drawAgainst,
+			/* string */plane
+		){
+			//	summary
+			//	Renders this axis to the given plot.
+			
+			//	get the origin plot point.
+			var area = plotArea.getArea();
+			var stroke = 1;
+			var style = "stroke:#000;stroke-width:"+stroke+"px;";
+			var textSize=10;
+			var coord = drawAgainst.getCoord(this.origin, plotArea, plot);
+
+			//	draw the axis.
+			this.nodes.main = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			var g = this.nodes.main;
+			g.setAttribute("id", this.getId());	//	need a handle if we have to kill parts of the axis def.
+			var line = this.nodes.axis = document.createElementNS(dojo.svg.xmlns.svg, "line");
+			if(plane == "x"){
+				line.setAttribute("y1", coord);
+				line.setAttribute("y2", coord);
+				line.setAttribute("x1", area.left-stroke);
+				line.setAttribute("x2", area.right+stroke);
+				line.setAttribute("style", style);
+
+				//	set up the labels
+				var y = coord+textSize+2;
+				if(this.showLines){
+					g.appendChild(this.renderLines(plotArea, plot, plane, y));
+				}
+				if(this.showTicks){
+					g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
+				}
+				if(this.showLabels){
+					g.appendChild(this.renderLabels(plotArea, plot, plane, y, textSize, "middle"));
+				}
+				if(this.showLabel && this.label){
+					var x = plotArea.size.width/2;
+					var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+					text.setAttribute("x", x);
+					text.setAttribute("y", (coord + (textSize*2) + (textSize/2)));
+					text.setAttribute("style", "text-anchor:middle;font-family:sans-serif;font-weight:bold;font-size:"+(textSize+2)+"px;fill:#000;");
+					text.appendChild(document.createTextNode(this.label));
+					g.appendChild(text);
+				}
+			} else {
+				line.setAttribute("x1", coord);
+				line.setAttribute("x2", coord);
+				line.setAttribute("y1", area.top);
+				line.setAttribute("y2", area.bottom);
+				line.setAttribute("style", style);
+
+				//	set up the labels
+				var isMax = this.origin == drawAgainst.range.upper;
+				var x = coord + (isMax?4:-4);
+				var anchor = isMax?"start":"end";
+				if(this.showLines){
+					g.appendChild(this.renderLines(plotArea, plot, plane, x));
+				}
+				if(this.showTicks){
+					g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
+				}
+				if(this.showLabels){
+					g.appendChild(this.renderLabels(plotArea, plot, plane, x, textSize, anchor));
+				}
+				if(this.showLabel && this.label){
+					var x = isMax?(coord+(textSize*2)+(textSize/2)):(coord-(textSize*4));
+					var y = plotArea.size.height / 2;
+					var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+					text.setAttribute("x", x);
+					text.setAttribute("y", y);
+					text.setAttribute("transform", "rotate(90, " + x + ", " + y + ")");
+					text.setAttribute("style", "text-anchor:middle;font-family:sans-serif;font-weight:bold;font-size:"+(textSize+2)+"px;fill:#000;");
+					text.appendChild(document.createTextNode(this.label));
+					g.appendChild(text);
+				}
+			}
+			g.appendChild(line);
+			return g;	// 	SVGGElement
+		}
+	});
+}

Added: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/PlotArea.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/PlotArea.js?view=auto&rev=495409
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/PlotArea.js (added)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/charting/svg/PlotArea.js Thu Jan 11 14:35:53 2007
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.charting.svg.PlotArea");
+dojo.require("dojo.lang.common");
+
+if(dojo.render.svg.capable){
+	dojo.require("dojo.svg");
+	dojo.extend(dojo.charting.PlotArea, {
+		initializePlot: function(plot){
+			//	summary
+			//	Initialize the plot node for data rendering.
+			plot.destroy();
+			plot.dataNode = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			plot.dataNode.setAttribute("id", plot.getId());
+			return plot.dataNode;	//	SVGGElement
+		},
+		initialize: function(){
+			//	summary
+			//	Initialize the PlotArea.
+		
+			this.destroy();	//	kill everything first.
+			
+			//	start with the background
+			this.nodes.main = document.createElement("div");
+
+			this.nodes.area = document.createElementNS(dojo.svg.xmlns.svg, "svg");
+			this.nodes.area.setAttribute("id", this.getId());
+			this.nodes.area.setAttribute("width", this.size.width);
+			this.nodes.area.setAttribute("height", this.size.height);
+			this.nodes.main.appendChild(this.nodes.area);
+
+			var area=this.getArea();
+			var defs = document.createElementNS(dojo.svg.xmlns.svg, "defs");
+			var clip = document.createElementNS(dojo.svg.xmlns.svg, "clipPath");
+			clip.setAttribute("id",this.getId()+"-clip");
+			var rect = document.createElementNS(dojo.svg.xmlns.svg, "rect");		
+			rect.setAttribute("x", area.left);
+			rect.setAttribute("y", area.top);
+			rect.setAttribute("width", area.right-area.left);
+			rect.setAttribute("height", area.bottom-area.top);
+			clip.appendChild(rect);
+			defs.appendChild(clip);
+			this.nodes.area.appendChild(defs);
+			
+			this.nodes.background = document.createElementNS(dojo.svg.xmlns.svg, "rect");
+			this.nodes.background.setAttribute("id", this.getId()+"-background");
+			this.nodes.background.setAttribute("width", this.size.width);
+			this.nodes.background.setAttribute("height", this.size.height);
+			this.nodes.background.setAttribute("fill", "#fff");
+			this.nodes.area.appendChild(this.nodes.background);
+
+			this.nodes.plots = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			this.nodes.plots.setAttribute("id", this.getId()+"-plots");
+			this.nodes.plots.setAttribute("style","clip-path:url(#"+this.getId()+"-clip);");
+			this.nodes.area.appendChild(this.nodes.plots);
+
+			for(var i=0; i<this.plots.length; i++){
+				this.nodes.plots.appendChild(this.initializePlot(this.plots[i]));
+			}
+
+			//	do the axes
+			this.nodes.axes = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			this.nodes.axes.setAttribute("id", this.getId()+"-axes");
+			this.nodes.area.appendChild(this.nodes.axes);
+			var axes = this.getAxes();
+			for(var p in axes){
+				var obj = axes[p];
+				this.nodes.axes.appendChild(obj.axis.initialize(this, obj.plot, obj.drawAgainst, obj.plane));
+			}
+			return this.nodes.main;	//	HTMLDivElement
+		}
+	});
+}