blob: 809ec703ddcc44a12c07ddcb55e3ee431de9de41 [file] [log] [blame]
/*==================================================
* 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;
};