|
|
|
function renderForceDirectedGraph (dataset, totalMaxValue, dom_element_to_append_to,isCurrency, rootNodeName){ |
|
|
|
var margin = {top: 20, right: 20, bottom: 20, left: 20}; |
|
|
|
var width = 700 - margin.left - margin.right; |
|
// height = $(window).height() - 120 - margin.top - margin.bottom; |
|
var height = width*3/5; |
|
|
|
var links = dataset; |
|
var nodes = {}; |
|
|
|
// Compute the distinct nodes from the links. |
|
links.forEach(function(link) { |
|
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); |
|
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); |
|
}); |
|
|
|
Object.keys(nodes).forEach(function(key) { |
|
if(key=="Positive Cashflow"){ |
|
nodes["Positive Cashflow"].fixed=true; |
|
nodes["Positive Cashflow"].x=0 + 200; |
|
nodes["Positive Cashflow"].y=height/2; |
|
} |
|
else if(key=="Negative Cashflow"){ |
|
nodes["Negative Cashflow"].fixed=true; |
|
nodes["Negative Cashflow"].x=width - 200; |
|
nodes["Negative Cashflow"].y=height/2; |
|
} |
|
|
|
else if(key==rootNodeName){ |
|
nodes[rootNodeName].fixed=true; |
|
nodes[rootNodeName].x=width/2; |
|
nodes[rootNodeName].y=0 + 50; |
|
} |
|
|
|
else if(key=="Others"){ |
|
nodes["Others"].fixed=true; |
|
nodes["Others"].x=width*3/4; |
|
nodes["Others"].y=height*2/3; |
|
} |
|
else if(key=="Promotional"){ |
|
nodes["Promotional"].fixed=true; |
|
nodes["Promotional"].x=width/2; |
|
nodes["Promotional"].y=height*2/3; |
|
} |
|
else if(key=="Transactional"){ |
|
nodes["Transactional"].fixed=true; |
|
nodes["Transactional"].x=width/4; |
|
nodes["Transactional"].y=height*2/3; |
|
} |
|
|
|
}); |
|
|
|
var scaleLength = d3.scale.linear().domain([ 0, totalMaxValue ]).range([ 20, 100 ]); |
|
var scaleThickness = d3.scale.linear().domain([ 0, totalMaxValue ]).range([ 5, 30 ]); |
|
|
|
var force = d3.layout.force() |
|
.nodes(d3.values(nodes)) |
|
.links(links) |
|
.size([width, height]) |
|
.linkDistance(function(d){return scaleLength(d.value)*3;}) |
|
.charge(-900) |
|
.on("tick", tick) |
|
.start(); |
|
|
|
var svg = d3.select(dom_element_to_append_to).append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var path = svg.append("g").selectAll("path") |
|
.data(force.links()) |
|
.enter().append("path") |
|
.attr("stroke-width", function(d) { return scaleThickness(d.value)/2; }) |
|
.attr("class", function(d) { return "link " + d.type; }) |
|
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); |
|
|
|
var circle = svg.append("g").selectAll("circle") |
|
.data(force.nodes()) |
|
.enter().append("circle") |
|
.attr("class", function(d) { return "circle " + d.type; }) |
|
.attr("r", function(d) { if(d.name=='Positive Cashflow' || d.name=='Negative Cashflow'){return 14;}else if(d.name==rootNodeName){return 18;}return 10; }) |
|
.call(force.drag); |
|
|
|
var text = svg.append("g").selectAll("text") |
|
.data(force.nodes()) |
|
.enter().append("text") |
|
.attr("x", 8) |
|
.attr("y", ".31em") |
|
.text(function(d) { return d.name; }); |
|
|
|
// Use elliptical arc path segments to doubly-encode directionality. |
|
function tick() { |
|
path.attr("d", linkArc); |
|
circle.attr("transform", transform); |
|
text.attr("transform", transform); |
|
} |
|
|
|
function linkArc(d) { |
|
var dx = d.target.x - d.source.x, |
|
dy = d.target.y - d.source.y, |
|
dr = Math.sqrt(dx * dx + dy * dy); |
|
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; |
|
} |
|
|
|
function transform(d) { |
|
return "translate(" + d.x + "," + d.y + ")"; |
|
} |
|
|
|
var tip_node = d3.tip() |
|
.attr('class', 'd3-tip') |
|
.offset([-10, 0]) |
|
.html(function(d) { |
|
return "<div><span>Category:</span> <span style='color:white'>" + d.name + "</span></div>"; |
|
}); |
|
|
|
var tip_path = d3.tip() |
|
.attr('class', 'd3-tip') |
|
.offset([-10, 0]) |
|
.html(function(d) { |
|
var currency = "₹"; |
|
if (isCurrency) |
|
return "<div><span>Value:</span> <span style='color:white'>" + currency + " " + d.value + "</span></div>"; |
|
return "<div><span>Value:</span> <span style='color:white'>" + d.value + "</span></div>"; |
|
}); |
|
|
|
svg.call(tip_path); |
|
svg.call(tip_node); |
|
|
|
d3.selectAll(dom_element_to_append_to+ " circle") |
|
.on('mouseover', tip_node.show).on('mouseout',tip_node.hide); |
|
|
|
d3.selectAll(dom_element_to_append_to+ " path") |
|
.on('mouseover', tip_path.show).on('mouseout',tip_path.hide); |
|
|
|
} |