Развернуть и свернуть свернутое дерево с отступом D3 глобально в Angular с помощью кнопок - PullRequest
0 голосов
/ 16 ноября 2018

Layout

Демонстрация StackBlitz

У меня уже есть запущенное дерево, где вся моя логика написана в ngAfterViewInit() Hook.

Код работает хорошо.Однако я хочу добавить кнопки Collapse All и Expand 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;
      }
    }
  }
}

Ссылки

Развернуть все / Свернуть все дерево d3 предоставляет некоторую логику, но требует от меня использования root переменной, которая на самом деле является локальной только для ngAfterViewInit() Hook и может быть недоступна для других методов класса.

Как мне этого добиться?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...