Commit 5e6cc941 authored by Romain Loth's avatar Romain Loth

use SystemState to store global selections

global var selections removed and stored inside SystemState + transformed into an array everywhere (was inconsistent) + fixed changeType selection materialization ; possible TODOES: better setState function, possible integration of opposite side neighbors in SystemState too
parent 846d1d9f
......@@ -505,33 +505,6 @@ function RenderTweet( tweet) {
return html;
}
//FOR UNI-PARTITE
// function selectionUni(currentNode){
// console.log("\tin selectionUni:"+currentNode.id);
// if(TW.gui.checkBox==false && TW.gui.circleSize==0) {
// highlightSelectedNodes(false);
// opossites = [];
// selections = [];
// }
//
// if((typeof selections[currentNode.id])=="undefined"){
// selections[currentNode.id] = 1;
// currentNode.active=true;
// }
// else {
// delete selections[currentNode.id];
// currentNode.active=false;
// }
// //highlightOpossites(nodes1[currentNode.id].neighbours);
// // currentNode.color = currentNode.customAttrs['true_color'];
// // currentNode.customAttrs['grey'] = 0;
// //
// //
//
//
// TW.partialGraph.zoomTo(TW.partialGraph._core.width / 2, TW.partialGraph._core.height / 2, 0.8);
// TW.partialGraph.render();
// }
//JUST ADEME
function camaraButton(){
......
......@@ -6,20 +6,19 @@ function SelectionEngine() {
// creates the union of prevsels and currsels, if addvalue
this.SelectorEngine = function( args ) {
console.log("addvalue, prevsels, currsels", args)
// console.log("addvalue, prevsels, currsels", args)
if (!args) args = {}
if (!args.addvalue) args.addvalue = false
if (!args.prevsels) args.prevsels = {} // FIXME easier with array like currsels.concat(buffer)
if (!args.prevsels) args.prevsels = []
if (!args.currsels) args.currsels = []
var targeted = []
var buffer = Object.keys(args.prevsels);
// currsels = bunch of nodes from a click in the map
if(args.addvalue) {
// FOR SIMPLE UNIQUE UNION
targeted = args.currsels.concat(buffer.filter(function (item) {
targeted = args.currsels.concat(args.prevsels.filter(function (item) {
return args.currsels.indexOf(item) < 0;
}));
} else targeted = args.currsels;
......@@ -27,34 +26,34 @@ function SelectionEngine() {
if(targeted.length==0) return [];
// ------------ FOR SETWISE COMPLEMENT ---------------------->8---------
// if(buffer.length>0) {
// if(JSON.stringify(buffer)==JSON.stringify(targeted)) {
// if(args.prevsels.length>0) {
// if(JSON.stringify(args.prevsels)==JSON.stringify(targeted)) {
// // this is just effective for Add[ ] ...
// // If previous selection is equal to the current one, you've nothing :D
// cancelSelection(false);
// return [];
// }
// var inter = this.intersect_safe(buffer,targeted)
// var inter = this.intersect_safe(args.prevsels,targeted)
// if(inter.length>0) {
// var blacklist = {} , whitelist = {};
// for(var k in inter) blacklist[inter[k]]=true;
// for(var k in buffer){
// let n = buffer[k]
// if(!blacklist[n]) {
// whitelist[n] = true;
// for(var k in args.prevsels){
// let nid = args.prevsels[k]
// if(!blacklist[nid]) {
// whitelist[nid] = true;
// }
// }
// for(var k in targeted){
// let n = targeted[k]
// if(!blacklist[n]) {
// whitelist[n] = true;
// let nid = targeted[k]
// if(!blacklist[nid]) {
// whitelist[nid] = true;
// }
// }
// targeted = Object.keys(whitelist);
// } else {// inter = 0 ==> click in other portion of the graph (!= current selection)
// // Union!
// if(args.addvalue) {
// targeted = currsels.concat(buffer.filter(function (item) {
// targeted = currsels.concat(args.prevsels.filter(function (item) {
// return currsels.indexOf(item) < 0;
// }));
// }
......@@ -70,7 +69,7 @@ function SelectionEngine() {
// we assume string is normalized
this.search_n_select = function(string) {
let previousSelections = selections
let previousSelections = TW.SystemState.selectionNids
cancelSelection(false, {norender:true});
......@@ -189,7 +188,7 @@ function SelectionEngine() {
var nodes_2_colour = args.nodesDict
var edges_2_colour = args.edgesDict
selections = {}
let selections = {}
// targeted arg 'nodes' can be nid array or single nid
......@@ -239,12 +238,12 @@ function SelectionEngine() {
// we make the selected (source) node active too
nodes_2_colour[s]=true;
// update GLOBAL selections dict
// (FIXME it's widely used but TW.SystemStates.selections has the same)
// update local selections dict
selections[ndsids[i]]=1;
}
}
// FIXME: could be done in previous loop
for(var nid in nodes_2_colour) {
if(nid) {
n = TW.partialGraph.graph.nodes(nid)
......@@ -255,7 +254,6 @@ function SelectionEngine() {
// it's a selected node
if(nodes_2_colour[nid]) {
n.active = true;
// selections[nid]=1
}
// it's a neighbor
else {
......@@ -279,30 +277,32 @@ function SelectionEngine() {
// show the button to remove selection
$("#unselectbutton").show() ;
var the_new_sels = Object.keys(selections)
if (the_new_sels.length && the_new_sels[0] == 'NaN') {
// £TODO: all this should be done in one line via TW.setState or ref
TW.SystemState.selectionNids = Object.keys(selections)
TW.states.slice(-1)[0].selectionNids = TW.SystemState.selectionNids;
TW.setState( { sels: TW.SystemState.selectionNids} )
if (TW.SystemState.selectionNids.length
&& TW.SystemState.selectionNids[0] == 'NaN') {
console.error("NaN selection key error")
}
TW.states.slice(-1)[0].selections = the_new_sels;
TW.setState( { sels: the_new_sels} )
// alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(the_new_sels))
// alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(TW.SystemState.selectionNids))
// we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection)
$('#searchinput').trigger({
type: "tw:gotNodeSet",
q: $("#searchinput").val(),
nodeIds: the_new_sels
nodeIds: TW.SystemState.selectionNids
});
// console.log("Event [gotNodeSet] sent from Tinaweb MultipleSelection2")
// neighbors of the opposite type
if(TW.Relations["1|1"]) {
for(var s in the_new_sels) {
var bipaNeighs = TW.Relations["1|1"][the_new_sels[s]];
for(var s in TW.SystemState.selectionNids) {
var bipaNeighs = TW.Relations["1|1"][TW.SystemState.selectionNids[s]];
for(var n in bipaNeighs) {
if (typeof oppositeSideNeighbors[bipaNeighs[n]] == "undefined")
......@@ -314,16 +314,8 @@ function SelectionEngine() {
}
}
// debug
// var neiLabls = []
// for (var neiId in sameSideNeighbors) {
// neiLabls.push(TW.Nodes[neiId].label)
// }
// console.log('sameSideNeighbors labels', neiLabls)
// NB doesn't only sort by value but also
// rewrites dict[id]: val
// as array[order]: {key:id, value:val}
// Sort by descending value
// and rewrites dict[id]: val as array[order]: {key:id, value:val}
var oppos = ArraySortByValue(oppositeSideNeighbors, function(a,b){
return b-a
});
......@@ -332,7 +324,7 @@ function SelectionEngine() {
});
if (TW.conf.debug.logSelections) {
console.debug('selections', selections)
console.debug('TW.SystemState.selectionNids', TW.SystemState.selectionNids)
console.debug('oppos', oppos)
console.debug('same', same)
}
......@@ -342,15 +334,12 @@ function SelectionEngine() {
TW.partialGraph.render();
updateRelatedNodesPanel( selections , same, oppos );
updateRelatedNodesPanel( TW.SystemState.selectionNids , same, oppos )
if (TW.conf.debug.logSelections) {
var tMS2_fin = performance.now()
console.log("end MultipleSelection2, own time:", tMS2_fin-tMS2_deb)
}
}
};
......@@ -838,16 +827,17 @@ var TinaWebJS = function ( sigmacanvas ) {
camCoords.y
)
// 1) clear previous while keeping its list (useful iff 'Add' TW.gui.checkBox)
var previousSelection = selections
cancelSelection(false)
// 2) show selection + do all related effects
// 1) determine new selection
var targeted = selInst.SelectorEngine( {
addvalue:TW.gui.checkBox,
currsels:circleNodes,
prevsels:previousSelection
prevsels:TW.SystemState.selectionNids
} )
// 2) clear previous selection
cancelSelection(false)
// 3) show new selection + do all related effects
if(targeted.length>0) {
selInst.MultipleSelection2( {nodes:targeted} )
}
......@@ -862,16 +852,16 @@ var TinaWebJS = function ( sigmacanvas ) {
// new sigma.js gives easy access to clicked node!
var theNodeId = e.data.node.id
// we keep the global selections and then clear it and all its effects
var previousSelection = selections
cancelSelection(false, {norender:true}); // no need to render before MS2
if (TW.gui.circleSize == 0) {
// 1)
var targeted = selInst.SelectorEngine( {
addvalue:TW.gui.checkBox,
currsels:[theNodeId],
prevsels:previousSelection
prevsels: TW.SystemState.selectionNids
} )
// 2)
cancelSelection(false, {norender:true}); // no need to render before MS2
// 3)
if(targeted.length>0) {
selInst.MultipleSelection2( {nodes:targeted} )
}
......@@ -887,7 +877,7 @@ var TinaWebJS = function ( sigmacanvas ) {
// console.log("clickStage event e", e)
if (! e.data.captor.isDragging
&& Object.keys(selections).length
&& TW.SystemState.selectionNids.length
&& ! TW.gui.circleSize) {
// we clear selections and all its effects
......@@ -1029,7 +1019,7 @@ var TinaWebJS = function ( sigmacanvas ) {
if (TW.partialGraph && TW.partialGraph.graph) {
TW.partialGraph.graph.clear()
TW.partialGraph.refresh()
selections = []
TW.SystemState.selectionNids = []
}
}
......
......@@ -197,14 +197,14 @@ function changeType() {
var level = present.level;
var sels = present.selections
var sels = present.selectionNids
var t0Activetypes = present.activetypes;
var t0ActivetypesKey = t0Activetypes.map(Number).join("|")
console.debug("CHANGE TYPE, present.selections", present.selections)
// console.debug("CHANGE TYPE, present.selections", present.selectionNids)
var selsbackup = present.selections.slice();
var selsbackup = present.selectionNids.slice();
// type "grammar"
......@@ -359,7 +359,7 @@ function changeType() {
str_nextState = nextState.map(Number).join("|")
var sumNextState = nextState.map(Number).reduce(function(a, b){return a+b;})
// [ ChangeType: incremental selection ]
// [ ChangeType: incremental selection ;]
if(sumCats==1 && sumNextState<2) {
var indexCat = str_binSumCats;//(level)? t1ActivetypesKey : str_binSumCats ;
......@@ -385,8 +385,8 @@ function changeType() {
// output: newsels=[opposite-neighs]
} // [ / ChangeType: incremental selection ]
// console.log("new virtually selected nodes:")
// console.log(sels)
if (TW.conf.debug.logSelections)
console.log("new virtually selected nodes:", sels)
var selDict={}
for(var i in sels) // useful for case: (sumNextState==2)
......@@ -434,25 +434,26 @@ function changeType() {
// to recreate the selection in the new type graph
// TW.instance.selNgn.MultipleSelection2({
// nodesDict:nodes_2_colour,
// edgesDict:edges_2_colour
// });
TW.instance.selNgn.MultipleSelection2({ nodes: sels });
TW.instance.selNgn.MultipleSelection2({
nodes: sels,
nodesDict:nodes_2_colour,
edgesDict:edges_2_colour
});
TW.gui.selectionActive=true;
}
// £TODO this should be done by setState()
TW.states[avantlastpos] = {};
TW.states[avantlastpos].LouvainFait = false;
TW.states[avantlastpos].level = present.level;
TW.states[avantlastpos].selections = selsbackup;
TW.states[avantlastpos].selectionNids = selsbackup;
TW.states[avantlastpos].activetypes = present.activetypes;
TW.states[avantlastpos].opposites = present.opposites;
// possible: integrated highlighted opposite- and same-side neighbours from MS2
// (var used to exist but wasn't filled and used consistently)
TW.setState({
activetypes: nextState,
level: level,
sels: Object.keys(selections),
sels: sels,
oppos: []
})
......@@ -492,8 +493,12 @@ function changeLevel() {
var avantlastpos = lastpos-1;
var level = present.level;
var sels = present.selections;//[144, 384, 543]//TW.states.selections;
var sels = present.selectionNids ;//[144, 384, 543]//TW.states[last].selectionNids;
let selsChecker = {}
for (let i in sels) {
selsChecker[sels[i]] = true
}
// type "grammar"
// used to distinguish types in TW.Relations
......@@ -526,7 +531,7 @@ function changeLevel() {
nodes_2_colour[t]=false;
edges_2_colour[s+";"+t]=true;
edges_2_colour[t+";"+s]=true;
if( !selections[t] )
if( !selsChecker[t] )
voisinage[ t ] = true;
}
}
......@@ -535,7 +540,6 @@ function changeLevel() {
nodes_2_colour[sels[i]]=true;
var futurelevel = []
if(present.level) { // [Change to Local] when level=Global(1)
......@@ -590,18 +594,15 @@ function changeLevel() {
}
// console.log("enviroment changeLevel nodes_2_colour", nodes_2_colour)
TW.states[avantlastpos] = {};
TW.states[avantlastpos].level = present.level;
TW.states[avantlastpos].selections = present.selections;
TW.states[avantlastpos].activetypes = present.activetypes;
TW.states[avantlastpos].opposites = present.opposites;
TW.states[avantlastpos].selectionNids = present.selectionNids;
TW.setState({
activetypes: present.activetypes,
level: futurelevel,
sels: Object.keys(selections),
sels: sels,
oppos: []
})
......
......@@ -17,10 +17,9 @@ TW.catDict = {};
// SystemState is a summary of current situation
TW.SystemState = {}
TW.SystemState.activetypes = [] // <== filled from TW.categories
TW.SystemState.level = true;
TW.SystemState.activetypes = [] // will be filled from TW.categories
TW.SystemState.selections = [];
TW.SystemState.opposites = [];
TW.SystemState.selectionNids = []; // <== current selection !!
TW.SystemState.LouvainFait = false;
// states[] is an array of SystemStates for future CTRL+Z or usage track
......@@ -28,21 +27,13 @@ TW.states = []
TW.states[0] = false;
TW.states[1] = TW.SystemState
// £TODO should become TW.* or TW.SystemState.*
var selections = [];
var deselections={};
var opossites = {};
var opos=[];
var oposMAX;
var matches = [];
// -------------------------------8<--------------
// £TODO remove deprecated here and in parseCustom
var nodes1 = {};
var nodes2 = {};
var bipartiteD2N = {};
var bipartiteN2D = {};
// -------------------------------8<--------------
// ======== [ what to do at start ] ========= //
console.log("Starting TWJS")
......
......@@ -12,7 +12,7 @@ TW.setState = function( args ) {
var present = TW.states.slice(-1)[0]; // Last
var past = TW.states.slice(-2)[0] // avant Last
console.log("setState args: ", args);
if (TW.conf.debug.logSelections) console.log("setState args: ", args);
if(!isUndef(args.activetypes)) {
......@@ -28,15 +28,14 @@ TW.setState = function( args ) {
// console.log("printing the typesKey:", typesKey)
if(!isUndef(args.level)) present.level = args.level;
if(!isUndef(args.sels)) present.selections = args.sels;
if(!isUndef(args.oppos)) present.opposites = args.oppos;
if(!isUndef(args.sels)) present.selectionNids = args.sels;
present.LouvainFait = false;
// change level needs a selection
LevelButtonDisable(false); // £TODO rename toggleLevelButton
if( present.level
&& present.selections
&& present.selections.length==0)
&& present.selectionNids
&& present.selectionNids.length==0)
LevelButtonDisable(true);
// case to go back
......@@ -88,12 +87,9 @@ function cancelSelection (fromTagCloud, settings) {
if (!settings) settings = {}
highlightSelectedNodes(false); //Unselect the selected ones :D
opossites = [];
selections = [];
//selections.length = 0;
selections.splice(0, selections.length);
TW.states.slice(-1)[0].selections=[]
// clear the current state's selection and neighbors arrays
TW.SystemState.selectionNids.splice(0, TW.SystemState.selectionNids.length)
// global flag
TW.gui.selectionActive = false
......@@ -143,19 +139,6 @@ function cancelSelection (fromTagCloud, settings) {
$('#searchinput').trigger("tw:eraseNodeSet");
// (signal for plugins that any selection behavior is finished)
for(var nid in deselections){
let n = TW.partialGraph.graph.nodes(nid)
if( !isUndef(n) ) {
n.customAttrs.forceLabel = false;
n.customAttrs.highlight = false;
n.customAttrs.grey=false
// like old graphResetColor but now rather graphResetFlags...
n.active=false;
}
}
deselections={};
if(TW.states.slice(-1)[0].level)
LevelButtonDisable(true);
......@@ -213,11 +196,10 @@ function swActual(aNodetype) {
function highlightSelectedNodes(flag){
if (TW.conf.debug.logSelections)
console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" selEmpty:"+is_empty(selections))
if(!is_empty(selections)){
for(var i in selections) {
TW.partialGraph.graph.nodes(i).active = flag
}
console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" sel:"+TW.SystemState.selectionNids)
for(let i in TW.SystemState.selectionNids) {
let nid = TW.SystemState.selectionNids[i]
TW.partialGraph.graph.nodes(nid).active = flag
}
}
......@@ -425,6 +407,9 @@ function htmlfied_nodesatts(elems){
var socnodes=[]
var semnodes=[]
if (TW.conf.debug.logSelections) console.log("htmlfied_nodesatts", elems)
for(var i in elems) {
var information=[]
......@@ -516,21 +501,6 @@ function htmlProportionalLabels(elems , limit, selectableFlag) {
//considering complete graphs case! <= maybe i should mv it
function updateRelatedNodesPanel( sels , same, oppos ) {
// debug
// neiLabls = []
// for (var l in same) {
// var neiId = same[l].key
// if (TW.Nodes[neiId]) {
//
// neiLabls.push(TW.Nodes[neiId].label)
// }
// else {
// console.warn("missing entry for neiId", neiId)
// }
// }
// console.log("updateRelatedNodesPanel, same:",neiLabls)
var namesDIV=''
var alterNodesDIV=''
var informationDIV=''
......@@ -548,7 +518,7 @@ function updateRelatedNodesPanel( sels , same, oppos ) {
alterNodesDIV+= '</div>';
}
if(getNodeIDs(sels).length>0) {
if(sels.length>0) {
sameNodesDIV+='<div id="sameNodes">';//tagcloud
var sameNeighTagcloudHtml = htmlProportionalLabels( same , TW.conf.tagcloudSameLimit, true )
sameNodesDIV+= (sameNeighTagcloudHtml!=false) ? sameNeighTagcloudHtml.join("\n") : "No related items.";
......@@ -558,7 +528,7 @@ function updateRelatedNodesPanel( sels , same, oppos ) {
// getTopPapers("semantic");
informationDIV += '<br><h4>Information:</h4><ul>';
informationDIV += htmlfied_nodesatts( getNodeIDs(sels) ).join("<br>\n")
informationDIV += htmlfied_nodesatts( sels ).join("<br>\n")
informationDIV += '</ul><br>';
//using the readmore.js
......@@ -585,9 +555,11 @@ function printStates() {
console.log("\t\t\t\tswActual: "+swclickActual+" | swPrev: "+swclickPrev)
console.log("\t\t\t\tNOW: "+NOW+" | PAST: "+PAST)
console.log("\t\t\t\tselections: ")
console.log(Object.keys(selections))
console.log("\t\t\t\topposites: ")
console.log(Object.keys(opossites))
console.log(TW.SystemState.selectionNids)
console.log("\t\t\t\topposites neighbors: ")
console.log(TW.SystemState.opposideSortdNeighs)
console.log("\t\t\t\tsame neighbors: ")
console.log(TW.SystemState.samesideSortdNeighs)
console.log("\t\t\t\t------------------------------------")
}
......@@ -609,6 +581,11 @@ function graphTagCloudElem(nodes) {
if(! $.isArray(nodes)) ndsids.push(nodes);
else ndsids=nodes;
let newselsChecker = {}
for (let i in ndsids) {
newselsChecker[ndsids[i]] = true
}
var vars = []
var catDict = TW.catDict;
......@@ -635,7 +612,7 @@ function graphTagCloudElem(nodes) {
edges_2_colour[nid+";"+t]=true;
edges_2_colour[t+";"+s]=true;
if( !selections[t] )
if( !newselsChecker[t] )
voisinage[ Number(t) ] = true;
}
}
......@@ -644,7 +621,7 @@ function graphTagCloudElem(nodes) {
}
// old strategy recreated a graph with the selected and its neighbors:
// we know do it only if type is different
// we now do it only if type is different
if (nextTypesKey != getActivetypesKey()) {
TW.partialGraph.graph.clear();
for(var nid in nodes_2_colour)
......@@ -657,7 +634,7 @@ function graphTagCloudElem(nodes) {
for(var i=0;i<voisinage.length;i++) {
for(var j=1;j<voisinage.length;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] )
}
}
......@@ -682,17 +659,15 @@ function graphTagCloudElem(nodes) {
// £TODO setState should be doing this shifting
var avantlastpos = lastpos-1;
TW.states[avantlastpos] = {};
TW.states[avantlastpos].selections = present.selections;
TW.states[avantlastpos].selectionNids = present.selectionNids;
TW.states[avantlastpos].level = present.level;
TW.states[avantlastpos].activetypes = present.activetypes;
TW.states[avantlastpos].opposites = present.opposites;
// recording the new state
TW.setState({
activetypes: nextTypes,
level: false, // forced macro
sels: Object.keys(selections),
oppos: []
sels: present.selectionNids
})
TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0})
......
......@@ -687,29 +687,20 @@ function exactfind(label) {
function getNodeLabels(elems){
var labelss=[]
for(var i in elems){
console.debug(i, elems[i])
var id=(!isUndef(elems[i].id))?elems[i].id:i
labelss.push(TW.Nodes[id].label)
for(let i in elems){
labelss.push(TW.Nodes[elems[i]].label)
}
return labelss
}
function getNodeIDs(elems){
return Object.keys(elems)
}
function getSelections(){
let params=[];
for(var i in selections){
params.push(TW.Nodes[i].label);
let selLabels=[];
for(let i in TW.SystemState.selectionNids){
let nid = TW.SystemState.selectionNids[i]
selLabels.push(TW.Nodes[nid].label);
}
return params;
return selLabels;
}
......
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