presented by hao Ding

 

USE the FORce, Luke! 

 

LAYouts: Force

The Simplest Possible Graph

 

Define the data

 
var nodes = [
    { x:   width/3, y: height/2 },
    { x: 2*width/3, y: height/2 }
];

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

Define the data

 
var nodes = [
    { x:   width/3, y: height/2 },
    { x: 2*width/3, y: height/2 }
];

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

Define the SVg and Force

 
var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height);

var force = d3.layout.force()
    .size([width, height])
    .nodes(nodes)
    .links(links)

force.linkDistance(width/2);

Add nodes and Links 

 
// add links first (WHY?)

var link = svg.selectAll('.link')
    .data(links)
    .enter().append('line')
    .attr('class', 'link');


var node = svg.selectAll('.node')
    .data(nodes)
    .enter().append('circle')
    .attr('class', 'node');

Start the Force

 
force.on('end', function() {

    node.attr('r', width/25)
        .attr('cx', function(d) { return d.x; })
        .attr('cy', function(d) { return d.y; });

    link.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; });

});


force.start();

WHat we get?

 

More Nodes

 

define the nodes and links

 
var graph = {
    "nodes": [  { "x": 208.992345, "y": 273.053211 },
                { "x": 595.98896,  "y":  56.377057 },
                { "x": 319.568434, "y": 278.523637 },
                { "x": 482.664139, "y": 340.386773 },
                { "x":  84.078465, "y": 192.021902 },
                { "x": 196.952261, "y": 370.798667 },
                { "x": 107.358165, "y": 435.15643  },
                ...
            ],
    "links": [  { "target": 11, "source":  0 },
                { "target":  3, "source":  0 },
                { "target": 10, "source":  0 },
                { "target": 16, "source":  0 },
                { "target":  1, "source":  0 },
                { "target":  3, "source":  0 },
                ....
            ]
    };

The Rest are the same

 

Seeing a Layout in Action

 

changes

 

force.on('tick', function() {

...

What's different?

 

force.on('tick', function() {

...

start

tick

end

force.linkDistance()

 

Define the data

 
var dataNodes = [
    { x:   width/3, y:   height/3 },
    { x:   width/3, y: 2*height/3 },
    { x: 2*width/3, y:   height/3 },
    { x: 2*width/3, y: 2*height/3 }
];

var dataLinks = [
    { source: 0, target: 1, graph: 0 },
    { source: 2, target: 3, graph: 1 }
];

force = d3.layout.force()
          .size([width, height])
          .nodes(dataNodes)
          .links(dataLinks);

Define Gravity & linkdistance

 
force.gravity(0);

force.linkDistance(function(link) {
       return link.graph === 0 ? height/2 : height/4;
});

force.linkDistance() takes both constant and function

Define Gravity & linkdistance

 
force.gravity(0);

force.linkDistance(function(link) {
       return link.graph === 0 ? height/2 : height/4;
});

force.linkDistance() takes both constant and function

 

Charge

 

Charge

 
    force.linkDistance(height/6);

   
    force.linkStrength(0.1);

  
    force.charge(function(node) {
       return node.graph === 0 ? -30 : -300;
    });

Charge(CON.)

 

linkStrength

 

linkStrength

 
force.linkStrength(function(link) {
    if (link.className === 'red')  return 0.1;
    return 1;
});

fisheye

 

fisheye

 

fisheye

 
svg.on("mousemove", function() {
   fisheye.focus(d3.mouse(this));

   node.each(function(d) { d.fisheye = fisheye(d); })
       .attr("cx", function(d) { return d.fisheye.x; })
       .attr("cy", function(d) { return d.fisheye.y; })
       .attr("r", function(d) { return d.fisheye.z * 4.5; });

   link.attr("x1", function(d) { return d.source.fisheye.x; })
       .attr("y1", function(d) { return d.source.fisheye.y; })
       .attr("x2", function(d) { return d.target.fisheye.x; })
       .attr("y2", function(d) { return d.target.fisheye.y; });
});

fisheye.js

 
function fisheye(d) {
   var dx = d.x - focus[0],
       dy = d.y - focus[1],
       dd = Math.sqrt(dx * dx + dy * dy);
   if (!dd || dd >= radius) return {x: d.x, y: d.y, z: 1};
   var k = k0 * (1 - Math.exp(-dd * k1)) / dd * .75 + .25;
   return 
        {x: focus[0] + dx * k, y: focus[1] + dy * k, z: Math.min(k, 10)};
}

Matrix visualization

 

fisheye.js

 
svg.on("mousemove", function() {
   fisheye.focus(d3.mouse(this));

   node.each(function(d) { d.fisheye = fisheye(d); })
       .attr("cx", function(d) { return d.fisheye.x; })
       .attr("cy", function(d) { return d.fisheye.y; })
       .attr("r", function(d) { return d.fisheye.z * 4.5; });

   link.attr("x1", function(d) { return d.source.fisheye.x; })
       .attr("y1", function(d) { return d.source.fisheye.y; })
       .attr("x2", function(d) { return d.target.fisheye.x; })
       .attr("y2", function(d) { return d.target.fisheye.y; });
});

Want an Abstraction?

The End

THANK YOU FOR LISTENING

 

The slides are made by reveal.js and slides.com