/// <summary> /// Initializes a new instance of the <see cref="ChartPolarTransformer"/> class. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="xAxis">The x axis.</param> /// <param name="yAxis">The y axis.</param> public ChartPolarTransformer(Rect viewport, ChartAxis xAxis, ChartAxis yAxis) { m_viewport = viewport; m_xAxis = xAxis; m_yAxis = yAxis; m_center = ChartLayoutUtils.GetCenter(m_viewport); m_radius = 0.5 * Math.Min(m_viewport.Width, m_viewport.Height); }
/// <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) { double bottom; Point center = ChartLayoutUtils.GetCenter(transformer.Viewport); bottom = center.Y; center.Y = 0; center.Y += ((CurrY * bottom) * 2) - (Height / 2) * 4; this.X = center.X; this.Y = center.Y; }
/// <summary> /// Arranges the elements in a panel. /// </summary> /// <param name="finalSize">final Size of the panel.</param> /// <returns>returns Size.</returns> public Size Arrange(Size finalSize) { double dx = finalSize.Width - 2 * m_maxLabelsSize.Width; double dy = finalSize.Height - 2 * m_maxLabelsSize.Height; this.Radius = Math.Max(0, 0.5 * Math.Min(dx, dy) - Math.Max(Axis.TickLineSize, 0)); this.Center = (Point)ChartLayoutUtils.GetCenter(finalSize); RenderElements(); return(finalSize); }
/// <summary> /// Arranges the elements in a panel /// </summary> /// <param name="finalSize">final size of the panel.</param> /// <returns>returns Size</returns> public Size Arrange(Size finalSize) { Rect clientRect = new Rect(0, 0, finalSize.Width, finalSize.Height); if (PolarAxis != null) { PolarAxis.ArrangeRect = clientRect; PolarAxis.Measure(new Size(clientRect.Width, clientRect.Height)); PolarAxis.Arrange(clientRect); Canvas.SetLeft(PolarAxis, clientRect.Left); Canvas.SetTop(PolarAxis, clientRect.Top); } ChartAxis yAxis = this.CartesianAxis; if (yAxis != null) { Point center = ChartLayoutUtils.GetCenter(clientRect); CalculateCartesianArrangeRect(center, yAxis); Rect rect = new Rect(this.CartesianAxis.ArrangeRect.Left, this.CartesianAxis.ArrangeRect.Top, this.CartesianAxis.ComputedDesiredSize.Width, this.CartesianAxis.ComputedDesiredSize.Height); if (CartesianAxis.PolarAngle != ChartPolarAngle.Rotate90 && (!yAxis.OpposedPosition || CartesianAxis.PolarAngle == ChartPolarAngle.Rotate180)) { CartesianAxis.Measure(new Size(rect.Width, rect.Height)); } else { CartesianAxis.Measure(new Size(rect.Left, rect.Height)); } CartesianAxis.Arrange(rect); Canvas.SetLeft(CartesianAxis, CartesianAxis.ArrangeRect.Left); Canvas.SetTop(CartesianAxis, CartesianAxis.ArrangeRect.Top); if (CartesianAxis.PolarAngle == ChartPolarAngle.Rotate90 || CartesianAxis.PolarAngle == ChartPolarAngle.Rotate180) { Area.InternalSecondaryAxis.IsInversed = !Area.InternalSecondaryAxis.IsInversed; } } return(finalSize); }
/// <summary> /// Initializes a new instance of the <see cref="ChartPolarTransformer"/> class. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="series">The series.</param> public ChartPolarTransformer(Rect viewport, ChartSeriesBase series) { m_viewport = viewport; m_xAxis = series.ActualXAxis; m_yAxis = series.ActualYAxis; m_center = ChartLayoutUtils.GetCenter(m_viewport); m_radius = 0.5 * Math.Min(m_viewport.Width, m_viewport.Height); x_IsLogarithmic = series.ActualXAxis is LogarithmicAxis; y_IsLogarithmic = series.ActualYAxis is LogarithmicAxis; if (x_IsLogarithmic) { xlogarithmicBase = (series.ActualXAxis as LogarithmicAxis).LogarithmicBase; } if (y_IsLogarithmic) { ylogarithmicBase = (series.ActualYAxis as LogarithmicAxis).LogarithmicBase; } }
/// <summary> /// Measures the elements in a panel. /// </summary> /// <param name="availableSize">available size of the panel.</param> /// <returns>returns Size.</returns> public Size Measure(Size availableSize) { m_maxLabelsSize = new Size(); IEnumerable enumerator = contentControlRecycler as IEnumerable; foreach (UIElement element in enumerator) { element.Measure(availableSize); m_maxLabelsSize.Width = Math.Max(element.DesiredSize.Width, m_maxLabelsSize.Width); m_maxLabelsSize.Height = Math.Max(element.DesiredSize.Height, m_maxLabelsSize.Height); } double dx = availableSize.Width - 2 * m_maxLabelsSize.Width; double dy = availableSize.Height - 2 * m_maxLabelsSize.Height; this.Radius = 0.5 * Math.Min(dx, dy) - Math.Max(Axis.TickLineSize, 0); this.Center = (Point)ChartLayoutUtils.GetCenter(availableSize); return(availableSize); }
/// <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) { double radius = Radius; double actualRadius = Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; if (Series is PieSeries) { var hostSeries = Series as PieSeries; double pieSeriesCount = hostSeries.GetPieSeriesCount(); double equalParts = actualRadius / pieSeriesCount; double innerRadius = equalParts * pieIndex; Point center; if (pieSeriesCount == 1) { center = hostSeries.Center; } else { center = ChartLayoutUtils.GetCenter(transformer.Viewport); } if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { if (pieIndex > 0) { double difference = (radius - innerRadius) / 2; radius = radius - difference; } else { radius = radius / 2; } } this.X = center.X + radius * Math.Cos(Angle); this.Y = center.Y + radius * Math.Sin(Angle); } else if (Series is DoughnutSeries) { var hostSeries = Series as DoughnutSeries; actualRadius *= hostSeries.InternalDoughnutSize; Point center; double remainingWidth = 0d, equalParts = 0d, innerRadius = 0d; var adornmentAngle = Angle; if (hostSeries.IsStackedDoughnut) { var adornmentIndex = Series.Adornments.IndexOf(this); var doughnutSegment = hostSeries.Segments[adornmentIndex] as DoughnutSegment; int doughnutSegmentsCount = hostSeries.Segments.Count; center = hostSeries.Center; remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); equalParts = (remainingWidth / doughnutSegmentsCount) * hostSeries.InternalDoughnutCoefficient; radius = actualRadius - (equalParts * (doughnutSegmentsCount - (doughnutSegment.DoughnutSegmentIndex + 1))); InnerDoughnutRadius = innerRadius = radius - equalParts; radius = radius - equalParts * hostSeries.SegmentSpacing; Radius = radius; innerRadius = ChartMath.MaxZero(innerRadius); double difference = (radius - innerRadius) / 2; radius = radius - difference; adornmentAngle = hostSeries.LabelPosition == CircularSeriesLabelPosition.Outside ? doughnutSegment.StartAngle : hostSeries.LabelPosition == CircularSeriesLabelPosition.OutsideExtended ? doughnutSegment.EndAngle : Angle; } else { int doughnutSeriesCount = hostSeries.GetDoughnutSeriesCount(); center = doughnutSeriesCount == 1 ? hostSeries.Center : ChartLayoutUtils.GetCenter(transformer.Viewport); remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); equalParts = remainingWidth / doughnutSeriesCount; InnerDoughnutRadius = innerRadius = radius - (equalParts * hostSeries.InternalDoughnutCoefficient); innerRadius = ChartMath.MaxZero(innerRadius); if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { double difference = (radius - innerRadius) / 2; radius = radius - difference; } } this.X = center.X + radius * Math.Cos(adornmentAngle); this.Y = center.Y + radius * Math.Sin(adornmentAngle); } }
/// <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 (!this.IsSegmentVisible) { segmentPath.Visibility = Visibility.Collapsed; } else { segmentPath.Visibility = Visibility.Visible; } segmentPath.StrokeLineJoin = PenLineJoin.Round; segmentPath.Width = transformer.Viewport.Width; segmentPath.Height = transformer.Viewport.Height; segmentPath.VerticalAlignment = VerticalAlignment.Center; segmentPath.HorizontalAlignment = HorizontalAlignment.Center; double actualRadius = Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; double equalParts = actualRadius / (pieSeriesCount); if (pieIndex == 0) { Point center; if (pieSeriesCount == 1) { center = (Series as CircularSeriesBase).Center; } else { center = ChartLayoutUtils.GetCenter(transformer.Viewport); } double radius = parentSeries.InternalPieCoefficient * (equalParts); parentSeries.Radius = radius; if (Math.Round((ActualEndAngle - ActualStartAngle), 2) == 6.28) { EllipseGeometry ellipseGeometry = new EllipseGeometry() { Center = center, RadiusX = radius, RadiusY = radius }; this.segmentPath.Data = ellipseGeometry; } else if ((ActualEndAngle - ActualStartAngle) != 0) { if (this.IsExploded) { center = new Point(center.X + (parentSeries.ExplodeRadius * Math.Cos(AngleOfSlice)), center.Y + (parentSeries.ExplodeRadius * Math.Sin(AngleOfSlice))); } startPoint = new Point(center.X + radius * Math.Cos(ActualStartAngle), center.Y + radius * Math.Sin(ActualStartAngle)); Point endPoint = new Point(center.X + radius * Math.Cos(ActualEndAngle), center.Y + radius * Math.Sin(ActualEndAngle)); PathFigure figure = new PathFigure(); figure.StartPoint = center; WindowsLineSegment line = new WindowsLineSegment(); line.Point = startPoint; figure.Segments.Add(line); ArcSegment seg = new ArcSegment(); seg.Point = endPoint; seg.Size = new Size(radius, radius); seg.RotationAngle = ActualEndAngle + ActualStartAngle; seg.IsLargeArc = ActualEndAngle - ActualStartAngle > Math.PI; seg.SweepDirection = StartAngle > EndAngle ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; figure.Segments.Add(seg); figure.IsClosed = true; this.segmentGeometry = new PathGeometry(); segmentGeometry.Figures = new PathFigureCollection() { figure }; this.segmentPath.Data = segmentGeometry; } else { this.segmentPath.Data = null; } } else if (pieIndex >= 1) { double radius = (equalParts * (pieIndex + 1)) - (equalParts * (1 - parentSeries.InternalPieCoefficient)); double innerRadius = equalParts * pieIndex; parentSeries.Radius = radius; Point center = ChartLayoutUtils.GetCenter(transformer.Viewport); if (this.IsExploded) { center = new Point(center.X + (parentSeries.ExplodeRadius * Math.Cos(AngleOfSlice)), center.Y + (parentSeries.ExplodeRadius * Math.Sin(AngleOfSlice))); } startPoint = new Point(center.X + radius * Math.Cos(ActualStartAngle), center.Y + radius * Math.Sin(ActualStartAngle)); Point endPoint = new Point(center.X + radius * Math.Cos(ActualEndAngle), center.Y + radius * Math.Sin(ActualEndAngle)); if (Math.Round((ActualEndAngle - ActualStartAngle), 2) == 6.28) { GeometryGroup geometryGroup = new GeometryGroup(); geometryGroup.Children.Add(new EllipseGeometry() { Center = center, RadiusX = radius, RadiusY = radius }); geometryGroup.Children.Add(new EllipseGeometry() { Center = center, RadiusX = innerRadius, RadiusY = innerRadius }); this.segmentPath.Data = geometryGroup; } else if ((ActualEndAngle - ActualStartAngle) != 0) { Point startDPoint = new Point(center.X + innerRadius * Math.Cos(ActualStartAngle), center.Y + innerRadius * Math.Sin(ActualStartAngle)); Point endDPoint = new Point(center.X + innerRadius * Math.Cos(ActualEndAngle), center.Y + innerRadius * Math.Sin(ActualEndAngle)); PathFigure figure = new PathFigure(); figure.StartPoint = startPoint; ArcSegment arcseg = new ArcSegment(); arcseg.Point = endPoint; arcseg.Size = new Size(radius, radius); arcseg.RotationAngle = ActualEndAngle - ActualStartAngle; arcseg.IsLargeArc = ActualEndAngle - ActualStartAngle > Math.PI; arcseg.SweepDirection = StartAngle > EndAngle ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; figure.Segments.Add(arcseg); WindowsLineSegment line = new WindowsLineSegment(); line.Point = endDPoint; figure.Segments.Add(line); arcseg = new ArcSegment(); arcseg.Point = startDPoint; arcseg.Size = new Size(innerRadius, innerRadius); arcseg.RotationAngle = ActualEndAngle - ActualStartAngle; arcseg.IsLargeArc = ActualEndAngle - ActualStartAngle > Math.PI; arcseg.SweepDirection = StartAngle < EndAngle ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; figure.Segments.Add(arcseg); figure.IsClosed = true; this.segmentGeometry = new PathGeometry(); segmentGeometry.Figures = new PathFigureCollection() { figure }; this.segmentPath.Data = segmentGeometry; } else { this.segmentPath.Data = null; } } }