Files
CryptoProfile-Tracker/CryptoPortfolio Tracker/ViewModels/CryptoChartViewModel.cs
T

131 lines
4.0 KiB
C#

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using CommunityToolkit.Mvvm.ComponentModel;
using CryptoPortfolio_Tracker.Models;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;
namespace CryptoPortfolio_Tracker.ViewModels;
public partial class CryptoChartViewModel : ViewModelBase
{
[ObservableProperty] public partial string CryptocurrencyName { get; set; } = null!;
[ObservableProperty] public partial decimal CurrentPrice { get; set; }
[ObservableProperty] public partial decimal PriceChangePercentage24H { get; set; }
[ObservableProperty] public partial decimal PriceChange24H { get; set; }
[ObservableProperty] public partial decimal? MarketCap { get; set; }
[ObservableProperty] public partial decimal? Volume24H { get; set; }
[ObservableProperty] public partial bool IsPositive { get; set; }
[ObservableProperty] public partial bool IsNegative { get; set; }
[ObservableProperty] public partial DateTime StartDate { get; set; }
[ObservableProperty] public partial DateTime EndDate { get; set; }
public ObservableCollection<DateTimePoint> PriceHistory7D { get; } = [];
public TimeSpan UnitWidth { get; } = TimeSpan.FromHours(1);
public Func<DateTime, string> DateFormatter { get; } =
date => date.ToString("dd.MM HH:mm");
public Func<double, string> PriceFormatter { get; } =
FormatPrice;
public SolidColorPaint GridPaint { get; } =
new(new SKColor(255, 255, 255, 25));
public SolidColorPaint ChartStroke { get; } =
new(new SKColor(0x3B, 0xB3, 0x46));
public ISeries[] Series { get; private set; } = [];
public CryptoChartViewModel(Cryptocurrency cryptocurrency)
{
CryptocurrencyName = cryptocurrency.Name;
CurrentPrice = cryptocurrency.CurrentPriceUsd;
PriceChangePercentage24H = cryptocurrency.PriceChangePercentage24H ?? 0;
PriceChange24H = cryptocurrency.PriceChange24H ?? 0;
MarketCap = cryptocurrency.MarketCapUsd;
Volume24H = cryptocurrency.Volume24HUsd;
IsPositive = cryptocurrency.PriceChangePercentage24H > 0;
IsNegative = cryptocurrency.PriceChangePercentage24H < 0;
foreach (var point in cryptocurrency.PriceHistory7D)
{
PriceHistory7D.Add(point);
}
if (PriceHistory7D.Count > 0)
{
StartDate = PriceHistory7D[0].DateTime;
EndDate = PriceHistory7D[^1].DateTime;
}
UpdateSeries();
}
partial void OnStartDateChanged(DateTime value)
{
UpdateSeries();
}
partial void OnEndDateChanged(DateTime value)
{
UpdateSeries();
}
private void UpdateSeries()
{
ObservableCollection<DateTimePoint> visiblePoints = [];
foreach (var point in PriceHistory7D)
{
if (point.DateTime >= StartDate &&
point.DateTime <= EndDate)
{
visiblePoints.Add(point);
}
}
if (visiblePoints.Count == 0)
{
Series = [];
OnPropertyChanged(nameof(Series));
return;
}
LineSeries<DateTimePoint> lineSeries =
new()
{
Values = visiblePoints,
GeometrySize = 0,
Fill = null,
GeometryFill = null,
GeometryStroke = null,
Stroke = ChartStroke,
LineSmoothness = 0.2
};
Series =
[
lineSeries
];
OnPropertyChanged(nameof(Series));
}
private static string FormatPrice(double price)
{
return price switch
{
>= 1000 => price.ToString("N0", CultureInfo.InvariantCulture),
>= 1 => price.ToString("N2", CultureInfo.InvariantCulture),
>= 0.01 => price.ToString("N4", CultureInfo.InvariantCulture),
_ => price.ToString("0.########", CultureInfo.InvariantCulture)
};
}
}