⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bargraph2d.cs

📁 C#自定义查询控件
💻 CS
字号:
// Disclaimer and Copyright Information
// BarGraph2D.cs : 
//
// All rights reserved.
//
// Written by Pardesi Services, LLC
// Version 1.0.1
//
// Distribute freely, except: don't remove our name from the source or
// documentation (don't take credit for my work), mark your changes (don't
// get me blamed for your possible bugs), don't alter or remove this
// notice.
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// softomatix@CommonComponent.com
///////////////////////////////////////////////////////////////////////////////
//

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;

namespace CommonComponent.CommonChart
{
	/// <summary>
	/// 
	/// </summary>
	public class BarGraph2D : CommonChart.BarGraph
	{
		public BarGraph2D()
		{
			this.m_GraphType = Type.BarGraph2D;
			this.m_QuadrantToShow = QuadrantType.Quad1;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawData()
		{
			bool bRet = false;

			// Calculate bar and island width data.
			CalculateBarWidth(0);

			// Caluclate the direction for drawing tickers.
			this.CalculateTickerTextDirection();

			// Calculate the direction for drawing island legends.
			this.CalculateIslandLegendTextDirection();

			ArrayList dataList = (ArrayList)this.m_obIslandList[0];
			if (null == dataList || dataList.Count == 0)
			{
				throw new ArgumentException("There is no data for display");
			}

			int nCount = dataList.Count;
			this.CalculateBarHeightScale();

			// Gemerate the random colors.
			if (this.UseRandomColors)
			{
				ColorUtil.GenerateRandomColors(nCount, out m_arrColors);
			}
			else
			{
				ColorUtil.GenerateColorValues(this.Colors, out m_arrColors);
			}

			//TODO: For now we will process only first array of data list. Later
			//		on implementation needs to take into account that there may
			//		be more than one list.
			if (Alignment.Vertical == this.GraphAlignment)
			{
				bRet = this.DrawDataForVerticalAlignment();
			}
			else
			{
				bRet = this.DrawDataForHorizontalAlignment();
			}

			return bRet;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawDataForVerticalAlignment()
		{
			PointF pt = new PointF();
			pt.X = (float)(this.m_ChartAxis.Origin.X);
			pt.Y = this.m_ChartAxis.Origin.Y;

			double ptX = 0.0;
			double ptY = 0.0;
			double nHeight = 0;
			double nWidth = 0;
			double diff = m_dEqualBarWidth - m_dDrawBarWidth;
			float fStartY = this.m_ChartAxis.Origin.Y - m_fIslandSpacing/2.0F;
			int nStartX = (int)(this.m_ChartAxis.Origin.X);
			for (int nIdx = 0; nIdx < this.m_obDataIslandNodes.Count; nIdx++)
			{
				ArrayList obIslandDataList = (ArrayList)this.m_obIslandList[nIdx];
				int nCount = obIslandDataList.Count;
				for (int i = 0; i < nCount; i++)
				{
					Color fillColor = (Color)this.m_arrColors[i];
					SolidBrush obBrush = new SolidBrush(fillColor);
					GraphDataObject obData = (GraphDataObject)obIslandDataList[i];
					if (null != obData)
					{
						pt.Y = (float)(fStartY - nIdx*(this.m_fIslandWidth + this.m_fIslandSpacing) - (i + 1) * this.m_dEqualBarWidth);

						// First draw the front rectangle.
						nHeight = this.m_dDrawBarWidth;
						nWidth = (obData.Y * this.m_dBarHeightScale);

						this.DrawBar(this.m_obGraphics, (int)pt.X, (int)pt.Y, (float)nWidth, (float)nHeight, 0.0, fillColor);

						// Draw the data value text.
						try
						{
							this.DrawDataValue(this.m_obGraphics, this.m_YTickFont, pt.X, pt.Y, nWidth, nHeight,
								obData.Y.ToString(), this.m_TickerTextDirection, this.GraphAlignment, this.m_TickColor, fillColor);
						}
						catch (Exception ex)
						{
							Trace.WriteLine(ex.Message);
						}

						// Draw the ticker.
						this.DrawChartTicker(this.m_obGraphics, pt.X, pt.Y, nWidth, nHeight, 3,
							this.m_LegendsList[i], this.m_TickerTextDirection, this.GraphAlignment, this.m_TickColor);
					}
					obBrush.Dispose();
				}

				// Draw Island legend.
				if (this.DrawXAxisLegend)
				{
					ptX = nStartX;
					ptY = (float)(fStartY - nIdx*(this.m_fIslandWidth + this.m_fIslandSpacing));
					this.DrawIslandLegendText(m_obGraphics, this.m_XTickFont, ptX, ptY, this.m_fIslandDrawWidth,
						m_IslandLegendsList[nIdx], this.GraphAlignment, this.m_TickColor);
				}
			}
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawDataForHorizontalAlignment()
		{
			PointF [] rect = new PointF[4];
			double ptX = 0.0;
			double ptY = 0.0;
			int nHeight = 0;
			int nWidth = 0;
			//int nStartX = (int)(this.m_ChartAxis.Origin.X + LeftSpacing);
			int nStartX = (int)(this.m_ChartAxis.Origin.X + + m_fIslandSpacing/2.0F);

			for (int nIdx = 0; nIdx < this.m_obDataIslandNodes.Count; nIdx++)
			{
				ArrayList obIslandDataList = (ArrayList)this.m_obIslandList[nIdx];
				int nCount = obIslandDataList.Count;
				for (int i = 0; i < nCount; i++)
				{
					Color fillColor = (Color)this.m_arrColors[i];
					Brush obBrush = null;
					
					GraphDataObject obData = (GraphDataObject)obIslandDataList[i];
					if (null != obData)
					{
						// First draw the front rectangle.
						nHeight = (int)(obData.Y * this.m_dBarHeightScale);
						nWidth = (int)this.m_dDrawBarWidth;

						//rect[0].X = (int)(this.m_ChartAxis.Origin.X + (i * this.m_dEqualBarWidth) + obData.X);
						//rect[0].X = (int)(this.m_ChartAxis.Origin.X + (i * this.m_dEqualBarWidth));
						rect[0].X = (int)(nStartX + nIdx*(this.m_fIslandWidth + this.m_fIslandSpacing) + i * this.m_dEqualBarWidth);
						rect[0].Y = this.m_ChartAxis.Origin.Y;

						rect[1].X = rect[0].X + nWidth;
						rect[1].Y = rect[0].Y;

						rect[2].X = rect[1].X;
						rect[2].Y = rect[1].Y - nHeight;

						rect[3].X = rect[0].X;
						rect[3].Y = rect[2].Y;

						Rectangle rectFill = new Rectangle();
						rectFill.X = (int)rect[0].X;
						rectFill.Y = (int)rect[0].Y;
						rectFill.Width = (int)m_dEqualBarWidth;
						rectFill.Height = nHeight;
						if (this.UseGradientColors == true)
						{
							obBrush = DrawingUtil.GetLinearGradientBrush(rectFill, fillColor, GraphGradientFactor, LinearGradientMode.Horizontal);
						}
						else
						{
							obBrush = new SolidBrush(fillColor);
						}

						this.m_obGraphics.FillPolygon(obBrush, rect);

						// Draw the data value text.
						try
						{
							this.DrawDataValue(this.m_obGraphics, this.m_YTickFont, rect[0].X, rect[0].Y, nWidth, nHeight,
								obData.Y.ToString(), this.m_TickerTextDirection, this.GraphAlignment, this.m_TickColor, fillColor);
						}
						catch (Exception ex)
						{
							Trace.WriteLine(ex.Message);
						}
						// Draw the ticker.
						try
						{
							this.DrawChartTicker(this.m_obGraphics, rect[0].X, rect[0].Y, nWidth, nHeight, 3,
								this.m_LegendsList[i], this.m_TickerTextDirection, this.GraphAlignment, this.m_TickColor);
						}
						catch (Exception ex)
						{
							Trace.WriteLine(ex.Message);
						}

						obBrush.Dispose();
					}
				}

				// Draw Island legend.
				if (this.DrawXAxisLegend)
				{
					ptX = (nStartX + nIdx*(this.m_fIslandWidth + this.m_fIslandSpacing));
					ptY = this.m_ChartAxis.Origin.Y;
					this.DrawIslandLegendText(m_obGraphics, this.m_XTickFont, ptX, ptY, this.m_fIslandDrawWidth,
						m_IslandLegendsList[nIdx], this.GraphAlignment, this.m_TickColor);
				}
			}
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawAxisForVerticalAlignment(bool bDrawGrid)
		{
			Pen obPen = null;
			Pen obGridPen = null;
			Pen obSubGridPen = null;
			try
			{
				// Draw the grid lines now.
				if (this.YTickSpacing > 0)
				{
					SizeF rectText;
					string strVal = "";
					PointF pt1 = new PointF();
					PointF pt2 = new PointF();
					PointF pt3 = new PointF();
					PointF pt4 = new PointF();
					PointF stPt = new PointF();
					PointF endPt = new PointF();

					obGridPen = new Pen(GridColor);
					obGridPen.DashStyle = LineUtil.GetDashStyle(this.GridType);

					if (this.HasSubGridLines)
					{
						obSubGridPen = new Pen(SubGridColor);
						obSubGridPen.DashStyle = LineUtil.GetDashStyle(SubGridType);
					}

					int iTickCount = (int)((this.MaxYValue - this.MinYValue)/this.YTickSpacing);
					float dXScale = (this.m_iXAxisSpan)/(float)(this.MaxYValue - this.MinYValue);
					for (int i = 0; i <= iTickCount; i++)
					{
						pt1.X = this.m_ChartAxis.X1.X + (i * this.YTickSpacing) * dXScale;
						pt2.X = pt1.X;
						pt1.Y = this.m_ChartAxis.Y2.Y;
						pt2.Y = pt1.Y - this.m_iYAxisSpan;

						if (HasGridLines & bDrawGrid)
						{
							this.m_obGraphics.DrawLine(obGridPen, pt1, pt2);
						}

						if (this.HasSubGridLines && bDrawGrid)
						{
							if (i > 0)
							{
								pt3.X = this.m_ChartAxis.X1.X + ((i - 1) * this.YTickSpacing) * dXScale;
								pt4.X = pt1.X;
								pt3.Y = pt1.Y = this.m_ChartAxis.Y2.Y;
								pt4.Y = pt3.Y - this.m_iYAxisSpan;

								stPt.Y = pt1.Y;
								endPt.Y = pt2.Y;

								float diff = pt1.X - pt3.X;

								for (int k = 1; k <= this.SubGridLines; k++)
								{
									endPt.X = stPt.X = pt3.X + diff*k/(SubGridLines+1);
									this.m_obGraphics.DrawLine(obSubGridPen, stPt, endPt);
								}
							}
						}

						// TODO: Parameterize tick size. For now we are using 3px.
						pt2.Y = pt1.Y + 3;
						this.m_obGraphics.DrawLine(obGridPen, pt1, pt2);

						strVal = (MinYValue + (i * YTickSpacing)).ToString();
						rectText = this.m_obGraphics.MeasureString(strVal, this.m_YTickFont);
						pt1.X = pt1.X - (rectText.Width/2.0F);
						
						// TODO: Parameterize buffer between tickers and text.
						pt1.Y = pt1.Y + 3 + 2;
						this.m_obGraphics.DrawString(strVal, this.m_YTickFont, new SolidBrush(this.m_TitleColor), pt1);
					}
				}

				obPen = new Pen(new SolidBrush(Color.Black));
				this.m_obGraphics.DrawLine(obPen, this.m_ChartAxis.X1, this.m_ChartAxis.X2);
				this.m_obGraphics.DrawLine(obPen, this.m_ChartAxis.Y2, this.m_ChartAxis.Y1);
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.Message);
				throw ex;
			}
			finally
			{
				if (obPen != null)
				{
					obPen.Dispose();
				}
			}
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawAxisForHorizontalAlignment(bool bDrawGrid)
		{
			Pen obPen = null;
			Pen obGridPen = null;
			Pen obSubGridPen = null;
			try
			{
				// Draw the grid lines now.
				if (this.YTickSpacing > 0)
				{
					SizeF rectText;
					string strVal = "";
					
					PointF pt1 = new PointF();
					PointF pt2 = new PointF();
					PointF pt3 = new PointF();
					PointF pt4 = new PointF();
					PointF stPt = new PointF();
					PointF endPt = new PointF();

					obGridPen = new Pen(GridColor);
					obGridPen.DashStyle = LineUtil.GetDashStyle(this.GridType);

					if (this.HasSubGridLines)
					{
						obSubGridPen = new Pen(SubGridColor);
						obSubGridPen.DashStyle = LineUtil.GetDashStyle(SubGridType);
					}

					int iTickCount = (int)((this.MaxYValue - this.MinYValue)/this.YTickSpacing);
					float dYScale = (this.m_iYAxisSpan)/(float)(this.MaxYValue - this.MinYValue);
					for (int i = 0; i <= iTickCount; i++)
					{
						pt1.X = this.m_ChartAxis.X1.X;
						pt2.X = pt1.X + this.m_iXAxisSpan;
						pt1.Y = this.m_ChartAxis.Y2.Y - (i * this.YTickSpacing) * dYScale;
						pt2.Y = pt1.Y;

						if (HasGridLines && bDrawGrid)
						{
							this.m_obGraphics.DrawLine(obGridPen, pt1, pt2);
						}

						if (this.HasSubGridLines && bDrawGrid)
						{
							if (i > 0)
							{
								pt3.X = this.m_ChartAxis.X1.X;
								pt4.X = pt1.X + this.m_iXAxisSpan;
								pt3.Y = this.m_ChartAxis.Y2.Y - ((i - 1) * this.YTickSpacing) * dYScale;
								pt4.Y = pt3.Y;

								stPt.X = pt3.X;
								endPt.X = pt4.X;

								float diff = pt3.Y - pt2.Y;

								for (int k = 1; k <= this.SubGridLines; k++)
								{
									endPt.Y = stPt.Y = pt3.Y - diff*k/(SubGridLines+1);
									this.m_obGraphics.DrawLine(obSubGridPen, stPt, endPt);
								}
							}
						}

						// TODO: Parameterize tick size. For now we are using 3px.
						pt2.X = pt1.X - 3;
						this.m_obGraphics.DrawLine(obGridPen, pt1, pt2);

						strVal = (MinYValue + (i * YTickSpacing)).ToString();
						rectText = this.m_obGraphics.MeasureString(strVal, this.m_YTickFont);
						//TODO: Parameterize tick length
						pt1.X = pt1.X - 3 -(rectText.Width + 2);
						pt1.Y = pt1.Y - (rectText.Height/2.0F);
						this.m_obGraphics.DrawString(strVal, this.m_YTickFont, new SolidBrush(this.m_TitleColor), pt1);

					}
				}

				obPen = new Pen(new SolidBrush(Color.Black));
				this.m_obGraphics.DrawLine(obPen, this.m_ChartAxis.X1, this.m_ChartAxis.X2);
				this.m_obGraphics.DrawLine(obPen, this.m_ChartAxis.Y2, this.m_ChartAxis.Y1);
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.Message);
				throw ex;
			}
			finally
			{
				if (obPen != null)
				{
					obPen.Dispose();
				}

				if (obGridPen != null)
				{
					obGridPen.Dispose();
				}

				if (obSubGridPen != null)
				{
					obPen.Dispose();
				}
			}
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawAxisLabels()
		{
			/*
			try
			{
				// 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>
		override protected bool DrawGridLines()
		{
			// Check if the client has asked for Grid Lines or not.
			if (false == HasGridLines)
			{
				return true;
			}
			return true;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -