1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-22 07:36:05 +08:00

refactor(osu.Game): arrange the code for the timing distribution graph

This commit is contained in:
Acid Chicken (硫酸鶏) 2022-09-07 23:29:10 +09:00
parent 99ef0c95fe
commit b560b6f745
No known key found for this signature in database
GPG Key ID: 3E87B98A3F6BAB99

View File

@ -47,9 +47,6 @@ namespace osu.Game.Screens.Ranking.Statistics
/// </summary> /// </summary>
private readonly IReadOnlyList<HitEvent> hitEvents; private readonly IReadOnlyList<HitEvent> hitEvents;
[Resolved]
private OsuColour colours { get; set; }
/// <summary> /// <summary>
/// Creates a new <see cref="HitEventTimingDistributionGraph"/>. /// Creates a new <see cref="HitEventTimingDistributionGraph"/>.
/// </summary> /// </summary>
@ -129,13 +126,7 @@ namespace osu.Game.Screens.Ranking.Statistics
else else
{ {
int maxCount = bins.Max(b => b.Values.Sum()); int maxCount = bins.Max(b => b.Values.Sum());
barDrawables = new Bar[total_timing_distribution_bins]; barDrawables = bins.Select((bin, i) => new Bar(bins[i], maxCount, i == timing_distribution_centre_bin_index)).ToArray();
for (int i = 0; i < barDrawables.Length; i++)
{
IReadOnlyList<BarValue> values = bins[i].Select(b => new BarValue(b.Key.OrderingIndex(), b.Value, colours.DrawForHitResult(b.Key))).OrderBy(b => b.Index).ToList();
barDrawables[i] = new Bar(values, maxCount, i == timing_distribution_centre_bin_index);
}
Container axisFlow; Container axisFlow;
@ -216,53 +207,53 @@ namespace osu.Game.Screens.Ranking.Statistics
} }
} }
private readonly struct BarValue
{
public readonly int Index;
public readonly float Value;
public readonly Color4 Colour;
public BarValue(int index, float value, Color4 colour)
{
Index = index;
Value = value;
Colour = colour;
}
}
private class Bar : CompositeDrawable private class Bar : CompositeDrawable
{ {
private float totalValue => values.Sum(v => v.Value); private float totalValue => values.Sum(v => v.Value);
private float basalHeight => BoundingBox.Width / BoundingBox.Height; private float basalHeight => BoundingBox.Width / BoundingBox.Height;
private float availableHeight => 1 - basalHeight; private float availableHeight => 1 - basalHeight;
private readonly IReadOnlyList<BarValue> values; private readonly IReadOnlyList<KeyValuePair<HitResult, int>> values;
private readonly float maxValue; private readonly float maxValue;
private readonly bool isCentre;
private readonly Circle[] boxOriginals; private Circle[] boxOriginals;
private Circle boxAdjustment; private Circle boxAdjustment;
public Bar(IReadOnlyList<BarValue> values, float maxValue, bool isCentre) [Resolved]
private OsuColour colours { get; set; }
public Bar(IDictionary<HitResult, int> values, float maxValue, bool isCentre)
{ {
this.values = values; this.values = values.OrderBy(v => v.Key.OrderingIndex()).ToList();
this.maxValue = maxValue; this.maxValue = maxValue;
this.isCentre = isCentre;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Masking = true; Masking = true;
}
[BackgroundDependencyLoader]
private void load()
{
if (values.Any()) if (values.Any())
{ {
InternalChildren = boxOriginals = values.Select((v, i) => new Circle boxOriginals = values.Select((v, i) => new Circle
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
Colour = isCentre && i == 0 ? Color4.White : v.Colour, Colour = isCentre && i == 0 ? Color4.White : colours.DrawForHitResult(v.Key),
Height = 0, Height = 0,
}).ToArray(); }).ToArray();
// The bars of the stacked bar graph will be processed (stacked) from the bottom, which is the base position,
// to the top, and the bottom bar should be drawn more toward the front by design,
// while the drawing order is from the back to the front, so the order passed to `InternalChildren` is the opposite.
InternalChildren = boxOriginals.Reverse().ToArray();
} }
else else
{ {
// A bin with no value draws a grey dot instead.
InternalChildren = boxOriginals = new[] InternalChildren = boxOriginals = new[]
{ {
new Circle new Circle