internal void Add(FlameBox flameBox) { var row = new Range(flameBox.Y, flameBox.Y + flameBox.Height); if (!boxesMap.TryGetValue(row, out var list)) { boxesMap.Add(row, list = new List <FlameBox>()); } list.Add(flameBox); }
public static IEnumerable <FlameBox> Calculate(CallTree callTree, double maxWidth, double maxHeight) { double maxDepth = GetMaxDepth(callTree.Root); double boxHeight = maxHeight / maxDepth; double pixelsPerIncusiveSample = maxWidth / callTree.Root.InclusiveMetric; var rootBox = new FlameBox(callTree.Root, maxWidth, boxHeight, 0, maxHeight - boxHeight); yield return(rootBox); var nodesToVisit = new Queue <FlamePair>(); nodesToVisit.Enqueue(new FlamePair(rootBox, callTree.Root)); while (nodesToVisit.Count > 0) { var current = nodesToVisit.Dequeue(); var parentBox = current.ParentBox; var currentNode = current.Node; double nextBoxX = (parentBox.Width - (currentNode.Callees.Sum(child => child.InclusiveMetric) * pixelsPerIncusiveSample)) / 2.0; // centering the starting point foreach (var child in currentNode.Callees) { double childBoxWidth = child.InclusiveMetric * pixelsPerIncusiveSample; var childBox = new FlameBox(child, childBoxWidth, boxHeight, parentBox.X + nextBoxX, parentBox.Y - boxHeight); nextBoxX += childBoxWidth; if (child.Callees != null) { nodesToVisit.Enqueue(new FlamePair(childBox, child)); } yield return(childBox); } } }
private static FrameworkElement CreateRectangle(FlameBox box, int index) { var tooltip = $"Method: {box.Node.DisplayName} ({box.Node.InclusiveCount} inclusive samples, {box.Node.InclusiveMetricPercent:F}%)"; var background = Brushes[++index % Brushes.Length]; // in the future, the color could be chosen according to the belonging of the method (JIT, GC, user code, OS etc) // for small boxes we create Rectangles, because they are much faster (too many TextBlocks === bad perf) // also for small rectangles it's impossible to read the name of the method anyway (only few characters are printed) if (box.Width < 50) { return new Rectangle { Height = box.Height, Width = box.Width, Fill = background, ToolTip = new ToolTip { Content = tooltip }, DataContext = box.Node } } ; return(new TextBlock { Height = box.Height, Width = box.Width, Background = background, ToolTip = new ToolTip { Content = tooltip }, Text = box.Node.DisplayName, DataContext = box.Node, FontFamily = FontFamily, FontSize = Math.Min(20.0, box.Height) }); } }
private static int CompareByX(FlameBox left, FlameBox right) => left.X.CompareTo(right.X);
public FlamePair(FlameBox parentBox, CallTreeNode node) { ParentBox = parentBox; Node = node; }