{
let data1 = data.slice(0, data.length/2);
let data2 = data.slice(data.length/2);;
let nodeR = 10;
let offset = 40;
let height = 900;
let two = new Two({
type: Two.Types.canvas,
width: width,
height: height
});
let scale1 = d3.scaleLinear()
.domain([-3, data1.length+2])
.range([0, Math.PI]);
let scale2 = d3.scaleLinear()
.domain([-3, data2.length+2])
.range([0, -Math.PI]);
let nodes = [];
let links = [];
data1.forEach((entry, i) => {
let theta = scale1(i);
let r = 200;
entry.x = r * Math.sin(theta);
entry.y = -(r * Math.cos(theta));
entry.r = nodeR;
entry.textX = (r + 20) * Math.sin(theta);
entry.textY = -((r + 20) * Math.cos(theta));
entry.theta = theta;
entry.x += offset;
entry.textX += offset;
nodes.push(entry);
//extract links
links = links.concat(entry.connections.map( (connetion) => {
return {
source: entry,
target: data.find(d => d.name === connetion)
}
}));
});
data2.forEach((entry, i) => {
let theta = scale2(i);
let r = 200;
entry.x = r * Math.sin(theta);
entry.y = -(r * Math.cos(theta));
entry.r = nodeR;
entry.textX = (r + 20) * Math.sin(theta);
entry.textY = -((r + 20) * Math.cos(theta));
entry.theta = theta;
entry.x -= offset;
entry.textX -= offset;
nodes.push(entry);
//extract links
links = links.concat(entry.connections.map( (connetion) => {
return {
source: entry,
target: data.find(d => d.name === connetion)
}
}));
});
let group = two.makeGroup();
group.translation.set(width/2, height/2);
links.forEach( link => {
let magicNr = 3.5;
let x1 = link.source.x;
let y1 = link.source.y;
let x2 = link.source.x - link.source.x / magicNr;
let y2 = link.source.y - link.source.y / magicNr;
let x3 = link.target.x - link.target.x / magicNr;
let y3 = link.target.y - link.target.y / magicNr;
let x4 = link.target.x;
let y4 = link.target.y;
let points = [
new Two.Anchor(x1, y1, null, null, x2, y2, Two.Commands.move),
new Two.Anchor(x4, y4, x3, y3, null, null, Two.Commands.curve)
];
points.forEach(p => p.relative = false);
let path = new Two.Path(points);
path.automatic = false;
path.fill = 'none';
path.stroke = 'grey';
path.opacity = 0.3;
path.linewidth = 1;
group.add(path);
});
nodes.forEach( node => {
let circle = two.makeCircle(node.x, node.y, node.r);
circle.stroke = 'grey';
let text = two.makeText(node.name, node.textX, node.textY)
text.fill = 'grey';
if (node.x >= 0) {
text.alignment = 'start';
text.rotation = node.theta - degreesToRadians(90);
} else {
text.alignment = 'end';
text.rotation = node.theta - degreesToRadians(-90);
}
group.add(circle, text);
});
two.update();
return two.renderer.domElement;
}