Commit ad7d31f1 authored by Romain Loth's avatar Romain Loth

fix the setState mecanism

the new variant pushState will append new states itself + SystemState becomes an accessor to TW.states[-1] + start simplifying changeType
parent 3c0e1b3c
...@@ -187,6 +187,9 @@ TW.conf = (function(TW){ ...@@ -187,6 +187,9 @@ TW.conf = (function(TW){
// TW.geomap = false; // TW.geomap = false;
// TW.twittertimeline = false; // TW.twittertimeline = false;
TWConf.maxPastStates = 5 ; // number of TW.states to remember (~CTRL-Z)
// Layout options // Layout options
// -------------- // --------------
TWConf.fa2Available=true; // show/hide fa2Button TWConf.fa2Available=true; // show/hide fa2Button
...@@ -294,8 +297,9 @@ TW.conf = (function(TW){ ...@@ -294,8 +297,9 @@ TW.conf = (function(TW){
// show verbose console logs... // show verbose console logs...
logFetchers: false, // ...about ajax/fetching of graph data logFetchers: false, // ...about ajax/fetching of graph data
logParsers: false, // ...about parsing said data logParsers: false, // ...about parsing said data
logFacets: true, // ...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: true, // ...about TW.states array
logSelections: false logSelections: false
} }
......
...@@ -69,7 +69,7 @@ function SelectionEngine() { ...@@ -69,7 +69,7 @@ function SelectionEngine() {
// we assume string is normalized // we assume string is normalized
this.search_n_select = function(string) { this.search_n_select = function(string) {
let previousSelections = TW.SystemState.selectionNids let previousSelections = TW.SystemState().selectionNids
cancelSelection(false, {norender:true}); cancelSelection(false, {norender:true});
...@@ -147,8 +147,7 @@ function SelectionEngine() { ...@@ -147,8 +147,7 @@ function SelectionEngine() {
* *
* @nodes: eg targeted array (only ids) * @nodes: eg targeted array (only ids)
* *
* external usage : partialGraph.states, * external usage : clickHandler, search, changeType, filters, tag click...
* updateRelatedNodesPanel();
*/ */
// ==================== // ====================
this.MultipleSelection2 = function(args) { this.MultipleSelection2 = function(args) {
...@@ -170,7 +169,7 @@ function SelectionEngine() { ...@@ -170,7 +169,7 @@ function SelectionEngine() {
var sameSideNeighbors = {} var sameSideNeighbors = {}
var oppositeSideNeighbors = {} var oppositeSideNeighbors = {}
// TW.states.slice(-1)[0] is the present graph state // TW.SystemState() is the present graph state
// eg // eg
// {categories: ["someNodeCat"] // {categories: ["someNodeCat"]
// categoriesDict: {"someNodeCat":0} // where val 0 or 1 is type sem or soc // categoriesDict: {"someNodeCat":0} // where val 0 or 1 is type sem or soc
...@@ -277,32 +276,24 @@ function SelectionEngine() { ...@@ -277,32 +276,24 @@ function SelectionEngine() {
// show the button to remove selection // show the button to remove selection
$("#unselectbutton").show() ; $("#unselectbutton").show() ;
let theSelection = Object.keys(selections)
// £TODO: all this should be done in one line via TW.setState or ref // it's a new SystemState
TW.SystemState.selectionNids = Object.keys(selections) TW.pushState( { sels: theSelection } )
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")
}
// alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(TW.SystemState.selectionNids))
// we send our "gotNodeSet" event // we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection) // (signal for plugins that a search-selection was done or a new hand picked selection)
$('#searchinput').trigger({ $('#searchinput').trigger({
type: "tw:gotNodeSet", type: "tw:gotNodeSet",
q: $("#searchinput").val(), q: $("#searchinput").val(),
nodeIds: TW.SystemState.selectionNids nodeIds: theSelection
}); });
// console.log("Event [gotNodeSet] sent from Tinaweb MultipleSelection2") // console.log("Event [gotNodeSet] sent from Tinaweb MultipleSelection2")
// neighbors of the opposite type // neighbors of the opposite type
if(TW.Relations["1|1"]) { if(TW.Relations["1|1"]) {
for(var s in TW.SystemState.selectionNids) { for(var s in theSelection) {
var bipaNeighs = TW.Relations["1|1"][TW.SystemState.selectionNids[s]]; var bipaNeighs = TW.Relations["1|1"][theSelection[s]];
for(var n in bipaNeighs) { for(var n in bipaNeighs) {
if (typeof oppositeSideNeighbors[bipaNeighs[n]] == "undefined") if (typeof oppositeSideNeighbors[bipaNeighs[n]] == "undefined")
...@@ -324,7 +315,7 @@ function SelectionEngine() { ...@@ -324,7 +315,7 @@ function SelectionEngine() {
}); });
if (TW.conf.debug.logSelections) { if (TW.conf.debug.logSelections) {
console.debug('TW.SystemState.selectionNids', TW.SystemState.selectionNids) console.debug('new states\'s selectionNids', theSelection)
console.debug('oppos', oppos) console.debug('oppos', oppos)
console.debug('same', same) console.debug('same', same)
} }
...@@ -334,7 +325,7 @@ function SelectionEngine() { ...@@ -334,7 +325,7 @@ function SelectionEngine() {
TW.partialGraph.render(); TW.partialGraph.render();
updateRelatedNodesPanel( TW.SystemState.selectionNids , same, oppos ) updateRelatedNodesPanel( theSelection , same, oppos )
if (TW.conf.debug.logSelections) { if (TW.conf.debug.logSelections) {
var tMS2_fin = performance.now() var tMS2_fin = performance.now()
...@@ -831,7 +822,7 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -831,7 +822,7 @@ var TinaWebJS = function ( sigmacanvas ) {
var targeted = selInst.SelectorEngine( { var targeted = selInst.SelectorEngine( {
addvalue:TW.gui.checkBox, addvalue:TW.gui.checkBox,
currsels:circleNodes, currsels:circleNodes,
prevsels:TW.SystemState.selectionNids prevsels:TW.SystemState().selectionNids
} ) } )
// 2) clear previous selection // 2) clear previous selection
...@@ -847,7 +838,7 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -847,7 +838,7 @@ var TinaWebJS = function ( sigmacanvas ) {
// when one node and normal click // when one node and normal click
// =============================== // ===============================
partialGraph.bind('clickNode', function(e) { partialGraph.bind('clickNode', function(e) {
// console.log("clickNode event e", e.data.node) console.log("clickNode event e", e.data.node)
// new sigma.js gives easy access to clicked node! // new sigma.js gives easy access to clicked node!
var theNodeId = e.data.node.id var theNodeId = e.data.node.id
...@@ -857,10 +848,10 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -857,10 +848,10 @@ var TinaWebJS = function ( sigmacanvas ) {
var targeted = selInst.SelectorEngine( { var targeted = selInst.SelectorEngine( {
addvalue:TW.gui.checkBox, addvalue:TW.gui.checkBox,
currsels:[theNodeId], currsels:[theNodeId],
prevsels: TW.SystemState.selectionNids prevsels: TW.SystemState().selectionNids
} ) } )
// 2) // 2)
cancelSelection(false, {norender:true}); // no need to render before MS2 // cancelSelection(false, {norender:true}); // no need to render before MS2
// 3) // 3)
if(targeted.length>0) { if(targeted.length>0) {
selInst.MultipleSelection2( {nodes:targeted} ) selInst.MultipleSelection2( {nodes:targeted} )
...@@ -1040,7 +1031,9 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -1040,7 +1031,9 @@ var TinaWebJS = function ( sigmacanvas ) {
if (TW.partialGraph && TW.partialGraph.graph) { if (TW.partialGraph && TW.partialGraph.graph) {
TW.partialGraph.graph.clear() TW.partialGraph.graph.clear()
TW.partialGraph.refresh() TW.partialGraph.refresh()
TW.SystemState.selectionNids = []
// ££TODO push state
TW.SystemState().selectionNids = []
} }
} }
......
...@@ -191,11 +191,8 @@ function createFilechooserEl () { ...@@ -191,11 +191,8 @@ function createFilechooserEl () {
// Documentation Level: ***** // Documentation Level: *****
function changeType() { function changeType() {
var present = TW.states.slice(-1)[0]; // Last
var past = TW.states.slice(-2)[0] // avant Last
var lastpos = TW.states.length-1;
var avantlastpos = lastpos-1;
var present = TW.SystemState() ; // current state before the change
var level = present.level; var level = present.level;
var sels = present.selectionNids var sels = present.selectionNids
...@@ -229,15 +226,8 @@ function changeType() { ...@@ -229,15 +226,8 @@ function changeType() {
if(level) nextState = t1Activetypes; if(level) nextState = t1Activetypes;
else nextState = binSumCats; else nextState = binSumCats;
if(!level && past!=false) { if(!level && t0ActivetypesKey == '1|1') {
var sum_past = present.activetypes.map(Number).reduce(function(a, b){return a+b;}) nextState = [true, false];
console.log("sum_past:")
console.log(sum_past)
console.log("past.activetypes:")
console.log(past.activetypes)
if(sum_past>1) {
nextState = past.activetypes;
}
} }
var str_nextState = nextState.map(Number).join("|") var str_nextState = nextState.map(Number).join("|")
...@@ -289,15 +279,6 @@ function changeType() { ...@@ -289,15 +279,6 @@ function changeType() {
} }
} else /* Local level, change to previous or alter component*/ { } else /* Local level, change to previous or alter component*/ {
if(sels.length==0) { if(sels.length==0) {
console.log(" * * * * * * * * * * * * * * ")
console.log("the past: ")
console.log(past.activetypes.map(Number)+" , "+past.level)
console.log(past)
console.log("the present: ")
console.log(present.activetypes.map(Number)+" , "+present.level)
console.log(present)
console.log("t0ActivetypesKey: "+t0ActivetypesKey) console.log("t0ActivetypesKey: "+t0ActivetypesKey)
console.log("t1ActivetypesKey: "+t1ActivetypesKey) console.log("t1ActivetypesKey: "+t1ActivetypesKey)
console.log("str_nextState: "+str_nextState) console.log("str_nextState: "+str_nextState)
...@@ -355,8 +336,6 @@ function changeType() { ...@@ -355,8 +336,6 @@ function changeType() {
var sumFutureCats = nextState.map(Number).reduce(function(a, b){return a+b;}) var sumFutureCats = nextState.map(Number).reduce(function(a, b){return a+b;})
nextState = (sumFutureCats==2 && !level && sumCats==1 )? nextState : t1Activetypes; nextState = (sumFutureCats==2 && !level && sumCats==1 )? nextState : t1Activetypes;
if(t1ActivetypesKey=="0|0" ) nextState=past.activetypes;
// nextState = ( past.activetypes && !level && sumCats==1 )? past.activetypes : t1Activetypes;
str_nextState = nextState.map(Number).join("|") str_nextState = nextState.map(Number).join("|")
var sumNextState = nextState.map(Number).reduce(function(a, b){return a+b;}) var sumNextState = nextState.map(Number).reduce(function(a, b){return a+b;})
...@@ -442,17 +421,10 @@ function changeType() { ...@@ -442,17 +421,10 @@ function changeType() {
TW.gui.selectionActive=true; 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].selectionNids = selsbackup;
TW.states[avantlastpos].activetypes = present.activetypes;
// possible: integrated highlighted opposite- and same-side neighbours from MS2 // possible: integrated highlighted opposite- and same-side neighbours from MS2
// (var used to exist but wasn't filled and used consistently) // (var used to exist but wasn't filled and used consistently)
TW.setState({ TW.pushState({
activetypes: nextState, activetypes: nextState,
level: level,
sels: sels, sels: sels,
oppos: [] oppos: []
}) })
...@@ -487,12 +459,8 @@ function changeLevel() { ...@@ -487,12 +459,8 @@ function changeLevel() {
// let the waiting cursor appear // let the waiting cursor appear
setTimeout(function() { setTimeout(function() {
var present = TW.states.slice(-1)[0]; // Last var present = TW.SystemState(); // Last
var past = TW.states.slice(-2)[0] // avant Last
var lastpos = TW.states.length-1;
var avantlastpos = lastpos-1;
var level = present.level;
var sels = present.selectionNids ;//[144, 384, 543]//TW.states[last].selectionNids; var sels = present.selectionNids ;//[144, 384, 543]//TW.states[last].selectionNids;
let selsChecker = {} let selsChecker = {}
...@@ -506,13 +474,8 @@ function changeLevel() { ...@@ -506,13 +474,8 @@ function changeLevel() {
// types eg [true] <=> '1' // types eg [true] <=> '1'
// [true, true] <=> '1|1' // [true, true] <=> '1|1'
var t0Activetypes = present.activetypes; var activetypes = present.activetypes;
var t0ActivetypesKey = t0Activetypes.map(Number).join("|") var activetypesKey = activetypes.map(Number).join("|")
// [X|Y]-change (NOT operation over the received state [X\Y] )
var t1Activetypes = []
for(var i in t0Activetypes) t1Activetypes[i] = !t0Activetypes[i]
var t1ActivetypesKey = t1Activetypes.map(Number).join("|")
TW.partialGraph.graph.clear(); TW.partialGraph.graph.clear();
...@@ -524,7 +487,7 @@ function changeLevel() { ...@@ -524,7 +487,7 @@ function changeLevel() {
// POSS: factorize with same strategy in MultipleSelection2 beginning // POSS: factorize with same strategy in MultipleSelection2 beginning
for(var i in sels) { for(var i in sels) {
s = sels[i]; s = sels[i];
neigh = TW.Relations[t0ActivetypesKey][s] neigh = TW.Relations[activetypesKey][s]
if(neigh) { if(neigh) {
for(var j in neigh) { for(var j in neigh) {
t = neigh[j] t = neigh[j]
...@@ -540,7 +503,7 @@ function changeLevel() { ...@@ -540,7 +503,7 @@ function changeLevel() {
nodes_2_colour[sels[i]]=true; nodes_2_colour[sels[i]]=true;
var futurelevel = [] var futurelevel = null
if(present.level) { // [Change to Local] when level=Global(1) if(present.level) { // [Change to Local] when level=Global(1)
for(var nid in nodes_2_colour) for(var nid in nodes_2_colour)
...@@ -568,12 +531,12 @@ function changeLevel() { ...@@ -568,12 +531,12 @@ function changeLevel() {
// var t0 = performance.now() // var t0 = performance.now()
for(var nid in TW.Nodes) { for(var nid in TW.Nodes) {
if(t0Activetypes[TW.catDict[TW.Nodes[nid].type]]) if(activetypes[TW.catDict[TW.Nodes[nid].type]])
// we add 1 by 1 // we add 1 by 1
add1Elem(nid) add1Elem(nid)
} }
for(var eid in TW.Edges) { for(var eid in TW.Edges) {
if(TW.Edges[eid].categ==t0ActivetypesKey) if(TW.Edges[eid].categ == activetypesKey)
add1Elem(eid) add1Elem(eid)
} }
...@@ -593,17 +556,8 @@ function changeLevel() { ...@@ -593,17 +556,8 @@ function changeLevel() {
} }
} }
// console.log("enviroment changeLevel nodes_2_colour", nodes_2_colour) TW.pushState({
TW.states[avantlastpos] = {}; level: futurelevel
TW.states[avantlastpos].level = present.level;
TW.states[avantlastpos].activetypes = present.activetypes;
TW.states[avantlastpos].selectionNids = present.selectionNids;
TW.setState({
activetypes: present.activetypes,
level: futurelevel,
sels: sels,
oppos: []
}) })
TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2, angle: 0})
......
...@@ -15,17 +15,21 @@ TW.gexfPaths={}; // for file selectors iff servermenu ...@@ -15,17 +15,21 @@ TW.gexfPaths={}; // for file selectors iff servermenu
TW.categories = []; // possible node types and their inverted map TW.categories = []; // possible node types and their inverted map
TW.catDict = {}; TW.catDict = {};
// SystemState is a summary of current situation
TW.SystemState = {} // a system state is the summary of tina situation
TW.SystemState.activetypes = [] // <== filled from TW.categories TW.initialSystemState = {
TW.SystemState.level = true; activetypes: [], // <== filled from TW.categories
TW.SystemState.selectionNids = []; // <== current selection !! level: true,
TW.SystemState.LouvainFait = false; selectionNids: [], // <== current selection !!
LouvainFait: false,
// states[] is an array of SystemStates for future CTRL+Z or usage track id: 0 // simple incremental stateid
TW.states = [] }
TW.states[0] = false;
TW.states[1] = TW.SystemState // states[] is an array of system states for future CTRL+Z or usage track
TW.states = [TW.initialSystemState]
// SystemState() returns the current situation
TW.SystemState = function() { return TW.states.slice(-1)[0] }
// -------------------------------8<-------------- // -------------------------------8<--------------
// £TODO remove deprecated here and in parseCustom // £TODO remove deprecated here and in parseCustom
...@@ -357,7 +361,7 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -357,7 +361,7 @@ function mainStartGraph(inFormat, inData, twInstance) {
var possibleActivetypes = TW.instance.allPossibleActivetypes( TW.categories ) var possibleActivetypes = TW.instance.allPossibleActivetypes( TW.categories )
// remember it // remember it
TW.states[1].activetypes = initialActivetypes ; TW.pushState({'activetypes': 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
......
...@@ -5,47 +5,44 @@ ...@@ -5,47 +5,44 @@
// ex: new selections: {sels: [268]} // ex: new selections: {sels: [268]}
// ex: new activetypes: {activetypes:[false, true]} // ex: new activetypes: {activetypes:[false, true]}
// ex: new level: {level:false} // ex: new level: {level:false}
TW.setState = function( args ) { TW.pushState = function( args ) {
var bistate=false, typesKey=false;
// £TODO we could append the new state in this function too
var present = TW.states.slice(-1)[0]; // Last let lastState = TW.states.slice(-1)[0] // <=> TW.SystemState()
var past = TW.states.slice(-2)[0] // avant Last
if (TW.conf.debug.logSelections) console.log("setState args: ", args); if (TW.conf.debug.logSelections) console.log("setState args: ", args);
if(!isUndef(args.activetypes)) { // 1) we start from a copy
let newState = Object.assign({}, lastState)
// record into last state // counter à toutes fins utiles
present.activetypes = args.activetypes; newState.id ++
// 2) we update it with provided args
if (!isUndef(args.sels)) newState.selectionNids = args.sels;
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.level)) newState.level = args.level;
bistate= present.activetypes.map(Number).reduce( // POSS1: add neighbors (of both types) in a .neighborsNids[type] slot
function(a, b){return a+b;} // POSS2: add filterSliders params to be able to recreate subsets at a given time
)
typesKey = present.activetypes.map(Number).join("|")
}
// console.log("printing the typesKey:", typesKey)
if(!isUndef(args.level)) present.level = args.level; // useful shortcut
if(!isUndef(args.sels)) present.selectionNids = args.sels; let typesKey = newState.activetypes.map(Number).join("|")
present.LouvainFait = false;
// change level needs a selection // legacy : we prefer to redo louvain than to miss a new nodeset
LevelButtonDisable(false); // £TODO rename toggleLevelButton // (wouldn't be needed if POSS2 implemented)
if( present.level newState.LouvainFait = false;
&& present.selectionNids
&& present.selectionNids.length==0)
LevelButtonDisable(true); // 3) apply all GUI effects
// case to go back // change level depends on a selection
if(present.level==false && bistate>1) LevelButtonDisable( (newState.selectionNids.length == 0) );
LevelButtonDisable(true)
// recreate sliders after activetype or level changes // recreate sliders after activetype or level changes
if (TW.conf.filterSliders if (TW.conf.filterSliders
&& (present.level != past.level && (newState.level != lastState.level
|| present.activetypes.map(Number).join("|") != past.activetypes.map(Number).join("|"))) { || typesKey != lastState.activetypes.map(Number).join("|"))) {
// terms // terms
if(typesKey=="0|1") { if(typesKey=="0|1") {
...@@ -77,9 +74,20 @@ TW.setState = function( args ) { ...@@ -77,9 +74,20 @@ TW.setState = function( args ) {
} }
} }
// 4) store it in TW.states
TW.states.push(newState)
// 5) forget oldest states if needed
while (TW.states.length > TW.conf.maxPastStates) {
TW.states.shift()
}
if (TW.conf.debug.logStates)
console.log(`updated states: ${JSON.stringify(TW.states)}`)
}; };
TW.resetGraph = function() { TW.resetGraph = function() {
// call the sigma graph clearing // call the sigma graph clearing
TW.instance.clearSigma() TW.instance.clearSigma()
...@@ -88,6 +96,8 @@ TW.resetGraph = function() { ...@@ -88,6 +96,8 @@ TW.resetGraph = function() {
// reset remaining global vars // reset remaining global vars
TW.labels = [] TW.labels = []
TW.Relations = {}
TW.states = [TW.initialSystemState]
// reset rendering gui flags // reset rendering gui flags
TW.gui.selectionActive = false TW.gui.selectionActive = false
...@@ -111,7 +121,9 @@ function cancelSelection (fromTagCloud, settings) { ...@@ -111,7 +121,9 @@ function cancelSelection (fromTagCloud, settings) {
highlightSelectedNodes(false); //Unselect the selected ones :D highlightSelectedNodes(false); //Unselect the selected ones :D
// clear the current state's selection and neighbors arrays // clear the current state's selection and neighbors arrays
TW.SystemState.selectionNids.splice(0, TW.SystemState.selectionNids.length)
// new state
TW.pushState({sels:[]})
// global flag // global flag
TW.gui.selectionActive = false TW.gui.selectionActive = false
...@@ -228,10 +240,11 @@ function swActual(aNodetype) { ...@@ -228,10 +240,11 @@ function swActual(aNodetype) {
function highlightSelectedNodes(flag){ function highlightSelectedNodes(flag){
let sels = TW.SystemState().selectionNids
if (TW.conf.debug.logSelections) if (TW.conf.debug.logSelections)
console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" sel:"+TW.SystemState.selectionNids) console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" sel:"+sels)
for(let i in TW.SystemState.selectionNids) { for(let i in sels) {
let nid = TW.SystemState.selectionNids[i] let nid = sels[i]
TW.partialGraph.graph.nodes(nid).active = flag TW.partialGraph.graph.nodes(nid).active = flag
} }
} }
......
...@@ -630,8 +630,9 @@ function getNodeLabels(elems){ ...@@ -630,8 +630,9 @@ function getNodeLabels(elems){
function getSelections(){ function getSelections(){
let selLabels=[]; let selLabels=[];
for(let i in TW.SystemState.selectionNids){ let sels = TW.SystemState().selectionNids
let nid = TW.SystemState.selectionNids[i] for(let i in sels ){
let nid = sels[i]
selLabels.push(TW.Nodes[nid].label); selLabels.push(TW.Nodes[nid].label);
} }
return selLabels; 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