Пример #1
0
        public DrawingData DrawRadial()
        {
            DrawingData data = InitDrawingData();

            TreeBorders borders = DrawSubtree(rootId, data, data.Height[rootId] + 1);

            double maxWidth = 0.0;
            double left     = 0.0;
            double right    = 0.0;

            for (int i = 0; i <= data.Height[rootId]; i++)
            {
                left  += borders[i, BorderSide.Left];
                right += borders[i, BorderSide.Right];

                maxWidth = Math.Max(maxWidth, right - left);
            }

            maxWidth += 1.0; // 1 unit space.
            double scale = 360.0 / maxWidth;

            CalculateAbsuluteValues(data, scale, true);

            return(data);
        }
Пример #2
0
        private TreeBorders DrawSubtree(int vId, DrawingData data, int borderCap)
        {
            TreeBorders borders;

            if (data.Height[vId] == 0)
            {
                borders = new TreeBorders(borderCap);
                borders.Add(0.0, 0.0);
                return(borders);
            }

            int maxHeigtIndex = -1;
            int maxHeigtId    = -1;
            int maxHeigt      = -1;

            int pId = forest.GetParent(vId);

            int[] neighs = forest[vId];

            for (int i = 0; i < neighs.Length; i++)
            {
                int nId = neighs[i];
                if (nId == pId)
                {
                    continue;
                }

                if (data.Height[nId] > maxHeigt)
                {
                    maxHeigtIndex = i;
                    maxHeigtId    = nId;
                    maxHeigt      = data.Height[nId];
                }
            }

            // Draw largest subtree with full capacity for borders.
            borders = DrawSubtree(maxHeigtId, data, borderCap);

            // Draw trees left of largest subtree.
            for (int i = maxHeigtIndex - 1; i >= 0; i--)
            {
                int leftId     = neighs[i];
                int leftHeight = data.Height[leftId];
                int hDif       = maxHeigt - leftHeight;

                if (leftId == pId)
                {
                    continue;
                }

                TreeBorders leftBorders = DrawSubtree(leftId, data, leftHeight + 1);

                // The distance the left tree is moved.
                // Because it will move to the left, shiftDist will become negative.
                double shiftDist = 0.0;

                double totalLeftShift = 0.0;
                double totalMaxShift  = 0.0;

                for (int h = 0; h <= leftHeight; h++)
                {
                    totalLeftShift += leftBorders[h, BorderSide.Right];
                    totalMaxShift  += borders[h, BorderSide.Left];

                    double dist = totalMaxShift - totalLeftShift;
                    shiftDist = Math.Min(shiftDist, dist);
                }

                // Have 1 unit space between both trees.
                shiftDist -= 1.0;

                // Move tree.
                data.XShift[leftId]         = shiftDist;
                borders[0, BorderSide.Left] = shiftDist;
                totalLeftShift = shiftDist;

                for (int h = 1; h <= leftHeight; h++)
                {
                    double localShift = leftBorders[h, BorderSide.Left];
                    totalLeftShift += localShift;
                    borders[h, BorderSide.Left] = localShift;
                }

                if (leftHeight < maxHeigt)
                {
                    totalMaxShift += borders[leftHeight + 1, BorderSide.Left];
                    borders[leftHeight + 1, BorderSide.Left] = totalMaxShift - totalLeftShift;
                }
            }


            // Draw trees right of largest subtree.
            for (int i = maxHeigtIndex + 1; i < neighs.Length; i++)
            {
                int rightId     = neighs[i];
                int rightHeight = data.Height[rightId];
                int hDif        = maxHeigt - rightHeight;

                if (rightId == pId)
                {
                    continue;
                }

                TreeBorders rightBorders = DrawSubtree(rightId, data, rightHeight + 1);

                // The distance the right tree is moved.
                // Because it will move to the right, shiftDist will become positive.
                double shiftDist = 0.0;

                double totalRightShift = 0.0;
                double totalMaxShift   = 0.0;

                for (int h = 0; h <= rightHeight; h++)
                {
                    totalRightShift += rightBorders[h, BorderSide.Left];
                    totalMaxShift   += borders[h, BorderSide.Right];

                    double dist = totalMaxShift - totalRightShift;
                    shiftDist = Math.Max(shiftDist, dist);
                }

                // Have 1 unit space between both trees.
                shiftDist += 1.0;

                // Move tree.
                data.XShift[rightId]         = shiftDist;
                borders[0, BorderSide.Right] = shiftDist;
                totalRightShift = shiftDist;

                for (int h = 1; h <= rightHeight; h++)
                {
                    double localShift = rightBorders[h, BorderSide.Right];
                    totalRightShift += localShift;
                    borders[h, BorderSide.Right] = localShift;
                }

                if (rightHeight < maxHeigt)
                {
                    totalMaxShift += borders[rightHeight + 1, BorderSide.Right];
                    borders[rightHeight + 1, BorderSide.Right] = totalMaxShift - totalRightShift;
                }
            }

            // Move trees such that center is 0.
            double xShift = -(borders[0, BorderSide.Right] + borders[0, BorderSide.Left]) / 2.0;

            borders[0, BorderSide.Right] += xShift;
            borders[0, BorderSide.Left]  += xShift;

            for (int i = 0; i < neighs.Length; i++)
            {
                int nId = neighs[i];
                if (nId == pId)
                {
                    continue;
                }

                data.XShift[nId] += xShift;
            }

            borders.Add(0.0, 0.0);
            return(borders);
        }