private void AddTopPoints(AreaRenderContext context) { PathFigure strokeFigure = null; PolyLineSegment strokeLineSegment = null; PolyLineSegment areaSegment = null; bool addTopPointsToStroke = this.ShouldAddTopPointsToStroke; this.FillEmptyPointsToTopSurface(context, context.CurrentSegment.StartIndex); foreach (Point point in this.GetTopPoints(context.CurrentSegment)) { this.topSurfacePoints.Add(point); context.LastTopPoint = point; // pass for first point if (areaSegment == null) { areaSegment = new PolyLineSegment(); context.AreaFigure.StartPoint = point; if (!context.IsFirstTopPointSet) { context.FirstTopPoint = point; context.IsFirstTopPointSet = true; } if (addTopPointsToStroke) { strokeFigure = new PathFigure(); strokeFigure.IsFilled = false; strokeFigure.StartPoint = point; strokeLineSegment = new PolyLineSegment(); } continue; } areaSegment.Points.Add(point); if (addTopPointsToStroke) { strokeLineSegment.Points.Add(point); } } context.AreaFigure.Segments.Add(areaSegment); if (addTopPointsToStroke) { strokeFigure.Segments.Add(strokeLineSegment); this.shapeGeometry.Figures.Add(strokeFigure); } }
private void AddRightStrokeLine(AreaRenderContext context) { if (this.ShouldAddRightPointsToStroke) { PathFigure strokeFigure = new PathFigure(); strokeFigure.IsFilled = false; strokeFigure.StartPoint = context.LastTopPoint; PolyLineSegment strokeLineSegment = new PolyLineSegment(); strokeLineSegment.Points.Add(context.LastBottomPoint); strokeFigure.Segments.Add(strokeLineSegment); this.shapeGeometry.Figures.Add(strokeFigure); } }
private void AddBottomPoints(AreaRenderContext context) { IList <Point> bottomPoints = this.GetBottomPoints(context); if (!context.IsFirstBottomPointSet) { context.FirstBottomPoint = bottomPoints[0]; context.IsFirstBottomPointSet = true; } context.LastBottomPoint = bottomPoints[bottomPoints.Count - 1]; // Add the bottom points in reverse order PathFigure strokeFigure = null; PolyLineSegment strokeLineSegment = null; bool addBottomPointsToStroke = this.ShouldAddBottomPointsToStroke; if (addBottomPointsToStroke) { strokeFigure = new PathFigure(); strokeFigure.IsFilled = false; strokeFigure.StartPoint = bottomPoints[bottomPoints.Count - 1]; strokeLineSegment = new PolyLineSegment(); } PolyLineSegment areaSegment = new PolyLineSegment(); for (int i = bottomPoints.Count - 1; i >= 0; i--) { Point point = bottomPoints[i]; areaSegment.Points.Add(point); if (addBottomPointsToStroke && i < bottomPoints.Count - 1) { // Skip last point since we already added it strokeLineSegment.Points.Add(point); } } context.AreaFigure.Segments.Add(areaSegment); if (addBottomPointsToStroke) { strokeFigure.Segments.Add(strokeLineSegment); this.shapeGeometry.Figures.Add(strokeFigure); } }
protected override IList <Point> GetBottomPoints(AreaRenderContext context) { AxisPlotDirection plotDirection = this.model.GetTypedValue <AxisPlotDirection>(AxisModel.PlotDirectionPropertyKey, AxisPlotDirection.Vertical); ReferenceDictionary <string, Delegate> valueExtractor = plotDirection == AxisPlotDirection.Vertical ? VerticalRangePlotValueExtractors : HorizontalRangePlotValueExtractors; Func <DataPoint, Point> bottomPointGetter = (Func <DataPoint, Point>)valueExtractor[BottomPointGetter]; DataPointSegment currentSegment = context.CurrentSegment; List <Point> points = new List <Point>(); int pointIndex = currentSegment.StartIndex; while (pointIndex <= currentSegment.EndIndex) { var currentPoint = this.renderPoints[pointIndex]; points.Add(bottomPointGetter(currentPoint)); pointIndex++; } return(points); }
protected override void RenderCore() { // we need at least two points to calculate the line if (this.renderPoints.Count < 2) { return; } AreaRenderContext context = new AreaRenderContext(this); foreach (DataPointSegment dataSegment in ChartSeriesRenderer.GetDataSegments(this.renderPoints)) { context.CurrentSegment = dataSegment; context.AreaFigure = new PathFigure(); this.AddTopPoints(context); this.AddBottomPoints(context); context.AreaFigure.IsClosed = true; this.areaShapeGeometry.Figures.Add(context.AreaFigure); context.PreviousSegmentEndIndex = dataSegment.EndIndex; } // Fill in top points this.FillEmptyPointsToTopSurface(context, this.renderPoints.Count - 1); if (!this.renderPoints[this.renderPoints.Count - 1].isEmpty) { this.AddRightStrokeLine(context); } if (!this.renderPoints[0].isEmpty) { this.AddLeftStrokeLine(context); } }
private void FillEmptyPointsToTopSurface(AreaRenderContext context, int lastDataPointIndex) { ReferenceDictionary <string, Delegate> valueExtractor; if (context.PlotDirection == AxisPlotDirection.Vertical) { valueExtractor = VerticalPlotValueExtractors; } else { valueExtractor = HorizontalPlotValueExtractors; } Func <DataPoint, bool, int> dataPointBoundsGetter = (Func <DataPoint, bool, int>)valueExtractor[DataPointBoundsGetter]; int lastPointBounds = dataPointBoundsGetter(this.renderPoints[lastDataPointIndex], context.IsPlotInverse); int previousSegmentEnd = dataPointBoundsGetter(this.renderPoints[context.PreviousSegmentEndIndex], context.IsPlotInverse); if (context.PreviousSegmentEndIndex == lastDataPointIndex || previousSegmentEnd == lastPointBounds) { return; } if (!context.IsStacked) { Func <DataPoint, double, Point> pointGetter = (Func <DataPoint, double, Point>)valueExtractor[PointGetter]; for (int i = context.PreviousSegmentEndIndex; i <= lastDataPointIndex; i++) { this.topSurfacePoints.Add(pointGetter(this.renderPoints[i], context.PlotLine)); } } else { Func <Point, int> pointBoundsGetter = (Func <Point, int>)valueExtractor[PointBoundsGetter]; Func <int, int, bool, bool> shouldSkipPreviousPoints = (Func <int, int, bool, bool>)valueExtractor[ShouldSkipPreviousPoints]; Func <int, int, bool, bool> segmentEndNotReached = (Func <int, int, bool, bool>)valueExtractor[SegmentEndNotReached]; Func <Point, Point, Point, bool> shouldRemoveDuplicate = (Func <Point, Point, Point, bool>)valueExtractor[ShouldRemoveDuplicate2]; int lastTopSurfacePointsCount = this.topSurfacePoints.Count; IList <Point> stackedPoints = context.PreviousStackedPoints; Point currentPoint; int currentPointBounds; do { currentPoint = stackedPoints[context.PreviousStackedPointsCurrentIndex]; currentPointBounds = pointBoundsGetter(currentPoint); context.PreviousStackedPointsCurrentIndex++; if (shouldSkipPreviousPoints(currentPointBounds, previousSegmentEnd, context.IsPlotInverse)) { continue; } this.topSurfacePoints.Add(currentPoint); }while (segmentEndNotReached(currentPointBounds, lastPointBounds, context.IsPlotInverse) && context.PreviousStackedPointsCurrentIndex < stackedPoints.Count); context.PreviousStackedPointsCurrentIndex--; if (lastTopSurfacePointsCount > 0 && shouldRemoveDuplicate(this.topSurfacePoints[lastTopSurfacePointsCount - 1], this.topSurfacePoints[lastTopSurfacePointsCount], this.topSurfacePoints[lastTopSurfacePointsCount + 1])) { this.topSurfacePoints.RemoveAt(lastTopSurfacePointsCount); } } }
protected abstract IList <Point> GetBottomPoints(AreaRenderContext context);
protected override IList <Windows.Foundation.Point> GetBottomPoints(AreaRenderContext context) { List <Point> points = new List <Point>(); DataPointSegment currentSegment = context.CurrentSegment; ReferenceDictionary <string, Delegate> valueExtractor; if (context.PlotDirection == AxisPlotDirection.Vertical) { valueExtractor = AreaRendererBase.VerticalPlotValueExtractors; } else { valueExtractor = AreaRendererBase.HorizontalPlotValueExtractors; } if (!context.IsStacked) { Func <DataPoint, double, Point> pointGetter = (Func <DataPoint, double, Point>)valueExtractor[PointGetter]; points.Add(pointGetter(this.renderPoints[currentSegment.StartIndex], context.PlotLine)); points.Add(pointGetter(this.renderPoints[currentSegment.EndIndex], context.PlotLine)); } else { Func <Point, int> pointBoundsGetter = (Func <Point, int>)valueExtractor[PointBoundsGetter]; Func <DataPoint, bool, int> dataPointBoundsGetter = (Func <DataPoint, bool, int>)valueExtractor[DataPointBoundsGetter]; Func <int, int, bool, bool> shouldSkipPreviousPoints = (Func <int, int, bool, bool>)valueExtractor[ShouldSkipPreviousPoints]; Func <int, int, bool, bool> segmentEndNotReached = (Func <int, int, bool, bool>)valueExtractor[SegmentEndNotReached]; Func <Point, Point, bool> shouldRemoveDuplicate = (Func <Point, Point, bool>)valueExtractor[ShouldRemoveDuplicate]; int segmentStart = dataPointBoundsGetter(this.renderPoints[currentSegment.StartIndex], context.IsPlotInverse); int segmentEnd = dataPointBoundsGetter(this.renderPoints[currentSegment.EndIndex], context.IsPlotInverse); IList <Point> stackedPoints = context.PreviousStackedPoints; Point currentPoint; int currentPointBounds; do { currentPoint = stackedPoints[context.PreviousStackedPointsCurrentIndex]; currentPointBounds = pointBoundsGetter(currentPoint); context.PreviousStackedPointsCurrentIndex++; if (shouldSkipPreviousPoints(currentPointBounds, segmentStart, context.IsPlotInverse)) { continue; } points.Add(currentPoint); }while (segmentEndNotReached(currentPointBounds, segmentEnd, context.IsPlotInverse) && context.PreviousStackedPointsCurrentIndex < stackedPoints.Count); context.PreviousStackedPointsCurrentIndex--; if (shouldRemoveDuplicate(points[0], points[1])) { points.RemoveAt(0); } } return(points); }