Skip to content

Instantly share code, notes, and snippets.

@cariaso
Created August 16, 2013 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cariaso/6254278 to your computer and use it in GitHub Desktop.
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
<!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>
@Vanuan
Copy link

Vanuan commented Sep 1, 2013

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

@Vanuan
Copy link

Vanuan commented Sep 1, 2013

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