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);
            }
        }
Esempio n. 4
0
        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);
        }