📄 compact-painter.js
字号:
/*==================================================
* Original Event Painter
*==================================================
*/
Timeline.CompactEventPainter = function(params) {
this._params = params;
this._onSelectListeners = [];
this._filterMatcher = null;
this._highlightMatcher = null;
this._frc = null;
this._eventIdToElmt = {};
};
Timeline.CompactEventPainter.prototype.initialize = function(band, timeline) {
this._band = band;
this._timeline = timeline;
this._backLayer = null;
this._eventLayer = null;
this._lineLayer = null;
this._highlightLayer = null;
this._eventIdToElmt = null;
};
Timeline.CompactEventPainter.prototype.addOnSelectListener = function(listener) {
this._onSelectListeners.push(listener);
};
Timeline.CompactEventPainter.prototype.removeOnSelectListener = function(listener) {
for (var i = 0; i < this._onSelectListeners.length; i++) {
if (this._onSelectListeners[i] == listener) {
this._onSelectListeners.splice(i, 1);
break;
}
}
};
Timeline.CompactEventPainter.prototype.getFilterMatcher = function() {
return this._filterMatcher;
};
Timeline.CompactEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
this._filterMatcher = filterMatcher;
};
Timeline.CompactEventPainter.prototype.getHighlightMatcher = function() {
return this._highlightMatcher;
};
Timeline.CompactEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
this._highlightMatcher = highlightMatcher;
};
Timeline.CompactEventPainter.prototype.paint = function() {
var eventSource = this._band.getEventSource();
if (eventSource == null) {
return;
}
this._eventIdToElmt = {};
this._prepareForPainting();
var theme = this._params.theme;
var eventTheme = theme.event;
var metrics = {
trackOffset: "trackOffset" in this._params ? this._params.trackOffset : 10,
trackHeight: "trackHeight" in this._params ? this._params.trackHeight : 10,
tapeHeight: theme.event.tape.height,
tapeBottomMargin: "tapeBottomMargin" in this._params ? this._params.tapeBottomMargin : 2,
labelBottomMargin: "labelBottomMargin" in this._params ? this._params.labelBottomMargin : 5,
labelRightMargin: "labelRightMargin" in this._params ? this._params.labelRightMargin : 5,
defaultIcon: eventTheme.instant.icon,
defaultIconWidth: eventTheme.instant.iconWidth,
defaultIconHeight: eventTheme.instant.iconHeight,
customIconWidth: "iconWidth" in this._params ? this._params.iconWidth : eventTheme.instant.iconWidth,
customIconHeight: "iconHeight" in this._params ? this._params.iconHeight : eventTheme.instant.iconHeight,
iconLabelGap: "iconLabelGap" in this._params ? this._params.iconLabelGap : 2,
iconBottomMargin: "iconBottomMargin" in this._params ? this._params.iconBottomMargin : 2
};
if ("compositeIcon" in this._params) {
metrics.compositeIcon = this._params.compositeIcon;
metrics.compositeIconWidth = this._params.compositeIconWidth || metrics.customIconWidth;
metrics.compositeIconHeight = this._params.compositeIconHeight || metrics.customIconHeight;
} else {
metrics.compositeIcon = metrics.defaultIcon;
metrics.compositeIconWidth = metrics.defaultIconWidth;
metrics.compositeIconHeight = metrics.defaultIconHeight;
}
metrics.defaultStackIcon = "icon" in this._params.stackConcurrentPreciseInstantEvents ?
this._params.stackConcurrentPreciseInstantEvents.icon : metrics.defaultIcon;
metrics.defaultStackIconWidth = "iconWidth" in this._params.stackConcurrentPreciseInstantEvents ?
this._params.stackConcurrentPreciseInstantEvents.iconWidth : metrics.defaultIconWidth;
metrics.defaultStackIconHeight = "iconHeight" in this._params.stackConcurrentPreciseInstantEvents ?
this._params.stackConcurrentPreciseInstantEvents.iconHeight : metrics.defaultIconHeight;
var minDate = this._band.getMinDate();
var maxDate = this._band.getMaxDate();
var filterMatcher = (this._filterMatcher != null) ?
this._filterMatcher :
function(evt) { return true; };
var highlightMatcher = (this._highlightMatcher != null) ?
this._highlightMatcher :
function(evt) { return -1; };
var iterator = eventSource.getEventIterator(minDate, maxDate);
var stackConcurrentPreciseInstantEvents = "stackConcurrentPreciseInstantEvents" in this._params && typeof this._params.stackConcurrentPreciseInstantEvents == "object";
var collapseConcurrentPreciseInstantEvents = "collapseConcurrentPreciseInstantEvents" in this._params && this._params.collapseConcurrentPreciseInstantEvents;
if (collapseConcurrentPreciseInstantEvents || stackConcurrentPreciseInstantEvents) {
var bufferedEvents = [];
var previousInstantEvent = null;
while (iterator.hasNext()) {
var evt = iterator.next();
if (filterMatcher(evt)) {
if (!evt.isInstant() || evt.isImprecise()) {
this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
} else if (previousInstantEvent != null &&
previousInstantEvent.getStart().getTime() == evt.getStart().getTime()) {
bufferedEvents[bufferedEvents.length - 1].push(evt);
} else {
bufferedEvents.push([ evt ]);
previousInstantEvent = evt;
}
}
}
for (var i = 0; i < bufferedEvents.length; i++) {
var compositeEvents = bufferedEvents[i];
if (compositeEvents.length == 1) {
this.paintEvent(compositeEvents[0], metrics, this._params.theme, highlightMatcher(evt));
} else {
var match = -1;
for (var j = 0; match < 0 && j < compositeEvents.length; j++) {
match = highlightMatcher(compositeEvents[j]);
}
if (stackConcurrentPreciseInstantEvents) {
this.paintStackedPreciseInstantEvents(compositeEvents, metrics, this._params.theme, match);
} else {
this.paintCompositePreciseInstantEvents(compositeEvents, metrics, this._params.theme, match);
}
}
}
} else {
while (iterator.hasNext()) {
var evt = iterator.next();
if (filterMatcher(evt)) {
this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
}
}
}
this._highlightLayer.style.display = "block";
this._lineLayer.style.display = "block";
this._eventLayer.style.display = "block";
};
Timeline.CompactEventPainter.prototype.softPaint = function() {
};
Timeline.CompactEventPainter.prototype._prepareForPainting = function() {
var band = this._band;
if (this._backLayer == null) {
this._backLayer = this._band.createLayerDiv(0, "timeline-band-events");
this._backLayer.style.visibility = "hidden";
var eventLabelPrototype = document.createElement("span");
eventLabelPrototype.className = "timeline-event-label";
this._backLayer.appendChild(eventLabelPrototype);
this._frc = SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
}
this._frc.update();
this._tracks = [];
if (this._highlightLayer != null) {
band.removeLayerDiv(this._highlightLayer);
}
this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
this._highlightLayer.style.display = "none";
if (this._lineLayer != null) {
band.removeLayerDiv(this._lineLayer);
}
this._lineLayer = band.createLayerDiv(110, "timeline-band-lines");
this._lineLayer.style.display = "none";
if (this._eventLayer != null) {
band.removeLayerDiv(this._eventLayer);
}
this._eventLayer = band.createLayerDiv(115, "timeline-band-events");
this._eventLayer.style.display = "none";
};
Timeline.CompactEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
if (evt.isInstant()) {
this.paintInstantEvent(evt, metrics, theme, highlightIndex);
} else {
this.paintDurationEvent(evt, metrics, theme, highlightIndex);
}
};
Timeline.CompactEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
if (evt.isImprecise()) {
this.paintImpreciseInstantEvent(evt, metrics, theme, highlightIndex);
} else {
this.paintPreciseInstantEvent(evt, metrics, theme, highlightIndex);
}
}
Timeline.CompactEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
if (evt.isImprecise()) {
this.paintImpreciseDurationEvent(evt, metrics, theme, highlightIndex);
} else {
this.paintPreciseDurationEvent(evt, metrics, theme, highlightIndex);
}
}
Timeline.CompactEventPainter.prototype.paintPreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
var commonData = {
tooltip: evt.getProperty("tooltip") || evt.getText()
};
var iconData = {
url: evt.getIcon()
};
if (iconData.url == null) {
iconData.url = metrics.defaultIcon;
iconData.width = metrics.defaultIconWidth;
iconData.height = metrics.defaultIconHeight;
iconData.className = "timeline-event-icon-default";
} else {
iconData.width = evt.getProperty("iconWidth") || metrics.customIconWidth;
iconData.height = evt.getProperty("iconHeight") || metrics.customIconHeight;
}
var labelData = {
text: evt.getText(),
color: evt.getTextColor() || evt.getColor(),
className: evt.getClassName()
};
var result = this.paintTapeIconLabel(
evt.getStart(),
commonData,
null, // no tape data
iconData,
labelData,
metrics,
theme,
highlightIndex
);
var self = this;
var clickHandler = function(elmt, domEvt, target) {
return self._onClickInstantEvent(result.iconElmtData.elmt, domEvt, evt);
};
SimileAjax.DOM.registerEvent(result.iconElmtData.elmt, "mousedown", clickHandler);
SimileAjax.DOM.registerEvent(result.labelElmtData.elmt, "mousedown", clickHandler);
this._eventIdToElmt[evt.getID()] = result.iconElmtData.elmt;
};
Timeline.CompactEventPainter.prototype.paintCompositePreciseInstantEvents = function(events, metrics, theme, highlightIndex) {
var evt = events[0];
var tooltips = [];
for (var i = 0; i < events.length; i++) {
tooltips.push(events[i].getProperty("tooltip") || events[i].getText());
}
var commonData = {
tooltip: tooltips.join("; ")
};
var iconData = {
url: metrics.compositeIcon,
width: metrics.compositeIconWidth,
height: metrics.compositeIconHeight,
className: "timeline-event-icon-composite"
};
var labelData = {
text: String.substitute(this._params.compositeEventLabelTemplate, [ events.length ])
};
var result = this.paintTapeIconLabel(
evt.getStart(),
commonData,
null, // no tape data
iconData,
labelData,
metrics,
theme,
highlightIndex
);
var self = this;
var clickHandler = function(elmt, domEvt, target) {
return self._onClickMultiplePreciseInstantEvent(result.iconElmtData.elmt, domEvt, events);
};
SimileAjax.DOM.registerEvent(result.iconElmtData.elmt, "mousedown", clickHandler);
SimileAjax.DOM.registerEvent(result.labelElmtData.elmt, "mousedown", clickHandler);
for (var i = 0; i < events.length; i++) {
this._eventIdToElmt[events[i].getID()] = result.iconElmtData.elmt;
}
};
Timeline.CompactEventPainter.prototype.paintStackedPreciseInstantEvents = function(events, metrics, theme, highlightIndex) {
var limit = "limit" in this._params.stackConcurrentPreciseInstantEvents ?
this._params.stackConcurrentPreciseInstantEvents.limit : 10;
var moreMessageTemplate = "moreMessageTemplate" in this._params.stackConcurrentPreciseInstantEvents ?
this._params.stackConcurrentPreciseInstantEvents.moreMessageTemplate : "%0 More Events";
var showMoreMessage = limit <= events.length - 2; // We want at least 2 more events above the limit.
// Otherwise we'd need the singular case of "1 More Event"
var band = this._band;
var getPixelOffset = function(date) {
return Math.round(band.dateToPixelOffset(date));
};
var getIconData = function(evt) {
var iconData = {
url: evt.getIcon()
};
if (iconData.url == null) {
iconData.url = metrics.defaultStackIcon;
iconData.width = metrics.defaultStackIconWidth;
iconData.height = metrics.defaultStackIconHeight;
iconData.className = "timeline-event-icon-stack timeline-event-icon-default";
} else {
iconData.width = evt.getProperty("iconWidth") || metrics.customIconWidth;
iconData.height = evt.getProperty("iconHeight") || metrics.customIconHeight;
iconData.className = "timeline-event-icon-stack";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -