d3 force graph zoom in and zoom out issue - javascript

I have a d3 force graph, but i don't really know how i could zoom in and out.
Currently to zoom out, i am decreasing the circle radius by 5 and to zoom in i am increasing it by 5.
The problem is that i don't have an idea, of how to shrink or increase the text size with the circle.
Link to jsFiddle:
http://jsfiddle.net/s5wfg7g6/2/
Code(HTML):
<input type="button" onClick="zoomIn();" value="Zoom In">
<input type="button" onClick="zoomOut();" value="Zoom Out">
<svg width="500" height="500" style="background-color: lightgrey; border: 1px solid black;">
</svg>
<script>
var r = 30;
function zoomIn()
{
r += 5;
d3.selectAll("circle").attr("r", r);
}
function zoomOut()
{
r -= 5;
d3.selectAll("circle").attr("r", r);
}
</script>
Code(JS):
var nodes = [
{
"name": "node1",
"group": "1"
},
{
"name": "subNode1",
"group": "1"
}
];
var links = [
{
"source": 0,
"target": 1
}
];
var width = 500;
var height = 500;
var svg = d3.select("svg");
var color = d3.scale.category20();
var textXPlus = 31;
var textYPlus = 2;
var force = d3.layout.force()
.charge(-160)
.size([width, height])
.linkDistance(150)
.nodes(nodes)
.links(links)
.start();
var texts = svg.selectAll("text")
.data(nodes)
.enter()
.append("text")
.attr("fill", "red")
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.text(function(d) { return d.name; });
var links = svg.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var nodes = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 30)
.attr("fill", function(d){ return color(d.group); })
.call(force.drag);
force.on("tick", function()
{
links.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; });
nodes.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
texts.attr("x", function(d){ return d.x + textXPlus; })
.attr("y", function(d){ return d.y + textYPlus; });
});

Related

D3.js - Text not showing up in node

I found this d3 code, and I am unable to put text to the nodes. I have seen some solutions to create a parent class for this but I am getting errors trying them out. The current code works but doesn't add text :(
Here's the plnkr link for the working code -
http://plnkr.co/edit/dqAaEhJnnK4i2nBsTaNu?p=preview
Also, this is the code
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<button id="clusterButton" type="button">Cluster</button>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="../netClustering.js"> </script>
<!-- <script type="text/javascript" src="groupInABox.js"> </script> -->
<script>
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
// var gb = GroupInABox(force, "");
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("miserables.json", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.call(force.drag);
// node.append("title")
// .text(function(d) { return d.name; });
node.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.text(function(d){ return d.name; });
// .call(force.drag);
// .attr("font-size", function(d){ return d.influence*1.5>9? d.influence*1.5: 9; })
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
d3.select("#clusterButton").on("click", function () {
netClustering.cluster(graph.nodes, graph.links);
svg.selectAll(".node").transition().duration(500).style("fill", function(d) { return color(d.cluster); });
});
});
</script>
You are appending a text to circle as child node. That will not render. A circle can't have a text. There are 2 ways, either define a new enter selection with the same data and append texts ,or create a g element append circle and text and on tick,vupdate transform attribute each tick. I did the first one, change the below part of your script and it will render:
// node.append("title")
// .text(function(d) { return d.name; });
var texts =svg.selectAll(".texts")
.data(graph.nodes)
.enter()
.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.text(function(d){ return d.name; });
// .call(force.drag);
// .attr("font-size", function(d){ return d.influence*1.5>9? d.influence*1.5: 9; })
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
texts.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
});
You entire html:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<button id="clusterButton" type="button">Cluster</button>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="netClustering.js"> </script>
<!-- <script type="text/javascript" src="groupInABox.js"> </script> -->
<script>
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
// var gb = GroupInABox(force, "");
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("miserables.json", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.call(force.drag);
var texts =svg.selectAll(".texts")
.data(graph.nodes)
.enter()
.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.text(function(d){ return d.name; });
// .call(force.drag);
// .attr("font-size", function(d){ return d.influence*1.5>9? d.influence*1.5: 9; })
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
texts.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
});
d3.select("#clusterButton").on("click", function () {
netClustering.cluster(graph.nodes, graph.links);
svg.selectAll(".node").transition().duration(500).style("fill", function(d) { return color(d.cluster); });
});
});
</script>

