lixiaojun
2024-12-02 dbcef6befb123066754141adef6dc3ef6653b6ce
WinFrmUI/Yw.WinFrmUI.Phart.Core/v2/02-pump/01-chart/PumpParallelChart.cs
copy from WinFrmUI/Yw.WinFrmUI.Phart.Core/v2/02-pump/01-view/PumpVariableSpeedChart.cs copy to WinFrmUI/Yw.WinFrmUI.Phart.Core/v2/02-pump/01-chart/PumpParallelChart.cs
Îļþ´Ó WinFrmUI/Yw.WinFrmUI.Phart.Core/v2/02-pump/01-view/PumpVariableSpeedChart.cs ¸´ÖÆ
@@ -1,16 +1,16 @@
using DevExpress.Utils;
using DevExpress.XtraCharts;
using SqlSugar;
using System.Text;
using Yw.Geometry;
namespace Yw.WinFrmUI.Phart
{
    /// <summary>
    ///  æ³µå˜é€Ÿå›¾è¡¨
    ///  æ³µå¹¶è”图表
    /// </summary>
    public partial class PumpVariableSpeedChart : DevExpress.XtraEditors.XtraUserControl
    public partial class PumpParallelChart : DevExpress.XtraEditors.XtraUserControl
    {
        public PumpVariableSpeedChart()
        public PumpParallelChart()
        {
            InitializeComponent();
            InitialChart();
@@ -19,11 +19,11 @@
        #region Private Variable 
        private List<PumpVariableSpeedInfoViewModel> _vm_list = new List<PumpVariableSpeedInfoViewModel>();
        private List<PumpParallelViewModel> _vm_list = new List<PumpParallelViewModel>();
        private readonly string _tag_qh = "QH", _tag_qe = "QE", _tag_qp = "QP";
        private XYDiagram _diagram;
        private XYDiagramDefaultPane _default_pane;
        private XYDiagramDefaultPane _default_pane;
        private XYDiagramPane _bottom_pane;
        private AxisX _axis_x_flow;
        private AxisY _axis_y_head;
@@ -35,11 +35,15 @@
        private bool _qe_visible = true;
        private bool _qp_visible = true;
        private bool _equip_visible = true;
        protected Yw.Geometry.Point2d _equip_pt;
        private bool _initialData = false;
        private Yw.Geometry.CubicSpline2d _equip_line = null;
        private Yw.Geometry.Point2d _equip_pt = null;
        private Yw.Geometry.Point2d _equip_sect_pt=null;
        private bool _initial_data = false;
        private PumpParallelViewModel _paralle_vm = null;
        #endregion
@@ -78,15 +82,25 @@
        #region Public Evnet
        public event Action<PumpCoordinate> OnCurveCoordinateChanged;
        /// <summary>
        /// åæ ‡å˜æ¢äº‹ä»¶
        /// </summary>
        public event Action<PumpCoordinate> CoordinateChangedEvent = null;
        public event Action<string, PumpGroupPt> OnCalcQueryPoint = null;
        /// <summary>
        /// å¹¶è”状态变换事件
        /// </summary>
        public event Action<bool,string> ParallelStatusChangedEvent = null;
        public event Action AddBySpeedEvent = null;
        /// <summary>
        /// æŸ¥è¯¢ç‚¹å˜æ¢äº‹ä»¶
        /// </summary>
        public event Action<List<PumpQueryPointViewModel>> QueryPointChangedEvent = null;
        public event Action AddByHzEvent = null;
        public event Action AddByPointEvent = null;
        /// <summary>
        /// è®¾è®¡ç‚¹å˜æ¢äº‹ä»¶
        /// </summary>
        public event Action<List<PumpDesignPointViewModel>> DesignPointChangedEvent = null;
        #endregion
@@ -101,7 +115,7 @@
            this.chartControl1.Legend.Direction = DevExpress.XtraCharts.LegendDirection.TopToBottom;
            _diagram = (XYDiagram)this.chartControl1.Diagram;
            _default_pane = _diagram.DefaultPane;
            _default_pane = _diagram.DefaultPane;
            _bottom_pane = (XYDiagramPane)_diagram.FindPaneByName("BottomPanel");
            _axis_x_flow = _diagram.AxisX;
@@ -128,8 +142,7 @@
            _axis_y_eff.GridLines.Visible = false;
            _axis_y_power.Visibility = DefaultBoolean.False;
            _axis_y_power.GridLines.Visible = false;
            _query_flow_line.Visible = false;
            _anno_txt_query_info.Visible = false;
@@ -141,62 +154,135 @@
            this.chartControl1.CustomPaint += ChartControl1_CustomPaint;
        }
        /// <summary>
        /// å›¾è¡¨é‡ç»˜
        /// </summary>
        private void ChartControl1_CustomPaint(object sender, CustomPaintEventArgs e)
        {
            if (e is not DXCustomPaintEventArgs dxArgs)
                return;
            if (_vm_list == null || !_vm_list.Any())
                return;
            if (_equip_pt == null || !_equip_visible)
                return;
            var dis_min_h = _coordinate.DispMinH();
            using Pen pen = new(Color.Black, 2);
            Brush brush = new SolidBrush(Color.Red);
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
            foreach (var vm in _vm_list)
            if (_equip_line != null && _equip_sect_pt != null && _equip_visible)
            {
                var equip_paras = EquipCurveHelper.CalcEquipCurve(vm.QhCalc, _equip_pt, dis_min_h, out Yw.Geometry.Point2d sect_pt);
                if (equip_paras == null || sect_pt == null)
                    continue;
                if (equip_paras.EquipCurve.IsInvalid())
                    continue;
                var c_pt_qh = _diagram.DiagramToPoint(sect_pt.X, sect_pt.Y, _axis_x_flow, _axis_y_head);
                var dis_min_h = _coordinate.DispMinH();
                using Pen pen = new(Color.Black, 2);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
                var c_pt_qh = _diagram.DiagramToPoint(_equip_sect_pt.X, _equip_sect_pt.Y, _axis_x_flow, _axis_y_head);
                dxArgs.Cache.DrawLine(pen, new Point((int)c_pt_qh.Point.X, (int)c_pt_qh.Point.Y - 10), new Point((int)c_pt_qh.Point.X, (int)c_pt_qh.Point.Y + 10));
                if (_qe_visible)
                {
                    var y_qe = vm.QeCalc.GetPointY(sect_pt.X);
                    var c_pt_qe = _diagram.DiagramToPoint(sect_pt.X, y_qe, _axis_x_flow, _axis_y_eff);
                    var y_qe = _paralle_vm.CurrentCurveQE.GetPointY(_equip_sect_pt.X);
                    var c_pt_qe = _diagram.DiagramToPoint(_equip_sect_pt.X, y_qe, _axis_x_flow, _axis_y_eff);
                    dxArgs.Cache.DrawLine(pen, new Point((int)c_pt_qe.Point.X, (int)c_pt_qe.Point.Y - 10), new Point((int)c_pt_qe.Point.X, (int)c_pt_qe.Point.Y + 10));
                }
                if (_qp_visible)
                {
                    var y_qp = vm.QpCalc.GetPointY(sect_pt.X);
                    var c_pt_qp = _diagram.DiagramToPoint(sect_pt.X, y_qp, _axis_x_flow, _axis_y_power);
                    var y_qp = _paralle_vm.CurrentCurveQP.GetPointY(_equip_sect_pt.X);
                    var c_pt_qp = _diagram.DiagramToPoint(_equip_sect_pt.X, y_qp, _axis_x_flow, _axis_y_power);
                    dxArgs.Cache.DrawLine(pen, new Point((int)c_pt_qp.Point.X, (int)c_pt_qp.Point.Y - 10), new Point((int)c_pt_qp.Point.X, (int)c_pt_qp.Point.Y + 10));
                }
                if (vm.IsDefault)
                {
                    var pts = equip_paras.EquipCurve.GetPointList().Select(x => new PointF((float)x.X, (float)x.Y)).ToArray();
                    using var path = new System.Drawing.Drawing2D.GraphicsPath();
                    var g_pts = new List<PointF>();
                    foreach (var pt in pts)
                    {
                        var x = pt.X;
                        var y = pt.Y;
                        var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_head);
                        g_pts.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
                    }
                    path.AddCurve(g_pts.ToArray());
                    dxArgs.Cache.DrawPath(pen, path);
                var pts = _equip_line.GetPointList().Select(x => new PointF((float)x.X, (float)x.Y)).ToArray();
                var g_pts = new List<PointF>();
                foreach (var pt in pts)
                {
                    var x = pt.X;
                    var y = pt.Y;
                    var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_head);
                    g_pts.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
                }
                vm.SectPoint = sect_pt;
                using var path = new System.Drawing.Drawing2D.GraphicsPath();
                path.AddCurve(g_pts.ToArray());
                dxArgs.Cache.DrawPath(pen, path);
            }
            foreach (var vm in _vm_list)
            {
                if (!vm.CurrentExtendFlow.HasValue)
                    continue;
                var max_flow = vm.CurrentExtendFlow.Value;
                using Pen pen = new(Color.White, 2);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                {
                    var pt_list = vm.CurrentCurveQH.GetPointList(12).ToList();
                    pt_list = pt_list.Where(x => x.X >= max_flow).ToList();
                    if (pt_list.Count > 0)
                    {
                        if (pt_list.Count == 1)
                        {
                            var max_flow_head = vm.CurrentCurveQH.GetPointY(max_flow);
                            pt_list.Add(new Yw.Geometry.Point2d(max_flow, max_flow_head));
                        }
                        var pt_c_list = new List<PointF>();
                        foreach (var pt in pt_list)
                        {
                            var x = pt.X;
                            var y = pt.Y;
                            var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_head);
                            pt_c_list.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
                        }
                        using var path = new System.Drawing.Drawing2D.GraphicsPath();
                        path.AddCurve(pt_c_list.ToArray());
                        dxArgs.Cache.DrawPath(pen, path);
                    }
                }
                if (_qe_visible)
                {
                    var pt_list = vm.CurrentCurveQE.GetPointList(12).ToList();
                    pt_list = pt_list.Where(x => x.X > max_flow).ToList();
                    if (pt_list.Count > 0)
                    {
                        if (pt_list.Count == 1)
                        {
                            var max_flow_eff = vm.CurrentCurveQE.GetPointY(max_flow);
                            pt_list.Add(new Yw.Geometry.Point2d(max_flow, max_flow_eff));
                        }
                        var pt_c_list = new List<PointF>();
                        foreach (var pt in pt_list)
                        {
                            var x = pt.X;
                            var y = pt.Y;
                            var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_eff);
                            pt_c_list.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
                        }
                        using var path = new System.Drawing.Drawing2D.GraphicsPath();
                        path.AddCurve(pt_c_list.ToArray());
                        dxArgs.Cache.DrawPath(pen, path);
                    }
                }
                if (_qp_visible)
                {
                    var pt_list = vm.CurrentCurveQP.GetPointList(12).ToList();
                    pt_list = pt_list.Where(x => x.X > max_flow).ToList();
                    if (pt_list.Count > 0)
                    {
                        if (pt_list.Count == 1)
                        {
                            var max_flow_power = vm.CurrentCurveQP.GetPointY(max_flow);
                            pt_list.Add(new Yw.Geometry.Point2d(max_flow, max_flow_power));
                        }
                        var pt_c_list = new List<PointF>();
                        foreach (var pt in pt_list)
                        {
                            var x = pt.X;
                            var y = pt.Y;
                            var c_pt = _diagram.DiagramToPoint(x, y, _axis_x_flow, _axis_y_power);
                            pt_c_list.Add(new PointF(c_pt.Point.X, c_pt.Point.Y));
                        }
                        using var path = new System.Drawing.Drawing2D.GraphicsPath();
                        path.AddCurve(pt_c_list.ToArray());
                        dxArgs.Cache.DrawPath(pen, path);
                    }
                }
            }
        }
        /// <summary>
@@ -204,7 +290,7 @@
        /// </summary>
        public void InitialChartData()
        {
            _initialData = false;
            _initial_data = false;
            _coordinate = null;
            UpdateChart(false);
@@ -212,174 +298,83 @@
        #endregion
        #region Add Set
        #region  Set
        /// <summary>
        /// æ·»åŠ æ›²çº¿
        /// ç»‘定数据
        /// </summary> 
        public void Add(List<PumpVariableSpeedInfoViewModel> vm_list, Yw.Geometry.Point2d equip_pt)
        public void SetBindingData(List<PumpParallelViewModel> list)
        {
            if (vm_list == null || !vm_list.Any())
                return;
            _vm_list = new List<PumpVariableSpeedInfoViewModel>();
            _equip_pt = equip_pt;
            _initialData = true;
            _vm_list.AddRange(vm_list);
            _vm_list = list;
            _initial_data = list != null && list.Any();
            UpdateChart(true);
        }
        /// <summary>
        /// æ·»åŠ æ›²çº¿
        /// è®¾ç½®è®¾è®¡ç‚¹
        /// </summary> 
        public void Add(List<PumpVariableSpeedInfoViewModel> vm_list)
        public void SetDesignPoint(double x, double y, double? start_head = null)
        {
            if (vm_list == null || !vm_list.Any())
                return;
            _vm_list = new List<PumpVariableSpeedInfoViewModel>();
            _initialData = true;
            _vm_list.AddRange(vm_list);
            UpdateChart(true);
        }
        /// <summary>
        /// æ·»åŠ æ›²çº¿
        /// </summary>
        public void Add(PumpVariableSpeedInfoViewModel vm, Yw.Geometry.Point2d equip_pt)
        {
            if (vm == null)
                return;
            if (_vm_list == null)
                _vm_list = new List<PumpVariableSpeedInfoViewModel>();
            _equip_pt = equip_pt;
            _initialData = true;
            _vm_list.Add(vm);
            UpdateChart(true);
        }
        /// <summary>
        /// æ·»åŠ æ›²çº¿
        /// </summary>
        public void Add(PumpVariableSpeedInfoViewModel vm)
        {
            if (vm == null)
                return;
            if (_vm_list == null)
                _vm_list = new List<PumpVariableSpeedInfoViewModel>();
            _initialData = true;
            _vm_list.Add(vm);
            UpdateChart(true);
        }
        /// <summary>
        /// è®¾ç½®æ›²çº¿
        /// </summary>
        public void Set(string id, Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qe, Yw.Geometry.CubicSpline2d qp, string name = "")
        {
            var exist = _vm_list.FirstOrDefault(x => x.Id == id);
            if (exist == null)
                return;
            if (!string.IsNullOrEmpty(name))
            _equip_pt = new Geometry.Point2d(x, y);
            _equip_line = null;
            _equip_sect_pt = null;
            if (_paralle_vm == null || (_vm_list == null || !_vm_list.Any()))
            {
                exist.Name = name;
                this.DesignPointChangedEvent?.Invoke(null);
                return;
            }
            exist.QhCalc = qh;
            exist.QeCalc = qe;
            exist.QpCalc = qp;
            UpdateChart(true);
        }
        /// <summary>
        /// è®¾ç½®æ›²çº¿
        /// </summary>
        public void Set(string id, double hz, double ex_ratio, Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qe, Yw.Geometry.CubicSpline2d qp)
        {
            var exist = _vm_list.FirstOrDefault(x => x.Id == id);
            if (exist == null)
            start_head ??= _coordinate.DispMinH();
            var equip_line = Yw.Geometry.EquipCurveHelper.CalcEquipCurve(_paralle_vm.CurrentCurveQH, _equip_pt, start_head.Value, out Yw.Geometry.Point2d sect_pt);
            if (equip_line == null || sect_pt == null)
                return;
            exist.CurrentHz = hz;
            exist.CurrentSpeed = Math.Round(hz / 50 * exist.RatedSpeed, 1);
            exist.ExtendRatio = ex_ratio;
            exist.QhCalc = qh;
            exist.QeCalc = qe;
            exist.QpCalc = qp;
            foreach (Series series in this.chartControl1.Series)
            {
                var tag = series.Tag;
                if (tag == null)
                    continue;
                if (tag.ToString() != exist.Id)
                    continue;
                exist.Name = $"{exist.CurrentSpeed}({exist.CurrentHz}hz)";
            }
            UpdateChart(true);
        }
        /// <summary>
        /// è®¾ç½®æ›²çº¿
        /// </summary>
        public void SetInfo(string id, Color color)
        {
            var exist = _vm_list.FirstOrDefault(x => x.Id == id);
            if (exist == null)
                return;
            foreach (Series series in this.chartControl1.Series)
            _equip_line = equip_line;
            _equip_sect_pt = sect_pt;
            var design_pt_list = new List<PumpDesignPointViewModel>();
            foreach (var vm in _vm_list)
            {
                var tag = series.Tag;
                if (tag == null)
                    continue;
                if (tag.ToString() != exist.Id)
                    continue;
                exist.Color = color;
                series.View.Color = color;
                for (int i = 0; i < this.chartControl1.AnnotationRepository.Count; i++)
                double flow = 0, head = 0;
                double? eff = null, power = null;
                flow = sect_pt.X;
                head = vm.CurrentCurveQH.GetPointY(flow);
                if (vm.CurrentCurveQP != null)
                {
                    var txt = this.chartControl1.AnnotationRepository[i];
                    if (txt.Name == _tag_qh + id)
                    {
                        (txt as TextAnnotation).TextColor = color;
                        (txt as TextAnnotation).Border.Color = color;
                    }
                    power = _paralle_vm.CurrentCurveQP.GetPointY(flow);
                    eff = PumpCalcHelper.CalculateE(flow, head, power.Value);
                }
            }
        }
                else if (vm.CurrentCurveQE != null)
                {
                    eff = _paralle_vm.CurrentCurveQE.GetPointY(flow);
                    power = PumpCalcHelper.CalculateP(flow, head, eff.Value);
                }
        /// <summary>
        /// è®¾ç½®è£…置点
        /// </summary>
        public void SetEquipPt(Yw.Geometry.Point2d equip_pt)
        {
            _equip_pt = equip_pt;
                var design_pt = new PumpDesignPointViewModel();
                design_pt.Id = vm.Id;
                design_pt.Q = flow;
                design_pt.H = head;
                design_pt.E = eff;
                design_pt.P = power;
                design_pt.Hz = vm.CurrentHz;
                design_pt.N = vm.CurrentN;
                design_pt_list.Add(design_pt);
            }
            this.DesignPointChangedEvent?.Invoke(design_pt_list);
            UpdateChart(true);
        }
        /// <summary>
        /// åˆ é™¤æ›²çº¿
        /// </summary>
        public void Delete()
        {
            _vm_list.Clear();
            UpdateChart(true);
            _initialData = false;
        }
        /// <summary>
        /// åˆ é™¤æ›²çº¿
        /// </summary> 
        public void Delete(string id)
        public void Clear()
        {
            var exist = _vm_list.FirstOrDefault(x => x.Id == id);
            if (exist == null)
                return;
            _vm_list.Remove(exist);
            UpdateChart(true);
            if (_vm_list.Count == 0)
            {
                _initialData = false;
            }
            _vm_list = new List<PumpParallelViewModel>();
            _initial_data = false;
            UpdateChart(true);
        }
        /// <summary>
        /// æ›´æ–°å›¾è¡¨
        /// </summary>s
