The VisDock toolkit has been integrated into the Collision Detection example built with D3.js (found here) by Mike Bostock. When the mouse pointer tool is selected, the particles will move away from the mouse pointer. When other Selection/Navagation Tools are selected, the particles will not respond to the mouse pointer. For more information about VisDock, cick on the link.
xxxxxxxxxx
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link href="https://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.css" rel="stylesheet" type="text/css"/>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://rawgithub.com/visdockhub/newvisdock/master/master/visdock.js"></script>
<script src="https://rawgithub.com/visdockhub/newvisdock/master/master/2d.js"></script>
<script src="https://rawgithub.com/visdockhub/newvisdock/master/master/intersectionutilities.js"></script>
<script src="https://rawgithub.com/visdockhub/newvisdock/master/master/visdock.utils.js"></script>
<style type="text/css">
circle {
stroke: #000;
stroke-opacity: .5;
}
</style>
</head>
<body>
<div id="body">
<div id="footer">
Collision Detection
<div class="hint">move the mouse to repel nodes</div>
</div>
</div>
<script type="text/javascript">
var w = 1280,
h = 800;
VisDock.init("body", {width: 1000, height: 700});
AnnotatedByData.layerTypes = [".Circ"]
var viewport = VisDock.getViewport();
var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),
color = d3.scale.category10();
var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) { return i ? 0 : -2000; })
.nodes(nodes)
.size([w, h]);
var root = nodes[0];
root.radius = 0;
root.fixed = true;
force.start();
var svg = viewport
Panel.x -= 150;
Panel.y -= 100;
Panel.setTransform();
svg.selectAll("circle")
.data(nodes.slice(1))
.enter().append("svg:circle")
.attr("class", "Circ")
.attr("r", function(d) { return d.radius - 2; })
.style("fill", function(d, i) { return color(i % 3); });
force.on("tick", function(e) {
VisDock.startChrome();
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length;
while (++i < n) {
q.visit(collide(nodes[i]));
}
var id = 0;
svg.selectAll(".Circ")
.attr("id", function(){
return "_c"+id++;
})
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
var layers = d3.selectAll(".VisDockEllipseLayer")[0]
for (var i = 0; i < layers.length; i++){
var id = layers[i].getAttributeNS(null, "id")
layers[i].setAttributeNS(null, "cx", d3.select("#_" + id).attr("cx"))
layers[i].setAttributeNS(null, "cy", d3.select("#_" + id).attr("cy"))
}
AnnotatedByData.update();
VisDock.finishChrome();
});
svg.on("mousemove", function() {
var p1 = d3.mouse(this);
root.px = p1[0];
root.py = p1[1];
force.resume();
});
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
};
}
VisDock.eventHandler = {
getHitsPolygon: function(points, inclusive){
var shapebound = new createPolygon(points);
return shapebound.intersectEllipse(d3.selectAll(".Circ")[0], inclusive)
},
getHitsEllipse: function(points, inclusive){
var shapebound = new createEllipse(points);
return shapebound.intersectEllipse(d3.selectAll(".Circ")[0], inclusive)
},
getHitsLine: function(points, inclusive){
var shapebound = new createLine(points);
return shapebound.intersectEllipse(d3.selectAll(".Circ")[0], inclusive)
},
setColor: function(hits){
QueryManager.layers[num - 1] = [];
for (var i=0;i<hits.length;i++){
var r = hits[i].getAttributeNS(null, "r")
var cx = hits[i].getAttributeNS(null, "cx")
var cy = hits[i].getAttributeNS(null, "cy")
QueryManager.layers[num - 1][i] = d3.select(hits[i].parentNode).append("circle")
.attr("r", r).attr("style", "fill: " + VisDock.color[num - 1] + "; opacity: 1; pointer-events: none")
.attr("cx", cx).attr("cy", cy)
.attr("id", hits[i].getAttributeNS(null, "id").split("_")[1])
.attr("class", "VisDockEllipseLayer")
}
},
changeColor: function(color, query, index){
var visibility = VisDock.utils.getQueryVisibility(index);
for (var i=0;i<query.length;i++){
query[i].attr("style","opacity:" + visibility + ";fill: " +color)
}
},
changeVisibility: function(vis, query, index){
var color = VisDock.utils.getQueryColor(index);
for (var i=0;i<query.length;i++){
query[i].attr("style","opacity:" + vis + ";fill: " +color)
}
},
removeColor: function(hits, index){
for (var i=0;i<hits.length;i++){
hits[i].remove();
}
}
}
BirdView.init(viewport, 1000, 700)
d3.select(self.frameElement).style("width", "1280px");
d3.select(self.frameElement).style("height", "800px");
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.js to a secure url
Modified http://rawgithub.com/VisDockHub/NewVisDock/master/master/2D.js to a secure url
Modified http://rawgithub.com/VisDockHub/NewVisDock/master/master/IntersectionUtilities.js to a secure url
Modified http://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.utils.js to a secure url
https://d3js.org/d3.v3.min.js
https://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.js
https://rawgithub.com/VisDockHub/NewVisDock/master/master/2D.js
https://rawgithub.com/VisDockHub/NewVisDock/master/master/IntersectionUtilities.js
https://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.utils.js