public void Reset()
 {
     _primitiveList.Clear();
     _cursorCoordinateCanvas.PointToText.Clear();
     GridLineOverrides.Clear();
     YAxisTitles.Clear();
     XAxisTitles.Clear();
     Title = "";
 }
        /// <summary>
        /// Renders the grid lines and labels in immediate mode rendering style
        /// </summary>
        /// <param name="dc"></param>
        protected override void OnRender(DrawingContext dc)
        {
            Func <double, string> DefaultLabelGenerator = x => x.ToString();

            // Make sure these functions are assigned
            XAxisLabelGenerator = XAxisLabelGenerator ?? DefaultLabelGenerator;
            YAxisLabelGenerator = YAxisLabelGenerator ?? DefaultLabelGenerator;
            GridLineSpacingX    = GridLineSpacingX ?? GridLineSpacings.Base10;
            GridLineSpacingY    = GridLineSpacingY ?? GridLineSpacings.Base10;

            // Work out all the limits and scaling factors for rendering grid lines

            Size size = new Size(this.ActualWidth, this.ActualHeight);

            double scaleX = 0.0;
            double scaleY = 0.0;

            if (MaxPoint.X != MinPoint.X)
            {
                scaleX = size.Width / (MaxPoint.X - MinPoint.X);
            }
            if (MaxPoint.Y != MinPoint.Y)
            {
                scaleY = size.Height / (MaxPoint.Y - MinPoint.Y);
            }

            double spacingX = GridLineSpacingX(_optimalGridLineSpacing.X / scaleX);
            double spacingY = GridLineSpacingY(_optimalGridLineSpacing.Y / scaleY);

            int startXmult = (int)Math.Ceiling(MinPoint.X / spacingX);
            int endXmult   = (int)Math.Floor(MaxPoint.X / spacingX);
            int startYmult = (int)Math.Ceiling(MinPoint.Y / spacingY);
            int endYmult   = (int)Math.Floor(MaxPoint.Y / spacingY);

            double maxYLabelWidth  = 0;
            double maxXLabelHeight = 0;

            // Do a first pass of the x axis labels to make sure we have enough grid spacing to fit them in
            double maxXLabelWidth = 0;

            for (int lineNo = startXmult; lineNo <= endXmult; ++lineNo)
            {
                // Get the x position in graphing coordinates
                double xValue = lineNo * spacingX;
                // Check if there are any grid line overrides for this area of the chart
                if (GridLineOverrides.Any(x => x.Orientation == Orientation.Vertical && x.Range.Contains(xValue)))
                {
                    continue;
                }
                FormattedText formattedText = GetText(XAxisLabelGenerator(xValue), _gridLabelBrush);
                maxXLabelWidth = Math.Max(maxXLabelWidth, formattedText.Width);
            }

            // Adjust the X spacing accordingly
            double minGridLineSpacingX = (maxXLabelWidth + 8) * 2;

            if (minGridLineSpacingX > _optimalGridLineSpacing.X)
            {
                spacingX   = GridLineSpacingX(minGridLineSpacingX / scaleX);
                startXmult = (int)Math.Ceiling(MinPoint.X / spacingX);
                endXmult   = (int)Math.Floor(MaxPoint.X / spacingX);
            }

            // Do a first pass of the y axis labels to make sure we have enough grid spacing to fit them in
            double maxYLabelHeight = 0;

            for (int lineNo = startYmult; lineNo <= endYmult; ++lineNo)
            {
                // Get the y position in graphing coordinates
                double yValue = lineNo * spacingY;
                // Check if there are any grid line overrides for this area of the chart
                if (GridLineOverrides.Any(y => y.Orientation == Orientation.Horizontal && y.Range.Contains(yValue)))
                {
                    continue;
                }
                FormattedText formattedText = GetText(YAxisLabelGenerator(yValue), _gridLabelBrush);
                maxYLabelHeight = Math.Max(maxYLabelHeight, formattedText.Width);
            }

            // Adjust the Y spacing accordingly
            double minGridLineSpacingY = (maxYLabelHeight + 8) * 2;

            if (minGridLineSpacingY > _optimalGridLineSpacing.Y)
            {
                spacingY   = GridLineSpacingY(minGridLineSpacingY / scaleY);
                startYmult = (int)Math.Ceiling(MinPoint.Y / spacingY);
                endYmult   = (int)Math.Floor(MaxPoint.Y / spacingY);
            }

            LastSpacingX = spacingX;
            LastSpacingY = spacingY;

            // Draw all the vertical gridlines

            for (int lineNo = startXmult; lineNo <= endXmult; ++lineNo)
            {
                // Get the x position in graphing coordinates
                double xValue = lineNo * spacingX;

                // Check if there are any grid line overrides for this area of the chart
                if (GridLineOverrides.Any(x => x.Orientation == Orientation.Vertical && x.Range.Contains(xValue)))
                {
                    continue;
                }

                double xPos       = (xValue - MinPoint.X) * scaleX;
                Point  startPoint = new Point(xPos, size.Height);
                Point  endPoint   = new Point(xPos, 0);

                FormattedText formattedText = GetText(XAxisLabelGenerator(xValue), _gridLabelBrush);

                maxXLabelHeight = Math.Max(maxXLabelHeight, formattedText.Height);

                Point textPoint = new Point(xPos - formattedText.Width * .5, size.Height + 1);
                dc.DrawText(formattedText, textPoint);
                dc.DrawLine(_gridLinePen, startPoint, endPoint);
            }

            // Draw all the horizontal gridlines

            for (int lineNo = startYmult; lineNo <= endYmult; ++lineNo)
            {
                // Get the y position in graphing coordinates
                double yValue = lineNo * spacingY;

                // Check if there are any grid line overrides for this area of the chart
                if (GridLineOverrides.Any(y => y.Orientation == Orientation.Horizontal && y.Range.Contains(yValue)))
                {
                    continue;
                }

                double yPos       = (-yValue + MinPoint.Y) * scaleY + size.Height;
                Point  startPoint = new Point(0, yPos);
                Point  endPoint   = new Point(size.Width, yPos);

                FormattedText   formattedText   = GetText(YAxisLabelGenerator(yValue), _gridLabelBrush);
                RotateTransform rotateTransform = new RotateTransform(-90);
                Point           textPoint       = new Point(-formattedText.Height - 1, yPos + formattedText.Width * .5);
                textPoint = rotateTransform.Inverse.Transform(textPoint);
                dc.PushTransform(rotateTransform);
                dc.DrawText(formattedText, textPoint);
                dc.Pop();

                dc.DrawLine(_gridLinePen, startPoint, endPoint);

                maxYLabelWidth = Math.Max(maxYLabelWidth, formattedText.Height);
            }

            foreach (var gridLineOverride in GridLineOverrides)
            {
                switch (gridLineOverride.Orientation)
                {
                case Orientation.Vertical:

                    // Draw the Vertical Lines

                    foreach (var gridLine in gridLineOverride.GridLines)
                    {
                        double xValue = gridLine.Location;
                        if (!RangeX.Contains(xValue))
                        {
                            continue;
                        }
                        double xPos       = (xValue - MinPoint.X) * scaleX;
                        Point  startPoint = new Point(xPos, size.Height);
                        Point  endPoint   = new Point(xPos, 0);
                        dc.DrawLine(gridLine.Pen, startPoint, endPoint);
                    }

                    break;

                case Orientation.Horizontal:

                    // Draw the Horizontal lines

                    foreach (var gridLine in gridLineOverride.GridLines)
                    {
                        double yValue = gridLine.Location;
                        if (!RangeY.Contains(yValue))
                        {
                            continue;
                        }
                        double yPos       = (-yValue + MinPoint.Y) * scaleY + size.Height;
                        Point  startPoint = new Point(gridLine.Extended ? -YGridLineLabelBar.Width : 0, yPos);
                        Point  endPoint   = new Point(size.Width, yPos);
                        dc.DrawLine(gridLine.Pen, startPoint, endPoint);
                    }
                    break;
                }
            }

            // Draw the grid line override Labels

            foreach (var gridLineOverride in GridLineOverrides)
            {
                switch (gridLineOverride.Orientation)
                {
                case Orientation.Vertical:
                    // TODO: Draw the X-Axis labels
                    break;

                case Orientation.Horizontal:
                    // Draw the Y-Axis labels
                    maxYLabelWidth = Math.Max(maxYLabelWidth, DrawYAxisLabels(dc, scaleY, gridLineOverride.GridLabels, 0));
                    break;
                }
            }

            XGridLineLabelBar.Height = maxXLabelHeight + 2;
            YGridLineLabelBar.Width  = maxYLabelWidth + 2;

            // Now render the Y axis label

            YAxisTitleBar.Width  = DrawYAxisLabels(dc, scaleY, YAxisTitles, -YGridLineLabelBar.Width - 2) + 2;
            XAxisTitleBar.Height = DrawXAxisLabels(dc, scaleX, XAxisTitles, XGridLineLabelBar.Height + 2 + this.ActualHeight) + 2;
        }