使用按钮在Angular中全局展开和折叠D3可折叠的缩进树

时间:2018-11-16 16:10:08

标签: angular d3.js

Layout

StackBlitz演示

我已经启动并运行了Tree,在ngAfterViewInit() Hook中编写了所有逻辑。

代码运行良好。但是,我希望全局添加Collapse AllExpand All按钮,以便用户可以相应地使用它们,而不必费心地单击所有节点来折叠或展开整个树。

不幸的是,我没有在组件内公开的类方法或变量。这将方法调用限制为按钮:

 <button (click)="expandAll()"></button> <!-- expandAll() has nothing to trigger as a parameter-->

hello.component.ts

export class HelloComponent  {
  @Input() name: string;

  ngAfterViewInit(): void {
    let margin = {top: 30, right: 10, bottom: 30, left: 20};
    let width = 960;
    let barHeight = 20;
    let barWidth = (width - margin.left - margin.right) * 0.8;

    let i = 0, duration = 400, root;
    let diagonal = d3.linkHorizontal()
        .x((d) => { return d.y; })
        .y((d) => { return d.x; });

    let svg = d3.select(".tree").append("svg")
      .attr("width", width) //+ margin.left + margin.right)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


    root = d3.hierarchy(flares);
    root.x0 = 0;
    root.y0 = 0;
    moveChildren(root);
    update(root);

    function update(source) {

      // Compute the flattened node list.
      let nodes = root.descendants();

      let height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);

      d3.select("svg").transition()
          .duration(duration)
          .attr("height", height);

      d3.select(self.frameElement).transition()
          .duration(duration)
          .style("height", height + "px");

      // Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
      let index = -1;
      root.eachBefore(function(n) {
        n.x = ++index * barHeight;
        n.y = n.depth * 20;
      });

      // Update the nodes…
      let node = svg.selectAll(".node")
        .data(nodes, function(d) { return d.id || (d.id = ++i); });

      let nodeEnter = node.enter().append("g")
          .attr("class", "node")
          .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
          .style("opacity", 0);

      // Enter any new nodes at the parent's previous position.
      nodeEnter.append("rect")
          .attr("y", -barHeight / 2)
          .attr("height", barHeight)
          .attr("width", barWidth)
          .style("fill", color)
          .on("click", click);

      nodeEnter.append("text")
          .attr("dy", 3.5)
          .attr("dx", 5.5)
          .text(function(d) { return d.data.name; });

      // Transition nodes to their new position.
      nodeEnter.transition()
          .duration(duration)
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
          .style("opacity", 1);

      node.transition()
          .duration(duration)
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
          .style("opacity", 1)
        .select("rect")
          .style("fill", color);

      // Transition exiting nodes to the parent's new position.
      node.exit().transition()
          .duration(duration)
          .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
          .style("opacity", 0)
          .remove();

      // Stash the old positions for transition.
      root.each(function(d) {
        d.x0 = d.x;
        d.y0 = d.y;
      });
    }

  // Toggle children on click.
    function click(d) {
      if (d.children) {
        d._children = d.children;
        d.children = null;
      } else {
        d.children = d._children;
        d._children = null;
      }
      update(d);
    }

    function color(d) {
      return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
    }

    function moveChildren(node) { // https://stackoverflow.com/questions/19423396/d3-js-how-to-make-all-the-nodes-collapsed-in-collapsible-indented-tree
    if(node.children) {
        node.children.forEach(function(c) { moveChildren(c); });
        node._children = node.children;
        node.children = null;
      }
    }
  }
}

参考

Expand All/Collapse All d3-tree提供了一些逻辑,但是它要求我使用root变量,该变量实际上仅是ngAfterViewInit() Hook的局部变量,其他类方法可能无法访问。

我该如何实现?

0 个答案:

没有答案