@@ -444,7 +439,7 @@
            foreach (var vm in _vm_list)
            {
                var qh_pt_list = vm.QhCalc.GetPointList();
                var qh_pt_list = vm.CurrentCurveQH.GetPointList();
                var xxx = qh_pt_list.Select(x => x.X);
                var yyy = qh_pt_list.Select(x => x.Y);
@@ -456,20 +451,20 @@
            }
            foreach (PumpVariableSpeedInfoViewModel vm in _vm_list)
            foreach (PumpParallelViewModel vm in _vm_list)
            {
                if (vm.QeCalc == null)
                if (vm.CurrentCurveQE == null)
                    continue;
                var qe_pt_list = vm.QeCalc.GetPointList();
                var qe_pt_list = vm.CurrentCurveQE.GetPointList();
                var yyy = qe_pt_list.Select(x => x.Y);
                _max_eff = Math.Max(_max_eff, yyy.Max());
            }
            foreach (PumpVariableSpeedInfoViewModel vm in _vm_list)
            foreach (PumpParallelViewModel vm in _vm_list)
            {
                if (vm.QpCalc == null)
                if (vm.CurrentCurveQP == null)
                    continue;
                var yyy = vm.QpCalc.GetPointList().Select(x => x.Y);
                var yyy = vm.CurrentCurveQP.GetPointList().Select(x => x.Y);
                _min_power = Math.Min(_min_power, yyy.Min());
                _max_power = Math.Max(_max_power, yyy.Max());
            }
