using DevExpress.Drawing; using DevExpress.XtraCharts; using System.Data; using Yw.Epanet; using Yw.Hydro; using Yw.Model; namespace Yw.WinFrmUI { public partial class HydroLossCurveCtrl : DevExpress.XtraEditors.XtraUserControl { public HydroLossCurveCtrl() { InitializeComponent(); } /// /// 水力点击事件 /// public event Action HydroClickEvent; /// /// 绑定数据 /// public void SetBindingData ( Yw.Model.HydroModelInfo hydroInfo, HydroWorkingVmo working, HydroNodeInfo node, HydroCalcuResult calcuResult = null, bool isHead = false, List allEvaluationList = null ) { var vm = HydroLossCurveHelper.Create(hydroInfo, working, node, calcuResult, isHead, allEvaluationList); SetBindingData(vm); } /// /// 绑定数据 /// public void SetBindingData(HydroLossCurveViewModel vm) { AutoFitAxises(vm?.Items); this.elevBindingSource.DataSource = vm?.Elev?.Items; this.elevBindingSource.ResetBindings(false); this.lossBindingSource.DataSource = vm?.Lower?.Items; this.lossBindingSource.ResetBindings(false); if (vm?.Total != null) { var sb = new StringBuilder(); sb.AppendLine($"水头损失:{vm?.Total.HeadLoss:N2}m"); sb.AppendLine($"局部损失:{vm?.Total.MinorLoss:N2}m"); sb.AppendLine($"沿程损失:{vm?.Total.FrictionLoss:N2}m"); var anno = this.chartControl1.AnnotationRepository[0] as DevExpress.XtraCharts.TextAnnotation; anno.Text = sb.ToString(); anno.AutoSize = true; } } //自动适应刻度 private void AutoFitAxises(List items) { if (items == null || items.Count < 1) { return; } var diagram = this.chartControl1.Diagram as XYDiagram; #region X轴 var allDistances = items.Select(x => x.Distance).Distinct().ToList(); var distanceMax = allDistances.Max(); diagram.AxisX.Tickmarks.MinorVisible = false; diagram.AxisX.WholeRange.SideMarginsValue = 0; if (distanceMax <= 10) { var maxValue = Math.Ceiling(distanceMax); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue; diagram.AxisX.NumericScaleOptions.GridSpacing = 1; } else if (distanceMax <= 50) { var maxValue = Math.Ceiling(distanceMax / 10); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 10; diagram.AxisX.NumericScaleOptions.GridSpacing = 5; } else if (distanceMax <= 100) { var maxValue = Math.Ceiling(distanceMax / 10); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 10; diagram.AxisX.NumericScaleOptions.GridSpacing = 10; } else if (distanceMax <= 500) { var maxValue = Math.Ceiling(distanceMax / 100); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 100; diagram.AxisX.NumericScaleOptions.GridSpacing = 50; } else if (distanceMax <= 3000) { var maxValue = Math.Ceiling(distanceMax / 100); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 100; diagram.AxisX.NumericScaleOptions.GridSpacing = 100; } else if (distanceMax <= 5000) { var maxValue = Math.Ceiling(distanceMax / 1000); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 1000; diagram.AxisX.NumericScaleOptions.GridSpacing = 200; } else if (distanceMax <= 10000) { var maxValue = Math.Ceiling(distanceMax / 1000); diagram.AxisX.WholeRange.MinValue = 0; diagram.AxisX.WholeRange.MaxValue = maxValue * 1000; diagram.AxisX.NumericScaleOptions.GridSpacing = 1000; } else { } #endregion #region 压力 var allPressMinList = items.Select(x => Math.Min(Math.Min(x.StartHead, x.EndHead), x.Elev)).ToList(); var allPressMaxList = items.Select(x => Math.Max(Math.Max(x.StartHead, x.EndHead), x.Elev)).ToList(); var pressMin = allPressMinList.Min(); var pressMax = allPressMaxList.Max(); diagram.AxisY.Tickmarks.MinorVisible = false; diagram.AxisY.WholeRange.SideMarginsValue = 0; diagram.AxisY.CrosshairAxisLabelOptions.EnableAntialiasing = DevExpress.Utils.DefaultBoolean.True; if (pressMax <= 10) { diagram.AxisY.WholeRange.MinValue = Math.Floor(pressMin); diagram.AxisY.WholeRange.MaxValue = 10; diagram.AxisY.NumericScaleOptions.GridSpacing = 1; diagram.AxisY.VisualRange.SetMinMaxValues(0, 10); } else if (pressMax <= 100) { var maxValue = Math.Ceiling(pressMax / 10); diagram.AxisY.WholeRange.MinValue = Math.Floor(pressMin); diagram.AxisY.WholeRange.MaxValue = maxValue * 10; diagram.AxisY.NumericScaleOptions.GridSpacing = 5; diagram.AxisY.VisualRange.SetMinMaxValues(0, maxValue * 10); } else if (pressMax <= 3000) { var maxValue = Math.Ceiling(pressMax / 100); diagram.AxisY.WholeRange.MinValue = Math.Floor(pressMin); diagram.AxisY.WholeRange.MaxValue = maxValue * 100; diagram.AxisY.NumericScaleOptions.GridSpacing = 50; diagram.AxisY.VisualRange.SetMinMaxValues(0, maxValue * 100); } else if (pressMax <= 6000) { var maxValue = Math.Ceiling(pressMax / 1000); diagram.AxisY.WholeRange.MinValue = Math.Floor(pressMin); diagram.AxisY.WholeRange.MaxValue = maxValue * 1000; diagram.AxisY.NumericScaleOptions.GridSpacing = 100; diagram.AxisY.VisualRange.SetMinMaxValues(0, maxValue * 1000); } else { } #endregion } //提示 private void chartControl1_CustomDrawCrosshair(object sender, CustomDrawCrosshairEventArgs e) { // Specify the crosshair argument line color, dash style and thickness. e.CrosshairLineElement.Color = Color.Green; e.CrosshairLineElement.LineStyle.DashStyle = DashStyle.DashDot; e.CrosshairLineElement.LineStyle.Thickness = 3; // Specify the back color for the crosshair argument axis label. foreach (CrosshairAxisLabelElement axisLabelElement in e.CrosshairAxisLabelElements) { axisLabelElement.BackColor = Color.Blue; axisLabelElement.Text = $"{axisLabelElement.AxisValue:N2}"; } foreach (CrosshairElementGroup group in e.CrosshairElementGroups) { CrosshairGroupHeaderElement groupHeaderElement = group.HeaderElement; var pt = group.HeaderElement.SeriesPoints.FirstOrDefault(); if (pt != null) { var model = pt.Tag as HydroLossCurvePointVieModel; if (model != null) { groupHeaderElement.Text = model.Name; } } // Specify the text, text color and font for the crosshair group header element. groupHeaderElement.TextColor = Color.Green; groupHeaderElement.DXFont = new DXFont("SegoeUI", 12, DXFontStyle.Bold); //groupHeaderElement.Text = group.CrosshairElements[0].AxisLabelElement.Text; foreach (var ele in group.CrosshairElements) { ele.AxisLabelElement.Text = $"{ele.AxisLabelElement.AxisValue:N1}"; ele.AxisLabelElement.DXFont = new DXFont(this.Font.Name, 6); } //// Obtain the first series. //CrosshairElement element = group.CrosshairElements[0]; //// Specify the color, dash style and thickness for the crosshair value lines. //element.LineElement.Color = Color.DarkViolet; //element.LineElement.LineStyle.DashStyle = DashStyle.Dash; //element.LineElement.LineStyle.Thickness = 2; //// Specify the text color and back color for the crosshair value labels. //element.AxisLabelElement.TextColor = Color.Red; //element.AxisLabelElement.BackColor = Color.Yellow; //// Format the text shown for the series in the crosshair cursor label. Specify the text color and marker size. //element.LabelElement.TextColor = Color.Red; //element.LabelElement.MarkerSize = new Size(15, 15); //element.LabelElement.Text = $"高程:{element.SeriesPoint.Values[0]}m"; } } //点击事件 private void chartControl1_MouseClick(object sender, MouseEventArgs e) { ChartHitInfo hitInfo = this.chartControl1.CalcHitInfo(e.Location); if (hitInfo.Series != null) { if (hitInfo.SeriesPoint != null) { var vm = hitInfo.SeriesPoint.Tag as HydroLossCurvePointVieModel; if (vm != null) { this.HydroClickEvent?.Invoke(vm.Code); } } } } /// /// 导出图片 /// public void ExportToImage(string filePath) { this.chartControl1.ExportToImage(filePath, DXImageFormat.Png); } } }