From 61fd6b2f3b145a3b70c91117706668cf315984e4 Mon Sep 17 00:00:00 2001 From: artzub Date: Sat, 7 Jul 2012 02:44:26 +0700 Subject: [PATCH 1/2] added the asynchronous parsing, reset zoom and position, progress bar on parse nodes and edges. --- config.js | 10 +- img/zoom-reset.png | Bin 0 -> 5596 bytes index.html | 14 ++ js/gexfjs.js | 453 ++++++++++++++++++++++++++++++++++----------- styles/gexfjs.css | 84 ++++++++- styles/probar.css | 99 ++++++++++ 6 files changed, 547 insertions(+), 113 deletions(-) create mode 100644 img/zoom-reset.png create mode 100644 styles/probar.css diff --git a/config.js b/config.js index 46110fe..26c337f 100644 --- a/config.js +++ b/config.js @@ -43,11 +43,19 @@ setParams({ Show the weight of edges in the list this setting can't be changed from the User Interface */ - language: false + language: false, /* Set to an ISO language code to switch the interface to that language. Available languages are English [en], French [fr], Spanish [es], Italian [it], Finnish [fi], Turkish [tr] and Greek [el]. If set to false, the language will be that of the user's browser. */ + alphaNode: .7, + /* + Change this parameter for set opacity of the nodes. + */ + alphaNodeBorder: .5 + /* + Change this parameter for set opacity of the border nodes. + */ }); diff --git a/img/zoom-reset.png b/img/zoom-reset.png new file mode 100644 index 0000000000000000000000000000000000000000..e3879e6ff62857da0830002e7e538c43609fcdf6 GIT binary patch literal 5596 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 Gephi: JavaScript GEXF Viewer + @@ -18,9 +19,22 @@ +
+
+
+
+ +
+
+
+
+
    +
  • + +
  • diff --git a/js/gexfjs.js b/js/gexfjs.js index f4ebf4f..9ee2030 100644 --- a/js/gexfjs.js +++ b/js/gexfjs.js @@ -6,6 +6,7 @@ * Jaakko Salonen (Finnish) * Zeynep Akata (Turkish) * Σωτήρης Φραγκίσκος (Greek) + * Артём Зубков (Russian) * */ // Namespace @@ -22,8 +23,15 @@ var GexfJS = { centreY : 350, activeNode : -1, currentNode : -1, + alphaNode :.7, + alphaNodeBorder :.5, + showEdgeLabel : true, + onErrorLoaded : null, }, + onLoading : null, + onLoaded : null, oldParams : {}, + mainCenter : null, minZoom : -3, maxZoom : 10, overviewWidth : 200, @@ -62,7 +70,38 @@ var GexfJS = { "edgeOff" : "Hide edges", "zoomIn" : "Zoom In", "zoomOut" : "Zoom Out", - "browserErr" : 'Your browser cannot properly display this page.
    We recommend you use the latest Firefox or Chrome version' + "browserErr" : 'Your browser cannot properly display this page.
    We recommend you use the latest Firefox or Chrome version', + "zoomReset" : "Reset/Set the zoom and position", + "zoomSet" : "Set the zoom and position" + }, + "ru" : { + "search" : "Поиск вершин", + "nodeAttr" : "Аттрибуты", + "nodes" : "Вершины", + "inLinks" : "Входящие:", + "outLinks" : "Исходящие:", + "undirLinks" : "Ненаправленные:", + "lensOn" : "Влючить линзу", + "lensOff" : "Отключить линзу", + "edgeOn" : "Показывать ребра", + "edgeOff" : "Спрятать ребра", + "zoomIn" : "Увеличить", + "zoomOut" : "Уменьшить", + "browserErr" : 'Ваш браузер не может правильно отобразить страницу.
    Мы рекомендуем использовать последнюю версию Firefox или Chrome', + "modularity_class" : "Класс модульности", + "degree" : "Степень", + "indegree" : "Степень заходов", + "outdegree" : "Степень исходов", + "weighted degree" : "Взвешенная степень", + "weighted indegree" : "Взвешенная степень заходов", + "weighted outdegree" : "Взвещеная степень исходов", + "closnesscentrality" : "Близость", + "betweenesscentrality" : "Посреднечиство", + "authority" : "Авторитет (HITS)", + "hub" : "Хаб (HITS)", + "pageranks" : "PageRank", + "zoomReset" : "Сброс масштаба и положения", + "zoomSet" : "Восстановить масштаб и положение" }, "es" : { "search" : "Buscar un nodo", @@ -213,7 +252,7 @@ function displayNode(_nodeIndex, _recentre) { var _e = GexfJS.graph.edgeList[i] if ( _e.target == _nodeIndex ) { var _n = GexfJS.graph.nodeList[_e.source]; - _str += '
  • ' + _n.label + '' + ( GexfJS.params.showEdgeWeight && _e.weight ? ' [' + _e.weight + ']' : '') + '
  • '; + _str += '
  • ' + ( GexfJS.params.showEdgeLabel && _e.label ? ' (' + _e.label + ') ' : '') + _n.label + '' + ( GexfJS.params.showEdgeWeight && _e.weight ? ' [' + _e.weight + ']' : '') + '
  • '; } } if (GexfJS.graph.directed) _str += '

