Hello,
I have a xamTimeline which is displaying a series of entries with a start date and a duration. Often, the duration will extend over the start date, and the two areas of the timeline will overlap. How do I stack the overlapping timelines?
I figured this one out on my own, but it required some seriously hacky code to fix. I ended up having to generate a ControlTemplate at runtime, which forced me to modify part of a string literal and feed it into XamlReader.Load. You guys should seriously spend some intense effort to make this happen automatically.
Here's the code for future reference:
List<DateTimeSeries> seriesList = new List<DateTimeSeries>();
seriesList.Add(new DateTimeSeries());
seriesList[0].EventSpanStyle = this.Resources["EventSpanStyle"] as Style;
seriesList[0].Stroke = new SolidColorBrush(seriesColor);
int currentMargin = 0;
foreach (ItemType item in ItemsToIterate)
{
DateTimeEntry dateEntry = new DateTimeEntry();
dateEntry.Time = ***; // obfuscated values
dateEntry.Duration = ***;
dateEntry.Title = ***;
dateEntry.Details = ***;
// Locate a series to add it to
int indexToAdd = -1;
for (int i = 0; i < seriesList.Count; i++)
bool hasOverlap = false;
foreach (DateTimeEntry entry in seriesList[i].Entries)
if ((entry.Time <= dateEntry.Time && entry.Time + entry.Duration >= dateEntry.Time) ||
(entry.Time <= dateEntry.Time + dateEntry.Duration &&
entry.Time + entry.Duration >= dateEntry.Time + dateEntry.Duration)) // Check overlap
hasOverlap = true;
break;
}
if (!hasOverlap)
indexToAdd = i;
if (indexToAdd != -1)
seriesList[indexToAdd].Entries.Add(dateEntry);
else
// Add a new series
currentMargin += 10;
Style newStyle = new Style(typeof(EventSpan))
BasedOn = this.Resources["EventSpanStyle"] as Style,
};
ControlTemplate template = (ControlTemplate)XamlReader.Load("<ControlTemplate xmlns:ig=\"http://schemas.infragistics.com/xaml\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" TargetType=\"ig:EventSpan\"><Grid Margin=\"0,2,0,2\"><Rectangle Margin=\"0 " + currentMargin.ToString() + " 0 0\" RadiusX=\"5\" RadiusY=\"5\" Fill=\"{TemplateBinding Fill}\" Height=\"10\" VerticalAlignment=\"Top\" /></Grid></ControlTemplate>");
newStyle.Setters.Add(new Setter()
Property = EventSpan.TemplateProperty,
Value = template,
});
seriesList[seriesList.Count - 1].EventSpanStyle = newStyle;
seriesList[seriesList.Count - 1].Stroke = new SolidColorBrush(seriesColor);
seriesList[seriesList.Count - 1].Entries.Add(dateEntry);
if (dateEntry.Time < minValue)
minValue = dateEntry.Time;
if (dateEntry.Time + dateEntry.Duration > maxValue)
maxValue = dateEntry.Time + dateEntry.Duration;
foreach (DateTimeSeries series in seriesList)
timeline.Series.Add(series);
return;