Sri
Sri

Reputation: 41

Open all Children at once under a parent on click in D3 Js Vertical Tree

I am trying to open all the children under a parent when I click on the parent

After clicking on 3rd parent it should open all the left and right children at once and if all children are in open when I click on parent it should close all. In order to get left and right I made all the children under another in nested JSON so I was able to get that left and right below is the code, I am using in d3js vertical tree

if (d.children) {
                    _callerNode = null;
                    _callerMode = 0; // Collapse
                    d._children = d.children;
                    d.children = null;
                } else {
                    _callerNode = null;
                    _callerMode = 1; // Expand
                    if (d.parent.children && d.IC==="Yes") {
                      expand(d)
                    }
                    else{
                      d.children = d._children;
                      d._children = null;
                    }
                }
                update(d);
            });
        } else {
            if (d.children) {
                _callerNode = d;
                _callerMode = 0; // Collapse
                d._children = d.children;
                d.children = null;
            } else {
                _callerNode = null;
                _callerMode = 1; // Expand
                if (d.parent.children && d.IC==="Yes") {
                  expand(d)
                }
                else {
                  d.children = d._children;
                  d._children = null;
                }
            }
            update(d);
        }

when I click on parent it should automatically open left right children There might be a chance I get more children left and right for parent 2 as well later

any help would be appreciated Thanks in advance for all the help

Upvotes: 1

Views: 382

Answers (1)

i alarmed alien
i alarmed alien

Reputation: 9520

You can use a similar principle to the collapse function that you call when you initiate the chart, but this one will expand all the nodes instead. Here's the appropriate expand function (I've inserted into the code just below the collapse function):

        expand = function(d) {
            if (d._children) {
                d.children = d._children;
                d.children.forEach(expand);
                d._children = null;
            }
        },

And then you just need to call it at the appropriate time, which is during your nodeclick function:

                if (d.children) {
                    _callerNode = d;
                    _callerMode = 0; // Collapse
                    d._children = d.children;
                    d.children = null;
                } else {
                    _callerNode = null;
                    _callerMode = 1; // Expand
                    // INSERT HERE!
                    // if the node depth is 2 or more, call the `expand` function
                    if ( d.depth >= 2 ) {
                      expand(d)
                    }
                    // otherwise, just do the standard node expansion
                    else {
                      d.children = d._children;
                      d._children = null;
                    }
                }

By the way, you have two very similar bits of code within a couple of lines of each other:

                    if (d.children) {
                        _callerNode = null;
                        _callerMode = 0; // Collapse
                        d._children = d.children;
                        //d._children.forEach(collapse);
                        d.children = null;
                    } else {
                        _callerNode = null;
                        _callerMode = 1; // Expand
                        if ( d.depth >= 2 ) {
                          expand(d)
                        }
                        else {
                          d.children = d._children;
                          d._children = null;
                        }
                    }
                    update(d);
                });
            } else {
                if (d.children) {
                    _callerNode = d;
                    _callerMode = 0; // Collapse
                    d._children = d.children;
                    d.children = null;
                } else {
                    _callerNode = null;
                    _callerMode = 1; // Expand
                    if ( d.depth >= 2 ) {
                      expand(d)
                    }
                    else {
                      d.children = d._children;
                      d._children = null;
                    }
                }
                update(d);
            }

You could think about refactoring this so that you don't have this repeated code - e.g. make a new function:

function expandCollapse(d, caller) {
    if (d.children) {
      _callerNode = caller;
      _callerMode = 0; // Collapse
      d._children = d.children;
      d.children = null;
    } else {
      _callerNode = null;
      _callerMode = 1; // Expand
      if ( d.depth >= 2 ) {
        expand(d)
      }
      else {
        d.children = d._children;
        d._children = null;
      }
    }
    update(d);
}

and then replace the existing code with expandCollapse(d, null) or expandCollapse(d, d).

Upvotes: 1

Related Questions