N叉树节点绘制

一、接地坐标计算思路

由于在绘制N叉树的时候要每一个节点不能重叠,因此不能从顶节点开始绘制,只能先绘制叶子节点,在根据叶子节点的坐标来求得父节点的位置;

1、绘制一个节点:在绘制一个节点的时候先遍历绘制所有的子节点,再通过计算求得该节点坐标并进行绘制;

2、在绘制叶子节点时要注意,由于可能各个叶子节点的深度不同,因此每一个叶子节点在深度方向上的值是不能重叠的(即X不能相同),因此在画每一个叶子节点的时候要记录该叶子节点的X值,后面的叶子节点必须在这个叶子节点的X的基础上加上间隔;这样叶子节点X就不会重复,最后每一个节点就不会重复;

3、各个节点的Y值可以通过间隔与节点升读求得;

 

 

下面代码知识求得节点坐标方法;

N叉树节点定义

 public class NXNode
    {
        public int X;
        public int Y;
        public List<NXNode> Children = new List<NXNode>();

        int _depth = -1;
        public int Depth
        {
            get
            {
                return _depth;
            }
        }
        public int ID { get; private set; }

        NXNode _parentNode = null;
        public NXNode ParentNode
        {
            get
            {
                return _parentNode;
            }
        }
        /// <summary>
        /// 构件一个N叉树的节点
        /// </summary>
        /// <param name="id"></param>
        public NXNode(int id)
        {
            this.ID = id;
        }

        /// <summary>
        /// 添加一个节点
        /// </summary>
        /// <param name="node"></param>
        public void AddChildren(NXNode node)
        {
            if (node != null)
            {
                Children.Add(node);
                node._parentNode = this;
                node._depth = this.Depth + 1;
                UpdataChildrenDeth(node);
            }
        }
        /// <summary>
        /// 移除一个节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool RemoveChildren(NXNode node)
        {
            if (node != null)
            {
                node._parentNode = null;
                node._depth = -1;
                UpdataChildrenDeth(node);
                return Children.Remove(node);
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 在添加和或者移除一个节点时候更新该节点子节点的深度值
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        bool UpdataChildrenDeth(NXNode node)
        {
            try
            {
                if (node.Children.Count > 0)
                {
                    foreach (NXNode item in node.Children)
                    {
                        item._depth = node.Depth + 1;
                        UpdataChildrenDeth(item);
                    }
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
下面是N叉树代码
   public class NXNodeTree
    {
        /// <summary>
        /// 节点间的宽度
        /// </summary>
        public static int NodeWSpacing = 10;
        /// <summary>
        /// 上下级节点的高度
        /// </summary>
        public static int NodeHSpacing = 10;
        /// <summary>
        /// Root 节点是虚拟的节点,在绘画的是时候不应该画出来
        /// </summary>
        public NXNode Root
        {
            get;
            private set;
        }
        public NXNodeTree(int maxNodeId)
        {
            NXNode rootNode = new NXNode(maxNodeId);
            this.Root = rootNode;
        }

        /// <summary>
        /// 用所给的PMapNode创建一棵NX树,这里的list的元素应该不能太多,要求nodeList进行排序
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        static public NXNodeTree CreatNXNodeTree(List<PMapNode> nodeList)
        {
            try
            {
                if (nodeList != null && nodeList.Count > 0)
                {
                    Dictionary<int, NXNode> dicNXNodes = new Dictionary<int, NXNode>();
                    int nodeParentID = nodeList[0].ParentID;
                    NXNodeTree nXNodeTree = new NXNodeTree(nodeParentID);
                    dicNXNodes.Add(nodeParentID, nXNodeTree.Root);

                    foreach (PMapNode item in nodeList)
                    {
                        NXNode node = new NXNode(item.ID);
                        if (dicNXNodes.ContainsKey(item.ParentID))
                        {
                            NXNode parentNode = dicNXNodes[item.ParentID];
                            parentNode.AddChildren(node);
                            dicNXNodes.Add(item.ID, node);
                        }
                        else
                        {

                        }
                    }
                    dicNXNodes.Clear();
                    return nXNodeTree;
                }
            }
            catch (Exception ex)
            {
                //TODO:记录错误
            }
            return null;
        }
        /// <summary>
        /// 计算树节点的坐标
        /// </summary>
        /// <param name="nXNodeTree"></param>
        public static void IniNXNodeTreeXY(NXNodeTree nXNodeTree)
        {
            if (nXNodeTree != null)
            {
                NXNode rootNode = nXNodeTree.Root;
                foreach (NXNode item in rootNode.Children)
                {
                    CalculateNXNodeXY(item);
                }
            }
        }
        /// <summary>
        /// 节点坐标的最小的X值
        /// </summary>
        static int drawMinX = 0;
        /// <summary>
        /// 如果需要绘制节点的时候对节点进行坐标计算
        /// </summary>
        /// <param name="node"></param>
        static void CalculateNXNodeXY(NXNode node)
        {
            if (node.Children.Count > 0)
            {
                int maxX = 0;
                foreach (NXNode childrenNode in node.Children)
                {
                    CalculateNXNodeXY(childrenNode);
                    maxX = childrenNode.X;
                }
                int minX = node.Children[0].X;
                node.X = (minX + maxX + 1) / 2;
                node.Y = node.Depth * NodeHSpacing;
            }
            else
            {
                drawMinX += NodeWSpacing;
                node.X = drawMinX;
                node.Y = node.Depth * NodeHSpacing;
            }
        }

    }
</pre><pre name="code" class="csharp">上下级关系定义类
</pre><pre name="code" class="csharp"> public class PMapNode
    {
        public int X;
        public int Y;
        public int ID { get; private set; }
        public PMapNode(int id, int parentID)
        {
            ID = id;
            ParentID = parentID;
        }
        public string Name { get; set; }
        public int ParentID { get; private set; }
        public int Generation { get; private set; }
    }



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值