using DevExpress.Utils;
using DevExpress.XtraCharts;
using Yw.WinFrmUI.Phart;
namespace PBS.WinFrmUI.Hydro
{
public partial class SystemCurveChartCtrl : DevExpress.XtraEditors.XtraUserControl
{
public SystemCurveChartCtrl()
{
InitializeComponent();
this.layoutControl1.SetupLayoutControl();
this.gridView1.SetNormalView();
this.sidePanel1.Visible = false;
InitialChart();
}
public void InitialChart()
{
this.chartControl1.Legend.Direction = LegendDirection.LeftToRight;
this.chartControl1.RuntimeHitTesting = true;
_xyDiagram = this.chartControl1.Diagram as XYDiagram;
_xyDiagramPane = _xyDiagram.DefaultPane;
_seriesWaterPoint = this.chartControl1.GetSeriesByName("SeriesWaterPoint");
_seriesUpperPressure = this.chartControl1.GetSeriesByName("SeriesUpperPressure");
_seriesLowerPressure = this.chartControl1.GetSeriesByName("SeriesLowerPressure");
_seriesAveragePressure = this.chartControl1.GetSeriesByName("SeriesAveragePressure");
_constantLineDynamicPressure = _xyDiagram.AxisY.ConstantLines.GetElementByName("ConstantLineDynamicPressure") as ConstantLine;
_constantLineStaticPressure = _xyDiagram.AxisY.ConstantLines.GetElementByName("ConstantLineStaticPressure") as ConstantLine;
_seriesWaterPoint.LegendTextPattern = "用水点";
_seriesUpperPressure.LegendTextPattern = "压力-上限";
_seriesLowerPressure.LegendTextPattern = "压力-下限";
_seriesAveragePressure.LegendTextPattern = "压力-平均";
_seriesWaterPoint.CrosshairEnabled = DevExpress.Utils.DefaultBoolean.False;
_seriesUpperPressure.CrosshairEnabled = DevExpress.Utils.DefaultBoolean.True;
_seriesLowerPressure.CrosshairEnabled = DevExpress.Utils.DefaultBoolean.True;
_seriesAveragePressure.CrosshairEnabled = DevExpress.Utils.DefaultBoolean.True;
this.chartControl1.CrosshairOptions.ShowOnlyInFocusedPane = false;
this.chartControl1.CrosshairOptions.GroupHeaderPattern = "{A:N2}";
this.chartControl1.CrosshairOptions.GroupHeaderTextOptions.EnableAntialiasing = DevExpress.Utils.DefaultBoolean.True;
_seriesUpperPressure.CrosshairLabelPattern = "{V:N2}";
_seriesLowerPressure.CrosshairLabelPattern = "{V:N2}";
_seriesAveragePressure.CrosshairLabelPattern = "{V:N2}";
_constantLineDynamicPressure.ShowInLegend = false;
_constantLineStaticPressure.ShowInLegend = false;
_constantLineDynamicPressure.Title.Alignment = ConstantLineTitleAlignment.Far;
_constantLineStaticPressure.Title.Alignment = ConstantLineTitleAlignment.Far;
_constantLineDynamicPressure.LineStyle.Thickness = 2;
_constantLineStaticPressure.LineStyle.Thickness = 2;
_xyDiagram.EnableAxisXZooming = true;
_xyDiagram.EnableAxisYZooming = true;
_xyDiagram.EnableAxisXScrolling = true;
_xyDiagram.EnableAxisYScrolling = true;
}
private XYDiagram _xyDiagram;
private XYDiagramDefaultPane _xyDiagramPane;
private Series _seriesWaterPoint;
private Series _seriesUpperPressure;
private Series _seriesLowerPressure;
private Series _seriesAveragePressure;
private ConstantLine _constantLineDynamicPressure;
private ConstantLine _constantLineStaticPressure;
///
/// 刷新数据事件
///
public event Action RefreshDataEvent;
public event Action RefreshCurveEvent;
///
/// 清空
///
public void Clear()
{
this.chartControl1.BeginInit();
_seriesWaterPoint.Points.Clear();
_seriesUpperPressure.Points.Clear();
_seriesLowerPressure.Points.Clear();
_seriesAveragePressure.Points.Clear();
this.chartControl1.CrosshairEnabled = DefaultBoolean.False;
this.chartControl1.CrosshairOptions.ShowArgumentLine = false;
_constantLineDynamicPressure.Visible = false;
_constantLineStaticPressure.Visible = false;
_xyDiagram.AxisX.Visibility = DefaultBoolean.False;
_xyDiagram.AxisX.GridLines.Visible = false;
_xyDiagram.AxisY.Visibility = DefaultBoolean.False;
_xyDiagram.AxisY.GridLines.Visible = false;
_xyDiagram.EnableAxisXZooming = false;
_xyDiagram.EnableAxisYZooming = false;
_xyDiagram.EnableAxisXScrolling = false;
_xyDiagram.EnableAxisYScrolling = false;
this.chartControl1.EndInit();
this.RefreshCurveEvent?.Invoke(null, null, null);
}
///
/// 绑定数据
///
public void SetBindingData(List waterPointCalcList)
{
if (waterPointCalcList == null || !waterPointCalcList.Any())
{
Clear();
return;
}
this.chartControl1.BeginInit();
_xyDiagram.EnableAxisXZooming = true;
_xyDiagram.EnableAxisYZooming = true;
_xyDiagram.EnableAxisXScrolling = true;
_xyDiagram.EnableAxisYScrolling = true;
this.chartControl1.CrosshairOptions.ShowArgumentLine = true;
_seriesWaterPoint.Points.Clear();
_seriesUpperPressure.Points.Clear();
_seriesLowerPressure.Points.Clear();
_seriesAveragePressure.Points.Clear();
_constantLineDynamicPressure.Visible = false;
_constantLineStaticPressure.Visible = false;
var upperPressurePtList = new List();
var lowerPressurePtList = new List();
var averagePressurePtList = new List();
var waterPointGroup = waterPointCalcList.GroupBy(x => Math.Round(x.TotalFlow, 1));
foreach (var item in waterPointGroup)
{
var x = item.Key;
var yList = item.Select(x => x.EndPressure).OrderBy(x => x).ToList();
var yUpper = CalculatePercentile(yList, 0.95);
var yLower = CalculatePercentile(yList, 0.05);
var yNumList = yList.Where(x => x >= yLower && x <= yUpper);
if (yNumList == null || !yNumList.Any())
{
continue;
}
var yAverage = yNumList.Where(x => x >= yLower && x <= yUpper).Average();
upperPressurePtList.Add(new Yw.Geometry.Point2d(x, yUpper));
lowerPressurePtList.Add(new Yw.Geometry.Point2d(x, yLower));
averagePressurePtList.Add(new Yw.Geometry.Point2d(x, yAverage));
}
if (averagePressurePtList.Count > 4)
{
var curveUpperPressure = new Yw.Ahart.CubicCurve(upperPressurePtList);
var curveLowerPressure = new Yw.Ahart.CubicCurve(lowerPressurePtList);
var curveAveragePressure = new Yw.Ahart.CubicCurve(averagePressurePtList);
var upperPressureCurvePtList = curveUpperPressure.GetPointList(100);
var lowerPressureCurvePtList = curveLowerPressure.GetPointList(100);
var averagePressureCurvePtList = curveAveragePressure.GetPointList(100);
foreach (var item in waterPointCalcList)
{
_seriesWaterPoint.Points.Add(new SeriesPoint(item.TotalFlow, item.EndPressure));
}
foreach (var item in upperPressureCurvePtList)
{
_seriesUpperPressure.Points.Add(new SeriesPoint(item.X, item.Y));
}
foreach (var item in lowerPressureCurvePtList)
{
_seriesLowerPressure.Points.Add(new SeriesPoint(item.X, item.Y));
}
foreach (var item in averagePressureCurvePtList)
{
_seriesAveragePressure.Points.Add(new SeriesPoint(item.X, item.Y));
}
this.RefreshCurveEvent?.Invoke(curveUpperPressure, curveLowerPressure, curveAveragePressure);
}
var minX = waterPointCalcList.Min(x => x.TotalFlow);
var maxX = waterPointCalcList.Max(x => x.TotalFlow);
var minY = waterPointCalcList.Min(x => x.EndPressure);
var maxY = waterPointCalcList.Max(x => x.EndPressure);
SetChartAxis(minX, maxX, minY, maxY);
this.chartControl1.EndInit();
}
//计算百分位数
private double CalculatePercentile(List sortedData, double percentile)
{
int n = sortedData.Count;
double index = (n - 1) * percentile;
int lower = (int)Math.Floor(index);
int upper = (int)Math.Ceiling(index);
double fraction = index - lower;
return sortedData[lower] * (1 - fraction) + sortedData[upper] * fraction;
}
#region Set Axis
///
/// 设置图表轴
///
private void SetChartAxis(double minX, double maxX, double minY, double maxY)
{
var coordinate = Yw.WinFrmUI.Phart.UniversalCoordinate.CalcCoordinate(minX, maxX, minY, maxY);
if (coordinate == null)
{
_xyDiagram.AxisX.Visibility = DefaultBoolean.False;
_xyDiagram.AxisX.GridLines.Visible = false;
_xyDiagram.AxisY.Visibility = DefaultBoolean.False;
_xyDiagram.AxisY.GridLines.Visible = false;
return;
}
if (coordinate.CoordMinX + coordinate.CoordSpaceX * coordinate.GridNumberX < maxX * 1.05)
coordinate.GridNumberX++;
//计算刻度 X
var axis_x_labels = new List();
var display_x = coordinate.CoordMinX;
for (int i = 0; i < coordinate.GridNumberX + 1; i++)
{
axis_x_labels.Add(new CustomAxisLabel(display_x.ToString("N0"), display_x));
display_x = display_x + coordinate.CoordSpaceX;
}
_xyDiagram.AxisX.CustomLabels.Clear();
_xyDiagram.AxisX.CustomLabels.AddRange(axis_x_labels.ToArray());
_xyDiagram.AxisX.Visibility = DefaultBoolean.True;
_xyDiagram.AxisX.GridLines.Visible = true;
//计算刻度 Y
var axis_y_labels = new List();
var display_y = coordinate.CoordMinY + coordinate.CoordSpaceY * coordinate.StartLineNoY;
for (int i = coordinate.StartLineNoY; i < coordinate.EndLineNoY + 1; i++)
{
axis_y_labels.Add(new CustomAxisLabel(display_y.ToString(), display_y));
display_y = display_y + coordinate.CoordSpaceY;
}
_xyDiagram.AxisY.CustomLabels.Clear();
_xyDiagram.AxisY.CustomLabels.AddRange(axis_y_labels.ToArray());
_xyDiagram.AxisY.Visibility = DefaultBoolean.True;
_xyDiagram.AxisY.GridLines.Visible = true;
_xyDiagram.AxisY.SetAxisRange(coordinate.CoordMinX, coordinate.DispMaxX());
_xyDiagram.AxisY.SetAxisRange(coordinate.DispMinY(), coordinate.DispMaxY());
}
#endregion
}
}