Add violin plots for reliability
And move custom imraii stuff to imraii2
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DalamudPackager" Version="2.1.12" />
|
<PackageReference Include="DalamudPackager" Version="2.1.12" />
|
||||||
|
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
|
||||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.106">
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.106">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Craftimizer;
|
namespace Craftimizer.Plugin;
|
||||||
|
|
||||||
internal static unsafe class ImGuiExtras
|
internal static unsafe class ImGuiExtras
|
||||||
{
|
{
|
||||||
|
|||||||
+71
-31
@@ -2,12 +2,16 @@ using Craftimizer.Utils;
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
using ImPlotNET;
|
||||||
|
using MathNet.Numerics.Statistics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -130,37 +134,6 @@ internal static class ImGuiUtils
|
|||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct EndUnconditionally : ImRaii.IEndObject, IDisposable
|
|
||||||
{
|
|
||||||
private Action EndAction { get; }
|
|
||||||
|
|
||||||
public bool Success { get; }
|
|
||||||
|
|
||||||
public bool Disposed { get; private set; }
|
|
||||||
|
|
||||||
public EndUnconditionally(Action endAction, bool success)
|
|
||||||
{
|
|
||||||
EndAction = endAction;
|
|
||||||
Success = success;
|
|
||||||
Disposed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (!Disposed)
|
|
||||||
{
|
|
||||||
EndAction();
|
|
||||||
Disposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ImRaii.IEndObject GroupPanel(string name, float width, out float internalWidth)
|
|
||||||
{
|
|
||||||
internalWidth = BeginGroupPanel(name, width);
|
|
||||||
return new EndUnconditionally(EndGroupPanel, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Vector2 UnitCircle(float theta)
|
private static Vector2 UnitCircle(float theta)
|
||||||
{
|
{
|
||||||
var (s, c) = MathF.SinCos(theta);
|
var (s, c) = MathF.SinCos(theta);
|
||||||
@@ -168,6 +141,7 @@ internal static class ImGuiUtils
|
|||||||
return new Vector2(c, -s);
|
return new Vector2(c, -s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static float Lerp(float a, float b, float t) =>
|
private static float Lerp(float a, float b, float t) =>
|
||||||
MathF.FusedMultiplyAdd(b - a, t, a);
|
MathF.FusedMultiplyAdd(b - a, t, a);
|
||||||
|
|
||||||
@@ -251,6 +225,72 @@ internal static class ImGuiUtils
|
|||||||
Arc(MathF.PI / 2, MathF.PI / 2 - MathF.Tau * Math.Clamp(value, 0, 1), radiusInner, radiusOuter, backgroundColor, filledColor);
|
Arc(MathF.PI / 2, MathF.PI / 2 - MathF.Tau * Math.Clamp(value, 0, 1), radiusInner, radiusOuter, backgroundColor, filledColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class ViolinData
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Point
|
||||||
|
{
|
||||||
|
public float X, Y, Y2;
|
||||||
|
|
||||||
|
public Point(float x, float y, float y2)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Y2 = y2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlySpan<Point> Data => (DataArray ?? Array.Empty<Point>()).AsSpan();
|
||||||
|
private Point[]? DataArray { get; set; }
|
||||||
|
public readonly float Min;
|
||||||
|
public readonly float Max;
|
||||||
|
|
||||||
|
public ViolinData(IEnumerable<int> samples, float min, float max, int resolution, double bandwidth)
|
||||||
|
{
|
||||||
|
Min = min;
|
||||||
|
Max = max;
|
||||||
|
bandwidth *= Max - Min;
|
||||||
|
var samplesList = samples.AsParallel().Select(s => (double)s).ToArray();
|
||||||
|
_ = Task.Run(() => {
|
||||||
|
var s = Stopwatch.StartNew();
|
||||||
|
var data = ParallelEnumerable.Range(0, resolution)
|
||||||
|
.Select(n => Lerp(min, max, n / (float)resolution))
|
||||||
|
.Select(n => (n, (float)KernelDensity.EstimateGaussian(n, bandwidth, samplesList)))
|
||||||
|
.Select(n => new Point(n.n, n.Item2, -n.Item2));
|
||||||
|
DataArray = data.ToArray();
|
||||||
|
s.Stop();
|
||||||
|
Log.Debug($"Violin plot processing took {s.Elapsed.TotalMilliseconds:0.00}ms");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ViolinPlot(in ViolinData data, Vector2 size)
|
||||||
|
{
|
||||||
|
using var padding = ImRaii2.PushStyle(ImPlotStyleVar.PlotPadding, Vector2.Zero);
|
||||||
|
using var plotBg = ImRaii2.PushColor(ImPlotCol.PlotBg, Vector4.Zero);
|
||||||
|
using var frameBg = ImRaii2.PushColor(ImPlotCol.FrameBg, Vector4.Zero);
|
||||||
|
using var fill = ImRaii2.PushColor(ImPlotCol.Fill, Vector4.One.WithAlpha(.5f));
|
||||||
|
|
||||||
|
using var plot = ImRaii2.Plot("##violin", size, ImPlotFlags.CanvasOnly);
|
||||||
|
if (plot)
|
||||||
|
{
|
||||||
|
ImPlot.SetupAxes(null, null, ImPlotAxisFlags.NoDecorations, ImPlotAxisFlags.NoDecorations | ImPlotAxisFlags.AutoFit);
|
||||||
|
ImPlot.SetupAxisLimits(ImAxis.X1, data.Min, data.Max, ImPlotCond.Always);
|
||||||
|
ImPlot.SetupFinish();
|
||||||
|
|
||||||
|
if (data.Data is { } points && !points.IsEmpty)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
var label_id = stackalloc byte[] { (byte)'\0' };
|
||||||
|
fixed (ViolinData.Point* p = points)
|
||||||
|
{
|
||||||
|
ImPlotNative.ImPlot_PlotShaded_FloatPtrFloatPtrFloatPtr(label_id, &p->X, &p->Y, &p->Y2, points.Length, ImPlotShadedFlags.None, 0, sizeof(ViolinData.Point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class SearchableComboData<T> where T : class
|
private sealed class SearchableComboData<T> where T : class
|
||||||
{
|
{
|
||||||
public readonly ImmutableArray<T> items;
|
public readonly ImmutableArray<T> items;
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using ImPlotNET;
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace Craftimizer.Plugin;
|
||||||
|
|
||||||
|
public static class ImRaii2
|
||||||
|
{
|
||||||
|
private struct EndUnconditionally : ImRaii.IEndObject, IDisposable
|
||||||
|
{
|
||||||
|
private Action EndAction { get; }
|
||||||
|
|
||||||
|
public bool Success { get; }
|
||||||
|
|
||||||
|
public bool Disposed { get; private set; }
|
||||||
|
|
||||||
|
public EndUnconditionally(Action endAction, bool success)
|
||||||
|
{
|
||||||
|
EndAction = endAction;
|
||||||
|
Success = success;
|
||||||
|
Disposed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!Disposed)
|
||||||
|
{
|
||||||
|
EndAction();
|
||||||
|
Disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct EndConditionally : ImRaii.IEndObject, IDisposable
|
||||||
|
{
|
||||||
|
public bool Success { get; }
|
||||||
|
|
||||||
|
public bool Disposed { get; private set; }
|
||||||
|
|
||||||
|
private Action EndAction { get; }
|
||||||
|
|
||||||
|
public EndConditionally(Action endAction, bool success)
|
||||||
|
{
|
||||||
|
EndAction = endAction;
|
||||||
|
Success = success;
|
||||||
|
Disposed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!Disposed)
|
||||||
|
{
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
EndAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
Disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject GroupPanel(string name, float width, out float internalWidth)
|
||||||
|
{
|
||||||
|
internalWidth = ImGuiUtils.BeginGroupPanel(name, width);
|
||||||
|
return new EndUnconditionally(ImGuiUtils.EndGroupPanel, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject Plot(string title_id, Vector2 size, ImPlotFlags flags)
|
||||||
|
{
|
||||||
|
return new EndConditionally(new Action(ImPlot.EndPlot), ImPlot.BeginPlot(title_id, size, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject PushStyle(ImPlotStyleVar idx, Vector2 val)
|
||||||
|
{
|
||||||
|
ImPlot.PushStyleVar(idx, val);
|
||||||
|
return new EndUnconditionally(ImPlot.PopStyleVar, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject PushStyle(ImPlotStyleVar idx, float val)
|
||||||
|
{
|
||||||
|
ImPlot.PushStyleVar(idx, val);
|
||||||
|
return new EndUnconditionally(ImPlot.PopStyleVar, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject PushColor(ImPlotCol idx, Vector4 col)
|
||||||
|
{
|
||||||
|
ImPlot.PushStyleColor(idx, col);
|
||||||
|
return new EndUnconditionally(ImPlot.PopStyleColor, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ public sealed class MacroClipboard : Window, IDisposable
|
|||||||
private void DrawMacro(int idx, string macro)
|
private void DrawMacro(int idx, string macro)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId(idx);
|
using var id = ImRaii.PushId(idx);
|
||||||
using var panel = ImGuiUtils.GroupPanel($"Macro {idx + 1}", -1, out var availWidth);
|
using var panel = ImRaii2.GroupPanel($"Macro {idx + 1}", -1, out var availWidth);
|
||||||
|
|
||||||
var cursor = ImGui.GetCursorPos();
|
var cursor = ImGui.GetCursorPos();
|
||||||
|
|
||||||
|
|||||||
@@ -79,31 +79,48 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
|
|
||||||
private readonly record struct SimulationReliablity
|
private readonly record struct SimulationReliablity
|
||||||
{
|
{
|
||||||
public record struct ParamReliability
|
public sealed class ParamReliability
|
||||||
{
|
{
|
||||||
|
private List<int> DataList { get; }
|
||||||
|
private ImGuiUtils.ViolinData? ViolinData { get; set; }
|
||||||
|
|
||||||
public int Max { get; private set; }
|
public int Max { get; private set; }
|
||||||
public int Min { get; private set; }
|
public int Min { get; private set; }
|
||||||
|
public float Median { get; private set; }
|
||||||
public float Average { get; private set; }
|
public float Average { get; private set; }
|
||||||
|
|
||||||
public ParamReliability()
|
public ParamReliability()
|
||||||
{
|
{
|
||||||
Min = int.MaxValue;
|
DataList = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(int value)
|
public void Add(int value)
|
||||||
{
|
{
|
||||||
Max = Math.Max(Max, value);
|
DataList.Add(value);
|
||||||
Min = Math.Min(Min, value);
|
|
||||||
Average += value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Finalize(int count)
|
public void FinalizeData()
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (DataList.Count == 0)
|
||||||
Average = Max = Min = 0;
|
{
|
||||||
|
Average = Median = Max = Min = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Max = DataList.Max();
|
||||||
|
Min = DataList.Min();
|
||||||
|
if (DataList.Count % 2 == 0)
|
||||||
|
Median = (float)DataList.Order().Skip(DataList.Count / 2 - 1).Take(2).Average();
|
||||||
else
|
else
|
||||||
Average /= count;
|
Median = DataList.Order().ElementAt(DataList.Count / 2);
|
||||||
|
Average = (float)DataList.Average();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImGuiUtils.ViolinData? GetViolinData(float barMax, int resolution, double bandwidth) =>
|
||||||
|
ViolinData ??=
|
||||||
|
Min != Max ?
|
||||||
|
new(DataList, 0, barMax, resolution, bandwidth) :
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly ParamReliability Progress = new();
|
public readonly ParamReliability Progress = new();
|
||||||
@@ -132,9 +149,9 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
Quality.Add(state.Quality);
|
Quality.Add(state.Quality);
|
||||||
Param.Add(getParam(state));
|
Param.Add(getParam(state));
|
||||||
}
|
}
|
||||||
Progress.Finalize(iterCount);
|
Progress.FinalizeData();
|
||||||
Quality.Finalize(iterCount);
|
Quality.FinalizeData();
|
||||||
Param.Finalize(iterCount);
|
Param.FinalizeData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +177,8 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SimulationReliablity GetReliability(in SimulationState initialState, IEnumerable<ActionType> actionSet, RecipeData recipeData) =>
|
public SimulationReliablity GetReliability(in SimulationState initialState, IEnumerable<ActionType> actionSet, RecipeData recipeData) =>
|
||||||
Reliability ??= new(initialState, actionSet, Service.Configuration.ReliabilitySimulationCount, recipeData);
|
Reliability ??=
|
||||||
|
new(initialState, actionSet, Service.Configuration.ReliabilitySimulationCount, recipeData);
|
||||||
};
|
};
|
||||||
|
|
||||||
private List<SimulatedActionStep> Macro { get; set; } = new();
|
private List<SimulatedActionStep> Macro { get; set; } = new();
|
||||||
@@ -195,7 +213,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
private CancellationTokenSource? popupImportUrlTokenSource;
|
private CancellationTokenSource? popupImportUrlTokenSource;
|
||||||
private MacroImport.RetrievedMacro? popupImportUrlMacro;
|
private MacroImport.RetrievedMacro? popupImportUrlMacro;
|
||||||
|
|
||||||
public MacroEditor(CharacterStats characterStats, RecipeData recipeData, CrafterBuffs buffs, IEnumerable<ActionType> actions, Action<IEnumerable<ActionType>>? setter) : base("Craftimizer Macro Editor", WindowFlags, false)
|
public MacroEditor(CharacterStats characterStats, RecipeData recipeData, CrafterBuffs buffs, IEnumerable<ActionType> actions, Action<IEnumerable<ActionType>>? setter) : base("Craftimizer Macro Editor", WindowFlags)
|
||||||
{
|
{
|
||||||
CharacterStats = characterStats;
|
CharacterStats = characterStats;
|
||||||
RecipeData = recipeData;
|
RecipeData = recipeData;
|
||||||
@@ -1000,7 +1018,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var actions = category.GetActions();
|
var actions = category.GetActions();
|
||||||
using var panel = ImGuiUtils.GroupPanel(category.GetDisplayName(), -1, out var availSpace);
|
using var panel = ImRaii2.GroupPanel(category.GetDisplayName(), -1, out var availSpace);
|
||||||
var itemsPerRow = (int)MathF.Floor((availSpace + spacing) / (imageSize + spacing));
|
var itemsPerRow = (int)MathF.Floor((availSpace + spacing) / (imageSize + spacing));
|
||||||
var itemCount = actions.Count;
|
var itemCount = actions.Count;
|
||||||
var iterCount = (int)(Math.Ceiling((float)itemCount / itemsPerRow) * itemsPerRow);
|
var iterCount = (int)(Math.Ceiling((float)itemCount / itemsPerRow) * itemsPerRow);
|
||||||
@@ -1076,7 +1094,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Buffs", -1, out _))
|
using (var panel = ImRaii2.GroupPanel("Buffs", -1, out _))
|
||||||
{
|
{
|
||||||
using var _font = ImRaii.PushFont(AxisFont.ImFont);
|
using var _font = ImRaii.PushFont(AxisFont.ImFont);
|
||||||
|
|
||||||
@@ -1134,7 +1152,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
var barSize = totalSize - textSize - spacing;
|
var barSize = totalSize - textSize - spacing;
|
||||||
foreach (var bar in bars)
|
foreach (var bar in bars)
|
||||||
{
|
{
|
||||||
using var panel = ImGuiUtils.GroupPanel(bar.Name, totalSize, out _);
|
using var panel = ImRaii2.GroupPanel(bar.Name, totalSize, out _);
|
||||||
if (bar.Condition is { } condition)
|
if (bar.Condition is { } condition)
|
||||||
{
|
{
|
||||||
using (var g = ImRaii.Group())
|
using (var g = ImRaii.Group())
|
||||||
@@ -1155,45 +1173,25 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bar.Reliability is { } reliability)
|
var pos = ImGui.GetCursorPos();
|
||||||
{
|
using (var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color))
|
||||||
// blend rgb colors, assume alpha is always 1
|
|
||||||
static Vector4 BlendColor(Vector4 A, Vector4 B)
|
|
||||||
{
|
|
||||||
return new(
|
|
||||||
A.X * (1 - B.W) + B.X * B.W,
|
|
||||||
A.Y * (1 - B.W) + B.Y * B.W,
|
|
||||||
A.Z * (1 - B.W) + B.Z * B.W,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
var relBars = new (float Value, Vector4 Color)[]
|
|
||||||
{
|
|
||||||
(bar.Value, bar.Color),
|
|
||||||
(reliability.Average, BlendColor(bar.Color, new(.5f,.5f,.5f,.6f))),
|
|
||||||
(reliability.Min, BlendColor(bar.Color, new(0,0,0,.6f))),
|
|
||||||
(reliability.Max, BlendColor(bar.Color, new(1,1,1,.6f))),
|
|
||||||
}.DistinctBy(v => Math.Clamp(v.Value, 0, bar.Max)).OrderByDescending(v => v.Value);
|
|
||||||
var i = 0;
|
|
||||||
var pos = ImGui.GetCursorPos();
|
|
||||||
foreach (var relBar in relBars)
|
|
||||||
{
|
|
||||||
ImGui.SetCursorPos(pos);
|
|
||||||
{
|
|
||||||
using var frameColor = ImRaii.PushColor(ImGuiCol.FrameBg, Vector4.Zero, i != 0);
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, relBar.Color);
|
|
||||||
ImGui.ProgressBar(Math.Clamp(relBar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
|
||||||
}
|
|
||||||
if (i++ == 0)
|
|
||||||
{
|
|
||||||
if (ImGui.IsItemHovered())
|
|
||||||
ImGui.SetTooltip($"Min: {reliability.Min}\nAvg: {reliability.Average:0.##}\nMax: {reliability.Max}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color);
|
|
||||||
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
||||||
|
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenOverlapped))
|
||||||
|
{
|
||||||
|
if (bar.Reliability is { } reliability)
|
||||||
|
{
|
||||||
|
if (reliability.GetViolinData(bar.Max, (int)(barSize / 2), 0.02) is { } violinData)
|
||||||
|
{
|
||||||
|
ImGui.SetCursorPos(pos);
|
||||||
|
ImGuiUtils.ViolinPlot(violinData, new(barSize, ImGui.GetFrameHeight()));
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip(
|
||||||
|
$"Min: {reliability.Min}\n" +
|
||||||
|
$"Med: {reliability.Median:0.##}\n" +
|
||||||
|
$"Avg: {reliability.Average:0.##}\n" +
|
||||||
|
$"Max: {reliability.Max}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui.SameLine(0, spacing);
|
ImGui.SameLine(0, spacing);
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
@@ -1217,7 +1215,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
var imageSize = ImGui.GetFrameHeight() * 2;
|
var imageSize = ImGui.GetFrameHeight() * 2;
|
||||||
var lastState = InitialState;
|
var lastState = InitialState;
|
||||||
|
|
||||||
using var panel = ImGuiUtils.GroupPanel("Macro", -1, out var availSpace);
|
using var panel = ImRaii2.GroupPanel("Macro", -1, out var availSpace);
|
||||||
ImGui.Dummy(new(0, imageSize));
|
ImGui.Dummy(new(0, imageSize));
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
|
|
||||||
@@ -1412,7 +1410,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
{
|
{
|
||||||
bool submittedText, submittedUrl;
|
bool submittedText, submittedUrl;
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("##text", -1, out var availWidth))
|
using (var panel = ImRaii2.GroupPanel("##text", -1, out var availWidth))
|
||||||
{
|
{
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGuiUtils.TextCentered("Paste your macro here");
|
ImGuiUtils.TextCentered("Paste your macro here");
|
||||||
@@ -1424,7 +1422,7 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
submittedText = ImGui.Button("Import", new(availWidth, 0));
|
submittedText = ImGui.Button("Import", new(availWidth, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("##url", -1, out var availWidth))
|
using (var panel = ImRaii2.GroupPanel("##url", -1, out var availWidth))
|
||||||
{
|
{
|
||||||
var availOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
var availOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public sealed class MacroList : Window, IDisposable
|
|||||||
|
|
||||||
var stateNullable = GetMacroState(macro);
|
var stateNullable = GetMacroState(macro);
|
||||||
|
|
||||||
using var panel = ImGuiUtils.GroupPanel(macro.Name, -1, out var availWidth);
|
using var panel = ImRaii2.GroupPanel(macro.Name, -1, out var availWidth);
|
||||||
var stepsAvailWidthOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
var stepsAvailWidthOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
||||||
var spacing = ImGui.GetStyle().ItemSpacing.Y;
|
var spacing = ImGui.GetStyle().ItemSpacing.Y;
|
||||||
var miniRowHeight = (windowHeight - spacing) / 2f;
|
var miniRowHeight = (windowHeight - spacing) / 2f;
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var panelWidth = availWidth - ImGui.GetStyle().ItemSpacing.X * 2;
|
var panelWidth = availWidth - ImGui.GetStyle().ItemSpacing.X * 2;
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Best Saved Macro", panelWidth, out _))
|
using (var panel = ImRaii2.GroupPanel("Best Saved Macro", panelWidth, out _))
|
||||||
{
|
{
|
||||||
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
||||||
if (BestSavedMacro is { } savedMacro)
|
if (BestSavedMacro is { } savedMacro)
|
||||||
@@ -228,7 +228,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
|
|||||||
DrawMacro(null, null, stepsPanelWidthOffset, true);
|
DrawMacro(null, null, stepsPanelWidthOffset, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Suggested Macro", panelWidth, out _))
|
using (var panel = ImRaii2.GroupPanel("Suggested Macro", panelWidth, out _))
|
||||||
{
|
{
|
||||||
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
||||||
if (BestSuggestedMacro is { } suggestedMacro)
|
if (BestSuggestedMacro is { } suggestedMacro)
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ public sealed class Settings : Window, IDisposable
|
|||||||
ImGui.SetTooltip("Disabled temporarily for testing");
|
ImGui.SetTooltip("Disabled temporarily for testing");
|
||||||
|
|
||||||
DrawOption(
|
DrawOption(
|
||||||
"Show Only One Macro Stat",
|
"Show Only One Macro Stat in Crafting Log",
|
||||||
"Only one stat will be shown for a macro. If a craft will be finished, quality\n" +
|
"Only one stat will be shown for a macro. If a craft will be finished, quality\n" +
|
||||||
"is shown. Otherwise, progress is shown. Durability and remaining CP will be\n" +
|
"is shown. Otherwise, progress is shown. Durability and remaining CP will be\n" +
|
||||||
"hidden.",
|
"hidden.",
|
||||||
@@ -200,9 +200,21 @@ public sealed class Settings : Window, IDisposable
|
|||||||
ref isDirty
|
ref isDirty
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DrawOption(
|
||||||
|
"Reliability Trial Count",
|
||||||
|
"When testing for reliability of a macro in the editor, this many trials will be\n" +
|
||||||
|
"run. You should set this value to at least 100 to get a reliable spread of data.\n" +
|
||||||
|
"If it's too low, you may not find an outlier, and the average might be skewed.",
|
||||||
|
Config.ReliabilitySimulationCount,
|
||||||
|
5,
|
||||||
|
5000,
|
||||||
|
v => Config.ReliabilitySimulationCount = v,
|
||||||
|
ref isDirty
|
||||||
|
);
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Copying Settings", -1, out _))
|
using (var panel = ImRaii2.GroupPanel("Copying Settings", -1, out _))
|
||||||
{
|
{
|
||||||
DrawOption(
|
DrawOption(
|
||||||
"Macro Copy Method",
|
"Macro Copy Method",
|
||||||
@@ -380,7 +392,7 @@ public sealed class Settings : Window, IDisposable
|
|||||||
|
|
||||||
var config = configRef;
|
var config = configRef;
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("General", -1, out _))
|
using (var panel = ImRaii2.GroupPanel("General", -1, out _))
|
||||||
{
|
{
|
||||||
if (ImGui.Button("Reset to Default", OptionButtonSize))
|
if (ImGui.Button("Reset to Default", OptionButtonSize))
|
||||||
{
|
{
|
||||||
@@ -501,7 +513,7 @@ public sealed class Settings : Window, IDisposable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Advanced", -1, out _))
|
using (var panel = ImRaii2.GroupPanel("Advanced", -1, out _))
|
||||||
{
|
{
|
||||||
DrawOption(
|
DrawOption(
|
||||||
"Score Storage Threshold",
|
"Score Storage Threshold",
|
||||||
@@ -538,7 +550,7 @@ public sealed class Settings : Window, IDisposable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var panel = ImGuiUtils.GroupPanel("Score Weights (Advanced)", -1, out _))
|
using (var panel = ImRaii2.GroupPanel("Score Weights (Advanced)", -1, out _))
|
||||||
{
|
{
|
||||||
ImGui.TextWrapped("All values should add up to 1. Otherwise, the Score Storage Threshold should be changed.");
|
ImGui.TextWrapped("All values should add up to 1. Otherwise, the Score Storage Threshold should be changed.");
|
||||||
ImGuiHelpers.ScaledDummy(10);
|
ImGuiHelpers.ScaledDummy(10);
|
||||||
|
|||||||
@@ -8,6 +8,12 @@
|
|||||||
"resolved": "2.1.12",
|
"resolved": "2.1.12",
|
||||||
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
|
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
|
||||||
},
|
},
|
||||||
|
"MathNet.Numerics": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[5.0.0, )",
|
||||||
|
"resolved": "5.0.0",
|
||||||
|
"contentHash": "pg1W2VwaEQMAiTpGK840hZgzavnqjlCMTVSbtVCXVyT+7AX4mc1o89SPv4TBlAjhgCOo9c1Y+jZ5m3ti2YgGgA=="
|
||||||
|
},
|
||||||
"Meziantou.Analyzer": {
|
"Meziantou.Analyzer": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[2.0.106, )",
|
"requested": "[2.0.106, )",
|
||||||
|
|||||||
Reference in New Issue
Block a user