public static string GetTextReport(IEnumerable <Counter> reportCounters, ReportOptions options = ReportOptions.LastValue) { // Group Counters by Type Dictionary <Type, List <Counter> > countersByType = new Dictionary <Type, List <Counter> >(); Type[] existingTypes = reportCounters.Select(c => c.GetType()).Distinct().ToArray(); foreach (Type type in existingTypes) { countersByType[type] = reportCounters.Where(c => c.GetType() == type).ToList(); } // Prepare text building StringBuilder reportBuilder = new StringBuilder(countersByType.Count * 256); // Handle each group separately foreach (var pair in countersByType) { IEnumerable <Counter> counters = pair.Value; int minDepth = counters.Min(c => c.ParentDepth); IEnumerable <Counter> rootCounters = counters.Where(c => c.ParentDepth == minDepth); int maxNameLen = counters.Max(c => c.DisplayName.Length + c.ParentDepth * 2); int maxSamples = counters.Max(c => c.SampleCount); if (options.HasFlag(ReportOptions.GroupHeader)) { reportBuilder.Append(options.HasFlag(ReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); reportBuilder.AppendLine(("[ " + pair.Key.Name + " ]").PadLeft(35, '-').PadRight(50, '-')); reportBuilder.Append(options.HasFlag(ReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); } else if (reportBuilder.Length > 0) { reportBuilder.Append(options.HasFlag(ReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); } if (options.HasFlag(ReportOptions.Header)) { reportBuilder.Append("Name"); reportBuilder.Append(' ', 1 + Math.Max((1 + maxNameLen) - "Name".Length, 0)); if (options.HasFlag(ReportOptions.LastValue)) { reportBuilder.Append(" Last Value "); } if (options.HasFlag(ReportOptions.AverageValue)) { reportBuilder.Append(" Avg. Value "); } if (options.HasFlag(ReportOptions.MinValue)) { reportBuilder.Append(" Min. Value "); } if (options.HasFlag(ReportOptions.MaxValue)) { reportBuilder.Append(" Max. Value "); } if (options.HasFlag(ReportOptions.SampleCount)) { reportBuilder.Append(" Samples "); } if (options.HasFlag(ReportOptions.TotalValue)) { reportBuilder.Append(" Total Value "); } reportBuilder.Append(options.HasFlag(ReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); } Stack <Counter> appendStack = new Stack <Counter>(rootCounters.Reverse()); while (appendStack.Count > 0) { Counter current = appendStack.Pop(); if (options.HasFlag(ReportOptions.FormattedText)) { float severity = current.Severity; ColorRgba lineColor = severity >= 0.5f ? ColorRgba.Mix(ColorRgba.White, ColorRgba.Red, 2.0f * (severity - 0.5f)) : ColorRgba.Mix(ColorRgba.TransparentWhite, ColorRgba.White, 0.1f + 0.9f * (2.0f * severity)); reportBuilder.Append(FormattedText.FormatColor(lineColor)); } reportBuilder.Append(' ', current.ParentDepth * 2); reportBuilder.Append(current.DisplayName); reportBuilder.Append(':'); reportBuilder.Append(' ', 1 + Math.Max((1 + maxNameLen) - (current.ParentDepth * 2 + current.DisplayName.Length + 1), 0)); if (options.HasFlag(ReportOptions.LastValue)) { string valStr = current.DisplayLastValue; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ReportOptions.AverageValue)) { string valStr = current.DisplayAverageValue; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ReportOptions.MinValue)) { string valStr = current.DisplayMinValue; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ReportOptions.MaxValue)) { string valStr = current.DisplayMaxValue; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ReportOptions.SampleCount)) { string valStr = string.Format("{0}", current.SampleCount); reportBuilder.Append(' ', Math.Max(15 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ReportOptions.TotalValue)) { string valStr = current.DisplayTotalValue; reportBuilder.Append(' ', Math.Max(15 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } reportBuilder.Append(options.HasFlag(ReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); IEnumerable <Counter> childCounters = counters.Where(c => c.Parent == current); foreach (Counter child in childCounters.Reverse()) { appendStack.Push(child); } } if (options.HasFlag(ReportOptions.FormattedText)) { reportBuilder.Append(FormattedText.FormatColor(ColorRgba.White)); } } return(reportBuilder.ToString());; }