1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 10:07:52 +08:00

Adjust API for returning statistics

This commit is contained in:
smoogipoo 2020-06-19 20:31:52 +09:00
parent 1cbbd6b442
commit 83e6c3efdb
10 changed files with 92 additions and 43 deletions

View File

@ -29,7 +29,9 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Skinning;
using System;
using System.Linq;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Statistics;
using osu.Game.Screens.Ranking.Statistics;
@ -190,36 +192,29 @@ namespace osu.Game.Rulesets.Osu
public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo);
public override StatisticRow[] CreateStatistics(ScoreInfo score) => new[]
public override StatisticRow[] CreateStatistics(ScoreInfo score)
{
new StatisticRow
var hitCircleEvents = score.HitEvents.Where(e => e.HitObject is HitCircle).ToList();
return new[]
{
Content = new Drawable[]
new StatisticRow
{
new StatisticContainer("Timing Distribution")
Columns = new[]
{
RelativeSizeAxes = Axes.X,
Height = 130,
Child = new HitEventTimingDistributionGraph(score)
new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(hitCircleEvents)
{
RelativeSizeAxes = Axes.Both
}
},
new StatisticContainer("Accuracy Heatmap")
{
RelativeSizeAxes = Axes.Both,
Child = new Heatmap(score)
RelativeSizeAxes = Axes.X,
Height = 130
}),
new StatisticItem("Accuracy Heatmap", new Heatmap(score)
{
RelativeSizeAxes = Axes.Both
}
},
},
ColumnDimensions = new[]
{
new Dimension(),
new Dimension(GridSizeMode.Absolute, 130),
RelativeSizeAxes = Axes.X,
Height = 130
}, new Dimension(GridSizeMode.Absolute, 130)),
}
}
}
};
};
}
}
}

View File

@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -147,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Statistics
// Todo: This should probably not be done like this.
float radius = OsuHitObject.OBJECT_RADIUS * (1.0f - 0.7f * (score.Beatmap.BaseDifficulty.CircleSize - 5) / 5) / 2;
foreach (var e in score.HitEvents)
foreach (var e in score.HitEvents.Where(e => e.HitObject is HitCircle))
{
if (e.LastHitObject == null || e.PositionOffset == null)
continue;

View File

@ -21,9 +21,12 @@ using osu.Game.Rulesets.Taiko.Difficulty;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Scoring;
using System;
using System.Linq;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Taiko.Edit;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Skinning;
using osu.Game.Screens.Ranking.Statistics;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko
@ -155,5 +158,20 @@ namespace osu.Game.Rulesets.Taiko
public int LegacyID => 1;
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame();
public override StatisticRow[] CreateStatistics(ScoreInfo score) => new[]
{
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(score.HitEvents.Where(e => e.HitObject is Hit).ToList())
{
RelativeSizeAxes = Axes.X,
Height = 130
}),
}
}
};
}
}

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens.Ranking.Statistics;
using osuTK;
@ -25,7 +24,7 @@ namespace osu.Game.Tests.Visual.Ranking
RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("#333")
},
new HitEventTimingDistributionGraph(new ScoreInfo { HitEvents = CreateDistributedHitEvents() })
new HitEventTimingDistributionGraph(CreateDistributedHitEvents())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -210,6 +210,7 @@ namespace osu.Game.Rulesets
/// <returns>An empty frame for the current ruleset, or null if unsupported.</returns>
public virtual IConvertibleReplayFrame CreateConvertibleReplayFrame() => null;
[NotNull]
public virtual StatisticRow[] CreateStatistics(ScoreInfo score) => Array.Empty<StatisticRow>();
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@ -10,10 +11,13 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Ranking.Statistics
{
/// <summary>
/// A graph which displays the distribution of hit timing in a series of <see cref="HitEvent"/>s.
/// </summary>
public class HitEventTimingDistributionGraph : CompositeDrawable
{
/// <summary>
@ -32,27 +36,31 @@ namespace osu.Game.Screens.Ranking.Statistics
private const int timing_distribution_centre_bin_index = timing_distribution_bins;
/// <summary>
/// The number of data points shown on the axis below the graph.
/// The number of data points shown on each side of the axis below the graph.
/// </summary>
private const float axis_points = 5;
private readonly ScoreInfo score;
private readonly IReadOnlyList<HitEvent> hitEvents;
public HitEventTimingDistributionGraph(ScoreInfo score)
/// <summary>
/// Creates a new <see cref="HitEventTimingDistributionGraph"/>.
/// </summary>
/// <param name="hitEvents">The <see cref="HitEvent"/>s to display the timing distribution of.</param>
public HitEventTimingDistributionGraph(IReadOnlyList<HitEvent> hitEvents)
{
this.score = score;
this.hitEvents = hitEvents;
}
[BackgroundDependencyLoader]
private void load()
{
if (score.HitEvents == null || score.HitEvents.Count == 0)
if (hitEvents == null || hitEvents.Count == 0)
return;
int[] bins = new int[total_timing_distribution_bins];
double binSize = score.HitEvents.Max(e => Math.Abs(e.TimeOffset)) / timing_distribution_bins;
double binSize = hitEvents.Max(e => Math.Abs(e.TimeOffset)) / timing_distribution_bins;
foreach (var e in score.HitEvents)
foreach (var e in hitEvents)
{
int binOffset = (int)(e.TimeOffset / binSize);
bins[timing_distribution_centre_bin_index + binOffset]++;
@ -67,6 +75,8 @@ namespace osu.Game.Screens.Ranking.Statistics
InternalChild = new GridContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Width = 0.8f,
Content = new[]

View File

@ -11,7 +11,7 @@ using osuTK;
namespace osu.Game.Screens.Ranking.Statistics
{
public class StatisticContainer : Container
internal class StatisticContainer : Container
{
protected override Container<Drawable> Content => content;

View File

@ -0,0 +1,23 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Screens.Ranking.Statistics
{
public class StatisticItem
{
public readonly string Name;
public readonly Drawable Content;
public readonly Dimension Dimension;
public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null)
{
Name = name;
Content = content;
Dimension = dimension;
}
}
}

View File

@ -1,15 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using JetBrains.Annotations;
namespace osu.Game.Screens.Ranking.Statistics
{
public class StatisticRow
{
public Drawable[] Content = Array.Empty<Drawable>();
public Dimension[] ColumnDimensions = Array.Empty<Dimension>();
/// <summary>
/// The columns of this <see cref="StatisticRow"/>.
/// </summary>
[ItemCanBeNull]
public StatisticItem[] Columns;
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -80,8 +81,8 @@ namespace osu.Game.Screens.Ranking.Statistics
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Content = new[] { row.Content },
ColumnDimensions = row.ColumnDimensions,
Content = new[] { row.Columns?.Select(c => c?.Content).ToArray() },
ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0).Select(i => row.Columns[i]?.Dimension ?? new Dimension()).ToArray(),
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }
});
}