using DevExpress.Drawing; using DevExpress.XtraCharts; using System.Data; using Yw.EPAnet; using Yw.Hydro; namespace Yw.WinFrmUI { public partial class HydroSingleWorkingLossCurveCtrl : DevExpress.XtraEditors.XtraUserControl { public HydroSingleWorkingLossCurveCtrl() { InitializeComponent(); } /// /// /// public event Action HydroClickEvent; /// /// 绑定数据 /// public void SetBindingData ( Yw.Model.HydroModelInfo hydroInfo, HydroCalcuResult calcuResult, Yw.Model.HydroVisualInfo visual ) { if (hydroInfo == null) { return; } var allVisualDict = hydroInfo.GetVisualDict(); var network = hydroInfo.ToNetwork(); if (network == null) { return; } var node = network.GetAllNodes()?.Find(x => x.Id == visual.Code); if (node == null) { return; } var allPathList1 = network.AnalyzeUpstreamPath(node, calcuResult.EPAnetCalcuResult); var allPathList2 = network.AnalyzeDownstreamPath(node, calcuResult.EPAnetCalcuResult); var allPathList= allPathList1.Concat(allPathList2).ToList(); var allEpaLossList = network.GetChartNodeByPathLinks(allPathList, calcuResult.EPAnetCalcuResult); var allNodeLossList = new List(); allEpaLossList?.ForEach(x => { var visualNode = allVisualDict?.GetValue(x.Id); if (visualNode != null) { allNodeLossList.Add(new HydroNodeLossViewModel(x, visualNode)); } }); SetBindingData(allNodeLossList); } /// /// 绑定数据 /// public void SetBindingData(List allNodeLossList) { AutoFitAxises(allNodeLossList); var allElevList = allNodeLossList?.Select(x => new HydroLossCurvePointVieModel(x.Code, x.Name, x.Distance, x.Elev)).ToList(); this.elevBindingSource.DataSource = allElevList; var allLossList = new List(); allNodeLossList?.ForEach(x => { allLossList.Add(new HydroLossCurvePointVieModel(x.Code, x.Name, x.Distance, x.StartHead)); allLossList.Add(new HydroLossCurvePointVieModel(x.Code, x.Name, x.Distance, x.EndHead)); }); this.lossBindingSource.DataSource = allLossList; if (allNodeLossList != null && allNodeLossList.Count > 0) { var startHead = allNodeLossList.Max(x => x.StartHead); var endHead = allNodeLossList.Min(x => x.EndHead); var allHeadLoss = startHead - endHead; var allMinorLoss = allNodeLossList.Sum(x => x.MinorLoss); var allForLoss = allHeadLoss - allMinorLoss; var sb = new StringBuilder(); sb.AppendLine($"水头损失:{allHeadLoss:N2}m"); sb.AppendLine($"局部损失:{allMinorLoss:N2}m"); sb.AppendLine($"沿程损失:{allForLoss:N2}m"); var anno = this.chartControl1.AnnotationRepository[0] as DevExpress.XtraCharts.TextAnnotation; anno.Text = sb.ToString(); anno.AutoSize = true; } } //自动适应刻度 private void AutoFitAxises(List allNodeLossList) { if (allNodeLossList == null || allNodeLossList.Count < 1) { return; } var diagram = this.chartControl1.Diagram as XYDiagram; #region X轴 var allDistances = allNodeLossList.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 = allNodeLossList.Select(x => Math.Min(Math.Min(x.StartHead, x.EndHead), x.Elev)).ToList(); var allPressMaxList = allNodeLossList.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); //ele.AxisLabelElement.Visible = false; } //// 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); } } }