Help talk:Timeline format/Archive

From semantic-mediawiki.org

timelineposition today?[edit]

timelineposition=today is obviously gone. Was wondering why timelines on wikis I'm working on all of a sudden did look a little strange. oO

Is there any chance to get it back? That would actually be quite nice. Otherwise timeline/eventline doesn't really fit my use-cases anymore.

--Eric 19:55, 7 January 2012 (CET)

Agree with Eric. There are the same problems on my wiki too. Let's try to ask Jeroen. Yury Katkov 23:37, 8 January 2012 (CET)
Here is the Task T35594.
This format basically needs a total rewrite which should indeed cater for this. There have been some mails on the userlist recently, too. Basically, all we need is time and money. Cheers --[[kgh]] 11:39, 9 January 2012 (CET)
For timeline=today you just need 1 line of code changed, since 'today' is the 'default' setting and support is still there. HTH - HAND BugBlue
in SemanticResultFormats/Timeline/SRF_Timeline.php line 368
-                $params['timelineposition']->addCriteria( new CriterionInArray( 'start', 'middle', 'end' ) );
+                $params['timelineposition']->addCriteria( new CriterionInArray( 'start', 'middle', 'end', 'today' ) );
Heiya BugBlue, thank you for your post. I will ask a coder to check and commit. To have this would be great, indeed. Cheers --[[kgh]] 00:00, 9 March 2012 (CET)
Thanks for the fix! Just checked it in. --Stephan Gambke 22:38, 9 March 2012 (CET)
This doesn't appear to be fixed to me, or perhaps the code has changed since last year. "today" doesn't appear to do anything in the current code. I think it's defaulting to "middle". In line 228 of SemanticResultFormats/formats/timeline/SRF_Timeline.php I changed the 'today' case to:
case 'today': 
    $result .= '<span class="smwtlposition" style="display:none;" >' . date("Y-m-d",time()) . '</span>';
    break;
With that change it appears to work. --James Montalvo (talk) 23:54, 7 May 2013 (CEST)

Multiple Points From One Page[edit]

I am hoping to create a timeline from an existing page that already has dates and descriptions on one page, but it looks like in order to get this to work, I will need to create a separate page for each entry I want to display on the timeline. Is there anyway to make this work?

