mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 19:54:15 +08:00
Improve ranked play rating graph's x-axis divisions (#37534)
the x axis division was set to a fixed number of steps rather than picking a neat step size, which created uneven numbers. this pr changes this so an appropriate factor is determined, the x-axis min/max is floor'd/ceil'd to that factor and the divisions are created based on that factor. the cumulative rating line also extends to the new end of the graph. in addition, the bars of the bar chart are now aligned using the left edge of the bar rather than the center. in the after-image, note how the left edge of the bar for 1600 rating aligns with the division. (this is based on the assumption that a rating bucket, say "1500", spans the interval [1500, 1600]. if the bucket spans [1450, 1550] instead, i will revert the change) before <img width="632" height="217" alt="image" src="https://github.com/user-attachments/assets/b7053d43-99bb-4e5b-87a4-dcec37d56b50" /> after <img width="608" height="230" alt="image" src="https://github.com/user-attachments/assets/3f9e4284-f1b1-4bcb-8f70-f75f4e242b19" /> could optimize the while loop into a single mathematical expression, but this is easier to read imo. lmk if you'd prefer the expression instead
This commit is contained in:
committed by
GitHub
Unverified
parent
25df5cc602
commit
c84777d7bf
@@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
public partial class RatingDistributionGraph : CompositeDrawable, IHasCustomTooltip<RatingDistributionGraph.RatingDistributionGraphTooltipData>
|
||||
{
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
barsContainer.Add(new Container
|
||||
{
|
||||
Origin = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativePositionAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@@ -393,7 +409,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
return new Vector2(xPos, yPos);
|
||||
}
|
||||
|
||||
private static double roundToSignificant(double value)
|
||||
private static double significantOfNumber(double value)
|
||||
{
|
||||
if (value == 0)
|
||||
return Math.Pow(10, Math.Floor(Math.Log10(value)));
|
||||
}
|
||||
|
||||
private static double floorWithFactor(double value, double factor)
|
||||
{
|
||||
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.Floor(value / factor) * factor;
|
||||
}
|
||||
|
||||
private static double ceilingWithFactor(double value, double factor)
|
||||
{
|
||||
if (value == 0 || factor == 0)
|
||||
return 0;
|
||||
|
||||
return Math.Ceiling(value / factor) * factor;
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
|
||||
@@ -474,7 +502,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user