X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=root%2Fjs%2Frelationship.js;h=a6b1bedb09207a0a2a328e9e6ebbee45269311d4;hb=5fe117bcdb6f760d1303fdd1833e0fe869775892;hp=0c346437dce29f2e988a5f6a7ecac220afcae19f;hpb=08f8443a751947e6222c425df3d118a84fa1dea1;p=scpubgit%2Fstemmaweb.git diff --git a/root/js/relationship.js b/root/js/relationship.js index 0c34643..a6b1bed 100644 --- a/root/js/relationship.js +++ b/root/js/relationship.js @@ -5,36 +5,29 @@ var start_element_height = 0; var reltypes = {}; var readingdata = {}; -function getTextPath() { - var currpath = window.location.pathname; - // Get rid of trailing slash - if( currpath.lastIndexOf('/') == currpath.length - 1 ) { - currpath = currpath.slice( 0, currpath.length - 1) - }; - // Get rid of query parameters - if( currpath.lastIndexOf('?') != -1 ) { - currpath = currpath.slice( 0, currpath.lastIndexOf('?') ); - }; - var path_elements = currpath.split('/'); - var textid = path_elements.pop(); - var basepath = path_elements.join( '/' ); - var path_parts = [ basepath, textid ]; - return path_parts; -} +jQuery.removeFromArray = function(value, arr) { + return jQuery.grep(arr, function(elem, index) { + return elem !== value; + }); +}; -function getRelativePath() { - var path_parts = getTextPath(); - return path_parts[0]; -} +function arrayUnique(array) { + var a = array.concat(); + for(var i=0; i').attr( + 'value', wit ).text( wit ) ); + }); + } // Now do the morphological properties. morphology_form( reading_info['lexemes'] ); // and then open the dialog. $('#reading-form').dialog("open"); } +function toggle_checkbox( box, value ) { + if( value == null ) { + value = false; + } + box.attr('checked', value ); +} + function morphology_form ( lexlist ) { - $('#morphology').empty(); - $.each( lexlist, function( idx, lex ) { - var morphoptions = []; - if( 'wordform_matchlist' in lex ) { - $.each( lex['wordform_matchlist'], function( tdx, tag ) { - var tagstr = stringify_wordform( tag ); - morphoptions.push( tagstr ); + if( lexlist.length ) { + $('#morph_outer').show(); + $('#morphology').empty(); + $.each( lexlist, function( idx, lex ) { + var morphoptions = []; + if( 'wordform_matchlist' in lex ) { + $.each( lex['wordform_matchlist'], function( tdx, tag ) { + var tagstr = stringify_wordform( tag ); + morphoptions.push( tagstr ); + }); + } + var formtag = 'morphology_' + idx; + var formstr = ''; + if( 'form' in lex ) { + formstr = stringify_wordform( lex['form'] ); + } + var form_morph_elements = morph_elements( + formtag, lex['string'], formstr, morphoptions ); + $.each( form_morph_elements, function( idx, el ) { + $('#morphology').append( el ); }); - } - var formtag = 'morphology_' + idx; - var formstr = ''; - if( 'form' in lex ) { - formstr = stringify_wordform( lex['form'] ); - } - var form_morph_elements = morph_elements( - formtag, lex['string'], formstr, morphoptions ); - $.each( form_morph_elements, function( idx, el ) { - $('#morphology').append( el ); }); - }); + } else { + $('#morph_outer').hide(); + } } function stringify_wordform ( tag ) { @@ -129,15 +142,18 @@ function color_inactive ( el ) { // If the reading info has any non-disambiguated lexemes, color it yellow; // otherwise color it green. $(el).attr( {stroke:'green', fill:'#b3f36d'} ); - $.each( reading_info['lexemes'], function ( idx, lex ) { - if( !lex['is_disambiguated'] ) { - $(el).attr( {stroke:'orange', fill:'#fee233'} ); - } - }); + if( reading_info ) { + $.each( reading_info['lexemes'], function ( idx, lex ) { + if( !lex['is_disambiguated'] || lex['is_disambiguated'] == 0 ) { + $(el).attr( {stroke:'orange', fill:'#fee233'} ); + } + }); + } } function relemmatize () { // Send the reading for a new lemmatization and reopen the form. + $('#relemmatize_pending').show(); var reading_id = $('#reading_id').val() ncpath = getReadingURL( reading_id ); form_values = { @@ -153,6 +169,7 @@ function relemmatize () { } else { alert("Could not relemmatize as requested: " + data['error']); } + $('#relemmatize_pending').hide(); }); } @@ -168,15 +185,11 @@ function svgEnlargementLoaded() { $("#loading_message").offset( { 'top': lo_height / 2 - $("#loading_message").height() / 2, 'left': lo_width / 2 - $("#loading_message").width() / 2 }); - //Set viewbox widht and height to widht and height of $('#svgenlargement svg'). - $('#update_workspace_button').data('locked', false); - $('#update_workspace_button').css('background-position', '0px 44px'); - //This is essential to make sure zooming and panning works properly. - var rdgpath = getTextURL( 'readings' ); - $.getJSON( rdgpath, function( data ) { - readingdata = data; - $('#svgenlargement ellipse').each( function( i, el ) { color_inactive( el ) }); - }); + if( editable ) { + // Show the update toggle button. + $('#update_workspace_button').data('locked', false); + $('#update_workspace_button').css('background-position', '0px 44px'); + } $('#svgenlargement ellipse').parent().dblclick( node_dblclick_listener ); var graph_svg = $('#svgenlargement svg'); var svg_g = $('#svgenlargement svg g')[0]; @@ -191,6 +204,8 @@ function svgEnlargementLoaded() { } } + //Set viewbox width and height to width and height of $('#svgenlargement svg'). + //This is essential to make sure zooming and panning works properly. svg_root.viewBox.baseVal.width = graph_svg.attr( 'width' ); svg_root.viewBox.baseVal.height = graph_svg.attr( 'height' ); //Now set scale and translate so svg height is about 150px and vertically centered in viewbox. @@ -205,36 +220,59 @@ function svgEnlargementLoaded() { svg_g.setAttribute('transform', transform); //used to calculate min and max zoom level: start_element_height = $('#__START__').children('ellipse')[0].getBBox().height; - add_relations( function() { $('#loading_overlay').hide(); }); + //some use of call backs to ensure succesive execution + add_relations( function() { + var rdgpath = getTextURL( 'readings' ); + $.getJSON( rdgpath, function( data ) { + readingdata = data; + $('#svgenlargement ellipse').each( function( i, el ) { color_inactive( el ) }); + // detach_node(null); + }); + $('#loading_overlay').hide(); + }); + + //initialize marquee + marquee = new Marquee(); + } function add_relations( callback_fn ) { - var basepath = getRelativePath(); + // Add the relationship types to the keymap list + $.each( relationship_types, function(index, typedef) { + li_elm = $('
  • ').css( "border-color", + relation_manager.relation_colors[index] ).text(typedef.name); + li_elm.append( $('
    ').attr('class', 'key_tip_container').append( + $('
    ').attr('class', 'key_tip').text(typedef.description) ) ); + $('#keymaplist').append( li_elm ); + }); + // Now fetch the relationships themselves and add them to the graph + var rel_types = $.map( relationship_types, function(t) { return t.name }); + // Save this list of names to the outer element data so that the relationship + // factory can access it + $('#keymap').data('relations', rel_types); var textrelpath = getTextURL( 'relationships' ); - $.getJSON( basepath + '/definitions', function(data) { - var rel_types = data.types.sort(); - $.getJSON( textrelpath, - function(data) { - $.each(data, function( index, rel_info ) { - var type_index = $.inArray(rel_info.type, rel_types); - var source_found = get_ellipse( rel_info.source ); - var target_found = get_ellipse( rel_info.target ); - if( type_index != -1 && source_found.size() && target_found.size() ) { - var relation = relation_manager.create( rel_info.source, rel_info.target, type_index ); - relation.data( 'type', rel_info.type ); - relation.data( 'scope', rel_info.scope ); - relation.data( 'note', rel_info.note ); - var node_obj = get_node_obj(rel_info.source); - node_obj.set_draggable( false ); - node_obj.ellipse.data( 'node_obj', null ); - node_obj = get_node_obj(rel_info.target); - node_obj.set_draggable( false ); - node_obj.ellipse.data( 'node_obj', null ); - } - }); - callback_fn.call(); - }); - }); + $.getJSON( textrelpath, function(data) { + $.each(data, function( index, rel_info ) { + var type_index = $.inArray(rel_info.type, rel_types); + var source_found = get_ellipse( rel_info.source ); + var target_found = get_ellipse( rel_info.target ); + if( type_index != -1 && source_found.size() && target_found.size() ) { + var relation = relation_manager.create( rel_info.source, rel_info.target, type_index ); + relation.data( 'type', rel_info.type ); + relation.data( 'scope', rel_info.scope ); + relation.data( 'note', rel_info.note ); + if( editable ) { + var node_obj = get_node_obj(rel_info.source); + node_obj.set_selectable( false ); + node_obj.ellipse.data( 'node_obj', null ); + node_obj = get_node_obj(rel_info.target); + node_obj.set_selectable( false ); + node_obj.ellipse.data( 'node_obj', null ); + } + } + }); + callback_fn.call(); + }); } function get_ellipse( node_id ) { @@ -263,16 +301,41 @@ function node_obj(ellipse) { return $(self.ellipse).parent().attr('id') } + this.set_selectable = function( clickable ) { + if( clickable && editable ) { + $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); + $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); + $(self.ellipse).parent().mousedown( function(evt) { evt.stopPropagation() } ); + $(self.ellipse).parent().click( function(evt) { + evt.stopPropagation(); + if( $('ellipse[fill="#9999ff"]').size() > 0 ) { + $('ellipse[fill="#9999ff"]').each( function() { + $(this).data( 'node_obj' ).set_draggable( false ); + } ); + } + self.set_draggable( true ) + }); + } else { + $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); + self.ellipse.siblings('text').attr('class', ''); + $(self.ellipse).parent().unbind(); + $('body').unbind('mousemove'); + $('body').unbind('mouseup'); + } + } + this.set_draggable = function( draggable ) { - if( draggable ) { - $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); + if( draggable && editable ) { + $(self.ellipse).attr( {stroke:'black', fill:'#9999ff'} ); $(self.ellipse).parent().mousedown( this.mousedown_listener ); - $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); + $(self.ellipse).parent().unbind( 'mouseenter' ).unbind( 'mouseleave' ); self.ellipse.siblings('text').attr('class', 'noselect draggable'); } else { + $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); self.ellipse.siblings('text').attr('class', ''); - $(self.ellipse).parent().unbind( 'mouseenter' ).unbind( 'mouseleave' ).unbind( 'mousedown' ); - color_inactive( self.ellipse ); + $(self.ellipse).parent().unbind( 'mousedown '); + $(self.ellipse).parent().mousedown( function(evt) { evt.stopPropagation() } ); + $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); } } @@ -283,7 +346,7 @@ function node_obj(ellipse) { $('body').mousemove( self.mousemove_listener ); $('body').mouseup( self.mouseup_listener ); $(self.ellipse).parent().unbind('mouseenter').unbind('mouseleave') - self.ellipse.attr( 'fill', '#ff66ff' ); + self.ellipse.attr( 'fill', '#6b6bb2' ); first_node_g_element = $("#svgenlargement g .node" ).filter( ":first" ); if( first_node_g_element.attr('id') !== self.get_g().attr('id') ) { self.get_g().insertBefore( first_node_g_element ) }; } @@ -311,8 +374,7 @@ function node_obj(ellipse) { }; $('body').unbind('mousemove'); $('body').unbind('mouseup'); - self.ellipse.attr( 'fill', '#fff' ); - $(self.ellipse).parent().hover( self.enter_node, self.leave_node ); + self.ellipse.attr( 'fill', '#9999ff' ); self.reset_elements(); } @@ -360,7 +422,11 @@ function node_obj(ellipse) { self.node_elements = node_elements_for(self.ellipse); } - self.set_draggable( true ); + this.get_witnesses = function() { + return readingdata[self.get_id()].witnesses + } + + self.set_selectable( true ); } function svgshape( shape_element ) { @@ -508,11 +574,11 @@ function relation_factory() { } } this.showinfo = function(relation) { - var htmlstr = 'type: ' + relation.data( 'type' ) + '
    scope: ' + relation.data( 'scope' ); + $('#delete_relation_type').text( relation.data('type') ); + $('#delete_relation_scope').text( relation.data('scope') ); if( relation.data( 'note' ) ) { - htmlstr = htmlstr + '
    note: ' + relation.data( 'note' ); + $('#delete_relation_note').text('note: ' + relation.data( 'note' ) ); } - $('#delete-form-text').html( htmlstr ); var points = relation.children('path').attr('d').slice(1).replace('C',' ').split(' '); var xs = parseFloat( points[0].split(',')[0] ); var xe = parseFloat( points[1].split(',')[0] ); @@ -529,6 +595,9 @@ function relation_factory() { dialog_aria.offset({ left: nx, top: ny }); } this.remove = function( relation_id ) { + if( !editable ) { + return; + } var relation = $( jq( relation_id ) ); relation.remove(); } @@ -567,29 +636,236 @@ function draw_relation( source_id, target_id, relation_color ) { return relation_element; } +function detach_node( readings ) { + + // This method is work in progress + // Todos: + // 1) Unproven/untested: readings.each will get us in trouble most likely for + // duplicating edges in a strand that both are incoming and outgoing + // like b and c in -i-> a -ii-> b -iii-> c -iv-> + // 2) Added edges and nodes look rough and unsmoothed, what the f.? + // + + // add new node(s) + $.extend( readingdata, readings ); + // remove from existing readings the witnesses for the new nodes/readings + $.each( readings, function( node_id, reading ) { + $.each( reading.witnesses, function( index, witness ) { + var witnesses = readingdata[ reading.orig_rdg ].witnesses; + readingdata[ reading.orig_rdg ].witnesses = $.removeFromArray( witness, witnesses ); + } ); + } ); + + detached_edges = []; + + // here we detach witnesses from the existing edges accoring to what's being relayed by readings + $.each( readings, function( node_id, reading ) { + var edges = edges_of( get_ellipse( reading.orig_rdg ) ); + incoming_remaining = []; + outgoing_remaining = []; + $.each( reading.witnesses, function( index, witness ) { + incoming_remaining.push( witness ); + outgoing_remaining.push( witness ); + } ); + $.each( edges, function( index, edge ) { + detached_edge = edge.detach_witnesses( reading.witnesses ); + if( detached_edge != null ) { + detached_edges.push( detached_edge ); + $.each( detached_edge.witnesses, function( index, witness ) { + if( detached_edge.is_incoming == true ) { + incoming_remaining = $.removeFromArray( witness, incoming_remaining ); + } else { + outgoing_remaining = $.removeFromArray( witness, outgoing_remaining ); + } + } ); + } + } ); + + // After detaching we still need to check if for *all* readings + // an edge was detached. It may be that a witness was not + // explicitly named on an edge but was part of a 'majority' edge + // in which case we need to duplicate and name that edge after those + // remaining witnesses. + if( outgoing_remaining.length > 0 ) { + $.each( edges, function( index, edge ) { + if( edge.get_label() == 'majority' && !edge.is_incoming ) { + detached_edges.push( edge.clone_for( outgoing_remaining ) ); + } + } ); + } + if( incoming_remaining.length > 0 ) { + $.each( edges, function( index, edge ) { + if( edge.get_label() == 'majority' && edge.is_incoming ) { + detached_edges.push( edge.clone_for( outgoing_remaining ) ); + } + } ); + } + + // Lots of unabstracted knowledge down here :/ + // Clone original node/reading, rename/id it.. + duplicate_node = get_ellipse( reading.orig_rdg ).parent().clone(); + duplicate_node.attr( 'id', node_id ); + duplicate_node.children( 'title' ).text( node_id ); + + // Add the node and all new edges into the graph + var graph_root = $('#svgenlargement svg g.graph'); + graph_root.append( duplicate_node ); + $.each( detached_edges, function( index, edge ) { + edge.g_elem.attr( 'id', ( edge.g_elem.attr( 'id' ) + "_0" ) ); + edge_title = edge.g_elem.children( 'title' ).text(); + edge_title = edge_title.replace( reading.orig_rdg, node_id ); + edge.g_elem.children( 'title' ).text( edge_title ); + // Reg unabstracted knowledge: isn't it more elegant to make + // it edge.append_to( graph_root )? + graph_root.append( edge.g_elem ); + } ); + + // Move the node somewhat up for 'dramatic effect' :-p + var node_elements = node_elements_for( get_ellipse( node_id ) ); + $.each( node_elements, function( index, element ) { + element.move( 0, -150 ); + } ); + + } ); + + +} + +function Marquee() { + + var self = this; + + this.x = 0; + this.y = 0; + this.dx = 0; + this.dy = 0; + this.enlargementOffset = $('#svgenlargement').offset(); + this.svg_rect = $('#svgenlargement svg').svg('get'); + + this.show = function( event ) { + // TODO: uncolor possible selected + // TODO: unless SHIFT? + self.x = event.clientX; + self.y = event.clientY; + p = svg_root.createSVGPoint(); + p.x = event.clientX - self.enlargementOffset.left; + p.y = event.clientY - self.enlargementOffset.top; + self.svg_rect.rect( p.x, p.y, 0, 0, { fill: 'black', 'fill-opacity': '0.1', stroke: 'black', 'stroke-dasharray': '4,2', strokeWidth: '0.02em', id: 'marquee' } ); + }; + + this.expand = function( event ) { + self.dx = (event.clientX - self.x); + self.dy = (event.clientY - self.y); + var rect = $('#marquee'); + if( rect.length != 0 ) { + var rect_w = Math.abs( self.dx ); + var rect_h = Math.abs( self.dy ); + var rect_x = self.x - self.enlargementOffset.left; + var rect_y = self.y - self.enlargementOffset.top; + if( self.dx < 0 ) { rect_x = rect_x - rect_w } + if( self.dy < 0 ) { rect_y = rect_y - rect_h } + rect.attr("x", rect_x).attr("y", rect_y).attr("width", rect_w).attr("height", rect_h); + } + }; + + this.select = function() { + var rect = $('#marquee'); + if( rect.length != 0 ) { + //unselect any possible selected first + if( $('ellipse[fill="#9999ff"]').size() > 0 ) { + $('ellipse[fill="#9999ff"]').each( function() { + $(this).data( 'node_obj' ).set_draggable( false ); + } ); + } + //compute dimension of marquee + var left = $('#marquee').offset().left; + var top = $('#marquee').offset().top; + var right = left + parseInt( $('#marquee').attr( 'width' ) ); + var bottom = top + parseInt( $('#marquee').attr( 'height' ) ); + var tf = svg_root_element.getScreenCTM().inverse(); + var p = svg_root.createSVGPoint(); + p.x=left; + p.y=top; + var cx_min = p.matrixTransform(tf).x; + var cy_min = p.matrixTransform(tf).y; + p.x=right; + p.y=bottom; + var cx_max = p.matrixTransform(tf).x; + var cy_max = p.matrixTransform(tf).y; + //select any node with its center inside the marquee + var readings = []; + //also merge witness sets from nodes + var witnesses = []; + $('#svgenlargement ellipse').each( function( index ) { + var cx = parseInt( $(this).attr('cx') ); + var cy = parseInt( $(this).attr('cy') ); + if( cx > cx_min && cx < cx_max) { + if( cy > cy_min && cy < cy_max) { + // we actually heve no real 'selected' state for nodes, except coloring + $(this).attr( 'fill', '#9999ff' ); + // Take note of the selected reading(s) and applicable witness(es) + // so we can populate the multipleselect-form + readings.push( $(this).parent().attr('id') ); + var this_witnesses = $(this).data( 'node_obj' ).get_witnesses(); + witnesses = arrayUnique( witnesses.concat( this_witnesses ) ); + } + } + }); + if( $('ellipse[fill="#9999ff"]').size() > 0 ) { + //add intersection of witnesses sets to the multi select form and open it + $('#detach_collated_form').empty(); + $.each( readings, function( index, value ) { + $('#detach_collated_form').append( $('').attr( + "type", "hidden").attr("name", "readings[]").attr( + "value", value ) ); + }); + $.each( witnesses, function( index, value ) { + $('#detach_collated_form').append( + '' + value + '
    ' ); + }); + $('#multiple_selected_readings').attr('value', readings.join(',') ); + $('#multipleselect-form').dialog( 'open' ); + } + self.svg_rect.remove( $('#marquee') ); + } + }; + + this.unselect = function() { + $('ellipse[fill="#9999ff"]').attr( 'fill', '#fff' ); + } + +} + $(document).ready(function () { timer = null; relation_manager = new relation_factory(); - $('#update_workspace_button').data('locked', false); + $('#update_workspace_button').data('locked', false); + $('#enlargement').mousedown(function (event) { $(this) .data('down', true) .data('x', event.clientX) .data('y', event.clientY) .data('scrollLeft', this.scrollLeft) - stateTf = svg_root_element.getCTM().inverse(); - var p = svg_root.createSVGPoint(); - p.x = event.clientX; - p.y = event.clientY; - stateOrigin = p.matrixTransform(stateTf); - event.returnValue = false; - event.preventDefault(); - return false; + stateTf = svg_root_element.getCTM().inverse(); + var p = svg_root.createSVGPoint(); + p.x = event.clientX; + p.y = event.clientY; + stateOrigin = p.matrixTransform(stateTf); + + // Activate marquee if in interaction mode + if( $('#update_workspace_button').data('locked') == true ) { marquee.show( event ) }; + + event.returnValue = false; + event.preventDefault(); + return false; }).mouseup(function (event) { - $(this).data('down', false); + marquee.select(); + $(this).data('down', false); }).mousemove(function (event) { if( timer != null ) { clearTimeout(timer); } if ( ($(this).data('down') == true) && ($('#update_workspace_button').data('locked') == false) ) { @@ -601,6 +877,7 @@ $(document).ready(function () { var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")"; svg_root_element.setAttribute("transform", s); } + marquee.expand( event ); event.returnValue = false; event.preventDefault(); }).mousewheel(function (event, delta) { @@ -631,96 +908,111 @@ $(document).ready(function () { 'cursor' : '-moz-grab' }); - - $( "#dialog-form" ).dialog({ - autoOpen: false, - height: 270, - width: 290, - modal: true, - buttons: { - "Ok": function() { - $('#status').empty(); - form_values = $('#collapse_node_form').serialize(); - ncpath = getTextURL( 'relationships' ); - $(':button :contains("Ok")').attr("disabled", true); - var jqjson = $.post( ncpath, form_values, function(data) { - $.each( data, function(item, source_target) { - var source_found = get_ellipse( source_target[0] ); - var target_found = get_ellipse( source_target[1] ); - if( source_found.size() && target_found.size() ) { - var relation = relation_manager.create( source_target[0], source_target[1], $('#rel_type')[0].selectedIndex-1 ); - relation.data( 'type', $('#rel_type :selected').text() ); + + if( editable ) { + $( "#dialog-form" ).dialog({ + autoOpen: false, + height: 270, + width: 290, + modal: true, + buttons: { + "Ok": function( evt ) { + $(evt.target).button("disable"); + $('#status').empty(); + form_values = $('#collapse_node_form').serialize(); + ncpath = getTextURL( 'relationships' ); + var jqjson = $.post( ncpath, form_values, function(data) { + $.each( data, function(item, source_target) { + var source_found = get_ellipse( source_target[0] ); + var target_found = get_ellipse( source_target[1] ); + var relation_found = $.inArray( source_target[2], $('#keymap').data('relations') ); + if( source_found.size() && target_found.size() && relation_found > -1 ) { + var relation = relation_manager.create( source_target[0], source_target[1], relation_found ); + relation.data( 'type', source_target[2] ); relation.data( 'scope', $('#scope :selected').text() ); relation.data( 'note', $('#note').val() ); relation_manager.toggle_active( relation.attr('id') ); } - }); - $( "#dialog-form" ).dialog( "close" ); - }, 'json' ); - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - create: function(event, ui) { - $(this).data( 'relation_drawn', false ); - //TODO? Err handling? - var basepath = getRelativePath(); - var jqjson = $.getJSON( basepath + '/definitions', function(data) { - var types = data.types.sort(); - $.each( types, function(index, value) { - $('#rel_type').append( $('
  • ').css( "border-color", relation_manager.relation_colors[index] ).text(value) ); - }); - var scopes = data.scopes; - $.each( scopes, function(index, value) { - $('#scope').append( $('