/// <summary> /// Updates the second points. /// </summary> /// <param name="xStart">The Start X Value</param> /// <param name="yStart">The Start Y Value</param> /// <param name="xEnd">The End X Value</param> /// <param name="yEnd">The End Y Value</param> /// <param name="leftThickness">The Left Thickness</param> /// <param name="rightThickness">The Right Thickness</param> private void UpdatePoints2(double xStart, double yStart, double xEnd, double yEnd, double leftThickness, double rightThickness) { LineSegment3D.GetLinePoints(xStart, yStart, xEnd, yEnd, leftThickness, rightThickness, point2); bool isIntersecting = this.FindIntersectingPoint( this.point1[0], this.point1[1], this.point1[2], this.point1[3], this.point2[0], this.point2[1], this.point2[2], this.point2[3]); if (isIntersecting) { var diff1 = this.intersectingPoint.X - this.point1[2]; var diff2 = this.point2[0] - this.point1[2]; bool canSwap = false; if (diff1 < 0) { canSwap = diff1 >= -3; } else { canSwap = diff2 >= diff1 || (diff1 - diff2) <= 3; } if (canSwap) { this.point1[2] = this.intersectingPoint.X; this.point1[3] = this.intersectingPoint.Y; this.point2[0] = this.intersectingPoint.X; this.point2[1] = intersectingPoint.Y; this.point2[8] = this.intersectingPoint.X; this.point2[9] = this.intersectingPoint.Y; } } isIntersecting = this.FindIntersectingPoint( this.point1[6], this.point1[7], this.point1[4], this.point1[5], this.point2[6], this.point2[7], this.point2[4], this.point2[5]); if (isIntersecting) { var diff1 = this.intersectingPoint.X - this.point1[4]; var diff2 = this.point2[6] - this.point1[4]; bool canSwap; if (diff1 < 0) { canSwap = diff1 >= -3; } else { canSwap = diff2 >= diff1 || (diff1 - diff2) <= 3; } if (canSwap) { this.point1[4] = this.intersectingPoint.X; this.point1[5] = this.intersectingPoint.Y; this.point2[6] = this.intersectingPoint.X; this.point2[7] = this.intersectingPoint.Y; } } }
/// <summary> /// Updates the segments based on its data point value. This method is not /// intended to be called explicitly outside the Chart but it can be overridden by /// any derived class. /// </summary> /// <param name="transformer">Represents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; if (cartesianTransformer != null) { Polygon3D bottomPolygon, topPolygon, startPolygon, endPolygon; LineSeries3D lineSeries = Series as LineSeries3D; if (this.area == null || this.xValues.Count == 1 || lineSeries.StrokeThickness == 0) { return; } var xBase = cartesianTransformer.XAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.XAxis).LogarithmicBase : 1; var yBase = cartesianTransformer.YAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.YAxis).LogarithmicBase : 1; var xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; var yIsLogarithmic = cartesianTransformer.YAxis.IsLogarithmic; double xStart = xIsLogarithmic ? Math.Pow(xBase, cartesianTransformer.XAxis.VisibleRange.Start) : cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = xIsLogarithmic ? Math.Pow(xBase, cartesianTransformer.XAxis.VisibleRange.End) : cartesianTransformer.XAxis.VisibleRange.End; var yStart = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.Start) : cartesianTransformer.YAxis.VisibleRange.Start; var yEnd = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.End) : cartesianTransformer.YAxis.VisibleRange.End; // Clipping the line series 3D if (xValues.Min() < xStart) { while (this.xValues[0] < xStart) { this.xValues.RemoveAt(0); this.yValues.RemoveAt(0); } } if (this.xValues.Max() > xEnd) { int index = this.xValues.IndexOf(xEnd); while (this.xValues[index + 1] > xEnd) { this.xValues.RemoveAt(index + 1); this.yValues.RemoveAt(index + 1); if (index >= this.xValues.Count - 1) { break; } } } var indexes = from val in this.yValues.ToList() where (val <yStart || val> yEnd) select this.yValues.IndexOf(val); if (this.yValues.Count - indexes.Count() < 2) { return; } if (indexes.Count() > 0) { foreach (var index in indexes) { if (yValues[index] < yStart) { this.yValues[index] = yStart; } else { this.yValues[index] = yEnd; } } } //// End of clipping logic double x = this.xValues[0]; double y = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[0] : (this.Y < this.yValues[0] && this.Y > 0) ? this.Y : this.yValues[0]; Point previousPoint = transformer.TransformToVisible(x, y); Point currentPoint; this.point2 = new double[10]; this.point1 = new double[10]; x = this.xValues[1]; y = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[1] : (this.Y < this.yValues[1] && Y > 0) ? this.Y : this.yValues[1]; currentPoint = transformer.TransformToVisible(x, y); int leftThickness = lineSeries.StrokeThickness / 2; int rightThickness = (lineSeries.StrokeThickness % 2 == 0 ? (lineSeries.StrokeThickness / 2) - 1 : lineSeries.StrokeThickness / 2); LineSegment3D.GetLinePoints(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y, leftThickness, rightThickness, this.point1); int j = 0; // To reset the polygon recycler collection index. this.polygonRecycler.Reset(); for (int i = 1; i < this.yValues.Count;) { this.point2 = new double[10]; previousPoint = currentPoint; bool isMultiColor = (Series.SegmentColorPath != null || Series.Palette != ChartColorPalette.None); this.color = isMultiColor ? (Series.GetInteriorColor(i - 1)) : (this.Interior); if (i == 1) { Vector3D[] startPolygonVects = new Vector3D[] { new Vector3D(this.point1[6], this.point1[7], startDepth), new Vector3D(this.point1[6], this.point1[7], endDepth), new Vector3D(this.point1[0], this.point1[1], endDepth), new Vector3D(this.point1[0], this.point1[1], startDepth) }; startPolygon = this.polygonRecycler.DequeuePolygon(startPolygonVects, this, Series.Segments.IndexOf(this), this.Stroke, this.StrokeThickness, this.color); if (lineSeries.IsAnimated || !Series.EnableAnimation) { this.area.Graphics3D.AddVisual(startPolygon); } } i++; if (i < this.xValues.Count) { x = this.xValues[i]; y = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[i] : (this.Y < this.yValues[i] && this.Y > 0) ? this.Y : this.yValues[i]; x = !(x >= xStart) ? xStart : !(x <= xEnd) ? xEnd : x; y = !(y >= yStart) ? yStart : !(y <= yEnd) ? yEnd : y; currentPoint = transformer.TransformToVisible(x, y); this.UpdatePoints2(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y, leftThickness, rightThickness); } Vector3D[] bottomPolyVects = new Vector3D[] { new Vector3D(this.point1[2], this.point1[3], startDepth), new Vector3D(this.point1[0], this.point1[1], startDepth), new Vector3D(this.point1[0], this.point1[1], endDepth), new Vector3D(this.point1[2], this.point1[3], endDepth) }; Vector3D[] topPolyVects = new Vector3D[] { new Vector3D(this.point1[6], this.point1[7], startDepth), new Vector3D(this.point1[4], this.point1[5], startDepth), new Vector3D(this.point1[4], this.point1[5], endDepth), new Vector3D(this.point1[6], point1[7], endDepth) }; bottomPolygon = new Polygon3D( bottomPolyVects, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, this.color); bottomPolygon.CalcNormal(bottomPolyVects[0], bottomPolyVects[1], bottomPolyVects[2]); bottomPolygon.CalcNormal(); topPolygon = new Polygon3D( topPolyVects, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, this.color); topPolygon.CalcNormal(topPolyVects[0], topPolyVects[1], topPolyVects[2]); topPolygon.CalcNormal(); if (lineSeries.IsAnimated || !Series.EnableAnimation) { this.area.Graphics3D.AddVisual(bottomPolygon); this.area.Graphics3D.AddVisual(topPolygon); this.RenderFrontPolygon(this.point1, this.startDepth, this.endDepth, this.color); } if (this.point2 != null && (i < this.xValues.Count)) { this.point1 = this.point2; } j++; } Vector3D[] endPolyVects = new Vector3D[] { new Vector3D(this.point1[4], this.point1[5], startDepth), new Vector3D(this.point1[4], this.point1[5], endDepth), new Vector3D(this.point1[2], this.point1[3], endDepth), new Vector3D(this.point1[2], this.point1[3], startDepth) }; endPolygon = new Polygon3D(endPolyVects, this, 0, Stroke, 1, this.color); endPolygon.CalcNormal(endPolyVects[0], endPolyVects[1], endPolyVects[2]); endPolygon.CalcNormal(); if (lineSeries.IsAnimated || !Series.EnableAnimation) { this.area.Graphics3D.AddVisual(endPolygon); } } }