using DevExpress.Utils;
|
using DevExpress.XtraCharts;
|
using System;
|
using System.Collections.Generic;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Windows.Forms;
|
|
namespace IStation.WinFrmUI.Curve
|
{
|
/// <summary>
|
/// bug:隐藏效率线计算剩下两条线的轴,计算轴坐标不合理
|
/// </summary>
|
public partial class MultiCurveExpressChart : DevExpress.XtraEditors.XtraUserControl
|
{
|
public MultiCurveExpressChart()
|
{
|
InitializeComponent();
|
InitialChart();
|
this.chartControl1.RuntimeHitTesting = true;
|
}
|
|
#region Private Variable
|
|
private class CurrentViewModel
|
{
|
public long ID { get; set; }
|
public string Name { get; set; }
|
public Model.CurveExpress CurveExpressQH { get; set; }
|
public Model.CurveExpress CurveExpressQE { get; set; }
|
public Model.CurveExpress CurveExpressQP { get; set; }
|
public List<Model.CurvePoint> PointsQH { get; set; }
|
public List<Model.CurvePoint> PointsQE { get; set; }
|
public List<Model.CurvePoint> PointsQP { get; set; }
|
public Color Color { get; set; }
|
}
|
|
private List<CurrentViewModel> _allCurves = new List<CurrentViewModel>();
|
private string _tagQH = "CurveQH", _tagQE = "CurveQE", _tagQP = "CurveQP";
|
|
private XYDiagram _mainChartDiagram;
|
private XYDiagramDefaultPane _paneQH;
|
private XYDiagramPane _paneQE;
|
private XYDiagramPane _paneQP;
|
private AxisX _axisXQ;
|
private AxisY _axisYQH;
|
private SecondaryAxisY _axisYQE, _axisYQP;
|
private ConstantLine _workPointLine;
|
|
private TextAnnotation _workPointTextAnnot;
|
|
private Model.CurveCoordinateParas _coordinateParas;
|
|
public bool _curveQHVisible = true;
|
public bool _curveQEVisible = true;
|
public bool _curveQPVisible = true;
|
|
|
private bool _initialData = false;
|
|
#endregion
|
|
#region Public Variable
|
|
/// <summary>
|
/// 工作线是否可见
|
/// </summary>
|
public bool LineVisible
|
{
|
get => _lineVisible;
|
set
|
{
|
_lineVisible = value;
|
this.barCekLineVisible.Checked = _lineVisible;
|
}
|
}
|
private bool _lineVisible = false;
|
|
/// <summary>
|
/// 曲线名是否可见
|
/// </summary>
|
public bool CurveNameVisible
|
{
|
get => _curveNameVisible;
|
set
|
{
|
_curveNameVisible = value;
|
this.barCekCurveNameVisible.Checked = _curveNameVisible;
|
}
|
}
|
private bool _curveNameVisible = false;
|
|
#endregion
|
|
#region Public Evnet
|
|
public event Action<Model.CurveCoordinateParas> OnCurveCoordinateParasChanged;
|
|
public event Action<long, Model.GroupPoint> OnCalcQueryPoint = null;
|
|
#endregion
|
|
#region Initial
|
|
/// <summary>
|
/// 初始化图表
|
/// </summary>
|
private void InitialChart()
|
{
|
this.chartControl1.SetChartDisplay();
|
this.chartControl1.Legend.Direction = DevExpress.XtraCharts.LegendDirection.TopToBottom;
|
|
|
_mainChartDiagram = (XYDiagram)chartControl1.Diagram;
|
_paneQH = _mainChartDiagram.DefaultPane;
|
_paneQE = (XYDiagramPane)_mainChartDiagram.FindPaneByName("PaneQE");
|
_paneQP = (XYDiagramPane)_mainChartDiagram.FindPaneByName("PaneQP");
|
|
_axisXQ = _mainChartDiagram.AxisX;
|
_axisXQ.SetAxisXQDisplay();
|
_axisYQH = _mainChartDiagram.AxisY;
|
_axisYQH.SetAxisYQHDisplay();
|
_axisYQE = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQE");
|
_axisYQE.SetSecondaryAxisYQEDisplay();
|
_axisYQE.Alignment = AxisAlignment.Near;
|
_axisYQP = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQP");
|
_axisYQP.SetSecondaryAxisYQPDisplay();
|
|
_workPointLine = (ConstantLine)_mainChartDiagram.AxisX.ConstantLines.GetElementByName("WorkPointLine");
|
_workPointLine.SetWorkPointLineDisplay();
|
|
_workPointTextAnnot = this.chartControl1.AnnotationRepository[0] as TextAnnotation;
|
_workPointTextAnnot.SetTextAnnoWorkPointDisplay();
|
|
_axisXQ.Visibility = DefaultBoolean.False;
|
_axisXQ.GridLines.Visible = false;
|
_axisYQH.Visibility = DefaultBoolean.False;
|
_axisYQH.GridLines.Visible = false;
|
_axisYQE.Visibility = DefaultBoolean.False;
|
_axisYQE.GridLines.Visible = false;
|
_axisYQP.Visibility = DefaultBoolean.False;
|
_axisYQP.GridLines.Visible = false;
|
|
|
_workPointLine.Visible = false;
|
_workPointTextAnnot.Visible = false;
|
|
this.chartControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseMove);
|
this.chartControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseUp);
|
this.chartControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseDown);
|
this.chartControl1.Resize += new System.EventHandler(this.chartControl1_Resize);
|
}
|
|
/// <summary>
|
/// 初始化图表数据
|
/// </summary>
|
public void InitialChartData()
|
{
|
_initialData = false;
|
_coordinateParas = null;
|
|
UpdateChart(false);
|
}
|
|
#endregion
|
|
#region Add Update Curve
|
|
/// <summary>
|
/// 添加曲线
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="curveQH"></param>
|
/// <param name="curveQE"></param>
|
/// <param name="curveQP"></param>
|
/// <param name="color"></param>
|
public void AddCurve(long id, string name, Model.CurveExpress curveQH, Model.CurveExpress curveQE,
|
Model.CurveExpress curveQP, Color color)
|
{
|
if (curveQH == null)
|
return;
|
if (_allCurves.Exists(x => x.ID == id))
|
return;
|
_initialData = true;
|
|
List<Model.CurvePoint> qhPoints, qePoints = null, qpPoints = null;
|
if (curveQH.DefinePoints != null)
|
qhPoints = curveQH.DefinePoints;
|
else
|
qhPoints = curveQH.GetFitPoints(12);
|
|
if (curveQE != null)
|
if (curveQE.DefinePoints != null)
|
qePoints = curveQE.DefinePoints;
|
else
|
qePoints = curveQE?.GetFitPoints(12);
|
|
if (curveQP != null)
|
if (curveQP?.DefinePoints != null)
|
qpPoints = curveQP.DefinePoints;
|
else
|
qpPoints = curveQP?.GetFitPoints(12);
|
|
AddCurve(id, name, curveQH, curveQE, curveQP, color, qhPoints, qePoints, qpPoints);
|
}
|
|
|
/// <summary>
|
/// 添加曲线
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="curveQH"></param>
|
/// <param name="curveQE"></param>
|
/// <param name="curveQP"></param>
|
/// <param name="color"></param>
|
/// <param name="definePointsQH"></param>
|
/// <param name="definePointsQE"></param>
|
/// <param name="definePointsQP"></param>
|
public void AddCurve(long id, string name, Model.CurveExpress curveQH, Model.CurveExpress curveQE,
|
Model.CurveExpress curveQP, Color color, List<Model.CurvePoint> definePointsQH = null,
|
List<Model.CurvePoint> definePointsQE = null, List<Model.CurvePoint> definePointsQP = null)
|
{
|
if (curveQH == null)
|
return;
|
if (_allCurves.Exists(x => x.ID == id))
|
return;
|
_initialData = true;
|
CurrentViewModel curve = new CurrentViewModel();
|
curve.ID = id;
|
curve.Name = name;
|
curve.CurveExpressQH = curveQH;
|
curve.CurveExpressQE = curveQE;
|
curve.CurveExpressQP = curveQP;
|
|
if (definePointsQH == null)
|
{
|
curve.PointsQH = curveQH.GetFitPoints();
|
}
|
else
|
{
|
curve.PointsQH = definePointsQH;
|
}
|
|
if (curveQE != null && definePointsQE == null)
|
{
|
curve.PointsQE = curveQE.GetFitPoints();
|
}
|
else
|
{
|
curve.PointsQE = definePointsQE;
|
}
|
|
if (curveQP != null && definePointsQP == null)
|
{
|
curve.PointsQP = curveQP.GetFitPoints();
|
}
|
else
|
{
|
curve.PointsQP = definePointsQP;
|
}
|
|
curve.Color = color;
|
|
_allCurves.Add(curve);
|
UpdateChart(true);
|
}
|
|
|
/// <summary>
|
/// 设置曲线
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="curveQH"></param>
|
/// <param name="curveQE"></param>
|
/// <param name="curveQP"></param>
|
/// <param name="name"></param>
|
public void SetCurve(long id, Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, string name = "")
|
{
|
var exist = _allCurves.FirstOrDefault(x => x.ID == id);
|
if (exist == null)
|
return;
|
if (!string.IsNullOrEmpty(name))
|
{
|
exist.Name = name;
|
}
|
exist.CurveExpressQH = curveQH;
|
exist.CurveExpressQE = curveQE;
|
exist.CurveExpressQP = curveQP;
|
|
exist.PointsQH = Model.FitCurveHelper.GetFitPoints(curveQH, 12);
|
exist.PointsQE = Model.FitCurveHelper.GetFitPoints(curveQE, 12);
|
exist.PointsQP = Model.FitCurveHelper.GetFitPoints(curveQP, 12);
|
|
UpdateChart(true);
|
}
|
|
/// <summary>
|
/// 设置曲线
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="color"></param>
|
public void SetCurve(long id, Color color)
|
{
|
var exist = _allCurves.FirstOrDefault(x => x.ID == id);
|
if (exist == null)
|
return;
|
foreach (Series series in this.chartControl1.Series)
|
{
|
var tag = series.Tag;
|
if (tag == null)
|
continue;
|
if (tag.ToString() != exist.ID.ToString())
|
continue;
|
exist.Color = color;
|
series.View.Color = color;
|
for (int i = 0; i < this.chartControl1.AnnotationRepository.Count; i++)
|
{
|
var txt = this.chartControl1.AnnotationRepository[i];
|
if (txt.Name == _tagQH + id.ToString())
|
{
|
(txt as TextAnnotation).TextColor = color;
|
(txt as TextAnnotation).Border.Color = color;
|
}
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 设置曲线(需手动更新图表)
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="name"></param>
|
public void SetCurveName(long id, string name)
|
{
|
var exist = _allCurves.FirstOrDefault(x => x.ID == id);
|
if (exist == null)
|
return;
|
exist.Name = name;
|
}
|
|
/// <summary>
|
/// 删除曲线
|
/// </summary>
|
public void DeleteCurve()
|
{
|
_allCurves.Clear();
|
UpdateChart(true);
|
_initialData = false;
|
|
}
|
|
/// <summary>
|
/// 删除曲线
|
/// </summary>
|
/// <param name="id"></param>
|
public void DeleteCurve(long id)
|
{
|
var exist = _allCurves.FirstOrDefault(x => x.ID == id);
|
if (exist == null)
|
return;
|
_allCurves.Remove(exist);
|
UpdateChart(true);
|
if (_allCurves.Count == 0)
|
{
|
_initialData = false;
|
}
|
}
|
|
/// <summary>
|
/// 更新图表
|
/// </summary>
|
/// <param name="calcCoordinate">计算坐标</param>
|
public void UpdateChart(bool calcCoordinate = false)
|
{
|
if (calcCoordinate || _coordinateParas == null)
|
{
|
//不强迫计算,就用上次更新的坐标系
|
CalcCoordinate();
|
}
|
|
CalcSeries();
|
|
CalcChartAxis();
|
|
CalcWorkPointByQ();
|
|
CalcTextAnchorPoint();
|
}
|
|
#endregion
|
|
#region Calc
|
|
private double _minQ, _maxQ;
|
private double _maxH = 0, _minH = 10000;
|
private double _maxE = 0, _minE = 0;
|
private double _maxP = 0, _minP = 1000;
|
|
/// <summary>
|
/// 计算坐标
|
/// </summary>
|
private void CalcCoordinate()
|
{
|
if (_allCurves == null || !_allCurves.Any())
|
{
|
//设置成白板坐标
|
_coordinateParas = new Model.CurveCoordinateParas();
|
_coordinateParas.GridNumberX = 30;
|
_coordinateParas.GridNumberY = 16;
|
//显示的坐标线号
|
_coordinateParas.StartLineNoH = 10;
|
_coordinateParas.EndLineNoH = 15;
|
_coordinateParas.StartLineNoE = 0;
|
_coordinateParas.EndLineNoE = 10;
|
_coordinateParas.StartLineNoP = 2;
|
_coordinateParas.EndLineNoP = 9;
|
//坐标最小值和间隔
|
_coordinateParas.CoordMinQ = 0; _coordinateParas.CoordSpaceQ = 1000;
|
_coordinateParas.CoordMinH = 10; _coordinateParas.CoordSpaceH = 100;
|
_coordinateParas.CoordMinE = 0; _coordinateParas.CoordSpaceE = 100;
|
_coordinateParas.CoordMinP = 10; _coordinateParas.CoordSpaceP = 100;
|
return;
|
}
|
|
_maxQ = 0; _minQ = 10000;
|
_maxH = 0; _minH = 10000;
|
_maxE = 0; _minE = 0;
|
_maxP = 0; _minP = 1000;
|
|
double _scaleMinH = 1, _scaleMaxH = 1;
|
|
foreach (var curve in _allCurves)
|
{
|
var xxx = curve.PointsQH.Select(x => x.X);
|
var yyy = curve.PointsQH.Select(x => x.Y);
|
|
_minQ = Math.Min(_minQ, xxx.Min());
|
_maxQ = Math.Max(_maxQ, xxx.Max());
|
|
_minH = Math.Min(_minH, yyy.Min());
|
_maxH = Math.Max(_maxH, yyy.Max());
|
}
|
|
|
foreach (CurrentViewModel info in _allCurves)
|
{
|
if (info.PointsQE == null)
|
continue;
|
var yyy = info.PointsQE?.Select(x => x.Y);
|
_maxE = Math.Max(_maxE, yyy.Max());
|
}
|
foreach (CurrentViewModel info in _allCurves)
|
{
|
var yyy = info.PointsQP.Select(x => x.Y);
|
|
_minP = Math.Min(_minP, yyy.Min());
|
_maxP = Math.Max(_maxP, yyy.Max());
|
}
|
|
_coordinateParas = Model.CurveCoordinateParas.CalcCoordinate(_minQ,
|
_maxQ,
|
_minH * _scaleMinH,
|
_maxH * _scaleMaxH,
|
_minE,
|
_maxE,
|
_minP,
|
_maxP);
|
|
if (_coordinateParas == null)
|
return;
|
if (_coordinateParas.CoordMinQ + _coordinateParas.CoordSpaceQ * this._coordinateParas.GridNumberX < _maxQ * 1.05)
|
{
|
_coordinateParas.GridNumberX++;
|
}
|
}
|
|
/// <summary>
|
/// 计算图表轴
|
/// </summary>
|
private void CalcChartAxis()
|
{
|
// if (_coordinateParas == null)
|
// {
|
_axisXQ.Visibility = DefaultBoolean.False;
|
_axisXQ.GridLines.Visible = false;
|
_axisYQH.Visibility = DefaultBoolean.False;
|
_axisYQH.GridLines.Visible = false;
|
_axisYQE.Visibility = DefaultBoolean.False;
|
_axisYQE.GridLines.Visible = false;
|
_axisYQP.Visibility = DefaultBoolean.False;
|
_axisYQP.GridLines.Visible = false;
|
|
_workPointLine.Visible = false;
|
|
_paneQE.Visibility = ChartElementVisibility.Hidden;
|
_paneQP.Visibility = ChartElementVisibility.Hidden;
|
// return;
|
// }
|
|
_paneQE.Visibility = _curveQEVisible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden;
|
_paneQP.Visibility = _curveQPVisible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden;
|
|
//计算刻度 Q
|
var axisQLabels = new List<CustomAxisLabel>();
|
var disQ = _coordinateParas.CoordMinQ;
|
for (int i = 0; i < _coordinateParas.GridNumberX + 1; i++)
|
{
|
axisQLabels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ));
|
disQ = disQ + _coordinateParas.CoordSpaceQ;
|
}
|
|
_axisXQ.CustomLabels.Clear();
|
_axisXQ.CustomLabels.AddRange(axisQLabels.ToArray());
|
_axisXQ.Visibility = DefaultBoolean.True;
|
_axisXQ.GridLines.Visible = true;
|
|
|
|
//计算刻度
|
var axisQHLabels = new List<CustomAxisLabel>();
|
var disH = _coordinateParas.CoordMinH + _coordinateParas.CoordSpaceH * _coordinateParas.StartLineNoH;
|
for (int i = _coordinateParas.StartLineNoH; i < _coordinateParas.EndLineNoH + 1; i++)
|
{
|
axisQHLabels.Add(new CustomAxisLabel(disH.ToString(), disH));
|
disH = disH + _coordinateParas.CoordSpaceH;
|
}
|
|
_axisYQH.CustomLabels.Clear();
|
_axisYQH.CustomLabels.AddRange(axisQHLabels.ToArray());
|
_axisYQH.Visibility = DefaultBoolean.True;
|
_axisYQH.GridLines.Visible = true;
|
|
//效率
|
if (_maxE > _minE && _curveQEVisible)
|
{
|
//计算刻度
|
var axisQELabels = new List<CustomAxisLabel>();
|
var disE = _coordinateParas.CoordMinE + _coordinateParas.CoordSpaceE * _coordinateParas.StartLineNoE;
|
for (int i = _coordinateParas.StartLineNoE; i < _coordinateParas.EndLineNoE + 1; i++)
|
{
|
axisQELabels.Add(new CustomAxisLabel(disE.ToString(), disE));
|
disE = disE + _coordinateParas.CoordSpaceE;
|
}
|
|
_axisYQE.CustomLabels.Clear();
|
_axisYQE.CustomLabels.AddRange(axisQELabels.ToArray());
|
_axisYQE.Visibility = DefaultBoolean.True;
|
_axisYQE.GridLines.Visible = true;
|
}
|
|
//功率
|
if (_maxP > _minP)
|
{
|
//计算刻度
|
var axisQPLabels = new List<CustomAxisLabel>();
|
double disP = _coordinateParas.CoordMinP + _coordinateParas.CoordSpaceP * _coordinateParas.StartLineNoP;
|
for (int i = _coordinateParas.StartLineNoP; i < _coordinateParas.EndLineNoP + 1; i++)
|
{
|
axisQPLabels.Add(new CustomAxisLabel(disP.ToString(), disP));
|
disP = disP + _coordinateParas.CoordSpaceP;
|
}
|
|
_axisYQP.CustomLabels.Clear();
|
_axisYQP.CustomLabels.AddRange(axisQPLabels.ToArray());
|
_axisYQP.Visibility = DefaultBoolean.True;
|
_axisYQP.GridLines.Visible = true;
|
}
|
|
|
_axisXQ.SetAxisRange(_coordinateParas.CoordMinQ, _coordinateParas.DispMaxQ());
|
_axisYQH.SetAxisRange(_coordinateParas.DispMinH(), _coordinateParas.DispMaxH());
|
_axisYQE.SetAxisRange(_coordinateParas.DispMinE(), _coordinateParas.DispMaxE());
|
_axisYQP.SetAxisRange(_coordinateParas.DispMinP(), _coordinateParas.DispMaxP());
|
}
|
|
/// <summary>
|
/// 计算系列
|
/// </summary>
|
private void CalcSeries()
|
{
|
this.chartControl1.BeginInit();
|
this.chartControl1.Series.Clear();
|
|
var annotationCount = this.chartControl1.AnnotationRepository.Count;
|
for (int i = annotationCount - 1; i > 0; i--)
|
{
|
if (i == 0)
|
break;
|
this.chartControl1.AnnotationRepository.RemoveAt(i);
|
}
|
|
this.chartControl1.Legend.CustomItems.Clear();
|
foreach (var curve in _allCurves)
|
{
|
CreateSeries(curve);
|
}
|
if (_allCurves.Count == 0)
|
{
|
LineVisible = false;
|
}
|
this.chartControl1.EndInit();
|
}
|
|
/// <summary>
|
/// 计算注释定位
|
/// </summary>
|
private void CalcTextAnchorPoint()
|
{
|
var x = this.chartControl1.Location.X + this.chartControl1.Width - (100);
|
var y = this.chartControl1.Height - (100);
|
|
(_workPointTextAnnot.AnchorPoint as ChartAnchorPoint).X = x;
|
(_workPointTextAnnot.AnchorPoint as ChartAnchorPoint).Y = y;
|
}
|
|
/// <summary>
|
/// 计算工作点
|
/// </summary>
|
/// <param name="workQ"></param>
|
public void CalcWorkPointByQ(double? workQ = null)
|
{
|
if (!_lineVisible)
|
{
|
_workPointLine.Visible = false;
|
_workPointLine.Title.Visible = false;
|
_workPointTextAnnot.Visible = false;
|
return;
|
}
|
else
|
{
|
_workPointLine.Visible = true;
|
_workPointLine.Title.Visible = true;
|
_workPointTextAnnot.Visible = true;
|
}
|
|
if (_allCurves == null || !_allCurves.Any())
|
return;
|
|
if (_allCurves.Exists(x => x.ID == -1))
|
{
|
_workPointTextAnnot.Visible = true;
|
}
|
else
|
{
|
_workPointTextAnnot.Visible = false;
|
}
|
|
|
if (workQ == null)
|
{
|
workQ = (_minQ + _maxQ) / 2;
|
}
|
|
if (workQ < _minQ || workQ > _maxQ)
|
return;
|
foreach (var curve in _allCurves)
|
{
|
var curveMinQ = curve.CurveExpressQH.Min;
|
var curveMaxQ = curve.CurveExpressQH.Max;
|
|
var workPoint = new Model.GroupPoint(0, 0, 0, 0, 0);
|
if (curveMinQ > workQ.Value || workQ.Value > curveMaxQ)
|
{
|
if (OnCalcQueryPoint != null)
|
{
|
OnCalcQueryPoint(curve.ID, workPoint);
|
}
|
|
if (curve.ID == -1)
|
{
|
_workPointTextAnnot.Visible = false;
|
}
|
continue;
|
}
|
workPoint.Q = workQ.Value;
|
workPoint.H = Common.FitCurveHelper.GetFitPointY(curve.CurveExpressQH, workQ.Value);
|
|
var workInfoStringBuilder = new StringBuilder();
|
workInfoStringBuilder.AppendLine($"流量:{workPoint.Q.ToString("N1")} ");
|
workInfoStringBuilder.AppendLine($"扬程:{workPoint.H.ToString("N1")} ");
|
|
|
|
if (curve.CurveExpressQE != null)
|
{
|
if (curve.CurveExpressQP != null)
|
{
|
workPoint.P = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQP, workPoint.Q);
|
workPoint.E = IStation.Common.PumpParaHelper.CalculateE(workPoint.Q, workPoint.H, workPoint.P);
|
}
|
else
|
{
|
workPoint.E = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQE, workPoint.Q);
|
}
|
|
workInfoStringBuilder.AppendLine($"效率:{workPoint.E.ToString("N2")} ");
|
}
|
if (curve.CurveExpressQP != null)
|
{
|
workPoint.P = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQP, workPoint.Q);
|
workInfoStringBuilder.Append($"功率:{workPoint.P.ToString("N1")} ");
|
}
|
|
if (curve.ID == -1)
|
{
|
_workPointTextAnnot.Text = workInfoStringBuilder.ToString();
|
_workPointTextAnnot.AutoSize = true;
|
}
|
else
|
{
|
|
if (OnCalcQueryPoint != null)
|
{
|
OnCalcQueryPoint(curve.ID, workPoint);
|
}
|
}
|
}
|
|
_workPointLine.AxisValue = workQ;
|
_workPointLine.Title.Text = workQ.Value.ToString("N1");
|
}
|
|
/// <summary>
|
/// 创建系列
|
/// </summary>
|
private void CreateSeries(CurrentViewModel curve)
|
{
|
var seriesCurveQH = new DevExpress.XtraCharts.Series();
|
seriesCurveQH.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
seriesCurveQH.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
seriesCurveQH.Name = _tagQH + curve.ID.ToString();
|
seriesCurveQH.ShowInLegend = false;
|
seriesCurveQH.CrosshairEnabled = DefaultBoolean.False;
|
seriesCurveQH.Tag = curve.ID.ToString();
|
seriesCurveQH.ShowInLegend = true;
|
seriesCurveQH.LegendTextPattern = curve.Name;
|
|
var seriesCurveQHView = new DevExpress.XtraCharts.SplineSeriesView();
|
seriesCurveQHView.LineStyle.Thickness = 2;
|
seriesCurveQHView.Color = curve.Color;
|
seriesCurveQHView.EnableAntialiasing = DefaultBoolean.True;
|
|
seriesCurveQH.SeriesPointsSorting = SortingMode.None;
|
seriesCurveQH.SeriesPointsSortingKey = SeriesPointKey.Value_1;
|
seriesCurveQH.View = seriesCurveQHView;
|
seriesCurveQH.Visible = _curveQHVisible;
|
|
var pointsQH = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQH, 12);
|
for (int i = 0; i < pointsQH.Count; i++)
|
{
|
seriesCurveQH.Points.Add(new SeriesPoint(pointsQH[i].X, new double[] { pointsQH[i].Y }));
|
}
|
|
var pointQH = pointsQH[pointsQH.Count() - 1];
|
var anchorPointQH = new DevExpress.XtraCharts.PaneAnchorPoint();
|
anchorPointQH.Pane = _paneQH;
|
anchorPointQH.AxisXCoordinate.AxisValue = pointQH.X.ToString();
|
anchorPointQH.AxisYCoordinate.AxisValue = pointQH.Y.ToString();
|
|
var positionQH = new DevExpress.XtraCharts.RelativePosition();
|
positionQH.Angle = 30;
|
positionQH.ConnectorLength = 35;
|
|
var txtQH = new TextAnnotation();
|
txtQH.Border.Visibility = DefaultBoolean.False;
|
txtQH.AnchorPoint = anchorPointQH;
|
txtQH.AutoHeight = true;
|
txtQH.AutoWidth = true;
|
txtQH.BackColor = System.Drawing.Color.Transparent;
|
txtQH.Border.Color = curve.Color;
|
txtQH.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.Line;
|
txtQH.DXFont = CurveChartDisplay.AnnoFontQH;
|
txtQH.Name = _tagQH + curve.ID.ToString();
|
txtQH.Padding.Bottom = 1;
|
txtQH.Padding.Left = 1;
|
txtQH.Padding.Right = 1;
|
txtQH.Padding.Top = 1;
|
txtQH.RuntimeAnchoring = false;
|
txtQH.RuntimeMoving = true;
|
txtQH.RuntimeResizing = false;
|
txtQH.RuntimeRotation = false;
|
txtQH.Text = curve.Name;
|
txtQH.TextColor = curve.Color;
|
txtQH.ShapePosition = positionQH;
|
txtQH.Visible = _curveNameVisible;
|
this.chartControl1.AnnotationRepository.Add(txtQH);
|
|
this.chartControl1.Series.Add(seriesCurveQH);
|
|
if (curve.CurveExpressQE != null)
|
{
|
var seriesCurveQE = new DevExpress.XtraCharts.Series();
|
seriesCurveQE.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
seriesCurveQE.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
seriesCurveQE.Name = _tagQE + curve.ID.ToString();
|
seriesCurveQE.ShowInLegend = false;
|
seriesCurveQE.CrosshairEnabled = DefaultBoolean.False;
|
seriesCurveQE.Tag = curve.ID.ToString();
|
|
var seriesCurveQEView = new DevExpress.XtraCharts.SplineSeriesView();
|
seriesCurveQEView.LineStyle.Thickness = 2;
|
seriesCurveQEView.Color = curve.Color;
|
seriesCurveQEView.AxisY = _axisYQE;
|
seriesCurveQEView.Pane = _paneQE;
|
seriesCurveQEView.EnableAntialiasing = DefaultBoolean.True;
|
|
seriesCurveQE.SeriesPointsSorting = SortingMode.None;
|
seriesCurveQE.SeriesPointsSortingKey = SeriesPointKey.Value_1;
|
seriesCurveQE.View = seriesCurveQEView;
|
seriesCurveQE.Visible = _curveQEVisible;
|
|
var pointsQE = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQE, 12);
|
for (int i = 0; i < pointsQE.Count; i++)
|
{
|
seriesCurveQE.Points.Add(new SeriesPoint(pointsQE[i].X, new double[] { pointsQE[i].Y }));
|
}
|
|
this.chartControl1.Series.Add(seriesCurveQE);
|
}
|
|
if (curve.CurveExpressQP != null)
|
{
|
var seriesCurveQP = new DevExpress.XtraCharts.Series();
|
seriesCurveQP.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
seriesCurveQP.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
seriesCurveQP.Name = _tagQP + curve.ID.ToString();
|
seriesCurveQP.ShowInLegend = false;
|
seriesCurveQP.CrosshairEnabled = DefaultBoolean.False;
|
seriesCurveQP.Tag = curve.ID.ToString();
|
|
var seriesCurveQPView = new DevExpress.XtraCharts.SplineSeriesView();
|
seriesCurveQPView.LineStyle.Thickness = 2;
|
seriesCurveQPView.Color = curve.Color;
|
seriesCurveQPView.AxisY = _axisYQP;
|
seriesCurveQPView.Pane = _paneQP;
|
seriesCurveQPView.EnableAntialiasing = DefaultBoolean.True;
|
|
seriesCurveQP.SeriesPointsSorting = SortingMode.None;
|
seriesCurveQP.SeriesPointsSortingKey = SeriesPointKey.Value_1;
|
seriesCurveQP.View = seriesCurveQPView;
|
seriesCurveQP.Visible = _curveQPVisible;
|
|
var pointsQP = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQP, 12);
|
for (int i = 0; i < pointsQP.Count; i++)
|
{
|
seriesCurveQP.Points.Add(new SeriesPoint(pointsQP[i].X, new double[] { pointsQP[i].Y }));
|
}
|
|
this.chartControl1.Series.Add(seriesCurveQP);
|
}
|
}
|
|
#endregion
|
|
#region ChartEvent
|
|
// 右键对象
|
private object _rightClickObj = null;
|
private bool _onMoveWorkPointLine = false;
|
private void chartControl1_MouseDown(object sender, MouseEventArgs e)
|
{
|
if (!_initialData)
|
return;
|
var hitInfo = chartControl1.CalcHitInfo(e.Location);
|
if (e.Button == MouseButtons.Left)
|
{
|
if (hitInfo.InSeries)
|
{
|
_rightClickObj = hitInfo.Series;
|
|
}
|
else if (hitInfo.InAxis)
|
{
|
_rightClickObj = hitInfo.Axis;
|
}
|
else if (hitInfo.InConstantLine)
|
{
|
if (hitInfo.ConstantLine == _workPointLine)
|
{
|
_onMoveWorkPointLine = true;
|
}
|
|
|
}
|
else if (hitInfo.InAnnotation)
|
{
|
_rightClickObj = hitInfo.Annotation;
|
}
|
else
|
{
|
_rightClickObj = null;
|
}
|
}
|
else if (e.Button == MouseButtons.Right)
|
{
|
if (hitInfo.InConstantLine)
|
{
|
this.popMenuLine.ShowPopup(MousePosition);
|
}
|
else
|
{
|
this.popMenuChart.ShowPopup(MousePosition);
|
}
|
}
|
}
|
|
private void chartControl1_MouseMove(object sender, MouseEventArgs e)
|
{
|
if (!_initialData)
|
return;
|
if (_onMoveWorkPointLine)
|
{
|
var diagramCoordinates = _mainChartDiagram.PointToDiagram(e.Location);
|
var axisValue = diagramCoordinates.GetAxisValue(_axisXQ);
|
if (axisValue == null)
|
return;
|
double chartQ = axisValue.NumericalValue;
|
CalcWorkPointByQ(chartQ);
|
|
}
|
}
|
|
private void chartControl1_MouseUp(object sender, MouseEventArgs e)
|
{
|
if (!_initialData)
|
return;
|
_onMoveWorkPointLine = false;
|
}
|
|
private void chartControl1_Resize(object sender, EventArgs e)
|
{
|
CalcTextAnchorPoint();
|
}
|
#endregion
|
|
#region Right Click Menu
|
|
#region Event
|
private void barBtnSetAxisQValue_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
if (_allCurves == null || !_allCurves.Any())
|
return;
|
var dlg = new AxisValueDlg();
|
dlg.SetBindingData();
|
dlg.VerifyValueChanged += (value) =>
|
{
|
if (value < _minQ || value > _maxQ)
|
return false;
|
CalcWorkPointByQ(value);
|
return true;
|
};
|
dlg.ShowDialog();
|
}
|
|
private void barCekLineVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
SetLineVisible(this.barCekLineVisible.Checked);
|
}
|
|
private void barCekCurveNameVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
SetCurveNameVisible(this.barCekCurveNameVisible.Checked);
|
}
|
|
|
private void barCekLegendVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
SetLegendVisible(this.barCekLegendVisible.Checked);
|
}
|
|
private void barCekSetAxisNameVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
SetAxisNameVisible(this.barCekSetAxisNameVisible.Checked);
|
}
|
|
private void barBtnSetChartAxis_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
SetChartAxis();
|
}
|
|
private void barCekCurveQHVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
_paneQH.Visibility = _paneQH.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible;
|
}
|
|
private void barCekCurveQEVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
_paneQE.Visibility = _paneQE.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible;
|
}
|
|
private void barCekCurveQPVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
_paneQP.Visibility = _paneQP.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible;
|
}
|
|
#endregion
|
|
/// <summary>
|
/// 设置工作点显示
|
/// </summary>
|
public void SetLineVisible(bool visible)
|
{
|
if (!_initialData)
|
return;
|
_lineVisible = visible;
|
CalcWorkPointByQ();
|
}
|
|
/// <summary>
|
/// 设置曲线名
|
/// </summary>
|
public void SetCurveNameVisible(bool visible)
|
{
|
if (!_initialData)
|
return;
|
_curveNameVisible = visible;
|
for (int i = 1; i < this.chartControl1.AnnotationRepository.Count; i++)
|
{
|
var anno = this.chartControl1.AnnotationRepository[i];
|
anno.Visible = _curveNameVisible;
|
}
|
}
|
|
/// <summary>
|
/// 设置图例显示
|
/// </summary>
|
public void SetLegendVisible(bool visible)
|
{
|
this.chartControl1.Legend.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False;
|
}
|
|
/// <summary>
|
/// 设置轴名称显示
|
/// </summary>
|
public void SetAxisNameVisible(bool visible)
|
{
|
_axisXQ.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False;
|
_axisYQH.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False;
|
_axisYQE.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False;
|
_axisYQP.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False;
|
}
|
|
/// <summary>
|
/// 设置坐标轴
|
/// </summary>
|
public void SetChartAxis()
|
{
|
var dlg = new ChartCoordinateDlg();
|
dlg.SetBindingData(_coordinateParas);
|
dlg.OnChangedCoord += (rhs) =>
|
{
|
_coordinateParas = rhs;
|
CalcChartAxis();
|
this.OnCurveCoordinateParasChanged?.Invoke(_coordinateParas);
|
};
|
dlg.ShowDialog();
|
}
|
|
#endregion
|
|
|
#region Get
|
|
/// <summary>
|
/// 获取曲线列表
|
/// </summary>
|
/// <param name="featCurveExpressGroups"></param>
|
public void GetCurves(out List<Model.FeatCurveExpressGroup> featCurveExpressGroups)
|
{
|
featCurveExpressGroups = null;
|
if (_allCurves == null || !_allCurves.Any())
|
return;
|
var list = new List<Model.FeatCurveExpressGroup>();
|
foreach (var item in _allCurves)
|
{
|
if (item.ID == -1)
|
continue;
|
var group = new Model.FeatCurveExpressGroup();
|
group.CurveQH = item.CurveExpressQH;
|
group.CurveQE = item.CurveExpressQE;
|
group.CurveQP = item.CurveExpressQP;
|
list.Add(group);
|
}
|
featCurveExpressGroups = list;
|
}
|
|
#endregion
|
}
|
}
|