diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/RatingDistributionGraph.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/RatingDistributionGraph.cs index 1f6107141b79..8a03e7b5243d 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/RatingDistributionGraph.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/RatingDistributionGraph.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue public partial class RatingDistributionGraph : CompositeDrawable, IHasCustomTooltip { private const int y_divisions = 4; - private const int x_divisions = 16; + private const int x_max_divisions = 16; [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; @@ -50,6 +50,7 @@ public partial class RatingDistributionGraph : CompositeDrawable, IHasCustomTool private int? userRating; private (int min, int max, int step) xRange; private (int min, int max) yRange; + private int xDivisionStep = 1; [BackgroundDependencyLoader] private void load() @@ -237,6 +238,17 @@ public void SetData((int x, int y)[] data, int? userRating) data.Zip(data.Skip(1), (a, b) => Math.Abs(b.x - a.x)).DefaultIfEmpty().Min() ); + xDivisionStep = Math.Max(xRange.step, 50); // avoid division by zero + + // Keep increasing the division until number of lines is appropriately low + while ((xRange.max - xRange.min) / xDivisionStep > x_max_divisions) + { + xDivisionStep *= 2; + } + + xRange.min = (int)floorWithFactor(xRange.min, xDivisionStep); + xRange.max = (int)ceilingWithFactor(xRange.max, xDivisionStep); + if (userRating < xRange.min) { this.data = this.data.Prepend((userRating.Value, 1)).ToArray(); @@ -249,9 +261,11 @@ public void SetData((int x, int y)[] data, int? userRating) xRange.max = userRating.Value; } + int yMax = this.data.Select(d => d.y).DefaultIfEmpty().Max(); + yRange = ( 0, - (int)roundToSignificant(this.data.Select(d => d.y).DefaultIfEmpty().Max()) + (int)ceilingWithFactor(yMax, significantOfNumber(yMax)) ); updateGraph(); @@ -274,13 +288,15 @@ private void updateGraph() => Scheduler.AddOnce(() => barsContainer.Clear(); userRatingContainer.Clear(); - for (int step = 0; step <= x_divisions; step++) + int xDivisions = Math.Max(1, (xRange.max - xRange.min) / xDivisionStep); + + for (int step = 0; step <= xDivisions; step++) { gridContainer.Add(new VerticalLine { RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.X, - X = (float)step / x_divisions, + X = (float)step / xDivisions, Colour = colourProvider.Background1 }); @@ -289,10 +305,10 @@ private void updateGraph() => Scheduler.AddOnce(() => Anchor = Anchor.TopLeft, Origin = Anchor.CentreRight, RelativePositionAxes = Axes.X, - X = (float)step / x_divisions, + X = (float)step / xDivisions, Margin = new MarginPadding { Right = -2 }, Rotation = -40, - Text = (xRange.min + (xRange.max - xRange.min) / x_divisions * step).ToString(), + Text = (xRange.min + xDivisionStep * step).ToString(), UseFullGlyphHeight = false, Font = OsuFont.Default.With(size: 12), Colour = colourProvider.Foreground1 @@ -337,7 +353,7 @@ private void updateGraph() => Scheduler.AddOnce(() => { barsContainer.Add(new Container { - Origin = Anchor.BottomCentre, + Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, RelativePositionAxes = Axes.X, RelativeSizeAxes = Axes.Both, @@ -393,7 +409,7 @@ private void updateGraph() => Scheduler.AddOnce(() => currentCount += d.y; float p = (float)currentCount / totalCount; return new Vector2(pointOnGraph(d.x, 0).X, 1 - p); - }).ToArray(); + }).Append(new Vector2(1, 0)).ToArray(); }); private Vector2 pointOnGraph(int x, int y) @@ -403,13 +419,25 @@ private Vector2 pointOnGraph(int x, int y) return new Vector2(xPos, yPos); } - private static double roundToSignificant(double value) + private static double significantOfNumber(double value) + { + return Math.Pow(10, Math.Floor(Math.Log10(value))); + } + + private static double floorWithFactor(double value, double factor) + { + if (value == 0 || factor == 0) + return 0; + + return Math.Floor(value / factor) * factor; + } + + private static double ceilingWithFactor(double value, double factor) { - if (value == 0) + if (value == 0 || factor == 0) return 0; - double scale = Math.Pow(10, Math.Floor(Math.Log10(value))); - return Math.Ceiling(value / scale) * scale; + return Math.Ceiling(value / factor) * factor; } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) @@ -474,7 +502,7 @@ protected override bool OnMouseMove(MouseMoveEvent e) int currentCount = 0; int totalCount = data.Sum(p => p.y); - for (int i = 0; i < cumulativePath.Vertices.Count; i++) + for (int i = 0; i < data.Length; i++) { currentCount += data[i].y;