using DevExpress.Utils; using DevExpress.XtraCharts; using Yw.Geometry; namespace Yw.WinFrmUI.Phart { /// /// /// public partial class ValveViewChart : DevExpress.XtraEditors.XtraUserControl { public ValveViewChart() { 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_loss; private SecondaryAxisX _axis_x_opening; private SecondaryAxisY _axis_y_k; private ConstantLine _const_line_x_flow; private ConstantLine _const_line_x_opening; private ConstantLine _const_line_y_k; private TextAnnotation _anno_txt_query_info; private ValveCoordinate _coordinate; private bool _line_visible = false; private bool _initial_data = false; private bool _exist_ql = false; private bool _exist_ol = false; private List _vm_list = null; #endregion #region Public Variable public bool LineVisible { get { return _line_visible; } set { _line_visible = value; _const_line_x_flow.Visible = value; _const_line_x_opening.Visible = value; _const_line_y_k.Visible = value; SetAxisXFlowValue(); SetAxisXOpeningValue(); } } #endregion #region Public Evnet /// /// 坐标变更事件 /// public event Action CoordinateChangedEvent; /// /// 定义点变更事件 /// public event Action> DefinePointChangedEvent; /// /// 选中点 /// public event Action SelectedPointIndexChangedEvent; #endregion #region Private Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; this.chartControl1.RuntimeHitTesting = true; 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); _diagram = (XYDiagram)this.chartControl1.Diagram; _default_pane = _diagram.DefaultPane; _bottom_pane = _diagram.Panes[0]; _axis_x_flow = _diagram.AxisX; _axis_x_flow.SetAxisXQDisplay(); _axis_y_head_loss = _diagram.AxisY; _axis_y_head_loss.SetAxisYQHDisplay(); _axis_x_flow.Visibility = DefaultBoolean.False; _axis_x_flow.GridLines.Visible = false; _axis_x_flow.GridLines.Color = Color.Silver; _axis_x_flow.Color = Color.Black; _axis_x_flow.Title.TextColor = Color.Black; _axis_x_flow.Label.TextColor = Color.Black; _axis_y_head_loss.Visibility = DefaultBoolean.False; _axis_y_head_loss.GridLines.Visible = false; _axis_y_head_loss.GridLines.Color = Color.Silver; _axis_y_head_loss.Color = Color.Black; _axis_y_head_loss.Title.TextColor = Color.Black; _axis_y_head_loss.Label.TextColor = Color.Black; _axis_x_opening = _diagram.SecondaryAxesX[0]; _axis_x_opening.SetAxisXQDisplay(); _axis_y_k = _diagram.SecondaryAxesY[0]; _axis_y_k.SetSecondaryAxisYQPDisplay(); _axis_x_opening.Visibility = DefaultBoolean.False; _axis_x_opening.GridLines.Visible = false; _axis_x_opening.GridLines.Color = Color.Silver; _axis_x_opening.Color = Color.Black; _axis_x_opening.Title.TextColor = Color.Black; _axis_x_opening.Label.TextColor = Color.Black; _axis_y_k.Visibility = DefaultBoolean.False; _axis_y_k.GridLines.Visible = false; _axis_y_k.GridLines.Color = Color.Silver; _axis_y_k.Color = Color.Black; _axis_y_k.Title.TextColor = Color.Black; _axis_y_k.Label.TextColor = Color.Black; _const_line_x_flow = (ConstantLine)_axis_x_flow.ConstantLines.GetElementByName("ConstantLineFlow"); _const_line_x_flow.SetWorkPointLineDisplay(); _const_line_x_opening = (ConstantLine)_axis_x_opening.ConstantLines.GetElementByName("ConstantLineOpening"); _const_line_x_opening.SetWorkPointLineDisplay(); _const_line_y_k = (ConstantLine)_axis_y_k.ConstantLines.GetElementByName("ConstantLineK"); _const_line_y_k.SetWorkPointLineDisplay(); _const_line_x_flow.Visible = false; _const_line_x_opening.Visible = false; _const_line_y_k.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 ValveCoordinate(); _coordinate.QL = new(); _coordinate.OL = new(); _coordinate.QL.GridNumberX = 30; _coordinate.QL.GridNumberY = 16; _coordinate.QL.StartLineNoY = 10; _coordinate.QL.EndLineNoY = 15; _coordinate.QL.CoordMinX = 0; _coordinate.QL.CoordSpaceX = 1000; _coordinate.QL.CoordMinY = 10; _coordinate.QL.CoordSpaceY = 100; _coordinate.OL.GridNumberX = 30; _coordinate.OL.GridNumberY = 16; _coordinate.OL.StartLineNoY = 10; _coordinate.OL.EndLineNoY = 15; _coordinate.OL.CoordMinX = 0; _coordinate.OL.CoordSpaceX = 1000; _coordinate.OL.CoordMinY = 10; _coordinate.OL.CoordSpaceY = 100; } #endregion Initial #region Private Chart Event private bool _on_move_x_flow_line = false; private bool _on_move_x_opening_line = false; private bool _on_move_y_k = false; 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_flow) { _on_move_x_flow_line = true; } else if (hitInfo.ConstantLine == _const_line_x_opening) { _on_move_x_opening_line = true; } else if (hitInfo.ConstantLine == _const_line_y_k) { _on_move_y_k = true; } } } } private void chartControl1_MouseMove(object sender, MouseEventArgs e) { if (!_initial_data) return; if (_on_move_x_flow_line) { var diagram_coordinates = _diagram.PointToDiagram(e.Location); var axis_value = diagram_coordinates.GetAxisValue(_axis_x_flow); if (axis_value == null) return; double x = axis_value.NumericalValue; SetAxisXFlowValue(x); } else if (_on_move_x_opening_line) { var diagram_coordinates = _diagram.PointToDiagram(e.Location); var axis_value = diagram_coordinates.GetAxisValue(_axis_x_opening); if (axis_value == null) return; double x = axis_value.NumericalValue; SetAxisXOpeningValue(x); } else if (_on_move_y_k) { var diagram_coordinates = _diagram.PointToDiagram(e.Location); var axis_value = diagram_coordinates.GetAxisValue(_axis_y_k); if (axis_value == null) return; double y = axis_value.NumericalValue; SetAxisYKValue(y); } 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; _on_move_x_flow_line = false; _on_move_x_opening_line = false; _on_move_y_k = false; } private void chartControl1_Resize(object sender, EventArgs e) { SetTextAnchorPoint(); } #endregion #region Set /// /// 绑定数据 /// public void Clear() { _initial_data = false; _coordinate = null; _vm_list = null; _exist_ql = false; _exist_ol = 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) { _initial_data = false; _coordinate = ValveCoordinate.ToModel(coordinate); _vm_list = vm_list; _exist_ql = false; _exist_ol = 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(); if (IsInvalidData()) { _initial_data = false; this.chartControl1.EndInit(); return; } AxisXBase axis_x = null; AxisYBase axis_y = null; XYDiagramPaneBase pane = null; foreach (var vm in _vm_list) { if (vm.CurveType == Ahart.eCurveType.QL) { axis_x = _axis_x_flow; axis_y = _axis_y_head_loss; pane = _default_pane; _exist_ql = true; } else if (vm.CurveType == Ahart.eCurveType.OL) { axis_x = _axis_x_opening; axis_y = _axis_y_k; pane = _bottom_pane; _exist_ol = true; } // AddPointSeries(vm.Color, axis_x, axis_y, pane, vm.DefPointList); AddLineSeries(vm.Color, axis_x, axis_y, pane, vm.FitPointList); if (!string.IsNullOrEmpty(vm.Name) && vm.CurveType == Ahart.eCurveType.QL) { AddAnnotation(vm.Id, vm.Name, vm.Color, axis_y, pane, vm.FitPointList.Last(), -40); } } if (_coordinate == null) SetCoordinate(); SetChartAxis(); this.chartControl1.EndInit(); _initial_data = true; SetAxisXFlowValue(); SetAxisXOpeningValue(); } //是否是无效数据 private bool IsInvalidData() { if (_vm_list == null || !_vm_list.Any()) { return true; } if (!_vm_list.Exists(x => x.IsSelect)) { return true; } return false; } #region Add Chart Data private Series AddPointSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List pt_list) { if (pt_list == null || !pt_list.Any()) return null; var view = new DevExpress.XtraCharts.PointSeriesView(); view.PointMarkerOptions.Size = 8; view.PointMarkerOptions.Kind = MarkerKind.Circle; 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 = new List(); for (int i = 0; i < pt_list.Count; i++) { var pt = pt_list[i]; var series_pt = new DevExpress.XtraCharts.SeriesPoint(pt.X, new double[] { pt.Y }); series_pt.Tag = i; series_pt_list.Add(series_pt); } var series = new DevExpress.XtraCharts.Series(); 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.ToArray()); this.chartControl1.Series.Add(series); return series; } private void AddLineSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List pt_list, DashStyle dash = 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; 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.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 caption, Color color, AxisYBase axis_y, XYDiagramPaneBase pane, Yw.Geometry.Point2d pt, double angle = -10) { 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; var relative_position = new DevExpress.XtraCharts.RelativePosition(); relative_position.Angle = angle; relative_position.ConnectorLength = 30; 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 = true; text_annotation.RuntimeAnchoring = false; text_annotation.RuntimeResizing = false; text_annotation.RuntimeRotation = false; text_annotation.Text = caption; text_annotation.TextColor = color; text_annotation.ShapePosition = relative_position; text_annotation.Visible = 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 _min_x_flow, _max_x_flow; private double _max_y_head_loss = 0, _min_y_head_loss = 10000; private double _min_x_opening, _max_x_opening; private double _max_y_k = 0, _min_y_k = 10000; /// /// 设置坐标 /// private void SetCoordinate() { InitialCoordinate(); if (IsInvalidData()) { return; } _max_x_flow = 0; _min_x_flow = 100000; _max_x_opening = 0; _min_x_opening = 100000; _max_y_head_loss = 0; _min_y_head_loss = 10000; _max_y_k = 0; _min_y_k = 10000; foreach (var vm in _vm_list) { if (vm.CurveType == Ahart.eCurveType.QL) { _min_x_flow = Math.Min(vm.DefPointList.Min(x => x.X), _min_x_flow); _max_x_flow = Math.Max(vm.DefPointList.Max(x => x.X), _max_x_flow); _min_y_head_loss = Math.Min(vm.DefPointList.Min(x => x.Y), _min_y_head_loss); _max_y_head_loss = Math.Max(vm.DefPointList.Max(x => x.Y), _max_y_head_loss); _min_x_flow = Math.Min(vm.FitPointList.Min(x => x.X), _min_x_flow); _max_x_flow = Math.Max(vm.FitPointList.Max(x => x.X), _max_x_flow); _min_y_head_loss = Math.Min(vm.FitPointList.Min(x => x.Y), _min_y_head_loss); _max_y_head_loss = Math.Max(vm.FitPointList.Max(x => x.Y), _max_y_head_loss); } else if (vm.CurveType == Ahart.eCurveType.OL) { _min_x_opening = Math.Min(vm.DefPointList.Min(x => x.X), _min_x_opening); _max_x_opening = Math.Max(vm.DefPointList.Max(x => x.X), _max_x_opening); _min_y_k = Math.Min(vm.DefPointList.Min(x => x.Y), _min_y_k); _max_y_k = Math.Max(vm.DefPointList.Max(x => x.Y), _max_y_k); _min_x_opening = Math.Min(vm.FitPointList.Min(x => x.X), _min_x_opening); _max_x_opening = Math.Max(vm.FitPointList.Max(x => x.X), _max_x_opening); _min_y_k = Math.Min(vm.FitPointList.Min(x => x.Y), _min_y_k); _max_y_k = Math.Max(vm.FitPointList.Max(x => x.Y), _max_y_k); } } _coordinate.QL = ValveQLCoordinate.CalcCoordinate(_min_x_flow, _max_x_flow, _min_y_head_loss, _max_y_head_loss); if (_coordinate.QL!=null) { if (_coordinate.QL.CoordMinX + _coordinate.QL.CoordSpaceX * this._coordinate.QL.GridNumberX < _max_x_flow * 1.05) { _coordinate.QL.GridNumberX++; } } _coordinate.OL = ValveOLCoordinate.CalcCoordinate(_min_x_opening, _max_x_opening, _min_y_k, _max_y_k); } /// /// 设置图表轴 /// public void SetChartAxis() { if (_coordinate == null || IsInvalidData()) { _axis_x_flow.Visibility = DefaultBoolean.False; _axis_x_flow.GridLines.Visible = false; _axis_y_head_loss.Visibility = DefaultBoolean.False; _axis_y_head_loss.GridLines.Visible = false; _axis_x_opening.Visibility = DefaultBoolean.False; _axis_x_opening.GridLines.Visible = false; _axis_y_k.Visibility = DefaultBoolean.False; _axis_y_k.GridLines.Visible = false; return; } if (_exist_ql) { //计算刻度 x_flow var axis_x_flow_labels = new List(); var display_x_flow = _coordinate.QL.CoordMinX; for (int i = 0; i < _coordinate.QL.GridNumberX + 1; i++) { var x = _coordinate.QL.CoordSpaceX < 1 ? $"{display_x_flow:N1}" : $"{display_x_flow:N0}"; axis_x_flow_labels.Add(new CustomAxisLabel(x, display_x_flow)); display_x_flow = display_x_flow + _coordinate.QL.CoordSpaceX; } _axis_x_flow.CustomLabels.Clear(); _axis_x_flow.CustomLabels.AddRange(axis_x_flow_labels.ToArray()); _axis_x_flow.Visibility = DefaultBoolean.True; _axis_x_flow.GridLines.Visible = true; //计算刻度 y_head_loss var axis_y_head_loss_labels = new List(); var display_y_head_loss = _coordinate.QL.CoordMinY + _coordinate.QL.CoordSpaceY * _coordinate.QL.StartLineNoY; for (int i = _coordinate.QL.StartLineNoY; i < _coordinate.QL.EndLineNoY + 1; i++) { var y = _coordinate.QL.CoordSpaceY < 1 ? $"{display_y_head_loss:N1}" : $"{display_y_head_loss:N0}"; axis_y_head_loss_labels.Add(new CustomAxisLabel(y, display_y_head_loss)); display_y_head_loss = display_y_head_loss + _coordinate.QL.CoordSpaceY; } _axis_y_head_loss.CustomLabels.Clear(); _axis_y_head_loss.CustomLabels.AddRange(axis_y_head_loss_labels.ToArray()); _axis_y_head_loss.Visibility = DefaultBoolean.True; _axis_y_head_loss.GridLines.Visible = true; _axis_x_flow.SetAxisRange(_coordinate.QL.CoordMinX, _coordinate.QL.DispMaxX()); _axis_y_head_loss.SetAxisRange(_coordinate.QL.DispMinY(), _coordinate.QL.DispMaxY()); _default_pane.Visibility = ChartElementVisibility.Visible; } else { _axis_x_flow.Visibility = DefaultBoolean.False; _axis_x_flow.GridLines.Visible = false; _axis_y_head_loss.Visibility = DefaultBoolean.False; _axis_y_head_loss.GridLines.Visible = false; _default_pane.Visibility = ChartElementVisibility.Hidden; } if (_exist_ol) { //计算刻度 x_opening var axis_x_opening_labels = new List(); var display_x_opening = _coordinate.OL.CoordMinX; for (int i = 0; i < _coordinate.OL.GridNumberX + 1; i++) { var x = _coordinate.OL.CoordSpaceX < 1 ? $"{display_x_opening:N1}" : $"{display_x_opening:N0}"; axis_x_opening_labels.Add(new CustomAxisLabel(x, display_x_opening)); display_x_opening = display_x_opening + _coordinate.OL.CoordSpaceX; } _axis_x_opening.CustomLabels.Clear(); _axis_x_opening.CustomLabels.AddRange(axis_x_opening_labels.ToArray()); _axis_x_opening.Visibility = DefaultBoolean.True; _axis_x_opening.GridLines.Visible = true; //计算刻度 y_k var axis_y_k_labels = new List(); var display_y_k = _coordinate.OL.CoordMinY + _coordinate.OL.CoordSpaceY * _coordinate.OL.StartLineNoY; for (int i = _coordinate.OL.StartLineNoY; i < _coordinate.OL.EndLineNoY + 1; i++) { var y = _coordinate.OL.CoordSpaceY < 1 ? $"{display_y_k:N1}" : $"{display_y_k:N0}"; axis_y_k_labels.Add(new CustomAxisLabel(y, display_y_k)); display_y_k = display_y_k + _coordinate.OL.CoordSpaceY; } _axis_y_k.CustomLabels.Clear(); _axis_y_k.CustomLabels.AddRange(axis_y_k_labels.ToArray()); _axis_y_k.Visibility = DefaultBoolean.True; _axis_y_k.GridLines.Visible = true; _axis_x_opening.SetAxisRange(_coordinate.OL.CoordMinX, _coordinate.OL.DispMaxX()); _axis_y_k.SetAxisRange(_coordinate.OL.DispMinY(), _coordinate.OL.DispMaxY()); _bottom_pane.Visibility = ChartElementVisibility.Visible; } else { _axis_x_opening.Visibility = DefaultBoolean.False; _axis_x_opening.GridLines.Visible = false; _axis_y_k.Visibility = DefaultBoolean.False; _axis_y_k.GridLines.Visible = false; _bottom_pane.Visibility = ChartElementVisibility.Hidden; } } /// /// 计算注释定位 /// private void SetTextAnchorPoint() { //var x = this.chartControl1.Location.X + this.chartControl1.Width; //var y = this.chartControl1.Location.Y+100; var axis_x = (double)_axis_x_flow.VisualRange.MaxValue; var axis_y = (double)_axis_y_head_loss.VisualRange.MinValue; var coord = _diagram.DiagramToPoint(axis_x, axis_y); (_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).X = coord.Point.X; (_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).Y = coord.Point.Y / 4; } #endregion Calc #region Set Axis Value /// /// 设置X轴值 /// public void SetAxisXFlowValue(double? x = null) { if (!_line_visible || !_exist_ql) { _const_line_x_flow.Visible = false; _const_line_x_flow.Title.Visible = false; _anno_txt_query_info.Visible = false; return; } else { _const_line_x_flow.Visible = true; _const_line_x_flow.Title.Visible = true; _anno_txt_query_info.Visible = true; } if (this.IsInvalidData()) return; var vm_list = _vm_list.Where(x => x.CurveType == Ahart.eCurveType.QL).ToList(); var pt_list = vm_list.SelectMany(x => x.FitPointList).ToList(); var min_x = pt_list.Min(x => x.X); var max_x = pt_list.Max(x => x.X); if (x == null) { x = (min_x + max_x) / 2; } else { if (x < min_x || x > max_x) return; } var query_info_builder = new StringBuilder(); var x_value = x.Value; query_info_builder.AppendLine($"{x_value:N2} m³/h "); var str_list = new List<(string, string)>(); foreach (var vm in vm_list) { var y_value = vm.FitPointList.GetInterPointsY(x_value)?.FirstOrDefault(); if (y_value.HasValue) { var name = string.IsNullOrEmpty(vm.Name) ? "默认" : vm.Name; str_list.Add((name, y_value.Value.ToString("N2"))); } } for (int i = 0; i < str_list.Count; i++) { var str = str_list[i]; var txt = $"{str.Item2} m [{str.Item1}]"; if (i == str_list.Count - 1) { query_info_builder.Append(txt); } else { query_info_builder.AppendLine(txt); } } _const_line_x_flow.AxisValue = x_value; _const_line_x_flow.Title.Text = $"{x_value:N2}"; _anno_txt_query_info.Text = query_info_builder.ToString(); _anno_txt_query_info.AutoSize = true; _anno_txt_query_info.Visible = true; } /// /// 设置Y轴值 /// public void SetAxisXOpeningValue(double? x = null) { if (!_line_visible || !_exist_ol) { _const_line_x_opening.Visible = false; _const_line_x_opening.Title.Visible = false; _const_line_y_k.Visible = false; _const_line_y_k.Title.Visible = false; return; } else { _const_line_x_opening.Visible = true; _const_line_x_opening.Title.Visible = true; _const_line_y_k.Visible = true; _const_line_y_k.Title.Visible = true; } if (this.IsInvalidData()) return; var vm_list = _vm_list.Where(x => x.CurveType == Ahart.eCurveType.OL).ToList(); var pt_list = vm_list.SelectMany(x => x.FitPointList).ToList(); var min_x = pt_list.Min(x => x.X); var max_x = pt_list.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 = pt_list.GetInterPointsY(x_value)?.FirstOrDefault(); _const_line_x_opening.AxisValue = x_value; _const_line_x_opening.Title.Text = $"{x_value:N2}"; _const_line_y_k.AxisValue = y_value; _const_line_y_k.Title.Text = $"{y_value:N2}"; } /// /// 设置Y轴值 /// public void SetAxisYKValue(double y) { if (!_line_visible || !_exist_ol) return; if (IsInvalidData()) return; var vm_list = _vm_list.Where(x => x.CurveType == Ahart.eCurveType.OL).ToList(); var pt_list = vm_list.SelectMany(x => x.FitPointList).ToList(); var min_y = pt_list.Min(x => x.Y); var max_y = pt_list.Max(x => x.Y); if (y < min_y || y > max_y) return; var x_value = pt_list.GetInterPointsX(y)?.LastOrDefault(); SetAxisXOpeningValue(x_value); } #endregion } }