Commit d10bdadf authored by Romain Loth's avatar Romain Loth

WIP: experimenting with input param syntax

parent 180e3f09
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
"gexfs": { "gexfs": {
"ProgrammeDesCandidats.enrichi.gexf": { "ProgrammeDesCandidats.enrichi.gexf": {
"social": {}, "social": {},
"semantic": {} "semantic": {"table":"terms"}
}, },
"ProgrammeDesCandidats.gexf": { "ProgrammeDesCandidats.gexf": {
"social": {}, "social": {},
"semantic": {} "semantic": {"table":"terms"}
} }
} }
}, },
......
...@@ -27,7 +27,7 @@ This will still evolve but the main steps for any graph initialization messily u ...@@ -27,7 +27,7 @@ This will still evolve but the main steps for any graph initialization messily u
- `somenode.attributes`: the `attributes` property is always an object - `somenode.attributes`: the `attributes` property is always an object
- any attribute listed in the sourcenode.attributes will be indexed if the TW.scanClusters flag is true - any attribute listed in the sourcenode.attributes will be indexed if the TW.scanClusters flag is true
- the mapping from attribute values to matching nodes is in TW.Clusters.aType.anAttr.aValue.map ! - the mapping from attribute values to matching nodes is in TW.Clusters.aType.anAttr.aValue.map
- coloration: "`age`" "`growth_rate`" + any attribute of type float or int - coloration: "`age`" "`growth_rate`" + any attribute of type float or int
- clustering: "`cluster_index`" ou nom figurant dans `TW.nodeClusAtt` - clustering: "`cluster_index`" ou nom figurant dans `TW.nodeClusAtt`
- vocabulary: (en cours) any attribute of type string and where the amount of distinct values is < TW.somesettings - vocabulary: (en cours) any attribute of type string and where the amount of distinct values is < TW.somesettings
......
...@@ -21,16 +21,16 @@ ...@@ -21,16 +21,16 @@
Widely available font (possibly available without this cdn request, actually). Widely available font (possibly available without this cdn request, actually).
Also condensed is good for labels in crowded graphs Also condensed is good for labels in crowded graphs
--> -->
<link href="https://fonts.googleapis.com/css?family=Ubuntu+Condensed" rel="stylesheet" type='text/css'> <!-- <link href="https://fonts.googleapis.com/css?family=Ubuntu+Condensed" rel="stylesheet" type='text/css'> -->
<!-- Roboto <!-- Roboto
Good for tweets if Helvetica is not present Good for tweets if Helvetica is not present
--> -->
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type='text/css'> <!-- <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type='text/css'> -->
<!-- Crete Round <!-- Crete Round
Original *and* informative :) --> Original *and* informative :) -->
<link href='https://fonts.googleapis.com/css?family=Crete+Round:400,400italic&subset=latin-ext' rel='stylesheet' type='text/css'> <!-- <link href='https://fonts.googleapis.com/css?family=Crete+Round:400,400italic&subset=latin-ext' rel='stylesheet' type='text/css'> -->
<!-- Lora <!-- Lora
"book" (roman style) + nice heading --> "book" (roman style) + nice heading -->
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<!-- Sahitya & Gurajada <!-- Sahitya & Gurajada
"book" (beautiful quality roman) + devanagari support + telugu --> "book" (beautiful quality roman) + devanagari support + telugu -->
<link href="https://fonts.googleapis.com/css?family=Gurajada" rel="stylesheet"> <!-- <link href="https://fonts.googleapis.com/css?family=Gurajada" rel="stylesheet"> -->
<!-- <link href="https://fonts.googleapis.com/css?family=Sahitya" rel="stylesheet"> --> <!-- <link href="https://fonts.googleapis.com/css?family=Sahitya" rel="stylesheet"> -->
<!-- Itim <!-- Itim
...@@ -411,7 +411,7 @@ ...@@ -411,7 +411,7 @@
<!-- class="my-legend" (absolute position bottom left) --> <!-- class="my-legend" (absolute position bottom left) -->
<div id="legend_for_clusters" class="over-panels"></div> <div id="legend-for-clusters" class="over-panels"></div>
</div> </div>
</div> </div>
......
...@@ -255,8 +255,8 @@ function set_ClustersLegend ( daclass, groupedByTicks ) { ...@@ -255,8 +255,8 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
//TW.partialGraph.states.slice(-1)[0].LouvainFait = true //TW.partialGraph.states.slice(-1)[0].LouvainFait = true
$("#legend_for_clusters").removeClass( "my-legend" ) $("#legend-for-clusters").removeClass( "my-legend" )
$("#legend_for_clusters").html("") $("#legend-for-clusters").html("")
if(daclass==null) return; if(daclass==null) return;
if (daclass=="clust_louvain") if (daclass=="clust_louvain")
...@@ -281,7 +281,7 @@ function set_ClustersLegend ( daclass, groupedByTicks ) { ...@@ -281,7 +281,7 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
if (!groupedByTicks && (!TW.Clusters[curType] || !TW.Clusters[curType][daclass])) { if (!groupedByTicks && (!TW.Clusters[curType] || !TW.Clusters[curType][daclass])) {
console.warn(`no class bins for ${daclass}, displaying no legend`) console.warn(`no class bins for ${daclass}, displaying no legend`)
$("#legend_for_clusters").hide() $("#legend-for-clusters").hide()
} }
else { else {
var LegendDiv = "" var LegendDiv = ""
...@@ -318,9 +318,9 @@ function set_ClustersLegend ( daclass, groupedByTicks ) { ...@@ -318,9 +318,9 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
LegendDiv += ' </ul>' LegendDiv += ' </ul>'
LegendDiv += ' </div>' LegendDiv += ' </div>'
$("#legend_for_clusters").addClass( "my-legend" ); $("#legend-for-clusters").addClass( "my-legend" );
$("#legend_for_clusters").html( LegendDiv ) $("#legend-for-clusters").html( LegendDiv )
$("#legend_for_clusters").show() $("#legend-for-clusters").show()
} }
} }
......
/* any block over the graph (legend, histogram...) */ /* any block over the graph (legend, histogram...) */
.over-panels { .over-panels {
z-index: 5 ; /* over the graph */ z-index: 5 ; /* over the graph */
padding: 5px;
-moz-border-radius: 3px; -moz-border-radius: 3px;
-webkit-border-radius: 3px; -webkit-border-radius: 3px;
-border-radius: 3px; -border-radius: 3px;
...@@ -25,38 +24,25 @@ ...@@ -25,38 +24,25 @@
font-size: 70%; font-size: 70%;
float:right; float:right;
margin-top:.5em; margin-top:.5em;
margin-right:1em margin-right:1em;
} }
""
/* LEGEND PANEL */ /* LEGEND PANEL */
.legend_for_clusters {
position:absolute;
bottom:1px;
left:1px;
border:solid 1px red;
font-size:xx-small;
}
/*
.my-legend * {
position: relative;
z-index: 5;
}*/
.my-legend { .my-legend {
position:fixed; position:fixed;
z-index: 5;
/* width: we set it equal or smaller than #lefttopbox width */ /* width: we set it equal or smaller than #lefttopbox width */
width:18%; max-width:18%;
max-height: 25%; max-height: 25%;
padding: 0 5px;
overflow-y:scroll; overflow-y:scroll;
bottom:5px; bottom:0;
left:5px; left:0;
border:solid 1px black;
background-color:white; background-color:white;
opacity: 0.8; opacity: 0.8;
color:#250587; color:#250587;
margin: 7px; margin: 7px;
font-size:small;
} }
.my-legend .legend-title { .my-legend .legend-title {
...@@ -286,6 +272,8 @@ ...@@ -286,6 +272,8 @@
overflow: hidden; overflow: hidden;
text-align:center; text-align:center;
padding: .3em 1em 1em 1em; padding: .3em 1em 1em 1em;
display: none; /* because no are nodes selected at page init time */
} }
#current-selection { #current-selection {
......
...@@ -2,13 +2,15 @@ ...@@ -2,13 +2,15 @@
var TW = {} var TW = {}
// POSSIBLE: group like TW.settings ?
// £TODO separate files for TW.vars and TW.settings (configfile)
TW.geomap = false; TW.geomap = false;
TW.colorByAtt = false; TW.colorByAtt = false;
TW.twittertimeline = false; TW.twittertimeline = false;
TW.minimap=false; TW.minimap=false;
TW.getAdditionalInfo = true;// True: Activate TopPapers feature. TW.getAdditionalInfo = true;// True: Activate TopPapers feature.
TW.filemenu = 'db.json'
// TW.mainfile = "data/mysuperproject/my.gexf" // TW.mainfile = "data/mysuperproject/my.gexf"
TW.mainfile = "data/politoscope/ProgrammeDesCandidats.enrichi.gexf" TW.mainfile = "data/politoscope/ProgrammeDesCandidats.enrichi.gexf"
TW.APINAME = "http://127.0.0.1:5000/twitter_search"; TW.APINAME = "http://127.0.0.1:5000/twitter_search";
...@@ -16,15 +18,7 @@ var TW = {} ...@@ -16,15 +18,7 @@ var TW = {}
TW.bridge={}; TW.bridge={};
TW.bridge["forFilteredQuery"] = "services/api/graph"; TW.bridge["forFilteredQuery"] = "services/api/graph";
TW.bridge["forNormalQuery"] = "services/api/graph"; TW.bridge["forNormalQuery"] = "services/api/graph";
TW.gexfPaths={};
TW.gexfDict={};
TW.gexfDictReverse={}
for (var i in TW.gexfDict){
TW.gexfDictReverse[TW.gexfDict[i]]=i;
}
TW.field = {}
// field["data/20141128_GPs_03_bi.gexf"] = "ISItermsfirstindexing";
// field["data/20141215_GPs_04.gexf"] = "ISItermsfirstindexing";
TW.Relations = {} TW.Relations = {}
// module_names to load // module_names to load
...@@ -40,7 +34,7 @@ var TW = {} ...@@ -40,7 +34,7 @@ var TW = {}
TW.SystemState = {} TW.SystemState = {}
TW.SystemState.level = true; TW.SystemState.level = true;
TW.SystemState.type = [ true, false ] // usually overridden by makeSystemStates TW.SystemState.type = [ true, false ] // usually overridden by initialActivetypes
TW.SystemState.selections = []; TW.SystemState.selections = [];
TW.SystemState.opposites = []; TW.SystemState.opposites = [];
TW.catSoc = "Document"; TW.catSoc = "Document";
...@@ -53,7 +47,8 @@ var SigmaUtils = function () {}; ...@@ -53,7 +47,8 @@ var SigmaUtils = function () {};
var TinaWebJS = function () {}; var TinaWebJS = function () {};
// node sizes
// ----------
var sizeMult = []; var sizeMult = [];
sizeMult[TW.catSoc] = 0.0; sizeMult[TW.catSoc] = 0.0;
sizeMult[TW.catSem] = 0.0; sizeMult[TW.catSem] = 0.0;
...@@ -70,24 +65,20 @@ var desirableTagCloudFont_MAX=20; ...@@ -70,24 +65,20 @@ var desirableTagCloudFont_MAX=20;
var desirableNodeSizeMIN=1; var desirableNodeSizeMIN=1;
var desirableNodeSizeMAX=12; var desirableNodeSizeMAX=12;
// apparently not used ?
var desirableScholarSize=6; //Remember that all scholars have the same size!
/*
*Three states:
* - true: fa2 auto-running at start
* - false: fa2 stopped at start, button exists
* - "off": button doesn't exist, fa2 stopped forever
**/ TW.fa2enabled=true;//"off";
TW.minNodesForAutoFA2 = 5
// layouts
// -------
// 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
// ============ < / DEVELOPER OPTIONS > ============ // ============ < / DEVELOPER OPTIONS > ============
TW.branding = 'test bipart' TW.branding = 'test bipart'
TW.libspath = 'libs' TW.libspath = 'libs' // NB path vars should not be used after page load
TW.nodeClusAtt = "modularity_class" TW.nodeClusAtt = "modularity_class"
...@@ -126,7 +117,7 @@ TW.debugFlags = { ...@@ -126,7 +117,7 @@ TW.debugFlags = {
logParsers: false, // ...about parsing said data logParsers: false, // ...about parsing said data
logFacets: false, // ...about parsing node attribute:value facets logFacets: false, // ...about parsing node attribute:value facets
logSettings: false, // ...about settings at Tina and Sigma init time logSettings: false, // ...about settings at Tina and Sigma init time
logSelections: false logSelections: true
} }
// triggers overriding sigma.canvas renderers: nodes.def, labels.def, edges.def // triggers overriding sigma.canvas renderers: nodes.def, labels.def, edges.def
......
...@@ -736,15 +736,20 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -736,15 +736,20 @@ TinaWebJS = function ( sigmacanvas ) {
// button CENTER // button CENTER
$("#lensButton").click(function () { $("#lensButton").click(function () {
// new sigma.js // new sigma.js
partialGraph.camera.goTo({x:0, y:0, ratio:1.2}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2})
}); });
if (TW.fa2Available) {
$("#layoutButton").click(function () { $("#layoutButton").click(function () {
sigma_utils.smartForceAtlas() sigma_utils.smartForceAtlas()
}); });
}
else {
$("#layoutButton").hide()
}
if (TW.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
theHtml.classList.add('waiting'); theHtml.classList.add('waiting');
...@@ -766,6 +771,11 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -766,6 +771,11 @@ TinaWebJS = function ( sigmacanvas ) {
return; return;
} }
}); });
}
else {
$("#noverlapButton").hide()
}
$("#edges-switch").click(function () { $("#edges-switch").click(function () {
sigma_utils.toggleEdges(this.checked) sigma_utils.toggleEdges(this.checked)
...@@ -1091,7 +1101,7 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1091,7 +1101,7 @@ TinaWebJS = function ( sigmacanvas ) {
var possibleActivetypes = {} var possibleActivetypes = {}
var N=Math.pow(2 , cats.length); var N=Math.pow(2 , cats.length);
for (i = 0; i < N; i++) { for (var i = 0; i < N; i++) {
let bin = (i).toString(2) let bin = (i).toString(2)
let bin_splitted = [] let bin_splitted = []
......
...@@ -74,18 +74,16 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) { ...@@ -74,18 +74,16 @@ var AjaxSync = (function(TYPE, URL, DATA, DT) {
return Result; return Result;
}).index(); }).index();
function getGexfPath(v){ function jsActionOnGexfSelector(gexfBasename){
var gexfpath=(TW.gexfDictReverse[v])?TW.gexfDictReverse[v]:v; let gexfPath = TW.gexfPaths[gexfBasename] || gexfBasename+".gexf"
return gexfpath; let serverPrefix = ''
} var pathcomponents = window.location.pathname.split('/')
for (var i in pathcomponents) {
function jsActionOnGexfSelector(gexfBasename , db_json){ if (pathcomponents[i] != 'explorerjs.html')
db_json = (db_json)?"&mode=db.json":"" serverPrefix += '/'+pathcomponents[i]
let gexfLegend = gexfBasename+".gexf" }
if(getGexfPath[gexfLegend]) var newDataRes = AjaxSync({ URL: window.location.origin+serverPrefix+'/'+gexfPath });
window.location=window.location.origin+window.location.pathname+"?file="+encodeURIComponent(getGexfPath(gexfLegend))+db_json; mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance)
else
window.location=window.location.origin+window.location.pathname+"?file="+encodeURIComponent( gexfLegend )+db_json;
} }
// === [ what to do at start ] === // // === [ what to do at start ] === //
...@@ -265,29 +263,17 @@ function syncRemoteGraphData () { ...@@ -265,29 +263,17 @@ function syncRemoteGraphData () {
var the_file = ""; var the_file = "";
// =================== // ===================
// direct urlparam file case
if( !isUndef(getUrlParam.file) ) {
the_file = getUrlParam.file
}
// direct file fallback case: specified file in settings_explorer
else if (TW.mainfile && linkCheck(TW.mainfile)) {
console.log("no @file arg: trying TW.mainfile from settings")
the_file = TW.mainfile;
}
// overall fallback case: try to open a listing of files (by default: db.json)
// TODO rename 'mode=' argkey into something more descriptive like 'menufile='
// here and in caller apps like tweetoscope etc.
else {
// we'll first retrieve the menu of available files in db.json, then get the real data in a second ajax
var infofile = ''
if ( !isUndef(getUrlParam.mode) ) { // TODO check if legacy apps use db.json name otherwise use mode == 'menufile'
infofile = getUrlParam.mode // and 'db.json' should be hardcoded (safer)
} // if (!isUndef(getUrlParam.mode) && getUrlParam.mode == 'menufile') {
// default
else {
infofile = "db.json" // 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")
// 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"
if (TW.debugFlags.logFetchers) console.info(`attempting to load infofile ${infofile}`) if (TW.debugFlags.logFetchers) console.info(`attempting to load infofile ${infofile}`)
var preRES = AjaxSync({ URL: infofile, DT:"json" }); var preRES = AjaxSync({ URL: infofile, DT:"json" });
...@@ -296,7 +282,6 @@ function syncRemoteGraphData () { ...@@ -296,7 +282,6 @@ function syncRemoteGraphData () {
console.log('initial AjaxSync result preRES', preRES) console.log('initial AjaxSync result preRES', preRES)
} }
var first_file = "" , first_path = "" var first_file = "" , first_path = ""
for( var path in preRES.data ) { for( var path in preRES.data ) {
...@@ -315,22 +300,29 @@ function syncRemoteGraphData () { ...@@ -315,22 +300,29 @@ function syncRemoteGraphData () {
the_file = first_path+"/"+getUrlParam.file the_file = first_path+"/"+getUrlParam.file
} }
var files_selector = '<select onchange="jsActionOnGexfSelector(this.value , true);">' 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 the_gexfs = preRES.data[path]["gexfs"]
for(var aGexf in the_gexfs) { for(var aGexf in the_gexfs) {
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
// ex : "RiskV2PageRank1000.gexf":data/AXA/RiskV2PageRank1000.gexf
// (we assume there's no duplicate basenames)
if (TW.debugFlags.logFetchers) if (TW.debugFlags.logFetchers)
console.log("\t\t\t"+gexfBasename+ " -> table:" +the_gexfs[aGexf]["semantic"]["table"] ) console.log("\t\t\t"+gexfBasename+ " -> table:" +the_gexfs[aGexf]["semantic"]["table"] )
TW.field[path+"/"+aGexf] = the_gexfs[aGexf]["semantic"]["table"]
// -------------------------->8------------------------------------------
// £TODO this part is underspecified
// if used in some usecases, port it to nodetypes
// otherwise remove
// TW.field[path+"/"+aGexf] = the_gexfs[aGexf]["semantic"]["table"]
// ex : data/AXA/RiskV2PageRank5000.gexf:"ISItermsAxa_2015" // ex : data/AXA/RiskV2PageRank5000.gexf:"ISItermsAxa_2015"
// -------------------------->8------------------------------------------
TW.gexfDict[path+"/"+aGexf] = aGexf
// ex : data/AXA/RiskV2PageRank1000.gexf:"RiskV2PageRank1000.gexf"
let cssFileSelected = (the_file==(path+"/"+aGexf))?"selected":"" let cssFileSelected = (the_file==(path+"/"+aGexf))?"selected":""
files_selector += '<option '+cssFileSelected+'>'+gexfBasename+'</option>' files_selector += '<option '+cssFileSelected+'>'+gexfBasename+'</option>'
...@@ -339,8 +331,21 @@ function syncRemoteGraphData () { ...@@ -339,8 +331,21 @@ function syncRemoteGraphData () {
break; break;
} }
files_selector += "</select>" files_selector += "</select>"
console.log("files_selector HTML", files_selector)
$("#network").html(files_selector) $("#network").html(files_selector)
} }
// direct urlparam file case
else if( !isUndef(getUrlParam.file) ) {
the_file = getUrlParam.file
}
// direct file fallback case: specified file in settings_explorer
else if (TW.mainfile && linkCheck(TW.mainfile)) {
console.log("no @file arg: trying TW.mainfile from settings")
the_file = TW.mainfile;
}
else {
console.warn("No specified input!")
}
var finalRes = AjaxSync({ URL: the_file }); var finalRes = AjaxSync({ URL: the_file });
inData = finalRes["data"] inData = finalRes["data"]
......
...@@ -749,31 +749,32 @@ function updateRelations(typedRelations, edgeCateg, srcId, tgtId){ ...@@ -749,31 +749,32 @@ function updateRelations(typedRelations, edgeCateg, srcId, tgtId){
// To fill the reverse map: values => nodeids of a given type // To fill the reverse map: values => nodeids of a given type
function updateValueFacets(facetIdx, Atts_2_Exclude, aNode){ function updateValueFacets(facetIdx, Atts_2_Exclude, aNode) {
if (!facetIdx[aNode.type]) facetIdx[aNode.type]={} if (!facetIdx[aNode.type]) facetIdx[aNode.type]={}
for (var at in aNode.attributes) { for (var at in aNode.attributes) {
if (!facetIdx[aNode.type][at]) facetIdx[aNode.type][at]={'vals':[],'map':{}} if (!facetIdx[aNode.type][at]) facetIdx[aNode.type][at]={'vals':[],'map':{}}
let castVal = Number(aNode.attributes[at]) let castVal = Number(aNode.attributes[at])
// Identifying the attribute datatype: exclude strings and objects // Identifying the attribute datatype: exclude strings and objects
if ( isNaN(castVal) ) { // if ( isNaN(castVal) ) {
if (!Atts_2_Exclude[at]) Atts_2_Exclude[at]=true; // if (!Atts_2_Exclude[at]) Atts_2_Exclude[at]=true;
//
// TODO: this old Atts_2_Exclude strategy could be replaced, // // TODO: this old Atts_2_Exclude strategy could be replaced,
// not to exclude but to store the datatype somewhere like facetIdx[aNode.type][at].dtype // // not to exclude but to store the datatype somewhere like facetIdx[aNode.type][at].dtype
// => the datatype would be a condition (no bins if not numeric, etc.) // // => the datatype would be a condition (no bins if not numeric, etc.)
// => it would also allow to index text values (eg country, affiliation, etc.) // // => it would also allow to index text values (eg country, affiliation, etc.)
// with the strategy "most frequent distinct values" + "others" // // with the strategy "most frequent distinct values" + "others"
// which would be useful (eg country, affiliation, etc.) !!! // // which would be useful (eg country, affiliation, etc.) !!!
//
} // }
// numeric attr => build facets // numeric attr => build facets
else { // else {
if (!facetIdx[aNode.type][at].map[castVal]) facetIdx[aNode.type][at].map[castVal] = [] if (!facetIdx[aNode.type][at].map[castVal]) facetIdx[aNode.type][at].map[castVal] = []
facetIdx[aNode.type][at].vals.push(castVal) // for ordered scale facetIdx[aNode.type][at].vals.push(castVal) // for ordered scale
facetIdx[aNode.type][at].map[castVal].push(aNode.id) // inverted index facetIdx[aNode.type][at].map[castVal].push(aNode.id) // inverted index
} // }
} }
return [facetIdx, Atts_2_Exclude] return [facetIdx, Atts_2_Exclude]
} }
...@@ -940,14 +941,15 @@ function dictfyJSON( data , categories ) { ...@@ -940,14 +941,15 @@ function dictfyJSON( data , categories ) {
nodes[node.id] = node; nodes[node.id] = node;
console.log(n.attributes)
// creating a faceted index from node.attributes // creating a faceted index from node.attributes
if (TW.scanClusters) { if (TW.scanClusters) {
[tmpVals, Atts_2_Exclude] = updateValueFacets(tmpVals, Atts_2_Exclude, node) [tmpVals, Atts_2_Exclude] = updateValueFacets(tmpVals, Atts_2_Exclude, node)
} }
} }
// test: json with string facet (eg lab affiliation in comex)
console.log(tmpVals['Document'])
TW.Clusters = facetsBinning (tmpVals, Atts_2_Exclude) TW.Clusters = facetsBinning (tmpVals, Atts_2_Exclude)
colorList.sort(function(){ return Math.random()-0.5; }); colorList.sort(function(){ return Math.random()-0.5; });
......
...@@ -502,6 +502,7 @@ SigmaUtils = function () { ...@@ -502,6 +502,7 @@ SigmaUtils = function () {
// - 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.fa2Available) {
if (!fa2duration) { if (!fa2duration) {
fa2duration = parseInt(TW.fa2milliseconds) || 4000 fa2duration = parseInt(TW.fa2milliseconds) || 4000
} }
...@@ -538,6 +539,8 @@ SigmaUtils = function () { ...@@ -538,6 +539,8 @@ SigmaUtils = function () {
} }
} }
}
} // /SigmaUtils object } // /SigmaUtils object
......
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