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

📄 performancegraph.cs

📁 rudp可靠保障得udp传输
💻 CS
📖 第 1 页 / 共 2 页
字号:
		protected override void OnPaint(PaintEventArgs e)
		{
			Graphics g = e.Graphics;// CreateGraphics();

			SmoothingMode prevSmoothingMode = g.SmoothingMode;
			g.SmoothingMode = (m_bHighQuality ? SmoothingMode.HighQuality
											  : SmoothingMode.Default);

			/* Reset our offset so we don't continually shift to the right: */

			m_OffsetX = 0;

			if (m_bShowMinMax)
			{
				DrawLabels(ref g);
			}

			if (m_bShowGrid)
			{
				DrawGrid(ref g);
			}

			if (m_OffsetX != 0)
			{
				/* This is to avoid crossing the left grid boundary when 
				 * working with lines with great thickness */

				g.Clip = new Region(
					new Rectangle(m_OffsetX, 0, Width - m_OffsetX, Height));
			}

			DrawLines(ref g);
			g.ResetClip();

			g.SmoothingMode = prevSmoothingMode;
		}

		#endregion

		#region UpdateGraph

		/// <summary> 
		/// This function is to be called after you have pushed new magnitude(s)
		/// to the graph's lines and want the control re-rendered to take the
		/// changes into account.
		/// </summary>
		public void UpdateGraph()
		{
			int greatestMCount = 0;
			foreach (Line line in m_Lines)
			{
				if (greatestMCount < line.m_MagnitudeList.Count)
				{
					greatestMCount = line.m_MagnitudeList.Count;
				}
			}

			if (greatestMCount >= m_MaxCoords)
			{
				m_MoveOffset =
					(m_MoveOffset - (((greatestMCount - m_MaxCoords) + 1) * m_LineInterval))
					% m_GridSize;
			}

			this.Refresh();
		}

		#endregion

		#region Draw...

		private void DrawLabels(ref Graphics g)
		{

			SizeF maxSize = g.MeasureString(m_MaxLabel, Font);
			SizeF minSize = g.MeasureString(m_MinLabel, Font);

			int textWidth = (int)((maxSize.Width > minSize.Width)
							? maxSize.Width
							: minSize.Width) + 6;

			SolidBrush textBrush = new SolidBrush(m_TextColor);


			/* Draw the labels (max: Top) (min: Bottom) */

			g.DrawString(m_MaxLabel, Font, textBrush,
						  textWidth / 2 - (maxSize.Width / 2),
						  2);

			g.DrawString(m_MinLabel, Font, textBrush,
						  textWidth / 2 - (minSize.Width / 2),
						  Height - minSize.Height - 2);

			textBrush.Dispose();


			/* Draw the bordering line */

			Pen borderPen = new Pen(m_GridColor, 1);
			g.DrawLine(borderPen, textWidth + 6, 0, textWidth + 6, Height);

			borderPen.Dispose();

			/* Update the offset so we don't draw the graph over the labels */
			m_OffsetX = textWidth + 6;
		}

		protected void RefreshLabels()
		{
			/* Within this function we ensure our labels are up to date
			 * if the user isn't using custom labels. It is called whenever
			 * the graph's range changes. */

			if (!m_bMinLabelSet)
			{
				/* Use the minimum magnitude as the label since the
				 * user has not yet assigned a custom label: */

				m_MinLabel = m_MinPeek.ToString();
			}

			if (!m_bMaxLabelSet)
			{
				/* Use the maximum magnitude as the label since the
				 * user has not yet assigned a custom label: */

				m_MaxLabel = m_MaxPeek.ToString();
			}
		}

		protected void DrawGrid(ref Graphics g)
		{
			Pen gridPen = new Pen(m_GridColor, 1);
			for (int n = Height - 1; n >= 0; n -= m_GridSize)
			{
				g.DrawLine(gridPen, m_OffsetX, n, Width, n);
			}

			for (int n = m_OffsetX + m_MoveOffset; n < Width; n += m_GridSize)
			{
				if (n < m_OffsetX)
				{
					continue;
				}

				g.DrawLine(gridPen, n, 0, n, Height);
			}

			gridPen.Dispose();
		}

		protected void DrawLines(ref Graphics g)
		{

			if (m_MaxCoords == -1)
			{
				/* Maximum push points not yet calculated */

				m_MaxCoords = ((Width - m_OffsetX) / m_LineInterval) + 2
							   + (((Width - m_OffsetX) % m_LineInterval) != 0 ? 1 : 0);

				if (m_MaxCoords <= 0)
				{
					m_MaxCoords = 1;
				}
			}


			int greatestMCount = 0;
			foreach (Line line in m_Lines)
			{
				if (!line.m_bVisible)
				{
					continue;
				}

				if (greatestMCount < line.m_MagnitudeList.Count)
				{
					greatestMCount = line.m_MagnitudeList.Count;
				}
			}

			if (greatestMCount == 0)
			{
				return; // No lines to draw
			}

			foreach (Line line in m_Lines)
			{

				/* If the line has less push points than the line with the greatest
				number of push points, new push points are appended with
				the same magnitude as the previous push point. If no push points
				exist for the line, one is added with the least magnitude possible. */

				if (line.m_MagnitudeList.Count == 0)
				{
					line.m_MagnitudeList.Add(m_MinPeek);
				}

				while (line.m_MagnitudeList.Count < greatestMCount)
				{
					line.m_MagnitudeList.Add(
						line.m_MagnitudeList[line.m_MagnitudeList.Count - 1]);
				}

				while (line.m_MagnitudeList.Count >= m_MaxCoords)
				{
					line.m_MagnitudeList.RemoveAt(0);
				}

				if (line.m_MagnitudeList.Count == 0)
				{
					//TODO: This may not be nescessary, so look into it.
					/* No push points to draw */
					return;
				}

				if (!line.m_bVisible)
				{
					continue;
				}

				/* Now prepare to draw the line or bar */

				Pen linePen = new Pen(line.m_Color, line.m_Thickness);

				Point lastPoint = new Point();
				lastPoint.X = m_OffsetX;
				lastPoint.Y = Height - ((line.m_MagnitudeList[0] *
				   Height) / (m_MaxPeek - m_MinPeek));

				for (int n = 0; n < line.m_MagnitudeList.Count; ++n)
				{
					if (line.m_bShowAsBar)
					{
						/* The line is set to be shown as a bar graph, so
						first we get the bars rectangle, then draw the bar */

						Rectangle barRect = new Rectangle();

						// Weird hack because BarRect.Location.* causes error
						Point p = barRect.Location;
						p.X = m_OffsetX + (n * m_LineInterval) + 1;
						p.Y = Height - ((line.m_MagnitudeList[n] * Height) /
											(m_MaxPeek - m_MinPeek));
						barRect.Location = p;

						barRect.Width = m_LineInterval - 1;
						barRect.Height = Height;

						DrawBar(barRect, line, ref g);
					}
					else
					{
						/* Draw a line */

						int newX = m_OffsetX + (n * m_LineInterval);
						int newY = Height - ((line.m_MagnitudeList[n] * Height) /
							(m_MaxPeek - m_MinPeek));

						g.DrawLine(linePen, lastPoint.X, lastPoint.Y, newX, newY);

						lastPoint.X = newX;
						lastPoint.Y = newY;
					}
				}

				linePen.Dispose();
			}
		}

		private void DrawBar(Rectangle rect, Line line, ref Graphics g)
		{
			SolidBrush barBrush = new SolidBrush(line.m_Color);
			g.FillRectangle(barBrush, rect);
			barBrush.Dispose();
		}

		#endregion

		#region Lines management

		/// <summary> 
		/// Returns a new line handle (LineHandle object) to the line 
		/// with the matching numerical ID. Returns NULL if a line with a 
		/// matching ID is not found.
		/// </summary>
		/// <param name="numID">
		/// The numerical ID of the line you wish to get a handle to.
		/// </param>
		public LineHandle GetLineHandle(int numID)
		{
			Object line = (Object)GetLine(numID);
			return (line != null ? new LineHandle(ref line, this) : null);
		}

		/// <summary> 
		/// Returns a new line handle (LineHandle object) to the line 
		/// with the matching name (case insensitive). Returns NULL if a 
		/// line with a matching name is not found.
		/// </summary>
		/// <param name="nameID">
		/// The case insensitive name of the line you wish to get a handle to.
		/// </param>
		public LineHandle GetLineHandle(string nameID)
		{
			Object line = (Object)GetLine(nameID);
			return (line != null ? new LineHandle(ref line, this) : null);
		}

		private Line GetLine(int numID)
		{
			foreach (Line line in m_Lines)
			{
				if (numID == line.m_NumID)
				{
					return line;
				}
			}
			return null;
		}

		private Line GetLine(string nameID)
		{
			foreach (Line line in m_Lines)
			{
				if (string.Compare(nameID, line.m_NameID, true) == 0)
				{
					return line;
				}
			}
			return null;
		}

		/// <summary> 
		/// Returns true if a line exists with an identification number mathing 
		/// the passed value. Returns false if no match is found.
		/// </summary>
		/// <param name="numID">
		/// The case numerical ID of the line you wish to check the existence
		/// of.
		/// </param>
		public bool LineExists(int numID)
		{
			return GetLine(numID) != null;
		}

		/// <summary> 
		/// Returns true if a line exists with a name that case insensitively
		/// matches the passes name. Returns false if no match is found.
		/// </summary>
		/// <param name="nameID">
		/// The case insensitive name of the line you wish to check the existence
		/// of.
		/// </param>
		public bool LineExists(string nameID)
		{
			return GetLine(nameID) != null;
		}

		/// <summary> 
		/// Adds a new line using the passed name as an identifier and sets
		/// the line's initial color to the passed color. If successful, returns
		/// a handle to the new line.
		/// </summary>
		/// <param name="nameID">
		/// A case insensitive name for the line you wish to create.
		/// </param>
		/// <param name="clr">
		/// The line's initial color.
		/// </param>
		public LineHandle AddLine(string nameID, Color clr)
		{
			if (LineExists(nameID))
			{
				return null;
			}

			Line line = new Line(nameID);
			line.m_Color = clr;

			m_Lines.Add(line);

			Object objLine = (Object)line;
			return (new LineHandle(ref objLine, this));
		}

		/// <summary> 
		/// I strongly suggest that you use this method when performance is critical
		/// 
		/// Adds a new line using the passed numeric ID as an identifier and sets
		/// the line's initial color to the passed color. If successful, returns
		/// a handle to the new line.
		/// </summary>
		/// <param name="numID">
		/// A unique numerical for the line you wish to create.
		/// </param>
		/// <param name="clr">
		/// The line's initial color.
		/// </param>
		public LineHandle AddLine(int numID, Color clr)
		{
			if (LineExists(numID))
			{
				return null;
			}

			Line line = new Line(numID);
			line.m_Color = clr;

			m_Lines.Add(line);
			Object objLine = (Object)line;
			return (new LineHandle(ref objLine, this));
		}

		/// <summary> 
		/// Removes a line by its name.
		/// </summary>
		/// <param name="nameID">
		/// The line's case-insensitive name.
		/// </param>  
		public bool RemoveLine(string nameID)
		{
			Line line = GetLine(nameID);
			if (line == null)
			{
				return false;
			}

			return m_Lines.Remove(line);
		}

		/// <summary> 
		/// Removes a line by its numerical ID.
		/// </summary>
		/// <param name="numID">
		/// The line's numerical ID.
		/// </param>  
		public bool RemoveLine(int numID)
		{
			Line line = GetLine(numID);
			if (line == null)
			{
				return false;
			}

			return m_Lines.Remove(line);
		}

		#endregion

		#region Push

		/// <summary> 
		/// Pushes a new magnitude (point) to the line with the passed name.
		/// </summary>
		/// <param name="magnitude">
		/// The magnitude of the new point.
		/// </param>  
		/// <param name="nameID">
		/// The line's case-insensitive name.
		/// </param>  
		public bool Push(int magnitude, string nameID)
		{
			Line line = GetLine(nameID);
			if (line == null)
			{
				return false;
			}

			return PushDirect(magnitude, line);
		}

		/// <summary> 
		/// Pushes a new magnitude (point) to the line with the passed 
		/// numerical ID.
		/// </summary>
		/// <param name="magnitude">
		/// The magnitude of the new point.
		/// </param>  
		/// <param name="numID">
		/// The line's numerical ID.
		/// </param>  
		public bool Push(int magnitude, int numID)
		{
			Line line = GetLine(numID);
			if (line == null)
			{
				return false;
			}

			return PushDirect(magnitude, line);
		}

		private bool PushDirect(int magnitude, Line line)
		{
			/* Now add the magnitude (push point) to the array of push points, but
			   first restrict it to the peek bounds */

			if (!m_bAutoScale && magnitude > m_MaxPeek)
			{
				magnitude = m_MaxPeek;
			}
			else if (m_bAutoScale && magnitude > m_MaxPeek)
			{
				m_MaxPeek = magnitude;
				RefreshLabels();
			}
			else if (!m_bAutoScale && magnitude < m_MinPeek)
			{
				magnitude = m_MinPeek;
			}
			else if (m_bAutoScale && magnitude < m_MinPeek)
			{
				m_MinPeek = magnitude;
				RefreshLabels();
			}

			magnitude -= m_MinPeek;

			line.m_MagnitudeList.Add(magnitude);
			return true;
		}

		#endregion

	}
}

⌨️ 快捷键说明

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