Beispiel #1
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++;
            foreach (ITreeNode tnCur in GetChildren(tn))
            {
                List <DPoint>   lstcpt = new List <DPoint>();
                LayeredTreeInfo ltiCur = Info(tnCur);
                lstcpt.Add(dptOrigin);
                DetermineFinalPositions(tnCur, iLayer, pxFromTop + pxRowHeight + _pxBufferVertical, lti.pxFromLeft);
                lstcpt.Add(new DPoint(ltiCur.pxFromLeft + tnCur.TreeWidth / 2, ltiCur.pxFromTop));
                _lsttcn.Add(new TreeConnection(tn, tnCur, lstcpt));
            }
        }
Beispiel #2
0
        private void CalculateBoundaryLists(ITreeNode tnRoot)
        {
            LayeredTreeInfo lti = Info(tnRoot);

            lti.lstPosLeftBoundaryRelativeToRoot.Add(0.0);
            lti.lstPosRightBoundaryRelativeToRoot.Add(tnRoot.TreeWidth);
            DetermineBoundary(tnRoot.TreeChildren, true /* fLeft */, lti.lstPosLeftBoundaryRelativeToRoot);
            DetermineBoundary(tnRoot.TreeChildren.Reverse(), false /* fLeft */, lti.lstPosRightBoundaryRelativeToRoot);
        }
Beispiel #3
0
        private static void LayoutLeafNode(ITreeNode tnRoot)
        {
            double          width = tnRoot.TreeWidth;
            LayeredTreeInfo lti   = new LayeredTreeInfo(width, tnRoot);

            lti.lstPosLeftBoundaryRelativeToRoot.Add(0);
            lti.lstPosRightBoundaryRelativeToRoot.Add(width);
            tnRoot.PrivateNodeInfo = lti;
        }
Beispiel #4
0
        private void DetermineParentRelativePositionsOfChildren(ITreeNode tnRoot)
        {
            LayeredTreeInfo ltiRoot = Info(tnRoot);

            foreach (ITreeNode tn in GetChildren(tnRoot))
            {
                LayeredTreeInfo ltiCur = Info(tn);
                ltiCur.pxLeftPosRelativeToParent = ltiCur.pxLeftPosRelativeToBoundingBox - ltiRoot.pxLeftPosRelativeToBoundingBox;
            }
        }
Beispiel #5
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);
                //lstcpt.Add(new DPoint(ltiCur.pxFromLeft + tnCur.TreeWidth / 2, ltiCur.pxFromTop));
                //_lsttcn.Add(new TreeConnection(tn, tnCur, lstcpt));

                //横竖线连接
                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));
                }
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        private double PxCalculateNewPos(
            LayeredTreeInfo lti,
            List <double> lstLeftToBB,
            List <int> lstitnResponsible,
            out int itnResponsible,
            out int iLayerRet)
        {
            //double pxOffsetToBB = lstLeftToBB[0];
            int    cLayers            = Math.Min(lti.lstPosLeftBoundaryRelativeToRoot.Count, lstLeftToBB.Count);
            double pxRootPosRightmost = 0.0;

            iLayerRet = 0;

            using (IEnumerator <double> enRight = lti.lstPosLeftBoundaryRelativeToRoot.GetEnumerator(),
                   enLeft = lstLeftToBB.GetEnumerator())
                using (IEnumerator <int> enResponsible = lstitnResponsible.GetEnumerator())
                {
                    itnResponsible = -1;

                    enRight.MoveNext();
                    enLeft.MoveNext();
                    enResponsible.MoveNext();
                    for (int iLayer = 0; iLayer < cLayers; iLayer++)
                    {
                        double pxLeftBorderFromBB    = enLeft.Current;
                        double pxRightBorderFromRoot = enRight.Current;
                        double pxRightRootBasedOnThisLevel;
                        int    itnResponsibleCur = enResponsible.Current;

                        enLeft.MoveNext();
                        enRight.MoveNext();
                        enResponsible.MoveNext();

                        pxRightRootBasedOnThisLevel = pxLeftBorderFromBB - pxRightBorderFromRoot;
                        if (pxRightRootBasedOnThisLevel > pxRootPosRightmost)
                        {
                            iLayerRet          = iLayer;
                            pxRootPosRightmost = pxRightRootBasedOnThisLevel;
                            itnResponsible     = itnResponsibleCur;
                        }
                    }
                }

            return(pxRootPosRightmost);
        }
Beispiel #9
0
        private void LayoutInteriorNode(ITreeNode tnRoot, int iLayer)
        {
            ITreeNode       tnLast = null;
            TreeNodeGroup   tng    = GetChildren(tnRoot);
            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);
        }
Beispiel #10
0
        private static void CenterOverChildren(ITreeNode tnRoot, LayeredTreeInfo ltiThis)
        {
            // We should be centered between  the connection points of our children...
            ITreeNode tnLeftMost   = tnRoot.TreeChildren.LeftMost();
            double    pxLeftChild  = Info(tnLeftMost).pxLeftPosRelativeToBoundingBox + tnLeftMost.TreeWidth / 2;
            ITreeNode tnRightMost  = tnRoot.TreeChildren.RightMost();
            double    pxRightChild = Info(tnRightMost).pxLeftPosRelativeToBoundingBox + tnRightMost.TreeWidth / 2;

            ltiThis.pxLeftPosRelativeToBoundingBox = (pxLeftChild + pxRightChild - tnRoot.TreeWidth) / 2;

            // If the m_RootNode node was wider than the subtree, then we'll have a negative position for it.  We need
            // to readjust things so that the left of the m_RootNode node represents the left of the bounding box and
            // the child distances to the Bounding box need to be adjusted accordingly.
            if (ltiThis.pxLeftPosRelativeToBoundingBox < 0)
            {
                foreach (ITreeNode tnChildCur in tnRoot.TreeChildren)
                {
                    Info(tnChildCur).pxLeftPosRelativeToBoundingBox -= ltiThis.pxLeftPosRelativeToBoundingBox;
                }
                ltiThis.pxLeftPosRelativeToBoundingBox = 0;
            }
        }
Beispiel #11
0
        private void DetermineBoundary(IEnumerable <ITreeNode> entn, bool fLeft, List <double> lstPos)
        {
            int           cLayersDeep = 1;
            List <double> lstPosCur;

            foreach (ITreeNode tnChild in entn)
            {
                LayeredTreeInfo ltiChild = Info(tnChild);

                if (fLeft)
                {
                    lstPosCur = ltiChild.lstPosLeftBoundaryRelativeToRoot;
                }
                else
                {
                    lstPosCur = ltiChild.lstPosRightBoundaryRelativeToRoot;
                }

                if (lstPosCur.Count >= lstPos.Count)
                {
                    using (IEnumerator <double> enPosCur = lstPosCur.GetEnumerator())
                    {
                        for (int i = 0; i < cLayersDeep - 1; i++)
                        {
                            enPosCur.MoveNext();
                        }

                        while (enPosCur.MoveNext())
                        {
                            lstPos.Add(enPosCur.Current + ltiChild.pxLeftPosRelativeToParent);
                            cLayersDeep++;
                        }
                    }
                }
            }
        }