using DevExpress.Utils; using DevExpress.XtraCharts; using DevExpress.XtraEditors; using System.Text; using Yw.Geometry; namespace Yw.WinFrmUI.Phart { /// /// /// public partial class PumpViewChart : DevExpress.XtraEditors.XtraUserControl { public PumpViewChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; } #region Private Variable private XYDiagram _diagram; private XYDiagramPane _bottom_panel; 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 Series _series_head, _series_eff, _series_power; private Series _series_head_pt, _series_eff_pt, _series_power_pt; private TextAnnotation _anno_txt_query_info; private Yw.Geometry.CubicSpline2d _qh; private Yw.Geometry.CubicSpline2d _qe; private Yw.Geometry.CubicSpline2d _qp; private List _qh_pt_list; private List _qe_pt_list; private List _qp_pt_list; private List _def_qh_pt_list; private List _def_qe_pt_list; private List _def_qp_pt_list; private PumpQueryPointViewModel _work_point = new(); private PumpCoordinate _coordinate; private bool _equip_visible = true; protected Yw.Geometry.Point2d _equip_pt; private bool _initial_data = false; #endregion #region Public Variable /// /// 定义点是否可见 /// public bool DefinePointVisible { get => _define_pt_visible; set { _define_pt_visible = value; this.barCekDefinePointVisible.Checked = _define_pt_visible; } } private bool _define_pt_visible = false; /// /// 工作线是否可见 /// public bool LineVisible { get => _line_visible; set { _line_visible = value; this.barCekLineVisible.Checked = _line_visible; this.barBtnSetAxisHValue.Enabled = _line_visible; this.barBtnSetAxisQValue.Enabled = _line_visible; this.barBtnPositioningMaxE.Enabled = _line_visible; this.barBtnPositioningMaxQ.Enabled = _line_visible; } } private bool _line_visible = 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; _diagram = (XYDiagram)chartControl1.Diagram; _bottom_panel = (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("AxisYQE"); _axis_y_eff.SetSecondaryAxisYQEDisplay(); _axis_y_power = _diagram.SecondaryAxesY.GetAxisByName("AxisYQP"); _axis_y_power.SetSecondaryAxisYQPDisplay(); _const_line_x = (ConstantLine)_diagram.AxisX.ConstantLines.GetElementByName("WorkPointLine"); _const_line_x.SetWorkPointLineDisplay(); _const_line_y = (ConstantLine)_diagram.AxisY.ConstantLines.GetElementByName("WorkHLine"); _const_line_y.SetWorkHLineDisplay(); _series_head = this.chartControl1.GetSeriesByName("SeriesCurveQH"); _series_head.SetCurveQHDisplay(); _series_eff = this.chartControl1.GetSeriesByName("SeriesCurveQE"); _series_eff.SetCurveQEDisplay(); _series_power = this.chartControl1.GetSeriesByName("SeriesCurveQP"); _series_power.SetCurveQPDisplay(); _series_head_pt = this.chartControl1.GetSeriesByName("SeriesPointQH"); _series_head_pt.SetPointQHDisplay(); _series_eff_pt = this.chartControl1.GetSeriesByName("SeriesPointQE"); _series_eff_pt.SetPointQEDisplay(); _series_power_pt = this.chartControl1.GetSeriesByName("SeriesPointQP"); _series_power_pt.SetPointQPDisplay(); _anno_txt_query_info = this.chartControl1.AnnotationRepository[0] as TextAnnotation; _anno_txt_query_info.SetTextAnnoWorkPointDisplay(); _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.Visible = false; _series_head_pt.Visible = false; _series_eff_pt.Visible = false; _series_power_pt.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); this.chartControl1.CustomPaint += ChartControl1_CustomPaint; } private void ChartControl1_CustomPaint(object sender, CustomPaintEventArgs e) { if (_qh == null) return; if (_equip_pt == null || !_equip_visible) return; if (e is not DXCustomPaintEventArgs dx_args) return; dx_args.Cache.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; try { var dis_min_h = _coordinate.DispMinH(); var equip_paras = EquipCurveHelper.CalcEquipCurve(_qh, _equip_pt, dis_min_h, out Yw.Geometry.Point2d sect_pt); if (equip_paras != null && equip_paras.IsValid()) { using Pen pen = new(Color.Black, 2); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot; var c_pt_qh = _diagram.DiagramToPoint(sect_pt.X, sect_pt.Y, _axis_x_flow, _axis_y_head); dx_args.Cache.DrawLine(pen, new Point((int)c_pt_qh.Point.X, (int)c_pt_qh.Point.Y - 10), new Point((int)c_pt_qh.Point.X, (int)c_pt_qh.Point.Y + 10)); if (_qe != null) { var y_qe = _qe.GetPointY(sect_pt.X); var c_pt_qe = _diagram.DiagramToPoint(sect_pt.X, y_qe, _axis_x_flow, _axis_y_eff); dx_args.Cache.DrawLine(pen, new Point((int)c_pt_qe.Point.X, (int)c_pt_qe.Point.Y - 10), new Point((int)c_pt_qe.Point.X, (int)c_pt_qe.Point.Y + 10)); } if (_qp != null) { var y_qp = _qp.GetPointY(sect_pt.X); var c_pt_qp = _diagram.DiagramToPoint(sect_pt.X, y_qp, _axis_x_flow, _axis_y_power); dx_args.Cache.DrawLine(pen, new Point((int)c_pt_qp.Point.X, (int)c_pt_qp.Point.Y - 10), new Point((int)c_pt_qp.Point.X, (int)c_pt_qp.Point.Y + 10)); } // 创建GraphicsPath对象,并添加样条线 var pts = equip_paras.GetPointList().Select(x => new PointF((float)x.X, (float)x.Y)).ToArray(); using var path = new System.Drawing.Drawing2D.GraphicsPath(); var g_pts = new List(); foreach (var pt in pts) { var x = pt.X; var y = pt.Y; var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_head); g_pts.Add(new PointF(c_pt.Point.X, c_pt.Point.Y)); } path.AddCurve(g_pts.ToArray()); dx_args.Cache.DrawPath(pen, path); } } catch (Exception) { throw; } } /// /// 初始化图表数据 /// public void InitialChartData() { _initial_data = false; _qh = null; _qe = null; _qp = null; _qh_pt_list = null; _qe_pt_list = null; _qp_pt_list = null; _def_qh_pt_list = null; _def_qe_pt_list = null; _def_qp_pt_list = null; _coordinate = null; _work_point = new PumpQueryPointViewModel(); UpdateChart(false); } #endregion /// /// 绑定数据 /// /// /// /// /// public void SetBindingData( Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qe, Yw.Geometry.CubicSpline2d qp, string coordinate_paras = "", bool calc_coordinate = false) { if (qh == null) { InitialChartData(); return; } List qh_pt_list, qe_pt_list = null, qp_pt_list = null; qh_pt_list = qh.GetPointList(100); if (qe != null) qe_pt_list = qe.GetPointList(100); if (qp != null) qp_pt_list = qp.GetPointList(100); SetBindingData(qh, qe, qp, qh_pt_list, qe_pt_list, qp_pt_list, null, qe_pt_list, null, coordinate_paras, calc_coordinate); } /// /// 绑定数据 /// /// /// /// /// /// public void SetBindingData( Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qe, Yw.Geometry.CubicSpline2d qp, List qh_pt_list, List qe_pt_list, List qp_pt_list, List def_qh_pt_list, List def_qe_pt_list, List def_qp_pt_list, string coordinate_paras = null, bool calc_coordinate = false) { if (qh_pt_list == null || !qh_pt_list.Any()) { InitialChartData(); return; } _initial_data = true; _qh = qh; _qe = qe; _qp = qp; _qh_pt_list = qh_pt_list; _qe_pt_list = qe_pt_list; _qp_pt_list = qp_pt_list; _def_qh_pt_list = def_qh_pt_list; _def_qe_pt_list = def_qe_pt_list; _def_qp_pt_list = def_qp_pt_list; _coordinate = PumpCoordinate.ToModel(coordinate_paras); UpdateChart(calc_coordinate); } /// /// 更新图表 /// /// 计算坐标 public void UpdateChart(bool calc_coordinate = false) { if (_qh_pt_list == null || !_qh_pt_list.Any()) { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (_qp_pt_list == null || !_qp_pt_list.Any()) { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (calc_coordinate || _coordinate == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcChartAxis(this.barCekSetSplitPanel.Checked); CalcSeries(); CalcWorkPointByQ(); CalcTextAnchorPoint(); } /// /// 设置装置点 /// /// public void SetEquipPt(Yw.Geometry.Point2d equip_pt) { _equip_pt = equip_pt; } #region Calc /// /// 计算坐标 /// public void CalcCoordinate() { if (_qh_pt_list == null || _qh_pt_list.Count < 4) { //设置成白板坐标 _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; return; } _coordinate = PumpCoordinate.CalcCoordinate(_qh_pt_list, _qe_pt_list, _qp_pt_list); } /// /// 计算图表轴 /// public void CalcChartAxis(bool split_panel) { if (_coordinate == null) { _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.Visible = false; _bottom_panel.Visibility = ChartElementVisibility.Hidden; return; } _bottom_panel.Visibility = split_panel ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; //流量 if (_qh_pt_list != null) { //计算刻度 var labels = new List(); var disQ = _coordinate.CoordMinQ; for (int i = 0; i < _coordinate.GridNumberX + 1; i++) { labels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinate.CoordSpaceQ; } //坐标刻度 _axis_x_flow.CustomLabels.Clear(); _axis_x_flow.CustomLabels.AddRange(labels.ToArray()); _axis_x_flow.Visibility = DefaultBoolean.True; _axis_x_flow.GridLines.Visible = true; _axis_x_flow.SetAxisRange(_coordinate.CoordMinQ, _coordinate.CoordMinQ + _coordinate.GridNumberX * _coordinate.CoordSpaceQ); _anno_txt_query_info.Visible = _line_visible; } //扬程 if (_qh_pt_list != null) { //计算刻度 var labels = new List(); var display_head = _coordinate.CoordMinH + _coordinate.CoordSpaceH * _coordinate.StartLineNoH; for (int i = _coordinate.StartLineNoH; i < _coordinate.EndLineNoH + 1; i++) { 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(labels.ToArray()); _axis_y_head.Visibility = DefaultBoolean.True; _axis_y_head.GridLines.Visible = true; } //效率 if (_qe_pt_list != null) { //计算刻度 var labels = new List(); var display_eff = _coordinate.CoordMinE + _coordinate.CoordSpaceE * _coordinate.StartLineNoE; for (int i = _coordinate.StartLineNoE; i < _coordinate.EndLineNoE + 1; i++) { labels.Add(new CustomAxisLabel(display_eff.ToString(), display_eff)); display_eff = display_eff + _coordinate.CoordSpaceE; } _axis_y_eff.CustomLabels.Clear(); _axis_y_eff.CustomLabels.AddRange(labels.ToArray()); _axis_y_eff.Visibility = DefaultBoolean.True; _axis_y_eff.GridLines.Visible = true; } //功率 if (_qp_pt_list != null) { //计算刻度 var labels = new List(); double display_power = _coordinate.CoordMinP + _coordinate.CoordSpaceP * _coordinate.StartLineNoP; for (int i = _coordinate.StartLineNoP; i < _coordinate.EndLineNoP + 1; i++) { labels.Add(new CustomAxisLabel(display_power.ToString(), display_power)); display_power = display_power + _coordinate.CoordSpaceP; } _axis_y_power.CustomLabels.Clear(); _axis_y_power.CustomLabels.AddRange(labels.ToArray()); _axis_y_power.Visibility = DefaultBoolean.True; _axis_y_power.GridLines.Visible = true; } //是否分割面板:流量效率在上,功率在下 if (split_panel) { var grid_count_head = _coordinate.EndLineNoH - _coordinate.StartLineNoH; var grid_count_eff = _coordinate.EndLineNoE - _coordinate.StartLineNoE; int grid_count_add = Math.Max(grid_count_head, grid_count_eff) + 2;//多两条 var max_axis_head = _coordinate.CoordMinH + _coordinate.EndLineNoH * _coordinate.CoordSpaceH; var min_axis_head = max_axis_head - grid_count_add * _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_add * _coordinate.CoordSpaceE; _axis_y_eff.SetAxisRange(min_axis_eff, max_axis_eff); var grid_count_power = _coordinate.EndLineNoP - _coordinate.StartLineNoP; var min_axis_power = _coordinate.CoordMinP + _coordinate.StartLineNoP * _coordinate.CoordSpaceP; var max_axis_power = min_axis_power + grid_count_power * _coordinate.CoordSpaceP; _axis_y_power.SetAxisRange(min_axis_power, max_axis_power); ((PointSeriesView)_series_power_pt.View).Pane = _bottom_panel; ((SplineSeriesView)_series_power.View).Pane = _bottom_panel; } else { _axis_x_flow.SetAxisRange(_coordinate.CoordMinQ, _coordinate.CoordMinQ + _coordinate.GridNumberX * _coordinate.CoordSpaceQ); if ((_qe_pt_list == null || !_qe_pt_list.Any()) && (_qp_pt_list == null || !_qp_pt_list.Any())) { _axis_y_head.SetAxisRange(_coordinate.DispMinH(), _coordinate.DispMaxH()); } else { _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); ((PointSeriesView)_series_power_pt.View).Pane = _diagram.DefaultPane; ((SplineSeriesView)_series_power.View).Pane = _diagram.DefaultPane; } } /// /// 计算系列 /// public void CalcSeries() { if (_qh_pt_list != null && _qh_pt_list.Count > 3) { _series_head.Visible = true; _series_head.Points.Clear(); foreach (var pt in _qh_pt_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_head.Points.Add(series_pt); } } else { _series_head.Points.Clear(); _series_head.Visible = false; _const_line_x.Visible = false; _const_line_y.Visible = false; _anno_txt_query_info.Visible = false; } if (_qe_pt_list != null && _qe_pt_list.Count > 3) { _series_eff.Visible = true; _series_eff.Points.Clear(); foreach (var pt in _qe_pt_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_eff.Points.Add(series_pt); } } else { _series_eff.Points.Clear(); _series_eff.Visible = false; } if (_qp_pt_list != null && _qp_pt_list.Count > 3) { _series_power.Visible = true; _series_power.Points.Clear(); foreach (var pt in _qp_pt_list) { var series_pt = new SeriesPoint(pt.X, pt.Y); _series_power.Points.Add(series_pt); } } else { _series_power.Points.Clear(); _series_power.Visible = false; } if (_def_qh_pt_list != null && _def_qh_pt_list.Any()) { _series_head_pt.Points.Clear(); foreach (var define_pt in _def_qh_pt_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_head_pt.Points.Add(series_pt); } } if (_def_qe_pt_list != null && _def_qe_pt_list.Any()) { _series_eff_pt.Points.Clear(); foreach (var define_pt in _def_qe_pt_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_eff_pt.Points.Add(series_pt); } } if (_def_qp_pt_list != null && _def_qp_pt_list.Any()) { _series_power_pt.Points.Clear(); foreach (var define_pt in _def_qp_pt_list) { var series_pt = new SeriesPoint(define_pt.X, define_pt.Y); _series_power_pt.Points.Add(series_pt); } } } /// /// 计算注释定位 /// private void CalcTextAnchorPoint() { var x = this.chartControl1.Location.X + this.chartControl1.Width; var y = this.chartControl1.Location.Y; (_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).X = x; (_anno_txt_query_info.AnchorPoint as ChartAnchorPoint).Y = y; } /// /// 计算工作点 /// /// public void CalcWorkPointByQ(double? workQ = 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 (_qh_pt_list == null || !_qh_pt_list.Any()) return; var min_flow = _qh_pt_list.Min(x => x.X); var max_flow = _qh_pt_list.Max(x => x.X); if (workQ == null) { if (_equip_pt!=null) { workQ = _equip_pt.X; } else { workQ = (min_flow + max_flow) / 2; } } else { if (workQ < min_flow || workQ > max_flow) return; } _work_point.Q = workQ.Value; _work_point.H = _qh.GetPointY(_work_point.Q); var workInfoStringBuilder = new StringBuilder(); workInfoStringBuilder.AppendLine($"流量:{_work_point.Q.ToString("N1")} "); workInfoStringBuilder.AppendLine($"扬程:{_work_point.H.ToString("N1")} "); if (_qe != null) { _work_point.E = _qe.GetPointY(_work_point.Q); workInfoStringBuilder.AppendLine($"效率:{_work_point.E.Value.ToString("N1")} "); } if (_qp != null) { _work_point.P = _qp.GetPointY(_work_point.Q); workInfoStringBuilder.Append($"功率:{_work_point.P.Value.ToString("N1")} "); } _const_line_x.AxisValue = _work_point.Q; _const_line_x.Title.Text = _work_point.Q.ToString("N1"); _const_line_y.AxisValue = _work_point.H; _const_line_y.Title.Text = _work_point.H.ToString("N1"); //测试展示效果 _anno_txt_query_info.Text = workInfoStringBuilder.ToString(); _anno_txt_query_info.AutoSize = true; if (OnCalcQueryPoint != null) { OnCalcQueryPoint(_work_point); } } /// /// 根据扬程计算工作点 /// /// public void CalcWorkPointByH(double workH) { if (!_line_visible) return; if (_qh == null) return; var min_head = _qh_pt_list.Min(x => x.Y); var max_head = _qh_pt_list.Max(x => x.Y); if (workH < min_head || workH > max_head) return; var workQ = _qh.GetPointsX(workH)?.LastOrDefault(); CalcWorkPointByQ(workQ); } /// /// 根据最大效率计算工作点 /// public void CalcWorkPointByMaxE() { if (!_line_visible) return; if (_qe == null) return; var pt_list = _qe.GetPointList(); pt_list = pt_list.OrderBy(x => x.Y).ToList(); var workQ = pt_list.Last().X; CalcWorkPointByQ(workQ); } /// /// 根据最大流量计算工作点 /// public void CalcWorkPointByMaxQ() { if (!_line_visible) return; if (_qh == null) return; var workQ = _qh.MaxX; CalcWorkPointByQ(workQ); } #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 == _const_line_x) { _onMoveWorkPointLine = true; } else if (hitInfo.ConstantLine == _const_line_y) { _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 = _diagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axis_x_flow); if (axisValue == null) return; double chartQ = axisValue.NumericalValue; CalcWorkPointByQ(chartQ); } else if (_onMoveWorkHLine) { var diagramCoordinates = _diagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axis_y_head); if (axisValue == null) return; double chartH = axisValue.NumericalValue; CalcWorkPointByH(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; _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 (_qh_pt_list == null || !_qh_pt_list.Any()) return; var dlg = new PumpAxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { var min = _qh_pt_list.Min(x => x.X); var max = _qh_pt_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 (_qh_pt_list == null || !_qh_pt_list.Any()) return; var dlg = new PumpAxisValueDlg(); dlg.SetBindingData(); dlg.Text = "扬程"; dlg.VerifyValueChanged += (value) => { var min = _qh_pt_list.Min(x => x.Y); var max = _qh_pt_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) { _equip_visible = this.barCekEqVisible.Checked; } 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_head_pt.Visible = visible; _series_eff_pt.Visible = visible; _series_power_pt.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) { _axis_x_flow.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axis_y_head.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axis_y_eff.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axis_y_power.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; } /// /// 设置图表显示 /// public void SetChartDisplay(bool monoColor) { if (monoColor) { this.chartControl1.SetChartMonoColorDisplay(); } else { this.chartControl1.SetChartBackColor(); _axis_x_flow.SetAxisYQColorDisplay(); _axis_y_head.SetAxisYQHColorDisplay(_series_head, _series_head_pt, true); _axis_y_eff.SetSecondaryAxisYQEColorDisplay(_series_eff, _series_eff_pt, true); _axis_y_power.SetSecondaryAxisYQPColorDisplay(_series_power, _series_power_pt, true); } } /// /// 设置坐标轴 /// public void SetChartAxis() { var dlg = new PumpChartCoordinateDlg(); var onlyQH = _qe == null && _qp == null; dlg.SetBindingData(_coordinate, onlyQH); dlg.OnChangedCoord += (rhs) => { _coordinate = rhs; CalcChartAxis(this.barCekSetSplitPanel.Checked); this.OnCurveCoordinateChanged?.Invoke(_coordinate); }; dlg.ShowDialog(); } /// /// 导出Excel /// public void ExportXls() { PumpChartExportHelper.ExportXLS(_qh, _qe, _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 } }