move to extension class utility method.
ADD
WalletWasabi.Fluent/Helpers/EnumerableExtensions.cs
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace WalletWasabi.Fluent.Helpers
+{
+ public static class EnumerableExtensions
+ {
+ /// <summary>
+ /// Creates a time sampled dataset from a source dataset.
+ /// </summary>
+ /// <param name="sourceData">Enumerable of source data, in reverse chronological order. i.e. newest data point first.</param>
+ /// <param name="timeSampler">An expression that determines the timestamp of an entry in the source.</param>
+ /// <param name="sampler">An expression that samples or selects the data from an entry.</param>
+ /// <param name="interval">The timespan between each sample.</param>
+ /// <param name="endTime">The oldest time offset where the sampling will end.</param>
+ /// <param name="startFrom">The time to start from.</param>
+ /// <typeparam name="TSource">The type of the elements in the dataset.</typeparam>
+ /// <typeparam name="TResult">The type of the sampled data.</typeparam>
+ /// <returns>A new IEnumerable if the Selected data at each sample point.</returns>
+ public static IEnumerable<(DateTimeOffset timestamp, TResult result)> SelectTimeSampleBackwards<TSource, TResult>(
+ this IEnumerable<TSource> sourceData,
+ Func<TSource, DateTimeOffset> timeSampler, Func<TSource, TResult> sampler,
+ TimeSpan interval, DateTimeOffset endTime, DateTimeOffset? startFrom = default)
+ {
+ var source = sourceData.ToArray();
+
+ if (!source.Any())
+ {
+ yield break;
+ }
+
+ var currentTime = startFrom ?? timeSampler(source.First());
+
+ var lastFound = startFrom is { }
+ ? (timestamp: currentTime, result: sampler(source.FirstOrDefault(x=>timeSampler(x) <= currentTime)!))
+ : (timestamp: currentTime, result: sampler(source.First()));
+
+ yield return lastFound;
+
+ currentTime -= interval;
+
+ while (currentTime > endTime)
+ {
+ var current = source.FirstOrDefault(x => timeSampler(x) <= currentTime);
+
+ if (current is { })
+ {
+ lastFound = (currentTime, sampler(current));
+
+ yield return lastFound;
+ }
+ else
+ {
+ yield break;
+ }
+
+ currentTime -= interval;
+ }
+ }
+ }
+}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/WalletBalanceChartTileViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/WalletBalanceChartTileViewModel.cs
@@ -6,75 +6,13 @@ using System.Windows.Input;
using DynamicData.Binding;
using NBitcoin;
using ReactiveUI;
+using WalletWasabi.Fluent.Helpers;
using WalletWasabi.Fluent.ViewModels.Wallets.Home.History;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles
{
- public static class EnumerableExtensions
- {
- /// <summary>
- /// Creates a time sampled dataset from a source dataset.
- /// </summary>
- /// <param name="sourceData">Enumerable of source data, in reverse chronological order. i.e. newest data point first.</param>
- /// <param name="timeSampler">An expression that determines the timestamp of an entry in the source.</param>
- /// <param name="sampler">An expression that samples or selects the data from an entry.</param>
- /// <param name="interval">The timespan between each sample.</param>
- /// <param name="endTime">The oldest time offset where the sampling will end.</param>
- /// <param name="startFrom">The time to start from.</param>
- /// <typeparam name="TSource">The type of the elements in the dataset.</typeparam>
- /// <typeparam name="TResult">The type of the sampled data.</typeparam>
- /// <returns></returns>
- public static IEnumerable<(DateTimeOffset timestamp, TResult result)> SelectTimeSampleBackwards<TSource, TResult>(
- this IEnumerable<TSource> sourceData,
- Func<TSource, DateTimeOffset> timeSampler, Func<TSource, TResult> sampler,
- TimeSpan interval, DateTimeOffset endTime, DateTimeOffset? startFrom = default)
- {
- var source = sourceData.ToArray();
-
- if (!source.Any())
- {
- yield break;
- }
-
- var currentTime = startFrom ?? timeSampler(source.First());
-
- var lastFound = startFrom is { }
- ? (timestamp: currentTime, result: sampler(source.FirstOrDefault(x=>timeSampler(x) <= currentTime)!))
- : (timestamp: currentTime, result: sampler(source.First()));
-
- yield return lastFound;
-
- currentTime -= interval;
-
- while (currentTime > endTime)
- {
- var current = source.FirstOrDefault(x => timeSampler(x) <= currentTime);
-
- if (current is { })
- {
- lastFound = (currentTime, sampler(current));
-
- yield return lastFound;
- }
- else
- {
- yield break;
- }
-
- currentTime -= interval;
- }
- }
- }
-
public partial class WalletBalanceChartTileViewModel : TileViewModel
{
- private readonly ReadOnlyObservableCollection<HistoryItemViewModel> _history;
- [AutoNotify] private ObservableCollection<double> _yValues;
- [AutoNotify] private ObservableCollection<double> _xValues;
- [AutoNotify] private double? _xMinimum;
- [AutoNotify] private List<string>? _yLabels;
- [AutoNotify] private List<string>? _xLabels;
-
enum TimePeriodOption
{
All,
@@ -86,16 +24,21 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles
Year
}
+ private readonly ReadOnlyObservableCollection<HistoryItemViewModel> _history;
+ [AutoNotify] private ObservableCollection<double> _yValues;
+ [AutoNotify] private ObservableCollection<double> _xValues;
+ [AutoNotify] private double? _xMinimum;
+ [AutoNotify] private List<string>? _yLabels;
+ [AutoNotify] private List<string>? _xLabels;
private TimePeriodOption _currentTimePeriod = TimePeriodOption.ThreeMonths;
-
public WalletBalanceChartTileViewModel(ReadOnlyObservableCollection<HistoryItemViewModel> history)
{
_history = history;
_yValues = new ObservableCollection<double>();
_xValues = new ObservableCollection<double>();
- var filtered = _history.ToObservableChangeSet().Subscribe(_ => UpdateSample ());
+ _history.ToObservableChangeSet().Subscribe(_ => UpdateSample ());
DayCommand = ReactiveCommand.Create(() => UpdateSample(TimePeriodOption.Day));

move to extension class utility method.