private void MeasureAxis(Size availableSize, Rect seriesClipRect) { bool needLayout = true; bool isFirstLayout = true; Rect currectClipRect; while (needLayout) { needLayout = false; leftSizes.Clear(); rightSizes.Clear(); CalcRowSize(seriesClipRect); foreach (ChartRowDefinition row in Area.RowDefinitions) { var rowSize = new Size(availableSize.Width, row.ComputedHeight); row.Measure(rowSize, leftSizes, rightSizes, isFirstLayout); } left = leftSizes.Sum(); right = rightSizes.Sum(); top = topSizes.Count > 0 ? topSizes.Sum() : 0; bottom = bottomSizes.Count > 0 ? bottomSizes.Sum() : 0; var thickness = new Thickness(left, top, right, bottom); currectClipRect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), thickness); if (Math.Abs(seriesClipRect.Width - currectClipRect.Width) > 0.5 || isFirstLayout) { topSizes.Clear(); bottomSizes.Clear(); seriesClipRect = currectClipRect; CalcColumnSize(seriesClipRect); foreach (ChartColumnDefinition column in Area.ColumnDefinitions) { var columnSize = new Size(column.ComputedWidth, availableSize.Height); column.Measure(columnSize, bottomSizes, topSizes); } left = leftSizes.Sum(); right = rightSizes.Sum(); top = topSizes.Sum(); bottom = bottomSizes.Sum(); thickness = new Thickness(left, top, right, bottom); currectClipRect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), thickness); needLayout = Math.Abs(seriesClipRect.Height - currectClipRect.Height) > 0.5; seriesClipRect = currectClipRect; } isFirstLayout = false; } }
/// <summary> /// Provides the behavior for the Measure pass of Silverlight layout. Classes can override this method to define their own Measure pass behavior. /// </summary> /// <returns> /// The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects; or based on other considerations, such as a fixed container size. /// </returns> /// <param name="availableSize">The Available Size</param> protected override Size MeasureOverride(Size availableSize) { var elements = new List <UIElement>(); Size size = ChartLayoutUtils.CheckSize(availableSize); if (Area != null) { Area.RootPanelDesiredSize = size; } foreach (UIElement element in Children) { elements.Add(element); } IEnumerable <UIElement> uiElements = elements.OrderBy(GetMeasurePriorityIndex); foreach (UIElement element in uiElements) { element.Measure(availableSize); } return(size); }
/// <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> /// Provides the behavior for the Measure pass of Silverlight layout. Classes can override this method to define their own Measure pass behavior. /// </summary> /// <returns> /// The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects; or based on other considerations, such as a fixed container size. /// </returns> /// <param name="availableSize"></param> protected override Size MeasureOverride(Size availableSize) { availableSize = ChartLayoutUtils.CheckSize(availableSize); if (AxisLayout != null) { AxisLayout.Measure(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 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> /// Updates the panel. /// </summary> /// <param name="finalSize"></param> internal void Update(Size finalSize) { bool canUpdate = !(Series is ISupportAxes); if (Series is ISupportAxes && Series.ActualXAxis != null && Series.ActualYAxis != null) { canUpdate = true; if (Series.Area != null) { Series.Area.ClearBuffer(); } } if (canUpdate) { IChartTransformer chartTransformer = Series.CreateTransformer(finalSize, true); if (Series is CircularSeriesBase) { CircularSeriesBase circularSeries = Series as CircularSeriesBase; Rect rect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(), finalSize), Series.Margin); chartTransformer = Series.CreateTransformer(new Size(rect.Width, rect.Height), true); var pieSeries = circularSeries as PieSeries; double coefficient = pieSeries != null ? pieSeries.InternalPieCoefficient : (circularSeries as DoughnutSeries).InternalDoughnutCoefficient; double radius = coefficient * Math.Min(chartTransformer.Viewport.Width, chartTransformer.Viewport.Height) / 2; circularSeries.Center = circularSeries.GetActualCenter(new Point(chartTransformer.Viewport.Width * 0.5d, chartTransformer.Viewport.Height * 0.5d), radius); } Series.Pixels.Clear(); Series.bitmapPixels.Clear(); Series.bitmapRects.Clear(); foreach (ChartSegment segment in Series.Segments) { segment.Update(chartTransformer); } if (Series.CanAnimate && Series.Segments.Count > 0) { Series.Animate(); Series.CanAnimate = false; } if (Series.IsLoading) { Series.IsLoading = false; } } }
/// <summary> /// Calculates the series rectangle. /// </summary> /// <param name="availableSize">The Available Size</param> private void CalculateSeriesRect(Size availableSize) { double width = Math.Max(availableSize.Width / 2 - Radius, 0); double height = Math.Max(availableSize.Height / 2 - Radius, 0); this.Area.AxisThickness = new Thickness(width, height, width, height); Rect rect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), this.Area.AxisThickness); this.Area.SeriesClipRect = new Rect(rect.Left, rect.Top, rect.Width, rect.Height); Area.InternalCanvas.Clip = new RectangleGeometry() { Rect = new Rect(0, 0, this.Area.SeriesClipRect.Width, this.Area.SeriesClipRect.Height) }; }
/// <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> /// Change the ItemsPanel orientation /// </summary> internal void ChangedOrientation() { ItemsPresenter itemsPresenter = ChartLayoutUtils.GetVisualChild <ItemsPresenter>(this); if (itemsPresenter != null) { if (VisualTreeHelper.GetChildrenCount(itemsPresenter) > 0) { StackPanel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 1) as StackPanel; if (itemsPanel != null) { itemsPanel.Orientation = ZoomBehavior.ToolBarOrientation; this.UpdateLayout(); ZoomBehavior.OnLayoutUpdated(); } } } }
/// <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); }
internal void ChangeOrientation() { ItemsPresenter itemsPresenter = ChartLayoutUtils.GetVisualChild <ItemsPresenter>(this); if (itemsPresenter != null) { if (VisualTreeHelper.GetChildrenCount(itemsPresenter) > 0) { StackPanel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 1) as StackPanel; if (itemsPanel != null) { itemsPanel.Orientation = (Orientation)Enum.Parse( typeof(Orientation) , (this.Orientation == ChartOrientation.Default ? ((this.DockPosition != ChartDock.Left && this.DockPosition != ChartDock.Right) ? ChartOrientation.Horizontal : ChartOrientation.Vertical) : this.Orientation).ToString(), false); } } } }
/// <summary> /// Provides the behavior for the Measure pass of Silverlight layout. Classes can override this method to define their own Measure pass behavior. /// </summary> /// <returns> /// The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects; or based on other considerations, such as a fixed container size. /// </returns> /// <param name="availableSize">The Available Size</param> protected override Size MeasureOverride(Size availableSize) { var topSizes = new List <double>(); var leftSizes = new List <double>(); var bottomSizes = new List <double>(); var rightSizes = new List <double>(); Thickness margin = this.ElementMargin; m_controlsThickness = this.ElementMargin; foreach (UIElement element in Children) { if (element == null) { continue; } if (element == m_rootElement) { continue; } element.Measure(availableSize); Size elemSize = ChartLayoutUtils.Addthickness(element.DesiredSize, margin); var chartLegend = element as ChartLegend; switch (GetDock(element)) { case ChartDock.Left: if (chartLegend != null) { var index = chartLegend.RowColumnIndex; if (leftSizes.Count <= index) { leftSizes.Add(elemSize.Width); } else if (leftSizes[index] < elemSize.Width) { leftSizes[index] = elemSize.Width; } } else { m_controlsThickness.Left += elemSize.Width; } break; case ChartDock.Right: if (chartLegend != null) { var index = chartLegend.RowColumnIndex; if (rightSizes.Count <= index) { rightSizes.Add(elemSize.Width); } else if (rightSizes[index] < elemSize.Width) { rightSizes[index] = elemSize.Width; } } else { m_controlsThickness.Right += elemSize.Width; } break; case ChartDock.Top: if (chartLegend != null) { var index = chartLegend.RowColumnIndex; if (topSizes.Count <= index) { topSizes.Add(elemSize.Height); } else if (topSizes[index] < elemSize.Height) { topSizes[index] = elemSize.Height; } } else { m_controlsThickness.Top += elemSize.Height; } break; case ChartDock.Bottom: if (chartLegend != null) { var index = chartLegend.RowColumnIndex; if (bottomSizes.Count <= index) { bottomSizes.Add(elemSize.Height); } else if (bottomSizes[index] < elemSize.Height) { bottomSizes[index] = elemSize.Height; } } else { m_controlsThickness.Bottom += elemSize.Height; } break; case ChartDock.Floating: // WPF - 33623 Force to measure the dockpanel when set the DockPosition and LegendPosition as Inside. if (chartLegend != null) { if (chartLegend.ActualHeight > 0 || chartLegend.ActualWidth > 0) { leftSizes.Add(0); } else { leftSizes.Add(0.1); } } break; } } m_controlsThickness.Left += leftSizes.Sum(); m_controlsThickness.Right += rightSizes.Sum(); m_controlsThickness.Top += topSizes.Sum(); m_controlsThickness.Bottom += bottomSizes.Sum(); try { var areasize = ChartLayoutUtils.Subtractthickness(availableSize, m_controlsThickness); m_rootElement.Measure(areasize); } catch (Exception) { } 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 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; } } }
/// <summary> /// Measures the control. /// </summary> /// <param name="availableSize">The Available Size</param> /// <returns>Returns the measure size.</returns> protected override Size MeasureOverride(Size availableSize) { base.MeasureOverride(availableSize); this.availableSize = ChartLayoutUtils.CheckSize(availableSize); if (this.Orientation == Orientation.Horizontal && NearHand != null && FarHand != null) { desiredSize.Width = this.availableSize.Width; desiredSize.Height = ResizableBarSize; if (NearHand.Visibility != Visibility.Collapsed) { NearHand.Measure(availableSize); Size thumbSize = NearHand.DesiredSize; if (thumbSize.Width == 0) { resizeThumbSize = NearHand.MinWidth; } else { resizeThumbSize = thumbSize.Width; } NearHand.Width = resizeThumbSize; FarHand.Width = resizeThumbSize; } else { resizeThumbSize = 0d; } if (this.ScrollButtonVisibility != Visibility.Collapsed) { SmallIncrease.Measure(availableSize); Size scrollButtonSize = SmallIncrease.DesiredSize; if (scrollButtonSize.Width == 0) { smallThumbSize = SmallIncrease.MinWidth; } else { smallThumbSize = (smallThumbSize == 0) ? scrollButtonSize.Width : Math.Min(smallThumbSize, scrollButtonSize.Width); } SmallDecrease.Width = smallThumbSize; SmallIncrease.Width = smallThumbSize; } else { SmallDecrease.Width = smallThumbSize = 0; SmallIncrease.Width = smallThumbSize = 0; } } else if (this.Orientation == Orientation.Vertical && FarHand != null && NearHand != null) { desiredSize.Height = this.availableSize.Height; desiredSize.Width = ResizableBarSize; NearHand.Measure(availableSize); if (NearHand.Visibility != Visibility.Collapsed) { Size thumbSize = NearHand.DesiredSize; if (thumbSize.Height == 0) { resizeThumbSize = NearHand.MinHeight; } else { resizeThumbSize = thumbSize.Height; } NearHand.Height = resizeThumbSize; FarHand.Height = resizeThumbSize; } else { resizeThumbSize = 0d; } if (this.ScrollButtonVisibility != Visibility.Collapsed) { SmallIncrease.Measure(availableSize); Size scrollButtonSize = SmallIncrease.DesiredSize; if (scrollButtonSize.Width == 0) { smallThumbSize = SmallIncrease.MinHeight; } else { smallThumbSize = smallThumbSize = (smallThumbSize == 0) ? scrollButtonSize.Height : Math.Min(smallThumbSize, scrollButtonSize.Height); } SmallDecrease.Height = smallThumbSize; SmallIncrease.Height = smallThumbSize; } else { SmallDecrease.Height = smallThumbSize = 0; SmallIncrease.Height = smallThumbSize = 0; } } return(desiredSize); }
private void MeasureAxis(Size availableSize, Rect seriesClipRect) { bool needLayout = true; bool isFirstLayout = true; Rect currectClipRect; while (needLayout) { needLayout = false; leftSizes.Clear(); rightSizes.Clear(); CalcRowSize(seriesClipRect); foreach (ChartRowDefinition row in Area.RowDefinitions) { var rowSize = new Size(availableSize.Width, row.ComputedHeight); row.Measure(rowSize, leftSizes, rightSizes, isFirstLayout); } left = leftSizes.Sum(); right = rightSizes.Sum(); top = topSizes.Count > 0 ? topSizes.Sum() : 0; bottom = bottomSizes.Count > 0 ? bottomSizes.Sum() : 0; var thickness = new Thickness(left, top, right, bottom); currectClipRect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), thickness); if (Math.Abs(seriesClipRect.Width - currectClipRect.Width) > 0.5 || isFirstLayout) { topSizes.Clear(); bottomSizes.Clear(); seriesClipRect = currectClipRect; CalcColumnSize(seriesClipRect); foreach (ChartColumnDefinition column in Area.ColumnDefinitions) { var columnSize = new Size(column.ComputedWidth, availableSize.Height); column.Measure(columnSize, bottomSizes, topSizes); //This is the place where the column is updated correctly just before the y axis and x axis arrangement. if (Area is SfChart3D) { if ((column.Axis.Any(x => (x as ChartAxisBase3D).IsZAxis && !(x as ChartAxisBase3D).IsManhattanAxis))) { (Area as SfChart3D).ActualDepth = column.ComputedWidth; } else { (Area as SfChart3D).ActualDepth = (Area as SfChart3D).Depth; } } } left = leftSizes.Sum(); right = rightSizes.Sum(); top = topSizes.Sum(); bottom = bottomSizes.Sum(); thickness = new Thickness(left, top, right, bottom); currectClipRect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), thickness); needLayout = Math.Abs(seriesClipRect.Height - currectClipRect.Height) > 0.5; seriesClipRect = currectClipRect; } isFirstLayout = false; } }
/// <summary> /// Measures the elements in the panel. /// </summary> /// <param name="availableSize">available size of the panel.</param> /// <returns>Returns the desired size</returns> public Size Measure(Size availableSize) { left = right = top = bottom = 0; if (Area.ColumnDefinitions.Count == 0) { Area.ColumnDefinitions.Add(new ChartColumnDefinition()); } if (Area.RowDefinitions.Count == 0) { Area.RowDefinitions.Add(new ChartRowDefinition()); } foreach (ChartColumnDefinition column in Area.ColumnDefinitions) { column.Axis.Clear(); } foreach (ChartRowDefinition row in Area.RowDefinitions) { row.Axis.Clear(); } foreach (ChartAxis content in Area.Axes) { if (content.DisableScrollbar) { ChartAxisBase2D chartAxisBase2D = content as ChartAxisBase2D; if (chartAxisBase2D != null) { chartAxisBase2D.EnableScrollBar = true; } } if (content.Orientation == Orientation.Horizontal) { Area.ColumnDefinitions[Area.GetActualColumn(content)].Axis.Add(content); } else { Area.RowDefinitions[Area.GetActualRow(content)].Axis.Add(content); } } // Spanning calculation for each axis if (Area != null) { AxisSpanCalculation(); } leftSizes.Clear(); rightSizes.Clear(); topSizes.Clear(); bottomSizes.Clear(); MeasureAxis(availableSize, new Rect(new Point(0, 0), availableSize)); Area.AxisThickness = new Thickness(left, top, right, bottom); // Area.SeriesClipRect = rect; UpdateArrangeRect(availableSize); Rect rect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), availableSize), this.Area.AxisThickness); currentAvalilableSize = availableSize; Area.SeriesClipRect = rect; foreach (ChartSeriesBase series in Area.VisibleSeries.OfType <ISupportAxes>()) { if (series.ActualXAxis != null && series.ActualYAxis != null) { ChartAxis xAxis = series.ActualXAxis.Orientation == Orientation.Horizontal ? series.ActualXAxis : series.ActualYAxis; ChartAxis yAxis = series.ActualYAxis.Orientation == Orientation.Vertical ? series.ActualYAxis : series.ActualXAxis; var x = xAxis.ArrangeRect.Left - rect.Left; var y = yAxis.ArrangeRect.Top - rect.Top; var width = xAxis.ArrangeRect.Width; var height = yAxis.ArrangeRect.Height; series.Clip = new RectangleGeometry() { Rect = new Rect(x, y, width + 0.5, height + 0.5) }; } } _desiredSize = availableSize; return(availableSize); }
protected override Size ArrangeOverride(Size finalSize) { m_resultDockRect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), finalSize), m_controlsThickness); Rect currRect = new Rect(new Point(0, 0), finalSize); Rect resRect = currRect; #region Arrange Central Element if (m_rootElement != null) { try { m_rootElement.Arrange(m_resultDockRect); } catch (Exception) { } } #endregion #region Arrange All Elements double legendTop = -1d; for (int i = 0; i < Children.Count; i++) { FrameworkElement element = Children[i] as FrameworkElement; Size elemSize = ChartLayoutUtils.Addthickness(element.DesiredSize, ElementMargin); double scale; if (element != null && element != m_rootElement) { var chartLegend = element as ChartLegend; var offsetX = 0d; var offsetY = 0d; if (chartLegend != null) { offsetX = double.IsNaN(chartLegend.OffsetX) ? 0d : chartLegend.OffsetX; offsetY = double.IsNaN(chartLegend.OffsetY) ? 0d : chartLegend.OffsetY; } #region Orientation == Orientation.Horizontal switch (GetDock(element)) { case ChartDock.Left: if (element is ChartLegend) { var arrangeRect = (element as ChartLegend).ArrangeRect; ArrangeElement(element, ChartDock.Left, new Rect(arrangeRect.Left + offsetX + currRect.Left, arrangeRect.Top + offsetY + m_controlsThickness.Top, arrangeRect.Width, arrangeRect.Height)); } else { ArrangeElement(element, ChartDock.Left, new Rect(currRect.Left, resRect.Y, elemSize.Width, resRect.Height)); currRect.X += elemSize.Width; scale = currRect.Width - elemSize.Width; currRect.Width = scale > 0 ? scale : 0; } break; case ChartDock.Right: if (element is ChartLegend) { var arrangeRect = (element as ChartLegend).ArrangeRect; ArrangeElement(element, ChartDock.Right, new Rect(arrangeRect.Left + offsetX + m_controlsThickness.Left, arrangeRect.Top + offsetY + m_controlsThickness.Top, arrangeRect.Width, arrangeRect.Height)); } else { scale = currRect.Width - elemSize.Width; currRect.Width = scale > 0 ? scale : 0; ArrangeElement(element, ChartDock.Right, new Rect(currRect.Right, resRect.Top + m_controlsThickness.Top, elemSize.Width, resRect.Height)); } break; case ChartDock.Top: if (element is ChartLegend) { if (legendTop == -1) { legendTop = currRect.Top; } var arrangeRect = (element as ChartLegend).ArrangeRect; ArrangeElement(element, ChartDock.Top, new Rect(arrangeRect.Left + offsetX + m_controlsThickness.Left, arrangeRect.Top + offsetY + legendTop, arrangeRect.Width, arrangeRect.Height)); } else { ArrangeElement(element, ChartDock.Top, new Rect(0, currRect.Top, finalSize.Width, elemSize.Height)); currRect.Y += elemSize.Height; scale = currRect.Height - elemSize.Height; currRect.Height = scale > 0 ? scale : 0; } break; case ChartDock.Bottom: if (element is ChartLegend) { var arrangeRect = (element as ChartLegend).ArrangeRect; ArrangeElement(element, ChartDock.Bottom, new Rect(arrangeRect.Left + offsetX + m_controlsThickness.Left, arrangeRect.Top + offsetY + m_controlsThickness.Top, arrangeRect.Width, arrangeRect.Height)); } else { scale = currRect.Height - elemSize.Height; currRect.Height = scale > 0 ? scale : 0; ArrangeElement(element, ChartDock.Bottom, new Rect(0, currRect.Bottom, finalSize.Width, elemSize.Height)); } break; case ChartDock.Floating: Rect elementRect = new Rect(new Point(0, 0), new Size(element.DesiredSize.Width, element.DesiredSize.Height)); if (chartLegend != null) { element.Arrange(EnsureRectIsInside(resRect, new Rect(chartLegend.ArrangeRect.Left + offsetX + m_controlsThickness.Left, chartLegend.ArrangeRect.Top + offsetY + m_controlsThickness.Top, element.DesiredSize.Width, chartLegend.DesiredSize.Height))); } else { element.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); } break; } #endregion } } #endregion #if Uno #if __ANDROID__ || __IOS__ || __WASM__ return(finalSize); #else return(base.ArrangeOverride(finalSize)); #endif #else return(base.ArrangeOverride(finalSize)); #endif }
/// <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> /// Provides the behavior for the Measure pass of Silverlight layout. Classes can override this method to define their own Measure pass behavior. /// </summary> /// <returns> /// The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects; or based on other considerations, such as a fixed container size. /// </returns> /// <param name="availableSize">The Available Size</param> protected override Size MeasureOverride(Size availableSize) { if (Adornment == null) { return(ChartLayoutUtils.CheckSize(availableSize)); } PredefinedSymbol.Measure(availableSize); m_symbolPresenter.Measure(availableSize); Size resultSize = new Size(); Size lblSz = Size.Empty; Size sblSz; if (Adornment.Series.adornmentInfo.Symbol == ChartSymbol.Custom) { sblSz = m_symbolPresenter.DesiredSize; } else { sblSz = PredefinedSymbol.DesiredSize; } switch (LabelHorizontalAlignment) { case HorizontalAlignment.Stretch: case HorizontalAlignment.Center: { resultSize.Width = Math.Max(lblSz.Width, sblSz.Width); m_symbolOffset.X = 0.5 * resultSize.Width; } break; case HorizontalAlignment.Left: resultSize.Width = Math.Max(lblSz.Width, sblSz.Width); m_symbolOffset.X = 0.5 * resultSize.Width; break; case HorizontalAlignment.Right: resultSize.Width = Math.Max(lblSz.Width, sblSz.Width); m_symbolOffset.X = 0.5 * resultSize.Width; break; } switch (LabelVerticalAlignment) { case VerticalAlignment.Bottom: resultSize.Height = Math.Max(lblSz.Height, sblSz.Height); m_symbolOffset.Y = 0.5 * resultSize.Height; break; case VerticalAlignment.Stretch: case VerticalAlignment.Center: { resultSize.Height = Math.Max(lblSz.Height, sblSz.Height); m_symbolOffset.Y = 0.5 * resultSize.Height; } break; case VerticalAlignment.Top: resultSize.Height = Math.Max(lblSz.Height, sblSz.Height); m_symbolOffset.Y = 0.5 * resultSize.Height; break; } return(resultSize); }
private void ArrangeCartesianElements(Size finalSize) { if (Axis == null) { return; } foreach (UIElement element in Children) { SetLeft(element, 0); SetTop(element, 0); } var headerContent = Children[0]; var labelsPanel = LayoutCalc.Count > 0 ? LayoutCalc[0] : null; var elementsPanel = LayoutCalc.Count > 1 ? LayoutCalc[1] : null; var multiLevelPanel = Axis.axisMultiLevelLabelsPanel; var scrollBar = Children.OfType <SfChartResizableBar>().FirstOrDefault(); var elements = new List <UIElement>(); var sizes = new List <Size>(); var isVertical = Axis.Orientation == Orientation.Vertical; var isInversed = Axis.OpposedPosition ^ isVertical; double headerMargin = 2; // Add some gap between the axis header and plot area. if (scrollBar != null) { elements.Add(scrollBar); sizes.Add(scrollBar.DesiredSize); } if (elementsPanel != null) { if (Axis.TickLinesPosition == AxisElementPosition.Inside) { elements.Insert(0, elementsPanel.Panel); sizes.Insert(0, elementsPanel.DesiredSize); } else { elements.Add(elementsPanel.Panel); sizes.Add(elementsPanel.DesiredSize); } } if (labelsPanel != null) { if (Axis.LabelsPosition == AxisElementPosition.Inside) { elements.Insert(0, labelsPanel.Panel); sizes.Insert(0, labelsPanel.DesiredSize); } else { elements.Add(labelsPanel.Panel); sizes.Add(labelsPanel.DesiredSize); } } if (Axis.MultiLevelLabels != null && Axis.MultiLevelLabels.Count > 0 && multiLevelPanel != null) { if (Axis.LabelsPosition == AxisElementPosition.Inside) { elements.Insert(0, multiLevelPanel.Panel); sizes.Insert(0, multiLevelPanel.DesiredSize); } else { elements.Add(multiLevelPanel.Panel); sizes.Add(multiLevelPanel.DesiredSize); } } if (headerContent != null) { elements.Add(headerContent as FrameworkElement); Size headerSize = (headerContent as FrameworkElement).DesiredSize; if (isVertical && headerContent.GetType() == typeof(ContentControl)) { headerSize = new Size(headerSize.Height, headerSize.Width); } sizes.Add(headerSize); } if (isInversed) { elements.Reverse(); sizes.Reverse(); } double currentPos = 0; for (int i = 0; i < elements.Count; i++) { UIElement element = elements[i]; var isResizableBar = element is SfChartResizableBar; double headerHeight = 0; double headerWidth = 0; if (isVertical) { if (element == headerContent) { double leftPosition = currentPos - ((element.DesiredSize.Width - sizes[i].Width) / 2); headerHeight = element.DesiredSize.Height; headerWidth = element.DesiredSize.Width; SetTop(element, (finalSize.Height - element.DesiredSize.Height) / 2); if (Axis.TickLinesPosition == AxisElementPosition.Inside) { double tickFactor = (elementsPanel.DesiredSize.Width - Axis.TickLineSize); // Positioning header according to the axis line thickness. double position = Axis.OpposedPosition ? leftPosition + tickFactor : leftPosition - tickFactor; SetLeft(element, position); } if (Axis.ShowAxisNextToOrigin && Axis.HeaderPosition == AxisHeaderPosition.Far) { ChartAxis axis = null; double value = 0; if (Axis.Area.InternalSecondaryAxis == Axis) { value = Axis.Area.InternalPrimaryAxis.ValueToCoefficientCalc(Axis.Origin); axis = Axis.Area.InternalPrimaryAxis; } else if (Axis.Area.InternalSecondaryAxis.Orientation == Orientation.Horizontal && Axis.Area.InternalPrimaryAxis == Axis) { value = Axis.Area.InternalSecondaryAxis.ValueToCoefficientCalc(Axis.Origin); axis = Axis.Area.InternalSecondaryAxis; } if (0 < value && 1 > value && axis != null) { if (Axis.OpposedPosition) { Rect rect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), Axis.AvailableSize), Axis.Area.AxisThickness); double position = (1 - value) * (rect.Width - (axis.ActualPlotOffset * 2)) + axis.ActualPlotOffset + Axis.InsidePadding; if (position > finalSize.Width - headerHeight) { if (axis.AxisLayoutPanel is ChartPolarAxisLayoutPanel) { SetLeft(element, leftPosition); } else { SetLeft(element, position - (headerWidth - headerHeight) / 2 + headerMargin); } } else { SetLeft(element, leftPosition); } } else if (Axis.ArrangeRect.Left + finalSize.Width - headerHeight > finalSize.Width - headerHeight) { if (axis.AxisLayoutPanel is ChartPolarAxisLayoutPanel) { SetLeft(element, leftPosition); } else { SetLeft(element, -(Axis.ArrangeRect.Left + (headerWidth - headerHeight) / 2)); } } else { SetLeft(element, leftPosition); } } else { SetLeft(element, leftPosition); } } else { SetLeft(element, leftPosition); } } else if (isResizableBar && Axis.EnableTouchMode) { SetLeft(element, currentPos - sizes[i].Width / 2); continue; } else if ((isResizableBar && !Axis.EnableTouchMode) && Axis.TickLinesPosition == AxisElementPosition.Inside) { double tickFactor = elementsPanel.DesiredSize.Width - Axis.TickLineSize; // Positioning scroll bar according to the axis line thickness. double position = Axis.OpposedPosition ? currentPos + tickFactor : currentPos - tickFactor; SetLeft(element, position); } else { SetLeft(element, currentPos); } currentPos += sizes[i].Width; } else { if (element == headerContent) { SetLeft(element, (finalSize.Width - sizes[i].Width) / 2); headerHeight = element.DesiredSize.Height; if (Axis.TickLinesPosition == AxisElementPosition.Inside) { double tickFactor = elementsPanel.DesiredSize.Height - Axis.TickLineSize; // Positioning header according to the axis line thickness. double position = Axis.OpposedPosition ? currentPos - tickFactor : currentPos + tickFactor; SetTop(element, position); } if (Axis.ShowAxisNextToOrigin && Axis.HeaderPosition == AxisHeaderPosition.Far) { ChartAxis axis = null; double value = 0; if (Axis.Area.InternalPrimaryAxis == Axis) { value = Axis.Area.InternalSecondaryAxis.ValueToCoefficientCalc(Axis.Origin); axis = Axis.Area.InternalSecondaryAxis; } else if (Axis.Area.InternalPrimaryAxis.Orientation == Orientation.Vertical && Axis.Area.InternalSecondaryAxis == Axis) { value = Axis.Area.InternalPrimaryAxis.ValueToCoefficientCalc(Axis.Origin); axis = Axis.Area.InternalPrimaryAxis; } if (0 < value && 1 > value && axis != null) { Rect rect = ChartLayoutUtils.Subtractthickness(new Rect(new Point(0, 0), Axis.AvailableSize), Axis.Area.AxisThickness); double position = value * (rect.Height - (axis.ActualPlotOffset * 2)) + axis.ActualPlotOffset + Axis.InsidePadding; if (Axis.OpposedPosition) { if (Axis.ArrangeRect.Top + finalSize.Height - headerHeight > finalSize.Height - headerHeight) { SetTop(element, -Axis.ArrangeRect.Top - headerMargin); } else { SetTop(element, currentPos); } } else if (position > finalSize.Height - headerHeight) { SetTop(element, (position + headerMargin)); } else { SetTop(element, currentPos); } } else { SetTop(element, currentPos); } } else { SetTop(element, currentPos); } } else if (isResizableBar && Axis.EnableTouchMode) { SetTop(element, currentPos - sizes[i].Height / 2); continue; } else if ((isResizableBar && !Axis.EnableTouchMode) && Axis.TickLinesPosition == AxisElementPosition.Inside) { double tickFactor = elementsPanel.DesiredSize.Height - Axis.TickLineSize; // Position axis line according to the axis line thickness. double position = Axis.OpposedPosition ? currentPos - tickFactor : currentPos + tickFactor; SetTop(element, position); } else { SetTop(element, currentPos); } currentPos += sizes[i].Height; } } foreach (ILayoutCalculator layout in this.LayoutCalc) { layout.Arrange(layout.DesiredSize); } foreach (UIElement element in elements) { if ((element as FrameworkElement).Name == "axisLabelsPanel") { SetLabelsPanelBounds(element, labelsPanel); break; } } // To arrange the children of multi level labels panel if (Axis.MultiLevelLabels != null && Axis.MultiLevelLabels.Count > 0 && multiLevelPanel != null) { multiLevelPanel.Arrange(multiLevelPanel.DesiredSize); } }
/// <summary> /// Arranges the elements inside the passing element. /// </summary> /// <param name="element">The Element</param> /// <param name="dock">The Dock Position</param> /// <param name="rect">The Reference Size <see cref="Rect"/></param> private void ArrangeElement(UIElement element, ChartDock dock, Rect rect) { element.Arrange(ChartLayoutUtils.Subtractthickness(rect, ElementMargin)); }
/// <summary> /// Computes the size of the <see cref="ChartCartesianAxisPanel"/>. /// </summary> /// <param name="availableSize">The Available Size</param> /// <returns>Returns the computed size.</returns> internal Size ComputeSize(Size availableSize) { Size size = Size.Empty; if (Axis.AxisLayoutPanel is ChartPolarAxisLayoutPanel) { foreach (UIElement element in this.Children) { element.Measure(availableSize); } (this.Children[0] as FrameworkElement).Visibility = Visibility.Collapsed;//Collapsing the visibility of polar/radar series X-Axis header foreach (ILayoutCalculator element in this.LayoutCalc) { element.Measure(availableSize); size = element.DesiredSize; ChartPolarAxisLayoutPanel axisLayoutPanel = Axis.AxisLayoutPanel as ChartPolarAxisLayoutPanel; ChartCircularAxisPanel circularAxisPanel = element as ChartCircularAxisPanel; axisLayoutPanel.Radius = circularAxisPanel.Radius; } } else { double horizontalPadding = 0; double verticalPadding = 0; double width = 0; double height = 0; double angle = 0d; //double.IsNaN(this.Axis.HeaderRotationAngle) ? 0d : this.Axis.HeaderRotationAngle; double direction = 1; if (Axis.headerContent != null) { Axis.headerContent.HorizontalAlignment = HorizontalAlignment.Center; Axis.headerContent.VerticalAlignment = VerticalAlignment.Center; if (Axis.Orientation == Orientation.Vertical) { direction = this.Axis.OpposedPosition ? 1 : -1; angle = direction * 90; var transform = new RotateTransform { Angle = angle }; Axis.headerContent.RenderTransform = transform; } else { Axis.headerContent.RenderTransform = null; } } foreach (UIElement element in this.Children) { bool isHeader = Axis.headerContent == element && this.Axis.Orientation == Orientation.Vertical; var measureSize = availableSize; if (isHeader) { measureSize.Width = Math.Max(availableSize.Width, element.DesiredSize.Width); measureSize.Height = Math.Max(availableSize.Height, element.DesiredSize.Height); } element.Measure(measureSize); if (element is SfChartResizableBar && Axis.EnableTouchMode) { continue; } width += isHeader ? element.DesiredSize.Height : element.DesiredSize.Width; height += isHeader ? element.DesiredSize.Width : element.DesiredSize.Height; } foreach (ILayoutCalculator element in LayoutCalc) { element.Measure(availableSize); if ((element is ChartCartesianAxisLabelsPanel && Axis.LabelsPosition == AxisElementPosition.Inside) || (element is ChartCartesianAxisElementsPanel && Axis.TickLinesPosition == AxisElementPosition.Inside)) { horizontalPadding += element.DesiredSize.Width; verticalPadding += element.DesiredSize.Height; } width += element.DesiredSize.Width; height += element.DesiredSize.Height; } // To measure the multi level labels panel if (Axis.MultiLevelLabels != null && Axis.MultiLevelLabels.Count > 0 && Axis.axisMultiLevelLabelsPanel != null) { Axis.axisMultiLevelLabelsPanel.Measure(availableSize); if (Axis.LabelsPosition == AxisElementPosition.Inside) { horizontalPadding += Axis.axisMultiLevelLabelsPanel.DesiredSize.Width; verticalPadding += Axis.axisMultiLevelLabelsPanel.DesiredSize.Height; } width += Axis.axisMultiLevelLabelsPanel.DesiredSize.Width; height += Axis.axisMultiLevelLabelsPanel.DesiredSize.Height; } if (Axis.Orientation == Orientation.Vertical) { Axis.InsidePadding = horizontalPadding; size = new Size(width, availableSize.Height); } else { Axis.InsidePadding = verticalPadding; size = new Size(availableSize.Width, height); } } return(ChartLayoutUtils.CheckSize(size)); }