Example #1
0
        /// <summary>
        /// Renders a chunk of points on the screen.
        /// </summary>
        /// <param name="context">Render context.</param>
        /// <param name="points">Screen points.</param>
        /// <returns>The list of resampled points.</returns>
        protected virtual List <ScreenPoint> RenderScreenPoints(AreaRenderContext context, List <ScreenPoint> points)
        {
            var final = points;

            if (context.Reverse)
            {
                final.Reverse();
            }

            if (this.InterpolationAlgorithm != null)
            {
                var resampled = ScreenPointHelper.ResamplePoints(final, this.MinimumSegmentLength);
                final = this.InterpolationAlgorithm.CreateSpline(resampled, false, 0.25);
            }

            context.RenderContext.DrawClippedLine(
                context.ClippingRect,
                final,
                context.MinDistSquared,
                this.GetSelectableColor(context.Color),
                this.StrokeThickness,
                this.EdgeRenderingMode,
                context.DashArray,
                this.LineJoin);

            return(final);
        }
Example #2
0
        /// <summary>
        /// Renders a chunk of points on the screen.
        /// </summary>
        /// <param name="context">Render context.</param>
        /// <param name="points">Screen points.</param>
        /// <returns>The list of resampled points.</returns>
        protected virtual List <ScreenPoint> RenderScreenPoints(AreaRenderContext context, List <ScreenPoint> points)
        {
            var final = points;

            if (context.Reverse)
            {
                final.Reverse();
            }

            if (this.Smooth)
            {
                var resampled = ScreenPointHelper.ResamplePoints(final, this.MinimumSegmentLength);
                final = CanonicalSplineHelper.CreateSpline(resampled, 0.5, null, false, 0.25);
            }

            context.RenderContext.DrawClippedLine(
                context.ClippingRect,
                final,
                context.MinDistSquared,
                this.GetSelectableColor(context.Color),
                this.StrokeThickness,
                context.DashArray,
                this.LineJoin,
                false);

            return(final);
        }
Example #3
0
        /// <summary>
        /// Renders data points skipping NaN values.
        /// </summary>
        /// <param name="context">Area rendering context.</param>
        /// <returns>The list of chunks.</returns>
        protected List <List <ScreenPoint> > RenderChunkedPoints(AreaRenderContext context)
        {
            var result       = new List <List <ScreenPoint> >();
            var screenPoints = new List <ScreenPoint>();

            int clipCount    = 0;
            var actualPoints = context.Points;

            for (int i = context.WindowStartIndex; i < actualPoints.Count; i++)
            {
                var point = actualPoints[i];

                if (double.IsNaN(point.Y))
                {
                    if (screenPoints.Count == 0)
                    {
                        continue;
                    }

                    result.Add(this.RenderScreenPoints(context, screenPoints));
                    screenPoints = new List <ScreenPoint>();
                }
                else
                {
                    var sp = this.XAxis.Transform(point.X, point.Y, this.YAxis);
                    screenPoints.Add(sp);
                }

                // We break after two points were seen beyond xMax to ensure glitch-free rendering.
                clipCount += point.x > context.XMax ? 1 : 0;
                if (clipCount > 1)
                {
                    break;
                }
            }

            if (screenPoints.Count > 0)
            {
                result.Add(this.RenderScreenPoints(context, screenPoints));
            }

            return(result);
        }
Example #4
0
        /// <summary>
        /// Renders a chunk of points on the screen.
        /// </summary>
        /// <param name="context">Render context.</param>
        /// <param name="points">Screen points.</param>
        /// <returns>The list of resampled points.</returns>
        protected override List <ScreenPoint> RenderScreenPoints(AreaRenderContext context, List <ScreenPoint> points)
        {
            var result          = base.RenderScreenPoints(context, points);
            var twoColorContext = (TwoColorAreaRenderContext)context;

            var baseline = this.GetConstantScreenPoints2(result, twoColorContext.Baseline);
            var poligon  = new List <ScreenPoint>(baseline);

            poligon.AddRange(result);

            context.RenderContext.DrawClippedPolygon(
                context.ClippingRect,
                poligon,
                context.MinDistSquared,
                this.GetSelectableFillColor(twoColorContext.Fill),
                OxyColors.Undefined,
                0,
                this.EdgeRenderingMode);

            if (this.IsPoints2Defined)
            {
                var markerSizes = new[] { this.MarkerSize };

                // draw the markers on top
                context.RenderContext.DrawMarkers(
                    context.ClippingRect,
                    result,
                    this.MarkerType,
                    null,
                    markerSizes,
                    twoColorContext.MarkerFill,
                    twoColorContext.MarkerStroke,
                    this.MarkerStrokeThickness,
                    this.EdgeRenderingMode,
                    1);
            }

            return(result);
        }
Example #5
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        public override void Render(IRenderContext rc)
        {
            this.VerifyAxes();

            var actualPoints = this.ActualPoints;

            if (actualPoints == null || actualPoints.Count == 0)
            {
                return;
            }

            var actualPoints2 = this.ActualPoints2;

            if (actualPoints2 == null || actualPoints2.Count == 0)
            {
                return;
            }

            int    startIdx  = 0;
            int    startIdx2 = 0;
            double xmax      = double.MaxValue;

            if (this.IsXMonotonic)
            {
                // determine render range
                var xmin = this.XAxis.ActualMinimum;
                xmax = this.XAxis.ActualMaximum;
                this.WindowStartIndex  = this.UpdateWindowStartIndex(actualPoints, point => point.X, xmin, this.WindowStartIndex);
                this.WindowStartIndex2 = this.UpdateWindowStartIndex(actualPoints2, point => point.X, xmin, this.WindowStartIndex2);

                startIdx  = this.WindowStartIndex;
                startIdx2 = this.WindowStartIndex2;
            }

            double minDistSquared = this.MinimumSegmentLength * this.MinimumSegmentLength;

            var clippingRect = this.GetClippingRect();

            rc.SetClip(clippingRect);

            var areaContext = new AreaRenderContext
            {
                Points           = actualPoints,
                WindowStartIndex = startIdx,
                XMax             = xmax,
                RenderContext    = rc,
                ClippingRect     = clippingRect,
                MinDistSquared   = minDistSquared,
                Reverse          = false,
                Color            = this.ActualColor,
                DashArray        = this.ActualDashArray
            };

            var chunksOfPoints = this.RenderChunkedPoints(areaContext);

            areaContext.Points           = actualPoints2;
            areaContext.WindowStartIndex = startIdx2;
            areaContext.Reverse          = this.Reverse2;
            areaContext.Color            = this.ActualColor2;

            var chunksOfPoints2 = this.RenderChunkedPoints(areaContext);

            if (chunksOfPoints.Count != chunksOfPoints2.Count)
            {
                rc.ResetClip();
                return;
            }

            // Draw the fill
            for (int chunkIndex = 0; chunkIndex < chunksOfPoints.Count; chunkIndex++)
            {
                var pts  = chunksOfPoints[chunkIndex];
                var pts2 = chunksOfPoints2[chunkIndex];

                // pts = SutherlandHodgmanClipping.ClipPolygon(clippingRect, pts);

                // combine the two lines and draw the clipped area
                var allPts = new List <ScreenPoint>();
                allPts.AddRange(pts2);
                allPts.AddRange(pts);
                rc.DrawClippedPolygon(
                    clippingRect,
                    allPts,
                    minDistSquared,
                    this.GetSelectableFillColor(this.ActualFill),
                    OxyColors.Undefined);

                var markerSizes = new[] { this.MarkerSize };

                // draw the markers on top
                rc.DrawMarkers(
                    clippingRect,
                    pts,
                    this.MarkerType,
                    null,
                    markerSizes,
                    this.MarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness,
                    1);
                rc.DrawMarkers(
                    clippingRect,
                    pts2,
                    this.MarkerType,
                    null,
                    markerSizes,
                    this.MarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness,
                    1);
            }

            rc.ResetClip();
        }
        /// <summary>
        /// Renders a chunk of points on the screen.
        /// </summary>
        /// <param name="context">Render context.</param>
        /// <param name="points">Screen points.</param>
        /// <returns>The list of resampled points.</returns>
        protected override List<ScreenPoint> RenderScreenPoints(AreaRenderContext context, List<ScreenPoint> points)
        {
            var result = base.RenderScreenPoints(context, points);
            var twoColorContext = (TwoColorAreaRenderContext)context;

            var baseline = this.GetConstantScreenPoints2(result, twoColorContext.Baseline);
            var poligon = new List<ScreenPoint>(baseline);
            poligon.AddRange(result);

            context.RenderContext.DrawClippedPolygon(
                context.ClippingRect,
                poligon,
                context.MinDistSquared,
                this.GetSelectableFillColor(twoColorContext.Fill),
                OxyColors.Undefined);

            if (this.IsPoints2Defined)
            {
                var markerSizes = new[] { this.MarkerSize };

                // draw the markers on top
                context.RenderContext.DrawMarkers(
                    context.ClippingRect,
                    result,
                    this.MarkerType,
                    null,
                    markerSizes,
                    twoColorContext.MarkerFill,
                    twoColorContext.MarkerStroke,
                    this.MarkerStrokeThickness,
                    1);
            }

            return result;
        }
Example #7
0
        /// <summary>
        /// Renders a chunk of points on the screen.
        /// </summary>
        /// <param name="context">Render context.</param>
        /// <param name="points">Screen points.</param>
        /// <returns>The list of resampled points.</returns>
        protected virtual List<ScreenPoint> RenderScreenPoints(AreaRenderContext context, List<ScreenPoint> points)
        {
            var final = points;

            if (context.Reverse)
            {
                final.Reverse();
            }

            if (this.Smooth)
            {
                var resampled = ScreenPointHelper.ResamplePoints(final, this.MinimumSegmentLength);
                final = CanonicalSplineHelper.CreateSpline(resampled, 0.5, null, false, 0.25);
            }

            context.RenderContext.DrawClippedLine(
                context.ClippingRect,
                final,
                context.MinDistSquared,
                this.GetSelectableColor(context.Color),
                this.StrokeThickness,
                context.DashArray,
                this.LineJoin,
                false);

            return final;
        }
