[C#] Graph Component - Developed by AceInfinity

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
This is not completely finished yet. But it's good enough for the idea. So here i'm releasing a good start to an experimental graph control I created in the last 10 or so minutes, and maybe i'll improve it at a later date, but I really don't have use for it currently, so I didn't know what to do.

Before I screw it up any further though, I just want to let you guys know that it does work lol. I've included a few comments along the way, and a known bug that I just haven't had a go at yet. I just finished getting the basic default colors looking nice, and i'm happy with it the way it is until I have new ideas for it, or at least until I have something to use it with.

Preview
bSdNt.png


Source
Code:
//*
// Name: Graph Component Control
// Author: AceInfinity
// Copyright 2012 - Tech.Reboot.Pro
//
// Description:
//      Experimental graph control allowing you to manually plot points
//      on the grid using the left and right mouse clicks.
//
//
// Known Bugs:
//
//      - Resize does not affect the points and line positioning
//*

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class GraphComponent : PictureBox

{
	#region Private Fields
	private int _TopPadding = 15;
	private Font _TitleFont = new Font(FontFamily.GenericSansSerif, 8f);
	private List<List<Point>> _Points = new List<List<Point>>();
	private int _PointSize = 3;
	#endregion Private Fields

	#region Public Properties
	public Color TitleColor { get; set; }
	public bool ShowVerticalMargin { get; set; }
	public bool ShowHorizontalMargin { get; set; }

	public Color GridLinesColor { get; set; }
	public Color GridMarginsColor { get; set; }

	public Color LineColor { get; set; }

	public Color DotBorderColor { get; set; }
	public Color DotTopGradient { get; set; }
	public Color DotBottomGradient { get; set; }

	public int TileSize { get; set; }

	public List<List<Point>> Points
	{
		get { return _Points; }
		private set
		{
			_Points = value;
			Invalidate();
		}
	}
	#endregion Public Properties

	#region Constructor
	public GraphComponent()
	{
		DoubleBuffered = true;
		
		//Title
		Text = "GraphComponent";
		TitleColor = Color.FromArgb(50, 50, 50);

		//Grid
		TileSize = 5;
		ShowVerticalMargin = true;
		ShowHorizontalMargin = true;
		GridLinesColor = Color.FromArgb(200, 200, 200);
		GridMarginsColor = Color.FromArgb(125, 125, 125);

		//Plot
		LineColor = Color.FromArgb(0, 200, 255);
		DotBorderColor = Color.FromArgb(0, 170, 255);
		DotTopGradient = Color.FromArgb(119, 221, 255);
		DotBottomGradient = Color.FromArgb(0, 100, 200);
	}
	#endregion Constructor

	#region Overrides

	#region Paint Event Methods
	/// <summary>
	/// Method used to paint the control.
	/// </summary>
	/// <param name="pe"></param>
	protected override void OnPaint(PaintEventArgs pe)
	{
		base.OnPaint(pe);
		int horTiles = this.Width / TileSize;
		int verTiles = this.Height + _TopPadding / TileSize;

		Pen P = new Pen(GridLinesColor);

		// Draw Tiles
		for (int v = 0; v < verTiles; v++)
		{
			for (int h = 0; h < horTiles; h++)
			{
				pe.Graphics.DrawRectangle(P, new Rectangle(h * TileSize, v * TileSize + _TopPadding, TileSize, TileSize));
			}
		}

		P = new Pen(GridMarginsColor);

		// Draw Center Margins
		if (ShowVerticalMargin)
		{
			int margin = this.Width / 2 / TileSize * TileSize; // Make sure it aligns with the edge of a tile
			pe.Graphics.DrawLine(P, margin, _TopPadding, margin, this.Height); // Vertical Margin
		}

		if (ShowHorizontalMargin)
		{
			int margin = this.Height / 2 / TileSize * TileSize; // Make sure it aligns with the edge of a tile
			pe.Graphics.DrawLine(P, 0, margin, this.Width, margin); // Horizontal Margin
		}

		// Draw Title String
		SolidBrush SB = new SolidBrush(TitleColor);
		pe.Graphics.DrawString(this.Text, _TitleFont, SB, 0, 2);

		if (Points.Count > 0)
		{
			P = new Pen(DotBorderColor);
			Pen LnPen = new Pen(LineColor);

			// Draw Points
			LinearGradientBrush LGB = default(LinearGradientBrush);
			foreach (List<Point> pts in Points)
			{
				foreach (Point p in pts)
				{
					Rectangle rect = new Rectangle(p.X - (_PointSize / 2), p.Y - (_PointSize / 2), _PointSize, _PointSize);
					LGB = new LinearGradientBrush(rect, DotTopGradient, DotBottomGradient, 70f);
					pe.Graphics.DrawEllipse(P, rect);
					pe.Graphics.FillEllipse(LGB, rect);
				}

				for (int x = 0; x < pts.Count - 1; x++)
				{
					pe.Graphics.DrawLine(LnPen, pts[x], pts[x + 1]);
				}
			}

			LGB.Dispose();
			LnPen.Dispose();
		}
		SB.Dispose();
		P.Dispose();
	}
	#endregion
		
	#region Mouse Event Methods
	protected override void OnMouseDown(MouseEventArgs e)
	{
		base.OnMouseDown(e);
		int posX = ((e.X / TileSize) * TileSize);
		int posY = ((e.Y / TileSize) * TileSize);

		if (e.Button == MouseButtons.Left)
		{
			// Add new point
			List<Point> P = new List<Point>();
			P.Add(new Point(posX, posY));
			Points.Add(P);
		}
		else if (e.Button == MouseButtons.Right)
		{
			// Modify last point
			List<Point> LastP = Points.LastOrDefault();
			if (LastP != null)
			{
				LastP.Add(new Point(posX, posY));
			}
		}
		Invalidate();
	}
	#endregion Mouse Event Methods

	#region Resize Event Methods
	/// <summary>
	/// OnResize event method, calls to re-paint the control.
	/// </summary>
	/// <param name="e"></param>
	protected override void OnResize(EventArgs e)
	{
		base.OnResize(e);
		Invalidate();
	}
	#endregion Resize Event Methods

	#region Properties
	/// <summary>
	/// Make sure that the minimum size of the control doesn't go below 100 x 100.
	/// </summary>
	private Size _MinimumSize = new Size(100, 100);
	public override Size MinimumSize
	{
		get { return _MinimumSize; }
		set
		{
			Size s = value;
			if (value.Height < 100) s.Height = 100;
			if (value.Width < 100) s.Width = 100;
			base.MinimumSize = s;
		}
	}

	/// <summary>
	/// Set the default cursor to the cross.
	/// </summary>
	protected override Cursor DefaultCursor { get { return Cursors.Cross; } }
	#endregion Properties

	#endregion Overrides

	#region Other Methods
	/// <summary>
	/// Wipes all points & lines off the grid
	/// </summary>
	public void ClearPoints()
	{
		Points.Clear();
		Invalidate();
	}
	#endregion Other Methods
}

Silly Features Overview:
- You've got a title
- Functionality to keep or remove both or either horizontal or vertical margin center lines
- You've got the ability to add a new point reference by the left click action on the graph
- If you right click, a line joins the point where you right clicked to the last point added to the graph.
- Resize snaps the marginal center lines to the actual grid lines, it's not just the center of the graph. same thing with plotting dots, they get plotted where the center of 4 corners of 4 tiles meet.

Bugs I've found in the 30 seconds I tested this:
- Resize does not adjust the Plotted dots and lines on the graph, so if you're expecting accuracy, don't allow the graph to be resized itself, or the plots are screwed up.
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top