What happens when you insert a {{#ask: [[{{PAGENAME}}]] |?... |format=timeline |... }} on that very page? Cheers --[[kgh]] 00:31, 14 March 2012 (CET)
Yes that works, but I can't get the dates to line up with the descriptions I have. For example, I have 10 dates and a description for those dates, but I can't put each date/line on a separate point on the timeline. So a line of |?News Date= only displays the most recent date property entered and the only description I have is the page name.
Ouch. I should have thought about this. Now I know the reason why I always use separate pages. I am afraid there is no work-around for this. Still you could write to the mailing list. Perhaps someone has an idea. Cheers --[[kgh]] 15:18, 14 March 2012 (CET)
I think you could use Semantic Internal Objects (SIO) to create grouped data. So for each date/description your SIO would look something like:
{{#set_internal:Time period
|Has start date=2010-01-30
|Has end date=2010-02-12
|Has description=Vacation
}}
--James Montalvo (talk) 23:20, 8 May 2013 (CEST)

timelineband value HOUR[edit]

I successfully use value HOUR in the timelinebands list, but this is not indicated in the help text.--Even Thorbergsen 22:18, 5 July 2012 (CEST)

Heiya Even, you are right, this was not documented. I also successfully tested MINUTE and added it, too. Thank you for noticing this. Cheers --[[kgh]] 01:36, 7 July 2012 (CEST)
With a little modification of the file SRF_Timeline.php in line 281 also centuries and millenia can be displayed:
$params['timelinebands']->addCriteria( new CriterionInArray( 'MILLENNIUM','CENTURY','DECADE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR', 'MINUTE' ) );
--Azchael (talk) 14:41, 30 March 2013 (CET)


Added ability to change event band color[edit]

I've modified SemanticResultFormats/Timeline to allow changing of colors of event duration bands. I modified three files: SRF_Timeline.php, ext.srf.timeline.js and SRF_Messages.php. The full code for each of these is below. Modify the color by including the parameter "durationcolor" in the #ask query, with values like "red", "blue", "#FFCC22", etc. Note, this only affects color on events with a start and end date.

There are still some issues:

  1. I don't like the way it handles the labels, with some labels not fitting inside the bands when they should fit. Some javascript magic in /extensions/SemanticResultFormats/formats/timeline/resources/SimileTimeline/scripts/painters.js around line 246 should do the trick.
  2. This is not working with Semantic Compound Queries, which is why I started this in the first place. I want to be able to say events of one category are red, and events of another category are blue. See the Semantic Compound Queries talk page for a discussion I started over there.

SemanticResultFormats/formats/timeline/SRF_Timeline.php

<?php
/**
 * Print query results in interactive timelines.
 * 
 * @file SRF_Timeline.php
 * @ingroup SemanticResultFormats
 * 
 * @author Markus Krötzsch
 * 
 * FIXME: this code is just insane; rewrite from 0 is probably the only way to get it right
 */

/**
 * Result printer for timeline data.
 * @ingroup SemanticResultFormats
 */
class SRFTimeline extends SMWResultPrinter {

    protected $m_tlstart = '';  // name of the start-date property if any
    protected $m_tlend = '';  // name of the end-date property if any
    protected $m_tlsize = ''; // CSS-compatible size (such as 400px)
    protected $m_tlbands = ''; // array of band IDs (MONTH, YEAR, ...)
    protected $m_tlpos = ''; // position identifier (start, end, today, middle)
    protected $m_tlcolor = ''; // color of events with start and end dates (duration bands)
    
    /**
     * @see SMWResultPrinter::handleParameters
     * 
     * @since 1.6.3
     * 
     * @param array $params
     * @param $outputmode
     */
    protected function handleParameters( array $params, $outputmode ) {
        parent::handleParameters( $params, $outputmode );
        
        $this->m_tlstart = smwfNormalTitleDBKey( $params['timelinestart'] );
        $this->m_tlend = smwfNormalTitleDBKey( $params['timelineend'] );
        $this->m_tlbands = $params['timelinebands'];
        $this->m_tlpos = strtolower( trim( $params['timelineposition'] ) );
        $this->m_tlcolor = strtolower( trim( $params['durationcolor'] ) );
        
            // str_replace makes sure this is only one value, not mutliple CSS fields (prevent CSS attacks)
            // / FIXME: this is either unsafe or redundant, since Timeline is Wiki-compatible. If the JavaScript makes user inputs to CSS then it is bad even if we block this injection path.
        $this->m_tlsize = htmlspecialchars( str_replace( ';', ' ', strtolower( $params['timelinesize'] ) ) );
    }
    
    public function getName() {
        return wfMessage( 'srf_printername_' . $this->mFormat )->text();
    }

    protected function getResultText( SMWQueryResult $res, $outputmode ) {
        global $smwgIQRunningNumber;
        
        $this->includeJS();

        $isEventline = 'eventline' == $this->mFormat;

        if ( !$isEventline && ( $this->m_tlstart == '' ) ) { // seek defaults
            foreach ( $res->getPrintRequests() as $pr ) {
                if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) && ( $pr->getTypeID() == '_dat' ) ) {
                    $dataValue = $pr->getData();
                    
                    $date_value = $dataValue->getDataItem()->getLabel();
                    
                    if ( ( $this->m_tlend == '' ) && ( $this->m_tlstart != '' ) &&
                         ( $this->m_tlstart != $date_value ) ) {
                        $this->m_tlend = $date_value;
                    } elseif ( ( $this->m_tlstart == '' ) && ( $this->m_tlend != $date_value ) ) {
                        $this->m_tlstart = $date_value;
                    }
                }
            }
        }

        // print header
        $link = $res->getQueryLink( wfMessage( 'srf-timeline-allresults' )->inContentLanguage()->text() );
        $result = "<div class=\"smwtimeline\" id=\"smwtimeline$smwgIQRunningNumber\" style=\"height: $this->m_tlsize\">";
        $result .= '<span class="smwtlcomment">'
            . wfMessage( 'srf-timeline-nojs' )->inContentLanguage()->escaped()
            . ' ' . $link->getText( $outputmode, $this->mLinker ) . '</span>'; // note for people without JavaScript

        foreach ( $this->m_tlbands as $band ) {
            $result .= '<span class="smwtlband" style="display:none;">' . htmlspecialchars( $band ) . '</span>';
            // just print any "band" given, the JavaScript will figure out what to make of it
        }


        // print all result rows        
        if ( ( $this->m_tlstart != '' ) || $isEventline ) {
            $result .= $this->getEventsHTML( $res, $outputmode, $isEventline );
        }
        // no further results displayed ...

        // print footer
        $result .= '</div>';
        
        // yes, our code can be viewed as HTML if requested, no more parsing needed
        $this->isHTML = $outputmode == SMW_OUTPUT_HTML;
        
        return $result;
    }    
    
    /**
     * Includes the JavaScript required for the timeline and eventline formats.
     * 
     * @since 1.5.3
     */
    protected function includeJS() {
        SMWOutputs::requireHeadItem( SMW_HEADER_STYLE );

        // MediaWiki 1.17 introduces the Resource Loader.
        $realFunction = array( 'SMWOutputs', 'requireResource' );
        if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) && is_callable( $realFunction ) ) {
            SMWOutputs::requireResource( 'ext.srf.timeline' );
        }
        else {
            global $srfgScriptPath;
            SMWOutputs::requireHeadItem(
                'smw_tlhelper',
                '<script type="text/javascript" src="' . $srfgScriptPath . 
                    '/timeline/resources/ext.srf.timeline.js"></script>'
            );
            SMWOutputs::requireHeadItem(
                'smw_tl',
                '<script type="text/javascript" src="' . $srfgScriptPath . 
                    '/timeline/resources/SimileTimeline/timeline-api.js"></script>'
            );            
        }        
    }
    
    /**
     * Returns the HTML for the events.
     * 
     * @since 1.5.3
     * 
     * @param SMWQueryResult $res
     * @param $outputmode
     * @param boolean $isEventline
     * 
     * @return string
     */
    protected function getEventsHTML( SMWQueryResult $res, $outputmode, $isEventline ) {
        global $curarticle, $cururl; // why not, code flow has reached max insanity already
        
        $positions = array(); // possible positions, collected to select one for centering
        $curcolor = 0; // color cycling is used for eventline        
        
        $result = '';
        
        $output = false; // true if output for the popup was given on current line
        if ( $isEventline ) $events = array(); // array of events that are to be printed
        
        while ( $row = $res->getNext() ) { // Loop over the objcts (pages)
            $hastime = false; // true as soon as some startdate value was found
            $hastitle = false; // true as soon as some label for the event was found
            $curdata = ''; // current *inner* print data (within some event span)
            $curmeta = ''; // current event meta data
            $cururl = '';
            $curarticle = ''; // label of current article, if it was found; needed only for eventline labeling
            $first_col = true;
            
            foreach ( $row as $field ) { // Loop over the returned properties
                $first_value = true;
                $pr = $field->getPrintRequest();
                $dataValue = $pr->getData();
                
                if ( $dataValue == '' ) {
                    $date_value = null;
                }
                else {
                    $date_value = $dataValue->getDataItem()->getLabel();
                }
                
                while ( ( $object = $field->getNextDataValue() ) !== false ) { // Loop over property values
                    $event = $this->handlePropertyValue( 
                        $object, $outputmode, $pr, $first_col, $hastitle, $hastime,
                        $first_value, $isEventline, $curmeta, $curdata, $date_value, $output, $positions
                    );
                    
                    if ( $event !== false ) {
                        $events[] = $event;
                    }
                    
                    $first_value = false;
                }
                
                if ( $output ) {
                    $curdata .= '<br />';
                }
                
                $output = false;
                $first_col = false;
            }

            if ( $hastime ) {
                $result .= Html::rawElement(
                    'span',
                    array( 'class' => 'smwtlevent', 'style' => 'display:none;' ),
                    $curmeta . // data from property values
                    Html::element( // which icon to use for instant events
                        'span',
                        array( 'class' => 'smwtlcoloricon' ),
                        $curcolor
                    ) . 
                    Html::element( // color to use for duration bands (events with start and end date)
                        'span',
                        array( 'class' => 'smwtldurationcolor' ),
                        $this->m_tlcolor
                    ) .
                    $curdata
                );
            }
            
            if ( $isEventline ) {
                foreach ( $events as $event ) {
                    $result .= '<span class="smwtlevent" style="display:none;" ><span class="smwtlstart">' . $event[0] . '</span><span class="smwtlurl">' . str_replace( ' ', '_', $curarticle ) . '</span><span class="smwtlcoloricon">' . $curcolor . '</span>';
                    if ( $curarticle != '' ) $result .= '<span class="smwtlprefix">' . $curarticle . ' </span>';
                    $result .=  $curdata . '</span>';
                    $positions[$event[2]] = $event[0];
                }
                $events = array();
                $curcolor = ( $curcolor + 1 ) % 10;
            }
        }
        
        if ( count( $positions ) > 0 ) {
            ksort( $positions );
            $positions = array_values( $positions );
                        
            switch ( $this->m_tlpos ) {
                case 'start':
                    $result .= '<span class="smwtlposition" style="display:none;" >' . $positions[0] . '</span>';
                    break;
                case 'end':
                    $result .= '<span class="smwtlposition" style="display:none;" >' . $positions[count( $positions ) - 1] . '</span>';
                    break;
                case 'today': 
                    $result .= '<span class="smwtlposition" style="display:none;" >' . date("Y-m-d",time()) . '</span>';
                    break;
                case 'middle': default:
                    $result .= '<span class="smwtlposition" style="display:none;" >' . $positions[ceil( count( $positions ) / 2 ) - 1] . '</span>';
                    break;
            }
        }
        //print_r($result);
        return $result;
    }
    
    /**
     * Hanldes a single property value. Returns an array with data for a single event or false.
     * 
     * FIXME: 13 arguments, of which a whole bunch are byref... not a good design :)
     * 
     * @since 1.5.3
     * 
     * @param SMWDataValue $object
     * @param $outputmode
     * @param SMWPrintRequest $pr
     * @param boolean $first_col
     * @param boolean &$hastitle
     * @param boolean &$hastime
     * @param boolean $first_value
     * @param boolean $isEventline
     * @param string &$curmeta
     * @param string &$curdata
     * @param &$date_value
     * @param boolean &$output
     * @param array &$positions
     * 
     * @return false or array
     */
    protected function handlePropertyValue( SMWDataValue $object, $outputmode, SMWPrintRequest $pr, $first_col, 
        &$hastitle, &$hastime, $first_value, $isEventline, &$curmeta, &$curdata, $date_value, &$output, array &$positions ) {
            global $curarticle, $cururl;
        
        $event = false;
        
        $l = $this->getLinker( $first_col );
        
        if ( !$hastitle && $object->getTypeID() != '_wpg' ) { // "linking" non-pages in title positions confuses timeline scripts, don't try this
            $l = null;
        }
        
        if ( $object->getTypeID() == '_wpg' ) { // use shorter "LongText" for wikipage
            $objectlabel = $object->getLongText( $outputmode, $l );
        } else {
            $objectlabel = $object->getShortText( $outputmode, $l );
        }
        
        $urlobject =  ( $l !== null );
        $header = '';
        
        if ( $first_value ) {
            // find header for current value:
            if ( $this->mShowHeaders && ( '' != $pr->getLabel() ) ) {
                $header = $pr->getText( $outputmode, $this->mLinker ) . ': ';
            }
            
            // is this a start date?
            if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) &&
                 ( $date_value == $this->m_tlstart ) ) {
                // FIXME: Timeline scripts should support XSD format explicitly. They
                // currently seem to implement iso8601 which deviates from XSD in cases.
                // NOTE: We can assume $object to be an SMWDataValue in this case.
                $curmeta .= Html::element(
                    'span',
                    array( 'class' => 'smwtlstart' ),
                    $object->getXMLSchemaDate()
                );
                $positions[$object->getHash()] = $object->getXMLSchemaDate();
                $hastime = true;
            }
            
            // is this the end date?
            if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) &&
                 ( $date_value == $this->m_tlend ) ) {
                // NOTE: We can assume $object to be an SMWDataValue in this case.
                $curmeta .= Html::element(
                    'span',
                    array( 'class' => 'smwtlend' ),
                    $object->getXMLSchemaDate( false )
                );
            }
            
            // find title for displaying event
            if ( !$hastitle ) {
                $curmeta .= Html::element(
                    'span',
                    array(
                        'class' => $urlobject ? 'smwtlurl' : 'smwtltitle'
                    ),
                    $objectlabel
                );

                if ( $pr->getMode() == SMWPrintRequest::PRINT_THIS ) {
                    $curarticle = $object->getShortText( $outputmode, false );
                    $cururl = $object->getTitle()->getFullUrl();
                }
                
                // NOTE: type Title of $object implied
                $hastitle = true;
            }
        } elseif ( $output ) {
            // it *can* happen that output is false here, if the subject was not printed (fixed subject query) and mutliple items appear in the first row
            $curdata .= ', '; 
        }
        
        if ( !$first_col || !$first_value || $isEventline ) {
            $curdata .= $header . $objectlabel;
            $output = true;
        }
        
        if ( $isEventline && ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) && ( $pr->getTypeID() == '_dat' ) && ( '' != $pr->getLabel() ) && ( $date_value != $this->m_tlstart ) && ( $date_value != $this->m_tlend ) ) {
            $event = array(
                $object->getXMLSchemaDate(),
                $pr->getLabel(),
                $object->getDataItem()->getSortKey(),
            );
        }
    
        return $event;
    }


    /**
     * @see SMWResultPrinter::getParamDefinitions
     *
     * @since 1.8
     *
     * @param $definitions array of IParamDefinition
     *
     * @return array of IParamDefinition|array
     */
    public function getParamDefinitions( array $definitions ) {
        $params = parent::getParamDefinitions( $definitions );

        $params['timelinesize'] = array(
            'default' => '300px',
            'message' => 'srf_paramdesc_timelinesize',
        );

        $params['timelineposition'] = array(
            'default' => 'middle',
            'message' => 'srf_paramdesc_timelineposition',
            'values' => array( 'start', 'middle', 'end', 'today' ),
        );

        $params['timelinestart'] = array(
            'default' => '',
            'message' => 'srf_paramdesc_timelinestart',
        );

        $params['timelineend'] = array(
            'default' => '',
            'message' => 'srf_paramdesc_timelineend',
        );

        $params['timelinebands'] = array(
            'islist' => true,
            'default' => array( 'MONTH', 'YEAR' ),
            'message' => 'srf_paramdesc_timelinebands',
            'values' => array( 'DECADE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR', 'MINUTE' ),
        );

        $params['durationcolor'] = array(
            'default' => 'red',
            'message' => 'srf_paramdesc_durationcolor'
        );
        
         return $params;
    }
    
}

