How to put custom event data in the event and access this

78 views
Skip to first unread message

mabra

unread,
Aug 5, 2009, 4:22:40 PM8/5/09
to SIMILE Widgets
Hi !

Dependent on the type of an event, I wish to provide additional
values, which I would see as "custom attributes". From my tests based
on json data, these values do not cause any error. But I do not know,
how to access them, especially in the event painter.

Thanks so far!

br--mabra

Michael Nosal

unread,
Aug 5, 2009, 4:53:51 PM8/5/09
to simile-...@googlegroups.com
The JSON loader already gives you access to your original JSON event
object. For example, in
Timeline.DefaultEventSource.prototype.loadJSON, look at:

var evt = new Timeline.DefaultEventSource.Event(
...
);
evt._obj = evnt;
evt.getProperty = function(name) {
return this._obj[name];
}

Now you've got a copy of all your original JSON data tacked onto the
Event object. This is much easier than adding additional arguments to
the Event constructor.

Then in your painter code, you can just access whatever attributes
were on your original JSON object:

{"events" : [
{"start" : "2001", "end" : "2003", "title" : "Blah blah",
"flavor" : "Cherry"},
....
]}

You can access the "flavor" attribute in your painter code:
labelDiv.innerHTML = text;
labelDiv.title = evt.getProperty("flavor");

Or in the fillInfoBubble code:
e.g. var title = this.getProperty("myCustomTitleField");

This makes it possible to (with customizations) do just about
anything, displaying all kinds of custom data, creative new painters,
advanced layouts, etc.

--Mike Nosal

mabra

unread,
Aug 6, 2009, 5:24:13 PM8/6/09
to SIMILE Widgets
Hello!

Much, much thanks!

That drives me into the right direction. Although I've not understand
your inital explanation, I generate my events on the server and direct
access to all of them on the client side is currently not needed.

I found a sample of an "fillInfoBubble" and can access my event
directly and your
this.getProperty("myCustomTitleField");
made it for me!!!

I'll even send custom classes to the client and simple GUIs fitting an
events class and made a simple prototype.

But what I recognized:I must build the whole popup my myself. You
mentioned a "painter". Do you have an example? I just use the
"fillInfoBubble", but must even remove the date and time etc. from the
event.

This tip could be great!

Anyway, much thanks for your help!

br--mabra
> > br--mabra- Hide quoted text -
>
> - Show quoted text -

Michael Nosal

unread,
Aug 6, 2009, 6:51:00 PM8/6/09
to simile-...@googlegroups.com
Customizing the visual display of items on the timeline (changing the
content shown, rather than the styles) usually requires some custom
Javascript coding. The code that draws the icons and bars on the
timeline are called "painters". The code that puts stuff inside the
bubble when you click on an event is part of the event-source code
(this is where the fillInfoBubble function lives.)

You can create customized versions of the various javascript functions
and use those instead of the default ones.

For example, I might want a timeline showing movies playing in local
theaters. I have a database of movies on my server and I can return a
list of movies for a given date range as JSON. The data might look
like this:

