Commit | Line | Data |
6afcd813 |
1 | function getTextPath() { |
2 | var currpath = window.location.pathname |
3 | if( currpath.lastIndexOf('/') == currpath.length - 1 ) { |
4 | currpath = currpath.slice( 0, currpath.length - 1) |
5 | }; |
6 | var path_elements = currpath.split('/'); |
7 | var textid = path_elements.pop(); |
8 | var basepath = path_elements.join( '/' ); |
9 | var path_parts = [ basepath, textid ]; |
10 | return path_parts; |
b28e606e |
11 | } |
12 | |
13 | function svgLoaded() { |
14 | // some initial scaling |
15 | var svg_element = $('#svgbasics').children('svg'); |
16 | var svg_graph = svg_element.svg().svg('get').root(); |
17 | var svg_vbwidth = svg_graph.viewBox.baseVal.width; |
18 | var svg_vbheight = svg_graph.viewBox.baseVal.height; |
19 | var scroll_padding = $('#graph_container').width(); |
20 | // (Use attr('width') to set width attr, otherwise style="width: npx;" is set.) |
21 | var svg_element_width = svg_vbwidth/svg_vbheight * parseInt(svg_element.attr('height')); |
22 | svg_element_width += scroll_padding; |
23 | svg_element.attr( 'width', svg_element_width ); |
24 | $('ellipse').attr( {stroke:'black', fill:'#fff'} ); |
25 | } |
26 | |
27 | function svgEnlargementLoaded() { |
28 | // some initial scaling |
29 | var svg_element = $('#svgenlargement').children('svg'); |
30 | var svg_graph = svg_element.svg().svg('get').root() |
31 | var svg_vbwidth = svg_graph.viewBox.baseVal.width; |
32 | var svg_vbheight = svg_graph.viewBox.baseVal.height; |
33 | var scroll_padding = $('#enlargement_container').width(); |
34 | // (Use attr('width') to set width attr, otherwise style="width: npx;" is set.) |
35 | var svg_element_width = svg_vbwidth/svg_vbheight * parseInt(svg_element.attr('height')); |
36 | svg_element_width += scroll_padding; |
37 | svg_element.attr( 'width', svg_element_width ); |
6afcd813 |
38 | $('ellipse').attr({ |
39 | stroke: 'black', |
40 | fill: '#fff' |
41 | }); |
b28e606e |
42 | var svg_height = parseInt( $('#svgenlargement').height() ); |
43 | scroll_enlargement_ratio = svg_height/svg_vbheight; |
6afcd813 |
44 | add_relations(); |
45 | } |
46 | |
47 | function add_relations() { |
48 | var pathparts = getTextPath(); |
49 | $.getJSON( pathparts[0] + '/definitions', function(data) { |
50 | var rel_types = data.types.sort(); |
51 | var pathparts = getTextPath(); |
52 | $.getJSON( pathparts[0] + '/' + pathparts[1] + '/relationships', |
53 | function(data) { |
54 | $.each(data, function( index, rel_info ) { |
55 | var type_index = $.inArray(rel_info.type, rel_types); |
56 | if( type_index != -1 ) { |
6afcd813 |
57 | relation_manager.create( rel_info.source, rel_info.target, type_index ); |
6afcd813 |
58 | } |
59 | }) |
60 | }); |
61 | }); |
b28e606e |
62 | } |
63 | |
64 | function get_ellipse( node_id ) { |
65 | return $('#svgenlargement .node').children('title').filter( function(index) { |
66 | return $(this).text() == node_id; |
67 | }).siblings('ellipse'); |
68 | } |
69 | |
70 | function get_node_obj( node_id ) { |
71 | return get_ellipse( node_id ).data( 'node_obj' ); |
72 | } |
73 | |
74 | function get_edge( edge_id ) { |
75 | return $('#svgenlargement .edge').filter( function(index) { |
76 | return $(this).children( 'title' ).text() == $('<div/>').html(edge_id).text() ; |
77 | }); |
78 | } |
79 | |
80 | function node_obj(ellipse) { |
81 | this.ellipse = ellipse; |
82 | var self = this; |
83 | |
84 | this.x = 0; |
85 | this.y = 0; |
86 | this.dx = 0; |
87 | this.dy = 0; |
88 | this.node_elements = node_elements_for(self.ellipse); |
89 | |
90 | this.get_id = function() { |
91 | return self.ellipse.siblings('title').text() |
92 | } |
93 | |
94 | this.set_draggable = function( draggable ) { |
95 | if( draggable ) { |
96 | self.ellipse.attr( {stroke:'black', fill:'#fff'} ); |
97 | self.ellipse.mousedown( this.mousedown_listener ); |
98 | self.ellipse.hover( this.enter_node, this.leave_node ); |
99 | } else { |
100 | self.ellipse.unbind('mouseenter').unbind('mouseleave').unbind('mousedown'); |
101 | self.ellipse.attr( {stroke:'green', fill:'#b3f36d'} ); |
102 | } |
103 | } |
104 | |
105 | this.mousedown_listener = function(evt) { |
106 | evt.stopPropagation(); |
107 | self.x = evt.clientX; |
108 | self.y = evt.clientY; |
109 | $('body').mousemove( self.mousemove_listener ); |
110 | $('body').mouseup( self.mouseup_listener ); |
111 | self.ellipse.unbind('mouseenter').unbind('mouseleave') |
112 | self.ellipse.attr( 'fill', '#ff66ff' ); |
113 | first_node_g_element = $("#svgenlargement g .node" ).filter( ":first" ); |
114 | if( first_node_g_element.attr('id') !== self.get_g().attr('id') ) { self.get_g().insertBefore( first_node_g_element ) }; |
115 | } |
116 | |
117 | this.mousemove_listener = function(evt) { |
15000820 |
118 | // magnification on workspace lock temporarily disabled |
119 | // self.dx = (evt.clientX - self.x) / mousemove_enlargement_ratio; |
120 | // self.dy = (evt.clientY - self.y) / mousemove_enlargement_ratio; |
121 | self.dx = (evt.clientX - self.x) / scroll_enlargement_ratio; |
122 | self.dy = (evt.clientY - self.y) / scroll_enlargement_ratio; |
b28e606e |
123 | self.move_elements(); |
124 | } |
125 | |
126 | this.mouseup_listener = function(evt) { |
127 | if( $('ellipse[fill="#ffccff"]').size() > 0 ) { |
128 | var source_node_id = self.ellipse.siblings('title').text(); |
129 | var target_node_id = $('ellipse[fill="#ffccff"]').siblings("title").text(); |
130 | $('#source_node_id').val( source_node_id ); |
131 | $('#target_node_id').val( target_node_id ); |
132 | $('#dialog-form').dialog( 'open' ); |
133 | }; |
134 | $('body').unbind('mousemove'); |
135 | $('body').unbind('mouseup'); |
136 | self.ellipse.attr( 'fill', '#fff' ); |
137 | self.ellipse.hover( self.enter_node, self.leave_node ); |
138 | self.reset_elements(); |
139 | } |
140 | |
141 | this.cpos = function() { |
142 | return { x: self.ellipse.attr('cx'), y: self.ellipse.attr('cy') }; |
143 | } |
144 | |
145 | this.get_g = function() { |
146 | return self.ellipse.parent('g'); |
147 | } |
148 | |
149 | this.enter_node = function(evt) { |
150 | self.ellipse.attr( 'fill', '#ffccff' ); |
151 | } |
152 | |
153 | this.leave_node = function(evt) { |
154 | self.ellipse.attr( 'fill', '#fff' ); |
155 | } |
156 | |
157 | this.greyout_edges = function() { |
158 | $.each( self.node_elements, function(index, value) { |
159 | value.grey_out('.edge'); |
160 | }); |
161 | } |
162 | |
163 | this.ungreyout_edges = function() { |
164 | $.each( self.node_elements, function(index, value) { |
165 | value.un_grey_out('.edge'); |
166 | }); |
167 | } |
168 | |
169 | this.move_elements = function() { |
170 | $.each( self.node_elements, function(index, value) { |
171 | value.move(self.dx,self.dy); |
172 | }); |
173 | } |
174 | |
175 | this.reset_elements = function() { |
176 | $.each( self.node_elements, function(index, value) { |
177 | value.reset(); |
178 | }); |
179 | } |
180 | |
181 | this.update_elements = function() { |
182 | self.node_elements = node_elements_for(self.ellipse); |
183 | } |
184 | |
185 | self.set_draggable( true ); |
186 | } |
187 | |
188 | function svgshape( shape_element ) { |
189 | this.shape = shape_element; |
190 | this.move = function(dx,dy) { |
191 | this.shape.attr( "transform", "translate(" + dx + " " + dy + ")" ); |
192 | } |
193 | this.reset = function() { |
194 | this.shape.attr( "transform", "translate( 0, 0 )" ); |
195 | } |
196 | this.grey_out = function(filter) { |
197 | if( this.shape.parent(filter).size() != 0 ) { |
198 | this.shape.attr({'stroke':'#e5e5e5', 'fill':'#e5e5e5'}); |
199 | } |
200 | } |
201 | this.un_grey_out = function(filter) { |
202 | if( this.shape.parent(filter).size() != 0 ) { |
203 | this.shape.attr({'stroke':'#000000', 'fill':'#000000'}); |
204 | } |
205 | } |
206 | } |
207 | |
208 | function svgpath( path_element, svg_element ) { |
209 | this.svg_element = svg_element; |
210 | this.path = path_element; |
211 | this.x = this.path.x; |
212 | this.y = this.path.y; |
213 | this.move = function(dx,dy) { |
214 | this.path.x = this.x + dx; |
215 | this.path.y = this.y + dy; |
216 | } |
217 | this.reset = function() { |
218 | this.path.x = this.x; |
219 | this.path.y = this.y; |
220 | } |
221 | this.grey_out = function(filter) { |
222 | if( this.svg_element.parent(filter).size() != 0 ) { |
223 | this.svg_element.attr('stroke', '#e5e5e5'); |
224 | this.svg_element.siblings('text').attr('fill', '#e5e5e5'); |
225 | } |
226 | } |
227 | this.un_grey_out = function(filter) { |
228 | if( this.svg_element.parent(filter).size() != 0 ) { |
229 | this.svg_element.attr('stroke', '#000000'); |
230 | this.svg_element.siblings('text').attr('fill', '#000000'); |
231 | } |
232 | } |
233 | } |
234 | |
235 | function node_elements_for( ellipse ) { |
236 | node_elements = get_edge_elements_for( ellipse ); |
237 | node_elements.push( new svgshape( ellipse.siblings('text') ) ); |
238 | node_elements.push( new svgshape( ellipse ) ); |
239 | return node_elements; |
240 | } |
241 | |
242 | function get_edge_elements_for( ellipse ) { |
243 | edge_elements = new Array(); |
244 | node_id = ellipse.siblings('title').text(); |
245 | edge_in_pattern = new RegExp( node_id + '$' ); |
246 | edge_out_pattern = new RegExp( '^' + node_id ); |
247 | $.each( $('#svgenlargement .edge,#svgenlargement .relation').children('title'), function(index) { |
248 | title = $(this).text(); |
249 | if( edge_in_pattern.test(title) ) { |
250 | polygon = $(this).siblings('polygon'); |
251 | if( polygon.size() > 0 ) { |
252 | edge_elements.push( new svgshape( polygon ) ); |
253 | } |
254 | path_segments = $(this).siblings('path')[0].pathSegList; |
255 | edge_elements.push( new svgpath( path_segments.getItem(path_segments.numberOfItems - 1), $(this).siblings('path') ) ); |
256 | } |
257 | if( edge_out_pattern.test(title) ) { |
258 | path_segments = $(this).siblings('path')[0].pathSegList; |
259 | edge_elements.push( new svgpath( path_segments.getItem(0), $(this).siblings('path') ) ); |
260 | } |
261 | }); |
262 | return edge_elements; |
263 | } |
264 | |
265 | function relation_factory() { |
266 | var self = this; |
267 | this.color_memo = null; |
268 | //TODO: colors hard coded for now |
269 | this.temp_color = '#FFA14F'; |
270 | this.relation_colors = [ "#5CCCCC", "#67E667", "#F9FE72", "#6B90D4", "#FF7673", "#E467B3", "#AA67D5", "#8370D8", "#FFC173" ]; |
271 | |
272 | this.create_temporary = function( source_node_id, target_node_id ) { |
273 | var relation = $('#svgenlargement .relation').filter( function(index) { |
274 | var relation_id = $(this).children('title').text(); |
275 | if( ( relation_id == ( source_node_id + '->' + target_node_id ) ) || ( relation_id == ( target_node_id + '->' + source_node_id ) ) ) { |
276 | return true; |
277 | } |
278 | } ); |
279 | if( relation.size() == 0 ) { |
280 | draw_relation( source_node_id, target_node_id, self.temp_color ); |
281 | } else { |
282 | self.color_memo = relation.children('path').attr( 'stroke' ); |
283 | relation.children('path').attr( 'stroke', self.temp_color ); |
284 | } |
285 | } |
286 | this.remove_temporary = function() { |
287 | var path_element = $('#svgenlargement .relation').children('path[stroke="' + self.temp_color + '"]'); |
288 | if( self.color_memo != null ) { |
289 | path_element.attr( 'stroke', self.color_memo ); |
290 | self.color_memo = null; |
291 | } else { |
292 | path_element.parent('g').remove(); |
293 | } |
294 | } |
295 | this.create = function( source_node_id, target_node_id, color_index ) { |
296 | //TODO: Protect from (color_)index out of bound.. |
297 | var relation_color = self.relation_colors[ color_index ]; |
298 | draw_relation( source_node_id, target_node_id, relation_color ); |
6afcd813 |
299 | var source_node = get_node_obj( source_node_id ); |
300 | var target_node = get_node_obj( target_node_id ); |
301 | if( source_node != null ) { source_node.update_elements() }; |
302 | if( target_node != null ) { target_node.update_elements() }; |
b28e606e |
303 | } |
304 | this.remove = function( source_node_id, target_id ) { |
305 | //TODO (When needed) |
306 | console.log( "Unsupported function node_obj.remove()." ); |
307 | } |
308 | } |
309 | |
310 | function draw_relation( source_id, target_id, relation_color ) { |
311 | var source_ellipse = get_ellipse( source_id ); |
312 | var target_ellipse = get_ellipse( target_id ); |
313 | var svg = $('#svgenlargement').children('svg').svg().svg('get'); |
314 | var path = svg.createPath(); |
315 | var sx = parseInt( source_ellipse.attr('cx') ); |
316 | var rx = parseInt( source_ellipse.attr('rx') ); |
317 | var sy = parseInt( source_ellipse.attr('cy') ); |
318 | var ex = parseInt( target_ellipse.attr('cx') ); |
319 | var ey = parseInt( target_ellipse.attr('cy') ); |
320 | var relation = svg.group( $("#svgenlargement svg g"), {'class':'relation'} ); |
321 | svg.title( relation, source_id + '->' + target_id ); |
322 | svg.path( relation, path.move( sx, sy ).curveC( sx + (2*rx), sy, ex + (2*rx), ey, ex, ey ), {fill: 'none', stroke: relation_color, strokeWidth: 4}); |
323 | var relation_element = $('#svgenlargement .relation').filter( ':last' ); |
324 | relation_element.insertBefore( $('#svgenlargement g g').filter(':first') ); |
325 | } |
326 | |
327 | $(document).ready(function () { |
328 | |
329 | relation_manager = new relation_factory(); |
330 | |
331 | scroll_ratio = $('#enlargement').height() / $('#graph').height(); |
332 | |
333 | $('#graph').mousedown(function (event) { |
334 | $(this) |
335 | .data('down', true) |
336 | .data('x', event.clientX) |
337 | .data('scrollLeft', this.scrollLeft); |
338 | return false; |
339 | }).mouseup(function (event) { |
340 | $(this).data('down', false); |
341 | }).mousemove(function (event) { |
342 | if ($(this).data('down') == true ) { |
343 | if ( $('#update_workspace_button').data('locked') != true ) { |
344 | var scroll_left = $(this).data('scrollLeft') + $(this).data('x') - event.clientX; |
345 | this.scrollLeft = scroll_left; |
346 | var enlarged_scroll_left = scroll_left * scroll_ratio; |
347 | $('#enlargement').scrollLeft( enlarged_scroll_left ); |
348 | color_enlarged(); |
349 | } |
350 | } |
351 | }).mousewheel(function (event, delta) { |
352 | if ( $('#update_workspace_button').data('locked') != true ) { |
353 | var scroll_left = delta * 30; |
354 | this.scrollLeft -= scroll_left; |
355 | var enlarged_scroll_left = $('#enlargement').scrollLeft(); |
356 | enlarged_scroll_left -= (scroll_left * scroll_ratio); |
357 | $('#enlargement').scrollLeft( enlarged_scroll_left ); |
358 | color_enlarged(); |
359 | } |
360 | }).css({ |
361 | 'overflow' : 'hidden', |
362 | 'cursor' : '-moz-grab' |
363 | }); |
364 | |
365 | |
366 | $( "#dialog-form" ).dialog({ |
367 | autoOpen: false, |
368 | height: 270, |
369 | width: 290, |
370 | modal: true, |
371 | buttons: { |
372 | "Ok": function() { |
373 | $('#status').empty(); |
374 | form_values = $('#collapse_node_form').serialize() |
6afcd813 |
375 | pathparts = getTextPath(); |
376 | ncpath = pathparts[0] + '/' + pathparts[1] + '/relationship'; |
b28e606e |
377 | var jqjson = $.post( ncpath, form_values, function(data) { |
378 | $.each( data, function(item, source_target) { |
379 | relation_manager.create( source_target[0], source_target[1], $('#rel_type').attr('selectedIndex') ); |
380 | }); |
381 | relation_manager.remove_temporary(); |
382 | $( "#dialog-form" ).dialog( "close" ); |
383 | }, 'json'); |
384 | }, |
385 | Cancel: function() { |
386 | relation_manager.remove_temporary(); |
387 | $( this ).dialog( "close" ); |
388 | } |
389 | }, |
390 | create: function(event, ui) { |
391 | $(this).data( 'relation_drawn', false ); |
392 | //TODO? Err handling? |
6afcd813 |
393 | var pathparts = getTextPath(); |
394 | var jqjson = $.getJSON( pathparts[0] + '/definitions', function(data) { |
b28e606e |
395 | var types = data.types.sort(); |
396 | $.each( types, function(index, value) { |
397 | $('#rel_type').append( $('<option>').attr( "value", value ).text(value) ); |
398 | $('#keymaplist').append( $('<li>').css( "border-color", relation_manager.relation_colors[index] ).text(value) ); |
399 | }); |
400 | var scopes = data.scopes; |
401 | $.each( scopes, function(index, value) { |
402 | $('#scope').append( $('<option>').attr( "value", value ).text(value) ); |
403 | }); |
404 | }); |
405 | }, |
406 | open: function() { |
407 | relation_manager.create_temporary( $('#source_node_id').val(), $('#target_node_id').val() ); |
408 | $(".ui-widget-overlay").css("background", "none"); |
409 | $("#dialog_overlay").show(); |
410 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
411 | $("#dialog_overlay").width( $("#enlargement_container").width() ); |
412 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
413 | }, |
414 | close: function() { |
415 | $( '#status' ).empty(); |
416 | $("#dialog_overlay").hide(); |
417 | } |
418 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
419 | if( ( ajaxSettings.url.split("?")[0] == 'set_relationship' ) && jqXHR.status == 403 ) { |
420 | $('#status').append( '<p class="error">The relationship can not be made in this way between these nodes.</p>' ); |
421 | } |
422 | } ); |
423 | |
424 | $('#update_workspace_button').click( function() { |
425 | var svg_enlargement = $('#svgenlargement').svg().svg('get').root(); |
426 | if( $(this).data('locked')==true) { |
427 | $.each( ellipses_in_magnifier, function( index, ellipse ) { |
428 | ellipse.data( 'node_obj' ).ungreyout_edges(); |
429 | ellipse.data( 'node_obj' ).set_draggable( false ); |
430 | ellipse.data( 'node_obj', null ); |
431 | }) |
15000820 |
432 | // magnification on workspace lock temporarily disabled |
433 | // svg_enlargement.children[0].setAttribute( 'transform', $(this).data('transform_memo') ); |
434 | // $('#enlargement').scrollLeft( $(this).data('scrollleft_memo') ); |
b28e606e |
435 | $(this).data('locked', false); |
436 | $(this).css('background-position', '0px 0px'); |
437 | } else { |
438 | $(this).css('background-position', '0px 17px'); |
439 | var y_min = parseInt( ellipses_in_magnifier[0].attr('cy') ) - parseInt( ellipses_in_magnifier[0].attr('ry') ); |
440 | var y_max = parseInt( ellipses_in_magnifier[0].attr('cy') ) + parseInt( ellipses_in_magnifier[0].attr('ry') ); |
441 | $.each( ellipses_in_magnifier, function( index, ellipse ) { |
442 | var ny_min = parseInt( ellipse.attr('cy') ) - parseInt( ellipse.attr('ry') ); |
443 | var ny_max = parseInt( ellipse.attr('cy') ) + parseInt( ellipse.attr('ry') ); |
444 | if( ny_min < y_min ) { y_min = ny_min }; |
445 | if( ny_max > y_max ) { y_max = ny_max }; |
446 | if( ellipse.data( 'node_obj' ) == null ) { |
447 | ellipse.data( 'node_obj', new node_obj( ellipse ) ); |
448 | } else { |
449 | ellipse.data( 'node_obj' ).set_draggable( true ); |
450 | } |
451 | ellipse.data( 'node_obj' ).greyout_edges(); |
452 | }) |
15000820 |
453 | // magnification on workspace lock temporarily disabled |
454 | // var graph_frag_height = y_max - y_min ; |
455 | // var svg_enlargement_vbheight = svg_enlargement.viewBox.baseVal.height; |
456 | // var svg_enlargement_vbwidth = svg_enlargement.viewBox.baseVal.width; |
457 | // var scale = svg_enlargement_vbheight / graph_frag_height; |
458 | // mousemove_enlargement_ratio = scroll_enlargement_ratio * scale; |
459 | // var scroll_padding = $('#enlargement_container').width(); |
460 | // var scroll_scale = svg_enlargement_vbwidth / ( parseFloat( $('#svgenlargement svg').attr('width') ) - scroll_padding ); |
461 | // var vbx_of_scroll = ( $('#enlargement').scrollLeft() ) * scroll_scale; |
462 | // var translate_x = vbx_of_scroll; |
463 | // var transform = svg_enlargement.children[0].getAttribute('transform'); |
464 | // $(this).data('transform_memo', transform ); |
465 | // $(this).data('scrollleft_memo', $('#enlargement').scrollLeft() ); |
b28e606e |
466 | $(this).data('locked', true ); |
15000820 |
467 | // $('#enlargement').scrollLeft(0); |
468 | // transform = 'scale(' + scale + ') translate(' + (-1 * translate_x) + ',' + (-1 * y_min) + ')'; |
469 | // svg_enlargement.children[0].setAttribute( 'transform', transform ); |
b28e606e |
470 | } |
471 | }); |
472 | |
473 | }); |
474 | |
475 | $(window).mouseout(function (event) { |
476 | if ($('#graph').data('down')) { |
477 | try { |
478 | if (event.originalTarget.nodeName == 'BODY' || event.originalTarget.nodeName == 'HTML') { |
479 | $('#graph').data('down', false); |
480 | } |
481 | } catch (e) {} |
482 | } |
483 | }); |
484 | |
485 | function color_enlarged() { |
486 | ellipses_in_magnifier = []; |
487 | var scroll_offset = parseInt( $('#enlargement').scrollLeft() ); |
488 | var scroll_padding = $('#enlargement_container').width()/2; |
489 | $('#svgenlargement ellipse,#svgbasics ellipse' ).each( function( index ) { |
490 | var cpos_inscrollcoor = parseInt( $(this).attr('cx') ) * scroll_enlargement_ratio; |
491 | if ( ( cpos_inscrollcoor > (scroll_offset - scroll_padding) ) && ( cpos_inscrollcoor < ( scroll_offset + scroll_padding ) ) ) { |
492 | $(this).attr( {stroke:'green', fill:'#b3f36d'} ); |
493 | if( $(this).parents('#svgenlargement').size() == 1 ) { ellipses_in_magnifier.push( $(this) ) }; |
494 | } else { |
495 | $(this).attr( {stroke:'black', fill:'#fff'} ); |
496 | } |
497 | }); |
498 | } |
499 | |
500 | |
501 | |
502 | |