using Billing.Models; using Billing.Themes; using Billing.UI; using Microcharts; using SkiaSharp; using SkiaSharp.Views.Forms; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Xamarin.Essentials; using Xamarin.Forms; using Resource = Billing.Languages.Resource; namespace Billing.Views { public partial class RankPage : BillingPage { private static readonly BindableProperty ChartProperty = Helper.Create(nameof(Chart)); private static readonly BindableProperty TopBillsProperty = Helper.Create, RankPage>(nameof(TopBills)); private static readonly BindableProperty NoResultProperty = Helper.Create(nameof(NoResult)); public Chart Chart { get => (Chart)GetValue(ChartProperty); set => SetValue(ChartProperty, value); } public IList TopBills { get => (IList)GetValue(TopBillsProperty); set => SetValue(TopBillsProperty, value); } public bool NoResult { get => (bool)GetValue(NoResultProperty); set => SetValue(NoResultProperty, value); } public Command LeftCommand { get; } public Command RightCommand { get; } public Command FilterCommand { get; } private DateTime current; private IEnumerable bills; private CategoryType type = CategoryType.Spending; public RankPage() { LeftCommand = new Command(OnLeftCommand); RightCommand = new Command(OnRightCommand); InitializeComponent(); } public override void OnLoaded() { Task.Run(() => SetMonth(DateTime.Today)); } private void OnLeftCommand() { Task.Run(() => { MainThread.BeginInvokeOnMainThread(async () => await scroller.ScrollToAsync(0, 0, true)); SetMonth(current.AddMonths(-1)); }); } private void OnRightCommand() { Task.Run(() => { MainThread.BeginInvokeOnMainThread(async () => await scroller.ScrollToAsync(0, 0, true)); SetMonth(current.AddMonths(1)); }); } private void SetMonth(DateTime date) { current = date.AddDays(1 - date.Day); var end = current.AddDays(DateTime.DaysInMonth(current.Year, current.Month)); var format = Resource.DateRangeFormat; Title = current.ToString(format) + " ~ " + end.AddDays(-1).ToString(format); bills = App.Bills.Where(b => b.CreateTime >= current && b.CreateTime <= end); var entries = new List(); var primaryColor = BaseTheme.CurrentPrimaryColor.ToSKColor(); var textColor = BaseTheme.CurrentSecondaryTextColor.ToSKColor(); for (var day = current; day <= end; day = day.AddDays(1)) { var daybills = bills.Where(b => Helper.IsSameDay(b.CreateTime, day)); decimal amount; if (type == CategoryType.Income) { amount = daybills.Where(b => b.Amount > 0).Sum(b => b.Amount); } else { amount = daybills.Where(b => b.Amount < 0).Sum(b => -b.Amount); } if (amount > 0) { entries.Add(new((float)amount) { Label = day.ToString("MM-dd"), ValueLabel = amount.ToString("#,##0.##"), Color = primaryColor, TextColor = textColor, ValueLabelColor = textColor }); } } if (entries.Count > 0) { NoResult = false; Chart = new LineChart { BackgroundColor = SKColors.Transparent, LabelTextSize = 24, Entries = entries }; if (type == CategoryType.Income) { TopBills = bills.Where(b => b.Amount > 0).OrderByDescending(b => b.Amount).Take(10).Select(b => Helper.WrapBill(b)).ToList(); } else { TopBills = bills.Where(b => b.Amount < 0).OrderBy(b => b.Amount).Take(10).Select(b => Helper.WrapBill(b)).ToList(); } } else { NoResult = true; Chart = null; TopBills = null; } } } }