Created
August 16, 2013 23:04
-
-
Save cariaso/6254278 to your computer and use it in GitHub Desktop.
D3 force directed graph. Zooming does not work. See http://snpedia.com/index.php/User_talk:Cariaso/D3bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<!-- D3 force directed graph. Zooming does not work. See http://snpedia.com/index.php/User_talk:Cariaso/D3bug --> | |
<head> | |
<meta charset="utf-8"> | |
<style> | |
.node { | |
stroke: black; | |
} | |
.link { | |
stroke: #999; | |
stroke-opacity: .6; | |
} | |
.nodelabel { | |
pointer-events: none; | |
stroke: black; | |
font-size : 12px | |
} | |
</style> | |
<title>D3 Graph</title> | |
<script type="text/javascript" src="http://cachedcommons.org/cache/jquery/1.4.2/javascripts/jquery-min.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript"> | |
var buttonBarHeight = 30, | |
redrawLag = 300, | |
w = window, | |
d = document, | |
e = d.documentElement, | |
g = d.getElementsByTagName("body")[0], | |
x = (w.innerWidth || e.clientWidth || g.clientWidth || 500)-100, | |
y = (w.innerHeight|| e.clientHeight|| g.clientHeight || 400)-100, | |
width = x, | |
height = y; | |
var delay = (function(){ | |
var timer = 0; | |
return function(callback, ms){ | |
clearTimeout (timer); | |
timer = setTimeout(callback, ms); | |
}; | |
})(); | |
function doresize() { | |
delay(function(){ | |
x = (w.innerWidth || e.clientWidth || g.clientWidth) - 100; | |
y = (w.innerHeight|| e.clientHeight|| g.clientHeight) - 100; | |
$("svg").attr("width", x).attr("height", y-buttonBarHeight); | |
}, redrawLag); | |
}; | |
window.onresize = doresize; | |
</script></head> | |
<body> | |
<div id="chart" class="resizable"> | |
<button onclick="resetGraph();">Reset</button> | |
<button onclick="freezeGraph();">Freeze</button> | |
<span style="color:red"><b>d</b></span>elete | |
<script type="text/javascript"> | |
var graph = { | |
nodes:[ | |
{nodeName:"gs145", group:1, size:120, color:"#FFFFD0"}, | |
{nodeName:"rs12255372(T;T)", group:1, size:105, color:"#FF9090", gene:"TCF7L2"}, | |
{nodeName:"Breast cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Prostate cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Type-2 diabetes", group:2, size:20, color:"blue"}, | |
{nodeName:"rs6983267(G;G)", group:1, size:96, color:"#FF9090"}, | |
{nodeName:"23andMe/SNPs", group:2, size:20, color:"blue"}, | |
{nodeName:"Bladder cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Colon cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Colorectal cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Coriell Personalized Medicine Collaborative", group:2, size:20, color:"blue"}, | |
{nodeName:"Liver cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"Lung cancer", group:2, size:20, color:"blue"}, | |
{nodeName:"rs2981582(T;T)", group:1, size:96, color:"#FF9090", gene:"FGFR2"}, | |
{nodeName:"gs192", group:1, size:93, color:"#FFFFD0"}, | |
{nodeName:"Homocystinuria", group:2, size:20, color:"blue"}, | |
{nodeName:"gs227", group:1, size:90, color:"#FFFFD0"}, | |
{nodeName:"Taste", group:2, size:20, color:"blue"}, | |
{nodeName:"rs3803662(T;T)", group:1, size:90, color:"#FF9090", gene:"LOC643714"}, | |
{nodeName:"rs16969968(A;A)", group:1, size:90, color:"#FF9090", gene:"CHRNA5"}, | |
{nodeName:"Addiction", group:2, size:20, color:"blue"}, | |
{nodeName:"Cholinesterase Inhibitors", group:2, size:20, color:"blue"}, | |
{nodeName:"Chronic obstructive pulmonary disease", group:2, size:20, color:"blue"}, | |
{nodeName:"ClinVar", group:2, size:20, color:"blue"}, | |
{nodeName:"Nicotine dependence", group:2, size:20, color:"blue"}, | |
{nodeName:"rs17602729(C;T)", group:1, size:90, color:"#FF9090", gene:"AMPD1"}, | |
{nodeName:"Coronary artery disease", group:2, size:20, color:"blue"}, | |
{nodeName:"rs2237717(T;T)", group:1, size:90, color:"#FF9090", gene:"MET"}, | |
], | |
links:[ | |
{source:1, target:2, value:1}, | |
{source:1, target:3, value:1}, | |
{source:1, target:4, value:1}, | |
{source:5, target:6, value:1}, | |
{source:5, target:7, value:1}, | |
{source:5, target:8, value:1}, | |
{source:5, target:9, value:1}, | |
{source:5, target:10, value:1}, | |
{source:5, target:11, value:1}, | |
{source:5, target:12, value:1}, | |
{source:5, target:13, value:1}, | |
{source:5, target:3, value:1}, | |
{source:14, target:2, value:1}, | |
{source:14, target:11, value:1}, | |
{source:15, target:16, value:1}, | |
{source:17, target:18, value:1}, | |
{source:19, target:2, value:1}, | |
{source:20, target:21, value:1}, | |
{source:20, target:22, value:1}, | |
{source:20, target:23, value:1}, | |
{source:20, target:24, value:1}, | |
{source:20, target:13, value:1}, | |
{source:20, target:25, value:1}, | |
{source:26, target:24, value:1}, | |
{source:26, target:27, value:1}, | |
], | |
}; | |
var xscale = d3.scale.linear() | |
.domain([0, width]) | |
.range([0, width]); | |
var yscale = d3.scale.linear() | |
.domain([0, height]) | |
.range([height, 0]); | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", x) | |
.attr("height", y-buttonBarHeight) | |
.call(d3.behavior.zoom() | |
.x(xscale).y(yscale).scaleExtent([0.5, 8]) | |
.on("zoom", rescale)) | |
; | |
var force = d3.layout.force() | |
.alpha(100) | |
.charge(-120) | |
.linkDistance(30) | |
.size([width, height]) | |
.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("g") | |
.attr("class", "node") | |
.attr("stroke", function(d) { return d.color; }) | |
.call(force.drag); | |
// for a colored circle | |
node.append("circle") | |
.attr("r", function(d) { return d.size/5; }) | |
.style("fill", function(d) { return d.color; }) | |
// for an image | |
//node.append("image") | |
// .attr("xlink:href", "https://github.com/favicon.ico") | |
// .attr("x", -8) | |
// .attr("y", -8) | |
// .attr("width", 16) | |
// .attr("height", 16); | |
node.append("svg:text") | |
.attr("class","nodelabel") | |
.attr("dx", 5) | |
// .attr("stroke", "black") | |
.text(function(d) { return d.nodeName }) | |
; | |
//var texts = svg.selectAll("text.label") | |
// .data(graph.nodes) | |
// .enter().append("text") | |
// .text(function(d) { return d.nodeName; }) | |
// ; | |
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
// node.attr("cx", function(d) { return d.x; }) | |
// .attr("cy", function(d) { return d.y; }); | |
// texts.attr("transform", function(d) { | |
// return "translate(" + d.x + "," + d.y + ")"; | |
// }); | |
}); | |
var frozen = false; | |
function resetGraph() { | |
for (v in graph.nodes) { | |
graph.nodes[v].x = NaN; | |
graph.nodes[v].y = NaN; | |
graph.nodes[v].px = NaN; | |
graph.nodes[v].py = NaN; | |
} | |
force.start() | |
frozen = false; | |
} | |
function freezeGraph() { | |
if (frozen) { | |
force.resume(); | |
frozen = false; | |
} else { | |
force.stop(); | |
frozen = true; | |
} | |
} | |
function rescale() { | |
var trans = d3.event.translate; | |
var scale = d3.event.scale; | |
var mouse = d3.mouse(this); | |
// svg.attr("transform", | |
// "translate(" + trans + ")" | |
// + " scale(" + scale + ")" | |
// ); | |
link.attr("transform", | |
"translate(" + trans + ")" | |
+ " scale(" + scale + ")" | |
); | |
// node.attr("transform", | |
// "translate(" + trans + ")" | |
// + " scale(" + scale + ")" | |
// ); | |
// node.attr("transform",function(d,i) { | |
// if (i == 3 || i == 5) { | |
// console.log(['d', d.x, d.y, 's', scale]); | |
// console.log(['t', trans[0], trans[1]]); | |
// console.log([i, [trans[0] + mouse[0]- d.x], [trans[1] + mouse[1]- d.y]]); | |
// return "translate(" + (trans[0] - mouse[0]+ d.x) + "," + (d.y)+") scale("+scale+")"; | |
// } | |
//}); | |
// texts.attr("transform", | |
// "translate(" + trans + ")" | |
// + " scale(" + scale + ")" | |
// ); | |
// svg.selectAll(".label").attr("transform", | |
// "translate(" + trans + ")" | |
// + " scale(" + scale + ")" | |
// ); | |
force.start(); | |
} | |
</script> | |
</div> | |
</body> | |
</html> |
If you need only edge zoom, use this for your zoom event:
force.charge(-3000*d3.event.scale);
force.start();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm afraid is not possible to zoom graph without zooming the labels.
You can try to play with
charge
, though:http://plnkr.co/edit/cDrRQwcMOmmJmHlL6DF2?p=preview