131 lines
4.0 KiB
C#
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)
|
|
};
|
|
}
|
|
} |