javascript - 如何在客户端生成父/子嵌套?

标签 javascript recursion tree d3.js

我在这里和其他地方搜索了无数父/子数组/对象/任何问题,但未能解决我的问题。我知道这有点长,但我想确保我为你们提供了足够的信息。

这是我想做的:

  1. 我有多个 <div> - 通过 php 从我的数据库中生成的具有父/子关系的页面上的项目
  2. 我想将这些项目用作 D3.js 树状图(节点链接 TreeMap http://mbostock.github.com/d3/ex/cluster.html)的数据源
  3. 我用左/右嵌套设置值和 parentID 值存储它们,所以我可以将 ID、parentID、rgt、lft 和 depth 属性添加到 <div>元素,所以我应该准备好在客户端生成父/子关系所需的一切
  4. 由于种种原因,我没有在服务器端创建一个JSON文件作为数据源,而是需要根据#3中的属性在客户端创建
  5. 我很难让各种建议的 javascript 函数起作用,我发现的所有 D3 示例都使用预先存在的 JSON 文件或生成的基于数学的文件,而不是页面上已有元素的属性

这是一个已经对我有用的 D3 树状图示例,但它不是动态生成的:

var tree3 = 
{"sid": "1", "children": [
    {"sid": "2", "children": [
        {"sid": "5", "children": [
            {"sid": "75"},
            {"sid": "85", "children": [
                {"sid": "87"}, ...

为了让您了解这些属性在 DOM 中的位置,我最初尝试了以下方法,但当然它不会生成任何层次结构:

function tree() {
    var tree=[];
    $("article").each(function(){
        tree.push({
            sid:$(this).attr("sid"), 
            l:$(this).attr("l"), 
            r:$(this).attr("r"),
            pid:$(this).attr("pid")
        });
    });
    return tree;
}

我一直在弄乱下面的变体以获得嵌套数组,但没有成功:

function tree2() {
   $("article").(function(d) {
       return d.parent().attr("pid") === 0;
}, function(parent, child) {
    return parent.attr("pid") === child.parent().attr("sid");
}).toArray();
}

因此,我正在疯狂地尝试创建正确嵌套的 javascript 数组,但我突然意识到我可能不需要这样做,D3 的数据选择器和方法就足够了。你能帮我写代码吗:

  1. 提取所需的属性以在 D3 函数中生成父/子关系(“sid”是标识符),或者,如果这不可能,
  2. 在 javascript 中创建所需的数组或类数组对象以供 D3 使用(仍然使用“sid”作为标识符)。

提前致谢。

最佳答案

你需要递归!基本上,诀窍是在进行时传递当前父级,这会更改上下文并允许您沿着树向下走。

更新:Working fiddle .

假设您的 HTML 结构是这样的:

<div sid="1" pid="">
    <div sid="1.1" pid="1">
        <div sid="1.1.1" pid="1.1">
        </div>
    </div>
</div>

你可以这样做:

var _json = {};

function addTreeNode(div, parentObj) {

    var childObj = {
        sid: $(div).attr("sid"),
        pid: $(div).attr("pid")
    }

    // add this to it's parent in the JSON hierarchy
    if (!parentObj.children) parentObj.children = [];
    parentObj.children.push(childObj);

    // keep adding for all children div's
    $(div).find("div").each(function() {
        addTreeNode(this, childObj);
    });
}

// start at the roots, it will magically work it's way out to the leaves
$("body > div").each(function(){
    addTreeNode(this, _json);
});

console.log(_json);

请注意,如果您的树足够大,导致堆栈溢出,尤其是在 IE 中。在这种情况下,您需要将其切换为 from recursion to iteration .不过,它并不那么漂亮。

关于javascript - 如何在客户端生成父/子嵌套?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9674651/

相关文章:

java - 二叉搜索树递归不起作用

c++ - 有效地从 n-ary 树中删除节点列表

javascript - 使用键值获取对 JSON/JS 对象中任意(深层)嵌套节点的引用

python - 程序不显示返回值

javascript - Material UI 中的 sx Prop 和 makeStyles 函数之间是否存在性能差异?

javascript - JavaScript 日期函数的 IE 字符集编码问题

sql - Postgresql 复制树表内的数据

tree - 哪些应用程序使用 R-Trees?

javascript - 在 GoJS 节点或 graphObject 中有 "visible overflow"

javascript - 传递参数时 AJAX setTimeout 不起作用