@@ -601,7 +596,7 @@
            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(min_axis_power, max_axis_power);
        }
        /// <summary>
@@ -627,8 +622,61 @@
                {
                    CreateLineSeries(vm);
                }
            }
                CalcParallelSeries(_vm_list);
            }
            this.chartControl1.EndInit();
        }
        /// <summary>
        /// è®¡ç®—并联线
        /// </summary>
        private void CalcParallelSeries(List<PumpParallelViewModel> list)
        {
            _paralle_vm = null;
            if (list == null || !list.Any())
                return;
            var helper = new Yw.WinFrmUI.Phart.PumpParallelConnectionHelper();
            foreach (var item in list)
            {
                if (item.CurrentCurveQH == null)
                    continue;
                if (item.CurrentCurveQP == null)
                    continue;
                helper.Add(item.CurrentCurveQH, item.CurrentCurveQP);
            }
            List<Yw.Geometry.Point2d> calc_pt_qh_list;
            List<Yw.Geometry.Point2d> calc_pt_qe_list;
            List<Yw.Geometry.Point2d> calc_pt_qp_list;
            var calc_staus = helper.CalculateParallel(out calc_pt_qh_list, out calc_pt_qe_list, out calc_pt_qp_list);
            if (!calc_staus || calc_pt_qh_list.Count < 4)
            {
                this.ParallelStatusChangedEvent?.Invoke(false, "并联失败!");
                return;
            }
            var qh = new Yw.Geometry.CubicSpline2d(calc_pt_qh_list);
            var qe = new Yw.Geometry.CubicSpline2d(calc_pt_qe_list);
            var qp = new Yw.Geometry.CubicSpline2d(calc_pt_qp_list);
            _paralle_vm = new Yw.WinFrmUI.Phart.PumpParallelViewModel();
            _paralle_vm.Id = "parallel";
            _paralle_vm.Name = "并联线";
            _paralle_vm.CurrentColor = Color.Black;
            _paralle_vm.CurveQH = qh;
            _paralle_vm.CurveQE = qe;
            _paralle_vm.CurveQP = qp;
            _paralle_vm.CurrentCurveQH = qh;
            _paralle_vm.CurrentCurveQE = qe;
            _paralle_vm.CurrentCurveQP = qp;
            _paralle_vm.CurveQH = qh;
            _paralle_vm.CurveQE = qe;
            _paralle_vm.CurveQP = qp;
            CreateLineSeries(_paralle_vm);
        }
        /// <summary>
@@ -646,8 +694,8 @@
        /// <summary>
        /// è®¡ç®—工作点
        /// </summary> 
        public void CalcWorkPointByQ(double? work_flow = null)
        {
        public void CalcWorkPointByQ(double? x_flow = null)
        {
            if (!_line_visible)
            {
                _query_flow_line.Visible = false;
@@ -662,93 +710,87 @@
                _anno_txt_query_info.Visible = true;
            }
            if (_paralle_vm==null)
                return;
            if (_vm_list == null || !_vm_list.Any())
                return;
            var exist_default = _vm_list.Exists(x => x.IsDefault);
            _anno_txt_query_info.Visible = exist_default;
            if (exist_default)
            var min_flow = _paralle_vm.CurveQH.MinX;
            var max_flow = _paralle_vm.CurveQH.MaxX;
            x_flow ??= _equip_pt?.X ?? max_flow / 3 * 2;
            if (x_flow < min_flow || x_flow > max_flow)
                return;
            double paralle_flow = 0, paralle_head = 0;
            double? paralle_eff = null, paralle_power = null;
            paralle_flow = x_flow.Value;
            paralle_head = _paralle_vm.CurrentCurveQH.GetPointY(paralle_flow);
            if (_paralle_vm.CurrentCurveQP != null)
            {
                var def_vm = _vm_list.Find(x => x.IsDefault);
                var min_flow = def_vm.Qh.MinX;
                var max_flow = def_vm.Qh.MaxX;
                work_flow ??= _equip_pt?.X ?? max_flow / 3 * 2;
                if (work_flow < min_flow || work_flow > max_flow)
                    return;
                var work_pt = new PumpGroupPt(0, 0, 0, 0, 0);
                work_pt.Q = work_flow.Value;
                work_pt.H = def_vm.QhCalc.GetPointY(work_flow.Value);
                var work_info_str_builder = new StringBuilder();
                work_info_str_builder.AppendLine($"流量:{work_pt.Q.ToString("N1")} ");
                work_info_str_builder.AppendLine($"扬程:{work_pt.H.ToString("N1")} ");
                if (def_vm.QeCalc != null)
                {
                    if (def_vm.QpCalc != null)
                    {
                        work_pt.P = def_vm.QpCalc.GetPointY(work_pt.Q);
                        work_pt.E = PumpCalcHelper.CalculateE(work_pt.Q, work_pt.H, work_pt.P);
                    }
                    else
                    {
                        work_pt.E = def_vm.QeCalc.GetPointY(work_pt.Q);
                    }
                    work_info_str_builder.AppendLine($"效率:{work_pt.E.ToString("N2")} ");
                }
                if (def_vm.QpCalc != null)
                {
                    work_pt.P = def_vm.QpCalc.GetPointY(work_pt.Q);
                    work_info_str_builder.Append($"功率:{work_pt.P.ToString("N1")} ");
                }
                _anno_txt_query_info.Text = work_info_str_builder.ToString();
                _anno_txt_query_info.AutoSize = true;
                foreach (var vm in _vm_list)
                {
                    if (vm.IsDefault)
                        continue;
                    var pump_work_pt = new PumpGroupPt(0, 0, 0, 0, 0);
                    pump_work_pt.Q = vm.QhCalc.GetPointsX(work_pt.H).LastOrDefault();
                    pump_work_pt.H = work_pt.H;
                    if (vm.QeCalc != null)
                    {
                        if (vm.QpCalc != null)
                        {
                            pump_work_pt.P = vm.QpCalc.GetPointY(pump_work_pt.Q);
                            pump_work_pt.E = PumpCalcHelper.CalculateE(pump_work_pt.Q, pump_work_pt.H, pump_work_pt.P);
                        }
                        else
                        {
                            pump_work_pt.E = vm.QeCalc.GetPointY(pump_work_pt.Q);
                        }
                    }
                    if (vm.QpCalc != null)
                    {
                        pump_work_pt.P = vm.QpCalc.GetPointY(pump_work_pt.Q);
                    }
                    if (this.OnCalcQueryPoint != null)
                    {
                        this.OnCalcQueryPoint(vm.Id, pump_work_pt);
                    }
                }
                paralle_power = _paralle_vm.CurrentCurveQP.GetPointY(paralle_flow);
                paralle_eff = PumpCalcHelper.CalculateE(paralle_flow, paralle_head, paralle_power.Value);
            }
            else
            else if (_paralle_vm.CurrentCurveQE != null)
            {
                work_flow ??= _max_flow / 3 * 2;
                if (work_flow < _min_flow || work_flow > _max_flow)
                    return;
                paralle_eff = _paralle_vm.CurrentCurveQE.GetPointY(paralle_flow);
                paralle_power = PumpCalcHelper.CalculateP(paralle_flow, paralle_head, paralle_eff.Value);
            }
            _query_flow_line.AxisValue = work_flow;
            _query_flow_line.Title.Text = work_flow.Value.ToString("N1");
            var query_pt_list = new List<PumpQueryPointViewModel>();
            foreach (var vm in _vm_list)
            {
                double flow = 0, head = 0;
                double? eff = null, power = null;
                head = paralle_head;
                flow = vm.CurrentCurveQH.GetPointsX(head).LastOrDefault();
                if (vm.CurrentCurveQP != null)
                {
                    power = _paralle_vm.CurrentCurveQP.GetPointY(flow);
                    eff = PumpCalcHelper.CalculateE(flow, head, power.Value);
                }
                else if (vm.CurrentCurveQE != null)
                {
                    eff = _paralle_vm.CurrentCurveQE.GetPointY(flow);
                    power = PumpCalcHelper.CalculateP(flow, head, eff.Value);
                }
                var pump_query_pt = new PumpQueryPointViewModel();
                pump_query_pt.Id = vm.Id;
                pump_query_pt.Q = flow;
                pump_query_pt.H = head;
                pump_query_pt.E = eff;
                pump_query_pt.P = power;
                pump_query_pt.Hz = vm.CurrentHz;
                pump_query_pt.N = vm.CurrentN;
                query_pt_list.Add(pump_query_pt);
            }
            var work_info_str_builder = new StringBuilder();
            work_info_str_builder.AppendLine($"流量:{paralle_flow:N2} ");
            work_info_str_builder.AppendLine($"扬程:{paralle_head:N2} ");
            if (paralle_eff.HasValue)
                work_info_str_builder.AppendLine($"效率:{paralle_eff:N2} ");
            if (paralle_power.HasValue)
                work_info_str_builder.Append($"功率:{paralle_power:N2}");
            _query_flow_line.AxisValue = x_flow;
            _query_flow_line.Title.Text = $"{x_flow:N1}";
            _anno_txt_query_info.Text = work_info_str_builder.ToString();
            _anno_txt_query_info.AutoSize = true;
            _anno_txt_query_info.Visible = true;
            this.QueryPointChangedEvent?.Invoke(query_pt_list);
        }
        /// <summary>
        /// åˆ›å»ºçº¿ç³»åˆ—
        /// </summary> 
        private void CreateLineSeries(PumpVariableSpeedInfoViewModel vm)
        private void CreateLineSeries(PumpParallelViewModel vm)
        {
            var series_qh = new DevExpress.XtraCharts.Series();
            series_qh.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
@@ -763,7 +805,7 @@
            var series_qh_view = new DevExpress.XtraCharts.SplineSeriesView();
            series_qh_view.LineStyle.Thickness = 2;
            series_qh_view.Color = vm.Color;
            series_qh_view.Color = vm.CurrentColor;
            series_qh_view.EnableAntialiasing = DefaultBoolean.True;
            series_qh_view.LineTensionPercent = 50;
@@ -772,7 +814,7 @@
            series_qh.View = series_qh_view;
            series_qh.Visible = true;
            var pt_qh_list = vm.QhCalc.GetPointList(12);
            var pt_qh_list = vm.CurrentCurveQH.GetPointList(12);
            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 }));
@@ -794,7 +836,7 @@
            txt_qh.AutoHeight = true;
            txt_qh.AutoWidth = true;
            txt_qh.BackColor = System.Drawing.Color.Transparent;
            txt_qh.Border.Color = vm.Color;
            txt_qh.Border.Color = vm.CurrentColor;
            txt_qh.ConnectorStyle = DevExpress.XtraCharts.AnnotationConnectorStyle.Line;
            txt_qh.DXFont = Perform2dChartDisplay.AnnoFontQH;
            txt_qh.Name = _tag_qh + vm.Id.ToString();
@@ -807,13 +849,13 @@
            txt_qh.RuntimeResizing = false;
            txt_qh.RuntimeRotation = false;
            txt_qh.Text = vm.Name;
            txt_qh.TextColor = vm.Color;
            txt_qh.TextColor = vm.CurrentColor;
            txt_qh.ShapePosition = position_qh;
            txt_qh.Visible = _line_name_visible;
            this.chartControl1.AnnotationRepository.Add(txt_qh);
            this.chartControl1.Series.Add(series_qh);
            if (vm.QeCalc != null)
            if (vm.CurrentCurveQE != null)
            {
                var series_qe = new DevExpress.XtraCharts.Series();
                series_qe.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
@@ -825,7 +867,7 @@
                var series_qe_view = new DevExpress.XtraCharts.SplineSeriesView();
                series_qe_view.LineStyle.Thickness = 2;
                series_qe_view.Color = vm.Color;
                series_qe_view.Color = vm.CurrentColor;
                series_qe_view.AxisY = _axis_y_eff;
                series_qe_view.Pane = _default_pane;
                series_qe_view.EnableAntialiasing = DefaultBoolean.True;
@@ -836,7 +878,7 @@
                series_qe.View = series_qe_view;
                series_qe.Visible = _qe_visible;
                var pt_qe_list = vm.QeCalc.GetPointList(12);
                var pt_qe_list = vm.CurrentCurveQE.GetPointList(12);
                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 }));
@@ -845,7 +887,7 @@
                this.chartControl1.Series.Add(series_qe);
            }
            if (vm.QpCalc != null)
            if (vm.CurrentCurveQP != null)
            {
                var series_qp = new DevExpress.XtraCharts.Series();
                series_qp.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
@@ -857,7 +899,7 @@
                var series_qp_view = new DevExpress.XtraCharts.SplineSeriesView();
                series_qp_view.LineStyle.Thickness = 2;
                series_qp_view.Color = vm.Color;
                series_qp_view.Color = vm.CurrentColor;
                series_qp_view.AxisY = _axis_y_power;
                series_qp_view.Pane = _bottom_pane;
                series_qp_view.EnableAntialiasing = DefaultBoolean.True;
@@ -868,7 +910,7 @@
                series_qp.View = series_qp_view;
                series_qp.Visible = _qp_visible;
                var pt_qp_list = vm.QpCalc.GetPointList(12);
                var pt_qp_list = vm.CurrentCurveQP.GetPointList(12);
                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 }));
@@ -889,7 +931,7 @@
        private bool _onMoveWorkPointLine = false;
        private void chartControl1_MouseDown(object sender, MouseEventArgs e)
        {
            if (!_initialData)
            if (!_initial_data)
                return;
            var hitInfo = chartControl1.CalcHitInfo(e.Location);
            if (e.Button == MouseButtons.Left)
@@ -921,22 +963,11 @@
                    _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)
            if (!_initial_data)
                return;
            if (_onMoveWorkPointLine)
            {
@@ -967,7 +998,7 @@
        private void chartControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (!_initialData)
            if (!_initial_data)
                return;
            _onMoveWorkPointLine = false;
        }
@@ -1053,7 +1084,7 @@
        /// </summary>
        public void SetLineVisible(bool visible)
        {
            if (!_initialData)
            if (!_initial_data)
                return;
            LineVisible = visible;
            CalcWorkPointByQ();
@@ -1064,7 +1095,7 @@
        /// </summary>
        public void SetEquipVisible(bool visible)
        {
            if (!_initialData)
            if (!_initial_data)
                return;
            _equip_visible = visible;
            UpdateChart(true);
@@ -1075,17 +1106,16 @@
        /// </summary>
        public void SetQeVisible(bool visible)
        {
            //if (!_initialData)
            //    return;
            this.barCekCurveQEVisible.Checked = visible;
        }
        /// <summary>
        /// è®¾ç½®æ›²çº¿å
        /// </summary>
        public void SetCurveNameVisible(bool visible)
        {
            if (!_initialData)
            if (!_initial_data)
                return;
            _line_name_visible = visible;
            for (int i = 1; i < this.chartControl1.AnnotationRepository.Count; i++)
@@ -1125,102 +1155,13 @@
            {
                _coordinate = rhs;
                CalcChartAxis();
                this.OnCurveCoordinateChanged?.Invoke(_coordinate);
                this.CoordinateChangedEvent?.Invoke(_coordinate);
            };
            dlg.ShowDialog();
        }
        #endregion
        #region Add Event
        private void barBtnAddBySpeed_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.AddBySpeedEvent?.Invoke();
        }
        private void barBtnAddByHz_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.AddByHzEvent?.Invoke();
        }
        private void barBtnAddByPoint_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.AddByPointEvent?.Invoke();
        }
        #endregion
        #region Get
        /// <summary>
        /// èŽ·å–ViewModel列表
        /// </summary>
        public List<PumpVariableSpeedInfoViewModel> GetVmList()
        {
            if (_vm_list == null || !_vm_list.Any())
                return default;
            return _vm_list.Select(x => new PumpVariableSpeedInfoViewModel(x)).ToList();
        }
        /// <summary>
        /// èŽ·å– SectPoint ViewModel åˆ—表
        /// </summary>
        public List<PumpSectPointViewModel> GetSectPointList()
        {
            if (_vm_list == null || !_vm_list.Any())
                return default;
            var list = new List<PumpSectPointViewModel>();
            foreach (var x in _vm_list)
            {
                var vm = new PumpSectPointViewModel();
                vm.Id = x.Id;
                vm.Name = x.Name;
                if (x.SectPoint != null)
                {
                    var flow = x.SectPoint.X;
                    var head = x.SectPoint.Y;
                    vm.QueryQ = $"{flow:N1}";
                    vm.QueryH = $"{head:N1}";
                    if (x.QeCalc != null)
                    {
                        vm.QueryE = $"{x.QeCalc.GetPointY(flow):N1}";
                    }
                    if (x.QpCalc != null)
                    {
                        vm.QueryP = $"{x.QpCalc.GetPointY(flow):N1}";
                    }
                }
                list.Add(vm);
            }
            return list;
        }
        /// <summary>
        /// èŽ·å–æ›²çº¿åˆ—è¡¨
        /// </summary>
        public void GetCubicSplineList(out List<Tuple<Yw.Geometry.CubicSpline2d, Yw.Geometry.CubicSpline2d, Yw.Geometry.CubicSpline2d>> list)
        {
            list = null;
            if (_vm_list == null || !_vm_list.Any())
                return;
            foreach (var item in _vm_list)
            {
                if (item.IsDefault)
                    continue;
                var qh = item.QhCalc;
                var qe = item.QeCalc;
                var qp = item.QpCalc;
                list.Add(new Tuple<Geometry.CubicSpline2d, Geometry.CubicSpline2d, Geometry.CubicSpline2d>(qh, qe, qp));
            }
        }
        #endregion
    }
    }
}