yaronmil
yaronmil

Reputation: 39

d3.js force graph with type script and angular2

i am trying to create a simple force graph (2 nodes with a relation) with angular 2 and type script . and cant make it work .

i would appreciate a working demo for this.

this the code i came up with' idont know if its correct or not

   export class SysRelationsComponent implements OnInit {

  private d3: D3;
  private parentNativeElement: any;

  private width:number=1200;
  private height:number=600;

  constructor(element: ElementRef, d3Service: D3Service ) {
    this.d3 = d3Service.getD3();
    this.parentNativeElement = element.nativeElement;

  }
  ngOnInit() {
    this.d3.select(this.parentNativeElement).style("color", "red");
    let color = this.d3.scaleOrdinal(this.d3.schemeCategory20);

    var nodes = [
      {"id": "Alice"},
      {"id": "Bob"},
      {"id": "Carol"}
    ];

    var links = [
      {"source": "0", "target": "1"},
    ];

    var simulation = this.d3.forceSimulation(nodes)
      .force("charge", this.d3.forceManyBody())
      .force("link", this.d3.forceLink(links) .id(function(d){return d.id}) )
      .force("center",this.d3.forceCenter());

    var link = this.parentNativeElement.append("g")
      .attr("class", "links")
      .selectAll("line")
      .data(links)
      .enter().append("line")
      .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

    var node = this.parentNativeElement.append("g")
      .attr("class", "nodes")
      .selectAll("circle")
      .data( nodes)
      .enter().append("circle")
      .attr("r", 25)
      .attr("fill", function(d) { return color(d.group); });


    node.append("title")
      .text(function(d) { return d.id; });

    simulation
      .nodes( nodes)
      .on("tick", this.ticked);

     /* .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));*/
    /*this.sdps.getSystemsWithRelataions();*/
  }

}

Upvotes: 0

Views: 7460

Answers (2)

eko
eko

Reputation: 40647

I couldn't create the exact example since you didn't provide the used methods like ticked() but I've created http://bl.ocks.org/mbostock/4062045 with angular2. You're free to customize it

I've used the miserables.json as the author did but you can replace the variable inside src/miserables.ts with

export var miserables = {
  "nodes": [
    {id: 'Alice', name: 'Alice'}, {id: 'Bob', name: 'Bob'}
  ],
  "links": [
    {"source": "Alice", "target": "Bob"}
  ]
}

To get the 2 node and 1 link example as you wanted.

css:

.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}

Full Plunker: http://plnkr.co/edit/qcESHb3cCwD6NZL1yuhX?p=preview

Upvotes: 3

yaronmil
yaronmil

Reputation: 39

doing lots of self research i came up with this working code. i hope it will help some of you !

credits to mike bostock Force-Directed Graph

d3/d3-force

 private width: number = 1800;
 private height: number = 600;
 var svg = this.d3.select(this.parentNativeElement).append("svg");
 svg.attr("width", this.width).attr("height", this.height);
 let color = this.d3.scaleOrdinal(this.d3.schemeCategory20);
 var nodes=[{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]
 var links = [
      {"source": "Alice", "target": "Bob"},

    ];
 var simulation = this.d3.forceSimulation(nodes)
      .force("charge", this.d3.forceManyBody())
      .force("link", this.d3.forceLink(links).id(function (d:{ id: string ,group:number}) {
        return d.id
      }))
      .force("center", this.d3.forceCenter(this.width / 2, this.height / 2));
 var link = svg.append("g")
      .attr("class", "links")
      .selectAll("line")
      .data(links)
      .enter().append("line");

    var that = this;
    var node = svg.append("g")
      .attr("class", "nodes")
      .selectAll("circle")
      .data(nodes)
      .enter().append("circle")
      .attr("r", 25)
      .attr("fill",function(d:{ id: string ,group:number}) { return color(d.id.toString()); })


    simulation
      .nodes(nodes)
      .on("tick", function () {
        link
          .attr("x1", function (d: SimulationLinkDatum<SimulationNodeDatum>) {
            return (<SimulationNodeDatum>d.source).x
          })
          .attr("y1", function (d: SimulationLinkDatum<SimulationNodeDatum>) {
            return (<SimulationNodeDatum>d.source).y
          })
          .attr("x2", function (d: SimulationLinkDatum<SimulationNodeDatum>) {
            return (<SimulationNodeDatum>d.target).x
          })
          .attr("y2", function (d: SimulationLinkDatum<SimulationNodeDatum>) {
            return (<SimulationNodeDatum>d.target).y
          });
        node
          .attr("cx", function (d: SimulationNodeDatum) {
            return d.x;
          })
          .attr("cy", function (d: SimulationNodeDatum) {
            return d.y;
          });
      });
    this.d3.selectAll("circle").call(this.d3.drag().on("start", function (d: SimulationNodeDatum) {
      if (!that.d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
      console.log(d)
    }).on("drag", function (d: SimulationNodeDatum) {
        d.fx = that.d3.event.x;
        d.fy = that.d3.event.y;
    }).on("end", function (d: SimulationNodeDatum) {
        if (!that.d3.event.active) simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
    }));

Upvotes: 1

Related Questions