Vertical Position of the RadTimeline Items

By default, RadTimeline positions its items first by their StartDate and then by their Duration, placing them in rows starting close to the control‘s timeline and moving away from it with every row. If an item, for example, starts earlier in time, it will be positioned closer to the control’s timeline. For items that start on the same date, items with smaller duration will be positioned closer to the control’s timeline. The control places an item on the next row, in case the span of this item overlaps with the span of an already positioned item.

While for most cases, this positioning logic is adequate, there are scenarios when you would like to apply your own custom logic for the vertical positioning of the timeline items. There are three approaches that you can use to change the default vertical positioning.

  • The first approach is to specify a larger minimum gap between items. This value is taken into account when calculating whether the span of an item overlaps the span of an already positioned item.

  • The second approach is to simply turn off the ordering by StartDate and Duration.

  • The third approach includes specifying your own custom vertical positioning logic.

Using the MinimumItemGap property

The first item in the ItemsSource of the RadTimeline control – that is, the one that starts earliest in time and has the smallest duration out of the items that start at this time, is placed in the first row. In case the span of the second item overlaps the span of the first item then the second item is placed in the second row. By default, two timeline items overlap in case the difference between the end date of the first and the start date of the second is less than TimeSpan.FromTicks(1).

You can change this default value of TimeSpan.FromTicks(1) in order to influence the vertical ordering of timeline items using the MinimumItemGap property. Have a look at the different result that the control produces with the default value of the MinimumItemGap property (TimeSpan.FromTicks(1)) and a custom value of TimeSpan.FromDays(8) with the following ItemsSource:

  1. Item 0: StartDate = new DateTime(2011, 1, 1), Duration = TimeSpan.FromDays(16)

  2. Item 1: StartDate = new DateTime(2011, 1, 24), Duration = TimeSpan.FromDays(20)

 <telerik:RadTimeline PeriodStart="2011-01-01" 
                        PeriodEnd="2012-01-01" 
                        StartPath="Date" 
                        DurationPath="Time" 
                        ItemsSource="{Binding Items}" 
                        MinimumItemGap="7:00:00:00"> 
    <telerik:RadTimeline.Intervals> 
        <telerik:DayInterval /> 
        <telerik:WeekInterval /> 
        <telerik:MonthInterval /> 
        <telerik:YearInterval /> 
    </telerik:RadTimeline.Intervals> 
</telerik:RadTimeline> 
radtimeline-howto-control-vertical-position-of-timeline-items 01

Using the AutoSort proprety

You can switch on/off the default ordering by StartDate and Duration by using the Boolean AutoSort property of RadTimeline. Its default value is “True”. By setting this property to “False”, you influence the vertical positioning in the following manner:

The first item in the ItemsSource of the RadTimeline control is placed in the first row. In case the span of the second item overlaps the span of the first item then the second item is placed in the second row.

The code sample below demonstrates how you can set the AutoSort property of a RadTimeline control:

  <telerik:RadTimeline PeriodStart="2011-01-01" 
                        PeriodEnd="2012-01-01" 
                        AutoSort="False" 
                        StartPath="Date" 
                        DurationPath="Time" 
                        ItemsSource="{Binding Items}"> 
    <telerik:RadTimeline.Intervals> 
        <telerik:DayInterval /> 
        <telerik:WeekInterval /> 
        <telerik:MonthInterval /> 
        <telerik:YearInterval /> 
    </telerik:RadTimeline.Intervals> 
</telerik:RadTimeline> 
You can check the difference in the result with AutoSort set to True/False with the following ItemsSource:
  1. Item 0: StartDate = new DateTime(2011, 2, 15), Duration = TimeSpan.FromDays(40)

  2. Item 1: StartDate = new DateTime(2011, 1, 1), Duration = TimeSpan.FromDays(55)

  3. Item 2: StartDate = new DateTime(2011, 2, 1), Duration = TimeSpan.FromDays(20)

radtimeline-howto-control-vertical-position-of-timeline-items 02

Using Item RowIndex Generators

Using the ItemRowIndexGenerator property of the RadTimeline control you can specify a custom IItemRowIndexGenerator instance that determines the RowIndex of every timeline item.

The example below shows how you can specify a custom item RowIndex generator for a RadTimeline control:

 <telerik:RadTimeline PeriodStart="2011-01-01" 
                     PeriodEnd="2012-01-01" 
                     StartPath="Date" 
                     DurationPath="Time" 
                     ItemsSource="{Binding Items}"> 
    <telerik:RadTimeline.ItemRowIndexGenerator> 
        <example:NewLineRowIndexGenerator /> 
    </telerik:RadTimeline.ItemRowIndexGenerator> 
    <telerik:RadTimeline.Intervals> 
        <telerik:DayInterval /> 
        <telerik:WeekInterval /> 
        <telerik:MonthInterval /> 
        <telerik:YearInterval /> 
    </telerik:RadTimeline.Intervals> 
</telerik:RadTimeline> 

The IItemRowIndexGenerator interface

An item RowIndex generator is a class that implements the IItemRowIndexGenerator interface. This interface has one method that needs to be implemented - GenerateRowIndexes. This method accepts a list of TimelineRowItem instances as argument. Every TimelineRowItem is basically a wrapper for the item and its RowIndex as calculated by the RadTimeline control itself. You can change the automatically calculated RowIndex of an item, by specifying a custom TimelineRowItem.RowIndex value for the appropriate TimelineRowItem instance. You can use the TimelineRowItem.DataItem property to identify the items that you want to position manually.

Below you can find an implementation of a sample generator that positions every item in a new row:

    using System.Collections.Generic; 
    using Telerik.Windows.Controls.Timeline; 
 
    public class TimelineData 
    { 
        public DateTime Date { get; set; } 
        public TimeSpan Time { get; set; } 
        public int RowIndex { get; set; } 
    } 
 
    public class NewLineRowIndexGenerator : IItemRowIndexGenerator 
    { 
        public void GenerateRowIndexes(List<TimelineRowItem> dataItems) 
        { 
            foreach (TimelineRowItem item in dataItems) 
            { 
                item.RowIndex = (item.DataItem as TimelineData).RowIndex; 
            } 
        } 
    } 
    Public Class TimelineData 
        Public Property Date As DateTime 
            Get 
                Return m_Date 
            End Get 
            Set 
                m_Date = Value 
            End Set 
        End Property 
        Private m_Date As DateTime 
        Public Property Time() As TimeSpan 
            Get 
                Return m_Time 
            End Get 
            Set 
                m_Time = Value 
            End Set 
        End Property 
        Private m_Time As TimeSpan 
        Public Property RowIndex() As Integer 
            Get 
                Return m_RowIndex 
            End Get 
            Set 
                m_RowIndex = Value 
            End Set 
        End Property 
        Private m_RowIndex As Integer 
    End Class 
 
    Public Class NewLineRowIndexGenerator 
        Implements IItemRowIndexGenerator 
        Public Sub GenerateRowIndexes(dataItems As List(Of TimelineRowItem)) 
            For Each item As TimelineRowItem In dataItems 
                item.RowIndex = TryCast(item.DataItem, TimelineData).RowIndex 
            Next 
        End Sub 
    End Class 

Using the item RowIndex generator above, you will get the following result:

radtimeline-howto-control-vertical-position-of-timeline-items 03

In this article