Added multiple edges
authorveltr
Thu, 30 Aug 2012 18:07:00 +0200
changeset 31 5e37072ec7b7
parent 30 8aa0cac741a0
child 32 bb240c58c87e
Added multiple edges
client/js/paper-renderer.js
client/js/renkan-publish.js
client/render-test.html
--- a/client/js/paper-renderer.js	Wed Aug 29 16:40:31 2012 +0200
+++ b/client/js/paper-renderer.js	Thu Aug 30 18:07:00 2012 +0200
@@ -3,6 +3,10 @@
     _MARGIN_Y: 50,
     _MIN_DRAG_DISTANCE: 2,
     _NODE_RADIUS: 15,
+    _NODE_BUTTON_INNER: 16,
+    _NODE_BUTTON_OUTER: 50,
+    _EDGE_BUTTON_INNER: 3,
+    _EDGE_BUTTON_OUTER: 40,
     _NODE_FONT_SIZE: 10,
     _EDGE_FONT_SIZE: 9,
     _NODE_MAX_CHAR: 50,
@@ -287,8 +291,9 @@
     this.type = "Edge";
     this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
+    this.bundle = this.renderer.addToBundles(this);
     this.line = new paper.Path();
-    this.line.add([0,0],[0,0]);
+    this.line.add([0,0],[0,0],[0,0]);
     this.line.__representation = this;
     this.arrow = new paper.Path();
     this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
@@ -309,20 +314,25 @@
 }
 
 Rkns.Renderer.Edge.prototype.redraw = function() {
-    var _p0o = this.from_representation.paper_coords,
-        _p1o = this.to_representation.paper_coords,
-        _v = _p1o.subtract(_p0o),
+    var _p0a = this.from_representation.paper_coords,
+        _p1a = this.to_representation.paper_coords,
+        _v = _p1a.subtract(_p0a),
         _r = _v.length,
         _u = _v.divide(_r),
-        _delta = new paper.Point([- _u.y, _u.x]).multiply( 4 ),
-        _p0 = _p0o.add(_delta), /* Adding a 4 px difference */
-        _p1 = _p1o.add(_delta), /* to differentiate inbound and outbound links */
+        _group_pos = this.bundle.getPosition(this),
+        _delta = new paper.Point([- _u.y, _u.x]).multiply( 12 * _group_pos ),
+        _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
+        _p1b = _p1a.add(_delta), /* to differentiate inbound and outbound links */
         _a = _v.angle,
+        _handle = _v.divide(3),
         _color = this.model.get("created_by").get("color");
-    this.paper_coords = _p0.add(_p1).divide(2);
+    this.paper_coords = _p0b.add(_p1b).divide(2);
     this.line.strokeColor = _color;
-    this.line.segments[0].point = _p0;
-    this.line.segments[1].point = _p1;
+    this.line.segments[0].point = _p0a;
+    this.line.segments[1].point = this.paper_coords;
+    this.line.segments[1].handleIn = _handle.multiply(-1);
+    this.line.segments[1].handleOut = _handle;
+    this.line.segments[2].point = _p1a;
     this.arrow.rotate(_a - this.arrow_angle);
     this.arrow.fillColor = _color;
     this.arrow.position = this.paper_coords.subtract(_u.multiply(4));
@@ -380,6 +390,10 @@
     this.text.remove();
     this.edit_button.destroy();
     this.remove_button.destroy();
+    var _this = this;
+    this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
+        return _edge === _this;
+    });
 }
 
 /* */
@@ -595,7 +609,7 @@
 Rkns.Renderer.NodeEditButton.prototype._init = function() {
     this.renderer.node_layer.activate();
     this.type = "Node-edit-button";
-    this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS, 3 * Rkns.Renderer._NODE_RADIUS, - 90, 30, 2, 'img/edit.png');
+    this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, - 90, 30, 2, 'img/edit.png');
 }
 
 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
@@ -638,7 +652,7 @@
 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
     this.renderer.node_layer.activate();
     this.type = "Node-remove-button";
-    this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS, 3 * Rkns.Renderer._NODE_RADIUS, -210, -90, 2, 'img/remove.png');
+    this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, -210, -90, 2, 'img/remove.png');
 }
 
 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
@@ -681,7 +695,7 @@
 Rkns.Renderer.NodeLinkButton.prototype._init = function() {
     this.renderer.node_layer.activate();
     this.type = "Node-link-button";
-    this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS , 3 * Rkns.Renderer._NODE_RADIUS, 30, 150, 2, 'img/link.png');
+    this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, 30, 150, 2, 'img/link.png');
 }
 
 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
@@ -718,7 +732,7 @@
 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
     this.renderer.edge_layer.activate();
     this.type = "Edge-edit-button";
-    this.sector = Rkns.Renderer.Utils.sector(this, 5 , 2 * Rkns.Renderer._NODE_RADIUS, - 60, 60, 2, 'img/edit.png');
+    this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 60, 60, 2, 'img/edit.png');
 }
 
 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
@@ -760,7 +774,7 @@
 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
     this.renderer.edge_layer.activate();
     this.type = "Edge-remove-button";
-    this.sector = Rkns.Renderer.Utils.sector(this, 5, 2 * Rkns.Renderer._NODE_RADIUS, - 240, -120, 2, 'img/remove.png');
+    this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 240, -120, 2, 'img/remove.png');
 }
 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
     this.sector.moveTo(_pos);
