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;
.fsslider {
text-align: center;
line-height: 8px;
font-size: 8px;
font-size: 10px;
font-family: "Lucida Grande", "Trebuchet MS";
}
.fsslider > * {
......
......@@ -107,7 +107,7 @@ html, body {
margin: 10px 0 0 0 ;
}
#defaultop .settingslider {
max-width: 120px !important;
max-width: 90px !important;
display: inline-block ;
}
......@@ -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 @@
caretRight.css({
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),
'z-index':isRight?1:0
});
......
......@@ -185,17 +185,28 @@ function SelectionEngine() {
else ndsids=nodes;
for(var i in ndsids) {
var s = ndsids[i];
if(TW.Relations[typeNow] && TW.Relations[typeNow][s] ) {
var neigh = TW.Relations[typeNow][s]
if(neigh) {
for(var j in neigh) {
var t = neigh[j]
// we add as neighbor to color it (except if already in targeted)
if (!nodes_2_colour[t]) nodes_2_colour[t]=false;
// highlight edges (except if n hidden or e dropped (<=> lock))
// 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[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') {
sameSideNeighbors[t]=0
}
......@@ -203,6 +214,7 @@ function SelectionEngine() {
}
}
}
}
// we make the selected (source) node active too
nodes_2_colour[s]=true;
......
'use strict;'
// always useful
var theHtml = document.getElementsByTagName('html')[0]
//============================ < NEW BUTTONS > =============================//
// Documentation Level: *****
......@@ -390,10 +394,15 @@ function changeLevel() {
//=========================== < FILTERS-SLIDERS > ===========================//
// Execution modes:
// EdgeWeightFilter("#sliderAEdgeWeight", "label" , "nodes1", "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) {
// if ($(sliderDivID).html()!="") {
// console.log("\t\t\t\t\t\t[[ algorithm not applied "+sliderDivID+" ]]")
......@@ -410,7 +419,28 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// type_attrb = "type"
// 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({
// range: true,
// step:1,
......@@ -423,29 +453,6 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// 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));
......@@ -453,6 +460,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
var present = TW.partialGraph.states.slice(-1)[0];
console.log('init freshslider for edges, steps:', steps)
var edgeSlideTimeout = null
//finished
$(sliderDivID).freshslider({
range: true,
......@@ -462,7 +474,21 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
max:steps-1,
value:[0,steps-1],
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
if(filtervalue!=lastFilter[sliderDivID]["last"]) {
......@@ -472,11 +498,11 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
// sliderDivID+"_"+filtervalue
setTimeout(function () {
console.log("\nprevious value "+lastvalue+" | current value "+filtervalue)
// [ Stopping FA2 ]
if (TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.stopForceAtlas2();
// [ / Stopping FA2 ]
......@@ -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+")")
add1Elem(ID)
} else {
for (var n in TW.partialGraph._core.graph.nodesIndex) {
sid = TW.Edges[ID].sourceID
tid = TW.Edges[ID].targetID
if (sid==n || tid==n) {
if(TW.partialGraph.graph.nodes(sid).hidden) unHide(sid)
if(TW.partialGraph.graph.nodes(tid).hidden) unHide(tid)
add1Elem(ID)
// console.log("\tADD "+ID)
}
}
// this fragment broken
console.error("TODO Unimplemented after port to 1.2")
// for (var n in TW.partialGraph._core.graph.nodesIndex) {
// sid = TW.Edges[ID].sourceID
// tid = TW.Edges[ID].targetID
// if (sid==n || tid==n) {
// if(TW.partialGraph.graph.nodes(sid).hidden) unHide(sid)
// 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) {
for(var id in ids) {
ID = ids[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;
// 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)
// n = ID.split(";")
// 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+")")
......@@ -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\t[ Starting FA2 ]")
// [ Starting FA2 ]
if (!TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.startForceAtlas2();
setTimeout(function(){
fa2enabled=true; TW.partialGraph.startForceAtlas2();
setTimeout(function(){
if (TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.stopForceAtlas2();
},
5000);
},
10);
3000);
// [ / Starting FA2 ]
lastvalue = filtervalue;
}, 300);
pushFilterValue( sliderDivID , filtervalue )
}
setTimeout( function() {
theHtml.classList.remove('waiting')
}, 20)
}, 100) // debounce timeout
}, 500) // wait cursor timeout
}
});
}
// Execution modes:
// NodeWeightFilter ( "#sliderANodeWeight" , "Document" , "type" , "size")
// NodeWeightFilter ( "#sliderBNodeWeight" , "NGram" , "type" , "size")
......@@ -608,7 +661,7 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
// type_attrb = "type"
// criteria = "size"
if(TW.partialGraph.graph.nodes().length < 3) {
if(TW.nNodes < 3) {
$(sliderDivID).freshslider({
range: true,
......@@ -632,6 +685,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
var steps = filterparams["steps"]
var finalarray = filterparams["finalarray"]
// console.warn('NodeWeightFilter: steps', steps)
if(steps<3) {
$(sliderDivID).freshslider({
range: true,
......@@ -645,6 +700,8 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
return;
}
var nodeSlideTimeout = null
//finished
$(sliderDivID).freshslider({
range: true,
......@@ -666,6 +723,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
TW.partialGraph.stopForceAtlas2();
// [ / 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) {
ids = finalarray[i]
if(i>=low && i<=high){
......@@ -690,13 +757,16 @@ function NodeWeightFilter( categories , sliderDivID , type_attrb , type , crit
// [ Starting FA2 ]
setTimeout(function() {
if (!TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.startForceAtlas2()
// duration = settings_explorerjs.fa2milliseconds
setTimeout(function() {
if (TW.partialGraph.isForceAtlas2Running())
TW.partialGraph.stopForceAtlas2()
}, parseInt(fa2milliseconds) || 5000)
}, 10)
// [ / Starting FA2 ]
}, 300)
}
}
......@@ -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
function getGraphElement(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) {
return { "steps":0 , "finalarray":[] };
// 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 )
// // extract [ "edgeID" : edgeWEIGHT ] | [ "nodeID" : nodeSIZE ]
// // and save this into edges_weight | nodes_size
......
......@@ -456,11 +456,11 @@ if(RES["OK"]) {
$("#changetype").hide();
$("#taboppos").remove();
if (TW.catSem && TW.catSoc) {
// if (TW.catSem && TW.catSoc) {
setTimeout(function () {
document.querySelector('.etabs a[href="#tabs2"]').click()
}, 500);
}
// }
}
ChangeGraphAppearanceByAtt(true)
......@@ -479,4 +479,9 @@ document.getElementById("graph-panels").style.display = "block"
// grey message in the search bar from settings
$("#searchinput").attr('placeholder', TW.strSearchBar) ;
setTimeout( function() {
theHtml.classList.remove('waiting')
}, 20)
console.log("finish")
......@@ -671,17 +671,25 @@ function add1Elem(id) {
}
} else { // It's an edge!
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 anedge = {
id: id,
sourceID: TW.Edges[id].source,
targetID: TW.Edges[id].target,
source: e.source,
target: e.target,
lock : false,
label: TW.Edges[id].label,
type: TW.Edges[id].type,
categ: TW.Edges[id].categ,
weight: TW.Edges[id].weight
hidden: false,
label: e.label,
type: e.type,
// categ: e.categ,
weight: e.weight,
customAttrs : {
grey: 0,
true_color : computedColorInfo.res,
rgb : computedColorInfo.rgb_array
}
};
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