Commit 81a271bf authored by Romain Loth's avatar Romain Loth

Merge ProjectExplorer (3 relation types shown) commit '98f68d' into with_tina_1.2

parents 5be215b5 086db2d8
{ {
"data/gargistex": { "data/gargistex": {
"first" : "shale_and_ice.gexf", "first" : "shale_and_ice.gexf",
"gexfs": { "graphs":{
"shale_and_ice.gexf": { "shale_and_ice.gexf": {
"dbtype": "csv", "node0": {
"semantic":["title","keywords","abstract"], "name": "terms",
"social":["authors"], "reldbtype": "csv",
"dbfile": "shale_and_ice.csv" "reldbfile": "shale_and_ice.csv",
"reldbqcols": ["title"],
"reltemplate": "_todo"
}
},
"model_calibration.gexf": {
"node0": {
"name": "terms",
"reldbtype": "csv",
"reldbfile": "model_calibration.csv",
"reldbqcols": ["title"],
"reltemplate": "_todo"
}
} }
} }
}, },
"data/test": { "data/test": {
"first" : "mini_for_csv.gexf", "first" : "mini_for_csv.gexf",
"gexfs": { "graphs": {
"mini_for_csv.gexf": { "mini_for_csv.gexf": {
"_comment": "NB: underspecified for csv and for db.json !! so this is a prototype structure", "node0": {
"_comment": "POSS: weighted columns for matching importance", "name": "term",
"dbtype": "csv", "reldbtype": "csv",
"semantic":["title","keywords","text"], "reldbfile": "mini_for_csv.csv",
"social":["author"], "reldbqcols": ["title","keywords","text"],
"dbfile": "mini_for_csv.csv" "reltemplate": "_todo"
},
"node1": {
"name": "person",
"reldbtype": "csv",
"reldbfile": "mini_for_csv.csv",
"reldbqcols": ["author"],
"reltemplate": "_todo"
}
}, },
"test_with_various_atts.gexf": {} "test_with_various_atts.gexf": {}
} }
}, },
"data/politoscope": { "data/politoscope": {
"dbname":null, "dbname":null,
"title":"Politoscope", "title":"Politoscope",
"date":"2017", "date":"2017",
"abstract":"", "abstract":"",
"first" : "ProgrammeDesCandidats.enrichi.gexf", "first" : "ProgrammeDesCandidats.enrichi.gexf",
"gexfs": { "graphs": {
"ProgrammeDesCandidats.enrichi.gexf": { "ProgrammeDesCandidats.enrichi.gexf": {
"social": {}, "node0": { "name": "terms" }
"semantic": {} },
}, "ProgrammeDesCandidats.gexf": {
"ProgrammeDesCandidats.gexf": { "node0": { "name": "terms" }
"social": {}, }
"semantic": {} }
} },
}
},
"data/ClimateChange": { "data/ClimateChange": {
"dbname":"wos_climate-change_title_2014-2015.db", "abstract":"ISIABSTRACT",
"title":"ISITITLE", "graphs": {
"date":"ISIpubdate", "Maps_S_800.gexf": {
"abstract":"ISIABSTRACT", "node0": {
"gexfs": { "name": "ISItermsWhitelistV2Oct_5 & ISItermsWhitelistV2Oct_5",
"Maps_S_800.gexf": { "reldbtable": "ISItermsWhitelistV2Oct_5",
"social": { "table":"ISIAUTHOR" , "textCol":"data","forkeyCol":"id"}, "reldbname" : "wos_climate-change_title_2014-2015.db",
"semantic": { "table":"ISItermsWhitelistV2Oct_5" , "textCol":"data","forkeyCol":"id"} "reldbtype": "CortextDB"
} }
} }
}
}, },
"data/comexjsons": { "data/comexjsons": {
"first" : "graph_example.json", "first" : "graph_example.json",
"gexfs": { "graphs": {
"graph_example.json": {} "graph_example.json": {
} "node0": { "name": "NGram" },
} "node1": { "name": "Document" }
}
}
}
} }
...@@ -467,7 +467,7 @@ ...@@ -467,7 +467,7 @@
class="custom-select form-control" class="custom-select form-control"
onchange="TW.conf.relatedDocsType=this.value; getTopPapers()"> onchange="TW.conf.relatedDocsType=this.value; getTopPapers()">
<option value="twitter">Twitter API</option> <option value="twitter">Twitter API</option>
<option value="wosLocalDB">Local DB query</option> <option value="LocalDB">Local DB query</option>
</select> </select>
</div> </div>
</div> </div>
......
...@@ -38,12 +38,12 @@ TW.conf = (function(TW){ ...@@ -38,12 +38,12 @@ TW.conf = (function(TW){
TWConf.relatedDocsMax = 10 TWConf.relatedDocsMax = 10
TWConf.relatedDocsAPI = "http://127.0.0.1:5000/twitter_search" TWConf.relatedDocsAPI = "http://127.0.0.1:5000/twitter_search"
TWConf.relatedDocsType = "twitter" // accepted: "twitter" | "wosLocalDB" TWConf.relatedDocsType = "LocalDB" // accepted: "twitter" | "LocalDB"
// POSSible: "elastic" // POSSible: "elastic"
TWConf.relatedDocsAPIS = { TWConf.relatedDocsAPIS = {
// routes by corresponding type // routes by corresponding type
"wosLocalDB": "twbackends/phpAPI", "LocalDB": "twbackends/phpAPI",
"twitter": "http://127.0.0.1:5000/twitter_search" "twitter": "http://127.0.0.1:5000/twitter_search"
} }
...@@ -158,8 +158,9 @@ TW.conf = (function(TW){ ...@@ -158,8 +158,9 @@ TW.conf = (function(TW){
// Node typology: categories (resp. 0 and 1) will get these default labels // Node typology: categories (resp. 0 and 1) will get these default labels
TWConf.catSem = "NGram"; TWConf.catSem = "NGram";
TWConf.catSoc = "Document"; TWConf.catSoc = "Document";
// NB: these labels may be superseded by the input data's node types values // NB: these labels may be superseded by:
// cf. sortNodeTypes() // - the input data's node types values cf. sortNodeTypes()
// - in servermenu mode, by the node0 & node1 properties
// Modules path // Modules path
// ------------ // ------------
...@@ -183,7 +184,7 @@ TW.conf = (function(TW){ ...@@ -183,7 +184,7 @@ TW.conf = (function(TW){
// Other GUI options // Other GUI options
// ------------------ // ------------------
TWConf.sidePanelSize = "300px" // width of the side panel (def: 400px) TWConf.sidePanelSize = "400px" // width of the side panel (def: 400px)
TWConf.filterSliders = true // show sliders for nodes/edges subsets TWConf.filterSliders = true // show sliders for nodes/edges subsets
...@@ -248,7 +249,7 @@ TW.conf = (function(TW){ ...@@ -248,7 +249,7 @@ TW.conf = (function(TW){
twNodeRendBorderColor: "#222", twNodeRendBorderColor: "#222",
// edges // edges
minEdgeSize: 1, // in fact used in tina as edge size minEdgeSize: 2, // in fact used in tina as edge size
defaultEdgeType: 'curve', // 'curve' or 'line' (curve only iff ourRendering) defaultEdgeType: 'curve', // 'curve' or 'line' (curve only iff ourRendering)
twEdgeDefaultOpacity: 0.4, // initial opacity added to src/tgt colors twEdgeDefaultOpacity: 0.4, // initial opacity added to src/tgt colors
...@@ -272,8 +273,8 @@ TW.conf = (function(TW){ ...@@ -272,8 +273,8 @@ TW.conf = (function(TW){
twSelectedColor: "default", // "node" for a label bg like the node color, twSelectedColor: "default", // "node" for a label bg like the node color,
// "default" for note-like yellow // "default" for note-like yellow
// not selected <=> grey // not selected <=> (1-greyness)
twNodesGreyOpacity: .35, // smaller value: more grey twNodesGreyOpacity: .7, // smaller value: more grey
twBorderGreyColor: "rgba(100, 100, 100, 0.5)", twBorderGreyColor: "rgba(100, 100, 100, 0.5)",
twEdgeGreyColor: "rgba(150, 150, 150, 0.5)", twEdgeGreyColor: "rgba(150, 150, 150, 0.5)",
}; };
...@@ -302,7 +303,7 @@ TW.conf = (function(TW){ ...@@ -302,7 +303,7 @@ TW.conf = (function(TW){
// relative sizes (iff ChangeType == both nodetypes) // relative sizes (iff ChangeType == both nodetypes)
TWConf.sizeMult = []; TWConf.sizeMult = [];
TWConf.sizeMult[0] = 1.0; // ie for node type 0 (<=> sem) TWConf.sizeMult[0] = 1.0; // ie for node type 0 (<=> sem)
TWConf.sizeMult[1] = 2.0; // ie for node type 1 (<=> soc) TWConf.sizeMult[1] = 2.5; // ie for node type 1 (<=> soc)
// =========== // ===========
...@@ -317,7 +318,7 @@ TW.conf = (function(TW){ ...@@ -317,7 +318,7 @@ TW.conf = (function(TW){
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
logStates: false, // ...about TW.states array logStates: false, // ...about TW.states array
logSelections: true logSelections: false
} }
......
...@@ -52,7 +52,7 @@ To use the API for the "topPapers" embedded search in ProjectExplorer, the corre ...@@ -52,7 +52,7 @@ To use the API for the "topPapers" embedded search in ProjectExplorer, the corre
- via the interface (side panel menu) - via the interface (side panel menu)
- or directly in settings_explorerjs.js: - or directly in settings_explorerjs.js:
``` ```
TWConf.relatedDocsType = "wosLocalDB" TWConf.relatedDocsType = "LocalDB" (CSV or CortextDB)
``` ```
Finally, to match the correct DB with the correct graph file: Finally, to match the correct DB with the correct graph file:
...@@ -64,7 +64,7 @@ Finally, to match the correct DB with the correct graph file: ...@@ -64,7 +64,7 @@ Finally, to match the correct DB with the correct graph file:
"title":"yourDocumentTitlesTable", "title":"yourDocumentTitlesTable",
"date":"yourDocumentPubDatesTable", "date":"yourDocumentPubDatesTable",
"abstract":"yourDocumentContentsTable", "abstract":"yourDocumentContentsTable",
"gexfs": { "graphs": {
"your.graph.gexf": { "your.graph.gexf": {
"semantic": { "table":"yourTableWithTerms"}, "semantic": { "table":"yourTableWithTerms"},
"social": { "table":"yourTableWithSocialNodes"} "social": { "table":"yourTableWithSocialNodes"}
......
...@@ -175,6 +175,7 @@ function SelectionEngine() { ...@@ -175,6 +175,7 @@ function SelectionEngine() {
var activetypesKey = getActivetypesKey() var activetypesKey = getActivetypesKey()
var activereltypes = TW.SystemState().activereltypes
// Dictionaries of: selection+neighbors for the new state and updateRelatedNodesPanel // Dictionaries of: selection+neighbors for the new state and updateRelatedNodesPanel
...@@ -182,7 +183,11 @@ function SelectionEngine() { ...@@ -182,7 +183,11 @@ function SelectionEngine() {
// detailed relations sorted by types and srcid (for state cache, deselects etc) // detailed relations sorted by types and srcid (for state cache, deselects etc)
let activeRelations = {} let activeRelations = {}
activeRelations[activetypesKey] = {}
for (var k in activereltypes) {
let activereltype = activereltypes[k]
activeRelations[activereltype] = {}
}
// cumulated neighbor weights no matter what srcid (for tagCloud etc) // cumulated neighbor weights no matter what srcid (for tagCloud etc)
let sameSideNeighbors = {} let sameSideNeighbors = {}
...@@ -197,59 +202,66 @@ function SelectionEngine() { ...@@ -197,59 +202,66 @@ function SelectionEngine() {
for(var i in ndsids) { for(var i in ndsids) {
var srcnid = ndsids[i]; var srcnid = ndsids[i];
if(TW.Relations[activetypesKey] && TW.Relations[activetypesKey][srcnid] ) {
var neighs = TW.Relations[activetypesKey][srcnid]
activeRelations[activetypesKey][srcnid] = {} for (var k in activereltypes) {
let activereltype = activereltypes[k]
if(neighs) { if(TW.Relations[activereltype] && TW.Relations[activereltype][srcnid] ) {
for(var j in neighs) { var neighs = TW.Relations[activereltype][srcnid]
var tgtnid = neighs[j]
let tgt = TW.partialGraph.graph.nodes(tgtnid) activeRelations[activereltype][srcnid] = {}
// highlight edges (except if n hidden or e dropped (<=> lock))
// POSS: use sigma's own index to avoid checking if edge dropped
if (tgt && !tgt.hidden) {
let eid1 = srcnid+';'+tgtnid if(neighs) {
let eid2 = tgtnid+';'+srcnid for(var j in neighs) {
var tgtnid = neighs[j]
if ( (TW.Edges[eid1] && !TW.Edges[eid1].lock) let tgt = TW.partialGraph.graph.nodes(tgtnid)
|| // highlight edges (except if n hidden or e dropped (<=> lock))
(TW.Edges[eid2] && !TW.Edges[eid2].lock) ) { // POSS: use sigma's own index to avoid checking if edge dropped
if (tgt && !tgt.hidden) {
let e1 = TW.partialGraph.graph.edges(eid1) let eid1 = srcnid+';'+tgtnid
let e2 = TW.partialGraph.graph.edges(eid2) let eid2 = tgtnid+';'+srcnid
// since we're there we'll also keep the neighbors info if ( (TW.Edges[eid1] && !TW.Edges[eid1].lock)
if (typeof sameSideNeighbors[tgtnid] == 'undefined') { ||
sameSideNeighbors[tgtnid]=0 (TW.Edges[eid2] && !TW.Edges[eid2].lock) ) {
}
// and the detailed info let e1 = TW.partialGraph.graph.edges(eid1)
if (typeof activeRelations[activetypesKey][srcnid][tgtnid] == 'undefined') { let e2 = TW.partialGraph.graph.edges(eid2)
activeRelations[activetypesKey][srcnid][tgtnid]=0
}
// **make the edge active** // since we're there we'll also keep the neighbors info
if (e1 && !e1.hidden) { if (typeof sameSideNeighbors[tgtnid] == 'undefined') {
e1.customAttrs.activeEdge = 1; sameSideNeighbors[tgtnid]=0
sameSideNeighbors[tgtnid] += e1.weight || 1 }
activeRelations[activetypesKey][srcnid][tgtnid] += e1.weight || 1
} // and the detailed info
if (e2 && !e2.hidden) { if (typeof activeRelations[activereltype][srcnid][tgtnid] == 'undefined') {
e2.customAttrs.activeEdge = 1; activeRelations[activereltype][srcnid][tgtnid]=0
sameSideNeighbors[tgtnid] += e2.weight || 1 }
activeRelations[activetypesKey][srcnid][tgtnid] += e2.weight || 1
} // **make the edge active**
if (e1 && !e1.hidden) {
e1.customAttrs.activeEdge = 1;
sameSideNeighbors[tgtnid] += e1.weight || 1
activeRelations[activereltype][srcnid][tgtnid] += e1.weight || 1
}
if (e2 && !e2.hidden) {
e2.customAttrs.activeEdge = 1;
sameSideNeighbors[tgtnid] += e2.weight || 1
activeRelations[activereltype][srcnid][tgtnid] += e2.weight || 1
}
// we add as neighbor to color it (except if already in targeted) // we add as neighbor to color it (except if already in targeted)
if (!tgt.customAttrs.active) tgt.customAttrs.highlight = 1; if (!tgt.customAttrs.active) tgt.customAttrs.highlight = 1;
}
} }
} }
} }
} }
} }
// we make the selected (source) node active too // we make the selected (source) node active too
let src = TW.partialGraph.graph.nodes(srcnid) let src = TW.partialGraph.graph.nodes(srcnid)
src.customAttrs.active = true; src.customAttrs.active = true;
...@@ -643,31 +655,22 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -643,31 +655,22 @@ var TinaWebJS = function ( sigmacanvas ) {
}); });
$("#changetype").click(function(){ $("#changetype").click(function(){
console.log("") console.log("changeTYPE click");
console.log(" ############ changeTYPE click");
if (TW.partialGraph.isForceAtlas2Running()) if (TW.partialGraph.isForceAtlas2Running())
sigma_utils.ourStopFA2(); sigma_utils.ourStopFA2();
console.log("DBG before changeType SystemState:", TW.SystemState())
changeType(); changeType();
setTimeout(function(){ setTimeout(function(){
$('.etabs a[href="#tabs1"]').trigger('click'); $('.etabs a[href="#tabs1"]').trigger('click');
},500) },500)
console.log(" ############ / changeTYPE click");
console.log("")
}); });
$("#changelevel").click(function(){ $("#changelevel").click(function(){
console.log("") console.log("changeLEVEL click");
console.log(" ############ changeLEVEL click");
if (TW.partialGraph.isForceAtlas2Running()) if (TW.partialGraph.isForceAtlas2Running())
sigma_utils.ourStopFA2(); sigma_utils.ourStopFA2();
changeLevel(); changeLevel();
console.log(" ############ / changeLEVEL click");
console.log("")
}); });
// sidepanel folding // sidepanel folding
...@@ -876,9 +879,9 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -876,9 +879,9 @@ var TinaWebJS = function ( sigmacanvas ) {
// to init local, instance-related listeners (need to run at new sigma instance) // to init local, instance-related listeners (need to run at new sigma instance)
// args: @partialGraph = a sigma instance // args: @partialGraph = a sigma instance
this.initSigmaListeners = function(partialGraph, initialActivetypes) { this.initSigmaListeners = function(partialGraph, initialActivetypes, initialActivereltypes) {
console.log("initSigmaListeners TW.categories", TW.categories) console.log("initSigmaListeners TW.categories / types array / reltypeskeys array: ", TW.categories, initialActivetypes, initialActivereltypes)
var selInst = this.selNgn var selInst = this.selNgn
...@@ -1075,18 +1078,28 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -1075,18 +1078,28 @@ var TinaWebJS = function ( sigmacanvas ) {
// the indice of the first cat to be active (ex: '1') // the indice of the first cat to be active (ex: '1')
let activeId = initialActivetypes.indexOf(true) let activeId = initialActivetypes.indexOf(true)
// args: for display: target div , for (let activeId in initialActivetypes) {
// for context: family/type prop value, if (initialActivetypes[activeId]) {
// for values: the property to filter // args: for display: target div ,
NodeWeightFilter ( `#slidercat${activeId}nodesweight` , // for context: family/type prop value,
TW.categories[activeId] // for values: the property to filter
); NodeWeightFilter ( `#slidercat${activeId}nodesweight` ,
TW.categories[activeId]
// ex: #slidercat1edgesweight );
EdgeWeightFilter(`#slidercat${activeId}edgesweight`, }
getActivetypesKey(), }
"weight"
); for (var k in initialActivereltypes) {
let reltypeKey = initialActivereltypes[k]
// ex: #slidercat1edgesweight
EdgeWeightFilter(`#slidercat${activeId}edgesweight`,
reltypeKey,
"weight"
);
}
} }
// node's label size // node's label size
...@@ -1170,14 +1183,39 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -1170,14 +1183,39 @@ var TinaWebJS = function ( sigmacanvas ) {
// our current choice: show only the last cat // our current choice: show only the last cat
// POSS make it a configuration settings // except when setting TW.conf.debug.initialShowAll
this.initialActivetypes = function( categories ) { this.initialActivetypes = function( categories ) {
var firstActivetypes = [] let firstActivetypes = []
for(var i=0; i<categories.length ; i++) { for(var i=0; i<categories.length ; i++) {
if(i==categories.length-1) firstActivetypes.push(true) if (TW.conf.debug.initialShowAll || i==categories.length-1) {
firstActivetypes.push(true)
}
else firstActivetypes.push(false) else firstActivetypes.push(false)
} }
return firstActivetypes; return firstActivetypes;
} }
// new business logic associating some activetypes to some activerels
// (it now allows multiple "relation-families" to be added as visible edges)
this.inferActivereltypes = function( nodeActivetypes ) {
let firstActivereltypes = []
// multiple nodetypes all true => all reltypes
if (TW.conf.debug.initialShowAll || nodeActivetypes.indexOf(false) == -1) {
let combinations = {}
if (TW.categories.length == 1) {
firstActivereltypes = ['1']
}
else if (TW.categories.length == 2) {
firstActivereltypes = ['0|1', '1|0', '1|1']
}
// POSSible: generalize if length > 1: recurse to generate all true/false combinations except the all-false one
}
// normal case: one activereltype, equal to the initialActivetype key
else {
firstActivereltypes = [nodeActivetypes.map(Number).join("|")]
}
return firstActivereltypes;
}
}; };
...@@ -275,7 +275,9 @@ function changeType() { ...@@ -275,7 +275,9 @@ function changeType() {
// new state is the complement of the received state ~[X\Y] // new state is the complement of the received state ~[X\Y]
var t1Activetypes = [] var t1Activetypes = []
for(var i in t0Activetypes) t1Activetypes[i] = !t0Activetypes[i] for(var i in t0Activetypes) t1Activetypes[i] = !t0Activetypes[i]
var t1ActivetypesKey = t1Activetypes.map(Number).join("|")
// apriori key
let t1ActivetypesKey = t1Activetypes.map(Number).join("|")
// "union realm" (where we'll search the real bipartite Relations) // "union realm" (where we'll search the real bipartite Relations)
var bipartiteKey = "1|1" var bipartiteKey = "1|1"
...@@ -288,7 +290,6 @@ function changeType() { ...@@ -288,7 +290,6 @@ function changeType() {
// so => we set here a fallback to "1|0" // so => we set here a fallback to "1|0"
if (t1ActivetypesKey == "0|0") { if (t1ActivetypesKey == "0|0") {
t1Activetypes = [true, false] t1Activetypes = [true, false]
t1ActivetypesKey = "1|0"
// this case "0|0" => "1|0" won't have a unique edge realm to look at // this case "0|0" => "1|0" won't have a unique edge realm to look at
// nodes of "1|0" will need their "1|0" neighbors // nodes of "1|0" will need their "1|0" neighbors
...@@ -299,6 +300,12 @@ function changeType() { ...@@ -299,6 +300,12 @@ function changeType() {
// special case: "macro level opens bipartite possibilities" // special case: "macro level opens bipartite possibilities"
if(!level) t1Activetypes = [true, true]; if(!level) t1Activetypes = [true, true];
// now that we have the future types, infer associated state representations
// let t1ActivetypesKey = t1Activetypes.map(Number).join("|")
let t1Activereltypes = TW.instance.inferActivereltypes(t1Activetypes)
console.log("activetypes:", t1ActivetypesKey)
console.log("activereltypes:", t1Activereltypes)
// list of present nodes: needed *before* clearing // list of present nodes: needed *before* clearing
// (but only needed if local and no selections) // (but only needed if local and no selections)
...@@ -324,12 +331,14 @@ function changeType() { ...@@ -324,12 +331,14 @@ function changeType() {
} }
} }
for(var eid in TW.Edges) { for(var eid in TW.Edges) {
for (var k in t1Activereltypes) {
if(TW.Edges[eid].categ==t1ActivetypesKey) let reltype = t1Activereltypes[k]
if(TW.Edges[eid].categ==reltype)
add1Elem(eid) add1Elem(eid)
}
// NB ie we don't add sameside edges "1|0" or "0|1" when target // NB ie we **do** add sameside edges "1|0" or "0|1" when target
// activetypes is "1|1" (aka "both") // activetypes is "1|1" (aka "both"), cf. inferActivereltypes
} }
sourceNodes = sels sourceNodes = sels
...@@ -361,8 +370,8 @@ function changeType() { ...@@ -361,8 +370,8 @@ function changeType() {
// [ ChangeType: incremental selection ;] // [ ChangeType: incremental selection ;]
// Dictionaries of: opposite-neighs of current source nodes // Dictionaries of: opposite-neighs of current source nodes
var newnodeset = {}
var newsels = {} var newsels = {}
var edgesToAdd = {}
for(var i in sourceNodes) { for(var i in sourceNodes) {
let srcnid = sourceNodes[i]; let srcnid = sourceNodes[i];
let srctyp = TW.Nodes[srcnid].type let srctyp = TW.Nodes[srcnid].type
...@@ -370,7 +379,17 @@ function changeType() { ...@@ -370,7 +379,17 @@ function changeType() {
if (!mixedStart) { if (!mixedStart) {
// case where we have an single kind of Relations to consider // case where we have an single kind of Relations to consider
// ie the realm of the bipartite relations called "1|1" // ie the realm of the bipartite relations called "1|1"
neighs = TW.Relations[bipartiteKey][srcnid]
for (var k in t1Activereltypes) {
let reltype = t1Activereltypes[k]
if (TW.Relations[reltype] && TW.Relations[reltype][srcnid])
neighs = neighs.concat(TW.Relations[reltype][srcnid])
}
console.log("=> neighs", neighs)
// neighs = TW.Relations[bipartiteKey][srcnid]
} }
else { else {
// case with a mixed starting point // case with a mixed starting point
...@@ -394,10 +413,9 @@ function changeType() { ...@@ -394,10 +413,9 @@ function changeType() {
if (t1Activetypes[TW.catDict[tgttyp]]) { if (t1Activetypes[TW.catDict[tgttyp]]) {
newsels[tgtnid]=true; newsels[tgtnid]=true;
// since we're here we keep the edges if needed // since we're here we keep in the new scope (nodeset) if local
if (!present.level) { if (!present.level) {
edgesToAdd[`${srcnid};${tgtnid}`] = true newnodeset[tgtnid] = true
edgesToAdd[`${tgtnid};${srcnid}`] = true
} }
} }
} }
...@@ -419,8 +437,23 @@ function changeType() { ...@@ -419,8 +437,23 @@ function changeType() {
for(var nid in newsels) { for(var nid in newsels) {
add1Elem(nid) add1Elem(nid)
} }
for(var eid in edgesToAdd) {
add1Elem(eid) // new loop on current scope to add sels edges and intra-neighbors edges
for(var srcnid in newnodeset) {
for(var tgtnid in newnodeset) {
let possEids = [`${srcnid};${tgtnid}`,`${tgtnid};${srcnid}`]
for (var l in possEids) {
let eid = possEids[l]
if (TW.Edges[eid]) {
let e = TW.Edges[eid]
for (var k in t1Activereltypes) {
let reltype = t1Activereltypes[k]
if (e.categ == reltype)
add1Elem(eid)
}
}
}
}
} }
} }
...@@ -430,6 +463,7 @@ function changeType() { ...@@ -430,6 +463,7 @@ function changeType() {
TW.pushState({ TW.pushState({
activetypes: t1Activetypes, activetypes: t1Activetypes,
activereltypes: t1Activereltypes,
sels: newselsArr, sels: newselsArr,
// rels: added by MS2 (highlighted opposite- and same-side neighbours) // rels: added by MS2 (highlighted opposite- and same-side neighbours)
// possible: add it in an early way here and request that MS2 doesn't change state // possible: add it in an early way here and request that MS2 doesn't change state
...@@ -491,6 +525,7 @@ function changeLevel() { ...@@ -491,6 +525,7 @@ function changeLevel() {
var activetypes = present.activetypes; var activetypes = present.activetypes;
var activetypesKey = activetypes.map(Number).join("|") var activetypesKey = activetypes.map(Number).join("|")
var activereltypes = present.activereltypes
TW.partialGraph.graph.clear(); TW.partialGraph.graph.clear();
...@@ -502,22 +537,26 @@ function changeLevel() { ...@@ -502,22 +537,26 @@ function changeLevel() {
for(var i in sels) { for(var i in sels) {
s = sels[i]; s = sels[i];
nodesToAdd[s]=true; nodesToAdd[s]=true;
if (TW.Relations[activetypesKey]) { for (var k in activereltypes) {
neigh = TW.Relations[activetypesKey][s] let activereltype = activereltypes[k]
if(neigh) { console.log("level: considering reltype ", activereltype)
for(var j in neigh) { if (TW.Relations[activereltype]) {
t = neigh[j] neigh = TW.Relations[activereltype][s]
nodesToAdd[t]=true; if(neigh) {
edgesToAdd[s+";"+t]=true; for(var j in neigh) {
edgesToAdd[t+";"+s]=true; t = neigh[j]
if( !selsChecker[t] ) nodesToAdd[t]=true;
voisinage[ t ] = true; edgesToAdd[s+";"+t]=true;
} edgesToAdd[t+";"+s]=true;
if( !selsChecker[t] )
voisinage[ t ] = true;
}
}
}
else {
// case where no edges at all (ex: scholars have no common keywords)
console.log("no edges between these nodes")
} }
}
else {
// case where no edges at all (ex: scholars have no common keywords)
console.log("no edges between these nodes")
} }
} }
...@@ -536,6 +575,7 @@ function changeLevel() { ...@@ -536,6 +575,7 @@ function changeLevel() {
if( voisinage[i]!=voisinage[j] ) { if( voisinage[i]!=voisinage[j] ) {
// console.log( "\t" + voisinage[i] + " vs " + voisinage[j] ) // console.log( "\t" + voisinage[i] + " vs " + voisinage[j] )
add1Elem( voisinage[i]+";"+voisinage[j] ) add1Elem( voisinage[i]+";"+voisinage[j] )
add1Elem( voisinage[j]+";"+voisinage[i] )
} }
} }
} }
...@@ -1040,8 +1080,8 @@ function createWaitIcon(idname, width) { ...@@ -1040,8 +1080,8 @@ function createWaitIcon(idname, width) {
} }
function jsActionOnGexfSelector(gexfBasename){ function jsActionOnGexfSelector(graphBasename){
let gexfPath = TW.gexfPaths[gexfBasename] || gexfBasename+".gexf" let graphPath = TW.gmenuPaths[graphBasename] || graphBasename+".gexf"
let serverPrefix = '' let serverPrefix = ''
var pathcomponents = window.location.pathname.split('/') var pathcomponents = window.location.pathname.split('/')
for (var i in pathcomponents) { for (var i in pathcomponents) {
...@@ -1049,13 +1089,21 @@ function jsActionOnGexfSelector(gexfBasename){ ...@@ -1049,13 +1089,21 @@ function jsActionOnGexfSelector(gexfBasename){
serverPrefix += '/'+pathcomponents[i] serverPrefix += '/'+pathcomponents[i]
} }
var newDataRes = AjaxSync({ "url": window.location.origin+serverPrefix+'/'+gexfPath }); var newDataRes = AjaxSync({ "url": window.location.origin+serverPrefix+'/'+graphPath });
// remove any previous instance and flags // remove any previous instance and flags
TW.resetGraph() TW.resetGraph()
// override default categories with the ones from db.json
if (TW.gmenuInfos[graphPath]) {
if (TW.gmenuInfos[graphPath].node0 && TW.gmenuInfos[graphPath].node0.name)
TW.conf.catSem = TW.gmenuInfos[graphPath].node0.name
if (TW.gmenuInfos[graphPath].node1 && TW.gmenuInfos[graphPath].node1.name)
TW.conf.catSem = TW.gmenuInfos[graphPath].node1.name
}
mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance) mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance)
writeLabel(gexfBasename) writeLabel(graphBasename)
TW.File = gexfPath TW.File = graphPath
} }
//============================= </OTHER ACTIONS > =============================// //============================= </OTHER ACTIONS > =============================//
...@@ -22,7 +22,7 @@ function changeGraphAppearanceByFacets(actypes) { ...@@ -22,7 +22,7 @@ function changeGraphAppearanceByFacets(actypes) {
let currentNbNodes = TW.partialGraph.graph.nNodes() let currentNbNodes = TW.partialGraph.graph.nNodes()
// create colormenu and 1st default entry // create colormenu and 1st default entry
var color_menu_info = '<li><a href="#" onclick="TW.gui.handpickedcolor = false ; graphResetLabelsAndSizes()">By Default</a></li>'; var color_menu_info = '<li><a href="#" onclick="TW.gui.handpickedcolor = false ; graphResetLabelsAndSizes() ; TW.partialGraph.refresh()">By Default</a></li>';
if( $( "#colorgraph-menu" ).length>0 ) { if( $( "#colorgraph-menu" ).length>0 ) {
for (var tid in actypes) { for (var tid in actypes) {
...@@ -404,6 +404,9 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -404,6 +404,9 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
if (isUndef(priorHtml)) priorHtml = '' if (isUndef(priorHtml)) priorHtml = ''
if (isUndef(cbNext)) cbNext = displayTopPapers if (isUndef(cbNext)) cbNext = displayTopPapers
// introducing the modern node type thanks to updated db.json specs
let nodetype = (swType == 'semantic') ? 0 : 1
let stockErrMsg = `<p class="micromessage"> let stockErrMsg = `<p class="micromessage">
Your settings for relatedDocsType are set on ${TW.conf.relatedDocsType} Your settings for relatedDocsType are set on ${TW.conf.relatedDocsType}
API but it couldn't be connected to.</p>` API but it couldn't be connected to.</p>`
...@@ -448,19 +451,18 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -448,19 +451,18 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
} }
}); });
} }
else if (TW.conf.relatedDocsType == "wosLocalDB") { else if (TW.conf.relatedDocsType == "LocalDB") {
let gexfinfos = TW.relDocsInfos[TW.File] let thisRelDocsConf = TW.gmenuInfos[TW.File][nodetype]
if (!gexfinfos || !gexfinfos[swType]) { if (!thisRelDocsConf) {
resHTML = resHTML =
`<p>Your settings for relatedDocsType are set on a local wos database, `<p>Your settings for relatedDocsType are set on a local database,
but your servermenu file does not provide any information about but your servermenu file does not provide any information about
the DB table to query for related documents the CSV or DB table to query for related documents
(on nodetype ${swType})</p>` (on nodetype ${nodetype}: ${swType})</p>`
cbNext(priorHtml + resHTML) cbNext(priorHtml + resHTML)
return return
} }
else { else {
// /!\ documentation and specification needed for the php use cases /!\ // /!\ documentation and specification needed for the php use cases /!\
let joinedQ = JSON.stringify(qWords).split('&').join('__and__'); let joinedQ = JSON.stringify(qWords).split('&').join('__and__');
// cf. the php code for these url args: // cf. the php code for these url args:
...@@ -469,23 +471,31 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -469,23 +471,31 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
// or 'csv' (like gargantext exports) // or 'csv' (like gargantext exports)
// POSS object + join.map(join) // POSS object + join.map(join)
let urlParams = "type="+swType+"&query="+joinedQ+"&gexf="+TW.File+"&n="+TW.conf.relatedDocsMax+"&dbtype="+gexfinfos.dbtype let urlParams = "type="+swType+"&query="+joinedQ+"&gexf="+TW.File+"&n="+TW.conf.relatedDocsMax+"&dbtype="+thisRelDocsConf.reldbtype
if (gexfinfos.dbtype == "sql") { if (thisRelDocsConf.reldbtype == "CortextDB") {
var qIndex = gexfinfos[swType] // a table var qIndex = thisRelDocsConf.reldbtable // a table
urlParams += `&index=${qIndex}` urlParams += `&index=${qIndex}`
} }
else { else {
// a list of csv columns to search in // a list of csv columns to search in
// ex: for semantic nodes matching we look in 'title', 'keywords' cols // ex: for semantic nodes matching we look in 'title', 'keywords' cols
// for social nodes matching we look in 'authors' col... etc. // for social nodes matching we look in 'authors' col... etc.
let joinedSearchCols = JSON.stringify(gexfinfos[swType]) let joinedSearchCols = JSON.stringify(thisRelDocsConf.reldbqcols)
urlParams += `&searchin=${joinedSearchCols}` urlParams += `&searchin=${joinedSearchCols}`
let joinedAllCols = JSON.stringify(gexfinfos) // HIGHER LEVEL SCOPE (whole indexation directive) WILL BE MOVED TO PHP
let allCols = {}
if (TW.gmenuInfos[TW.File][0])
allCols.semantic = TW.gmenuInfos[TW.File][0].reldbqcols
if (TW.gmenuInfos[TW.File][1])
allCols.social = TW.gmenuInfos[TW.File][1].reldbqcols
let joinedAllCols = JSON.stringify(allCols)
urlParams += `&toindex=${joinedAllCols}` urlParams += `&toindex=${joinedAllCols}`
// POSS use a direct access from php to db.json to avoid toindex // POSS use a direct access from php to db.json to avoid toindex
// POSS make it a REST array like: index[]=title&index[]=keywords
} }
$.ajax({ $.ajax({
...@@ -502,12 +512,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -502,12 +512,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
cbNext(priorHtml + stockErrMsg) cbNext(priorHtml + stockErrMsg)
} }
}); });
} }
} }
} }
......
...@@ -12,18 +12,19 @@ TW.File = "" // remember the currently opened file ...@@ -12,18 +12,19 @@ TW.File = "" // remember the currently opened file
TW.partialGraph = null // will contain the sigma visible graph instance TW.partialGraph = null // will contain the sigma visible graph instance
TW.labels=[]; // fulltext search list TW.labels=[]; // fulltext search list
TW.gexfPaths={}; // for file selectors iff servermenu
TW.relDocsInfos={}; // map [graphsource => relatedDocs db fields or tables names]
// TODO requires specifications !!
// (iff servermenu && relatedDocsType == 'wosLocalDB')
TW.categories = []; // possible node types and their inverted map TW.categories = []; // possible node types and their inverted map
TW.catDict = {}; TW.catDict = {};
// used iff servermenu
TW.gmenuPaths={}; // map [graphname => graphsource] for file selectors
TW.gmenuInfos={}; // map [graphsource => { node0/1 categories
// + relatedDocs db fields names}]
// a system state is the summary of tina situation // a system state is the summary of tina situation
TW.initialSystemState = { TW.initialSystemState = {
activetypes: [], // <== filled from TW.categories activetypes: [], // <== filled from TW.categories
activereltypes: [], // <== same for edges
level: true, level: true,
selectionNids: [], // <== current selection !! selectionNids: [], // <== current selection !!
selectionRels: [], // <== current highlighted neighbors selectionRels: [], // <== current highlighted neighbors
...@@ -259,58 +260,40 @@ function syncRemoteGraphData () { ...@@ -259,58 +260,40 @@ function syncRemoteGraphData () {
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 theGexfs = preRES.data[path]["gexfs"] var theGraphs = preRES.data[path]["graphs"]
for(var aGexf in theGexfs) { for(var aGraph in theGraphs) {
var gexfBasename = aGexf.replace(/\.gexf$/, "") // more human-readable in the menu var graphBasename = aGraph.replace(/\.gexf$/, "") // more human-readable in the menu
TW.gexfPaths[gexfBasename] = path+"/"+aGexf TW.gmenuPaths[graphBasename] = path+"/"+aGraph
// 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.conf.debug.logFetchers) if (TW.conf.debug.logFetchers)
console.log("\t\t\t"+gexfBasename) console.log("\t\t\t"+graphBasename)
// for associated wosLocalDBs sql queries
if (theGexfs[aGexf]) {
let gSrcEntry = theGexfs[aGexf]
TW.relDocsInfos[path+"/"+aGexf] = {"semantic":null, "social":null, "dbtype": null} // for associated LocalDB php queries: CSV (or CortextDBs sql)
if (theGraphs[aGraph]) {
// POSS have this type attribute in db.json *for all the entries* let gSrcEntry = theGraphs[aGraph]
// ---------------------------------------------------------------------------------- TW.gmenuInfos[path+"/"+aGraph] = new Array(2)
// choice: we'll keep a flat structure by source unless some use cases need otherwise
// ----------------------------------------------------------------------------------
// csv LocalDB ~ gargantext
if(gSrcEntry["dbtype"] && gSrcEntry["dbtype"] == "csv") {
TW.relDocsInfos[path+"/"+aGexf]['dbtype'] = "csv"
// it's CSV columns here if (gSrcEntry.node0) {
TW.relDocsInfos[path+"/"+aGexf]['semantic'] = gSrcEntry["semantic"] TW.gmenuInfos[path+"/"+aGraph][0] = gSrcEntry.node0
TW.relDocsInfos[path+"/"+aGexf]['social'] = gSrcEntry["social"]
} }
if (gSrcEntry.node1) {
// sqlite LocalDB ~ wos TW.gmenuInfos[path+"/"+aGraph][0] = gSrcEntry.node0
else {
TW.relDocsInfos[path+"/"+aGexf]['dbtype'] = "sql"
if (theGexfs[aGexf]["semantic"] && theGexfs[aGexf]["semantic"]["table"]) {
TW.relDocsInfos[path+"/"+aGexf]['semantic'] = theGexfs[aGexf]["semantic"]["table"]
}
if (theGexfs[aGexf]["social"] && theGexfs[aGexf]["social"]["table"]) {
TW.relDocsInfos[path+"/"+aGexf]['social'] = theGexfs[aGexf]["social"]["table"]
}
} }
} }
else { else {
TW.relDocsInfos[path+"/"+aGexf] = null TW.gmenuInfos[path+"/"+aGraph] = null
} }
// ^^^^^^ FIXME see if we got the expected behavior right // ^^^^^^ FIXME finish implementing new specifications
// (? specifications ?)
let cssFileSelected = (TW.File==(path+"/"+aGexf))?"selected":"" let cssFileSelected = (TW.File==(path+"/"+aGraph))?"selected":""
files_selector += '<option '+cssFileSelected+'>'+gexfBasename+'</option>' files_selector += '<option '+cssFileSelected+'>'+graphBasename+'</option>'
} }
// console.log( files_selector ) // console.log( files_selector )
} }
...@@ -384,6 +367,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -384,6 +367,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
// activetypes: the node categorie(s) that is (are) currently displayed // activetypes: the node categorie(s) that is (are) currently displayed
// ex: [true,false] = [nodes of type 0 shown ; nodes of type 1 not drawn] // ex: [true,false] = [nodes of type 0 shown ; nodes of type 1 not drawn]
var initialActivetypes = TW.instance.initialActivetypes( TW.categories ) var initialActivetypes = TW.instance.initialActivetypes( TW.categories )
var initialActivereltypes = TW.instance.inferActivereltypes( initialActivetypes )
// 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
...@@ -424,7 +408,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -424,7 +408,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
// preparing the data (TW.Nodes and TW.Edges filtered by initial type) // preparing the data (TW.Nodes and TW.Edges filtered by initial type)
// POSS: avoid this step and use the filters at rendering time! // POSS: avoid this step and use the filters at rendering time!
TW.graphData = {nodes: [], edges: []} TW.graphData = {nodes: [], edges: []}
TW.graphData = sigma_utils.FillGraph( initialActivetypes , TW.catDict , TW.Nodes , TW.Edges , TW.graphData ); TW.graphData = sigma_utils.FillGraph( initialActivetypes , initialActivereltypes, TW.catDict , TW.Nodes , TW.Edges , TW.graphData );
// // ----------- TEST stock parse gexf and use nodes to replace TW's --------- // // ----------- TEST stock parse gexf and use nodes to replace TW's ---------
...@@ -514,7 +498,10 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -514,7 +498,10 @@ function mainStartGraph(inFormat, inData, twInstance) {
// ================================================================== // ==================================================================
// a new state // a new state
TW.pushState({'activetypes': initialActivetypes}) TW.pushState({
'activetypes': initialActivetypes,
'activereltypes': initialActivereltypes
})
// NB the list of nodes and edges from TW.graphData will be changed // NB the list of nodes and edges from TW.graphData will be changed
// by changeLevel, changeType or subset sliders => no need to keep it // by changeLevel, changeType or subset sliders => no need to keep it
...@@ -528,7 +515,11 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -528,7 +515,11 @@ function mainStartGraph(inFormat, inData, twInstance) {
// renderer position depend on viewpoint/zoom (like ~ html absolute positions of the node in the div) // renderer position depend on viewpoint/zoom (like ~ html absolute positions of the node in the div)
// now that we have a sigma instance, let's bind our click handlers to it // now that we have a sigma instance, let's bind our click handlers to it
TW.instance.initSigmaListeners(TW.partialGraph, initialActivetypes) TW.instance.initSigmaListeners(
TW.partialGraph,
initialActivetypes, // to init node sliders and .class gui elements
initialActivereltypes // to init edge sliders
)
// [ / Poblating the Sigma-Graph ] // [ / Poblating the Sigma-Graph ]
......
...@@ -19,9 +19,10 @@ TW.pushState = function( args ) { ...@@ -19,9 +19,10 @@ TW.pushState = function( args ) {
newState.id ++ newState.id ++
// 2) we update it with provided args // 2) we update it with provided args
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.level)) newState.level = args.level; if (!isUndef(args.activereltypes)) newState.activereltypes = args.activereltypes
if (!isUndef(args.sels)) newState.selectionNids = args.sels; if (!isUndef(args.level)) newState.level = args.level;
if (!isUndef(args.sels)) newState.selectionNids = args.sels;
// neighbors (of any type) and their edges in an .selectionRels[type] slot // neighbors (of any type) and their edges in an .selectionRels[type] slot
if(!isUndef(args.rels)) newState.selectionRels = args.rels; if(!isUndef(args.rels)) newState.selectionRels = args.rels;
...@@ -72,9 +73,10 @@ TW.pushState = function( args ) { ...@@ -72,9 +73,10 @@ TW.pushState = function( args ) {
NodeWeightFilter( "#slidercat0nodesweight" , TW.categories[0]); NodeWeightFilter( "#slidercat0nodesweight" , TW.categories[0]);
NodeWeightFilter( "#slidercat1nodesweight" , TW.categories[1]); NodeWeightFilter( "#slidercat1nodesweight" , TW.categories[1]);
// only truly bipartite edges => only one GUI slider // one slider for each intra-type reltype
showDisabledSlider("#slidercat0edgesweight") EdgeWeightFilter("#slidercat0edgesweight", "1|0", "weight");
EdgeWeightFilter("#slidercat1edgesweight", "1|1", "weight"); EdgeWeightFilter("#slidercat1edgesweight", "0|1", "weight");
// NB: no slider for truly bipartite edges => 2 GUI sliders but 3 edge types
} }
} }
......
...@@ -3,19 +3,25 @@ ...@@ -3,19 +3,25 @@
var SigmaUtils = function () { var SigmaUtils = function () {
// input = GEXFstring // input = GEXFstring
this.FillGraph = function( initialActivetypes , catDict , nodes, edges , graph ) { this.FillGraph = function( initialActivetypes , initialActivereltypes, catDict , nodes, edges , graph ) {
console.log("Filling the graaaaph:") console.log("Filling the graaaaph:")
console.log("FillGraph catDict",catDict) console.log("FillGraph catDict",catDict)
// console.log("FillGraph nodes",nodes) // console.log("FillGraph nodes",nodes)
// console.log("FillGraph edges",edges) // console.log("FillGraph edges",edges)
// retrocompatibility -------------------------------- 8< -------------
if (!initialActivereltypes.length) {
initialActivereltypes = [initialActivetypes.map(Number).join("|")]
}
// ---------------------------------------------------- 8< -------------
let i = 0 let i = 0
for(var nid in nodes) { for(var nid in nodes) {
var n = nodes[nid]; var n = nodes[nid];
// console.debug('tr >>> fgr node', n) // console.debug('tr >>> fgr node', n)
if(initialActivetypes[catDict[n.type]] || TW.conf.debug.initialShowAll) { if(initialActivetypes[catDict[n.type]]) {
// var node = { // var node = {
// id : n.id, // id : n.id,
// label : n.label, // label : n.label,
...@@ -43,20 +49,20 @@ var SigmaUtils = function () { ...@@ -43,20 +49,20 @@ var SigmaUtils = function () {
} }
} }
// the typestrings in activereltypes are the key to stored Relations (<=> edges)
// the typestring of the activetypes is the key to stored Relations (<=> edges) for (var k in initialActivereltypes) {
var activetypesKey = initialActivetypes.map(Number).join("|") let reltype = initialActivereltypes[k]
for(let srcnid in TW.Relations[reltype]) {
for(let srcnid in TW.Relations[activetypesKey]) { for(var j in TW.Relations[reltype][srcnid]) {
for(var j in TW.Relations[activetypesKey][srcnid]) { let tgtnid = TW.Relations[reltype][srcnid][j]
let tgtnid = TW.Relations[activetypesKey][srcnid][j] let e = TW.Edges[srcnid+";"+tgtnid]
let e = TW.Edges[srcnid+";"+tgtnid] if(e) {
if(e) { if(e.source != e.target) {
if(e.source != e.target) { graph.edges.push( e);
graph.edges.push( e); }
} }
} }
} }
} }
return graph; return graph;
}// output = sigma graph }// output = sigma graph
...@@ -665,7 +671,6 @@ function edgeInfos(anEdge) { ...@@ -665,7 +671,6 @@ function edgeInfos(anEdge) {
function gradientColoring(daclass) { function gradientColoring(daclass) {
cancelSelection(false); // loops only on selected
graphResetLabelsAndSizes() // full loop graphResetLabelsAndSizes() // full loop
TW.gui.handpickedcolor = true TW.gui.handpickedcolor = true
...@@ -853,7 +858,6 @@ function heatmapColoring(daclass) { ...@@ -853,7 +858,6 @@ function heatmapColoring(daclass) {
binColors = getHeatmapColors(nColors) binColors = getHeatmapColors(nColors)
// let's go // let's go
cancelSelection(false); // loops only on selected
graphResetLabelsAndSizes() // full loop graphResetLabelsAndSizes() // full loop
// global flag // global flag
...@@ -909,9 +913,6 @@ function heatmapColoring(daclass) { ...@@ -909,9 +913,6 @@ function heatmapColoring(daclass) {
function clusterColoring(daclass) { function clusterColoring(daclass) {
console.log("clusterColoring ( "+daclass+" )")
cancelSelection(false); // now loops only on selected
graphResetLabelsAndSizes() // full loop graphResetLabelsAndSizes() // full loop
// louvain needs preparation // louvain needs preparation
......
...@@ -37,12 +37,12 @@ TW.conf = (function(TW){ ...@@ -37,12 +37,12 @@ TW.conf = (function(TW){
TWConf.getRelatedDocs = false TWConf.getRelatedDocs = false
TWConf.relatedDocsMax = 10 TWConf.relatedDocsMax = 10
TWConf.relatedDocsType = "twitter" // accepted: "twitter" | "wosLocalDB" TWConf.relatedDocsType = "twitter" // accepted: "twitter" | "LocalDB"
// POSSible: "elastic" // POSSible: "elastic"
TWConf.relatedDocsAPIS = { TWConf.relatedDocsAPIS = {
// routes by corresponding type // routes by corresponding type
"wosLocalDB": "twbackends/phpAPI", "LocalDB": "twbackends/phpAPI",
"twitter": "http://127.0.0.1:5000/twitter_search" "twitter": "http://127.0.0.1:5000/twitter_search"
} }
......
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