Commit 1c19957b authored by Romain Loth's avatar Romain Loth

meso view changeType: use selection as guide

parent 0bba98fb
...@@ -251,7 +251,7 @@ TW.conf = (function(TW){ ...@@ -251,7 +251,7 @@ TW.conf = (function(TW){
// ----------------------------------- // -----------------------------------
// normal and meso level background colors // normal and meso level background colors
TWConf.normalBackground = '#fff' // <= should match css default TWConf.normalBackground = '#fff' // <= should match css default
TWConf.mesoBackground = '#fcfcea' TWConf.mesoBackground = '#fcfcd5'
// mouse captor zoom limits // mouse captor zoom limits
TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64) TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64)
......
...@@ -351,15 +351,39 @@ function changeType(optionaltypeFlag) { ...@@ -351,15 +351,39 @@ function changeType(optionaltypeFlag) {
let mixedState = (outgoing.activereltypes.length > 1) let mixedState = (outgoing.activereltypes.length > 1)
let preservedNodes = {} let preservedNodes = {}
// needed selection content diagnostic for mixed meso target choice
let selectionTypeId = false
if (outgoing.selectionNids.length) {
if (!mixedState) {
selectionTypeId = oldTypeId
}
else if (!outgoing.level) {
let selMajorityType = TW.categories[oldTypeId]
let counts = {}
for (var j in outgoing.selectionNids) {
let ty = TW.Nodes[outgoing.selectionNids[j]].type
if (! counts[ty]) counts[ty] = 1
else counts[ty] += 1
}
for (var ty in counts) {
if (counts[ty] > counts[selMajorityType]) {
selMajorityType = ty
}
}
selectionTypeId = TW.catDict[ty]
}
}
// 1 - make the targetTypes choices // 1 - make the targetTypes choices
if (!isUndef(optionaltypeFlag)) { if (!isUndef(optionaltypeFlag)) {
typeFlag = optionaltypeFlag typeFlag = optionaltypeFlag
} }
else { else {
// "comeback" case: going back from mixed view to nodes0 view // "comeback" case: going back from mixed view to selections majority view
// (or last non-mixed view if no selection)
// ---------- // ----------
if (mixedState) { if (mixedState) {
typeFlag = 0 typeFlag = selectionTypeId || outgoing.comingFromType || 0
} }
// "jutsu" case: macrolevel opens mixed view // "jutsu" case: macrolevel opens mixed view
// ------- // -------
...@@ -390,29 +414,39 @@ function changeType(optionaltypeFlag) { ...@@ -390,29 +414,39 @@ function changeType(optionaltypeFlag) {
let newReltypes = TW.instance.inferActivereltypes(newActivetypes) let newReltypes = TW.instance.inferActivereltypes(newActivetypes)
// console.log('newReltypes', newReltypes) // console.log('newReltypes', newReltypes)
// nodes already in target type
let alreadyOk = {}
if (mixedState) {
let arr = TW.partialGraph.graph.getNodesByType(typeFlag)
for (var i in arr) {alreadyOk[arr[i]] = true}
}
// 3 - define the projected selection (sourceNids => corresponding opposites) // 3 - define the projected selection (sourceNids => corresponding opposites)
let sourceNids = outgoing.selectionNids let sourceNids = outgoing.selectionNids
if (!outgoing.level && !sourceNids.length) { // // when jutsu and no selection => by def nothing happens
// when local and no selection => all local graph is selection // // otherwise POSS: all local graph is selection
sourceNids = TW.partialGraph.graph.nodes().map(function(n){return n.id}) // if (typeFlag == 'all' && !sourceNids.length) {
} // sourceNids = TW.partialGraph.graph.nodes().map(function(n){return n.id})
// }
let targetNids = {} let targetNids = {}
if (!mixedState && outgoing.level) { if (!mixedState) {
targetNids = getNeighbors(sourceNids, 'XR') targetNids = getNeighbors(sourceNids, 'XR')
} }
else { else {
// in mixed state we need to separate those already tgt state from others // in mixed local state we need to separate those already tgt state from others
let alreadyOk = TW.partialGraph.graph.getNodesByType(typeFlag) let needXRTransition = []
let alreadyOkLookup = {}
for (var i in alreadyOk) {alreadyOkLookup[alreadyOk[i]] = true}
let needTransition = []
for (var i in sourceNids) { for (var i in sourceNids) {
let nid = sourceNids[i] let nid = sourceNids[i]
if (alreadyOkLookup[nid]) targetNids[nid] = true if (alreadyOk[nid]) targetNids[nid] = true
else needTransition.push(nid) else needXRTransition.push(nid)
}
// if none of the selection in new type => selection's projection
// if some of the selection in new type => this majority subset of selection
// without the projection of others
if (! Object.keys(targetNids).length) {
targetNids = getNeighbors(needXRTransition, "XR")
} }
targetNids = Object.assign(targetNids, getNeighbors(needTransition, 'XR')) // console.log("mixedState start, selections targetNids:", targetNids)
} }
// 4 - define the nodes to be added // 4 - define the nodes to be added
...@@ -426,10 +460,25 @@ function changeType(optionaltypeFlag) { ...@@ -426,10 +460,25 @@ function changeType(optionaltypeFlag) {
} }
} }
} }
// when scope is "local subset" => selection's projection
else { else {
for (var nid in targetNids) { if (Object.keys(targetNids).length) {
newNodes[nid] = TW.Nodes[nid] for (var nid in targetNids) {
newNodes[nid] = TW.Nodes[nid]
}
// also more added because they are the "meso" sameside neighbors of the selection
let rel = typeFlag.toString().repeat(2)
let additionalNewTypeNids = getNeighbors(Object.keys(targetNids), rel)
for (var nid in additionalNewTypeNids) {
newNodes[nid] = TW.Nodes[nid]
}
}
// if no selection, meso shouldn't be possible, but we can still
// show something: those that were already of the correct type
else if (mixedState) {
for (var nid in alreadyOk) {
newNodes[nid] = TW.Nodes[nid]
}
} }
} }
// console.log('newNodes', newNodes) // console.log('newNodes', newNodes)
...@@ -439,11 +488,12 @@ function changeType(optionaltypeFlag) { ...@@ -439,11 +488,12 @@ function changeType(optionaltypeFlag) {
if (outgoing.selectionNids.length) { if (outgoing.selectionNids.length) {
if (typeFlag != 'all') { if (typeFlag != 'all') {
newselsArr = Object.keys(targetNids) newselsArr = Object.keys(targetNids)
// NB: if mixedState we already filtered them at step 3
} }
else { else {
// not extending selection to all transitive neighbors // not extending selection to all transitive neighbors
// makes the operation stable (when clicked several times, // makes the operation stable (when clicked several times,
// we extend slower towards transitive closure) // without changing selection, we go back to original state)
newselsArr = outgoing.selectionNids newselsArr = outgoing.selectionNids
} }
} }
...@@ -504,13 +554,24 @@ function changeType(optionaltypeFlag) { ...@@ -504,13 +554,24 @@ function changeType(optionaltypeFlag) {
// 9 - refresh view and record the state // 9 - refresh view and record the state
TW.partialGraph.camera.goTo({x:0, y:0, ratio:1, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:1, angle: 0})
TW.partialGraph.refresh() TW.partialGraph.refresh()
TW.pushGUIState({
activetypes: newActivetypes, if (typeFlag != "all") {
activereltypes: newReltypes, TW.pushGUIState({
sels: newselsArr activetypes: newActivetypes,
// rels: added by MS2 (highlighted opposite- and same-side neighbours) activereltypes: newReltypes,
// possible: add it in an early way here and request that MS2 doesn't change state 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
})
}
else {
TW.pushGUIState({
activetypes: newActivetypes,
comingFromType: oldTypeId,
activereltypes: newReltypes,
sels: newselsArr
})
}
// to recreate the new selection in the new type graph, if we had one before // to recreate the new selection in the new type graph, if we had one before
// NB relies on new actypes so should be after pushState // NB relies on new actypes so should be after pushState
......
...@@ -25,6 +25,9 @@ TW.pushGUIState = function( args ) { ...@@ -25,6 +25,9 @@ TW.pushGUIState = function( args ) {
if (!isUndef(args.level)) newState.level = args.level; if (!isUndef(args.level)) newState.level = args.level;
if (!isUndef(args.sels)) newState.selectionNids = args.sels; if (!isUndef(args.sels)) newState.selectionNids = args.sels;
// this one just needed for changeType "comeback" case
if (!isUndef(args.comingFromType)) newState.comingFromType = args.comingFromType
// 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;
......
...@@ -265,7 +265,7 @@ TW.conf = (function(TW){ ...@@ -265,7 +265,7 @@ TW.conf = (function(TW){
// ----------------------------------- // -----------------------------------
// normal and meso level background colors // normal and meso level background colors
TWConf.normalBackground = '#fff' // <= should match css default TWConf.normalBackground = '#fff' // <= should match css default
TWConf.mesoBackground = '#fcfcea' TWConf.mesoBackground = '#fcfcd5'
// mouse captor zoom limits // mouse captor zoom limits
TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64) TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64)
......
...@@ -251,7 +251,7 @@ TW.conf = (function(TW){ ...@@ -251,7 +251,7 @@ TW.conf = (function(TW){
// ----------------------------------- // -----------------------------------
// normal and meso level background colors // normal and meso level background colors
TWConf.normalBackground = '#fff' // <= should match css default TWConf.normalBackground = '#fff' // <= should match css default
TWConf.mesoBackground = '#fcfcea' TWConf.mesoBackground = '#fcfcd5'
// mouse captor zoom limits // mouse captor zoom limits
TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64) TWConf.zoomMin = .015625 // for zoom IN (ex: 1/64 to allow zoom x64)
......
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