How to display source nodes of a clicked target?

How can I display the source nodes names of a clicked target node in a forced directed graph using D3?
The snippet below is from some example code for directed graphs by Mike Bostock. How can I go about modifying this base code so when a node is clicked on the graph, the target values of that node is displayed on the screen (in this case I would like to display the name attributes)?
For example the 0-th element in "nodes" is:
"nodes":[
{"name":"Myriel","group":1},
...
]
And in "links" the targets are define like so:
"links":[
{"source":1,"target":0,"value":1}, // Napoleon
{"source":2,"target":0,"value":8}, // Mlle.Baptistine
{"source":3,"target":0,"value":10}, // Mme.Magloire
{"source":3,"target":2,"value":6},
{"source":4,"target":0,"value":1}, // CountessdeLo
{"source":5,"target":0,"value":1}, // Geborand
{"source":6,"target":0,"value":1}, // Champtercier
{"source":7,"target":0,"value":1}, // Cravatte
{"source":8,"target":0,"value":2}, // Count
{"source":9,"target":0,"value":1}, // OldMan
...
{"source":11,"target":0,"value":5}, // Valjean
...
]
Then clicking on the node Myriel would display:
Napoleon,Mlle.Baptistine,Mme.Magloire,CountessdeLo,Geborand,Champtercier,Cravatte,Count,OldMan,Valjean
Myriel is located here in the graph:
Below is the JavaScript code:
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/9653f99dbf6050b0f28ceafbba659ac5e1e66fbd/miserables.json", function(error, graph) {
if (error) throw error;
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag)
.on("click",function(d){
var targets = graph.links.filter(function(i){
return i.target.name == d.name
});
tip.show( targets.map(function(i){ return i.source.name;}) );
});
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/9653f99dbf6050b0f28ceafbba659ac5e1e66fbd/miserables.json", function(error, graph) {
if (error) throw error;
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag)
.on("click",function(d){
var targets = graph.links.filter(function(i){
return i.target.name == d.name
});
tip.show( targets.map(function(i){ return i.source.name;}) );
});
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
Add a click event on each node, then inside we can get all the targets by filtering the graph.links array such that we only have the elements who's target.name is the same as the clicked nodes name d.name. Once we have that you can use .map() to return the array with .source.name to give the name of those items inside targets:
.on("click",function(d) {
var targets = graph.links.filter(function(i){
return i.target.name==d.name;
});
tip.show( targets.map(function(i){ return i.source.name; }) );
});
var tip = d3.tip().attr('class', 'd3-tip').html(function(d) { return d; });
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.call(tip);
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/9653f99dbf6050b0f28ceafbba659ac5e1e66fbd/miserables.json", function(error, graph) {
if (error) throw error;
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag)
.on("click",function(d){
var targets = graph.links.filter(function(i){
return i.target.name == d.name
});
tip.show( targets.map(function(i){ return i.source.name;}) );
});
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.7/d3-tip.min.js"></script>
Now for easy display of those values the d3-tip library can be used. This would be initialized for the graph like so:
var tip = d3.tip().attr('class', 'd3-tip').html(function(d) { return d; });
...
var svg = ..
svg.call(tip);
And finally the tip.show(...) function in the first code snippet will display those items on the graph.

d3 text doesn't move with the nodes

