javascript - d3 force directed graph moving away on the svg, separating into group of nodes -
my force directed graph drawn correctly. doesn't stay still. moves here , there on svg nodes disappear visibility leaving clusters of nodes here , there. how graph looks:
some time later looks this: nodes have gone every away div
var graph = new object(); var map = new object(); var index = 0; var linkindex = 0; var width = $("#d3graph").width(); var height = $("#d3graph").height() ; var svg = d3.select("#d3graph").append("svg:svg") .attr("width", width) .attr("height", height); // tool tip label var tip = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function (d) { return d.name + ""; }) svg.call(tip); /* take nodes , edges outside. part works fine*/ graph.links = dataset2; graph.nodes = dataset1; function drapgraph(graph) { svg.selectall("g.link").remove(); svg.selectall("g.gnode").remove(); var force = self.force = d3.layout.force() .nodes(graph.nodes) .links(graph.links) .gravity(.05) .distance(30) .charge(-120) .size([width, height]) .start(); //map radius domain--> range var rscale = d3.scale.linear() .domain([d3.min(graph.nodes, function (d) { return math.log(d.group); }), d3.max(graph.nodes, function (d) { return math.log(d.group); })]) .range([0, 30]); var link = svg.selectall(".link") .data(graph.links) .enter().append("line") .attr("class", "link") .style("stroke-width", 2) .style("stroke-length", function (d) {return (10000/d.value);}); var node = svg.selectall("g.gnode") .data(graph.nodes) .enter().append("g") .attr("class", "gnode") .on('mouseover', tip.show) .on('mouseout', tip.hide) .call(force.drag); var maxretweets = d3.max(graph.nodes, function (d) { return math.log(d.group); }); var minretweets = d3.min(graph.nodes, function (d) { return math.log(d.group); }); var maxcontent = d3.max(graph.nodes, function (d) { return d.degree; }); var minvalue = d3.min(graph.links, function (d) { return d.value; }); var circle = node.append("circle") .attr("r", function (d) { return rscale(math.log(d.group)); }) .style("fill", function (d) { return d.color; }) .style("stroke", "#000000") .on('mouseover', tip.show) .on('mouseout', tip.hide) .call(force.drag); //give nodes labels var label = node.append("text") .style("font-family", "sans-serif") .style("text-anchor", "middle") .style("font-size", "8") .style("stroke", "#404040") .text(function (d) { if (rscale(math.log(d.group)) > 5) { return d.name; } }); force.on("tick", function () { node.attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }); circle.attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }); label.attr("x", function (d) { return d.x; }) .attr("y", 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; }); }); svg.selectall("g").attr("x", function (d) { return d.x; }) .attr("y", function (d) { return d.y; }); }
can me solve problem? there small problem here couldn't figure out it, tried many things still doesn't work.
i suggest use bounded x
, y
values fix such issues.
try calculating x
, y
positions in tick function shown below.
node.attr("cx", function(d) { return d.x = math.max(radius, math.min(width - radius, d.x)); }) .attr("cy", function(d) { return d.y = math.max(radius, math.min(height - radius, d.y)); });
refer here sample.
edit: there no need update circle , text positions individually since grouped. need update group elements , links follows.
force.on("tick", function () { svg.selectall("g.node") .attr("transform", function (d) { d.x = math.max(radius, math.min(width - radius, d.x)); d.y = math.max(radius, math.min(height - radius, d.y)); return "translate("+d.x+","+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; }); }); }
Comments
Post a Comment