using Hydro.CommonBase;
|
using Hydro.CommonBase;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Data;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
using System.Windows.Forms.DataVisualization.Charting;
|
using static Hydro.Core.ObjectEnum;
|
|
namespace Hydro.MapView
|
{
|
[Serializable]
|
public class PumpViewModel : LinkViewModel
|
{
|
public static List<string> CurveStrings=new List<string> { "流量扬程曲线", "流量功率曲线", "流量效率曲线" };
|
|
[Browsable(false)]
|
public new string Name
|
{
|
get { return base.Name; }
|
set { base.Name = value; }
|
}
|
[Category("1、基本信息")]
|
[DisplayName("水泵类型")]
|
public new PumpType Type { get; set; }
|
|
[Browsable(false)]
|
public dict<string, Dataset> Datasets { get; set; } = new dict<string, Dataset>();
|
|
|
[Category("2、计算参数")]
|
public double 额定转速 { get; set; } = 1500;
|
|
[Category("2、计算参数")]
|
public double 额定流量 { get; set; } = 200;
|
[Category("2、计算参数")]
|
public double 额定扬程 { get; set; } = 50;
|
[Category("2、计算参数")]
|
public double 额定功率 { get; set; } = 75;
|
|
public double 转速比 { get; set; } = 1;
|
|
[DisplayName("2)当前转速")]
|
[Category("2、计算参数")]
|
public double 当前转速 { get; set; } = 1500;
|
|
[Browsable(false)]
|
public Dataset 流量扬程曲线
|
{
|
get
|
{
|
if (!Datasets.ContainsKey("流量扬程曲线")) Datasets.Add("流量扬程曲线", new Dataset("流量扬程曲线", null));
|
return Datasets["流量扬程曲线"];
|
}
|
}
|
[Browsable(false)]
|
public Dataset 流量功率曲线
|
{
|
get
|
{
|
if (!Datasets.ContainsKey("流量功率曲线")) Datasets.Add("流量功率曲线", new Dataset("流量功率曲线", null));
|
return Datasets["流量功率曲线"];
|
}
|
}
|
[Browsable(false)]
|
public Dataset 流量效率曲线
|
{
|
get
|
{
|
if (!Datasets.ContainsKey("流量效率曲线")) Datasets.Add("流量效率曲线", new Dataset("流量效率曲线", null));
|
return Datasets["流量效率曲线"];
|
}
|
}
|
[Browsable(false)]
|
public string factoryName
|
{
|
set; get;
|
//get
|
//{
|
// if (factory != null)
|
// return factory.Name;
|
// else
|
// return null;
|
//}
|
}
|
[Browsable(false)]
|
[JsonIgnore]
|
|
public Factory factory { get; set; } = null;
|
|
|
public PumpViewModel Copy()
|
{
|
PumpViewModel p = new PumpViewModel();
|
p.Name = Name;
|
p.额定流量 = 额定流量;
|
p.额定扬程 = 额定扬程;
|
p.额定功率 = 额定功率;
|
p.额定转速 = 额定转速;
|
p.当前转速 = 当前转速;
|
p.Type = Type;
|
p.factory = factory;
|
//为Datasets添加CurveStrings数据
|
foreach (var str in CurveStrings)
|
{
|
if (!p.Datasets.ContainsKey(str))
|
{
|
p.Datasets.Add(str, new Dataset(str,p));
|
}
|
}
|
|
foreach (var pair in Datasets)
|
{
|
List<PointF> list = new List<PointF>();
|
pair.Value._data.ForEach(m => list.Add(m));
|
p.Datasets[pair.Key].Data = list;
|
DRange rangeDefault = new DRange(double.MaxValue, double.MinValue);
|
p.Datasets[pair.Key].range_X = DRange.Union(rangeDefault, pair.Value.range_X);
|
p.Datasets[pair.Key].range_Y = DRange.Union(rangeDefault, pair.Value.range_Y);
|
}
|
p.CurveFit();
|
return p;
|
//factory.Pumps.Add(p);
|
//_EditFlag = true;
|
//DisplayFactoryListInTreeView(factoryList);
|
}
|
|
public void CurveFit()
|
{
|
|
|
foreach (var data in Datasets)
|
{
|
data.Value.Data.Sort((a, b) => a.X > b.X ? 1 : (a.X == b.X ? 0 : -1));
|
if (data.Value.HasData) data.Value.CurveFit();
|
}
|
string basetype = "流量扬程曲线";
|
string type = "";
|
|
|
type = "流量效率曲线";
|
var type1 = "流量功率曲线";
|
if (!Datasets.ContainsKey(type)) Datasets.Add(type, new Dataset(type, null));
|
if (!Datasets.ContainsKey(type1)) Datasets.Add(type1, new Dataset(type1, null));
|
if (Datasets[type].IsFitted && !Datasets[type1].IsFitted)
|
{
|
List<PointF> points = new List<PointF>();
|
List<PointF> points1 = new List<PointF>();
|
|
foreach (var yc in Datasets[basetype].Data)
|
{
|
float x = yc.X;
|
float y_扬程 = yc.Y;
|
|
float y_效率 = (float)Datasets[type].Evaluate(x);
|
float y_功率 = (float)x * y_扬程 / y_效率 / 3.6f;
|
points.Add(new PointF(x, y_效率));
|
points1.Add(new PointF(x, y_功率));
|
}
|
Datasets[type].Data = points;
|
Datasets[type1].Data = points1;
|
Datasets[type].CurveFit();
|
Datasets[type1].CurveFit();
|
}
|
|
|
|
if (!Datasets[type].IsFitted && Datasets[type1].IsFitted)
|
{
|
List<PointF> points = new List<PointF>();
|
List<PointF> points1 = new List<PointF>();
|
|
foreach (var yc in Datasets[basetype].Data)
|
{
|
float x = yc.X;
|
float y_扬程 = yc.Y;
|
float y_功率 = (float)Datasets[type1].Evaluate(x);
|
float y_效率 = (float)x * y_扬程 / y_功率 / 3.6f;
|
|
points.Add(new PointF(x, y_效率));
|
points1.Add(new PointF(x, y_功率));
|
|
|
}
|
Datasets[type].Data = points;
|
Datasets[type1].Data = points1;
|
Datasets[type].CurveFit();
|
Datasets[type1].CurveFit();
|
}
|
|
}
|
|
public void ShowInGrid(DataGridView dataGridView)
|
{
|
dataGridView.Rows.Clear();
|
// if ()
|
for (int i = 0; i < 流量扬程曲线.Data.Count; i++)
|
{
|
PointF p = 流量扬程曲线.Data[i];
|
PointF p_temp;
|
double y1 = 0, y2 = 0;
|
if (流量功率曲线.IsFitted)
|
{
|
if ((p_temp = 流量功率曲线.Data.Find(p0 => p0.X == p.X)) == default(PointF))
|
y1 = 流量功率曲线.Evaluate(p.X);
|
else
|
y1 = p_temp.Y;
|
}
|
|
|
|
if (流量效率曲线.IsFitted) //y2 = i< 流量效率曲线.Data.Count ? 流量效率曲线.Data[i].Y:0;
|
{
|
if ((p_temp = 流量效率曲线.Data.Find(p0 => p0.X == p.X)) == default(PointF))
|
y2 = 流量效率曲线.Evaluate(p.X);
|
else
|
y2 = p_temp.Y;
|
}
|
dataGridView.Rows.Add(Math.Round(p.X, 1), Math.Round(p.Y, 2), Math.Round(y1, 2), Math.Round(y2, 2));
|
}
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="chart"></param>
|
/// <param name="series"></param>
|
/// <param name="mode">是否使用第三轴</param>
|
public void AddSeries(Chart chart, Series series, bool mode, Color color)
|
{
|
series.Color = color;
|
if (mode)
|
CreateYAxis(chart, chart.ChartAreas[0], series, -8, 1, color);
|
else
|
chart.Series.Add(series);
|
|
|
|
}
|
public void AddCurve(Chart chart, string type = "流量扬程曲线", bool onlyOne = false, DRange Force_range_X = null)
|
{
|
Series series;
|
List<PointF> Points;
|
List<PointF> FittedCurve;
|
|
string baseType = "流量扬程曲线";
|
string baseType2 = "流量功率曲线";
|
string baseType3 = "流量效率曲线";
|
if (onlyOne)
|
{
|
if (Datasets[type].IsFitted)
|
{
|
FittedCurve = Datasets[type].FittedCurvebyRange(Force_range_X);
|
series = AddSeries("ChartArea1", SeriesChartType.Spline, Datasets[type].Legend, Datasets[type].axisType, $"{factoryName}_{Name}_{type}", FittedCurve, true);
|
chart.Series.Add(series);
|
}
|
|
}
|
else
|
{
|
|
//while (chart.ChartAreas.Count > 1)
|
//{
|
// chart.ChartAreas.RemoveAt(1);
|
//}
|
chart.ChartAreas[1].Visible = false;
|
chart.ChartAreas[2].Visible = false;
|
|
|
Points = Datasets[type].Data;
|
series = AddSeries("ChartArea1", SeriesChartType.Point, Datasets[type].Legend, Datasets[type].axisType, $"{type}点", Points, false);
|
//if (chart.ChartAreas.Count > 1) chart.ChartAreas.RemoveAt(1);
|
|
//series.ToolTip = "Value: #VALY{N2}";
|
AddSeries(chart, series, type == "流量效率曲线", Datasets[type].Color);
|
|
|
var series0 = series;
|
|
foreach (var data in Datasets)
|
{
|
var type0 = data.Key;
|
if (!Datasets[type0].IsFitted) continue;
|
FittedCurve = Datasets[type0].FittedCurve;
|
series = AddSeries("ChartArea1", SeriesChartType.Spline, Datasets[type0].Legend, Datasets[type0].axisType, $"{factoryName}_{Name}_{type0}", FittedCurve, true);
|
//CreateYAxis(chart, chart.ChartAreas[0], series, 0.5f, 1);
|
//chart.Series.Add(series);
|
AddSeries(chart, series, type0 == "流量效率曲线", Datasets[type0].Color);
|
|
}
|
|
if (chart.Series.Count == 1 && series0.Points.Count == 0)
|
{
|
series0.Points.Add(-2, -2);
|
series0.Points.Add(-1, -1);
|
series0.IsVisibleInLegend = true;
|
series0.YAxisType = AxisType.Primary;
|
chart.ChartAreas[0].AxisX.Minimum = 0;
|
chart.ChartAreas[0].AxisX.Maximum = 3000;
|
chart.ChartAreas[0].AxisY.Minimum = 0;
|
chart.ChartAreas[0].AxisY.Maximum = 50;
|
chart.ChartAreas[0].AxisY2.Minimum = 0;
|
chart.ChartAreas[0].AxisY2.Maximum = 500;
|
return;
|
}
|
}
|
|
DRange range_X = null;
|
|
|
//if (chart.ChartAreas[0].AxisY.Interval>5)
|
//chart.ChartAreas[0].AxisY.Interval = 2;
|
chart.ChartAreas[0].AxisY2.Interval = 25;
|
// 设置Y轴主刻度线的颜色为红色,透明度为50%
|
|
chart.ChartAreas[0].AxisX.Name = "流量";
|
chart.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.FromArgb(40, Color.Black);
|
chart.ChartAreas[0].AxisX.MajorTickMark.LineColor = Color.FromArgb(40, Color.Black);
|
|
chart.ChartAreas[0].AxisY.MajorTickMark.LineColor = Color.FromArgb(128, Color.Black);
|
chart.ChartAreas[0].AxisY.MajorTickMark.LineColor = Color.FromArgb(60, Color.Black);
|
chart.ChartAreas[0].AxisY2.MajorTickMark.LineColor = Color.FromArgb(128, Color.Red);
|
chart.ChartAreas[0].AxisY2.MajorTickMark.LineColor = Color.FromArgb(60, Color.Red);
|
|
chart.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.FromArgb(60, Color.Black);
|
chart.ChartAreas[0].AxisY2.MajorGrid.LineColor = Color.FromArgb(10, Color.Red);
|
|
chart.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.Blue;
|
chart.ChartAreas[0].AxisY2.LabelStyle.ForeColor = Color.Orange;
|
|
if (Force_range_X != null && Force_range_X.isValid)
|
{
|
range_X = Force_range_X;
|
}
|
else if (Datasets[type].range_X != null && Datasets[type].range_X.isValid)
|
{
|
range_X = Datasets[type].range_X;
|
}
|
else if (Datasets[baseType].range_X != null && Datasets[baseType].range_X.isValid)
|
{
|
range_X = Datasets[baseType].range_X;
|
}
|
else
|
{
|
range_X = new DRange(double.NaN, double.NaN);
|
|
}
|
if (range_X.isValid)
|
{
|
chart.ChartAreas[0].AxisX.Minimum = range_X.Min;
|
chart.ChartAreas[0].AxisX.Maximum = range_X.Max;
|
if (chart.ChartAreas.Count > 1)
|
{
|
chart.ChartAreas[2].AxisX.Minimum = range_X.Min;
|
chart.ChartAreas[2].AxisX.Maximum = range_X.Max;
|
chart.ChartAreas[2].AxisX.Crossing = range_X.Min + (range_X.Max - range_X.Min) * 0.96;
|
}
|
}
|
|
|
if (Datasets[baseType].range_Y != null && Datasets[baseType].range_Y.isValid)
|
{
|
// 设置 Y 轴的最大最小值
|
chart.ChartAreas[0].AxisY.Minimum = Datasets[baseType].range_Y.Min;
|
chart.ChartAreas[0].AxisY.Maximum = Datasets[baseType].range_Y.Max;
|
}
|
else
|
{
|
chart.ChartAreas[0].AxisY.Minimum = double.NaN;
|
chart.ChartAreas[0].AxisY.Maximum = double.NaN;
|
}
|
|
|
|
//if (type!=baseType && Datasets[type].range_Y != null)
|
//{
|
// // 设置 X 轴的最大最小值
|
// chart.ChartAreas[0].AxisY2.Minimum = Datasets[type].range_Y.Min;
|
// chart.ChartAreas[0].AxisY2.Maximum = Datasets[type].range_Y.Max;
|
//}
|
//else
|
if (Datasets[baseType2].range_Y != null && Datasets[baseType2].range_Y.isValid)
|
{
|
|
DRange range_Y2 = Datasets[baseType2].range_Y;
|
// 设置 Y 轴的最大最小值
|
chart.ChartAreas[0].AxisY2.Minimum = range_Y2.Min;
|
chart.ChartAreas[0].AxisY2.Maximum = range_Y2.Max;
|
}
|
else
|
{
|
chart.ChartAreas[0].AxisY2.Minimum = 0;
|
chart.ChartAreas[0].AxisY2.Maximum = 500;
|
}
|
|
|
|
|
if (chart.ChartAreas.Count > 1)
|
{
|
chart.ChartAreas[2].AxisY2.Interval = 10;
|
chart.ChartAreas[2].AxisY2.MajorTickMark.LineColor = Color.FromArgb(60, Color.Blue);
|
chart.ChartAreas[2].AxisY2.MinorTickMark.LineColor = Color.FromArgb(20, Color.Blue);
|
chart.ChartAreas[2].AxisY2.MajorGrid.LineColor = Color.FromArgb(60, Color.Blue);
|
if (Datasets[baseType3].range_Y != null && Datasets[baseType3].range_Y.isValid)
|
{
|
chart.ChartAreas[2].AxisY2.Minimum = Datasets[baseType3].range_Y.Min;
|
chart.ChartAreas[2].AxisY2.Maximum = Datasets[baseType3].range_Y.Max;
|
}
|
else
|
{
|
chart.ChartAreas[2].AxisY2.Minimum = 0;
|
chart.ChartAreas[2].AxisY2.Maximum = 100;
|
}
|
|
|
//chart.ChartAreas[2].AxisY.MajorTickMark.LineColor = Color.FromArgb(60, Color.Blue);
|
//chart.ChartAreas[2].AxisY.MinorTickMark.LineColor = Color.FromArgb(20, Color.Blue);
|
//chart.ChartAreas[1].AxisY2.MajorTickMark.LineColor = Color.FromArgb(60, Color.Blue);
|
//chart.ChartAreas[1].AxisY2.MinorTickMark.LineColor = Color.FromArgb(20, Color.Red);
|
//chart.ChartAreas[1].AxisY.MajorTickMark.LineColor = Color.FromArgb(60, Color.Blue);
|
//chart.ChartAreas[1].AxisY.MinorTickMark.LineColor = Color.FromArgb(20, Color.Red);
|
//chart.ChartAreas[1].AxisY.MajorTickMark.LineColor = Color.FromArgb(20, Color.Red);
|
//chart.ChartAreas[1].AxisY2.MajorTickMark.LineColor = Color.FromArgb(20, Color.Red);
|
}
|
|
}
|
|
public void CreateYAxis(Chart chart, ChartArea area, Series series, float axisOffset, float labelsSize, Color color)
|
{
|
// Create new chart area for original series
|
ChartArea areaSeries;
|
ChartArea areaAxis;
|
if (chart.ChartAreas.Count == 1)
|
{
|
areaSeries = chart.ChartAreas.Add("ChartArea_" + series.Name);
|
areaAxis = chart.ChartAreas.Add("AxisY_" + series.ChartArea);
|
}
|
else
|
{
|
areaSeries = chart.ChartAreas[1];
|
areaAxis = chart.ChartAreas[2];
|
|
}
|
areaSeries.Visible = false;
|
areaSeries.BackColor = Color.Transparent;
|
areaSeries.BorderColor = Color.Transparent;
|
areaSeries.Position.FromRectangleF(area.Position.ToRectangleF());
|
areaSeries.InnerPlotPosition.FromRectangleF(area.InnerPlotPosition.ToRectangleF());
|
areaSeries.AxisX.MajorGrid.Enabled = false;
|
areaSeries.AxisX.MajorTickMark.Enabled = false;
|
areaSeries.AxisX.LabelStyle.Enabled = false;
|
areaSeries.AxisY.Enabled = AxisEnabled.False;
|
areaSeries.AxisY2.Enabled = AxisEnabled.False;
|
areaSeries.AxisY2.MajorGrid.Enabled = false;
|
areaSeries.AxisY2.MajorTickMark.Enabled = false;
|
areaSeries.AxisY2.LabelStyle.Enabled = false;
|
areaSeries.AxisY2.IsStartedFromZero = area.AxisY.IsStartedFromZero;
|
|
|
|
|
series.ChartArea = areaSeries.Name;
|
|
// Create new chart area for axis
|
|
areaAxis.Visible = true;
|
areaAxis.BackColor = Color.Transparent;
|
areaAxis.BorderColor = Color.Transparent;
|
areaAxis.Position.FromRectangleF(chart.ChartAreas[0].Position.ToRectangleF());
|
areaAxis.InnerPlotPosition.FromRectangleF(chart.ChartAreas[0].InnerPlotPosition.ToRectangleF());
|
|
// Create a copy of specified series
|
Series seriesCopy = chart.Series.Add(series.Name);
|
seriesCopy.YAxisType = AxisType.Secondary;
|
seriesCopy.ChartType = series.ChartType;
|
foreach (DataPoint point in series.Points)
|
{
|
seriesCopy.Points.AddXY(point.XValue, point.YValues[0]);
|
}
|
|
// Hide copied series
|
seriesCopy.IsVisibleInLegend = true;
|
seriesCopy.Color = color;
|
seriesCopy.BorderColor = Color.Transparent;
|
seriesCopy.ChartArea = areaAxis.Name;
|
|
// Disable drid lines & tickmarks
|
areaAxis.AxisX.LineWidth = 0;
|
areaAxis.AxisX.MajorGrid.Enabled = false;
|
areaAxis.AxisX.MajorTickMark.Enabled = false;
|
areaAxis.AxisX.LabelStyle.Enabled = false;
|
|
|
areaAxis.AxisY.Enabled = AxisEnabled.False;
|
areaAxis.AxisY2.Enabled = AxisEnabled.True;
|
|
areaAxis.AxisY2.MajorGrid.Enabled = false;
|
areaAxis.AxisY2.IsStartedFromZero = area.AxisY.IsStartedFromZero;
|
areaAxis.AxisY2.LabelStyle.Font = area.AxisY.LabelStyle.Font;
|
areaAxis.AxisY2.LabelStyle.ForeColor = color;
|
float f = areaAxis.InnerPlotPosition.Width - axisOffset;
|
// Adjust area position
|
//if (f < 0 || f>100) f = 0;
|
//areaAxis.Position.Width = f;
|
//f = areaAxis.InnerPlotPosition.Width + labelsSize;
|
//if (f < 0 || f > 100) f = 100;
|
//areaAxis.InnerPlotPosition.Width = f;
|
// 设置Y2轴偏移量为5%
|
//areaAxis.AxisY2.Crossing = 50;
|
|
}
|
|
private Series AddSeries(string Area, SeriesChartType type, String Legend, AxisType axisType, String Name, List<PointF> Points, bool showLegend = true)
|
{
|
Series series = new Series();
|
series.ChartArea = Area;
|
series.ChartType = type;
|
series.Legend = Legend;
|
series.Name = Name;
|
series.IsVisibleInLegend = showLegend;
|
series.YAxisType = axisType;
|
|
if (Points != null) Points.ForEach(p => series.Points.AddXY(p.X, p.Y));
|
return series;
|
}
|
|
[Category("2、计算参数")]
|
[DisplayName("3)流量扬程曲线")]
|
public List<PointF> HeadCurvePoints
|
{
|
get
|
{
|
this.Datasets.TryGetValue("流量扬程曲线", out Dataset dataset);
|
if (dataset != null)
|
{
|
return dataset._data;
|
}
|
return null;
|
}
|
set
|
{
|
this.Datasets.TryGetValue("流量扬程曲线", out Dataset dataset);
|
if (dataset == null)
|
{
|
dataset = new Dataset("流量扬程曲线", this);
|
}
|
dataset._data = value;
|
|
}
|
}
|
[Category("2、计算参数")]
|
[DisplayName("4)流量效率曲线")]
|
public List<PointF> EfficCurvePoints
|
{
|
get
|
{
|
this.Datasets.TryGetValue("流量效率曲线", out Dataset dataset);
|
if (dataset != null)
|
{
|
return dataset._data;
|
}
|
return null;
|
}
|
set
|
{
|
this.Datasets.TryGetValue("流量效率曲线", out Dataset dataset);
|
if (dataset == null)
|
{
|
dataset = new Dataset("流量效率曲线", this);
|
}
|
dataset._data = value;
|
|
}
|
}
|
[Browsable(false)]
|
public string HeadCurve { get; set; } = "PumpDefault";
|
|
[Browsable(false)]
|
public List<string> Parameters { get; set; }
|
|
//实际需水量
|
[Category("3、计算结果")]
|
[DisplayName("2)扬程")]
|
[Browsable(true)]
|
public new float EN_HEADLOSS { get { return -base.EN_HEADLOSS; } }
|
|
[Browsable(false)]
|
public new float EN_VELOCITY { get { return base.EN_VELOCITY; } }
|
|
|
public override string ToString()
|
{
|
string para = Parameters == null ? null : string.Join("\t", Parameters);
|
return $"{ID}\t{Node1}\t{Node2}\tHead\t{HeadCurve}\tSPEED\t{转速比}\t{para}\t;\t";
|
}
|
}
|
}
|