【问题标题】:Nodes overlapping while drawing a binary tree in canvas在画布中绘制二叉树时节点重叠
【发布时间】:2015-02-01 23:31:54
【问题描述】:

我正在尝试在画布上绘制二叉树。从服务器端发送表单数据。数据是:要插入树的文本,x轴上的位置,y轴上的位置。

当我说“x轴和y轴位置”时,我指的是二叉树中节点的排列方式,我会尽量用一个图解的例子来解释清楚:

                (0,0)
                /   \
          (-1,1)     (1,1)
          /    \     /   \
      (-2,2) (0,2) (0,2) (2,2)

这是:根在位置(0,0),左孩子在位置(-1,1)(深度增加,但宽度减少。),右孩子(1,1)等等。问题是在某个位置,不同父节点的两个节点会重合,其中一个节点会重叠。

我以这种方式拥有组件,因为在服务器端,对是在遍历二叉树时形成的(当我走进当前节点的子节点时,我将 1 与对的第二个组件相加;如果孩子在左边,那么我在第一个分量中剩余 1,但如果孩子在右边,我将 1 与第一个分量相加。

我的画布代码是:

                var TreeDrawer = (function(){
                    var _depth = 20
                      , _breadth = 15
                      , _rootX = width/2
                      , _rootY = 50
                      ;

                    var _context = getContext("2d");

                    _context.textAlign = "center";
                    _context.fillStyle = "black";
                    _context.font = "16px Verdana";


                    var _getX = function (x) {
                        return _rootX + (x * 80);
                    }

                    var _getY = function(y) {
                        return _rootY + (y * 50);
                    }

                    var _drawText = function(partialText, x, y) {

                        console.log(x, y);
                        _context.fillText(partialText, x, y);
                    }

                    return {
                        drawRoot: function (value) {
                            _drawText(value, _rootX, _rootY);
                        },

                        drawNode: function(value, x, y) {
                            _drawText(value, _getX(x), _getY(y));
                        }
                    }
                });

                var _tree = new TreeDrawer();
                _tree.drawRoot("Raíz");
                _tree.drawNode("Nodo", -1, 1);
                _tree.drawNode("Nodo", 1, 1);

                _tree.drawNode("Nodo", -2, 2);
                _tree.drawNode("Nodo", 0, 2);

                _tree.drawNode("Nodo", 2, 2);
                _tree.drawNode("Nodo", 0, 2);

所以,问题是:我能做些什么来解决这个问题?即绘制树而不重叠。

PS:

  • 我不想要库,因为我的项目是用 C++(使用 Qt)编写的,所以库将无法工作。
  • 在本例中,我显式地插入节点,即,我调用了两次_tree.drawNode ("Node", 0,2) 方法,很明显节点将重叠。我的意思是,我想在这些情况下制定一个内部方法来调整我的树(我不知道哪个是来自服务器端的输入)。
  • 如果有帮助,我可以先验地确定这棵树会有多少叶子。

【问题讨论】:

  • 您可以使用行的索引位置,而不是使用相对位置 (0, 0) 的左子项 (-1, 1)。例如,具有两个节点的行将是 (0, 1) --- (1, 1),然后四个节点的下一行将是 (0, 2) --- (1, 2) --- (2, 2) --- (3, 2)。这样,您就可以确保唯一的节点位置。

标签: javascript html canvas tree


【解决方案1】:

这有点hacky,但这似乎有效。然而,节点可能会部分重叠,具体取决于stepX 的大小和每行的节点数量。

不像你解释的那样使用相对定位。

            (0,0)
            /   \
       (-1,1)     (1,1)
       /    \     /   \
   (-2,2) (0,2) (0,2) (2,2)

我用的是绝对定位,如下:

            (0,0)
            /   \
       (0,1)     (1,1)
       /    \     /   \
   (0,2) (1,2) (2,2) (3,2)

var TreeDrawer = (function(){
    var _depth = 15
    , _breadth = 16
    , _rootX = canvas.width/2
    , _rootY = 59
    ;

    _context.textAlign = "center";
    _context.fillStyle = "black";
    _context.font = "16px Verdana";

    var _drawText = function(partialText, x, y) {
        _context.fillText(partialText, x, y);
    }

    return {
        drawRoot: function (value) {
            _drawText(value, _rootX, _rootY);
        },
        drawNode: function(value, row, position) {
            var stepX = 56;
            var stepY = 32;
            // subtract half from x for symmetry
            var half = (Math.pow(2, row) * stepX) / 2;
            var x = _rootX + (stepX / 2) + (stepX * position) - half;
            var y = _rootY + (stepY * row);
            _drawText(value, x, y);
        }
    }
});

var _tree = TreeDrawer();
var root = "Raiz";
var rows = [
    new Array(2).fill("nodo"), 
    new Array(4).fill("nodo"), 
    new Array(8).fill("nodo"),
    new Array(16).fill("nodo")];

_tree.drawRoot(root);
rows.forEach(function (row, rowIndex) {
    row.forEach(function (node, index) {
        // the root is row zero, so I add 1 for the normal nodes.
        _tree.drawNode(node, rowIndex + 1, index);
    });
});

编辑:我刚才看到这并没有达到拆分的效果,很难继续拆分很多行,文本空间每次减半。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2018-11-25
    • 2012-04-15
    相关资源
    最近更新 更多