Commit 82a36d00 authored by Romain Loth's avatar Romain Loth

finish inits restructuration allowing repeated graph load

old initListeners split in three: initGUIListeners and initSearchListeners that are run once at page load, and initSigmaListeners that is run for each new graph open from local file... also env function and CSS for the local graph file input
parent 279768e3
...@@ -437,6 +437,8 @@ ...@@ -437,6 +437,8 @@
<div id="topPapers"></div> <div id="topPapers"></div>
<div id="localInput"></div>
<div id="information"></div> <div id="information"></div>
<!-- <!--
......
...@@ -269,6 +269,21 @@ p.micromessage{ ...@@ -269,6 +269,21 @@ p.micromessage{
font-size:80%; font-size:80%;
} }
#localInput {
font-size: 80%;
padding: 10px;
}
#localgraphfile {
margin-left: auto ;
margin-right: auto ;
}
.comment {
padding: 10px
}
.centered { .centered {
text-align: center; text-align: center;
} }
......
...@@ -40,7 +40,8 @@ var TW = {} ...@@ -40,7 +40,8 @@ var TW = {}
TW.SystemStates = {} TW.SystemStates = {}
TW.SystemStates.level = true; TW.SystemStates.level = true;
TW.SystemStates.type = [ true ] //[ true , false ]; //social activated! // TW.SystemStates.type = [ true ] //[ true , false ]; //social activated!
TW.SystemStates.type = [ true, false ] //[ true , false ]; //social activated!
TW.SystemStates.selections = []; TW.SystemStates.selections = [];
TW.SystemStates.opposites = []; TW.SystemStates.opposites = [];
TW.catSoc = "Document"; TW.catSoc = "Document";
...@@ -119,7 +120,7 @@ TW.customLegendsBins = { ...@@ -119,7 +120,7 @@ TW.customLegendsBins = {
TW.debugFlags = { TW.debugFlags = {
initialShowAll: false, // show all nodes on bipartite case init (docs + terms) initialShowAll: false, // show all nodes on bipartite case init (docs + terms in one view)
// show verbose console logs... // show verbose console logs...
logFetchers: false, // ...about ajax/fetching of graph data logFetchers: false, // ...about ajax/fetching of graph data
......
...@@ -470,28 +470,14 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -470,28 +470,14 @@ TinaWebJS = function ( sigmacanvas ) {
if (TW.debugFlags.logSettings) console.log('tw renderers registered in sigma module') if (TW.debugFlags.logSettings) console.log('tw renderers registered in sigma module')
} }
this.SearchListeners = function () { this.initSearchListeners = function () {
// REFA tempo expose var SelInst = new SelectionEngine();
// var SelInst = new SelectionEngine();
SelInst = new SelectionEngine();
//~ $.ui.autocomplete.prototype._renderItem = function(ul, item) {
//~ var searchVal = $("#searchinput").val();
//~ var desc = extractContext(item.desc, searchVal);
//~ return $('<li onclick=\'var s = "'+item.label+'"; search(s);$("#searchinput").val(strSearchBar);\'></li>')
//~ .data('item.autocomplete', item)
//~ .append("<a><span class=\"labelresult\">" + item.label + "</span></a>" )
//~ .appendTo(ul);
//~ };
$('input#searchinput').autocomplete({ $('input#searchinput').autocomplete({
source: function(request, response) { source: function(request, response) {
// console.log("in autocomplete:")
// labels initialized in settings, filled in updateSearchLabels // labels initialized in settings, filled in updateSearchLabels
// console.log(labels.length) // console.log(labels.length)
// console.log(" - - - - - - - - - ")
matches = []; matches = [];
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
// grep at heart // grep at heart
...@@ -646,18 +632,8 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -646,18 +632,8 @@ TinaWebJS = function ( sigmacanvas ) {
}); });
} }
// external usage: SelectorEngine*() , MultipleSelection2() , // to init handlers for tina GUI environment (run once on page load)
// enviroment.js:changeType()|changeLevel()|NodeWeightFilter()|EdgeWeightFilter this.initGUIListeners = function () {
this.initListeners = function (categories, partialGraph) {
var SelInst = new SelectionEngine();
document.getElementById('edges-switch').checked = TW.customSettings.drawEdges
// £TODO test if still needed
$("#semLoader").hide();
$("#closeloader").click();
var body=document.getElementsByTagName('body')[0]; var body=document.getElementsByTagName('body')[0];
body.style.paddingTop="41px"; body.style.paddingTop="41px";
...@@ -738,16 +714,8 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -738,16 +714,8 @@ TinaWebJS = function ( sigmacanvas ) {
} }
}); });
// £TODO test if still needed
pushSWClick("social");
cancelSelection(false);
$("#tips").html(getTips()); $("#tips").html(getTips());
// a bit costly, TODO make conditional or deprecated // a bit costly, TODO make conditional or deprecated
// showMeSomeLabels(6); // showMeSomeLabels(6);
...@@ -756,181 +724,12 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -756,181 +724,12 @@ TinaWebJS = function ( sigmacanvas ) {
// #saveAs => toggle #savemodal initialized in html + bootstrap-native // #saveAs => toggle #savemodal initialized in html + bootstrap-native
this.SearchListeners();
// button CENTER // button CENTER
$("#lensButton").click(function () { $("#lensButton").click(function () {
// new sigma.js // new sigma.js
partialGraph.camera.goTo({x:0, y:0, ratio:1.2}) partialGraph.camera.goTo({x:0, y:0, ratio:1.2})
}); });
// ---------------------------------------------------------------------
// new sigma.js: sigma events bindings
// ---------------------
// cf. https://github.com/jacomyal/sigma.js/wiki/Events-API
// cases:
// 'click' - simple click, early event
// used for area (with global: cursor_size)
// 'clickNode'- simple click, second event if one node
// POSS easy in new sigma.js:
// add doubleClick to select node + neighboors
// when circle area select
// ========================
// 1st event, even before we know if there are nodes
TW.partialGraph.bind('click', function(e) {
// console.log("sigma click event e", e)
// case with a selector circle cursor handled here
if (cursor_size > 0) {
// actual click position, but in graph coords
var x = e.data.x
var y = e.data.y
// convert
var camCoords = TW.cam.cameraPosition(x,y)
// retrieve area nodes, using indexed quadtree and global cursor_size
var circleNodes = circleGetAreaNodes(
camCoords.x,
camCoords.y
)
// 1) clear previous while keeping its list (useful iff 'Add' checkBox)
var previousSelection = selections
cancelSelection(false)
// 2) show selection + do all related effects
var targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
currsels:circleNodes,
prevsels:previousSelection
} )
if(targeted.length>0) {
SelInst.MultipleSelection2( {nodes:targeted} )
}
}
})
// when one node and normal click
// ===============================
TW.partialGraph.bind('clickNode', function(e) {
// console.log("clickNode event e", e.data.node)
// 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 (cursor_size == 0) {
var targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
currsels:[theNodeId],
prevsels:previousSelection
} )
if(targeted.length>0) {
SelInst.MultipleSelection2( {nodes:targeted} )
}
}
// case with a selector circle cursor handled
// just before, at click event
})
// when click in the empty background
// ==================================
if (TW.deselectOnclickStage) {
TW.partialGraph.bind('clickStage', function(e) {
// console.log("clickStage event e", e)
if (! e.data.captor.isDragging
&& Object.keys(selections).length
&& ! cursor_size) {
// we clear selections and all its effects
cancelSelection(false);
}
})
}
// for all TW.cam.goTo (move/zoom) events
// ===============
var zoomTimeoutId = null
TW.cam.bind('coordinatesUpdated', function(e) {
$("#zoomSlider").slider("value",1/TW.cam.ratio)
})
// ---------------------------------------------------------------------
// POSS: bind to captors (0=>mouse, 1=>touch)
// TW.rend.captors[0].bind('mousemove', function(e) {
// console.log("mousemove event e", e.data.node)
//
// })
// ---------------------------------------------------------------------
// raw events (non-sigma): handlers attached to the container
// ==========
$("#sigma-contnr")
.mousemove(function(e){
if(!isUndef(partialGraph)) {
// show/move selector circle cursor
if(cursor_size>0) circleTrackMouse(e);
}
})
// POSSible for the future: add tools to contextmenu
// .contextmenu(function(){
// return false;
// })
// sliders events
// ==============
$("#zoomSlider").slider({
orientation: "vertical",
// new sigma.js current zoom ratio
value: partialGraph.camera.ratio,
min: 1 / sigmaJsMouseProperties.maxRatio, // ex x.5
max: 1 / sigmaJsMouseProperties.minRatio, // ex x32
// range: true,
step: .2,
value: 1,
slide: function( event, ui ) {
partialGraph.camera.goTo({
// POSS: make a transform to increase detail around x = 1
ratio: 1 / ui.value
});
}
});
$("#zoomPlusButton").click(function () {
var newRatio = TW.cam.ratio * .75
if (newRatio >= sigmaJsMouseProperties.minRatio) {
// triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio});
return false;
}
});
$("#zoomMinusButton").click(function () {
var newRatio = TW.cam.ratio * 1.25
if (newRatio <= sigmaJsMouseProperties.maxRatio) {
// triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio});
return false;
}
});
$("#layoutButton").click(function () { $("#layoutButton").click(function () {
sigma_utils.smartForceAtlas() sigma_utils.smartForceAtlas()
}); });
...@@ -964,77 +763,6 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -964,77 +763,6 @@ TinaWebJS = function ( sigmacanvas ) {
}); });
if (TW.filterSliders) {
// args: for display: target div ,
// for context: family/type prop value,
// for values: the property to filter
NodeWeightFilter ( "#slidercat0nodesweight" ,
categories[0] ,
"size"
);
EdgeWeightFilter("#slidercat0edgesweight",
getCurrentTypeString(),
"weight"
);
}
$("#category1").hide();
//finished
var labelSizeTimeout = null
$("#sliderlabelsize").freshslider({
step:.25,
min:0,
max:5,
value: TW.partialGraph.settings('labelSizeRatio'),
bgcolor:"#27c470",
onchange:function(value){
if (labelSizeTimeout) {
clearTimeout(labelSizeTimeout)
}
labelSizeTimeout = setTimeout(function(){
if (TW.partialGraph.settings('labelSizeRatio') != value) {
var adaptedLabelThreshold = 7 - value
// console.log("value", value, "thres", adaptedLabelThreshold)
TW.partialGraph.settings('labelSizeRatio', value)
TW.partialGraph.settings('labelThreshold', adaptedLabelThreshold)
TW.partialGraph.render()
}
}, 200)
}
});
// //finished
// $("#slidercat1nodessize").freshslider({
// step:1,
// min:-20,
// max:20,
// value:0,
// bgcolor:"#FFA500",
// onchange:function(value){
// setTimeout(function (){
// // new sigma.js loop on nodes POSS optimize
// nds = TW.partialGraph.graph.nodes()
// console.log("init: slider resize")
// for(j=0 ; j<TW.partialGraph.nNodes ; j++){
// if (nds[j]
// && nds[j].type == TW.catSem) {
// var n = nds[j]
// var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3
// n.size = (newval<1.0)?1:newval;
// sizeMult[TW.catSem] = parseFloat(value-1)*0.3;
// }
// }
// partialGraph.render()
// },
// 100);
// }
// });
//Cursor Size slider //Cursor Size slider
var cursorSlider = $("#unranged-value").freshslider({ var cursorSlider = $("#unranged-value").freshslider({
step: 1, step: 1,
...@@ -1052,14 +780,33 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1052,14 +780,33 @@ TinaWebJS = function ( sigmacanvas ) {
cursorSlider.setValue(0) cursorSlider.setValue(0)
}); });
// general listener: shift key in the window <=> add to selection // //finished
$(document).on('keyup keydown', function(e){ // $("#slidercat1nodessize").freshslider({
// changes the global boolean ("add node to selection" status) if keydown and SHIFT // step:1,
checkBox = manuallyChecked || e.shiftKey // min:-20,
// max:20,
// value:0,
// bgcolor:"#FFA500",
// onchange:function(value){
// setTimeout(function (){
// // new sigma.js loop on nodes POSS optimize
// nds = TW.partialGraph.graph.nodes()
// console.log("init: slider resize")
// for(j=0 ; j<TW.partialGraph.nNodes ; j++){
// if (nds[j]
// && nds[j].type == TW.catSem) {
// var n = nds[j]
// var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3
// n.size = (newval<1.0)?1:newval;
// sizeMult[TW.catSem] = parseFloat(value-1)*0.3;
// }
// }
// partialGraph.render()
// },
// 100);
// }
// });
// show it in the real checkbox too
$('#checkboxdiv').prop("checked", manuallyChecked || e.shiftKey)
} );
// costly entire refresh (~400ms) only after stopped resizing for 3s // costly entire refresh (~400ms) only after stopped resizing for 3s
// NB: rescale middleware already reacted and, except for large win size changes, it handles the resize fine // NB: rescale middleware already reacted and, except for large win size changes, it handles the resize fine
...@@ -1071,13 +818,243 @@ TinaWebJS = function ( sigmacanvas ) { ...@@ -1071,13 +818,243 @@ TinaWebJS = function ( sigmacanvas ) {
} }
winResizeTimeout = setTimeout(function() { winResizeTimeout = setTimeout(function() {
console.log('did refresh') console.log('did refresh')
TW.partialGraph.refresh()
if (window.TW.partialGraph && window.TW.partialGraph.refresh) {
window.TW.partialGraph.refresh()
}
if (theHtml.classList) { if (theHtml.classList) {
theHtml.classList.remove('waiting'); theHtml.classList.remove('waiting');
} }
}, 3000) }, 3000)
}, true) }, true)
} // finish initListeners
// general listener: shift key in the window <=> add to selection
$(document).on('keyup keydown', function(e){
// changes the global boolean ("add node to selection" status) if keydown and SHIFT
checkBox = manuallyChecked || e.shiftKey
// show it in the real checkbox too
$('#checkboxdiv').prop("checked", manuallyChecked || e.shiftKey)
} );
} // finish envListeners
// to init local, instance-related listeners (need to run at new sigma instance)
// args: @partialGraph = a sigma instance
this.SigmaListeners = function(partialGraph) {
var SelInst = new SelectionEngine();
// sigma events bindings
// ---------------------
// cf. https://github.com/jacomyal/sigma.js/wiki/Events-API
// cases:
// 'click' - simple click, early event
// used for area (with global: cursor_size)
// 'clickNode'- simple click, second event if one node
// POSS easy in new sigma.js:
// add doubleClick to select node + neighboors
// when circle area select
// ========================
// 1st event, even before we know if there are nodes
partialGraph.bind('click', function(e) {
// console.log("sigma click event e", e)
// case with a selector circle cursor handled here
if (cursor_size > 0) {
// actual click position, but in graph coords
var x = e.data.x
var y = e.data.y
// convert
var camCoords = TW.cam.cameraPosition(x,y)
// retrieve area nodes, using indexed quadtree and global cursor_size
var circleNodes = circleGetAreaNodes(
camCoords.x,
camCoords.y
)
// 1) clear previous while keeping its list (useful iff 'Add' checkBox)
var previousSelection = selections
cancelSelection(false)
// 2) show selection + do all related effects
var targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
currsels:circleNodes,
prevsels:previousSelection
} )
if(targeted.length>0) {
SelInst.MultipleSelection2( {nodes:targeted} )
}
}
})
// when one node and normal click
// ===============================
partialGraph.bind('clickNode', function(e) {
// console.log("clickNode event e", e.data.node)
// 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 (cursor_size == 0) {
var targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
currsels:[theNodeId],
prevsels:previousSelection
} )
if(targeted.length>0) {
SelInst.MultipleSelection2( {nodes:targeted} )
}
}
// case with a selector circle cursor handled
// just before, at click event
})
// when click in the empty background
// ==================================
if (TW.deselectOnclickStage) {
partialGraph.bind('clickStage', function(e) {
// console.log("clickStage event e", e)
if (! e.data.captor.isDragging
&& Object.keys(selections).length
&& ! cursor_size) {
// we clear selections and all its effects
cancelSelection(false);
}
})
}
// for all TW.cam.goTo (move/zoom) events
// ===============
var zoomTimeoutId = null
TW.cam.bind('coordinatesUpdated', function(e) {
$("#zoomSlider").slider("value",1/TW.cam.ratio)
})
// ---------------------------------------------------------------------
// POSS: bind to captors (0=>mouse, 1=>touch)
// TW.rend.captors[0].bind('mousemove', function(e) {
// console.log("mousemove event e", e.data.node)
//
// })
// ---------------------------------------------------------------------
// raw events (non-sigma): handlers attached to the container
// ==========
$("#sigma-contnr")
.mousemove(function(e){
if(!isUndef(partialGraph)) {
// show/move selector circle cursor
if(cursor_size>0) circleTrackMouse(e);
}
})
// POSSible for the future: add tools to contextmenu
// .contextmenu(function(){
// return false;
// })
// sliders events
// ==============
$("#zoomSlider").slider({
orientation: "vertical",
// new sigma.js current zoom ratio
value: partialGraph.camera.ratio,
min: 1 / sigmaJsMouseProperties.maxRatio, // ex x.5
max: 1 / sigmaJsMouseProperties.minRatio, // ex x32
// range: true,
step: .2,
value: 1,
slide: function( event, ui ) {
partialGraph.camera.goTo({
// POSS: make a transform to increase detail around x = 1
ratio: 1 / ui.value
});
}
});
$("#zoomPlusButton").click(function () {
var newRatio = TW.cam.ratio * .75
if (newRatio >= sigmaJsMouseProperties.minRatio) {
// triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio});
return false;
}
});
$("#zoomMinusButton").click(function () {
var newRatio = TW.cam.ratio * 1.25
if (newRatio <= sigmaJsMouseProperties.maxRatio) {
// triggers coordinatesUpdated which sets the slider cursor
partialGraph.camera.goTo({ratio: newRatio});
return false;
}
});
if (TW.filterSliders) {
// args: for display: target div ,
// for context: family/type prop value,
// for values: the property to filter
NodeWeightFilter ( "#slidercat0nodesweight" ,
TW.categories[0] ,
"size"
);
EdgeWeightFilter("#slidercat0edgesweight",
getCurrentTypeString(),
"weight"
);
}
// node's label size
var labelSizeTimeout = null
$("#sliderlabelsize").freshslider({
step:.25,
min:0,
max:5,
value: sigmaJsDrawingProperties['labelSizeRatio'] || 1,
bgcolor:"#27c470",
onchange:function(value){
if (labelSizeTimeout) {
clearTimeout(labelSizeTimeout)
}
labelSizeTimeout = setTimeout(function(){
if (TW.partialGraph.settings('labelSizeRatio') != value) {
var adaptedLabelThreshold = 7 - value
// console.log("value", value, "thres", adaptedLabelThreshold)
TW.partialGraph.settings('labelSizeRatio', value)
TW.partialGraph.settings('labelThreshold', adaptedLabelThreshold)
TW.partialGraph.render()
}
}, 200)
}
});
document.getElementById('edges-switch').checked = TW.customSettings.drawEdges
cancelSelection(false);
}
}; };
...@@ -7,6 +7,71 @@ function writeBrand (brandString) { ...@@ -7,6 +7,71 @@ function writeBrand (brandString) {
document.getElementById('twbrand').innerHTML = brandString document.getElementById('twbrand').innerHTML = brandString
} }
function createFilechooserEl () {
var inputComment = document.createElement("p")
inputComment.innerHTML = `<strong>Choose a graph from your filesystem (gexf or json).</strong>`
inputComment.classList.add('comment')
inputComment.classList.add('centered')
var graphFileInput = document.createElement('input')
graphFileInput.id = 'localgraphfile'
graphFileInput.type = 'file'
graphFileInput.accept = 'application/xml,application/gexf,application/json'
graphFileInput.classList.add('centered')
// NB file input will trigger mainStartGraph() when the user chooses something
graphFileInput.onchange = function() {
if (this.files && this.files[0]) {
let clientLocalGraphFile = this.files[0]
// determine the format
let theFormat
if (/\.(?:gexf|xml)$/.test(clientLocalGraphFile.name)) {
theFormat = 'gexf'
}
else if (/\.json$/.test(clientLocalGraphFile.name)) {
theFormat = 'json'
}
else {
alert('unrecognized file format')
}
// retrieving the content
let rdr = new FileReader()
rdr.onload = function() {
if (! rdr.result || !rdr.result.length) {
alert('the selected file is not readable')
}
else {
// we might have a previous graph opened
if (TW.partialGraph && TW.partialGraph.graph) {
TW.partialGraph.graph.clear()
TW.partialGraph.refresh()
selections = []
}
// run
if (theFormat == 'json')
mainStartGraph(theFormat, JSON.parse(rdr.result), TW.instance)
else
mainStartGraph(theFormat, rdr.result, TW.instance)
}
}
rdr.readAsText(clientLocalGraphFile)
}
}
var filechooserBox = document.createElement('div')
filechooserBox.appendChild(inputComment)
filechooserBox.appendChild(graphFileInput)
return filechooserBox
}
//============================ < NEW BUTTONS > =============================// //============================ < NEW BUTTONS > =============================//
// Documentation Level: ***** // Documentation Level: *****
......
...@@ -98,6 +98,10 @@ TW.instance = new TinaWebJS('#sigma-contnr'); ...@@ -98,6 +98,10 @@ TW.instance = new TinaWebJS('#sigma-contnr');
// add once our tw rendering and index customizations into sigma module // add once our tw rendering and index customizations into sigma module
TW.instance.init() TW.instance.init()
// init the button, sliders and search handlers, also only once
TW.instance.initGUIListeners();
TW.instance.initSearchListeners();
// show the custom name of the app // show the custom name of the app
writeBrand(TW.branding) writeBrand(TW.branding)
...@@ -108,58 +112,19 @@ console.log("Starting TWJS") ...@@ -108,58 +112,19 @@ console.log("Starting TWJS")
// if page is being run locally ==> only possible source shall be via file input // if page is being run locally ==> only possible source shall be via file input
if (window.location.protocol == 'file:') { if (window.location.protocol == 'file:') {
// POSS we could actually provide this local file chooser in all cases let inputDiv = document.getElementById('localInput')
var graphFileInput = document.createElement('input') inputDiv.style.display = 'block'
graphFileInput.id = 'localgraphfile'
graphFileInput.type = 'file'
graphFileInput.accept = 'application/xml,application/gexf,application/json'
document.getElementById('gexfs').appendChild(graphFileInput)
// NB file input will trigger mainStartGraph() when the user chooses something
graphFileInput.onchange = function() {
if (this.files && this.files[0]) {
let clientLocalGraphFile = this.files[0]
// determine the format
let theFormat
if (/\.(?:gexf|xml)$/.test(clientLocalGraphFile.name)) {
theFormat = 'gexf'
}
else if (/\.json$/.test(clientLocalGraphFile.name)) {
theFormat = 'json'
}
else {
alert('unrecognized file format')
}
// retrieving the content
let rdr = new FileReader()
rdr.onload = function() { var remark = document.createElement("p")
if (! rdr.result || !rdr.result.length) { remark.innerHTML = `You're running project explorer as a local html file (no syncing).`
alert('the selected file is not readable') remark.classList.add('comment')
} remark.classList.add('centered')
else { inputDiv.appendChild(remark)
// we might have a previous graph opened
if (TW.partialGraph && TW.partialGraph.graph) {
TW.partialGraph.graph.clear()
TW.partialGraph.refresh()
selections = []
}
// run // user can open a gexf or json from his fs
if (theFormat == 'json') // POSS we could actually provide this local file chooser in all cases
mainStartGraph(theFormat, JSON.parse(rdr.result), TW.instance) var graphFileInput = createFilechooserEl()
else inputDiv.appendChild(graphFileInput)
mainStartGraph(theFormat, rdr.result, TW.instance)
}
}
rdr.readAsText(clientLocalGraphFile)
}
}
} }
// traditional cases: remote read from API or prepared server-side file // traditional cases: remote read from API or prepared server-side file
else { else {
...@@ -627,6 +592,9 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -627,6 +592,9 @@ function mainStartGraph(inFormat, inData, twInstance) {
// by default category0 is the initial type // by default category0 is the initial type
$(".category1").hide(); $(".category1").hide();
// now that we have a sigma instance, let's bind our handlers to it
TW.instance.SigmaListeners(TW.partialGraph)
// [ / Poblating the Sigma-Graph ] // [ / Poblating the Sigma-Graph ]
...@@ -780,7 +748,8 @@ function mainStartGraph(inFormat, inData, twInstance) { ...@@ -780,7 +748,8 @@ function mainStartGraph(inFormat, inData, twInstance) {
// REFA new sigma.js // REFA new sigma.js
TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:0.9, angle: 0})
twInstance.initListeners(TW.categories , TW.partialGraph);
$("#category1").hide();
// mostly json data are extracts provided by DB apis => no positions // mostly json data are extracts provided by DB apis => no positions
if (inFormat == "json") TW.fa2enabled = true if (inFormat == "json") TW.fa2enabled = true
......
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