📄 graph.cs
字号:
virtual protected bool CalculateQudarantToShow()
{
// Based on the minimum value sof x and y data that needs to be displayed
// we can decided how many quadrants needs to be displayed.
if (MinXDataValue < 0 && MaxXDataValue > 0 &&
MinYDataValue < 0 && MaxYDataValue > 0)
{
this.m_QuadrantToShow = QuadrantType.Quad1234;
}
else if (MinXDataValue >=0 && MinYDataValue >= 0)
{
this.m_QuadrantToShow = QuadrantType.Quad1;
}
else if (MaxXDataValue <= 0 && MinYDataValue >= 0)
{
this.m_QuadrantToShow = QuadrantType.Quad2;
}
else if (MaxXDataValue <= 0 && MinYDataValue <= 0)
{
this.m_QuadrantToShow = QuadrantType.Quad3;
}
else if (MinXDataValue >= 0 && MaxYDataValue <= 0)
{
this.m_QuadrantToShow = QuadrantType.Quad4;
}
else if (MinYDataValue >= 0 && MinXDataValue < 0 && MaxXDataValue > 0)
{
this.m_QuadrantToShow = QuadrantType.Quad12;
}
else if (MaxXDataValue <= 0 && MinYDataValue < 0 && MaxYDataValue > 0)
{
this.m_QuadrantToShow = QuadrantType.Quad23;
}
else if (MinYDataValue <= 0 && MinXDataValue < 0 && MaxXDataValue > 0)
{
this.m_QuadrantToShow = QuadrantType.Quad34;
}
else if (MinXDataValue >= 0 && MinYDataValue < 0 && MaxYDataValue > 0)
{
this.m_QuadrantToShow = QuadrantType.Quad14;
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected bool DrawGraphTitle()
{
PointF pt;
try
{
// For now we hard the value of 5 from top.
pt = new PointF();
pt.X = (float)((this.Width/2.0) - this.m_fTitleWidth/2.0);
pt.Y = (float)(this.TitlePaddingFromTop);
this.m_obGraphics.DrawString(Title, TitleFont, new SolidBrush(TitleColor), pt);
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
return false;
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
virtual protected bool DrawAxisLabels()
{
/*
try
{
this.m_obGraphics.DrawString(this.XAxisLabel, this.XAxisLabelFont, new SolidBrush(XAxisLabelColor), this.m_XAxisLabelLocation);
// YAxis will be drawn vertical.
StringFormat drawFormat = new StringFormat();
drawFormat.FormatFlags = StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
this.m_obGraphics.DrawString(this.YAxisLabel, this.YAxisLabelFont, new SolidBrush(YAxisLabelColor), this.m_YAxisLabelLocation, drawFormat);
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
return false;
}
*/
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
internal bool CalculateChartDimensions()
{
bool bRet = true;
// Perform calculations for dimensions common to
// all types of charts.
bRet = this.CalculateCommonDimensions();
if (bRet == false)
{
Trace.WriteLine("Failed during calculations of common dimensions.");
return false;
}
bRet = this.CalculateSpecificDimensions();
if (bRet == false)
{
Trace.WriteLine("Failed during calculations of specific dimensions.");
return false;
}
// Perform calculatios fr diemensions that are specific
// to a certain type of chart.
return true;
}
/// <summary>
/// This method is used to perform calculations for diemnsions that are
/// common to all types of charts.
/// </summary>
/// <returns></returns>
internal bool CalculateCommonDimensions()
{
// First calculate some bounding rectangles.
m_ChartRectangle = new RectangleF();
m_TopLeftRectangle = new RectangleF();
m_TopRightRectangle = new RectangleF();
m_BottomLeftRectangle = new RectangleF();
m_BottomRightRectangle = new RectangleF();
m_TopMiddleRectangle = new RectangleF();
m_BottomMiddleRectangle = new RectangleF();
m_RightMiddleRectangle = new RectangleF();
m_LeftMiddleRectangle = new RectangleF();
m_ChartCenter = new PointF();
/* --- Inner Rectangle For Drawing Chart ---*/
m_ChartRectangle.X = LeftSpacing;
m_ChartRectangle.Y = TopSpacing;
m_ChartRectangle.Width = Width - (LeftSpacing + RightSpacing);
m_ChartRectangle.Height = Height - (TopSpacing + BottomSpacing);
/* --- Top Left Rectangle ---*/
m_TopLeftRectangle.X = 0.0F;
m_TopLeftRectangle.Y = 0.0F;
m_TopLeftRectangle.Width = LeftSpacing;
m_TopLeftRectangle.Height = TopSpacing;
/* -- Top Right Rectangle -- */
m_TopRightRectangle.X = Width - RightSpacing;
m_TopRightRectangle.Y = 0.0F;
m_TopRightRectangle.Width = RightSpacing;
m_TopRightRectangle.Height = TopSpacing;
/* -- Bottom Left Rectangle -- */
m_BottomLeftRectangle.X = 0.0F;
m_BottomLeftRectangle.Y = Height - BottomSpacing;
m_BottomLeftRectangle.Width = LeftSpacing;
m_BottomLeftRectangle.Height = BottomSpacing;
/* -- Bottom Right Rectangle -- */
m_BottomRightRectangle.X = Width - RightSpacing;
m_BottomRightRectangle.Y = Height - BottomSpacing;
m_BottomRightRectangle.Width = RightSpacing;
m_BottomRightRectangle.Height = BottomSpacing;
/* -- Top Middle Rectangle --*/
m_TopMiddleRectangle.X = m_ChartRectangle.X;
m_TopMiddleRectangle.Y = 0.0F;
m_TopMiddleRectangle.Width = m_ChartRectangle.Width;
m_TopMiddleRectangle.Height = TopSpacing;
/* -- Bottom middle rectangle -- */
m_BottomMiddleRectangle.X = m_TopMiddleRectangle.X;
m_BottomMiddleRectangle.Y = m_BottomLeftRectangle.Y;
m_BottomMiddleRectangle.Width = m_TopMiddleRectangle.Width;
m_BottomMiddleRectangle.Height = BottomSpacing;
/* -- Left Middle Rectangle -- */
m_LeftMiddleRectangle.X = 0.0F;
m_LeftMiddleRectangle.Y = TopSpacing;
m_LeftMiddleRectangle.Width = LeftSpacing;
m_LeftMiddleRectangle.Height = m_ChartRectangle.Height;
/* -- Right Middle Rectangle -- */
m_RightMiddleRectangle.X = m_TopRightRectangle.X;
m_RightMiddleRectangle.Y = TopSpacing;
m_RightMiddleRectangle.Width = RightSpacing;
m_RightMiddleRectangle.Height = m_ChartRectangle.Height;
/* -- Chart Center Rectangle -- */
m_ChartCenter.X = m_ChartRectangle.X + m_ChartRectangle.Width/2.0F;
m_ChartCenter.Y = m_ChartRectangle.Y + m_ChartRectangle.Height/2.0F;
/* -- Calculate title dimensions --*/
CalculateTitleDimensions();
/* -- Calculate dimensions for drawing legends --*/
CalculateLegendDimensions();
return true;
}
/// <summary>
/// This method is used to perform calculations that are specific to
/// a particular type of chart. Every derived class should override this
/// method to perfom diemnsion calculations for that type.
/// </summary>
/// <returns></returns>
protected virtual bool CalculateSpecificDimensions()
{
return true;
}
private void CalculateTitleDimensions()
{
SizeF strSize;
// Caculate the X & Y cordinate of location of drawing the title.
strSize = this.m_obGraphics.MeasureString(this.m_strTitle, this.m_TitleFont);
this.m_fTitleHeight = strSize.Height;
this.m_fTitleWidth = strSize.Width;
}
/// <summary>
/// This method is used to perform calculations for diemnsions for rectangle
/// that will house the legends represeting different data points on the chart.
/// </summary>
private void CalculateLegendDimensions()
{
m_iMaxLegendsInRow = this.DataPointCount;
// Depending on the alignment of the legend diemensions chosen by user
// call for horizontal or vertical caculations.
this.m_LegendRectangle = new RectangleF();
switch (this.m_LegendAlignment)
{
case LegendAlignmentType.Horizontal:
this.CalculateLegendsRectangleH();
break;
case LegendAlignmentType.Vertical:
this.CalculateLegendsRectangleV();
break;
}
RectangleF srcRect = m_ChartRectangle;
m_LegendRectangle.Width = m_fLegendRectWidth;
m_LegendRectangle.Height = m_fLegendRectHeight;
// Depending on the location of the legend, calculate the rectangle.
if (this.m_LegendLocation == LegendLocationType.OutsideChart)
{
switch(this.m_LegendPosition)
{
case PositionType.Right:
srcRect = this.m_RightMiddleRectangle;
break;
case PositionType.Bottom:
srcRect = m_BottomMiddleRectangle;
break;
case PositionType.Left:
srcRect = this.m_LeftMiddleRectangle;
break;
case PositionType.Top:
srcRect = this.m_TopMiddleRectangle;
break;
default:
throw new ArgumentException("Invalid legend position type specified", "LegendPosition");
}
}
this.CreateLegendsRectangle(m_fLegendRectWidth, m_fLegendRectHeight, srcRect);
}
/// <summary>
///
/// </summary>
protected virtual void CalculateLegendsRectangleH()
{
// If marker height is greater than the max text string height then
// use that to caluclate the rectangle height otherwise use
// maximum text string height.
// Also adjust the legend widths and heights accrodingly.
if (this.m_fMaxLegendTextHeight > m_sLegendHeight)
{
m_sLegendHeight = (short)m_fMaxLegendTextHeight;
m_sLegendWidth = m_sLegendHeight;
}
// Width = Buffer + LegendWidth + TextSpacing + MaxTextWidth + Buffer
m_fLegendRectWidth = this.m_sLegendWidth;
m_fLegendRectWidth += this.m_sLegendTextSpacing;
m_fLegendRectWidth += this.m_fMaxLegendTextWidth;
m_fLegendRectWidth += m_sLegendsBuffer;
m_fLegendRectWidth += m_sLegendsBuffer;
m_fLegendRectWidth *= DataPointCount;
// If the total width is more than axis span, create multiple
// rows for legends.
if (m_fLegendRectWidth > m_ChartRectangle.Width)
{
m_bMultiRowHorizontalLegends = true;
float fTemp = m_fLegendRectWidth / m_ChartRectangle.Width;
m_sLegendRowCount = (short)fTemp;
if (fTemp > m_sLegendRowCount)
{
m_sLegendRowCount++;
}
// Recalculate the width by dividing the width based on N number of rows.
fTemp = (float)DataPointCount/(float)m_sLegendRowCount;
int nCols = (int)fTemp;
if (fTemp > nCols)
{
nCols++;
}
m_iMaxLegendsInRow = nCols;
m_fLegendRectWidth = this.m_sLegendWidth;
m_fLegendRectWidth += this.m_sLegendTextSpacing;
m_fLegendRectWidth += this.m_fMaxLegendTextWidth;
m_fLegendRectWidth += m_sLegendsBuffer;
m_fLegendRectWidth += m_sLegendsBuffer;
m_fLegendRectWidth *= nCols;
}
m_fLegendRectHeight = 0.0F;
m_fLegendRectHeight += m_sLegendRowCount*(m_sLegendHeight + m_sLegendsBuffer);
m_fLegendRectHeight += m_sLegendsBuffer;
}
/// <summary>
///
/// </summary>
protected virtual void CalculateLegendsRectangleV()
{
m_fLegendRectHeight = 0.0F;
// If marker height is greater than the max text string height then
// use that to caluclate the rectangle height otherwise use
// maximum text string height.
// Also adjust the legend widths and heights accrodingly.
if (this.m_fMaxLegendTextHeight > m_sLegendHeight)
{
m_sLegendHeight = (short)m_fMaxLegendTextHeight;
m_sLegendWidth = m_sLegendHeight;
}
m_fLegendRectHeight += DataPointCount * m_sLegendHeight;
m_fLegendRectHeight += DataPointCount * this.m_sVertcalLegendSpacing;
m_fLegendRectHeight += 2;
// Width = Buffer + LegendWidth + TextSpacing + MaxTextWidth + Buffer
m_fLegendRectWidth = this.m_sLegendWidth;
m_fLegendRectWidth += this.m_sLegendTextSpacing;
m_fLegendRectWidth += this.m_fMaxLegendTextWidth;
m_fLegendRectWidth += m_sLegendsBuffer;
m_fLegendRectWidth += m_sLegendsBuffer;
}
/// <summary>
///
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
private void CreateLegendsRectangle(float fWidth, float fHeight, RectangleF srcRect)
{
switch(this.m_LegendPosition)
{
case PositionType.Right:
m_LegendRectangle.X = srcRect.X + srcRect.Width - (m_sLegendsBuffer + fWidth);
m_LegendRectangle.Y = srcRect.Y + m_sLegendsBuffer;
break;
case PositionType.Left:
m_LegendRectangle.X = srcRect.X + m_sLegendsBuffer;
m_LegendRectangle.Y = srcRect.Y + m_sLegendsBuffer;
break;
case PositionType.Bottom:
m_LegendRectangle.X = srcRect.X + (srcRect.Width - fWidth)/2.0F;
m_LegendRectangle.Y = Height - (m_sLegendsBuffer + fHeight);
break;
case PositionType.Top:
m_LegendRectangle.X = srcRect.X + (srcRect.Width - fWidth)/2.0F;
if (this.LegendLocation == LegendLocationType.InsideChart)
{
m_LegendRectangle.Y = srcRect.Y + m_sLegendsBuffer;
}
else
{
m_LegendRectangle.Y = srcRect.Y + srcRect.Height - (fHeight + m_sLegendsBuffer);
}
break;
default:
throw new ArgumentException("Invalid legend position type specified", "LegendPosition");
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private bool DrawGraph()
{
this.SetBackground(this.m_obGraphics, this.m_BackgroundType);
// Process the data.
ProcessChartData();
// Determine what quadarants will be show.
CalculateQudarantToShow();
// Calculate some dimension values for later use.
CalculateChartDimensions();
// Draw the compnay logo. IT is very important that
// you call this method after diemnesions have been
// calculated because the method depends on those to
// position the logo.
DrawLogo();
// Calculate all the required chart dimensions.
// Draw the title
DrawGraphTitle();
// Draw the axis.
DrawGraphAxis(true);
DrawData();
if (this.HasLegends)
{
DrawLegends();
}
// Draw the axis.
// Turn off the grid drawing now.
DrawGraphAxis(false);
// If the flag for drawing border has been set, then draw that.
if (this.m_bHasBorder)
{
DrawBorder();
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
virtual public bool DrawGraph(ImageFormat imgFormat, ref Stream obOutputStream)
{
bool bRet = false;
// Cretae the graphics object on which we will draw the charts.
bRet = this.CreateGraphics();
DrawGraph();
try
{
this.m_obGraphics.DrawImage(this.m_obBitmap, 0, 0);
this.m_obBitmap.Save(obOutputStream, imgFormat);
bRet = true;
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
throw ex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -