/// <summary>
        /// Gets a closed polygon version of the specified drawing points.
        /// </summary>
        /// <param name="surface">The target surface.</param>
        /// <param name="points">The drawing points.</param>
        /// <returns></returns>
        protected virtual IEnumerable <PointF> GetFillPoints(IGraphSurface <TDataSeries> surface, IEnumerable <PointF> points)
        {
            List <PointF> closed = points.ToList();

            closed.Add(new PointF(points.Last().X, surface.GetSize().Width));
            closed.Add(new PointF(0, surface.GetSize().Height));
            return(closed.ToArray());
        }
        /// <summary>
        /// Arranges the series of data points and returns a series of drawing points.
        /// </summary>
        /// <param name="surface">The target graph surface.</param>
        /// <param name="series">The instance of the current rendered data series.</param>
        /// <param name="range">Instance of graph range.</param>
        /// <param name="xx">Collection of x coordinates.</param>
        /// <param name="yy">Collection of y coordinates.</param>
        /// <param name="minimumX">The minimum x coordinates value.</param>
        /// <param name="maximumX">The maximum x coordinates value.</param>
        /// <param name="minimumY">The minimum y coordinates value.</param>
        /// <param name="maximumY">The maximum y coordinates value.</param>
        /// <returns></returns>
        public override IEnumerable <PointF> Render(IGraphSurface <TDataSeries> surface, TDataSeries series, IGraphRange range, List <GraphDataPoint> xx, List <GraphDataPoint> yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY)
        {
            var dxList = xx.Select(x => x.ComputeRelativePosition(minimumX, maximumX)).ToList();
            var dyList = yy.Select(x => x.ComputeRelativePosition(minimumY, maximumY)).ToList();

            if (maximumX - minimumX > range.MaximumX)
            {
                var offset = ((maximumX - minimumX) - range.MaximumX) + minimumX;

                for (int i = 0; i < xx.Count; i++)
                {
                    if (xx[i] < offset)
                    {
                        xx.RemoveAt(i);
                        yy.RemoveAt(i);
                        i--;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            List <PointF> points = new List <PointF>();

            for (int i = 0; i < dxList.Count; i++)
            {
                float image_x = ConvertXValueToRendererValue(surface, dxList[i]);
                float image_y = (float)Math.Min(ConvertYValueToRendererValue(surface, dyList[i]), surface.GetSize().Height - 2);

                PointF point = new PointF(image_x, image_y);
                points.Add(point);
            }

            return(points);
        }
 /// <summary>
 /// Converts the specified relative y position to a graph surface absolute position.
 /// </summary>
 /// <param name="surface">The surface.</param>
 /// <param name="y">The relative y position.</param>
 /// <returns></returns>
 protected virtual float ConvertYValueToRendererValue(IGraphSurface <TDataSeries> surface, double y)
 {
     return((float)(surface.GetSize().Height - (y * surface.GetSize().Height / 100)));
 }
 /// <summary>
 /// Converts the specified relative x position to a graph surface absolute position.
 /// </summary>
 /// <param name="surface">The target surface.</param>
 /// <param name="x">The relative x position.</param>
 /// <returns></returns>
 protected virtual float ConvertXValueToRendererValue(IGraphSurface <TDataSeries> surface, double x)
 {
     return((float)(x * surface.GetSize().Width / 100));
 }