简体   繁体   English

打字稿和 d3 版本 v3 中的可折叠树

[英]collapsible trees in typescript and d3 version v3

I am trying to create collapsible trees with d3 ( https://bl.ocks.org/mbostock/4339083 ) in Angular4 project using typescript.我正在尝试使用打字稿在 Angular4 项目中使用 d3 ( https://bl.ocks.org/mbostock/4339083 ) 创建可折叠树。 My trees is not getting generated for all nodes only last node is displaying.我的树没有为所有节点生成,只有最后一个节点显示。 Can someone help how to create d3 collapsible trees in typescript有人可以帮助如何在打字稿中创建 d3 可折叠树

There is some iteration or loop issues i guess all nodes are not iterated.有一些迭代或循环问题,我猜所有节点都没有迭代。

const data =
  {
    "name": "Top Level",
    "children": [
      {
        "name": "Level 2: A",
        "children": [
          { "name": "Son of A" },
          { "name": "Daughter of A" }
        ]
      },
      { "name": "Level 2: B" }
    ]
  };



export class ClusterChartComponent implements OnInit{

  //@ViewChild('container') private chartContainer: ElementRef;
  private margin: any = {top: 20, right: 120, bottom: 20, left: 120};
  private width: number;
  private height: number;
  private i = 0;
  private duration = 750;
  private root: any;
  private tree;
  private svg;
  private diagonal;

  constructor() {
  }


  ngOnInit() {
    this.width = 960 - this.margin.right - this.margin.left;
    this.height = 800 - this.margin.top - this.margin.bottom;

    this.tree = d3.layout.tree()
      .size([this.height, this.width]);

    this.diagonal = d3.svg.diagonal()
      .projection((d) => { return [d.y, d.x]; });

    this.svg = d3.select('.container').append("svg")
      .attr("width", this.width + this.margin.right + this.margin.left)
      .attr("height", this.height + this.margin.top + this.margin.bottom)
      .append("g")
      .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");

    console.log("flare inside",data);
    this.root = data;
    this.root.x0 = this.height / 2;
    this.root.y0 = 0;


    this.root.children.forEach(this.collapse);
    this.update(this.root);


    //d3.select(self.frameElement).style("height", "800px");

  }

  collapse = (d) => {
    if (d.children) {
      d._children = d.children;
      d._children.forEach(this.collapse);
      d.children = null;
    }
  };

  click = (d) => {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    this.update(d);
  };

  update (source): any {

    let nodes = this.tree.nodes(this.root).reverse()
    let links = this.tree.links(nodes);
    nodes.forEach(function(d){ d.y = d.depth * 180});

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

    // Enter any new nodes at the parent's previous position.
    var nodeEnter = node.enter().append('g')
      .attr('class', 'node')
      .attr('transform', function () {
        return 'translate(' + source.y0 + ',' + source.x0 + ')';
      })
      .on('click', this.click);



    // Add Circle for the nodes
    nodeEnter.append('circle')
      .attr('r', 1e-6)
      .style('fill', function (d: any) {
        return d._children ? 'lightsteelblue' : '#fff';
      });
    // Add labels to the nodes
    nodeEnter.append('text')
      .attr('x', function (d: any) {
        return d.children || d._children ? -10 : 10;
      })
      .attr('dy', '.35em')
      .attr('text-anchor', function (d: any) {
        return d.children || d._children ? 'end' : 'start';
      })
      .text(function (d: any) {
        return d.name;

      })
      .style('fill-opacity', 1e-6);

    //i have to see whats this

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


    nodeEnter.append('svg:title').text(function (d: any) {
      return d.name;
    });




    // Transition to the proper position for the node
    var nodeUpdate =  node.transition()
      .duration(this.duration)
      .attr('transform', function(d) {
        return 'translate(' + d.y + "," + d.x + ')';
      });

    // Update the node attributes and style
    nodeUpdate.select('circle')
      .attr('r', 10)
      .style('fill', function (d: any) {
        return d._children ? 'lightsteelblue' : '#fff';
      })
      .attr('cursor', 'pointer');

    nodeUpdate.select('text')
      .style('fill-opacity', 1);

    // Transition exiting nodes to the parent's new position (and remove the nodes)
    var nodeExit = node.exit().transition()
      .duration(this.duration);

    nodeExit
      .attr('transform', function (d) {
        return 'translate(' + source.y + ',' + source.x + ')';
      })
      .remove();

    nodeExit.select('circle')
      .attr('r', 1e-6);

    nodeExit.select('text')
      .style('fill-opacity', 1e-6);

    // ****************** links section ***************************

    // Update the links…
    var link = this.svg.selectAll('path.link')
      .data(links, function (d: any) {
          return d.id;
        }
      );

    // Enter any new links at the parent's previous position.
    link.enter().insert('path', 'g')
      .attr('class', 'link')
      .attr('d', (d) => {
        var o = {x: source.x0, y: source.y0};
        return this.diagonal({source: o, target: o});
      });


    // Transition links to their new position.
    link.transition()
      .duration(this.duration)
      .attr('d', this.diagonal);


    // // Transition exiting nodes to the parent's new position.
    let linkExit = link.exit().transition()
      .duration(this.duration)
      .attr('d', (d: any) => {
        var o = {x: source.x, y: source.y};
        return this.diagonal({source: o, target: o});
      })
      .remove();

    // Stash the old positions for transition.
    nodes.forEach(function (d: any) {
      d.x0 = d.x;
      d.y0 = d.y;
    });

  }


}

Here is an exemple I did from this link : https://github.com/tomwanzek/d3-v4-definitelytyped/blob/master/tests/d3-hierarchy/d3-hierarchy-test.ts这是我从这个链接做的一个例子: https : //github.com/tomwanzek/d3-v4-definelytyped/blob/master/tests/d3-hierarchy/d3-hierarchy-test.ts

 import { Component, Inject } from '@angular/core';
 import { Http } from '@angular/http';
 import {
     hierarchy,
     HierarchyNode,
     HierarchyPointNode,
     HierarchyLink,
     HierarchyPointLink,
     StratifyOperator,
     TreeLayout,
     tree,
     ClusterLayout,
     cluster
 } from 'd3-hierarchy'
 import * as d3 from 'd3';
 import { forEach } from '@angular/router/src/utils/collection';
 interface HierarchyDatum {
     name: string;
     value: number;
     children?: Array<HierarchyDatum>;
 }
 const data: HierarchyDatum = {
     name: "A1",
     value: 100,
     children: [
         {
             name: "B1",
             value: 100,
             children: [
                 {
                     name: "C1",
                     value: 100,
                     children: undefined 
                 },
                 {
                     name: "C2",
                     value: 300,
                     children: [
                         {
                             name: "D1",
                             value: 100,
                             children: undefined
                         },
                         {
                             name: "D2",
                             value: 300,
                             children: undefined
                         }
                     ] 
                 },
                 {
                     name: "C3",
                     value: 200,
                     children: undefined 
                 }
             ]
         },
         {
             name: "B2",
             value: 200,
             children: [
                 {
                     name: "C4",
                     value: 100,
                     children: undefined 
                 },
                 {
                     name: "C5",
                     value: 300,
                     children: undefined 
                 },
                 {
                     name: "C6",
                     value: 200,
                     children: [
                         {
                             name: "D3",
                             value: 100,
                             children: undefined
                         },
                         {
                             name: "D4",
                             value: 300,
                             children: undefined
                         }
                     ]  
                 }
             ]
         }
     ]
 };
 @Component({
     selector: 'chart',
     templateUrl: './chart.component.html',
     styleUrls: ['./chart.component.scss']
 })
 export class ChartComponent {
     private margin: any = { top: 20, right: 120, bottom: 20, left: 120 };
     private width: number;
     private height: number;
     private root: HierarchyPointNode<HierarchyDatum>;
     private tree: TreeLayout<HierarchyDatum>;
     private svg: any;
     private diagonal: any;
     constructor() {
     }
     ngOnInit() {
         this.width = 720 - this.margin.right - this.margin.left;
         this.height = 640 - this.margin.top - this.margin.bottom;
         this.svg = d3.select('.container').append("svg")
             .attr("width", this.width + this.margin.right + this.margin.left)
             .attr("height", this.height + this.margin.top + this.margin.bottom)
             .append("g")
             .attr("class", "g")
             //.attr("transform", "translate(5,5)");
             .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
         d3.select('svg g.g')
             .append("g")
             .attr("class", "links");
         d3.select('svg g.g')
             .append("g")
             .attr("class", "nodes");
         console.log("flare inside", data);
         this.tree = tree<HierarchyDatum>();
         this.tree.size([this.height, this.width]);
         this.root = this.tree(hierarchy<HierarchyDatum>(data));
         this.draw(this.root);
     }
     private draw(root: HierarchyPointNode<HierarchyDatum>) {
         // Nodes
         d3.select('svg g.nodes')
             .selectAll('circle.node')
             .data(root.descendants())
             .enter()
             .append('circle')
             .classed('node', true)
             .attr('style', "fill: steelblue;stroke: #ccc;stroke-width: 3px;")
             .attr('cx', function (d) { return d.x; })
             .attr('cy', function (d) { return d.y; })
             .attr('r', 10);
         // Links
         d3.select('svg g.links')
             .selectAll('line.link')
             .data(root.links())
             .enter()
             .append('line')
             .classed('link', true)
             .attr('style', "stroke: #ccc;stroke-width: 3px;")
             .attr('x1', function (d) { return d.source.x; })
             .attr('y1', function (d) { return d.source.y; })
             .attr('x2', function (d) { return d.target.x; })
             .attr('y2', function (d) { return d.target.y; });
     }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM