/// <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) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double edgeValue = xIsLogarithmic ? Math.Log(xVal, xBase) : xVal; if (edgeValue >= xStart && edgeValue <= xEnd && ((!double.IsNaN(highValue) && !double.IsNaN(lowValue)) || Series.ShowEmptyPoints)) { Point hipoint = transformer.TransformToVisible(xVal, highValue); Point lopoint = transformer.TransformToVisible(xVal, lowValue); segLine.X1 = hipoint.X; segLine.Y1 = hipoint.Y; segLine.X2 = lopoint.X; segLine.Y2 = lopoint.Y; } else { segLine.ClearUIValues(); } } }
/// <summary> /// Method used to calculate the segment's rendering rect. /// </summary> /// <param name="transformer"></param> /// <param name="segment"></param> /// <returns></returns> private Rect CalculateSegmentRect(IChartTransformer transformer) { double spacing = (Series is HistogramSeries) ? 0.0 : (Series as ISegmentSpacing).SegmentSpacing; Point tlpoint = transformer.TransformToVisible(Left, Top); Point rbpoint = transformer.TransformToVisible(Right, Bottom); Rect segmentRect = new Rect(tlpoint, rbpoint); if (spacing > 0.0 && spacing <= 1) { if (Series.IsActualTransposed == true) { double leftpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, segmentRect.Bottom, segmentRect.Top); segmentRect.Y = leftpos; Height = segmentRect.Height = (1 - spacing) * segmentRect.Height; } else { double leftpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, segmentRect.Right, segmentRect.Left); segmentRect.X = leftpos; Width = segmentRect.Width = (1 - spacing) * segmentRect.Width; } } return(segmentRect); }
/// <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) { PathFigure figure = new PathFigure(); int startIndex = 0; int endIndex = AreaPoints.Count - 1; if (AreaPoints.Count > 0) { figure.StartPoint = transformer.TransformToVisible(AreaPoints[0].X, AreaPoints[0].Y); for (int i = startIndex; i < AreaPoints.Count; i += 2) { WindowsLinesegment lineSeg = new WindowsLinesegment(); lineSeg.Point = transformer.TransformToVisible(AreaPoints[i].X, AreaPoints[i].Y); figure.Segments.Add(lineSeg); } for (int i = endIndex; i >= 1; i -= 2) { WindowsLinesegment lineSeg = new WindowsLinesegment(); lineSeg.Point = transformer.TransformToVisible(AreaPoints[i].X, AreaPoints[i].Y); figure.Segments.Add(lineSeg); } figure.IsClosed = true; Series.SeriesRootPanel.Clip = null; } PathGeometry segmentGeometry = new PathGeometry(); segmentGeometry.Figures.Add(figure); segPath.Data = segmentGeometry; }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { if (transformer != null) { if (isSegmentUpdated) { Series.SeriesRootPanel.Clip = null; } ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double left = xIsLogarithmic ? Math.Log(Point1.X, xBase) : Point1.X; double right = xIsLogarithmic ? Math.Log(Point4.X, xBase) : Point4.X; if ((left <= xEnd && right >= xStart)) { PathFigure figure = new PathFigure(); BezierSegment bezierSeg = new BezierSegment(); PathGeometry segGeometry = new PathGeometry(); P1 = figure.StartPoint = transformer.TransformToVisible(Point1.X, Point1.Y); Q1 = bezierSeg.Point1 = transformer.TransformToVisible(Point2.X, Point2.Y); Q2 = bezierSeg.Point2 = transformer.TransformToVisible(Point3.X, Point3.Y); P2 = bezierSeg.Point3 = transformer.TransformToVisible(Point4.X, Point4.Y); figure.Segments.Add(bezierSeg); segGeometry.Figures = new PathFigureCollection() { figure }; var path = this.segPath; if (path != null) { path.Data = segGeometry; } else { Data = segGeometry; } } else { if (segPath != null) { this.segPath.Data = null; } else if (Data != null) { Data = null; } } isSegmentUpdated = true; } }
/// <summary> /// This method is used to gets the selected data point segment pixel positions /// </summary> internal void GenerateColumnPixels() { if (!double.IsNaN(dataPoint.YData)) { WriteableBitmap bmp = Area.fastRenderSurface; IChartTransformer chartTransformer = CreateTransformer( new Size( Area.SeriesClipRect.Width, Area.SeriesClipRect.Height), true); bool x_isInversed = ActualXAxis.IsInversed; bool y_isInversed = ActualYAxis.IsInversed; DoubleRange sbsInfo = GetSideBySideInfo(this); double origin = ActualXAxis != null ? ActualXAxis.Origin : 0; double x1 = x_isInversed ? dataPoint.XData + sbsInfo.End : dataPoint.XData + sbsInfo.Start; double x2 = x_isInversed ? dataPoint.XData + sbsInfo.Start : dataPoint.XData + sbsInfo.End; double y1 = y_isInversed ? origin : dataPoint.YData; double y2 = y_isInversed ? dataPoint.YData : origin; Point tlpoint = chartTransformer.TransformToVisible(x1, y1); Point rbpoint = chartTransformer.TransformToVisible(x2, y2); double _x1 = tlpoint.X; double _x2 = rbpoint.X; double _y1 = y1 > 0 ? tlpoint.Y : rbpoint.Y; double _y2 = y1 > 0 ? rbpoint.Y : tlpoint.Y; int width = (int)Area.SeriesClipRect.Width; int height = (int)Area.SeriesClipRect.Height; var spacingSegment = this as ISegmentSpacing; if (spacingSegment != null) { double spacing = spacingSegment.SegmentSpacing; if (spacing > 0 && spacing <= 1) { double leftpos = spacingSegment.CalculateSegmentSpacing(spacing, _x2, _x1); double rightpos = spacingSegment.CalculateSegmentSpacing(spacing, _x1, _x2); _x1 = (float)(leftpos); _x2 = (float)(rightpos); } } selectedSegmentPixels.Clear(); if (_y1 < _y2) { selectedSegmentPixels = bmp.GetRectangle(width, height, (int)(_x1), (int)_y1, (int)_x2, (int)_y2, selectedSegmentPixels); } else { selectedSegmentPixels = bmp.GetRectangle(width, height, (int)(_x1), (int)_y2, (int)_x2, (int)_y1, selectedSegmentPixels); } } }
/// <summary> /// Updates the real coordinates of segment. /// </summary> /// <param name="transformer">Instance of class that implements <see cref="IChartTransformer"/> interface.</param> public override void Update(IChartTransformer transformer) { if (this.Interior.CanFreeze) { this.Interior.Freeze(); } if (this.Stroke.CanFreeze) { this.Stroke.Freeze(); } // Generate the Spline Curve Geomentry PathFigure figure = new PathFigure(); figure.StartPoint = transformer.TransformToVisible(AreaPoints[0].X, 0); figure.Segments.Add(new LineSegment(transformer.TransformToVisible(AreaPoints[0].X, AreaPoints[0].Y), true)); int i; for (i = 1; i < CorrespondingPoints.Length; i++) { Point point1 = transformer.TransformToVisible(i, CorrespondingPoints[i].DataPoint.Y); Point point2 = transformer.TransformToVisible(i, CorrespondingPoints[i].DataPoint.Y); Point point3 = transformer.TransformToVisible(i, CorrespondingPoints[i].DataPoint.Y); figure.Segments.Add(new BezierSegment(point1, point2, point3, true)); } Point point11 = transformer.TransformToVisible(CorrespondingPoints[CorrespondingPoints.Length - 1].DataPoint.X, CorrespondingPoints[CorrespondingPoints.Length - 1].DataPoint.Y); Point point21 = transformer.TransformToVisible(CorrespondingPoints[CorrespondingPoints.Length - 1].DataPoint.X, CorrespondingPoints[CorrespondingPoints.Length - 1].DataPoint.Y); Point point31 = transformer.TransformToVisible(CorrespondingPoints[CorrespondingPoints.Length - 1].DataPoint.X, m_HybirdLineValue.Y); figure.Segments.Add(new BezierSegment(point11, point21, point31, true)); figure.Segments.Add(new LineSegment(transformer.TransformToVisible(0, m_HybirdLineValue.Y), false)); figure.IsClosed = true; PathGeometry pathgeomentry = new PathGeometry(); pathgeomentry.Figures.Add(figure); PathFigureCollection PathFigurecoll = new PathFigureCollection(); PathFigurecoll.Add(figure); //Initialize the Spline curve Geometry data this.Geometry = pathgeomentry; // Calculates the value for HybridLine Point point = transformer.TransformToVisible(0d, m_HybirdLineValue.Y); this.HybirdMargin = new Thickness(0, point.Y, 0, 0); }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { var adornment3D = this as ChartAdornment3D; if (this.Series is XyzDataSeries3D && !string.IsNullOrEmpty((this.Series as XyzDataSeries3D).ZBindingPath)) { var vector3D = (transformer as ChartTransform.ChartCartesianTransformer).TransformToVisible3D(XPos, YPos, adornment3D.StartDepth); this.X = vector3D.X; this.Y = vector3D.Y; adornment3D.ActualStartDepth = vector3D.Z; } else { if (Series is RangeColumnSeries && !Series.IsMultipleYPathRequired) { YPos = (Series.ActualYAxis.VisibleRange.End - Math.Abs(Series.ActualYAxis.VisibleRange.Start)) / 2; } Point point = transformer.TransformToVisible(XPos, YPos); this.X = point.X; this.Y = point.Y; if (adornment3D != null) { adornment3D.ActualStartDepth = adornment3D.StartDepth; } } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { this.Points = new PointCollection(); foreach (var item in distributionPoints) { Point point = transformer.TransformToVisible(item.X, item.Y); Points.Add(point); } this.polyLine.Points = Points; }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { if (Series is RangeColumnSeries && !Series.IsMultipleYPathRequired) { YPos = (Series.ActualYAxis.VisibleRange.End - Math.Abs(Series.ActualYAxis.VisibleRange.Start)) / 2; } Point point = transformer.TransformToVisible(XPos, YPos); this.X = point.X; this.Y = point.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) { if (transformer != null) { Point position = transformer.TransformToVisible(XData, YData); this.X = position.X - (EmptyPointSymbolWidth / 2); this.Y = position.Y - (EmptyPointSymbolHeight / 2); } if (Series.EmptyPointSymbolTemplate == null) { base.Update(transformer); } }
internal void UpdateSegment(int index, NotifyCollectionChangedAction action, IChartTransformer transformer) { if (action == NotifyCollectionChangedAction.Remove) { this.Points.RemoveAt(index); } else if (action == NotifyCollectionChangedAction.Add) { Point point = transformer.TransformToVisible(xChartVals[index], yChartVals[index]); Points.Add(point); UpdateVisual(false); } }
internal void UpdateMeanSymbol(IChartTransformer cartesianTransformer, bool showMedian) { if (showMedian) { averagePath.Visibility = Visibility.Visible; Point averagePoint = cartesianTransformer.TransformToVisible(Center, average); double sizeRatio = 0.25, CenterX, CenterY; if (this.Series.IsActualTransposed) { //To retain with the path size when the size is increased. double widthFactor = rect.Height * sizeRatio; widthFactor = widthFactor > averagePathSize ? averagePathSize : widthFactor; averagePath.Width = widthFactor; averagePath.Height = widthFactor; CenterX = averagePoint.X; CenterY = (rect.Top + rect.Height / 2); } else { double widthFactor = rect.Width * sizeRatio; widthFactor = widthFactor > averagePathSize ? averagePathSize : widthFactor; averagePath.Width = widthFactor; averagePath.Height = widthFactor; CenterX = (rect.X + rect.Width / 2); CenterY = averagePoint.Y; } Canvas.SetLeft(averagePath, CenterX - averagePath.Width / 2); Canvas.SetTop(averagePath, CenterY - averagePath.Height / 2); if (!segmentCanvas.Children.Contains(averagePath)) { segmentCanvas.Children.Add(averagePath); } } else { if (segmentCanvas.Children.Contains(averagePath)) { segmentCanvas.Children.Remove(averagePath); } } }
/// <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) { PathFigure figure = new PathFigure(); if (AreaPoints.Count > 1) { int endIndex = AreaPoints.Count - 1; WindowsLineSegment lineSegment = new WindowsLineSegment(); figure.StartPoint = transformer.TransformToVisible(AreaPoints[0].X, AreaPoints[0].Y); lineSegment.Point = transformer.TransformToVisible(AreaPoints[1].X, AreaPoints[1].Y); figure.Segments.Add(lineSegment); for (int i = 2; i < AreaPoints.Count - 1; i += 6) { BezierSegment segment = new BezierSegment(); segment.Point1 = transformer.TransformToVisible(AreaPoints[i].X, AreaPoints[i].Y); segment.Point2 = transformer.TransformToVisible(AreaPoints[i + 1].X, AreaPoints[i + 1].Y); segment.Point3 = transformer.TransformToVisible(AreaPoints[i + 2].X, AreaPoints[i + 2].Y); figure.Segments.Add(segment); } lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(AreaPoints[endIndex].X, AreaPoints[endIndex].Y); figure.Segments.Add(lineSegment); for (int i = endIndex - 1; i > 1; i -= 6) { BezierSegment segment = new BezierSegment(); segment.Point1 = transformer.TransformToVisible(AreaPoints[i].X, AreaPoints[i].Y); segment.Point2 = transformer.TransformToVisible(AreaPoints[i - 1].X, AreaPoints[i - 1].Y); segment.Point3 = transformer.TransformToVisible(AreaPoints[i - 2].X, AreaPoints[i - 2].Y); figure.Segments.Add(segment); } } PathGeometry segmentGeometry = new PathGeometry(); segmentGeometry.Figures.Add(figure); this.segPath.Data = segmentGeometry; }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { if (transformer != null) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double pos = xIsLogarithmic ? Math.Log(xPos, xBase) : xPos; if (pos >= xStart && pos <= xEnd && (!double.IsNaN(yPos) || Series.ShowEmptyPoints)) { Point point1 = transformer.TransformToVisible(xPos, yPos); if (ellipseSegment != null) { ellipseSegment.Visibility = Visibility.Visible; ellipseSegment.Height = ellipseSegment.Width = 2 * this.segmentRadius; ellipseSegment.SetValue(Canvas.LeftProperty, point1.X - this.segmentRadius); ellipseSegment.SetValue(Canvas.TopProperty, point1.Y - this.segmentRadius); } else { control.Visibility = Visibility.Visible; RectX = point1.X - this.segmentRadius; RectY = point1.Y - this.segmentRadius; Size = SegmentRadius = 2 * this.segmentRadius; } } else if (customTemplate == null) { ellipseSegment.Visibility = Visibility.Collapsed; } else { control.Visibility = Visibility.Collapsed; } } }
/// <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) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(Left, xBase) : Left; double right = xIsLogarithmic ? Math.Log(Right, xBase) : Right; double xStart = Math.Floor(cartesianTransformer.XAxis.VisibleRange.Start); double xEnd = Math.Ceiling(cartesianTransformer.XAxis.VisibleRange.End); if (!double.IsNaN(Top) && !double.IsNaN(Bottom) && (left <= xEnd && right >= xStart) && (!double.IsNaN(YData) || Series.ShowEmptyPoints)) { double spacing = (Series is HistogramSeries) ? 0.0 : (Series as ISegmentSpacing).SegmentSpacing; Point tlpoint = transformer.TransformToVisible(Left, Top); Point rbpoint = transformer.TransformToVisible(Right, Bottom); rect = new Rect(tlpoint, rbpoint); if (spacing > 0.0 && spacing <= 1) { if (Series.IsActualTransposed == true) { double leftpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Bottom, rect.Top); rect.Y = leftpos; Height = rect.Height = (1 - spacing) * rect.Height; } else { double leftpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Right, rect.Left); rect.X = leftpos; Width = rect.Width = (1 - spacing) * rect.Width; } } if (RectSegment != null) { RectSegment.SetValue(Canvas.LeftProperty, rect.X); RectSegment.SetValue(Canvas.TopProperty, rect.Y); RectSegment.Visibility = Visibility.Visible; Width = RectSegment.Width = rect.Width; Height = RectSegment.Height = rect.Height; } else { control.Visibility = Visibility.Visible; RectX = rect.X; RectY = rect.Y; Width = rect.Width; Height = rect.Height; } } else if (customTemplate == null) { RectSegment.Visibility = Visibility.Collapsed; } else { control.Visibility = Visibility.Collapsed; } } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents 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) { if (isSegmentUpdated) { Series.SeriesRootPanel.Clip = null; } double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(X1Value, xBase) : X1Value; double right = xIsLogarithmic ? Math.Log(X2Value, xBase) : X2Value; if ((left <= xEnd && right >= xStart) && ((!double.IsNaN(Y1Value) && !double.IsNaN(Y2Value)) || Series.ShowEmptyPoints)) { Point point1 = transformer.TransformToVisible(X1Value, Y1Value); Point point2 = transformer.TransformToVisible(X2Value, Y2Value); if (line != null) { line.X1 = point1.X; line.Y1 = point1.Y; line.X2 = point2.X; line.Y2 = point2.Y; line.Visibility = Visibility.Visible; } else { control.Visibility = Visibility.Visible; this.X1 = point1.X; this.Y1 = point1.Y; this.X2 = point2.X; this.Y2 = point2.Y; } } else if (CustomTemplate == null) { line.ClearUIValues(); //WPF-16603 In Line series stroke is applied when there is emptypoint data line.Visibility = Visibility.Collapsed; } else { control.Visibility = Visibility.Collapsed; } isSegmentUpdated = true; } else { ChartTransform.ChartPolarTransformer polarTransformer = transformer as ChartTransform.ChartPolarTransformer; if (Series.ShowEmptyPoints || ((!double.IsNaN(Y1Value) && !double.IsNaN(Y2Value)))) { Point point1 = polarTransformer.TransformToVisible(X1Value, Y1Value); Point point2 = polarTransformer.TransformToVisible(X2Value, Y2Value); if (line != null) { line.Visibility = Visibility.Visible; line.X1 = point1.X; line.Y1 = point1.Y; line.X2 = point2.X; line.Y2 = point2.Y; } else { this.X1 = point1.X; this.Y1 = point1.Y; this.X2 = point2.X; this.Y2 = point2.Y; } } else if (line != null) //WPF-20827 - Polar series render wrongly { line.Visibility = Visibility.Collapsed; } } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents 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 (isSegmentUpdated) { Series.SeriesRootPanel.Clip = null; } double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(X1Value, xBase) : X1Value; double right = xIsLogarithmic ? Math.Log(X2Value, xBase) : X2Value; if (left <= xEnd && right >= xStart) { if (poly != null) { poly.Visibility = Visibility.Visible; } Point point1 = transformer.TransformToVisible(pointStart.X, pointStart.Y); Point point2 = transformer.TransformToVisible(pointEnd.X, pointEnd.Y); Point stepPoint = transformer.TransformToVisible(stepMidPoint.X, stepMidPoint.Y); points = new PointCollection(); if (X1 != point1.X || X2 != point2.X || Y1 != point1.Y || Y2 != point2.Y || X3 != stepPoint.X || Y3 != stepPoint.Y) { this.X1 = point1.X; this.X2 = point2.X; this.Y1 = point1.Y; this.Y2 = point2.Y; this.X3 = stepPoint.X; this.Y3 = stepPoint.Y; points.Add(point1); points.Add(point2); points.Add(stepPoint); if (poly != null) { poly.Points = points; } else { Points = points; } } } else { if (poly != null) { poly.ClearUIValues(); poly.Visibility = Visibility.Collapsed; } } isSegmentUpdated = true; }
/// <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); } } }
/// <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); } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { if (transformer != null) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(XRange.Start, xBase) : XRange.Start; double right = xIsLogarithmic ? Math.Log(XRange.End, xBase) : XRange.End; double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; if ((left <= xEnd && right >= xStart) || Series.ShowEmptyPoints) { Point hiPoint = transformer.TransformToVisible(hipoint.X, hipoint.Y); Point loPoint = transformer.TransformToVisible(lowpoint.X, lowpoint.Y); Point startopenpoint = transformer.TransformToVisible(sopoint.X, sopoint.Y); Point endopenpoint = transformer.TransformToVisible(eopoint.X, eopoint.Y); Point startclosepoint = transformer.TransformToVisible(scpoint.X, scpoint.Y); Point endclosepoint = transformer.TransformToVisible(ecpoint.X, ecpoint.Y); if (!double.IsNaN(hipoint.Y) && !double.IsNaN(lowpoint.Y)) { hiLoline.X1 = hiPoint.X; hiLoline.Y1 = hiPoint.Y; hiLoline.X2 = loPoint.X; hiLoline.Y2 = loPoint.Y; } else { hiLoline.ClearUIValues(); } if (!double.IsNaN(sopoint.Y) && !double.IsNaN(eopoint.Y)) { this.openLine.X1 = startopenpoint.X; this.openLine.Y1 = startopenpoint.Y; this.openLine.X2 = endopenpoint.X; this.openLine.Y2 = endopenpoint.Y; } else { openLine.ClearUIValues(); } if (!double.IsNaN(scpoint.Y) && !double.IsNaN(ecpoint.Y)) { this.closeLine.X1 = startclosepoint.X; this.closeLine.Y1 = startclosepoint.Y; this.closeLine.X2 = endclosepoint.X; this.closeLine.Y2 = endclosepoint.Y; } else { closeLine.ClearUIValues(); } } else { hiLoline.ClearUIValues(); openLine.ClearUIValues(); closeLine.ClearUIValues(); } } }
public override void Update(IChartTransformer transformer) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; if (cartesianTransformer != null) { 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; // Clippiing the area series 3D. if (this.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; } } } if (this.yValues.Min() < yStart) { List <double> tempYVal = this.yValues.ToList(); foreach (var yVal in tempYVal) { if (yVal < yStart) { this.yValues[this.yValues.IndexOf(yVal)] = yStart; } } } if (this.yValues.Max() > yEnd) { List <double> tempYVal = this.yValues.ToList(); foreach (var yVal in tempYVal) { if (yVal > yEnd) { this.yValues[this.yValues.IndexOf(yVal)] = yEnd; } } } // End of clipping logic double x = this.xValues[0]; double y = !(Series as AreaSeries3D).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; List <Point> areaPoint = new List <Point>(); areaPoint.Add(previousPoint); this.topPolygonCollection = new Polygon3D[this.yValues.Count]; Vector3D vector1, vector2, vector3, vector4; for (int i = 1; i < this.xValues.Count; i++) { x = this.xValues[i]; y = !(Series as AreaSeries3D).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); vector1 = new Vector3D(previousPoint.X, previousPoint.Y, startDepth); vector2 = new Vector3D(currentPoint.X, currentPoint.Y, startDepth); vector3 = new Vector3D(currentPoint.X, currentPoint.Y, endDepth); vector4 = new Vector3D(previousPoint.X, previousPoint.Y, endDepth); var points = new Vector3D[] { vector1, vector2, vector3, vector4 }; this.topPolygonCollection[i] = new Polygon3D(points, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.topPolygonCollection[i].CalcNormal(points[0], points[1], points[2]); this.topPolygonCollection[i].CalcNormal(); previousPoint = currentPoint; areaPoint.Add(currentPoint); } x = this.xValues[0]; y = !(Series as AreaSeries3D).IsAnimated && !Series.EnableAnimation ? this.yValues[0] : (this.Y < this.yValues[0] && this.Y > 0) ? this.Y : this.yValues[0]; Point topLeft = transformer.TransformToVisible(x, y); x = this.xValues[this.xValues.Count - 1]; y = !(Series as AreaSeries3D).IsAnimated && !Series.EnableAnimation ? this.yValues[this.xValues.Count - 1] : (this.Y < this.yValues[this.yValues.Count - 1]) ? this.Y : this.yValues[this.yValues.Count - 1]; Point topRight = transformer.TransformToVisible(x, y); double origin = Series.ActualYAxis.Origin < yStart ? yStart : Series.ActualYAxis.Origin; x = this.xValues[0]; Point bottomLeft = transformer.TransformToVisible(x, origin); x = this.xValues[this.xValues.Count - 1]; Point bottomRight = transformer.TransformToVisible(x, origin); areaPoint.Add(bottomRight); areaPoint.Add(bottomLeft); Vector3D tlfVector = new Vector3D(topLeft.X, topLeft.Y, startDepth); Vector3D tldVector = new Vector3D(topLeft.X, topLeft.Y, endDepth); Vector3D trfVector = new Vector3D(topRight.X, topRight.Y, startDepth); Vector3D trdVector = new Vector3D(topRight.X, topRight.Y, endDepth); Vector3D blfVector = new Vector3D(bottomLeft.X, bottomLeft.Y, startDepth); Vector3D bldVector = new Vector3D(bottomLeft.X, bottomLeft.Y, endDepth); Vector3D brfVector = new Vector3D(bottomRight.X, bottomRight.Y, startDepth); Vector3D brdVector = new Vector3D(bottomRight.X, bottomRight.Y, endDepth); Vector3D[] leftVectors = new Vector3D[4] { tlfVector, tldVector, bldVector, blfVector }; Vector3D[] rightVectors = new Vector3D[4] { trfVector, trdVector, brdVector, brfVector }; Vector3D[] bottomVectors = new Vector3D[4] { blfVector, bldVector, brdVector, brfVector }; Vector3D[] frontVector = new Vector3D[areaPoint.Count]; Vector3D[] backVector = new Vector3D[areaPoint.Count]; for (int i = 0; i < areaPoint.Count; i++) { Point point = areaPoint[i]; frontVector[i] = new Vector3D(point.X, point.Y, startDepth); backVector[i] = new Vector3D(point.X, point.Y, endDepth); } if ((Series as AreaSeries3D).IsAnimated || !Series.EnableAnimation) { this.leftPolygon = new Polygon3D( leftVectors, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.leftPolygon.CalcNormal(leftVectors[0], leftVectors[1], leftVectors[2]); this.leftPolygon.CalcNormal(); this.area.Graphics3D.AddVisual(this.leftPolygon); this.rightPolygon = new Polygon3D( rightVectors, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.rightPolygon.CalcNormal(rightVectors[0], rightVectors[1], rightVectors[2]); this.rightPolygon.CalcNormal(); this.area.Graphics3D.AddVisual(this.rightPolygon); this.bottomPolygon = new Polygon3D( bottomVectors, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.bottomPolygon.CalcNormal(bottomVectors[0], bottomVectors[1], bottomVectors[2]); this.bottomPolygon.CalcNormal(); this.area.Graphics3D.AddVisual(this.bottomPolygon); this.frontPolygon = new Polygon3D( frontVector, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.frontPolygon.CalcNormal(frontVector[0], frontVector[1], frontVector[2]); this.frontPolygon.CalcNormal(); this.area.Graphics3D.AddVisual(this.frontPolygon); this.backPolygon = new Polygon3D( backVector, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior); this.backPolygon.CalcNormal(backVector[0], backVector[1], backVector[2]); this.backPolygon.CalcNormal(); this.area.Graphics3D.AddVisual(this.backPolygon); for (int i = 1; i < this.yValues.Count; i++) { this.area.Graphics3D.AddVisual(this.topPolygonCollection[i]); } } } }
/// <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) { if (isSegmentUpdated) { Series.SeriesRootPanel.Clip = null; } ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; DoubleRange range = cartesianTransformer.XAxis.VisibleRange; PathFigure figure = new PathFigure(); PathGeometry segmentGeometry = new PathGeometry(); double origin = containerSeries.ActualXAxis != null ? containerSeries.ActualXAxis.Origin : 0;//setting origin value for splinearea segment WindowsLineSegment lineSegment; figure.StartPoint = transformer.TransformToVisible(segmentPoints[0].X, segmentPoints[0].Y); lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y); figure.Segments.Add(lineSegment); strokeGeometry = new PathGeometry(); strokeFigure = new PathFigure(); strokePath = new Path(); if (containerSeries.IsClosed && isEmpty) { AddStroke(figure.StartPoint); lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y); strokeFigure.Segments.Add(lineSegment); } else if (!containerSeries.IsClosed) { AddStroke(transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y)); } int i; for (i = 2; i < segmentPoints.Count; i += 3) { double xVal = segmentPoints[i].X; if (xVal >= range.Start && xVal <= range.End || xEnd >= range.Start && xEnd <= range.End) { if (Series.ShowEmptyPoints || ((!double.IsNaN(segmentPoints[i].Y) && !double.IsNaN(segmentPoints[i + 1].Y) && !double.IsNaN(segmentPoints[i + 2].Y)))) { BezierSegment segment = new BezierSegment(); segment.Point1 = transformer.TransformToVisible(segmentPoints[i].X, segmentPoints[i].Y); segment.Point2 = transformer.TransformToVisible(segmentPoints[i + 1].X, segmentPoints[i + 1].Y); segment.Point3 = transformer.TransformToVisible(segmentPoints[i + 2].X, segmentPoints[i + 2].Y); figure.Segments.Add(segment); if ((isEmpty && !Series.ShowEmptyPoints) || !containerSeries.IsClosed) { BezierSegment strokeSegment = new BezierSegment(); strokeSegment.Point1 = segment.Point1; strokeSegment.Point2 = segment.Point2; strokeSegment.Point3 = segment.Point3; strokeFigure.Segments.Add(strokeSegment); } } else { if ((double.IsNaN(segmentPoints[i].Y) && double.IsNaN(segmentPoints[i + 1].Y) && double.IsNaN(segmentPoints[i + 2].Y))) { lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[i - 1].X, origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, origin); figure.Segments.Add(lineSegment); } else if (i > 0 && (double.IsNaN(segmentPoints[i - 1].Y) || double.IsNaN(segmentPoints[i].Y))) { lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLineSegment(); lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, double.IsNaN(segmentPoints[i + 2].Y) ? origin : segmentPoints[i + 2].Y); if ((!Series.ShowEmptyPoints && !double.IsNaN(segmentPoints[i + 2].Y)) || !containerSeries.IsClosed) { strokeFigure = new PathFigure(); strokeFigure.StartPoint = lineSegment.Point; strokeGeometry.Figures.Add(strokeFigure); } figure.Segments.Add(lineSegment); } } } } Point point = transformer.TransformToVisible(segmentPoints[i - 1].X, origin); lineSegment = new WindowsLineSegment(); lineSegment.Point = point; figure.Segments.Add(lineSegment); if (containerSeries.IsClosed && !double.IsNaN(segmentPoints[i - 1].Y)) { lineSegment = new WindowsLineSegment(); lineSegment.Point = point; strokeFigure.Segments.Add(lineSegment); } //figure.IsClosed = true; isSegmentUpdated = true; segmentGeometry.Figures.Add(figure); this.segPath.Data = segmentGeometry; }
/// <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 overriden 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) { if (segmentUpdated) { Series.SeriesRootPanel.Clip = null; } PathFigure figure = new PathFigure(); PathGeometry segmentGeometry = new PathGeometry(); WindowsLinesegment lineSegment; double origin = containerSeries.ActualXAxis.Origin; if (containerSeries.ActualXAxis != null && containerSeries.ActualXAxis.Origin == 0 && containerSeries.ActualYAxis is LogarithmicAxis && (containerSeries.ActualYAxis as LogarithmicAxis).Minimum != null) { origin = (double)(containerSeries.ActualYAxis as LogarithmicAxis).Minimum; } figure.StartPoint = transformer.TransformToVisible(XValues[0], origin); strokeGeometry = new PathGeometry(); strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokePath = new Path(); if (!containerSeries.IsClosed && !double.IsNaN(YValues[YValues.Count / 2])) { AddStroke(transformer.TransformToVisible(XValues[YValues.Count / 2], YValues[YValues.Count / 2])); } else if (isEmpty) { AddStroke(transformer.TransformToVisible(XValues[YValues.Count / 2 - 1], YValues[YValues.Count / 2 - 1])); } for (int index = 0; index < XValues.Count; index++) { if (!double.IsNaN(YValues[index])) { Point point = transformer.TransformToVisible(XValues[index], YValues[index]); lineSegment = new WindowsLinesegment(); lineSegment.Point = point; figure.Segments.Add(lineSegment); if ((isEmpty && !Series.ShowEmptyPoints) || !containerSeries.IsClosed) { if (index > (int)(YValues.Count / 2 - 1)) { if (double.IsNaN(YValues[index - 1])) { strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokeFigure.StartPoint = point; strokeGeometry.Figures.Add(strokeFigure); strokeFigure.Segments.Add(strokePolyLine); } strokePolyLine.Points.Add(point); } } } else if (XValues.Count > 1) { if (index > 0 && index < XValues.Count - 1) { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index - 1], origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index], origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index + 1], origin); figure.Segments.Add(lineSegment); } else if (index == YValues.Count - 1) { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index - 1], origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index], origin); figure.Segments.Add(lineSegment); } else { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index], origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index + 1], origin); figure.Segments.Add(lineSegment); } } } lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[XValues.Count - 1], origin); figure.Segments.Add(lineSegment); if (containerSeries.IsClosed && isEmpty && !double.IsNaN(YValues[YValues.Count - 1])) { strokePolyLine.Points.Add(lineSegment.Point); } segmentGeometry.Figures.Add(figure); this.segPath.Data = segmentGeometry; segmentUpdated = true; } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { PathFigure figure = new PathFigure(); if (this.stepAreaPoints.Count > 0) { if (isSegmentUpdated) { Series.SeriesRootPanel.Clip = null; } figure.StartPoint = transformer.TransformToVisible(this.stepAreaPoints[1].X, this.stepAreaPoints[1].Y); PathGeometry segmentGeometry = new PathGeometry(); WindowsLinesegment linesegment; double origin = Series.ActualXAxis != null ? Series.ActualXAxis.Origin : 0; strokeGeometry = new PathGeometry(); strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokePath = new Path(); if (!(Series as StepAreaSeries).IsClosed && !double.IsNaN(this.stepAreaPoints[3].Y)) { AddStroke(transformer.TransformToVisible(this.stepAreaPoints[2].X, this.stepAreaPoints[3].Y)); } else if (isEmpty) { AddStroke(figure.StartPoint); } for (int i = 1; i < this.stepAreaPoints.Count; i += 2) { if (!double.IsNaN(stepAreaPoints[i].Y) && !double.IsNaN(stepAreaPoints[i + 1].Y)) { Point point1 = transformer.TransformToVisible(this.stepAreaPoints[i].X, stepAreaPoints[i].Y); Point point2 = transformer.TransformToVisible(this.stepAreaPoints[i + 1].X, stepAreaPoints[i + 1].Y); linesegment = new WindowsLinesegment(); linesegment.Point = point1; figure.Segments.Add(linesegment); linesegment = new WindowsLinesegment(); linesegment.Point = point2; figure.Segments.Add(linesegment); if (isEmpty && !Series.ShowEmptyPoints && (Series as StepAreaSeries).IsClosed) { strokePolyLine.Points.Add(point1); if (i <= stepAreaPoints.Count - 3 && !double.IsNaN(stepAreaPoints[i + 3].Y)) { strokePolyLine.Points.Add(point2); } } else if (!(Series as StepAreaSeries).IsClosed) { if (i > 1) { strokePolyLine.Points.Add(point1); if (i <= stepAreaPoints.Count - 3 && !double.IsNaN(stepAreaPoints[i + 3].Y)) { strokePolyLine.Points.Add(point2); } } } } else { linesegment = new WindowsLinesegment(); linesegment.Point = transformer.TransformToVisible(this.stepAreaPoints[i - 1].X, origin); figure.Segments.Add(linesegment); if (double.IsNaN(stepAreaPoints[i - 1].Y)) { linesegment = new WindowsLinesegment(); linesegment.Point = transformer.TransformToVisible(this.stepAreaPoints[i - 1].X, origin); figure.Segments.Add(linesegment); } if (i < stepAreaPoints.Count - 1) //WPF-14682 { linesegment = new WindowsLinesegment(); linesegment.Point = transformer.TransformToVisible(this.stepAreaPoints[i + 1].X, origin); figure.Segments.Add(linesegment); if (double.IsNaN(stepAreaPoints[i - 1].Y) && !double.IsNaN(stepAreaPoints[i + 1].Y)) { Point point1 = transformer.TransformToVisible(this.stepAreaPoints[i].X, stepAreaPoints[i + 1].Y); if (!Series.ShowEmptyPoints && (Series as StepAreaSeries).IsClosed) { strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokeFigure.StartPoint = point1; strokeGeometry.Figures.Add(strokeFigure); strokeFigure.Segments.Add(strokePolyLine); } else if (!(Series as StepAreaSeries).IsClosed) { if (i > 1) { strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokeFigure.StartPoint = point1; strokeGeometry.Figures.Add(strokeFigure); strokeFigure.Segments.Add(strokePolyLine); } } linesegment = new WindowsLinesegment(); linesegment.Point = point1; figure.Segments.Add(linesegment); } } } } linesegment = new WindowsLinesegment(); linesegment.Point = transformer.TransformToVisible(this.stepAreaPoints[stepAreaPoints.Count - 1].X, origin); figure.Segments.Add(linesegment); if ((Series as StepAreaSeries).IsClosed && (isEmpty && !double.IsNaN(stepAreaPoints[stepAreaPoints.Count - 1].Y))) { strokePolyLine.Points.Add(linesegment.Point); } segmentGeometry.Figures.Add(figure); this.segPath.Data = segmentGeometry; isSegmentUpdated = true; } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xStart = Math.Floor(cartesianTransformer.XAxis.VisibleRange.Start); double xEnd = Math.Ceiling(cartesianTransformer.XAxis.VisibleRange.End); double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(cdpBottomLeft.X, xBase) : cdpBottomLeft.X; double right = xIsLogarithmic ? Math.Log(cdpRightTop.X, xBase) : cdpRightTop.X; if ((left <= xEnd && right >= xStart) || Series.ShowEmptyPoints) { double spacing = (Series as ISegmentSpacing).SegmentSpacing; columnSegment.Visibility = Visibility.Visible; hiLoLine.Visibility = Visibility.Visible; hiLoLine1.Visibility = Visibility.Visible; openCloseLine.Visibility = Visibility.Visible; Point blpoint = transformer.TransformToVisible(cdpBottomLeft.X, cdpBottomLeft.Y); Point trpoint = transformer.TransformToVisible(cdpRightTop.X, cdpRightTop.Y); rect = new Rect(blpoint, trpoint); if (spacing > 0 && spacing <= 1) { if (Series.IsActualTransposed) { rect.Y = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Bottom, rect.Top); columnSegment.Height = rect.Height = (1 - spacing) * rect.Height; } else { rect.X = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Right, rect.Left); columnSegment.Width = rect.Width = (1 - spacing) * rect.Width; } } if (cdpBottomLeft.Y == cdpRightTop.Y) { if (!double.IsNaN(cdpBottomLeft.Y) && !double.IsNaN(cdpRightTop.Y)) { columnSegment.Visibility = Visibility.Collapsed; this.openCloseLine.X1 = rect.Left; this.openCloseLine.Y1 = rect.Top; this.openCloseLine.X2 = rect.Right; this.openCloseLine.Y2 = rect.Bottom; } else { openCloseLine.Visibility = Visibility.Collapsed; openCloseLine.ClearUIValues(); } } else if (!double.IsNaN(cdpBottomLeft.Y) && !double.IsNaN(cdpRightTop.Y)) { openCloseLine.Visibility = Visibility.Collapsed; columnSegment.SetValue(Canvas.LeftProperty, rect.X); columnSegment.SetValue(Canvas.TopProperty, rect.Y); columnSegment.Width = rect.Width; columnSegment.Height = rect.Height; } else { columnSegment.Visibility = Visibility.Collapsed; columnSegment.ClearUIValues(); } Point point1 = transformer.TransformToVisible(this.hiPoint.X, this.hiPoint.Y); Point point2 = transformer.TransformToVisible(this.hiPoint1.X, this.hiPoint1.Y); Point point3 = transformer.TransformToVisible(this.loPoint.X, this.loPoint.Y); Point point4 = transformer.TransformToVisible(this.loPoint1.X, this.loPoint1.Y); if (!double.IsNaN(point1.Y) && !double.IsNaN(point2.Y) && !double.IsNaN(point1.X) && !double.IsNaN(point2.X) && !double.IsNaN(point3.Y) && !double.IsNaN(point4.Y) && !double.IsNaN(point3.X) && !double.IsNaN(point4.X)) { this.hiLoLine.X1 = point1.X; this.hiLoLine.X2 = point2.X; this.hiLoLine.Y1 = point1.Y; this.hiLoLine.Y2 = point2.Y; this.hiLoLine1.X1 = point3.X; this.hiLoLine1.X2 = point4.X; this.hiLoLine1.Y1 = point3.Y; this.hiLoLine1.Y2 = point4.Y; if (rect.Contains(point1)) { this.hiLoLine.Visibility = Visibility.Collapsed; } if (rect.Contains(point3)) { this.hiLoLine1.Visibility = Visibility.Collapsed; } } else { hiLoLine.Visibility = Visibility.Collapsed; hiLoLine.ClearUIValues(); hiLoLine1.Visibility = Visibility.Collapsed; hiLoLine1.ClearUIValues(); } } else { columnSegment.ClearUIValues(); hiLoLine.ClearUIValues(); hiLoLine1.ClearUIValues(); openCloseLine.ClearUIValues(); columnSegment.Visibility = Visibility.Collapsed; hiLoLine.Visibility = Visibility.Collapsed; hiLoLine1.Visibility = Visibility.Collapsed; openCloseLine.Visibility = Visibility.Collapsed; } }
/// <summary> /// Updates the box and whisker segment 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 (double.IsNaN(Minimum) && double.IsNaN(LowerQuartile) && double.IsNaN(Median) && double.IsNaN(UppperQuartile) && double.IsNaN(Maximum)) { return; } ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer; double xStart = Math.Floor(cartesianTransformer.XAxis.VisibleRange.Start); double xEnd = Math.Ceiling(cartesianTransformer.XAxis.VisibleRange.End); double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double left = xIsLogarithmic ? Math.Log(Left, xBase) : Left; double right = xIsLogarithmic ? Math.Log(Right, xBase) : Right; if ((left <= xEnd && right >= xStart)) { lowerQuartileLine.Visibility = Visibility.Visible; upperQuartileLine.Visibility = Visibility.Visible; medianLine.Visibility = Visibility.Visible; minimumLine.Visibility = Visibility.Visible; maximumLine.Visibility = Visibility.Visible; rectangle.Visibility = Visibility.Visible; Point minimumPoint = transformer.TransformToVisible(Center, Minimum); Point lowerQuartilePoint = transformer.TransformToVisible(Center, LowerQuartile); Point medianPoint = transformer.TransformToVisible(Center, Median); Point upperQuartilePoint = transformer.TransformToVisible(Center, UppperQuartile); Point maximumPoint = transformer.TransformToVisible(Center, Maximum); var tlPoint = transformer.TransformToVisible(Left, UppperQuartile); var brPoint = transformer.TransformToVisible(Right, LowerQuartile); double spacing = (Series as ISegmentSpacing).SegmentSpacing; rect = new Rect(tlPoint, brPoint); if (Series.IsActualTransposed) { if (spacing > 0 && spacing <= 1) { rect.Y = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Bottom, rect.Top); rect.Height = (1 - spacing) * rect.Height; } var percentHeight = rect.Height / 2 * WhiskerWidth; var centerLinePosition = rect.Y + rect.Height / 2; var topPercentWidth = centerLinePosition - percentHeight; var bottomPercentWidth = centerLinePosition + percentHeight; this.medianLine.X1 = medianPoint.X; this.medianLine.X2 = medianPoint.X; this.medianLine.Y1 = rect.Top; this.medianLine.Y2 = rect.Bottom; this.maximumLine.X1 = maximumPoint.X; this.maximumLine.Y1 = topPercentWidth; this.maximumLine.X2 = maximumPoint.X; this.maximumLine.Y2 = bottomPercentWidth; this.minimumLine.X1 = minimumPoint.X; this.minimumLine.Y1 = topPercentWidth; this.minimumLine.X2 = minimumPoint.X; this.minimumLine.Y2 = bottomPercentWidth; } else { if (spacing > 0 && spacing <= 1) { rect.X = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, rect.Right, rect.Left); rect.Width = (1 - spacing) * rect.Width; } var percentWidth = rect.Width / 2 * WhiskerWidth; var centerLinePosition = rect.X + rect.Width / 2; var leftPercentWidth = centerLinePosition - percentWidth; var rightPercentWidth = centerLinePosition + percentWidth; this.medianLine.X1 = rect.Left; this.medianLine.X2 = rect.Right; this.medianLine.Y1 = medianPoint.Y; this.medianLine.Y2 = medianPoint.Y; this.maximumLine.X1 = leftPercentWidth; this.maximumLine.Y1 = maximumPoint.Y; this.maximumLine.X2 = rightPercentWidth; this.maximumLine.Y2 = maximumPoint.Y; this.minimumLine.X1 = leftPercentWidth; this.minimumLine.Y1 = minimumPoint.Y; this.minimumLine.X2 = rightPercentWidth; this.minimumLine.Y2 = minimumPoint.Y; } rectangle.Width = rect.Width; rectangle.Height = rect.Height; rectangle.SetValue(Canvas.LeftProperty, rect.X); rectangle.SetValue(Canvas.TopProperty, rect.Y); this.lowerQuartileLine.X1 = minimumPoint.X; this.lowerQuartileLine.X2 = lowerQuartilePoint.X; this.lowerQuartileLine.Y1 = minimumPoint.Y; this.lowerQuartileLine.Y2 = lowerQuartilePoint.Y; this.upperQuartileLine.X1 = upperQuartilePoint.X; this.upperQuartileLine.X2 = maximumPoint.X; this.upperQuartileLine.Y1 = upperQuartilePoint.Y; this.upperQuartileLine.Y2 = maximumPoint.Y; UpdateMeanSymbol(cartesianTransformer, (Series as BoxAndWhiskerSeries).ShowMedian); } else { medianLine.Visibility = Visibility.Collapsed; minimumLine.Visibility = Visibility.Collapsed; maximumLine.Visibility = Visibility.Collapsed; lowerQuartileLine.Visibility = Visibility.Collapsed; upperQuartileLine.Visibility = Visibility.Collapsed; rectangle.Visibility = Visibility.Collapsed; averagePath.Visibility = Visibility.Collapsed; } }
/// <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 overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents 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) { double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic; double xStart = cartesianTransformer.XAxis.VisibleRange.Start; double xEnd = cartesianTransformer.XAxis.VisibleRange.End; double edgeValue = xIsLogarithmic ? Math.Log(xPos, xBase) : xPos; if (edgeValue >= xStart && edgeValue <= xEnd && (!double.IsNaN(YData) || Series.ShowEmptyPoints)) { Point point1 = transformer.TransformToVisible(xPos, yPos); var emptyPointSegment = this as EmptyPointSegment; if (emptyPointSegment != null) { ScatterHeight = emptyPointSegment.EmptyPointSymbolHeight; ScatterWidth = emptyPointSegment.EmptyPointSymbolWidth; } else { // To prevent the issues when scattersegment is used in other series. var series = (Series as ScatterSeries); if (series != null) { ScatterHeight = series.ScatterHeight; ScatterWidth = series.ScatterWidth; } } if (EllipseSegment != null) { EllipseSegment.SetValue(Canvas.LeftProperty, point1.X - ScatterWidth / 2); EllipseSegment.SetValue(Canvas.TopProperty, point1.Y - ScatterHeight / 2); } else { control.Visibility = Visibility.Visible; RectX = point1.X - (ScatterWidth / 2); RectY = point1.Y - (ScatterHeight / 2); } } else if (CustomTemplate == null) { ScatterHeight = 0; ScatterWidth = 0; } else { control.Visibility = Visibility.Collapsed; } } else { ScatterWidth = 0; ScatterHeight = 0; } }
/// <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) { _canvas.Children.Clear(); if (HorLine != null && _parentSeries.Mode != ErrorBarMode.Vertical && !(double.IsNaN(_horLeftpoint.Y) || double.IsNaN(_horRightpoint.Y))) { var hLPoint = transformer.TransformToVisible(_horLeftpoint.X, _horLeftpoint.Y); var hRPoint = transformer.TransformToVisible(_horRightpoint.X, _horRightpoint.Y); HorLine.X1 = hLPoint.X; HorLine.Y1 = hLPoint.Y; HorLine.X2 = hRPoint.X; HorLine.Y2 = hRPoint.Y; _canvas.Children.Add(HorLine); if (_parentSeries.HorizontalCapLineStyle.Visibility == Visibility.Visible) { var horWidth = _parentSeries.HorizontalCapLineStyle.LineWidth / 2; if (_parentSeries.IsTransposed) { HorLeftCapLine.X1 = HorLine.X1 - horWidth; HorLeftCapLine.Y1 = HorLine.Y1; HorLeftCapLine.X2 = HorLine.X1 + horWidth; HorLeftCapLine.Y2 = HorLine.Y1; } else { HorLeftCapLine.X1 = HorLine.X1; HorLeftCapLine.Y1 = HorLine.Y1 + horWidth; HorLeftCapLine.X2 = HorLine.X1; HorLeftCapLine.Y2 = HorLine.Y1 - horWidth; } _canvas.Children.Add(HorLeftCapLine); if (_parentSeries.HorizontalDirection == ErrorBarDirection.Plus) { HorLeftCapLine.Visibility = Visibility.Collapsed; } else { HorLeftCapLine.Visibility = Visibility.Visible; } if (_parentSeries.IsTransposed) { HorRightCapLine.X1 = HorLine.X2 - horWidth; HorRightCapLine.Y1 = HorLine.Y2; HorRightCapLine.X2 = HorLine.X2 + horWidth; HorRightCapLine.Y2 = HorLine.Y2; } else { HorRightCapLine.X1 = HorLine.X2; HorRightCapLine.Y1 = HorLine.Y2 + horWidth; HorRightCapLine.X2 = HorLine.X2; HorRightCapLine.Y2 = HorLine.Y2 - horWidth; } _canvas.Children.Add(HorRightCapLine); if (_parentSeries.HorizontalDirection == ErrorBarDirection.Minus) { HorRightCapLine.Visibility = Visibility.Collapsed; } else { HorRightCapLine.Visibility = Visibility.Visible; } } } if (VerLine != null && _parentSeries.Mode != ErrorBarMode.Horizontal && !(double.IsNaN(_verToppoint.Y) || double.IsNaN(_verBottompoint.Y))) { var vTPoint = transformer.TransformToVisible(_verToppoint.X, _verToppoint.Y); var vBPoint = transformer.TransformToVisible(_verBottompoint.X, _verBottompoint.Y); this.VerLine.X1 = vTPoint.X; this.VerLine.Y1 = vTPoint.Y; this.VerLine.X2 = vBPoint.X; this.VerLine.Y2 = vBPoint.Y; _canvas.Children.Add(VerLine); if (_parentSeries.VerticalCapLineStyle.Visibility == Visibility.Visible) { var halfwidth = _parentSeries.VerticalCapLineStyle.LineWidth / 2; if (_parentSeries.IsTransposed) { VerBottomCapLine.X1 = VerLine.X1; VerBottomCapLine.Y1 = VerLine.Y1 + halfwidth; VerBottomCapLine.X2 = VerLine.X1; VerBottomCapLine.Y2 = VerLine.Y1 - halfwidth; } else { VerBottomCapLine.X1 = VerLine.X1 - halfwidth; VerBottomCapLine.Y1 = VerLine.Y1; VerBottomCapLine.X2 = VerLine.X1 + halfwidth; VerBottomCapLine.Y2 = VerLine.Y1; } _canvas.Children.Add(VerBottomCapLine); if (_parentSeries.VerticalDirection == ErrorBarDirection.Plus) { VerBottomCapLine.Visibility = Visibility.Collapsed; } else { VerBottomCapLine.Visibility = Visibility.Visible; } if (_parentSeries.IsTransposed) { VerTopCapLine.X1 = VerLine.X2; VerTopCapLine.Y1 = VerLine.Y2 + halfwidth; VerTopCapLine.X2 = VerLine.X2; VerTopCapLine.Y2 = VerLine.Y2 - halfwidth; } else { VerTopCapLine.X1 = VerLine.X1 - halfwidth; VerTopCapLine.Y1 = VerLine.Y2; VerTopCapLine.X2 = VerLine.X1 + halfwidth; VerTopCapLine.Y2 = VerLine.Y2; } _canvas.Children.Add(VerTopCapLine); if (_parentSeries.VerticalDirection == ErrorBarDirection.Minus) { VerTopCapLine.Visibility = Visibility.Collapsed; } else { VerTopCapLine.Visibility = 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) { ChartAxis xAxis = this.Series.ActualXAxis; double xValue = 0; int lastIndex = 0; if (transformer != null) { if (segmentUpdated) { Series.SeriesRootPanel.Clip = null; } PathGeometry segmentGeometry = new PathGeometry(); PathFigure figure = new PathFigure(); WindowsLinesegment lineSegment; double start = containerSeries.ActualYAxis.ActualRange.Start; double origin = containerSeries.ActualXAxis.Origin; if (containerSeries.ActualXAxis != null && containerSeries.ActualXAxis.Origin == 0 && containerSeries.ActualYAxis is LogarithmicAxis && (containerSeries.ActualYAxis as LogarithmicAxis).Minimum != null) { origin = (double)(containerSeries.ActualYAxis as LogarithmicAxis).Minimum; } origin = origin == 0d ? start < 0d ? 0d : start : origin; figure.StartPoint = transformer.TransformToVisible(XValues[0], origin); ResetStrokeShapes(); if (Series is PolarRadarSeriesBase && !double.IsNaN(YValues[0])) { figure.StartPoint = transformer.TransformToVisible(XValues[0], YValues[0]); } if ((Series is AreaSeries) && !(Series as AreaSeries).IsClosed && !double.IsNaN(YValues[0])) { this.AddStroke(transformer.TransformToVisible(XValues[0], YValues[0])); } else if (isEmpty) { this.AddStroke(figure.StartPoint); } var logarithmicXAxis = xAxis as LogarithmicAxis; double rangeStart = logarithmicXAxis != null?Math.Pow(logarithmicXAxis.LogarithmicBase, xAxis.VisibleRange.Start) : xAxis.VisibleRange.Start; double rangeEnd = logarithmicXAxis != null?Math.Pow(logarithmicXAxis.LogarithmicBase, xAxis.VisibleRange.End) : xAxis.VisibleRange.End; for (int index = 0; index < XValues.Count; index++) { // UWP - 256 Aea series is fuzzy on chart if it is in zoomed state xValue = XValues[index]; if (!(rangeStart <= xValue && rangeEnd >= xValue)) { if (rangeStart >= xValue && index + 1 < XValues.Count && rangeStart <= XValues[index + 1]) { figure.StartPoint = transformer.TransformToVisible(xValue, origin); //To avoid stroke blur when IsClosed & Empty point stroke is false. if ((Series is AreaSeries) && !(Series as AreaSeries).IsClosed && !double.IsNaN(YValues[0])) { ResetStrokeShapes(); this.AddStroke(transformer.TransformToVisible(xValue, YValues[index])); } else if (isEmpty) { ResetStrokeShapes(); this.AddStroke(figure.StartPoint); } } else if (!(rangeEnd <= xValue && index - 1 > -1 && rangeEnd >= XValues[index - 1])) { continue; } } if (!double.IsNaN(YValues[index])) { Point point = transformer.TransformToVisible(xValue, YValues[index]); lineSegment = new WindowsLinesegment(); lineSegment.Point = point; figure.Segments.Add(lineSegment); if ((isEmpty && !Series.ShowEmptyPoints) || (Series is AreaSeries && !(Series as AreaSeries).IsClosed)) { if (index > 0 && double.IsNaN(YValues[index - 1])) { strokeFigure = new PathFigure(); strokePolyLine = new PolyLineSegment(); strokeFigure.StartPoint = point; strokeGeometry.Figures.Add(strokeFigure); strokeFigure.Segments.Add(strokePolyLine); } strokePolyLine.Points.Add(point); } } else if (XValues.Count > 1) { if (index > 0 && index < XValues.Count - 1) { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index - 1], origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(xValue, origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index + 1], origin); figure.Segments.Add(lineSegment); } else if (index == 0) { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(xValue, origin); figure.Segments.Add(lineSegment); lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index + 1], origin); figure.Segments.Add(lineSegment); } else { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[index - 1], origin); figure.Segments.Add(lineSegment); } } lastIndex = index; } if (!(Series is PolarRadarSeriesBase)) { lineSegment = new WindowsLinesegment(); lineSegment.Point = transformer.TransformToVisible(XValues[lastIndex], origin); figure.Segments.Add(lineSegment); if ((Series is AreaSeries && (Series as AreaSeries).IsClosed) && isEmpty && !double.IsNaN(YValues[lastIndex])) { strokePolyLine.Points.Add(lineSegment.Point); } } segmentGeometry.Figures.Add(figure); this.segPath.Data = segmentGeometry; segmentUpdated = true; } }