📄 bargraph.cs
字号:
if (lblFormat != null) lblFormat.Dispose();
if (pen != null) pen.Dispose();
if (sfVLabel != null) sfVLabel.Dispose();
}
}
//*********************************************************************
//
// This method draws x axis and all x labels
//
//*********************************************************************
private void DrawXLabelArea(Graphics graph)
{
Font lblFont = null;
SolidBrush brs = null;
StringFormat lblFormat = null;
Pen pen = null;
try
{
lblFont = new Font(_fontFamily, _labelFontSize);
brs = new SolidBrush(_fontColor);
lblFormat = new StringFormat();
pen = new Pen(_fontColor);
lblFormat.Alignment = StringAlignment.Center;
// Draw x axis
graph.DrawLine(pen, _xOrigin, _yOrigin + _graphHeight, _xOrigin + _graphWidth, _yOrigin + _graphHeight);
float currentX;
float currentY = _yOrigin + _graphHeight + 2.0f; // All x labels are drawn 2 pixels below x-axis
float labelWidth = _barWidth + _spaceBtwBars; // Fits exactly below the bar
int i = 0;
// Draw x labels
foreach(ChartItem item in DataPoints)
{
currentX = _xOrigin + (i * labelWidth);
RectangleF recLbl = new RectangleF(currentX, currentY, labelWidth, lblFont.Height);
string lblString = _displayLegend ? item.Label : item.Description; // Decide what to show: short or long
graph.DrawString(lblString, lblFont, brs, recLbl, lblFormat);
i++;
}
}
finally
{
if (lblFont != null) lblFont.Dispose();
if (brs != null) brs.Dispose();
if (lblFormat != null) lblFormat.Dispose();
if (pen != null) pen.Dispose();
}
}
//*********************************************************************
//
// This method determines where to place the legend box.
// It draws the legend border, legend description, and legend color code.
//
//*********************************************************************
private void DrawLegend(Graphics graph)
{
Font lblFont = null;
SolidBrush brs = null;
StringFormat lblFormat = null;
Pen pen = null;
try
{
lblFont = new Font(_fontFamily, _legendFontSize);
brs = new SolidBrush(_fontColor);
lblFormat = new StringFormat();
pen = new Pen(_fontColor);
lblFormat.Alignment = StringAlignment.Near;
// Calculate Legend drawing start point
float startX = _xOrigin + _graphWidth + _graphLegendSpacer;
float startY = _yOrigin;
float xColorCode = startX + _spacer;
float xLegendText = xColorCode + _legendRectangleSize + _spacer;
float legendHeight = 0.0f;
for(int i=0; i<DataPoints.Count; i++)
{
ChartItem point = DataPoints[i];
string text = point.Description + " (" + point.Label + ")";
float currentY = startY + _spacer + (i * (lblFont.Height + _spacer));
legendHeight += lblFont.Height + _spacer;
// Draw legend description
graph.DrawString(text, lblFont, brs, xLegendText, currentY, lblFormat);
// Draw color code
graph.FillRectangle(new SolidBrush(DataPoints[i].ItemColor), xColorCode, currentY + 3f, _legendRectangleSize, _legendRectangleSize);
}
// Draw legend border
graph.DrawRectangle(pen, startX, startY, _legendWidth, legendHeight + _spacer);
}
finally
{
if (lblFont != null) lblFont.Dispose();
if (brs != null) brs.Dispose();
if (lblFormat != null) lblFormat.Dispose();
if (pen != null) pen.Dispose();
}
}
//*********************************************************************
//
// This method calculates all measurement aspects of the bar graph from the given data points
//
//*********************************************************************
private void CalculateGraphDimension()
{
FindLongestTickValue();
// Need to add another character for spacing; this is not used for drawing, just for calculation
_longestTickValue += "0";
_maxTickValueWidth = CalculateImgFontWidth(_longestTickValue, _labelFontSize, FontFamily);
float leftOffset = _spacer + _maxTickValueWidth;
float rtOffset = 0.0f;
if (_displayLegend)
{
_legendWidth = _spacer + _legendRectangleSize + _spacer + _maxLabelWidth + _spacer;
rtOffset = _graphLegendSpacer + _legendWidth + _spacer;
}
else
rtOffset = _spacer; // Make graph in the middle
_graphHeight = _totalHeight - _topBuffer - _bottomBuffer; // Buffer spaces are used to print labels
_graphWidth = _totalWidth - leftOffset - rtOffset;
_xOrigin = leftOffset;
_yOrigin = _topBuffer;
// Once the correct _maxValue is determined, then calculate _scaleFactor
_scaleFactor = _maxValue / _graphHeight;
}
//*********************************************************************
//
// This method determines the longest tick value from the given data points.
// The result is needed to calculate the correct graph dimension.
//
//*********************************************************************
private void FindLongestTickValue()
{
float currentTick;
string tickString;
for (int i=0; i<_yTickCount; i++)
{
currentTick = _maxValue - i*_yTickValue;
tickString = currentTick.ToString("#,###.##");
if (_longestTickValue.Length < tickString.Length)
_longestTickValue = tickString;
}
}
//*********************************************************************
//
// This method calculates the image width in pixel for a given text
//
//*********************************************************************
private float CalculateImgFontWidth(string text, int size, string family)
{
Bitmap bmp = null;
Graphics graph = null;
Font font = null;
try
{
font = new Font(family, size);
// Calculate the size of the string.
bmp = new Bitmap(1,1,PixelFormat.Format32bppArgb);
graph = Graphics.FromImage(bmp);
SizeF oSize = graph.MeasureString(text, font);
return oSize.Width;
}
finally
{
if (graph != null) graph.Dispose();
if (bmp != null) bmp.Dispose();
if (font != null) font.Dispose();
}
}
//*********************************************************************
//
// This method creates abbreviation from long description; used for making legend
//
//*********************************************************************
private string MakeShortLabel(string text)
{
string label = text;
if (text.Length > 2)
{
int midPostition = Convert.ToInt32(Math.Floor(text.Length/2));
label = text.Substring(0,1) + text.Substring(midPostition, 1) + text.Substring(text.Length-1,1);
}
return label;
}
//*********************************************************************
//
// This method calculates the max value and each tick mark value for the bar graph.
//
//*********************************************************************
private void CalculateTickAndMax()
{
float tempMax = 0.0f;
// Give graph some head room first about 10% of current max
_maxValue *= 1.1f;
if (_maxValue != 0.0f)
{
// Find a rounded value nearest to the current max value
// Calculate this max first to give enough space to draw value on each bar
double exp = Convert.ToDouble(Math.Floor(Math.Log10(_maxValue)));
tempMax = Convert.ToSingle(Math.Ceiling(_maxValue / Math.Pow(10, exp)) * Math.Pow(10, exp));
}
else
tempMax = 1.0f;
// Once max value is calculated, tick value can be determined; tick value should be a whole number
_yTickValue = tempMax / _yTickCount;
double expTick = Convert.ToDouble(Math.Floor(Math.Log10(_yTickValue)));
_yTickValue = Convert.ToSingle(Math.Ceiling(_yTickValue / Math.Pow(10, expTick)) * Math.Pow(10, expTick));
// Re-calculate the max value with the new tick value
_maxValue = _yTickValue * _yTickCount;
}
//*********************************************************************
//
// This method calculates the height for each bar in the graph
//
//*********************************************************************
private void CalculateSweepValues()
{
// Called when all values and scale factor are known
// All values calculated here are relative from (_xOrigin, _yOrigin)
int i = 0;
foreach(ChartItem item in DataPoints)
{
// This implementation does not support negative value
if (item.Value >= 0) item.SweepSize = item.Value/_scaleFactor;
// (_spaceBtwBars/2) makes half white space for the first bar
item.StartPos = (_spaceBtwBars/2) + i * (_barWidth+_spaceBtwBars);
i++;
}
}
//*********************************************************************
//
// This method calculates the width for each bar in the graph
//
//*********************************************************************
private void CalculateBarWidth(int dataCount, float barGraphWidth)
{
// White space between each bar is the same as bar width itself
_barWidth = barGraphWidth / (dataCount * 2); // Each bar has 1 white space
_spaceBtwBars = _barWidth;
}
//*********************************************************************
//
// This method assigns default value to the bar graph properties and is only
// called from BarGraph constructors
//
//*********************************************************************
private void AssignDefaultSettings()
{
// default values
_totalWidth = 700f;
_totalHeight = 450f;
_fontFamily = "Verdana";
_backColor = Color.White;
_fontColor = Color.Black;
_topBuffer = 30f;
_bottomBuffer = 30f;
_yTickCount = 2;
_displayLegend = false;
_displayBarData = false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -