/// <summary> /// Exports events to PlantUML. /// </summary> /// <param name="States">PlantUML States</param> public void ExportPlantUmlEvents(PlantUmlStates States) { foreach (ProfilerEvent Event in this.events) { Event.ExportPlantUml(States); } foreach (ProfilerThread Thread in this.subThreads) { Thread.ExportPlantUmlEvents(States); } if (this.startedAt.HasValue && this.stoppedAt.HasValue) { StringBuilder Output = States.Summary; long Ticks = this.stoppedAt.Value - this.startedAt.Value; string ElapsedStr = this.profiler.ToTimeStr(Ticks, this, States.TimeUnit); KeyValuePair <double, string> Time; Output.Append(this.Key); Output.Append('@'); Time = this.profiler.ToTime(this.startedAt.Value, this, States.TimeUnit); Output.Append(Time.Key.ToString("F0").Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".")); Output.Append(" <-> @"); Time = this.profiler.ToTime(this.stoppedAt.Value, this, States.TimeUnit); Output.Append(Time.Key.ToString("F0").Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".")); Output.Append(" : "); Output.AppendLine(ElapsedStr); } }
/// <summary> /// Exports events to PlantUML. /// </summary> /// <param name="States">PlantUML States</param> public virtual void ExportPlantUml(PlantUmlStates States) { StringBuilder Output = States.GetBuilder(this.ticks); Output.Append(this.thread.Key); Output.Append(" is "); Output.AppendLine(this.PlantUmlState); }
/// <inheritdoc/> public override void ExportPlantUml(PlantUmlStates States) { StringBuilder Output = States.GetBuilder(this.Ticks); Output.Append("E"); Output.Append(this.ordinal.ToString()); Output.Append(" -> "); Output.AppendLine(this.Thread.Key); }
/// <summary> /// Exports events to PlantUML. /// </summary> /// <param name="Output">PlantUML output.</param> /// <param name="TimeUnit">Time unit to use.</param> /// <param name="GoalWidth">Goal width of diagram, in pixels.</param> public void ExportPlantUml(StringBuilder Output, TimeUnit TimeUnit, int GoalWidth) { switch (TimeUnit) { case TimeUnit.DynamicPerEvent: case TimeUnit.DynamicPerThread: throw new InvalidOperationException("Diagram requires the same time base to be used through-out."); } Output.AppendLine("@startuml"); foreach (ProfilerThread Thread in this.threads) { if (Thread.Parent is null) { Thread.ExportPlantUmlDescription(Output, TimeUnit); } } lock (this.eventOrdinals) { foreach (KeyValuePair <string, int> P in this.eventOrdinals) { Output.Append("concise \""); Output.Append(P.Key); Output.Append("\" as E"); Output.AppendLine(P.Value.ToString()); } } lock (this.exceptionOrdinals) { foreach (KeyValuePair <string, int> P in this.exceptionOrdinals) { Output.Append("concise \""); Output.Append(P.Key); Output.Append("\" as X"); Output.AppendLine(P.Value.ToString()); } } double TimeSpan; double StepSize; int NrSteps; do { KeyValuePair <double, string> TotalTime = this.ToTime(this.mainThread.StoppedAt ?? this.ElapsedTicks, this.mainThread, TimeUnit); TimeSpan = TotalTime.Key; StepSize = Math.Pow(10, Math.Round(Math.Log10(TimeSpan / 10))); NrSteps = (int)Math.Floor(TimeSpan / StepSize); if (NrSteps >= 50) { StepSize *= 5; } else if (NrSteps >= 25) { StepSize *= 2.5; } else if (NrSteps >= 20) { StepSize *= 2; } else if (NrSteps <= 2) { StepSize /= 5; } else if (NrSteps <= 4) { StepSize /= 2.5; } else if (NrSteps <= 5) { StepSize /= 2; } if (StepSize < 1) { this.timeScale *= 1e-3; } }while (StepSize < 1); StepSize = Math.Floor(StepSize); NrSteps = (int)Math.Floor(TimeSpan / StepSize); int PixelsPerStep = GoalWidth / NrSteps; Output.Append("scale "); Output.Append(StepSize.ToString("F0")); Output.Append(" as "); Output.Append(PixelsPerStep); Output.AppendLine(" pixels"); PlantUmlStates States = new PlantUmlStates(TimeUnit); foreach (ProfilerThread Thread in this.threads) { if (Thread.Parent is null) { Thread.ExportPlantUmlEvents(States); } } foreach (KeyValuePair <long, StringBuilder> P in States.ByTime) { KeyValuePair <double, string> Time = this.ToTime(P.Key, null, TimeUnit); Output.Append('@'); Output.AppendLine(Time.Key.ToString("F3").Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".")); Output.Append(P.Value.ToString()); } Output.Append(States.Summary.ToString()); Output.AppendLine("@enduml"); }