Hi,

Here you go. A quick hack.
Using an event like this..

  <event start="Nov 01 2007" end="Nov 15 2007" isDuration="true"
         title="Test Task with pctComplete"
         pctComplete="33">
    Test Task with pctComplete
  </event>


Use the below my-painter.js file (see_createPctCompleteDiv() function)
You can diff it with original-painter.js to see the differences

-------------------------------------
cut------------------------------------------
/*==================================================
 *  Original Event Painter
 *==================================================
 */

Timeline.OriginalEventPainter = function(params) {
    this._params = params;
    this._onSelectListeners = [];

    this._filterMatcher = null;
    this._highlightMatcher = null;
    this._frc = null;

    this._eventIdToElmt = {};
};

Timeline.OriginalEventPainter.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.OriginalEventPainter.prototype.addOnSelectListener =
function(listener) {
    this._onSelectListeners.push(listener);
};

Timeline.OriginalEventPainter.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.OriginalEventPainter.prototype.getFilterMatcher = function()
{
    return this._filterMatcher;
};

Timeline.OriginalEventPainter.prototype.setFilterMatcher =
function(filterMatcher) {
    this._filterMatcher = filterMatcher;
};

Timeline.OriginalEventPainter.prototype.getHighlightMatcher =
function() {
    return this._highlightMatcher;
};

Timeline.OriginalEventPainter.prototype.setHighlightMatcher =
function(highlightMatcher) {
    this._highlightMatcher = highlightMatcher;
};

Timeline.OriginalEventPainter.prototype.paint = function() {
    var eventSource = this._band.getEventSource();
    if (eventSource == null) {
        return;
    }

    this._eventIdToElmt = {};
    this._prepareForPainting();

    var eventTheme = this._params.theme.event;
    var trackHeight = Math.max(eventTheme.track.height,
eventTheme.tape.height + this._frc.getLineHeight());
    var metrics = {
        trackOffset:    eventTheme.track.gap,
        trackHeight:    trackHeight,
        trackGap:       eventTheme.track.gap,
        trackIncrement: trackHeight + eventTheme.track.gap,
        icon:           eventTheme.instant.icon,
        iconWidth:      eventTheme.instant.iconWidth,
        iconHeight:     eventTheme.instant.iconHeight,
        labelWidth:     eventTheme.label.width
    }

    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.getEventReverseIterator(minDate,
maxDate);
    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.OriginalEventPainter.prototype.softPaint = function() {
};

Timeline.OriginalEventPainter.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.OriginalEventPainter.prototype.paintEvent = function(evt,
metrics, theme, highlightIndex) {
    if (evt.isInstant()) {
        this.paintInstantEvent(evt, metrics, theme, highlightIndex);
    } else {
        this.paintDurationEvent(evt, metrics, theme, highlightIndex);
    }
};

Timeline.OriginalEventPainter.prototype.paintInstantEvent =
function(evt, metrics, theme, highlightIndex) {
    if (evt.isImprecise()) {
        this.paintImpreciseInstantEvent(evt, metrics, theme,
highlightIndex);
    } else {
        this.paintPreciseInstantEvent(evt, metrics, theme,
highlightIndex);
    }
}

Timeline.OriginalEventPainter.prototype.paintDurationEvent =
function(evt, metrics, theme, highlightIndex) {
    if (evt.isImprecise()) {
        this.paintImpreciseDurationEvent(evt, metrics, theme,
highlightIndex);
    } else {
        this.paintPreciseDurationEvent(evt, metrics, theme,
highlightIndex);
    }
}

Timeline.OriginalEventPainter.prototype.paintPreciseInstantEvent =
function(evt, metrics, theme, highlightIndex) {
    var doc = this._timeline.getDocument();
    var text = evt.getText();

    var startDate = evt.getStart();
    var startPixel =
Math.round(this._band.dateToPixelOffset(startDate));
    var iconRightEdge = Math.round(startPixel + metrics.iconWidth /
2);
    var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);

    var labelSize = this._frc.computeSize(text);
    var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
    var labelRight = labelLeft + labelSize.width;

    var rightEdge = labelRight;
    var track = this._findFreeTrack(rightEdge);

    var labelTop = Math.round(
        metrics.trackOffset + track * metrics.trackIncrement +
        metrics.trackHeight / 2 - labelSize.height / 2);

    var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge,
metrics, theme);
    var labelElmtData = this._paintEventLabel(evt, text, labelLeft,
labelTop, labelSize.width, labelSize.height, theme);

    var self = this;
    var clickHandler = function(elmt, domEvt, target) {
        return self._onClickInstantEvent(iconElmtData.elmt, domEvt,
evt);
    };
    SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown",