Example #8
0
        /// <summary>
        /// Renders data points skipping NaN values.
        /// </summary>
        /// <param name="context">Area rendering context.</param>
        /// <returns>The list of chunks.</returns>
        protected List<List<ScreenPoint>> RenderChunkedPoints(AreaRenderContext context)
        {
            var result = new List<List<ScreenPoint>>();
            var screenPoints = new List<ScreenPoint>();

            int clipCount = 0;
            var actualPoints = context.Points;
            for (int i = context.WindowStartIndex; i < actualPoints.Count; i++)
            {
                var point = actualPoints[i];

                if (double.IsNaN(point.Y))
                {
                    if (screenPoints.Count == 0)
                    {
                        continue;
                    }

                    result.Add(this.RenderScreenPoints(context, screenPoints));
                    screenPoints = new List<ScreenPoint>();
                }
                else
                {
                    var sp = this.XAxis.Transform(point.X, point.Y, this.YAxis);
                    screenPoints.Add(sp);
                }

                // We break after two points were seen beyond xMax to ensure glitch-free rendering.
                clipCount += point.x > context.XMax ? 1 : 0;
                if (clipCount > 1)
                {
                    break;
                }
            }

            if (screenPoints.Count > 0)
            {
                result.Add(this.RenderScreenPoints(context, screenPoints));
            }

            return result;
        }
Example #9
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        public override void Render(IRenderContext rc)
        {
            this.VerifyAxes();

            var actualPoints = this.ActualPoints;
            if (actualPoints == null || actualPoints.Count == 0)
            {
                return;
            }

            var actualPoints2 = this.ActualPoints2;
            if (actualPoints2 == null || actualPoints2.Count == 0)
            {
                return;
            }

            int startIdx = 0;
            int startIdx2 = 0;
            double xmax = double.MaxValue;

            if (this.IsXMonotonic)
            {
                // determine render range
                var xmin = this.XAxis.ActualMinimum;
                xmax = this.XAxis.ActualMaximum;
                this.WindowStartIndex = this.UpdateWindowStartIndex(actualPoints, point => point.X, xmin, this.WindowStartIndex);
                this.WindowStartIndex2 = this.UpdateWindowStartIndex(actualPoints2, point => point.X, xmin, this.WindowStartIndex2);

                startIdx = this.WindowStartIndex;
                startIdx2 = this.WindowStartIndex2;
            }

            double minDistSquared = this.MinimumSegmentLength * this.MinimumSegmentLength;

            var clippingRect = this.GetClippingRect();
            rc.SetClip(clippingRect);

            var areaContext = new AreaRenderContext
            {
                Points = actualPoints,
                WindowStartIndex = startIdx,
                XMax = xmax,
                RenderContext = rc,
                ClippingRect = clippingRect,
                MinDistSquared = minDistSquared,
                Reverse = false,
                Color = this.ActualColor,
                DashArray = this.ActualDashArray
            };

            var chunksOfPoints = this.RenderChunkedPoints(areaContext);

            areaContext.Points = actualPoints2;
            areaContext.WindowStartIndex = startIdx2;
            areaContext.Reverse = this.Reverse2;
            areaContext.Color = this.ActualColor2;

            var chunksOfPoints2 = this.RenderChunkedPoints(areaContext);

            if (chunksOfPoints.Count != chunksOfPoints2.Count)
            {
                rc.ResetClip();
                return;
            }

            // Draw the fill
            for (int chunkIndex = 0; chunkIndex < chunksOfPoints.Count; chunkIndex++)
            {
                var pts = chunksOfPoints[chunkIndex];
                var pts2 = chunksOfPoints2[chunkIndex];

                // pts = SutherlandHodgmanClipping.ClipPolygon(clippingRect, pts);

                // combine the two lines and draw the clipped area
                var allPts = new List<ScreenPoint>();
                allPts.AddRange(pts2);
                allPts.AddRange(pts);
                rc.DrawClippedPolygon(
                    clippingRect,
                    allPts,
                    minDistSquared,
                    this.GetSelectableFillColor(this.ActualFill),
                    OxyColors.Undefined);

                var markerSizes = new[] { this.MarkerSize };

                // draw the markers on top
                rc.DrawMarkers(
                    clippingRect,
                    pts,
                    this.MarkerType,
                    null,
                    markerSizes,
                    this.MarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness,
                    1);
                rc.DrawMarkers(
                    clippingRect,
                    pts2,
                    this.MarkerType,
                    null,
                    markerSizes,
                    this.MarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness,
                    1);
            }

            rc.ResetClip();
        }