409 lines
10 KiB
C#
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;
|
|
}
|
|
}
|