enmi12/glossaire/graph/js/gexfjs.js
changeset 0 d970ebf37754
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 /* Copyright (c) 2011 Raphaël Velt
       
     2  * Licensed under the MIT License
       
     3  * Translations by :
       
     4  *    Vicenzo Cosenza (Italian)
       
     5  *    Eduardo Ramos Ibáñez (Spanish)
       
     6  *    Jaakko Salonen (Finnish)
       
     7  *    Zeynep Akata (Turkish)
       
     8  *    Σωτήρης Φραγκίσκος (Greek)
       
     9  * */
       
    10 
       
    11 // Namespace
       
    12 var GexfJS = {
       
    13     lensRadius : 200,
       
    14     lensGamma : 0.5,
       
    15     graphZone : {
       
    16         width : 0,
       
    17         height : 0
       
    18     },
       
    19     oldGraphZone : {},
       
    20     params : {
       
    21         centreX : 400,
       
    22         centreY : 350,
       
    23         activeNode : -1,
       
    24         currentNode : -1
       
    25     },
       
    26     oldParams : {},
       
    27     minZoom : -3,
       
    28     maxZoom : 10,
       
    29     overviewWidth : 200,
       
    30     overviewHeight : 175,
       
    31     baseWidth : 800,
       
    32     baseHeight : 700,
       
    33     overviewScale : .25,
       
    34     totalScroll : 0,
       
    35     autoCompletePosition : 0,
       
    36     i18n : {
       
    37         "el" : {
       
    38             "search" : "Αναζήτηση Κόμβων",
       
    39             "nodeAttr" : "Χαρακτηριστικά",
       
    40             "nodes" : "Κόμβοι",
       
    41             "inLinks" : "Εισερχόμενοι δεσμοί από",
       
    42             "outLinks" : "Εξερχόμενοι δεσμοί προς",
       
    43             "undirLinks" : "Ακατεύθυντοι δεσμοί με",
       
    44             "lensOn" : "Ενεργοποίηση φακού",
       
    45             "lensOff" : "Απενεργοποίηση φακού",
       
    46             "edgeOn" : "Εμφάνιση ακμών",
       
    47             "edgeOff" : "Απόκρυψη ακμών",
       
    48             "zoomIn" : "Μεγέθυνση",
       
    49             "zoomOut" : "Σμίκρυνση",
       
    50             "browserErr" : 'Ο περιηγητής σας δεν μπορεί να εμφανίσει σωστά αυτή τη σελίδα.<br />Σας προτείνουμε να χρησιμοποιήσετε την τελευταία έκδοση του <a href="http://www.mozilla.com/" target="_blank">Firefox</a> ή του <a href="http://www.google.com/chrome/" target="_blank">Chrome</a>'
       
    51         },
       
    52         "en" : {
       
    53             "search" : "Search nodes",
       
    54             "nodeAttr" : "Attributes",
       
    55             "nodes" : "Nodes",
       
    56             "inLinks" : "Inbound Links from :",
       
    57             "outLinks" : "Outbound Links to :",
       
    58             "undirLinks" : "Undirected links with :",
       
    59             "lensOn" : "Activate lens mode",
       
    60             "lensOff" : "Deactivate lens mode",
       
    61             "edgeOn" : "Show edges",
       
    62             "edgeOff" : "Hide edges",
       
    63             "zoomIn" : "Zoom In",
       
    64             "zoomOut" : "Zoom Out",
       
    65             "browserErr" : 'Your browser cannot properly display this page.<br />We recommend you use the latest <a href="http://www.mozilla.com/" target="_blank">Firefox</a> or <a href="http://www.google.com/chrome/" target="_blank">Chrome</a> version'
       
    66         },
       
    67         "es" : {
       
    68             "search" : "Buscar un nodo",
       
    69             "nodeAttr" : "Atributos",
       
    70             "nodes" : "Nodos",
       
    71             "inLinks" : "Aristas entrantes desde :",
       
    72             "outLinks" : "Aristas salientes hacia :",
       
    73             "undirLinks" : "Aristas no dirigidas con :",
       
    74             "lensOn" : "Activar el modo lupa",
       
    75             "lensOff" : "Desactivar el modo lupa",
       
    76             "edgeOn" : "Mostrar aristas",
       
    77             "edgeOff" : "Ocultar aristas",
       
    78             "zoomIn" : "Acercar",
       
    79             "zoomOut" : "Alejar",
       
    80             "browserErr" : 'Tu navegador no es capaz de mostrar esta p&aacute;gina correctamente.<br />Le recomendamos utilizar la &uacute;ltima versi&oacute;n de <a href="http://www.mozilla.com/" target="_blank">Firefox</a> o <a href="http://www.google.com/chrome/" target="_blank">Chrome</a>',
       
    81             "modularity_class" : "Clase de modularidad",
       
    82             "degree" : "Grado",
       
    83             "indegree" : "Grado de entrada",
       
    84             "outdegree" : "Grado de salida",
       
    85             "weighted degree" : "Grado ponderado",
       
    86             "weighted indegree" : "Grado de entrada ponderado",
       
    87             "weighted outdegree" : "Grado de salida ponderado",
       
    88             "closnesscentrality" : "Cercan&iacute;a",
       
    89             "betweenesscentrality" : "Intermediaci&oacute;n",
       
    90             "authority" : "Puntuaci&oacute;n de autoridad (HITS)",
       
    91             "hub" : "Puntuaci&oacute; de hub (HITS)",
       
    92             "pageranks" : "Puntuaci&oacute; de PageRank"
       
    93         },
       
    94         "fi" : {
       
    95             "search" : "Etsi solmuja",
       
    96             "nodeAttr" : "Attribuutit",
       
    97             "nodes" : "Solmut",
       
    98             "inLinks" : "Lähtevät yhteydet :",
       
    99             "outLinks" : "Tulevat yhteydet :",
       
   100             "undirLinks" : "Yhteydet :",
       
   101             "lensOn" : "Ota linssitila käyttöön",
       
   102             "lensOff" : "Poista linssitila käytöstä",
       
   103             "edgeOn" : "Näytä kaikki yhteydet",
       
   104             "edgeOff" : "Näytä vain valitun solmun yhteydet",
       
   105             "zoomIn" : "Suurenna",
       
   106             "zoomOut" : "Pienennä",
       
   107             "browserErr" : 'Selaimesi ei voi näyttää tätä sivua.<br />Suosittelemme käyttämään uusinta versiota <a href="http://www.mozilla.com/" target="_blank">Firefox</a>- tai <a href="http://www.google.com/chrome/" target="_blank">Chrome</a>-selaimesta'
       
   108         },
       
   109         "fr" : {
       
   110             "search" : "Rechercher un n&oelig;ud",
       
   111             "nodeAttr" : "Attributs",
       
   112             "nodes" : "N&oelig;uds",
       
   113             "inLinks" : "Liens entrants depuis :",
       
   114             "outLinks" : "Liens sortants vers :",
       
   115             "undirLinks" : "Liens non-dirigés avec :",
       
   116             "lensOn" : "Activer le mode loupe",
       
   117             "lensOff" : "Désactiver le mode loupe",
       
   118             "edgeOn" : "Afficher les sommets",
       
   119             "edgeOff" : "Cacher les sommets",
       
   120             "zoomIn" : "S'approcher",
       
   121             "zoomOut" : "S'éloigner",
       
   122             "browserErr" : 'Votre navigateur n\'est malheureusement pas compatible avec les fonctionnalités de ce site<br />Nous vous suggérons d\'utiliser une version récente de <a href="http://www.mozilla.com/" target="_blank">Firefox</a> ou <a href="http://www.google.com/chrome/" target="_blank">Chrome</a>',
       
   123             "modularity_class" : "Classe de modularité",
       
   124             "degree" : "Degr&eacute;",
       
   125             "indegree" : "&frac12; degr&eacute; int&eacute;rieur",
       
   126             "outdegree" : "&frac12; degr&eacute; ext&eacute;rieur",
       
   127             "weighted degree" : "Degr&eacute; pond&eacute;r&eacute;",
       
   128             "weighted indegree" : "&frac12; degr&eacute; int&eacute;rieur pond&eacute;r&eacute;",
       
   129             "weighted outdegree" : "&frac12; degr&eacute; ext&eacute;rieur pond&eacute;r&eacute;",
       
   130             "closnesscentrality" : "Centralit&eacute; de proximit&eacute;",
       
   131             "betweenesscentrality" : "Centralit&eacute; d'interm&eacute;diarit&eacute;",
       
   132             "authority" : "Score d'autorit&eacute; (HITS)",
       
   133             "hub" : "Score de hub (HITS)",
       
   134             "pageranks" : "Score de PageRank"
       
   135         },
       
   136         "it" : {
       
   137             "search" : "Cerca i nodi",
       
   138             "nodeAttr" : "Attributi",
       
   139             "nodes" : "Nodi",
       
   140             "inLinks" : "Link in entrata da :",
       
   141             "outLinks" : "Link in uscita verso :",
       
   142             "undirLinks" : "Link non direzionati con :",
       
   143             "lensOn" : "Attiva la lente d'ingrandimento",
       
   144             "lensOff" : "Disattiva la lente d'ingrandimento",
       
   145             "edgeOn" : "Mostra gli spigoli",
       
   146             "edgeOff" : "Nascondi gli spigoli",
       
   147             "zoomIn" : "Zoom in avanti",
       
   148             "zoomOut" : "Zoom indietro",
       
   149             "browserErr" : 'Il tuo browser non pu&ograve; visualizzare correttamente questa pagina.<br />Ti raccomandiamo l\'uso dell\'ultima versione di  <a href="http://www.mozilla.com/" target="_blank">Firefox</a> o <a href="http://www.google.com/chrome/" target="_blank">Chrome</a>'
       
   150         },
       
   151         "tr" : {
       
   152             "search" : "Düğüm ara",
       
   153             "nodeAttr" : "Özellikler",
       
   154             "nodes" : "Düğümler",
       
   155             "inLinks" : "Gelen bağlantılar",
       
   156             "outLinks" : "Giden bağlantılar",
       
   157             "undirLinks" : "Yönsüz bağlantılar",
       
   158             "lensOn" : "Merceği etkinleştir",
       
   159             "lensOff" : "Merceği etkisizleştir",
       
   160             "edgeOn" : "Kenar çizgilerini göster",
       
   161             "edgeOff" : "Kenar çizgilerini gizle",
       
   162             "zoomIn" : "Yaklaştır",
       
   163             "zoomOut" : "Uzaklaştır",
       
   164             "browserErr" : "Tarayıcınız sayfayı doğru bir biçimde görüntüleyemiyor.<br />En son Firefox veya Chrome sürümünü kullanmanızı tavsiye ederiz."
       
   165         }
       
   166     },
       
   167     lang : "en"
       
   168 }
       
   169 
       
   170 function strLang(_str) {
       
   171     var _l = GexfJS.i18n[GexfJS.lang];
       
   172     return ( _l[_str] ? _l[_str] : ( GexfJS.i18n["en"][_str] ? GexfJS.i18n["en"][_str] : _str.replace("_"," ") ) );
       
   173 }
       
   174 
       
   175 function replaceURLWithHyperlinks(text) {
       
   176     if (GexfJS.params.replaceUrls) {
       
   177         var _urlExp = /(\b(https?:\/\/)?[-A-Z0-9]+\.[-A-Z0-9.:]+(\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*)?)/ig,
       
   178             _protocolExp = /^https?:\/\//i;
       
   179         return text.replace(_urlExp, function(_found) {
       
   180             return '<a href="'
       
   181                 + ( _protocolExp.test(_found) ? '' : 'http://' )
       
   182                 + _found + '" target="_blank">'
       
   183                 + _found.replace(_protocolExp,'')
       
   184                 + "</a>";
       
   185         });
       
   186     }
       
   187     return text;
       
   188 }
       
   189 
       
   190 function displayNode(_nodeIndex, _recentre) {
       
   191     GexfJS.params.currentNode = _nodeIndex;
       
   192     if (_nodeIndex != -1) {
       
   193         var _d = GexfJS.graph.nodeList[_nodeIndex],
       
   194             _b = _d.coords.base,
       
   195             _str = '',
       
   196             _cG = $("#leftcolumn");
       
   197             _cG.animate({
       
   198                 "left" : "0px"
       
   199             }, function() {
       
   200                 $("#aUnfold").attr("class","leftarrow");
       
   201                 $("#zonecentre").css({
       
   202                     left: _cG.width() + "px"
       
   203                 });
       
   204             });
       
   205         _str += '<h3><div class="largepill" style="background: ' + _d.color.base +'"></div>' + _d.label + '</h3>';
       
   206         _str += '<h4>' + strLang("nodeAttr") + '</h4>';
       
   207         _str += '<ul><li><b>id</b> : ' + _d.id + '</li>';
       
   208         for (var i in _d.attributes) {
       
   209             _str += '<li><b>' + strLang(i) + '</b> : ' + replaceURLWithHyperlinks( _d.attributes[i] ) + '</li>';
       
   210         }
       
   211         _str += '</ul><h4>' + ( GexfJS.graph.directed ? strLang("inLinks") : strLang("undirLinks") ) + '</h4><ul>';
       
   212         for (var i in GexfJS.graph.edgeList) {
       
   213             var _e = GexfJS.graph.edgeList[i]
       
   214             if ( _e.target == _nodeIndex ) {
       
   215                 var _n = GexfJS.graph.nodeList[_e.source];
       
   216                 _str += '<li><div class="smallpill" style="background: ' + _n.color.base +'"></div><a href="#" onmouseover="GexfJS.params.activeNode = ' + _e.source + '" onclick="displayNode(' + _e.source + ', true); return false;">' + _n.label + '</a>' + ( GexfJS.params.showEdgeWeight && _e.weight ? ' [' + _e.weight + ']' : '') + '</li>';
       
   217             }
       
   218         }
       
   219         if (GexfJS.graph.directed) _str += '</ul><h4>' + strLang("outLinks") + '</h4><ul>';
       
   220         for (var i in GexfJS.graph.edgeList) {
       
   221             var _e = GexfJS.graph.edgeList[i]
       
   222             if ( _e.source == _nodeIndex ) {
       
   223                 var _n = GexfJS.graph.nodeList[_e.target];
       
   224                 _str += '<li><div class="smallpill" style="background: ' + _n.color.base +'"></div><a href="#" onmouseover="GexfJS.params.activeNode = ' + _e.target + '" onclick="displayNode(' + _e.target + ', true); return false;">' + _n.label + '</a>' + ( GexfJS.params.showEdgeWeight && _e.weight ? ' [' + _e.weight + ']' : '') + '</li>';
       
   225             }
       
   226         }
       
   227         _str += '</ul><p></p>';
       
   228         $("#leftcontent").html(_str);
       
   229         if (_recentre) {
       
   230             GexfJS.params.centreX = _b.x;
       
   231             GexfJS.params.centreY = _b.y;
       
   232         }
       
   233         $("#searchinput")
       
   234             .val(_d.label)
       
   235             .removeClass('grey');
       
   236     }
       
   237 }
       
   238 
       
   239 function updateWorkspaceBounds() {
       
   240     
       
   241     var _elZC = $("#zonecentre");
       
   242     var _top = {
       
   243         top : $("#titlebar").height() + "px"
       
   244     }
       
   245     _elZC.css(_top);
       
   246     
       
   247     $("#leftcolumn").css(_top);
       
   248     GexfJS.graphZone.width = _elZC.width();
       
   249     GexfJS.graphZone.height = _elZC.height();
       
   250     GexfJS.areParamsIdentical = true;
       
   251     
       
   252     for (var i in GexfJS.graphZone) {
       
   253         GexfJS.areParamsIdentical = GexfJS.areParamsIdentical && ( GexfJS.graphZone[i] == GexfJS.oldGraphZone[i] );
       
   254     }
       
   255     if (!GexfJS.areParamsIdentical) {
       
   256     
       
   257     $("#carte")
       
   258         .attr({
       
   259             width : GexfJS.graphZone.width,
       
   260             height : GexfJS.graphZone.height
       
   261         })
       
   262         .css({
       
   263             width : GexfJS.graphZone.width + "px",
       
   264             height : GexfJS.graphZone.height + "px"
       
   265         });
       
   266         for (var i in GexfJS.graphZone) {
       
   267             GexfJS.oldGraphZone[i] = GexfJS.graphZone[i];
       
   268         }
       
   269     }
       
   270 }
       
   271 
       
   272 function startMove(evt) {
       
   273     evt.preventDefault();
       
   274     GexfJS.dragOn = true;
       
   275     GexfJS.lastMouse = {
       
   276         x : evt.pageX,
       
   277         y : evt.pageY
       
   278     }
       
   279     GexfJS.mouseHasMoved = false;
       
   280 }
       
   281 
       
   282 function endMove(evt) {
       
   283     document.body.style.cursor = "default";
       
   284     GexfJS.dragOn = false;
       
   285     GexfJS.mouseHasMoved = false;
       
   286 }
       
   287 
       
   288 function onGraphClick(evt) {
       
   289     if (!GexfJS.mouseHasMoved) {
       
   290         displayNode(GexfJS.params.activeNode);
       
   291     }
       
   292     endMove();
       
   293 }
       
   294 
       
   295 function changeGraphPosition(evt, echelle) {
       
   296     document.body.style.cursor = "move";
       
   297     var _coord = {
       
   298         x : evt.pageX,
       
   299         y : evt.pageY
       
   300     };
       
   301     GexfJS.params.centreX += ( GexfJS.lastMouse.x - _coord.x ) / echelle;
       
   302     GexfJS.params.centreY += ( GexfJS.lastMouse.y - _coord.y ) / echelle;
       
   303     GexfJS.lastMouse = _coord;
       
   304 }
       
   305 
       
   306 function onGraphMove(evt) {
       
   307     evt.preventDefault();
       
   308     if (!GexfJS.graph) {
       
   309         return;
       
   310     }
       
   311     GexfJS.mousePosition = {
       
   312         x : evt.pageX - $(this).offset().left,
       
   313         y : evt.pageY - $(this).offset().top
       
   314     }
       
   315     if (GexfJS.dragOn) {
       
   316         changeGraphPosition(evt,GexfJS.echelleGenerale);
       
   317         GexfJS.mouseHasMoved = true;
       
   318     } else {
       
   319         GexfJS.params.activeNode = getNodeFromPos(GexfJS.mousePosition);
       
   320         document.body.style.cursor = ( GexfJS.params.activeNode != -1 ? "pointer" : "default" );
       
   321     }
       
   322 }
       
   323 
       
   324 function onOverviewMove(evt) {
       
   325     if (GexfJS.dragOn) {
       
   326         changeGraphPosition(evt,-GexfJS.overviewScale);
       
   327     }
       
   328 }
       
   329 
       
   330 function onGraphScroll(evt, delta) {
       
   331     GexfJS.totalScroll += delta;
       
   332     if (Math.abs(GexfJS.totalScroll) >= 1) {
       
   333         if (GexfJS.totalScroll < 0) {
       
   334             if (GexfJS.params.zoomLevel > GexfJS.minZoom) {
       
   335                 GexfJS.params.zoomLevel--;
       
   336                 var _el = $(this),
       
   337                     _off = $(this).offset(),
       
   338                     _deltaX = evt.pageX - _el.width() / 2 - _off.left,
       
   339                     _deltaY = evt.pageY - _el.height() / 2 - _off.top;
       
   340                 GexfJS.params.centreX -= ( Math.SQRT2 - 1 ) * _deltaX / GexfJS.echelleGenerale;
       
   341                 GexfJS.params.centreY -= ( Math.SQRT2 - 1 ) * _deltaY / GexfJS.echelleGenerale;
       
   342                 $("#zoomSlider").slider("value",GexfJS.params.zoomLevel);
       
   343             }
       
   344         } else {
       
   345             if (GexfJS.params.zoomLevel < GexfJS.maxZoom) {
       
   346                 GexfJS.params.zoomLevel++;
       
   347                 GexfJS.echelleGenerale = Math.pow( Math.SQRT2, GexfJS.params.zoomLevel );
       
   348                 var _el = $(this),
       
   349                     _off = $(this).offset(),
       
   350                     _deltaX = evt.pageX - _el.width() / 2 - _off.left,
       
   351                     _deltaY = evt.pageY - _el.height() / 2 - _off.top;
       
   352                 GexfJS.params.centreX += ( Math.SQRT2 - 1 ) * _deltaX / GexfJS.echelleGenerale;
       
   353                 GexfJS.params.centreY += ( Math.SQRT2 - 1 ) * _deltaY / GexfJS.echelleGenerale;
       
   354                 $("#zoomSlider").slider("value",GexfJS.params.zoomLevel);
       
   355             }
       
   356         }
       
   357         GexfJS.totalScroll = 0;
       
   358     }
       
   359 }
       
   360 
       
   361 function initializeMap() {
       
   362     clearInterval(GexfJS.timeRefresh);
       
   363     GexfJS.oldParams = {};
       
   364     GexfJS.ctxGraphe.clearRect(0, 0, GexfJS.graphZone.width, GexfJS.graphZone.height);
       
   365     $("#zoomSlider").slider({
       
   366         orientation: "vertical",
       
   367         value: GexfJS.params.zoomLevel,
       
   368         min: GexfJS.minZoom,
       
   369         max: GexfJS.maxZoom,
       
   370         range: "min",
       
   371         step: 1,
       
   372         slide: function( event, ui ) {
       
   373             GexfJS.params.zoomLevel = ui.value;
       
   374         }
       
   375     });
       
   376     $("#overviewzone").css({
       
   377         width : GexfJS.overviewWidth + "px",
       
   378         height : GexfJS.overviewHeight + "px"
       
   379     });
       
   380     $("#overview").attr({
       
   381         width : GexfJS.overviewWidth,
       
   382         height : GexfJS.overviewHeight
       
   383     });
       
   384     GexfJS.timeRefresh = setInterval(traceMap,60);
       
   385     GexfJS.graph = null;
       
   386     loadGraph();
       
   387 }
       
   388 
       
   389 function loadGraph() {
       
   390     
       
   391     $.ajax({
       
   392         url: ( document.location.hash.length > 1 ? document.location.hash.substr(1) : GexfJS.params.graphFile ),
       
   393         dataType: "xml",
       
   394         success: function(data) {
       
   395             var _s = new Date();
       
   396             var _g = $(data).find("graph"),
       
   397                 _nodes = _g.children().filter("nodes").children(),
       
   398                 _edges = _g.children().filter("edges").children();
       
   399             GexfJS.graph = {
       
   400                 directed : ( _g.attr("defaultedgetype") == "directed" ),
       
   401                 source : data,
       
   402                 nodeList : [],
       
   403                 nodeIndexById : [],
       
   404                 nodeIndexByLabel : [],
       
   405                 edgeList : []
       
   406             }
       
   407             var _xmin = 1e9, _xmax = -1e9, _ymin = 1e9, _ymax = -1e9; _marge = 30;
       
   408             $(_nodes).each(function() {
       
   409                 var _n = $(this),
       
   410                 _pos = _n.find("viz\\:position,position"),
       
   411                 _x = _pos.attr("x"),
       
   412                 _y = _pos.attr("y");
       
   413                 _xmin = Math.min(_x, _xmin);
       
   414                 _xmax = Math.max(_x, _xmax);
       
   415                 _ymin = Math.min(_y, _ymin);
       
   416                 _ymax = Math.max(_y, _ymax);
       
   417             });
       
   418             
       
   419             var _echelle = Math.min( ( GexfJS.baseWidth - _marge ) / ( _xmax - _xmin ) , ( GexfJS.baseHeight - _marge ) / ( _ymax - _ymin ) );
       
   420             var _deltax = ( GexfJS.baseWidth - _echelle * ( _xmin + _xmax ) ) / 2;
       
   421             var _deltay = ( GexfJS.baseHeight - _echelle * ( _ymin + _ymax ) ) / 2;
       
   422             
       
   423             GexfJS.ctxMini.clearRect(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight);
       
   424             
       
   425             $(_nodes).each( function() {
       
   426                 var _n = $(this),
       
   427                     _id = _n.attr("id"),
       
   428                     _label = _n.attr("label") || _id,
       
   429                     _d = {
       
   430                         id: _id,
       
   431                         label: _label
       
   432                     },
       
   433                     _pos = _n.find("viz\\:position,position"),
       
   434                     _x = _pos.attr("x"),
       
   435                     _y = _pos.attr("y"),
       
   436                     _size = _n.find("viz\\:size,size").attr("value"),
       
   437                     _col = _n.find("viz\\:color,color"),
       
   438                     _r = _col.attr("r"),
       
   439                     _g = _col.attr("g"),
       
   440                     _b = _col.attr("b"),
       
   441                     _attr = _n.find("attvalue");
       
   442                 _d.coords = {
       
   443                     base : {
       
   444                         x : _deltax + _echelle * _x,
       
   445                         y : _deltay - _echelle * _y,
       
   446                         r : _echelle * _size
       
   447                     }
       
   448                 }
       
   449                 _d.color = {
       
   450                     rgb : {
       
   451                         r : _r,
       
   452                         g : _g,
       
   453                         b : _b
       
   454                     },
       
   455                     base : "rgba(" + _r + "," + _g + "," + _b + ",.7)",
       
   456                     gris : "rgba(" + Math.floor(84 + .33 * _r) + "," + Math.floor(84 + .33 * _g) + "," + Math.floor(84 + .33 * _b) + ",.5)"
       
   457                 }
       
   458                 _d.attributes = [];
       
   459                 $(_attr).each(function() {
       
   460                     var _a = $(this),
       
   461                         _for = _a.attr("for");                    
       
   462                     _d.attributes[ _for ? _for : 'attribute_' + _a.attr("id") ] = _a.attr("value");
       
   463                 });
       
   464                 GexfJS.graph.nodeIndexById.push(_id);
       
   465                 GexfJS.graph.nodeIndexByLabel.push(_label.toLowerCase());
       
   466                 GexfJS.graph.nodeList.push(_d);
       
   467                 GexfJS.ctxMini.fillStyle = _d.color.base;
       
   468                 GexfJS.ctxMini.beginPath();
       
   469                 GexfJS.ctxMini.arc( _d.coords.base.x * GexfJS.overviewScale , _d.coords.base.y * GexfJS.overviewScale , _d.coords.base.r * GexfJS.overviewScale + 1 , 0 , Math.PI*2 , true );
       
   470                 GexfJS.ctxMini.closePath();
       
   471                 GexfJS.ctxMini.fill();
       
   472             });
       
   473             
       
   474             $(_edges).each(function() {
       
   475                 var _e = $(this),
       
   476                     _sid = _e.attr("source"),
       
   477                     _six = GexfJS.graph.nodeIndexById.indexOf(_sid);
       
   478                     _tid = _e.attr("target"),
       
   479                     _tix = GexfJS.graph.nodeIndexById.indexOf(_tid);
       
   480                     _w = _e.find('attvalue[for="weight"]').attr('value') || _e.attr('weight');
       
   481                     _col = _e.find("viz\\:color,color");
       
   482                 if (_col.length) {
       
   483                     var _r = _col.attr("r"),
       
   484                         _g = _col.attr("g"),
       
   485                         _b = _col.attr("b");
       
   486                 } else {
       
   487                     var _scol = GexfJS.graph.nodeList[_six].color.rgb;
       
   488                     if (GexfJS.graph.directed) {
       
   489                         var _r = _scol.r,
       
   490                             _g = _scol.g,
       
   491                             _b = _scol.b;
       
   492                     } else {
       
   493                         var _tcol = GexfJS.graph.nodeList[_tix].color.rgb,
       
   494                             _r = Math.floor( .5 * _scol.r + .5 * _tcol.r ),
       
   495                             _g = Math.floor( .5 * _scol.g + .5 * _tcol.g ),
       
   496                             _b = Math.floor( .5 * _scol.b + .5 * _tcol.b );
       
   497                     }
       
   498                 }
       
   499                 GexfJS.graph.edgeList.push({
       
   500                     source : _six,
       
   501                     target : _tix,
       
   502                     width : Math.max( GexfJS.params.minEdgeWidth, Math.min( GexfJS.params.maxEdgeWidth, ( _w || 1 ) ) ) * _echelle,
       
   503                     weight : parseFloat(_w || 0),
       
   504                     color : "rgba(" + _r + "," + _g + "," + _b + ",.7)"
       
   505                 });
       
   506             });
       
   507             
       
   508             GexfJS.imageMini = GexfJS.ctxMini.getImageData(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight);
       
   509         
       
   510         //changeNiveau(0);
       
   511         }
       
   512     });
       
   513 }
       
   514 
       
   515 function getNodeFromPos( _coords ) {
       
   516     for (var i = GexfJS.graph.nodeList.length - 1; i >= 0; i--) {
       
   517         var _d = GexfJS.graph.nodeList[i];
       
   518         if (_d.visible && _d.withinFrame) {
       
   519             var _c = _d.coords.actual;
       
   520                 _r = Math.sqrt( Math.pow( _c.x - _coords.x , 2) + Math.pow( _c.y - _coords.y , 2 ) );
       
   521             if ( _r < _c.r ) {
       
   522                 return i;
       
   523             }
       
   524         }
       
   525     }
       
   526     return -1;
       
   527 }
       
   528 
       
   529 function calcCoord(x, y, coord) {
       
   530     var _r = Math.sqrt( Math.pow( coord.x - x , 2 ) + Math.pow( coord.y - y , 2 ) );
       
   531     if ( _r < GexfJS.lensRadius ) {
       
   532         var _cos = ( coord.x - x ) / _r;
       
   533         var _sin = ( coord.y - y ) / _r;
       
   534         var _newr = GexfJS.lensRadius * Math.pow( _r / GexfJS.lensRadius, GexfJS.lensGamma );
       
   535         var _coeff = ( GexfJS.lensGamma * Math.pow( ( _r + 1 ) / GexfJS.lensRadius, GexfJS.lensGamma - 1 ) );
       
   536         return {
       
   537             "x" : x + _newr * _cos,
       
   538             "y" : y + _newr * _sin,
       
   539             "r" : _coeff * coord.r
       
   540         }
       
   541     }
       
   542     else {
       
   543         return coord;
       
   544     }
       
   545 }
       
   546 
       
   547 function traceArc(contexte, source, target) {
       
   548     contexte.beginPath();
       
   549     contexte.moveTo(source.x, source.y);
       
   550     if (GexfJS.params.curvedEdges) {
       
   551         if ( ( source.x == target.x ) && ( source.y == target.y ) ) {
       
   552             var x3 = source.x + 2.8 * source.r;
       
   553             var y3 = source.y - source.r;
       
   554             var x4 = source.x;
       
   555             var y4 = source.y + 2.8 * source.r;
       
   556             contexte.bezierCurveTo(x3,y3,x4,y4,source.x + 1,source.y);
       
   557         } else {
       
   558             var x3 = .3 * target.y - .3 * source.y + .8 * source.x + .2 * target.x;
       
   559             var y3 = .8 * source.y + .2 * target.y - .3 * target.x + .3 * source.x;
       
   560             var x4 = .3 * target.y - .3 * source.y + .2 * source.x + .8 * target.x;
       
   561             var y4 = .2 * source.y + .8 * target.y - .3 * target.x + .3 * source.x;
       
   562             contexte.bezierCurveTo(x3,y3,x4,y4,target.x,target.y);
       
   563         }
       
   564     } else {
       
   565         contexte.lineTo(target.x,target.y);
       
   566     }
       
   567     contexte.stroke();
       
   568 }
       
   569 
       
   570 function traceMap() {
       
   571     updateWorkspaceBounds();
       
   572     if (!GexfJS.graph) {
       
   573         return;
       
   574     }
       
   575     var _identical = GexfJS.areParamsIdentical;
       
   576     GexfJS.params.mousePosition = ( GexfJS.params.useLens ? ( GexfJS.mousePosition ? ( GexfJS.mousePosition.x + "," + GexfJS.mousePosition.y ) : "out" ) : null );
       
   577     for (var i in GexfJS.params) {
       
   578         _identical = _identical && ( GexfJS.params[i] == GexfJS.oldParams[i] );
       
   579     }
       
   580     if (_identical) {
       
   581         return;
       
   582     } else {
       
   583         for (var i in GexfJS.params) {
       
   584             GexfJS.oldParams[i] = GexfJS.params[i];
       
   585         }
       
   586     }
       
   587     
       
   588     GexfJS.echelleGenerale = Math.pow( Math.SQRT2, GexfJS.params.zoomLevel );
       
   589     GexfJS.decalageX = ( GexfJS.graphZone.width / 2 ) - ( GexfJS.params.centreX * GexfJS.echelleGenerale );
       
   590     GexfJS.decalageY = ( GexfJS.graphZone.height / 2 ) - ( GexfJS.params.centreY * GexfJS.echelleGenerale );
       
   591     
       
   592     var _sizeFactor = GexfJS.echelleGenerale * Math.pow(GexfJS.echelleGenerale, -.15),
       
   593         _edgeSizeFactor = _sizeFactor * GexfJS.params.edgeWidthFactor,
       
   594         _nodeSizeFactor = _sizeFactor * GexfJS.params.nodeSizeFactor,
       
   595         _textSizeFactor = 1;
       
   596     
       
   597     GexfJS.ctxGraphe.clearRect(0, 0, GexfJS.graphZone.width, GexfJS.graphZone.height);
       
   598     
       
   599     if (GexfJS.params.useLens && GexfJS.mousePosition) {
       
   600         GexfJS.ctxGraphe.fillStyle = "rgba(220,220,250,0.4)";
       
   601         GexfJS.ctxGraphe.beginPath();
       
   602         GexfJS.ctxGraphe.arc( GexfJS.mousePosition.x , GexfJS.mousePosition.y , GexfJS.lensRadius , 0 , Math.PI*2 , true );
       
   603         GexfJS.ctxGraphe.closePath();
       
   604         GexfJS.ctxGraphe.fill();
       
   605     }
       
   606     
       
   607     var _centralNode = ( ( GexfJS.params.activeNode != -1 ) ? GexfJS.params.activeNode : GexfJS.params.currentNode );
       
   608     
       
   609     for (var i in GexfJS.graph.nodeList) {
       
   610         var _d = GexfJS.graph.nodeList[i];
       
   611         _d.coords.actual = {
       
   612             x : GexfJS.echelleGenerale * _d.coords.base.x + GexfJS.decalageX,
       
   613             y : GexfJS.echelleGenerale * _d.coords.base.y + GexfJS.decalageY,
       
   614             r : _nodeSizeFactor * _d.coords.base.r 
       
   615         }
       
   616         _d.withinFrame = ( ( _d.coords.actual.x + _d.coords.actual.r > 0 ) && ( _d.coords.actual.x - _d.coords.actual.r < GexfJS.graphZone.width ) && ( _d.coords.actual.y + _d.coords.actual.r > 0) && (_d.coords.actual.y - _d.coords.actual.r < GexfJS.graphZone.height) );
       
   617         _d.visible = ( GexfJS.params.currentNode == -1 || i == _centralNode || GexfJS.params.showEdges );
       
   618     }
       
   619     
       
   620     var _tagsMisEnValeur = [];
       
   621     
       
   622     if ( _centralNode != -1 ) {
       
   623         _tagsMisEnValeur = [ _centralNode ];
       
   624     }
       
   625     
       
   626     var _displayEdges = ( GexfJS.params.showEdges && GexfJS.params.currentNode == -1 );
       
   627     
       
   628     for (var i in GexfJS.graph.edgeList) {
       
   629         var _d = GexfJS.graph.edgeList[i],
       
   630             _six = _d.source,
       
   631             _tix = _d.target,
       
   632             _ds = GexfJS.graph.nodeList[_six],
       
   633             _dt = GexfJS.graph.nodeList[_tix];
       
   634         var _isLinked = false;
       
   635         if (_centralNode != -1) {
       
   636             if (_six == _centralNode) {
       
   637                 _tagsMisEnValeur.push(_tix);
       
   638                 _coulTag = _dt.color.base;
       
   639                 _isLinked = true;
       
   640                 _dt.visible = true;
       
   641             }
       
   642             if (_tix == _centralNode) {
       
   643                 _tagsMisEnValeur.push(_six);
       
   644                 _coulTag = _ds.color.base;
       
   645                 _isLinked = true;
       
   646                 _ds.visible = true;
       
   647             }
       
   648         }
       
   649 
       
   650         if ( ( _isLinked || _displayEdges ) && ( _ds.withinFrame || _dt.withinFrame ) &&  _ds.visible && _dt.visible ) {
       
   651             GexfJS.ctxGraphe.lineWidth = _edgeSizeFactor * _d.width;
       
   652             var _coords = ( ( GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _ds.coords.actual ) : _ds.coords.actual );
       
   653             _coordt = ( (GexfJS.params.useLens && GexfJS.mousePosition) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _dt.coords.actual ) : _dt.coords.actual );
       
   654             GexfJS.ctxGraphe.strokeStyle = ( _isLinked ? _d.color : "rgba(100,100,100,0.2)" );
       
   655             traceArc(GexfJS.ctxGraphe, _coords, _coordt);
       
   656         }
       
   657     }
       
   658     GexfJS.ctxGraphe.lineWidth = 4;
       
   659     GexfJS.ctxGraphe.strokeStyle = "rgba(0,100,0,0.8)";
       
   660     
       
   661     if (_centralNode != -1) {
       
   662         var _dnc = GexfJS.graph.nodeList[_centralNode];
       
   663         _dnc.coords.real = ( (GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _dnc.coords.actual ) : _dnc.coords.actual );
       
   664     }
       
   665     
       
   666     for (var i in GexfJS.graph.nodeList) {
       
   667         var _d = GexfJS.graph.nodeList[i];
       
   668         if (_d.visible && _d.withinFrame) {
       
   669             if (i != _centralNode) {
       
   670                 _d.coords.real = ( ( GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _d.coords.actual ) : _d.coords.actual );
       
   671                 _d.isTag = ( _tagsMisEnValeur.indexOf(parseInt(i)) != -1 );
       
   672                 GexfJS.ctxGraphe.beginPath();
       
   673                 GexfJS.ctxGraphe.fillStyle = ( ( _tagsMisEnValeur.length && !_d.isTag ) ? _d.color.gris : _d.color.base );
       
   674                 GexfJS.ctxGraphe.arc( _d.coords.real.x , _d.coords.real.y , _d.coords.real.r , 0 , Math.PI*2 , true );
       
   675                 GexfJS.ctxGraphe.closePath();
       
   676                 GexfJS.ctxGraphe.fill();
       
   677             }
       
   678         }
       
   679     }
       
   680     
       
   681     for (var i in GexfJS.graph.nodeList) {
       
   682         var _d = GexfJS.graph.nodeList[i];
       
   683         if (_d.visible && _d.withinFrame) {
       
   684             if (i != _centralNode) {
       
   685                 var _fs = _d.coords.real.r * _textSizeFactor;
       
   686                 if (_d.isTag) {
       
   687                     if (_centralNode != -1) {
       
   688                         var _dist = Math.sqrt( Math.pow( _d.coords.real.x - _dnc.coords.real.x, 2 ) + Math.pow( _d.coords.real.y - _dnc.coords.real.y, 2 ) );
       
   689                         if (_dist > 80) {
       
   690                             _fs = Math.max(GexfJS.params.textDisplayThreshold + 2, _fs);
       
   691                         }
       
   692                     } else {
       
   693                         _fs = Math.max(GexfJS.params.textDisplayThreshold + 2, _fs);
       
   694                     }
       
   695                 }
       
   696                 if (_fs > GexfJS.params.textDisplayThreshold) {
       
   697                     GexfJS.ctxGraphe.fillStyle = ( ( i != GexfJS.params.activeNode ) && _tagsMisEnValeur.length && ( ( !_d.isTag ) || ( _centralNode != -1 ) ) ? "rgba(60,60,60,0.7)" : "rgb(0,0,0)" );
       
   698                     GexfJS.ctxGraphe.font = Math.floor( _fs )+"px Arial";
       
   699                     GexfJS.ctxGraphe.textAlign = "center";
       
   700                     GexfJS.ctxGraphe.textBaseline = "middle";
       
   701                     GexfJS.ctxGraphe.fillText(_d.label, _d.coords.real.x, _d.coords.real.y);
       
   702                 }
       
   703             }
       
   704         }
       
   705     }
       
   706     
       
   707     if (_centralNode != -1) {
       
   708         GexfJS.ctxGraphe.fillStyle = _dnc.color.base;
       
   709         GexfJS.ctxGraphe.beginPath();
       
   710         GexfJS.ctxGraphe.arc( _dnc.coords.real.x , _dnc.coords.real.y , _dnc.coords.real.r , 0 , Math.PI*2 , true );
       
   711         GexfJS.ctxGraphe.closePath();
       
   712         GexfJS.ctxGraphe.fill();
       
   713         GexfJS.ctxGraphe.stroke();
       
   714         var _fs = Math.max(GexfJS.params.textDisplayThreshold + 2, _dnc.coords.real.r * _textSizeFactor) + 2;
       
   715         GexfJS.ctxGraphe.font = "bold " + Math.floor( _fs )+"px Arial";
       
   716         GexfJS.ctxGraphe.textAlign = "center";
       
   717         GexfJS.ctxGraphe.textBaseline = "middle";
       
   718         GexfJS.ctxGraphe.fillStyle = "rgba(255,255,250,0.8)";
       
   719         GexfJS.ctxGraphe.fillText(_dnc.label, _dnc.coords.real.x - 2, _dnc.coords.real.y);
       
   720         GexfJS.ctxGraphe.fillText(_dnc.label, _dnc.coords.real.x + 2, _dnc.coords.real.y);
       
   721         GexfJS.ctxGraphe.fillText(_dnc.label, _dnc.coords.real.x, _dnc.coords.real.y - 2);
       
   722         GexfJS.ctxGraphe.fillText(_dnc.label, _dnc.coords.real.x, _dnc.coords.real.y + 2);
       
   723         GexfJS.ctxGraphe.fillStyle = "rgb(0,0,0)";
       
   724         GexfJS.ctxGraphe.fillText(_dnc.label, _dnc.coords.real.x, _dnc.coords.real.y);
       
   725     }
       
   726     
       
   727     GexfJS.ctxMini.putImageData(GexfJS.imageMini, 0, 0);
       
   728     var _r = GexfJS.overviewScale / GexfJS.echelleGenerale,
       
   729         _x = - _r * GexfJS.decalageX,
       
   730         _y = - _r * GexfJS.decalageY,
       
   731         _w = _r * GexfJS.graphZone.width,
       
   732         _h = _r * GexfJS.graphZone.height;
       
   733     
       
   734     GexfJS.ctxMini.strokeStyle = "rgb(220,0,0)";
       
   735     GexfJS.ctxMini.lineWidth = 3;
       
   736     GexfJS.ctxMini.fillStyle = "rgba(120,120,120,0.2)";
       
   737     GexfJS.ctxMini.beginPath();
       
   738     GexfJS.ctxMini.fillRect( _x, _y, _w, _h );
       
   739     GexfJS.ctxMini.strokeRect( _x, _y, _w, _h );
       
   740 }
       
   741 
       
   742 function hoverAC() {
       
   743     $("#autocomplete li").removeClass("hover");
       
   744     $("#liac_"+GexfJS.autoCompletePosition).addClass("hover");
       
   745     GexfJS.params.activeNode = GexfJS.graph.nodeIndexByLabel.indexOf( $("#liac_"+GexfJS.autoCompletePosition).text().toLowerCase() );
       
   746 }
       
   747 
       
   748 function changePosAC(_n) {
       
   749     GexfJS.autoCompletePosition = _n;
       
   750     hoverAC();
       
   751 }
       
   752 
       
   753 function updateAutoComplete(_sender) {
       
   754     var _val = $(_sender).val().toLowerCase();
       
   755     var _ac = $("#autocomplete");
       
   756     if (_val != GexfJS.dernierAC || _ac.html() == "") {
       
   757         GexfJS.dernierAC = _val;
       
   758         var _strAC = "<div><h4>" + strLang("nodes") + "</h4><ul>";
       
   759         var _n = 0;
       
   760         for (var i in GexfJS.graph.nodeIndexByLabel) {
       
   761             var _l = GexfJS.graph.nodeIndexByLabel[i];
       
   762             if (_l.search(_val) != -1) {
       
   763                 _strAC += '<li id="liac_' + _n + '" onmouseover="changePosAC(' + _n + ')"><a href="#" onclick="displayNode(\'' + i + '\', true); return false;"><span>' + GexfJS.graph.nodeList[i].label + '</span></a>';
       
   764                 _n++;
       
   765             }
       
   766             if (_n >= 20) {
       
   767                 break;
       
   768             }
       
   769         }
       
   770         GexfJS.autoCompletePosition = 0;
       
   771         _ac.html(_strAC + "</ul></div>");
       
   772     }
       
   773     hoverAC();
       
   774     _ac.show();
       
   775 }
       
   776 
       
   777 function updateButtonStates() {
       
   778     $("#lensButton").attr("class",GexfJS.params.useLens?"":"off")
       
   779         .attr("title", strLang( GexfJS.params.showEdges ? "lensOff" : "lensOn" ) );
       
   780 
       
   781     $("#edgesButton").attr("class",GexfJS.params.showEdges?"":"off")
       
   782         .attr("title", strLang( GexfJS.params.showEdges ? "edgeOff" : "edgeOn" ) );
       
   783 }
       
   784 
       
   785 function setParams(paramlist) {
       
   786     for (var i in paramlist) {
       
   787         GexfJS.params[i] = paramlist[i];
       
   788     }
       
   789 }
       
   790 
       
   791 $(document).ready(function() {
       
   792     
       
   793     var lang = (
       
   794         typeof GexfJS.params.language != "undefined" && GexfJS.params.language
       
   795         ? GexfJS.params.language
       
   796         : (
       
   797             navigator.language
       
   798             ? navigator.language.substr(0,2).toLowerCase()
       
   799             : (
       
   800                 navigator.userLanguage
       
   801                 ? navigator.userLanguage.substr(0,2).toLowerCase()
       
   802                 : "en"
       
   803             )
       
   804         )
       
   805     );
       
   806     GexfJS.lang = (GexfJS.i18n[lang] ? lang : "en");
       
   807     
       
   808     if ( !document.createElement('canvas').getContext ) {
       
   809         $("#bulle").html('<p><b>' + strLang("browserErr") + '</b></p>');
       
   810         return;
       
   811     }
       
   812     
       
   813     updateButtonStates();
       
   814     
       
   815     GexfJS.ctxGraphe = document.getElementById('carte').getContext('2d');
       
   816     GexfJS.ctxMini = document.getElementById('overview').getContext('2d');
       
   817     updateWorkspaceBounds();
       
   818     
       
   819     initializeMap();
       
   820     
       
   821     window.onhashchange = initializeMap;
       
   822     
       
   823     $("#searchinput")
       
   824         .focus(function() {
       
   825             if ( $(this).is('.grey') ) {
       
   826                 $(this).val('').removeClass('grey');
       
   827             }
       
   828         })
       
   829         .keyup(function(evt) {
       
   830             updateAutoComplete(this);
       
   831         }).keydown(function(evt){
       
   832             var _l = $("#autocomplete li").length;
       
   833             switch (evt.keyCode) {
       
   834                 case 40 :
       
   835                     if (GexfJS.autoCompletePosition < _l - 1) {
       
   836                         GexfJS.autoCompletePosition++;
       
   837                     } else {
       
   838                         GexfJS.autoCompletePosition = 0;
       
   839                     }
       
   840                 break;
       
   841                 case 38 :
       
   842                     if (GexfJS.autoCompletePosition > 0) {
       
   843                         GexfJS.autoCompletePosition--;
       
   844                     } else {
       
   845                         GexfJS.autoCompletePosition = _l - 1;
       
   846                     }
       
   847                 break;
       
   848                 case 27 :
       
   849                     $("#autocomplete").slideUp();
       
   850                 break;
       
   851                 case 13 :
       
   852                     if ($("#autocomplete").is(":visible")) {
       
   853                         var _liac = $("#liac_"+GexfJS.autoCompletePosition);
       
   854                         if (_liac.length) {
       
   855                             $(this).val(_liac.find("span").text());
       
   856                         }
       
   857                     }
       
   858                 break;
       
   859                 default :
       
   860                     GexfJS.autoCompletePosition = 0;
       
   861                 break;
       
   862             }
       
   863             updateAutoComplete(this);
       
   864             if (evt.keyCode == 38 || evt.keyCode == 40) {
       
   865                 return false;
       
   866             }
       
   867         });
       
   868     $("#recherche").submit(function() {
       
   869         if (GexfJS.graph) {
       
   870             displayNode( GexfJS.graph.nodeIndexByLabel.indexOf($("#searchinput").val().toLowerCase()), true);
       
   871         }
       
   872         return false;
       
   873     });
       
   874     $("#carte")
       
   875         .mousemove(onGraphMove)
       
   876         .click(onGraphClick)
       
   877         .mousedown(startMove)
       
   878         .mouseout(function() {
       
   879             GexfJS.mousePosition = null;
       
   880             endMove();
       
   881         })
       
   882         .mousewheel(onGraphScroll);
       
   883     $("#overview")
       
   884         .mousemove(onOverviewMove)
       
   885         .mousedown(startMove)
       
   886         .mouseup(endMove)
       
   887         .mouseout(endMove)
       
   888         .mousewheel(onGraphScroll);
       
   889     $("#zoomMinusButton").click(function() {
       
   890         GexfJS.params.zoomLevel = Math.max( GexfJS.minZoom, GexfJS.params.zoomLevel - 1);
       
   891         $("#zoomSlider").slider("value",GexfJS.params.zoomLevel);
       
   892         return false;
       
   893     })
       
   894         .attr("title", strLang("zoomOut"));
       
   895     $("#zoomPlusButton").click(function() {
       
   896         GexfJS.params.zoomLevel = Math.min( GexfJS.maxZoom, GexfJS.params.zoomLevel + 1);
       
   897         $("#zoomSlider").slider("value",GexfJS.params.zoomLevel);
       
   898         return false;
       
   899     })
       
   900         .attr("title", strLang("zoomIn"));
       
   901     $(document).click(function(evt) {
       
   902         $("#autocomplete").slideUp();
       
   903     });
       
   904     $("#autocomplete").css({
       
   905         top: ( $("#searchinput").offset().top + $("#searchinput").outerHeight() ) + "px",
       
   906         left: $("#searchinput").offset().left + "px"
       
   907     });
       
   908     $("#lensButton").click(function () {
       
   909         GexfJS.params.useLens = !GexfJS.params.useLens;
       
   910         updateButtonStates();
       
   911         return false;
       
   912     });
       
   913     $("#edgesButton").click(function () {
       
   914         GexfJS.params.showEdges = !GexfJS.params.showEdges;
       
   915         updateButtonStates();
       
   916         return false;
       
   917     });
       
   918     $("#aUnfold").click(function() {
       
   919         var _cG = $("#leftcolumn");
       
   920         if (_cG.offset().left < 0) {
       
   921             _cG.animate({
       
   922                 "left" : "0px"
       
   923             }, function() {
       
   924                 $("#aUnfold").attr("class","leftarrow");
       
   925                 $("#zonecentre").css({
       
   926                     left: _cG.width() + "px"
       
   927                 });
       
   928             });
       
   929         } else {
       
   930             _cG.animate({
       
   931                 "left" : "-" + _cG.width() + "px"
       
   932             }, function() {
       
   933                 $("#aUnfold").attr("class","rightarrow");
       
   934                 $("#zonecentre").css({
       
   935                     left: "0"
       
   936                 });
       
   937             });
       
   938         }
       
   939         return false;
       
   940     });
       
   941 });