javascript - 将节点动态添加到 D3 树布局请求(切换时)

标签 javascript d3.js

简介: 我正在尝试扩展 d3 - 树布局。

我正在尝试通过 ajax/setTimeout 在切换事件上添加新节点。

我做了什么: 我成功同步添加新节点: https://jsfiddle.net/xfj875vc/1/

我只更改了代码的两部分:

更改 1(添加了向没有子节点的节点添加新子节点的方法): 函数 addNewNode(d, 项目) { d._children = d._children || []; d._children = d._children.concat(item); }

更改 2(单击切换时调用 addNewNode,我仅为没有子节点的节点添加新节点):

 var nodeEnter = node.enter().append("svg:g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .on("click", function(d) {

            // change start
            var newItem;

            if (!d._children || d._children.length === 0) {
                newItem = [
                    {
                        "name": "i am new",
                        "children": [
                            { "name": "i am new child 1"},
                            { "name": "i am new child 2"}
                        ]
                    }
                ];
                addNewNode(d, newItem);
            }
            // change end

            toggle(d); update(d);
        });

2个问题:

  1. 当添加带有子节点的节点时,它会显示它并展开所有内容,子节点应该最小化。
  2. 如果我尝试将代码包装在 setTimeout 中,它会添加子项。但是,过渡和动画无法正常工作,d3 还展开了嵌套子项,您可以在这里看到它:

https://jsfiddle.net/xfj875vc/3/ (尝试点击更多一次)

谢谢

最佳答案

首先是你的方法

   function addNewNode(d, item) {
        d._children = d._children || [];
        d._children = d._children.concat(item);
    }
  • 我们必须明白,d._children 在折叠时具有值,并且因此 d.children 将是未定义的。 当节点扩展时反之亦然。因此我不确定您在上面的代码中想要做什么。

  • 其次,这将放置一个 d._children.concat(item);数组内的数组。这不是预期的,因此我对下面的 for 循环执行相同的操作。

应该是:

function addNewNode(d, item) {
      item.forEach(function(i){
        if(d._children)
            d._children.push(i)//will add child to the closed node      
        else 
            d.children.push(i)//will add child to expanded node.
      })
}

接下来,我将在数据中保留一个标志,以指示它不需要通过点击时的 ajax 加载。

{
 "name": "flare",
 "loaded" : true, //so this node flare will not be loaded on click via ajax
 "children": [
  {
   "name": "analytics",
   "loaded" : true,//so this node analytics will not be loaded on click via ajax
   "children": [...

最后,在我的点击函数中,只有当该标志未定义时,我才会加载。

.on("click", function(d) {

  if (d.loaded === undefined) {\\do ajax
    setTimeout(function() {
      var newItem;

      newItem = [{
        "name": "i am new",
        "children": [{
          "name": "i am new child 1"
        }, {
          "name": "i am new child 2"
        }]
      }];
      addNewNode(d, newItem);
      d.loaded = true;//mark it as loaded so it doesn't load next time
      console.log("called", d)

      toggle(d);
      update(d);

    }, 1000)
  } else {//already loaded so dont do ajax
      toggle(d);
      update(d);
  }
});

工作代码here

如果您希望折叠加载的节点。

您创建一个新节点,如下所示:

      newItem = [{
        "name": "i am new",
        "children": [{
          "name": "i am new child 1"
        }, {
          "name": "i am new child 2"
        }]
      }];

而不是这样做

      newItem = [{
        "name": "i am new",
        "_children": [{ //note its changed to _children to show collapsed
          "name": "i am new child 1"
        }, {
          "name": "i am new child 2"
        }]
      }];

工作代码here

希望这有帮助!

关于javascript - 将节点动态添加到 D3 树布局请求(切换时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34543373/

相关文章:

javascript - 使用具有相同键的 JSON 数据(在 D3 中)

javascript - 我总是得到最后一个 onload 函数,但我需要两者,是否有其他替代选项而不删除任何 window.onload 事件?

javascript - 结合使用 .toUpperCase() 和 .includes()

javascript - Hyperapp 中输入元素输入事件的去抖 Action

javascript - React 中的类变量与 ES6

javascript - D3 Force Layout - 子图聚类特性

javascript - 不卡住的 GulpJs 错误处理

javascript - 如果元素被删除,我是否必须从 DOM 中清除事件?

javascript - 取消 D3 中元素的分组

javascript - NVD3 线图工具提示不跟随鼠标