private Panel CreatePanelForLane()

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;
        }