using DevExpress.Utils;
|
using DevExpress.Utils.Drawing;
|
using DevExpress.XtraCharts;
|
using Yw.Ahart;
|
using Yw.Geometry;
|
|
namespace Yw.WinFrmUI.Phart
|
{
|
/// <summary>
|
/// 泵图表
|
/// </summary>
|
public partial class PumpViewChart : DevExpress.XtraEditors.XtraUserControl
|
{
|
public PumpViewChart()
|
{
|
InitializeComponent();
|
InitialChart();
|
}
|
|
#region Private Variable
|
|
private XYDiagram _diagram;
|
private XYDiagramDefaultPane _default_pane;
|
private XYDiagramPane _bottom_pane;
|
|
private AxisX _axis_x_flow;
|
private AxisY _axis_y_head;
|
private SecondaryAxisY _axis_y_eff, _axis_y_power;
|
|
private ConstantLine _const_line_x;
|
private ConstantLine _const_line_y;
|
private TextAnnotation _anno_txt_query_info;
|
|
private PumpCoordinate _coordinate = null;
|
private List<PumpViewChartViewModel> _vm_list = null;
|
private List<(List<Yw.Geometry.Point2d> FitPointList, bool IsClosed, double Tension)> _equal_eff_list = null;
|
private (List<Yw.Geometry.Point2d> FitPointList, PumpSectPointViewModel SectPoint)? _equip = null;
|
|
private bool _power_visible = false;
|
private bool _eff_visible = false;
|
private bool _equal_eff_visible = false;
|
private bool _split_panel = false;
|
|
private bool _line_visible = false;
|
private bool _initial_data = false;
|
|
|
#endregion
|
|
#region Public Variable
|
|
/// <summary>
|
///
|
/// </summary>
|
public bool LineVisible
|
{
|
get
|
{
|
return _line_visible;
|
}
|
set
|
{
|
_line_visible = value;
|
_const_line_x.Visible = value;
|
_const_line_y.Visible = value;
|
_anno_txt_query_info.Visible = value;
|
SetAxisXValue();
|
}
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
|
public bool SplitPanel
|
{
|
get
|
{
|
return _split_panel;
|
}
|
set
|
{
|
_split_panel = value;
|
}
|
}
|
|
#endregion
|
|
#region Public Evnet
|
|
/// <summary>
|
/// 坐标变换事件
|
/// </summary>
|
public event Action<PumpCoordinate> CoordinateChangedEvent = null;
|
|
/// <summary>
|
/// 查询点变换事件
|
/// </summary>
|
public event Action<(long DbId,string Tag,double X,double Y)> AnnotationChangedEvent = null;
|
|
#endregion
|
|
#region Private Initial
|
|
/// <summary>
|
/// 初始化图表
|
/// </summary>
|
private void InitialChart()
|
{
|
this.chartControl1.SetChartDisplay();
|
this.chartControl1.RuntimeHitTesting = true;
|
//this.chartControl1.AnimationStartMode = ChartAnimationMode.OnLoad;
|
|
this.chartControl1.ObjectHotTracked += new DevExpress.XtraCharts.HotTrackEventHandler(this.chartControl1_ObjectHotTracked);
|
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);
|
this.chartControl1.CustomPaint += ChartControl1_CustomPaint;
|
|
|
|
_diagram = (XYDiagram)this.chartControl1.Diagram;
|
_default_pane = _diagram.DefaultPane;
|
_bottom_pane = (XYDiagramPane)_diagram.FindPaneByName("BottomPanel");
|
|
_axis_x_flow = _diagram.AxisX;
|
_axis_x_flow.SetAxisXQDisplay();
|
_axis_y_head = _diagram.AxisY;
|
_axis_y_head.SetAxisYQHDisplay();
|
_axis_y_eff = _diagram.SecondaryAxesY.GetAxisByName("AxisYEff");
|
_axis_y_eff.SetSecondaryAxisYQEDisplay();
|
_axis_y_eff.Alignment = AxisAlignment.Far;
|
_axis_y_power = _diagram.SecondaryAxesY.GetAxisByName("AxisYPower");
|
_axis_y_power.SetSecondaryAxisYQPDisplay();
|
|
|
_const_line_x = (ConstantLine)_diagram.AxisX.ConstantLines.GetElementByName("ConstantLineX");
|
_const_line_x.SetWorkPointLineDisplay();
|
|
_const_line_y = (ConstantLine)_diagram.AxisY.ConstantLines.GetElementByName("ConstantLineY");
|
_const_line_y.SetWorkPointLineDisplay();
|
|
_axis_x_flow.Visibility = DefaultBoolean.False;
|
_axis_x_flow.GridLines.Visible = false;
|
_axis_y_head.Visibility = DefaultBoolean.False;
|
_axis_y_head.GridLines.Visible = false;
|
_axis_y_eff.Visibility = DefaultBoolean.False;
|
_axis_y_eff.GridLines.Visible = false;
|
_axis_y_power.Visibility = DefaultBoolean.False;
|
_axis_y_power.GridLines.Visible = false;
|
|
_const_line_x.Visible = false;
|
_const_line_y.Visible = false;
|
|
_anno_txt_query_info = this.chartControl1.AnnotationRepository[0] as TextAnnotation;
|
_anno_txt_query_info.SetTextAnnoWorkPointDisplay();
|
_anno_txt_query_info.Visible = false;
|
}
|
|
|
|
|
/// <summary>
|
/// 初始化坐标轴
|
/// </summary>
|
private void InitialCoordinate()
|
{
|
//设置成白板坐标
|
_coordinate = new PumpCoordinate();
|
_coordinate.GridNumberX = 30;
|
_coordinate.GridNumberY = 16;
|
//显示的坐标线号
|
_coordinate.StartLineNoH = 10;
|
_coordinate.EndLineNoH = 15;
|
_coordinate.StartLineNoE = 0;
|
_coordinate.EndLineNoE = 10;
|
_coordinate.StartLineNoP = 2;
|
_coordinate.EndLineNoP = 9;
|
//坐标最小值和间隔
|
_coordinate.CoordMinQ = 0; _coordinate.CoordSpaceQ = 1000;
|
_coordinate.CoordMinH = 10; _coordinate.CoordSpaceH = 100;
|
_coordinate.CoordMinE = 0; _coordinate.CoordSpaceE = 100;
|
_coordinate.CoordMinP = 10; _coordinate.CoordSpaceP = 100;
|
}
|
|
#endregion
|
|
#region Private Chart Event
|
|
ToolTipController _tool_tip = new();
|
private void chartControl1_ObjectHotTracked(object sender, HotTrackEventArgs e)
|
{
|
//if (!_initial_data)
|
// return;
|
//if (e.AdditionalObject is SeriesPoint series_pt)
|
//{
|
// var tip = string.Format("X:{0:N1} Y:{1:N1}", series_pt.Argument, series_pt.Values[0]);
|
// _tool_tip.ShowHint(tip);
|
//}
|
//else
|
//{
|
// _tool_tip.HideHint();
|
//}
|
}
|
|
private bool _on_move_x_line = false;
|
private bool _on_move_y_line = false;
|
private bool _on_move_annotation = false;
|
private TextAnnotation _on_move_annotation_obj = null;
|
private void chartControl1_MouseDown(object sender, MouseEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
var hitInfo = chartControl1.CalcHitInfo(e.Location);
|
|
if (e.Button == MouseButtons.Left)
|
{
|
if (hitInfo.InConstantLine)
|
{
|
if (hitInfo.ConstantLine == _const_line_x)
|
{
|
_on_move_x_line = true;
|
}
|
else if (hitInfo.ConstantLine == _const_line_y)
|
{
|
_on_move_y_line = true;
|
}
|
}
|
else if (hitInfo.InAnnotation)
|
{
|
if (hitInfo.Annotation.Tag is not string id)
|
return;
|
if (!long.TryParse(id, out long db_id))
|
return;
|
_on_move_annotation = true;
|
_on_move_annotation_obj = (TextAnnotation)hitInfo.Annotation;
|
}
|
|
}
|
|
}
|
|
private void chartControl1_MouseMove(object sender, MouseEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
|
if (_on_move_x_line)
|
{
|
var diagram_coordinates = _diagram.PointToDiagram(e.Location);
|
var axis_value = diagram_coordinates.GetAxisValue(_axis_x_flow);
|
if (axis_value == null)
|
return;
|
double chartQ = axis_value.NumericalValue;
|
SetAxisXValue(chartQ);
|
}
|
else if (_on_move_y_line)
|
{
|
var diagram_coordinates = _diagram.PointToDiagram(e.Location);
|
var axis_value = diagram_coordinates.GetAxisValue(_axis_y_head);
|
if (axis_value == null)
|
return;
|
double chartH = axis_value.NumericalValue;
|
SetAxisYValue(chartH);
|
}
|
else
|
{
|
var hitInfo = chartControl1.CalcHitInfo(e.Location);
|
if (hitInfo.InConstantLine)
|
{
|
this.chartControl1.Cursor = Cursors.Hand;
|
}
|
else if (hitInfo.InAnnotation)
|
{
|
this.chartControl1.Cursor = Cursors.SizeAll;
|
|
}
|
else
|
{
|
this.chartControl1.Cursor = Cursors.Default;
|
}
|
}
|
|
}
|
|
private void chartControl1_MouseUp(object sender, MouseEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
if (_on_move_annotation && _on_move_annotation_obj != null)
|
{
|
if (this.AnnotationChangedEvent != null)
|
{
|
var db_id = Convert.ToInt64(_on_move_annotation_obj.Tag);
|
|
var pane_anchor_pt = _on_move_annotation_obj.AnchorPoint as PaneAnchorPoint;
|
if (pane_anchor_pt != null)
|
{
|
var diagram_coordinates = _diagram.PointToDiagram(e.Location);
|
AxisValue axis_x_value= diagram_coordinates.GetAxisValue(_axis_x_flow);
|
AxisValue axis_y_value = diagram_coordinates.GetAxisValue(pane_anchor_pt.AxisYCoordinate.Axis);
|
|
if (axis_x_value==null|| axis_y_value==null)
|
{
|
return;
|
}
|
|
var tag = pane_anchor_pt.Tag?.ToString() ?? null;
|
var x = axis_x_value.NumericalValue;
|
var y = axis_y_value.NumericalValue;
|
|
pane_anchor_pt.AxisXCoordinate.AxisValue = x;
|
pane_anchor_pt.AxisYCoordinate.AxisValue = y;
|
this.AnnotationChangedEvent?.Invoke((db_id, tag, x, y));
|
}
|
|
|
}
|
|
}
|
|
_on_move_x_line = false;
|
_on_move_y_line = false;
|
_on_move_annotation = false;
|
_on_move_annotation_obj = null;
|
}
|
|
private void chartControl1_Resize(object sender, EventArgs e)
|
{
|
var x = this.chartControl1.Location.X + this.chartControl1.Width*0.90;
|
var y = this.chartControl1.Location.Y+this.chartControl1.Height *0.1;
|
|
(_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).X = (int)x;
|
(_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).Y = (int)y;
|
}
|
|
|
private void ChartControl1_CustomPaint(object sender, CustomPaintEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
if (_vm_list == null)
|
return;
|
if (_axis_x_flow.Visibility == DefaultBoolean.False)
|
return;
|
if (e is not DXCustomPaintEventArgs dx_args)
|
return;
|
var cache = dx_args.Cache;
|
cache.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
if (_equal_eff_list != null && _equal_eff_list.Any())
|
{
|
using Pen pen = new(Color.Green, 2);
|
foreach (var vm in _equal_eff_list)
|
{
|
var fit_pt_list = vm.FitPointList;
|
var pic_eq_eff_pt_list = new List<Point>();
|
foreach (var eq_eff_pt in fit_pt_list)
|
{
|
var x = eq_eff_pt.X;
|
var y = eq_eff_pt.Y;
|
var coordinates = _diagram.DiagramToPoint(x, y, _diagram.AxisX, _diagram.AxisY);
|
if (coordinates == null)
|
continue;
|
var pt = new Point(coordinates.Point.X, coordinates.Point.Y);
|
pic_eq_eff_pt_list.Add(pt);
|
}
|
|
var pt_count = pic_eq_eff_pt_list.Count;
|
if (pt_count > 2)
|
{
|
if (vm.IsClosed)
|
{
|
var path = cache.CreatePath();
|
path.AddClosedCurve(pic_eq_eff_pt_list.ToArray(), (float)vm.Tension);
|
cache.DrawPath(pen, path);
|
}
|
else
|
{
|
var path = cache.CreatePath();
|
path.AddCurve(pic_eq_eff_pt_list.ToArray(), (float)vm.Tension);
|
cache.DrawPath(pen, path);
|
}
|
}
|
else if (pt_count == 2)
|
{
|
cache.DrawLine(pen, pic_eq_eff_pt_list[0], pic_eq_eff_pt_list[1]);
|
}
|
else if (pt_count == 1)
|
{
|
Rectangle rc = new Rectangle(pic_eq_eff_pt_list[0].X - 2, pic_eq_eff_pt_list[0].Y - 2, 4, 4);
|
using Brush b = new SolidBrush(pen.Color);
|
cache.FillEllipse(b, rc);
|
}
|
}
|
|
}
|
|
if (_equip.HasValue)
|
{
|
using Pen pen = new(Color.Black, 2);
|
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
|
DrawEquipLine(dx_args.Cache, pen, _equip.Value.FitPointList);
|
DrawEquipPoint(dx_args.Cache, pen, _equip.Value.SectPoint);
|
}
|
}
|
|
private void DrawEquipPoint(GraphicsCache cache, Pen pen, PumpSectPointViewModel sect_pt)
|
{
|
if (sect_pt == null)
|
return;
|
|
double Q = sect_pt.Q;
|
double H = sect_pt.H;
|
double? E = sect_pt.E;
|
double? P = sect_pt.P;
|
|
var offset_size = 10;
|
var qh_pt = _diagram.DiagramToPoint(Q, H, _axis_x_flow, _axis_y_head);
|
|
var qh_pt_x = qh_pt.Point.X;
|
var qh_pt_y = qh_pt.Point.Y;
|
cache.DrawLine(pen, new Point(qh_pt_x, qh_pt_y - offset_size), new Point(qh_pt_x, qh_pt_y + offset_size));
|
|
if (E.HasValue && _eff_visible)
|
{
|
var qe_pt = _diagram.DiagramToPoint(Q, E.Value, _axis_x_flow, _axis_y_eff);
|
var qe_pt_x = qe_pt.Point.X;
|
var qe_pt_y = qe_pt.Point.Y;
|
cache.DrawLine(pen, new Point(qe_pt_x, qe_pt_y - offset_size), new Point(qe_pt_x, qe_pt_y + offset_size));
|
}
|
|
if (P.HasValue && _power_visible)
|
{
|
var qp_pt = _diagram.DiagramToPoint(Q, P.Value, _axis_x_flow, _axis_y_power);
|
var qp_pt_x = qp_pt.Point.X;
|
var qp_pt_y = qp_pt.Point.Y;
|
cache.DrawLine(pen, new Point(qp_pt_x, qp_pt_y - offset_size), new Point(qp_pt_x, qp_pt_y + offset_size));
|
}
|
|
}
|
|
private void DrawEquipLine(GraphicsCache cache, Pen pen, List<Yw.Geometry.Point2d> pt_list)
|
{
|
if (pt_list == null || !pt_list.Any())
|
return;
|
var pt_f_list = new List<PointF>();
|
foreach (var pt in pt_list)
|
{
|
var x = pt.X;
|
var y = pt.Y;
|
var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_head);
|
pt_f_list.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
|
}
|
|
using var path = new System.Drawing.Drawing2D.GraphicsPath();
|
path.AddCurve(pt_f_list.ToArray());
|
cache.DrawPath(pen, path);
|
}
|
#endregion
|
|
#region Set
|
|
/// <summary>
|
/// 清空图表
|
/// </summary>
|
public void Clear()
|
{
|
_vm_list = null;
|
_equal_eff_list = null;
|
_equip = null;
|
_coordinate = null;
|
_split_panel = false;
|
_eff_visible = false;
|
_power_visible = false;
|
_initial_data = false;
|
this.chartControl1.BeginInit();
|
this.chartControl1.Series.Clear();
|
for (int i = this.chartControl1.AnnotationRepository.Count - 1; i > 0; i--)
|
{
|
if (i == 0)
|
break;
|
this.chartControl1.AnnotationRepository.RemoveAt(i);
|
}
|
this.chartControl1.Legend.CustomItems.Clear();
|
this.chartControl1.EndInit();
|
}
|
|
/// <summary>
|
/// 设置图表
|
/// </summary>
|
public void SetBindingData(List<PumpViewChartViewModel> vm_list, string coordinate = null, bool split_panel = true, bool eff_visible = true, bool power_visible = true, bool equal_eff_visible = true)
|
{
|
_vm_list = vm_list;
|
_equal_eff_list = null;
|
_equip = null;
|
_coordinate = PumpCoordinate.ToModel(coordinate);
|
_split_panel = split_panel;
|
_eff_visible = eff_visible;
|
_power_visible = power_visible;
|
_equal_eff_visible = equal_eff_visible;
|
|
this.chartControl1.BeginInit();
|
this.chartControl1.Series.Clear();
|
for (int i = this.chartControl1.AnnotationRepository.Count - 1; i > 0; i--)
|
{
|
if (i == 0)
|
break;
|
this.chartControl1.AnnotationRepository.RemoveAt(i);
|
}
|
this.chartControl1.Legend.CustomItems.Clear();
|
if (IsInvalidData())
|
{
|
_initial_data = false;
|
this.chartControl1.EndInit();
|
return;
|
}
|
|
AxisXBase axis_x = null;
|
AxisYBase axis_y = null;
|
XYDiagramPaneBase pane = null;
|
|
_equal_eff_list = new List<(List<Point2d> FitPointList, bool IsClosed, double Tension)>();
|
foreach (var vm in _vm_list)
|
{
|
if (vm.CurveType == Ahart.eCurveType.EqualE)
|
{
|
axis_x = _axis_x_flow;
|
axis_y = _axis_y_head;
|
pane = _default_pane;
|
var paras = PhartGraphHelper.GetGraphParas<EqualEGraphParasViewModel>(vm.CurveType, vm.GraphParas);
|
if (paras.Tension<=0)
|
{
|
paras.Tension = 0.7;
|
}
|
_equal_eff_list.Add((vm.FitPointList, paras.IsClosed, paras.Tension));
|
}
|
else if (vm.CurveType == Ahart.eCurveType.QH)
|
{
|
axis_x = _axis_x_flow;
|
axis_y = _axis_y_head;
|
pane = _default_pane;
|
|
}
|
else if (vm.CurveType == Ahart.eCurveType.QE)
|
{
|
axis_x = _axis_x_flow;
|
axis_y = _axis_y_eff;
|
pane = _default_pane;
|
|
}
|
else if (vm.CurveType == Ahart.eCurveType.QP)
|
{
|
axis_x = _axis_x_flow;
|
axis_y = _axis_y_power;
|
pane = _split_panel? _bottom_pane: _default_pane;
|
}
|
|
if (vm.AnnotationList != null && vm.AnnotationList.Any())
|
{
|
foreach (var name in vm.AnnotationList)
|
{
|
AddAnnotation(vm.Id, name.Tag, name.Text, vm.Color, axis_y, pane, new Geometry.Point2d(name.X, name.Y), 0,0);
|
}
|
}
|
|
|
if (vm.CurveType == Ahart.eCurveType.EqualE)
|
continue;
|
|
var dash_style = DashStyle.Solid;
|
if (vm.Hz == 50)
|
dash_style = DashStyle.Dot;
|
|
AddLineSeries(vm.Id, vm.Color, axis_x, axis_y, pane, vm.FitPointList, dash_style);
|
}
|
|
if (_coordinate == null)
|
SetCoordinate();
|
|
SetChartAxis();
|
this.chartControl1.EndInit();
|
_initial_data = true;
|
|
}
|
|
/// <summary>
|
/// 设置图表
|
/// </summary>
|
public void SetEquip(List<Yw.Geometry.Point2d> fit_pt_list, PumpSectPointViewModel sect_pt)
|
{
|
_equip = null;
|
if (fit_pt_list != null && fit_pt_list.Any() && sect_pt != null)
|
{
|
_equip = (fit_pt_list, sect_pt);
|
}
|
|
SetCoordinate();
|
SetChartAxis();
|
}
|
|
//是否是无效数据
|
private bool IsInvalidData()
|
{
|
if (_vm_list == null || !_vm_list.Any())
|
{
|
return true;
|
}
|
if (!_vm_list.Exists(x => x.CurveType == Ahart.eCurveType.QH))
|
{
|
return true;
|
}
|
return false;
|
}
|
|
|
#region Add Chart Data
|
|
private void AddPointSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list, MarkerKind marker = MarkerKind.Circle)
|
{
|
if (pt_list == null || !pt_list.Any())
|
return;
|
|
var view = new DevExpress.XtraCharts.PointSeriesView();
|
view.PointMarkerOptions.Size = 8;
|
view.PointMarkerOptions.Kind = marker;
|
view.PointMarkerOptions.BorderColor = color;
|
view.Color = color;
|
view.AxisX = axis_x;
|
view.AxisY = axis_y;
|
view.EmptyPointOptions.Color = Color.Transparent;
|
view.Pane = pane;
|
|
var series_pt_list = pt_list.Select(x => x.ToSeriesPoint()).ToArray();
|
var series = new DevExpress.XtraCharts.Series();
|
series.Tag = id;
|
series.ShowInLegend = false;
|
series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
series.CrosshairEnabled = DefaultBoolean.False;
|
series.CrosshairLabelVisibility = DefaultBoolean.False;
|
series.ToolTipEnabled = DefaultBoolean.False;
|
series.SeriesPointsSorting = SortingMode.None;
|
series.Visible = true;
|
series.View = view;
|
series.CrosshairLabelPattern = "{A}";
|
series.Points.AddRange(series_pt_list);
|
this.chartControl1.Series.Add(series);
|
}
|
|
private void AddLineSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list, DevExpress.XtraCharts.DashStyle dash = DevExpress.XtraCharts.DashStyle.Solid)
|
{
|
if (pt_list == null || !pt_list.Any())
|
return;
|
|
var view = new DevExpress.XtraCharts.LineSeriesView();
|
view.LineStyle.DashStyle = dash;
|
view.LineStyle.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
|
view.LineStyle.Thickness = 2;
|
if (dash!= DashStyle.Solid)
|
{
|
view.LineStyle.Thickness =3;
|
}
|
view.Color = color;
|
view.EnableAntialiasing = DefaultBoolean.True;
|
view.MarkerVisibility = DefaultBoolean.False;
|
view.AxisX = axis_x;
|
view.AxisY = axis_y;
|
view.EmptyPointOptions.Color = Color.Transparent;
|
view.Pane = pane;
|
|
var series_pt_list = pt_list.Select(x => x.ToSeriesPoint()).ToArray();
|
var series = new DevExpress.XtraCharts.Series();
|
series.Tag = id;
|
series.ShowInLegend = false;
|
series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
series.CrosshairEnabled = DefaultBoolean.False;
|
series.ToolTipEnabled = DefaultBoolean.False;
|
series.SeriesPointsSorting = SortingMode.None;
|
series.Visible = true;
|
series.View = view;
|
series.Points.AddRange(series_pt_list);
|
|
this.chartControl1.Series.Add(series);
|
}
|
|
private void AddAnnotation(string id, string tag, string caption, Color color, AxisYBase axis_y, XYDiagramPaneBase pane, Yw.Geometry.Point2d pt, double angle = -10, double connector_length = 20)
|
{
|
if (pt == null)
|
return;
|
var anchor_pt = pt;
|
var pane_anchor_pt = new DevExpress.XtraCharts.PaneAnchorPoint();
|
pane_anchor_pt.Pane = pane;
|
pane_anchor_pt.AxisYCoordinate.Axis = axis_y;
|
pane_anchor_pt.AxisXCoordinate.AxisValue = anchor_pt.X;
|
pane_anchor_pt.AxisYCoordinate.AxisValue = anchor_pt.Y;
|
pane_anchor_pt.Tag = tag;
|
|
|
|
var relative_position = new DevExpress.XtraCharts.RelativePosition();
|
relative_position.Angle = angle;
|
relative_position.ConnectorLength = connector_length;
|
|
var text_annotation = new TextAnnotation();
|
text_annotation.AnchorPoint = pane_anchor_pt;
|
text_annotation.AutoHeight = true;
|
text_annotation.AutoWidth = true;
|
text_annotation.BackColor = System.Drawing.Color.Transparent;
|
text_annotation.Border.Color = System.Drawing.Color.Transparent;
|
text_annotation.Border.Visibility = DefaultBoolean.False;
|
text_annotation.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.None;
|
text_annotation.Tag = id;
|
text_annotation.Padding.Bottom = 1;
|
text_annotation.Padding.Left = 1;
|
text_annotation.Padding.Right = 1;
|
text_annotation.Padding.Top = 1;
|
text_annotation.RuntimeMoving = false;
|
text_annotation.RuntimeAnchoring = true;
|
text_annotation.RuntimeResizing = false;
|
text_annotation.RuntimeRotation = false;
|
text_annotation.RuntimeEditing = false;
|
text_annotation.Text = caption;
|
text_annotation.TextColor = color;
|
text_annotation.ShapePosition = relative_position;
|
text_annotation.Visible = true;
|
text_annotation.EnableAntialiasing = DefaultBoolean.True;
|
|
text_annotation.DXFont = new DevExpress.Drawing.DXFont(this.Font.Name, 10F);
|
|
this.chartControl1.AnnotationRepository.Add(text_annotation);
|
}
|
|
#endregion
|
|
#endregion
|
|
#region Set Axis
|
|
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 SetCoordinate()
|
{
|
if (IsInvalidData())
|
{
|
InitialCoordinate();
|
return;
|
}
|
|
_maxQ = 0; _minQ = 100000;
|
_maxH = 0; _minH = 10000;
|
_maxE = 0; _minE = 0;
|
_maxP = 0; _minP = 1000;
|
|
var q_list_list = new List<List<double>>();
|
var h_list_list = new List<List<double>>();
|
var e_list_list = new List<List<double>>();
|
var p_list_list = new List<List<double>>();
|
|
foreach (var vm in _vm_list)
|
{
|
if (vm.CurveType == Ahart.eCurveType.QH || vm.CurveType == Ahart.eCurveType.EqualE)
|
{
|
q_list_list.Add(vm.FitPointList.Select(x => x.X).ToList());
|
h_list_list.Add(vm.FitPointList.Select(x => x.Y).ToList());
|
}
|
else if (vm.CurveType == Ahart.eCurveType.QE)
|
{
|
e_list_list.Add(vm.FitPointList.Select(x => x.Y).ToList());
|
}
|
else if (vm.CurveType == Ahart.eCurveType.QP)
|
{
|
p_list_list.Add(vm.FitPointList.Select(x => x.Y).ToList());
|
}
|
}
|
|
if (_equip.HasValue)
|
{
|
var fit_pt_list = _equip.Value.FitPointList;
|
q_list_list.Add(fit_pt_list.Select(x => x.X).ToList());
|
h_list_list.Add(fit_pt_list.Select(x => x.Y).ToList());
|
}
|
|
|
foreach (var list in q_list_list)
|
{
|
_minQ = Math.Min(_minQ, list.Min());
|
_maxQ = Math.Max(_maxQ, list.Max());
|
}
|
|
foreach (var list in h_list_list)
|
{
|
_minH = Math.Min(_minH, list.Min());
|
_maxH = Math.Max(_maxH, list.Max());
|
}
|
|
|
foreach (var list in e_list_list)
|
{
|
_minE = Math.Max(_minE, list.Min());
|
_maxE = Math.Max(_maxE, list.Max());
|
}
|
|
|
foreach (var list in p_list_list)
|
{
|
_minP = Math.Min(_minP, list.Min());
|
_maxP = Math.Max(_maxP, list.Max());
|
}
|
|
_coordinate = PumpCoordinate.CalcCoordinate(_minQ, _maxQ, _minH, _maxH, _minE, _maxE, _minP, _maxP);
|
if (_coordinate == null)
|
return;
|
if (_coordinate.CoordMinQ + _coordinate.CoordSpaceQ * this._coordinate.GridNumberX < _maxQ * 1.05)
|
{
|
_coordinate.GridNumberX++;
|
}
|
|
}
|
|
/// <summary>
|
/// 设置图表轴
|
/// </summary>
|
private void SetChartAxis()
|
{
|
_axis_x_flow.Visibility = DefaultBoolean.False;
|
_axis_x_flow.GridLines.Visible = false;
|
_axis_y_head.Visibility = DefaultBoolean.False;
|
_axis_y_head.GridLines.Visible = false;
|
_axis_y_eff.Visibility = DefaultBoolean.False;
|
_axis_y_eff.GridLines.Visible = false;
|
_axis_y_power.Visibility = DefaultBoolean.False;
|
_axis_y_power.GridLines.Visible = false;
|
if (_coordinate == null)
|
{
|
_const_line_x.Visible = false;
|
_const_line_y.Visible = false;
|
_bottom_pane.Visibility = ChartElementVisibility.Hidden;
|
return;
|
}
|
|
|
//计算刻度 Q
|
var axisQLabels = new List<CustomAxisLabel>();
|
var disQ = _coordinate.CoordMinQ;
|
for (int i = 0; i < _coordinate.GridNumberX + 1; i++)
|
{
|
axisQLabels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ));
|
disQ = disQ + _coordinate.CoordSpaceQ;
|
}
|
|
_axis_x_flow.CustomLabels.Clear();
|
_axis_x_flow.CustomLabels.AddRange(axisQLabels.ToArray());
|
_axis_x_flow.Visibility = DefaultBoolean.True;
|
_axis_x_flow.GridLines.Visible = true;
|
|
|
//计算刻度
|
var axis_head_labels = new List<CustomAxisLabel>();
|
var display_head = _coordinate.CoordMinH + _coordinate.CoordSpaceH * _coordinate.StartLineNoH;
|
for (int i = _coordinate.StartLineNoH; i < _coordinate.EndLineNoH + 1; i++)
|
{
|
axis_head_labels.Add(new CustomAxisLabel(display_head.ToString(), display_head));
|
display_head = display_head + _coordinate.CoordSpaceH;
|
}
|
|
_axis_y_head.CustomLabels.Clear();
|
_axis_y_head.CustomLabels.AddRange(axis_head_labels.ToArray());
|
_axis_y_head.Visibility = DefaultBoolean.True;
|
_axis_y_head.GridLines.Visible = true;
|
|
//效率
|
if (_maxE > _minE && _eff_visible)
|
{
|
//计算刻度
|
var label_list = new List<CustomAxisLabel>();
|
var display_eff = _coordinate.CoordMinE + _coordinate.CoordSpaceE * _coordinate.StartLineNoE;
|
for (int i = _coordinate.StartLineNoE; i < _coordinate.EndLineNoE + 1; i++)
|
{
|
label_list.Add(new CustomAxisLabel(display_eff.ToString(), display_eff));
|
display_eff = display_eff + _coordinate.CoordSpaceE;
|
}
|
|
_axis_y_eff.CustomLabels.Clear();
|
_axis_y_eff.CustomLabels.AddRange(label_list.ToArray());
|
_axis_y_eff.Visibility = DefaultBoolean.True;
|
_axis_y_eff.GridLines.Visible = true;
|
}
|
|
//功率
|
if (_maxP > _minP && _power_visible)
|
{
|
//计算刻度
|
var label_list = new List<CustomAxisLabel>();
|
double display_power = _coordinate.CoordMinP + _coordinate.CoordSpaceP * _coordinate.StartLineNoP;
|
for (int i = _coordinate.StartLineNoP; i < _coordinate.EndLineNoP + 1; i++)
|
{
|
label_list.Add(new CustomAxisLabel(display_power.ToString(), display_power));
|
display_power = display_power + _coordinate.CoordSpaceP;
|
}
|
|
_axis_y_power.CustomLabels.Clear();
|
_axis_y_power.CustomLabels.AddRange(label_list.ToArray());
|
_axis_y_power.Visibility = DefaultBoolean.True;
|
_axis_y_power.GridLines.Visible = true;
|
}
|
|
|
_axis_x_flow.SetAxisRange(_coordinate.CoordMinQ, _coordinate.CoordMinQ + _coordinate.GridNumberX * _coordinate.CoordSpaceQ);
|
if (_split_panel)
|
{
|
|
var grid_count_head = _coordinate.EndLineNoH - _coordinate.StartLineNoH;
|
var grid_count_eff = _coordinate.EndLineNoE - _coordinate.StartLineNoE;
|
int grid_count_up = Math.Max(grid_count_head, grid_count_eff);
|
if (_eff_visible)
|
{
|
grid_count_up += 4;//多两条
|
}
|
|
var max_axis_head = _coordinate.CoordMinH + _coordinate.EndLineNoH * _coordinate.CoordSpaceH;
|
var min_axis_head = max_axis_head - grid_count_up * _coordinate.CoordSpaceH;
|
_axis_y_head.SetAxisRange(min_axis_head, max_axis_head);
|
|
var min_axis_eff = _coordinate.CoordMinE + _coordinate.StartLineNoE * _coordinate.CoordSpaceE;
|
var max_axis_eff = min_axis_eff + grid_count_up * _coordinate.CoordSpaceE;
|
_axis_y_eff.SetAxisRange(min_axis_eff, max_axis_eff);
|
|
if ((!_eff_visible) && (!_power_visible))
|
{
|
_axis_y_head.SetAxisRange(_coordinate.DispMinH(), _coordinate.DispMaxH());
|
}
|
|
_axis_y_power.SetAxisRange(_coordinate.DispMinP(), _coordinate.DispMaxP());
|
_bottom_pane.Visibility = ChartElementVisibility.Visible;
|
}
|
else
|
{
|
if (_eff_visible)
|
{
|
_axis_y_head.SetAxisRange(_coordinate.CoordMinH, _coordinate.CoordMinH + _coordinate.GridNumberY * _coordinate.CoordSpaceH);
|
_axis_y_eff.SetAxisRange(_coordinate.CoordMinE, _coordinate.CoordMinE + _coordinate.GridNumberY * _coordinate.CoordSpaceE);
|
_axis_y_power.SetAxisRange(_coordinate.CoordMinP, _coordinate.CoordMinP + _coordinate.GridNumberY * _coordinate.CoordSpaceP);
|
}
|
else
|
{
|
|
var grid_count_eff = _coordinate.GridNumberY - (_coordinate.EndLineNoH - _coordinate.StartLineNoH+ _coordinate.EndLineNoP - _coordinate.StartLineNoP);
|
var grid_delete_head = grid_count_eff * _coordinate.CoordSpaceH;
|
double min_head = _coordinate.CoordMinH;
|
if (true)
|
{
|
if (_coordinate.CoordMinH<0)
|
{
|
min_head=_coordinate.CoordMinH - -grid_delete_head;
|
}
|
else
|
{
|
min_head = _coordinate.CoordMinH+grid_delete_head;
|
}
|
}
|
var grid_delete_power = grid_count_eff * _coordinate.CoordSpaceP;
|
_axis_y_head.SetAxisRange(min_head, _coordinate.CoordMinH + _coordinate.GridNumberY * _coordinate.CoordSpaceH);
|
_axis_y_power.SetAxisRange(_coordinate.CoordMinP, _coordinate.CoordMinP + _coordinate.GridNumberY * _coordinate.CoordSpaceP - grid_delete_power);
|
}
|
|
|
_bottom_pane.Visibility = ChartElementVisibility.Hidden;
|
}
|
|
}
|
|
#endregion
|
|
#region Set Axis Value
|
|
/// <summary>
|
/// 设置X轴值
|
/// </summary>
|
public void SetAxisXValue(double? x = null)
|
{
|
if (!_line_visible)
|
{
|
_const_line_x.Visible = false;
|
_const_line_x.Title.Visible = false;
|
_const_line_y.Visible = false;
|
_const_line_y.Title.Visible = false;
|
_anno_txt_query_info.Visible = false;
|
return;
|
}
|
else
|
{
|
_const_line_x.Visible = true;
|
_const_line_x.Title.Visible = true;
|
_const_line_y.Visible = true;
|
_const_line_y.Title.Visible = true;
|
_anno_txt_query_info.Visible = true;
|
}
|
if (this.IsInvalidData())
|
return;
|
var qh = _vm_list.Find(x => x.IsSelect&&x.CurveType== eCurveType.QH);
|
if (qh == null)
|
return;
|
|
var min_x = qh.FitPointList.Min(x => x.X);
|
var max_x = qh.FitPointList.Max(x => x.X);
|
|
if (x == null)
|
{
|
x = (min_x + max_x) / 2;
|
}
|
else
|
{
|
if (x < min_x || x > max_x)
|
return;
|
}
|
|
var x_value = x.Value;
|
var y_value = qh.FitPointList.GetInterPointsY(x_value)?.FirstOrDefault();
|
|
_const_line_x.AxisValue = x_value;
|
_const_line_x.Title.Text = $"{x_value:N1}";
|
|
_const_line_y.AxisValue = y_value;
|
_const_line_y.Title.Text = $"{y_value:N1}";
|
|
var query_info_builder = new StringBuilder();
|
query_info_builder.AppendLine($"{x_value:N2} m³/h ");
|
query_info_builder.AppendLine($"{y_value:N2} m");
|
|
var qe = _vm_list.Find(x => x.IsSelect && x.CurveType == eCurveType.QE);
|
if (qe != null)
|
{
|
var eff = qe.FitPointList.GetInterPointsY(x_value).FirstOrDefault();
|
query_info_builder.AppendLine($"{eff:N2} % ");
|
}
|
|
var qp = _vm_list.Find(x => x.IsSelect && x.CurveType == eCurveType.QP);
|
if (qp != null)
|
{
|
var power = qp.FitPointList.GetInterPointsY(x_value).FirstOrDefault();
|
query_info_builder.Append($"{power:N2} kW/h ");
|
}
|
|
|
_anno_txt_query_info.Text = query_info_builder.ToString();
|
_anno_txt_query_info.AutoSize = true;
|
_anno_txt_query_info.Visible = true;
|
|
}
|
|
/// <summary>
|
/// 设置Y轴值
|
/// </summary>
|
public void SetAxisYValue(double y)
|
{
|
if (!_line_visible)
|
return;
|
if (IsInvalidData())
|
return;
|
var vm_sel = _vm_list.Find(x => x.IsSelect);
|
if (vm_sel == null)
|
return;
|
|
var min_y = vm_sel.FitPointList.Min(x => x.Y);
|
var max_y = vm_sel.FitPointList.Max(x => x.Y);
|
if (y < min_y || y > max_y)
|
return;
|
|
var x_value = vm_sel.FitPointList.GetInterPointsX(y)?.LastOrDefault();
|
SetAxisXValue(x_value);
|
}
|
|
#endregion
|
}
|
}
|