using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms.DataVisualization.Charting; using Common; using SharedDatabase.Entities; using SharedDatabase.Resources; namespace SharedDatabase.Output { public class WMChart { public static Chart GetChart(WaterMeter wm, bool isPrinter) { return GetChart(wm, isPrinter, Common.Unit.lph); } public static Chart GetChart(WaterMeter wm, bool isPrinter, Common.Unit flowUnit) { double maxFlow_m3h = 0; IList unsortedPoints = new List(); foreach (var mtr in wm.RegularMeterTestRslts()) { if (mtr.IsPilotRslt() && mtr.TestRslt.TestData.Evaluate && (mtr.TestRslt.TestTime > 0) && (mtr.TestRslt.PulsesMaster > 0)) { double flow_m3h = (mtr.TestTime != 0) ? (3.6 * mtr.TestRslt.VolumeCTV / mtr.TestTime * mtr.PulsesMaster / mtr.TestRslt.PulsesMaster) : (3.6 * mtr.TestRslt.VolumeCTV / mtr.TestRslt.TestTime); if (flow_m3h > maxFlow_m3h) maxFlow_m3h = flow_m3h; double flow = Common.Units.ConvertTo(flowUnit, flow_m3h); /// Convert to specified units if (flow > 0) { unsortedPoints.Add(new PointF((float)flow, (float)mtr.Error)); } } } IEnumerable sortedPoints = unsortedPoints.OrderBy(x => x.X); bool isQ4 = (maxFlow_m3h > 1.1 * wm.WaterMeterData.Q3_Qn); Chart chart = new Chart { Name = "chart", Text = "chart", Dock = System.Windows.Forms.DockStyle.Fill, TabIndex = 0, Size = new System.Drawing.Size(5, 5), Location = new System.Drawing.Point(3, 3), }; ChartArea chArea = new ChartArea { Name = "ChartArea1" }; chArea.AxisX.Title = Strings.Flow; chArea.AxisX.IsLogarithmic = true; chArea.AxisX.LogarithmBase = 10; chArea.AxisX.IsLabelAutoFit = true; List xs = new List() { 0.0001, 0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000 }; double spacer = 0.8; double from = Common.Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin); double to = Common.Units.ConvertTo(flowUnit, isQ4 ? wm.WaterMeterData.Q4_Qmax : wm.WaterMeterData.Q3_Qn); bool inRange = false; for (int i = 0; i < xs.Count - 3; i += 3) { if (xs[i] <= from && from < xs[i + 3]) { chArea.AxisX.Minimum = xs[i]; inRange = true; } if (inRange) { for (int j = i; j < i + 3; j++) { CustomLabel cl = new CustomLabel(); cl.Text = string.Format("{0} {1}", xs[j], flowUnit.ToDescription()); cl.FromPosition = Math.Log10(xs[j] * spacer); cl.ToPosition = Math.Log10(xs[j] / spacer); chArea.AxisX.CustomLabels.Add(cl); } } if (xs[i] < to && to <= xs[i + 3]) { chArea.AxisX.Maximum = xs[i + 3]; CustomLabel cl = new CustomLabel(); cl.Text = string.Format("{0} {1}", xs[i + 3], flowUnit.ToDescription()); cl.FromPosition = Math.Log10(xs[i + 3] * spacer); cl.ToPosition = Math.Log10(xs[i + 3] / spacer); chArea.AxisX.CustomLabels.Add(cl); break; } } chArea.AxisY.Title = Strings.Relative_error; chArea.AxisY.Interval = 3; chArea.AxisY.LabelStyle.Format = "{#} %"; Legend legend1 = new Legend { Name = "Legend1" }; Series upperLimit = new Series { Name = Strings.Upper_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red }; upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), 5); upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), 5); upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), 2); upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), 2); if (isQ4) upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), 2); Series lowerLimit = new Series { Name = Strings.Lower_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red }; lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), -5); lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -5); lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -2); lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), -2); if (isQ4) lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), -2); Series line = new Series { Name = Strings.Relative_error, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.DeepSkyBlue }; Series dots = new Series { Name = Strings.Relative_error + " ", ChartArea = "ChartArea1", ChartType = SeriesChartType.Point, Color = Color.RoyalBlue }; dots.MarkerStyle = MarkerStyle.Circle; if (isPrinter) dots.MarkerSize = 1; foreach (var point in sortedPoints) { line.Points.AddXY(point.X, point.Y); dots.Points.AddXY(point.X, point.Y); } chart.ChartAreas.Add(chArea); chart.Legends.Add(legend1); chart.Series.Add(upperLimit); chart.Series.Add(lowerLimit); chart.Series.Add(dots); chart.Series.Add(line); return chart; } } }