Shuxia Ning
2024-12-20 1bf6b7a300e21e9b8996f9ebeeb55a1eccda7a02
WinFrmUI/Yw.WinFrmUI.Phart.Core/01-pump/00-/PumpChart.cs
@@ -1,7 +1,5 @@
using DevExpress.Utils;
using DevExpress.XtraCharts;
using SqlSugar;
using System.Text;
namespace Yw.WinFrmUI.Phart
{
@@ -14,7 +12,15 @@
        {
            InitializeComponent();
            InitialChart();
            this.chartControl1.RuntimeHitTesting = true;
            this.chartControl1.AnimationStartMode = ChartAnimationMode.OnLoad;
            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;
        }
        #region Private Variable 
@@ -30,21 +36,19 @@
        private ConstantLine _const_line_x;
        private ConstantLine _const_line_y;
        private TextAnnotation _const_txt_annotation; 
        //private bool _eff_visible = true;
        //private bool _power_visible = true;
        //private bool _equip_visible = true;
        //private bool _equivalent_eff_visible = true;
        //private bool _equivalent_power_visible = true;
        private bool _initial_data = false;
        private PumpCoordinate _coordinate = null;
        private PumpChartViewModel _vm = null;
        private XYDiagramPaneBase _bottom_pane_use;
        private PumpChartViewModel _vm = null;
        private bool _default_visible = false;
        private bool _power_visible = false;
        private bool _eff_visible = false;
        private bool _split_panel = false;
        private bool _initial_data = false;
        /// <summary>
        /// 初始化图表
        /// </summary>
@@ -81,46 +85,211 @@
            _axis_y_power.Visibility = DefaultBoolean.False;
            _axis_y_power.GridLines.Visible = false;
            _const_line_x.Visible = false;
            _const_line_x.Visible = false;
            _const_line_y.Visible = false;
        }
        /// <summary>
        /// 初始化坐标轴
        /// </summary>
        private void InitialCoordinate()
        {
            //设置成白板坐标
            _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; 
        }
        #endregion
        #region  Set
        #region Chart Event
        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;
                }
            }
        }
        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)
        {
        }
        private void ChartControl1_CustomPaint(object sender, CustomPaintEventArgs e)
        {
        }
        #endregion
        #region  Set
        /// <summary>
        /// 设置图表
        /// </summary>
        private void SetChart(PumpChartViewModel vm, bool rated_curve_show = true, bool split_panel = false)
        public void SetChart(PumpChartViewModel vm, bool default_visible = true, bool split_panel = false, bool eff_visible = false, bool power_visible = true)
        {
            _vm = vm;
            _default_visible = default_visible;
            _split_panel = split_panel;
            //_split_panel = true;
            _eff_visible = eff_visible;
            _eff_visible = true;
            _power_visible = power_visible;
            _power_visible = true;
            this.chartControl1.BeginInit();
            this.chartControl1.Series.Clear();
            this.chartControl1.AnnotationRepository.Clear();
            this.chartControl1.Legend.CustomItems.Clear();
            if (vm == null)
            {
                _initial_data = false;
                this.chartControl1.EndInit();
                return;
            }
            _bottom_pane_use = split_panel ? _default_pane : _bottom_pane;
            if (rated_curve_show)
                AddRated(vm);
            if (default_visible)
                AddDefault(vm);
            AddEquip(vm.Equip);
            AddVariableSpeedList(vm.VariableSpeedList);
            AddEquivEffList(vm.EquivEffList);
            AddEquivPowerList(vm.EquivPowerList);
            AddEqualEffList(vm.EqualEffList);
            AddEqualPowerList(vm.EqualPowerList);
            if (vm.Coordinate == null)
            {
                SetCoordinate();
            }
            else
            {
                _coordinate = vm.Coordinate;
            }
            SetChartAxis();
            this.chartControl1.EndInit();
            _initial_data = true;
        }
        private void AddRated(PumpChartViewModel vm)
        #region Add Data
        private void AddDefault(PumpChartViewModel vm)
        {
            var id = vm.Id;
            var caption_qh = vm.CurveQHName;
@@ -133,25 +302,27 @@
            var qe = vm.CurveQE;
            var qp = vm.CurveQP;
            AddLineSeries(id, color_qh, _axis_x_flow, _axis_y_head, qh);
            if (string.IsNullOrEmpty(caption_qh))
                AddAnnotation(id, caption_qh, color_qh, _default_pane, qh.Last());
            XYDiagramPaneBase bottom_pane = _split_panel ? _bottom_pane : _default_pane;
            if (qe != null && qe.Any())
            AddLineSeries(id, color_qh, _axis_x_flow, _axis_y_head, _default_pane, qh, DashStyle.Dash);
            if (!string.IsNullOrEmpty(caption_qh))
                AddAnnotation(id, caption_qh, color_qh, _axis_y_head, _default_pane, qh.Last());
            if (qe != null && qe.Any() && _eff_visible)
            {
                AddLineSeries(id, color_qe, _axis_x_flow, _axis_y_eff, qe);
                AddLineSeries(id, color_qe, _axis_x_flow, _axis_y_eff, _default_pane, qe, DashStyle.Dash);
            }
            if (qp != null && qp.Any())
            if (qp != null && qp.Any() && _power_visible)
            {
                AddLineSeries(id, color_qp, _axis_x_flow, _axis_y_power, qp);
                if (string.IsNullOrEmpty(caption_qp))
                AddLineSeries(id, color_qp, _axis_x_flow, _axis_y_power, bottom_pane, qp, DashStyle.Dash);
                if (!string.IsNullOrEmpty(caption_qp))
                {
                    AddAnnotation(id, caption_qp, color_qp, _bottom_pane_use, qp.Last());
                    AddAnnotation(id, caption_qp, color_qp, _axis_y_power, bottom_pane, qp.Last());
                }
            }
            }
        }
        private void AddEquip(PumpChartEquipViewModel vm)
        {
            if (vm == null)
@@ -163,17 +334,17 @@
            var equip = vm.CurveEquip;
            var equip_pt = new Yw.Geometry.Point2d(vm.PipeQ, vm.PipeH);
            AddLineSeries(id, color, _axis_x_flow, _axis_y_head, equip, DashStyle.DashDotDot);
            AddPointSeries(id, color, _axis_x_flow, _axis_y_head, new List<Geometry.Point2d>() { equip_pt });
            AddLineSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, equip, DashStyle.DashDotDot);
            AddPointSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, new List<Geometry.Point2d>() { equip_pt });
            if (!string.IsNullOrEmpty(caption))
                AddAnnotation(id, caption, color, _default_pane, equip.Last());
                AddAnnotation(id, caption, color, _axis_y_head, _default_pane, equip.Last());
        }
        private void AddVariableSpeedList(List<PumpChartVariableSpeedViewModel> vm_list)
        {
            if (vm_list == null || vm_list.Any())
            if (vm_list == null || !vm_list.Any())
                return;
            XYDiagramPaneBase bottom_pane = _split_panel ? _bottom_pane : _default_pane;
            foreach (var vm in vm_list)
            {
                if (!vm.IsValid())
@@ -190,30 +361,56 @@
                var qe = vm.CurveQE;
                var qp = vm.CurveQP;
                AddLineSeries(id, color_qh, _axis_x_flow, _axis_y_head, qh);
                if (string.IsNullOrEmpty(caption_qh))
                    AddAnnotation(id, caption_qh, color_qh, _default_pane, qh.Last());
                AddLineSeries(id, color_qh, _axis_x_flow, _axis_y_head, _default_pane, qh);
                if (!string.IsNullOrEmpty(caption_qh))
                    AddAnnotation(id, caption_qh, color_qh, _axis_y_head, _default_pane, qh.Last());
                if (qe != null && qe.Any())
                if (qe != null && qe.Any() && _eff_visible)
                {
                    AddLineSeries(id, color_qe, _axis_x_flow, _axis_y_eff, qe);
                    AddLineSeries(id, color_qe, _axis_x_flow, _axis_y_eff, _default_pane, qe);
                }
                if (qp != null && qp.Any())
                if (qp != null && qp.Any() && _power_visible)
                {
                    AddLineSeries(id, color_qp, _axis_x_flow, _axis_y_power, qp);
                    if (string.IsNullOrEmpty(caption_qp))
                    AddLineSeries(id, color_qp, _axis_x_flow, _axis_y_power, bottom_pane, qp);
                    if (!string.IsNullOrEmpty(caption_qp))
                    {
                        AddAnnotation(id, caption_qp, color_qp, _bottom_pane_use, qp.Last());
                        AddAnnotation(id, caption_qp, color_qp, _axis_y_power, bottom_pane, qp.Last());
                    }
                }
            }
        }
        }
        private void AddEquivEffList(List<PumpChartEquivEffViewModel> vm_list)
        private void AddEqualEffList(List<PumpChartEqualEffViewModel> vm_list)
        {
            if (vm_list == null || vm_list.Any())
            if (vm_list == null || !vm_list.Any())
                return;
            foreach (var vm in vm_list)
            {
                if (!vm.IsValid())
                    continue;
                var id = vm.Id;
                var caption = vm.CurveName;
                var color = vm.Color ?? Color.Green;
                var equif_eff = vm.CurveEqualEff;
                if (equif_eff.Count < 2)
                {
                    AddPointSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, equif_eff);
                }
                else
                {
                    AddLineSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, equif_eff, DashStyle.Dash);
                }
                if (!string.IsNullOrEmpty(caption))
                    AddAnnotation(id, caption, color, _axis_y_head, _default_pane, equif_eff.Last(), 60);
            }
        }
        private void AddEqualPowerList(List<PumpChartEqualPowerViewModel> vm_list)
        {
            if (vm_list == null || !vm_list.Any())
                return;
            foreach (var vm in vm_list)
@@ -224,50 +421,39 @@
                var id = vm.Id;
                var caption = vm.CurveName;
                var color = vm.Color ?? Color.Green;
                var equif_eff = vm.CurveEquivEff;
                AddLineSeries(id, color, _axis_x_flow, _axis_y_head, equif_eff);
                var equif_power = vm.CurveEqualPower;
                if (equif_power.Count < 2)
                {
                    AddPointSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, equif_power);
                }
                else
                {
                    AddLineSeries(id, color, _axis_x_flow, _axis_y_head, _default_pane, equif_power, DashStyle.Dash);
                }
                if (!string.IsNullOrEmpty(caption))
                    AddAnnotation(id, caption, color, _default_pane, equif_eff.Last());
                    AddAnnotation(id, caption, color, _axis_y_head, _default_pane, equif_power.Last());
            }
        }
        private void AddEquivPowerList(List<PumpChartEquivPowerViewModel> vm_list)
        {
            if (vm_list == null || vm_list.Any())
                return;
        #endregion
            foreach (var vm in vm_list)
            {
                if (!vm.IsValid())
                    continue;
        #region Add Chart Data
                var id = vm.Id;
                var caption = vm.CurveName;
                var color = vm.Color ?? Color.Green;
                var equif_eff = vm.CurveEquivPower;
                AddLineSeries(id, color, _axis_x_flow, _axis_y_head, equif_eff);
                if (!string.IsNullOrEmpty(caption))
                    AddAnnotation(id, caption, color, _default_pane, equif_eff.Last());
            }
        }
        private void AddPointSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, List<Yw.Geometry.Point2d> pt_list)
        private void AddPointSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list)
        {
            if (pt_list == null || !pt_list.Any())
                return;
            var view = new DevExpress.XtraCharts.PointSeriesView();
            view.PointMarkerOptions.Size = 10;
            view.PointMarkerOptions.Size = 8;
            view.PointMarkerOptions.Kind = MarkerKind.Circle;
            view.PointMarkerOptions.BorderColor = color;
            view.Color = color;
            view.AxisX = axis_x;
            view.AxisY = axis_y;
            view.EmptyPointOptions.Color = Color.Transparent;
            view.AxisY = axis_y;
            view.EmptyPointOptions.Color = Color.Transparent;
            view.Pane = pane;
            var series_pt_list = pt_list.Select(x => x.ToSeriesPoint()).ToArray();
            var series = new DevExpress.XtraCharts.Series();
@@ -276,14 +462,17 @@
            series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
            series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
            series.CrosshairEnabled = DefaultBoolean.False;
            series.CrosshairLabelVisibility = DefaultBoolean.False;
            series.ToolTipEnabled = DefaultBoolean.False;
            series.SeriesPointsSorting = SortingMode.None;
            series.Visible = true;
            series.View = view;
            series.CrosshairLabelPattern = "{A}";
            series.Points.AddRange(series_pt_list);
            this.chartControl1.Series.Add(series);
        }
        private void AddLineSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, List<Yw.Geometry.Point2d> pt_list, DashStyle dash= DashStyle.Solid)
        private void AddLineSeries(string id, Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list, DashStyle dash = DashStyle.Solid)
        {
            if (pt_list == null || !pt_list.Any())
                return;
@@ -298,6 +487,7 @@
            view.AxisX = axis_x;
            view.AxisY = axis_y;
            view.EmptyPointOptions.Color = Color.Transparent;
            view.Pane = pane;
            var series_pt_list = pt_list.Select(x => x.ToSeriesPoint()).ToArray();
            var series = new DevExpress.XtraCharts.Series();
@@ -306,28 +496,65 @@
            series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
            series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
            series.CrosshairEnabled = DefaultBoolean.False;
            series.ToolTipEnabled = DefaultBoolean.False;
            series.SeriesPointsSorting = SortingMode.None;
            series.Visible = true;
            series.View = view;
            series.Points.AddRange(series_pt_list);
            this.chartControl1.Series.Add(series);
        }
        private void AddAnnotation(string id, string caption, Color color, XYDiagramPaneBase pane, Yw.Geometry.Point2d pt)
        private void AddAnnotation(string id, string caption, Color color, AxisYBase axis_y, XYDiagramPaneBase pane, Yw.Geometry.Point2d pt, double angle = -10)
        {
            if (pt == null)
                return;
            var anchor_pt = pt;
            var pane_anchor_pt = new DevExpress.XtraCharts.PaneAnchorPoint();
            pane_anchor_pt.Pane = pane;
            pane_anchor_pt.AxisYCoordinate.Axis = axis_y;
            pane_anchor_pt.AxisXCoordinate.AxisValue = anchor_pt.X;
            pane_anchor_pt.AxisYCoordinate.AxisValue = anchor_pt.Y;
            var relative_position = new DevExpress.XtraCharts.RelativePosition();
            relative_position.Angle = -50;
            relative_position.ConnectorLength = 10;
            relative_position.Angle = angle;
            relative_position.ConnectorLength = 20;
            var text_annotation = new TextAnnotation();
            text_annotation.Border.Visibility = DefaultBoolean.False;
@@ -354,23 +581,10 @@
            this.chartControl1.AnnotationRepository.Add(text_annotation);
        }
        //private void SetAxis(PumpChartViewModel vm)
        //{
        //    double minQ, maxQ;
        //    double maxH = 0, minH = 10000;
        //    double maxE = 0, minE = 0;
        //    double maxP = 0, minP = 1000;
        //    if (vm == null)
        //    {
        //    }
        //}
        #endregion
        #endregion
        #region Calc
        #region Set Axis
        private double _minQ, _maxQ;
        private double _maxH = 0, _minH = 10000;
