Commit f11872b1 authored by Romain Loth's avatar Romain Loth

fix nodes/edges subset sliders

cursor positioning, neigbors only if not hidden, wait timer for expensive dropEdge loop, classic debouncing, add1Elem for edges
parent 09c12d64
...@@ -16,7 +16,7 @@ color: #000; ...@@ -16,7 +16,7 @@ color: #000;
.fsslider { .fsslider {
text-align: center; text-align: center;
line-height: 8px; line-height: 8px;
font-size: 8px; font-size: 10px;
font-family: "Lucida Grande", "Trebuchet MS"; font-family: "Lucida Grande", "Trebuchet MS";
} }
.fsslider > * { .fsslider > * {
......
...@@ -107,7 +107,7 @@ html, body { ...@@ -107,7 +107,7 @@ html, body {
margin: 10px 0 0 0 ; margin: 10px 0 0 0 ;
} }
#defaultop .settingslider { #defaultop .settingslider {
max-width: 120px !important; max-width: 90px !important;
display: inline-block ; display: inline-block ;
} }
...@@ -344,3 +344,17 @@ p.micromessage{ ...@@ -344,3 +344,17 @@ p.micromessage{
} }
} }
/* freshslider right-side cursor positioning fix
* (cf. freshslider.js l. 125)
*/
.fss-right {
margin-left: 0 !important ;
}
/* to display wait cursor
*/
html.waiting {
cursor: wait;
}
...@@ -120,6 +120,9 @@ ...@@ -120,6 +120,9 @@
caretRight.css({ caretRight.css({
left:values[1] * realWidth + caretRightWidth / 2, left:values[1] * realWidth + caretRightWidth / 2,
// this line is a mistake by freshslider dev but instead of
// modifying it here we override it in our own css with "important"
"margin-left": -(caretRightWidth/2), "margin-left": -(caretRightWidth/2),
'z-index':isRight?1:0 'z-index':isRight?1:0
}); });
......
...@@ -185,17 +185,28 @@ function SelectionEngine() { ...@@ -185,17 +185,28 @@ function SelectionEngine() {
else ndsids=nodes; else ndsids=nodes;
for(var i in ndsids) { for(var i in ndsids) {
var s = ndsids[i]; var s = ndsids[i];
if(TW.Relations[typeNow] && TW.Relations[typeNow][s] ) { if(TW.Relations[typeNow] && TW.Relations[typeNow][s] ) {
var neigh = TW.Relations[typeNow][s] var neigh = TW.Relations[typeNow][s]
if(neigh) { if(neigh) {
for(var j in neigh) { for(var j in neigh) {
var t = neigh[j] var t = neigh[j]
// we add as neighbor to color it (except if already in targeted) // highlight edges (except if n hidden or e dropped (<=> lock))
if (!nodes_2_colour[t]) nodes_2_colour[t]=false; // POSS: use sigma's own index to avoid checking if edge dropped
if (! TW.partialGraph.graph.nodes(t).hidden
&& (
(TW.Edges[s+";"+t] && !TW.Edges[s+";"+t].lock)
||
(TW.Edges[t+";"+s] && !TW.Edges[t+";"+s].lock)
)
) {
edges_2_colour[s+";"+t]=true; edges_2_colour[s+";"+t]=true;
edges_2_colour[t+";"+s]=true; edges_2_colour[t+";"+s]=true;
// since we're there we keep the info // we add as neighbor to color it (except if already in targeted)
if (!nodes_2_colour[t]) nodes_2_colour[t]=false;
// since we're there we keep the neighbors info
if (typeof sameSideNeighbors[t] == 'undefined') { if (typeof sameSideNeighbors[t] == 'undefined') {
sameSideNeighbors[t]=0 sameSideNeighbors[t]=0
} }
...@@ -203,6 +214,7 @@ function SelectionEngine() { ...@@ -203,6 +214,7 @@ function SelectionEngine() {
} }
} }
} }
}
// we make the selected (source) node active too // we make the selected (source) node active too
nodes_2_colour[s]=true; nodes_2_colour[s]=true;
......
'use strict;' 'use strict;'
// always useful
var theHtml = document.getElementsByTagName('html')[0]
//============================ < NEW BUTTONS > =============================// //============================ < NEW BUTTONS > =============================//
// Documentation Level: ***** // Documentation Level: *****
...@@ -390,10 +394,15 @@ function changeLevel() { ...@@ -390,10 +394,15 @@ function changeLevel() {
//=========================== < FILTERS-SLIDERS > ===========================// //=========================== < FILTERS-SLIDERS > ===========================//
// Execution modes: // Execution modes:
// EdgeWeightFilter("#sliderAEdgeWeight", "label" , "nodes1", "weight"); // EdgeWeightFilter("#sliderAEdgeWeight", "label" , "nodes1", "weight");
// EdgeWeightFilter("#sliderBEdgeWeight", "label" , "nodes2", "weight"); // EdgeWeightFilter("#sliderBEdgeWeight", "label" , "nodes2", "weight");
// NB new sigma js: dropEdge is quite slow so we add a waiting cursor
function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// if ($(sliderDivID).html()!="") { // if ($(sliderDivID).html()!="") {
// console.log("\t\t\t\t\t\t[[ algorithm not applied "+sliderDivID+" ]]") // console.log("\t\t\t\t\t\t[[ algorithm not applied "+sliderDivID+" ]]")
...@@ -410,7 +419,28 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -410,7 +419,28 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// type_attrb = "type" // type_attrb = "type"
// criteria = "size" // criteria = "size"
// if(TW.partialGraph.nEdges<3) { if(TW.nEdges<3) {
$(sliderDivID).freshslider({
range: true,
step:1,
value:[10, 60],
enabled: false,
onchange:function(low, high){
console.log(low, high);
}
});
return;
}
var filterparams = AlgorithmForSliders ( TW.Edges , type_attrb , type , criteria) //OK
// TODO make an index
// console.log("EdgeWeightFilter: "+type)
// console.log(filterparams)
var steps = filterparams["steps"]
var finalarray = filterparams["finalarray"]
// if(steps<3) {
// $(sliderDivID).freshslider({ // $(sliderDivID).freshslider({
// range: true, // range: true,
// step:1, // step:1,
...@@ -423,29 +453,6 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -423,29 +453,6 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// return; // return;
// } // }
var filterparams = AlgorithmForSliders ( TW.Edges , type_attrb , type , criteria) //OK
// TODO make an index
// console.log("EdgeWeightFilter: "+type)
// console.log(filterparams)
var steps = filterparams["steps"]
var finalarray = filterparams["finalarray"]
if(steps<3) {
$(sliderDivID).freshslider({
range: true,
step:1,
value:[10, 60],
enabled: false,
onchange:function(low, high){
// TODO REFA fix edge selector
// console.log(low, high);
}
});
return;
}
var lastvalue=("0-"+(steps-1)); var lastvalue=("0-"+(steps-1));
...@@ -453,6 +460,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -453,6 +460,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
var present = TW.partialGraph.states.slice(-1)[0]; var present = TW.partialGraph.states.slice(-1)[0];
console.log('init freshslider for edges, steps:', steps)
var edgeSlideTimeout = null
//finished //finished
$(sliderDivID).freshslider({ $(sliderDivID).freshslider({
range: true, range: true,
...@@ -462,7 +474,21 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -462,7 +474,21 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
max:steps-1, max:steps-1,
value:[0,steps-1], value:[0,steps-1],
onchange:function(low, high) { onchange:function(low, high) {
theHtml.classList.add('waiting');
// 500ms timeout to let the waiting cursor appear
setTimeout(function() {
var totalDeletingTime = 0
// debounced
if (edgeSlideTimeout){
// console.log('clearing updated function', edgeSlideTimeout)
clearTimeout(edgeSlideTimeout)
}
// scheduled: costly graph rm edges
edgeSlideTimeout = setTimeout ( function () {
var filtervalue = low+"-"+high var filtervalue = low+"-"+high
if(filtervalue!=lastFilter[sliderDivID]["last"]) { if(filtervalue!=lastFilter[sliderDivID]["last"]) {
...@@ -472,11 +498,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -472,11 +498,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// sliderDivID+"_"+filtervalue // sliderDivID+"_"+filtervalue
setTimeout(function () {
console.log("\nprevious value "+lastvalue+" | current value "+filtervalue) console.log("\nprevious value "+lastvalue+" | current value "+filtervalue)
// [ Stopping FA2 ] // [ Stopping FA2 ]
if (TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.stopForceAtlas2(); TW.partialGraph.stopForceAtlas2();
// [ / Stopping FA2 ] // [ / Stopping FA2 ]
...@@ -532,16 +558,18 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -532,16 +558,18 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// console.log("\t\tsource:("+TW.Nodes[n[0]].x+","+TW.Nodes[n[0]].y+") ||| target:("+TW.Nodes[n[1]].x+","+TW.Nodes[n[1]].y+")") // console.log("\t\tsource:("+TW.Nodes[n[0]].x+","+TW.Nodes[n[0]].y+") ||| target:("+TW.Nodes[n[1]].x+","+TW.Nodes[n[1]].y+")")
add1Elem(ID) add1Elem(ID)
} else { } else {
for (var n in TW.partialGraph._core.graph.nodesIndex) { // this fragment broken
sid = TW.Edges[ID].sourceID console.error("TODO Unimplemented after port to 1.2")
tid = TW.Edges[ID].targetID // for (var n in TW.partialGraph._core.graph.nodesIndex) {
if (sid==n || tid==n) { // sid = TW.Edges[ID].sourceID
if(TW.partialGraph.graph.nodes(sid).hidden) unHide(sid) // tid = TW.Edges[ID].targetID
if(TW.partialGraph.graph.nodes(tid).hidden) unHide(tid) // if (sid==n || tid==n) {
add1Elem(ID) // if(TW.partialGraph.graph.nodes(sid).hidden) unHide(sid)
// console.log("\tADD "+ID) // if(TW.partialGraph.graph.nodes(tid).hidden) unHide(tid)
} // add1Elem(ID)
} // // console.log("\tADD "+ID)
// }
// }
} }
} }
...@@ -553,9 +581,19 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -553,9 +581,19 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
for(var id in ids) { for(var id in ids) {
ID = ids[id] ID = ids[id]
if(!isUndef(TW.partialGraph.graph.edges(ID))) { if(!isUndef(TW.partialGraph.graph.edges(ID))) {
TW.partialGraph.dropEdge(ID) var t0 = performance.now()
TW.partialGraph.graph.dropEdge(ID)
var t1 = performance.now()
TW.Edges[ID].lock = true; TW.Edges[ID].lock = true;
// usually very long b/c sigma has to update indexes
// <=> shift same arrays many times
totalDeletingTime += (t1-t0)
// POSS ideally: implement a batch dropEdges
// or use graph.clear and rebuild the rest
// console.log("\tDEL "+ID) // console.log("\tDEL "+ID)
// n = ID.split(";") // n = ID.split(";")
// if(n.length>1) // if(n.length>1)
// console.log("\t\tsource:("+TW.Nodes[n[0]].x+","+TW.Nodes[n[0]].y+") ||| target:("+TW.Nodes[n[1]].x+","+TW.Nodes[n[1]].y+")") // console.log("\t\tsource:("+TW.Nodes[n[0]].x+","+TW.Nodes[n[0]].y+") ||| target:("+TW.Nodes[n[1]].x+","+TW.Nodes[n[1]].y+")")
...@@ -565,29 +603,44 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) { ...@@ -565,29 +603,44 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
} }
} }
TW.partialGraph.render() if (delflag)
console.info('totalDeletingTime', totalDeletingTime)
// console.log("\t\tedgesfilter:") // console.log("\t\tedgesfilter:")
// console.log("\t\t[ Starting FA2 ]") // console.log("\t\t[ Starting FA2 ]")
// [ Starting FA2 ] // [ Starting FA2 ]
if (!TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.startForceAtlas2();
setTimeout(function(){ setTimeout(function(){
fa2enabled=true; TW.partialGraph.startForceAtlas2(); if (TW.partialGraph.isForceAtlas2Running())
setTimeout(function(){
TW.partialGraph.stopForceAtlas2(); TW.partialGraph.stopForceAtlas2();
}, },
5000); 3000);
},
10);
// [ / Starting FA2 ] // [ / Starting FA2 ]
lastvalue = filtervalue; lastvalue = filtervalue;
}, 300);
pushFilterValue( sliderDivID , filtervalue ) pushFilterValue( sliderDivID , filtervalue )
} }
setTimeout( function() {
theHtml.classList.remove('waiting')
}, 20)
}, 100) // debounce timeout
}, 500) // wait cursor timeout
} }
}); });
} }
// Execution modes: // Execution modes:
// NodeWeightFilter ( "#sliderANodeWeight" , "Document" , "type" , "size") // NodeWeightFilter ( "#sliderANodeWeight" , "Document" , "type" , "size")
// NodeWeightFilter ( "#sliderBNodeWeight" , "NGram" , "type" , "size") // NodeWeightFilter ( "#sliderBNodeWeight" , "NGram" , "type" , "size")
...@@ -608,7 +661,7 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -608,7 +661,7 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
// type_attrb = "type" // type_attrb = "type"
// criteria = "size" // criteria = "size"
if(TW.partialGraph.graph.nodes().length < 3) { if(TW.nNodes < 3) {
$(sliderDivID).freshslider({ $(sliderDivID).freshslider({
range: true, range: true,
...@@ -632,6 +685,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -632,6 +685,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
var steps = filterparams["steps"] var steps = filterparams["steps"]
var finalarray = filterparams["finalarray"] var finalarray = filterparams["finalarray"]
// console.warn('NodeWeightFilter: steps', steps)
if(steps<3) { if(steps<3) {
$(sliderDivID).freshslider({ $(sliderDivID).freshslider({
range: true, range: true,
...@@ -645,6 +700,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -645,6 +700,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
return; return;
} }
var nodeSlideTimeout = null
//finished //finished
$(sliderDivID).freshslider({ $(sliderDivID).freshslider({
range: true, range: true,
...@@ -666,6 +723,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -666,6 +723,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
TW.partialGraph.stopForceAtlas2(); TW.partialGraph.stopForceAtlas2();
// [ / Stopping FA2 ] // [ / Stopping FA2 ]
// debounced
if (nodeSlideTimeout){
// console.log('clearing updated function', nodeSlideTimeout)
clearTimeout(nodeSlideTimeout)
}
// scheduled: graph rm nodes
nodeSlideTimeout = setTimeout ( function () {
for(var i in finalarray) { for(var i in finalarray) {
ids = finalarray[i] ids = finalarray[i]
if(i>=low && i<=high){ if(i>=low && i<=high){
...@@ -690,13 +757,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -690,13 +757,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
// [ Starting FA2 ] // [ Starting FA2 ]
setTimeout(function() { setTimeout(function() {
if (!TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.startForceAtlas2() TW.partialGraph.startForceAtlas2()
// duration = settings_explorerjs.fa2milliseconds // duration = settings_explorerjs.fa2milliseconds
setTimeout(function() { setTimeout(function() {
if (TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.stopForceAtlas2() TW.partialGraph.stopForceAtlas2()
}, parseInt(fa2milliseconds) || 5000) }, parseInt(fa2milliseconds) || 5000)
}, 10) }, 10)
// [ / Starting FA2 ] // [ / Starting FA2 ]
}, 300)
} }
} }
...@@ -706,7 +776,7 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit ...@@ -706,7 +776,7 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
// new sigma.js nodesIndex and edgesIndex are private attributes so we use getters // new sigma.js nodesIndex and edgesIndex are private attributes so we use getters
function getGraphElement(elemId) { function getGraphElement(elemId) {
if(elemId.split(";").length==1) return TW.partialGraph.graph.nodes(elemId); if(elemId.split(";").length==1) return TW.partialGraph.graph.nodes(elemId);
else return TW.partialGraph.graph.nodes(elemId) else return TW.partialGraph.graph.edges(elemId)
} }
...@@ -737,7 +807,9 @@ function AlgorithmForSliders( elements , type_attrb , type , criteria) { ...@@ -737,7 +807,9 @@ function AlgorithmForSliders( elements , type_attrb , type , criteria) {
return { "steps":0 , "finalarray":[] }; return { "steps":0 , "finalarray":[] };
// identifying if you received nodes or edges // identifying if you received nodes or edges
var edgeflag = ( !isNaN(elems.slice(-1)[0].id) || elems.slice(-1)[0].id.split(";").length>1)? true : false; var edgeflag = (elems[0].id.split(";").length>1);
console.log("AlgorithmForSliders edgeflag", edgeflag)
// // ( 2 ) // // ( 2 )
// // extract [ "edgeID" : edgeWEIGHT ] | [ "nodeID" : nodeSIZE ] // // extract [ "edgeID" : edgeWEIGHT ] | [ "nodeID" : nodeSIZE ]
// // and save this into edges_weight | nodes_size // // and save this into edges_weight | nodes_size
......
...@@ -456,11 +456,11 @@ if(RES["OK"]) { ...@@ -456,11 +456,11 @@ if(RES["OK"]) {
$("#changetype").hide(); $("#changetype").hide();
$("#taboppos").remove(); $("#taboppos").remove();
if (TW.catSem && TW.catSoc) { // if (TW.catSem && TW.catSoc) {
setTimeout(function () { setTimeout(function () {
document.querySelector('.etabs a[href="#tabs2"]').click() document.querySelector('.etabs a[href="#tabs2"]').click()
}, 500); }, 500);
} // }
} }
ChangeGraphAppearanceByAtt(true) ChangeGraphAppearanceByAtt(true)
...@@ -479,4 +479,9 @@ document.getElementById("graph-panels").style.display = "block" ...@@ -479,4 +479,9 @@ document.getElementById("graph-panels").style.display = "block"
// grey message in the search bar from settings // grey message in the search bar from settings
$("#searchinput").attr('placeholder', TW.strSearchBar) ; $("#searchinput").attr('placeholder', TW.strSearchBar) ;
setTimeout( function() {
theHtml.classList.remove('waiting')
}, 20)
console.log("finish") console.log("finish")
...@@ -671,17 +671,25 @@ function add1Elem(id) { ...@@ -671,17 +671,25 @@ function add1Elem(id) {
} }
} else { // It's an edge! } else { // It's an edge!
if(!isUndef(TW.partialGraph.graph.edges(id))) return; if(!isUndef(TW.partialGraph.graph.edges(id))) return;
if(TW.Edges[id] && !TW.Edges[id].lock){ var e = TW.Edges[id]
if(e && !e.lock){
var computedColorInfo = sigmaTools.edgeColor(e.source, e.target, TW.Nodes)
// var present = TW.partialGraph.states.slice(-1)[0]; // var present = TW.partialGraph.states.slice(-1)[0];
var anedge = { var anedge = {
id: id, id: id,
sourceID: TW.Edges[id].source, source: e.source,
targetID: TW.Edges[id].target, target: e.target,
lock : false, lock : false,
label: TW.Edges[id].label, hidden: false,
type: TW.Edges[id].type, label: e.label,
categ: TW.Edges[id].categ, type: e.type,
weight: TW.Edges[id].weight // categ: e.categ,
weight: e.weight,
customAttrs : {
grey: 0,
true_color : computedColorInfo.res,
rgb : computedColorInfo.rgb_array
}
}; };
TW.partialGraph.graph.addEdge(anedge); TW.partialGraph.graph.addEdge(anedge);
......
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