/// <summary> /// Updates the stroke rendering for empty points. /// </summary> private void UpdateEmptyPointSegments() { FastRangeAreaSegment previousEmptySegment = null; for (int i = 0; i < Segments.Count; i++) { FastRangeAreaSegment segment = Segments[i] as FastRangeAreaSegment; int count = segment.AreaValues.Count(value => !double.IsNaN(value.Y)); if (count > 1 && count == segment.AreaValues.Count) { if (previousEmptySegment == null) { segment.EmptyStroke = EmptyStroke.Right; } else if (previousEmptySegment.EmptyStroke == EmptyStroke.Right) { segment.EmptyStroke = EmptyStroke.Left; } else if (previousEmptySegment.EmptyStroke == EmptyStroke.Left) { previousEmptySegment.EmptyStroke = EmptyStroke.Both; segment.EmptyStroke = EmptyStroke.Left; } previousEmptySegment = segment; } } }
/// <summary> /// Creates the segments of <see cref="FastRangeAreaBitmapSeries"/>. /// </summary> public override void CreateSegments() { ChartPoint point1; ChartPoint point2; ChartPoint point3; ChartPoint point4; ChartPoint? crossPoint = null; List <ChartPoint> segPoints = new List <ChartPoint>(); List <double> xValues = null; if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (xValues != null) { bool isGrouping = this.ActualXAxis is CategoryAxis ? (this.ActualXAxis as CategoryAxis).IsIndexed : true; if (!isGrouping) { Segments.Clear(); Adornments.Clear(); if (double.IsNaN(GroupedSeriesYValues[1][0]) || !double.IsNaN(GroupedSeriesYValues[0][0])) { segPoints.Add(new ChartPoint(xValues[0], GroupedSeriesYValues[1][0])); segPoints.Add(new ChartPoint(xValues[0], GroupedSeriesYValues[0][0])); var segment = new FastRangeAreaSegment(segPoints, false, this) { High = GroupedSeriesYValues[0][0], Low = GroupedSeriesYValues[1][0], Item = ActualData[0] }; AddSegment(segment, segPoints); } segPoints = new List <ChartPoint>(); int i; for (i = 0; i < xValues.Count - 1; i++) { if (!double.IsNaN(GroupedSeriesYValues[1][i]) && !double.IsNaN(GroupedSeriesYValues[0][i])) { point1 = new ChartPoint(xValues[i], GroupedSeriesYValues[1][i]); point3 = new ChartPoint(xValues[i], GroupedSeriesYValues[0][i]); if (i == 0 || (i < xValues.Count - 1 && (double.IsNaN(GroupedSeriesYValues[1][i - 1]) || double.IsNaN(GroupedSeriesYValues[0][i - 1])))) { segPoints.Add(point1); segPoints.Add(point3); } if (!double.IsNaN(GroupedSeriesYValues[1][i + 1]) && !double.IsNaN(GroupedSeriesYValues[0][i + 1])) { point2 = new ChartPoint(xValues[i + 1], GroupedSeriesYValues[1][i + 1]); point4 = new ChartPoint(xValues[i + 1], GroupedSeriesYValues[0][i + 1]); // UWP-8718 Use ChartMath.GetCrossPoint since it returns the ChartDataPoint withou rounding the values. crossPoint = ChartMath.GetCrossPoint(point1, point2, point3, point4); if (crossPoint != null) { var crossPointValue = new ChartPoint(crossPoint.Value.X, crossPoint.Value.Y); segPoints.Add(crossPointValue); segPoints.Add(crossPointValue); var segment = new FastRangeAreaSegment(segPoints, (GroupedSeriesYValues[1][i] > GroupedSeriesYValues[0][i]), this) { High = GroupedSeriesYValues[0][i], Low = GroupedSeriesYValues[1][i], Item = ActualData[i] }; AddSegment(segment, segPoints); segPoints = new List <ChartPoint>(); segPoints.Add(crossPointValue); segPoints.Add(crossPointValue); } segPoints.Add(point2); segPoints.Add(point4); } else if (i != 0 && !double.IsNaN(GroupedSeriesYValues[1][i - 1]) && !double.IsNaN(GroupedSeriesYValues[0][i - 1])) { segPoints.Add(point1); segPoints.Add(point3); } } else { if (segPoints.Count > 0) { if (!double.IsNaN(GroupedSeriesYValues[1][i - 1]) && !double.IsNaN(GroupedSeriesYValues[0][i - 1])) { var segment = new FastRangeAreaSegment(segPoints, false, this) { High = GroupedSeriesYValues[0][i - 1], Low = GroupedSeriesYValues[1][i - 1], Item = ActualData[i - 1] }; AddSegment(segment, segPoints); } } segPoints = new List <ChartPoint>(); } } if (segPoints.Count > 0) { var segment = new FastRangeAreaSegment(segPoints, (GroupedSeriesYValues[1][i] > GroupedSeriesYValues[0][i]), this) { High = GroupedSeriesYValues[0][i], Low = GroupedSeriesYValues[1][i], Item = ActualData[i] }; AddSegment(segment, segPoints); } else if (i == xValues.Count - 1 && (double.IsNaN(GroupedSeriesYValues[1][i]) || double.IsNaN(GroupedSeriesYValues[0][i]))) { segPoints.Add(new ChartPoint(xValues[i], GroupedSeriesYValues[1][i])); segPoints.Add(new ChartPoint(xValues[i], GroupedSeriesYValues[0][i])); var segment = new FastRangeAreaSegment(segPoints, false, this) { High = GroupedSeriesYValues[0][i], Low = GroupedSeriesYValues[1][i], Item = ActualData[i] }; AddSegment(segment, segPoints); } for (int j = 0; j < xValues.Count; j++) { if (AdornmentsInfo != null) { AddAdornments(xValues[j], 0, GroupedSeriesYValues[0][j], GroupedSeriesYValues[1][j], j); } } } else { Segments.Clear(); if (AdornmentsInfo != null) { if (AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom) { ClearUnUsedAdornments(this.DataCount * 2); } else { ClearUnUsedAdornments(this.DataCount); } } if (xValues != null) { if (double.IsNaN(LowValues[0]) || double.IsNaN(HighValues[0])) { segPoints.Add(new ChartPoint(xValues[0], LowValues[0])); segPoints.Add(new ChartPoint(xValues[0], HighValues[0])); var segment = new FastRangeAreaSegment(segPoints, false, this) { High = HighValues[0], Low = LowValues[0], Item = ActualData[0] }; AddSegment(segment, segPoints); } segPoints = new List <ChartPoint>(); int i; for (i = 0; i < DataCount - 1; i++) { if (!double.IsNaN(LowValues[i]) && !double.IsNaN(HighValues[i])) { point1 = new ChartPoint(xValues[i], LowValues[i]); point3 = new ChartPoint(xValues[i], HighValues[i]); if (i == 0 || (i < DataCount - 1 && (double.IsNaN(LowValues[i - 1]) || double.IsNaN(HighValues[i - 1])))) { segPoints.Add(point1); segPoints.Add(point3); } if (!double.IsNaN(LowValues[i + 1]) && !double.IsNaN(HighValues[i + 1])) { point2 = new ChartPoint(xValues[i + 1], LowValues[i + 1]); point4 = new ChartPoint(xValues[i + 1], HighValues[i + 1]); // UWP-8718 Use ChartMath.GetCrossPoint since it returns the ChartDataPoint withou rounding the values. crossPoint = ChartMath.GetCrossPoint(point1, point2, point3, point4); if (crossPoint != null) { var crossPointValue = new ChartPoint(crossPoint.Value.X, crossPoint.Value.Y); segPoints.Add(crossPointValue); segPoints.Add(crossPointValue); var segment = new FastRangeAreaSegment(segPoints, (LowValues[i] > HighValues[i]), this) { High = HighValues[i], Low = LowValues[i], Item = ActualData[i] }; AddSegment(segment, segPoints); segPoints = new List <ChartPoint>(); segPoints.Add(crossPointValue); segPoints.Add(crossPointValue); } segPoints.Add(point2); segPoints.Add(point4); } } else { if (segPoints.Count > 0) { if (!double.IsNaN(LowValues[i - 1]) && !double.IsNaN(HighValues[i - 1])) { var segment = new FastRangeAreaSegment(segPoints, false, this) { High = HighValues[i - 1], Low = LowValues[i - 1], Item = ActualData[i - 1] }; AddSegment(segment, segPoints); } } segPoints = new List <ChartPoint>(); } } if (segPoints.Count > 0) { var segment = new FastRangeAreaSegment(segPoints, (LowValues[i] > HighValues[i]), this) { High = HighValues[i], Low = LowValues[i], Item = ActualData[i] }; AddSegment(segment, segPoints); } else if (i == DataCount - 1 && (double.IsNaN(LowValues[i]) || double.IsNaN(HighValues[i]))) { segPoints.Add(new ChartPoint(xValues[i], LowValues[i])); segPoints.Add(new ChartPoint(xValues[i], HighValues[i])); var segment = new FastRangeAreaSegment(segPoints, false, this) { High = HighValues[i], Low = LowValues[i], Item = ActualData[i] }; AddSegment(segment, segPoints); } } for (int i = 0; i < xValues.Count; i++) { if (AdornmentsInfo != null) { AddAdornments(xValues[i], 0, HighValues[i], LowValues[i], i); } } } } // Updates the stroke rendering for empty points. if (Segments.Count > 1) { UpdateEmptyPointSegments(); } }
/// <summary> /// Adds the created segment to the segment collection. /// </summary> /// <param name="segment">The segment to be added.</param> /// <param name="segPoints">The segment values used to render the <see cref="FastRangeAreaSegment"/>.</param> private void AddSegment(FastRangeAreaSegment segment, List <ChartPoint> segPoints) { segment.Series = this; segment.SetData(segPoints); Segments.Add(segment); }