using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Wpf;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace FastGithub.UI
{
///
/// FlowChart.xaml 的交互逻辑
///
public partial class FlowChart : UserControl
{
private readonly LineSeries readSeries = new LineSeries
{
Title = "上行速率",
PointGeometry = null,
LineSmoothness = 1D,
Values = new ChartValues()
};
private readonly LineSeries writeSeries = new LineSeries()
{
Title = "下行速率",
PointGeometry = null,
LineSmoothness = 1D,
Values = new ChartValues()
};
private static DateTime GetDateTime(double timestamp) => new DateTime(1970, 1, 1).Add(TimeSpan.FromMilliseconds(timestamp)).ToLocalTime();
private static double GetTimestamp(DateTime dateTime) => dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
public SeriesCollection Series { get; } = new SeriesCollection(Mappers.Xy().X(item => item.Timestamp).Y(item => item.Rate));
public Func XFormatter { get; } = timestamp => GetDateTime(timestamp).ToString("HH:mm:ss");
public Func YFormatter { get; } = value => $"{FlowStatistics.ToNetworkSizeString((long)value)}/s";
public FlowChart()
{
InitializeComponent();
this.Series.Add(this.readSeries);
this.Series.Add(this.writeSeries);
this.DataContext = this;
this.InitFlowChartAsync();
}
private async void InitFlowChartAsync()
{
using var httpClient = new HttpClient();
while (this.Dispatcher.HasShutdownStarted == false)
{
try
{
await this.FlushFlowStatisticsAsync(httpClient);
}
catch (Exception)
{
}
finally
{
await Task.Delay(TimeSpan.FromSeconds(1d));
}
}
}
private async Task FlushFlowStatisticsAsync(HttpClient httpClient)
{
var response = await httpClient.GetAsync("http://localhost/flowStatistics");
var json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
var flowStatistics = JsonConvert.DeserializeObject(json);
if (flowStatistics == null)
{
return;
}
this.textBlockRead.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalRead);
this.textBlockWrite.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalWrite);
var timestamp = GetTimestamp(DateTime.Now);
this.readSeries.Values.Add(new RateTick(flowStatistics.ReadRate, timestamp));
this.writeSeries.Values.Add(new RateTick(flowStatistics.WriteRate, timestamp));
if (this.readSeries.Values.Count > 60)
{
this.readSeries.Values.RemoveAt(0);
this.writeSeries.Values.RemoveAt(0);
}
}
private class RateTick
{
public double Rate { get; }
public double Timestamp { get; }
public RateTick(double rate, double timestamp)
{
this.Rate = rate;
this.Timestamp = timestamp;
}
}
}
}