📄 chartbox.cs
字号:
originX = (int) (mRegion.X+mRegion.Width*0.76);
originY = (int) (mRegion.Y+sf.Height+12);
width = (int) (mRegion.Width*0.22);
height = (int) (mRegion.Height-sf.Height-20);
mLegendArea = new Rectangle(originX,originY,width,height);
}
else
{
int originX = (int) (mRegion.X+mRegion.Width*0.02);
int originY = (int) (mRegion.Y+sf.Height+12);
int width = (int) (mRegion.Width*0.96);
int height = (int) (mRegion.Height-sf.Height-20);
mMapArea = new Rectangle(originX,originY,width,height);
}
}
private void drawBars(Graphics g)
{
float overlappingFactor = 0.2f;
float fillSliceFactor = 0.9f;
int theNumberOfCategories = mXCategories.Length;
if (theNumberOfCategories==0) return;
int theNumberOfSeries = mYSeries.Count;
float sliceWidth = (float)mMapArea.Width/theNumberOfCategories;
float recWidth = fillSliceFactor*sliceWidth/(theNumberOfSeries*(1-overlappingFactor)+overlappingFactor);
float recOffset = recWidth*(1-overlappingFactor);
float zeroPosition = calculateZeroPosition();
for (int i=0;i<mYSeries.Count;i++)
{
double[] theValues = (double[]) mYSeries[i];
for (int j=0;j<theNumberOfCategories;j++)
{
double theValue = 0;
if (j<theValues.Length)
theValue = theValues[j];
float recHeight = calculateBarHeight(theValue);
if (theValue>=0)
{
g.FillRectangle(new SolidBrush(mSeriesColors[i]),mMapArea.X+j*sliceWidth+sliceWidth*(1-fillSliceFactor)/2+i*recOffset,zeroPosition-recHeight,recWidth,recHeight);
g.DrawRectangle(new Pen(Color.Black,1),mMapArea.X+j*sliceWidth+sliceWidth*(1-fillSliceFactor)/2+i*recOffset,zeroPosition-recHeight,recWidth,recHeight);
}
else
{
g.FillRectangle(new SolidBrush(mSeriesColors[i]),mMapArea.X+j*sliceWidth+sliceWidth*(1-fillSliceFactor)/2+i*recOffset,zeroPosition,recWidth,recHeight);
g.DrawRectangle(new Pen(Color.Black,1),mMapArea.X+j*sliceWidth+sliceWidth*(1-fillSliceFactor)/2+i*recOffset,zeroPosition,recWidth,recHeight);
}
}
}
}
private void drawBarsDiagram(Graphics g)
{
drawTitle(g);
calculateBarsMapArea(g);
drawBarsMapArea(g);
drawLabels(g);
drawBars(g);
if (mShowLegend)
drawBarsLegend(g);
}
private void drawBarsLegend(Graphics g)
{
g.DrawRectangle(new Pen(Color.Black,1),mLegendArea);
for (int i=0;i<mYSeries.Count;i++)
{
SizeF sf = g.MeasureString(mSeriesNames[i],mLabelFont);
int yPos = mLegendArea.Y + 8 + i*20;
g.FillRectangle(new SolidBrush(mSeriesColors[i]),mLegendArea.X+4,yPos,6,6);
g.DrawString(mSeriesNames[i],mLabelFont,new SolidBrush(Color.Black),mLegendArea.X+11,yPos+3-sf.Height/2);
}
}
private void drawBarsMapArea(Graphics g)
{
g.FillRectangle(new SolidBrush(mMapAreaColor),mMapArea);
g.DrawRectangle(new Pen(Color.Black,1),mMapArea);
int theNumberOfCategories = mXCategories.Length;
if (theNumberOfCategories==0) return;
float sliceWidth = (float)mMapArea.Width/theNumberOfCategories;
for (int i=0;i<theNumberOfCategories;i++)
{
SizeF sf = g.MeasureString(mXCategories[i],mLabelFont);
g.DrawString(mXCategories[i],mLabelFont,new SolidBrush(Color.Black),mMapArea.X+i*sliceWidth+sliceWidth/2-sf.Width/2,mRegion.Bottom-2*sf.Height-6);
if (i!= theNumberOfCategories-1)
g.DrawLine(new Pen(Color.Black,1),mMapArea.X+(i+1)*sliceWidth,mMapArea.Top,mMapArea.X+(i+1)*sliceWidth,mMapArea.Bottom);
}
}
private void drawLabels(Graphics g)
{
resolveRange();
SizeF sf = g.MeasureString(mXLabel,mLabelFont);
g.DrawString(mXLabel,mLabelFont,new SolidBrush(Color.Black),mMapArea.X+mMapArea.Width/2-sf.Width/2,mRegion.Bottom-sf.Height-3);
float step = Math.Min(Math.Abs(mMinY),Math.Abs(mMaxY))/2f;
if (mMaxY!=0 && mMinY!=0)
step = Math.Min(Math.Abs(mMinY),Math.Abs(mMaxY))/2f;
else if (mMaxY!=0 && mMinY==0)
step = Math.Abs(mMaxY)/4f;
else if (mMaxY==0 && mMinY!=0)
step = Math.Abs(mMinY)/4f;
else
return;
for ( float i=mMinY;i<=mMaxY;i+=step)
{
string numLabel = i.ToString("#,##0.#");
sf = g.MeasureString(numLabel,mLabelFont);
float theYPosition = calculatePosition(i);
g.DrawString(numLabel,mLabelFont,new SolidBrush(Color.Black),mMapArea.Left-2-sf.Width,theYPosition-sf.Height/2);
if (i!=mMinY && i!=mMaxY)
g.DrawLine(new Pen(Color.DarkGray,1),mMapArea.Left,theYPosition,mMapArea.Right,theYPosition);
}
}
private void drawPie(Graphics g)
{
if (mYSeries.Count == 0) return;
int theNumberOfCategories = mXCategories.Length;
double[] theValues = mYSeries[0] as double[];
double theSum = 0;
for (int i=0;i<theNumberOfCategories;i++)
{
double x = 0;
if (i<theValues.Length)
x = Math.Abs(theValues[i]);
theSum += x;
}
if (theSum==0) return;
int pieRecWidth = (int) (Math.Min(mMapArea.Width,mMapArea.Height)*0.82f);
Rectangle pieRectangle = new Rectangle(mMapArea.X + (mMapArea.Width-pieRecWidth)/2,mMapArea.Y + (mMapArea.Height-pieRecWidth)/2,pieRecWidth,pieRecWidth);
int colorRedStep = (int)((255-mSeriesColors[0].R)/theNumberOfCategories);
int colorGreenStep = (int)((255-mSeriesColors[0].G)/theNumberOfCategories);
int colorBlueStep = (int)((255-mSeriesColors[0].B)/theNumberOfCategories);
mPieColors = new Color[theNumberOfCategories];
float currentAngle = 0;
for (int i=0;i<theNumberOfCategories;i++)
{
double x = 0;
if (i<theValues.Length)
x = Math.Abs(theValues[i]);
mPieColors[i] = Color.FromArgb( mSeriesColors[0].R+i*colorRedStep,mSeriesColors[0].G+i*colorGreenStep,mSeriesColors[0].B+i*colorBlueStep);
float theAngle = (float) (360 * Math.Abs(x) / theSum) ;
float percentage = (float) (Math.Abs(x) / theSum) ;
g.FillPie(new SolidBrush(mPieColors[i]),pieRectangle,currentAngle,theAngle);
g.DrawPie(new Pen(Color.Black,1),pieRectangle,currentAngle,theAngle);
float labelAngle = currentAngle + theAngle/2;
int labelRadius = pieRecWidth/2 + 1;
string labelString = XCategories[i] + " (" + percentage.ToString("#0.#%") + ")";
float labelX = (float)(pieRectangle.X + pieRectangle.Width/2 + labelRadius*Math.Cos(6.28*labelAngle/360)) ;
float labelY = (float)(pieRectangle.Y + pieRectangle.Height/2 + labelRadius*Math.Sin(6.28*labelAngle/360)) ;
SizeF sf = g.MeasureString(labelString,mLabelFont);
if (labelX < pieRectangle.X + pieRectangle.Width/2)
labelX = labelX - sf.Width;
if (labelY < pieRectangle.Y + pieRectangle.Height/2)
labelY = labelY - sf.Height;
if (percentage>0.01)
g.DrawString(labelString,mLabelFont,new SolidBrush(Color.Black),labelX,labelY);
currentAngle += theAngle;
}
}
private void drawPieDiagram(Graphics g)
{
drawTitle(g);
calculatePieMapArea(g);
drawPieMapArea(g);
drawPie(g);
if (mShowLegend)
drawPieLegend(g);
}
private void drawPieLegend(Graphics g)
{
g.DrawRectangle(new Pen(Color.Black,1),mLegendArea);
if (XCategories.Length==0 || mYSeries.Count == 0) return;
double[] theValues = mYSeries[0] as double[];
for (int i=0;i<XCategories.Length;i++)
{
double x = 0;
if (i<theValues.Length)
x = Math.Abs(theValues[i]);
string legendText = XCategories[i] + " (" + x.ToString("#0.##") + ")";
SizeF sf = g.MeasureString(legendText,mLabelFont);
int yPos = mLegendArea.Y + 8 + i*20;
g.FillRectangle(new SolidBrush(mPieColors[i]),mLegendArea.X+4,yPos,6,6);
g.DrawString(legendText,mLabelFont,new SolidBrush(Color.Black),mLegendArea.X+11,yPos+3-sf.Height/2);
}
}
private void drawPieMapArea(Graphics g)
{
g.FillRectangle(new SolidBrush(this.mMapAreaColor),mMapArea);
}
private void drawTitle(Graphics g)
{
SizeF sf = g.MeasureString(mTitle,mTitleFont);
g.DrawString(mTitle,mTitleFont,new SolidBrush(Color.Black),mRegion.X+mRegion.Width/2-sf.Width/2,mRegion.Y+5);
}
private void resolveRange()
{
double maxValue = 0;
double minValue = 0;
for (int i=0;i<mYSeries.Count;i++)
{
double[] theValues = (double[])mYSeries[i];
double[] tmp = new double[theValues.Length];
Array.Copy(theValues,0,tmp,0,theValues.Length);
Array.Sort(tmp);
maxValue = Math.Max(maxValue,tmp[tmp.Length-1]);
minValue = Math.Min(minValue,tmp[0]);
}
if (maxValue==0 && minValue==0)
{
maxValue = 100;
minValue = 0;
}
else if (maxValue!=0 && minValue==0)
{
int theBase = (int)Math.Ceiling(Math.Log10(maxValue));
mMaxY = (float)Math.Pow(10,theBase);
if (maxValue<=mMaxY/2) mMaxY=mMaxY/2;
}
else
{
int theBase = (int)Math.Max( Math.Ceiling(Math.Log10(Math.Abs(maxValue))),Math.Ceiling(Math.Log10(Math.Abs(minValue))) );
mMaxY = (float)Math.Pow(10,theBase);
mMinY = (float)Math.Pow(10,theBase)*Math.Sign(minValue);
if (maxValue<=mMaxY/2) mMaxY=mMaxY/2;
if (minValue>=mMinY/2) mMinY=mMinY/2;
}
}
#endregion
#region Private Properties
private float calculateBarHeight(double theValue)
{
double ratio = (double)mMapArea.Height/(mMaxY-mMinY);
return (float) Math.Abs(theValue*ratio);
}
private float calculatePosition(float x)
{
return calculateZeroPosition() - mMapArea.Height*x/(mMaxY-mMinY);
}
private float calculateZeroPosition()
{
return (float)(mMapArea.Top+mMapArea.Height*mMaxY/(mMaxY-mMinY));
}
#endregion
#region Creator
/// <summary>
/// Initializes a new instance of the ChartBox class.
/// </summary>
/// <param name="x">x-position of the new ChartBox</param>
/// <param name="y">y-position of the new ChartBox</param>
/// <param name="width">Width of the new ChartBox</param>
/// <param name="height">Height of the new ChartBox</param>
/// <param name="parent">Parent of the new ChartBox</param>
public ChartBox(int x,int y, int width, int height, DaPrintDocument parent)
{
document = parent;
mRegion = new Rectangle(x,y,width,height);
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -