summaryrefslogtreecommitdiff
path: root/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'main.js')
-rw-r--r--main.js202
1 files changed, 119 insertions, 83 deletions
diff --git a/main.js b/main.js
index 0eb433c..94e511e 100644
--- a/main.js
+++ b/main.js
@@ -12,7 +12,8 @@
var particleSystem
var canvasBackground;
-
+ var mainNode;
+ var balloonNode;
var that = {
init:function(system){
//
@@ -86,7 +87,80 @@
ctx.fill();
}
- particleSystem.eachEdge(function(edge, pt1, pt2){
+ var detectDestination = function(pt1, pt2, imageBox) {
+ var destination = {};
+ var intersectingSegment = undefined;
+ if (pt1.x != pt2.x) {
+ var lineSlope = (pt1.y - pt2.y) / (pt1.x - pt2.x);
+ var width = imageBox.width;
+ var height = imageBox.height;
+ if ((-height / 2 <= lineSlope * width / 2)
+ && (lineSlope * width / 2 <= height / 2)) {
+ if (pt1.x > pt2.x) {
+ intersectingSegment = [
+ { x: pt2.x + width / 2,
+ y: pt2.y - height / 2 },
+ { x: pt2.x + width / 2,
+ y: pt2.y + height / 2 }
+ ];
+ }
+ else {
+ intersectingSegment = [
+ { x: pt2.x - width / 2,
+ y: pt2.y - height / 2 },
+ { x: pt2.x - width / 2,
+ y: pt2.y + height / 2 }
+ ];
+ }
+ }
+ if ((-width / 2 <= (height / 2) / lineSlope)
+ && ((height / 2) / lineSlope <= width / 2)) {
+ if (pt1.y > pt2.y) {
+ intersectingSegment = [
+ { x: pt2.x - width / 2,
+ y: pt2.y + height / 2 },
+ { x: pt2.x + width / 2,
+ y: pt2.y + height / 2 }
+ ];
+ }
+ else {
+ intersectingSegment = [
+ { x: pt2.x - width / 2,
+ y: pt2.y - height / 2 },
+ { x: pt2.x + width / 2,
+ y: pt2.y - height / 2 }
+ ];
+ }
+ }
+ }
+ else {
+ intersectingSegment = (pt1.y > pt2.y) ? [
+ { x: pt2.x - width / 2,
+ y: pt2.y - height / 2 },
+ { x: pt2.x + width / 2,
+ y: pt2.y - height / 2 }
+ ] : [
+ { x: pt2.x - width / 2,
+ y: pt2.y + height / 2 },
+ { x: pt2.x + width / 2,
+ y: pt2.y + height / 2 }
+ ];
+ }
+ if (intersectingSegment) {
+ var intersectAngle = ((intersectingSegment[1].y - intersectingSegment[0].y) * (pt2.x - pt1.x))
+ - ((intersectingSegment[1].x - intersectingSegment[0].x) * (pt2.y - pt1.y));
+ var aSlope = pt1.y - intersectingSegment[0].y;
+ var bSlope = pt1.x - intersectingSegment[0].x;
+ var numerator1 = ((intersectingSegment[1].x - intersectingSegment[0].x) * aSlope)
+ - ((intersectingSegment[1].y - intersectingSegment[0].y) * bSlope);
+ var intersectSlope = numerator1 / intersectAngle;
+ destination = { x: pt1.x + (intersectSlope * (pt2.x - pt1.x)),
+ y: pt1.y + (intersectSlope * (pt2.y - pt1.y)) };
+ }
+ return destination;
+ }
+
+ var drawEdge = function(edge, pt1, pt2) {
// edge: {source:Node, target:Node, length:#, data:{}}
// pt1: {x:#, y:#} source position in screen coords
// pt2: {x:#, y:#} target position in screen coords
@@ -101,87 +175,35 @@
if (edge.data.arrow) {
if (edge.target.data.imageObject) {
- var destination = {};
- var intersectingSegment = undefined;
- if (pt1.x != pt2.x) {
- var lineSlope = (pt1.y - pt2.y) / (pt1.x - pt2.x);
- var width = edge.target.data.imageObject.width;
- var height = edge.target.data.imageObject.height;
- if ((-height / 2 <= lineSlope * width / 2)
- && (lineSlope * width / 2 <= height / 2)) {
- if (pt1.x > pt2.x) {
- intersectingSegment = [
- { x: pt2.x + width / 2,
- y: pt2.y - height / 2 },
- { x: pt2.x + width / 2,
- y: pt2.y + height / 2 }
- ];
- }
- else {
- intersectingSegment = [
- { x: pt2.x - width / 2,
- y: pt2.y - height / 2 },
- { x: pt2.x - width / 2,
- y: pt2.y + height / 2 }
- ];
- }
- }
- if ((-width / 2 <= (height / 2) / lineSlope)
- && ((height / 2) / lineSlope <= width / 2)) {
- if (pt1.y > pt2.y) {
- intersectingSegment = [
- { x: pt2.x - width / 2,
- y: pt2.y + height / 2 },
- { x: pt2.x + width / 2,
- y: pt2.y + height / 2 }
- ];
- }
- else {
- intersectingSegment = [
- { x: pt2.x - width / 2,
- y: pt2.y - height / 2 },
- { x: pt2.x + width / 2,
- y: pt2.y - height / 2 }
- ];
- }
- }
- }
- else {
- intersectingSegment = (pt1.y > pt2.y) ? [
- { x: pt2.x - width / 2,
- y: pt2.y - height / 2 },
- { x: pt2.x + width / 2,
- y: pt2.y - height / 2 }
- ] : [
- { x: pt2.x - width / 2,
- y: pt2.y + height / 2 },
- { x: pt2.x + width / 2,
- y: pt2.y + height / 2 }
- ];
- }
- if (intersectingSegment) {
- var intersectAngle = ((intersectingSegment[1].y - intersectingSegment[0].y) * (pt2.x - pt1.x))
- - ((intersectingSegment[1].x - intersectingSegment[0].x) * (pt2.y - pt1.y));
- var aSlope = pt1.y - intersectingSegment[0].y;
- var bSlope = pt1.x - intersectingSegment[0].x;
- var numerator1 = ((intersectingSegment[1].x - intersectingSegment[0].x) * aSlope)
- - ((intersectingSegment[1].y - intersectingSegment[0].y) * bSlope);
- var intersectSlope = numerator1 / intersectAngle;
- destination = { x: pt1.x + (intersectSlope * (pt2.x - pt1.x)),
- y: pt1.y + (intersectSlope * (pt2.y - pt1.y)) };
+ var destination = detectDestination(pt1, pt2, edge.target.data.imageObject);
+ if (destination) {
+ pt2 = destination;
}
}
}
- if (destination) {
- pt2 = destination;
+ var setOpacity = function(color, opacity) {
+ if (color.substring(0, 5) == 'rgba(') {
+ color = color.replace(/,[^,]*\)$/, ',' + opacity + ')');
+ }
+ return color;
+ }
+
+ if (mainNode && balloonNode) {
+ if (edge.source.data.balloon || edge.target.data.balloon ||
+ (balloonNode != mainNode
+ && particleSystem.getEdgesTo(balloonNode)[0].source == edge.target
+ && edge.source == mainNode)) {
+ ctx.strokeStyle = setOpacity(edge.target.data.color, 0.8);
+ }
}
+
ctx.lineTo(pt2.x, pt2.y);
ctx.stroke();
if (edge.data.arrow) {
drawArrow(pt1, pt2, edge.data.arrow, ctx.strokeStyle);
}
- })
+ };
var drawImage = function(image, coords, color) {
if (!image.height) {
@@ -213,10 +235,20 @@
var repositionBalloon = function(div, node) {
var topOffset = node.data.p.y - node.data.height / 2;
+ if (topOffset < 0) {
+ topOffset = 0;
+ }
if (topOffset + div.outerHeight() > $(window).height()) {
topOffset = $(window).height() - div.outerHeight();
}
- var leftOffset = node.data.p.x + node.data.width / 2 + 2;
+ var leftMargin = node.data.width / 2 + 2;
+ if (mainNode && node.data.p.x < mainNode.data.p.x) {
+ leftMargin = -leftMargin - div.outerWidth();
+ }
+ var leftOffset = node.data.p.x + leftMargin;
+ if (leftOffset < 0) {
+ leftOffset += div.outerWidth() + node.data.width + 4;
+ }
if (leftOffset + div.outerWidth() > $(window).width()) {
leftOffset -= div.outerWidth() + node.data.width + 4;
}
@@ -226,20 +258,22 @@
}
var currentZIndex = 0;
- var balloonNode = undefined;
var drawNode = function(node, pt){
// node: {mass:#, p:{x,y}, name:"", data:{}}
// pt: {x:#, y:#} node position in screen coords
+ node.data.p = pt;
node.data.zindex = currentZIndex++;
+ if (node.data.main) {
+ mainNode = node;
+ }
- if (node.data.image) {
+ if (node.data.image && node.data.width > 10) {
if (node.data.imageObject) {
node.data.imageObject.width = node.data.width;
node.data.imageObject.height = node.data.height;
drawImage(node.data.imageObject, pt, node.data.color);
- }
- else {
+ } else {
var img = new Image(node.data.width, node.data.height);
img.onload = function() {
node.data.imageObject = img;
@@ -247,8 +281,7 @@
};
img.src = '_img/' + node.data.image;
}
- }
- else {
+ } else {
var color = node.data.color || 'black';
ctx.fillStyle = color;
ctx.lineWidth = 5;
@@ -260,7 +293,6 @@
}
if (node.data.balloon) {
- node.data.p = pt;
repositionBalloon(node.data.balloon, node);
if (node.data.oldWidth) {
node.data.width = node.data.oldWidth;
@@ -272,6 +304,7 @@
}
};
+ particleSystem.eachEdge(drawEdge);
particleSystem.eachNode(drawNode);
if (balloonNode) {
var selectedDimension = Math.max((balloonNode.data.image) ? 150 : 50, balloonNode.data.width);
@@ -291,6 +324,7 @@
balloon.data('node').data.balloon = undefined;
balloon.remove();
balloon = undefined;
+ balloonNode = undefined;
}
var pos = $(canvas).offset();
_mouseP = arbor.Point(e.pageX-pos.left, e.pageY-pos.top)
@@ -307,8 +341,10 @@
balloon = $('<div>');
balloon.css({
'position': 'absolute',
- 'background': 'rgba(0,0,0,0.8)', 'color': 'red',
- 'max-width': '250px',
+ 'background': 'rgba(0,0,0,0.45)', 'color': 'red',
+ 'max-width': '150px',
+ 'max-height': '150px',
+ 'overflow': 'hidden',
'padding': '5px',
'border': 'solid 2px white',
'border-radius': '5px'