CPF/CPF.ReoGrid/Chart/AxisChart.cs
2024-06-24 10:15:59 +08:00

409 lines
10 KiB
C#

using System;
using CPF.Drawing;
using CPF.ReoGrid.Drawing;
namespace CPF.ReoGrid.Chart
{
public abstract class AxisChart : Chart
{
public virtual AxisDataInfo PrimaryAxisInfo { get; set; }
public virtual AxisDataInfo SecondaryAxisInfo { get; set; }
public virtual AxisInfoView HorizontalAxisInfoView { get; set; }
public virtual AxisInfoView VerticalAxisInfoView { get; set; }
public virtual AxisGuideLinePlotView GuideLineBackgroundView { get; set; }
public virtual bool ShowHorizontalGuideLines { get; set; }
public virtual bool ShowVerticalGuideLines { get; set; }
public AxisChart()
{
this.ShowHorizontalGuideLines = true;
this.ShowVerticalGuideLines = false;
this.PrimaryAxisInfo = new AxisDataInfo();
this.SecondaryAxisInfo = null;
Rect bounds = this.PlotViewContainer.Bounds;
Rect clientBounds = this.ClientBounds;
base.AddPlotViewLayer(this.GuideLineBackgroundView = this.CreateGuideLineBackgroundView(bounds));
this.Children.Add(this.HorizontalAxisInfoView = this.CreatePrimaryAxisSerialLabelView(bounds));
this.Children.Add(this.VerticalAxisInfoView = this.CreatePrimaryAxisCategoryLabelView(bounds));
}
protected virtual AxisGuideLinePlotView CreateGuideLineBackgroundView(Rect bodyBounds)
{
AxisGuideLinePlotView axisGuideLinePlotView = new AxisGuideLinePlotView(this);
float width = bodyBounds.Width;
float height = bodyBounds.Height;
axisGuideLinePlotView.Size = new Size(ref width, ref height);
return axisGuideLinePlotView;
}
protected virtual AxisInfoView CreatePrimaryAxisSerialLabelView(Rect bodyBounds)
{
return new AxisSerialLabelView(this, AxisTypes.Primary, AxisOrientation.Horizontal)
{
Bounds = this.GetDefaultHorizontalAxisInfoViewBounds(bodyBounds)
};
}
protected virtual Rect GetDefaultHorizontalAxisInfoViewBounds(Rect bodyBounds)
{
float x = bodyBounds.X;
float num = bodyBounds.Bottom + 6f;
float width = bodyBounds.Width;
float num2 = 24f;
return new Rect(ref x, ref num, ref width, ref num2);
}
protected virtual AxisInfoView CreatePrimaryAxisCategoryLabelView(Rect bodyBounds)
{
return new AxisCategoryLabelView(this, AxisTypes.Primary, AxisOrientation.Vertical)
{
Bounds = this.GetDefaultVerticalAxisInfoViewBounds(bodyBounds)
};
}
protected virtual Rect GetDefaultVerticalAxisInfoViewBounds(Rect bodyBounds)
{
float num = bodyBounds.X - 35f;
float num2 = bodyBounds.Y - 5f;
float num3 = 30f;
float num4 = bodyBounds.Height + 10f;
return new Rect(ref num, ref num2, ref num3, ref num4);
}
protected override void OnDataSourceChanged()
{
base.OnDataSourceChanged();
this.ResetDrawPoints();
this.UpdateDrawPoints();
}
protected override void OnDataChanged()
{
base.OnDataChanged();
this.UpdateDrawPoints();
}
protected override void UpdatePlotData()
{
WorksheetChartDataSource dataSource = this.DataSource;
bool flag = dataSource == null;
if (!flag)
{
double num = 0.0;
double num2 = 0.0;
bool flag2 = true;
for (int i = 0; i < dataSource.SerialCount; i++)
{
for (int j = 0; j < dataSource.CategoryCount; j++)
{
double? num3 = dataSource[i][j];
bool flag3 = num3 != null;
if (flag3)
{
bool flag4 = flag2;
if (flag4)
{
num = num3.Value;
num2 = num;
flag2 = false;
}
else
{
double num4 = num;
double? num5 = num3;
bool flag5 = num4 > num5.GetValueOrDefault() & num5 != null;
if (flag5)
{
num = num3.Value;
}
double num6 = num2;
num5 = num3;
bool flag6 = num6 < num5.GetValueOrDefault() & num5 != null;
if (flag6)
{
num2 = num3.Value;
}
}
}
}
}
this.UpdateAxisInfo(this.PrimaryAxisInfo, num, num2);
}
}
protected virtual void UpdateAxisInfo(AxisDataInfo ai, double minData, double maxData)
{
IDrawingContainer plotViewContainer = this.PlotViewContainer;
double range = maxData - minData;
ai.Levels = (int)Math.Ceiling((double)(plotViewContainer.Height / 30f));
bool flag = double.IsNaN((double)ai.Levels);
if (!flag)
{
bool flag2 = minData == maxData;
if (flag2)
{
bool flag3 = maxData == 0.0;
if (flag3)
{
maxData = (double)ai.Levels;
}
else
{
minData = 0.0;
}
}
int scaler;
double num = ChartUtility.CalcLevelStride(minData, maxData, ai.Levels, out scaler);
ai.Scaler = scaler;
bool flag4 = !ai.AutoMinimum;
if (flag4)
{
bool flag5 = this.AxisOriginToZero(minData, maxData, range);
if (flag5)
{
ai.Minimum = 0.0;
}
else
{
double num2 = minData % num;
bool flag6 = num2 == 0.0;
if (flag6)
{
bool flag7 = minData == 0.0;
if (flag7)
{
ai.Minimum = minData;
}
else
{
ai.Minimum = minData - num;
}
}
else
{
bool flag8 = minData < 0.0;
if (flag8)
{
ai.Minimum = minData - num - num2;
}
else
{
ai.Minimum = minData - num2;
}
}
}
}
bool flag9 = !ai.AutoMaximum;
if (flag9)
{
double num2 = maxData % num;
bool flag10 = num2 == 0.0;
if (flag10)
{
ai.Maximum = maxData + num;
}
else
{
ai.Maximum = maxData - num2 + num;
}
}
ai.Levels = (int)Math.Round((ai.Maximum - ai.Minimum) / num);
ai.LargeStride = num;
}
}
protected virtual void MeasureAxisRuler(AxisDataInfo info, double data)
{
bool flag = info.Minimum > data;
if (flag)
{
info.Minimum = data;
}
bool flag2 = info.Maximum < data;
if (flag2)
{
info.Maximum = data;
}
info.LargeStride = (info.Maximum - info.Minimum) / 5.0;
}
protected virtual bool AxisOriginToZero(double minData, double maxData, double range)
{
return ((maxData > 0.0 && minData > 0.0) || (maxData < 0.0 && minData < 0.0)) && Math.Abs(minData) < range;
}
public float ZeroWidth { get; protected set; }
public float ZeroHeight { get; protected set; }
internal PlotPointRow[] PlotDataPoints
{
get
{
return this.platRowPoints;
}
}
internal float[] PlotColumnPoints
{
get
{
return this.platColPoints;
}
}
protected virtual void ResetDrawPoints()
{
WorksheetChartDataSource dataSource = this.DataSource;
bool flag = dataSource != null;
if (flag)
{
bool flag2 = this.platRowPoints == null;
if (flag2)
{
this.platRowPoints = new PlotPointRow[dataSource.SerialCount];
}
else
{
bool flag3 = this.platRowPoints.Length != dataSource.SerialCount;
if (flag3)
{
Array.Resize<float>(ref this.platColPoints, dataSource.SerialCount);
}
}
for (int i = 0; i < dataSource.SerialCount; i++)
{
this.platRowPoints[i].columns = new PlotPointColumn[dataSource.CategoryCount];
}
bool flag4 = this.platColPoints == null;
if (flag4)
{
this.platColPoints = new float[dataSource.CategoryCount];
}
else
{
bool flag5 = this.platColPoints.Length != dataSource.CategoryCount;
if (flag5)
{
Array.Resize<float>(ref this.platColPoints, dataSource.CategoryCount);
}
for (int j = 0; j < dataSource.CategoryCount; j++)
{
this.platColPoints[j] = 0f;
}
}
}
else
{
for (int k = 0; k < this.platRowPoints.Length; k++)
{
PlotPointRow plotPointRow = this.platRowPoints[k];
for (int l = 0; l < plotPointRow.Length; l++)
{
this.platRowPoints[k][l] = 0f;
}
}
for (int m = 0; m < this.platColPoints.Length; m++)
{
this.platColPoints[m] = 0f;
}
}
}
protected virtual void UpdateDrawPoints()
{
WorksheetChartDataSource dataSource = this.DataSource;
bool flag = dataSource != null;
if (flag)
{
AxisDataInfo primaryAxisInfo = this.PrimaryAxisInfo;
bool flag2 = !double.IsNaN((double)primaryAxisInfo.Levels);
if (flag2)
{
int serialCount = dataSource.SerialCount;
int categoryCount = dataSource.CategoryCount;
double num = primaryAxisInfo.Maximum - primaryAxisInfo.Minimum;
Size size = this.PlotViewContainer.Size;
float num2 = size.Width / (float)categoryCount;
double num3 = (double)size.Height / num;
this.ZeroHeight = (float)((double)size.Height + (double)size.Height * primaryAxisInfo.Minimum / num);
this.ZeroWidth = (float)((double)size.Width * primaryAxisInfo.Minimum / num);
float num4 = size.Width / (float)categoryCount / 2f;
for (int i = 0; i < serialCount; i++)
{
WorksheetChartDataSerial serial = dataSource.GetSerial(i);
for (int j = 0; j < categoryCount; j++)
{
bool flag3 = i == 0;
if (flag3)
{
this.platColPoints[j] = num4 + (float)j * num2;
}
double? num5 = serial[j];
bool flag4 = num5 == null;
if (flag4)
{
this.platRowPoints[i][j] = PlotPointColumn.Nil;
}
else
{
this.platRowPoints[i][j] = (float)(num5 * num3).Value;
}
}
}
}
}
}
public override void OnBoundsChanged(Rect oldRect)
{
base.OnBoundsChanged(oldRect);
this.UpdatePlotData();
this.UpdateDrawPoints();
}
protected override void UpdateLayout()
{
base.UpdateLayout();
this.GuideLineBackgroundView.Bounds = this.PlotViewContainer.ClientBounds;
this.UpdateAxisLabelViewLayout(this.PlotViewContainer.Bounds);
}
protected virtual void UpdateAxisLabelViewLayout(Rect plotRect)
{
FloatingObject verticalAxisInfoView = this.VerticalAxisInfoView;
float x = this.ClientBounds.X;
float num = plotRect.Y - 5f;
float num2 = 30f;
float num3 = plotRect.Height + 10f;
verticalAxisInfoView.Bounds = new Rect(ref x, ref num, ref num2, ref num3);
FloatingObject horizontalAxisInfoView = this.HorizontalAxisInfoView;
x = plotRect.X;
num = plotRect.Bottom + 10f;
num2 = plotRect.Width;
num3 = 10f;
horizontalAxisInfoView.Bounds = new Rect(ref x, ref num, ref num2, ref num3);
}
protected override Rect GetPlotViewBounds(Rect bodyBounds)
{
Rect plotViewBounds = base.GetPlotViewBounds(bodyBounds);
float num = plotViewBounds.X + 30f + 10f;
float y = plotViewBounds.Y;
float num2 = plotViewBounds.Width - 30f - 10f;
float num3 = plotViewBounds.Height - 10f;
return new Rect(ref num, ref y, ref num2, ref num3);
}
private PlotPointRow[] platRowPoints = null;
private float[] platColPoints = null;
}
}