using DevExpress.Utils; using DevExpress.XtraCharts; namespace Yw.WinFrmUI.Phart { /// /// 泵运行视图图表 /// public partial class PumpRunViewChart : DevExpress.XtraEditors.XtraUserControl { public PumpRunViewChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; this.chartControl1.SelectionMode = ElementSelectionMode.Extended; this.chartControl1.SeriesSelectionMode = SeriesSelectionMode.Point; } #region Private Variable private readonly string _tag_qh = "QH", _tag_qe = "QE", _tag_qp = "QP"; private XYDiagram _diagram; private XYDiagramDefaultPane _default_pane; private XYDiagramPane _bottom_pane; private AxisX _axis_x_flow; private AxisY _axis_y_head; private SecondaryAxisY _axis_y_eff, _axis_y_power; private PumpCoordinate _coordinate; private bool _eff_visible = true; private bool _power_visible = true; private bool _run_point_visible = true; private bool _initial_data = false; private PumpRunViewViewModel _vm = null; private Yw.Ahart.eFeatType _feat_type_qh = Yw.Ahart.eFeatType.Cubic; private Yw.Ahart.eFeatType _feat_type_qe = Yw.Ahart.eFeatType.Cubic; private Yw.Ahart.eFeatType _feat_type_qp = Yw.Ahart.eFeatType.Cubic; #endregion #region Public Variable /// /// 扬程线拟合方式 /// public Yw.Ahart.eFeatType QHFeatType { get => _feat_type_qh; set { _feat_type_qh = value; UpdateChart(); } } /// /// 效率线拟合方式 /// public Yw.Ahart.eFeatType QEFeatType { get => _feat_type_qe; set { _feat_type_qe = value; UpdateChart(); } } /// /// 功率线拟合方式 /// public Yw.Ahart.eFeatType QPFeatType { get => _feat_type_qp; set { _feat_type_qp = value; UpdateChart(); } } /// /// 效率显示 /// public bool QEVisible { get => _eff_visible; set { _eff_visible = value; SetQEVisible(_eff_visible); } } /// /// 功率显示 /// public bool QPVisble { get => _power_visible; set { _power_visible = value; SetQPVisible(_power_visible); } } /// /// 运行点显示 /// public bool RunPointVisible { get => _run_point_visible; set { _run_point_visible = value; } } #endregion #region Public Evnet /// /// 坐标变换事件 /// public event Action CoordinateChangedEvent = null; /// /// 运行点选择事件 /// public event Action RunPointSelectedEvent = null; #endregion #region Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Direction = DevExpress.XtraCharts.LegendDirection.TopToBottom; _diagram = (XYDiagram)this.chartControl1.Diagram; _default_pane = _diagram.DefaultPane; _bottom_pane = (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_eff.Alignment = AxisAlignment.Far; _axis_y_power = _diagram.SecondaryAxesY.GetAxisByName("AxisYQP"); _axis_y_power.SetSecondaryAxisYQPDisplay(); this.chartControl1.SetChartMonoColorDisplay(); _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; this.chartControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseDown); this.chartControl1.CustomPaint += ChartControl1_CustomPaint; } private List> _rect_list = new(); private Point? _rect_point = null; private void chartControl1_MouseDown(object sender, MouseEventArgs e) { if (!_initial_data) return; if (!_run_point_visible) return; if (_rect_list == null || !_rect_list.Any()) return; foreach (var rect in _rect_list) { if (rect.Item1.Contains(e.Location)) { _rect_point = new Point(rect.Item1.X + 5, rect.Item1.Y + 5); this.RunPointSelectedEvent?.Invoke(rect.Item3); break; } } } private void ChartControl1_CustomPaint(object sender, CustomPaintEventArgs e) { if (e is not DXCustomPaintEventArgs dx_args) return; if (_vm == null) return; _rect_list.Clear(); if (_vm.Items != null && _vm.Items.Any() && _run_point_visible) { foreach (var vm in _vm.Items) { var color = vm.Color; var flow = vm.Q; var head = vm.H; var eff = vm.E; var power = vm.P; { var dg_pt = _diagram.DiagramToPoint(flow, head, _axis_x_flow, _axis_y_head); var dg_x = dg_pt.Point.X - 5; var dg_y = dg_pt.Point.Y - 5; dx_args.Cache.FillEllipse(dg_x, dg_y, 10, 10, color); _rect_list.Add(new(new Rectangle(dg_x, dg_y, 10, 10), color, vm)); } if (eff.HasValue && _eff_visible) { var dg_pt = _diagram.DiagramToPoint(flow, eff.Value, _axis_x_flow, _axis_y_eff); var dg_x = dg_pt.Point.X - 5; var dg_y = dg_pt.Point.Y - 5; dx_args.Cache.FillEllipse(dg_x, dg_y, 10, 10, color); _rect_list.Add(new(new Rectangle(dg_x, dg_y, 10, 10), color, vm)); } if (power.HasValue && _power_visible) { var dg_pt = _diagram.DiagramToPoint(flow, power.Value, _axis_x_flow, _axis_y_power); var dg_x = dg_pt.Point.X - 5; var dg_y = dg_pt.Point.Y - 5; dx_args.Cache.FillEllipse(dg_x, dg_y, 10, 10, color); _rect_list.Add(new(new Rectangle(dg_x, dg_y, 10, 10), color, vm)); } } if (_rect_point.HasValue) { var x = _rect_point.Value.X; var y = _rect_point.Value.Y; var length = 20; using Pen pen = new Pen(Color.Magenta, 2); dx_args.Cache.DrawLine(pen, new Point(x - length, y), new Point(x + length, y)); dx_args.Cache.DrawLine(pen, new Point(x, y - length), new Point(x, y + length)); dx_args.Cache.DrawEllipse(pen, new Rectangle(x - 10, y - 10, length, length)); } } } /// /// 初始化图表数据 /// public void InitialChartData() { _initial_data = false; _coordinate = null; UpdateChart(false); } #endregion #region Set /// /// 绑定数据 /// public void SetBindingData(PumpRunViewViewModel vm) { _vm = vm; _initial_data = vm != null; UpdateChart(true); } /// /// 清空曲线 /// public void Clear() { _vm = null; _initial_data = false; UpdateChart(true); } /// /// 更新图表 /// public void UpdateChart(bool calc_coordinate = false) { _rect_point = null; _rect_list = new(); if (calc_coordinate || _coordinate == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcSeries(); CalcChartAxis(); } #endregion #region Calc private double _min_flow, _max_flow; private double _max_head = 0, _min_head = 10000; private double _max_eff = 0, _min_eff = 0; private double _max_power = 0, _min_power = 1000; /// /// 计算坐标 /// private void CalcCoordinate() { if (_vm == null) { //设置成白板坐标 _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; } _max_flow = 0; _min_flow = 10000; _max_head = 0; _min_head = 10000; _max_eff = 0; _min_eff = 0; _max_power = 0; _min_power = 1000; double _scaleMinH = 1, _scaleMaxH = 1; { var qh_pt_list = _vm.CurveQH.GetPointList(_feat_type_qh); var xxx = qh_pt_list.Select(x => x.X); var yyy = qh_pt_list.Select(x => x.Y); _min_flow = Math.Min(_min_flow, xxx.Min()); _max_flow = Math.Max(_max_flow, xxx.Max()); _min_head = Math.Min(_min_head, yyy.Min()); _max_head = Math.Max(_max_head, yyy.Max()); } if (_vm.CurveQE != null) { var yyy = _vm.CurveQE.GetYList(_feat_type_qe); _min_eff = Math.Min(_min_eff, yyy.Min()); _max_eff = Math.Max(_max_eff, yyy.Max()); } if (_vm.CurveQP != null) { var yyy = _vm.CurveQP.GetYList(_feat_type_qp); _min_power = Math.Min(_min_power, yyy.Min()); _max_power = Math.Max(_max_power, yyy.Max()); } if (_vm.Items != null && _vm.Items.Any()) { foreach (var vm in _vm.Items) { var qh_pt_list = vm.CurveQH.GetPointList(_feat_type_qh); if (vm.Q <= 0) { continue; } var max_ratio = vm.Q / qh_pt_list.Max(x => x.X); if (max_ratio > 1) { var qh_pt_list_ex = qh_pt_list.GetExpandPointList(_feat_type_qh, 1, max_ratio); if (qh_pt_list_ex == null || !qh_pt_list_ex.Any()) { continue; } qh_pt_list = qh_pt_list_ex; } { var xxx = qh_pt_list.Select(x => x.X); var yyy = qh_pt_list.Select(x => x.Y); _min_flow = Math.Min(_min_flow, xxx.Min()); _max_flow = Math.Max(_max_flow, xxx.Max()); _min_head = Math.Min(_min_head, yyy.Min()); _max_head = Math.Max(_max_head, yyy.Max()); } if (vm.CurveQE != null) { var qe_pt_list = vm.CurveQE.GetExpandPointList(_feat_type_qe, 1, max_ratio); if (qe_pt_list == null || !qe_pt_list.Any()) { continue; } var yyy = qe_pt_list.Select(x => x.Y); _min_eff = Math.Min(_min_eff, yyy.Min()); _max_eff = Math.Max(_max_eff, yyy.Max()); } if (vm.CurveQP != null) { var qp_pt_list = vm.CurveQP.GetExpandPointList(_feat_type_qp, 1, max_ratio); var yyy = qp_pt_list.Select(x => x.Y); _min_power = Math.Min(_min_power, yyy.Min()); _max_power = Math.Max(_max_power, yyy.Max()); } } } _coordinate = PumpCoordinate.CalcCoordinate(_min_flow, _max_flow, _min_head * _scaleMinH, _max_head * _scaleMaxH, _min_eff, _max_eff, _min_power, _max_power); if (_coordinate == null) return; if (_coordinate.CoordMinQ + _coordinate.CoordSpaceQ * this._coordinate.GridNumberX < _max_flow * 1.05) { _coordinate.GridNumberX++; } } /// /// 计算图表轴 /// private void CalcChartAxis() { _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; _bottom_pane.Visibility = ChartElementVisibility.Hidden; _bottom_pane.Visibility = _power_visible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; //计算刻度 Q var axisQLabels = new List(); var disQ = _coordinate.CoordMinQ; for (int i = 0; i < _coordinate.GridNumberX + 1; i++) { axisQLabels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinate.CoordSpaceQ; } _axis_x_flow.CustomLabels.Clear(); _axis_x_flow.CustomLabels.AddRange(axisQLabels.ToArray()); _axis_x_flow.Visibility = DefaultBoolean.True; _axis_x_flow.GridLines.Visible = true; //计算刻度 var axis_head_labels = new List(); var display_head = _coordinate.CoordMinH + _coordinate.CoordSpaceH * _coordinate.StartLineNoH; for (int i = _coordinate.StartLineNoH; i < _coordinate.EndLineNoH + 1; i++) { axis_head_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(axis_head_labels.ToArray()); _axis_y_head.Visibility = DefaultBoolean.True; _axis_y_head.GridLines.Visible = true; //效率 if (_max_eff > _min_eff && _eff_visible) { //计算刻度 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 (_max_power > _min_power && _power_visible) { //计算刻度 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; } var min_flow = _coordinate.CoordMinQ; var max_flow = _coordinate.DispMaxQ(); _axis_x_flow.SetAxisRange(min_flow, max_flow); var grid_count_head = _coordinate.EndLineNoH - _coordinate.StartLineNoH; var grid_count_eff = _coordinate.EndLineNoE - _coordinate.StartLineNoE; int grid_count_up = Math.Max(grid_count_head, grid_count_eff); if (_eff_visible) { grid_count_up += 2;//多两条 } var max_axis_head = _coordinate.CoordMinH + _coordinate.EndLineNoH * _coordinate.CoordSpaceH; var min_axis_head = max_axis_head - grid_count_up * _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_up * _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); } /// /// 计算系列 /// private void CalcSeries() { this.chartControl1.BeginInit(); this.chartControl1.Series.Clear(); this.chartControl1.AnnotationRepository.Clear(); this.chartControl1.Legend.CustomItems.Clear(); if (_vm != null) { if (_vm.Items == null || !_vm.Items.Any()) { CreateLineSeries(_vm.Id, _vm.Color, _vm.Name, _vm.CurveQH, _vm.CurveQE, _vm.CurveQP); } else { if (_vm.Items != null && _vm.Items.Any()) { if (_vm.Items[0].Hz != 50) CreateLineSeries(_vm.Id, _vm.Color, _vm.Name, _vm.CurveQH, _vm.CurveQE, _vm.CurveQP); for (int i = 0; i < _vm.Items.Count; i++) { var vm = _vm.Items[i]; var qh = vm.CurveQH.GetFeatCurve(_feat_type_qh); if (qh.IsInvalid()) continue; var max_pt = qh.GetPointList().LastOrDefault(); Yw.Geometry.Point2d run_pt = new Geometry.Point2d(vm.Q, vm.H); CreateCurrentLineSeries(vm.Id, vm.Color, vm.CurveName, vm.CurveQH, vm.CurveQE, vm.CurveQP, run_pt); if (max_pt.X < vm.Q) { var max_ratio = vm.Q / max_pt.X * 1.05; var qh_pt_ex_list = qh.GetPointListByXRatioRange(1, max_ratio, 100); qh_pt_ex_list = qh_pt_ex_list.Where(x => x.X >= max_pt.X).ToList(); qh_pt_ex_list.Add(max_pt); CreateLineSeries(vm.Id + "qh", vm.Color, qh_pt_ex_list, _default_pane, _axis_y_head, DashStyle.Dot); if (vm.CurveQE != null && vm.CurveQE.Any() && _eff_visible) { var qe = vm.CurveQE.GetFeatCurve(_feat_type_qe); var qe_pt_ex_list = vm.CurveQE.GetExpandPointList(_feat_type_qe, 1, max_ratio, 100); qe_pt_ex_list = qe_pt_ex_list.Where(x => x.X >= max_pt.X * 0.8).ToList(); CreateLineSeries(vm.Id + "qe", vm.Color, qe_pt_ex_list, _default_pane, _axis_y_eff, DashStyle.Dot); } if (vm.CurveQP != null && vm.CurveQP.Any() && _power_visible) { var qp = vm.CurveQP.GetFeatCurve(_feat_type_qp); var qp_pt_ex_list = vm.CurveQP.GetExpandPointList(_feat_type_qp, 1, max_ratio, 100); qp_pt_ex_list = qp_pt_ex_list.Where(x => x.X >= max_pt.X * 0.8).ToList(); CreateLineSeries(vm.Id + "qp", vm.Color, qp_pt_ex_list, _bottom_pane, _axis_y_power, DashStyle.Dot); } } } } } } this.chartControl1.EndInit(); } /// /// 创建线系列 /// private void CreateLineSeries(string id, Color color, string curve_name, List qh, List qe, List qp, Yw.Geometry.Point2d run_pt = null) { var series_qh = new DevExpress.XtraCharts.Series(); series_qh.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qh.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qh.Name = _tag_qh + id; series_qh.ShowInLegend = false; series_qh.CrosshairEnabled = DefaultBoolean.False; series_qh.LegendTextPattern = curve_name; var series_qh_view = new DevExpress.XtraCharts.LineSeriesView(); series_qh_view.LineStyle.Thickness = 2; series_qh_view.LineStyle.DashStyle = DashStyle.Dash; series_qh_view.LineStyle.LineJoin = System.Drawing.Drawing2D.LineJoin.MiterClipped; series_qh_view.Color = color; series_qh_view.EnableAntialiasing = DefaultBoolean.True; series_qh.SeriesPointsSorting = SortingMode.None; series_qh.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qh.View = series_qh_view; series_qh.Visible = true; var pt_qh_list = qh.GetPointList(_feat_type_qh, 100); for (int i = 0; i < pt_qh_list.Count; i++) { series_qh.Points.Add(new SeriesPoint(pt_qh_list[i].X, new double[] { pt_qh_list[i].Y })); } var point_qh = pt_qh_list[pt_qh_list.Count - 1]; var anchor_qh_pt = new DevExpress.XtraCharts.PaneAnchorPoint(); anchor_qh_pt.Pane = _default_pane; if (run_pt != null) { anchor_qh_pt.AxisXCoordinate.AxisValue = run_pt.X.ToString(); anchor_qh_pt.AxisYCoordinate.AxisValue = run_pt.Y.ToString(); } else { anchor_qh_pt.AxisXCoordinate.AxisValue = point_qh.X.ToString(); anchor_qh_pt.AxisYCoordinate.AxisValue = point_qh.Y.ToString(); } var position_qh = new DevExpress.XtraCharts.RelativePosition(); position_qh.Angle = -50; position_qh.ConnectorLength = 10; var txt_qh = new TextAnnotation(); txt_qh.Border.Visibility = DefaultBoolean.False; txt_qh.AnchorPoint = anchor_qh_pt; txt_qh.AutoHeight = true; txt_qh.AutoWidth = true; txt_qh.BackColor = System.Drawing.Color.Transparent; txt_qh.Border.Color = color; txt_qh.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.Line; txt_qh.DXFont = PumpChartDisplay.AnnoFontQH; txt_qh.Name = _tag_qh + id; txt_qh.Padding.Bottom = 1; txt_qh.Padding.Left = 1; txt_qh.Padding.Right = 1; txt_qh.Padding.Top = 1; txt_qh.RuntimeAnchoring = false; txt_qh.RuntimeMoving = true; txt_qh.RuntimeResizing = false; txt_qh.RuntimeRotation = false; txt_qh.Text = curve_name; txt_qh.TextColor = color; txt_qh.ShapePosition = position_qh; txt_qh.Visible = true; this.chartControl1.AnnotationRepository.Add(txt_qh); this.chartControl1.Series.Add(series_qh); if (qe != null) { var series_qe = new DevExpress.XtraCharts.Series(); series_qe.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qe.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qe.Name = _tag_qe + id; series_qe.ShowInLegend = false; series_qe.CrosshairEnabled = DefaultBoolean.False; series_qe.Tag = id; var series_qe_view = new DevExpress.XtraCharts.LineSeriesView(); series_qe_view.LineStyle.Thickness = 2; series_qe_view.LineStyle.DashStyle = DashStyle.Dash; series_qe_view.LineStyle.LineJoin = System.Drawing.Drawing2D.LineJoin.MiterClipped; series_qe_view.Color = color; series_qe_view.AxisY = _axis_y_eff; series_qe_view.Pane = _default_pane; series_qe_view.EnableAntialiasing = DefaultBoolean.True; series_qe.SeriesPointsSorting = SortingMode.None; series_qe.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qe.View = series_qe_view; series_qe.Visible = _eff_visible; var pt_qe_list = qe.GetPointList(_feat_type_qe, 100); for (int i = 0; i < pt_qe_list.Count; i++) { series_qe.Points.Add(new SeriesPoint(pt_qe_list[i].X, new double[] { pt_qe_list[i].Y })); } this.chartControl1.Series.Add(series_qe); } if (qp != null) { var series_qp = new DevExpress.XtraCharts.Series(); series_qp.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qp.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qp.Name = _tag_qp + id; series_qp.ShowInLegend = false; series_qp.CrosshairEnabled = DefaultBoolean.False; series_qp.Tag = id; var series_qp_view = new DevExpress.XtraCharts.LineSeriesView(); series_qp_view.LineStyle.Thickness = 2; series_qp_view.LineStyle.DashStyle = DashStyle.Dash; series_qp_view.LineStyle.LineJoin = System.Drawing.Drawing2D.LineJoin.MiterClipped; series_qp_view.Color = color; series_qp_view.AxisY = _axis_y_power; series_qp_view.Pane = _bottom_pane; series_qp_view.EnableAntialiasing = DefaultBoolean.True; series_qp.SeriesPointsSorting = SortingMode.None; series_qp.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qp.View = series_qp_view; series_qp.Visible = _power_visible; var pt_qp_list = qp.GetPointList(_feat_type_qp, 100); for (int i = 0; i < pt_qp_list.Count; i++) { series_qp.Points.Add(new SeriesPoint(pt_qp_list[i].X, new double[] { pt_qp_list[i].Y })); } this.chartControl1.Series.Add(series_qp); } } /// /// 创建线系列 /// private void CreateCurrentLineSeries(string id, Color color, string curve_name, List qh, List qe, List qp, Yw.Geometry.Point2d run_pt = null) { var series_qh = new DevExpress.XtraCharts.Series(); series_qh.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qh.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qh.Name = _tag_qh + id; series_qh.ShowInLegend = false; series_qh.CrosshairEnabled = DefaultBoolean.False; series_qh.LegendTextPattern = curve_name; var series_qh_view = new DevExpress.XtraCharts.SplineSeriesView(); series_qh_view.LineStyle.Thickness = 2; series_qh_view.Color = color; series_qh_view.EnableAntialiasing = DefaultBoolean.True; series_qh_view.LineTensionPercent = 50; series_qh.SeriesPointsSorting = SortingMode.None; series_qh.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qh.View = series_qh_view; series_qh.Visible = true; var pt_qh_list = qh.GetPointList(_feat_type_qh, 100); for (int i = 0; i < pt_qh_list.Count; i++) { series_qh.Points.Add(new SeriesPoint(pt_qh_list[i].X, new double[] { pt_qh_list[i].Y })); } var point_qh = pt_qh_list[pt_qh_list.Count() - 1]; var anchor_qh_pt = new DevExpress.XtraCharts.PaneAnchorPoint(); anchor_qh_pt.Pane = _default_pane; if (run_pt != null) { anchor_qh_pt.AxisXCoordinate.AxisValue = run_pt.X.ToString(); anchor_qh_pt.AxisYCoordinate.AxisValue = run_pt.Y.ToString(); } else { anchor_qh_pt.AxisXCoordinate.AxisValue = point_qh.X.ToString(); anchor_qh_pt.AxisYCoordinate.AxisValue = point_qh.Y.ToString(); } var position_qh = new DevExpress.XtraCharts.RelativePosition(); position_qh.Angle = -50; position_qh.ConnectorLength = 10; var txt_qh = new TextAnnotation(); txt_qh.Border.Visibility = DefaultBoolean.False; txt_qh.AnchorPoint = anchor_qh_pt; txt_qh.AutoHeight = true; txt_qh.AutoWidth = true; txt_qh.BackColor = System.Drawing.Color.Transparent; txt_qh.Border.Color = color; txt_qh.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.Line; txt_qh.DXFont = PumpChartDisplay.AnnoFontQH; txt_qh.Name = _tag_qh + id; txt_qh.Padding.Bottom = 1; txt_qh.Padding.Left = 1; txt_qh.Padding.Right = 1; txt_qh.Padding.Top = 1; txt_qh.RuntimeAnchoring = false; txt_qh.RuntimeMoving = true; txt_qh.RuntimeResizing = false; txt_qh.RuntimeRotation = false; txt_qh.Text = curve_name; txt_qh.TextColor = color; txt_qh.ShapePosition = position_qh; txt_qh.Visible = true; this.chartControl1.AnnotationRepository.Add(txt_qh); this.chartControl1.Series.Add(series_qh); if (qe != null) { var series_qe = new DevExpress.XtraCharts.Series(); series_qe.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qe.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qe.Name = _tag_qe + id; series_qe.ShowInLegend = false; series_qe.CrosshairEnabled = DefaultBoolean.False; series_qe.Tag = id; var series_qe_view = new DevExpress.XtraCharts.SplineSeriesView(); series_qe_view.LineStyle.Thickness = 2; series_qe_view.Color = color; series_qe_view.AxisY = _axis_y_eff; series_qe_view.Pane = _default_pane; series_qe_view.EnableAntialiasing = DefaultBoolean.True; series_qe_view.LineTensionPercent = 50; series_qe.SeriesPointsSorting = SortingMode.None; series_qe.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qe.View = series_qe_view; series_qe.Visible = _eff_visible; var pt_qe_list = qe.GetPointList(_feat_type_qe, 100); for (int i = 0; i < pt_qe_list.Count; i++) { series_qe.Points.Add(new SeriesPoint(pt_qe_list[i].X, new double[] { pt_qe_list[i].Y })); } this.chartControl1.Series.Add(series_qe); } if (qp != null) { var series_qp = new DevExpress.XtraCharts.Series(); series_qp.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series_qp.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series_qp.Name = _tag_qp + id; series_qp.ShowInLegend = false; series_qp.CrosshairEnabled = DefaultBoolean.False; series_qp.Tag = id; var series_qp_view = new DevExpress.XtraCharts.SplineSeriesView(); series_qp_view.LineStyle.Thickness = 2; series_qp_view.Color = color; series_qp_view.AxisY = _axis_y_power; series_qp_view.Pane = _bottom_pane; series_qp_view.EnableAntialiasing = DefaultBoolean.True; series_qp_view.LineTensionPercent = 50; series_qp.SeriesPointsSorting = SortingMode.None; series_qp.SeriesPointsSortingKey = SeriesPointKey.Value_1; series_qp.View = series_qp_view; series_qp.Visible = _power_visible; var pt_qp_list = qp.GetPointList(_feat_type_qp, 100); for (int i = 0; i < pt_qp_list.Count; i++) { series_qp.Points.Add(new SeriesPoint(pt_qp_list[i].X, new double[] { pt_qp_list[i].Y })); } this.chartControl1.Series.Add(series_qp); } } /// /// 创建线系列 /// private void CreateLineSeries(string id, Color color, List pt_list, XYDiagramPaneBase pane, AxisYBase axiy, DashStyle dash = DashStyle.Solid) { var series = new DevExpress.XtraCharts.Series(); series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical; series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False; series.Name = id; series.ShowInLegend = false; series.CrosshairEnabled = DefaultBoolean.False; var series_view = new DevExpress.XtraCharts.LineSeriesView(); series_view.LineStyle.Thickness = 2; series_view.Color = color; series_view.EnableAntialiasing = DefaultBoolean.True; series_view.LineStyle.DashStyle = dash; series_view.Pane = pane; series_view.AxisY = axiy; series.SeriesPointsSorting = SortingMode.None; series.SeriesPointsSortingKey = SeriesPointKey.Value_1; series.View = series_view; series.Visible = true; for (int i = 0; i < pt_list.Count; i++) { series.Points.Add(new SeriesPoint(pt_list[i].X, new double[] { pt_list[i].Y })); } this.chartControl1.Series.Add(series); } #endregion #region Right Click Menu /// /// 设置坐标轴 /// public void SetChartAxis() { var dlg = new PumpChartCoordinateDlg(); dlg.SetBindingData(_coordinate); dlg.OnChangedCoord += (rhs) => { _coordinate = rhs; CalcChartAxis(); this.CoordinateChangedEvent?.Invoke(_coordinate); }; dlg.ShowDialog(); } /// /// 设置运行点显示 /// public void SetEQVisible(bool visible) { _run_point_visible = visible; } /// /// 设置效率显示 /// public void SetQEVisible(bool visible) { _eff_visible = visible; UpdateChart(); } /// /// 设置功率显示 /// public void SetQPVisible(bool visible) { _power_visible = visible; _bottom_pane.Visibility = _power_visible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden; UpdateChart(); } /// /// 导出图片 /// public void ExportToImage(string filePath) { this.chartControl1.ExportToImage(filePath, DevExpress.Drawing.DXImageFormat.Png); } #endregion } }