using DevExpress.Utils; using DevExpress.Utils.Drawing; using DevExpress.XtraCharts; using Yw.Ahart; using Yw.Geometry; namespace Yw.WinFrmUI.Phart { /// /// 泵图表 /// 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 _vm_list = null; private List<(List FitPointList, bool IsClosed, double Tension)> _equal_eff_list = null; private (List 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 /// /// /// 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(); } } /// /// /// public bool SplitPanel { get { return _split_panel; } set { _split_panel = value; } } #endregion #region Public Evnet /// /// 坐标变换事件 /// public event Action CoordinateChangedEvent = null; /// /// 查询点变换事件 /// public event Action<(long DbId,string Tag,double X,double Y)> AnnotationChangedEvent = null; #endregion #region Private Initial /// /// 初始化图表 /// 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; } /// /// 初始化坐标轴 /// 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(); 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 pt_list) { if (pt_list == null || !pt_list.Any()) return; var pt_f_list = new List(); 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 /// /// 清空图表 /// 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(); } /// /// 设置图表 /// public void SetBindingData(List 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 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(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; } /// /// 设置图表 /// public void SetEquip(List 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 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 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; /// /// 设置坐标 /// 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>(); var h_list_list = new List>(); var e_list_list = new List>(); var p_list_list = new List>(); 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++; } } /// /// 设置图表轴 /// 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(); 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(); 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(); 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(); 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 /// /// 设置X轴值 /// 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; } /// /// 设置Y轴值 /// 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 } }