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 7.3 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. Control[] controls = new Control[]
  39. {
  40. StatisticsEnabledCheckBox,PingCheckBox,PackagePerPingLabel,
  41. byHourOfDayCheckBox,CollectDataPerLabel,MinutesLabel1,KeepChoiceForLabel,MinutesLabel2,
  42. FinalScoreLabel,chartModeSelector,dayMode,allMode,
  43. OKButton,CancelButton
  44. };
  45. foreach (var item in controls)
  46. {
  47. item.Text = I18N.GetString(item.Text);
  48. }
  49. foreach (var item in StatisticsChart.Series)
  50. {
  51. item.Name = I18N.GetString(item.Name);
  52. }
  53. }
  54. private void LoadConfiguration()
  55. {
  56. var configs = _controller.GetCurrentConfiguration().configs;
  57. _servers = configs.Select(server => server.Identifier()).ToList();
  58. _configuration = _controller.StatisticsConfiguration
  59. ?? new StatisticsStrategyConfiguration();
  60. if (_configuration.Calculations == null)
  61. {
  62. _configuration = new StatisticsStrategyConfiguration();
  63. }
  64. }
  65. private void InitData()
  66. {
  67. bindingConfiguration.Add(_configuration);
  68. foreach (var kv in _configuration.Calculations)
  69. {
  70. var calculation = new CalculationControl(I18N.GetString(kv.Key), kv.Value);
  71. calculationContainer.Controls.Add(calculation);
  72. }
  73. serverSelector.DataSource = _servers;
  74. _dataTable.Columns.Add("Timestamp", typeof(DateTime));
  75. _dataTable.Columns.Add("Speed", typeof(int));
  76. _speedSeries.XValueMember = "Timestamp";
  77. _speedSeries.YValueMembers = "Speed";
  78. // might be empty
  79. _dataTable.Columns.Add("Package Loss", typeof(int));
  80. _dataTable.Columns.Add("Ping", typeof(int));
  81. _packageLossSeries.XValueMember = "Timestamp";
  82. _packageLossSeries.YValueMembers = "Package Loss";
  83. _pingSeries.XValueMember = "Timestamp";
  84. _pingSeries.YValueMembers = "Ping";
  85. StatisticsChart.DataSource = _dataTable;
  86. LoadChartData();
  87. StatisticsChart.DataBind();
  88. }
  89. private void CancelButton_Click(object sender, EventArgs e)
  90. {
  91. Close();
  92. }
  93. private void OKButton_Click(object sender, EventArgs e)
  94. {
  95. foreach (CalculationControl calculation in calculationContainer.Controls)
  96. {
  97. _configuration.Calculations[calculation.Value] = calculation.Factor;
  98. }
  99. _controller?.SaveStrategyConfigurations(_configuration);
  100. _controller?.UpdateStatisticsConfiguration(StatisticsEnabledCheckBox.Checked);
  101. Close();
  102. }
  103. private void LoadChartData()
  104. {
  105. var serverName = _servers[serverSelector.SelectedIndex];
  106. _dataTable.Rows.Clear();
  107. //return directly when no data is usable
  108. if (_controller.availabilityStatistics?.FilteredStatistics == null) return;
  109. List<StatisticsRecord> statistics;
  110. if (!_controller.availabilityStatistics.FilteredStatistics.TryGetValue(serverName, out statistics)) return;
  111. IEnumerable<IGrouping<int, StatisticsRecord>> dataGroups;
  112. if (allMode.Checked)
  113. {
  114. _pingSeries.XValueType = ChartValueType.DateTime;
  115. _packageLossSeries.XValueType = ChartValueType.DateTime;
  116. _speedSeries.XValueType = ChartValueType.DateTime;
  117. dataGroups = statistics.GroupBy(data => data.Timestamp.DayOfYear);
  118. StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "g";
  119. StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "g";
  120. }
  121. else
  122. {
  123. _pingSeries.XValueType = ChartValueType.Time;
  124. _packageLossSeries.XValueType = ChartValueType.Time;
  125. _speedSeries.XValueType = ChartValueType.Time;
  126. dataGroups = statistics.GroupBy(data => data.Timestamp.Hour);
  127. StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "HH:00";
  128. StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "HH:00";
  129. }
  130. var finalData = from dataGroup in dataGroups
  131. orderby dataGroup.Key
  132. select new
  133. {
  134. dataGroup.First().Timestamp,
  135. Speed = dataGroup.Max(data => data.MaxInboundSpeed) ?? 0,
  136. Ping = (int)(dataGroup.Average(data => data.AverageResponse) ?? 0),
  137. PackageLossPercentage = (int)(dataGroup.Average(data => data.PackageLoss) ?? 0) * 100
  138. };
  139. foreach (var data in finalData.Where(data => data.Speed != 0 || data.PackageLossPercentage != 0 || data.Ping != 0))
  140. {
  141. _dataTable.Rows.Add(data.Timestamp, data.Speed, data.PackageLossPercentage, data.Ping);
  142. }
  143. StatisticsChart.DataBind();
  144. }
  145. private void serverSelector_SelectionChangeCommitted(object sender, EventArgs e)
  146. {
  147. LoadChartData();
  148. }
  149. private void dayMode_CheckedChanged(object sender, EventArgs e)
  150. {
  151. LoadChartData();
  152. }
  153. private void allMode_CheckedChanged(object sender, EventArgs e)
  154. {
  155. LoadChartData();
  156. }
  157. private void PingCheckBox_CheckedChanged(object sender, EventArgs e)
  158. {
  159. repeatTimesNum.ReadOnly = !PingCheckBox.Checked;
  160. }
  161. }
  162. }