/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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(); }