clickHandler);

    this._createHighlightDiv(highlightIndex, iconElmtData, theme);

    this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
    this._tracks[track] = iconLeftEdge;
};

Timeline.OriginalEventPainter.prototype.paintImpreciseInstantEvent =
function(evt, metrics, theme, highlightIndex) {
    var doc = this._timeline.getDocument();
    var text = evt.getText();

    var startDate = evt.getStart();
    var endDate = evt.getEnd();
    var startPixel =
Math.round(this._band.dateToPixelOffset(startDate));
    var endPixel = Math.round(this._band.dateToPixelOffset(endDate));

    var iconRightEdge = Math.round(startPixel + metrics.iconWidth /
2);
    var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);

    var labelSize = this._frc.computeSize(text);
    var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
    var labelRight = labelLeft + labelSize.width;

    var rightEdge = Math.max(labelRight, endPixel);
    var track = this._findFreeTrack(rightEdge);
    var labelTop = Math.round(
        metrics.trackOffset + track * metrics.trackIncrement +
        metrics.trackHeight / 2 - labelSize.height / 2);

    var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge,
metrics, theme);
    var labelElmtData = this._paintEventLabel(evt, text, labelLeft,
labelTop, labelSize.width, labelSize.height, theme);
    var tapeElmtData = this._paintEventTape(evt, track, startPixel,
endPixel,
        theme.event.instant.impreciseColor,
theme.event.instant.impreciseOpacity, metrics, theme);

    var self = this;
    var clickHandler = function(elmt, domEvt, target) {
        return self._onClickInstantEvent(iconElmtData.elmt, domEvt,
evt);
    };
    SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown",
clickHandler);

    this._createHighlightDiv(highlightIndex, iconElmtData, theme);

    this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
    this._tracks[track] = iconLeftEdge;
};

Timeline.OriginalEventPainter.prototype.paintPreciseDurationEvent =
function(evt, metrics, theme, highlightIndex) {
    var doc = this._timeline.getDocument();
    var text = evt.getText();

    var startDate = evt.getStart();
    var endDate = evt.getEnd();
    var startPixel =
Math.round(this._band.dateToPixelOffset(startDate));
    var endPixel = Math.round(this._band.dateToPixelOffset(endDate));

    var pctComplete = evt.getProperty("pctComplete");
    if (pctComplete == null || pctComplete.length == 0) {
        pctComplete = 0;
    }
    text = text + " [" + pctComplete + "%]";

    var labelSize = this._frc.computeSize(text);
    var labelLeft = startPixel;
    var labelRight = labelLeft + labelSize.width;

    var rightEdge = Math.max(labelRight, endPixel);
    var track = this._findFreeTrack(rightEdge);
    var labelTop = Math.round(
        metrics.trackOffset + track * metrics.trackIncrement +
theme.event.tape.height);

    var color = evt.getColor();
    color = color != null ? color : theme.event.duration.color;

    var tapeElmtData = this._paintEventTape(evt, track, startPixel,
endPixel, color, 100, metrics, theme);
    var labelElmtData = this._paintEventLabel(evt, text, labelLeft,
labelTop, labelSize.width, labelSize.height, theme);
    var pctCompleteElmtData =
this._createPctCompleteDiv(highlightIndex, tapeElmtData, theme, evt);

    var self = this;
    var clickHandler = function(elmt, domEvt, target) {
        return self._onClickDurationEvent(tapeElmtData.elmt, domEvt,
evt);
    };
    SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(pctCompleteElmtData.elmt,
"mousedown", clickHandler);

    this._createHighlightDiv(highlightIndex, tapeElmtData, theme);

    this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
    this._tracks[track] = startPixel;
};

