From baa586a0254200edea6105226e9083eb1e63e6e3 Mon Sep 17 00:00:00 2001
From: rloth <romain.loth@iscpif.fr>
Date: Wed, 31 May 2017 14:53:31 +0200
Subject: [PATCH] more settings harmonization (presentation, sourcefile, sigma
 drawing params)

---
 settings_explorerjs.js   | 148 ++++++++++++++++++---------------------
 tinawebJS/Tinaweb.js     |  16 ++++-
 tinawebJS/enviroment.js  |  12 ++--
 tinawebJS/main.js        |  34 ++++-----
 tinawebJS/methods.js     |   8 +--
 tinawebJS/sigmaUtils.js  |  14 ++--
 tinawebJS/sigma_tools.js |   2 +-
 7 files changed, 118 insertions(+), 116 deletions(-)

diff --git a/settings_explorerjs.js b/settings_explorerjs.js
index 8c22eb7..88d9f1a 100644
--- a/settings_explorerjs.js
+++ b/settings_explorerjs.js
@@ -13,7 +13,6 @@ TW.conf = (function(TW){
   // TINA POSSIBLE DATA SOURCES
   // ==========================
 
-
   // Graph data source
   // -----------------
   // the graph input depends on TWConf.sourcemode (or manual url arg 'sourcemode')
@@ -42,18 +41,16 @@ TW.conf = (function(TW){
   // TWConf.relatedDocsType
 
 
-  // ===========
-  // DATA FACETS
-  // ===========
-
+  // =======================
+  // DATA FACETS AND LEGENDS
+  // =======================
+  // to process node attributes values from data
+  //    => colors   (continuous numeric attributes)
+  //    => clusters (discrete numeric or str attributes),
 
   // create facets ?
   TWConf.scanClusters = true
 
-  // to handle node attributes from data
-  //    => clusters (discrete numeric or str vars),
-  //    => colors   (continuous numeric vars)
-
   // for continuous attrvalues/colors (cf. clustersBy), how many levels in legend?
   TWConf.legendsBins = 7 ;
 
@@ -67,7 +64,7 @@ TW.conf = (function(TW){
     'growth_rate': 12
   }
 
-  // default clustering (used to show as initial color)
+  // default clustering attribute (<---> used for initial node colors)
   TWConf.nodeClusAtt = "modularity_class"
 
 
@@ -121,7 +118,7 @@ TW.conf = (function(TW){
 
   // if fa2Available, the auto-run config:
 
-    TWConf.fa2Enabled= false;       // fa2 auto-run at start and after graph modified ?
+    TWConf.fa2Enabled= true;        // fa2 auto-run at start and after graph modified ?
     TWConf.fa2Milliseconds=5000;    // duration of auto-run
     TWConf.minNodesForAutoFA2 = 5   // graph size threshold to auto-run
 
@@ -133,86 +130,81 @@ TW.conf = (function(TW){
   TWConf.strSearchBar = "Select topics";
 
 
-  // =======================
-  // TINA RENDERING SETTINGS
-  // =======================
-  TWConf.overSampling = true    // costly hi-def rendering (true => pixelRatio x 2)
-
-  // relative sizes (iff graph display with both nodetypes)
-  TWConf.sizeMult = [];
-  TWConf.sizeMult[0] = 1.5;    // ie for node type 0
-  TWConf.sizeMult[1] = 1.0;    // ie for node type 1
-
-  // circle selection cursor
-  TWConf.circleSizeMin = 0;
-  TWConf.circleSizeMax = 100;
-
-  // size range for neighbor nodes "tagcloud"
-  TWConf.tagcloudFontsizeMin = 12;
-  TWConf.tagcloudFontsizeMax = 24;
-
-  TWConf.tagcloudSameLimit = 50   // display at most how many neighbors of the same type
-  TWConf.tagcloudOpposLimit = 10    // display at most how many neighbors of the opposite type
-
+  // ===================
+  // RENDERING SETTINGS
+  // ===================
+  TWConf.twRendering = true ;     // false: use sigma "stock" rendering
+                                  // true:  use our rendering customizations
+                                  //        (nodes with borders,
+                                  //         edges with curves,
+                                  //         better labels, etc)
 
-  TWConf.defaultNodeColor = "rgb(40,40,40)"
+  TWConf.overSampling = true      // hi-def rendering (true => pixelRatio x 2)
 
-  // selected/deselected rendering
-  TWConf.nodesGreyBorderColor = "rgba(100, 100, 100, 0.5)";  // not selected nodes
-
-
-  TWConf.selectedColor = "default"  // "node" for a background like the node's color,
-                                    // "default" for note-like yellow
+  // sigma rendering settings
+  // ------------------------
+  TWConf.sigmaJsDrawingProperties = {
+      // nodes
+      defaultNodeColor: "#333",
+      twNodeRendBorderSize: 1,           // node borders (only iff ourRendering)
+      twNodeRendBorderColor: "#eee",
+
+      // edges
+      minEdgeSize: 2,                    // in fact used in tina as edge size
+      defaultEdgeType: 'curve',          // 'curve' or 'line' (curve only iff ourRendering)
+      twEdgeDefaultOpacity: 0.4,         // initial opacity added to src/tgt colors
+
+      // labels
+      font: "Droid Sans",                // font params
+      fontStyle: "bold",
+      defaultLabelColor: '#000',         // labels text color
+      labelSizeRatio: 1,                 // initial label size (on the slider)
+      labelThreshold: 5,                 // min node cam size to start showing label
+                                         // (old tina: showLabelsIfZoom)
 
-  TWConf.edgeDefaultOpacity = 0.4                      // opacity when true_color
-  TWConf.edgeGreyColor = "rgba(150, 150, 150, 0.5)";   // not selected edges
+      // hovered nodes
+      defaultHoverLabelBGColor: '#fff',
+      defaultHoverLabelColor: '#000',
+      borderSize: 2.5,                   // for ex, bigger border when hover
+      nodeBorderColor: "node",           // choices: 'default' color vs. node color
+      defaultNodeBorderColor: "black",   // <- if nodeBorderColor = 'default'
 
 
-  // ========================
-  // SIGMA RENDERING SETTINGS
-  // ========================
-  // triggers overriding sigma.canvas renderers: nodes.def, labels.def, edges.def
-  TWConf.ourRendering = true ;
+      // selected nodes <=> special label
+      twSelectedColor: "node",     // "node" for a label bg like the node color,
+                                   // "default" for note-like yellow
 
+      // not selected <=> grey
+      twNodesGreyOpacity: .35,                       // smaller value: more grey
+      twBorderGreyColor: "rgba(100, 100, 100, 0.5)",
+      twEdgeGreyColor: "rgba(150, 150, 150, 0.5)",
+  };
+  // NB: sigmaJsDrawingProperties are available as 'settings' in all renderers
+  // cf. https://github.com/jacomyal/sigma.js/wiki/Settings#renderers-settings
 
-  TWConf.sigmaJsDrawingProperties = {
-      defaultLabelColor: 'black',
-      defaultLabelSize: 30, // in fact usually overridden by node data...
-      labelSizeRatio: 1,   // ...but this ratio allows truly adjusting the sizes
 
-      labelThreshold: 5,   // <- replaces deprecated showLabelsIfZoom
+  // tina environment rendering settings
+  // -----------------------------------
+  // mouse captor zoom limits
+  TWConf.zoomMin = .015625         // for zoom IN   (ex: 1/64 to allow zoom x64)
+  TWConf.zoomMax = 2               // for zoom OUT
 
-      defaultEdgeType: 'curve',  // 'curve' or 'line'
+  // circle selection cursor
+  TWConf.circleSizeMin = 0;
+  TWConf.circleSizeMax = 100;
 
-      defaultBorderView: "always",
+  // size range for neighbor nodes "tagcloud"
+  TWConf.tagcloudFontsizeMin = 12;
+  TWConf.tagcloudFontsizeMax = 24;
 
-      // new sigma.js only for hover + new settingnames
-      defaultHoverLabelBGColor: '#fff',
-      defaultHoverLabelColor: '#000',
-      borderSize: 2.5, // (only for hovered nodes)
-      defaultNodeBorderColor: "black",
-      nodeBorderColor: "default",  // vs. node
-
-      // for custom TW node renderer with borders
-      twNodeRendBorderSize: 1,   // (for all normal nodes, iff TWConf.nodeRendBorder)
-      twNodeRendBorderColor: "#222",
-      // twNodeRendBorderColor: "#eee",
-
-      font: "Droid Sans",
-      // font: "Crete Round",
-      // font: "Ubuntu Condensed",
-      fontStyle: "bold",
-  };
+  TWConf.tagcloudSameLimit = 50     // max displayed neighbors of the same type
+  TWConf.tagcloudOpposLimit = 10    // max displayed neighbors of the opposite type
 
-  TWConf.sigmaJsGraphProperties = {
-      minEdgeSize: 3,
-      // maxEdgeSize: 10
-  };
+  // relative sizes (iff ChangeType == both nodetypes)
+  TWConf.sizeMult = [];
+  TWConf.sizeMult[0] = 1.5;    // ie for node type 0
+  TWConf.sizeMult[1] = 1.0;    // ie for node type 1
 
-  TWConf.sigmaJsMouseProperties = {
-      minRatio: .03125,  // 1/32  pour permettre zoom x32
-      maxRatio: 2
-  };
 
 
   // ===========
diff --git a/tinawebJS/Tinaweb.js b/tinawebJS/Tinaweb.js
index b783dce..b16d2cb 100644
--- a/tinawebJS/Tinaweb.js
+++ b/tinawebJS/Tinaweb.js
@@ -873,7 +873,7 @@ TinaWebJS = function ( sigmacanvas ) {
 
     // to init local, instance-related listeners (need to run at new sigma instance)
     // args: @partialGraph = a sigma instance
-    this.SigmaListeners = function(partialGraph, initialActivetypes) {
+    this.initSigmaListeners = function(partialGraph, initialActivetypes) {
 
       var SelInst = new SelectionEngine();
 
@@ -1009,8 +1009,8 @@ TinaWebJS = function ( sigmacanvas ) {
 
           // new sigma.js current zoom ratio
           value: partialGraph.camera.ratio,
-          min: 1 / TW.conf.sigmaJsMouseProperties.maxRatio,   // ex x.5
-          max: 1 / TW.conf.sigmaJsMouseProperties.minRatio,   // ex x32
+          min: 1 / TW.conf.zoomMax,   // ex x.5
+          max: 1 / TW.conf.zoomMin,   // ex x32
           // range: true,
           step: .2,
           value: 1,
@@ -1098,6 +1098,16 @@ TinaWebJS = function ( sigmacanvas ) {
     }
 
 
+    // clears the graph instance
+    this.clearSigma = function() {
+      if (TW.partialGraph && TW.partialGraph.graph) {
+        TW.partialGraph.graph.clear()
+        TW.partialGraph.refresh()
+        selections = []
+      }
+    }
+
+
     this.initialActivetypes = function( categories ) {
         var firstActivetypes = []
         for(var i=0; i<categories.length ; i++) {
diff --git a/tinawebJS/enviroment.js b/tinawebJS/enviroment.js
index 040984a..dc1980e 100755
--- a/tinawebJS/enviroment.js
+++ b/tinawebJS/enviroment.js
@@ -52,11 +52,7 @@ function createFilechooserEl () {
         }
         else {
           // we might have a previous graph opened
-          if (TW.partialGraph && TW.partialGraph.graph) {
-            TW.partialGraph.graph.clear()
-            TW.partialGraph.refresh()
-            selections = []
-          }
+          TW.instance.clearSigma()
 
           // run
           if (theFormat == 'json')
@@ -978,7 +974,11 @@ function jsActionOnGexfSelector(gexfBasename){
       if (pathcomponents[i] != 'explorerjs.html')
         serverPrefix += '/'+pathcomponents[i]
     }
-    var newDataRes = AjaxSync({ URL: window.location.origin+serverPrefix+'/'+gexfPath });
+    var newDataRes = AjaxSync({ URL: window.location.origin+serverPrefix+gexfPath });
+
+    // remove any previous instance
+    TW.instance.clearSigma()
+
     mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance)
     writeLabel(gexfBasename)
 }
diff --git a/tinawebJS/main.js b/tinawebJS/main.js
index 08bdca3..a7526a5 100644
--- a/tinawebJS/main.js
+++ b/tinawebJS/main.js
@@ -104,11 +104,13 @@ if (window.location.protocol == 'file:'
   let inputDiv = document.getElementById('localInput')
   inputDiv.style.display = 'block'
 
-  var remark = document.createElement("p")
-  remark.innerHTML = `You're running project explorer as a local html file (no syncing).`
-  remark.classList.add('comment')
-  remark.classList.add('centered')
-  inputDiv.appendChild(remark)
+  if (window.location.protocol == 'file:') {
+    var remark = document.createElement("p")
+    remark.innerHTML = `You're running project explorer as a local html file (no syncing).`
+    remark.classList.add('comment')
+    remark.classList.add('centered')
+    inputDiv.appendChild(remark)
+  }
 
   // user can open a gexf or json from his fs
   var graphFileInput = createFilechooserEl()
@@ -263,11 +265,11 @@ function syncRemoteGraphData () {
 
     // menufile case : a list of source files in ./db.json
     if (sourcemode == 'servermenu') {
-        console.log("no @file arg nor TW.mainfile: trying FILEMENU TW.conf.sourceMenu")
+        console.log("reading from FILEMENU TW.conf.sourceMenu")
         // we'll first retrieve the menu of available files in db.json, then get the real data in a second ajax
         var infofile = TW.conf.sourceMenu
 
-        if (TW.conf.debug.logFetchers)  console.info(`attempting to load infofile ${infofile}`)
+        if (TW.conf.debug.logFetchers)  console.info(`attempting to load filemenu ${infofile}`)
         var preRES = AjaxSync({ URL: infofile, DT:"json" });
 
         if (preRES['OK'] && preRES.data) {
@@ -323,7 +325,6 @@ function syncRemoteGraphData () {
                 files_selector += '<option '+cssFileSelected+'>'+gexfBasename+'</option>'
             }
             // console.log( files_selector )
-            break;
         }
         files_selector += "</select>"
         console.log("files_selector HTML", files_selector)
@@ -336,7 +337,7 @@ function syncRemoteGraphData () {
     }
     // direct file fallback case: specified file in settings_explorer
     else if (TW.conf.sourceFile && linkCheck(TW.conf.sourceFile)) {
-      console.log("no @file arg: trying TW.mainfile from settings")
+      console.log("no @file arg: trying TW.conf.sourceFile from settings")
       the_file = TW.conf.sourceFile;
     }
     else {
@@ -495,15 +496,13 @@ function mainStartGraph(inFormat, inData, twInstance) {
       // our final sigma params (cf github.com/jacomyal/sigma.js/wiki/Settings)
       TW.customSettings = Object.assign(
 
-          // 1) default values
+          // 1) optimal low-level values (was: "developer settings")
           {
               drawEdges: true,
               drawNodes: true,
               drawLabels: true,
 
               labelSize: "proportional",
-              // font: "Ubuntu Condensed",   // overridden by settings_explorer.js
-              // labelColor: "node",
 
               // nodesPowRatio: .3,
               batchEdgesDrawing: false,
@@ -520,13 +519,14 @@ function mainStartGraph(inFormat, inData, twInstance) {
               touchEnabled: false,
 
               animationsTime:150,
-              mouseZoomDuration:250
+              mouseZoomDuration:250,
+
+              zoomMin: TW.conf.zoomMin,
+              zoomMax: TW.conf.zoomMax
           },
 
-          // 2) settings_explorer values
+          // 2) user-configurable values (cf. settings_explorer)
           TW.conf.sigmaJsDrawingProperties,
-          TW.conf.sigmaJsGraphProperties,
-          TW.conf.sigmaJsMouseProperties
       )
 
 
@@ -574,7 +574,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
       // (new graph => new categories combinations => new array)
 
       // now that we have a sigma instance, let's bind our click handlers to it
-      TW.instance.SigmaListeners(TW.partialGraph, initialActivetypes)
+      TW.instance.initSigmaListeners(TW.partialGraph, initialActivetypes)
 
       // [ / Poblating the Sigma-Graph ]
 
diff --git a/tinawebJS/methods.js b/tinawebJS/methods.js
index 196fa74..a891b56 100755
--- a/tinawebJS/methods.js
+++ b/tinawebJS/methods.js
@@ -735,15 +735,15 @@ function prepareNodesRenderingProperties(nodesDict) {
       n.color = `rgb(${rgbStr})`
     }
     else {
-      n.color = TW.conf.defaultNodeColor
-      rgbStr = TW.conf.defaultNodeColor.split(',').splice(0, 3).join(',');
+      n.color = TW.conf.sigmaJsDrawingProperties.defaultNodeColor
+      rgbStr = n.color.split(',').splice(0, 3).join(',');
     }
 
     n.customAttrs = {
       grey: false,
       highlight: false,
       true_color : n.color,
-      defgrey_color : "rgba("+rgbStr+",.35)"
+      defgrey_color : "rgba("+rgbStr+","+TW.conf.sigmaJsDrawingProperties.twNodesGreyOpacity+")"
     }
 
     // POSS n.type: distinguish rendtype and twtype
@@ -770,7 +770,7 @@ function prepareEdgesRenderingProperties(edgesDict, nodesDict) {
 
     var rgbStr = sigmaTools.edgeRGB(nodesDict[e.source].color, nodesDict[e.target].color)
 
-    e.color = "rgba("+rgbStr+","+TW.conf.edgeDefaultOpacity+")"
+    e.color = "rgba("+rgbStr+","+TW.conf.sigmaJsDrawingProperties.twEdgeDefaultOpacity+")"
     e.customAttrs = {
       grey: false,
       activeEdge : false,
diff --git a/tinawebJS/sigmaUtils.js b/tinawebJS/sigmaUtils.js
index 398966f..7a32688 100755
--- a/tinawebJS/sigmaUtils.js
+++ b/tinawebJS/sigmaUtils.js
@@ -110,7 +110,7 @@ SigmaUtils = function () {
 
         context.beginPath();
 
-        if (TW.conf.nodesGreyBorderColor == "node")
+        if (settings('twSelectedColor') == "node")
           context.fillStyle = TW.handpickedcolor? node.customAttrs.alt_color : node.color; // node's
         else
           context.fillStyle = "#F7E521"; // yellow
@@ -203,11 +203,11 @@ SigmaUtils = function () {
         // console.debug(`t=${tstamp()} curve render activeedge: ${edgeInfos(edge)})`)
       }
       else if (edge.customAttrs.grey) {
-        color = TW.conf.edgeGreyColor
+        color = settings('twEdgeGreyColor')
         size = 1
       }
       else {
-        color = "rgba( "+baseRGB+" , "+TW.conf.edgeDefaultOpacity+")";
+        color = "rgba( "+baseRGB+" , "+TW.conf.sigmaJsDrawingProperties.twEdgeDefaultOpacity+")";
         size = defSize
       }
 
@@ -255,11 +255,11 @@ SigmaUtils = function () {
         color = 'rgba('+rgb.join()+',.7)'
       }
       else if (edge.customAttrs.grey) {
-        color = TW.conf.edgeGreyColor
+        color = settings('twEdgeGreyColor')
         size = 1
       }
       else {
-        // color = "rgba( "+rgb.join()+" , "+TW.conf.edgeDefaultOpacity+")";
+        // color = "rgba( "+rgb.join()+" , "+TW.conf.sigmaJsDrawingProperties.twEdgeDefaultOpacity+")";
         color = edge.customAttrs.true_color
         size = defSize
       }
@@ -293,7 +293,7 @@ SigmaUtils = function () {
 
         // mode variants
         if (TW.selectionActive) {
-          // passive nodes should blend in the grey of TW.conf.edgeGreyColor
+          // passive nodes should blend in the grey of twEdgeGreyColor
           // cf settings_explorerjs, defgrey_color and greyEverything()
           if (node.customAttrs.grey) {
             if (! TW.handpickedcolor) {
@@ -309,7 +309,7 @@ SigmaUtils = function () {
               nodeColor = node.customAttrs.altgrey_color
             }
             // nice looking uniform grey
-            borderColor = TW.conf.nodesGreyBorderColor
+            borderColor = TW.conf.sigmaJsDrawingProperties.twBorderGreyColor
           }
           // neighbor nodes <=> (highlight flag AND selectionActive)
           else if(node.customAttrs.highlight) {
diff --git a/tinawebJS/sigma_tools.js b/tinawebJS/sigma_tools.js
index d31c5c9..6792651 100644
--- a/tinawebJS/sigma_tools.js
+++ b/tinawebJS/sigma_tools.js
@@ -45,7 +45,7 @@ sigmaTools = (function(stools) {
         var rawEdge = rawGexfEdges[i]
 
         var rgbStr = sigmaTools.edgeRGB(newNodes[rawEdge.source].color, newNodes[rawEdge.target].color)
-        var leColor = "rgba("+rgbStr+","+TW.conf.edgeDefaultOpacity+")"
+        var leColor = "rgba("+rgbStr+","+TW.conf.sigmaJsDrawingProperties.twEdgeDefaultOpacity+")"
 
         var newEid = rawEdge.source+";"+rawEdge.target;
         var newEdge = {
-- 
2.21.0