Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js Mon Feb 19 09:56:06 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); + Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/iCalendar.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js Mon Feb 19 09:56:06 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 +} Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/cal/textDirectory.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js Mon Feb 19 09:56:06 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"); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Axis.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js Mon Feb 19 09:56:06 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]); + } + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Chart.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js Mon Feb 19 09:56:06 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; + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plot.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js Mon Feb 19 09:56:06 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"); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/PlotArea.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js Mon Feb 19 09:56:06 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"); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Plotters.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt Mon Feb 19 09:56:06 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 Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/README.txt ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js Mon Feb 19 09:56:06 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; + } + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/Series.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/__package__.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/charting/__package__.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/charti |
Free forum by Nabble | Edit this page |