You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

StatisticsStrategyConfigurationForm.cs 6.9 kB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Drawing;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Linq;
  6. using System.Windows.Forms;
  7. using System.Windows.Forms.DataVisualization.Charting;
  8. using Shadowsocks.Controller;
  9. using Shadowsocks.Model;
  10. using Shadowsocks.Properties;
  11. namespace Shadowsocks.View
  12. {
  13. public partial class StatisticsStrategyConfigurationForm : Form
  14. {
  15. private readonly ShadowsocksController _controller;
  16. private StatisticsStrategyConfiguration _configuration;
  17. private readonly DataTable _dataTable = new DataTable();
  18. private List<string> _servers;
  19. private readonly Series _speedSeries;
  20. private readonly Series _packageLossSeries;
  21. private readonly Series _pingSeries;
  22. public StatisticsStrategyConfigurationForm(ShadowsocksController controller)
  23. {
  24. if (controller == null) return;
  25. InitializeComponent();
  26. Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
  27. _speedSeries = StatisticsChart.Series["Speed"];
  28. _packageLossSeries = StatisticsChart.Series["Package Loss"];
  29. _pingSeries = StatisticsChart.Series["Ping"];
  30. _controller = controller;
  31. _controller.ConfigChanged += (sender, args) => LoadConfiguration();
  32. UpdateTexts();
  33. LoadConfiguration();
  34. Load += (sender, args) => InitData();
  35. }
  36. private void UpdateTexts()
  37. {
  38. I18N.TranslateForm(this);
  39. foreach (var item in StatisticsChart.Series)
  40. {
  41. item.Name = I18N.GetString(item.Name);
  42. }
  43. }
  44. private void LoadConfiguration()
  45. {
  46. var configs = _controller.GetCurrentConfiguration().configs;
  47. _servers = configs.Select(server => server.Identifier()).ToList();
  48. _configuration = _controller.StatisticsConfiguration
  49. ?? new StatisticsStrategyConfiguration();
  50. if (_configuration.Calculations == null)
  51. {
  52. _configuration = new StatisticsStrategyConfiguration();
  53. }
  54. }
  55. private void InitData()
  56. {
  57. bindingConfiguration.Add(_configuration);
  58. foreach (var kv in _configuration.Calculations)
  59. {
  60. var calculation = new CalculationControl(I18N.GetString(kv.Key), kv.Value);
  61. calculationContainer.Controls.Add(calculation);
  62. }
  63. serverSelector.DataSource = _servers;
  64. _dataTable.Columns.Add("Timestamp", typeof(DateTime));
  65. _dataTable.Columns.Add("Speed", typeof(int));
  66. _speedSeries.XValueMember = "Timestamp";
  67. _speedSeries.YValueMembers = "Speed";
  68. // might be empty
  69. _dataTable.Columns.Add("Package Loss", typeof(int));
  70. _dataTable.Columns.Add("Ping", typeof(int));
  71. _packageLossSeries.XValueMember = "Timestamp";
  72. _packageLossSeries.YValueMembers = "Package Loss";
  73. _pingSeries.XValueMember = "Timestamp";
  74. _pingSeries.YValueMembers = "Ping";
  75. StatisticsChart.DataSource = _dataTable;
  76. LoadChartData();
  77. StatisticsChart.DataBind();
  78. }
  79. private void CancelButton_Click(object sender, EventArgs e)
  80. {
  81. Close();
  82. }
  83. private void OKButton_Click(object sender, EventArgs e)
  84. {
  85. foreach (CalculationControl calculation in calculationContainer.Controls)
  86. {
  87. _configuration.Calculations[calculation.Value] = calculation.Factor;
  88. }
  89. _controller?.SaveStrategyConfigurations(_configuration);
  90. _controller?.UpdateStatisticsConfiguration(StatisticsEnabledCheckBox.Checked);
  91. Close();
  92. }
  93. private void LoadChartData()
  94. {
  95. var serverName = _servers[serverSelector.SelectedIndex];
  96. _dataTable.Rows.Clear();
  97. //return directly when no data is usable
  98. if (_controller.availabilityStatistics?.FilteredStatistics == null) return;
  99. List<StatisticsRecord> statistics;
  100. if (!_controller.availabilityStatistics.FilteredStatistics.TryGetValue(serverName, out statistics)) return;
  101. IEnumerable<IGrouping<int, StatisticsRecord>> dataGroups;
  102. if (allMode.Checked)
  103. {
  104. _pingSeries.XValueType = ChartValueType.DateTime;
  105. _packageLossSeries.XValueType = ChartValueType.DateTime;
  106. _speedSeries.XValueType = ChartValueType.DateTime;
  107. dataGroups = statistics.GroupBy(data => data.Timestamp.DayOfYear);
  108. StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "g";
  109. StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "g";
  110. }
  111. else
  112. {
  113. _pingSeries.XValueType = ChartValueType.Time;
  114. _packageLossSeries.XValueType = ChartValueType.Time;
  115. _speedSeries.XValueType = ChartValueType.Time;
  116. dataGroups = statistics.GroupBy(data => data.Timestamp.Hour);
  117. StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "HH:00";
  118. StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "HH:00";
  119. }
  120. var finalData = from dataGroup in dataGroups
  121. orderby dataGroup.Key
  122. select new
  123. {
  124. dataGroup.First().Timestamp,
  125. Speed = dataGroup.Max(data => data.MaxInboundSpeed) ?? 0,
  126. Ping = (int)(dataGroup.Average(data => data.AverageResponse) ?? 0),
  127. PackageLossPercentage = (int)(dataGroup.Average(data => data.PackageLoss) ?? 0) * 100
  128. };
  129. foreach (var data in finalData.Where(data => data.Speed != 0 || data.PackageLossPercentage != 0 || data.Ping != 0))
  130. {
  131. _dataTable.Rows.Add(data.Timestamp, data.Speed, data.PackageLossPercentage, data.Ping);
  132. }
  133. StatisticsChart.DataBind();
  134. }
  135. private void serverSelector_SelectionChangeCommitted(object sender, EventArgs e)
  136. {
  137. LoadChartData();
  138. }
  139. private void dayMode_CheckedChanged(object sender, EventArgs e)
  140. {
  141. LoadChartData();
  142. }
  143. private void allMode_CheckedChanged(object sender, EventArgs e)
  144. {
  145. LoadChartData();
  146. }
  147. private void PingCheckBox_CheckedChanged(object sender, EventArgs e)
  148. {
  149. repeatTimesNum.ReadOnly = !PingCheckBox.Checked;
  150. }
  151. }
  152. }