FlowChart.xaml.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using LiveCharts;
  2. using LiveCharts.Configurations;
  3. using LiveCharts.Wpf;
  4. using Newtonsoft.Json;
  5. using System;
  6. using System.Net.Http;
  7. using System.Threading.Tasks;
  8. using System.Windows.Controls;
  9. namespace FastGithub.UI
  10. {
  11. /// <summary>
  12. /// FlowChart.xaml 的交互逻辑
  13. /// </summary>
  14. public partial class FlowChart : UserControl
  15. {
  16. private readonly LineSeries readSeries = new LineSeries
  17. {
  18. Title = "上行速率",
  19. PointGeometry = null,
  20. LineSmoothness = 1D,
  21. Values = new ChartValues<RateTick>()
  22. };
  23. private readonly LineSeries writeSeries = new LineSeries()
  24. {
  25. Title = "下行速率",
  26. PointGeometry = null,
  27. LineSmoothness = 1D,
  28. Values = new ChartValues<RateTick>()
  29. };
  30. private static DateTime GetDateTime(double timestamp) => new DateTime(1970, 1, 1).Add(TimeSpan.FromMilliseconds(timestamp)).ToLocalTime();
  31. private static double GetTimestamp(DateTime dateTime) => dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
  32. public SeriesCollection Series { get; } = new SeriesCollection(Mappers.Xy<RateTick>().X(item => item.Timestamp).Y(item => item.Rate));
  33. public Func<double, string> XFormatter { get; } = timestamp => GetDateTime(timestamp).ToString("HH:mm:ss");
  34. public Func<double, string> YFormatter { get; } = value => $"{FlowStatistics.ToNetworkSizeString((long)value)}/s";
  35. public FlowChart()
  36. {
  37. InitializeComponent();
  38. this.Series.Add(this.readSeries);
  39. this.Series.Add(this.writeSeries);
  40. this.DataContext = this;
  41. this.InitFlowChartAsync();
  42. }
  43. private async void InitFlowChartAsync()
  44. {
  45. using var httpClient = new HttpClient();
  46. while (this.Dispatcher.HasShutdownStarted == false)
  47. {
  48. try
  49. {
  50. await this.FlushFlowStatisticsAsync(httpClient);
  51. }
  52. catch (Exception)
  53. {
  54. }
  55. finally
  56. {
  57. await Task.Delay(TimeSpan.FromSeconds(1d));
  58. }
  59. }
  60. }
  61. private async Task FlushFlowStatisticsAsync(HttpClient httpClient)
  62. {
  63. var response = await httpClient.GetAsync("http://127.0.0.1/flowStatistics");
  64. var json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
  65. var flowStatistics = JsonConvert.DeserializeObject<FlowStatistics>(json);
  66. if (flowStatistics == null)
  67. {
  68. return;
  69. }
  70. this.textBlockRead.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalRead);
  71. this.textBlockWrite.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalWrite);
  72. var timestamp = GetTimestamp(DateTime.Now);
  73. this.readSeries.Values.Add(new RateTick(flowStatistics.ReadRate, timestamp));
  74. this.writeSeries.Values.Add(new RateTick(flowStatistics.WriteRate, timestamp));
  75. if (this.readSeries.Values.Count > 60)
  76. {
  77. this.readSeries.Values.RemoveAt(0);
  78. this.writeSeries.Values.RemoveAt(0);
  79. }
  80. }
  81. private class RateTick
  82. {
  83. public double Rate { get; }
  84. public double Timestamp { get; }
  85. public RateTick(double rate, double timestamp)
  86. {
  87. this.Rate = rate;
  88. this.Timestamp = timestamp;
  89. }
  90. }
  91. }
  92. }