using DevExpress.Utils; using DevExpress.XtraCharts; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace IStation.WinFrmUI.Curve { /// /// /// public partial class CurveExpressChart : DevExpress.XtraEditors.XtraUserControl { public CurveExpressChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; } #region Private Variable private XYDiagram _mainChartDiagram; private XYDiagramPane _bottomPanel; private AxisX _axisXQ; private AxisY _axisYQH; private SecondaryAxisY _axisYQE, _axisYQP; private ConstantLine _workPointLine; private ConstantLine _workHLine; private Series _seriesCurveQH, _seriesCurveQE, _seriesCurveQP; private Series _seriesPointQH, _seriesPointQE, _seriesPointQP; private TextAnnotation _workPointTextAnnot; private Model.CurveExpress _curveExpressQH; private Model.CurveExpress _curveExpressQE; private Model.CurveExpress _curveExpressQP; private List _curvePointsQH; private List _curvePointsQE; private List _curvePointsQP; private List _definePointsQH; private List _definePointsQE; private List _definePointsQP; private Model.CurveCoordinateParas _coordinateParas; private Model.GroupPoint _workPoint = new Model.GroupPoint(0, 0, 0, 0, 0); private bool _initialData = 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 OnCurveCoordinateParasChanged; #endregion #region Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; _mainChartDiagram = (XYDiagram)chartControl1.Diagram; _bottomPanel = (XYDiagramPane)_mainChartDiagram.FindPaneByName("BottomPanel"); _axisXQ = _mainChartDiagram.AxisX; _axisXQ.SetAxisXQDisplay(); _axisYQH = _mainChartDiagram.AxisY; _axisYQH.SetAxisYQHDisplay(); _axisYQE = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQE"); _axisYQE.SetSecondaryAxisYQEDisplay(); _axisYQP = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQP"); _axisYQP.SetSecondaryAxisYQPDisplay(); _workPointLine = (ConstantLine)_mainChartDiagram.AxisX.ConstantLines.GetElementByName("WorkPointLine"); _workPointLine.SetWorkPointLineDisplay(); _workHLine = (ConstantLine)_mainChartDiagram.AxisY.ConstantLines.GetElementByName("WorkHLine"); _workHLine.SetWorkHLineDisplay(); _seriesCurveQH = this.chartControl1.GetSeriesByName("SeriesCurveQH"); _seriesCurveQH.SetCurveQHDisplay(); _seriesCurveQE = this.chartControl1.GetSeriesByName("SeriesCurveQE"); _seriesCurveQE.SetCurveQEDisplay(); _seriesCurveQP = this.chartControl1.GetSeriesByName("SeriesCurveQP"); _seriesCurveQP.SetCurveQPDisplay(); _seriesPointQH = this.chartControl1.GetSeriesByName("SeriesPointQH"); _seriesPointQH.SetPointQHDisplay(); _seriesPointQE = this.chartControl1.GetSeriesByName("SeriesPointQE"); _seriesPointQE.SetPointQEDisplay(); _seriesPointQP = this.chartControl1.GetSeriesByName("SeriesPointQP"); _seriesPointQP.SetPointQPDisplay(); _workPointTextAnnot = this.chartControl1.AnnotationRepository[0] as TextAnnotation; _workPointTextAnnot.SetTextAnnoWorkPointDisplay(); _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQH.Visibility = DefaultBoolean.False; _axisYQH.GridLines.Visible = false; _axisYQE.Visibility = DefaultBoolean.False; _axisYQE.GridLines.Visible = false; _axisYQP.Visibility = DefaultBoolean.False; _axisYQP.GridLines.Visible = false; _workPointLine.Visible = false; _workHLine.Visible = false; _workPointTextAnnot.Visible = false; _seriesPointQH.Visible = false; _seriesPointQE.Visible = false; _seriesPointQP.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() { _initialData = false; _curveExpressQH = null; _curveExpressQE = null; _curveExpressQP = null; _curvePointsQH = null; _curvePointsQE = null; _curvePointsQP = null; _definePointsQH = null; _definePointsQE = null; _definePointsQP = null; _coordinateParas = null; _workPoint = new Model.GroupPoint(0, 0, 0, 0, 0); UpdateChart(false); } #endregion /// /// 绑定数据 /// /// /// public void SetBindingData(Model.FeatCurveExpressGroup curveInfo, Model.CurveCoordinateParas coordinateParas = null, bool calcCoordinate = false) { if (curveInfo == null) { InitialChartData(); return; } if (curveInfo.CurveQH == null) { InitialChartData(); return; } List qhPoints, qePoints = null, qpPoints = null; if (curveInfo.CurveQH.DefinePoints != null) qhPoints = curveInfo.CurveQH.DefinePoints; else qhPoints = curveInfo.CurveQH.GetFitPoints(12); if (curveInfo.CurveQE != null) if (curveInfo.CurveQE.DefinePoints != null) qePoints = curveInfo.CurveQE.DefinePoints; else qePoints = curveInfo.CurveQE.GetFitPoints(12); if (curveInfo.CurveQP != null) if (curveInfo.CurveQP?.DefinePoints != null) qpPoints = curveInfo.CurveQP.DefinePoints; else qpPoints = curveInfo.CurveQP.GetFitPoints(12); SetBindingData(curveInfo.CurveQH, curveInfo.CurveQE, curveInfo.CurveQP, qhPoints, qePoints, qpPoints, coordinateParas, calcCoordinate); } /// /// 绑定数据 /// /// /// /// /// public void SetBindingData( Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, Model.CurveCoordinateParas coordinateParas = null, bool calcCoordinate = false) { if (curveQH == null) { InitialChartData(); return; } List qhPoints, qePoints = null, qpPoints = null; if (curveQH.DefinePoints != null) qhPoints = curveQH.DefinePoints; else qhPoints = curveQH.GetFitPoints(12); if (curveQE != null) if (curveQE.DefinePoints != null) qePoints = curveQE.DefinePoints; else qePoints = curveQE.GetFitPoints(12); if (curveQP != null) if (curveQP?.DefinePoints != null) qpPoints = curveQP.DefinePoints; else qpPoints = curveQP.GetFitPoints(12); SetBindingData(curveQH, curveQE, curveQP, qhPoints, qePoints, qpPoints, coordinateParas, calcCoordinate); } /// /// 绑定数据 /// /// /// /// /// /// /// /// /// public void SetBindingData( Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, List definePointsQH, List definePointsQE, List definePointsQP, Model.CurveCoordinateParas coordinateParas = null, bool calcCoordinate = false) { if (curveQH == null) { InitialChartData(); return; } _initialData = true; _curveExpressQH = curveQH; _curveExpressQE = curveQE; _curveExpressQP = curveQP; _curvePointsQH = curveQH.GetFitPoints(30); _curvePointsQE = curveQE?.GetFitPoints(30); _curvePointsQP = curveQP?.GetFitPoints(30); _definePointsQH = definePointsQH; _definePointsQE = definePointsQE; _definePointsQP = definePointsQP; _coordinateParas = coordinateParas; UpdateChart(calcCoordinate); } /// /// 更新图表 /// /// 计算坐标 public void UpdateChart(bool calcCoordinate = false) { if (_curveExpressQE == null) { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barBtnPositioningMaxE.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (_curveExpressQP == null) { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } else { this.barCekSetSplitPanel.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } if (calcCoordinate || _coordinateParas == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcChartAxis(this.barCekSetSplitPanel.Checked); CalcSeries(); CalcWorkPointByQ(); CalcTextAnchorPoint(); } #region Calc /// /// 计算坐标 /// public void CalcCoordinate() { if (_curvePointsQH == null || _curvePointsQH.Count < 4) { //设置成白板坐标 _coordinateParas = new Model.CurveCoordinateParas(); _coordinateParas.GridNumberX = 30; _coordinateParas.GridNumberY = 16; //显示的坐标线号 _coordinateParas.StartLineNoH = 10; _coordinateParas.EndLineNoH = 15; _coordinateParas.StartLineNoE = 0; _coordinateParas.EndLineNoE = 10; _coordinateParas.StartLineNoP = 2; _coordinateParas.EndLineNoP = 9; //坐标最小值和间隔 _coordinateParas.CoordMinQ = 0; _coordinateParas.CoordSpaceQ = 1000; _coordinateParas.CoordMinH = 10; _coordinateParas.CoordSpaceH = 100; _coordinateParas.CoordMinE = 0; _coordinateParas.CoordSpaceE = 100; _coordinateParas.CoordMinP = 10; _coordinateParas.CoordSpaceP = 100; return; } _coordinateParas = Model.CurveCoordinateParas.CalcCoordinate(_curveExpressQH, _curveExpressQE, _curveExpressQP); } /// /// 计算图表轴 /// public void CalcChartAxis(bool splitPanel) { if (_coordinateParas == null) { _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQH.Visibility = DefaultBoolean.False; _axisYQH.GridLines.Visible = false; _axisYQE.Visibility = DefaultBoolean.False; _axisYQE.GridLines.Visible = false; _axisYQP.Visibility = DefaultBoolean.False; _axisYQP.GridLines.Visible = false; _workPointLine.Visible = false; _workHLine.Visible = false; _workPointTextAnnot.Visible = false; _bottomPanel.Visibility = ChartElementVisibility.Hidden; return; } _bottomPanel.Visibility = splitPanel ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; var pointView = (PointSeriesView)_seriesPointQP.View; var curveView = (SplineSeriesView)_seriesCurveQP.View; //流量 if (_curvePointsQH != null) { //计算刻度 var labels = new List(); var disQ = _coordinateParas.CoordMinQ; for (int i = 0; i < _coordinateParas.GridNumberX + 1; i++) { labels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinateParas.CoordSpaceQ; } //坐标刻度 _axisXQ.CustomLabels.Clear(); _axisXQ.CustomLabels.AddRange(labels.ToArray()); _axisXQ.Visibility = DefaultBoolean.True; _axisXQ.GridLines.Visible = true; _axisXQ.SetAxisRange(_coordinateParas.CoordMinQ, _coordinateParas.CoordMinQ + _coordinateParas.GridNumberX * _coordinateParas.CoordSpaceQ); _workPointTextAnnot.Visible = _lineVisible; } //扬程 if (_curvePointsQH != null) { //计算刻度 var labels = new List(); var disH = _coordinateParas.CoordMinH + _coordinateParas.CoordSpaceH * _coordinateParas.StartLineNoH; for (int i = _coordinateParas.StartLineNoH; i < _coordinateParas.EndLineNoH + 1; i++) { labels.Add(new CustomAxisLabel(disH.ToString(), disH)); disH = disH + _coordinateParas.CoordSpaceH; } _axisYQH.CustomLabels.Clear(); _axisYQH.CustomLabels.AddRange(labels.ToArray()); _axisYQH.Visibility = DefaultBoolean.True; _axisYQH.GridLines.Visible = true; } //效率 if (_curvePointsQE != null) { //计算刻度 var labels = new List(); var disE = _coordinateParas.CoordMinE + _coordinateParas.CoordSpaceE * _coordinateParas.StartLineNoE; for (int i = _coordinateParas.StartLineNoE; i < _coordinateParas.EndLineNoE + 1; i++) { labels.Add(new CustomAxisLabel(disE.ToString(), disE)); disE = disE + _coordinateParas.CoordSpaceE; } _axisYQE.CustomLabels.Clear(); _axisYQE.CustomLabels.AddRange(labels.ToArray()); _axisYQE.Visibility = DefaultBoolean.True; _axisYQE.GridLines.Visible = true; } //功率 if (_curvePointsQP != null) { //计算刻度 var labels = new List(); double disP = _coordinateParas.CoordMinP + _coordinateParas.CoordSpaceP * _coordinateParas.StartLineNoP; for (int i = _coordinateParas.StartLineNoP; i < _coordinateParas.EndLineNoP + 1; i++) { labels.Add(new CustomAxisLabel(disP.ToString(), disP)); disP = disP + _coordinateParas.CoordSpaceP; } _axisYQP.CustomLabels.Clear(); _axisYQP.CustomLabels.AddRange(labels.ToArray()); _axisYQP.Visibility = DefaultBoolean.True; _axisYQP.GridLines.Visible = true; } //是否分割面板:流量效率在上,功率在下 if (splitPanel) { var gridNumH = _coordinateParas.EndLineNoH - _coordinateParas.StartLineNoH; var gridNumE = _coordinateParas.EndLineNoE - _coordinateParas.StartLineNoE; int gridNumUp = Math.Max(gridNumH, gridNumE) + 2;//多两条 var maxAxisH = _coordinateParas.CoordMinH + _coordinateParas.EndLineNoH * _coordinateParas.CoordSpaceH; var minAxisH = maxAxisH - gridNumUp * _coordinateParas.CoordSpaceH; _axisYQH.SetAxisRange(minAxisH, maxAxisH); var minAxisE = _coordinateParas.CoordMinE + _coordinateParas.StartLineNoE * _coordinateParas.CoordSpaceE; var maxAxisE = minAxisE + gridNumUp * _coordinateParas.CoordSpaceE; _axisYQE.SetAxisRange(minAxisE, maxAxisE); var gridNumP = _coordinateParas.EndLineNoP - _coordinateParas.StartLineNoP; var minAxisP = _coordinateParas.CoordMinP + _coordinateParas.StartLineNoP * _coordinateParas.CoordSpaceP; var maxAxisP = minAxisP + gridNumP * _coordinateParas.CoordSpaceP; _axisYQP.SetAxisRange(minAxisP, maxAxisP); pointView.Pane = _bottomPanel; curveView.Pane = _bottomPanel; } else { _axisXQ.SetAxisRange(_coordinateParas.CoordMinQ, _coordinateParas.CoordMinQ + _coordinateParas.GridNumberX * _coordinateParas.CoordSpaceQ); if (_curveExpressQE == null && _curveExpressQP == null) { _axisYQH.SetAxisRange(_coordinateParas.DispMinH(), _coordinateParas.DispMaxH()); } else { _axisYQH.SetAxisRange(_coordinateParas.CoordMinH, _coordinateParas.CoordMinH + _coordinateParas.GridNumberY * _coordinateParas.CoordSpaceH); } _axisYQE.SetAxisRange(_coordinateParas.CoordMinE, _coordinateParas.CoordMinE + _coordinateParas.GridNumberY * _coordinateParas.CoordSpaceE); _axisYQP.SetAxisRange(_coordinateParas.CoordMinP, _coordinateParas.CoordMinP + _coordinateParas.GridNumberY * _coordinateParas.CoordSpaceP); pointView.Pane = _mainChartDiagram.DefaultPane; curveView.Pane = _mainChartDiagram.DefaultPane; } } /// /// 计算系列 /// public void CalcSeries() { if (_curvePointsQH != null && _curvePointsQH.Count > 3) { _seriesCurveQH.Visible = true; _seriesCurveQH.Points.Clear(); foreach (var curvePoint in _curvePointsQH) { var seriesPoint = new SeriesPoint(curvePoint.X, curvePoint.Y); _seriesCurveQH.Points.Add(seriesPoint); } } else { _seriesCurveQH.Points.Clear(); _seriesCurveQH.Visible = false; _workPointLine.Visible = false; _workHLine.Visible = false; _workPointTextAnnot.Visible = false; } if (_curvePointsQE != null && _curvePointsQE.Count > 3) { _seriesCurveQE.Visible = true; _seriesCurveQE.Points.Clear(); foreach (var curvePoint in _curvePointsQE) { var seriesPoint = new SeriesPoint(curvePoint.X, curvePoint.Y); _seriesCurveQE.Points.Add(seriesPoint); } } else { _seriesCurveQE.Points.Clear(); _seriesCurveQE.Visible = false; } if (_curvePointsQP != null && _curvePointsQP.Count > 3) { _seriesCurveQP.Visible = true; _seriesCurveQP.Points.Clear(); foreach (var curvePoint in _curvePointsQP) { var seriesPoint = new SeriesPoint(curvePoint.X, curvePoint.Y); _seriesCurveQP.Points.Add(seriesPoint); } } else { _seriesCurveQP.Points.Clear(); _seriesCurveQP.Visible = false; } if (_definePointsQH != null && _definePointsQH.Any()) { _seriesPointQH.Points.Clear(); foreach (var definePoint in _definePointsQH) { var seriesPoint = new SeriesPoint(definePoint.X, definePoint.Y); _seriesPointQH.Points.Add(seriesPoint); } } if (_definePointsQE != null && _definePointsQE.Any()) { _seriesPointQE.Points.Clear(); foreach (var definePoint in _definePointsQE) { var seriesPoint = new SeriesPoint(definePoint.X, definePoint.Y); _seriesPointQE.Points.Add(seriesPoint); } } if (_definePointsQP != null && _definePointsQP.Any()) { _seriesPointQP.Points.Clear(); foreach (var definePoint in _definePointsQP) { var seriesPoint = new SeriesPoint(definePoint.X, definePoint.Y); _seriesPointQP.Points.Add(seriesPoint); } } } /// /// 计算注释定位 /// private void CalcTextAnchorPoint() { var x = this.chartControl1.Location.X + this.chartControl1.Width - (100); var y = this.chartControl1.Height - (200); (_workPointTextAnnot.AnchorPoint as ChartAnchorPoint).X = x; (_workPointTextAnnot.AnchorPoint as ChartAnchorPoint).Y = y; } /// /// 计算工作点 /// /// public void CalcWorkPointByQ(double? workQ = null) { if (!_lineVisible) { _workPointLine.Visible = false; _workPointLine.Title.Visible = false; _workHLine.Visible = false; _workHLine.Title.Visible = false; _workPointTextAnnot.Visible = false; return; } else { _workPointLine.Visible = true; _workPointLine.Title.Visible = true; _workHLine.Visible = true; _workHLine.Title.Visible = true; _workPointTextAnnot.Visible = true; } if (_curveExpressQH == null) return; var minQ = _curvePointsQH.Min(x => x.X); var maxQ = _curvePointsQH.Max(x => x.X); if (workQ == null) { workQ = (minQ + maxQ) / 2; } else { if (workQ < minQ || workQ > maxQ) return; } _workPoint.Q = workQ.Value; _workPoint.H = Model.FitCurveHelper.GetFitPointY(_curveExpressQH, _workPoint.Q); var workInfoStringBuilder = new StringBuilder(); workInfoStringBuilder.AppendLine($"流量:{_workPoint.Q.ToString("N1")} "); workInfoStringBuilder.AppendLine($"扬程:{_workPoint.H.ToString("N1")} "); if (_curveExpressQE != null) { _workPoint.E = Model.FitCurveHelper.GetFitPointY(_curveExpressQE, _workPoint.Q); workInfoStringBuilder.AppendLine($"效率:{_workPoint.E.ToString("N1")} "); } if (_curveExpressQP != null) { _workPoint.P = Model.FitCurveHelper.GetFitPointY(_curveExpressQP, _workPoint.Q); workInfoStringBuilder.Append($"功率:{_workPoint.P.ToString("N1")} "); } _workPointLine.AxisValue = _workPoint.Q; _workPointLine.Title.Text = _workPoint.Q.ToString("N1"); _workHLine.AxisValue = _workPoint.H; _workHLine.Title.Text = _workPoint.H.ToString("N1"); //测试展示效果 _workPointTextAnnot.Text = workInfoStringBuilder.ToString(); _workPointTextAnnot.AutoSize = true; } /// /// 根据扬程计算工作点 /// /// public void CalcWorkPointByH(double workH) { if (!_lineVisible) return; if (_curveExpressQH == null) return; var minH = _curvePointsQH.Min(x => x.Y); var maxH = _curvePointsQH.Max(x => x.Y); if (workH < minH || workH > maxH) return; var InterPoints = Model.FitCurveHelper.GetInterPointX(_curveExpressQH, workH); if (InterPoints == null || InterPoints.Count == 0) return; var workQ = InterPoints.Last().X; CalcWorkPointByQ(workQ); } /// /// 根据最大效率计算工作点 /// public void CalcWorkPointByMaxE() { if (!_lineVisible) return; if (_curveExpressQE == null) return; var maxE = Model.FitCurveHelper.GetMaxPoint(_curveExpressQE); var workQ = maxE.X; CalcWorkPointByQ(workQ); } /// /// 根据最大流量计算工作点 /// public void CalcWorkPointByMaxQ() { if (!_lineVisible) return; if (_curveExpressQH == null) return; var workQ = _curveExpressQH.Max; CalcWorkPointByQ(workQ); } #endregion #region ChartEvent ToolTipController toolTip = new ToolTipController(); private void chartControl1_ObjectHotTracked(object sender, HotTrackEventArgs e) { if (!_initialData) return; if (e.AdditionalObject is SeriesPoint seriesPoint) { var tip = string.Format("X:{0:N1} Y:{1:N1}", seriesPoint.Argument, seriesPoint.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 (!_initialData) 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 == _workPointLine) { _onMoveWorkPointLine = true; } else if (hitInfo.ConstantLine == _workHLine) { _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 (!_initialData) return; if (_onMoveWorkPointLine) { var diagramCoordinates = _mainChartDiagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axisXQ); if (axisValue == null) return; double chartQ = axisValue.NumericalValue; CalcWorkPointByQ(chartQ); } else if (_onMoveWorkHLine) { var diagramCoordinates = _mainChartDiagram.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 (!_initialData) 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 (_curvePointsQH == null || !_curvePointsQH.Any()) return; var dlg = new AxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { var min = _curvePointsQH.Min(x => x.X); var max = _curvePointsQH.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 (_curvePointsQH == null || !_curvePointsQH.Any()) return; var dlg = new AxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { var min = _curvePointsQH.Min(x => x.Y); var max = _curvePointsQH.Max(x => x.Y); if (value < min || value > max) return false; CalcWorkPointByH(value); return true; }; dlg.ShowDialog(); } 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) { 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) { _seriesPointQH.Visible = visible; _seriesPointQE.Visible = visible; _seriesPointQP.Visible = visible; } /// /// 设置工作点显示 /// public void SetLineVisible(bool visible) { if (!_initialData) 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; _axisYQE.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axisYQP.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(_seriesCurveQH, _seriesPointQH, true); _axisYQE.SetSecondaryAxisYQEColorDisplay(_seriesCurveQE, _seriesPointQE, true); _axisYQP.SetSecondaryAxisYQPColorDisplay(_seriesCurveQP, _seriesPointQP, true); } } /// /// 设置坐标轴 /// public void SetChartAxis() { var dlg = new ChartCoordinateDlg(); var onlyQH = _curveExpressQE == null && _curveExpressQP == null; dlg.SetBindingData(_coordinateParas, onlyQH); dlg.OnChangedCoord += (rhs) => { _coordinateParas = rhs; CalcChartAxis(this.barCekSetSplitPanel.Checked); this.OnCurveCoordinateParasChanged?.Invoke(_coordinateParas); }; dlg.ShowDialog(); } /// /// 曲线方程 /// public void SetChartEquation() { var dlg = new CurveEquationDlg(); dlg.SetBindingData(_curveExpressQH, _curveExpressQE, _curveExpressQP); dlg.ShowDialog(); } /// /// 导出Excel /// public void ExportXls() { CurveExpressExportXLS.Export(_curveExpressQH, _curveExpressQE, _curveExpressQP, 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 } }