@@ -378,28 +592,18 @@
        private double _maxP = 0, _minP = 1000;
        /// <summary>
        /// 计算坐标
        /// 设置坐标
        /// </summary>
        private void CalcCoordinate()
        private void SetCoordinate()
        {
            if (_vm_list == null || !_vm_list.Any())
            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;
                InitialCoordinate();
                return;
            }
            if (_vm.CurveQH == null || !_vm.CurveQH.Any())
            {
                InitialCoordinate();
                return;
            }
@@ -408,118 +612,125 @@
            _maxE = 0; _minE = 0;
            _maxP = 0; _minP = 1000;
            double _scaleMinH = 1, _scaleMaxH = 1;
            var q_list_list = new List<List<double>>();
            var h_list_list = new List<List<double>>();
            var e_list_list = new List<List<double>>();
            var p_list_list = new List<List<double>>();
            foreach (var vm in _vm_list)
            if (_default_visible)
            {
                var qh_pt_list = vm.CurveQH.GetPointList();
                if (vm.CurrentCurveQH != null)
                    qh_pt_list.AddRange(vm.CurrentCurveQH.GetPointList());
                var xxx = qh_pt_list.Select(x => x.X);
                var yyy = qh_pt_list.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 (PumpChartViewModel vm in _vm_list)
            {
                var qe_pt_list = vm.CurveQE.GetPointList();
                if (vm.CurrentCurveQE != null)
                    qe_pt_list.AddRange(vm.CurrentCurveQE.GetPointList());
                var yyy = qe_pt_list.Select(x => x.Y);
                _minE = Math.Max(_minE, yyy.Min());
                _maxE = Math.Max(_maxE, yyy.Max());
            }
            foreach (PumpChartViewModel vm in _vm_list)
            {
                var qe_pt_list = vm.CurveQP.GetPointList();
                if (vm.CurrentCurveQP != null)
                    qe_pt_list.AddRange(vm.CurrentCurveQP.GetPointList());
                var yyy = qe_pt_list.Select(x => x.Y);
                _minP = Math.Min(_minP, yyy.Min());
                _maxP = Math.Max(_maxP, yyy.Max());
            }
            if (_vm != null)
            {
                {
                    var qh_pt_list = _vm.CurveQH.GetPointList();
                    var xxx = qh_pt_list.Select(x => x.X);
                    var yyy = qh_pt_list.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());
                }
                q_list_list.Add(_vm.CurveQH.Select(x => x.X).ToList());
                h_list_list.Add(_vm.CurveQH.Select(x => x.Y).ToList());
                if (_vm.CurveQE != null)
                {
                    var qe_pt_list = _vm.CurveQE.GetPointList();
                    var yyy = qe_pt_list.Select(x => x.Y);
                    _minE = Math.Max(_minE, yyy.Min());
                    _maxE = Math.Max(_maxE, yyy.Max());
                    e_list_list.Add(_vm.CurveQE.Select(x => x.Y).ToList());
                }
                if (_vm.CurveQP != null)
                {
                    var qp_pt_list = _vm.CurveQP.GetPointList();
                    var yyy = qp_pt_list.Select(x => x.Y);
                    _minP = Math.Min(_minP, yyy.Min());
                    _maxP = Math.Max(_maxP, yyy.Max());
                    p_list_list.Add(_vm.CurveQP.Select(x => x.Y).ToList());
                }
            }
            if (_vm.Equip != null)
            {
                var item = _vm.Equip;
                q_list_list.Add(item.CurveEquip.Select(x => x.X).ToList());
                h_list_list.Add(item.CurveEquip.Select(x => x.Y).ToList());
            }
            if (_vm.VariableSpeedList != null && _vm.VariableSpeedList.Any())
            {
                foreach (var item in _vm.VariableSpeedList)
                {
                    q_list_list.Add(item.CurveQH.Select(x => x.X).ToList());
                    h_list_list.Add(item.CurveQH.Select(x => x.Y).ToList());
                    if (item.CurveQE != null )
                    {
                        e_list_list.Add(item.CurveQE.Select(x => x.Y).ToList());
                    }
                    if (item.CurveQP != null )
                    {
                        p_list_list.Add(item.CurveQP.Select(x => x.Y).ToList());
                    }
                }
            }
            _coordinate = PumpCoordinate.CalcCoordinate(_minQ,
                                                                         _maxQ,
                                                                         _minH * _scaleMinH,
                                                                         _maxH * _scaleMaxH,
                                                                         _minE,
                                                                         _maxE,
                                                                         _minP,
                                                                         _maxP);
            if (_vm.EqualEffList != null && _vm.EqualEffList.Any())
            {
                foreach (var item in _vm.EqualEffList)
                {
                    q_list_list.Add(item.CurveEqualEff.Select(x => x.X).ToList());
                    h_list_list.Add(item.CurveEqualEff.Select(x => x.Y).ToList());
                }
            }
            if (_vm.EqualPowerList != null && _vm.EqualPowerList.Any())
            {
                foreach (var item in _vm.EqualPowerList)
                {
                    q_list_list.Add(item.CurveEqualPower.Select(x => x.X).ToList());
                    h_list_list.Add(item.CurveEqualPower.Select(x => x.Y).ToList());
                }
            }
            foreach (var list in q_list_list)
            {
                _minQ = Math.Min(_minQ, list.Min());
                _maxQ = Math.Max(_maxQ, list.Max());
            }
            foreach (var list in h_list_list)
            {
                _minH = Math.Min(_minH, list.Min());
                _maxH = Math.Max(_maxH, list.Max());
            }
            foreach (var list in e_list_list)
            {
                _minE = Math.Max(_minE, list.Min());
                _maxE = Math.Max(_maxE, list.Max());
            }
            foreach (var list in p_list_list)
            {
                _minP = Math.Min(_minP, list.Min());
                _maxP = Math.Max(_maxP, list.Max());
            }
            _coordinate = PumpCoordinate.CalcCoordinate(_minQ, _maxQ, _minH, _maxH, _minE, _maxE, _minP, _maxP);
            if (_coordinate == null)
                return;
            if (_coordinate.CoordMinQ + _coordinate.CoordSpaceQ * this._coordinate.GridNumberX < _maxQ * 1.05)
            {
                _coordinate.GridNumberX++;
            }
        }
        /// <summary>
        /// 计算图表轴
        /// 设置图表轴
        /// </summary>
        private void CalcChartAxis()
        private void SetChartAxis()
        {
            _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;
            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;
            _bottom_pane.Visibility = ChartElementVisibility.Hidden;
            _bottom_pane.Visibility = _power_visible ? ChartElementVisibility.Visible : ChartElementVisibility.Hidden;
                _const_line_x.Visible = false;
                _const_line_y.Visible = false;
                _bottom_pane.Visibility = ChartElementVisibility.Hidden;
                return;
            }
            //计算刻度 Q
            var axisQLabels = new List<CustomAxisLabel>();
