private static RadRect CalculatePlotAreaRect(RadRect availableRect, AxisStack leftStack, AxisStack topStack, AxisStack rightStack, AxisStack bottomStack) { RadPoint topLeft = new RadPoint(); double finalLeftRectWidth = leftStack.desiredWidth + leftStack.desiredMargin.Left + leftStack.desiredMargin.Right; double maxLeftMargin = Math.Max(topStack.desiredMargin.Left, bottomStack.desiredMargin.Left); topLeft.X = Math.Max(finalLeftRectWidth, maxLeftMargin); double finalTopRectHeight = topStack.desiredHeight + topStack.desiredMargin.Top + topStack.desiredMargin.Bottom; double maxTopMargin = Math.Max(leftStack.desiredMargin.Top, rightStack.desiredMargin.Top); topLeft.Y = Math.Max(finalTopRectHeight, maxTopMargin); RadPoint bottomRight = new RadPoint(); double finalRightRectWidth = rightStack.desiredWidth + rightStack.desiredMargin.Left + rightStack.desiredMargin.Right; double maxRightMargin = Math.Max(topStack.desiredMargin.Right, bottomStack.desiredMargin.Right); bottomRight.X = availableRect.Width - Math.Max(finalRightRectWidth, maxRightMargin); double finalBottomRectHeight = bottomStack.desiredHeight + bottomStack.desiredMargin.Top + bottomStack.desiredMargin.Bottom; double maxBottomMargin = Math.Max(leftStack.desiredMargin.Bottom, rightStack.desiredMargin.Bottom); bottomRight.Y = availableRect.Height - Math.Max(finalBottomRectHeight, maxBottomMargin); RadRect plotAreaRect = new RadRect(topLeft, bottomRight); return(RadRect.Round(plotAreaRect)); }
private AxisStack[] PrepareAxesStacks(RadSize availableSize) { // horizontal stacks AxisStack leftStack; AxisStack rightStack; List <AxisModel> leftAxes = new List <AxisModel>(); List <AxisModel> rightAxes = new List <AxisModel>(); foreach (var axis in this.SecondAxes) { if (axis.HorizontalLocation == AxisHorizontalLocation.Left) { leftAxes.Add(axis); } else { rightAxes.Add(axis); } } leftStack = new AxisStack(leftAxes); rightStack = new AxisStack(rightAxes); // vertical stacks AxisStack topStack; AxisStack bottomStack; List <AxisModel> topAxes = new List <AxisModel>(); List <AxisModel> bottomAxes = new List <AxisModel>(); foreach (var axis in this.FirstAxes) { if (axis.VerticalLocation == AxisVerticalLocation.Bottom) { bottomAxes.Add(axis); } else { topAxes.Add(axis); } } bottomStack = new AxisStack(bottomAxes); topStack = new AxisStack(topAxes); leftStack.Measure(availableSize); topStack.Measure(availableSize); rightStack.Measure(availableSize); bottomStack.Measure(availableSize); return(new AxisStack[] { leftStack, topStack, rightStack, bottomStack }); }
internal ActiveAxis(Asttree axisTree) { _axisTree = axisTree; // only a pointer. do i need it? _currentDepth = -1; // context depth is 0 -- enforce moveToChild for the context node // otherwise can't deal with "." node _axisStack = new ArrayList(axisTree.SubtreeArray.Count); // defined length // new one stack element for each one for (int i = 0; i < axisTree.SubtreeArray.Count; ++i) { AxisStack stack = new AxisStack((ForwardAxis)axisTree.SubtreeArray[i], this); _axisStack.Add(stack); } _isActive = true; }
protected override RadRect ArrangeAxes(RadRect availableRect) { RadSize availableSize = new RadSize(availableRect.Width, availableRect.Height); // Populate stacks AxisStack[] stacks = this.PrepareAxesStacks(availableSize); AxisStack leftStack = stacks[0]; AxisStack topStack = stacks[1]; AxisStack rightStack = stacks[2]; AxisStack bottomStack = stacks[3]; RadRect plotAreaRect = CalculatePlotAreaRect(availableRect, leftStack, topStack, rightStack, bottomStack); int maxIterations = 10; int currentIteration = 0; // axes may need several passes to adjust their desired size due to label fit mode bool isArrangeValid; do { isArrangeValid = true; // Although this seems an anti-pattern, it actually is safety coding // The logic behind axes layout is not completely verified yet and we do not want to enter an endless loop if (currentIteration > maxIterations) { Debug.Assert(false, "Entering endless loop"); break; } if (!leftStack.IsEmpty) { double lastRightPoint = plotAreaRect.X; foreach (var axis in leftStack.axes) { var finalRect = new RadRect(lastRightPoint - axis.desiredSize.Width, plotAreaRect.Y, axis.desiredSize.Width, plotAreaRect.Height); lastRightPoint = finalRect.X; RadSize lastAxisDesiredSize = axis.desiredSize; axis.Arrange(finalRect); if (axis.desiredSize.Width != lastAxisDesiredSize.Width) { leftStack.desiredWidth += axis.desiredSize.Width - lastAxisDesiredSize.Width; isArrangeValid = false; } } } if (!topStack.IsEmpty) { double lastBottomPoint = plotAreaRect.Y; foreach (var axis in topStack.axes) { var finalRect = new RadRect(plotAreaRect.X, lastBottomPoint - axis.desiredSize.Height, plotAreaRect.Width, axis.desiredSize.Height); lastBottomPoint = finalRect.Y; RadSize lastAxisDesiredSize = axis.desiredSize; axis.Arrange(finalRect); if (axis.desiredSize.Height != lastAxisDesiredSize.Height) { topStack.desiredHeight += axis.desiredSize.Height - lastAxisDesiredSize.Height; isArrangeValid = false; } } } if (!rightStack.IsEmpty) { double lastLeftPoint = plotAreaRect.Right; foreach (var axis in rightStack.axes) { var finalRect = new RadRect(lastLeftPoint, plotAreaRect.Y, axis.desiredSize.Width, plotAreaRect.Height); lastLeftPoint = finalRect.Right; RadSize lastAxisDesiredSize = axis.desiredSize; axis.Arrange(finalRect); if (axis.desiredSize.Width != lastAxisDesiredSize.Width) { rightStack.desiredWidth += axis.desiredSize.Width - lastAxisDesiredSize.Width; isArrangeValid = false; } } } if (!bottomStack.IsEmpty) { double lastTopPoint = plotAreaRect.Bottom; foreach (var axis in bottomStack.axes) { var finalRect = new RadRect(plotAreaRect.X, lastTopPoint, plotAreaRect.Width, axis.desiredSize.Height); lastTopPoint = finalRect.Bottom; RadSize lastAxisDesiredSize = axis.desiredSize; axis.Arrange(finalRect); if (axis.desiredSize.Height != finalRect.Height) { bottomStack.desiredHeight += axis.desiredSize.Height - lastAxisDesiredSize.Height; isArrangeValid = false; } } } if (!isArrangeValid) { plotAreaRect = CalculatePlotAreaRect(availableRect, leftStack, topStack, rightStack, bottomStack); } currentIteration++; }while (!isArrangeValid); return(plotAreaRect); }
internal ActiveAxis (Asttree axisTree) { this.axisTree = axisTree; // only a pointer. do i need it? this.currentDepth = -1; // context depth is 0 -- enforce moveToChild for the context node // otherwise can't deal with "." node this.axisStack = new ArrayList(axisTree.SubtreeArray.Count); // defined length // new one stack element for each one foreach (ForwardAxis faxis in axisTree.SubtreeArray) { AxisStack stack = new AxisStack (faxis, this); axisStack.Add (stack); } this.isActive = true; }