tbf/SharedDatabase/Output/WMChart.cs

152 lines
6.8 KiB
C#
Raw Permalink Normal View History

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<PointF> unsortedPoints = new List<PointF>();
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<PointF> 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<double> xs = new List<double>() { 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;
}
}
}