Timeline.OriginalEventPainter.prototype.paintImpreciseDurationEvent =
function(evt, metrics, theme, highlightIndex) {
    var doc = this._timeline.getDocument();
    var text = evt.getText();

    var startDate = evt.getStart();
    var latestStartDate = evt.getLatestStart();
    var endDate = evt.getEnd();
    var earliestEndDate = evt.getEarliestEnd();

    var startPixel =
Math.round(this._band.dateToPixelOffset(startDate));
    var latestStartPixel =
Math.round(this._band.dateToPixelOffset(latestStartDate));
    var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
    var earliestEndPixel =
Math.round(this._band.dateToPixelOffset(earliestEndDate));

    var labelSize = this._frc.computeSize(text);
    var labelLeft = latestStartPixel;
    var labelRight = labelLeft + labelSize.width;

    var rightEdge = Math.max(labelRight, endPixel);
    var track = this._findFreeTrack(rightEdge);
    var labelTop = Math.round(
        metrics.trackOffset + track * metrics.trackIncrement +
theme.event.tape.height);

    var color = evt.getColor();
    color = color != null ? color : theme.event.duration.color;

    var impreciseTapeElmtData = this._paintEventTape(evt, track,
startPixel, endPixel,
        theme.event.duration.impreciseColor,
theme.event.duration.impreciseOpacity, metrics, theme);
    var tapeElmtData = this._paintEventTape(evt, track,
latestStartPixel, earliestEndPixel, color, 100, metrics, theme);

    var labelElmtData = this._paintEventLabel(evt, text, labelLeft,
labelTop, labelSize.width, labelSize.height, theme);

    var self = this;
    var clickHandler = function(elmt, domEvt, target) {
        return self._onClickDurationEvent(tapeElmtData.elmt, domEvt,
evt);
    };
    SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown",
clickHandler);
    SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown",
clickHandler);

    this._createHighlightDiv(highlightIndex, tapeElmtData, theme);

    this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
    this._tracks[track] = startPixel;
};

Timeline.OriginalEventPainter.prototype._findFreeTrack =
function(rightEdge) {
    for (var i = 0; i < this._tracks.length; i++) {
        var t = this._tracks[i];
        if (t > rightEdge) {
            break;
        }
    }
    return i;
};

Timeline.OriginalEventPainter.prototype._paintEventIcon =
function(evt, iconTrack, left, metrics, theme) {
    var icon = evt.getIcon();
    icon = icon != null ? icon : metrics.icon;

    var middle = metrics.trackOffset + iconTrack *
metrics.trackIncrement + metrics.trackHeight / 2;
    var top = Math.round(middle - metrics.iconHeight / 2);

    var img = SimileAjax.Graphics.createTranslucentImage(icon);
    var iconDiv = this._timeline.getDocument().createElement("div");
    iconDiv.style.position = "absolute";
    iconDiv.style.left = left + "px";
    iconDiv.style.top = top + "px";
    iconDiv.appendChild(img);
    iconDiv.style.cursor = "pointer";
    this._eventLayer.appendChild(iconDiv);

    return {
        left:   left,
        top:    top,
        width:  metrics.iconWidth,
        height: metrics.iconHeight,
        elmt:   iconDiv
    };
};

Timeline.OriginalEventPainter.prototype._paintEventLabel =
function(evt, text, left, top, width, height, theme) {
    var doc = this._timeline.getDocument();

    var labelDiv = doc.createElement("div");
    labelDiv.style.position = "absolute";
    labelDiv.style.left = left + "px";
    labelDiv.style.width = width + "px";
    labelDiv.style.top = top + "px";
    labelDiv.innerHTML = text;
    labelDiv.style.cursor = "pointer";

    var color = evt.getTextColor();
    if (color == null) {
        color = evt.getColor();
    }
    if (color != null) {
        labelDiv.style.color = color;
    }

    this._eventLayer.appendChild(labelDiv);

    return {
        left:   left,
        top:    top,
        width:  width,
        height: height,
        elmt:   labelDiv
    };
};

Timeline.OriginalEventPainter.prototype._paintEventTape = function(
    evt, iconTrack, startPixel, endPixel, color, opacity, metrics,
theme) {

    var tapeWidth = endPixel - startPixel;
    var tapeHeight = theme.event.tape.height;
    var top = metrics.trackOffset + iconTrack *
metrics.trackIncrement;

    var tapeDiv = this._timeline.getDocument().createElement("div");
    tapeDiv.style.position = "absolute";
    tapeDiv.style.left = startPixel + "px";
    tapeDiv.style.width = tapeWidth + "px";
    tapeDiv.style.top = top + "px";
    tapeDiv.style.height = tapeHeight + "px";
    tapeDiv.style.backgroundColor = color;
    tapeDiv.style.overflow = "hidden";
    tapeDiv.style.cursor = "pointer";
    SimileAjax.Graphics.setOpacity(tapeDiv, opacity);

    this._eventLayer.appendChild(tapeDiv);

    return {
        left:   startPixel,
        top:    top,
        width:  tapeWidth,
        height: tapeHeight,
        elmt:   tapeDiv
    };
}

Timeline.OriginalEventPainter.prototype._createHighlightDiv =
function(highlightIndex, dimensions, theme) {
    if (highlightIndex >= 0) {
        var doc = this._timeline.getDocument();
        var eventTheme = theme.event;

        var color =
eventTheme.highlightColors[Math.min(highlightIndex,
eventTheme.highlightColors.length - 1)];

        var div = doc.createElement("div");
        div.style.position = "absolute";
        div.style.overflow = "hidden";
        div.style.left =    (dimensions.left - 2) + "px";
        div.style.width =   (dimensions.width + 4) + "px";
        div.style.top =     (dimensions.top - 2) + "px";
        div.style.height =  (dimensions.height + 4) + "px";
        div.style.background = color;

        this._highlightLayer.appendChild(div);
    }
};

Timeline.OriginalEventPainter.prototype._createPctCompleteDiv =
function(highlightIndex, dimensions, theme, evt) {

    var doc = this._timeline.getDocument();
    var eventTheme = theme.event;

    var color =
      eventTheme.highlightColors[Math.min(highlightIndex>=0?
highlightIndex:0
                                         ,eventTheme.highlightColors.length
- 1)];

    var pctComplete = evt.getProperty("pctComplete");
    var widthReduction = dimensions.width - 2;
    if (pctComplete != null && pctComplete.length > 0) {
        widthReduction = Math.round(dimensions.width * (100 - pctComplete)/
100 );
        widthReduction = (widthReduction <= 0) ? 2 : widthReduction;
    }

    var div = doc.createElement("div");
    div.style.position = "absolute";
    div.style.overflow = "hidden";
    div.style.cursor = "pointer";
    div.style.left =    (dimensions.left + 1) + "px";

    div.style.width =   (dimensions.width - widthReduction) + "px";

    div.style.top =     (dimensions.top + 1) + "px";
    div.style.height =  (dimensions.height - 2) + "px";
    div.style.background = color;

    this._eventLayer.appendChild(div);

    return {
        left:   dimensions.left + 1,
            top:    dimensions.top + 1,
            width:  dimensions.width - widthReduction,
            height: dimensions.height - 2,
            elmt:   div
            };
};


Timeline.OriginalEventPainter.prototype._onClickInstantEvent =
function(icon, domEvt, evt) {
    var c = SimileAjax.DOM.getPageCoordinates(icon);
    this._showBubble(
        c.left + Math.ceil(icon.offsetWidth / 2),
        c.top + Math.ceil(icon.offsetHeight / 2),
        evt
    );
    this._fireOnSelect(evt.getID());

    domEvt.cancelBubble = true;
    SimileAjax.DOM.cancelEvent(domEvt);
    return false;
};

Timeline.OriginalEventPainter.prototype._onClickDurationEvent =
function(target, domEvt, evt) {
    if ("pageX" in domEvt) {
        var x = domEvt.pageX;
        var y = domEvt.pageY;
    } else {
        var c = SimileAjax.DOM.getPageCoordinates(target);
        var x = domEvt.offsetX + c.left;
        var y = domEvt.offsetY + c.top;
    }
    this._showBubble(x, y, evt);
    this._fireOnSelect(evt.getID());

    domEvt.cancelBubble = true;
    SimileAjax.DOM.cancelEvent(domEvt);
    return false;
};

Timeline.OriginalEventPainter.prototype.showBubble = function(evt) {
    var elmt = this._eventIdToElmt[evt.getID()];
    if (elmt) {
        var c = SimileAjax.DOM.getPageCoordinates(elmt);
        this._showBubble(c.left + elmt.offsetWidth / 2, c.top +
elmt.offsetHeight / 2, evt);
    }
};

Timeline.OriginalEventPainter.prototype._showBubble = function(x, y,
evt) {
    var div = document.createElement("div");
    evt.fillInfoBubble(div, this._params.theme,
this._band.getLabeller());

    SimileAjax.WindowManager.cancelPopups();
    SimileAjax.Graphics.createBubbleForContentAndPoint(div, x, y,
this._params.theme.event.bubble.width);
};

Timeline.OriginalEventPainter.prototype._fireOnSelect =
function(eventID) {
    for (var i = 0; i < this._onSelectListeners.length; i++) {
        this._onSelectListeners[i](eventID);
    }
};
-------------------------------------
cut------------------------------------------

Sincerely,

-Mohsin


On Aug 20, 11:27 pm, mohsin beg <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I am looking for suggestions as how I can show an event progress/
> completion (via a "percentage_complete" event attribute) or some other
> means (e.g. like showing an event pair aligned vertically etc).
>
> I am using timeline (very successfully) to manage a complex project,
> but it's hard to communicate to other team members about the current
> status, or percentage complete, of each task (i.e. event).
>
> Thank you in advance for your suggestions.
>
> Sincerely,
>
> -Mohsin
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"SIMILE Widgets" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/simile-widgets?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to