/// /// Copyright (c) 2019 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using Results.Entities; using ResultsBrowser.Resources; using ResultsBrowser.Output.Printers.Statistics; namespace ResultsBrowser.Forms { public partial class HistogramDlg : Form { const int NrBins = 11; IList waterMeters; HistogramOptionsDlg options; public HistogramDlg(IList waterMeters, HistogramOptionsDlg options, string title) { InitializeComponent(); this.waterMeters = waterMeters; this.options = options; Text = title; closeButton.Text = Strings.OkBtnText; printButton.Text = Strings.Print; } private void HistogramDlg_Load(object sender, EventArgs e) { CalculateAndDraw(); } void CalculateAndDraw() { for (int i = 0; i < options.SelectedItems.Count; i++) { Results.WMeterRsltItemSpec item = options.SelectedItems[i]; try { /// Find minimum and maximum double min = Double.MaxValue; double max = Double.MinValue; double sum = 0; int count = 0; foreach (var wm in waterMeters) { string strValue = item.Print(wm); double value; if (!double.TryParse(strValue, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.CurrentCulture, out value) && !double.TryParse(strValue, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out value)) { throw new Exception(string.Format("{0} is not a number, cannot calculate histogram", item.Caption)); } sum += value; count++; if (min > value) min = value; if (max < value) max = value; } double mean = (count != 0) ? (sum / count) : 0; /// Prevent division by zero /// /// Determine limits for bins /// double[] binHiLim; string[] labels; if ((-0.55 <= min) && (max <= 0.55)) { labels = new string[] { "-0.6", "", "-0.4", "", "-0.2", "", "0", "", "0.2", "", "0.4", "", "0.6" }; binHiLim = new double[] { -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55 }; } else if ((-1.1 <= min) && (max <= 1.1)) { labels = new string[] { "-1.2", "", "-0.8", "", "-0.4", "", "0", "", "0.4", "", "0.8", "", "1.2" }; binHiLim = new double[] { -0.9, -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1 }; } else if ((-2.2 <= min) && (max <= 2.2)) { labels = new string[] { "-2.4", "", "-1.6", "", "-0.8", "", "0", "", "0.8", "", "1.6", "", "2.4" }; binHiLim = new double[] { -1.8, -1.4, -1.0, -0.6, -0.2, 0.2, 0.6, 1.0, 1.4, 1.8, 2.2 }; } else if ((-4.4 <= min) && (max <= 4.4)) { labels = new string[] { "-4.8", "", "-3.2", "", "-1.6", "", "0", "", "1.6", "", "3.2", "", "4.8" }; binHiLim = new double[] { -3.6, -2.8, -2.0, -1.2, -0.4, 0.4, 1.2, 2.0, 2.8, 3.6, 4.4 }; } else { labels = new string[] { "-9.6", "", "-6.4", "", "-3.2", "", "0", "", "3.2", "", "6.4", "", "9.6" }; binHiLim = new double[] { -7.2, -5.6, -4.0, -2.4, -0.8, 0.8, 2.4, 4.0, 5.6, 7.2, 8.8 }; } int nrBins = Math.Min(labels.Length - 1, binHiLim.Length + 1); double[] bins = new double[nrBins]; for (int j = 0; j < nrBins; j++) bins[j] = 0; /// Calculate bins foreach (var wm in waterMeters) { string strValue = item.Print(wm); double value; if (!double.TryParse(strValue, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.CurrentCulture, out value) && !double.TryParse(strValue, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out value)) { throw new Exception(string.Format("{0} is not a number, cannot calculate histogram", item.Caption)); } for (int j = 0; j < nrBins - 1; j++) { if (value < binHiLim[j]) { bins[j] += 1.0; break; } } if (value >= binHiLim[nrBins - 2]) { bins[nrBins - 1] += 1.0; } } /// /// Draw /// HistogramCtrl histo = new HistogramCtrl(string.Format("{0} mean = {1}", item.Caption, mean.ToString("F3")), bins, labels); flowLayoutPanel1.Controls.Add(histo); } catch (Exception exc) { string msg = exc.Message; } } } private void closeButton_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; Close(); } } }