Merging functionality added, rough round the corners.
[scpubgit/stemmaweb.git] / root / js / detach_helpers.js
1 function edges_of( ellipse ) {
2   var edges = new Array();
3   var node_id = ellipse.parent().attr('id');
4   var edge_in_pattern = new RegExp( node_id + '$' );
5   $.each( $('#svgenlargement .edge'), function(index) {
6       title = $(this).children('title').text();
7       if( title.search( node_id ) > -1 ) {
8           var edge = new Edge( $(this) );
9           edge.node_id = node_id;
10           if( edge_in_pattern.test(title) ) {
11               edge.is_incoming  = true;
12           }
13           edges.push( edge );
14       }
15   } );
16   return edges;
17 }
18
19 function Edge( g_elem ) {
20     
21     var self = this;
22     
23     this.g_elem = g_elem;
24     this.witnesses = g_elem.children('text').text().split( /,\s*/ );
25     this.is_incoming = false;
26     this.start_node_id = g_elem.children('title').text().split('-')[0];
27     this.end_node_id = g_elem.children('title').text().split('>')[1];
28     
29     this.detach_witnesses = function( witnesses_to_detach ) {
30         var detached = [];
31         var left = '';
32         var clone = null;
33         $.each( witnesses_to_detach, function( index, witness_to_detach ) {
34             witness_index = self.witnesses.indexOf( witness_to_detach );
35             if( witness_index > -1 ) {  
36                 self.witnesses.splice( witness_index, 1 );
37                 detached.push( witness_to_detach );
38             }
39         } );
40         if( detached != '' ) {
41             clone = self.clone_for( detached );
42         }
43         var remaining = self.create_label( self.witnesses );
44         if( remaining == '' ) {
45             self.g_elem.remove();
46         } else {
47             self.g_elem.children('text').text( remaining );
48         }
49         return clone;
50     }
51     
52     this.get_label = function() {
53         return self.g_elem.children('text').text();
54     }
55     
56     this.create_label = function( witnesses ) {
57         var label = '';
58         $.each( witnesses, function( index, witness ) {
59             label = label + witness + ', ';
60         } );
61         label = label.replace( /, $/, '' );
62         return label;
63     }
64     
65     this.clone_for = function( witnesses ) {
66         var label = self.create_label( witnesses );
67         var clone = g_elem.clone();
68         clone.children('text').text( label );
69         var duplicate_data = g_elem.data( 'repositioned' );
70         if( duplicate_data != null ) {
71             clone.data( 'repositioned', duplicate_data );
72         }
73         clone = new Edge( clone );        
74         clone.is_incoming = self.is_incoming;
75         return clone;
76     }
77     
78     this.attach_witnesses = function( witnesses ) {
79         self.witnesses.concat( witnesses );
80         self.g_elem.children( 'text' ).text( self.create_label( self.witnesses ) );
81         var edge_weight = 0.8 + ( 0.2 * self.witnesses.length );
82         self.g_elem.children( 'path' ).attr( 'stroke-width', edge_weight );
83         
84     }
85     
86     this.attach_endpoint = function( target_node_id ) {
87         // first let's find out if the startpoint might also be linked to the target already
88         // in that case we need to remove this edge and transfer the witnesses to the 
89         // appropriate edge of the target_node
90         $.each( edges_of( get_ellipse( target_node_id ) ), function( index, target_edge ) {
91             if( (self != null) && (self.start_node_id == target_edge.start_node_id) ) {
92                 target_edge.attach_witnesses( self.witnesses );
93                 self.g_elem.remove();
94                 self = null;
95             }
96         } );
97         // if not let's really move the end pointer towards the target node
98         if( self != null ) {
99             var polygon = self.g_elem.children( 'polygon' ); 
100             if( polygon.size() > 0 ) {
101                 var end_point_arrowhead = new svgshape( polygon );
102                 var path_segments = self.g_elem.children('path')[0].pathSegList;
103                 var edge_path = new svgpath( path_segments.getItem(path_segments.numberOfItems - 1), self.g_elem.children('path') );
104                 var target_ellipse = get_ellipse( target_node_id );
105                 var target_cx = target_ellipse.attr( 'cx' );
106                 var target_cy = target_ellipse.attr( 'cy' );
107                 var target_rx = target_ellipse.attr( 'rx' );
108                 var source_ellipse = get_ellipse( self.end_node_id );
109                 var source_cx = source_ellipse.attr( 'cx' );
110                 var source_cy = source_ellipse.attr( 'cy' );
111                 var source_rx = source_ellipse.attr( 'rx' );
112                 var dx = (target_cx - target_rx) - (source_cx - source_rx);
113                 var dy = (target_cy - source_cy);
114                 end_point_arrowhead.reposition( dx, dy );
115                 edge_path.reposition( dx, dy );
116             }
117         }
118     }
119
120     this.attach_startpoint = function( target_node_id ) {
121         // first let's find out if the endpoint might also be linked to the target already
122         // in that case we need to remove this edge and transfer the witnesses to the 
123         // appropriate edge of the target_node
124         $.each( edges_of( get_ellipse( target_node_id ) ), function( index, target_edge ) {
125             if( (self != null) && (self.end_node_id == target_edge.end_node_id) ) {
126                 target_edge.attach_witnesses( self.witnesses );
127                 self.g_elem.remove();
128                 self = null;
129             }
130         } );
131         // if not let's really move the end pointer towards the target node
132         if( self != null ) {
133             var path_segments = self.g_elem.children('path')[0].pathSegList;                
134             var edge_path = new svgpath( path_segments.getItem(0), self.g_elem.children('path') );
135             var target_ellipse = get_ellipse( target_node_id );
136             var target_cx = target_ellipse.attr( 'cx' );
137             var target_cy = target_ellipse.attr( 'cy' );
138             var target_rx = target_ellipse.attr( 'rx' );
139             var source_ellipse = get_ellipse( self.start_node_id );
140             var source_cx = source_ellipse.attr( 'cx' );
141             var source_cy = source_ellipse.attr( 'cy' );
142             var source_rx = source_ellipse.attr( 'rx' );
143             var dx = (target_cx + target_rx) - (source_cx + source_rx);
144             var dy = (target_cy - source_cy);
145             edge_path.reposition( dx, dy );
146         }
147     }
148     
149 }