0
votes

I have d3 collapsable tree. I have external button that controls expansion and collapsing of tree. I can expand all, collapsable all. And also, I can expand one level at a time. I am having trouble collapsing one level at a time.

For any one without prior understanding of d3. If node is expanded then d.children is not empty & d.children is empty and if node is collapsed d.children is not empty and d.children is empty.

Here is my logic to expand one level :

private expandNodeOneLevel(d) {
    var children = (d.children) ? d.children : d._children;
    if (!d.children) {
       if (children) {
           d.children = d._children;
           d._children = null;
       }
       return;
     }
    if (children) {
       children.forEach((node) => this.expandNodeOneLevel(node));
     }
}



 public expandOneLevelNodes() {
    this.expandNodeOneLevel(this.root);
    this.update(this.root);
  }

Here is my logic to collapse one level at a time, which is wrong as it is collapsing all the tree nodes. I am having trouble to break the recursion.

private collpaseOneLevelNodes = (d) => {
    var children = (d.children) ? d.children : d._children;
    if (!children) {
      return;
    }
    children.forEach((node) => {
      this.collpaseOneLevelNodes(node);
    });
    if (d.children) {
        d._children = d.children;
        d.children = null;
    }
    return;
  }



 public collapseOneLevel() {
    this.collpaseOneLevelNodes(this.root);
    this.update(this.root);
  }

I would really appreciate if some one points out where my mistake is or any other better approach.

1

1 Answers

0
votes

Figured it. Didn't notice d3 provides parent info.

 private collpaseOneLevelNodes = (d) => {
var children = (d.children) ? d.children : d._children;
if (!children || !d.children) {
  if (!d.parent._children) {
    d.parent._children = d.parent.children;
    d.parent.children = null;
  }
  return;
}
if (d.children) {
  children.forEach((node) => {
    this.collpaseOneLevelNodes(node);
  });
}

}

 public collapseOneLevel() {
    this.collpaseOneLevelNodes(this.root);
    this.update(this.root);
  }