private void LayoutAllOurChildren(int iLayer, ITreeNode tnLast, TreeNodeGroup tng) { List <Double> lstLeftToBB = new List <double>(); List <int> lstResponsible = new List <int>(); for (int i = 0; i < tng.Count; i++) { ITreeNode tn = tng[i]; LayoutTree(tn, iLayer + 1); RepositionSubtree(i, tng, lstLeftToBB, lstResponsible); tnLast = tn; } }
private void RepositionSubtree( int itn, TreeNodeGroup tngSiblings, List <double> lstLeftToBB, List <int> lsttnResponsible) { int itnResponsible; ITreeNode tn = tngSiblings[itn]; LayeredTreeInfo lti = Info(tn); if (itn == 0) { // No shifting but we still have to prepare the initial version of the // left hand skeleton list foreach (double pxRelativeToRoot in lti.lstPosRightBoundaryRelativeToRoot) { lstLeftToBB.Add(pxRelativeToRoot + lti.pxLeftPosRelativeToBoundingBox); lsttnResponsible.Add(0); } return; } ITreeNode tnLeft = tngSiblings[itn - 1]; LayeredTreeInfo ltiLeft = Info(tnLeft); int iLayer; double pxHorizontalBuffer = _pxBufferHorizontal; double pxNewPosFromBB = PxCalculateNewPos(lti, lstLeftToBB, lsttnResponsible, out itnResponsible, out iLayer); if (iLayer != 0) { pxHorizontalBuffer = _pxBufferHorizontalSubtree; } lti.pxToLeftSibling = pxNewPosFromBB - lstLeftToBB.First() + tnLeft.TreeWidth + pxHorizontalBuffer; int cLevels = Math.Min(lti.lstPosRightBoundaryRelativeToRoot.Count, lstLeftToBB.Count); for (int i = 0; i < cLevels; i++) { lstLeftToBB[i] = lti.lstPosRightBoundaryRelativeToRoot[i] + pxNewPosFromBB + pxHorizontalBuffer; lsttnResponsible[i] = itn; } for (int i = lstLeftToBB.Count; i < lti.lstPosRightBoundaryRelativeToRoot.Count; i++) { lstLeftToBB.Add(lti.lstPosRightBoundaryRelativeToRoot[i] + pxNewPosFromBB + pxHorizontalBuffer); lsttnResponsible.Add(itn); } ApportionSlop(itn, itnResponsible, tngSiblings); }
private void ApportionSlop(int itn, int itnResponsible, TreeNodeGroup tngSiblings) { LayeredTreeInfo lti = Info(tngSiblings[itn]); ITreeNode tnLeft = tngSiblings[itn - 1]; double pxSlop = lti.pxToLeftSibling - tnLeft.TreeWidth - _pxBufferHorizontal; if (pxSlop > 0) { for (int i = itnResponsible + 1; i < itn; i++) { Info(tngSiblings[i]).pxToLeftSibling += pxSlop * (i - itnResponsible) / (itn - itnResponsible); } lti.pxToLeftSibling -= (itn - itnResponsible - 1) * pxSlop / (itn - itnResponsible); } }
private void DetermineFinalPositions(ITreeNode tn, int iLayer, double pxFromTop, double pxParentFromLeft) { double pxRowHeight = _lstLayerHeight[iLayer]; LayeredTreeInfo lti = Info(tn); double pxBottom; DPoint dptOrigin; lti.pxFromTop = pxFromTop + CalcJustify(tn.TreeHeight, pxRowHeight); pxBottom = lti.pxFromTop + tn.TreeHeight; if (pxBottom > PxOverallHeight) { PxOverallHeight = pxBottom; } lti.pxFromLeft = lti.pxLeftPosRelativeToParent + pxParentFromLeft; dptOrigin = new DPoint(lti.pxFromLeft + tn.TreeWidth / 2, lti.pxFromTop + tn.TreeHeight); iLayer++; TreeNodeGroup tng = GetChildren(tn); foreach (ITreeNode tnCur in tng) { List <DPoint> lstcpt = new List <DPoint>(); LayeredTreeInfo ltiCur = Info(tnCur); lstcpt.Add(dptOrigin); DetermineFinalPositions(tnCur, iLayer, pxFromTop + pxRowHeight + _pxBufferVertical, lti.pxFromLeft); //If parent node has only one child then no changes here, just a normal TreeConnection if (tng.Count == 1) { lstcpt.Add(new DPoint(ltiCur.pxFromLeft + tnCur.TreeWidth / 2, ltiCur.pxFromTop)); _lsttcn.Add(new TreeConnection(tn, tnCur, lstcpt)); } else { //If parent node has more than one child then add the extra connection points double halfHeight = (ltiCur.pxFromTop - dptOrigin.Y) / 2; DPoint p2 = new DPoint(dptOrigin.X, dptOrigin.Y + halfHeight); lstcpt.Add(p2); DPoint p3 = new DPoint(ltiCur.pxFromLeft + tnCur.TreeWidth / 2, dptOrigin.Y + halfHeight); lstcpt.Add(p3); DPoint p4 = new DPoint(ltiCur.pxFromLeft + tnCur.TreeWidth / 2, ltiCur.pxFromTop + 5); lstcpt.Add(p4); _lsttcn.Add(new TreeConnection(tn, tnCur, lstcpt)); } } }
private void LayoutInteriorNode(ITreeNode tnRoot, int iLayer) { ITreeNode tnLast = null; TreeNodeGroup tng = GetChildren(tnRoot); ITreeNode itn = tng[0]; LayeredTreeInfo ltiThis; LayoutAllOurChildren(iLayer, tnLast, tng); // This width doesn't account for the parent node's width... ltiThis = new LayeredTreeInfo(CalculateWidthFromInterChildDistances(tnRoot), tnRoot); tnRoot.PrivateNodeInfo = ltiThis; // ...so that this centering may place the parent node negatively while the "width" is the width of // all the child nodes. CenterOverChildren(tnRoot, ltiThis); DetermineParentRelativePositionsOfChildren(tnRoot); CalculateBoundaryLists(tnRoot); }