using DevExpress.Utils; using DevExpress.XtraCharts; using DevExpress.XtraEditors; using System.Text; using Yw.Geometry; namespace Yw.WinFrmUI.Phart { /// /// /// public partial class PumpPerformChart : DevExpress.XtraEditors.XtraUserControl { public PumpPerformChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; } #region Private Variable private XYDiagram _main_chart_diagram; private XYDiagramPane _bottom_panel; private AxisX _axisXQ; private AxisY _axisYQH; private SecondaryAxisY _axis_y_qe, _axis_y_qp; private ConstantLine _work_pt_line; private ConstantLine _work_h_line; private Series _series_cubic_spline_qh, _series_cubic_spline_qe, _series_cubic_spline_qp, _series_cubic_spline_eq; private Series _series_pt_qh, _series_pt_qe, _series_pt_qp; private List _series_eq_pt_list; private TextAnnotation _work_pt_txt_annot; private Yw.Geometry.CubicSpline2d _cubic_spline_qh; private Yw.Geometry.CubicSpline2d _cubic_spline_qe; private Yw.Geometry.CubicSpline2d _cubic_spline_qp; private List _pt_qh_list; private List _pt_qe_list; private List _pt_qp_list; private List _def_pt_qh_list; private List _def_pt_qe_list; private List _def_pt_qp_list; private PumpGroupPt _design_pt = new(0, 0, 0, 0, 0); private PumpGroupPt _work_point = new(0, 0, 0, 0, 0); private bool _eq_visible = true; private PumpCoordinate _coordinate_paras; private bool _initial_data = false; #endregion #region Public Variable /// /// 定义点是否可见 /// public bool DefinePointVisible { get => _definePointVisible; set { _definePointVisible = value; this.barCekDefinePointVisible.Checked = _definePointVisible; } } private bool _definePointVisible = false; /// /// 工作线是否可见 /// public bool LineVisible { get => _lineVisible; set { _lineVisible = value; this.barCekLineVisible.Checked = _lineVisible; } } private bool _lineVisible = false; #endregion #region Public Evnet public event Action OnCurveCoordinateChanged; public event Action OnCalcQueryPoint = null; #endregion #region Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; _main_chart_diagram = (XYDiagram)chartControl1.Diagram; _bottom_panel = (XYDiagramPane)_main_chart_diagram.FindPaneByName("BottomPanel"); _axisXQ = _main_chart_diagram.AxisX; _axisXQ.SetAxisXQDisplay(); _axisYQH = _main_chart_diagram.AxisY; _axisYQH.SetAxisYQHDisplay(); _axis_y_qe = _main_chart_diagram.SecondaryAxesY.GetAxisByName("AxisYQE"); _axis_y_qe.SetSecondaryAxisYQEDisplay(); _axis_y_qp = _main_chart_diagram.SecondaryAxesY.GetAxisByName("AxisYQP"); _axis_y_qp.SetSecondaryAxisYQPDisplay(); _work_pt_line = (ConstantLine)_main_chart_diagram.AxisX.ConstantLines.GetElementByName("WorkPointLine"); _work_pt_line.SetWorkPointLineDisplay(); _work_h_line = (ConstantLine)_main_chart_diagram.AxisY.ConstantLines.GetElementByName("WorkHLine"); _work_h_line.SetWorkHLineDisplay(); _series_cubic_spline_qh = this.chartControl1.GetSeriesByName("SeriesCurveQH"); _series_cubic_spline_qh.SetCurveQHDisplay(); _series_cubic_spline_qe = this.chartControl1.GetSeriesByName("SeriesCurveQE"); _series_cubic_spline_qe.SetCurveQEDisplay(); _series_cubic_spline_qp = this.chartControl1.GetSeriesByName("SeriesCurveQP"); _series_cubic_spline_qp.SetCurveQPDisplay(); _series_cubic_spline_eq = this.chartControl1.GetSeriesByName("SeriesEquipCurve"); _series_pt_qh = this.chartControl1.GetSeriesByName("SeriesPointQH"); _series_pt_qh.SetPointQHDisplay(); _series_pt_qe = this.chartControl1.GetSeriesByName("SeriesPointQE"); _series_pt_qe.SetPointQEDisplay(); _series_pt_qp = this.chartControl1.GetSeriesByName("SeriesPointQP"); _series_pt_qp.SetPointQPDisplay(); _work_pt_txt_annot = this.chartControl1.AnnotationRepository[0] as TextAnnotation; _work_pt_txt_annot.SetTextAnnoWorkPointDisplay(); _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQH.Visibility = DefaultBoolean.False; _axisYQH.GridLines.Visible = false; _axis_y_qe.Visibility = DefaultBoolean.False; _axis_y_qe.GridLines.Visible = false; _axis_y_qp.Visibility = DefaultBoolean.False; _axis_y_qp.GridLines.Visible = false; _work_pt_line.Visible = false; _work_h_line.Visible = false; _work_pt_txt_annot.Visible = false; _series_pt_qh.Visible = false; _series_pt_qe.Visible = false; _series_pt_qp.Visible = false; 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); } /// /// 初始化图表数据 /// public void InitialChartData() { _initial_data = false; _cubic_spline_qh = null; _cubic_spline_qe = null; _cubic_spline_qp = null; _pt_qh_list = null; _pt_qe_list = null; _pt_qp_list = null; _def_pt_qh_list = null; _def_pt_qe_list = null; _def_pt_qp_list = null; _coordinate_paras = null; _work_point = new PumpGroupPt(0, 0, 0, 0, 0); _design_pt = new PumpGroupPt(0, 0, 0, 0, 0); UpdateChart(false); } #endregion /// /// 绑定数据 /// /// /// /// /// public void SetBindingData( Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qe, Yw.Geometry.CubicSpline2d cubic_spline_qp, string coordinate_paras = "", bool calc_coordinate = false) { if (cubic_spline_qh == null) { InitialChartData(); return; } List pt_qh_list, pt_qe_list = null, pt_qp_list = null; pt_qh_list = cubic_spline_qh.GetPointList(12); if (cubic_spline_qe != null) pt_qe_list = cubic_spline_qe.GetPointList(12); if (cubic_spline_qp != null) pt_qp_list = cubic_spline_qp.GetPointList(12); SetBindingData(cubic_spline_qh, cubic_spline_qe, cubic_spline_qp, pt_qh_list, pt_qe_list, pt_qp_list, null, null, null, coordinate_paras, calc_coordinate); } /// /// 绑定数据 /// /// /// /// /// /// public void SetBindingData( Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qe, Yw.Geometry.CubicSpline2d cubic_spline_qp, List pt_qh_list, List pt_qe_list, List pt_qp_list, List def_pt_qh_list, List def_pt_qe_list, List def_pt_qp_list, string coordinate_paras = null, bool calc_coordinate = false) { if (pt_qh_list == null || !pt_qh_list.Any()) { InitialChartData(); return; } _initial_data = true; _cubic_spline_qh = cubic_spline_qh; _cubic_spline_qe = cubic_spline_qe; _cubic_spline_qp = cubic_spline_qp; _pt_qh_list = pt_qh_list; _pt_qe_list = pt_qe_list; _pt_qp_list = pt_qp_list; _def_pt_qh_list = def_pt_qh_list; _def_pt_qe_list = def_pt_qe_list; _def_pt_qp_list = def_pt_qp_list; _coordinate_paras = PumpCoordinate.ToModel(coordinate_paras); UpdateChart(calc_coordinate); } /// /// 更新图表 /// /// 计算坐标 public void UpdateChart(bool calc_coordinate = false) { if (_pt_qh_list == null || !_pt_qh_list.Any()) { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (_pt_qp_list == null || !_pt_qp_list.Any()) { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (calc_coordinate || _coordinate_paras == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcChartAxis(this.barCekSetSplitPanel.Checked); CalcSeries(); CalcWorkPointByQ(); CalcDesignPointByQ(); CalcTextAnchorPoint(); } #region Calc /// /// 计算坐标 /// public void CalcCoordinate() { if (_pt_qh_list == null || _pt_qh_list.Count < 4) { //设置成白板坐标 _coordinate_paras = new PumpCoordinate(); _coordinate_paras.GridNumberX = 30; _coordinate_paras.GridNumberY = 16; //显示的坐标线号 _coordinate_paras.StartLineNoH = 10; _coordinate_paras.EndLineNoH = 15; _coordinate_paras.StartLineNoE = 0; _coordinate_paras.EndLineNoE = 10; _coordinate_paras.StartLineNoP = 2; _coordinate_paras.EndLineNoP = 9; //坐标最小值和间隔 _coordinate_paras.CoordMinQ = 0; _coordinate_paras.CoordSpaceQ = 1000; _coordinate_paras.CoordMinH = 10; _coordinate_paras.CoordSpaceH = 100; _coordinate_paras.CoordMinE = 0; _coordinate_paras.CoordSpaceE = 100; _coordinate_paras.CoordMinP = 10; _coordinate_paras.CoordSpaceP = 100; return; } _coordinate_paras = PumpCoordinate.CalcCoordinate(_pt_qh_list, _pt_qe_list, _pt_qp_list); } /// /// 计算图表轴 /// public void CalcChartAxis(bool splitPanel) { if (_coordinate_paras == null) { _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQH.Visibility = DefaultBoolean.False; _axisYQH.GridLines.Visible = false; _axis_y_qe.Visibility = DefaultBoolean.False; _axis_y_qe.GridLines.Visible = false; _axis_y_qp.Visibility = DefaultBoolean.False; _axis_y_qp.GridLines.Visible = false; _work_pt_line.Visible = false; _work_h_line.Visible = false; _work_pt_txt_annot.Visible = false; _bottom_panel.Visibility = ChartElementVisibility.Hidden; return; } _bottom_panel.Visibility = splitPanel ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; PointSeriesView series_eq_p_pt_view = null; if (_series_eq_pt_list != null && _series_eq_pt_list.Any()) { var series = _series_eq_pt_list.Find(x => (Yw.Pump.eCurveType)x.Tag == Yw.Pump.eCurveType.QP); if (series != null) { series_eq_p_pt_view = (PointSeriesView)series.View; } } //流量 if (_pt_qh_list != null) { //计算刻度 var labels = new List(); var disQ = _coordinate_paras.CoordMinQ; for (int i = 0; i < _coordinate_paras.GridNumberX + 1; i++) { labels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinate_paras.CoordSpaceQ; } //坐标刻度 _axisXQ.CustomLabels.Clear(); _axisXQ.CustomLabels.AddRange(labels.ToArray()); _axisXQ.Visibility = DefaultBoolean.True; _axisXQ.GridLines.Visible = true; _axisXQ.SetAxisRange(_coordinate_paras.CoordMinQ, _coordinate_paras.CoordMinQ + _coordinate_paras.GridNumberX * _coordinate_paras.CoordSpaceQ); _work_pt_txt_annot.Visible = _lineVisible; } //扬程 if (_pt_qh_list != null) { //计算刻度 var labels = new List(); var disH = _coordinate_paras.CoordMinH + _coordinate_paras.CoordSpaceH * _coordinate_paras.StartLineNoH; for (int i = _coordinate_paras.StartLineNoH; i < _coordinate_paras.EndLineNoH + 1; i++) { labels.Add(new CustomAxisLabel(disH.ToString(), disH)); disH = disH + _coordinate_paras.CoordSpaceH; } _axisYQH.CustomLabels.Clear(); _axisYQH.CustomLabels.AddRange(labels.ToArray()); _axisYQH.Visibility = DefaultBoolean.True; _axisYQH.GridLines.Visible = true; } //效率 if (_pt_qe_list != null) { //计算刻度 var labels = new List(); var disE = _coordinate_paras.CoordMinE + _coordinate_paras.CoordSpaceE * _coordinate_paras.StartLineNoE; for (int i = _coordinate_paras.StartLineNoE; i < _coordinate_paras.EndLineNoE + 1; i++) { labels.Add(new CustomAxisLabel(disE.ToString(), disE)); disE = disE + _coordinate_paras.CoordSpaceE; } _axis_y_qe.CustomLabels.Clear(); _axis_y_qe.CustomLabels.AddRange(labels.ToArray()); _axis_y_qe.Visibility = DefaultBoolean.True; _axis_y_qe.GridLines.Visible = true; } //功率 if (_pt_qp_list != null) { //计算刻度 var labels = new List(); double disP = _coordinate_paras.CoordMinP + _coordinate_paras.CoordSpaceP * _coordinate_paras.StartLineNoP; for (int i = _coordinate_paras.StartLineNoP; i < _coordinate_paras.EndLineNoP + 1; i++) { labels.Add(new CustomAxisLabel(disP.ToString(), disP)); disP = disP + _coordinate_paras.CoordSpaceP; } _axis_y_qp.CustomLabels.Clear(); _axis_y_qp.CustomLabels.AddRange(labels.ToArray()); _axis_y_qp.Visibility = DefaultBoolean.True; _axis_y_qp.GridLines.Visible = true; } //是否分割面板:流量效率在上,功率在下 if (splitPanel) { var gridNumH = _coordinate_paras.EndLineNoH - _coordinate_paras.StartLineNoH; var gridNumE = _coordinate_paras.EndLineNoE - _coordinate_paras.StartLineNoE; int gridNumUp = Math.Max(gridNumH, gridNumE) + 2;//多两条 var maxAxisH = _coordinate_paras.CoordMinH + _coordinate_paras.EndLineNoH * _coordinate_paras.CoordSpaceH; var minAxisH = maxAxisH - gridNumUp * _coordinate_paras.CoordSpaceH; _axisYQH.SetAxisRange(minAxisH, maxAxisH); var minAxisE = _coordinate_paras.CoordMinE + _coordinate_paras.StartLineNoE * _coordinate_paras.CoordSpaceE; var maxAxisE = minAxisE + gridNumUp * _coordinate_paras.CoordSpaceE; _axis_y_qe.SetAxisRange(minAxisE, maxAxisE); var gridNumP = _coordinate_paras.EndLineNoP - _coordinate_paras.StartLineNoP; var minAxisP = _coordinate_paras.CoordMinP + _coordinate_paras.StartLineNoP * _coordinate_paras.CoordSpaceP; var maxAxisP = minAxisP + gridNumP * _coordinate_paras.CoordSpaceP; _axis_y_qp.SetAxisRange(minAxisP, maxAxisP); ((PointSeriesView)_series_pt_qp.View).Pane = _bottom_panel; ((SplineSeriesView)_series_cubic_spline_qp.View).Pane = _bottom_panel; if (series_eq_p_pt_view != null) { series_eq_p_pt_view.Pane = _bottom_panel; } } else { _axisXQ.SetAxisRange(_coordinate_paras.CoordMinQ, _coordinate_paras.CoordMinQ + _coordinate_paras.GridNumberX * _coordinate_paras.CoordSpaceQ); if ((_pt_qe_list == null || !_pt_qe_list.Any()) && (_pt_qp_list == null || !_pt_qp_list.Any())) { _axisYQH.SetAxisRange(_coordinate_paras.DispMinH(), _coordinate_paras.DispMaxH()); } else { _axisYQH.SetAxisRange(_coordinate_paras.CoordMinH, _coordinate_paras.CoordMinH + _coordinate_paras.GridNumberY * _coordinate_paras.CoordSpaceH); } _axis_y_qe.SetAxisRange(_coordinate_paras.CoordMinE, _coordinate_paras.CoordMinE + _coordinate_paras.GridNumberY * _coordinate_paras.CoordSpaceE); _axis_y_qp.SetAxisRange(_coordinate_paras.CoordMinP, _coordinate_paras.CoordMinP + _coordinate_paras.GridNumberY * _coordinate_paras.CoordSpaceP); ((PointSeriesView)_series_pt_qp.View).Pane = _main_chart_diagram.DefaultPane; ((SplineSeriesView)_series_cubic_spline_qp.View).Pane = _main_chart_diagram.DefaultPane; if (series_eq_p_pt_view != null) { series_eq_p_pt_view.Pane = _main_chart_diagram.DefaultPane; } } } /// /// 计算系列 /// public void CalcSeries() { if (_pt_qh_list != null && _pt_qh_list.Count > 3) { _series_cubic_spline_qh.Visible = true; _series_cubic_spline_qh.Points.Clear(); foreach (var pt in _pt_qh_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_cubic_spline_qh.Points.Add(series_pt); } } else { _series_cubic_spline_qh.Points.Clear(); _series_cubic_spline_qh.Visible = false; _work_pt_line.Visible = false; _work_h_line.Visible = false; _work_pt_txt_annot.Visible = false; _series_cubic_spline_eq.Points.Clear(); _series_cubic_spline_eq.Visible = false; } if (_pt_qe_list != null && _pt_qe_list.Count > 3) { _series_cubic_spline_qe.Visible = true; _series_cubic_spline_qe.Points.Clear(); foreach (var pt in _pt_qe_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_cubic_spline_qe.Points.Add(series_pt); } } else { _series_cubic_spline_qe.Points.Clear(); _series_cubic_spline_qe.Visible = false; } if (_pt_qp_list != null && _pt_qp_list.Count > 3) { _series_cubic_spline_qp.Visible = true; _series_cubic_spline_qp.Points.Clear(); foreach (var pt in _pt_qp_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_cubic_spline_qp.Points.Add(series_pt); } } else { _series_cubic_spline_qp.Points.Clear(); _series_cubic_spline_qp.Visible = false; } if (_def_pt_qh_list != null && _def_pt_qh_list.Any()) { _series_pt_qh.Points.Clear(); foreach (var define_pt in _def_pt_qh_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_pt_qh.Points.Add(series_pt); } } if (_def_pt_qe_list != null && _def_pt_qe_list.Any()) { _series_pt_qe.Points.Clear(); foreach (var define_pt in _def_pt_qe_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_pt_qe.Points.Add(series_pt); } } if (_def_pt_qp_list != null && _def_pt_qp_list.Any()) { _series_pt_qp.Points.Clear(); foreach (var define_pt in _def_pt_qp_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_pt_qp.Points.Add(series_pt); } } } /// /// 计算注释定位 /// private void CalcTextAnchorPoint() { var x = this.chartControl1.Location.X + this.chartControl1.Width - (100); var y = this.chartControl1.Height - (200); (_work_pt_txt_annot.AnchorPoint as ChartAnchorPoint).X = x; (_work_pt_txt_annot.AnchorPoint as ChartAnchorPoint).Y = y; } /// /// 计算工作点 /// /// public void CalcWorkPointByQ(double? workQ = null) { if (!_lineVisible) { _work_pt_line.Visible = false; _work_pt_line.Title.Visible = false; _work_h_line.Visible = false; _work_h_line.Title.Visible = false; _work_pt_txt_annot.Visible = false; return; } else { _work_pt_line.Visible = true; _work_pt_line.Title.Visible = true; _work_h_line.Visible = true; _work_h_line.Title.Visible = true; _work_pt_txt_annot.Visible = true; } if (_pt_qh_list == null || !_pt_qh_list.Any()) return; var minQ = _pt_qh_list.Min(x => x.X); var maxQ = _pt_qh_list.Max(x => x.X); if (workQ == null) { workQ = (minQ + maxQ) / 2; } else { if (workQ < minQ || workQ > maxQ) return; } _work_point.Q = workQ.Value; _work_point.H = _cubic_spline_qh.GetPointY(_work_point.Q); var workInfoStringBuilder = new StringBuilder(); workInfoStringBuilder.AppendLine($"流量:{_work_point.Q.ToString("N1")} "); workInfoStringBuilder.AppendLine($"扬程:{_work_point.H.ToString("N1")} "); if (_cubic_spline_qe != null) { _work_point.E = _cubic_spline_qe.GetPointY(_work_point.Q); workInfoStringBuilder.AppendLine($"效率:{_work_point.E.ToString("N1")} "); } if (_cubic_spline_qp != null) { _work_point.P = _cubic_spline_qp.GetPointY(_work_point.Q); workInfoStringBuilder.Append($"功率:{_work_point.P.ToString("N1")} "); } _work_pt_line.AxisValue = _work_point.Q; _work_pt_line.Title.Text = _work_point.Q.ToString("N1"); _work_h_line.AxisValue = _work_point.H; _work_h_line.Title.Text = _work_point.H.ToString("N1"); //测试展示效果 _work_pt_txt_annot.Text = workInfoStringBuilder.ToString(); _work_pt_txt_annot.AutoSize = true; if (OnCalcQueryPoint != null) { OnCalcQueryPoint(_work_point); } } /// /// 根据扬程计算工作点 /// /// public void CalcWorkPointByH(double workH) { if (!_lineVisible) return; if (_cubic_spline_qh == null) return; var minH = _pt_qh_list.Min(x => x.Y); var maxH = _pt_qh_list.Max(x => x.Y); if (workH < minH || workH > maxH) return; var workQ = _cubic_spline_qh.GetPointY(workH); CalcWorkPointByQ(workQ); } /// /// 根据最大效率计算工作点 /// public void CalcWorkPointByMaxE() { if (!_lineVisible) return; if (_cubic_spline_qe == null) return; var workQ = _cubic_spline_qe.MaxX; CalcWorkPointByQ(workQ); } /// /// 根据最大流量计算工作点 /// public void CalcWorkPointByMaxQ() { if (!_lineVisible) return; if (_cubic_spline_qh == null) return; var workQ = _cubic_spline_qh.MaxX; CalcWorkPointByQ(workQ); } /// /// 设计点 /// /// public void CalcDesignPointByQ(double? design_pt_q = null, double? design_pt_h = null) { _series_cubic_spline_eq.Visible = true; _series_cubic_spline_eq.Points.Clear(); if (_series_eq_pt_list != null && _series_eq_pt_list.Any()) { this.chartControl1.BeginInit(); foreach (var series in _series_eq_pt_list) { var exist_series = this.chartControl1.GetSeriesByName(series.Name); if (exist_series != null) { this.chartControl1.Series.Remove(exist_series); } } this.chartControl1.EndInit(); } _series_eq_pt_list = new List(); if (_pt_qh_list == null || !_pt_qh_list.Any()) return; if (design_pt_q == null) return; var minQ = _pt_qh_list.Min(x => x.X); var maxQ = _pt_qh_list.Max(x => x.X); if (design_pt_q < minQ || design_pt_q > maxQ) return; _design_pt.Q = design_pt_q.Value; if (design_pt_h.HasValue) { _design_pt.H = design_pt_h.Value; } else { _design_pt.H = _cubic_spline_qh.GetPointY(_design_pt.Q); } _series_cubic_spline_eq.Visible = _eq_visible; var design_pt = new Yw.Geometry.Point2d(_design_pt.Q, _design_pt.H); var eq_paras = EquipCurveHelper.CalcEquipCurve(_cubic_spline_qh, design_pt, out Yw.Geometry.Point2d sect_pt); if (eq_paras != null && eq_paras.EquipCurve != null) { var eq_pt_list = eq_paras.EquipCurve.GetPointList(); foreach (var pt in eq_pt_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_cubic_spline_eq.Points.Add(series_pt); } } var design_pt_qh = CreatePointSeries(Pump.eCurveType.QH, sect_pt.X, sect_pt.Y); _series_eq_pt_list.Add(design_pt_qh); this.chartControl1.Series.Add(design_pt_qh); if (_cubic_spline_qe != null) { _design_pt.E = _cubic_spline_qe.GetPointY(_design_pt.Q); var design_pt_qe = CreatePointSeries(Pump.eCurveType.QE, _design_pt.Q, _design_pt.E); _series_eq_pt_list.Add(design_pt_qe); this.chartControl1.Series.Add(design_pt_qe); } if (_cubic_spline_qp != null) { _design_pt.P = _cubic_spline_qp.GetPointY(_design_pt.Q); var design_pt_qp = CreatePointSeries(Pump.eCurveType.QP, _design_pt.Q, _design_pt.P); _series_eq_pt_list.Add(design_pt_qp); this.chartControl1.Series.Add(design_pt_qp); } } /// /// 创建点系列 /// private Series CreatePointSeries(Yw.Pump.eCurveType curve_type, double x, double y) { string name = string.Empty; Color color = Color.White; AxisYBase axis_y = _axisYQH; switch (curve_type) { case Pump.eCurveType.QH: { name = "流量扬程作用点"; color = Perform2dChartDisplay.PointColorQH; axis_y = _axisYQH; } break; case Pump.eCurveType.QE: { name = "流量效率作用点"; color = Perform2dChartDisplay.PointColorQE; axis_y = _axis_y_qe; } break; case Pump.eCurveType.QP: { name = "流量功率设计点"; color = Perform2dChartDisplay.PointColorQP; axis_y = _axis_y_qp; } break; default: break; } var series_point_view = new DevExpress.XtraCharts.PointSeriesView(); series_point_view.Color = color; series_point_view.PointMarkerOptions.BorderColor = color; series_point_view.PointMarkerOptions.Size = 12; series_point_view.PointMarkerOptions.Kind = MarkerKind.Cross; series_point_view.AxisY = axis_y; var series_point = new DevExpress.XtraCharts.Series(); series_point.Tag = curve_type; series_point.View = series_point_view; series_point.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_point.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_point.Name = name; series_point.ShowInLegend = false; series_point.CrosshairEnabled = DefaultBoolean.False; series_point.ShowInLegend = true; series_point.SeriesPointsSorting = SortingMode.None; series_point.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_point.Visible = _eq_visible; series_point.LabelsVisibility = DefaultBoolean.True; series_point.Label.TextPattern = "{V:N1}"; //series_point.CrosshairLabelPattern = "{V:N1}"; series_point.CrosshairLabelVisibility = DefaultBoolean.False; series_point.Points.Add(new SeriesPoint(x, new double[] { y })); return series_point; } #endregion #region ChartEvent ToolTipController toolTip = new ToolTipController(); 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]); toolTip.ShowHint(tip); } else { toolTip.HideHint(); } } // 右键对象 private object _rightClickObj = null; private bool _onMoveWorkPointLine = false; private bool _onMoveWorkHLine = 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.InSeries) { _rightClickObj = hitInfo.Series; } else if (hitInfo.InAxis) { _rightClickObj = hitInfo.Axis; } else if (hitInfo.InConstantLine) { if (hitInfo.ConstantLine == _work_pt_line) { _onMoveWorkPointLine = true; } else if (hitInfo.ConstantLine == _work_h_line) { _onMoveWorkHLine = 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 (!_initial_data) return; if (_onMoveWorkPointLine) { var diagramCoordinates = _main_chart_diagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axisXQ); if (axisValue == null) return; double chartQ = axisValue.NumericalValue; CalcWorkPointByQ(chartQ); } else if (_onMoveWorkHLine) { var diagramCoordinates = _main_chart_diagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axisYQH); if (axisValue == null) return; double chartH = axisValue.NumericalValue; CalcWorkPointByH(chartH); } } private void chartControl1_MouseUp(object sender, MouseEventArgs e) { if (!_initial_data) return; _onMoveWorkPointLine = false; _onMoveWorkHLine = 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 (_pt_qh_list == null || !_pt_qh_list.Any()) return; var dlg = new PumpAxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { var min = _pt_qh_list.Min(x => x.X); var max = _pt_qh_list.Max(x => x.X); if (value < min || value > max) return false; CalcWorkPointByQ(value); return true; }; dlg.ShowDialog(); } private void barBtnSetAxisHValue_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (_pt_qh_list == null || !_pt_qh_list.Any()) return; var dlg = new PumpAxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { var min = _pt_qh_list.Min(x => x.Y); var max = _pt_qh_list.Max(x => x.Y); if (value < min || value > max) return false; CalcWorkPointByH(value); return true; }; dlg.ShowDialog(); } private void barCekEqVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _eq_visible = this.barCekEqVisible.Checked; if (_series_cubic_spline_eq != null) { _series_cubic_spline_eq.Visible = _eq_visible; } if (_series_eq_pt_list != null && _series_eq_pt_list.Any()) { foreach (var item in _series_eq_pt_list) { item.Visible = _eq_visible; } } } private void barBtnPositioningMaxQ_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { CalcWorkPointByMaxQ(); } private void barBtnPositioningMaxE_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { CalcWorkPointByMaxE(); } private void barCekDefinePointVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetDefinePointVisible(this.barCekDefinePointVisible.Checked); } private void barCekLineVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetLineVisible(this.barCekLineVisible.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 barCekSetSplitPanel_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { CalcChartAxis(this.barCekSetSplitPanel.Checked); } private void barCekChartDisplay_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetChartDisplay(this.barCekChartDisplay.Checked); } private void barBtnSetChartAxis_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetChartAxis(); } private void barBtnSetChartEquation_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { XtraMessageBox.Show("待补充"); //SetChartEquation(); } private void barBtnExportXls_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { ExportXls(); } private void barBtnExportImage_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { ExportImage(); } #endregion /// /// 设置定义点显示 /// public void SetDefinePointVisible(bool visible) { _series_pt_qh.Visible = visible; _series_pt_qe.Visible = visible; _series_pt_qp.Visible = visible; } /// /// 设置工作点显示 /// public void SetLineVisible(bool visible) { if (!_initial_data) return; _lineVisible = visible; CalcWorkPointByQ(); } /// /// 设置图例显示 /// public void SetLegendVisible(bool visible) { this.chartControl1.Legend.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; } /// /// 设置轴名称显示 /// public void SetAxisNameVisible(bool visible) { _axisXQ.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axisYQH.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axis_y_qe.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axis_y_qp.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; } /// /// 设置图表显示 /// public void SetChartDisplay(bool monoColor) { if (monoColor) { this.chartControl1.SetChartMonoColorDisplay(); } else { this.chartControl1.SetChartBackColor(); _axisXQ.SetAxisYQColorDisplay(); _axisYQH.SetAxisYQHColorDisplay(_series_cubic_spline_qh, _series_pt_qh, true); _axis_y_qe.SetSecondaryAxisYQEColorDisplay(_series_cubic_spline_qe, _series_pt_qe, true); _axis_y_qp.SetSecondaryAxisYQPColorDisplay(_series_cubic_spline_qp, _series_pt_qp, true); } } /// /// 设置坐标轴 /// public void SetChartAxis() { var dlg = new PumpChartCoordinateDlg(); var onlyQH = _cubic_spline_qe == null && _cubic_spline_qp == null; dlg.SetBindingData(_coordinate_paras, onlyQH); dlg.OnChangedCoord += (rhs) => { _coordinate_paras = rhs; CalcChartAxis(this.barCekSetSplitPanel.Checked); this.OnCurveCoordinateChanged?.Invoke(_coordinate_paras); }; dlg.ShowDialog(); } ///// ///// 曲线方程 ///// //public void SetChartEquation() //{ // var dlg = new CurveEquationDlg(); // dlg.SetBindingData(_cubic_spline_qh, _cubic_spline_qe, _cubic_spline_qp); // dlg.ShowDialog(); //} /// /// 导出Excel /// public void ExportXls() { Perform2dExportHelper.ExportXLS(_cubic_spline_qh, _cubic_spline_qe, _cubic_spline_qp, 12); } /// /// 导出图片 /// public void ExportImage() { var dlg = new SaveFileDialog(); dlg.Filter = "jpg 图片(*.jpg)|*.jpg"; if (dlg.ShowDialog() != DialogResult.OK) return; this.chartControl1.ExportToImage(dlg.FileName, System.Drawing.Imaging.ImageFormat.Jpeg); } #endregion } }