@@ -534,7 +745,7 @@
            _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<CustomAxisLabel>();
@@ -554,16 +765,16 @@
            if (_maxE > _minE && _eff_visible)
            {
                //计算刻度
                var labels = new List<CustomAxisLabel>();
                var label_list = new List<CustomAxisLabel>();
                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));
                    label_list.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.CustomLabels.AddRange(label_list.ToArray());
                _axis_y_eff.Visibility = DefaultBoolean.True;
                _axis_y_eff.GridLines.Visible = true;
            }
@@ -572,56 +783,100 @@
            if (_maxP > _minP && _power_visible)
            {
                //计算刻度
                var labels = new List<CustomAxisLabel>();
                var label_list = new List<CustomAxisLabel>();
                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));
                    label_list.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.CustomLabels.AddRange(label_list.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)
            _axis_x_flow.SetAxisRange(_coordinate.CoordMinQ, _coordinate.CoordMinQ + _coordinate.GridNumberX * _coordinate.CoordSpaceQ);
            //是否分割面板:流量效率在上,功率在下
            if (_split_panel)
            {
                grid_count_up += 2;//多两条
                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);
                if (_eff_visible)
                    grid_count_add += +5;//多两条
                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);
                _axis_y_power.SetAxisRange(_coordinate.DispMinP(), _coordinate.DispMaxP());
                _bottom_pane.Visibility = ChartElementVisibility.Visible;
            }
            else
            {
                if ((!_eff_visible) && (!_power_visible))
                {
                    _axis_y_head.SetAxisRange(_coordinate.DispMinH(), _coordinate.DispMaxH());
                }
                else if ((!_eff_visible) && _power_visible)
                {
                    var grid_count_eff = _coordinate.EndLineNoE - _coordinate.StartLineNoE;
                    var grid_delete_head = grid_count_eff * _coordinate.CoordSpaceH;
                    grid_delete_head = _coordinate.CoordMinH < 0 ? -grid_delete_head : grid_delete_head;
                    var grid_delete_power = grid_count_eff * _coordinate.CoordSpaceP;
                    _axis_y_head.SetAxisRange(_coordinate.CoordMinH - grid_delete_head, _coordinate.CoordMinH + _coordinate.GridNumberY * _coordinate.CoordSpaceH);
                    _axis_y_power.SetAxisRange(_coordinate.CoordMinP, _coordinate.CoordMinP + _coordinate.GridNumberY * _coordinate.CoordSpaceP - grid_delete_power);
                }
                else if (_eff_visible && (!_power_visible))
                {
                    var grid_count_power = _coordinate.EndLineNoP - _coordinate.StartLineNoP;
                    var grid_delete_head = grid_count_power * _coordinate.CoordSpaceH;
                    grid_delete_head = _coordinate.CoordMinH < 0 ? -grid_delete_head : grid_delete_head;
                    var grid_delete_eff = (grid_count_power) * _coordinate.CoordSpaceE;
                    grid_delete_eff = _coordinate.CoordMinE < 0 ? -grid_delete_eff : grid_delete_eff;
                    _axis_y_head.SetAxisRange(_coordinate.CoordMinH - grid_delete_head, _coordinate.CoordMinH + _coordinate.GridNumberY * _coordinate.CoordSpaceH);
                    _axis_y_eff.SetAxisRange(_coordinate.CoordMinE - grid_delete_eff, _coordinate.CoordMinE + _coordinate.GridNumberY * _coordinate.CoordSpaceE);
                }
                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);
                }
                _bottom_pane.Visibility = ChartElementVisibility.Hidden;
            }
            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);
        }
        #endregion
    } 
}