axialgraph.cs

来自「C#自定义查询控件」· CS 代码 · 共 523 行

CS
523
字号
// Disclaimer and Copyright Information
// AxialGraph.cs : 
//
// All rights reserved.
//
// Written by Pardesi Services, LLC
// Version 1.01
//
// 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.Collections;
using System.Drawing;
using System.Xml;


namespace CommonComponent.CommonChart
{
	/// <summary>
	/// Summary description for AxialGraph.
	/// </summary>
	public abstract class AxialGraph : Graph
	{
		private bool m_bDrawXTickerText;
		private bool m_bDrawYTickerText;
		private bool m_bDrawXAxisLegend;
		private bool m_bDrawYAxisLegend;

		private bool m_bHasSubGridLines;
		private bool m_bHasGridLines;

		private float m_fXTickSpacing;
		private float m_fYTickSpacing;

		private string m_strXAxisLabel;
		private string m_strYAxisLabel;

		private float m_fMinXVal;						// Min tick value to be shown on x-axis
		private float m_fMaxXVal;						// Max tick value to be shown on x-axis
		private float m_fMinYVal;						// Min tick value to be shown on y-axis
		private float m_fMaxYVal;						// Max tick value to be shown on y-axis

		private Color m_XAxisLabelColor;
		private Color m_YAxisLabelColor;

		private LineType m_GridType;
		private LineType m_SubGridType;

		public AxialGraph()
		{
			m_bDrawXTickerText = true;
			m_bDrawYTickerText = true;
			m_bDrawXAxisLegend = true;
			m_bDrawYAxisLegend = true;

			this.m_fXTickSpacing = 10.0F;
			this.m_fYTickSpacing = 10.0F;

			this.m_strXAxisLabel = "X";
			this.m_strYAxisLabel = "Y";

			this.m_XAxisLabelColor = Color.Blue;
			this.m_YAxisLabelColor = Color.Blue;

			m_GridType = LineType.Solid;
			m_SubGridType = LineType.Dashed;
		}

