tnt.tree
Version:
TnT tree display
111 lines (92 loc) • 3.1 kB
JavaScript
var apijs = require('tnt.api');
var tree = {};
tree.diagonal = function () {
var d = function (diagonalPath) {
var source = diagonalPath.source;
var target = diagonalPath.target;
var midpointX = (source.x + target.x) / 2;
var midpointY = (source.y + target.y) / 2;
var pathData = [source, {x: target.x, y: source.y}, target];
pathData = pathData.map(d.projection());
return d.path()(pathData, radial_calc.call(this,pathData))
};
var api = apijs (d)
.getset ('projection')
.getset ('path')
var coordinateToAngle = function (coord, radius) {
var wholeAngle = 2 * Math.PI,
quarterAngle = wholeAngle / 4
var coordQuad = coord[0] >= 0 ? (coord[1] >= 0 ? 1 : 2) : (coord[1] >= 0 ? 4 : 3),
coordBaseAngle = Math.abs(Math.asin(coord[1] / radius))
// Since this is just based on the angle of the right triangle formed
// by the coordinate and the origin, each quad will have different
// offsets
var coordAngle;
switch (coordQuad) {
case 1:
coordAngle = quarterAngle - coordBaseAngle
break
case 2:
coordAngle = quarterAngle + coordBaseAngle
break
case 3:
coordAngle = 2*quarterAngle + quarterAngle - coordBaseAngle
break
case 4:
coordAngle = 3*quarterAngle + coordBaseAngle
}
return coordAngle
};
var radial_calc = function (pathData) {
var src = pathData[0];
var mid = pathData[1];
var dst = pathData[2];
var radius = Math.sqrt(src[0]*src[0] + src[1]*src[1]);
var srcAngle = coordinateToAngle(src, radius);
var midAngle = coordinateToAngle(mid, radius);
var clockwise = Math.abs(midAngle - srcAngle) > Math.PI ? midAngle <= srcAngle : midAngle > srcAngle;
return {
radius : radius,
clockwise : clockwise
};
};
return d;
};
// vertical diagonal for rect branches
tree.diagonal.vertical = function () {
var path = function(pathData, obj) {
var src = pathData[0];
var mid = pathData[1];
var dst = pathData[2];
var radius = 200000; // Number long enough
return "M" + src + " A" + [radius,radius] + " 0 0,0 " + mid + "M" + mid + "L" + dst;
};
var projection = function(d) {
return [d.y, d.x];
}
return tree.diagonal()
.path(path)
.projection(projection);
};
tree.diagonal.radial = function () {
var path = function(pathData, obj) {
var src = pathData[0];
var mid = pathData[1];
var dst = pathData[2];
var radius = obj.radius;
var clockwise = obj.clockwise;
if (clockwise) {
return "M" + src + " A" + [radius,radius] + " 0 0,0 " + mid + "M" + mid + "L" + dst;
} else {
return "M" + mid + " A" + [radius,radius] + " 0 0,0 " + src + "M" + mid + "L" + dst;
}
};
var projection = function(d) {
var r = d.y, a = (d.x - 90) / 180 * Math.PI;
return [r * Math.cos(a), r * Math.sin(a)];
};
return tree.diagonal()
.path(path)
.projection(projection)
};
module.exports = exports = tree.diagonal;