New to Telerik UI for WinFormsStart a free 30-day trial

Custom Timeline

Updated over 6 months ago

RadGanttView offers a number of built-in TimeRange settings which allow users to display the timeline in different views. Although these settings would cover most cases the users might require a view that is not available out-of-the-box. In this case developers can build their own timeline views. This article demonstrates the process for creating a custom timeline view which displays items in decades (10-year time spans). The following image demonstrates the final goal:

WinForms RadGanttView Custom Timeline

1. First you need to set the TimelineRange property of the gantt view graphical element to Custom. If you want you can override and modify the default views as well but for this example we will use the custom value.

C#
this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineRange = TimeRange.Custom;

2. Next you need to create a custom timeline behavior class and assign it to the graphical view. In this class you will add the logic for the new decades view.

C#
this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineBehavior = new DecadesGanttViewTimelineBehavior();

3. Now you can fill the class with the code that will create the view. You should note that because we want to preserve the built-in views throughout the example we will check whether the time range is Custom and only handle this case.

  • First you have to override the AdjustedTimelineStart and AdjustedTimelineEnd properties. What these properties do is to enlarge the timeline start and end to allow only whole timeline cells to be displayed. Here is an example. Imagine you use a view with quarters and your TimelineStart property is set to 15.05.2013. This date is somewhere in the middle of the year’s second quarter. The AdjustedTimelineStart property takes this date and the fact you use quarters and returns an adjusted date which is the actual start of the quarter. In this particular case the property will return 03.04.2013 which is the start date of the quarter that contains the TimelineStart date. The AdjustedTimelineEnd property does the same for the end of the timeline. For the decades view this properties will adjust the start and end dates to years:
C#
public override DateTime AdjustedTimelineStart
{
    get
    {
        if (this.GraphicalViewElement.TimelineRange != TimeRange.Custom)
        {
            return base.AdjustedTimelineStart;
        }
        return new DateTime(this.GraphicalViewElement.TimelineStart.Year, 1, 1);
    }
}
public override DateTime AdjustedTimelineEnd
{
    get
    {
        if (this.GraphicalViewElement.TimelineRange != TimeRange.Custom)
        {
            return base.AdjustedTimelineEnd;
        }
        return new DateTime(this.GraphicalViewElement.TimelineEnd.Year + 1, 1, 1);
    }
}
  • Next you should override the BuildTimelineDataItems method. The method returns a list of GanttViewTimelineDataItems. Each data item will represent a decade.
C#
public override IList<GanttViewTimelineDataItem> BuildTimelineDataItems(TimeRange range)
{
    if (range != TimeRange.Custom)
    {
        return base.BuildTimelineDataItems(range);
    }
    return this.BuildTimelineDataItemsForDecadesRange();
}
public IList<GanttViewTimelineDataItem> BuildTimelineDataItemsForDecadesRange()
{
    List<GanttViewTimelineDataItem> result = new List<GanttViewTimelineDataItem>();
    DateTime adjustedStart = this.AdjustedTimelineStart;
    DateTime adjustedEnd = this.AdjustedTimelineEnd;
    DateTime currentDate = adjustedStart.Date;
    int currentYearNumber = currentDate.Year;
    int newYearNumber = currentYearNumber;
    GanttViewTimelineDataItem item = new GanttViewTimelineDataItem(currentDate.Date, currentDate.AddYears(1), this.GraphicalViewElement.TimelineRange, this.GraphicalViewElement.OnePixelTime);
    result.Add(item);
    while (currentDate < adjustedEnd)
    {
        item.End = currentDate.AddYears(1);
        currentDate = currentDate.AddYears(1);
        newYearNumber = currentDate.Year;
        if (newYearNumber != currentYearNumber && newYearNumber % 10 == 0 && currentDate <= adjustedEnd)
        {
            currentYearNumber = newYearNumber;
            item = new GanttViewTimelineDataItem(currentDate, currentDate, this.GraphicalViewElement.TimelineRange, this.GraphicalViewElement.OnePixelTime);
            result.Add(item);
        }
    }
    return result;
}
  • Next we have to calculate the timeline cells for each timeline data item. To this we override the GetTimelineCellInfoForItem method. The method returns an instance of the GanttTimelineCellsInfo struct. This struct contains two properties. The first one, NumberOfcells, indicates how many cells the given timeline data item will display. The second one, StartIndex, is useful in the case where you use repeatable cell items e.g. quarters, halves, thirds etc. The property is useful when the start of the timeline is not the first item in the repeatable values collection. Here is an example. Imagine the timeline starts is the third quarter of the year with this property you will later be able to set the proper text to the cell item. If you do not have this info your cells will always start at 0 or 1. Since in this example the start is the third quarter starting at 0 or 1 would be wrong. In our example we have continuous data so we will not use this property:
C#
public override GanttTimelineCellsInfo GetTimelineCellInfoForItem(GanttViewTimelineDataItem item, TimeRange timeRange)
{
    if (timeRange != TimeRange.Custom)
    {
        return base.GetTimelineCellInfoForItem(item, timeRange);
    }
    return this.GetTimelineCellInfoForDecadeRange(item);
}
public GanttTimelineCellsInfo GetTimelineCellInfoForDecadeRange(GanttViewTimelineDataItem item)
{
    int years = 10;
    if (item.Start == this.AdjustedTimelineStart)
    {
        if (item.Start.Year % 10 > 0)
        {
            years = 10 - (item.Start.Year % 10);
        }
    }
    if (item.End == this.AdjustedTimelineEnd)
    {
        if (item.End.Year % 10 > 0)
        {
            years = item.End.Year % 10;
        }
    }
    return new GanttTimelineCellsInfo(years);
}
  • Finally we want to have a proper text inside our decade timeline items. For this purpose we override the GetTimelineTopElementText and GetTimelineBottomElementText methods.
C#
public override string GetTimelineTopElementText(GanttViewTimelineDataItem item)
{
    if (item.Range != TimeRange.Custom)
    {
        return base.GetTimelineTopElementText(item);
    }
    string format = "{0:yyyy} - {1:yyyy}";
    return string.Format(System.Threading.Thread.CurrentThread.CurrentUICulture, format, item.Start, item.End.AddYears(-1));
}
public override string GetTimelineBottomElementText(GanttViewTimelineDataItem item, int index)
{
    if (item.Range != TimeRange.Custom)
    {
        return base.GetTimelineBottomElementText(item, index);
    }
    string format = "{0:yyyy}";
    return string.Format(System.Threading.Thread.CurrentThread.CurrentCulture, format, new DateTime(item.Start.Year + index, 1, 1));
}

See Also

In this article
See Also
Not finding the help you need?
Contact Support