@@ -814,6 +828,7 @@
     this.edge_layer = new paper.Layer();
     this.node_layer = new paper.Layer();
     this.overlay_layer = new paper.Layer();
+    this.bundles = [];
     var _tool = new paper.Tool(),
         _this = this;
     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
@@ -884,6 +899,30 @@
     + '</div>'
 );
 
+Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
+    var _bundle = Rkns._(this.bundles).find(function(_bundle) {
+        return ( 
+            ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation )
+            || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
+        );
+    });
+    if (typeof _bundle !== "undefined") {
+        _bundle.edges.push(_edgeRepr)
+    } else {
+        _bundle = {
+            from: _edgeRepr.from_representation,
+            to: _edgeRepr.to_representation,
+            edges: [ _edgeRepr ],
+            getPosition: function(_er) {
+                var _dir = (_er.from_representation === this.from) ? 1 : -1;
+                return _dir * ( Rkns._(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );
+            }
+        }
+        this.bundles.push(_bundle);
+    }
+    return _bundle;
+}
+
 Rkns.Renderer.Scene.prototype.setScale = function(_newScale) {
     this.scale = _newScale;
     this.redraw();
--- a/client/js/renkan-publish.js	Wed Aug 29 16:40:31 2012 +0200
+++ b/client/js/renkan-publish.js	Thu Aug 30 18:07:00 2012 +0200
@@ -452,8 +452,9 @@
     this.type = "Edge";
     this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
+    this.bundle = this.renderer.addToBundles(this);
     this.line = new paper.Path();
-    this.line.add([0,0],[0,0]);
+    this.line.add([0,0],[0,0],[0,0]);
     this.line.__representation = this;
     this.arrow = new paper.Path();
     this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
@@ -470,20 +471,25 @@
 }
 
 Rkns.Renderer.Edge.prototype.redraw = function() {
-    var _p0o = this.from_representation.paper_coords,
-        _p1o = this.to_representation.paper_coords,
-        _v = _p1o.subtract(_p0o),
+    var _p0a = this.from_representation.paper_coords,
+        _p1a = this.to_representation.paper_coords,
+        _v = _p1a.subtract(_p0a),
         _r = _v.length,
         _u = _v.divide(_r),
-        _delta = new paper.Point([- _u.y, _u.x]).multiply( 4 ),
-        _p0 = _p0o.add(_delta), /* Adding a 4 px difference */
-        _p1 = _p1o.add(_delta), /* to differentiate inbound and outbound links */
+        _group_pos = this.bundle.getPosition(this),
+        _delta = new paper.Point([- _u.y, _u.x]).multiply( 12 * _group_pos ),
+        _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
+        _p1b = _p1a.add(_delta), /* to differentiate inbound and outbound links */
         _a = _v.angle,
+        _handle = _v.divide(3),
         _color = this.model.get("created_by").get("color");
-    this.paper_coords = _p0.add(_p1).divide(2);
+    this.paper_coords = _p0b.add(_p1b).divide(2);
     this.line.strokeColor = _color;
-    this.line.segments[0].point = _p0;
-    this.line.segments[1].point = _p1;
+    this.line.segments[0].point = _p0a;
+    this.line.segments[1].point = this.paper_coords;
+    this.line.segments[1].handleIn = _handle.multiply(-1);
+    this.line.segments[1].handleOut = _handle;
+    this.line.segments[2].point = _p1a;
     this.arrow.rotate(_a - this.arrow_angle);
     this.arrow.fillColor = _color;
     this.arrow.position = this.paper_coords.subtract(_u.multiply(4));
@@ -531,6 +537,10 @@
     this.line.remove();
     this.arrow.remove();
     this.text.remove();
+    var _this = this;
+    this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
+        return _edge === _this;
+    });
 }
 
 /* */
@@ -664,6 +674,7 @@
     this.edge_layer = new paper.Layer();
     this.node_layer = new paper.Layer();
     this.overlay_layer = new paper.Layer();
+    this.bundles = [];
     var _tool = new paper.Tool(),
         _this = this;
     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
@@ -728,6 +739,30 @@
     + '</div>'
 );
 
+Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
+    var _bundle = Rkns._(this.bundles).find(function(_bundle) {
+        return ( 
+            ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation )
+            || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
+        );
+    });
+    if (typeof _bundle !== "undefined") {
+        _bundle.edges.push(_edgeRepr)
+    } else {
+        _bundle = {
+            from: _edgeRepr.from_representation,
+            to: _edgeRepr.to_representation,
+            edges: [ _edgeRepr ],
+            getPosition: function(_er) {
+                var _dir = (_er.from_representation === this.from) ? 1 : -1;
+                return _dir * ( Rkns._(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );
+            }
+        }
+        this.bundles.push(_bundle);
+    }
+    return _bundle;
+}
+
 Rkns.Renderer.Scene.prototype.autoScale = function() {
     if (this.renkan.project.get("nodes").length) {
         var _xx = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").x }),
--- a/client/render-test.html	Wed Aug 29 16:40:31 2012 +0200
+++ b/client/render-test.html	Thu Aug 30 18:07:00 2012 +0200
@@ -48,7 +48,7 @@
                             title: "LDT Project",
                             bin: Rkns.Bins.LdtJson,
                             project_id: "67280b1c-ff30-11e0-a82d-00145ea49a02",
-                            ldt_platform: "http://ubuntu/pf/"
+                            ldt_platform: "http://capsicum/pf/"
                         }
                     ],
                     search: [