Skip to content

Instantly share code, notes, and snippets.

@VisDockHub
Last active August 29, 2015 13:56
Show Gist options
  • Save VisDockHub/9082328 to your computer and use it in GitHub Desktop.
Save VisDockHub/9082328 to your computer and use it in GitHub Desktop.
Binary Tree

The Binary Tree organizes hierarchical data in the tree structure with each node containing only 2 child nodes. Branches of higher hierarchy are thicker than those of lower hierarchy. Each branch is an SVG line element that represents a datapoint. When the user howers the mouse pointer over a branch, it shows all the higher branches that connect the current branch with the root of the tree. Users can use various selection tools to query these branches. The VisDock toolkit has been integrated into the Bundle Chart example built with D3.js (found here) by Peter Cook. For more information about VisDock, please cick on the link.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<link href="http://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.css" rel="stylesheet" type="text/css"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.js"></script>
<script src="http://rawgithub.com/VisDockHub/NewVisDock/master/master/2D.js"></script>
<script src="http://rawgithub.com/VisDockHub/NewVisDock/master/master/IntersectionUtilities.js"></script>
<script src="http://rawgithub.com/VisDockHub/NewVisDock/master/master/visdock.utils.js"></script>
<script>
VisDock.init("body", {width: 1000, height: 800});
var viewport = VisDock.getViewport();
/* VisDock Integrated into */
/* Original D3 Tree */
/* Copyright 2013 Peter Cook (@prcweb); Licensed MIT */
// Tree configuration
var branches = [];
var seed = {i: 0, x: 420, y: 600, a: 0, l: 130, d:0}; // a = angle, l = length, d = depth
var da = 0.5; // Angle delta
var dl = 0.8; // Length delta (factor)
var ar = 0.7; // Randomness
var maxDepth = 10;
var line_query = [];
// Tree creation functions
function branch(b) {
var end = endPt(b), daR, newB;
branches.push(b);
if (b.d === maxDepth)
return;
// Left branch
daR = ar * Math.random() - ar * 0.5;
newB = {
i: branches.length,
x: end.x,
y: end.y,
a: b.a - da + daR,
l: b.l * dl,
d: b.d + 1,
parent: b.i
};
branch(newB);
// Right branch
daR = ar * Math.random() - ar * 0.5;
newB = {
i: branches.length,
x: end.x,
y: end.y,
a: b.a + da + daR,
l: b.l * dl,
d: b.d + 1,
parent: b.i
};
branch(newB);
}
function regenerate(initialise) {
branches = [];
branch(seed);
initialise ? create() : update();
}
function endPt(b) {
// Return endpoint of branch
var x = b.x + b.l * Math.sin( b.a );
var y = b.y - b.l * Math.cos( b.a );
return {x: x, y: y};
}
// D3 functions
function x1(d) {return d.x;}
function y1(d) {return d.y;}
function x2(d) {return endPt(d).x;}
function y2(d) {return endPt(d).y;}
function highlightParents(d) {
var colour = d3.event.type === 'mouseover' ? 'green' : '#777';
var depth = d.d;
for(var i = 0; i <= depth; i++) {
d3.select('#id-'+parseInt(d.i)).style('stroke', colour);
d = branches[d.parent];
}
}
function create() {
viewport
.selectAll('line')
.data(branches)
.enter()
.append('line')
.attr('class', 'treebranches')
.attr('x1', x1)
.attr('y1', y1)
.attr('x2', x2)
.attr('y2', y2)
.style('stroke','#777')
.style('stroke-width', function(d) {return parseInt(maxDepth + 1 - d.d) + 'px';})
.attr('id', function(d) {return 'id-'+d.i;})
.on('mouseover', highlightParents)
.on('mouseout', highlightParents);
}
function update() {
viewport
.selectAll('line')
.data(branches)
.transition()
.attr('x1', x1)
.attr('y1', y1)
.attr('x2', x2)
.attr('y2', y2);
}
d3.selectAll('.regenerate')
.on('click', regenerate);
regenerate(true);
create();
VisDock.eventHandler = {
getHitsPolygon : function(points, inclusive) {
var shapebound = new createPolygon(points);
return shapebound.intersectLine(d3.selectAll(".treebranches")[0], inclusive)
},
getHitsLine : function(points, inclusive) {
var shapebound = new createLine(points);
return shapebound.intersectLine(d3.selectAll(".treebranches")[0], inclusive)
},
getHitsEllipse : function(points, inclusive) {
var shapebound = new createEllipse(points);
return shapebound.intersectLine(d3.selectAll(".treebranches")[0], inclusive)
},
setColor : function(hits) {
for (var i = 0; i < hits.length; i++) {
var sw = parseInt(maxDepth + 1 - hits[i].__data__.d + 'px')
VisDock.utils.addLineLayer(hits[i], "stroke: "+ VisDock.color[num - 1] + "; stroke-width:" + sw+"; opacity: 1", num-1);
}
},
changeColor : function(color, query, index) {
for (var i = 0; i < query.length; i++) {
var s1 = query[i][0][0].getAttributeNS(null, "style").split(";")[1]
"; "+ query[i][0][0].getAttributeNS(null, "style").split(";")[2]
query[i][0][0].setAttributeNS(null, "style", "stroke: " + color + "; " + s1)
}
},
changeVisibility : function(vis, query, index) {
for (var i = 0; i < query.length; i++) {
var style = query[i][0][0].getAttributeNS(null, "style").split("opacity")[0]
query[i][0][0].setAttributeNS(null, "style", style + "; opacity: " + vis)
}
},
removeColor : function(hits, index) {
for (var i = 0; i < hits.length; i++) {
hits[i].remove();
}
},
QueryClick : function(query, index) {
}
}
BirdView.init(viewport, 1000, 800)
d3.select(self.frameElement).style("width", "1000px")
d3.select(self.frameElement).style("height", "800px")
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment