| /*================================================== |
| * Linear Ether |
| *================================================== |
| */ |
| |
| Timeline.LinearEther = function(params) { |
| this._params = params; |
| this._interval = params.interval; |
| this._pixelsPerInterval = params.pixelsPerInterval; |
| }; |
| |
| Timeline.LinearEther.prototype.initialize = function(timeline) { |
| this._timeline = timeline; |
| this._unit = timeline.getUnit(); |
| |
| if ("startsOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.startsOn); |
| } else if ("endsOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.endsOn); |
| this.shiftPixels(-this._timeline.getPixelLength()); |
| } else if ("centersOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.centersOn); |
| this.shiftPixels(-this._timeline.getPixelLength() / 2); |
| } else { |
| this._start = this._unit.makeDefaultValue(); |
| this.shiftPixels(-this._timeline.getPixelLength() / 2); |
| } |
| }; |
| |
| Timeline.LinearEther.prototype.setDate = function(date) { |
| this._start = this._unit.cloneValue(date); |
| }; |
| |
| Timeline.LinearEther.prototype.shiftPixels = function(pixels) { |
| var numeric = this._interval * pixels / this._pixelsPerInterval; |
| this._start = this._unit.change(this._start, numeric); |
| }; |
| |
| Timeline.LinearEther.prototype.dateToPixelOffset = function(date) { |
| var numeric = this._unit.compare(date, this._start); |
| return this._pixelsPerInterval * numeric / this._interval; |
| }; |
| |
| Timeline.LinearEther.prototype.pixelOffsetToDate = function(pixels) { |
| var numeric = pixels * this._interval / this._pixelsPerInterval; |
| return this._unit.change(this._start, numeric); |
| }; |
| |
| /*================================================== |
| * Hot Zone Ether |
| *================================================== |
| */ |
| |
| Timeline.HotZoneEther = function(params) { |
| this._params = params; |
| this._interval = params.interval; |
| this._pixelsPerInterval = params.pixelsPerInterval; |
| }; |
| |
| Timeline.HotZoneEther.prototype.initialize = function(timeline) { |
| this._timeline = timeline; |
| this._unit = timeline.getUnit(); |
| |
| this._zones = [{ |
| startTime: Number.NEGATIVE_INFINITY, |
| endTime: Number.POSITIVE_INFINITY, |
| magnify: 1 |
| }]; |
| var params = this._params; |
| for (var i = 0; i < params.zones.length; i++) { |
| var zone = params.zones[i]; |
| var zoneStart = this._unit.parseFromObject(zone.start); |
| var zoneEnd = this._unit.parseFromObject(zone.end); |
| |
| for (var j = 0; j < this._zones.length && this._unit.compare(zoneEnd, zoneStart) > 0; j++) { |
| var zone2 = this._zones[j]; |
| |
| if (this._unit.compare(zoneStart, zone2.endTime) < 0) { |
| if (this._unit.compare(zoneStart, zone2.startTime) > 0) { |
| this._zones.splice(j, 0, { |
| startTime: zone2.startTime, |
| endTime: zoneStart, |
| magnify: zone2.magnify |
| }); |
| j++; |
| |
| zone2.startTime = zoneStart; |
| } |
| |
| if (this._unit.compare(zoneEnd, zone2.endTime) < 0) { |
| this._zones.splice(j, 0, { |
| startTime: zoneStart, |
| endTime: zoneEnd, |
| magnify: zone.magnify * zone2.magnify |
| }); |
| j++; |
| |
| zone2.startTime = zoneEnd; |
| zoneStart = zoneEnd; |
| } else { |
| zone2.magnify *= zone.magnify; |
| zoneStart = zone2.endTime; |
| } |
| } // else, try the next existing zone |
| } |
| } |
| |
| if ("startsOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.startsOn); |
| } else if ("endsOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.endsOn); |
| this.shiftPixels(-this._timeline.getPixelLength()); |
| } else if ("centersOn" in this._params) { |
| this._start = this._unit.parseFromObject(this._params.centersOn); |
| this.shiftPixels(-this._timeline.getPixelLength() / 2); |
| } else { |
| this._start = this._unit.makeDefaultValue(); |
| this.shiftPixels(-this._timeline.getPixelLength() / 2); |
| } |
| }; |
| |
| Timeline.HotZoneEther.prototype.setDate = function(date) { |
| this._start = this._unit.cloneValue(date); |
| }; |
| |
| Timeline.HotZoneEther.prototype.shiftPixels = function(pixels) { |
| this._start = this.pixelOffsetToDate(pixels); |
| }; |
| |
| Timeline.HotZoneEther.prototype.dateToPixelOffset = function(date) { |
| return this._dateDiffToPixelOffset(this._start, date); |
| }; |
| |
| Timeline.HotZoneEther.prototype.pixelOffsetToDate = function(pixels) { |
| return this._pixelOffsetToDate(pixels, this._start); |
| }; |
| |
| Timeline.HotZoneEther.prototype._dateDiffToPixelOffset = function(fromDate, toDate) { |
| var scale = this._getScale(); |
| var fromTime = fromDate; |
| var toTime = toDate; |
| |
| var pixels = 0; |
| if (this._unit.compare(fromTime, toTime) < 0) { |
| var z = 0; |
| while (z < this._zones.length) { |
| if (this._unit.compare(fromTime, this._zones[z].endTime) < 0) { |
| break; |
| } |
| z++; |
| } |
| |
| while (this._unit.compare(fromTime, toTime) < 0) { |
| var zone = this._zones[z]; |
| var toTime2 = this._unit.earlier(toTime, zone.endTime); |
| |
| pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify)); |
| |
| fromTime = toTime2; |
| z++; |
| } |
| } else { |
| var z = this._zones.length - 1; |
| while (z >= 0) { |
| if (this._unit.compare(fromTime, this._zones[z].startTime) > 0) { |
| break; |
| } |
| z--; |
| } |
| |
| while (this._unit.compare(fromTime, toTime) > 0) { |
| var zone = this._zones[z]; |
| var toTime2 = this._unit.later(toTime, zone.startTime); |
| |
| pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify)); |
| |
| fromTime = toTime2; |
| z--; |
| } |
| } |
| return pixels; |
| }; |
| |
| Timeline.HotZoneEther.prototype._pixelOffsetToDate = function(pixels, fromDate) { |
| var scale = this._getScale(); |
| var time = fromDate; |
| if (pixels > 0) { |
| var z = 0; |
| while (z < this._zones.length) { |
| if (this._unit.compare(time, this._zones[z].endTime) < 0) { |
| break; |
| } |
| z++; |
| } |
| |
| while (pixels > 0) { |
| var zone = this._zones[z]; |
| var scale2 = scale / zone.magnify; |
| |
| if (zone.endTime == Number.POSITIVE_INFINITY) { |
| time = this._unit.change(time, pixels * scale2); |
| pixels = 0; |
| } else { |
| var pixels2 = this._unit.compare(zone.endTime, time) / scale2; |
| if (pixels2 > pixels) { |
| time = this._unit.change(time, pixels * scale2); |
| pixels = 0; |
| } else { |
| time = zone.endTime; |
| pixels -= pixels2; |
| } |
| } |
| z++; |
| } |
| } else { |
| var z = this._zones.length - 1; |
| while (z >= 0) { |
| if (this._unit.compare(time, this._zones[z].startTime) > 0) { |
| break; |
| } |
| z--; |
| } |
| |
| pixels = -pixels; |
| while (pixels > 0) { |
| var zone = this._zones[z]; |
| var scale2 = scale / zone.magnify; |
| |
| if (zone.startTime == Number.NEGATIVE_INFINITY) { |
| time = this._unit.change(time, -pixels * scale2); |
| pixels = 0; |
| } else { |
| var pixels2 = this._unit.compare(time, zone.startTime) / scale2; |
| if (pixels2 > pixels) { |
| time = this._unit.change(time, -pixels * scale2); |
| pixels = 0; |
| } else { |
| time = zone.startTime; |
| pixels -= pixels2; |
| } |
| } |
| z--; |
| } |
| } |
| return time; |
| }; |
| |
| Timeline.HotZoneEther.prototype._getScale = function() { |
| return this._interval / this._pixelsPerInterval; |
| }; |