/// <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) { if (transformer == null) { return; } var cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; if (cartesianTransformer == null) { return; } if (double.IsNaN(this.YData) && !Series.ShowEmptyPoints) { return; } var xBase = cartesianTransformer.XAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.XAxis).LogarithmicBase : 1; var xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; var left = xIsLogarithmic ? Math.Log(this.Left, xBase) : this.Left; var right = xIsLogarithmic ? Math.Log(this.Right, xBase) : this.Right; var yBase = cartesianTransformer.YAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.YAxis).LogarithmicBase : 1; var yIsLogarithmic = cartesianTransformer.YAxis.IsLogarithmic; var bottom = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.Start) : cartesianTransformer.YAxis.VisibleRange.Start; var top = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.End) : cartesianTransformer.YAxis.VisibleRange.End; var xStart = cartesianTransformer.XAxis.VisibleRange.Start; var xEnd = cartesianTransformer.XAxis.VisibleRange.End; double z1 = startDepth, z2 = endDepth; var zSeries = this.Series as XyzDataSeries3D; bool isZAxis = cartesianTransformer.ZAxis != null && zSeries.ActualZAxis != null && zSeries.ActualZValues != null; double spacing = (Series as ISegmentSpacing).SegmentSpacing; if (!(left <= xEnd && right >= xStart)) { return; } // WPF -14524 3D Column and Bar Series is rendering out of the pane. while cross the bar value to visualRange of axis. double topValue; if (this.Top < 0) { topValue = this.Top > bottom ? this.Top : bottom; } else { topValue = this.Top < top ? this.Top : top; } this.Bottom = this.Bottom > top ? top : this.Bottom; if (spacing > 0 && spacing <= 1) { double leftpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, right, left); double rightpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, left, right); this.Left = leftpos; this.Right = rightpos; } var area = Series.ActualArea as SfChart3D; var tlfVector = new Vector3D(0, 0, 0); var brbVector = new Vector3D(0, 0, 0); var tlpoint = transformer.TransformToVisible(left > xStart ? this.Left : xStart, topValue < bottom ? bottom : topValue); var rbpoint = transformer.TransformToVisible(xEnd > right ? this.Right : xEnd, bottom > this.Bottom ? bottom : this.Bottom); if (isZAxis) { double zStart = cartesianTransformer.ZAxis.VisibleRange.Start; double zEnd = cartesianTransformer.ZAxis.VisibleRange.End; var zIsLogarithmic = cartesianTransformer.ZAxis.IsLogarithmic; var zBase = zIsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.ZAxis).LogarithmicBase : 1; var actualZ1 = zIsLogarithmic ? Math.Log(z1, zBase) : z1; var actualZ2 = zIsLogarithmic ? Math.Log(z2, zBase) : z2; if (!(actualZ1 <= zEnd && actualZ2 >= zStart)) { return; } tlfVector = cartesianTransformer.TransformToVisible3D(this.Left > xStart ? this.Left : xStart, topValue <bottom?bottom : topValue, z1> zStart ? z1 : zStart); brbVector = cartesianTransformer.TransformToVisible3D(xEnd > this.Right ? this.Right : xEnd, bottom > this.Bottom ? bottom : this.Bottom, zEnd > z2 ? z2 : zEnd); } else { var rect = new Rect(tlpoint, rbpoint); tlfVector = new Vector3D(rect.Left, rect.Top, z1); brbVector = new Vector3D(rect.Right, rect.Bottom, z2); } if (this.plans == null) { this.plans = Polygon3D.CreateBox( tlfVector, brbVector, this, Series.Segments.IndexOf(this), area.Graphics3D, this.Stroke, Interior, this.StrokeThickness, Series.IsActualTransposed); } else { Polygon3D.UpdateBox(this.plans, tlfVector, brbVector, this.Interior, tlpoint.Y == rbpoint.Y ? Visibility.Collapsed : Visibility.Visible); } }
/// <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) { Rect rect; double x, y, width, height; if (transformer == null) { return; } var cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; if (cartesianTransformer == null) { return; } if (double.IsNaN(YData) && !Series.ShowEmptyPoints) { return; } ScatterSeries3D series = (Series as ScatterSeries3D); 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; var xValue = xIsLogarithmic ? Math.Log(X, xBase) : X; var yValue = yIsLogarithmic ? Math.Log(Y, yBase) : Y; var yStart = cartesianTransformer.YAxis.VisibleRange.Start; var yEnd = cartesianTransformer.YAxis.VisibleRange.End; var xStart = cartesianTransformer.XAxis.VisibleRange.Start; var xEnd = cartesianTransformer.XAxis.VisibleRange.End; var zSeries = this.Series as XyzDataSeries3D; bool isZAxis = cartesianTransformer.ZAxis != null && zSeries.ActualZAxis != null && (zSeries as XyzDataSeries3D).ActualZValues != null; Point tlpoint = new Point(0, 0); double frontDepth = 0d; double backDepth = 0d; if (isZAxis) { var z1value = startDepth; var z2value = endDepth; var depthDelta = (this.Series as ScatterSeries3D).GetSegmentDepth((this.Series.ActualArea as SfChart3D).ActualDepth).Delta / 2; var zStart = cartesianTransformer.ZAxis.VisibleRange.Start; var zEnd = cartesianTransformer.ZAxis.VisibleRange.End; var zIsLogarithmic = cartesianTransformer.ZAxis.IsLogarithmic; var zBase = zIsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.ZAxis).LogarithmicBase : 1; var actualZ1 = zIsLogarithmic ? Math.Log(z1value, zBase) : z1value; var actualZ2 = zIsLogarithmic ? Math.Log(z2value, zBase) : z2value; if (!(actualZ1 <= zEnd && actualZ2 >= zStart)) { return; } var zLogStart = zIsLogarithmic ? Math.Pow(zBase, zStart) : zStart; var zLogEnd = zIsLogarithmic ? Math.Pow(zBase, zEnd) : zEnd; var tldpoint = cartesianTransformer.TransformToVisible3D(xValue, yValue, actualZ1 <zStart?zLogStart : actualZ1> zEnd ? zLogEnd : z1value); tlpoint = new Point(tldpoint.X, tldpoint.Y); frontDepth = (z1value == zStart) ? tldpoint.Z : tldpoint.Z - ScatterHeight / 2 < tldpoint.Z - depthDelta ? tldpoint.Z - depthDelta : tldpoint.Z - ScatterHeight / 2; backDepth = (z2value == zEnd) ? tldpoint.Z : tldpoint.Z + ScatterHeight / 2 > tldpoint.Z + depthDelta ? tldpoint.Z + depthDelta : tldpoint.Z + ScatterHeight / 2; } else { tlpoint = transformer.TransformToVisible(X, Y); } if (!series.Area.SeriesClipRect.Contains(tlpoint) && ((xValue != xEnd && xValue != xStart) || (yValue != yEnd && yValue != yStart)) && !(series.IsTransposed)) { return; } if (series.ScatterHeight <= 0 || series.ScatterWidth <= 0) { return; } x = (xValue == (series.IsTransposed ? xEnd : xStart)) ? tlpoint.X : tlpoint.X - (series.IsTransposed ? ScatterHeight / 2 : ScatterWidth / 2); y = (yValue == (series.IsTransposed ? yStart : yEnd)) ? tlpoint.Y : tlpoint.Y - (series.IsTransposed ? ScatterWidth / 2 : ScatterHeight / 2); width = (xValue == xStart) || (xValue == xEnd) ? ScatterWidth / 2 : ScatterWidth; height = (yValue == yStart) || (yValue == yEnd) ? ScatterHeight / 2 : ScatterHeight; rect = new Rect(x, y, width, height); if (!series.IsTransposed) { // Clipping segment of nearest range point if (!Series.ActualArea.SeriesClipRect.Contains(new Point(x, y))) { rect = new Rect(x, Series.ActualArea.SeriesClipRect.Top, width, height + y); } if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left, rect.Bottom))) { rect = new Rect(x, y, width, Math.Abs(height + (Series.ActualArea.SeriesClipRect.Bottom - rect.Bottom) > ScatterHeight ? height : height + (Series.ActualArea.SeriesClipRect.Bottom - rect.Bottom))); } if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left, rect.Top))) { var modifiedWidth = Math.Abs(width - (Series.ActualXAxis.RenderedRect.X - rect.X)); rect = new Rect(Series.ActualXAxis.RenderedRect.X, y, modifiedWidth, rect.Height); } if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left + rect.Width, rect.Top))) { var modifiedWidth = Math.Abs(rect.Width + (Series.ActualArea.SeriesClipRect.Right - rect.Right)); rect = new Rect(rect.X, rect.Y, modifiedWidth, rect.Height); } } else { rect = new Rect(x, y, height, width); if (x < tlpoint.X && xValue == xStart && yValue == yStart) { rect = new Rect(tlpoint.X, y, height, width); } if (y < tlpoint.Y && yValue == yStart) { rect = new Rect(tlpoint.X, tlpoint.Y, height, width); } if (y == tlpoint.Y && yValue == yStart) { rect = new Rect(tlpoint.X, tlpoint.Y - ScatterWidth / 2, height, width); } if (y < tlpoint.Y && xValue == xEnd) { rect = new Rect(tlpoint.X, tlpoint.Y, height, width); } if (x == tlpoint.X && xValue == xEnd) { rect = new Rect(tlpoint.X, tlpoint.Y, height, width); } if (x == tlpoint.X && xValue == xEnd && yValue != yStart) { rect = new Rect(tlpoint.X - ScatterHeight / 2, tlpoint.Y, height, width); } } var area = Series.ActualArea as SfChart3D; Vector3D tlfVector = new Vector3D(0, 0, 0); Vector3D brbVector = new Vector3D(0, 0, 0); if (isZAxis) { tlfVector = new Vector3D(rect.Left, rect.Top, frontDepth); brbVector = new Vector3D(rect.Right, rect.Bottom, backDepth); } else { tlfVector = new Vector3D(rect.Left, rect.Top, startDepth); brbVector = new Vector3D(rect.Right, rect.Bottom, startDepth + ScatterHeight > endDepth ? endDepth : startDepth + ScatterHeight); } if (plans == null) { plans = Polygon3D.CreateBox( tlfVector, brbVector, this, series.Segments.IndexOf(this), area.Graphics3D, Stroke, Interior, StrokeThickness, Series.IsActualTransposed); } else { Polygon3D.UpdateBox(plans, tlfVector, brbVector, Interior, Visibility.Visible); } }