Commit 086db2d8 authored by Romain Loth's avatar Romain Loth

WIP edgetypes: first quick working version (unoptimized)

parent 039ff7ad
This diff is collapsed.
......@@ -275,7 +275,9 @@ function changeType() {
// new state is the complement of the received state ~[X\Y]
var t1Activetypes = []
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)
var bipartiteKey = "1|1"
......@@ -288,7 +290,6 @@ function changeType() {
// so => we set here a fallback to "1|0"
if (t1ActivetypesKey == "0|0") {
t1Activetypes = [true, false]
t1ActivetypesKey = "1|0"
// 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
......@@ -299,6 +300,12 @@ function changeType() {
// special case: "macro level opens bipartite possibilities"
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
// (but only needed if local and no selections)
......@@ -324,12 +331,14 @@ function changeType() {
}
}
for(var eid in TW.Edges) {
if(TW.Edges[eid].categ==t1ActivetypesKey)
for (var k in t1Activereltypes) {
let reltype = t1Activereltypes[k]
if(TW.Edges[eid].categ==reltype)
add1Elem(eid)
}
// NB ie we don't add sameside edges "1|0" or "0|1" when target
// activetypes is "1|1" (aka "both")
// NB ie we **do** add sameside edges "1|0" or "0|1" when target
// activetypes is "1|1" (aka "both"), cf. inferActivereltypes
}
sourceNodes = sels
......@@ -361,8 +370,8 @@ function changeType() {
// [ ChangeType: incremental selection ;]
// Dictionaries of: opposite-neighs of current source nodes
var newnodeset = {}
var newsels = {}
var edgesToAdd = {}
for(var i in sourceNodes) {
let srcnid = sourceNodes[i];
let srctyp = TW.Nodes[srcnid].type
......@@ -370,7 +379,17 @@ function changeType() {
if (!mixedStart) {
// case where we have an single kind of Relations to consider
// 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 {
// case with a mixed starting point
......@@ -394,10 +413,9 @@ function changeType() {
if (t1Activetypes[TW.catDict[tgttyp]]) {
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) {
edgesToAdd[`${srcnid};${tgtnid}`] = true
edgesToAdd[`${tgtnid};${srcnid}`] = true
newnodeset[tgtnid] = true
}
}
}
......@@ -419,8 +437,23 @@ function changeType() {
for(var nid in newsels) {
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() {
TW.pushState({
activetypes: t1Activetypes,
activereltypes: t1Activereltypes,
sels: newselsArr,
// 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
......@@ -491,6 +525,7 @@ function changeLevel() {
var activetypes = present.activetypes;
var activetypesKey = activetypes.map(Number).join("|")
var activereltypes = present.activereltypes
TW.partialGraph.graph.clear();
......@@ -502,22 +537,26 @@ function changeLevel() {
for(var i in sels) {
s = sels[i];
nodesToAdd[s]=true;
if (TW.Relations[activetypesKey]) {
neigh = TW.Relations[activetypesKey][s]
if(neigh) {
for(var j in neigh) {
t = neigh[j]
nodesToAdd[t]=true;
edgesToAdd[s+";"+t]=true;
edgesToAdd[t+";"+s]=true;
if( !selsChecker[t] )
voisinage[ t ] = true;
}
for (var k in activereltypes) {
let activereltype = activereltypes[k]
console.log("level: considering reltype ", activereltype)
if (TW.Relations[activereltype]) {
neigh = TW.Relations[activereltype][s]
if(neigh) {
for(var j in neigh) {
t = neigh[j]
nodesToAdd[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() {
if( voisinage[i]!=voisinage[j] ) {
// console.log( "\t" + voisinage[i] + " vs " + voisinage[j] )
add1Elem( voisinage[i]+";"+voisinage[j] )
add1Elem( voisinage[j]+";"+voisinage[i] )
}
}
}
......
......@@ -24,6 +24,7 @@ TW.gmenuInfos={}; // map [graphsource => { node0/1 categories
// a system state is the summary of tina situation
TW.initialSystemState = {
activetypes: [], // <== filled from TW.categories
activereltypes: [], // <== same for edges
level: true,
selectionNids: [], // <== current selection !!
selectionRels: [], // <== current highlighted neighbors
......@@ -366,6 +367,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
// activetypes: the node categorie(s) that is (are) currently displayed
// ex: [true,false] = [nodes of type 0 shown ; nodes of type 1 not drawn]
var initialActivetypes = TW.instance.initialActivetypes( TW.categories )
var initialActivereltypes = TW.instance.inferActivereltypes( initialActivetypes )
// XML parsing from ParseCustom
var dicts = start.makeDicts(TW.categories); // > parse json or gexf, dictfy
......@@ -406,7 +408,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
// preparing the data (TW.Nodes and TW.Edges filtered by initial type)
// POSS: avoid this step and use the filters at rendering time!
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 ---------
......@@ -496,7 +498,10 @@ function mainStartGraph(inFormat, inData, twInstance) {
// ==================================================================
// 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
// by changeLevel, changeType or subset sliders => no need to keep it
......@@ -510,7 +515,11 @@ function mainStartGraph(inFormat, inData, twInstance) {
// 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
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 ]
......
......@@ -19,9 +19,10 @@ TW.pushState = function( args ) {
newState.id ++
// 2) we update it with provided args
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.level)) newState.level = args.level;
if (!isUndef(args.sels)) newState.selectionNids = args.sels;
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.activereltypes)) newState.activereltypes = args.activereltypes
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
if(!isUndef(args.rels)) newState.selectionRels = args.rels;
......@@ -72,9 +73,10 @@ TW.pushState = function( args ) {
NodeWeightFilter( "#slidercat0nodesweight" , TW.categories[0]);
NodeWeightFilter( "#slidercat1nodesweight" , TW.categories[1]);
// only truly bipartite edges => only one GUI slider
showDisabledSlider("#slidercat0edgesweight")
EdgeWeightFilter("#slidercat1edgesweight", "1|1", "weight");
// one slider for each intra-type reltype
EdgeWeightFilter("#slidercat0edgesweight", "1|0", "weight");
EdgeWeightFilter("#slidercat1edgesweight", "0|1", "weight");
// NB: no slider for truly bipartite edges => 2 GUI sliders but 3 edge types
}
}
......
......@@ -3,19 +3,25 @@
var SigmaUtils = function () {
// 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("FillGraph catDict",catDict)
// console.log("FillGraph nodes",nodes)
// console.log("FillGraph edges",edges)
// retrocompatibility -------------------------------- 8< -------------
if (!initialActivereltypes.length) {
initialActivereltypes = [initialActivetypes.map(Number).join("|")]
}
// ---------------------------------------------------- 8< -------------
let i = 0
for(var nid in nodes) {
var n = nodes[nid];
// console.debug('tr >>> fgr node', n)
if(initialActivetypes[catDict[n.type]] || TW.conf.debug.initialShowAll) {
if(initialActivetypes[catDict[n.type]]) {
// var node = {
// id : n.id,
// label : n.label,
......@@ -43,20 +49,20 @@ var SigmaUtils = function () {
}
}
// the typestring of the activetypes is the key to stored Relations (<=> edges)
var activetypesKey = initialActivetypes.map(Number).join("|")
for(let srcnid in TW.Relations[activetypesKey]) {
for(var j in TW.Relations[activetypesKey][srcnid]) {
let tgtnid = TW.Relations[activetypesKey][srcnid][j]
let e = TW.Edges[srcnid+";"+tgtnid]
if(e) {
if(e.source != e.target) {
graph.edges.push( e);
}
}
}
// the typestrings in activereltypes are the key to stored Relations (<=> edges)
for (var k in initialActivereltypes) {
let reltype = initialActivereltypes[k]
for(let srcnid in TW.Relations[reltype]) {
for(var j in TW.Relations[reltype][srcnid]) {
let tgtnid = TW.Relations[reltype][srcnid][j]
let e = TW.Edges[srcnid+";"+tgtnid]
if(e) {
if(e.source != e.target) {
graph.edges.push( e);
}
}
}
}
}
return graph;
}// output = sigma graph
......
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