diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs
index d99fee3b15..aa313c92b3 100644
--- a/osu.Game.Rulesets.Osu/OsuRuleset.cs
+++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs
@@ -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)),
+ }
}
- }
- };
+ };
+ }
}
}
diff --git a/osu.Game.Rulesets.Osu/Statistics/Heatmap.cs b/osu.Game.Rulesets.Osu/Statistics/Heatmap.cs
index 49d7f67b7f..86cb8e682f 100644
--- a/osu.Game.Rulesets.Osu/Statistics/Heatmap.cs
+++ b/osu.Game.Rulesets.Osu/Statistics/Heatmap.cs
@@ -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;
diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
index 4cdd1fbc24..cd4e699262 100644
--- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
@@ -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
+ }),
+ }
+ }
+ };
}
}
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneTimingDistributionGraph.cs b/osu.Game.Tests/Visual/Ranking/TestSceneTimingDistributionGraph.cs
index bfdc216aa1..b34529cca7 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneTimingDistributionGraph.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneTimingDistributionGraph.cs
@@ -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,
diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs
index f05685b6e9..52784e354f 100644
--- a/osu.Game/Rulesets/Ruleset.cs
+++ b/osu.Game/Rulesets/Ruleset.cs
@@ -210,6 +210,7 @@ namespace osu.Game.Rulesets
/// An empty frame for the current ruleset, or null if unsupported.
public virtual IConvertibleReplayFrame CreateConvertibleReplayFrame() => null;
+ [NotNull]
public virtual StatisticRow[] CreateStatistics(ScoreInfo score) => Array.Empty();
}
}
diff --git a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs
index b258e92aeb..4acbc7da3c 100644
--- a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs
+++ b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs
@@ -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
{
+ ///
+ /// A graph which displays the distribution of hit timing in a series of s.
+ ///
public class HitEventTimingDistributionGraph : CompositeDrawable
{
///
@@ -32,27 +36,31 @@ namespace osu.Game.Screens.Ranking.Statistics
private const int timing_distribution_centre_bin_index = timing_distribution_bins;
///
- /// 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.
///
private const float axis_points = 5;
- private readonly ScoreInfo score;
+ private readonly IReadOnlyList hitEvents;
- public HitEventTimingDistributionGraph(ScoreInfo score)
+ ///
+ /// Creates a new .
+ ///
+ /// The s to display the timing distribution of.
+ public HitEventTimingDistributionGraph(IReadOnlyList 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[]
diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs
index d7b42c1c2f..b8dde8f85e 100644
--- a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs
+++ b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs
@@ -11,7 +11,7 @@ using osuTK;
namespace osu.Game.Screens.Ranking.Statistics
{
- public class StatisticContainer : Container
+ internal class StatisticContainer : Container
{
protected override Container Content => content;
diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs
new file mode 100644
index 0000000000..2605ae9f1b
--- /dev/null
+++ b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . 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;
+ }
+ }
+}
diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs
index 5d39ef57b2..ebab148fc2 100644
--- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs
+++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs
@@ -1,15 +1,16 @@
// Copyright (c) ppy Pty Ltd . 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();
- public Dimension[] ColumnDimensions = Array.Empty();
+ ///
+ /// The columns of this .
+ ///
+ [ItemCanBeNull]
+ public StatisticItem[] Columns;
}
}
diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs
index acaf91246d..3d81229ac3 100644
--- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs
+++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . 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) }
});
}