Commit 0ca4e2f3 authored by Romain Loth's avatar Romain Loth

basic version of one search bar

parent d3fcaa96
......@@ -58,15 +58,28 @@
margin: 0 ;
padding: 0;
}
/* small messages */
p.micromessage{
font-size: 85%;
color: #707070 ;
}
/* ------------- crowdsourcing proprement dit ----------------------- */
#crowdsourcing_intro{
#crowdsourcing_answer{
font-size: 85%;
color: #707070 ;
padding:0 1em ;
text-align:center ;
}
#savesuggestion.btn {
#crowdsourcing_answer p {
margin: 2px 0;
}
#savesuggestion.btn {
}
#savesuggestion.btn[disabled], #savesuggestion.btn.disabled {
background-color: #B0B0B0 ;
......
......@@ -14,8 +14,9 @@ loadCSS(module_name+"/crowdTerms.css")
loadJS(module_name+"/modal.js") ;
// histogram
loadJS(module_name+"/dygraph/dygraph.combined.js") ;
loadCSS(module_name+"/dygraph/gallery.css") ;
loadCSS(module_name+"/dygraph/textarea.css") ;
loadJS(module_name+"/dygraph/dygraph.combined.js") ;
console.log("OK LOADED " + module_name) ;
......@@ -7,8 +7,7 @@
// labels of map terms...
var Label2ID = {} ;
// ...initialized from TW.Nodes
// ...initialized from TW.Nodes (nodes' info sorted by id)
for (id in TW.Nodes) {
// console.log("label: " + TW.Nodes[id].label) ;
// console.log("id: " + id) ;
......@@ -16,71 +15,24 @@ for (id in TW.Nodes) {
}
// TODO: use ExtraWords to know already suggested terms
// var ExtraWords = {'a miam term': true} ;
// Crowdsourcing terms load
// => building the autocomplete data
// Input: Label2ID
// Output: ExtraWords
$( "#proposed_terms" ).autocomplete({
source: Object.keys(Label2ID),
// on response callback
// (only if crowdsourcingTerms module)
response: function (event, ui_response_array) {
// console.log(JSON.stringify(ui_response_array)) ;
// exemple in ui_response_array
// {"content":
// [{"label":"warning system","value":"warning system"},
// {"label":"training programme","value":"training programme"}
// ]
// }
if (ui_response_array.content.length == 0) {
// when there is no corresponding term
// the user gains the right to suggest it
$('#savesuggestion').prop('disabled', false) ;
}
else {
$('#savesuggestion').prop('disabled', true) ;
}
},
});
// autocomplete the user input
$("#proposed_terms").keypress(function(e) {
clean_histogram() ;
if(e.keyCode == 13) { //if press enter then:
e.preventDefault();
$("#search_proposed_terms").click();
$(this).autocomplete('close');
}
// (only if crowdsourcingTerms module)
clean_crowdsourcingform();
})
//method for calling the ISC-API and get pubs-distribution of the suggested term
function search_proposed_terms_and_draw( the_query ) {
// alert("i'm searching:\n"+JSON.stringify(the_query)) ;
function search_proposed_terms_and_draw( the_queries ) {
// console.log("search_proposed_terms_and_draw:\n"
// +"i'm searching:\n"
// +JSON.stringify(the_queries)) ;
$("#search_histogram").html("Searching for matching twitter data...")
var args = {
// query is an array of str
"q": the_query,
// the_queries is an array of str
"q": the_queries,
"since": 1989,
"until": 2013
}
var docs_years = [] ;
$("#search_histogram")
.html('<p class="micromessage">Waiting for histogram data</p>')
$.ajax({
type: "GET",
......@@ -91,6 +43,9 @@ function search_proposed_terms_and_draw( the_query ) {
// ES aggs response, for example
// data = {"took":91,"total":121673,"aggs":{"publicationCount":{"buckets":[{"key":1989,"doc_count":880},{"key":1990,"doc_count":1088},...,{"key":2012,"doc_count":9543},{"key":2013,"doc_count":8832}]}},"hits":{"total":121673,"max_score":0,"hits":[]}}
// console.log(">> incoming api data <<")
// console.log(data)
if(data.total==0) {
return false;
}
......@@ -102,44 +57,65 @@ function search_proposed_terms_and_draw( the_query ) {
// counts_by_year_array
draw_histogram(docs_years, "search_histogram") ;
return true ;
}
},
error: function(exception) {
console.log("exception!:"+exception.status)
$("#search_histogram").prepend(msg)
console.log("search_proposed_terms_and_draw:exception"
+ JSON.stringify(exception))
$("#search_histogram")
.html('<p class="micromessage">'
+'<b>No histogram</b>: too many nodes selected</b>'
+'</p>')
}
})
}
// input value retrieval/handling
$("#search_proposed_terms").click(function() {
// gotNodeSet event when Tinawab did main search behavior (select nodes)
$("#searchinput").on("tw:gotNodeSet", function(e) {
// console.log("event 'nodes' --> the event's nodes: " + JSON.stringify(e.nodeIds)) ;
clean_histogram() ;
clean_crowdsourcingform() ;
// now we may want to do other things (draw histogram, suggest term)
newnodesHistogramBehavior(e.nodeIds, e.q) ;
});
// eraseNodeSet event when Tinawab canceled the previous selections
$("#searchinput").on("tw:eraseNodeSet", function(e) {
// console.log("event 'erase'") ;
clean_histogram() ;
});
// emptyNodeSet event when Tinaweb search found nothing
$("#searchinput").on("tw:emptyNodeSet", function(e) {
clean_histogram() ;
});
if($("#proposed_terms").val()=="")
return false;
// var msg = "" ;
var query = $("#proposed_terms").val()
query = $.trim( query.toLowerCase() )
console.log('===\nyour query was: "'+query+'"');
if( Label2ID[query] ) {
// query : IF in the Map !!!
// -> GO to ISC-API (search it and draw it)
search_proposed_terms_and_draw ( [query] ) ;
function newnodesHistogramBehavior(selectedNodeIds, unusedQuery) {
console.log('/////////\nFUN additionalSearchBehavior' + '\nselectedNodeIds:' +JSON.stringify(selectedNodeIds) ) ;
if( selectedNodeIds != null && selectedNodeIds.length > 0 ) {
// query : IF in the Map -> GO to ISC-API (search and draw it)
var selectedLabels = [] ;
for (i in selectedNodeIds) {
var thisId = selectedNodeIds[i]
if (TW.Nodes[thisId] != null) {
selectedLabels.push(TW.Nodes[thisId].label)
}
else {
// activate save suggestion button
// (if subchain was in no autocomplete term, it's already on)
$('#savesuggestion').prop('disabled', false) ;
// save_suggestions
$("#crowdsourcing_answer").html("<p>This topic (<i>\"" + query + "\"</i> isn't in the maps. You can click the grey button to propose it as a suggestion.</p>") ;
console.log('ID error on TW.Nodes['+thisId+']')
}
}
console.log('\n\n\n<---!--->\nselectedLabels' + JSON.stringify(selectedLabels))
$("#proposed_terms").autocomplete('close');
});
search_proposed_terms_and_draw ( selectedLabels ) ;
}
}
// use dygraph lib to draw below the crowdsourcing div
......@@ -164,6 +140,7 @@ function draw_histogram(counts_by_year_array, div_id) {
counts_by_year_array,
{
labels: ['year', 'n'],
pixelsPerLabel: 25 ,
drawPoints: true,
fillGraph: true
});
......@@ -180,8 +157,48 @@ function clean_histogram() {
/* ---------------------------------------------------------------- */
/* 3 possible events affect crowdsourcing */
// catch noAutocomplete event when Tinaweb ui.autocomplete becomes empty
$("#searchinput").on("tw:noAutocomplete", function(e) {
// when there is no corresponding term
// the user gains the right to suggest it
$('#savesuggestion').prop('disabled', false) ;
});
// catch gotAutocomplete event when Tinaweb ui.autocomplete is full
$("#searchinput").on("tw:gotAutocomplete", function(e) {
$('#savesuggestion').prop('disabled', true) ;
});
// eraseNodeSet event when Tinawab had an empty search or unclick
$("#searchinput").on("tw:eraseNodeSet", function(e) {
clean_crowdsourcingzone() ;
});
// emptyNodeSet event when Tinawab had a search but with no matches
$("#searchinput").on("tw:emptyNodeSet", function(e) {
$('#savesuggestion').prop('disabled', false) ;
// when query has no match
if (e.nodeIds == null || e.nodeIds.length == 0) {
// activate save suggestion button
// (if subchain was in no autocomplete term, it's already on)
$('#savesuggestion').prop('disabled', false) ;
// save_suggestions
$("#crowdsourcing_answer").html("<p>The topic <i>\"" + e.q + "\"</i> is not in the map.</p> <p>(You can click the grey <span class=\"glyphicon glyphicon-save\"></span> button to propose it as a suggestion.)</p>") ;
// $("#searchinput").val() = query ;
}
});
$("#savesuggestion").click(function(){
var query = $("#proposed_terms").val()
var query = $("#searchinput").val()
if (typeof query != "string" || !query.length) {
query = TW.lastQuery ;
}
query = $.trim( query.toLowerCase() ) ;
save_suggestions(query) ;
})
......@@ -193,6 +210,14 @@ function save_suggestions(term) {
"date" : (new Date()).toISOString(),
"geo" : "ip and geoloc"
}
// sqlite columns in table 'terms'
// 0|source|CHAR(250)|0||0
// 1|suggestion|CHAR(250)|0||0
// 2|time|CHAR(30)|0||0
// 3|space|CHAR(100)|0||0
// 4|new|INTEGER|0||0
// console.log( "SAVE INFO:" + info )
$.ajax({
type: "POST",
......@@ -213,7 +238,7 @@ function save_suggestions(term) {
// reset state after 3 secs
setTimeout(function() {
clean_crowdsourcingform() ;
clean_crowdsourcingzone() ;
// if we want to reset the input value too
// $("#proposed_terms").val('') ;
......@@ -229,7 +254,7 @@ function save_suggestions(term) {
}
function clean_crowdsourcingform() {
function clean_crowdsourcingzone() {
$("#crowdsourcing_answer").html('') ;
$("#saveicon").removeClass("glyphicon-saved");
$("#saveicon").addClass("glyphicon-save");
......@@ -237,7 +262,6 @@ function clean_crowdsourcingform() {
}
// non utilisé si termes depuis map
//~ function get_already_suggested_terms() {
//~ $("#sendcrowds").html("...")
//~ $.ajax({
......@@ -253,7 +277,7 @@ function clean_crowdsourcingform() {
//~ setTimeout(function(){
//~ //$("#sendcrowds").html(D["#sendcrowds"]["thanks"][LA]) //showing message
//~ setTimeout(function(){
//~ clean_crowdsourcingform()
//~ clean_crowdsourcingzone()
//~ }, 3000);
//~ }, 1000);
//~ },
......@@ -265,10 +289,3 @@ function clean_crowdsourcingform() {
//~
//~ })
//~ }
// sqlite columns in table 'terms'
// 0|source|CHAR(250)|0||0
// 1|suggestion|CHAR(250)|0||0
// 2|time|CHAR(30)|0||0
// 3|space|CHAR(100)|0||0
// 4|new|INTEGER|0||0
......@@ -147,19 +147,63 @@
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a>
<input type="checkbox" id="checkboxdiv" onclick="alertCheckBox(this);">Add</input>
</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a>
<input id="searchinput" autocomplete="off" class="form-control input-sm col-lg-8" placeholder="Search" type="text">
</a></li>
</ul>
<div class="colorgraph_div"></div>
<div class="container" >
<div class='row' id="searchnav">
<!-- the smaller the viewport, the larger the relative search box size -->
<div class="col-sm-3 col-md-4 col-lg-6" >
<div id="search_input_group" class="input-group input-group-sm">
<span class="input-group-btn crowdsourcingTerms">
<button id="savesuggestion"
disabled
title="Save this topic as a new suggestion"
class="btn btn-default"
type="button">
<span class="glyphicon glyphicon-save"
id="saveicon">
</span>
</button>
</span>
<span class="input-group-btn">
<button id="searchbutton"
title="Search the topic in the map"
class="btn btn-info"
type="button">
<span class="glyphicon glyphicon-search">
</span>
</button>
</span>
<!-- ########## THE SEARCH BAR ########## -->
<input id="searchinput"
type="text"
class="form-control"
placeholder="Select node(s)" />
<!-- strSearchBar will replace placeholder value -->
<!-- #################################### -->
</div>
<!-- messages below the search bar -->
<!-- say thanks for the suggestion, etc. -->
<div id="crowdsourcing_answer" class="crowdsourcingTerms"></div>
</div>
<div class="col-sm-3 col-md-3 col-lg-5">
<input id="checkboxdiv" onclick="alertCheckBox(this);"
title="Add next search results to current selection"
class="btn btn-info"
type="checkbox"></input>
<p style="font-size:75%; line-height:90%">Add to selection</p>
</div>
</div>
<!--
......@@ -177,61 +221,17 @@
</li>
</ul>
-->
</div>
</div><!-- /.nav-collapse -->
</div><!-- /.navbar -->
</div>
<div id="wrapper">
<!-- Sidebar left, new css -->
<div id="leftcolumn" class="newleftbar">
<div class="row">
<div id="crowdsourcing_intro" class="col-md-12 crowdsourcingTerms">
<!-- <button type="button" class="close">×</button> -->
<h5>Search or suggest topics</h5>
</div>
</div><!-- /row -->
<div class="row">
<div id="mainform" class="form-horizontal col-md-12">
<div id="search_input_group" class="input-group input-group-sm">
<span class="input-group-btn crowdsourcingTerms">
<button id="savesuggestion"
disabled
title="Save this topic as a new suggestion"
class="btn btn-default"
type="button"><i id="saveicon" class="glyphicon glyphicon-save"></i></button>
</span>
<span class="input-group-btn">
<button id="search_proposed_terms"
title="Search the topic in the map"
class="btn btn-info"
type="button"><i class="glyphicon glyphicon-search"></i></button>
</span>
<!-- ideally should be appended by jquery for autocomplete -->
<input id="proposed_terms" type="text" class="form-control" placeholder="Recherche" />
</div><!-- /search_input_group -->
</div><!-- /form -->
</div><!-- /row -->
<div class="row" class="crowdsourcingTerms">
<!-- say thanks for the suggestion -->
<div id="crowdsourcing_answer" class="col-md-12"></div>
</div><!-- /row -->
<div class="row" class="TODOhistogramModule">
<div class="row" class="£TODOhistogramModule">
<!-- filled by query (user search value) to wos api -->
<div id="search_histogram_wrapper" class="col-md-12">
<div id="search_histogram"></div>
......@@ -350,8 +350,7 @@
</div>
</div>
<!-- £TODO check </div> -->
<div id="savemodal" class="modal fade">
<div class="modal-dialog">
......
......@@ -11,6 +11,7 @@ function newPopup(url) {
// Execution: ChangeGraphAppearanceByAtt( true )
// It scans the existing node-attributes and t keeps only those which are Numeric.
// then, add the button in the html with the sigmaUtils.clustersBy(x) listener.
// [TODO: fonction un peu lourde dans le profilage]
function ChangeGraphAppearanceByAtt( manualflag ) {
if ( !isUndef(manualflag) && !TW.colorByAtt ) TW.colorByAtt = manualflag;
......
......@@ -28,6 +28,11 @@
max-height: 10%;
}
/* searchnav gets same padding as bootstrap's .navbar-nav > li > a */
#defaultop div#searchnav {
padding-top: 13px;
padding-bottom: 9px;
}
#sigma-example {
width: 100%;
height: 300px;
......@@ -45,6 +50,10 @@
.my-legend {
position:fixed;
/* width: we set it smaller than #leftcolumn container's width */
width:16%;
max-height: 40%;
overflow-y:scroll;
bottom:5px;
left:5px;
......
.fsslider {
position: relative;
min-width: 100px;
/* min-width: 100px; */
min-width: 75px;
height: 8px;
display: inline-block;
width: 100%;
......
......@@ -52,6 +52,8 @@ var TW = {}
TW.catSoc = "Document";
TW.catSem = "NGram";
TW.strSearchBar = "Select or suggest topics";
var ParseCustom = function () {};
var SigmaUtils = function () {};
var TinaWebJS = function () {};
......@@ -67,7 +69,6 @@ var inactiveColor = '#666';
var startingNodeId = "1";
var minLengthAutoComplete = 1;
var maxSearchResults = 10;
var strSearchBar = "Search";
var cursor_size_min= 0;
var cursor_size= 0;
......
......@@ -47,6 +47,9 @@ function sigmaLimits( sigmacanvas ) {
}
// will be instanciated as SelInst
SelectionEngine = function() {
......@@ -194,7 +197,20 @@ SelectionEngine = function() {
}).index();
// uses: SelectorEngine() and MultipleSelection2()
this.search = function(string) {
// we assume string is normalized
this.search_n_select = function(string) {
// alert("search is happening !")
cancelSelection(false);
if (typeof string != "string") {
return -1 ;
}
else if (string.length == 0) {
// alert("really? empty query?") ;
return 0 ;
}
else {
var id_node = '';
var results = find(string)
......@@ -202,20 +218,40 @@ SelectionEngine = function() {
for(var i in results) {
coincd.push(results[i].id)
}
var targeted = SelectorEngine( {
var targeted = this.SelectorEngine( {
addvalue:checkBox,
clicktype:"simple",
prevsels:selections,
currsels:coincd
} )
if(targeted.length>0) {
cancelSelection(false);
MultipleSelection2(targeted);
// got results
// -----------
this.MultipleSelection2({nodes:targeted});
}
else {
// no results
// ----------
// we send event for plugins
// (eg: propose to add the missing string to the graph)
$('#searchinput').trigger({
type: "tw:emptyNodeSet",
q: string,
nodeIds: []
});
// console.log("\n\n\n sent [[ emptyNodes ]] \n\n ")
}
TW.partialGraph.draw();
// anyway
// ------
TW.lastQuery = string ;
$("input#searchinput").val("");
$("input#searchinput").autocomplete( "close" );
TW.partialGraph.draw();
return targeted.length
}
}
//Util
......@@ -267,18 +303,21 @@ SelectionEngine = function() {
/**
* Main function for any selecting action
*
* @nodes: eg targeted array
*/
// external usage : partialGraph , updateLeftPanel_fix();
this.MultipleSelection2 = (function(nodes,nodesDict,edgesDict) {
console.log("IN SelectionEngine.MultipleSelection2:")
console.log(nodes)
// console.log(nodes)
greyEverything();
// TW.partialGraph.states.slice(-1)[0] is the present graph state
var typeNow = TW.partialGraph.states.slice(-1)[0].type.map(Number).join("|")
console.log ("console.loging the Type:")
console.log (typeNow)
console.log (" - - - - - - ")
// console.log ("console.loging the Type:")
// console.log (typeNow)
// console.log (" - - - - - - ")
// Dictionaries of: selection+neighbors
var nodes_2_colour = (nodesDict)? nodesDict : {};
......@@ -338,6 +377,18 @@ SelectionEngine = function() {
TW.partialGraph.states.slice(-1)[0].selections = the_new_sels;
TW.partialGraph.states.slice(-1)[0].setState( { sels: the_new_sels} )
// alert("MultipleSelection2=======\nthe_new_sels:" + JSON.stringify(the_new_sels))
// we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection)
$('#searchinput').trigger({
type: "tw:gotNodeSet",
q: $("#searchinput").val(),
nodeIds: the_new_sels
});
// console.log("Event [gotNodeSet] sent from Tinaweb MultipleSelection2")
var neighsDict = {}
if(TW.Relations["1|1"]) {
for(var s in the_new_sels) {
......@@ -401,11 +452,14 @@ TinaWebJS = function ( sigmacanvas ) {
$('input#searchinput').autocomplete({
source: function(request, response) {
console.log("in autocomplete:")
console.log(labels.length)
console.log(" - - - - - - - - - ")
// console.log("in autocomplete:")
// labels initialized in settings, filled in updateSearchLabels
// console.log(labels.length)
// console.log(" - - - - - - - - - ")
matches = [];
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
// grep at heart
var results = $.grep(labels, function(e) {
return matcher.test(e.label); //|| matcher.test(e.desc);
});
......@@ -419,26 +473,64 @@ TinaWebJS = function ( sigmacanvas ) {
response(matches);
},
minLength: minLengthAutoComplete
minLength: minLengthAutoComplete,
// ----------------------->8---------------------
// send a "no more suggestions event"
response: function (event, ui_response_array) {
// exemple in ui_response_array
// {"content":
// [{id: 239, label:"warning system",desc:"ISIterms.."},
// ...
// ]
// }
if (ui_response_array.content.length == 0) {
// we send our "noAutocomplete" event
$('#searchinput').trigger("tw:noAutocomplete");
// (signal for plugins like crowdsourcing that
// are sensitive to autocomplete being empty)
// console.log("000 Event [noAutocomplete] sent from Tinaweb search")
}
else {
// we send a "hasAutocomplete" event
// (/!\ will be sent for each typed char)
$('#searchinput').trigger("tw:gotAutocomplete");
// console.log("+++ Event [gotAutocomplete] sent from Tinaweb search")
}
}
// ----------------------->8---------------------
});
// is_open flag for keydown choice
$('#searchinput').bind('autocompleteopen', function(event, ui) {
$(this).data('is_open',true);
});
$('#searchinput').bind('autocompleteclose', function(event, ui) {
$(this).data('is_open',false);
});
$("#searchinput").focus(function () {
if ($(this).val() == strSearchBar) {
$(this).val('');
}
});
$("#searchinput").blur(function () {
if ($(this).val() == '') {
$(this).val(strSearchBar);
}
// default search value now handled through input/@placeholder
// $("#searchinput").focus(function () { });
// $("#searchinput").blur(function () { });
// i click on the search button, independently from autocomplete
$("#searchbutton").click(function() {
var query = normalizeString($("#searchinput").val())
// console.log('===\nyour query was: "'+query+'"');
// --- SelectionEngine.search() -------------------
// -> will call sigmaUtils.find()
// over sigmaUtils.getnodesIndex()
// -> then call this.SelectorEngine
// and this.MultipleSelection2
SelInst.search_n_select(query)
// ------------------------------------------------
});
// i've a list of coincidences and i press enter like a boss >:D
// external usage: partialGraph, SelectorEngine() , MultipleSelection2()
$("#searchinput").keydown(function (e) {
......@@ -450,7 +542,7 @@ TinaWebJS = function ( sigmacanvas ) {
coincidences.push(matches[j].id)
}
$.doTimeout(30,function (){
var targeted = SelInst.SelectorEngine( {
targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
clicktype:"double",
prevsels:selections,
......@@ -473,6 +565,16 @@ TinaWebJS = function ( sigmacanvas ) {
});
//$("input#searchinput").trigger('autocompleteclose');
}
// alert("matches[].id\n" + JSON.stringify(matches.map(function(n) {return n.id})))
}
else if (e.keyCode == 13 && $("input#searchinput").data('is_open') !== true) {
// pressed down [ENTER] but with no autocomplete
// it really means "do search_and_select()"
// (but we know the results will be empty)
// (we still do it for the side effects: events, cleaning)
var query = normalizeString($("#searchinput").val())
SelInst.search_n_select(query)
}
});
......@@ -480,12 +582,13 @@ TinaWebJS = function ( sigmacanvas ) {
// external usage: partialGraph, SelectorEngine() , MultipleSelection2()
$("#searchinput").keyup(function (e) {
if (e.keyCode == 13 && $("input#searchinput").data('is_open') !== true) {
var targeted = [] ;
var exfnd = exactfind( $("#searchinput").val() )
if (exfnd!=null) {
console.log("search KEY UP");
$.doTimeout(30,function (){
var targeted = SelInst.SelectorEngine( {
targeted = SelInst.SelectorEngine( {
addvalue:checkBox,
clicktype:"double",
prevsels:selections,
......@@ -543,9 +646,9 @@ TinaWebJS = function ( sigmacanvas ) {
console.log("")
console.log(" ############ changeLEVEL click");
changeLevel();
changeLevel(); // <- est-ce que ça fait quelquechose ?
// $("#tabs1").click()
ChangeGraphAppearanceByAtt(true)
ChangeGraphAppearanceByAtt(true) // cf. extras_explorer
console.log(" ############ / changeLEVEL click");
console.log("")
});
......@@ -756,7 +859,10 @@ TinaWebJS = function ( sigmacanvas ) {
bgcolor:"#27c470",
onchange:function(value){
$.doTimeout(100,function (){
// sigma permet qu'on lui passe une fonction
// à effectuer sur l'itérateur
partialGraph.iterNodes(function (n) {
// TODO fonction un peu lourde dans le profilage
if(TW.Nodes[n.id].type==TW.catSoc) {
var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3
n.size = (newval<1.0)?1:newval;
......
......@@ -833,6 +833,8 @@ function extractContext(string, context) {
return begin_pts + str + end_pts;
}
// TODO check duplicate function with sigmaUtils exactfind()
function searchLabel(string){
var id_node = '';
var n;
......
......@@ -193,6 +193,46 @@ function rgbToHex(r, g, b) {
}
// lowercase etc query strings
normalizeString = function(string) {
if (! typeof string == "string") {
return "" ;
}
else {
return $.trim( string.toLowerCase() )
}
}
// html-escape user input strings
// /!\ TODO check if safe enough?
saferString = function(string) {
// TODO table in an outer scope
conversions = {
'&' : '&amp;' ,
'<' : '&lt;' ,
'>' : '&gt;' ,
'"' : '&quot;' ,
"'" : '&apos;' ,
'%' : '&percnt;'
} ;
matchables = /[&<>"'%]/ ;
if (! typeof string == "string") {
return "" ;
}
else {
return string.replace(
matchables,
function(char) {
return conversions[char]
}
)
}
}
/**
* function to load a given css file
*/
......
......@@ -265,7 +265,7 @@ if(RES["OK"]) {
console.log(typestring)
if(typestring=="0|1") {
$("#category0").hide();set_ClustersLegend
$("#category0").hide();
$("#category1").show();
if($("#slidercat1nodesweight").html()=="")
......@@ -364,6 +364,9 @@ if(RES["OK"]) {
// load optional modules
ProcessDivsFlags() ;
// grey message in the search bar from settings
$("#searchinput").attr('placeholder', TW.strSearchBar) ;
console.log("finish")
......
......@@ -38,6 +38,11 @@ function cancelSelection (fromTagCloud) {
$("#unselectbutton").hide();
$("#tips").html(getTips());
}
// we send our "eraseNodeSet" event
// (signal for plugins that any selection behavior is finished)
$('#searchinput').trigger("tw:eraseNodeSet");
for(var i in deselections){
if( !isUndef(TW.partialGraph._core.graph.nodesIndex[i]) ) {
TW.partialGraph._core.graph.nodesIndex[i].forceLabel=false;
......
......@@ -27,6 +27,8 @@ SigmaUtils = function () {
if(Number(n.id)==287) console.log("coordinates of node 287: ( "+n.x+" , "+n.y+" ) ")
graph.addNode( n.id , node);
// fill the "labels" global variable
updateSearchLabels( n.id , n.label , n.type);
}
}
......@@ -148,24 +150,28 @@ function gete(id){
}
function find(label){
function find(lquery){
var results=[];
if (typeof lquery == 'string' && lquery.length > 0) {
lquery=lquery.toLowerCase() ;
var nds=getnodesIndex();
label=label.toLowerCase()
for(var i in nds){
var n=nds[i];
if(n.hidden==false){
var possiblematch=n.label.toLowerCase()
if (possiblematch.indexOf(label)!==-1) {
// string.indexOf(substring) faster than search/match
if (possiblematch.indexOf(lquery)!==-1) {
results.push(n);
}
}
}
}
return results;
}
function exactfind(label) {
nds=getnodesIndex();
if (typeof lquery == 'string' && lquery.length > 0) {
for(var i in nds){
n=nds[i];
if(!n.hidden){
......@@ -174,6 +180,7 @@ function exactfind(label) {
}
}
}
}
return null;
}
......
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