New code for SemanticResultFormats/formats/timeline/resources/ext.srf.timeline.js

/**
 * A script for scraping Simile Timeline suitable data from HTML, and
 * for inserting the required Simile scripts if needed.
 */

var smwtl;

addOnloadHook(smw_timeline_init);

function smw_timeline_init() {
    if (!document.getElementsByName) return;
    tbls = document.getElementsByTagName("div");

    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];
        if (((' '+thisTbl.className+' ').indexOf("smwtimeline") != -1) && (thisTbl.id)) {
            smw_make_timeline(thisTbl);
        }
    }
}

function smw_make_timeline(div) {
    // extract relevant event data:
    var eventSource = new Timeline.DefaultEventSource();

    var theme = Timeline.ClassicTheme.create();
    // make some elements opaque to unify look across platforms
    // Timelines way of setting transparency fails on some browsers (some IE6s, Konquerors)
    // Also, we use "imprecise instants" to display durations, since Timeline fails if
    // only durations are used and multiple bands appear. See below.
    theme.ether.highlightColor = "#E7E7E7";
    theme.ether.highlightOpacity = 100;
    theme.event.instant.impreciseOpacity = 100;
    //theme.event.instant.icon = Timeline.urlPrefix + "images/blue-circle.png";
    //theme.ether.interval.line.opacity = 100;
    //theme.ether.interval.weekend.opacity = 100;
    //theme.ether.interval.weekend.color = "#FFFFE0";

    var childs = div.childNodes;
    var l = childs.length;
    var bands = [];
    var bandcount = 0;
    var position = new Date(); //fallback position: today;
    for (var i = 0; i < childs.length; div.removeChild(childs[0])) {
        switch (childs[i].nodeType) {
            case 1: //ELEMENT_NODE -- an event or some general data
                if (childs[i].className == "smwtlevent")
                    smw_add_event(childs[i],eventSource);
                else if (childs[i].className == "smwtlband") {
                    switch (childs[i].firstChild.data) {
                        case "MILLISECOND": bands[bandcount] = Timeline.DateTime.MILLISECOND; break;
                        case "SECOND": bands[bandcount] = Timeline.DateTime.SECOND; break;
                        case "MINUTE": bands[bandcount] = Timeline.DateTime.MINUTE; break;
                        case "HOUR": bands[bandcount] = Timeline.DateTime.HOUR; break;
                        case "DAY": bands[bandcount] = Timeline.DateTime.DAY; break;
                        case "WEEK": bands[bandcount] = Timeline.DateTime.WEEK; break;
                        case "MONTH": bands[bandcount] = Timeline.DateTime.MONTH; break;
                        case "YEAR": bands[bandcount] = Timeline.DateTime.YEAR; break;
                        case "DECADE": bands[bandcount] = Timeline.DateTime.DECADE; break;
                        case "CENTURY": bands[bandcount] = Timeline.DateTime.CENTURY; break;
                        case "MILLENNIUM": bands[bandcount] = Timeline.DateTime.MILLENNIUM; break;
                        default: bandcount--; //dont count unrecognized bands
                    }
                    bandcount++;
                } else if (childs[0].className == "smwtlposition") {
                    position = Timeline.DateTime.parseIso8601DateTime(childs[i].firstChild.data);
                } /*else if (childs[i].className == "smwtlsize") {
                    div.setAttribute("style","height: " + childs[i].firstChild.data + ";");
                }*/
                break;
            case 3:    //TEXT_NODE -- ignore text on this level
                break;
        }

    }

    // create bands
    var bandInfos = [];
    var bandinfo;
    for (var i = 0; i < bandcount; i++) {
        if (i == 0) {
            bandinfo = Timeline.createBandInfo({
                eventSource:    eventSource,
                width:          smw_get_bandwidth(i,bandcount),
                intervalUnit:   bands[i],
                intervalPixels: 100,
                date:           position,
                theme:          theme
            })
        } else {
            bandinfo = Timeline.createBandInfo({
                showEventText:  false,
                trackHeight:    0.5,
                trackGap:       0.2,
                eventSource:    eventSource,
                width:          smw_get_bandwidth(i,bandcount),
                intervalUnit:   bands[i],
                intervalPixels: 100,
                date:           position,
                theme:          theme
            })
            bandinfo.syncWith = 0;
            bandinfo.highlight = true;
        }
        bandInfos[i] = bandinfo;
    }

    // default band
    if (bandcount == 0) {
        bandInfos[0] = Timeline.createBandInfo({
            eventSource:    eventSource,
            width:          "100%",
            intervalUnit:   Timeline.DateTime.MONTH,
            intervalPixels: 100,
            theme:          theme
        })
    }

    smwtl = Timeline.create(div, bandInfos);
}

