using DevExpress.Utils; using DevExpress.XtraCharts; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace IStation.WinFrmUI.Curve { /// /// bug:隐藏效率线计算剩下两条线的轴,计算轴坐标不合理 /// public partial class MultiCurveExpressChart : DevExpress.XtraEditors.XtraUserControl { public MultiCurveExpressChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; } #region Private Variable private class CurrentViewModel { public long ID { get; set; } public string Name { get; set; } public Model.CurveExpress CurveExpressQH { get; set; } public Model.CurveExpress CurveExpressQE { get; set; } public Model.CurveExpress CurveExpressQP { get; set; } public List PointsQH { get; set; } public List PointsQE { get; set; } public List PointsQP { get; set; } public Color Color { get; set; } } private List _allCurves = new List(); private string _tagQH = "CurveQH", _tagQE = "CurveQE", _tagQP = "CurveQP"; private XYDiagram _mainChartDiagram; private XYDiagramDefaultPane _paneQH; private XYDiagramPane _paneQE; private XYDiagramPane _paneQP; private AxisX _axisXQ; private AxisY _axisYQH; private SecondaryAxisY _axisYQE, _axisYQP; private ConstantLine _workPointLine; private TextAnnotation _workPointTextAnnot; private Model.CurveCoordinateParas _coordinateParas; public bool _curveQHVisible = true; public bool _curveQEVisible = true; public bool _curveQPVisible = true; private bool _initialData = false; #endregion #region Public Variable /// /// 工作线是否可见 /// public bool LineVisible { get => _lineVisible; set { _lineVisible = value; this.barCekLineVisible.Checked = _lineVisible; } } private bool _lineVisible = false; /// /// 曲线名是否可见 /// public bool CurveNameVisible { get => _curveNameVisible; set { _curveNameVisible = value; this.barCekCurveNameVisible.Checked = _curveNameVisible; } } private bool _curveNameVisible = false; #endregion #region Public Evnet public event Action OnCurveCoordinateParasChanged; public event Action OnCalcQueryPoint = null; #endregion #region Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Direction = DevExpress.XtraCharts.LegendDirection.TopToBottom; _mainChartDiagram = (XYDiagram)chartControl1.Diagram; _paneQH = _mainChartDiagram.DefaultPane; _paneQE = (XYDiagramPane)_mainChartDiagram.FindPaneByName("PaneQE"); _paneQP = (XYDiagramPane)_mainChartDiagram.FindPaneByName("PaneQP"); _axisXQ = _mainChartDiagram.AxisX; _axisXQ.SetAxisXQDisplay(); _axisYQH = _mainChartDiagram.AxisY; _axisYQH.SetAxisYQHDisplay(); _axisYQE = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQE"); _axisYQE.SetSecondaryAxisYQEDisplay(); _axisYQE.Alignment = AxisAlignment.Near; _axisYQP = _mainChartDiagram.SecondaryAxesY.GetAxisByName("AxisYQP"); _axisYQP.SetSecondaryAxisYQPDisplay(); _workPointLine = (ConstantLine)_mainChartDiagram.AxisX.ConstantLines.GetElementByName("WorkPointLine"); _workPointLine.SetWorkPointLineDisplay(); _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; _workPointTextAnnot.Visible = false; 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; _coordinateParas = null; UpdateChart(false); } #endregion #region Add Update Curve /// /// 添加曲线 /// /// /// /// /// /// public void AddCurve(long id, string name, Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, Color color) { if (curveQH == null) return; if (_allCurves.Exists(x => x.ID == id)) return; _initialData = true; 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); AddCurve(id, name, curveQH, curveQE, curveQP, color, qhPoints, qePoints, qpPoints); } /// /// 添加曲线 /// /// /// /// /// /// /// /// /// public void AddCurve(long id, string name, Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, Color color, List definePointsQH = null, List definePointsQE = null, List definePointsQP = null) { if (curveQH == null) return; if (_allCurves.Exists(x => x.ID == id)) return; _initialData = true; CurrentViewModel curve = new CurrentViewModel(); curve.ID = id; curve.Name = name; curve.CurveExpressQH = curveQH; curve.CurveExpressQE = curveQE; curve.CurveExpressQP = curveQP; if (definePointsQH == null) { curve.PointsQH = curveQH.GetFitPoints(); } else { curve.PointsQH = definePointsQH; } if (curveQE != null && definePointsQE == null) { curve.PointsQE = curveQE.GetFitPoints(); } else { curve.PointsQE = definePointsQE; } if (curveQP != null && definePointsQP == null) { curve.PointsQP = curveQP.GetFitPoints(); } else { curve.PointsQP = definePointsQP; } curve.Color = color; _allCurves.Add(curve); UpdateChart(true); } /// /// 设置曲线 /// /// /// /// /// /// public void SetCurve(long id, Model.CurveExpress curveQH, Model.CurveExpress curveQE, Model.CurveExpress curveQP, string name = "") { var exist = _allCurves.FirstOrDefault(x => x.ID == id); if (exist == null) return; if (!string.IsNullOrEmpty(name)) { exist.Name = name; } exist.CurveExpressQH = curveQH; exist.CurveExpressQE = curveQE; exist.CurveExpressQP = curveQP; exist.PointsQH = Model.FitCurveHelper.GetFitPoints(curveQH, 12); exist.PointsQE = Model.FitCurveHelper.GetFitPoints(curveQE, 12); exist.PointsQP = Model.FitCurveHelper.GetFitPoints(curveQP, 12); UpdateChart(true); } /// /// 设置曲线 /// /// /// public void SetCurve(long id, Color color) { var exist = _allCurves.FirstOrDefault(x => x.ID == id); if (exist == null) return; foreach (Series series in this.chartControl1.Series) { var tag = series.Tag; if (tag == null) continue; if (tag.ToString() != exist.ID.ToString()) continue; exist.Color = color; series.View.Color = color; for (int i = 0; i < this.chartControl1.AnnotationRepository.Count; i++) { var txt = this.chartControl1.AnnotationRepository[i]; if (txt.Name == _tagQH + id.ToString()) { (txt as TextAnnotation).TextColor = color; (txt as TextAnnotation).Border.Color = color; } } } } /// /// 设置曲线(需手动更新图表) /// /// /// public void SetCurveName(long id, string name) { var exist = _allCurves.FirstOrDefault(x => x.ID == id); if (exist == null) return; exist.Name = name; } /// /// 删除曲线 /// public void DeleteCurve() { _allCurves.Clear(); UpdateChart(true); _initialData = false; } /// /// 删除曲线 /// /// public void DeleteCurve(long id) { var exist = _allCurves.FirstOrDefault(x => x.ID == id); if (exist == null) return; _allCurves.Remove(exist); UpdateChart(true); if (_allCurves.Count == 0) { _initialData = false; } } /// /// 更新图表 /// /// 计算坐标 public void UpdateChart(bool calcCoordinate = false) { if (calcCoordinate || _coordinateParas == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcSeries(); CalcChartAxis(); CalcWorkPointByQ(); CalcTextAnchorPoint(); } #endregion #region Calc private double _minQ, _maxQ; private double _maxH = 0, _minH = 10000; private double _maxE = 0, _minE = 0; private double _maxP = 0, _minP = 1000; /// /// 计算坐标 /// private void CalcCoordinate() { if (_allCurves == null || !_allCurves.Any()) { //设置成白板坐标 _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; } _maxQ = 0; _minQ = 10000; _maxH = 0; _minH = 10000; _maxE = 0; _minE = 0; _maxP = 0; _minP = 1000; double _scaleMinH = 1, _scaleMaxH = 1; foreach (var curve in _allCurves) { var xxx = curve.PointsQH.Select(x => x.X); var yyy = curve.PointsQH.Select(x => x.Y); _minQ = Math.Min(_minQ, xxx.Min()); _maxQ = Math.Max(_maxQ, xxx.Max()); _minH = Math.Min(_minH, yyy.Min()); _maxH = Math.Max(_maxH, yyy.Max()); } foreach (CurrentViewModel info in _allCurves) { if (info.PointsQE == null) continue; var yyy = info.PointsQE?.Select(x => x.Y); _maxE = Math.Max(_maxE, yyy.Max()); } foreach (CurrentViewModel info in _allCurves) { var yyy = info.PointsQP.Select(x => x.Y); _minP = Math.Min(_minP, yyy.Min()); _maxP = Math.Max(_maxP, yyy.Max()); } _coordinateParas = Model.CurveCoordinateParas.CalcCoordinate(_minQ, _maxQ, _minH * _scaleMinH, _maxH * _scaleMaxH, _minE, _maxE, _minP, _maxP); if (_coordinateParas == null) return; if (_coordinateParas.CoordMinQ + _coordinateParas.CoordSpaceQ * this._coordinateParas.GridNumberX < _maxQ * 1.05) { _coordinateParas.GridNumberX++; } } /// /// 计算图表轴 /// private void CalcChartAxis() { // 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; _paneQE.Visibility = ChartElementVisibility.Hidden; _paneQP.Visibility = ChartElementVisibility.Hidden; // return; // } _paneQE.Visibility = _curveQEVisible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; _paneQP.Visibility = _curveQPVisible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; //计算刻度 Q var axisQLabels = new List(); var disQ = _coordinateParas.CoordMinQ; for (int i = 0; i < _coordinateParas.GridNumberX + 1; i++) { axisQLabels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinateParas.CoordSpaceQ; } _axisXQ.CustomLabels.Clear(); _axisXQ.CustomLabels.AddRange(axisQLabels.ToArray()); _axisXQ.Visibility = DefaultBoolean.True; _axisXQ.GridLines.Visible = true; //计算刻度 var axisQHLabels = new List(); var disH = _coordinateParas.CoordMinH + _coordinateParas.CoordSpaceH * _coordinateParas.StartLineNoH; for (int i = _coordinateParas.StartLineNoH; i < _coordinateParas.EndLineNoH + 1; i++) { axisQHLabels.Add(new CustomAxisLabel(disH.ToString(), disH)); disH = disH + _coordinateParas.CoordSpaceH; } _axisYQH.CustomLabels.Clear(); _axisYQH.CustomLabels.AddRange(axisQHLabels.ToArray()); _axisYQH.Visibility = DefaultBoolean.True; _axisYQH.GridLines.Visible = true; //效率 if (_maxE > _minE && _curveQEVisible) { //计算刻度 var axisQELabels = new List(); var disE = _coordinateParas.CoordMinE + _coordinateParas.CoordSpaceE * _coordinateParas.StartLineNoE; for (int i = _coordinateParas.StartLineNoE; i < _coordinateParas.EndLineNoE + 1; i++) { axisQELabels.Add(new CustomAxisLabel(disE.ToString(), disE)); disE = disE + _coordinateParas.CoordSpaceE; } _axisYQE.CustomLabels.Clear(); _axisYQE.CustomLabels.AddRange(axisQELabels.ToArray()); _axisYQE.Visibility = DefaultBoolean.True; _axisYQE.GridLines.Visible = true; } //功率 if (_maxP > _minP) { //计算刻度 var axisQPLabels = new List(); double disP = _coordinateParas.CoordMinP + _coordinateParas.CoordSpaceP * _coordinateParas.StartLineNoP; for (int i = _coordinateParas.StartLineNoP; i < _coordinateParas.EndLineNoP + 1; i++) { axisQPLabels.Add(new CustomAxisLabel(disP.ToString(), disP)); disP = disP + _coordinateParas.CoordSpaceP; } _axisYQP.CustomLabels.Clear(); _axisYQP.CustomLabels.AddRange(axisQPLabels.ToArray()); _axisYQP.Visibility = DefaultBoolean.True; _axisYQP.GridLines.Visible = true; } _axisXQ.SetAxisRange(_coordinateParas.CoordMinQ, _coordinateParas.DispMaxQ()); _axisYQH.SetAxisRange(_coordinateParas.DispMinH(), _coordinateParas.DispMaxH()); _axisYQE.SetAxisRange(_coordinateParas.DispMinE(), _coordinateParas.DispMaxE()); _axisYQP.SetAxisRange(_coordinateParas.DispMinP(), _coordinateParas.DispMaxP()); } /// /// 计算系列 /// private void CalcSeries() { this.chartControl1.BeginInit(); this.chartControl1.Series.Clear(); var annotationCount = this.chartControl1.AnnotationRepository.Count; for (int i = annotationCount - 1; i > 0; i--) { if (i == 0) break; this.chartControl1.AnnotationRepository.RemoveAt(i); } this.chartControl1.Legend.CustomItems.Clear(); foreach (var curve in _allCurves) { CreateSeries(curve); } if (_allCurves.Count == 0) { LineVisible = false; } this.chartControl1.EndInit(); } /// /// 计算注释定位 /// private void CalcTextAnchorPoint() { var x = this.chartControl1.Location.X + this.chartControl1.Width - (100); var y = this.chartControl1.Height - (100); (_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; _workPointTextAnnot.Visible = false; return; } else { _workPointLine.Visible = true; _workPointLine.Title.Visible = true; _workPointTextAnnot.Visible = true; } if (_allCurves == null || !_allCurves.Any()) return; if (_allCurves.Exists(x => x.ID == -1)) { _workPointTextAnnot.Visible = true; } else { _workPointTextAnnot.Visible = false; } if (workQ == null) { workQ = (_minQ + _maxQ) / 2; } if (workQ < _minQ || workQ > _maxQ) return; foreach (var curve in _allCurves) { var curveMinQ = curve.CurveExpressQH.Min; var curveMaxQ = curve.CurveExpressQH.Max; var workPoint = new Model.GroupPoint(0, 0, 0, 0, 0); if (curveMinQ > workQ.Value || workQ.Value > curveMaxQ) { if (OnCalcQueryPoint != null) { OnCalcQueryPoint(curve.ID, workPoint); } if (curve.ID == -1) { _workPointTextAnnot.Visible = false; } continue; } workPoint.Q = workQ.Value; workPoint.H = Common.FitCurveHelper.GetFitPointY(curve.CurveExpressQH, workQ.Value); var workInfoStringBuilder = new StringBuilder(); workInfoStringBuilder.AppendLine($"流量:{workPoint.Q.ToString("N1")} "); workInfoStringBuilder.AppendLine($"扬程:{workPoint.H.ToString("N1")} "); if (curve.CurveExpressQE != null) { if (curve.CurveExpressQP != null) { workPoint.P = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQP, workPoint.Q); workPoint.E = IStation.Common.PumpParaHelper.CalculateE(workPoint.Q, workPoint.H, workPoint.P); } else { workPoint.E = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQE, workPoint.Q); } workInfoStringBuilder.AppendLine($"效率:{workPoint.E.ToString("N2")} "); } if (curve.CurveExpressQP != null) { workPoint.P = Model.FitCurveHelper.GetFitPointY(curve.CurveExpressQP, workPoint.Q); workInfoStringBuilder.Append($"功率:{workPoint.P.ToString("N1")} "); } if (curve.ID == -1) { _workPointTextAnnot.Text = workInfoStringBuilder.ToString(); _workPointTextAnnot.AutoSize = true; } else { if (OnCalcQueryPoint != null) { OnCalcQueryPoint(curve.ID, workPoint); } } } _workPointLine.AxisValue = workQ; _workPointLine.Title.Text = workQ.Value.ToString("N1"); } /// /// 创建系列 /// private void CreateSeries(CurrentViewModel curve) { var seriesCurveQH = new DevExpress.XtraCharts.Series(); seriesCurveQH.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; seriesCurveQH.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; seriesCurveQH.Name = _tagQH + curve.ID.ToString(); seriesCurveQH.ShowInLegend = false; seriesCurveQH.CrosshairEnabled = DefaultBoolean.False; seriesCurveQH.Tag = curve.ID.ToString(); seriesCurveQH.ShowInLegend = true; seriesCurveQH.LegendTextPattern = curve.Name; var seriesCurveQHView = new DevExpress.XtraCharts.SplineSeriesView(); seriesCurveQHView.LineStyle.Thickness = 2; seriesCurveQHView.Color = curve.Color; seriesCurveQHView.EnableAntialiasing = DefaultBoolean.True; seriesCurveQH.SeriesPointsSorting = SortingMode.None; seriesCurveQH.SeriesPointsSortingKey = SeriesPointKey.Value_1; seriesCurveQH.View = seriesCurveQHView; seriesCurveQH.Visible = _curveQHVisible; var pointsQH = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQH, 12); for (int i = 0; i < pointsQH.Count; i++) { seriesCurveQH.Points.Add(new SeriesPoint(pointsQH[i].X, new double[] { pointsQH[i].Y })); } var pointQH = pointsQH[pointsQH.Count() - 1]; var anchorPointQH = new DevExpress.XtraCharts.PaneAnchorPoint(); anchorPointQH.Pane = _paneQH; anchorPointQH.AxisXCoordinate.AxisValue = pointQH.X.ToString(); anchorPointQH.AxisYCoordinate.AxisValue = pointQH.Y.ToString(); var positionQH = new DevExpress.XtraCharts.RelativePosition(); positionQH.Angle = 30; positionQH.ConnectorLength = 35; var txtQH = new TextAnnotation(); txtQH.Border.Visibility = DefaultBoolean.False; txtQH.AnchorPoint = anchorPointQH; txtQH.AutoHeight = true; txtQH.AutoWidth = true; txtQH.BackColor = System.Drawing.Color.Transparent; txtQH.Border.Color = curve.Color; txtQH.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.Line; txtQH.DXFont = CurveChartDisplay.AnnoFontQH; txtQH.Name = _tagQH + curve.ID.ToString(); txtQH.Padding.Bottom = 1; txtQH.Padding.Left = 1; txtQH.Padding.Right = 1; txtQH.Padding.Top = 1; txtQH.RuntimeAnchoring = false; txtQH.RuntimeMoving = true; txtQH.RuntimeResizing = false; txtQH.RuntimeRotation = false; txtQH.Text = curve.Name; txtQH.TextColor = curve.Color; txtQH.ShapePosition = positionQH; txtQH.Visible = _curveNameVisible; this.chartControl1.AnnotationRepository.Add(txtQH); this.chartControl1.Series.Add(seriesCurveQH); if (curve.CurveExpressQE != null) { var seriesCurveQE = new DevExpress.XtraCharts.Series(); seriesCurveQE.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; seriesCurveQE.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; seriesCurveQE.Name = _tagQE + curve.ID.ToString(); seriesCurveQE.ShowInLegend = false; seriesCurveQE.CrosshairEnabled = DefaultBoolean.False; seriesCurveQE.Tag = curve.ID.ToString(); var seriesCurveQEView = new DevExpress.XtraCharts.SplineSeriesView(); seriesCurveQEView.LineStyle.Thickness = 2; seriesCurveQEView.Color = curve.Color; seriesCurveQEView.AxisY = _axisYQE; seriesCurveQEView.Pane = _paneQE; seriesCurveQEView.EnableAntialiasing = DefaultBoolean.True; seriesCurveQE.SeriesPointsSorting = SortingMode.None; seriesCurveQE.SeriesPointsSortingKey = SeriesPointKey.Value_1; seriesCurveQE.View = seriesCurveQEView; seriesCurveQE.Visible = _curveQEVisible; var pointsQE = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQE, 12); for (int i = 0; i < pointsQE.Count; i++) { seriesCurveQE.Points.Add(new SeriesPoint(pointsQE[i].X, new double[] { pointsQE[i].Y })); } this.chartControl1.Series.Add(seriesCurveQE); } if (curve.CurveExpressQP != null) { var seriesCurveQP = new DevExpress.XtraCharts.Series(); seriesCurveQP.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; seriesCurveQP.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; seriesCurveQP.Name = _tagQP + curve.ID.ToString(); seriesCurveQP.ShowInLegend = false; seriesCurveQP.CrosshairEnabled = DefaultBoolean.False; seriesCurveQP.Tag = curve.ID.ToString(); var seriesCurveQPView = new DevExpress.XtraCharts.SplineSeriesView(); seriesCurveQPView.LineStyle.Thickness = 2; seriesCurveQPView.Color = curve.Color; seriesCurveQPView.AxisY = _axisYQP; seriesCurveQPView.Pane = _paneQP; seriesCurveQPView.EnableAntialiasing = DefaultBoolean.True; seriesCurveQP.SeriesPointsSorting = SortingMode.None; seriesCurveQP.SeriesPointsSortingKey = SeriesPointKey.Value_1; seriesCurveQP.View = seriesCurveQPView; seriesCurveQP.Visible = _curveQPVisible; var pointsQP = Model.FitCurveHelper.GetFitPoints(curve.CurveExpressQP, 12); for (int i = 0; i < pointsQP.Count; i++) { seriesCurveQP.Points.Add(new SeriesPoint(pointsQP[i].X, new double[] { pointsQP[i].Y })); } this.chartControl1.Series.Add(seriesCurveQP); } } private Series _seriesCurvePointQH, _seriesCurvePointQE, _seriesCurvePointQP; /// /// 创建系列 /// public void CreatePointSeries(List curvePointsQH, List curvePointsQE, List curvePointsQP) { this.chartControl1.BeginInit(); if (curvePointsQH == null) { if (_seriesCurvePointQH != null) { this.chartControl1.Series.Remove(_seriesCurvePointQH); } if (_seriesCurvePointQE != null) { this.chartControl1.Series.Remove(_seriesCurvePointQE); } if (_seriesCurvePointQP != null) { this.chartControl1.Series.Remove(_seriesCurvePointQP); } _seriesCurvePointQH = null; _seriesCurvePointQE = null; _seriesCurvePointQP = null; this.chartControl1.EndInit(); return; } _seriesCurvePointQH = new DevExpress.XtraCharts.Series(); _seriesCurvePointQH.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; _seriesCurvePointQH.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; _seriesCurvePointQH.Name = _tagQH + "CurvePoint"; _seriesCurvePointQH.ShowInLegend = false; _seriesCurvePointQH.CrosshairEnabled = DefaultBoolean.False; _seriesCurvePointQH.ShowInLegend = true; _seriesCurvePointQH.LegendTextPattern = "流量扬程点"; _seriesCurvePointQH.LabelsVisibility = DefaultBoolean.True; var seriesCurveQHView = new DevExpress.XtraCharts.PointSeriesView(); seriesCurveQHView.Color = CurveChartDisplay.PointColorQH; _seriesCurvePointQH.SeriesPointsSorting = SortingMode.None; _seriesCurvePointQH.SeriesPointsSortingKey = SeriesPointKey.Value_1; _seriesCurvePointQH.View = seriesCurveQHView; _seriesCurvePointQH.Visible = _curveQHVisible; for (int i = 0; i < curvePointsQH.Count; i++) { _seriesCurvePointQH.Points.Add(new SeriesPoint(curvePointsQH[i].X, new double[] { curvePointsQH[i].Y })); } this.chartControl1.Series.Add(_seriesCurvePointQH); if (curvePointsQE != null) { _seriesCurvePointQE = new DevExpress.XtraCharts.Series(); _seriesCurvePointQE.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; _seriesCurvePointQE.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; _seriesCurvePointQE.Name = _tagQE + "CurvePoint"; _seriesCurvePointQE.ShowInLegend = false; _seriesCurvePointQE.CrosshairEnabled = DefaultBoolean.False; _seriesCurvePointQE.LabelsVisibility = DefaultBoolean.True; var seriesCurveQEView = new DevExpress.XtraCharts.PointSeriesView(); seriesCurveQEView.Color = CurveChartDisplay.PointColorQE; seriesCurveQEView.AxisY = _axisYQE; seriesCurveQEView.Pane = _paneQE; _seriesCurvePointQE.SeriesPointsSorting = SortingMode.None; _seriesCurvePointQE.SeriesPointsSortingKey = SeriesPointKey.Value_1; _seriesCurvePointQE.View = seriesCurveQEView; _seriesCurvePointQE.Visible = _curveQEVisible; for (int i = 0; i < curvePointsQE.Count; i++) { _seriesCurvePointQE.Points.Add(new SeriesPoint(curvePointsQE[i].X, new double[] { curvePointsQE[i].Y })); } this.chartControl1.Series.Add(_seriesCurvePointQE); } if (curvePointsQP != null) { _seriesCurvePointQP = new DevExpress.XtraCharts.Series(); _seriesCurvePointQP.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; _seriesCurvePointQP.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; _seriesCurvePointQP.Name = _tagQP + "CurvePoint"; _seriesCurvePointQP.ShowInLegend = false; _seriesCurvePointQP.CrosshairEnabled = DefaultBoolean.False; _seriesCurvePointQP.LabelsVisibility = DefaultBoolean.True; var seriesCurveQPView = new DevExpress.XtraCharts.PointSeriesView(); seriesCurveQPView.Color = CurveChartDisplay.PointColorQP; seriesCurveQPView.AxisY = _axisYQP; seriesCurveQPView.Pane = _paneQP; _seriesCurvePointQP.SeriesPointsSorting = SortingMode.None; _seriesCurvePointQP.SeriesPointsSortingKey = SeriesPointKey.Value_1; _seriesCurvePointQP.View = seriesCurveQPView; _seriesCurvePointQP.Visible = _curveQPVisible; for (int i = 0; i < curvePointsQP.Count; i++) { _seriesCurvePointQP.Points.Add(new SeriesPoint(curvePointsQP[i].X, new double[] { curvePointsQP[i].Y })); } this.chartControl1.Series.Add(_seriesCurvePointQP); } this.chartControl1.EndInit(); } public void SetPointSeries(bool show, bool showLabel) { if (_seriesCurvePointQH == null || _seriesCurvePointQE == null || _seriesCurvePointQP == null) { return; } var labelsVisibility = showLabel ? DefaultBoolean.True : DefaultBoolean.False; _seriesCurvePointQH.Visible = show; _seriesCurvePointQH.LabelsVisibility = labelsVisibility; if (_seriesCurvePointQE != null) { _seriesCurvePointQE.Visible = show; _seriesCurvePointQE.LabelsVisibility = labelsVisibility; } if (_seriesCurvePointQP != null) { _seriesCurvePointQP.Visible = show; _seriesCurvePointQP.LabelsVisibility = labelsVisibility; } } #endregion #region ChartEvent // 右键对象 private object _rightClickObj = null; private bool _onMoveWorkPointLine = 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.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); } } private void chartControl1_MouseUp(object sender, MouseEventArgs e) { if (!_initialData) return; _onMoveWorkPointLine = 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 (_allCurves == null || !_allCurves.Any()) return; var dlg = new AxisValueDlg(); dlg.SetBindingData(); dlg.VerifyValueChanged += (value) => { if (value < _minQ || value > _maxQ) return false; CalcWorkPointByQ(value); return true; }; dlg.ShowDialog(); } private void barCekLineVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetLineVisible(this.barCekLineVisible.Checked); } private void barCekCurveNameVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetCurveNameVisible(this.barCekCurveNameVisible.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 barBtnSetChartAxis_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetChartAxis(); } private void barCekCurveQHVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _paneQH.Visibility = _paneQH.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible; } private void barCekCurveQEVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _paneQE.Visibility = _paneQE.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible; } private void barCekCurveQPVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _paneQP.Visibility = _paneQP.Visibility == ChartElementVisibility.Visible ? ChartElementVisibility.Hidden : ChartElementVisibility.Visible; } #endregion /// /// 设置工作点显示 /// public void SetLineVisible(bool visible) { if (!_initialData) return; _lineVisible = visible; CalcWorkPointByQ(); } /// /// 设置曲线名 /// public void SetCurveNameVisible(bool visible) { if (!_initialData) return; _curveNameVisible = visible; for (int i = 1; i < this.chartControl1.AnnotationRepository.Count; i++) { var anno = this.chartControl1.AnnotationRepository[i]; anno.Visible = _curveNameVisible; } } /// /// 设置图例显示 /// 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 SetChartAxis() { var dlg = new ChartCoordinateDlg(); dlg.SetBindingData(_coordinateParas); dlg.OnChangedCoord += (rhs) => { _coordinateParas = rhs; CalcChartAxis(); this.OnCurveCoordinateParasChanged?.Invoke(_coordinateParas); }; dlg.ShowDialog(); } #endregion #region Get /// /// 获取曲线列表 /// /// public void GetCurves(out List featCurveExpressGroups) { featCurveExpressGroups = null; if (_allCurves == null || !_allCurves.Any()) return; var list = new List(); foreach (var item in _allCurves) { if (item.ID == -1) continue; var group = new Model.FeatCurveExpressGroup(); group.CurveQH = item.CurveExpressQH; group.CurveQE = item.CurveExpressQE; group.CurveQP = item.CurveExpressQP; list.Add(group); } featCurveExpressGroups = list; } #endregion } }