		/// <summary>
		/// 
		/// </summary>
		public bool HasGridLines
		{
			get{return this.m_bHasGridLines;}
			set{this.m_bHasGridLines = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool HasSubGridLines
		{
			get{return this.m_bHasSubGridLines;}
			set{this.m_bHasSubGridLines = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public LineType GridType
		{
			get{return this.m_GridType;}
			set{this.m_GridType = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public LineType SubGridType
		{
			get{return this.m_SubGridType;}
			set{this.m_SubGridType = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public string XAxisLabel
		{
			get{return this.m_strXAxisLabel;}
			set{this.m_strXAxisLabel = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public string YAxisLabel
		{
			get{return this.m_strYAxisLabel;}
			set{this.m_strYAxisLabel = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float XTickSpacing
		{
			get{return this.m_fXTickSpacing;}
			set{this.m_fXTickSpacing = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float YTickSpacing
		{
			get{return this.m_fYTickSpacing;}
			set{this.m_fYTickSpacing = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float MinXValue
		{
			get{return this.m_fMinXVal;}
			set{this.m_fMinXVal = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float MaxXValue
		{
			get{return this.m_fMaxXVal;}
			set{this.m_fMaxXVal = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float MinYValue
		{
			get{return this.m_fMinYVal;}
			set{this.m_fMinYVal = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public float MaxYValue
		{
			get{return this.m_fMaxYVal;}
			set{this.m_fMaxYVal = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public Color XAxisLabelColor
		{
			get{return this.m_XAxisLabelColor;}
			set{this.m_XAxisLabelColor = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public Color YAxisLabelColor
		{
			get{return this.m_YAxisLabelColor;}
			set{this.m_YAxisLabelColor = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DrawXTickerText
		{
			get{return m_bDrawXTickerText;}
			set{m_bDrawXTickerText = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DrawYTickerText
		{
			get{return m_bDrawYTickerText;}
			set{m_bDrawYTickerText = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DrawXAxisLegend
		{
			get{return m_bDrawXAxisLegend;}
			set{m_bDrawXAxisLegend = value;}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DrawYAxisLegend
		{
			get{return m_bDrawYAxisLegend;}
			set{m_bDrawYAxisLegend = value;}
		}


		override protected bool CalculateAxis()
		{
			Point x1, x2, y1, y2;
			int iOriginFromBottom = 0;
			x1 = new Point();
			x2 = new Point();
			y1 = new Point();
			y2 = new Point();
			this.m_Origin = new Point();

			// Calculate location of origin from bottom.
			double factor = (double)this.MinYValue/(this.MaxYValue - this.MinYValue);
			iOriginFromBottom = (int)(this.m_iYAxisSpan * factor);
			switch (this.m_QuadrantToShow)
			{
				case QuadrantType.Quad1:
					this.m_Origin.X = (int)this.LeftSpacing;
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing);
					x1.X = y2.X = y1.X = this.m_Origin.X;
					x1.Y = y2.Y = this.m_Origin.Y;
					x2.X = x1.X + this.m_iXAxisSpan;
					x2.Y = x1.Y;
					y1.Y = (int)this.TopSpacing;
					break;
				case QuadrantType.Quad2:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan);
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing);
					x1.X = (int)this.LeftSpacing;
					x1.Y = x2.Y = y2.Y = this.m_Origin.Y;
					x2.X = y1.X = y2.X = this.m_Origin.X;
					y1.Y = (int)this.TopSpacing;
					break;
				case QuadrantType.Quad3:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan);
					this.m_Origin.Y = (int)this.TopSpacing;
					x1.X = (int)this.LeftSpacing;
					x1.Y = x2.Y = y1.Y = this.m_Origin.Y;
					x2.X = y1.X = y2.X = this.m_Origin.X;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
				case QuadrantType.Quad4:
					this.m_Origin.X = (int)this.LeftSpacing;
					this.m_Origin.Y = (int)this.TopSpacing;
					x1.X = y1.X = y2.X = this.m_Origin.X;
					x1.Y = y1.Y = x2.Y = this.m_Origin.Y;
					x2.X = x1.X + this.m_iXAxisSpan;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
				case QuadrantType.Quad12:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan/2);
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing);
					x1.X = (int)this.LeftSpacing;
					x1.Y = y2.Y = x2.Y = this.m_Origin.Y;
					x2.X = x1.X + this.m_iXAxisSpan;
					y2.X = y1.X = this.m_Origin.X;
					y1.Y = (int)this.TopSpacing;
					break;
				case QuadrantType.Quad23:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan);
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing - this.m_iYAxisSpan/2);
					x1.X = (int)this.LeftSpacing;
					x1.Y = x2.Y = this.m_Origin.Y;
					x2.X = y1.X = y2.X = this.m_Origin.X;
					y1.Y = (int)this.TopSpacing;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
				case QuadrantType.Quad34:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan/2);
					this.m_Origin.Y = (int)this.TopSpacing;
					x1.X = (int)this.LeftSpacing;
					x1.Y = x2.Y = y1.Y = this.m_Origin.Y;
					y1.X = y2.X = this.m_Origin.X;
					x2.X = x1.X + this.m_iXAxisSpan;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
				case QuadrantType.Quad14:
					this.m_Origin.X = (int)this.LeftSpacing;
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing + iOriginFromBottom);
					x1.X = y1.X = y2.X = this.m_Origin.X;
					x1.Y = x2.Y = this.m_Origin.Y;
					x2.X = x1.X + this.m_iXAxisSpan;
					y1.Y = (int)this.TopSpacing;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
				case QuadrantType.Quad1234:
					this.m_Origin.X = (int)(this.LeftSpacing + this.m_iXAxisSpan/2);
					this.m_Origin.Y = (int)(this.m_iHeight - this.BottomSpacing - this.m_iYAxisSpan/2);

					x1.X = (int)this.LeftSpacing;
					x2.X = x1.X + this.m_iXAxisSpan;
					x1.Y = x2.Y = this.m_Origin.Y;
					y1.X = y2.X = this.m_Origin.X;
					y1.Y = (int)this.TopSpacing;
					y2.Y = y1.Y + this.m_iYAxisSpan;
					break;
			}

			this.m_ChartAxis.Origin = this.m_Origin;
			this.m_ChartAxis.X1 = x1;
			this.m_ChartAxis.X2 = x2;
			this.m_ChartAxis.Y1 = y1;
			this.m_ChartAxis.Y2 = y2;
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool CalculateAxisLabelLocations()
		{
			SizeF xLabelSize;
			SizeF yLabelSize; 
			xLabelSize = this.m_obGraphics.MeasureString(this.XAxisLabel, this.XAxisLabelFont);
			yLabelSize = this.m_obGraphics.MeasureString(this.YAxisLabel, this.YAxisLabelFont);

			// Calculate x-axis label location
			int iX = (int)((this.m_iXAxisSpan/2) - xLabelSize.Width + this.LeftSpacing);

			// Calculate y-axis label location
			int iY = (int)((this.m_iYAxisSpan/2) - yLabelSize.Width + this.TopSpacing);

			this.m_XAxisLabelLocation = new PointF();
			this.m_YAxisLabelLocation = new PointF();

			this.m_XAxisLabelLocation.X = iX;
			this.m_XAxisLabelLocation.Y = this.m_iHeight - (this.BottomSpacing - this.m_iXAxisLabelPadding) + xLabelSize.Height/2;

			this.m_YAxisLabelLocation.X = this.LeftSpacing - this.m_iYAxisLabelPadding - yLabelSize.Height;
			this.m_YAxisLabelLocation.Y = iY;
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		override protected bool DrawAxisLabels()
		{
			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);
			return true;
		}

		/// <summary>
		/// Set x,y Axes range
		/// </summary>
		public void SetXYAxesRange(int xMin, int xMax, int yMin, int yMax)
		{
			MinXValue = xMin;
			MaxXValue = xMax;
			MinYValue = yMin;
			MaxYValue = yMax;
		}

		/// <summary>
		/// Set Graph Feature
		/// </summary>
		public void SetTicker(bool hasXTickerText, bool hasYTickerText, bool hasGridLines, bool hasTickers)
		{
			DrawXTickerText = hasXTickerText;
			DrawYTickerText = hasYTickerText;				
			HasGridLines = hasGridLines;
			HasTickers = hasTickers;
		}

		/// <summary>
		/// The method will process the XML document containing the data and
		/// store it in the appropriare format for use in drawing.
		/// </summary>
		/// <returns></returns>
		override protected bool ProcessChartData()
		{
			if (null == this.m_obGraphData)
			{
				throw new ArgumentException("Null XML document provided");
			}

			// Select the nodes of data from document.
			XmlElement obRoot;
			string strLegend = "";
			string strIslandLegend = "";
			obRoot = this.m_obGraphData.DocumentElement;
			// Get the nodes.
			this.m_obDataIslandNodes = obRoot.SelectNodes("//chartdataisland");
			this.m_iNumberOfDataIslands = m_obDataIslandNodes.Count;
			if (m_iNumberOfDataIslands == 0)
			{
				Trace.WriteLine("There is no data in the xml document.");
				return false;
			}

			// Set the flag if the data has multiple islands or not.
			this.MultiIslandData = (m_iNumberOfDataIslands > 1);
			m_obIslandList = new ArrayList(m_iNumberOfDataIslands);

			// Initialize legends text collection.
			InitializeLegendsCollection();

			for (int i = 0; i < m_iNumberOfDataIslands; i++)
			{
				XmlNode obIslandNode = m_obDataIslandNodes[i];
				if (obIslandNode != null)
				{
					// Get the legend text for island.
					try
					{
						strIslandLegend = obIslandNode.Attributes["legend"].Value;
					}
					catch (Exception ex)
					{
						Trace.Write(ex.Message);
					}

					if (strIslandLegend.Length == 0)
					{
						strIslandLegend = ("Data" + i.ToString());
					}

					this.AddIslandLegendTextToCollection(strIslandLegend);

					XmlNodeList obDataNodes = obIslandNode.SelectNodes("chartdata");
					if (obDataNodes != null)
					{
						int nCount = obDataNodes.Count;
						this.m_sLegendCount = (short)nCount;

						// Incase the user has specified data series with uneven numbers of points,
						// we need to make sure that we have the count as MAX of all counts.
						DataPointCount = Math.Max(nCount, this.DataPointCount);
						
						if (nCount > 0)
						{
							ArrayList obDataList = new ArrayList(nCount);
							ArrayList xValList = new ArrayList(nCount);
							ArrayList yValList = new ArrayList(nCount);
							for (int j = 0; j < nCount; j++)
							{
								XmlNode obDataNode = obDataNodes[j];
								if (obDataNode != null)
								{
									GraphDataObject ob = new GraphDataObject();
									ob.X = Convert.ToSingle(obDataNode["x"].InnerText);
									ob.Y = Convert.ToSingle(obDataNode["y"].InnerText);
									try
									{
										strLegend = obDataNode["x"].Attributes["legend"].Value;
									}
									catch (Exception ex)
									{
										strLegend = ("Item" + j.ToString());
										Trace.Write(ex.Message);
									}

									this.AddLegendTextToCollection(strLegend);
									obDataList.Add(ob);
									xValList.Add(ob.X);
									yValList.Add(ob.Y);
								}
							}

							GetMinMax(xValList, ref m_fMinXDataValue, ref m_fMaxXDataValue);
							GetMinMax(yValList, ref m_fMinYDataValue, ref m_fMaxYDataValue);
							m_obIslandList.Add(obDataList);
						}
					}
				}
			}
			return true;
		}

	}
}

⌨️ 快捷键说明

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