Timeline event placement / ordering / sorting of events?

265 views
Skip to first unread message

erikM

unread,
Mar 18, 2012, 5:00:46 PM3/18/12
to simile-...@googlegroups.com

Hi all,
I have been searching around and I have been trying to figure this out with no luck, so hopefully someone her can tell how to sort this out :)

I I'm fetching all my timeline data from a Java REST service, in this service I have sorted all the Events in the order that I want them to appear. I'm only dealing with duration = true events.
And I want the first elements in the xml to end up first in my Band. But the way it ends up right now, its all reverse compared to my wanted result.

My events turn up like this:
                                                                                                  3 |-----------------------------------------------|
                                                     2 |--------------------------------------------|
1 |----------------------------------------------------|

And I need them to be sorted out like this:

1 |----------------------------------------------------|
                                                     2 |--------------------------------------------|
                                                                                                  3 |-----------------------------------------------|


Is this achievable?

Best regards
Erik


Michael Nosal

unread,
Mar 22, 2012, 4:03:13 PM3/22/12
to simile-...@googlegroups.com
I've done this. It takes a few JS code changes.

Note: You can put all of these changes in separate .js files that you load after Timeline. Don't make the changes in the Timeline source, or worse, in the timeline-bundle.js file. You'll save yourself a lot of trouble if you avoid patching/hacking on the Timeline code directly.

First, let's add some constants that let us specify which direction we want the events to be laid out. I'll call the default behavior Timeline.REVERSE, and the new behavior Timeline.FORWARD

Timeline.REVERSE=0;
Timeline.FORWARD=1;


We'll want this behavior specified per-band, so we'll need to add the direction parameter.

In Timeline.createBandInfo and Timeline.createHotZoneBandInfo, change the eventPainterParams variable:

var eventPainterParams = {
showText: ("showEventText" in params) ? params.showEventText : true,
direction : ("direction" in params) ? params.direction : Timeline.REVERSE,
theme: theme
};

Since the reverse painting of events is the current behavior, it is the default direction.

Now you'll need to customize the painter to respect the direction. Make a copy of original-painter.js and call it my-original-painter.js or something.

In the event painter, add this to the constructor:
Timeline.OriginalEventPainter = function(params) {
this._params = params;
...
this._direction = ("direction" in params) ? params.direction : Timeline.REVERSE;
}

Then, you'll need to check the direction when painting. In Timeline.OriginalEventPainter.prototype.paint, change:
var iterator = this._direction == Timeline.FORWARD ?
eventSource.getEventIterator(minDate, maxDate) :
eventSource.getEventReverseIterator(minDate, maxDate);

Because we don't want our labels touching events on the right edge, add a right buffer to the computations:
var labelRight = labelLeft + labelSize.width + theme.event.label.rightBuffer;
(Add 'rightBuffer : 10' to theme.event.label in themes.js)

When painting individual events, we need to check the spacing on the left when iterating forward and on the right when iterating in reverse. In paintPreciseInstantEvent:

var track = this._direction == Timeline.FORWARD ?
this._findFreeTrack(evt,labelLeft) :
this._findFreeTrack(evt,rightEdge);

And you'll need to switch which pixel is stored in the _tracks array depending on your direction:
this._tracks[track] = this._direction == Timeline.FORWARD ? rightEdge : iconLeftEdge;

Make the same changes for paintImpreciseInstantEvent.

Do the same thing for paintPreciseDurationEvent and paintImpreciseDurationEvent:
var labelRight = labelLeft + labelSize.width + theme.event.label.rightBuffer;

var track = this._direction == Timeline.FORWARD ?
this._findFreeTrack(evt,labelLeft) :
this._findFreeTrack(evt,rightEdge);

this._tracks[track] = this._direction == Timeline.FORWARD ? rightEdge : startPixel;

And finally change:
Timeline.OriginalEventPainter.prototype._findFreeTrack = function(event, edgePixel) {
var trackAttribute = event.getTrackNum();
if (trackAttribute != null) {
return trackAttribute; // early return since event includes track number
}

// normal case: find an open track
for (var i = 0; i < this._tracks.length; i++) {
var t = this._tracks[i];
if (this._direction == Timeline.FORWARD ? t < edgePixel : t > edgePixel) {
break;
}
}
return i;
};

Once you've done all this (told you it would be a few JS changes), you can now specify the direction of painting when constructing your bandInfos:
var bandInfos = [
Timeline.createHotZoneBandInfo({
width: "80%",
intervalUnit: Timeline.DateTime.WEEK,
intervalPixels: 220,
zones: zones,
direction: Timeline.FORWARD,
eventSource: eventSource,
date: date,
timeZone: -6,
theme: theme
}),
etc.

I've just done this and it seems to work correctly on the jfk and test examples.
Let me know if you get this working.

--Mike

Reply all
Reply to author
Forward
0 new messages