Commit a2e71efe authored by Romain Loth's avatar Romain Loth

tina directories refactoring 2/2

moved 3rd party libs separately ; added a script to adapt relative paths in the html for production ; started harmonizing documentation
parent f6ce97c8
......@@ -12,20 +12,39 @@ The app can be tested by simply opening explorerjs.html and providing a graph in
#### Basic integration policy
As a client-side lib, **tinawebJS can entirely reside in the `static` directory of your app**.
So the procedure to integrate is basically just to extract the tinawebJS distribution in your `static` directory
For the rest of the exemples we assume you cloned the code in a directory called `path/to/yourapp/static/ProjectExplorer`
So the procedure to integrate is basically just to extract the tinawebJS distribution in your `static` directory.
There are two exceptions are:
- the html starting point itself:
- to use it as is:
1) just link to it from your html dir or templates dir
1) go into the root directory of projectExplorer in your static dir
```
# with our exemple
cd path/to/yourapp/static/ProjectExplorer
```
2) apply the changing paths tool `adapt_html_paths.sh` like this:
```
bash twtools/adapt_html_paths.sh 'static/projectExplorer/'
# ------------------------
# the relative url prefix in your deployment routes
```
this creates a new file: `explorerjs.prod.html`
3) now just link to the new file from your html dir or templates dir
```
~/yourapp > ln -s static/tinawebJS/explorerjs.html
~/yourapp > ls -l
4,0K 2030-03-15 16:49 HTML ELEMENTS OF YOUR APP
32 2030-06-28 10:14 explorerjs.html -> static/tinawebJS/explorerjs.html
# cd back/to/your/app/root (or html files dir)
cd ../../
ln -s static/ProjectExplorer/explorerjs.prod.html explorerjs.html
# now `ls -l` should show something like this:
# - HTML ELEMENTS OF YOUR APP
# - HTML ELEMENTS OF YOUR APP
# - explorerjs.html -> static/ProjectExplorer/explorerjs.prod.html
```
2) apply the changing paths tool from `twtools/adapt_html_paths.sh`
- to use it within a different GUI layout: take our html as an exemple and create your own html importing the same libs and exposing the same div ids.
......
// dot call_graph.dot -Tpng -o tina_call_graph.png
digraph tina_call_graph {
graph [ordering="out"];
rankdir=LR ;
edge [fontsize=10] ;
label=<<B><U>tinawebJS</U></B><BR/>(initialization callgraph)>;
labelloc="t" ;
// settings
"settings var" -> "settings:SystemStates";
"settings var" -> "settings:sigmaJsDrawingProperties";
"settings var" -> "etc.";
// getUrlParam
"t.globalUtils:getUrlParam" -> "var mainfile (url)" ;
// main 1: get graph
"t.main" -> "var mainfile (url)" ;
"var mainfile (url)" -> "ajax garg" ;
"ajax garg" -> "t.main:MainFunction" ;
// main 2: parse graph
"t.main:MainFunction" -> "t.sigma.parseCustom:ParseCustom" ;
"t.main:MainFunction" -> "t.sigma.parseCustom:scanFile" ;
"t.sigma.parseCustom:scanFile" -> "t.sigma.parseCustom:getJSONCategories" ;
"t.sigma.parseCustom:getJSONCategories" -> "t.sigma.parseCustom:scanJSON" ;
"t.main:MainFunction" -> "t.sigma.parseCustom:makeSystemStates" ;
"t.main:MainFunction" -> "t.sigma.parseCustom:buildInitialState" ;
"t.main:MainFunction" -> "t.sigma.parseCustom:makeDicts" ;
"t.sigma.parseCustom:makeDicts" -> "t.sigma.parseCustom:dictfyJSON" [label="cats={'terms':0}"] ;
// main 3: new TinaWebJS()
"t.main:MainFunction" -> "var twjs_" ;
"var twjs_" -> "t.TinawebJS:TinaWebJS:new" ;
// main 4: adjust canvas routine
"t.main:MainFunction" -> "t.TinawebJS:AdjustSigmaCanvas" ; // twjs_.AdjustSigmaCanvas()
"t.TinawebJS:AdjustSigmaCanvas" -> "t.TinawebJS:sigmaLimits" ;
"t.TinawebJS:sigmaLimits" -> "t.TinawebJS:visibleHeight" ;
"t.TinawebJS:sigmaLimits" -> "new canvas!" ;
// main 5: partialGraph and new SigmaUtils()
"t.main:MainFunction" -> "var partialGraph" ;
"var partialGraph" -> "sigma:init";
"t.main:MainFunction" -> "t.SigmaUtils:SigmaUtils:new" ;
"t.main:MainFunction" -> "t.SigmaUtils:SigmaUtils:FillGraph" ; // [ Poblating the Sigma-Graph ]
"t.SigmaUtils:SigmaUtils:FillGraph" -> "SigmaPublic.addNode" [label="x N"];
"t.SigmaUtils:SigmaUtils:FillGraph" -> "SigmaPublic.addEdge" [label="x N"];
"SigmaPublic.addEdge" -> "t.globalUtils:hex2rga" [label="x M"];
"t.SigmaUtils:SigmaUtils:FillGraph" -> "t.enviroment:updateSearchLabels" [label="N x push labels"];
// main 6: state and settings for partialGraph
// "settings:sigmaJsDrawingProperties" -> "var partialGraph" ;
// "settings:SystemStates" -> "var partialGraph" ;
"var partialGraph" -> "t.main:partialGraph:setState";
// main 7: twjs_.initListeners( categories , partialGraph)
"t.main:MainFunction" -> "t.TinawebJS:initListeners" ;
"t.TinawebJS:initListeners" -> "t.TinawebJS:SelectionEngine:new" [label="initListeners:SelInst"] ;
"t.TinawebJS:initListeners" -> "onclick:#changetype" ;
"t.TinawebJS:initListeners" -> "onclick:#changelevel" ;
"t.TinawebJS:initListeners" -> "onclick:#aUnfold" ;
"t.TinawebJS:initListeners" -> "t.minimap:startMiniMap" [label = "if minimap"] ;
"t.TinawebJS:initListeners" -> "t.methods:pushSWClick" [label = "var swclickActual"] ;
"t.TinawebJS:initListeners" -> "t.methods:cancelSelection" ;
"t.methods:cancelSelection" -> "t.methods:highlightSelectedNodes" [label = "false"] ;
"t.methods:highlightSelectedNodes" -> "t.globalUtils:is_empty" ;
"t.methods:cancelSelection" -> "erase:#names" ;
"t.methods:cancelSelection" -> "erase:#ngrams_actions" ;
"t.methods:cancelSelection" -> "erase:#topPapers" ;
"t.methods:cancelSelection" -> "erase:#opossiteNodes" ;
"t.methods:cancelSelection" -> "erase:#searchinput" ;
"t.methods:cancelSelection" -> "t.methods:LevelButtonDisable" ;
"t.TinawebJS:initListeners" -> "t.sigmaUtils:showMeSomeLabels" ;
"t.sigmaUtils:showMeSomeLabels" -> "t.sigmaUtils:getVisibleNodes" ;
"t.TinawebJS:initListeners" -> "t.TinawebJS:SearchListeners" ;
"t.TinawebJS:SearchListeners" -> "autocomplete:#searchinput" ;
"autocomplete:#searchinput" -> "t.TinawebJS:SelectionEngine:new" [label="SearchListeners:SelInst"] ;
/*t.methods:highlightSelectedNodes*/
}
// THIS IS THE ORIGINAL FIRST VERSION OF changeType()
// It's not used since before I arrived, but useful as a logical resume
//
// States:
// A : Macro-Social
// B : Macro-Semantic
// A*: Macro-Social w/selections
// B*: Macro-Semantic w/selections
// a : Meso-Social
// b : Meso-Semantic
// AaBb: Socio-Semantic
function RefreshState(newNOW){
console.log("\t\t\tin RefreshState newNOW:_"+newNOW+"_.")
if (newNOW!="") {
PAST = NOW;
NOW = newNOW;
// if(NOW=="a" || NOW=="A" || NOW=="AaBb") {
// $("#category-A").show();
// }
// if(NOW=="b" || NOW=="B" || NOW=="AaBb") {
// $("#category-B").show();
// }
}
$("#category-A").hide();
$("#category-B").hide();
// i=0; for(var s in selections) { i++; break;}
// if(is_empty(selections) || i==0) LevelButtonDisable(true);
// else LevelButtonDisable(false);
//complete graphs case
// sels=getNodeIDs(selections).length
if(NOW=="A" || NOW=="a") {
// N : number of nodes
// k : number of ( selected nodes + their neighbors )
// s : number of selections
var N=( Object.keys(TW.Nodes).filter(function(n){return TW.Nodes[n].type==TW.conf.catSoc}) ).length
var k=Object.keys(getNeighs(Object.keys(selections),nodes1)).length
var s=Object.keys(selections).length
console.log("in social N: "+N+" - k: "+k+" - s: "+s)
if(NOW=="A"){
if( (s==0 || k>=(N-1)) ) {
LevelButtonDisable(true);
} else LevelButtonDisable(false);
if(s==N) LevelButtonDisable(false);
}
if(NOW=="a") {
LevelButtonDisable(false);
}
$("#semLoader").hide();
$("#category-A").show();
$("#colorGraph").show();
}
if(NOW=="B" || NOW=="b") {
var N=( Object.keys(TW.Nodes).filter(function(n){return TW.Nodes[n].type==TW.conf.catSem}) ).length
var k=Object.keys(getNeighs(Object.keys(selections),nodes2)).length
var s=Object.keys(selections).length
console.log("in semantic N: "+N+" - k: "+k+" - s: "+s)
if(NOW=="B") {
if( (s==0 || k>=(N-1)) ) {
LevelButtonDisable(true);
} else LevelButtonDisable(false);
if(s==N) LevelButtonDisable(false);
}
if(NOW=="b") {
LevelButtonDisable(false);
}
if ( semanticConverged ) {
$("#semLoader").hide();
$("#category-B").show();
setTimeout(function(){
EdgeWeightFilter("#sliderBEdgeWeight", "0|1", "weight");
NodeWeightFilter ( "#sliderBNodeWeight" , "NGram", "size");
},30)
} else {
$("#semLoader").css('visibility', 'visible');
$("#semLoader").show();
}
}
if(NOW=="AaBb"){
LevelButtonDisable(true);
$("#category-A").show();
$("#category-B").show();
}
TW.partialGraph.render();
}
Remarques sur l'intégration de tina
===================================
### Pour info: procédure suivie
Je copie ici les 2 commandes utilisées pour rendre visible comment a été faite la fusion du git de tina dans celui de garg.
Grace à cette méthode, quand on clonera le dépot gargantext, on obtiendra aussi les contenus du dépôt tina dans notre sous-dossier **`static/lib/graphExplorer`**.
**NB**
Il n'est pas nécessaire de refaire cette procédure, dorénavant les fichiers restent là dans le sous-dossier.
1. on a ajouté le dépôt extérieur de graphExplorer comme si c'était une remote normale
```
git remote add dependancy_graphExplorer_garg https://gogs.iscpif.fr/humanities/graphExplorer_garg
```
2. on a lancé la commande `subtree` avec cette remote, pour récupérer le dépôt tina et le placer dans garg dans le dossier indiqué par l'option `prefix`
```
git subtree add --prefix=static/lib/graphExplorer dependancy_graphExplorer_garg master
```
Résultat:
```
# git fetch dependancy_graphExplorer_garg master
# (...)
# Receiving objects: 100% (544/544), 1.72 MiB | 0 bytes/s, done.
# Resolving deltas: 100% (307/307), done.
# From https://gogs.iscpif.fr/humanities/graphExplorer_garg
# * branch master -> FETCH_HEAD
# * [new branch] master -> dependancy_graphExplorer_garg/master
# Added dir 'static/lib/graphExplorer'
```
3. au passage la même commande a aussi créé le commit suivant dans ma branche gargantext
```
# commit b8d7f061f8c236bad390eb968d153fd6729b7434
# Merge: 3bfb707 d256049
# Author: rloth <romain.loth@iscpif.fr>
# Date: Thu Jul 7 16:01:46 2016 +0200
#
# Add 'static/lib/graphExplorer/' from commit 'd256049'
```
(ici le commit *d256049* indique le point où en était le dépôt tina quand il a été copié)
### Utilisation en développement quotidien
Il n'y a plus rien de particulier à faire. Le dossier contient les éléments de tina qui nous sont nécessaires. On peut ignorer l'existence du subtree et travailler normalement, dans ce dossier et ailleurs.
**=> nos opérations de commit / pull quotidiennes ne sont pas affectées**
Il n'est pas non plus nécessaire de prendre en compte la présence ou l'absence de la "remote" (lien extérieur) dans son travail.
### Utilisation avancée: pour propager les résultats entre dépôts
A présent le dépôt tina peut être vu comme une sorte de dépôt upstream circonscrit à un seul sous-dossier **`static/lib/graphExplorer`** !
Mais si des changements interviennent dans le dépôt tina, ils ne seront pas automatiquement intégrés dans sa copie intégrée à garg. Pour opérer des A/R entre les dépôts le plus simple est une 1ère fois d'ajouter le même pointeur extérieur :
```
git remote add dependancy_graphExplorer_garg https://gogs.iscpif.fr/humanities/graphExplorer_garg
```
A partir de là, il devient très simple de faire des opérations push/pull entre dépôts si besoin est..
1. Récupération de mises à jour tina => garg.
Pour intégrer des changements upstream de tina vers garg, il suffit de lancer la commande suivante:
```
git subtree pull --prefix=static/lib/graphExplorer dependancy_graphExplorer_garg master --squash
```
2. Inversement, les changements effectués dans le dossier **`static/lib/graphExplorer`** par les développeurs garg peuvent aussi être poussés du dépôt garg vers le dépôt tina par un subtree push
```
git subtree push --prefix=static/lib/graphExplorer dependancy_graphExplorer_garg master
```
// KEPT FOR REFERENCE, BINNING NOW PRECOMPUTED in parseCustom
// rewrite of gradientColors with binning and for attributes that can have negative float values
// /!\ age and growth_rate attributes referred to by name
function colorsRelByBins_old(daclass) {
cancelSelection(false);
var binColors
var doModifyLabel = false
TW.handpickedcolor = true
// for debug of heatmapColoring
var totalsPerBinMin = {}
// should be = binColors.length
var nTicksParam = (daclass == 'age') ? 8 : 12
// do first loop entirely to get percentiles => bins, then modify alt_color
// estimating ticks
let tickThresholds = []
let valArray = []
for (var j=0 ; j < TW.nNodes ; j++) {
let n = TW.partialGraph.graph.nodes(TW.nodeIds[j])
if (
!n.hidden
&& n.attributes
&& n.attributes.category == 'terms'
&& n.attributes[daclass] != undefined
) {
valArray.push(Number(n.attributes[daclass]))
}
}
var len = valArray.length
valArray.sort(function(a, b) {return a - b;}) // important :)
for (var l=0 ; l < nTicksParam ; l++) {
let nthVal = Math.floor(len * l / nTicksParam)
tickThresholds.push(valArray[nthVal])
}
// also always add the max+1 as last tick (excluded upper bound of last bin)
tickThresholds.push((valArray[len-1])+1)
console.info(`[|===|=== ${nTicksParam} color ticks ===|===|]\n`, tickThresholds)
cancelSelection(false);
if (daclass == 'age') {
// 9 colors
binColors = TW.gui.getHeatmapColors(9)
}
else if (daclass == 'growth_rate') {
doModifyLabel = true
// 12 colors
binColors = TW.gui.getHeatmapColors(12)
}
// verification
if (nTicksParam != binColors.length) {
console.warn (`heatmapColoring setup mismatch: nTicksParam ${nTicksParam} should == nColors ${binColors.length}`)
}
// get the nodes
for (var j=0 ; j < TW.nNodes ; j++) {
let n = TW.partialGraph.graph.nodes(TW.nodeIds[j])
if (! n.hidden
&& n.attributes
&& n.attributes.category == 'terms'
&& ! isUndef(n.attributes[daclass])
) {
var valSt = n.attributes[daclass]
var originalLabel = TW.Nodes[n.id].label
if (doModifyLabel) {
n.label = `(${valSt}) ${originalLabel}`
}
else {
n.label = originalLabel
}
var theVal = parseFloat(valSt)
var foundBin = false
// console.log('theVal:',theVal)
if( !isNaN(theVal) ) { //is float
// iterate over bins
for(var k=0 ; k < tickThresholds.length-1; k++) {
var binMin = tickThresholds[k]
var binMax = tickThresholds[(k+1)]
if((theVal >= binMin) && (theVal < binMax)) {
// TW.partialGraph._core.graph.nodesIndex[n.id].binMin = binMin
// TW.partialGraph._core.graph.nodesIndex[n.id].color = binColors[j]
n.binMin = binMin
n.color = binColors[k]
n.customAttrs.alt_color = binColors[k]
n.customAttrs.altgrey_color = false
foundBin = true
// console.log(`theVal ${theVal} => found its bin ${binMin} ... ${binColors[k]}`)
if (!totalsPerBinMin[binMin]) {
totalsPerBinMin[binMin] = 1
}
else {
totalsPerBinMin[binMin]++
}
break
}
}
// case no bin after loop (perhaps more ticks than colors-1 ??)
if (!foundBin) {
console.warn('no bin for theVal', theVal, n.id)
n.binMin = null
n.color = '#000'
n.customAttrs.alt_color = '#000'
}
}
else {
// case no val
// console.log('no val for', n.id)
n.binMin = null
n.color = '#555'
n.customAttrs.alt_color = '#555'
}
}
}
// console.debug(valArray)
console.info('coloring distribution per tick thresholds' , totalsPerBinMin)
// Edge precompute alt_rgb by new source-target nodes-colours combination
repaintEdges()
// set_ClustersLegend ( daclass )
TW.partialGraph.render();
}
// frequent commands
TW.rend.clear()
TW.rend.render()
TW.partialGraph.settings.embedObjects({prefix: 'renderer1:'})('singleHover')
// POSS: edit config of CanvasRenderingContext2D
// TW.rend.contexts.nodes.imageSmoothingQuality = "high"
// TW.rend.contexts.edges.imageSmoothingQuality = "high"
// TW.rend.contexts.labels.imageSmoothingQuality = "high"
// cf. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
TW.rend.contexts.nodes.globalCompositeOperation = "multiply"
TW.rend.contexts.edges.globalCompositeOperation = "multiply"
TW.rend.contexts.labels.globalCompositeOperation = "multiply"
// rendering one
var oneNode = TW.partialGraph.graph.nodes(4)
sigma.canvas.nodes.def(
oneNode,
TW.rend.contexts.nodes,
TW.partialGraph.settings.embedObjects({prefix: 'cam0:'})
)
// for fixed "hoverlike" labels => override the module's sigma.canvas.labels.def with an "if" like below (or add another type)
// cf. sigmaUtils.twRender.canvas.labels
// current commands
TW.partialGraph.settings.embedObjects({prefix: 'renderer1:'})('singleHover')
// POSS: edit config of CanvasRenderingContext2D
// TW.rend.contexts.nodes.imageSmoothingQuality = "high"
// TW.rend.contexts.edges.imageSmoothingQuality = "high"
// TW.rend.contexts.labels.imageSmoothingQuality = "high"
// cf. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
TW.rend.contexts.nodes.globalCompositeOperation = "multiply"
TW.rend.contexts.edges.globalCompositeOperation = "multiply"
TW.rend.contexts.labels.globalCompositeOperation = "multiply"
// rendering one
var oneNode = TW.partialGraph.graph.nodes(4)
sigma.canvas.nodes.def(
oneNode,
TW.rend.contexts.nodes,
TW.partialGraph.settings.embedObjects({prefix: 'cam0:'})
)
## Liste des principaux changements effectués
... durant la refonte à l'occasion du passage à sigma 1.2
1. refonte du début du `main` pour distinguer les choix initiaux (mode gexf et mode json, biparti ou pas) de la suite harmonisée (instanciation du graphe)
2. réécriture accesseurs et actions d'affichage (suppression de certains rendus identiques consécutifs)
3. préparation d'un index inversé par attributs
- structure valeurs par attributs => liste des nodes
- ou groupes de valeurs par attributs => liste des nodes
- utile pour les filtres, les légendes et facettes de recherche
- sait créer de façon configurable des "bins" (= paniers de valeurs) pour tout attribut à valeurs continues ou ayant un effectif très nombreux
4. selection: code simplifié pour les évenements click, et rendu plus esthtique pour l'identification des voisins
5. sélection sur zone beaucoup plus rapide grace au quadtree
6. exploration plus fluide grace au précalcul des couleurs de base, alternatives, grisées
7. optimisations mémoire
- éviter dans une large mesure les copies implicites de l'ensemble des nodes
- version sigma.noIndexes.js sans les indexs faisant doublons avec tina
- par défaut ces indexs doublaient la signature RAM
- ancien tina 60MB => nouveau 120MB
- avec la version noIndexes ancien 60MB => nouveau 64MB
8. nouvelle api topPapers pour l'interrogation directe de twitter
9. meilleure stratégie pour les customizations du rendering (elles ne nécessitent plus de modifier le code de sigma lui-même)
10. nouveau layout plus rapide lors des évenements resize
11. reconnexion du mode biparti qui était fonctionnel dans les versions tina classiques (types nommés en durs "sem/soc" avant 2014) avec l'architecture SystemStates dans les tina après 2014 (qui préserve l'historique des types mais les encode d'une façon plus compliquée à base de "typestrings")
12. plusieurs rangements
- suppression des anciennes structures "localdb" inutilisées (héritées de cortext?)
- portage vers les librairies bootstrap et jquery dans leurs nouvelles versions
- ajout de namespaces pour limiter le nombre de variables globales
- settings_explorer: suppression de settings non utilisés, reconnexion de settings présents
- suppression de fonctions obsolètes
13. debugFlags dans les settings
14. intégration du plugin sigma noverlap: fonctionnalité très importante (mais coûteuse)
15. mode 'standalone' (local), ajout d'un <input type='file'>
### Changements cours ou encore à faire:
15. architecture générale
- fonctions linéaires sur scénarios ==> objets d'interaction + évenements
(serait beaucoup plus facile à maintenir et faciliterait la modularité)
16. utilisation plus à fond des nouveaux plugins sigma
- cf. http://twjs.org/sigma
- `filters` très puissant
- stratégie via la prop `hidden` (au lieu de del/add comme actuellement)
- primitives combinables: nodesBy, edgesBy, neighborsOf
- dragNodes: plus agréable de pouvoir déplacer les noeuds
17. clarifications reverse api
- specifications sur arguments en entrée (url) et possibilités bridge
- specifications sur types de documents
- noms des categories attendues, et attributs possibles
- formats à savoir traiter
18. clarifications API pour les serveurs de sources
- serveur topPapers à inclure comme module ou projets à part
- spécificités API gargantext (actions sur les Ngrammes/listes) : inclure ou à part ?
19. cohérence de certains choix:
- la selection des "opposite neighbors" n'est pas close: on ne retrouve que le voisinage local, mais on ne peut pas retomber sur le graphe d'origine sans recharger la page
- pourquoi catSoc par défaut? => FAIT
- pourquoi ne pas intégrer fillGraph dans l'instance parseCustom ?
- pourquoi ne pas intégrer env/listeners dans l'instance TW ?
20. thèmes de couleurs possibles + effets canvas eg multiply => possibilités GUI
// £TODO rendering optimization: reduce effort by looping only on previously selected and neighbors
// and having (!active && !highlight) tested instead of then useless grey flag
This diff is collapsed.
......@@ -113,7 +113,7 @@ foreach ($wos_ids as $id => $score) {
$sql = 'SELECT data FROM ISITITLE WHERE id='.$id.' group by data';
foreach ($base->query($sql) as $row) {
$external_link="<a href=http://google.com/webhp?#q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=15px src="libs/img2/google.png"></a>';
$external_link="<a href=http://google.com/webhp?#q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=15px src="twlibs/img/google.png"></a>';
$output.="<li title='".$score."'>";
$output.=$external_link.imagestar($score,$factor,$twjs).' ';
$output.='<a href="JavaScript:newPopup(\''.$twjs.'default_doc_details.php?gexf='.urlencode($gexf).'&index='.$table.'&query='.urlencode($query).'&type='.urlencode($_GET["type"]).'&id='.$id.' \')">'.$row['data']." </a> ";
......@@ -294,10 +294,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
......@@ -114,10 +114,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
......@@ -100,7 +100,7 @@ foreach ($wos_ids as $id => $score) {
//the old one:
//$output.='<a href="JavaScript:newPopup(\''.$twjs.'php/default_doc_details.php?id='.$id.' \')">'.$row['data']." </a> ";
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="libs/img2/gs.png"></a>';
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="twlibs/img/gs.png"></a>';
//$output.='<a href="JavaScript:newPopup(''php/doc_details.php?id='.$id.''')"> Link</a>';
}
......@@ -133,10 +133,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
......@@ -101,7 +101,7 @@ foreach ($wos_ids as $id => $score) {
//the old one:
//$output.='<a href="JavaScript:newPopup(\''.$twjs.'php/default_doc_details.php?id='.$id.' \')">'.$row['data']." </a> ";
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="libs/img2/gs.png"></a>';
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="twlibs/img/gs.png"></a>';
//$output.='<a href="JavaScript:newPopup(''php/doc_details.php?id='.$id.''')"> Link</a>';
}
......@@ -134,10 +134,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
......@@ -147,7 +147,7 @@ foreach ($wos_ids as $id => $score) {
//the old one:
//$output.='<a href="JavaScript:newPopup(\''.$twjs.'php/default_doc_details.php?id='.$id.' \')">'.$row['data']." </a> ";
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="libs/img2/gs.png"></a>';
$external_link="<a href=http://scholar.google.com/scholar?q=".urlencode('"'.$row['data'].'"')." target=blank>".' <img width=20px src="twlibs/img/gs.png"></a>';
//$output.='<a href="JavaScript:newPopup(''php/doc_details.php?id='.$id.''')"> Link</a>';
}
......@@ -190,10 +190,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
......@@ -99,7 +99,7 @@ foreach ($wos_ids as $id => $score) {
$sql = 'SELECT data FROM ISITITLE WHERE id='.$id.' group by data';
foreach ($base->query($sql) as $row) {
$external_link="<a href=http://google.com/webhp?#q=".urlencode('"'.utf8_decode($row['data']).'"')." target=blank>".' <img width=15px src="libs/img2/google.png"></a>';
$external_link="<a href=http://google.com/webhp?#q=".urlencode('"'.utf8_decode($row['data']).'"')." target=blank>".' <img width=15px src="twlibs/img/google.png"></a>';
$output.="<li title='".$score."'>";
$output.=$external_link.imagestar($score,$factor,$twjs).' ';
$output.='<a href="JavaScript:newPopup(\''.$twjs.'default_doc_details2.php?gexf='.urlencode($gexf).'&query='.urlencode($query).'&type='.urlencode($_GET["type"]).'&id='.$id.' \')">'.htmlentities($row['data'], ENT_QUOTES, "UTF-8")." </a> ";
......@@ -177,10 +177,10 @@ function imagestar($score,$factor,$twjs) {
if ($score > .5) {
$star_image = '';
for ($s = 0; $s < min(5,$score/$factor); $s++) {
$star_image.='<img src="libs/img2/star.gif" border="0" >';
$star_image.='<img src="twlibs/img/star.gif" border="0" >';
}
} else {
$star_image.='<img src="libs/img2/stargrey.gif" border="0">';
$star_image.='<img src="twlibs/img/stargrey.gif" border="0">';
}
return $star_image;
}
......
### tinawebJS CSS, image and fonts dependencies
......@@ -127,7 +127,7 @@
display: block;
width: 24px;
height: 24px;
background:url("../img2/plusmoins.png");
background:url("../img/plusmoins.png");
margin: 0 auto;
}
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment