|
- using System;
- using System.Drawing;
- using System.Collections.Generic;
- using System.Data;
- using System.Linq;
- using System.Windows.Forms;
- using System.Windows.Forms.DataVisualization.Charting;
- using Shadowsocks.Controller;
- using Shadowsocks.Model;
- using Shadowsocks.Properties;
-
- namespace Shadowsocks.View
- {
- public partial class StatisticsStrategyConfigurationForm : Form
- {
- private readonly ShadowsocksController _controller;
- private StatisticsStrategyConfiguration _configuration;
- private readonly DataTable _dataTable = new DataTable();
- private List<string> _servers;
- private readonly Series _speedSeries;
- private readonly Series _packageLossSeries;
- private readonly Series _pingSeries;
-
- public StatisticsStrategyConfigurationForm(ShadowsocksController controller)
- {
- if (controller == null) return;
- InitializeComponent();
- Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
- _speedSeries = StatisticsChart.Series["Speed"];
- _packageLossSeries = StatisticsChart.Series["Package Loss"];
- _pingSeries = StatisticsChart.Series["Ping"];
- _controller = controller;
- _controller.ConfigChanged += (sender, args) => LoadConfiguration();
- UpdateTexts();
- LoadConfiguration();
- Load += (sender, args) => InitData();
- }
-
- private void UpdateTexts()
- {
- I18N.TranslateForm(this);
-
- foreach (var item in StatisticsChart.Series)
- {
- item.Name = I18N.GetString(item.Name);
- }
-
- }
- private void LoadConfiguration()
- {
- var configs = _controller.GetCurrentConfiguration().configs;
- _servers = configs.Select(server => server.Identifier()).ToList();
- _configuration = _controller.StatisticsConfiguration
- ?? new StatisticsStrategyConfiguration();
- if (_configuration.Calculations == null)
- {
- _configuration = new StatisticsStrategyConfiguration();
- }
- }
-
- private void InitData()
- {
- bindingConfiguration.Add(_configuration);
- foreach (var kv in _configuration.Calculations)
- {
- var calculation = new CalculationControl(I18N.GetString(kv.Key), kv.Value);
- calculationContainer.Controls.Add(calculation);
- }
-
- serverSelector.DataSource = _servers;
-
- _dataTable.Columns.Add("Timestamp", typeof(DateTime));
- _dataTable.Columns.Add("Speed", typeof(int));
- _speedSeries.XValueMember = "Timestamp";
- _speedSeries.YValueMembers = "Speed";
-
- // might be empty
- _dataTable.Columns.Add("Package Loss", typeof(int));
- _dataTable.Columns.Add("Ping", typeof(int));
- _packageLossSeries.XValueMember = "Timestamp";
- _packageLossSeries.YValueMembers = "Package Loss";
- _pingSeries.XValueMember = "Timestamp";
- _pingSeries.YValueMembers = "Ping";
-
- StatisticsChart.DataSource = _dataTable;
- LoadChartData();
- StatisticsChart.DataBind();
- }
-
- private void CancelButton_Click(object sender, EventArgs e)
- {
- Close();
- }
-
- private void OKButton_Click(object sender, EventArgs e)
- {
- foreach (CalculationControl calculation in calculationContainer.Controls)
- {
- _configuration.Calculations[calculation.Value] = calculation.Factor;
- }
- _controller?.SaveStrategyConfigurations(_configuration);
- _controller?.UpdateStatisticsConfiguration(StatisticsEnabledCheckBox.Checked);
- Close();
- }
-
- private void LoadChartData()
- {
- var serverName = _servers[serverSelector.SelectedIndex];
- _dataTable.Rows.Clear();
-
- //return directly when no data is usable
- if (_controller.availabilityStatistics?.FilteredStatistics == null) return;
- List<StatisticsRecord> statistics;
- if (!_controller.availabilityStatistics.FilteredStatistics.TryGetValue(serverName, out statistics)) return;
- IEnumerable<IGrouping<int, StatisticsRecord>> dataGroups;
- if (allMode.Checked)
- {
- _pingSeries.XValueType = ChartValueType.DateTime;
- _packageLossSeries.XValueType = ChartValueType.DateTime;
- _speedSeries.XValueType = ChartValueType.DateTime;
- dataGroups = statistics.GroupBy(data => data.Timestamp.DayOfYear);
- StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "g";
- StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "g";
- }
- else
- {
- _pingSeries.XValueType = ChartValueType.Time;
- _packageLossSeries.XValueType = ChartValueType.Time;
- _speedSeries.XValueType = ChartValueType.Time;
- dataGroups = statistics.GroupBy(data => data.Timestamp.Hour);
- StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "HH:00";
- StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "HH:00";
- }
- var finalData = from dataGroup in dataGroups
- orderby dataGroup.Key
- select new
- {
- dataGroup.First().Timestamp,
- Speed = dataGroup.Max(data => data.MaxInboundSpeed) ?? 0,
- Ping = (int)(dataGroup.Average(data => data.AverageResponse) ?? 0),
- PackageLossPercentage = (int)(dataGroup.Average(data => data.PackageLoss) ?? 0) * 100
- };
- foreach (var data in finalData.Where(data => data.Speed != 0 || data.PackageLossPercentage != 0 || data.Ping != 0))
- {
- _dataTable.Rows.Add(data.Timestamp, data.Speed, data.PackageLossPercentage, data.Ping);
- }
- StatisticsChart.DataBind();
- }
-
- private void serverSelector_SelectionChangeCommitted(object sender, EventArgs e)
- {
- LoadChartData();
- }
-
- private void dayMode_CheckedChanged(object sender, EventArgs e)
- {
- LoadChartData();
- }
-
- private void allMode_CheckedChanged(object sender, EventArgs e)
- {
- LoadChartData();
- }
-
- private void PingCheckBox_CheckedChanged(object sender, EventArgs e)
- {
- repeatTimesNum.ReadOnly = !PingCheckBox.Checked;
- }
- }
- }
|