Stellarworks
Welcome Guest [Login] or [Register] 
    
Ordering FAQ    View Shopping Cart (0)

Code Snippet - Line Graph
C# .Net
24-10-2011

The .Net Framework has a lot of inbuilt GUI components that cover most application requirements, but one thing it doesn't have is a Line Graph. To that end the following code describes a thread safe customizable line graph that anyone can use and modify to suit their project's needs. It needs a little more error checking, but should otherwise get the job done. It inherits from the User Control so it can be drag and dropped onto a form once it has been copied into a project. Graph Points can then be set through a call to SetGraphPoints or AddGraphPoint using System.Drawing.Point and Lists.

Graph Features:
-Customizable colors, labels and line lengths
-Adjustable scale - number of points, start at the first X value
-Mouse Over Tool Tips with configurable units
-Max Y value - a horizontal line
-Mark Graph Points with an adjustable dot




 Code 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Toolbox
{
    public partial class swLineGraph : UserControl
    {
        Point mBottomPad = new Point(65, 40);
        Point mTopPad = new Point(40, 40);
        string mXAxisLabel = "X";
        string mYAxisLabel = "Y";
        float mAxisWidth = 1;
        Color mAxisColor = System.Drawing.Color.Black;
        List<Point> mGraphPoints = new List<Point>();
        float mLineWidth = 1;
        Color mLineColor = System.Drawing.Color.Black;
        bool mMarkPoints = false;
        float mMarkPointWidth = 4;
        Color mScaleTextColor = System.Drawing.Color.Black;
        Color mScaleLineColor = System.Drawing.Color.Black;
        int mXScalePoints = 5;
        int mYScalePoints = 5;
        int mXScalePointLineLength = 8;
        int mYScalePointLineLength = 8;
        int mXScalePadY = 30;
        int mYScalePadX = 35;
        bool mUseMaxValueY = false;
        int mMaxValueY = 0;
        Color mMaxValueColor = System.Drawing.Color.Orange;
        string mToolTipUnits = "";
        bool mStartXScaleAtFirstEntry = false;


        Rectangle mMouseOverBox = new Rectangle(0, 0, 5, 5);


        object mLock = new object();




        public swLineGraph()
        {
            InitializeComponent();
            this.MouseMove += new MouseEventHandler(swLineGraph_MouseMove);
        }//End constructor



        //Displays the value of the graph point the mouse is over
        private void swLineGraph_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                lock (mLock)
                {
                    //Convert the mouse point to control coords
                    Point mousePoint = PointToClient(new Point(MousePosition.X, MousePosition.Y));


                    /////Convert our graph points into control coords////

                    //Graph Width
                    int graphWidth = Width - mBottomPad.X - mBottomPad.X;//Count padding Twice
                    int graphHeight = Height - mBottomPad.Y - mTopPad.Y;


                    //Find the lowest X Point
                    int lowerXValue = 0;
                    if (mStartXScaleAtFirstEntry)
                    {
                        for (int i = 0; i < mGraphPoints.Count; i++)
                        {
                            if (i == 0)
                                lowerXValue = mGraphPoints[i].X;

                            for (int x = 0; x < mGraphPoints.Count; x++)
                            {
                                if ((i != x) && (lowerXValue > mGraphPoints[x].X))
                                    lowerXValue = mGraphPoints[x].X;
                            }
                        }//End outter for
                    }//End lowest



                    //Graph scaling
                    float maxGraphX = 0;
                    float minGraphX = 0;
                    float maxGraphY = 0;
                    float minGraphY = 0;

                    //Find the max graph X
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        if (i == 0)
                            maxGraphX = mGraphPoints[i].X;

                        for (int x = 0; x < mGraphPoints.Count; x++)
                        {
                            if ((i != x) && (maxGraphX < mGraphPoints[x].X))
                                maxGraphX = mGraphPoints[x].X;
                        }
                    }//End outter for


                    //Find the max graph Y
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        if (i == 0)
                            maxGraphY = mGraphPoints[i].Y;

                        for (int x = 0; x < mGraphPoints.Count; x++)
                        {
                            if ((i != x) && (maxGraphY < mGraphPoints[x].Y))
                                maxGraphY = mGraphPoints[x].Y;
                        }
                    }//End outter for

                    //Check if max value y is bigger, if we are using it
                    if (mUseMaxValueY && (maxGraphY < mMaxValueY))
                        maxGraphY = mMaxValueY;



                    //Shift max X axis value by the smallest value. We will do this to everything later as well
                    if (mStartXScaleAtFirstEntry)
                    {
                        maxGraphX = maxGraphX - lowerXValue;
                    }


                    //Graph area
                    float maxAreaX = graphWidth;
                    float minAreaX = 0;
                    float maxAreaY = graphHeight;
                    float minAreaY = 0;


                    //X Scale factor
                    float Sx = 0;
                    if (((maxAreaX - minAreaX) != 0) && ((maxGraphX - minGraphX) != 0))
                        Sx = (maxAreaX - minAreaX) / (maxGraphX - minGraphX);


                    //X Shift factor
                    float Tx = 0;
                    if (((maxGraphX * minAreaX) - (minGraphX * maxAreaX) != 0) && ((maxGraphX - minGraphX) != 0))
                        Tx = (maxGraphX * minAreaX) - (minGraphX * maxAreaX) / (maxGraphX - minGraphX);

                    //Y Scale factor
                    float Sy = 0;
                    if (((maxAreaY - minAreaY) != 0) && ((maxGraphY - minGraphY) != 0))
                        Sy = (maxAreaY - minAreaY) / (maxGraphY - minGraphY);


                    //Y Shift factor
                    float Ty = 0;
                    if (((maxGraphY - minGraphY) != 0) && ((maxGraphY * minAreaY) - (minGraphY * maxAreaY) != 0))
                        Ty = (maxGraphY * minAreaY) - (minGraphY * maxAreaY) / (maxGraphY - minGraphY);



                    //Check graph points
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        //Scale point into graph boundaries
                        Point currentPoint = new Point((int)(Sx * (mGraphPoints[i].X - lowerXValue) + Tx), (int)(Sy * mGraphPoints[i].Y + Ty));

                        //Invert graph point because the top left corner is zero in drawing coords but for graph coords its the origin of the graph
                        currentPoint.Y = Height - currentPoint.Y;

                        //Shift point by inner graph padding
                        currentPoint.X = currentPoint.X + mBottomPad.X;
                        currentPoint.Y = currentPoint.Y - mBottomPad.Y;

                        currentPoint = new Point((int)(currentPoint.X - (mMarkPointWidth / 2)), (int)(currentPoint.Y - (mMarkPointWidth / 2)));

                        //Check if the mouse is over this point
                        if ((currentPoint.Y <= (mousePoint.Y + mMouseOverBox.Height)) && (currentPoint.Y >= (mousePoint.Y - mMouseOverBox.Height)) && (currentPoint.X <= (mousePoint.X + mMouseOverBox.Width)) && (currentPoint.X >= (mousePoint.X - mMouseOverBox.Width)))
                        {
                            //Show Tool Tip if it's not already
                            if (ttGraphPoint.GetToolTip(this) == "")
                                ttGraphPoint.SetToolTip(this, mGraphPoints[i].Y + mToolTipUnits);

                            return;//Stop here
                        }
                    }//End for



                    //Check max line points
                    if (mUseMaxValueY)
                    {
                        //Invert graph point because the top left corner is zero in drawing coords but for graph coords its the origin of the graph
                        int maxYPos = Height - (int)(Sy * mMaxValueY + Ty);

                        //Shift point by inner graph padding
                        maxYPos = maxYPos - mBottomPad.Y;

                        //Add max line
                        Point maxPointLine = new Point(graphWidth + mBottomPad.X, maxYPos);

                        //Check if the mouse is over the max line - width is graph width
                        if ((maxPointLine.Y <= (mousePoint.Y + mMouseOverBox.Height)) && (maxPointLine.Y >= (mousePoint.Y - mMouseOverBox.Height)) && (mousePoint.X <= (maxPointLine.X + mMouseOverBox.Width)) && (mousePoint.X >= (mBottomPad.X - mMouseOverBox.Width)))
                        {
                            //Show Tool Tip if it's not already
                            if (ttGraphPoint.GetToolTip(this) == "")
                                ttGraphPoint.SetToolTip(this, mMaxValueY.ToString() + mToolTipUnits);

                            return;//Stop here
                        }
                    }//End max value


                    //Nothing to show
                    ttGraphPoint.SetToolTip(this, "");
                    ttGraphPoint.Hide(this);
                }//End lock
            }//End try

            catch (Exception ex)
            {
                //Silent error
            }
        }//End swLineGraph_MouseMove



        public string ToolTipUnits
        {
            get
            {
                lock (mLock)
                    return mToolTipUnits;
            }

            set
            {
                lock (mLock)
                {
                    mToolTipUnits = value;
                }
            }
        }//End ToolTipUnits



        private delegate void RequestRefreshDelegate();
        private void RequestRefresh()
        {
            if (this.InvokeRequired)
                this.Invoke(new RequestRefreshDelegate(RequestRefresh), null);
            else
                this.Invalidate();
        }//End RequestRefresh



        private void SortGraphPontsNoLock()
        {
            //Sort into Ascending order according according to X axis
            for (int i = 0; i < mGraphPoints.Count; i++)
            {
                for (int x = 0; x < mGraphPoints.Count; x++)
                {
                    //Swap lower values with the higher values
                    if ((x != i) && mGraphPoints[i].X < mGraphPoints[x].X)
                    {
                        Point temp = mGraphPoints[i];
                        mGraphPoints[i] = mGraphPoints[x];
                        mGraphPoints[x] = temp;
                    }
                }
            }//End outter for
        }//End SortGraphPontsNoLock



        public void SetGraphPoints(List<Point> pPoints)
        {
            lock (mLock)
            {
                if (pPoints != null)
                {
                    mGraphPoints = pPoints;
                    SortGraphPontsNoLock();
                }
                else
                    mGraphPoints.Clear();
            }//End lock

            RequestRefresh();
        }//End SetGraphPoint



        public void AddGraphPoint(Point pPoint)
        {
            lock (mLock)
            {
                mGraphPoints.Add(pPoint);
                SortGraphPontsNoLock();
            }

            RequestRefresh();
        }//End AddGraphPoint



        public void AddGraphPointRange(List<Point> pPoints)
        {
            lock (mLock)
            {
                mGraphPoints.AddRange(pPoints);
                SortGraphPontsNoLock();
            }

            RequestRefresh();
        }//End AddGraphPointRage



        public void ClearGraphPoints()
        {
            lock (mLock)
            {
                mGraphPoints.Clear();
            }

            RequestRefresh();
        }//End ClearGraphicPoints



        public string YAxisLabel
        {
            get
            {
                lock (mLock)
                    return mYAxisLabel;
            }


            set
            {
                lock (mLock)
                {
                    mYAxisLabel = value;
                }

                RequestRefresh();
            }
        }//End YAxisLabel



        public string XAxisLabel
        {
            get
            {
                lock (mLock)
                    return mXAxisLabel;
            }

            set
            {
                lock (mLock)
                {
                    mXAxisLabel = value;
                }

                RequestRefresh();
            }
        }//End XAxisLabel



        public float AxisWidth
        {
            get
            {
                lock (mLock)
                    return mAxisWidth;
            }

            set
            {
                lock (mLock)
                {
                    mAxisWidth = value;
                }

                RequestRefresh();
            }
        }//End AxisWidth




        public Color AxisColor
        {
            get
            {
                lock (mLock)
                    return mAxisColor;
            }

            set
            {
                lock (mLock)
                {
                    mAxisColor = value;
                }

                RequestRefresh();
            }
        }//End AxisColor



        public float LineWidth
        {
            get
            {
                lock (mLock)
                    return mLineWidth;
            }

            set
            {
                lock (mLock)
                {
                    mLineWidth = value;
                }

                RequestRefresh();
            }
        }//End LineWidth




        public Color LineColor
        {
            get
            {
                lock (mLock)
                    return mLineColor;
            }

            set
            {
                lock (mLock)
                {
                    mLineColor = value;
                }

                RequestRefresh();
            }
        }//End LineColor



        public bool MarkPoints
        {
            get
            {
                lock (mLock)
                    return mMarkPoints;
            }

            set
            {
                lock (mLock)
                {
                    mMarkPoints = value;
                }

                RequestRefresh();
            }
        }//End MarkPoints



        public float MarkPointsWidth
        {
            get
            {
                lock (mLock)
                    return mMarkPointWidth;
            }

            set
            {
                lock (mLock)
                {
                    mMarkPointWidth = value;
                }

                RequestRefresh();
            }
        }//End MarkPointsWidth



        public Color ScaleTextColor
        {
            get
            {
                lock (mLock)
                    return mScaleTextColor;
            }

            set
            {
                lock (mLock)
                {
                    mScaleTextColor = value;
                }

                RequestRefresh();
            }
        }//End ScaleTextColor



        public Color ScaleLineColor
        {
            get
            {
                lock (mLock)
                    return mScaleLineColor;
            }

            set
            {
                lock (mLock)
                {
                    mScaleLineColor = value;
                }
                RequestRefresh();
            }
        }//End ScaleLineColor



        public int XScalePoints
        {
            get
            {
                lock (mLock)
                    return mXScalePoints;
            }

            set
            {
                lock (mLock)
                {
                    mXScalePoints = value;
                }

                RequestRefresh();
            }
        }//End XScalePoints




        public int YScalePoints
        {
            get
            {
                lock (mLock)
                    return mYScalePoints;
            }

            set
            {
                lock (mLock)
                {
                    mYScalePoints = value;
                }

                RequestRefresh();
            }
        }//End YScalePoints



        public int XScalePointLineLength
        {
            get
            {
                lock (mLock)
                    return mXScalePointLineLength;
            }

            set
            {
                lock (mLock)
                {
                    mXScalePointLineLength = value;
                }

                RequestRefresh();
            }
        }//End XScalePointLineLength


        public int YScalePointLineLength
        {
            get
            {
                lock (mLock)
                    return mYScalePointLineLength;
            }

            set
            {
                lock (mLock)
                {
                    mYScalePointLineLength = value;
                }

                RequestRefresh();
            }
        }//End YScalePointLineLength




        public int XScalePadY
        {
            get
            {
                lock (mLock)
                    return mXScalePadY;
            }

            set
            {
                lock (mLock)
                {
                    mXScalePadY = value;
                }

                RequestRefresh();
            }
        }//End XScalePadY



        public int YScalePadX
        {
            get
            {
                lock (mLock)
                    return mYScalePadX;
            }

            set
            {
                lock (mLock)
                {
                    mYScalePadX = value;
                }

                RequestRefresh();
            }
        }//End YScalePadX



        public bool UseMaxValueY
        {
            get
            {
                lock (mLock)
                    return mUseMaxValueY;
            }

            set
            {
                lock (mLock)
                {
                    mUseMaxValueY = value;
                }

                RequestRefresh();
            }
        }//End UseMaxValueY



        public int MaxValueY
        {
            get
            {
                lock (mLock)
                    return mMaxValueY;
            }

            set
            {
                lock (mLock)
                {
                    mMaxValueY = value;
                }

                RequestRefresh();
            }
        }//End MaxValueY



        public Color MaxValueColor
        {
            get
            {
                lock (mLock)
                    return mMaxValueColor;
            }

            set
            {
                lock (mLock)
                {
                    mMaxValueColor = value;
                }

                RequestRefresh();
            }
        }//End MaxValueColor



        public bool StartXScaleAtFirstEntry
        {
            get
            {
                lock (mLock)
                    return mStartXScaleAtFirstEntry;
            }

            set
            {
                lock (mLock)
                {
                    mStartXScaleAtFirstEntry = value;
                }
            }
        }//End StartXScaleAtFirstEntry




        protected override void OnPaint(PaintEventArgs e)
        {
            try
            {
                lock (mLock)
                {
                    Pen newLine = new Pen(mAxisColor, mAxisWidth);
                    Brush newBrush = new SolidBrush(ForeColor);

                    //X Axis
                    e.Graphics.DrawLine(newLine, new Point(mBottomPad.X, Height - mBottomPad.Y), new Point(Width - mBottomPad.X, Height - mBottomPad.Y));

                    //TODO: zero check label size

                    //X Axis label
                    SizeF labelSize = e.Graphics.MeasureString(mXAxisLabel, Font);
                    e.Graphics.DrawString(mXAxisLabel, Font, newBrush, new Point(Width / 2 - ((int)labelSize.Width / 2), Height - (mBottomPad.Y / 3) - ((int)labelSize.Height / 2)));


                    //Y Axis
                    e.Graphics.DrawLine(newLine, new Point(mBottomPad.X, Height - mBottomPad.Y), new Point(mBottomPad.X, mTopPad.Y));

                    //Y Axis label
                    //Vertical
                    labelSize = e.Graphics.MeasureString(mYAxisLabel, Font);
                    System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat(StringFormatFlags.DirectionVertical);
                    e.Graphics.DrawString(mYAxisLabel, Font, newBrush, new Point((mBottomPad.X / 3) - ((int)labelSize.Height / 2), (Height / 2) - ((int)labelSize.Width / 2)), drawFormat);


                    //Graph Width
                    int graphWidth = Width - mBottomPad.X - mBottomPad.X;//Count padding Twice
                    int graphHeight = Height - mBottomPad.Y - mTopPad.Y;



                    //Find the lowest X Point
                    int lowerXValue = 0;
                    if (mStartXScaleAtFirstEntry)
                    {
                        for (int i = 0; i < mGraphPoints.Count; i++)
                        {
                            if (i == 0)
                                lowerXValue = mGraphPoints[i].X;

                            for (int x = 0; x < mGraphPoints.Count; x++)
                            {
                                if ((i != x) && (lowerXValue > mGraphPoints[x].X))
                                    lowerXValue = mGraphPoints[x].X;
                            }
                        }//End outter for
                    }//End lowest



                    //Graph scaling
                    float maxGraphX = 0;
                    float minGraphX = 0;
                    float maxGraphY = 0;
                    float minGraphY = 0;

                    //Find the max graph X
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        if (i == 0)
                            maxGraphX = mGraphPoints[i].X;

                        for (int x = 0; x < mGraphPoints.Count; x++)
                        {
                            if ((i != x) && (maxGraphX < mGraphPoints[x].X))
                                maxGraphX = mGraphPoints[x].X;
                        }
                    }//End outter for


                    //Find the max graph Y
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        if (i == 0)
                            maxGraphY = mGraphPoints[i].Y;

                        for (int x = 0; x < mGraphPoints.Count; x++)
                        {
                            if ((i != x) && (maxGraphY < mGraphPoints[x].Y))
                                maxGraphY = mGraphPoints[x].Y;
                        }
                    }//End outter for

                    //Check if max value y is bigger, if we are using it
                    if (mUseMaxValueY && (maxGraphY < mMaxValueY))
                        maxGraphY = mMaxValueY;


                    //Shift max X axis value by the smallest value. We will do this to everything later as well
                    if (mStartXScaleAtFirstEntry)
                    {
                        maxGraphX = maxGraphX - lowerXValue;
                    }


                    //Graph area
                    float maxAreaX = graphWidth;
                    float minAreaX = 0;
                    float maxAreaY = graphHeight;
                    float minAreaY = 0;


                    //X Scale factor
                    float Sx = 0;
                    if (((maxAreaX - minAreaX) != 0) && ((maxGraphX - minGraphX) != 0))
                        Sx = (maxAreaX - minAreaX) / (maxGraphX - minGraphX);


                    //X Shift factor
                    float Tx = 0;
                    if (((maxGraphX * minAreaX) - (minGraphX * maxAreaX) != 0) && ((maxGraphX - minGraphX) != 0))
                        Tx = (maxGraphX * minAreaX) - (minGraphX * maxAreaX) / (maxGraphX - minGraphX);

                    //Y Scale factor
                    float Sy = 0;
                    if (((maxAreaY - minAreaY) != 0) && ((maxGraphY - minGraphY) != 0))
                        Sy = (maxAreaY - minAreaY) / (maxGraphY - minGraphY);


                    //Y Shift factor
                    float Ty = 0;
                    if (((maxGraphY - minGraphY) != 0) && ((maxGraphY * minAreaY) - (minGraphY * maxAreaY) != 0))
                        Ty = (maxGraphY * minAreaY) - (minGraphY * maxAreaY) / (maxGraphY - minGraphY);



                    //Draw Scale

                    //////X Scale///////
                    //float xFloatPoints = (Sx * (maxGraphX + Tx) / (float)mXScalePoints;
                    float scaleSpacing = graphWidth / (float)mXScalePoints;
                    float scaleStep = scaleStep = maxGraphX / mXScalePoints;


                    //Round Scale Up
                    //if ((xFloatPoints - xIntPoints) != 0)
                    //    xIntPoints += 1;

                    Pen scaleLine = new Pen(mScaleLineColor);
                    Brush scaleBrush = new SolidBrush(mScaleTextColor);
                    for (int i = 1; i <= mXScalePoints; i++)
                    {
                        //Size
                        labelSize = e.Graphics.MeasureString((lowerXValue + (i * scaleStep)).ToString(), Font);

                        //TODO: Zero check  ScalePointLineLength and label sizes

                        //Verticle Line
                        e.Graphics.DrawLine(scaleLine, new Point(mBottomPad.X + (int)Math.Round(i * scaleSpacing, MidpointRounding.AwayFromZero), Height - mBottomPad.Y + (mXScalePointLineLength / 2)), new Point(mBottomPad.X + (int)Math.Round(i * scaleSpacing, MidpointRounding.AwayFromZero), Height - mBottomPad.Y - (mXScalePointLineLength / 2)));

                        //Label
                        e.Graphics.DrawString((lowerXValue + (i * scaleStep)).ToString(), Font, scaleBrush, new Point(mBottomPad.X - ((int)labelSize.Width / 2) + (int)(i * scaleSpacing), Height - mXScalePadY - ((int)labelSize.Height / 2)));
                    }//End for


                    //Draw origin scale
                    if (mStartXScaleAtFirstEntry)
                    {
                        //Size
                        labelSize = e.Graphics.MeasureString(lowerXValue.ToString(), Font);

                        //Label
                        e.Graphics.DrawString(lowerXValue.ToString(), Font, scaleBrush, new Point(mBottomPad.X - ((int)labelSize.Width / 2), Height - mXScalePadY - ((int)labelSize.Height / 2)));
                    }

                    ////////End X Scale/////////



                    //////Y Scale///////
                    float yFloatPoints = (Sy * maxGraphY + Ty) / (float)mYScalePoints;
                    scaleSpacing = graphHeight / (float)mYScalePoints;
                    scaleStep = maxGraphY / mYScalePoints;

                    //Round Scale Up
                    //if ((xFloatPoints - xIntPoints) != 0)
                    //    xIntPoints += 1;


                    for (int i = 1; i <= mYScalePoints; i++)
                    {
                        //Size
                        labelSize = e.Graphics.MeasureString((i * scaleStep).ToString(), Font);

                        //Verticle Line
                        e.Graphics.DrawLine(scaleLine, new Point(mBottomPad.X - (mYScalePointLineLength / 2), Height - mBottomPad.Y - (int)Math.Round(i * scaleSpacing, MidpointRounding.AwayFromZero)), new Point(mBottomPad.X + (mYScalePointLineLength / 2), Height - mBottomPad.Y - (int)Math.Round(i * scaleSpacing, MidpointRounding.AwayFromZero)));

                        //Label
                        e.Graphics.DrawString((i * scaleStep).ToString(), Font, scaleBrush, new Point(mYScalePadX - ((int)labelSize.Width / 2), Height - mBottomPad.Y - ((int)labelSize.Height / 2) - (int)(i * scaleSpacing)));
                    }//End for

                    ///////End Y Scale////////



                    //Draw Max Value Y
                    if (mUseMaxValueY)
                    {
                        Pen maxLine = new Pen(mMaxValueColor);

                        //Invert graph point because the top left corner is zero in drawing coords but for graph coords its the origin of the graph
                        int maxYPos = Height - (int)(Sy * mMaxValueY + Ty);

                        //Shift point by inner graph padding
                        maxYPos = maxYPos - mBottomPad.Y;

                        //Draw the max value
                        e.Graphics.DrawLine(maxLine, new Point(mBottomPad.X, maxYPos), new Point(graphWidth + mBottomPad.X, maxYPos));
                    }



                    //Draw the points on the graph and the origin point
                    Point lastPoint = new Point(mBottomPad.X, Height - mBottomPad.Y);
                    Pen graphLine = new Pen(mLineColor, mLineWidth);
                    Brush graphBrush = new SolidBrush(mLineColor);
                    for (int i = 0; i < mGraphPoints.Count; i++)
                    {
                        //Scale point into graph boundaries
                        Point currentPoint = new Point((int)(Sx * (mGraphPoints[i].X - lowerXValue) + Tx), (int)(Sy * mGraphPoints[i].Y + Ty));

                        //Invert graph point because the top left corner is zero in drawing coords but for graph coords its the origin of the graph
                        currentPoint.Y = Height - currentPoint.Y;

                        //Shift point by inner graph padding
                        currentPoint.X = currentPoint.X + mBottomPad.X;
                        currentPoint.Y = currentPoint.Y - mBottomPad.Y;

                        //Draw a line by connecting it with the last graph point
                        e.Graphics.DrawLine(graphLine, lastPoint, currentPoint);

                        //TODO: Zero check MarkPointWidth

                        //Draw Mark point
                        if (mMarkPoints)
                            e.Graphics.FillRectangle(graphBrush, currentPoint.X - (mMarkPointWidth / 2), currentPoint.Y - (mMarkPointWidth / 2), mMarkPointWidth, mMarkPointWidth);

                        //Update Last point
                        lastPoint = currentPoint;
                    }//End for
                }//End lock
            }//End try

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Graph Draw Error");
            }
        }


        private System.Windows.Forms.ToolTip ttGraphPoint;
        private System.ComponentModel.IContainer components = null;
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.ttGraphPoint = new System.Windows.Forms.ToolTip(this.components);
            this.SuspendLayout();
            //
            // swLineGraph
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Name = "swLineGraph";
            this.Size = new System.Drawing.Size(360, 198);
            this.ResumeLayout(false);

        }
    }//End swLineGraph
}



ABN 16685017405
Stellarworks® 2011-15