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 "
Category: " + d.name + "
"; }); var tip_path = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { var currency = "₹"; if (isCurrency) return "
Value: " + currency + " " + d.value + "
"; return "
Value: " + d.value + "
"; }); 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); }