function smw_get_bandwidth(number,count) {
    switch (count) {
        case 1: if (number == 0) return "100%"; else return "0%";
        case 2:
            switch (number) {
                case 0: return "70%";
                case 1: return "30%";
                default: return "0%";
            }
        case 3:
            switch (number) {
                case 0: return "60%";
                case 1: return "25%";
                case 2: return "15%";
                default: return "0%";
            }
        default: // dont support more than 4 bands
            switch (number) {
                case 0: return "50%";
                case 1: return "25%";
                case 2: return "15%";
                case 3: return "10%";
                default: return "0%";
            }
    }
}

function smw_add_event(evspan,evs) {
    var startdate = null;
    var enddate = null;
    var desc = "";
    var ttl = "";
    var linkurl = "";
    var prefix = "";
    var postfix = "";
    var color = "";
    var icon = Timeline.urlPrefix + "images/dull-blue-circle.png";

    var childs = evspan.childNodes;
    for (var i = 0; i < childs.length; /* manual increment below */ ) {
        if (childs[i].nodeType == 1) { //ELEMENT_NODE -- some data element
            switch (childs[i].className) {
                case "smwtlstart":
                    if (childs[i].firstChild.nodeType == 3)
                        startdate = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                case "smwtlend":
                    if (childs[i].firstChild.nodeType == 3)
                        enddate = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                case "smwtltitle":
                    if (childs[i].firstChild.nodeType == 3)
                        ttl = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                case "smwtlprefix":
                    if (childs[i].firstChild.nodeType == 3)
                        prefix = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                case "smwtlpostfix":
                    if (childs[i].firstChild.nodeType == 3)
                        postfix = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                case "smwtlurl": // accept both plain text and anchor, use text of anchor for title
                    if (childs[i].firstChild.nodeType == 3)
                        linkurl = childs[i].firstChild.data;
                    else {
                        linkurl = childs[i].firstChild.getAttribute("href");
                        if (childs[i].firstChild.hasChildNodes())
                            ttl = childs[i].firstChild.firstChild.data;
                    }
                    evspan.removeChild(childs[i]);
                break;
                case "smwtlcoloricon":
                    if (childs[i].firstChild.nodeType == 3) {
                        switch ( childs[i].firstChild.data ) {
                            case "0": icon =Timeline.urlPrefix + "images/dull-blue-circle.png";
                            break;
                            case "1": icon =Timeline.urlPrefix + "images/dull-red-circle.png";
                            break;
                            case "2": icon =Timeline.urlPrefix + "images/dull-green-circle.png";
                            break;
                            case "3": icon =Timeline.urlPrefix + "images/gray-circle.png";
                            break;
                            case "4": icon =Timeline.urlPrefix + "images/dark-blue-circle.png";
                            break;
                            case "5": icon =Timeline.urlPrefix + "images/dark-red-circle.png";
                            break;
                            case "6": icon =Timeline.urlPrefix + "images/dark-green-circle.png";
                            break;
                            case "7": icon =Timeline.urlPrefix + "images/blue-circle.png";
                            break;
                            case "8": icon =Timeline.urlPrefix + "images/red-circle.png";
                            break;
                            case "9": icon =Timeline.urlPrefix + "images/green-circle.png";
                            break;
                        }
                    }
                    evspan.removeChild(childs[i]);
                break;
                case "smwtldurationcolor":
                    if (childs[i].firstChild.nodeType == 3)
                        color = childs[i].firstChild.data;
                    evspan.removeChild(childs[i]);
                break;
                 default: //proceed
                    i++;
            }
        }  else i++; //proceed
    }
    desc = evspan.innerHTML; // the remaining nodes form the description of the event

    var parseDateTimeFunction = evs._events.getUnit().getParser("iso8601");
    var evt = new Timeline.DefaultEventSource.Event(
        parseDateTimeFunction(startdate),
        parseDateTimeFunction(enddate),
        parseDateTimeFunction(enddate ? startdate : null),
        parseDateTimeFunction(enddate ? enddate : null),
        false, // was true ( enddate == null ), // FIXME: timeline currently fails if there are only durations and mutliple bands
        prefix + ttl + postfix,
        desc,
        "", //no image
        linkurl,
        icon,
        color, //"#CC2200", //color
        ""  //text color #99FF44
    );
// TODO: must the following have a meaningful definition?
//             evt.getProperty = function(name) {
//                 return "";
//             };
    evs._events.add(evt);
}

//FIXME: Not used at the moment. Is this needed?
//addEvent(window, "resize", onResize);

// var resizeTimerID = null;
// function onResize() {
//     if (resizeTimerID == null) {
//         resizeTimerID = window.setTimeout(function() {
//             resizeTimerID = null;
//             smwtl.layout();
//         }, 500);
//     }
// }

In SemanticResultFormats/SRF_Messages.php add the following at line 100:

'srf_paramdesc_durationcolor' => 'The color of events with a start and end date',

--James Montalvo (talk) 00:40, 9 May 2013 (CEST)

There are no threads on this page yet.