I hava tried some methods, such as d3 Node Labeling proposed by mbostock. But it doesn't work, my text still doesn't move with the nodes, they are static.
(Coded by using CoffeeScript)
vis = d3.select(selection).append("svg")
.attr("width", width)
.attr("height", height)
linksG = vis.append("g").attr("class", "links")
nodesG = vis.append("g").attr("class", "nodes")
labelG = vis.append("g").attr("class", "labels")
nodeP = nodesG.selectAll("circle.node")
.data(curNodesDataP)
nodeP.enter().append("circle")
.attr("class", "node")
.attr("r", 15)
.style("fill", (d) -> nodeColors(d.id))
.style("stroke", (d) -> strokeFor(d))
.style("stroke-width", 1.0)
.call(force.drag)
text = labelG.selectAll("text")
.data(curNodesDataP)
text.enter().append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text((d) -> d.id)
I have troubled that several days, and how can i repair it? Thanks!
--zzcheng
You are appending the links, nodes and labels in separate g groups. So you should update the position of each group in tick function (Link group, Node group and label Group).
Here is a sample fiddle for the same. Note that I am updating position of label group also in the tick function.
var w = 900,
h = 400;
var circleWidth = 5;
var nodes = [{
"name": "Matteo"
}, {
"name": "Daniele"
}, {
"name": "Marco"
}, {
"name": "Lucio"
}, {
"name": "Davide"
}];
var links = [{
source: nodes[0],
target: nodes[1]
}, {
source: nodes[1],
target: nodes[2]
}, {
source: nodes[0],
target: nodes[3]
}, {
source: nodes[4],
target: nodes[2]
}, {
source: nodes[2],
target: nodes[3]
}];
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "stage")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(nodes)
.links([])
.gravity(0.1)
.charge(-1000)
.size([w, h]);
var link = vis.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("stroke", "#CCC")
.attr("fill", "none");
var node = vis.selectAll("circle.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
var labels = vis.selectAll("text.label")
.data(nodes)
.enter().append("g")
.attr("class", "label");
//CIRCLE
node.append("svg:circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", circleWidth)
.attr("fill", "pink");
//TEXT
labels.append("text")
.text(function(d, i) {
return d.name;
})
.attr("x", function(d, i) {
return circleWidth + 5;
})
.attr("y", function(d, i) {
if (i > 0) {
return circleWidth + 0
} else {
return 8
}
})
.attr("font-family", "Bree Serif")
.attr("fill", "green")
.attr("font-size", "1em")
.attr("text-anchor", function(d, i) {
if (i > 0) {
return "beginning";
} else {
return "end"
}
})
force.on("tick", function(e) {
node.attr("transform", function(d, i) {
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;
});
labels.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
});
force.start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Other possible and more efficient way would be to group nodes and labels together. Here is a sample fiddle in which nodes and labels are grouped and updated position of the node group and link group only in tick function.
var w = 900,
h = 400;
var circleWidth = 5;
var nodes = [{
"name": "Matteo"
}, {
"name": "Daniele"
}, {
"name": "Marco"
}, {
"name": "Lucio"
}, {
"name": "Davide"
}];
var links = [{
source: nodes[0],
target: nodes[1]
}, {
source: nodes[1],
target: nodes[2]
}, {
source: nodes[0],
target: nodes[3]
}, {
source: nodes[4],
target: nodes[2]
}, {
source: nodes[2],
target: nodes[3]
}];
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "stage")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(nodes)
.links([])
.gravity(0.1)
.charge(-1000)
.size([w, h]);
var link = vis.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("stroke", "#CCC")
.attr("fill", "none");
var node = vis.selectAll("circle.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
//CIRCLE
node.append("svg:circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", circleWidth)
.attr("fill", "pink");
//TEXT
node.append("text")
.text(function(d, i) {
return d.name;
})
.attr("x", function(d, i) {
return circleWidth + 5;
})
.attr("y", function(d, i) {
if (i > 0) {
return circleWidth + 0
} else {
return 8
}
})
.attr("font-family", "Bree Serif")
.attr("fill", "green")
.attr("font-size", "1em")
.attr("text-anchor", function(d, i) {
if (i > 0) {
return "beginning";
} else {
return "end"
}
})
force.on("tick", function(e) {
node.attr("transform", function(d, i) {
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;
})
});
force.start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Node drag not working on iPad

I would like to drag node and drag canvas (svg element)
On a desktop browser, it works fine, but on an iPad it only drags the canvas; node dragging is not working. Where did I go wrong?
My source code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
}
</style>
<body>
<script src="d3.js"></script>
<script>
var view_w = width = 960,
view_h = height = 500,
view_y = 0,
view_x = 0;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", view_x+" "+view_y+" "+view_w+" "+view_h);
var canvasdrag = d3.behavior.drag().on("drag", function(d){
view_x -= d3.event.dx;
view_y -= d3.event.dy;
//change svg position
svg.attr("translate", view_x + " " + view_y);
//change viewBox start position
svg.attr("viewBox", view_x+" "+view_y+" "+view_w+" "+view_h);
});
svg.call(canvasdrag);
d3.json("./sample.json", function(error, graph) {
graph.links.forEach(function(d) {
d.source = graph.nodes[d.source];
d.target = graph.nodes[d.target];
});
var link = svg.append("g")
.attr("class", "link")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.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; });
var node = svg.append("g")
.attr("class", "node")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 6)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.call(d3.behavior.drag()
.origin(function(d) { return d; })
.on("drag", function(d) {
d.x = d3.event.x, d.y = d3.event.y;
d3.select(this).attr("cx", d.x).attr("cy", d.y);
link.filter(function(l) { return l.source === d; }).attr("x1", d.x).attr("y1", d.y);
link.filter(function(l) { return l.target === d; }).attr("x2", d.x).attr("y2", d.y);
}));
});
</script>
[sample.json]
{"nodes":[{"x":444,"y":275},{"x":378,"y":324},{"x":478,"y":278},{"x":471,"y":256},{"x":382,"y":269},{"x":371,"y":247},{"x":359,"y":276},{"x":364,"y":302},{"x":400,"y":330},{"x":388,"y":298},{"x":524,"y":296},{"x":570,"y":243},{"x":552,"y":159},{"x":502,"y":287},{"x":511,"y":313},{"x":513,"y":265},{"x":602,"y":132},{"x":610,"y":90},{"x":592,"y":91},{"x":575,"y":89},{"x":607,"y":73},{"x":591,"y":68},{"x":574,"y":73},{"x":589,"y":149},{"x":620,"y":205},{"x":621,"y":230},{"x":589,"y":234},{"x":602,"y":223},{"x":548,"y":188},{"x":532,"y":196},{"x":548,"y":114},{"x":575,"y":174},{"x":497,"y":250},{"x":576,"y":196},{"x":504,"y":201},{"x":494,"y":186},{"x":482,"y":199},{"x":505,"y":219},{"x":486,"y":216},{"x":590,"y":306},{"x":677,"y":169},{"x":657,"y":258},{"x":667,"y":205},{"x":552,"y":227},{"x":518,"y":173},{"x":473,"y":125},{"x":796,"y":260},{"x":731,"y":272},{"x":642,"y":288},{"x":576,"y":269},{"x":605,"y":187},{"x":559,"y":289},{"x":544,"y":356},{"x":505,"y":365},{"x":579,"y":289},{"x":619,"y":282},{"x":574,"y":329},{"x":664,"y":306},{"x":627,"y":304},{"x":643,"y":327},{"x":664,"y":348},{"x":665,"y":327},{"x":653,"y":317},{"x":650,"y":338},{"x":622,"y":321},{"x":633,"y":338},{"x":647,"y":357},{"x":718,"y":362},{"x":636,"y":240},{"x":640,"y":227},{"x":617,"y":249},{"x":631,"y":254},{"x":566,"y":213},{"x":713,"y":322},{"x":716,"y":298},{"x":666,"y":241},{"x":627,"y":355}],"links":[{"source":1,"target":0},{"source":2,"target":0},{"source":3,"target":0},{"source":3,"target":2},{"source":4,"target":0},{"source":5,"target":0},{"source":6,"target":0},{"source":7,"target":0},{"source":8,"target":0},{"source":9,"target":0},{"source":11,"target":10},{"source":11,"target":3},{"source":11,"target":2},{"source":11,"target":0},{"source":12,"target":11},{"source":13,"target":11},{"source":14,"target":11},{"source":15,"target":11},{"source":17,"target":16},{"source":18,"target":16},{"source":18,"target":17},{"source":19,"target":16},{"source":19,"target":17},{"source":19,"target":18},{"source":20,"target":16},{"source":20,"target":17},{"source":20,"target":18},{"source":20,"target":19},{"source":21,"target":16},{"source":21,"target":17},{"source":21,"target":18},{"source":21,"target":19},{"source":21,"target":20},{"source":22,"target":16},{"source":22,"target":17},{"source":22,"target":18},{"source":22,"target":19},{"source":22,"target":20},{"source":22,"target":21},{"source":23,"target":16},{"source":23,"target":17},{"source":23,"target":18},{"source":23,"target":19},{"source":23,"target":20},{"source":23,"target":21},{"source":23,"target":22},{"source":23,"target":12},{"source":23,"target":11},{"source":24,"target":23},{"source":24,"target":11},{"source":25,"target":24},{"source":25,"target":23},{"source":25,"target":11},{"source":26,"target":24},{"source":26,"target":11},{"source":26,"target":16},{"source":26,"target":25},{"source":27,"target":11},{"source":27,"target":23},{"source":27,"target":25},{"source":27,"target":24},{"source":27,"target":26},{"source":28,"target":11},{"source":28,"target":27},{"source":29,"target":23},{"source":29,"target":27},{"source":29,"target":11},{"source":30,"target":23},{"source":31,"target":30},{"source":31,"target":11},{"source":31,"target":23},{"source":31,"target":27},{"source":32,"target":11},{"source":33,"target":11},{"source":33,"target":27},{"source":34,"target":11},{"source":34,"target":29},{"source":35,"target":11},{"source":35,"target":34},{"source":35,"target":29},{"source":36,"target":34},{"source":36,"target":35},{"source":36,"target":11},{"source":36,"target":29},{"source":37,"target":34},{"source":37,"target":35},{"source":37,"target":36},{"source":37,"target":11},{"source":37,"target":29},{"source":38,"target":34},{"source":38,"target":35},{"source":38,"target":36},{"source":38,"target":37},{"source":38,"target":11},{"source":38,"target":29},{"source":39,"target":25},{"source":40,"target":25},{"source":41,"target":24},{"source":41,"target":25},{"source":42,"target":41},{"source":42,"target":25},{"source":42,"target":24},{"source":43,"target":11},{"source":43,"target":26},{"source":43,"target":27},{"source":44,"target":28},{"source":44,"target":11},{"source":45,"target":28},{"source":47,"target":46},{"source":48,"target":47},{"source":48,"target":25},{"source":48,"target":27},{"source":48,"target":11},{"source":49,"target":26},{"source":49,"target":11},{"source":50,"target":49},{"source":50,"target":24},{"source":51,"target":49},{"source":51,"target":26},{"source":51,"target":11},{"source":52,"target":51},{"source":52,"target":39},{"source":53,"target":51},{"source":54,"target":51},{"source":54,"target":49},{"source":54,"target":26},{"source":55,"target":51},{"source":55,"target":49},{"source":55,"target":39},{"source":55,"target":54},{"source":55,"target":26},{"source":55,"target":11},{"source":55,"target":16},{"source":55,"target":25},{"source":55,"target":41},{"source":55,"target":48},{"source":56,"target":49},{"source":56,"target":55},{"source":57,"target":55},{"source":57,"target":41},{"source":57,"target":48},{"source":58,"target":55},{"source":58,"target":48},{"source":58,"target":27},{"source":58,"target":57},{"source":58,"target":11},{"source":59,"target":58},{"source":59,"target":55},{"source":59,"target":48},{"source":59,"target":57},{"source":60,"target":48},{"source":60,"target":58},{"source":60,"target":59},{"source":61,"target":48},{"source":61,"target":58},{"source":61,"target":60},{"source":61,"target":59},{"source":61,"target":57},{"source":61,"target":55},{"source":62,"target":55},{"source":62,"target":58},{"source":62,"target":59},{"source":62,"target":48},{"source":62,"target":57},{"source":62,"target":41},{"source":62,"target":61},{"source":62,"target":60},{"source":63,"target":59},{"source":63,"target":48},{"source":63,"target":62},{"source":63,"target":57},{"source":63,"target":58},{"source":63,"target":61},{"source":63,"target":60},{"source":63,"target":55},{"source":64,"target":55},{"source":64,"target":62},{"source":64,"target":48},{"source":64,"target":63},{"source":64,"target":58},{"source":64,"target":61},{"source":64,"target":60},{"source":64,"target":59},{"source":64,"target":57},{"source":64,"target":11},{"source":65,"target":63},{"source":65,"target":64},{"source":65,"target":48},{"source":65,"target":62},{"source":65,"target":58},{"source":65,"target":61},{"source":65,"target":60},{"source":65,"target":59},{"source":65,"target":57},{"source":65,"target":55},{"source":66,"target":64},{"source":66,"target":58},{"source":66,"target":59},{"source":66,"target":62},{"source":66,"target":65},{"source":66,"target":48},{"source":66,"target":63},{"source":66,"target":61},{"source":66,"target":60},{"source":67,"target":57},{"source":68,"target":25},{"source":68,"target":11},{"source":68,"target":24},{"source":68,"target":27},{"source":68,"target":48},{"source":68,"target":41},{"source":69,"target":25},{"source":69,"target":68},{"source":69,"target":11},{"source":69,"target":24},{"source":69,"target":27},{"source":69,"target":48},{"source":69,"target":41},{"source":70,"target":25},{"source":70,"target":69},{"source":70,"target":68},{"source":70,"target":11},{"source":70,"target":24},{"source":70,"target":27},{"source":70,"target":41},{"source":70,"target":58},{"source":71,"target":27},{"source":71,"target":69},{"source":71,"target":68},{"source":71,"target":70},{"source":71,"target":11},{"source":71,"target":48},{"source":71,"target":41},{"source":71,"target":25},{"source":72,"target":26},{"source":72,"target":27},{"source":72,"target":11},{"source":73,"target":48},{"source":74,"target":48},{"source":74,"target":73},{"source":75,"target":69},{"source":75,"target":68},{"source":75,"target":25},{"source":75,"target":48},{"source":75,"target":41},{"source":75,"target":70},{"source":75,"target":71},{"source":76,"target":64},{"source":76,"target":65},{"source":76,"target":66},{"source":76,"target":63},{"source":76,"target":62},{"source":76,"target":48},{"source":76,"target":58}]}
I’m using d3.js version 788855b4a4141fab9554513976dcc50004c76489.

