in src/StructuredLogViewer/Controls/TimelineControl.xaml.cs [145:296]
private Panel CreatePanelForLane(Lane lane, double start)
{
var blocks = lane.Blocks.ToList();
if (blocks.Count == 0)
{
return null;
}
var canvas = new Canvas();
canvas.VerticalAlignment = VerticalAlignment.Top;
var endpoints = new List<BlockEndpoint>();
foreach (var block in blocks)
{
block.StartPoint = new BlockEndpoint()
{
Block = block,
Timestamp = block.StartTime.Ticks,
IsStart = true
};
block.EndPoint = new BlockEndpoint()
{
Block = block,
Timestamp = block.EndTime.Ticks
};
endpoints.Add(block.StartPoint);
endpoints.Add(block.EndPoint);
}
endpoints.Sort();
int level = 0;
foreach (var endpoint in endpoints)
{
if (endpoint.IsStart)
{
level++;
endpoint.Block.Indent = level;
}
else
{
level--;
}
}
blocks.Sort((l, r) =>
{
var startDifference = l.StartTime.Ticks.CompareTo(r.StartTime.Ticks);
if (startDifference != 0)
{
return startDifference;
}
return l.Length.CompareTo(r.Length);
});
DateTime minDateTime = blocks[0].StartTime;
DateTime maxDateTime = blocks[blocks.Count - 1].StartTime;
foreach (var block in blocks)
{
block.Start = block.StartTime.Ticks;
block.End = block.EndTime.Ticks;
}
double end = maxDateTime.Ticks;
double totalDuration = end - start;
if (totalDuration == 0)
{
totalDuration = 1;
}
double width = 0;
var sample = new TextBlock();
sample.Text = "W";
sample.Measure(new Size(10000, 10000));
var textHeight = sample.DesiredSize.Height;
double preferredTotalHeight = textHeight * blocks.Count(b => b.Length > totalDuration / 2000);
double currentHeight = 0;
double totalHeight = 0;
foreach (var block in blocks)
{
//if (block.Length > minimumDurationToInclude)
{
var content = new ContentControl();
var textBlock = new TextBlock();
textBlock.Text = $"{block.Text} ({TextUtilities.DisplayDuration(block.Duration)})";
textBlock.Background = ChooseBackground(block);
double left = 24 * block.Indent;
double top = (block.Start - start) / totalDuration * preferredTotalHeight;
double height = (block.End - block.Start) / totalDuration * preferredTotalHeight;
if (height < textHeight)
{
height = textHeight;
continue;
}
textBlock.Measure(new Size(10000, 10000));
double currentTotalWidth = left + textBlock.DesiredSize.Width;
if (currentTotalWidth > width)
{
width = currentTotalWidth;
}
double minimumTop = currentHeight;
if (minimumTop > top)
{
double adjustment = minimumTop - top;
if (height > adjustment + textHeight)
{
height = height - adjustment;
top = minimumTop;
}
else
{
continue;
}
}
textBlock.Height = height;
textBlock.ToolTip = block.GetTooltip();
textBlock.MouseUp += TextBlock_MouseUp;
textBlock.Tag = block;
TextBlocks.Add(block.Node, textBlock);
currentHeight = top + textHeight;
if (totalHeight < top + height)
{
totalHeight = top + height;
}
Canvas.SetLeft(content, left);
Canvas.SetTop(content, top);
content.Content = textBlock;
content.MouseDoubleClick += Content_MouseDoubleClick;
canvas.Children.Add(content);
}
}
canvas.Height = totalHeight;
canvas.Width = width;
return canvas;
}