📄 band.js
字号:
/*=================================================
*
* Coding standards:
*
* We aim towards Douglas Crockford's Javascript conventions.
* See: http://javascript.crockford.com/code.html
* See also: http://www.crockford.com/javascript/javascript.html
*
* That said, this JS code was written before some recent JS
* support libraries became widely used or available.
* In particular, the _ character is used to indicate a class function or
* variable that should be considered private to the class.
*
* The code mostly uses accessor methods for getting/setting the private
* class variables.
*
* Over time, we'd like to formalize the convention by using support libraries
* which enforce privacy in objects.
*
* We also want to use jslint: http://www.jslint.com/
*
*
*==================================================
*/
/*==================================================
* Band
*==================================================
*/
Timeline._Band = function(timeline, bandInfo, index) {
// Set up the band's object
// Munge params: If autoWidth is on for the Timeline, then ensure that
// bandInfo.width is an integer
if (timeline.autoWidth && typeof bandInfo.width == 'string') {
bandInfo.width = bandInfo.width.indexOf("%") > -1 ? 0 : parseInt(bandInfo.width);
}
this._timeline = timeline;
this._bandInfo = bandInfo;
this._index = index;
this._locale = ("locale" in bandInfo) ? bandInfo.locale : Timeline.getDefaultLocale();
this._timeZone = ("timeZone" in bandInfo) ? bandInfo.timeZone : 0;
this._labeller = ("labeller" in bandInfo) ? bandInfo.labeller :
(("createLabeller" in timeline.getUnit()) ?
timeline.getUnit().createLabeller(this._locale, this._timeZone) :
new Timeline.GregorianDateLabeller(this._locale, this._timeZone));
this._theme = bandInfo.theme;
this._zoomIndex = ("zoomIndex" in bandInfo) ? bandInfo.zoomIndex : 0;
this._zoomSteps = ("zoomSteps" in bandInfo) ? bandInfo.zoomSteps : null;
this._dragging = false;
this._changing = false;
this._originalScrollSpeed = 5; // pixels
this._scrollSpeed = this._originalScrollSpeed;
this._onScrollListeners = [];
var b = this;
this._syncWithBand = null;
this._syncWithBandHandler = function(band) {
b._onHighlightBandScroll();
};
this._selectorListener = function(band) {
b._onHighlightBandScroll();
};
/*
* Install a textbox to capture keyboard events
*/
var inputDiv = this._timeline.getDocument().createElement("div");
inputDiv.className = "timeline-band-input";
this._timeline.addDiv(inputDiv);
this._keyboardInput = document.createElement("input");
this._keyboardInput.type = "text";
inputDiv.appendChild(this._keyboardInput);
SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keydown", this, "_onKeyDown");
SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keyup", this, "_onKeyUp");
/*
* The band's outer most div that slides with respect to the timeline's div
*/
this._div = this._timeline.getDocument().createElement("div");
this._div.id = "timeline-band-" + index;
this._div.className = "timeline-band timeline-band-" + index;
this._timeline.addDiv(this._div);
SimileAjax.DOM.registerEventWithObject(this._div, "mousedown", this, "_onMouseDown");
SimileAjax.DOM.registerEventWithObject(this._div, "mousemove", this, "_onMouseMove");
SimileAjax.DOM.registerEventWithObject(this._div, "mouseup", this, "_onMouseUp");
SimileAjax.DOM.registerEventWithObject(this._div, "mouseout", this, "_onMouseOut");
SimileAjax.DOM.registerEventWithObject(this._div, "dblclick", this, "_onDblClick");
var mouseWheel = this._theme!= null ? this._theme.mouseWheel : 'scroll'; // theme is not always defined
if (mouseWheel === 'zoom' || mouseWheel === 'scroll' || this._zoomSteps) {
// capture mouse scroll
if (SimileAjax.Platform.browser.isFirefox) {
SimileAjax.DOM.registerEventWithObject(this._div, "DOMMouseScroll", this, "_onMouseScroll");
} else {
SimileAjax.DOM.registerEventWithObject(this._div, "mousewheel", this, "_onMouseScroll");
}
}
/*
* The inner div that contains layers
*/
this._innerDiv = this._timeline.getDocument().createElement("div");
this._innerDiv.className = "timeline-band-inner";
this._div.appendChild(this._innerDiv);
/*
* Initialize parts of the band
*/
this._ether = bandInfo.ether;
bandInfo.ether.initialize(this, timeline);
this._etherPainter = bandInfo.etherPainter;
bandInfo.etherPainter.initialize(this, timeline);
this._eventSource = bandInfo.eventSource;
if (this._eventSource) {
this._eventListener = {
onAddMany: function() { b._onAddMany(); },
onClear: function() { b._onClear(); }
}
this._eventSource.addListener(this._eventListener);
}
this._eventPainter = bandInfo.eventPainter;
this._eventTracksNeeded = 0; // set by painter via updateEventTrackInfo
this._eventTrackIncrement = 0;
bandInfo.eventPainter.initialize(this, timeline);
this._decorators = ("decorators" in bandInfo) ? bandInfo.decorators : [];
for (var i = 0; i < this._decorators.length; i++) {
this._decorators[i].initialize(this, timeline);
}
};
Timeline._Band.SCROLL_MULTIPLES = 5;
Timeline._Band.prototype.dispose = function() {
this.closeBubble();
if (this._eventSource) {
this._eventSource.removeListener(this._eventListener);
this._eventListener = null;
this._eventSource = null;
}
this._timeline = null;
this._bandInfo = null;
this._labeller = null;
this._ether = null;
this._etherPainter = null;
this._eventPainter = null;
this._decorators = null;
this._onScrollListeners = null;
this._syncWithBandHandler = null;
this._selectorListener = null;
this._div = null;
this._innerDiv = null;
this._keyboardInput = null;
};
Timeline._Band.prototype.addOnScrollListener = function(listener) {
this._onScrollListeners.push(listener);
};
Timeline._Band.prototype.removeOnScrollListener = function(listener) {
for (var i = 0; i < this._onScrollListeners.length; i++) {
if (this._onScrollListeners[i] == listener) {
this._onScrollListeners.splice(i, 1);
break;
}
}
};
Timeline._Band.prototype.setSyncWithBand = function(band, highlight) {
if (this._syncWithBand) {
this._syncWithBand.removeOnScrollListener(this._syncWithBandHandler);
}
this._syncWithBand = band;
this._syncWithBand.addOnScrollListener(this._syncWithBandHandler);
this._highlight = highlight;
this._positionHighlight();
};
Timeline._Band.prototype.getLocale = function() {
return this._locale;
};
Timeline._Band.prototype.getTimeZone = function() {
return this._timeZone;
};
Timeline._Band.prototype.getLabeller = function() {
return this._labeller;
};
Timeline._Band.prototype.getIndex = function() {
return this._index;
};
Timeline._Band.prototype.getEther = function() {
return this._ether;
};
Timeline._Band.prototype.getEtherPainter = function() {
return this._etherPainter;
};
Timeline._Band.prototype.getEventSource = function() {
return this._eventSource;
};
Timeline._Band.prototype.getEventPainter = function() {
return this._eventPainter;
};
Timeline._Band.prototype.getTimeline = function() {
return this._timeline;
};
// Autowidth support
Timeline._Band.prototype.updateEventTrackInfo = function(tracks, increment) {
this._eventTrackIncrement = increment; // doesn't vary for a specific band
if (tracks > this._eventTracksNeeded) {
this._eventTracksNeeded = tracks;
}
};
// Autowidth support
Timeline._Band.prototype.checkAutoWidth = function() {
// if a new (larger) width is needed by the band
// then: a) updates the band's bandInfo.width
//
// desiredWidth for the band is
// (number of tracks + margin) * track increment
if (! this._timeline.autoWidth) {
return; // early return
}
var overviewBand = this._eventPainter.getType() == 'overview';
var margin = overviewBand ?
this._theme.event.overviewTrack.autoWidthMargin :
this._theme.event.track.autoWidthMargin;
var desiredWidth = Math.ceil((this._eventTracksNeeded + margin) *
this._eventTrackIncrement);
// add offset amount (additional margin)
desiredWidth += overviewBand ? this._theme.event.overviewTrack.offset :
this._theme.event.track.offset;
var bandInfo = this._bandInfo;
if (desiredWidth != bandInfo.width) {
bandInfo.width = desiredWidth;
}
};
Timeline._Band.prototype.layout = function() {
this.paint();
};
Timeline._Band.prototype.paint = function() {
this._etherPainter.paint();
this._paintDecorators();
this._paintEvents();
};
Timeline._Band.prototype.softLayout = function() {
this.softPaint();
};
Timeline._Band.prototype.softPaint = function() {
this._etherPainter.softPaint();
this._softPaintDecorators();
this._softPaintEvents();
};
Timeline._Band.prototype.setBandShiftAndWidth = function(shift, width) {
var inputDiv = this._keyboardInput.parentNode;
var middle = shift + Math.floor(width / 2);
if (this._timeline.isHorizontal()) {
this._div.style.top = shift + "px";
this._div.style.height = width + "px";
inputDiv.style.top = middle + "px";
inputDiv.style.left = "-1em";
} else {
this._div.style.left = shift + "px";
this._div.style.width = width + "px";
inputDiv.style.left = middle + "px";
inputDiv.style.top = "-1em";
}
};
Timeline._Band.prototype.getViewWidth = function() {
if (this._timeline.isHorizontal()) {
return this._div.offsetHeight;
} else {
return this._div.offsetWidth;
}
};
Timeline._Band.prototype.setViewLength = function(length) {
this._viewLength = length;
this._recenterDiv();
this._onChanging();
};
Timeline._Band.prototype.getViewLength = function() {
return this._viewLength;
};
Timeline._Band.prototype.getTotalViewLength = function() {
return Timeline._Band.SCROLL_MULTIPLES * this._viewLength;
};
Timeline._Band.prototype.getViewOffset = function() {
return this._viewOffset;
};
Timeline._Band.prototype.getMinDate = function() {
return this._ether.pixelOffsetToDate(this._viewOffset);
};
Timeline._Band.prototype.getMaxDate = function() {
return this._ether.pixelOffsetToDate(this._viewOffset + Timeline._Band.SCROLL_MULTIPLES * this._viewLength);
};
Timeline._Band.prototype.getMinVisibleDate = function() {
return this._ether.pixelOffsetToDate(0);
};
Timeline._Band.prototype.getMinVisibleDateAfterDelta = function(delta) {
return this._ether.pixelOffsetToDate(delta);
};
Timeline._Band.prototype.getMaxVisibleDate = function() {
// Max date currently visible on band
return this._ether.pixelOffsetToDate(this._viewLength);
};
Timeline._Band.prototype.getMaxVisibleDateAfterDelta = function(delta) {
// Max date visible on band after delta px view change is applied
return this._ether.pixelOffsetToDate(this._viewLength + delta);
};
Timeline._Band.prototype.getCenterVisibleDate = function() {
return this._ether.pixelOffsetToDate(this._viewLength / 2);
};
Timeline._Band.prototype.setMinVisibleDate = function(date) {
if (!this._changing) {
this._moveEther(Math.round(-this._ether.dateToPixelOffset(date)));
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -