using DevExpress.Utils; using DevExpress.XtraCharts; using Yw.WinFrmUI.Phart; namespace HStation.WinFrmUI { /// /// /// public partial class ExchangerPerform2dEditChart : DevExpress.XtraEditors.XtraUserControl { public ExchangerPerform2dEditChart() { InitializeComponent(); InitialChart(); this.chartControl1.RuntimeHitTesting = true; } #region Private Variable private XYDiagram _mainChartDiagram; private AxisX _axisXQ; private AxisY _axisYQL; private Series _seriesCurveQL; private Series _seriesPointQL; private List _def_pt_ql_list; private List _pt_ql_list; private ValveCoordinate _coordinate_paras; private bool _initial_data = false; #endregion Private Variable #region Public Evnet public event Action OnCurveCoordinateChanged; public event Action> OnDefinePointChanged; #endregion Public Evnet #region Initial /// /// 初始化图表 /// private void InitialChart() { this.chartControl1.SetChartDisplay(); this.chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; this.chartControl1.SeriesSelectionMode = SeriesSelectionMode.Point; this.chartControl1.SelectionMode = ElementSelectionMode.Single; _mainChartDiagram = (XYDiagram)chartControl1.Diagram; _axisXQ = _mainChartDiagram.AxisX; _axisXQ.SetAxisXQDisplay(); _axisYQL = _mainChartDiagram.AxisY; _axisYQL.SetAxisYQLDisplay(); _seriesCurveQL = this.chartControl1.GetSeriesByName("SeriesCurveQL"); _seriesCurveQL.SetCurveQLDisplay(); _seriesPointQL = this.chartControl1.GetSeriesByName("SeriesPointQL"); _seriesPointQL.SetPointQLDisplay(); _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQL.Visibility = DefaultBoolean.False; _axisYQL.GridLines.Visible = false; _seriesPointQL.Visible = false; this.chartControl1.SetChartMonoColorDisplay(); 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.KeyUp += new System.Windows.Forms.KeyEventHandler(this.chartControl1_KeyUp); } /// /// 初始化图表数据 /// public void InitialChartData() { _initial_data = false; _pt_ql_list = null; _def_pt_ql_list = null; _coordinate_paras = null; UpdateChart(false); } public void SetAxisTitle(string x, string y) { _axisXQ.Title.Text = x; _axisYQL.Title.Text = y; } #endregion Initial #region SetBindingData /// /// 绑定数据(目前没有定义点) /// /// /// /// public void SetBindingData(Yw.Geometry.CubicSpline2d cubic_spline_ql, string coordinate_paras = null, bool calc_coordinate = false) { if (cubic_spline_ql == null) { InitialChartData(); return; } List pt_ql_list; pt_ql_list = cubic_spline_ql.GetPointList(12); SetBindingData(pt_ql_list, pt_ql_list, coordinate_paras, calc_coordinate); } /// /// 绑定数据 /// /// /// /// /// public void SetBindingData( List pt_ql_list, List def_pt_ql_list, string coordinate_paras = null, bool calc_coordinate = false) { if (pt_ql_list == null || !pt_ql_list.Any()) { InitialChartData(); return; } _initial_data = true; _pt_ql_list = pt_ql_list; _def_pt_ql_list = def_pt_ql_list; _coordinate_paras = ValveCoordinate.ToModel(coordinate_paras); UpdateChart(calc_coordinate); } #endregion SetBindingData #region Update /// /// 更新曲线 /// /// /// public void UpdateCurve(List fit_point_list) { if (fit_point_list == null || !fit_point_list.Any()) return; _def_pt_ql_list = fit_point_list; _pt_ql_list = fit_point_list.GetFitPointList(); _axisYQL.SetAxisYQLColorDisplay(_seriesCurveQL, _seriesPointQL, true); UpdateChart(true); } /// /// 更新图表 /// /// 计算坐标 public void UpdateChart(bool calc_coordinate = false) { if (calc_coordinate || _coordinate_paras == null) { //不强迫计算,就用上次更新的坐标系 CalcCoordinate(); } CalcChartAxis(); CalcSeries(); } #endregion Update #region Calc /// /// 计算坐标 /// public void CalcCoordinate() { if (_pt_ql_list == null || _pt_ql_list.Count < 4) { //设置成白板坐标 _coordinate_paras = new ValveCoordinate(); _coordinate_paras.GridNumberX = 30; _coordinate_paras.GridNumberY = 16; //显示的坐标线号 _coordinate_paras.StartLineNoL = 10; _coordinate_paras.EndLineNoL = 15; //坐标最小值和间隔 _coordinate_paras.CoordMinQ = 0; _coordinate_paras.CoordSpaceQ = 1000; _coordinate_paras.CoordMinL = 10; _coordinate_paras.CoordSpaceL = 100; return; } _coordinate_paras = ValveCoordinate.CalcCoordinate(_pt_ql_list); } /// /// 计算图表轴 /// public void CalcChartAxis() { if (_coordinate_paras == null) { _axisXQ.Visibility = DefaultBoolean.False; _axisXQ.GridLines.Visible = false; _axisYQL.Visibility = DefaultBoolean.False; _axisYQL.GridLines.Visible = false; return; } //流量 if (_pt_ql_list != null) { //计算刻度 var labels = new List(); var disQ = _coordinate_paras.CoordMinQ; for (int i = 0; i < _coordinate_paras.GridNumberX + 1; i++) { labels.Add(new CustomAxisLabel(disQ.ToString("N0"), disQ)); disQ = disQ + _coordinate_paras.CoordSpaceQ; } //坐标刻度 _axisXQ.CustomLabels.Clear(); _axisXQ.CustomLabels.AddRange(labels.ToArray()); _axisXQ.Visibility = DefaultBoolean.True; _axisXQ.GridLines.Visible = true; _axisXQ.SetAxisRange(_coordinate_paras.CoordMinQ, _coordinate_paras.CoordMinQ + _coordinate_paras.GridNumberX * _coordinate_paras.CoordSpaceQ); } //水损 if (_pt_ql_list != null) { //计算刻度 var labels = new List(); var disH = _coordinate_paras.CoordMinL + _coordinate_paras.CoordSpaceL * _coordinate_paras.StartLineNoL; for (int i = _coordinate_paras.StartLineNoL; i < _coordinate_paras.EndLineNoL + 1; i++) { labels.Add(new CustomAxisLabel(disH.ToString(), disH)); disH = disH + _coordinate_paras.CoordSpaceL; } _axisYQL.CustomLabels.Clear(); _axisYQL.CustomLabels.AddRange(labels.ToArray()); _axisYQL.Visibility = DefaultBoolean.True; _axisYQL.GridLines.Visible = true; } _axisXQ.SetAxisRange(_coordinate_paras.CoordMinQ, _coordinate_paras.CoordMinQ + _coordinate_paras.GridNumberX * _coordinate_paras.CoordSpaceQ); _axisYQL.SetAxisRange(_coordinate_paras.DispMinL(), _coordinate_paras.DispMaxL()); } /// /// 计算系列 /// public void CalcSeries() { if (_pt_ql_list != null && _pt_ql_list.Count > 3) { _seriesCurveQL.Visible = true; _seriesCurveQL.Points.Clear(); foreach (var curvePoint in _pt_ql_list) { var seriesPoint = new SeriesPoint(curvePoint.X, curvePoint.Y); _seriesCurveQL.Points.Add(seriesPoint); } } else { _seriesCurveQL.Points.Clear(); _seriesCurveQL.Visible = false; } if (_def_pt_ql_list != null && _def_pt_ql_list.Any()) { _seriesPointQL.Points.Clear(); for (int i = 0; i < _def_pt_ql_list.Count; i++) { var definePoint = _def_pt_ql_list[i]; var seriesPoint = new SeriesPoint(definePoint.X, definePoint.Y); seriesPoint.Tag = i; _seriesPointQL.Points.Add(seriesPoint); } _seriesPointQL.Visible = true; } else { _seriesPointQL.Visible = false; } } #endregion Calc #region ChartEvent private bool _mouseMode = false;//鼠标模式 private SeriesPoint _pickPoint = null;// 选中点 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.InSeriesPoint) { //if ((int)hitInfo.Series.TagName != (int)_edit_curve_type) //{ // _pickPoint = null; // return; //} _pickPoint = hitInfo.SeriesPoint; } else { _pickPoint = null; } } else if (e.Button == MouseButtons.Right) { _pickPoint = null; this.popMenuChart.ShowPopup(MousePosition); } } private void chartControl1_MouseMove(object sender, MouseEventArgs e) { if (!_initial_data) return; if (!_mouseMode) return; if (_pickPoint == null) return; var diagramCoordinates = _mainChartDiagram.PointToDiagram(e.Location); var axisValue = diagramCoordinates.GetAxisValue(_axisYQL); if (axisValue == null) return; _pickPoint.Values[0] = axisValue.NumericalValue; _pickPoint.NumericalArgument = diagramCoordinates.NumericalArgument; } private void chartControl1_MouseUp(object sender, MouseEventArgs e) { if (!_initial_data) return; if (_mouseMode) { _pickPoint = null; ChartUpdateCurve(); } } private void chartControl1_KeyUp(object sender, KeyEventArgs e) { if (!_initial_data) return; if (_pickPoint == null) return; double spaceX = _coordinate_paras.CoordSpaceQ / 50; double spaceY = 0; spaceY = _coordinate_paras.CoordSpaceL / 50; double x = _pickPoint.NumericalArgument; double y = _pickPoint.Values[0]; if (e.KeyCode == Keys.Up) { y += spaceY; } else if (e.KeyCode == Keys.Down) { y -= spaceY; } else if (e.KeyCode == Keys.Left) { x -= spaceX; } else if (e.KeyCode == Keys.Right) { x += spaceX; } _pickPoint.Values[0] = y; _pickPoint.NumericalArgument = x; ChartUpdateCurve(); } /// /// 更新曲线 /// private void ChartUpdateCurve() { _def_pt_ql_list = _seriesPointQL.Points.Select(x => new Yw.Geometry.Point2d(x.ArgumentX.NumericalArgument, x.NumericalValue)).ToList(); _pt_ql_list = _def_pt_ql_list.GetFitPointList(); _seriesCurveQL.Points.Clear(); foreach (var curvePoint in _pt_ql_list) { var seriesPoint = new SeriesPoint(curvePoint.X, curvePoint.Y); _seriesCurveQL.Points.Add(seriesPoint); } OnDefinePointChanged?.Invoke(_def_pt_ql_list); CalcChartAxis(); } #endregion ChartEvent #region Right Click Menu #region Event private void barCekChartEditMode_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _mouseMode = this.barCekChartEditMode.Checked; var text = "修改模式:鼠标 / 键盘☑"; if (_mouseMode) { text = "修改模式:鼠标☑ / 键盘"; } _mainChartDiagram.DefaultPane.Title.Text = text; } private void BarBtnCalcCoordinate_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { CalcCoordinate(); CalcChartAxis(); } private void barCekLegendVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetLegendVisible(this.barCekLegendVisible.Checked); } private void barCekSetAxisNameVisible_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetAxisNameVisible(this.barCekSetAxisNameVisible.Checked); } private void barBtnSetChartAxis_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SetChartAxis(); } #endregion Event /// /// 设置图例显示 /// public void SetLegendVisible(bool visible) { this.chartControl1.Legend.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; } /// /// 设置轴名称显示 /// public void SetAxisNameVisible(bool visible) { _axisXQ.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; _axisYQL.Title.Visibility = visible ? DefaultBoolean.True : DefaultBoolean.False; } /// /// 设置坐标轴 /// public void SetChartAxis() { var dlg = new ValveChartCoordinateDlg(); dlg.SetBindingData(_coordinate_paras); dlg.OnChangedCoord += (rhs) => { _coordinate_paras = rhs; CalcChartAxis(); this.OnCurveCoordinateChanged?.Invoke(_coordinate_paras); }; dlg.ShowDialog(); } #endregion Right Click Menu } }