d3.js force layout increase linkDistance

How to increase linkDistance without affecting the node alignment,
example: http://mbostock.github.com/d3/talk/20110921/force.html
when I try to increase the circle radius and linkDistance
the it collapse
<script type="text/javascript">
var w = 1280,
h = 800,
z = d3.scale.category20c();
var force = d3.layout.force()
.size([w, h]);
var svg = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
svg.append("svg:rect")
.attr("width", w)
.attr("height", h);
d3.json("flare.json", function(root) {
var nodes = flatten(root),
links = d3.layout.tree().links(nodes);
force
.nodes(nodes)
.links(links)
.start();
var link = svg.selectAll("line")
.data(links)
.enter().insert("svg:line")
.style("stroke", "#999")
.style("stroke-width", "1px");
var node = svg.selectAll("circle.node")
.data(nodes)
.enter().append("svg:circle")
.attr("r", 4.5)
.style("fill", function(d) { return z(d.parent && d.parent.name); })
.style("stroke", "#000")
.call(force.drag);
force.on("tick", function(e) {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
function flatten(root) {
var nodes = [];
function recurse(node, depth) {
if (node.children) {
node.children.forEach(function(child) {
child.parent = node;
recurse(child, depth + 1);
});
}
node.depth = depth;
nodes.push(node);
}
recurse(root, 1);
return nodes;
}
</script>
Play around with the .charge parameter. It defines how much the nodes repel each other.

Categories

Resources