Commit d76ab522 authored by Romain Loth's avatar Romain Loth

WIP settings refacto + urlparams 1/2

reordered params inside settings_explorerjs with new packaging in TW.conf property and more meaningful/transparent variable names + newurl param sourcemode
parent d10bdadf
...@@ -57,3 +57,16 @@ They are handled in Tinaweb.MultipleSelection2. ...@@ -57,3 +57,16 @@ They are handled in Tinaweb.MultipleSelection2.
For any node `n` the relevant flags at selection are: For any node `n` the relevant flags at selection are:
- `n.active` iff node is selected - `n.active` iff node is selected
- `n.customAttrs.highlight` if node is a neighbor of a selected node - `n.customAttrs.highlight` if node is a neighbor of a selected node
## Variae
#### Facets: node attributes as colors/clusters
At parsing time, every node attributes are indexed by values.
This indexes are stored in TW.Clusters and provide an access to sets of nodes that have a given value or range of values.
- if discrete attrvalues with <= 30 classes (colorsBy, clustersBy), the storage structure is: `TW.Clusters[nodeType][clusterType].classes.[possibleValue]`
(the content is a list of ids with the value `possibleValue`)
- if continuous or many possible values (>30) (clustersBy, colorsRelByBins), the storage uses ordered ranges ("bins"):
`TW.Clusters[nodeType][clusterType].ranges.[interval]`
...@@ -336,18 +336,18 @@ function set_ClustersLegend ( daclass, groupedByTicks ) { ...@@ -336,18 +336,18 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
// jsonparams = jsonparams.split('&').join('__and__'); // jsonparams = jsonparams.split('&').join('__and__');
// //dbsPaths.push(getGlobalDBs()); // //dbsPaths.push(getGlobalDBs());
// thisgexf=JSON.stringify(decodeURIComponent(getUrlParam.file)); // thisgexf=JSON.stringify(decodeURIComponent(getUrlParam.file));
// image='<img style="display:block; margin: 0px auto;" src="'+TW.APINAME+'img/ajax-loader.gif"></img>'; // image='<img style="display:block; margin: 0px auto;" src="'+TW.companionAPI+'img/ajax-loader.gif"></img>';
// $("#tab-container-top").show(); // $("#tab-container-top").show();
// $("#topPapers").show(); // $("#topPapers").show();
// $("#topPapers").html(image); // $("#topPapers").html(image);
// $.ajax({ // $.ajax({
// type: 'GET', // type: 'GET',
// url: TW.APINAME+'info_div.php', // url: TW.companionAPI+'info_div.php',
// data: "type="+type+"&bi="+bi+"&query="+jsonparams+"&gexf="+thisgexf+"&index="+TW.field[getUrlParam.file], // data: "type="+type+"&bi="+bi+"&query="+jsonparams+"&gexf="+thisgexf+"&index="+TW.field[getUrlParam.file],
// //contentType: "application/json", // //contentType: "application/json",
// //dataType: 'json', // //dataType: 'json',
// success : function(data){ // success : function(data){
// console.log(TW.APINAME+'info_div.php?'+"type="+type+"&bi="+bi+"&query="+jsonparams+"&gexf="+thisgexf+"&index="+TW.field[getUrlParam.file]); // console.log(TW.companionAPI+'info_div.php?'+"type="+type+"&bi="+bi+"&query="+jsonparams+"&gexf="+thisgexf+"&index="+TW.field[getUrlParam.file]);
// $("#topPapers").html(data); // $("#topPapers").html(data);
// }, // },
// error: function(){ // error: function(){
...@@ -370,7 +370,7 @@ function getTopPapers(type){ ...@@ -370,7 +370,7 @@ function getTopPapers(type){
// //
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: TW.APINAME, url: TW.companionAPI,
data: {'query': joined_q}, data: {'query': joined_q},
contentType: "application/json", contentType: "application/json",
success : function(data){ success : function(data){
...@@ -506,7 +506,7 @@ function RenderTweet( tweet) { ...@@ -506,7 +506,7 @@ function RenderTweet( tweet) {
//FOR UNI-PARTITE //FOR UNI-PARTITE
// function selectionUni(currentNode){ // function selectionUni(currentNode){
// console.log("\tin selectionUni:"+currentNode.id); // console.log("\tin selectionUni:"+currentNode.id);
// if(checkBox==false && cursor_size==0) { // if(checkBox==false && TW.circleSize==0) {
// highlightSelectedNodes(false); // highlightSelectedNodes(false);
// opossites = []; // opossites = [];
// selections = []; // selections = [];
...@@ -683,7 +683,7 @@ function circleTrackMouse(e) { ...@@ -683,7 +683,7 @@ function circleTrackMouse(e) {
// } // }
// } // }
ctx.arc(x, y, cursor_size, 0, Math.PI * 2, true); ctx.arc(x, y, TW.circleSize, 0, Math.PI * 2, true);
ctx.closePath(); ctx.closePath();
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
...@@ -694,7 +694,7 @@ function circleTrackMouse(e) { ...@@ -694,7 +694,7 @@ function circleTrackMouse(e) {
// exact subset of nodes under circle // exact subset of nodes under circle
function circleGetAreaNodes(camX0, camY0) { function circleGetAreaNodes(camX0, camY0) {
var cursor_ray = cursor_size * TW.cam.ratio // cursor_size to cam units var cursor_ray = TW.circleSize * TW.cam.ratio // converting TW.circleSize to cam units
// prepare an approximate neighborhood // prepare an approximate neighborhood
var slightlyLargerNodeset = circleLocalSubset( var slightlyLargerNodeset = circleLocalSubset(
...@@ -799,8 +799,8 @@ function flashNodesArray (nodesArray) { ...@@ -799,8 +799,8 @@ function flashNodesArray (nodesArray) {
// - the dirname of the submodule's files (with a mandatory init.js) // - the dirname of the submodule's files (with a mandatory init.js)
// - the css class of all html elements added by the submodule // - the css class of all html elements added by the submodule
function ProcessDivsFlags() { function ProcessDivsFlags() {
for(var key in TW.DivsFlags) { for(var key in TW.conf.DivsFlags) {
if(TW.DivsFlags[key]===false) { if(TW.conf.DivsFlags[key]===false) {
$("."+key).remove() ; // hide elements of module's class $("."+key).remove() ; // hide elements of module's class
} }
else { else {
......
...@@ -2,248 +2,199 @@ ...@@ -2,248 +2,199 @@
var TW = {} var TW = {}
TW.conf = (function(TW){
// £TODO separate files for TW.vars and TW.settings (configfile) let TWConf = {}
TW.geomap = false;
TW.colorByAtt = false;
TW.twittertimeline = false;
TW.minimap=false;
TW.getAdditionalInfo = true;// True: Activate TopPapers feature.
TW.filemenu = 'db.json'
// TW.mainfile = "data/mysuperproject/my.gexf"
TW.mainfile = "data/politoscope/ProgrammeDesCandidats.enrichi.gexf"
TW.APINAME = "http://127.0.0.1:5000/twitter_search";
TW.tagcloud_limit = 50;
TW.bridge={};
TW.bridge["forFilteredQuery"] = "services/api/graph";
TW.bridge["forNormalQuery"] = "services/api/graph";
TW.gexfPaths={};
TW.Relations = {}
// module_names to load
// ----------------------
TW.DivsFlags = {} ;
// flag name is div class to be removed if false
// *and* subdirectory to import if true
// see also ProcessDivsFlags()
TW.DivsFlags["histogramModule"] = false ;
TW.DivsFlags["histogramDailyVariantModule"] = false ;
// TODO more generic module integrating the variants cf. experiments/histogramModule_STUB_GENERIQUE
TW.DivsFlags["crowdsourcingModule"] = false ;
TW.SystemState = {}
TW.SystemState.level = true;
TW.SystemState.type = [ true, false ] // usually overridden by initialActivetypes
TW.SystemState.selections = [];
TW.SystemState.opposites = [];
TW.catSoc = "Document";
TW.catSem = "NGram";
TW.strSearchBar = "Select or suggest topics";
var ParseCustom = function () {}; TWConf.branding = 'test bipart' // <----- the name displayed in upper left
var SigmaUtils = function () {};
var TinaWebJS = function () {};
// node sizes // ==========================
// ---------- // TINA POSSIBLE DATA SOURCES
var sizeMult = []; // ==========================
sizeMult[TW.catSoc] = 0.0;
sizeMult[TW.catSem] = 0.0;
var minLengthAutoComplete = 1; // the graph input depends on TWConf.sourcemode (or manual url arg 'sourcemode')
var maxSearchResults = 10; TWConf.sourcemode = "api" // accepted: "api" | "serverfile" | "servermenu" | "localfile"
var cursor_size_min= 0; // server-side gexf default source
var cursor_size= 0; TWConf.sourceFile = "data/politoscope/ProgrammeDesCandidats.enrichi.gexf"
var cursor_size_max= 100;
var desirableTagCloudFont_MIN=12; // or remote bridge to default source api ajax queries
var desirableTagCloudFont_MAX=20; TWConf.sourceAPI={};
var desirableNodeSizeMIN=1; TWConf.sourceAPI["forNormalQuery"] = "services/api/graph";
var desirableNodeSizeMAX=12; TWConf.sourceAPI["forFilteredQuery"] = "services/api/graph";
// layouts // ===========
// ------- // DATA FACETS
// just a simple flag on this one // ===========
TW.disperseAvailable=false; // disperseButton hidden at start, disperse stopped forever
TW.fa2Available=false; // fa2Button hidden at start, fa2 stopped forever
// if fa2Button:
TW.fa2enabled=0; // fa2 auto-running at start ?
TW.minNodesForAutoFA2 = 5 // fa2 not run if graph has less nodes than this threshold
// to handle node attributes from data
// => clusters (discrete numeric or str vars),
// => colors (continuous numeric vars)
// ============ < / DEVELOPER OPTIONS > ============ // for continuous attrvalues/colors (cf. clustersBy), how many levels in legend?
TW.branding = 'test bipart' TWConf.legendsBins = 7 ;
TW.libspath = 'libs' // NB path vars should not be used after page load
TW.nodeClusAtt = "modularity_class" // some specific attributes may have other number of levels
TWConf.customLegendsBins = {
'age': 8,
'growth_rate': 12
}
TW.filterSliders = true // ===================
// TINA ACTIVE MODULES
// ===================
TWConf.DivsFlags = {} ;
// flag name is div class to be removed if false
// *and* subdirectory to import if true
// see also ProcessDivsFlags()
TWConf.DivsFlags["histogramModule"] = false ;
TWConf.DivsFlags["histogramDailyVariantModule"] = false ;
// TODO more generic module integrating the variants cf. experiments/histogramModule_STUB_GENERIQUE
TWConf.DivsFlags["crowdsourcingModule"] = false ;
TW.histogramStartThreshold = 10 ; TWConf.libspath = 'libs' // FIXME path vars should not be used after page load !
TW.defaultNodeColor = "rgb(40,40,40)" // =============
TW.edgeDefaultOpacity = 0.4 // opacity when true_color // TINA BEHAVIOR
TW.edgeGreyColor = "rgba(150, 150, 150, 0.5)"; // =============
TW.nodesGreyBorderColor = "rgba(100, 100, 100, 0.5)";
TW.selectedColor = "default" // "node" for a background like the node's color,
// "default" for note-like yellow
TW.overSampling = false // costly hi-def rendering (true => pixelRatio x 2) // Node typology
TWConf.catSoc = "Document";
TWConf.catSem = "NGram";
TW.deselectOnclickStage = true // will a click on the background remove selection ? (except when dragging) // Events handling
var showLabelsIfZoom=1.0; TWConf.deselectOnclickStage = true // will a click on the background remove selection ? (except when dragging)
// for continuous attrvalues/colors (cf. clustersBy), how many levels in legend?
TW.legendsBins = 7 ;
// some specific attributes may have other number of levels // debug flags & log levels
TW.customLegendsBins = { TWConf.debug = {
'age': 8, initialShowAll: false, // show all nodes on bipartite case init (docs + terms in one view)
'growth_rate': 12
}
// show verbose console logs...
logFetchers: false, // ...about ajax/fetching of graph data
logParsers: false, // ...about parsing said data
logFacets: false, // ...about parsing node attribute:value facets
logSettings: false, // ...about settings at Tina and Sigma init time
logSelections: false
}
TW.debugFlags = {
initialShowAll: false, // show all nodes on bipartite case init (docs + terms in one view)
// show verbose console logs... // Layouts
logFetchers: false, // ...about ajax/fetching of graph data // -------
logParsers: false, // ...about parsing said data TWConf.fa2Available=true; // show/hide fa2Button
logFacets: false, // ...about parsing node attribute:value facets TWConf.disperseAvailable=true; // show/hide disperseButton
logSettings: false, // ...about settings at Tina and Sigma init time
logSelections: true
}
// triggers overriding sigma.canvas renderers: nodes.def, labels.def, edges.def // if fa2Available, the auto-run config:
TW.ourRendering = true ;
// ============ < / DEVELOPER OPTIONS > ============ 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
// ============ < SIGMA.JS PROPERTIES > ============ // Full-text search
// ----------------
TWConf.minLengthAutoComplete = 1;
TWConf.maxSearchResults = 10;
var sigmaJsDrawingProperties = {
defaultLabelColor: 'black',
defaultLabelSize: 30, // in fact usually overridden by node data...
labelSizeRatio: 1, // ...but this ratio allows truly adjusting the sizes
labelThreshold: 5, // SIGMA BEHAVIOR SETTINGS
defaultEdgeType: 'curve', // 'curve' or 'line'
defaultBorderView: "always", // SIGMA RENDERING SETTINGS
// triggers overriding sigma.canvas renderers: nodes.def, labels.def, edges.def
TWConf.ourRendering = true ;
// 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 TWConf.sigmaJsDrawingProperties = {
twNodeRendBorderSize: 1, // (for all normal nodes, iff TW.nodeRendBorder) defaultLabelColor: 'black',
twNodeRendBorderColor: "#222", defaultLabelSize: 30, // in fact usually overridden by node data...
// twNodeRendBorderColor: "#eee", labelSizeRatio: 1, // ...but this ratio allows truly adjusting the sizes
font: "Droid Sans", labelThreshold: 5, // <- replaces deprecated showLabelsIfZoom
// font: "Crete Round",
// font: "Ubuntu Condensed",
fontStyle: "bold",
};
var sigmaJsGraphProperties = {
minEdgeSize: 3,
// maxEdgeSize: 10
};
var sigmaJsMouseProperties = {
minRatio: .03125, // 1/32 pour permettre zoom x32
maxRatio: 2
};
// ============ < / SIGMA.JS PROPERTIES > ============
defaultEdgeType: 'curve', // 'curve' or 'line'
defaultBorderView: "always",
// 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
// ============ < VARIABLES.JS > ============ // for custom TW node renderer with borders
twNodeRendBorderSize: 1, // (for all normal nodes, iff TWConf.nodeRendBorder)
twNodeRendBorderColor: "#222",
// twNodeRendBorderColor: "#eee",
var twjs="tinawebJS/"; font: "Droid Sans",
// font: "Crete Round",
// font: "Ubuntu Condensed",
fontStyle: "bold",
};
// possible node types and their inverted map TWConf.sigmaJsGraphProperties = {
TW.categories = []; minEdgeSize: 3,
TW.catDict = {}; // maxEdgeSize: 10
};
var gexfFile; TWConf.sigmaJsMouseProperties = {
//var zoom=0; minRatio: .03125, // 1/32 pour permettre zoom x32
maxRatio: 2
};
var checkBox=false;
var manuallyChecked = false;
var overNodes=false;
var shift_key=false;
var NOW="A"; // =======================
var PAST="--"; // TINA RENDERING SETTINGS
// =======================
TWConf.overSampling = false // costly hi-def rendering (true => pixelRatio x 2)
var swclickActual=""; TWConf.sizeMult = [];
var swclickPrev="";
var swMacro=true;
var socsemFlag=false; TWConf.sizeMult[0] = 1.0; // ie for node type 0
var constantNGramFilter; TWConf.sizeMult[1] = 1.0; // ie for node type 1
TWConf.circleSizeMin= 0;
TWConf.circleSizeMax= 100;
var lastFilter = []
lastFilter["#slidercat0nodesweight"] = {"orig":"-" , "last":"-"}
lastFilter["#slidercat1nodesweight"] = {"orig":"-" , "last":"-"}
lastFilter["#slidercat0edgesweight"] = {"orig":"-" , "last":"-"}
lastFilter["#slidercat1edgesweight"] = {"orig":"-" , "last":"-"}
// ========
// A RANGER £TODO
// ========
// TWConf.nodeClusAtt = "modularity_class"
// var overviewWidth = 200;
// var overviewHeight = 175;
// var overviewScale = 0.25;
// var overviewHover=false;
var moveDelay = 80, zoomDelay = 2;
//var Vecindad;
TW.partialGraph;
var otherGraph;
TW.Nodes = [];
TW.Edges = [];
TW.Clusters = [];
// new dev properties TWConf.filterSliders = true
TW.scanClusters = true // build TW.Clusters in an (attr+val => nodes) reverse index (aka facets)
TW.maxDiscreteValues = 40 // max discrete levels in facet legend (aka bins)
// new TW.Clusters structure
// --------------------------
// was: built in separate loop from read of all attr values
// TW.Clusters[nodeType][clusterType][possibleValue] = clst_idx_of_possible_value
// from now on: TWConf.histogramStartThreshold = 10 ;
// still built in ChangeGraphAppearanceByAtt
// POSS: build in parseCustom (when reading all nodes attributes anyway)
// if discrete attrvalues with <= 30 classes (colorsBy, clustersBy)
// => TW.Clusters[nodeType][clusterType].classes.[possibleValue] = list of ids with the value
// if continuous or many possible values (>30) (clustersBy, colorsRelByBins)
// => TW.Clusters[nodeType][clusterType].ranges.[interval] = list of ids in the interval
TWConf.defaultNodeColor = "rgb(40,40,40)"
TWConf.edgeDefaultOpacity = 0.4 // opacity when true_color
TWConf.edgeGreyColor = "rgba(150, 150, 150, 0.5)";
TWConf.nodesGreyBorderColor = "rgba(100, 100, 100, 0.5)";
TWConf.selectedColor = "default" // "node" for a background like the node's color,
// "default" for note-like yellow
TW.fa2milliseconds=5000; // for initial auto-run if fa2enabled and any console.warn("current conf:", TWConf)
// subsequent auto-runs if graph modified
return TWConf
})()
var nodeslength=0;
var labels = []; // INITIALIZED VARS (£TODO move to main or Tina)
// ================
TW.Nodes = [];
TW.Edges = [];
TW.Relations = {}
TW.Clusters = []; // A "by value" index, built in parseCustom, (aka facets)
var numberOfDocs=0; // not used! TW.gexfPaths={};
var numberOfNGrams=0; // not used, but cf TW.nNodes TW.nEdges TW.labels=[];
// FIXME should become TW.* // FIXME should become TW.*
var selections = []; var selections = [];
...@@ -259,44 +210,50 @@ var nodes2 = {}; ...@@ -259,44 +210,50 @@ var nodes2 = {};
var bipartiteD2N = {}; var bipartiteD2N = {};
var bipartiteN2D = {}; var bipartiteN2D = {};
var flag=0; // possible node types and their inverted map
var firstime=0; TW.categories = [];
var leftright=true; TW.catDict = {};
var edgesTF=false;
//This variables will be updated in sigma.parseCustom.js TW.nodeslength = 0 // <=== £TODO harmonize use with TW.partialGraph.graph.nNodes()
var minNodeSize=10000000;
var maxNodeSize=0; var gexfFile;
// var minEdgeWeight=5.0; // in fact never used... //var zoom=0;
// var maxEdgeWeight=0.0; TW.checkBox=false;
//--------------------------------------------------- TW.shiftKey=false;
TW.manuallyChecked = false;
var bipartite=false;
TW.SystemState = {}
var colorList = ["#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059", "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87", "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80", "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100", "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F", "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09", "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66", "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C","#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81", "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00", "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700", "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329", "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C", "#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800", "#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51", "#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58"]; TW.SystemState.level = true;
TW.SystemState.type = [ true, false ] // usually overridden by initialActivetypes
var RVUniformC = function(seed){ TW.SystemState.selections = [];
this.a=16807; TW.SystemState.opposites = [];
this.b=0;
this.m=2147483647;
this.u; TW.colorList = ["#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059", "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87", "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80", "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100", "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F", "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09", "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66", "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C","#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81", "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00", "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700", "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329", "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C", "#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800", "#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51", "#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58"];
this.seed=seed;
this.x = this.seed;
// this.generar = function(n){
// uniforme = []; var ParseCustom = function () {};
// x = 0.0; var SigmaUtils = function () {};
// x = this.seed; var TinaWebJS = function () {};
// for(i = 1; i < n ; i++){
// x = ((x*this.a)+this.b)%this.m;
// uniforme[i] = x/this.m;
// } // £TODO à ranger
// return uniforme; TW.circleSize= 0;
// }; var lastFilter = []
this.getRandom = function(){ lastFilter["#slidercat0nodesweight"] = {"orig":"-" , "last":"-"}
x = ((this.x*this.a)+this.b)%this.m; lastFilter["#slidercat1nodesweight"] = {"orig":"-" , "last":"-"}
this.x = x; lastFilter["#slidercat0edgesweight"] = {"orig":"-" , "last":"-"}
this.u = this.x/this.m; lastFilter["#slidercat1edgesweight"] = {"orig":"-" , "last":"-"}
return this.u;
}; var desirableTagCloudFont_MIN=12;
} var desirableTagCloudFont_MAX=20;
//unifCont = new RVUniformC(100000000) var desirableNodeSizeMIN=1;
var desirableNodeSizeMAX=12;
// These variables will be updated in sigma.parseCustom.js
var minNodeSize
var maxNodeSize
...@@ -83,7 +83,7 @@ function SelectionEngine() { ...@@ -83,7 +83,7 @@ function SelectionEngine() {
coincd.push(results[i].id) coincd.push(results[i].id)
} }
var targeted = this.SelectorEngine( { var targeted = this.SelectorEngine( {
addvalue:checkBox, addvalue:TW.checkBox,
prevsels:selections, prevsels:selections,
currsels:coincd currsels:coincd
} ) } )
...@@ -147,7 +147,7 @@ function SelectionEngine() { ...@@ -147,7 +147,7 @@ function SelectionEngine() {
// ==================== // ====================
this.MultipleSelection2 = (function(nodes,nodesDict,edgesDict) { this.MultipleSelection2 = (function(nodes,nodesDict,edgesDict) {
if (TW.debugFlags.selections) { if (TW.conf.debug.selections) {
var tMS2_deb = performance.now() var tMS2_deb = performance.now()
console.log("IN SelectionEngine.MultipleSelection2:") console.log("IN SelectionEngine.MultipleSelection2:")
...@@ -273,9 +273,6 @@ function SelectionEngine() { ...@@ -273,9 +273,6 @@ function SelectionEngine() {
// alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(the_new_sels)) // alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(the_new_sels))
// global flag
TW.selectionActive = true
// we send our "gotNodeSet" event // we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection) // (signal for plugins that a search-selection was done or a new hand picked selection)
$('#searchinput').trigger({ $('#searchinput').trigger({
...@@ -315,19 +312,20 @@ function SelectionEngine() { ...@@ -315,19 +312,20 @@ function SelectionEngine() {
return b-a return b-a
}); });
if (TW.debugFlags.selections) { if (TW.conf.debug.selections) {
console.debug('selections', selections) console.debug('selections', selections)
console.debug('oppos', oppos) console.debug('oppos', oppos)
console.debug('same', same) console.debug('same', same)
} }
overNodes=true; // global flag
TW.selectionActive = true
TW.partialGraph.render(); TW.partialGraph.render();
updateRelatedNodesPanel( selections , same, oppos ); updateRelatedNodesPanel( selections , same, oppos );
if (TW.debugFlags.selections) { if (TW.conf.debug.selections) {
var tMS2_fin = performance.now() var tMS2_fin = performance.now()
console.log("end MultipleSelection2, own time:", tMS2_fin-tMS2_deb) console.log("end MultipleSelection2, own time:", tMS2_fin-tMS2_deb)
} }
...@@ -344,7 +342,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -344,7 +342,7 @@ TinaWebJS = function ( sigmacanvas ) {
// functions that modify the sigma module (not sigma instance!) // functions that modify the sigma module (not sigma instance!)
this.init = function () { this.init = function () {
if (TW.debugFlags.logSettings) console.info("TW settings", TW) if (TW.conf.debug.logSettings) console.info("TW settings", TW)
let initErrMsg = null let initErrMsg = null
...@@ -354,12 +352,12 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -354,12 +352,12 @@ TinaWebJS = function ( sigmacanvas ) {
else { else {
this.prepareSigmaCustomIndices(sigma) this.prepareSigmaCustomIndices(sigma)
if (TW.ourRendering) if (TW.conf.ourRendering)
this.prepareSigmaCustomRenderers(sigma) this.prepareSigmaCustomRenderers(sigma)
} }
// overriding pixelRatio is possible if we need high definition // overriding pixelRatio is possible if we need high definition
if (TW.overSampling) { if (TW.conf.overSampling) {
var realRatio = sigma.utils.getPixelRatio var realRatio = sigma.utils.getPixelRatio
sigma.utils.getPixelRatio = function() { sigma.utils.getPixelRatio = function() {
return 2 * realRatio() return 2 * realRatio()
...@@ -476,7 +474,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -476,7 +474,7 @@ TinaWebJS = function ( sigmacanvas ) {
// - additionnaly supports 'active/forcelabel' node property (magnify x 3) // - additionnaly supports 'active/forcelabel' node property (magnify x 3)
sigmaModule.canvas.hovers.def = tempo.twRender.canvas.hovers.largerall sigmaModule.canvas.hovers.def = tempo.twRender.canvas.hovers.largerall
if (TW.debugFlags.logSettings) console.log('tw renderers registered in sigma module') if (TW.conf.debug.logSettings) console.log('tw renderers registered in sigma module')
} }
this.initSearchListeners = function () { this.initSearchListeners = function () {
...@@ -487,10 +485,10 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -487,10 +485,10 @@ TinaWebJS = function ( sigmacanvas ) {
source: function(request, response) { source: function(request, response) {
// labels initialized in settings, filled in updateSearchLabels // labels initialized in settings, filled in updateSearchLabels
// console.log(labels.length) // console.log(labels.length)
matches = []; var matches = [];
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
// grep at heart // grep at heart
var results = $.grep(labels, function(e) { var results = $.grep(TW.labels, function(e) {
return matcher.test(e.label); //|| matcher.test(e.desc); return matcher.test(e.label); //|| matcher.test(e.desc);
}); });
...@@ -499,11 +497,11 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -499,11 +497,11 @@ TinaWebJS = function ( sigmacanvas ) {
} else { } else {
$("#noresults").empty(); $("#noresults").empty();
} }
matches = results.slice(0, maxSearchResults); matches = results.slice(0, TW.conf.minLengthAutoComplete);
response(matches); response(matches);
}, },
minLength: minLengthAutoComplete, minLength: TW.conf.minLengthAutoComplete,
// ----------------------->8--------------------- // ----------------------->8---------------------
...@@ -574,7 +572,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -574,7 +572,7 @@ TinaWebJS = function ( sigmacanvas ) {
setTimeout( setTimeout(
function (){ function (){
targeted = SelInst.SelectorEngine( { targeted = SelInst.SelectorEngine( {
addvalue:checkBox, addvalue:TW.checkBox,
clicktype:"double", clicktype:"double",
prevsels:selections, prevsels:selections,
currsels:coincidences currsels:coincidences
...@@ -582,12 +580,12 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -582,12 +580,12 @@ TinaWebJS = function ( sigmacanvas ) {
// tricky stuff for simulating a multiple selection D: // tricky stuff for simulating a multiple selection D:
// ... to be improved in the future ... // ... to be improved in the future ...
var prev_cursor_size = cursor_size; var prev_cursor_size = TW.circleSize;
if(targeted.length>0) { if(targeted.length>0) {
cursor_size = (cursor_size==0)? 1 : cursor_size; TW.circleSize = (TW.circleSize==0)? 1 : TW.circleSize;
cancelSelection(false); cancelSelection(false);
SelInst.MultipleSelection2({nodes:targeted}); SelInst.MultipleSelection2({nodes:targeted});
cursor_size = prev_cursor_size; TW.circleSize = prev_cursor_size;
} }
$("input#searchinput").val(""); $("input#searchinput").val("");
...@@ -621,7 +619,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -621,7 +619,7 @@ TinaWebJS = function ( sigmacanvas ) {
setTimeout( setTimeout(
function() { function() {
targeted = SelInst.SelectorEngine( { targeted = SelInst.SelectorEngine( {
addvalue:checkBox, addvalue:TW.checkBox,
clicktype:"double", clicktype:"double",
prevsels:selections, prevsels:selections,
currsels:[exfnd.id] currsels:[exfnd.id]
...@@ -739,7 +737,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -739,7 +737,7 @@ TinaWebJS = function ( sigmacanvas ) {
TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2})
}); });
if (TW.fa2Available) { if (TW.conf.fa2Available) {
$("#layoutButton").click(function () { $("#layoutButton").click(function () {
sigma_utils.smartForceAtlas() sigma_utils.smartForceAtlas()
}); });
...@@ -748,7 +746,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -748,7 +746,7 @@ TinaWebJS = function ( sigmacanvas ) {
$("#layoutButton").hide() $("#layoutButton").hide()
} }
if (TW.disperseAvailable) { if (TW.conf.disperseAvailable) {
$("#noverlapButton").click(function () { $("#noverlapButton").click(function () {
if(! TW.partialGraph.isNoverlapRunning()) { if(! TW.partialGraph.isNoverlapRunning()) {
// show waiting cursor on page and button // show waiting cursor on page and button
...@@ -785,12 +783,12 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -785,12 +783,12 @@ TinaWebJS = function ( sigmacanvas ) {
//Cursor Size slider //Cursor Size slider
var cursorSlider = $("#unranged-value").freshslider({ var cursorSlider = $("#unranged-value").freshslider({
step: 1, step: 1,
min:cursor_size_min, min:TW.conf.circleSizeMin,
max:cursor_size_max, max:TW.conf.circleSizeMax,
value:cursor_size, value:TW.circleSize,
onchange:function(value){ onchange:function(value){
// console.log("en cursorsize: "+value); // console.log("en cursorsize: "+value);
cursor_size=value; TW.circleSize=value;
} }
}); });
...@@ -813,11 +811,11 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -813,11 +811,11 @@ TinaWebJS = function ( sigmacanvas ) {
// console.log("init: slider resize") // console.log("init: slider resize")
// for(j=0 ; j<TW.partialGraph.nNodes ; j++){ // for(j=0 ; j<TW.partialGraph.nNodes ; j++){
// if (nds[j] // if (nds[j]
// && nds[j].type == TW.catSem) { // && nds[j].type == TW.conf.catSem) {
// var n = nds[j] // var n = nds[j]
// var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3 // var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3
// n.size = (newval<1.0)?1:newval; // n.size = (newval<1.0)?1:newval;
// sizeMult[TW.catSem] = parseFloat(value-1)*0.3; // sizeMult[TW.conf.catSem] = parseFloat(value-1)*0.3;
// } // }
// } // }
// partialGraph.render() // partialGraph.render()
...@@ -851,10 +849,10 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -851,10 +849,10 @@ TinaWebJS = function ( sigmacanvas ) {
// general listener: shift key in the window <=> add to selection // general listener: shift key in the window <=> add to selection
$(document).on('keyup keydown', function(e){ $(document).on('keyup keydown', function(e){
// changes the global boolean ("add node to selection" status) if keydown and SHIFT // changes the global boolean ("add node to selection" status) if keydown and SHIFT
checkBox = manuallyChecked || e.shiftKey TW.checkBox = TW.manuallyChecked || e.shiftKey
// show it in the real checkbox too // show it in the real TW.checkBox too
$('#checkboxdiv').prop("checked", manuallyChecked || e.shiftKey) $('#checkboxdiv').prop("checked", TW.manuallyChecked || e.shiftKey)
} ); } );
} // finish envListeners } // finish envListeners
...@@ -873,7 +871,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -873,7 +871,7 @@ TinaWebJS = function ( sigmacanvas ) {
// cases: // cases:
// 'click' - simple click, early event // 'click' - simple click, early event
// used for area (with global: cursor_size) // used for area (with global: TW.circleSize)
// 'clickNode'- simple click, second event if one node // 'clickNode'- simple click, second event if one node
// POSS easy in new sigma.js: // POSS easy in new sigma.js:
...@@ -887,7 +885,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -887,7 +885,7 @@ TinaWebJS = function ( sigmacanvas ) {
// console.log("sigma click event e", e) // console.log("sigma click event e", e)
// case with a selector circle cursor handled here // case with a selector circle cursor handled here
if (cursor_size > 0) { if (TW.circleSize > 0) {
// actual click position, but in graph coords // actual click position, but in graph coords
var x = e.data.x var x = e.data.x
var y = e.data.y var y = e.data.y
...@@ -895,19 +893,19 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -895,19 +893,19 @@ TinaWebJS = function ( sigmacanvas ) {
// convert // convert
var camCoords = TW.cam.cameraPosition(x,y) var camCoords = TW.cam.cameraPosition(x,y)
// retrieve area nodes, using indexed quadtree and global cursor_size // retrieve area nodes, using indexed quadtree and global TW.circleSize
var circleNodes = circleGetAreaNodes( var circleNodes = circleGetAreaNodes(
camCoords.x, camCoords.x,
camCoords.y camCoords.y
) )
// 1) clear previous while keeping its list (useful iff 'Add' checkBox) // 1) clear previous while keeping its list (useful iff 'Add' TW.checkBox)
var previousSelection = selections var previousSelection = selections
cancelSelection(false) cancelSelection(false)
// 2) show selection + do all related effects // 2) show selection + do all related effects
var targeted = SelInst.SelectorEngine( { var targeted = SelInst.SelectorEngine( {
addvalue:checkBox, addvalue:TW.checkBox,
currsels:circleNodes, currsels:circleNodes,
prevsels:previousSelection prevsels:previousSelection
} ) } )
...@@ -929,9 +927,9 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -929,9 +927,9 @@ TinaWebJS = function ( sigmacanvas ) {
var previousSelection = selections var previousSelection = selections
cancelSelection(false, {norender:true}); // no need to render before MS2 cancelSelection(false, {norender:true}); // no need to render before MS2
if (cursor_size == 0) { if (TW.circleSize == 0) {
var targeted = SelInst.SelectorEngine( { var targeted = SelInst.SelectorEngine( {
addvalue:checkBox, addvalue:TW.checkBox,
currsels:[theNodeId], currsels:[theNodeId],
prevsels:previousSelection prevsels:previousSelection
} ) } )
...@@ -945,13 +943,13 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -945,13 +943,13 @@ TinaWebJS = function ( sigmacanvas ) {
// when click in the empty background // when click in the empty background
// ================================== // ==================================
if (TW.deselectOnclickStage) { if (TW.conf.deselectOnclickStage) {
partialGraph.bind('clickStage', function(e) { partialGraph.bind('clickStage', function(e) {
// console.log("clickStage event e", e) // console.log("clickStage event e", e)
if (! e.data.captor.isDragging if (! e.data.captor.isDragging
&& Object.keys(selections).length && Object.keys(selections).length
&& ! cursor_size) { && ! TW.circleSize) {
// we clear selections and all its effects // we clear selections and all its effects
cancelSelection(false); cancelSelection(false);
...@@ -982,7 +980,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -982,7 +980,7 @@ TinaWebJS = function ( sigmacanvas ) {
.mousemove(function(e){ .mousemove(function(e){
if(!isUndef(partialGraph)) { if(!isUndef(partialGraph)) {
// show/move selector circle cursor // show/move selector circle cursor
if(cursor_size>0) circleTrackMouse(e); if(TW.circleSize>0) circleTrackMouse(e);
} }
}) })
...@@ -998,8 +996,8 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -998,8 +996,8 @@ TinaWebJS = function ( sigmacanvas ) {
// new sigma.js current zoom ratio // new sigma.js current zoom ratio
value: partialGraph.camera.ratio, value: partialGraph.camera.ratio,
min: 1 / sigmaJsMouseProperties.maxRatio, // ex x.5 min: 1 / TW.conf.sigmaJsMouseProperties.maxRatio, // ex x.5
max: 1 / sigmaJsMouseProperties.minRatio, // ex x32 max: 1 / TW.conf.sigmaJsMouseProperties.minRatio, // ex x32
// range: true, // range: true,
step: .2, step: .2,
value: 1, value: 1,
...@@ -1013,7 +1011,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1013,7 +1011,7 @@ TinaWebJS = function ( sigmacanvas ) {
$("#zoomPlusButton").click(function () { $("#zoomPlusButton").click(function () {
var newRatio = TW.cam.ratio * .75 var newRatio = TW.cam.ratio * .75
if (newRatio >= sigmaJsMouseProperties.minRatio) { if (newRatio >= TW.conf.sigmaJsMouseProperties.minRatio) {
// triggers coordinatesUpdated which sets the slider cursor // triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio}); partialGraph.camera.goTo({ratio: newRatio});
return false; return false;
...@@ -1022,14 +1020,14 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1022,14 +1020,14 @@ TinaWebJS = function ( sigmacanvas ) {
$("#zoomMinusButton").click(function () { $("#zoomMinusButton").click(function () {
var newRatio = TW.cam.ratio * 1.25 var newRatio = TW.cam.ratio * 1.25
if (newRatio <= sigmaJsMouseProperties.maxRatio) { if (newRatio <= TW.conf.sigmaJsMouseProperties.maxRatio) {
// triggers coordinatesUpdated which sets the slider cursor // triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio}); partialGraph.camera.goTo({ratio: newRatio});
return false; return false;
} }
}); });
if (TW.filterSliders) { if (TW.conf.filterSliders) {
// args: for display: target div , // args: for display: target div ,
// for context: family/type prop value, // for context: family/type prop value,
...@@ -1051,7 +1049,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1051,7 +1049,7 @@ TinaWebJS = function ( sigmacanvas ) {
step:.25, step:.25,
min:0, min:0,
max:5, max:5,
value: sigmaJsDrawingProperties['labelSizeRatio'] || 1, value: TW.conf.sigmaJsDrawingProperties['labelSizeRatio'] || 1,
bgcolor:"#27c470", bgcolor:"#27c470",
onchange:function(value){ onchange:function(value){
if (labelSizeTimeout) { if (labelSizeTimeout) {
...@@ -1097,7 +1095,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1097,7 +1095,7 @@ TinaWebJS = function ( sigmacanvas ) {
} }
this.allPossibleActivetypes = function (cats) { this.allPossibleActivetypes = function (cats) {
if (TW.debugFlags.logSettings) console.debug(`allPossibleActivetypes(cats=${cats})`) if (TW.conf.debug.logSettings) console.debug(`allPossibleActivetypes(cats=${cats})`)
var possibleActivetypes = {} var possibleActivetypes = {}
var N=Math.pow(2 , cats.length); var N=Math.pow(2 , cats.length);
......
...@@ -907,7 +907,7 @@ function showDisabledSlider(someDivId) { ...@@ -907,7 +907,7 @@ function showDisabledSlider(someDivId) {
//============================= < SEARCH > =============================// //============================= < SEARCH > =============================//
function updateSearchLabels(id,name,type){ function updateSearchLabels(id,name,type){
labels.push({ TW.labels.push({
'id' : id, 'id' : id,
'label' : name, 'label' : name,
'desc': type 'desc': type
......
...@@ -37,7 +37,7 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) { ...@@ -37,7 +37,7 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) {
else DT = 'text' // ie "if not json then raw xml string" else DT = 'text' // ie "if not json then raw xml string"
if (TW.debugFlags.logFetchers) if (TW.conf.debug.logFetchers)
console.log("---AjaxSync---\n", TYPE, URL, DATA, DT, "\n--------------") console.log("---AjaxSync---\n", TYPE, URL, DATA, DT, "\n--------------")
$.ajax({ $.ajax({
...@@ -60,7 +60,7 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) { ...@@ -60,7 +60,7 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) {
format = "gexf" ; format = "gexf" ;
} }
else { else {
if (TW.debugFlags.logFetchers) if (TW.conf.debug.logFetchers)
console.debug("after AjaxSync("+URL+") => response header="+header +"not xml => fallback on json"); console.debug("after AjaxSync("+URL+") => response header="+header +"not xml => fallback on json");
format = "json" ; format = "json" ;
} }
...@@ -101,7 +101,7 @@ TW.instance.initGUIListeners(); ...@@ -101,7 +101,7 @@ TW.instance.initGUIListeners();
TW.instance.initSearchListeners(); TW.instance.initSearchListeners();
// show the custom name of the app // show the custom name of the app
writeBrand(TW.branding) writeBrand(TW.conf.branding)
console.log("Starting TWJS") console.log("Starting TWJS")
...@@ -140,9 +140,15 @@ function syncRemoteGraphData () { ...@@ -140,9 +140,15 @@ function syncRemoteGraphData () {
var inFormat; // = { db|api.json , somefile.json|gexf } var inFormat; // = { db|api.json , somefile.json|gexf }
var inData; // = {nodes: [....], edges: [....], cats:...} var inData; // = {nodes: [....], edges: [....], cats:...}
// case (1) read from DB => one ajax to api eg /services/api/graph?q=filters... var mapLabel; // user displayed label for this input dataset
if (getUrlParam.type) {
console.warn("input case: @type [future: @sourcemode=api], using TW.bridge") // type of input
let sourcemode = isUndef(getUrlParam.sourcemode)?TW.sourcemode:getUrlParam.sourcemode
// case (1) read from remote DB via API bridge fetching
// ex: /services/api/graph?q=filters...
if (sourcemode == "api") {
console.log("input case: api, using TW.conf.sourceAPI")
// the only API format, cf. inData // the only API format, cf. inData
inFormat = 'json' inFormat = 'json'
...@@ -151,29 +157,29 @@ function syncRemoteGraphData () { ...@@ -151,29 +157,29 @@ function syncRemoteGraphData () {
var sourceinfo = getUrlParam.nodeidparam var sourceinfo = getUrlParam.nodeidparam
var qtype = getUrlParam.type var qtype = getUrlParam.type
if(isUndef(sourceinfo) || isUndef(qtype)) { if(isUndef(sourceinfo) || isUndef(qtype)) {
console.warn("missing nodes filter/id param"); console.warn("missing nodes filter/id param to transmit to source api");
} }
else { else {
console.log("Received query of type:", qtype) console.log("Received query of type:", qtype)
if(qtype == "filter" || qtype == "uid"){ if(qtype == "filter" || qtype == "uid"){
var theurl,thedata,thename; var theurl,thedata
// console.warn("===> PASSING ON QUERY (type "+qtype+") TO BRIDGE <===") // console.warn("===> PASSING ON QUERY (type "+qtype+") TO BRIDGE <===")
if(qtype=="uid") { if (qtype=="uid") {
// pr("bring the noise, case: unique_id"); // pr("bring the noise, case: unique_id");
// pr(getClientTime()+" : DataExt Ini"); // pr(getClientTime()+" : DataExt Ini");
// < === DATA EXTRACTION === > // < === DATA EXTRACTION === >
theurl = TW.bridge["forNormalQuery"] theurl = TW.conf.sourceAPI["forNormalQuery"]
// NB before also passed it for Fa2 iterations (useless?) // NB before also passed it for Fa2 iterations (useless?)
thedata = "qtype=uid&unique_id="+sourceinfo; thedata = "qtype=uid&unique_id="+sourceinfo;
thename = "unique scholar"; mapLabel = "unique scholar";
} }
if (qtype=="filter") { if (qtype=="filter") {
// pr("bring the noise, case: multipleQuery"); // pr("bring the noise, case: multipleQuery");
// pr(getClientTime()+" : DataExt Ini"); // pr(getClientTime()+" : DataExt Ini");
theurl = TW.bridge["forFilteredQuery"]; theurl = TW.conf.sourceAPI["forFilteredQuery"];
// json is twice URI encoded by whoswho to avoid both '"' and '%22' // json is twice URI encoded by whoswho to avoid both '"' and '%22'
var json_constraints = decodeURIComponent(sourceinfo) var json_constraints = decodeURIComponent(sourceinfo)
...@@ -191,7 +197,7 @@ function syncRemoteGraphData () { ...@@ -191,7 +197,7 @@ function syncRemoteGraphData () {
// => thedata (for comexAPI): // => thedata (for comexAPI):
// keywords[]="complex systems"&keywords[]="something"&countries="France"&countries[]="USA" // keywords[]="complex systems"&keywords[]="something"&countries="France"&countries[]="USA"
// => thename (for user display): // => mapLabel (for user display):
// ("complex systems" or "something") and ("France" or "USA") // ("complex systems" or "something") and ("France" or "USA")
// console.log("decoded filtering query", filteringKeyArrayPairs) // console.log("decoded filtering query", filteringKeyArrayPairs)
...@@ -212,16 +218,16 @@ function syncRemoteGraphData () { ...@@ -212,16 +218,16 @@ function syncRemoteGraphData () {
if (restParams.length) { if (restParams.length) {
thedata = "qtype=filters&" + restParams.join("&") thedata = "qtype=filters&" + restParams.join("&")
thename = nameElts.join(" and ") mapLabel = nameElts.join(" and ")
} }
else { else {
thedata = "qtype=filters&query=*" thedata = "qtype=filters&query=*"
thename = "(ENTIRE NETWORK)" mapLabel = "(ENTIRE NETWORK)"
} }
} }
// Assigning name for the network // Assigning name for the network
if (! thename) { if (! mapLabel) {
elements = [] elements = []
queryarray = JSON.parse(ourGetUrlParam.nodeidparam) queryarray = JSON.parse(ourGetUrlParam.nodeidparam)
for(var i in queryarray) { for(var i in queryarray) {
...@@ -230,52 +236,47 @@ function syncRemoteGraphData () { ...@@ -230,52 +236,47 @@ function syncRemoteGraphData () {
for(var j in item) elements.push(item[j]) for(var j in item) elements.push(item[j])
} }
} }
thename = '"'+elements.join('" , "')+'"'; mapLabel = '"'+elements.join('" , "')+'"';
} }
// £TODO restore thename
console.warn (thename, ":name not used anymore since refacto 10/05 could put on same level as inData as inMapname or smth")
var bridgeRes = AjaxSync({ URL: theurl, DATA:thedata, TYPE:'GET', DT:'json' }) var bridgeRes = AjaxSync({ URL: theurl, DATA:thedata, TYPE:'GET', DT:'json' })
// should be a js object with 'nodes' and 'edges' properties // should be a js object with 'nodes' and 'edges' properties
inData = bridgeRes.data inData = bridgeRes.data
if (TW.debugFlags.logFetchers) console.info("JSON input data", inData) if (TW.conf.debug.logFetchers) console.info("JSON input data", inData)
} }
else { else {
console.warn ("=> unsupported query type !") console.warn ("=> unsupported query type !")
} }
} }
} }
// case (2) gexf => in params or in preRes db.json, then 2nd ajax for a gexf file => covered here
// sourcemode == "serverfile"
// cases (2) and (3) : we'll read a file from server
// sourcemode == "serverfile" or "servermenu" (several files with <select>)
else { else {
console.warn("input case: @mode=db.json or @file=... [future: @sourcemode=serverfile], using server's gexf(s)") console.log("input case: server-side file, using db.json or getUrlParam.file or TW.conf.sourceFile")
// subcases:
// -> gexf file path is already specified in TW.mainfile // -> @mode is servermenu, files are listed in db.json file (preRes ajax)
// -> gexf file path is in the urlparam @file // --> if @file also in url, choose the db.json one matching <=== £TODO THIS CASE STILL TO FIX
// -> @mode is db.json, files are listed in db.json file // --> otherwise, choose the "first_file" from db.json list
// --> if @file also in url, choose the db.json one matching
// --> otherwise, choose the "first_file" from db.json list // -> @mode is serverfile
// -> gexf file path is in the urlparam @file
// -> gexf file path is already specified in TW.conf.sourceFile
// =================== // ===================
var the_file = ""; var the_file = "";
// =================== // ===================
// menufile case : a list of source files in ./db.json
// TODO check if legacy apps use db.json name otherwise use mode == 'menufile' if (sourcemode == 'servermenu') {
// and 'db.json' should be hardcoded (safer)
// if (!isUndef(getUrlParam.mode) && getUrlParam.mode == 'menufile') {
// menufile case comes before single file because it uses urlparam file too
if (!isUndef(getUrlParam.mode) && getUrlParam.mode == 'db.json') {
console.log("no @file arg nor TW.mainfile: trying FILEMENU db.json") console.log("no @file arg nor TW.mainfile: trying FILEMENU db.json")
// we'll first retrieve the menu of available files in db.json, then get the real data in a second ajax // we'll first retrieve the menu of available files in db.json, then get the real data in a second ajax
var infofile = "db.json" var infofile = "db.json"
if (TW.debugFlags.logFetchers) console.info(`attempting to load infofile ${infofile}`) if (TW.conf.debug.logFetchers) console.info(`attempting to load infofile ${infofile}`)
var preRES = AjaxSync({ URL: infofile, DT:"json" }); var preRES = AjaxSync({ URL: infofile, DT:"json" });
if (preRES['OK'] && preRES.data) { if (preRES['OK'] && preRES.data) {
...@@ -297,29 +298,30 @@ function syncRemoteGraphData () { ...@@ -297,29 +298,30 @@ function syncRemoteGraphData () {
if( isUndef(getUrlParam.file) ) { if( isUndef(getUrlParam.file) ) {
the_file = first_path+"/"+first_file the_file = first_path+"/"+first_file
} else { } else {
// £POSS; match on the full paths from db.json
the_file = first_path+"/"+getUrlParam.file the_file = first_path+"/"+getUrlParam.file
} }
var files_selector = '<select onchange="jsActionOnGexfSelector(this.value);">' var files_selector = '<select onchange="jsActionOnGexfSelector(this.value);">'
for( var path in preRES.data ) { for( var path in preRES.data ) {
var the_gexfs = preRES.data[path]["gexfs"] var theGexfs = preRES.data[path]["gexfs"]
for(var aGexf in the_gexfs) { for(var aGexf in theGexfs) {
var gexfBasename = aGexf.replace(/\.gexf$/, "") // more human-readable in the menu var gexfBasename = aGexf.replace(/\.gexf$/, "") // more human-readable in the menu
TW.gexfPaths[gexfBasename] = path+"/"+aGexf TW.gexfPaths[gexfBasename] = path+"/"+aGexf
// ex : "RiskV2PageRank1000.gexf":data/AXA/RiskV2PageRank1000.gexf // ex : "RiskV2PageRank1000.gexf":data/AXA/RiskV2PageRank1000.gexf
// (we assume there's no duplicate basenames) // (we assume there's no duplicate basenames)
if (TW.debugFlags.logFetchers) if (TW.conf.debug.logFetchers)
console.log("\t\t\t"+gexfBasename+ " -> table:" +the_gexfs[aGexf]["semantic"]["table"] ) console.log("\t\t\t"+gexfBasename+ " -> table:" +theGexfs[aGexf]["semantic"]["table"] )
// -------------------------->8------------------------------------------ // -------------------------->8------------------------------------------
// £TODO this part is underspecified // £TODO this part is underspecified
// if used in some usecases, port it to nodetypes // if used in some usecases, port it to nodetypes
// otherwise remove // otherwise remove
// TW.field[path+"/"+aGexf] = the_gexfs[aGexf]["semantic"]["table"] // TW.field[path+"/"+aGexf] = theGexfs[aGexf]["semantic"]["table"]
// ex : data/AXA/RiskV2PageRank5000.gexf:"ISItermsAxa_2015" // ex : data/AXA/RiskV2PageRank5000.gexf:"ISItermsAxa_2015"
// -------------------------->8------------------------------------------ // -------------------------->8------------------------------------------
...@@ -334,24 +336,25 @@ function syncRemoteGraphData () { ...@@ -334,24 +336,25 @@ function syncRemoteGraphData () {
console.log("files_selector HTML", files_selector) console.log("files_selector HTML", files_selector)
$("#network").html(files_selector) $("#network").html(files_selector)
} }
// direct urlparam file case // direct urlparam file case
else if( !isUndef(getUrlParam.file) ) { else if( !isUndef(getUrlParam.file) ) {
the_file = getUrlParam.file the_file = getUrlParam.file
} }
// direct file fallback case: specified file in settings_explorer // direct file fallback case: specified file in settings_explorer
else if (TW.mainfile && linkCheck(TW.mainfile)) { 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.mainfile from settings")
the_file = TW.mainfile; the_file = TW.conf.sourceFile;
} }
else { else {
console.warn("No specified input!") console.error(`No specified input and neither db.json nor TW.conf.sourceFile ${TW.conf.sourceFile} are present`)
} }
var finalRes = AjaxSync({ URL: the_file }); var finalRes = AjaxSync({ URL: the_file });
inData = finalRes["data"] inData = finalRes["data"]
inFormat = finalRes["format"] inFormat = finalRes["format"]
if (TW.debugFlags.logFetchers) { if (TW.conf.debug.logFetchers) {
console.warn('@the_file', finalRes["OK"], the_file) console.warn('@the_file', finalRes["OK"], the_file)
console.log(' fetch result: format', inFormat) console.log(' fetch result: format', inFormat)
console.log(' fetch result: typeof data', typeof inData) console.log(' fetch result: typeof data', typeof inData)
...@@ -359,7 +362,7 @@ function syncRemoteGraphData () { ...@@ -359,7 +362,7 @@ function syncRemoteGraphData () {
} }
} }
return [inFormat, inData] return [inFormat, inData, mapLabel]
} }
...@@ -380,13 +383,13 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -380,13 +383,13 @@ function mainStartGraph(inFormat, inData, twInstance) {
} }
else { else {
if (TW.debugFlags.logParsers) console.log("parsing the data") if (TW.conf.debug.logParsers) console.log("parsing the data")
let start = new ParseCustom( inFormat , inData ); let start = new ParseCustom( inFormat , inData );
let catsInfos = start.scanFile(); let catsInfos = start.scanFile();
TW.categories = catsInfos.categories TW.categories = catsInfos.categories
if (TW.debugFlags.logParsers){ if (TW.conf.debug.logParsers){
console.log(`Source scan found ${TW.categories.length} node categories: ${TW.categories}`) console.log(`Source scan found ${TW.categories.length} node categories: ${TW.categories}`)
} }
...@@ -407,7 +410,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -407,7 +410,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
// XML parsing from ParseCustom // XML parsing from ParseCustom
var dicts = start.makeDicts(TW.categories); // > parse json or gexf, dictfy var dicts = start.makeDicts(TW.categories); // > parse json or gexf, dictfy
if (TW.debugFlags.logParsers) console.info("parsing result:", dicts) if (TW.conf.debug.logParsers) console.info("parsing result:", dicts)
TW.Nodes = dicts.nodes; TW.Nodes = dicts.nodes;
TW.Edges = dicts.edges; TW.Edges = dicts.edges;
...@@ -436,21 +439,21 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -436,21 +439,21 @@ function mainStartGraph(inFormat, inData, twInstance) {
// so we just need to handle mismatches here (when user-suggested cats were absent) // so we just need to handle mismatches here (when user-suggested cats were absent)
if (TW.categories.length == 2) { if (TW.categories.length == 2) {
console.info("== 'bipartite' case ==") console.info("== 'bipartite' case ==")
if (TW.catSoc != TW.categories[0]) { if (TW.conf.catSoc != TW.categories[0]) {
console.warn(`Observed social category "${TW.categories[0]}" overwrites user-suggested TW.catSoc ("${TW.catSoc}")`) console.warn(`Observed social category "${TW.categories[0]}" overwrites user-suggested TW.conf.catSoc ("${TW.conf.catSoc}")`)
TW.catSoc = TW.categories[0] TW.conf.catSoc = TW.categories[0]
} }
if (TW.catSem != TW.categories[1]) { if (TW.conf.catSem != TW.categories[1]) {
console.warn(`Observed semantic category "${TW.categories[1]}" overwrites user-suggested TW.catSem "(${TW.catSem})"`) console.warn(`Observed semantic category "${TW.categories[1]}" overwrites user-suggested TW.conf.catSem "(${TW.conf.catSem})"`)
TW.catSem = TW.categories[1] TW.conf.catSem = TW.categories[1]
} }
} }
else if (TW.categories.length == 1) { else if (TW.categories.length == 1) {
console.info("== monopartite case ==") console.info("== monopartite case ==")
// FIXME it would be more coherent with all tina usecases (like gargantext or tweetoscope) for the default category to be catSem instead of Soc // FIXME it would be more coherent with all tina usecases (like gargantext or tweetoscope) for the default category to be catSem instead of Soc
if (TW.catSoc != TW.categories[0]) { if (TW.conf.catSoc != TW.categories[0]) {
console.warn(`Observed unique category "${TW.categories[0]}" overwrites user-suggested TW.catSoc ("${TW.catSoc}")`) console.warn(`Observed unique category "${TW.categories[0]}" overwrites user-suggested TW.conf.catSoc ("${TW.conf.catSoc}")`)
TW.catSoc = TW.categories[0] TW.conf.catSoc = TW.categories[0]
} }
} }
else { else {
...@@ -528,13 +531,13 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -528,13 +531,13 @@ function mainStartGraph(inFormat, inData, twInstance) {
}, },
// 2) settings_explorer values // 2) settings_explorer values
sigmaJsDrawingProperties, TW.conf.sigmaJsDrawingProperties,
sigmaJsGraphProperties, TW.conf.sigmaJsGraphProperties,
sigmaJsMouseProperties TW.conf.sigmaJsMouseProperties
) )
if (TW.debugFlags.logSettings) console.info("sigma settings", TW.customSettings) if (TW.conf.debug.logSettings) console.info("sigma settings", TW.customSettings)
// ================================================================== // ==================================================================
...@@ -629,7 +632,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -629,7 +632,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
LevelButtonDisable(true) LevelButtonDisable(true)
// recreate sliders after activetype or level changes // recreate sliders after activetype or level changes
if (TW.filterSliders if (TW.conf.filterSliders
&& (present.level != past.level && (present.level != past.level
|| present.activetypes.map(Number).join("|") != past.activetypes.map(Number).join("|"))) { || present.activetypes.map(Number).join("|") != past.activetypes.map(Number).join("|"))) {
...@@ -666,7 +669,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -666,7 +669,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
}; };
if (!TW.filterSliders) { if (!TW.conf.filterSliders) {
var filterEls = document.getElementsByClassName('weight-selectors') var filterEls = document.getElementsByClassName('weight-selectors')
...@@ -698,7 +701,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -698,7 +701,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
outboundAttractionDistribution: false outboundAttractionDistribution: false
} }
if (TW.debugFlags.logSettings) console.info("FA2 settings", TW.FA2Params) if (TW.conf.debug.logSettings) console.info("FA2 settings", TW.FA2Params)
// init FA2 for any future forceAtlas2 calls // init FA2 for any future forceAtlas2 calls
TW.partialGraph.configForceAtlas2(TW.FA2Params) TW.partialGraph.configForceAtlas2(TW.FA2Params)
...@@ -720,9 +723,9 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -720,9 +723,9 @@ function mainStartGraph(inFormat, inData, twInstance) {
TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0})
// mostly json data are extracts provided by DB apis => no positions // mostly json data are extracts provided by DB apis => no positions
if (inFormat == "json") TW.fa2enabled = true if (inFormat == "json") TW.conf.fa2Enabled = true
// will run fa2 if enough nodes and TW.fa2enabled == true // will run fa2 if enough nodes and TW.conf.fa2Enabled == true
sigma_utils.smartForceAtlas() sigma_utils.smartForceAtlas()
...@@ -731,7 +734,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -731,7 +734,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
$("#changetype").hide(); $("#changetype").hide();
$("#taboppos").hide(); $("#taboppos").hide();
// if (TW.catSem && TW.catSoc) { // if (TW.conf.catSem && TW.conf.catSoc) {
setTimeout(function () { setTimeout(function () {
// tabneigh: show "Related" tab // tabneigh: show "Related" tab
document.querySelector('.etabs a[href="#tabs2"]').click() document.querySelector('.etabs a[href="#tabs2"]').click()
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// settings: {norender: Bool} // settings: {norender: Bool}
function cancelSelection (fromTagCloud, settings) { function cancelSelection (fromTagCloud, settings) {
if (TW.debugFlags.selections) { console.log("\t***in cancelSelection"); } if (TW.conf.debug.selections) { console.log("\t***in cancelSelection"); }
if (!settings) settings = {} if (!settings) settings = {}
highlightSelectedNodes(false); //Unselect the selected ones :D highlightSelectedNodes(false); //Unselect the selected ones :D
...@@ -14,8 +14,9 @@ function cancelSelection (fromTagCloud, settings) { ...@@ -14,8 +14,9 @@ function cancelSelection (fromTagCloud, settings) {
TW.partialGraph.states.slice(-1)[0].selections=[] TW.partialGraph.states.slice(-1)[0].selections=[]
//Nodes colors go back to normal // global flag
overNodes=false; TW.selectionActive = false
//Edges colors go back to normal //Edges colors go back to normal
if (TW.partialGraph.settings('drawEdges')) { if (TW.partialGraph.settings('drawEdges')) {
...@@ -77,9 +78,6 @@ function cancelSelection (fromTagCloud, settings) { ...@@ -77,9 +78,6 @@ function cancelSelection (fromTagCloud, settings) {
if(TW.partialGraph.states.slice(-1)[0].level) if(TW.partialGraph.states.slice(-1)[0].level)
LevelButtonDisable(true); LevelButtonDisable(true);
// global flag
TW.selectionActive = false
if (!settings.norender) { if (!settings.norender) {
// finally redraw // finally redraw
TW.partialGraph.render(); TW.partialGraph.render();
...@@ -115,7 +113,7 @@ function getActivetypesKey() { ...@@ -115,7 +113,7 @@ function getActivetypesKey() {
function highlightSelectedNodes(flag){ function highlightSelectedNodes(flag){
if (TW.debugFlags.logSelections) if (TW.conf.debug.logSelections)
console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" selEmpty:"+is_empty(selections)) console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" selEmpty:"+is_empty(selections))
if(!is_empty(selections)){ if(!is_empty(selections)){
for(var i in selections) { for(var i in selections) {
...@@ -126,11 +124,11 @@ function highlightSelectedNodes(flag){ ...@@ -126,11 +124,11 @@ function highlightSelectedNodes(flag){
function alertCheckBox(eventCheck){ function alertCheckBox(eventCheck){
// NB: we use 2 booleans to adapt to SHIFT checking // NB: we use 2 booleans to adapt to SHIFT checking
// - var checkBox ---------> has the real box state // - var TW.checkBox ---------> has the real box state
// - var manuallyChecked --> remembers if it was changed here // - var TW.manuallyChecked --> remembers if it was changed here
if(!isUndef(eventCheck.checked)) { if(!isUndef(eventCheck.checked)) {
checkBox=eventCheck.checked; TW.checkBox=eventCheck.checked;
manuallyChecked = eventCheck.checked TW.manuallyChecked = eventCheck.checked
} }
} }
...@@ -174,7 +172,7 @@ function RefreshState(newNOW){ ...@@ -174,7 +172,7 @@ function RefreshState(newNOW){
// N : number of nodes // N : number of nodes
// k : number of ( selected nodes + their neighbors ) // k : number of ( selected nodes + their neighbors )
// s : number of selections // s : number of selections
var N=( Object.keys(TW.Nodes).filter(function(n){return TW.Nodes[n].type==TW.catSoc}) ).length 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 k=Object.keys(getNeighs(Object.keys(selections),nodes1)).length
var s=Object.keys(selections).length var s=Object.keys(selections).length
console.log("in social N: "+N+" - k: "+k+" - s: "+s) console.log("in social N: "+N+" - k: "+k+" - s: "+s)
...@@ -195,7 +193,7 @@ function RefreshState(newNOW){ ...@@ -195,7 +193,7 @@ function RefreshState(newNOW){
} }
if(NOW=="B" || NOW=="b") { if(NOW=="B" || NOW=="b") {
var N=( Object.keys(TW.Nodes).filter(function(n){return TW.Nodes[n].type==TW.catSem}) ).length 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 k=Object.keys(getNeighs(Object.keys(selections),nodes2)).length
var s=Object.keys(selections).length var s=Object.keys(selections).length
console.log("in semantic N: "+N+" - k: "+k+" - s: "+s) console.log("in semantic N: "+N+" - k: "+k+" - s: "+s)
...@@ -357,7 +355,7 @@ function htmlfied_nodesatts(elems){ ...@@ -357,7 +355,7 @@ function htmlfied_nodesatts(elems){
} }
socnodes.push(information); socnodes.push(information);
} else { } else {
if(node.type==TW.catSoc){ if(node.type==TW.conf.catSoc){
information += '<li><b>' + node.label + '</b></li>'; information += '<li><b>' + node.label + '</b></li>';
if(node.htmlCont==""){ if(node.htmlCont==""){
if (!isUndef(node.level)) { if (!isUndef(node.level)) {
...@@ -369,7 +367,7 @@ function htmlfied_nodesatts(elems){ ...@@ -369,7 +367,7 @@ function htmlfied_nodesatts(elems){
socnodes.push(information) socnodes.push(information)
} }
if(node.type==TW.catSem){ if(node.type==TW.conf.catSem){
information += '<li><b>' + node.label + '</b></li>'; information += '<li><b>' + node.label + '</b></li>';
google='<a href=http://www.google.com/#hl=en&source=hp&q=%20'+node.label.replace(" ","+")+'%20><img src="'+'img/google.png"></img></a>'; google='<a href=http://www.google.com/#hl=en&source=hp&q=%20'+node.label.replace(" ","+")+'%20><img src="'+'img/google.png"></img></a>';
wiki = '<a href=http://en.wikipedia.org/wiki/'+node.label.replace(" ","_")+'><img src="'+'img/wikipedia.png"></img></a>'; wiki = '<a href=http://en.wikipedia.org/wiki/'+node.label.replace(" ","_")+'><img src="'+'img/wikipedia.png"></img></a>';
...@@ -606,7 +604,7 @@ function graphTagCloudElem(nodes) { ...@@ -606,7 +604,7 @@ function graphTagCloudElem(nodes) {
TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0})
TW.partialGraph.refresh({skipIndexation:true}); TW.partialGraph.refresh({skipIndexation:true});
sigma_utils.smartForceAtlas(TW.fa2milliseconds/2) sigma_utils.smartForceAtlas(TW.conf.fa2Milliseconds/2)
// //
// ChangeGraphAppearanceByAtt(true) // ChangeGraphAppearanceByAtt(true)
...@@ -681,9 +679,11 @@ function prepareNodesRenderingProperties(nodesDict) { ...@@ -681,9 +679,11 @@ function prepareNodesRenderingProperties(nodesDict) {
for (var nid in nodesDict) { for (var nid in nodesDict) {
var n = nodesDict[nid] var n = nodesDict[nid]
let sizeFactor = TW.conf.sizeMult[TW.catDict[n.type]] || 1
// 3 decimals is way more tractable // 3 decimals is way more tractable
// and quite enough in precision !! // and quite enough in precision !!
n.size = Math.round(n.size*1000)/1000 n.size = Math.round(n.size*sizeFactor*1000)/1000
// new initial setup of properties // new initial setup of properties
n.active = false n.active = false
...@@ -722,8 +722,8 @@ function prepareNodesRenderingProperties(nodesDict) { ...@@ -722,8 +722,8 @@ function prepareNodesRenderingProperties(nodesDict) {
n.color = `rgb(${rgbStr})` n.color = `rgb(${rgbStr})`
} }
else { else {
n.color = TW.defaultNodeColor n.color = TW.conf.defaultNodeColor
rgbStr = TW.defaultNodeColor.split(',').splice(0, 3).join(','); rgbStr = TW.conf.defaultNodeColor.split(',').splice(0, 3).join(',');
} }
n.customAttrs = { n.customAttrs = {
...@@ -757,7 +757,7 @@ function prepareEdgesRenderingProperties(edgesDict, nodesDict) { ...@@ -757,7 +757,7 @@ function prepareEdgesRenderingProperties(edgesDict, nodesDict) {
var rgbStr = sigmaTools.edgeRGB(nodesDict[e.source].color, nodesDict[e.target].color) var rgbStr = sigmaTools.edgeRGB(nodesDict[e.source].color, nodesDict[e.target].color)
e.color = "rgba("+rgbStr+","+TW.edgeDefaultOpacity+")" e.color = "rgba("+rgbStr+","+TW.conf.edgeDefaultOpacity+")"
e.customAttrs = { e.customAttrs = {
grey: false, grey: false,
activeEdge : false, activeEdge : false,
......
...@@ -213,7 +213,7 @@ function scanGexf(gexfContent) { ...@@ -213,7 +213,7 @@ function scanGexf(gexfContent) {
// sorting observed node types into Sem/Soc (factorized 11/05/2017) // sorting observed node types into Sem/Soc (factorized 11/05/2017)
// -------------------- // --------------------
// FIXME this factorizes what we had twice (json & gexf scanFile workflows), // FIXME this factorizes what we had twice (json & gexf scanFile workflows),
// and we just added missing TW.catSoc/Sem comparisons // and we just added missing TW.conf.catSoc/Sem comparisons
// *but it doesn't fix the underlying logic* // *but it doesn't fix the underlying logic*
// (current expected structure in 'categories' can only accomodate 2 types // (current expected structure in 'categories' can only accomodate 2 types
// and the way it and catDict are used is not entirely coherent throughout // and the way it and catDict are used is not entirely coherent throughout
...@@ -239,7 +239,7 @@ function sortNodeTypes(observedTypesDict) { ...@@ -239,7 +239,7 @@ function sortNodeTypes(observedTypesDict) {
// but in practice it's more often terms. anyways doesn't affect much // but in practice it's more often terms. anyways doesn't affect much
catDict[observedTypes[0]] = 0; catDict[observedTypes[0]] = 0;
if (TW.debugFlags.logParsers) if (TW.conf.debug.logParsers)
console.log(`cat unique (${observedTypes[0]}) =>0`) console.log(`cat unique (${observedTypes[0]}) =>0`)
} }
if(nTypes>1) { if(nTypes>1) {
...@@ -248,7 +248,7 @@ function sortNodeTypes(observedTypesDict) { ...@@ -248,7 +248,7 @@ function sortNodeTypes(observedTypesDict) {
// POSSible: allow more than 2 cats // POSSible: allow more than 2 cats
for(var i in observedTypes) { for(var i in observedTypes) {
let c = observedTypes[i] let c = observedTypes[i]
if(c == TW.catSoc || (c != TW.catSem && c.indexOf("term")==-1)) {// NOT a term-category if(c == TW.conf.catSoc || (c != TW.catSem && c.indexOf("term")==-1)) {// NOT a term-category
newcats[0] = c; newcats[0] = c;
catDict[c] = 0; catDict[c] = 0;
} }
...@@ -281,14 +281,14 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) { ...@@ -281,14 +281,14 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) {
let facetIdx = {} let facetIdx = {}
if (TW.debugFlags.logFacets) { if (TW.conf.debug.logFacets) {
console.log('dictfyGexf: begin TW.Clusters') console.log('dictfyGexf: begin TW.Clusters')
var classvalues_deb = performance.now() var classvalues_deb = performance.now()
} }
// var gotClusters = false // var gotClusters = false
// for (var nodecat in valuesIdx) { // for (var nodecat in valuesIdx) {
// gotClusters = gotClusters || (valuesIdx[nodecat]['cluster_index'] || valuesIdx[nodecat][TW.nodeClusAtt]) // gotClusters = gotClusters || (valuesIdx[nodecat]['cluster_index'] || valuesIdx[nodecat][TW.conf.nodeClusAtt])
// } // }
// all scanned attributes get an inverted index // all scanned attributes get an inverted index
...@@ -332,11 +332,11 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) { ...@@ -332,11 +332,11 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) {
// how many bins for this attribute ? // how many bins for this attribute ?
var nBins = 3 var nBins = 3
if (TW.customLegendsBins && TW.customLegendsBins[at]) { if (TW.conf.customLegendsBins && TW.conf.customLegendsBins[at]) {
nBins = TW.customLegendsBins[at] nBins = TW.conf.customLegendsBins[at]
} }
else if (TW.legendsBins) { else if (TW.conf.legendsBins) {
nBins = TW.legendsBins nBins = TW.conf.legendsBins
} }
// create tick thresholds // create tick thresholds
...@@ -345,7 +345,7 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) { ...@@ -345,7 +345,7 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) {
legendRefTicks.push(valuesIdx[cat][at].vals[nthVal]) legendRefTicks.push(valuesIdx[cat][at].vals[nthVal])
} }
if (TW.debugFlags.logFacets) console.debug("intervals for", at, legendRefTicks) if (TW.conf.debug.logFacets) console.debug("intervals for", at, legendRefTicks)
var nTicks = legendRefTicks.length var nTicks = legendRefTicks.length
var sortedDistinctVals = Object.keys(valuesIdx[cat][at].map).sort(function(a,b){return Number(a)-Number(b)}) var sortedDistinctVals = Object.keys(valuesIdx[cat][at].map).sort(function(a,b){return Number(a)-Number(b)})
...@@ -413,16 +413,16 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) { ...@@ -413,16 +413,16 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) {
} }
// 'clust_default' is an alias to the user-defined default clustering // 'clust_default' is an alias to the user-defined default clustering
if (TW.nodeClusAtt != undefined if (TW.conf.nodeClusAtt != undefined
&& facetIdx[cat][TW.nodeClusAtt] // <= if found in data && facetIdx[cat][TW.conf.nodeClusAtt] // <= if found in data
&& !facetIdx[cat]['clust_default'] // <= and if an attr named 'clust_default' was not already in data && !facetIdx[cat]['clust_default'] // <= and if an attr named 'clust_default' was not already in data
) { ) {
facetIdx[cat]['clust_default'] = facetIdx[cat][TW.nodeClusAtt] facetIdx[cat]['clust_default'] = facetIdx[cat][TW.conf.nodeClusAtt]
} }
} }
if (TW.debugFlags.logFacets) { if (TW.conf.debug.logFacets) {
var classvalues_fin = performance.now() var classvalues_fin = performance.now()
console.log('end TW.Clusters, own time:', classvalues_fin-classvalues_deb) console.log('end TW.Clusters, own time:', classvalues_fin-classvalues_deb)
} }
...@@ -435,7 +435,7 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) { ...@@ -435,7 +435,7 @@ function facetsBinning (valuesIdx, Atts_2_Exclude) {
// for {1,2}partite graphs // for {1,2}partite graphs
function dictfyGexf( gexf , categories ){ function dictfyGexf( gexf , categories ){
if (TW.debugFlags.logParsers) if (TW.conf.debug.logParsers)
console.log("ParseCustom gexf 2nd loop, main data extraction, with categories", categories) console.log("ParseCustom gexf 2nd loop, main data extraction, with categories", categories)
...@@ -455,11 +455,9 @@ function dictfyGexf( gexf , categories ){ ...@@ -455,11 +455,9 @@ function dictfyGexf( gexf , categories ){
// var edgesAttributes = declaredAtts.eAttrs // var edgesAttributes = declaredAtts.eAttrs
var elsNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural) var elsNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural)
labels = []; TW.labels = [];
minNodeSize=999.00; minNodeSize=10000000;
maxNodeSize=0.001; maxNodeSize=0;
numberOfDocs=0;
numberOfNGrams=0;
// debug: for local stats // debug: for local stats
// let allSizes = [] // let allSizes = []
...@@ -579,8 +577,8 @@ function dictfyGexf( gexf , categories ){ ...@@ -579,8 +577,8 @@ function dictfyGexf( gexf , categories ){
if(!node.size) console.log("node without size: "+node.id+" : "+node.label); if(!node.size) console.log("node without size: "+node.id+" : "+node.label);
// user-indicated default => copy for old default accessors // user-indicated default => copy for old default accessors
if (node.attributes[TW.nodeClusAtt]) { if (node.attributes[TW.conf.nodeClusAtt]) {
node.attributes['clust_default'] = node.attributes[TW.nodeClusAtt] node.attributes['clust_default'] = node.attributes[TW.conf.nodeClusAtt]
} }
// save record // save record
...@@ -636,7 +634,7 @@ function dictfyGexf( gexf , categories ){ ...@@ -636,7 +634,7 @@ function dictfyGexf( gexf , categories ){
var edgesNode = edgesNodes[i]; var edgesNode = edgesNodes[i];
var edgeNodes = edgesNode.getElementsByTagName('edge'); var edgeNodes = edgesNode.getElementsByTagName('edge');
if (TW.debugFlags.logParsers) if (TW.conf.debug.logParsers)
console.log("edgeNodes.length", edgeNodes.length) console.log("edgeNodes.length", edgeNodes.length)
for(j=0; j<edgeNodes.length; j++) { for(j=0; j<edgeNodes.length; j++) {
...@@ -651,7 +649,7 @@ function dictfyGexf( gexf , categories ){ ...@@ -651,7 +649,7 @@ function dictfyGexf( gexf , categories ){
id: indice, id: indice,
source: source, source: source,
target: target, target: target,
type : (type) ? type : sigmaJsDrawingProperties['defaultEdgeType'], type : (type) ? type : TW.conf.sigmaJsDrawingProperties['defaultEdgeType'],
label: "", label: "",
categ: "", categ: "",
attributes: [] attributes: []
...@@ -895,7 +893,7 @@ function scanJSON( data ) { ...@@ -895,7 +893,7 @@ function scanJSON( data ) {
// Level-00 // Level-00
// for {1,2}partite graphs // for {1,2}partite graphs
function dictfyJSON( data , categories ) { function dictfyJSON( data , categories ) {
if (TW.debugFlags.logParsers) if (TW.conf.debug.logParsers)
console.log("ParseCustom json 2nd loop, main data extraction, with categories", categories) console.log("ParseCustom json 2nd loop, main data extraction, with categories", categories)
var catDict = {} var catDict = {}
...@@ -952,11 +950,11 @@ function dictfyJSON( data , categories ) { ...@@ -952,11 +950,11 @@ function dictfyJSON( data , categories ) {
TW.Clusters = facetsBinning (tmpVals, Atts_2_Exclude) TW.Clusters = facetsBinning (tmpVals, Atts_2_Exclude)
colorList.sort(function(){ return Math.random()-0.5; }); TW.colorList.sort(function(){ return Math.random()-0.5; });
for (var i in nodes ){ for (var i in nodes ){
if (nodes[i].color=="#FFFFFF") { if (nodes[i].color=="#FFFFFF") {
var attval = ( isUndef(nodes[i].attributes) || isUndef(nodes[i].attributes["clust_default"]) )? 0 : nodes[i].attributes["clust_default"] ; var attval = ( isUndef(nodes[i].attributes) || isUndef(nodes[i].attributes["clust_default"]) )? 0 : nodes[i].attributes["clust_default"] ;
nodes[i].color = colorList[ attval ] nodes[i].color = TW.colorList[ attval ]
} }
} }
......
...@@ -14,7 +14,7 @@ SigmaUtils = function () { ...@@ -14,7 +14,7 @@ SigmaUtils = function () {
var n = nodes[i]; var n = nodes[i];
// console.debug('tr >>> fgr node', n) // console.debug('tr >>> fgr node', n)
if(initialActivetypes[catDict[n.type]] || TW.debugFlags.initialShowAll) { if(initialActivetypes[catDict[n.type]] || TW.conf.debug.initialShowAll) {
// var node = { // var node = {
// id : n.id, // id : n.id,
// label : n.label, // label : n.label,
...@@ -111,7 +111,7 @@ SigmaUtils = function () { ...@@ -111,7 +111,7 @@ SigmaUtils = function () {
context.beginPath(); context.beginPath();
if (TW.selectedColor == "node") if (TW.conf.nodesGreyBorderColor == "node")
context.fillStyle = TW.handpickedcolor? node.customAttrs.alt_color : node.color; // node's context.fillStyle = TW.handpickedcolor? node.customAttrs.alt_color : node.color; // node's
else else
context.fillStyle = "#F7E521"; // yellow context.fillStyle = "#F7E521"; // yellow
...@@ -204,11 +204,11 @@ SigmaUtils = function () { ...@@ -204,11 +204,11 @@ SigmaUtils = function () {
// console.debug(`t=${tstamp()} curve render activeedge: ${edgeInfos(edge)})`) // console.debug(`t=${tstamp()} curve render activeedge: ${edgeInfos(edge)})`)
} }
else if (edge.customAttrs.grey) { else if (edge.customAttrs.grey) {
color = TW.edgeGreyColor color = TW.conf.edgeGreyColor
size = 1 size = 1
} }
else { else {
color = "rgba( "+baseRGB+" , "+TW.edgeDefaultOpacity+")"; color = "rgba( "+baseRGB+" , "+TW.conf.edgeDefaultOpacity+")";
size = defSize size = defSize
} }
...@@ -256,11 +256,11 @@ SigmaUtils = function () { ...@@ -256,11 +256,11 @@ SigmaUtils = function () {
color = 'rgba('+rgb.join()+',.7)' color = 'rgba('+rgb.join()+',.7)'
} }
else if (edge.customAttrs.grey) { else if (edge.customAttrs.grey) {
color = TW.edgeGreyColor color = TW.conf.edgeGreyColor
size = 1 size = 1
} }
else { else {
// color = "rgba( "+rgb.join()+" , "+TW.edgeDefaultOpacity+")"; // color = "rgba( "+rgb.join()+" , "+TW.conf.edgeDefaultOpacity+")";
color = edge.customAttrs.true_color color = edge.customAttrs.true_color
size = defSize size = defSize
} }
...@@ -294,7 +294,7 @@ SigmaUtils = function () { ...@@ -294,7 +294,7 @@ SigmaUtils = function () {
// mode variants // mode variants
if (TW.selectionActive) { if (TW.selectionActive) {
// passive nodes should blend in the grey of TW.edgeGreyColor // passive nodes should blend in the grey of TW.conf.edgeGreyColor
// cf settings_explorerjs, defgrey_color and greyEverything() // cf settings_explorerjs, defgrey_color and greyEverything()
if (node.customAttrs.grey) { if (node.customAttrs.grey) {
if (! TW.handpickedcolor) { if (! TW.handpickedcolor) {
...@@ -310,7 +310,7 @@ SigmaUtils = function () { ...@@ -310,7 +310,7 @@ SigmaUtils = function () {
nodeColor = node.customAttrs.altgrey_color nodeColor = node.customAttrs.altgrey_color
} }
// nice looking uniform grey // nice looking uniform grey
borderColor = TW.nodesGreyBorderColor borderColor = TW.conf.nodesGreyBorderColor
} }
// neighbor nodes <=> (highlight flag AND selectionActive) // neighbor nodes <=> (highlight flag AND selectionActive)
else if(node.customAttrs.highlight) { else if(node.customAttrs.highlight) {
...@@ -501,10 +501,9 @@ SigmaUtils = function () { ...@@ -501,10 +501,9 @@ SigmaUtils = function () {
// - conditions on graph size (£TODO use these to slowDown small graphs) // - conditions on graph size (£TODO use these to slowDown small graphs)
// - edges management (turns them off and restores them after finished) // - edges management (turns them off and restores them after finished)
this.smartForceAtlas = function (fa2duration) { this.smartForceAtlas = function (fa2duration) {
if (TW.conf.fa2Available) {
if (TW.fa2Available) {
if (!fa2duration) { if (!fa2duration) {
fa2duration = parseInt(TW.fa2milliseconds) || 4000 fa2duration = parseInt(TW.conf.fa2Milliseconds) || 4000
} }
// togglability case // togglability case
...@@ -514,7 +513,7 @@ SigmaUtils = function () { ...@@ -514,7 +513,7 @@ SigmaUtils = function () {
} }
// normal case // normal case
else { else {
if ( TW.fa2enabled && TW.partialGraph.graph.nNodes() >= TW.minNodesForAutoFA2) { if ( TW.conf.fa2Enabled && TW.partialGraph.graph.nNodes() >= TW.conf.minNodesForAutoFA2) {
// hide edges during work for smaller cpu load // hide edges during work for smaller cpu load
if (TW.partialGraph.settings('drawEdges')) { if (TW.partialGraph.settings('drawEdges')) {
this.toggleEdges(false) this.toggleEdges(false)
...@@ -547,7 +546,7 @@ SigmaUtils = function () { ...@@ -547,7 +546,7 @@ SigmaUtils = function () {
function createWaitIcon(idname, width) { function createWaitIcon(idname, width) {
let icon = document.createElement('img') let icon = document.createElement('img')
icon.src = TW.libspath + '/img2/loader.gif' icon.src = TW.conf.libspath + '/img2/loader.gif'
icon.style.position = 'absolute' icon.style.position = 'absolute'
icon.style.left = '0' icon.style.left = '0'
...@@ -886,7 +885,7 @@ function repaintEdges() { ...@@ -886,7 +885,7 @@ function repaintEdges() {
// rewrite of clustersBy with binning and for attributes that can have negative float values // rewrite of clustersBy with binning and for attributes that can have negative float values
// NB - binning is done at parseCustom // NB - binning is done at parseCustom
// - number of bins can be specified by attribute name in TW.customLegendsBins // - number of bins can be specified by attribute name in TW.conf.customLegendsBins
function colorsRelByBins(daclass) { function colorsRelByBins(daclass) {
var binColors var binColors
var doModifyLabel = false var doModifyLabel = false
...@@ -1202,7 +1201,7 @@ function colorsBy(daclass) { ...@@ -1202,7 +1201,7 @@ function colorsBy(daclass) {
} }
else { else {
// shuffle on entire array is better than random sorting function on each element // shuffle on entire array is better than random sorting function on each element
var randomColorList = shuffle(colorList) var randomColorList = shuffle(TW.colorList)
for(var j in TW.nodeIds) { for(var j in TW.nodeIds) {
var the_node = TW.Nodes[ TW.nodeIds[j] ] var the_node = TW.Nodes[ TW.nodeIds[j] ]
......
...@@ -45,7 +45,7 @@ sigmaTools = (function(stools) { ...@@ -45,7 +45,7 @@ sigmaTools = (function(stools) {
var rawEdge = rawGexfEdges[i] var rawEdge = rawGexfEdges[i]
var rgbStr = sigmaTools.edgeRGB(newNodes[rawEdge.source].color, newNodes[rawEdge.target].color) var rgbStr = sigmaTools.edgeRGB(newNodes[rawEdge.source].color, newNodes[rawEdge.target].color)
var leColor = "rgba("+rgbStr+","+TW.edgeDefaultOpacity+")" var leColor = "rgba("+rgbStr+","+TW.conf.edgeDefaultOpacity+")"
var newEid = rawEdge.source+";"+rawEdge.target; var newEid = rawEdge.source+";"+rawEdge.target;
var newEdge = { var newEdge = {
......
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