' + strLang("outLinks") + '

'; @@ -305,6 +344,7 @@ function changeGraphPosition(evt, echelle) { function onGraphMove(evt) { evt.preventDefault(); + GexfJS.mainCenter.backX = null; if (!GexfJS.graph) { return; } @@ -323,11 +363,13 @@ function onGraphMove(evt) { function onOverviewMove(evt) { if (GexfJS.dragOn) { + GexfJS.mainCenter.backX = null; changeGraphPosition(evt,-GexfJS.overviewScale); } } function onGraphScroll(evt, delta) { + GexfJS.totalScroll += delta; if (Math.abs(GexfJS.totalScroll) >= 1) { if (GexfJS.totalScroll < 0) { @@ -368,7 +410,6 @@ function initializeMap() { width : GexfJS.overviewWidth, height : GexfJS.overviewHeight }); - GexfJS.timeRefresh = setInterval(traceMap,60); GexfJS.graph = null; loadGraph(); } @@ -378,6 +419,13 @@ function loadGraph() { $.ajax({ url: ( document.location.hash.length > 1 ? document.location.hash.substr(1) : GexfJS.params.graphFile ), dataType: "xml", + error : function(jqXHR, textStatus, errorThrown) { + $("#error").html(textStatus + "
" + errorThrown); + $("#error").slideDown(); + + if(GexfJS.onLoaded) + GexfJS.onLoaded(this); + }, success: function(data) { var _s = new Date(); var _g = $(data).find("graph"), @@ -392,109 +440,202 @@ function loadGraph() { edgeList : [] } var _xmin = 1e9, _xmax = -1e9, _ymin = 1e9, _ymax = -1e9; _marge = 30; - $(_nodes).each(function() { - var _n = $(this), - _pos = _n.find("viz\\:position,position"), - _x = _pos.attr("x"), - _y = _pos.attr("y"); - _xmin = Math.min(_x, _xmin); - _xmax = Math.max(_x, _xmax); - _ymin = Math.min(_y, _ymin); - _ymax = Math.max(_y, _ymax); - }); - - var _echelle = Math.min( ( GexfJS.baseWidth - _marge ) / ( _xmax - _xmin ) , ( GexfJS.baseHeight - _marge ) / ( _ymax - _ymin ) ); - var _deltax = ( GexfJS.baseWidth - _echelle * ( _xmin + _xmax ) ) / 2; - var _deltay = ( GexfJS.baseHeight - _echelle * ( _ymin + _ymax ) ) / 2; - - GexfJS.ctxMini.clearRect(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight); - - $(_nodes).each( function() { - var _n = $(this), - _id = _n.attr("id"), - _label = _n.attr("label") || _id, - _d = { - id: _id, - label: _label - }, + + var nextMethod = 0; + + var len = $(_nodes).length; + var i = 0; + var step = 0; + var curPos = 0; + + var calcRange = function(focusItem) { + if (focusItem) { + var _n = $(focusItem), _pos = _n.find("viz\\:position,position"), _x = _pos.attr("x"), - _y = _pos.attr("y"), - _size = _n.find("viz\\:size,size").attr("value"), - _col = _n.find("viz\\:color,color"), - _r = _col.attr("r"), - _g = _col.attr("g"), - _b = _col.attr("b"), - _attr = _n.find("attvalue"); - _d.coords = { - base : { - x : _deltax + _echelle * _x, - y : _deltay - _echelle * _y, - r : _echelle * _size + _y = _pos.attr("y"); + _xmin = Math.min(_x, _xmin); + _xmax = Math.max(_x, _xmax); + _ymin = Math.min(_y, _ymin); + _ymax = Math.max(_y, _ymax); + if (step < curPos++) { + curPos = 0; + if(GexfJS.onLoading) + GexfJS.onLoading(i, len, "Loading... (" + i + " of " + len + ")"); } } - _d.color = { - rgb : { - r : _r, - g : _g, - b : _b - }, - base : "rgba(" + _r + "," + _g + "," + _b + ",.7)", - gris : "rgba(" + Math.floor(84 + .33 * _r) + "," + Math.floor(84 + .33 * _g) + "," + Math.floor(84 + .33 * _b) + ",.5)" + else { + nextMethod++; + if(GexfJS.onLoading) + GexfJS.onLoading(len, len, "Loading... (" + len + " of " + len + ")"); } - _d.attributes = []; - $(_attr).each(function() { - var _a = $(this), - _for = _a.attr("for"); - _d.attributes[ _for ? _for : 'attribute_' + _a.attr("id") ] = _a.attr("value"); - }); - GexfJS.graph.nodeIndexById.push(_id); - GexfJS.graph.nodeIndexByLabel.push(_label.toLowerCase()); - GexfJS.graph.nodeList.push(_d); - GexfJS.ctxMini.fillStyle = _d.color.base; - GexfJS.ctxMini.beginPath(); - 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 ); - GexfJS.ctxMini.closePath(); - GexfJS.ctxMini.fill(); - }); - - $(_edges).each(function() { - var _e = $(this), - _sid = _e.attr("source"), - _six = GexfJS.graph.nodeIndexById.indexOf(_sid); - _tid = _e.attr("target"), - _tix = GexfJS.graph.nodeIndexById.indexOf(_tid); - _w = _e.find('attvalue[for="weight"]').attr('value') || _e.attr('weight'); - _col = _e.find("color"); - if (_col.length) { - var _r = _col.attr("r"), + } + + var _echelle = 0; + var _deltax = 0; + var _deltay = 0; + + var parseNodes = function(focusItem) { + if (focusItem) { + var _n = $(focusItem), + _id = _n.attr("id"), + _label = _n.attr("label") || _id, + _d = { + id: _id, + label: _label + }, + _pos = _n.find("viz\\:position,position"), + _x = _pos.attr("x"), + _y = _pos.attr("y"), + _size = _n.find("viz\\:size,size").attr("value"), + _col = _n.find("viz\\:color,color"), + _r = _col.attr("r"), _g = _col.attr("g"), - _b = _col.attr("b"); - } else { - var _scol = GexfJS.graph.nodeList[_six].color.rgb; - if (GexfJS.graph.directed) { - var _r = _scol.r, - _g = _scol.g, - _b = _scol.b; + _b = _col.attr("b"), + _attr = _n.find("attvalue"); + _d.coords = { + base : { + x : _deltax + _echelle * _x, + y : _deltay - _echelle * _y, + r : _echelle * _size + } + } + _d.color = { + rgb : { + r : _r, + g : _g, + b : _b + }, + base : "rgba(" + _r + "," + _g + "," + _b + "," + GexfJS.params.alphaNode + ")", + gris : "rgba(" + Math.floor(84 + .33 * _r) + "," + Math.floor(84 + .33 * _g) + "," + Math.floor(84 + .33 * _b) + "," + GexfJS.params.alphaNodeBorder + ")" + } + _d.attributes = []; + $(_attr).each(function() { + var _a = $(this), + _for = _a.attr("for"); + _d.attributes[ _for ? _for : 'attribute_' + _a.attr("id") ] = _a.attr("value"); + }); + GexfJS.graph.nodeIndexById.push(_id); + GexfJS.graph.nodeIndexByLabel.push(_label.toLowerCase()); + GexfJS.graph.nodeList.push(_d); + GexfJS.ctxMini.fillStyle = _d.color.base; + GexfJS.ctxMini.beginPath(); + 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 ); + GexfJS.ctxMini.closePath(); + GexfJS.ctxMini.fill(); + if (step < curPos++) { + curPos = 0; + if(GexfJS.onLoading) + GexfJS.onLoading(i, len, "Parsing nodes... (" + i + " of " + len + ")"); + } + } + else { + nextMethod++; + if(GexfJS.onLoading) + GexfJS.onLoading(len, len, "Parsing nodes... (" + len + " of " + len + ")"); + } + } + + var parseEdges = function(focusItem) { + if (focusItem) { + var _e = $(focusItem), + _sid = _e.attr("source"), + _six = GexfJS.graph.nodeIndexById.indexOf(_sid); + _tid = _e.attr("target"), + _tix = GexfJS.graph.nodeIndexById.indexOf(_tid); + _label = _e.attr("label") || undefined, + _w = _e.find('attvalue[for="weight"]').attr('value') || _e.attr('weight'); + _col = _e.find("color"); + if (_col.length) { + var _r = _col.attr("r"), + _g = _col.attr("g"), + _b = _col.attr("b"); } else { - var _tcol = GexfJS.graph.nodeList[_tix].color.rgb, - _r = Math.floor( .5 * _scol.r + .5 * _tcol.r ), - _g = Math.floor( .5 * _scol.g + .5 * _tcol.g ), - _b = Math.floor( .5 * _scol.b + .5 * _tcol.b ); + var _scol = GexfJS.graph.nodeList[_six].color.rgb; + if (GexfJS.graph.directed) { + var _r = _scol.r, + _g = _scol.g, + _b = _scol.b; + } else { + var _tcol = GexfJS.graph.nodeList[_tix].color.rgb, + _r = Math.floor( .5 * _scol.r + .5 * _tcol.r ), + _g = Math.floor( .5 * _scol.g + .5 * _tcol.g ), + _b = Math.floor( .5 * _scol.b + .5 * _tcol.b ); + } + } + GexfJS.graph.edgeList.push({ + source : _six, + target : _tix, + label : _label, + width : ( _w ? _w : 1 ) * _echelle, + weight : _w || false, + color : "rgba(" + _r + "," + _g + "," + _b + ",.7)" + }); + if (step < curPos++) { + curPos = 0; + if(GexfJS.onLoading) + GexfJS.onLoading(i, len, "Parsing edges... (" + i + " of " + len + ")"); } } - GexfJS.graph.edgeList.push({ - source : _six, - target : _tix, - width : ( _w ? _w : 1 ) * _echelle, - weight : _w || false, - color : "rgba(" + _r + "," + _g + "," + _b + ",.7)" - }); - }); - - GexfJS.imageMini = GexfJS.ctxMini.getImageData(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight); - - //changeNiveau(0); + else { + nextMethod++; + if(GexfJS.onLoading) + GexfJS.onLoading(len, len, "Parsing edges... (" + len + " of " + len + ")"); + } + } + + var poolMethods = [ calcRange, parseNodes, parseEdges ]; + var lastMethod = -1; + var curArr = null; + + var run = function() { + var changeMethod = lastMethod != nextMethod; + var runTime = false; + + if (changeMethod) { + if(GexfJS.onLoading) + GexfJS.onLoading(len, len); + switch (nextMethod){ + case 0: + curArr = _nodes; + break; + case 1: + _echelle = Math.min( ( GexfJS.baseWidth - _marge ) / ( _xmax - _xmin ) , ( GexfJS.baseHeight - _marge ) / ( _ymax - _ymin ) ); + _deltax = ( GexfJS.baseWidth - _echelle * ( _xmin + _xmax ) ) / 2; + _deltay = ( GexfJS.baseHeight - _echelle * ( _ymin + _ymax ) ) / 2; + + GexfJS.ctxMini.clearRect(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight); + break; + case 2: + curArr = _edges; + + break; + } + len = $(curArr).length; + i = 0; + step = parseInt(len / 25); + lastMethod = nextMethod; + } + var focusItem = null; + if (i < len) + focusItem = curArr[i++]; + if (nextMethod < poolMethods.length) + setTimeout(function() { + if (poolMethods[nextMethod]) + poolMethods[nextMethod](focusItem); + run(); + }, 1); + else { + GexfJS.imageMini = GexfJS.ctxMini.getImageData(0, 0, GexfJS.overviewWidth, GexfJS.overviewHeight); + + if(GexfJS.onLoaded) + GexfJS.onLoaded(this); + + GexfJS.timeRefresh = setInterval(traceMap,60); + } + } + run(); + //changeNiveau(0); } }); } @@ -612,6 +753,11 @@ function traceMap() { } var _displayEdges = ( GexfJS.params.showEdges && GexfJS.params.currentNode == -1 ); + + if (_centralNode != -1) { + var _dnc = GexfJS.graph.nodeList[_centralNode]; + _dnc.coords.real = ( (GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _dnc.coords.actual ) : _dnc.coords.actual ); + } for (var i in GexfJS.graph.edgeList) { var _d = GexfJS.graph.edgeList[i], @@ -640,17 +786,37 @@ function traceMap() { var _coords = ( ( GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _ds.coords.actual ) : _ds.coords.actual ); _coordt = ( (GexfJS.params.useLens && GexfJS.mousePosition) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _dt.coords.actual ) : _dt.coords.actual ); GexfJS.ctxGraphe.strokeStyle = ( _isLinked ? _d.color : "rgba(100,100,100,0.2)" ); + + if (_centralNode != -1 && + _d.label && + (_six == _centralNode || _tix == _centralNode)) { + + var _fs = Math.max(_limTxt + 2, (_six == _centralNode ? _coords.r : _coordt.r ) * _textSizeFactor) + 2; + + var x3 = _coords.x; + var y3 = _coords.y; + var x4 = _coordt.x; + var y4 = _coordt.y; + if (GexfJS.params.curvedEdges) { + x3 = .3 * _coordt.y - .3 * _coords.y + .8 * _coords.x + .2 * _coordt.x; + y3 = .8 * _coords.y + .2 * _coordt.y - .3 * _coordt.x + .3 * _coords.x; + x4 = .3 * _coordt.y - .3 * _coords.y + .2 * _coords.x + .8 * _coordt.x; + y4 = .2 * _coords.y + .8 * _coordt.y - .3 * _coordt.x + .3 * _coords.x; + } + + GexfJS.ctxGraphe.fillStyle = "rgb(0,0,0)"; + GexfJS.ctxGraphe.font = Math.floor( _fs )+"px Arial"; + GexfJS.ctxGraphe.textAlign = "center"; + GexfJS.ctxGraphe.textBaseline = "middle"; + GexfJS.ctxGraphe.fillText(_d.label, x3 - (x3 - x4)/2, y3 - (y3 - y4) / 2); + } + traceArc(GexfJS.ctxGraphe, _coords, _coordt); } } GexfJS.ctxGraphe.lineWidth = 4; GexfJS.ctxGraphe.strokeStyle = "rgba(0,100,0,0.8)"; - if (_centralNode != -1) { - var _dnc = GexfJS.graph.nodeList[_centralNode]; - _dnc.coords.real = ( (GexfJS.params.useLens && GexfJS.mousePosition ) ? calcCoord( GexfJS.mousePosition.x , GexfJS.mousePosition.y , _dnc.coords.actual ) : _dnc.coords.actual ); - } - for (var i in GexfJS.graph.nodeList) { var _d = GexfJS.graph.nodeList[i]; if (_d.visible && _d.withinFrame) { @@ -764,10 +930,13 @@ function updateAutoComplete(_sender) { function updateButtonStates() { $("#lensButton").attr("class",GexfJS.params.useLens?"":"off") - .attr("title", strLang( GexfJS.params.showEdges ? "lensOff" : "lensOn" ) ); + .attr("title", strLang( GexfJS.params.useLens ? "lensOff" : "lensOn" ) ); $("#edgesButton").attr("class",GexfJS.params.showEdges?"":"off") .attr("title", strLang( GexfJS.params.showEdges ? "edgeOff" : "edgeOn" ) ); + + $("#zoomReset").attr("class",GexfJS.params.zoomReset?"":"off") + .attr("title", strLang( GexfJS.params.zoomReset ? "zoomReset" : "zoomSet" ) ); } function setParams(paramlist) { @@ -776,6 +945,30 @@ function setParams(paramlist) { } } +function resetZoom() { + var lvl = GexfJS.mainCenter.lvl, + x = GexfJS.mainCenter.x, + y = GexfJS.mainCenter.y; + GexfJS.params.zoomReset = false; + if(GexfJS.mainCenter.backX) { + GexfJS.params.zoomReset = true; + lvl = GexfJS.mainCenter.backZoomLevel; + x = GexfJS.mainCenter.backX; + y = GexfJS.mainCenter.backY; + GexfJS.mainCenter.backX = null; + } + else { + GexfJS.mainCenter.backZoomLevel = GexfJS.params.zoomLevel; + GexfJS.mainCenter.backX = GexfJS.params.centreX; + GexfJS.mainCenter.backY = GexfJS.params.centreY; + } + GexfJS.params.centreX = x; + GexfJS.params.centreY = y; + GexfJS.params.zoomLevel = lvl; + updateButtonStates(); + $("#zoomSlider").slider("value",GexfJS.params.zoomLevel); +} + $(document).ready(function() { var lang = ( @@ -797,16 +990,47 @@ $(document).ready(function() { $("#bulle").html('

' + strLang("browserErr") + '

'); return; } - + + GexfJS.proBar = document.getElementById('probar'); + GexfJS.onLoading = function(pos, maxResults, state) { + if(pos && pos < 0) + pos = -pos; + pos = !maxResults || !pos ? '0%' : (parseInt(pos * 100 / maxResults)) + '%'; + GexfJS.proBar.style.width = pos; + GexfJS.proBar.textContent = pos + " " + (state || ""); + } + GexfJS.params.zoomReset = true; updateButtonStates(); GexfJS.ctxGraphe = document.getElementById('carte').getContext('2d'); GexfJS.ctxMini = document.getElementById('overview').getContext('2d'); updateWorkspaceBounds(); - - initializeMap(); - - window.onhashchange = initializeMap; + + GexfJS.doHashChange = function() { + $("#error").hide(); + $("#overwindow").show(); + if (!GexfJS.onHashChange) + GexfJS.onHashChange = function() { + initializeMap(); + } + $("#top-box-cont > div").hide(); + $("#progb").show(); + GexfJS.onLoading(); + GexfJS.onLoaded = function(item) { + $("#overwindow").hide(); + if (( !GexfJS.graph + || !GexfJS.graph.nodeList + || GexfJS.graph.nodeList.length < 1)) { + if (GexfJS.params.onErrorLoaded) + GexfJS.params.onErrorLoaded(); + } + } + GexfJS.onHashChange(); + } + + GexfJS.doHashChange(); + + window.onhashchange = GexfJS.doHashChange; $("#searchinput") .focus(function() { @@ -886,6 +1110,11 @@ $(document).ready(function() { return false; }) .attr("title", strLang("zoomIn")); + $("#zoomReset").click(function() { + resetZoom(); + return false; + }) + .attr("title", strLang("zoomReset")); $(document).click(function(evt) { $("#autocomplete").slideUp(); }); @@ -926,4 +1155,10 @@ $(document).ready(function() { } return false; }); + GexfJS.mainCenter = { + backX : false, + lvl : GexfJS.params.zoomLevel, + x : GexfJS.params.centreX, + y : GexfJS.params.centreY + }; }); \ No newline at end of file diff --git a/styles/gexfjs.css b/styles/gexfjs.css index 8818c6e..9337de8 100644 --- a/styles/gexfjs.css +++ b/styles/gexfjs.css @@ -26,7 +26,6 @@ body { position: absolute; left: 0; top: 0; width: 250px; text-align: center; } - h1 { margin:0; } @@ -44,7 +43,9 @@ h1 a { #searchinput { background: #fff url(../img/search.gif) no-repeat right; border: 1px solid #DDD; - font-size: 14px; line-height: 14px, height: 14px; + font-size: 14px; + line-height: 14px; + height: 14px; left: 250px; padding: 1px 4px; margin: 0; position: absolute; @@ -109,10 +110,30 @@ h1 a { background-position: -24px 0; } -#lensButton, #edgesButton { +#lensButton, #edgesButton, #zoomReset { display: block; width: 36px; height: 36px; background:url(../img/loupe-edges.png); margin: 0 auto; } +#zoomReset { + background:url(../img/zoom-reset.png); +} + +#zoomReset { + background-position: 0px 0; +} + +#zoomReset:hover { + background-position: -36px 0; +} + +#zoomReset.off { + background-position: -72px 0; +} + +#zoomReset.off:hover { + background-position: -108px 0; +} + #lensButton { background-position: -72px 0; } @@ -271,4 +292,61 @@ a:hover { #autocomplete img { float: left; border: 0; width: 24px; height: 24px; margin: 2px 6px; +} + +#overwindow { + overflow: hidden; +} + +.box_top { + z-index: 1000; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + overflow: auto; +} +.box_override { + position: absolute; + top: 0; + left: 0; + opacity: .5; + z-index: 999; + height: 100%; + width: 100%; + overflow: hidden; + background: #000000; +} + +.prog { + margin: 35% 80px 0; +} + +#probar { + text-align: center; + vertical-align: middle; + color: white; + text-shadow: 0 1px 1px black; + padding-top: 2px; +} + +#progb { + overflow: hidden; + width: 100%; + /*display: none;*/ +} + +#error { + position: absolute; + top: 45px; + left: 20px; + z-index: 2; + padding: 6px; + background: #fdf5ce; + border: 1px dotted #F9E16C; + border-top: 0; + color: #F9746C; + font-size: 10pt; + font-weight: bold; } \ No newline at end of file diff --git a/styles/probar.css b/styles/probar.css new file mode 100644 index 0000000..011b8fd --- /dev/null +++ b/styles/probar.css @@ -0,0 +1,99 @@ +.meter { + height: 20px; + position: relative; + margin: 20px 0 20px 0; + background: #555; + padding: 10px; + -webkit-box-shadow: inset 0 -1px 1px rgba(255,255,255,0.3); + -moz-box-shadow : inset 0 -1px 1px rgba(255,255,255,0.3); + box-shadow : inset 0 -1px 1px rgba(255,255,255,0.3); +} +.meter > span { + display: block; + height: 100%; + background-color: rgb(43,194,83); + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0, rgb(43,194,83)), + color-stop(1, rgb(84,240,84)) + ); + background-image: -moz-linear-gradient( + center bottom, + rgb(43,194,83) 37%, + rgb(84,240,84) 69% + ); + -webkit-box-shadow: + inset 0 2px 9px rgba(255,255,255,0.3), + inset 0 -2px 6px rgba(0,0,0,0.4); + -moz-box-shadow: + inset 0 2px 9px rgba(255,255,255,0.3), + inset 0 -2px 6px rgba(0,0,0,0.4); + box-shadow: + inset 0 2px 9px rgba(255,255,255,0.3), + inset 0 -2px 6px rgba(0,0,0,0.4); + position: relative; + overflow: hidden; +} +.meter > span:after, .animate > span > span { + content: ""; + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + background-image: + -webkit-gradient(linear, 0 0, 100% 100%, + color-stop(.25, rgba(255, 255, 255, .2)), + color-stop(.25, transparent), color-stop(.5, transparent), + color-stop(.5, rgba(255, 255, 255, .2)), + color-stop(.75, rgba(255, 255, 255, .2)), + color-stop(.75, transparent), to(transparent) + ); + background-image: + -moz-linear-gradient( + -45deg, + rgba(255, 255, 255, .2) 25%, + transparent 25%, + transparent 50%, + rgba(255, 255, 255, .2) 50%, + rgba(255, 255, 255, .2) 75%, + transparent 75%, + transparent + ); + z-index: 1; + -webkit-background-size: 50px 50px; + -moz-background-size: 50px 50px; + -webkit-animation: move 2s linear infinite; + overflow: hidden; +} + +.animate > span:after { + display: none; +} + +@-webkit-keyframes move { + 0% { + background-position: 0 0; + } + 100% { + background-position: 50px 50px; + } +} + +.orange > span { + background-color: #f1a165; + background-image: -moz-linear-gradient(top, #f1a165, #f36d0a); + background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f1a165),color-stop(1, #f36d0a)); + background-image: -webkit-linear-gradient(#f1a165, #f36d0a); +} + +.red > span { + background-color: #f0a3a3; + background-image: -moz-linear-gradient(top, #f0a3a3, #f42323); + background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f0a3a3),color-stop(1, #f42323)); + background-image: -webkit-linear-gradient(#f0a3a3, #f42323); +} + +.nostripes > span > span, .nostripes > span:after { + -webkit-animation: none; + background-image: none; +} From 16ccdc3cdfd1e4c17e7efeeac8dea86cc9e30380 Mon Sep 17 00:00:00 2001 From: Artem Zubkov Date: Fri, 1 Nov 2013 11:31:25 +0700 Subject: [PATCH 2/2] Changed readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d822601..53f16c5 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,11 @@ Gexf-JS now speaks 7 languages: English, French, Italian, Spanish, Finnish, Turk #### Σωτήρης Φραγκίσκος (greek translation) +#### Artem Zubkov (async parsing graph, zoom back, russian translation) + +* http://artzub.com/ +* Twitter: [@artzub](http://twitter.com/artzub) + ### How to use ? ## 1. Export your graph from Gephi as a GEXF file @@ -79,4 +84,4 @@ Strings to translate : 1. Hide edges 1. Zoom In 1. Zoom Out -1. Your browser cannot properly display this page. We recommend you use the latest Firefox or Chrome version \ No newline at end of file +1. Your browser cannot properly display this page. We recommend you use the latest Firefox or Chrome version