using DevExpress.Drawing;
using DevExpress.Pdf.Native;
using DevExpress.XtraCharts;
using System.Data;
using Yw.DAL.Basic;
using Yw.EPAnet;
using Yw.Hydro;
using Yw.Model;
namespace Yw.WinFrmUI
{
public partial class HydroLossCurveInteropCtrl : DevExpress.XtraEditors.XtraUserControl
{
public HydroLossCurveInteropCtrl()
{
InitializeComponent();
this.layoutControl1.SetupLayoutControl();
}
///
/// 水力点击事件
///
public event Action HydroClickEvent;
///
/// 水力特殊显示事件
///
public event Action> HydroSpecialDisplayEvent;
///
/// 水力取消特殊显示事件
///
public event Action HydroCancelSpecialDisplayEvent;
private Yw.Model.HydroModelInfo _hydroInfo = null;//水力信息
private HydroWorkingVmo _working = null;//工况
private Yw.Model.HydroNodeInfo _node = null;//节点
private HydroCalcuResult _calcuResult = null;//计算结果
///
/// 绑定数据
///
public void SetBindingData
(
Yw.Model.HydroModelInfo hydroInfo,
HydroWorkingVmo working,
HydroNodeInfo node,
HydroCalcuResult calcuResult = null,
bool isHead = false,
List allEvaluationList = null
)
{
if (hydroInfo == null)
{
return;
}
if (working == null)
{
return;
}
if (node == null)
{
return;
}
_hydroInfo = hydroInfo;
_working = working;
_node = node;
if (calcuResult == null)
{
hydroInfo.UpdateWorkingInfo(working.WorkingInfo);
calcuResult = hydroInfo.Calcu(Yw.EPAnet.CalcuMode.MinorLoss, isHead, allEvaluationList);
}
_calcuResult = calcuResult;
Analy();
}
///
/// 绑定数据
///
private void SetBindingData(HydroLossCurveViewModel vm)
{
AutoFitAxises(vm?.Items);
this.elevBindingSource.DataSource = vm?.Elev?.Items;
this.elevBindingSource.ResetBindings(false);
this.lossBindingSource.DataSource = vm?.Lower;
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);
}
//上游追踪选择
private void ckStart_CheckedChanged(object sender, EventArgs e)
{
Analy();
}
//下游追踪选择
private void ckEnd_CheckedChanged(object sender, EventArgs e)
{
Analy();
}
//高亮显示
private void ckSpecial_CheckedChanged(object sender, EventArgs e)
{
Analy();
}
//分析
private void Analy()
{
if (_hydroInfo == null)
{
return;
}
if (_working == null)
{
return;
}
if (_node == null)
{
return;
}
if (_calcuResult == null)
{
return;
}
var network = _hydroInfo.ToNetwork();
if (network == null)
{
return;
}
var epaNode = network.GetAllNodes()?.Find(x => x.Id == _node.Code);
if (epaNode == null)
{
return;
}
var allStartPathList = new List();
if (this.ckStart.Checked)
{
allStartPathList = network.AnalyzeUpstreamPath(epaNode, _calcuResult?.EPAnetCalcuResult);
if (allStartPathList == null)
{
allStartPathList = new List();
}
}
var allEndPathList = new List();
if (this.ckEnd.Checked)
{
allEndPathList = network.AnalyzeDownstreamPath(epaNode, _calcuResult?.EPAnetCalcuResult);
if (allEndPathList == null)
{
allEndPathList = new List();
}
}
var allPathList = allStartPathList.Concat(allEndPathList).ToList();
var allEpaLossList = network.GetChartNodeByPathLinks(allPathList, _calcuResult?.EPAnetCalcuResult);
var allVisualDict = _hydroInfo.GetVisualDict();
var vm = new HydroLossCurveViewModel();
vm.Items = new List();
allEpaLossList?.ForEach(x =>
{
var visualNode = allVisualDict?.GetValue(x.Id);
if (visualNode != null)
{
vm.Items.Add(new HydroLossCurveItemViewModel(x, visualNode));
}
});
vm.Elev = new HydroLossCurveElevViewModel(vm.Items);
vm.Start = new HydroLossCurveStartViewModel(vm.Items);
vm.End = new HydroLossCurveEndViewModel(vm.Items);
vm.Lower = new HydroLossCurveLowerViewModel(vm.Items);
vm.Total = new HydroLossCurveTotalViewModel(vm.Items);
SetBindingData(vm);
if (this.ckSpecial.Checked)
{
var allCodeList = new List();
allPathList?.ForEach(x => allCodeList.Add(x.Id));
vm.Items?.ForEach(x => allCodeList.Add(x.Code));
this.HydroSpecialDisplayEvent?.Invoke(allCodeList);
}
else
{
this.HydroCancelSpecialDisplayEvent?.Invoke();
}
}
}
}