{"events" : [
{"start":"2009 Aug 06 15:30",
"end" : "2009 Aug 06 17:35",
"title" : "Shark Attack!",
"genre" : "Action/Adventure",
"rating" : "PG13",
"description" : "Angry sharks with lasers cause mayhem."},
{....etc}

When the user clicks on a movie, I want to show them a nice little
summary of the movie in the bubble. The default fillInfoBubble method
will automatically show the title and description in the bubble, but I
want it to show the start and end times, the rating and the genre for
the movie. I'll also highlight any movie that has an "R" rating with a
note.

To do this, just make your own version of this function: (I used
innerHTML here because it's quick and dirty. There are many different
ways of filling in the content of the bubble).

Timeline.DefaultEventSource.Event.prototype.fillInfoBubble =
function(elmt, theme, labeller) {
var rating = this.getProperty("rating");
var bubbleText = "<div class='title'>" + this.getText() + "</div>" +
"<table class='movie'><tr><th>Description:</th>" +
"<td style='width:65%'>" + this.getDescription() + "</td></tr>"+
"<tr><th>Genre:</th><td>" +
this.getProperty("genre") + "</td></tr>" +
"<tr><th>Rating" + "</th><td>" +
rating +
(rating == "R" ? "<br>(Note: No one under 13 allowed)" : "") +
"</td></tr>" +
"<tr><th>Start:</th>" +
"<td>" + this.getStart() + "</td></tr>" +
"<tr><th>End:</th>" +
"<td>" + this.getEnd() + "</td></tr></table>";

elmt.innerHTML= bubbleText;
}

I include this custom fillInfoBubble function in my javascript and
make sure it loads after I load Timeline (so it overrides the
default). Now when the user clicks on a movie, they see this nice
little table of movie information.

I was able to include whatever attributes I want in the JSON that is
sent back from my server (genre, rating, etc) and customize the
infoBubble to show those custom attributes using the .getProperty()
method on my event.

Suppose I wanted to show "rating" on the timeline itself, as part of
the label. This is done by the painter. Suppose we're using the
original painter. The labels for the events are made in
Timeline.OriginalEventPainter.prototype._paintEventLabel.

We can copy and paste the entire function into our own file and then
change it:
labelDiv.innerHTML = text + " (" + evt.getProperty("rating") + ")";

Now, the genre for every movie on our timeline is appended to the label:
Shark Attack! (PG13)

So there are two examples of customizing the contents of the bubble
and the labels on the timeline using custom attributes for an event
that are passed inside the JSON.

Feel free to ask if you have any more questions.

--Mike Nosal

mabra

unread,
Aug 7, 2009, 1:10:07 PM8/7/09
to SIMILE Widgets
Hi !

Great explanation, much, much thanks for your investigation!

From the moment, you pointed me to use "evt.getProperty(..), I changed
my custom infoBubble with javascript to "recognize" the following
json:

{
'title': "ServerCrash",
'description': 'Server crashed serevral times',
'start': 'Mar 26 2009 00:00:00 GMT',
'end': 'Mar 26 2009 01:00:00 GMT',
'isDuration': true,
'evtType': '1',
'server': { 'name': 'BigHope01', 'address': '127.0.0.2' },
'icon': 'bomb.png'
},
{
'title': "ClientProblem",
'description': 'User cannot log on',
'start': 'Mar 26 2009 02:00:00 GMT',
'end': 'Mar 26 2009 03:00:00 GMT',
'isDuration': false,
'caption': 'popup something here!',
'textColor': 'brown',
'evtType': '2',
'client': { 'user': 'xyz', 'location': 'Buxtehude' }
},

Depending on the given "evtType", I prepare the bubble. This is really
great! In my second attempt, I even provide the html used to build the
popup depending on the "evtType", so it's very general.

Thanks to you new explanations, I lastly got it:The "elmt" passed to
the custom function is really the bubble itself. Before, I just used
"appendElement", but now, I can use "innerHTML" directly.

Thanks to your last explanation, I got a picture of the painters. The
idea, to show more inside the band, may be - sometimes - a good one.
But I see other code in the "original" [I use 2.3.0], than that, that
you posted.

In that code, I should do:
B.innerHTML=L + "(" + this.getProperty("rating") + ")";

assuming that "this", inside the function, is a reference to the
event.
Additionally, I have to override the prototype!??
Am I right??

From my json, you probably may imagine, what I do and plan:I am
[mostly] administrator using too many different tools whith no
relationships. What I wish, is a status panel, correlating everything
which is relevant to "service availability", in one graph! Timeline
looks great!

Anyway, much thanks for your great help!!!

br--mabra

Michael Nosal

unread,
Aug 7, 2009, 1:28:19 PM8/7/09
to simile-...@googlegroups.com
I was referring to original-painter.js. In v2.3.0, the _paintEventLabel method is at line 490:
Timeline.OriginalEventPainter.prototype._paintEventLabel = function(evt, text, left, top, width,
    height, theme, labelDivClassName, highlightIndex) {
    var doc = this._timeline.getDocument();
   
    var labelDiv = doc.createElement("div");
    labelDiv.className = labelDivClassName;
    labelDiv.id = this._encodeEventElID('label', evt);
    labelDiv.style.left = left + "px";
    labelDiv.style.width = width + "px";
    labelDiv.style.top = top + "px";
    labelDiv.innerHTML = text;

    if(evt._title != null)
        labelDiv.title = evt._title;    

    var color = evt.getTextColor();
    if (color == null) {
        color = evt.getColor();
    }
    if (color != null) {
        labelDiv.style.color = color;
    }
    if (theme.event.highlightLabelBackground && highlightIndex >= 0) {
        labelDiv.style.background = this._getHighlightColor(highlightIndex, theme);
    }
   
    this._eventLayer.appendChild(labelDiv);
   
    return {
        left:   left,
        top:    top,
        width:  width,
        height: height,
        elmt:   labelDiv
    };
};
Line 500:
labelDiv.innerHTML = text;
is how the text gets on the timeline. Inside this function, evt is the variable that holds the actual Event object that is responsible for the item being shown on the timeline. "this" would refer to the instance of the OriginalEventPainter that is doing the drawing, not the Event object. So you want to call evt.getProperty("propertyName") to add additional text to the label. 
There are several different approaches one can take to customize how Timeline works. In the case of relatively small modifications like this, it is easiest to simply copy the entire ._paintEventLabel function code into a new file, and make your changes to that copy. As long as your copy of the function is loaded after Timeline has been loaded, then it will replace (override) the default Timeline behavior. 
Good luck.
--Mike Nosal
On Aug 7, 2009, at 1:10 PM, mabra wrote:
...

mabra

unread,
Aug 8, 2009, 5:13:36 AM8/8/09
to SIMILE Widgets
Hi !

Ok, I see.
Much, much thanks again. You seems to be a real expert on this!

br--mabra
> > Am I right??- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages