Commit 8d97e039 authored by delanoe's avatar delanoe

Merge branch 'refactoring-rom' into refactoring

parents ab0aa5ba 5239fc98
...@@ -4,13 +4,14 @@ API views for advanced operations on ngrams and ngramlists ...@@ -4,13 +4,14 @@ API views for advanced operations on ngrams and ngramlists
- retrieve several lists together ("family") - retrieve several lists together ("family")
- retrieve detailed list infos (ngram_id, term strings, scores...) - retrieve detailed list infos (ngram_id, term strings, scores...)
- modify NodeNgram lists (PUT/DEL an ngram to a MAINLIST OR MAPLIST...) - modify NodeNgram lists (PUT/DEL an ngram to a MAINLIST OR MAPLIST...)
- modify NodeNgramNgram groups (POST a list of groupings like {"767":[209,640],"779":[436,265,385]}")
""" """
from gargantext.util.http import APIView, get_parameters, JsonHttpResponse,\ from gargantext.util.http import APIView, get_parameters, JsonHttpResponse,\
ValidationException, Http404 ValidationException, Http404
from gargantext.util.db import session, aliased, desc from gargantext.util.db import session, aliased, desc, bulk_insert
from gargantext.util.db_cache import cache from gargantext.util.db_cache import cache, or_
from gargantext.models import Ngram, NodeNgram, NodeNodeNgram from gargantext.models import Ngram, NodeNgram, NodeNodeNgram, NodeNgramNgram
from gargantext.util.lists import UnweightedList, Translations from gargantext.util.lists import UnweightedList, Translations
...@@ -62,6 +63,43 @@ def _query_list(list_id, ...@@ -62,6 +63,43 @@ def _query_list(list_id,
def _query_grouped_ngrams(groupings_id, details=False, scoring_metric_id=None):
"""
Listing of "hidden" ngram_ids from the groups
Works only for grouplists
Parameter:
- details: if False, send just the array of ngram_ids
if True, send triples with (ngram_id, term, scoring)
^^^^^^^
- scoring_metric_id: id of a scoring metric node (TFIDF or OCCS)
(for details and sorting)
"""
if not details:
# simple contents
query = session.query(NodeNgramNgram.ngram2_id)
else:
# detailed contents (terms and some NodeNodeNgram for score)
query = (session
.query(
NodeNgramNgram.ngram2_id,
Ngram.terms,
NodeNodeNgram.score
)
.join(Ngram, NodeNgramNgram.ngram2_id == Ngram.id)
.join(NodeNodeNgram, NodeNgramNgram.ngram2_id == NodeNodeNgram.ngram_id)
.filter(NodeNodeNgram.node1_id == scoring_metric_id)
.order_by(desc(NodeNodeNgram.score))
)
# main filter
# -----------
query = query.filter(NodeNgramNgram.node_id == groupings_id)
return query
class List(APIView): class List(APIView):
""" """
see already available API query api/nodes/<list_id>?fields[]=ngrams see already available API query api/nodes/<list_id>?fields[]=ngrams
...@@ -69,6 +107,94 @@ class List(APIView): ...@@ -69,6 +107,94 @@ class List(APIView):
pass pass
class GroupChange(APIView):
"""
Modification of some groups
(typically new subform nodes under a mainform)
USAGE EXEMPLE:
HOST/api/ngramlists/groups?node=43
vvvvvv
group node
to modify
We use POST HTTP method to send group data with structure like:
{
mainform_A: [subform_A1],
mainformB: [subform_B1,subform_B2,subform_B3]
...
}
Chained effect:
NB: request.user is also checked for current authentication status
"""
def initial(self, request):
"""
Before dispatching to post()
Checks current user authentication to prevent remote DB manipulation
"""
if not request.user.is_authenticated():
raise Http404()
# can't use return in initial() (although 401 maybe better than 404)
# can't use @requires_auth because of positional 'self' within class
def post(self, request):
"""
Rewrites the group node **selectively**
=> removes couples where newly reconnected ngrams where involved
=> adds new couples from GroupsBuffer of terms view
TODO see use of util.lists.Translations
TODO benchmark selective delete compared to entire list rewrite
"""
group_node = get_parameters(request)['node']
all_nodes_involved = []
links = []
print([i for i in request.POST.lists()])
pass
for (mainform_key, subforms_ids) in request.POST.lists():
mainform_id = mainform_key[:-2] # remove brackets '543[]' -> '543'
all_nodes_involved.append(mainform_id)
for subform_id in subforms_ids:
links.append((mainform_id,subform_id))
all_nodes_involved.append(subform_id)
# remove selectively all groupings with these nodes involved
# TODO benchmark
old_links = (session.query(NodeNgramNgram)
.filter(NodeNgramNgram.node_id == group_node)
.filter(or_(
NodeNgramNgram.ngram1_id.in_(all_nodes_involved),
NodeNgramNgram.ngram2_id.in_(all_nodes_involved)))
)
n_removed = old_links.count()
old_links.delete(synchronize_session='fetch')
print('n_removed', n_removed)
print("links", links)
print(
[i for i in ((group_node, mainform, subform, 1.0) for (mainform,subform) in links)]
)
bulk_insert(
NodeNgramNgram,
('node_id', 'ngram1_id', 'ngram2_id', 'weight'),
((group_node, mainform, subform, 1.0) for (mainform,subform) in links)
)
return JsonHttpResponse({
'count_removed': n_removed,
'count_added': len(links),
}, 200)
class ListChange(APIView): class ListChange(APIView):
""" """
Any ngram action on standard NodeNgram lists (MAIN, MAP, STOP) Any ngram action on standard NodeNgram lists (MAIN, MAP, STOP)
...@@ -270,10 +396,17 @@ class ListFamily(APIView): ...@@ -270,10 +396,17 @@ class ListFamily(APIView):
pagination_limit = glance_limit, pagination_limit = glance_limit,
scoring_metric_id= scores_id) scoring_metric_id= scores_id)
else: else:
# infos for all ngrams # infos for all ngrams from mainlist
mainlist_query = _query_list(mainlist_id, details=True, mainlist_query = _query_list(mainlist_id, details=True,
scoring_metric_id= scores_id) scoring_metric_id= scores_id)
# infos for grouped ngrams, absent from mainlist
hidden_ngrams_query = _query_grouped_ngrams(groups_id, details=True,
scoring_metric_id= scores_id)
# and for the other lists (stop and map) # and for the other lists (stop and map)
# no details needed here, just the member ids
# - maplist ngrams will already be in ngraminfos b/c of mainlist
# - stoplist ngrams will not be shown in detail
for li in other_list_ids: for li in other_list_ids:
li_elts = _query_list(other_list_ids[li], details=False li_elts = _query_list(other_list_ids[li], details=False
).all() ).all()
...@@ -286,11 +419,14 @@ class ListFamily(APIView): ...@@ -286,11 +419,14 @@ class ListFamily(APIView):
linkinfo = links.groups linkinfo = links.groups
# the output form # the output form
for ng in mainlist_query.all(): for ng in mainlist_query.all() + hidden_ngrams_query.all():
ng_id = ng[0] ng_id = ng[0]
# id => [term, weight] # id => [term, weight]
ngraminfo[ng_id] = ng[1:] ngraminfo[ng_id] = ng[1:]
# NB the client js will sort mainlist ngs from hidden ngs after ajax
# using linkinfo (otherwise needs redundant listmembers for main)
return JsonHttpResponse({ return JsonHttpResponse({
'ngraminfos' : ngraminfo, 'ngraminfos' : ngraminfo,
'listmembers' : listmembers, 'listmembers' : listmembers,
......
...@@ -16,6 +16,11 @@ urlpatterns = [ ...@@ -16,6 +16,11 @@ urlpatterns = [
# rm <=> DEL ngramlists/change?list=42&ngrams=1,2 # rm <=> DEL ngramlists/change?list=42&ngrams=1,2
url(r'^ngramlists/change$', ngramlists.ListChange.as_view()), url(r'^ngramlists/change$', ngramlists.ListChange.as_view()),
# modify grouping couples of a group node
# ex: POST ngramlists/groups?node=43
# post data looks like : {"767":[209,640],"779":[436,265,385]}"
url(r'^ngramlists/groups$', ngramlists.GroupChange.as_view()),
# get entire combination of lists from a corpus # get entire combination of lists from a corpus
# (or any combination of lists that go together : # (or any combination of lists that go together :
# - a mainlist # - a mainlist
......
...@@ -30,21 +30,37 @@ th a { ...@@ -30,21 +30,37 @@ th a {
/* notes under table titles */ /* notes under table titles */
th p.note { th .note {
color: #ccc; color: #ccc;
}
td .note {
color: #444;
}
span.note {
font-size: 10px;
color: #333;
}
p.note {
font-size: 0.6em; font-size: 0.6em;
margin: 1em 0 0 0 ; margin: 1em 0 0 0 ;
} }
th p.note > input { p.note > input {
float: left; float: left;
margin: 0 .2em 0 0 ; margin: 0 .2em 0 0 ;
} }
th p.note > label { p.note > label {
float: left; float: left;
} }
.note.greyed {
opacity: 0.2;
}
tr:hover { tr:hover {
cursor: pointer; cursor: pointer;
font-weight: bold; font-weight: bold;
...@@ -69,19 +85,34 @@ tr:hover { ...@@ -69,19 +85,34 @@ tr:hover {
cursor: default; cursor: default;
} }
/* group box with + */ /* group box row on top of table with + */
.group_box { #group_box {
font-size: 90%; font-size: 90%;
border: 1px solid blue;
} }
.group_box .header {
font-size: 120%; #group_flag {
font-size: 0.7em;
margin-top: 3em;
margin-bottom: 1em;
}
#group_box_mainform {
margin-bottom: 0;
line-height: 1 ;
margin-left: .05em ;
} }
.group_box .content {
border: 1px solid yellow; #group_box_content {
line-height: 1 ;
margin-bottom: 1em;
} }
#group_flag { .oldsubform {
color: #777 ;
}
.usersubform {
color: blue ;
} }
.dynatable-record-count { .dynatable-record-count {
......
...@@ -5,21 +5,22 @@ ...@@ -5,21 +5,22 @@
* - the ngrams groupings * - the ngrams groupings
* - the score chart * - the score chart
* *
* Main_test() is the entry point. A dynatable is the main UI element. * MainTableAndCharts() is the entry point. A dynatable is the main UI element.
* *
* Dynatable uses <thead> for columns and ulWriter() for row formatting. * Dynatable uses <thead> for columns and ulWriter() for row formatting.
* *
* Here, the user can modify DB lists by toggling Ngrams states and * Here, the user can modify DB lists by toggling Ngrams states and
* save to DB via the API in the functions SaveLocalChanges() and CRUD() * save to DB via the API in the functions SaveLocalChanges() and CRUD()
* *
* Local persistence of states is in AjaxRecord[tableId].state * Local persistence of states is in AjaxRecord[ngramId].state
* (access by table ids, *not* ngram ids) * (access by ngram ids)
*
* Local persistence of groups is in GroupsBuffer (result of modification)
* *
* Their values are initialized in the functions AfterAjax() and Refresh(). * Their values are initialized in the functions AfterAjax() and Refresh().
* *
* The stateIds are described by the System object. * The stateIds are described by the System object.
* - columns use stateId [0..2] (miam aka normal, map aka keep, stop aka delete) * - columns use stateId [0..2] (miam aka normal, map aka keep, stop aka delete)
* - stateId 3 is for grouped items (TODO clarify use)
* *
* @author * @author
* Samuel Castillo (original 2015 work) * Samuel Castillo (original 2015 work)
...@@ -34,109 +35,113 @@ ...@@ -34,109 +35,113 @@
*/ */
function pr(msg) { // =============================================================================
console.log(msg) // GLOBALS <=> INTERACTIVE STATUS etc
} // =============================================================================
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// ngram infos (<-> row data)
// --------------------------
// from /api/ngramlists/lexmodel?corpus=312
// with some expanding in AfterAjax
var AjaxRecords = [] ;
var latest,oldest;
var TheBuffer = false // table element (+config +events)
// -------------------------------
var MyTable ;
var PossibleActions = [ // definition of switching statuses for the 3 lists
{ // --------------------------------------------------
"id":"delete", // mainlist (+ maplist)
"name": "Delete", // vs
"color":"red" // stoplist
}, var GState = 0 // do we have an open group
{
"id":"keep",
"name": "Keep",
"color":"green"
},
// {
// "id":"to_group",
// "name": "Group",
// "color":"blue"
// }
]
var GState = 0
var System = { var System = {
// 1: { // 1: {
// }, // },
0: { 0: {
"states" : [ "normal" , "keep" , "delete" , "group"] , "states" : [ "normal" , "keep" , "delete"] ,
"statesD" : {} , // will be inverted map of states "statesD" : {} , // will be inverted map of states
"dict" : { "dict" : {
"normal": { "normal": {
"id":"normal", "id":"normal",
"name": "Normal", "name": "Normal",
"color":"black" "color":"black"
}, },
"delete": { "delete": {
"id":"delete", "id":"delete",
"name": "Delete", "name": "Delete",
"color":"red" "color":"red"
}, },
"keep": { "keep": {
"id":"keep", "id":"keep",
"name": "Keep", "name": "Keep",
"color":"green" "color":"green"
}, }
"group": { }
"id":"group", }
"name": "MainForm",
"color":"white"
}
}
}
} }
// States : [ "normal" , "keep" , "delete"]
/** /**
* inverted mapping useful for state_id lookup * inverted mapping useful for state_id lookup
* *
* System[GState]["statesD"] = {'normal':0,'keep':1,'delete':2,'group':3} * System[GState]["statesD"] = {'normal':0,'keep':1,'delete':2}
*/ */
for(var i in System[GState]["states"] ) { for(var i in System[GState]["states"] ) {
System[GState]["statesD"][ System[GState]["states"][i] ] = Number(i) System[GState]["statesD"][ System[GState]["states"][i] ] = Number(i)
} }
// System[0]["statesD"]
// { "normal" , "keep" , "delete" }
// 0 1 2
// DICT BUFFERS FOR MAP/MAIN//STOP SAVING LOGIC
// ----------------------------------------------
var FlagsBuffer = {} var FlagsBuffer = {}
// 3 main buffers per state (and later additional per target)
for(var i in System[GState]["states"]) { for(var i in System[GState]["states"]) {
FlagsBuffer[System[GState]["states"][i]] = {} FlagsBuffer[System[GState]["states"][i]] = {}
} }
var corpusesList = {} // + 1 for groups
var MyTable; GroupsBuffer = {}
var AjaxRecords = []
// D3.js: Interactive timerange variables. // GROUP "WINDOWS"
// ----------------
// keeps track of seeGroup() opened frames
var vizopenGroup = {} ;
// (if currently this group is under modification)
// ngramId of mainform + oldSubNgramIds + newSubNgramIds
var activeGroup = {'now_mainform_id':undefined, 'were_mainforms':{}} ;
// CHARTS ELEMENTS
// -----------------
// D3.js: Interactive timerange variables.
var LineChart = dc.lineChart("#monthly-move-chart"); var LineChart = dc.lineChart("#monthly-move-chart");
var volumeChart = dc.barChart("#monthly-volume-chart"); var volumeChart = dc.barChart("#monthly-volume-chart");
// volumeChart chart limits actualized on dc "filtered" event
var latest,oldest;
var TheBuffer = false
// width of the table in columns, updated after main
var tableSpan ;
// if "print portfolio" (TODO clarify use)
var corpusesList = {}
// =============================================================================
// ELEMENT CONTROLLERS AND ROW PROCESSORS
// =============================================================================
// Get all projects and corpuses of the user // Get all projects and corpuses of the user
function GetUserPortfolio() { function GetUserPortfolio() {
//http://localhost:8000/api/corpusintersection/1a50317a50145 //http://localhost:8000/api/corpusintersection/1a50317a50145
...@@ -227,12 +232,12 @@ function printCorpuses() { ...@@ -227,12 +232,12 @@ function printCorpuses() {
// EXTERNAL CORPUS TO COMPARE: // EXTERNAL CORPUS TO COMPARE:
var whichlist = $('input[name=whichlist]:checked').val() var whichlist = $('input[name=whichlist]:checked').val()
var url = window.location.origin+"/api/node/"+selected_corpus+"/ngrams/list/"+whichlist//+"?custom" var url = window.location.origin+"/api/node/"+selected_corpus+"/ngrams/list/"+whichlist//+"?custom"
console.log( url ) console.log( url )
GET_( url , function(results) { GET_( url , function(results) {
if(Object.keys( results ).length>0) { if(Object.keys( results ).length>0) {
var sub_ngrams_data = { var sub_ngrams_data = {
"ngrams":[], "ngrams":[],
"scores": $.extend({}, NGrams["main"].scores) "scores": $.extend({}, NGrams["main"].scores)
...@@ -250,31 +255,9 @@ function printCorpuses() { ...@@ -250,31 +255,9 @@ function printCorpuses() {
// } // }
// } // }
} }
var result = Main_test(sub_ngrams_data , NGrams["main"].scores.initial , "filter_all") var result = MainTableAndCharts(sub_ngrams_data , NGrams["main"].scores.initial , "filter_all")
// var sub_ngrams_data = { }
// "ngrams":[], });
// "scores": $.extend({}, NGrams["main"].scores)
// }
// if(whichlist=="stop") {
// for(var r in results) {
// var a_ngram = results[r]
// a_ngram["state"] = System[0]["statesD"]["delete"]
// sub_ngrams_data["ngrams"].push( a_ngram )
// }
// var result = Main_test(sub_ngrams_data , NGrams["main"].scores.initial , "filter_stop-list")
// }
// if(whichlist=="miam") {
// for(var i in NGrams["main"].ngrams) {
// var local_ngram = NGrams["main"].ngrams[i]
// console.log( local_ngram )
// }
// var result = Main_test(sub_ngrams_data , NGrams["main"].scores.initial , "filter_all")
// }
}
});
} }
...@@ -350,10 +333,10 @@ function Final_UpdateTable( action ) { ...@@ -350,10 +333,10 @@ function Final_UpdateTable( action ) {
pr("\tfrom ["+dataini+"] to ["+datafin+"]") pr("\tfrom ["+dataini+"] to ["+datafin+"]")
TimeRange = [] TimeRange = []
for (var i in AjaxRecords) { for (var ngramId in AjaxRecords) {
if(AjaxRecords[i].score>=dataini && AjaxRecords[i].score<=datafin){ if(AjaxRecords[ngramId].score>=dataini && AjaxRecords[ngramId].score<=datafin){
// pr( AjaxRecords[i].date+" : "+AjaxRecords[i].id ) // pr( AjaxRecords[ngramId].date+" : "+ngramId )
TimeRange.push(AjaxRecords[i]) TimeRange.push(AjaxRecords[ngramId])
} }
} }
...@@ -377,209 +360,370 @@ function Final_UpdateTable( action ) { ...@@ -377,209 +360,370 @@ function Final_UpdateTable( action ) {
MyTable.data('dynatable').process(); MyTable.data('dynatable').process();
} }
function getRecord(rec_id) { function getRecord(ngramId) {
return MyTable.data('dynatable').settings.dataset.originalRecords[rec_id]; return MyTable.data('dynatable').settings.dataset.originalRecords[ngramId];
// return AjaxRecords[rec_id] // return AjaxRecords[ngramId]
} }
function getRecords() { function getRecords() {
return MyTable.data('dynatable').settings.dataset.originalRecords; return MyTable.data('dynatable').settings.dataset.originalRecords;
} }
function save_groups() {
var groupdiv = "#group_box"
var gcontent = groupdiv+"_content"
var count = 0
var mainform = -1
var writeflag = ($("#group_box_content").children('span').length>1)?true:false
$(gcontent).children('span').each(function () {
var nid = $(this).data("id");
if (count==0) {
if(writeflag) {
// AjaxRecords[nid].name += "*"
FlagsBuffer["group"][ nid ] = []
mainform = nid
AjaxRecords[nid].state = 1
var label = AjaxRecords[nid].name
AjaxRecords[nid].name = (label[0]=="*") ? label : ("*"+label)
} else {
AjaxRecords[nid].state = 0;
// var label = AjaxRecords[nid].name
// AjaxRecords[nid].name = (label[0] == '*') ? label.slice(1) : label.name;
}
} else {
if(writeflag) {
FlagsBuffer["group"][ mainform ].push( nid )
AjaxRecords[nid].state = -1
}
}
count++
});
$("#group_box").remove()
$("#group_flag").remove()
GState=0
MyTable.data('dynatable').dom.update();
}
function cancel_groups() { // GROUPS CONTROLLERS
var groupdiv = "#group_box" // ------------------
var gcontent = groupdiv+"_content" function saveActiveGroup() {
$(gcontent).children('span').each(function () { var mainform = activeGroup.now_mainform_id
var nid = $(this).data("id"); // pr("saving mainform to GroupsBuffer: " + mainform)
AjaxRecords[nid].state = 0
var label = AjaxRecords[nid].name // the new array to save is in now_links -------------
AjaxRecords[nid].name = (label[0] == '*') ? label.slice(1) : label; GroupsBuffer[mainform] = activeGroup.now_links
}); // ---------------------------------------------------
$("#group_box").remove()
$("#group_flag").remove() // also we prefix "*" to the name
GState=0 AjaxRecords[mainform].name = "*" + AjaxRecords[mainform].name
MyTable.data('dynatable').dom.update();
} // TODO check if necessary to update
function add2groupdiv( elem_id ) { // the previous mainforms that became subforms can't stay in the main records
$('<span/>', { for (downgradedNgramId in activeGroup.were_mainforms) {
"data-id":AjaxRecords[elem_id].id, if (downgradedNgramId != mainform) {
"data-stuff": elem_id,
title: 'Click to remove', AjaxRecords[downgradedNgramId].state = -1
text: AjaxRecords[elem_id].name,
css: { // they go to nodesmemory
"cursor":"pointer", // NGrams.group.nodesmemory = AjaxRecords[downgradedNgramId]
"border": "1px solid blue", // delete AjaxRecords[downgradedNgramId]
"margin": "3px", }
"padding": "3px", }
}
}) // TODO posttest
.click(function() { // the previous "old" links are now in GroupsBuffer so from now on
AjaxRecords[$(this).data("stuff")].state=0; // they'll be searched in AjaxRecords by updateActiveGroupInfo()
$(this).remove() delete NGrams.group.links[mainform]
// if nothing in group div, then remove it for (i in activeGroup.now_links) {
if( $("#group_box_content").children().length==0 ) { newLink = activeGroup.now_links[i] ;
$("#group_box").remove() if (activeGroup.ngraminfo[newLink].origin == 'old' || activeGroup.ngraminfo[newLink].origin == 'oldnew') {
GState=0 // new AjaxRecords entry from nodesmemory
} AjaxRecords[newLink] = NGrams.group.nodesmemory[newLink]
MyTable.data('dynatable').dom.update(); delete NGrams.group.nodesmemory[newLink]
}) // console.log('oldLinkThatBecameNew: '+AjaxRecords[newLink].name)
.appendTo('#group_box_content') }
AjaxRecords[elem_id].state=3;// 3: "group" state }
// clean group modification zone and buffer
removeActiveGroup()
} }
// new
function add2group ( elem ) { function removeActiveGroup() {
if( $("#group_box").length==0 ) { // erases now_links and restores empty activeGroup global cache
var div_name = "#my-ajax-table > thead > tr > th:nth-child(1)" activeGroup = {'now_mainform_id':undefined, 'were_mainforms':{}} ;
var prctg = $(div_name).width()// / $(div_name).parent().width() * 100;
var group_html = ' <span class="group_box" style="max-width:'+prctg+'px;" id="group_box">'+'\n'; // remove the entire top row that was used as group modification zone
group_html += ' <span class="group_box content" id="group_box_content"></span>'+'\n'; $("#group_box").remove()
group_html += ' </span>'+'\n'; GState=0
group_html += ' <span id="group_flag"></span>'+'\n';
$(group_html).insertAfter( "#my-ajax-table > thead" ) // we also close the open sublists in case some of them don't exist any more
$("#group_flag").append ('<span onclick="save_groups()"> [ Ok</span> - <span onclick="cancel_groups()">No ] </span>') vizopenGroup = {}
}
GState=1 MyTable.data('dynatable').dom.update();
var elem_id = $( elem ).data("stuff")
add2groupdiv( elem_id )
if( FlagsBuffer["group"][ AjaxRecords[elem_id].id ] ) {
for(var i in FlagsBuffer["group"][ AjaxRecords[elem_id].id ] ) {
var nodeid = FlagsBuffer["group"][ AjaxRecords[elem_id].id ][i]
add2groupdiv ( nodeid )
}
}
delete FlagsBuffer["group"][ AjaxRecords[elem_id].id ]
MyTable.data('dynatable').dom.update();
} }
// for click open/close
function toggleSeeGroup(plusicon, ngramId) {
// when already open => we close
if (ngramId in vizopenGroup) {
$("#subforms-"+ngramId).remove() ;
delete vizopenGroup[ngramId] ;
plusicon.classList.remove('glyphicon-triangle-bottom') ;
plusicon.classList.add('glyphicon-triangle-right') ;
}
else {
var subNgramHtml = seeGroup(ngramId) ;
// we target the html in the mainform term's box
$( "#box-"+ngramId).append(subNgramHtml) ;
// change icon
plusicon.classList.remove('glyphicon-triangle-right') ;
plusicon.classList.add('glyphicon-triangle-bottom') ;
}
}
/** /**
* click red, click keep, click normal... * shows the ngrams grouped under this ngram
*
* called at 'plusicon click' via toggleSeeGroup()
* or at table rows rewriting via transformContent()
* *
* @param elem - the table row that contains the term cell * @param ngramId (of the mainform)
*/ */
function clickngram_action ( elem ) { function seeGroup ( ngramId ) {
// local id // 1/7 create new element container
var elem_id = $( elem ).data("stuff") ; var subNgramHtml = $('<p class="note">') ;
// console.log("click: state before: "+ AjaxRecords[elem_id].state) ; subNgramHtml.attr("id", "subforms-"+ngramId) ;
subNgramHtml.css("line-height", 1.2) ;
// cycle the statuses (omitting status 3 = group) subNgramHtml.css('margin-left','.3em') ;
AjaxRecords[elem_id].state = (AjaxRecords[elem_id].state==(System[0]["states"].length-2))?0:(AjaxRecords[elem_id].state+1); subNgramHtml.css("margin-top", '.5em') ;
// 2/7 attach flag open to global state register
vizopenGroup[ngramId] = true ;
// 3/7 retrieve names of the original (from DB) grouped ngrams
var oldlinksNames = [] ;
if( ngramId in NGrams.group.links ) {
for (var i in NGrams.group.links[ngramId]) {
var subNgramId = NGrams.group.links[ngramId][i] ;
oldlinksNames[i] = NGrams.group.nodesmemory[subNgramId].name
}
}
// State <=> term color <=> checked colums // 4/7 retrieve names of the newly created grouped ngrams
var newlinksNames = [] ;
if( ngramId in GroupsBuffer ) {
for(var i in GroupsBuffer[ ngramId ] ) {
var subNgramId = GroupsBuffer[ ngramId ][i] ;
newlinksNames[i] = AjaxRecords[subNgramId].name
}
}
// console.log("\n\nRECORD visible on click --- " + JSON.stringify(AjaxRecords[elem_id])) ; // 5/7 create the "tree" from the names, as html lines
var htmlMiniTree = drawSublist(oldlinksNames.concat(newlinksNames))
subNgramHtml.append(htmlMiniTree)
var ngramId = AjaxRecords[elem_id].id ; // 6/7 add a "modify group" button
var changeGroupsButton = '<button style="float:right"' ;
changeGroupsButton += 'onclick="modifyGroup('+ngramId+')">' ;
changeGroupsButton += 'modify group' ;
changeGroupsButton += '</button>' ;
subNgramHtml.append(changeGroupsButton) ;
// console.log("click: state after: "+ AjaxRecords[elem_id].state) ; // 7/7 return html snippet (ready for rendering)
MyTable.data('dynatable').dom.update(); return(subNgramHtml)
} }
/** /*
* Works for ulWriter. Connects a record's state with table UI outcome. * Creates an "ASCIIart" tree from subforms names
* * Exemple:
* @param rec_id - the local id for this ngram record in AjaxRecords * BEES
* ├── bee
* ├── honey bee
* └── honey bees
*/ */
function transformContent(rec_id) { function drawSublist (linkNamesArray) {
// debug var sublistHtml = "" ;
// console.log("\nFUN transformContent() !!!!") var last_i = linkNamesArray.length - 1 ;
var ngram_info = AjaxRecords[rec_id]; for(var i in linkNamesArray) {
var subNgramName = linkNamesArray[i] ;
// ex: ngram_info = { if (i != last_i) {
// "id":2349,"name":"failure","score":1,"flag":false, sublistHtml += ' ├─── ' + subNgramName + '<br>' ;
// "group_plus":true,"group_blocked":false,"state":0 }
// } else {
sublistHtml += ' └─── ' + subNgramName ;
// console.log( }
// "transformContent got ngram_info no " + rec_id + ": " }
// + JSON.stringify(ngram_info) return sublistHtml
// ) }
// result {} contains instanciated column html for dynatables
var result = {}
var atts = System[0]["dict"][ System[0]["states"][ngram_info.state] ]
// avec System[0]["dict"] contenant {"normal":{"id":"normal","name":"Normal","color":"black"},"delete":{"id":"delete","name":"Delete","color":"red"}...}
var plus_event = ""
function drawActiveSublist (tgtElementId, linkIdsArray, ngInfos) {
var sublistHtml = "" ;
var last_i = linkIdsArray.length - 1 ;
for(var i in linkIdsArray) {
var subNgramId = linkIdsArray[i] ;
if (i != last_i) {
sublistHtml += ' ├── ' + subformSpan(ngInfos[subNgramId]) + '<br>' ;
}
else {
sublistHtml += ' └── ' + subformSpan(ngInfos[subNgramId]) ;
}
}
// GState = 1 if previously had add_group // write html
// it influences state lookup $(tgtElementId).html(sublistHtml)
if(GState==0 && ngram_info.state!=System[0]["statesD"]["delete"] ) // if deleted, no + button }
plus_event = " <a class=\"plusclass\" onclick=\"add2group(this.parentNode.parentNode)\">(+)</a>"
if(GState==1 ) {
if(ngram_info.state!=System[0]["statesD"]["delete"] && ngram_info.state!=System[0]["statesD"]["group"]) { // if deleted and already group, no Up button
plus_event = " <a class=\"plusclass\" onclick=\"add2group(this.parentNode.parentNode)\">(▲)</a>"
}
}
// uncomment if column ngramId (here and in Main_test) // makes each subform's html
result["ngramId"] = ngram_info["id"] ; function subformSpan( subNgramInfo ) {
// each item is a new ngram under the group
span = $('<span/>', {
text: subNgramInfo.name,
title: subNgramInfo.id,
id: 'active-subform-' + subNgramInfo.id
})
// uncomment if column state (here and in Main_test) if (subNgramInfo.origin == 'old') {
// result["state"] = AjaxRecords[rec_id].state span.addClass("oldsubform")
}
else if (subNgramInfo.origin == 'new' || subNgramInfo.origin == 'oldnew'){
span.addClass("usersubform")
}
// -------------------------------------------
// check box state columns 'will_be_map' and 'will_be_stop'
map_flag = (AjaxRecords[rec_id].state == 1) ; // 1 = System[0]["statesD"]["keep"] // £TODO remove Button has a bug when mainform doesn't reappear in its row
stop_flag = (AjaxRecords[rec_id].state == 2) ; // 2 = System[0]["statesD"]["delete"] // var removeButton = '&nbsp;<span class="note glyphicon glyphicon-minus-sign"'
// removeButton += ' onclick="removeSubform('+ subNgramInfo.id +')"></span>'
// span.append(removeButton)
return(span[0].outerHTML)
}
result["will_be_map"] = '<input type="checkbox" onclick="checkBox(\'keep\',this.parentNode.parentNode)" ' function removeSubform(ngramId) {
+(map_flag?'checked':'') $('#active-subform-'+ngramId).remove()
+'></input>' if (activeGroup.now_links.length == 1) {
result["will_be_stop"] = '<input type="checkbox" onclick="checkBox(\'delete\', this.parentNode.parentNode)" ' removeActiveGroup()
+(stop_flag?'checked':'') }
+'></input>' else {
// possible todo: 3 way switch ?? var i = activeGroup.now_links.indexOf(ngramId)
// par exemple http://codepen.io/pamgriffith/pen/zcntm activeGroup.now_links.splice(i,1)
// ------------------------------------------- // if (activeGroup.ngraminfo[ngramId].origin == 'new') {
// AjaxRecords[ngramId].state = 0 ;
// }
// redraw active group_box_content
drawActiveSublist(
'#group_box_content',
activeGroup.now_links,
activeGroup.ngraminfo
)
// and update
MyTable.data('dynatable').dom.update();
}
}
function modifyGroup ( mainFormNgramId ) {
// create modification dialog
//
var group_html = ' <tr class="group_box" id="group_box">\n';
group_html += ' <td colspan='+tableSpan+'>\n';
// mainform
group_html += ' <p id="group_box_mainform">\n';
group_html += ' '+subformSpan(AjaxRecords[mainFormNgramId])+'\n'
group_html += ' <br> │<br>';
group_html += ' </p>\n';
// sublist
group_html += ' <p id="group_box_content"></p>\n';
// save/cancel buttons
group_html += ' <p id="activeGroupButtons"></p>\n';
group_html += ' </td>\n';
group_html += ' </tr>\n';
$( "#my-ajax-table > thead" ).append(group_html)
// Ok - No
var cancelGroupButton = '<button onclick="removeActiveGroup()">' ;
cancelGroupButton += 'cancel' ;
cancelGroupButton += '</button>' ;
var tempoSaveGroupButton = '<button onclick="saveActiveGroup()">' ;
tempoSaveGroupButton += 'finish' ;
tempoSaveGroupButton += '</button>' ;
$("#activeGroupButtons").append(cancelGroupButton)
.append(tempoSaveGroupButton)
// set global 'grouping in progress' states
GState = 1 ;
activeGroup.now_mainform_id = mainFormNgramId ;
activeGroup.were_mainforms[mainFormNgramId] = true ;
activeGroup.now_links = [] ;
activeGroup.ngraminfo = {} ; // standard rec info + 'origin' property
// add relevant information from old & new links to activeGroup.now_links
updateActiveGroupInfo (mainFormNgramId, false)
// groupBox rendering
drawActiveSublist(
'#group_box_content',
activeGroup.now_links,
activeGroup.ngraminfo
)
MyTable.data('dynatable').dom.update();
}
// add new ngramid (and any present subforms) to currently modified group
function add2group ( ngramId ) {
console.log("FUN add2group(" + AjaxRecords[ngramId].name + ")")
var toOther = true ;
activeGroup.were_mainforms[ngramId] = true ;
if (GState == 1) {
// add this mainform as a new subform
activeGroup.now_links.push(ngramId)
activeGroup.ngraminfo[ngramId] = AjaxRecords[ngramId]
activeGroup.ngraminfo[ngramId].origin = 'new'
// also add all its subforms as new subforms
updateActiveGroupInfo (ngramId, toOther)
// redraw active group_box_content
drawActiveSublist(
'#group_box_content',
activeGroup.now_links,
activeGroup.ngraminfo
)
MyTable.data('dynatable').dom.update();
}
else {
console.warn("ADD2GROUP but no active group")
}
}
/**
* subforms from DB have their info in a separate NGrams.group.nodesmemory
* so here and in saveActiveGroup we need to take it into account
*
* TODO: remove this mecanism
*
* @param ngramId
* @param toOtherMainform = flag if ngram was a subform of another mainform
* @param (global) activeGroup = current state struct of modify group dialog
*/
function updateActiveGroupInfo (ngramId, toOtherMainform) {
// console.log("FUN updateActiveGroupInfo(" + AjaxRecords[ngramId].name + ")")
// console.log(activeGroup)
// fill active link info
if( ngramId in NGrams.group.links ) {
for (var i in NGrams.group.links[ngramId]) {
var subId = NGrams.group.links[ngramId][i] ;
// ----------- old links (already in DB)
activeGroup.now_links.push(subId)
activeGroup.ngraminfo[subId] = NGrams.group.nodesmemory[subId]
activeGroup.ngraminfo[subId].origin = toOtherMainform ? 'oldnew' : 'old'
}
}
if( ngramId in GroupsBuffer ) {
for(var i in GroupsBuffer[ ngramId ] ) {
var subId = GroupsBuffer[ ngramId ][i] ;
// ----------- new links (not in DB)
activeGroup.now_links.push(subId)
activeGroup.ngraminfo[subId] = AjaxRecords[subId]
activeGroup.ngraminfo[subId].origin = 'new'
}
}
}
// LIST MEMBERSHIP CONTROLLERS
// ----------------------------
/**
* click red, click keep, click normal...
*
* @param ngramId - the record's id
*/
function clickngram_action ( ngramId ) {
// cycle the statuses (0 => 1 => 2 => 0 => etc) (we are omitting status 3 = group)
AjaxRecords[ngramId].state = (AjaxRecords[ngramId].state==(System[0]["states"].length-2))?0:(AjaxRecords[ngramId].state+1);
// State <=> term color <=> checked colums
// atts.id (ex: "normal" or "delete" etc) // console.log("click: state after: "+ AjaxRecords[ngramId].state) ;
result["score"] = '<span class="'+atts.id+'">'+ngram_info["score"]+'</span>' MyTable.data('dynatable').dom.update();
result["name"] = "<span class=\""+atts.id+
"\" onclick=\"clickngram_action(this.parentNode.parentNode)\">"+ngram_info["name"]+"</span>"+
plus_event
return result;
} }
...@@ -587,17 +731,13 @@ function transformContent(rec_id) { ...@@ -587,17 +731,13 @@ function transformContent(rec_id) {
* Click on a checkbox in a row * Click on a checkbox in a row
* *
* @boxType : 'keep' or 'delete' (resp. maplist and stoplist) * @boxType : 'keep' or 'delete' (resp. maplist and stoplist)
* @elem : entire element row with attribute 'data-stuff' (= rec_id) * @ngramId : corresponding record's id for record.state modifications
*/ */
function checkBox(boxType, elem) { function checkBox(boxType, ngramId) {
console.log ('CLICK on check box') ; // console.log ('CLICK on check box (ngramId = '+ngramId+')') ;
var currentState = AjaxRecords[ngramId].state ;
var elemId = elem.getAttribute("data-stuff") ; // alert('NGRAM: ' + ngramId + '\n'
var ngramId = AjaxRecords[elemId].id ;
var currentState = AjaxRecords[elemId].state ;
// alert('ELEMENT: ' + elemId + '\n'
// + 'NGRAM: ' + ngramId + '\n'
// + 'CURRENT STATE: ' + currentState) ; // + 'CURRENT STATE: ' + currentState) ;
// find out which box // find out which box
...@@ -614,11 +754,133 @@ function checkBox(boxType, elem) { ...@@ -614,11 +754,133 @@ function checkBox(boxType, elem) {
targetState = 0 ; targetState = 0 ;
} }
// set old state and color // replace old state and color
AjaxRecords[elemId].state = targetState ; AjaxRecords[ngramId].state = targetState ;
MyTable.data('dynatable').dom.update(); MyTable.data('dynatable').dom.update();
} }
// TABLE WRITERS PROCESSORS
// ------------------------
/**
* Works for ulWriter. Connects a record's state with table UI outcome.
*
* @param ngramId - the id for this ngram record in AjaxRecords
*
* Returns <tr> contents: an array of html contents to be each injected (by
* dynatable) into respective <td> cells of the row
*/
function transformContent(ngramId) {
var ngram_info = AjaxRecords[ngramId];
// ex: ngram_info = {
// "id":2349,"name":"failure","score":1,"flag":false,
// "group_exists":false,"state":0
// }
// result will contain instanciated cell html for each column in dynatable
var result = {}
// debug
// ------
// console.log(
// "transformContent got ngram_info no " + ngramId + ": "
// + JSON.stringify(ngram_info)
// )
var atts = System[0]["dict"][ System[0]["states"][ngram_info.state] ]
// avec System[0]["dict"] contenant {"normal":{"id":"normal","name":"Normal","color":"black"},"delete":{"id":"delete","name":"Delete","color":"red"}...}
// -------------------------------------------
// prerequisite
var plus_event = ""
// define "plus_event" symbol depending on "grouping" status
// normal situation: button allows to see group contents
if(GState==0) {
var plusicon = '' ;
if (ngram_info["id"] in vizopenGroup) {
plusicon = "glyphicon-triangle-bottom"
} else {
plusicon = "glyphicon-triangle-right"
}
if (ngram_info.group_exists) {
plus_event = '<span class="note glyphicon '+plusicon+'"'
} else {
plus_event = '<span class="note glyphicon '+plusicon+' greyed"'
}
plus_event += ' onclick="toggleSeeGroup(this, '+ ngramId +')"></span>'
}
// GState = 1 situation: button allows to add to active group
// (if previously had add2group button clicked)
if(GState==1 ) {
if(ngram_info.state!=System[0]["statesD"]["delete"] && ! GroupsBuffer[ngramId]) { // if deleted and already group, no Up button
plus_event = '<span class="note glyphicon glyphicon-plus"'
plus_event += ' color="#FF530D"'
plus_event += ' onclick="add2group('+ ngramId +')"></span>'
}
}
// -------------------------------------------
// score and name column cells
// -------------------------------------------
// <td> score </td> atts.id (ex: "normal" or "delete" etc)
result["score"] = '<span class="'+atts.id+'">'+ngram_info["score"]+'</span>\n'
// <td> name </td> aka "ngrambox"
result["name"] = '<div class="ngrambox" id="box-'+ngram_info["id"]+'">\n'
if (ngram_info["id"] != activeGroup.now_mainform_id && !(ngram_info["id"] in activeGroup.were_mainforms)) {
result["name"] += plus_event + '\n'
result["name"] += '<span title="'+ngram_info["id"]+'" class="'+atts.id+'" '
result["name"] += 'onclick="clickngram_action('+ngram_info["id"]+')">'
result["name"] += ngram_info["name"] + '\n'
result["name"] += '</span>\n'
// if curently open we also add #subforms p with the sublist
if (ngram_info["id"] in vizopenGroup) {
result["name"] += seeGroup(ngram_info["id"])[0].outerHTML ;
}
}
result["name"] += '</div>\n'
// -------------------------------------------
// other optional column cells
// uncomment if column ngramId (here and in MainTableAndCharts)
// result["ngramId"] = ngram_info["id"] ;
// uncomment if column state (here and in MainTableAndCharts)
// result["state"] = AjaxRecords[ngramId].state
// -------------------------------------------
// 2 cells for check box state columns
// ('will_be_map' and 'will_be_stop')
map_flag = (AjaxRecords[ngramId].state == 1) ; // 1 = System[0]["statesD"]["keep"]
stop_flag = (AjaxRecords[ngramId].state == 2) ; // 2 = System[0]["statesD"]["delete"]
// <td> checkbox 1 </td>
result["will_be_map"] = '<input type="checkbox" '+(map_flag?'checked ':'')
result["will_be_map"] += 'onclick=\'checkBox("keep",this.parentNode.parentNode.getAttribute("ngram-id"))\'>'
result["will_be_map"] += '</input>'
// <td> checkbox 2 </td>
result["will_be_stop"] = '<input type="checkbox" '+(stop_flag?'checked ':'')
result["will_be_stop"] += 'onclick=\'checkBox("delete",this.parentNode.parentNode.getAttribute("ngram-id"))\'>'
result["will_be_stop"] += '</input>'
// possible todo: 3 way switch ??
// par exemple http://codepen.io/pamgriffith/pen/zcntm
// --------------------------------------------
// {"name":tdcontent1, "score":tdcontent2, ...}
return result;
}
/** /**
* "generic enough" * "generic enough"
* *
...@@ -628,8 +890,7 @@ function checkBox(boxType, elem) { ...@@ -628,8 +890,7 @@ function checkBox(boxType, elem) {
* *
* @param rowIndex: int i++ * @param rowIndex: int i++
* @param record: { "id":1793,"name":"planet","score":1,"flag":false, * @param record: { "id":1793,"name":"planet","score":1,"flag":false,
* "group_plus":true,"group_blocked":false, * "group_exists":false, "state":0}
* "state":0}
* @param columns: constant array * @param columns: constant array
* (with column template for cellWriter) * (with column template for cellWriter)
* (auto-built from html <thead> elements) * (auto-built from html <thead> elements)
...@@ -662,25 +923,23 @@ function ulWriter(rowIndex, record, columns, cellWriter) { ...@@ -662,25 +923,23 @@ function ulWriter(rowIndex, record, columns, cellWriter) {
cp_rec = transformContent(record.id) cp_rec = transformContent(record.id)
// ----------------------------------------------------- // -----------------------------------------------------
// console.log("cp_rec" + JSON.stringify(cp_rec))
// console.log("\n----\nrecord" + JSON.stringify(record))
// grab the record's attribute for each column // grab the record's attribute for each column
for (var i = 0, len = columns.length; i < len; i++) { for (var i = 0, len = columns.length; i < len; i++) {
tr += cellWriter(columns[i], cp_rec); tr += cellWriter(columns[i], cp_rec);
} }
return '<tr data-stuff='+record.id+'>' + tr + '</tr>'; return '<tr ngram-id='+record.id+'>' + tr + '</tr>';
} }
// PAGE SELECTION CONTROLLER
// --------------------------
/** /**
* SelectAll: toggle all checkboxes in a column by changing their list in System * Toggle all checkboxes in a column by changing their list in System
* *
* @boxType : 'keep' or 'delete' (resp. maplist and stoplist) * @boxType : 'keep' or 'delete' (resp. maplist and stoplist)
* @elem : entire element row with attribute 'data-stuff' (= rec_id) * @elem : entire element row with attribute 'ngram-id' (= ngramId)
* *
* 2016-01-12: new version without the old Delete|Keep radio choice * 3-state boxes:
* 2016-01-26: new version with 3-state boxes:
* - indeterminate (SOME del SOME map SOME normal) = original state * - indeterminate (SOME del SOME map SOME normal) = original state
* - check (ALL del or map) * - check (ALL del or map)
* - uncheck (NONE --- " ---) * - uncheck (NONE --- " ---)
...@@ -690,9 +949,9 @@ function ulWriter(rowIndex, record, columns, cellWriter) { ...@@ -690,9 +949,9 @@ function ulWriter(rowIndex, record, columns, cellWriter) {
* of each commanded ngrams (map, stop, miam) * of each commanded ngrams (map, stop, miam)
*/ */
function SelectAll(boxType, boxElem) { function SelectPage(boxType, boxElem) {
// debug // debug
// console.log("\nFUN SelectAll()") // console.log("\nFUN SelectPage()")
// real checkAll flags : SOME|ALL|NONE // real checkAll flags : SOME|ALL|NONE
var previousColumnSelection = $(boxElem).data("columnSelection") ; var previousColumnSelection = $(boxElem).data("columnSelection") ;
...@@ -700,13 +959,13 @@ function SelectAll(boxType, boxElem) { ...@@ -700,13 +959,13 @@ function SelectAll(boxType, boxElem) {
// we will also need the other "checkall box" // we will also need the other "checkall box"
// - to uncheck "delete" when we check "map" & vice-versa // - to uncheck "delete" when we check "map" & vice-versa
// - to make them both "indeterminate" when we restore buffered original state // - to make them both "indeterminate" when we restore cached original state
// - to prevent buffering if the second column is already buffered // - to prevent cacheing if the second column is already cached
if (boxType == 'keep') { otherBoxId = "delAll" ; } if (boxType == 'keep') { otherBoxId = "delAll" ; }
else { otherBoxId = "mapAll" ; } else { otherBoxId = "mapAll" ; }
// did we already buffer original states ? // did we already cache original states ?
var columnBufferExists = null ; var columnCacheExists = null ;
// console.log("-------------INCOMING----------------") // console.log("-------------INCOMING----------------")
// console.log(boxElem.id) // console.log(boxElem.id)
...@@ -719,16 +978,16 @@ function SelectAll(boxType, boxElem) { ...@@ -719,16 +978,16 @@ function SelectAll(boxType, boxElem) {
switch (previousColumnSelection) { switch (previousColumnSelection) {
case 'ALL': case 'ALL':
newColumnSelection = "NONE" ; newColumnSelection = "NONE" ;
columnBufferExists = true ; columnCacheExists = true ;
break ; break ;
case 'NONE': case 'NONE':
newColumnSelection = "SOME" ; newColumnSelection = "SOME" ;
columnBufferExists = true ; columnCacheExists = true ;
break ; break ;
case 'SOME': case 'SOME':
newColumnSelection = "ALL" ; newColumnSelection = "ALL" ;
// probably no buffer, except if other column was set // probably no cache, except if other column was set
columnBufferExists = ($("input#"+otherBoxId).data('columnSelection') != 'SOME') ; columnCacheExists = ($("input#"+otherBoxId).data('columnSelection') != 'SOME') ;
break ; break ;
default: alert('invalid flag for columnSelection'); default: alert('invalid flag for columnSelection');
...@@ -790,22 +1049,21 @@ function SelectAll(boxType, boxElem) { ...@@ -790,22 +1049,21 @@ function SelectAll(boxType, boxElem) {
// console.log("data became:" + newColumnSelection) // console.log("data became:" + newColumnSelection)
$("tbody tr").each(function (i, row) { $("tbody tr").each(function (i, row) {
var rec_id = $(row).data('stuff'); // ids for old state system var ngramId = $(row).attr("ngram-id") ;
//var ngramId = AjaxRecords[rec_id].id; // for future by ngramId
// a buffer to restore previous states if unchecked // a cache to restore previous states if unchecked
if (!columnBufferExists) { if (!columnCacheExists) {
AjaxRecords[rec_id]["state_buff"] = AjaxRecords[rec_id]["state"] ; AjaxRecords[ngramId]["state_buff"] = AjaxRecords[ngramId]["state"] ;
} }
if (stateId != null) { if (stateId != null) {
// check all with the requested change // check all with the requested change
AjaxRecords[rec_id]["state"] = stateId ; AjaxRecords[ngramId]["state"] = stateId ;
} }
else { else {
// restore previous states, remove buffer // restore previous states, remove cache
AjaxRecords[rec_id]["state"] = AjaxRecords[rec_id]["state_buff"] ; AjaxRecords[ngramId]["state"] = AjaxRecords[ngramId]["state_buff"] ;
AjaxRecords[rec_id]["state_buff"] = null ; AjaxRecords[ngramId]["state_buff"] = null ;
} }
}); });
...@@ -817,6 +1075,37 @@ function SelectAll(boxType, boxElem) { ...@@ -817,6 +1075,37 @@ function SelectAll(boxType, boxElem) {
} }
// =============================================================================
// MAIN
// =============================================================================
// MAIN TABLE STATUS CONTROLLERS
// -----------------------------
$("#Clean_All").click(function(){
for(var id in AjaxRecords)
AjaxRecords[id]["state"] = 0;
$("#group_box").remove()
GState=0
MyTable.data('dynatable').dom.update();
for(var i in FlagsBuffer)
for(var j in FlagsBuffer[i])
delete FlagsBuffer[i][j];
// $("#Clean_All, #Save_All").attr( "disabled", "disabled" );
});
$("#Save_All").click(function(){
SaveLocalChanges()
});
// MAIN SAVE + MAIN CREATE TABLE
// -----------------------------
// Save changes to all corpusA-lists // Save changes to all corpusA-lists
function SaveLocalChanges() { function SaveLocalChanges() {
console.log("\nFUN SaveLocalChanges()") console.log("\nFUN SaveLocalChanges()")
...@@ -830,22 +1119,22 @@ function SaveLocalChanges() { ...@@ -830,22 +1119,22 @@ function SaveLocalChanges() {
FlagsBuffer["inmap"] = {} FlagsBuffer["inmap"] = {}
for(var id in AjaxRecords) { for(var id in AjaxRecords) {
if( NGrams["map"][ AjaxRecords[id]["id"] ] ) { if( NGrams["map"][ id ] ) {
if(AjaxRecords[id]["state"]==System[0]["statesD"]["normal"] || AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) { if(AjaxRecords[id]["state"]==System[0]["statesD"]["normal"] || AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) {
FlagsBuffer["outmap"][ AjaxRecords[id].id ] = true FlagsBuffer["outmap"][ id ] = true
if(AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) { if(AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) {
FlagsBuffer["delete"][AjaxRecords[id].id] = true FlagsBuffer["delete"][id] = true
} }
} }
if(FlagsBuffer["group"][AjaxRecords[id].id] && AjaxRecords[id]["state"]==System[0]["statesD"]["keep"]) { if(GroupsBuffer[id] && AjaxRecords[id]["state"]==System[0]["statesD"]["keep"]) {
FlagsBuffer["inmap"][ AjaxRecords[id].id ] = true FlagsBuffer["inmap"][ id ] = true
} }
} else { } else {
if(AjaxRecords[id]["state"]==System[0]["statesD"]["keep"]) { if(AjaxRecords[id]["state"]==System[0]["statesD"]["keep"]) {
FlagsBuffer["inmap"][ AjaxRecords[id].id ] = true FlagsBuffer["inmap"][ id ] = true
} }
if(AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) { if(AjaxRecords[id]["state"]==System[0]["statesD"]["delete"]) {
FlagsBuffer["delete"][AjaxRecords[id].id] = true FlagsBuffer["delete"][id] = true
} }
} }
} }
...@@ -862,8 +1151,8 @@ function SaveLocalChanges() { ...@@ -862,8 +1151,8 @@ function SaveLocalChanges() {
} }
} }
if(FlagsBuffer["inmap"][i]) { if(FlagsBuffer["inmap"][i]) {
for(var j in FlagsBuffer["group"][i] ) { for(var j in GroupsBuffer[i] ) {
FlagsBuffer["outmap"][FlagsBuffer["group"][i][j]] = true FlagsBuffer["outmap"][GroupsBuffer[i][j]] = true
} }
} }
} }
...@@ -876,7 +1165,7 @@ function SaveLocalChanges() { ...@@ -876,7 +1165,7 @@ function SaveLocalChanges() {
var nodes_2del = Object.keys(FlagsBuffer["delete"]).map(Number) // main => stop var nodes_2del = Object.keys(FlagsBuffer["delete"]).map(Number) // main => stop
var nodes_2keep = Object.keys(FlagsBuffer["keep"]).map(Number) // ??? stop => main ??? var nodes_2keep = Object.keys(FlagsBuffer["keep"]).map(Number) // ??? stop => main ???
var nodes_2group = $.extend({}, FlagsBuffer["group"]) var nodes_2group = $.extend({}, GroupsBuffer)
var nodes_2inmap = $.extend({}, FlagsBuffer["inmap"]) // add to map var nodes_2inmap = $.extend({}, FlagsBuffer["inmap"]) // add to map
var nodes_2outmap = $.extend({}, FlagsBuffer["outmap"]) // remove from map var nodes_2outmap = $.extend({}, FlagsBuffer["outmap"]) // remove from map
...@@ -899,14 +1188,13 @@ function SaveLocalChanges() { ...@@ -899,14 +1188,13 @@ function SaveLocalChanges() {
var mainlist_id = $("#mainlist_id").val() var mainlist_id = $("#mainlist_id").val()
var maplist_id = $("#maplist_id" ).val() var maplist_id = $("#maplist_id" ).val()
var stoplist_id = $("#stoplist_id" ).val() var stoplist_id = $("#stoplist_id" ).val()
var groupnode_id = $("#groups_id" ).val()
// var corpus_id = getIDFromURL( "corpora" ) // var corpus_id = getIDFromURL( "corpora" )
$("#stoplist_content").html() $("#stoplist_content").html()
// CRUD( list_id , "" , Object.keys(FlagsBuffer["inmap"]).map(Number) , [] , "PUT", function(result) { // The AJAX CRUDs in cascade:
// console.log( result )
// });
$("#Save_All").append('<img width="8%" src="/static/img/ajax-loader.gif"></img>') $("#Save_All").append('<img width="8%" src="/static/img/ajax-loader.gif"></img>')
...@@ -915,6 +1203,7 @@ function SaveLocalChanges() { ...@@ -915,6 +1203,7 @@ function SaveLocalChanges() {
// add some ngrams to maplist // add some ngrams to maplist
function CRUD_1_AddMap() { function CRUD_1_AddMap() {
console.log("===> AJAX CRUD1 AddMap <===\n") ;
CRUD( maplist_id , Object.keys(nodes_2inmap), "PUT" , function(success) { CRUD( maplist_id , Object.keys(nodes_2inmap), "PUT" , function(success) {
if (success) { if (success) {
CRUD_2_RmMap() // chained AJAX 1 -> 2 CRUD_2_RmMap() // chained AJAX 1 -> 2
...@@ -926,6 +1215,7 @@ function SaveLocalChanges() { ...@@ -926,6 +1215,7 @@ function SaveLocalChanges() {
} }
// remove some ngrams from maplist // remove some ngrams from maplist
function CRUD_2_RmMap() { function CRUD_2_RmMap() {
console.log("===> AJAX CRUD2 RmMap <===\n") ;
CRUD( maplist_id , Object.keys(nodes_2outmap), "DELETE" , function(success) { CRUD( maplist_id , Object.keys(nodes_2outmap), "DELETE" , function(success) {
if (success) { if (success) {
CRUD_3_AddStopRmMain() // chained AJAX 2 -> 3 CRUD_3_AddStopRmMain() // chained AJAX 2 -> 3
...@@ -938,6 +1228,7 @@ function SaveLocalChanges() { ...@@ -938,6 +1228,7 @@ function SaveLocalChanges() {
// 2 operations going together: add ngrams to stoplist and remove them from mainlist // 2 operations going together: add ngrams to stoplist and remove them from mainlist
function CRUD_3_AddStopRmMain() { function CRUD_3_AddStopRmMain() {
console.log("===> AJAX CRUD3a+b AddStopRmMain <===\n") ;
CRUD( stoplist_id , nodes_2del, "PUT" , function(success) { CRUD( stoplist_id , nodes_2del, "PUT" , function(success) {
if (success) { if (success) {
// console.log("OK CRUD 3a add stop") // console.log("OK CRUD 3a add stop")
...@@ -957,33 +1248,20 @@ function SaveLocalChanges() { ...@@ -957,33 +1248,20 @@ function SaveLocalChanges() {
}); });
} }
// add to groups reading data from GroupsBuffer
// TODO add to groups
function CRUD_4() { function CRUD_4() {
window.location.reload() // refresh whole page if all OK console.log("===> AJAX CRUD4 RewriteGroups <===\n") ;
GROUPCRUD(groupnode_id, GroupsBuffer, function(success) {
if (success) {
window.location.reload() // all 4 CRUDs OK => refresh whole page
}
else {
console.warn('CRUD error on ngrams add to group node ('+groupings_id+')')
}
}) ;
} }
} } // end of SaveLocalChanges
$("#Clean_All").click(function(){
for(var id in AjaxRecords)
AjaxRecords[id]["state"] = 0;
$("#group_box").remove()
GState=0
MyTable.data('dynatable').dom.update();
for(var i in FlagsBuffer)
for(var j in FlagsBuffer[i])
delete FlagsBuffer[i][j];
// $("#Clean_All, #Save_All").attr( "disabled", "disabled" );
});
$("#Save_All").click(function(){
SaveLocalChanges()
});
// For list modifications (add/delete), all http-requests // For list modifications (add/delete), all http-requests
function CRUD( list_id , ngram_ids , http_method , callback) { function CRUD( list_id , ngram_ids , http_method , callback) {
...@@ -991,7 +1269,7 @@ function CRUD( list_id , ngram_ids , http_method , callback) { ...@@ -991,7 +1269,7 @@ function CRUD( list_id , ngram_ids , http_method , callback) {
var the_url = window.location.origin+"/api/ngramlists/change?list="+list_id+"&ngrams="+ngram_ids.join(","); var the_url = window.location.origin+"/api/ngramlists/change?list="+list_id+"&ngrams="+ngram_ids.join(",");
// debug // debug
// console.log("starting CRUD AJAX => URL: " + the_url + " (" + http_method + ")") // console.log(" ajax target: " + the_url + " (" + http_method + ")")
if(ngram_ids.length>0) { if(ngram_ids.length>0) {
$.ajax({ $.ajax({
...@@ -1010,7 +1288,7 @@ function CRUD( list_id , ngram_ids , http_method , callback) { ...@@ -1010,7 +1288,7 @@ function CRUD( list_id , ngram_ids , http_method , callback) {
}, },
error: function(result) { error: function(result) {
console.log("-- CRUD ----------") console.log("-- CRUD ----------")
console.log("Data not found in #Save_All"); console.log("AJAX Error on " + http_method + " " + the_url);
console.log(result) console.log(result)
console.log("------------------") console.log("------------------")
callback(false); callback(false);
...@@ -1018,7 +1296,41 @@ function CRUD( list_id , ngram_ids , http_method , callback) { ...@@ -1018,7 +1296,41 @@ function CRUD( list_id , ngram_ids , http_method , callback) {
}); });
} else callback(true); } else callback(true);
} }
// For group modifications (POST: {mainformA: [subformsA1,A2,A3], mainformB:..})
function GROUPCRUD( groupnode_id , post_data , callback) {
// ngramlists/change?node_id=42&ngram_ids=1,2
var the_url = window.location.origin+"/api/ngramlists/groups?node="+groupnode_id;
// debug
// console.log(" ajax target: " + the_url + " (" + http_method + ")")
$.ajax({
method: 'POST',
url: the_url,
data: post_data, // currently all data explicitly in the url (like a GET)
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data){
console.log("-- GROUPCRUD ----------")
console.log("POST ok!!")
console.log(JSON.stringify(data))
console.log("-----------------------")
callback(true);
},
error: function(result) {
console.log("-- GROUPCRUD ----------")
console.log("AJAX Error on POST " + the_url);
console.log(result)
console.log("-----------------------")
callback(false);
}
});
}
...@@ -1037,21 +1349,21 @@ function CRUD( list_id , ngram_ids , http_method , callback) { ...@@ -1037,21 +1349,21 @@ function CRUD( list_id , ngram_ids , http_method , callback) {
* @param initial: initial score type "occs" or "tfidf" * @param initial: initial score type "occs" or "tfidf"
* @param search_filter: eg 'filter_all' (see SearchFilters.MODE) * @param search_filter: eg 'filter_all' (see SearchFilters.MODE)
*/ */
function Main_test( data , initial , search_filter) { function MainTableAndCharts( data , initial , search_filter) {
// debug // debug
// alert("refresh main") // alert("refresh main")
console.log("") console.log("")
console.log(" = = = = MAIN_TEST: = = = = ") console.log(" = = = = MainTableAndCharts: = = = = ")
console.log("data:") console.log("data:")
console.log(data) console.log(data)
console.log("initial:") // console.log("initial:") //
console.log(initial) console.log(initial)
console.log("search_filter:") // eg 'filter_all' console.log("search_filter:") // eg 'filter_all'
console.log(search_filter) console.log(search_filter)
console.log(" = = = = / MAIN_TEST: = = = = ") console.log(" = = = = / MainTableAndCharts: = = = = ")
console.log("") console.log("")
// Expected infos in "data.ngrams" should have the form: // Expected infos in "data.ngrams" should have the form:
// { "1": { id: "1", name: "réalité", score: 36 }, // { "1": { id: "1", name: "réalité", score: 36 },
...@@ -1071,7 +1383,7 @@ function Main_test( data , initial , search_filter) { ...@@ -1071,7 +1383,7 @@ function Main_test( data , initial , search_filter) {
var arrayd3 = [] var arrayd3 = []
// div_table += "\t"+"\t"+"\t"+'<input type="checkbox" id="multiple_selection" onclick="SelectAll(this);" /> Select'+"\n" // div_table += "\t"+"\t"+"\t"+'<input type="checkbox" id="multiple_selection" onclick="SelectPage(this);" /> Select'+"\n"
$("#div-table").html("") $("#div-table").html("")
$("#div-table").empty(); $("#div-table").empty();
...@@ -1085,10 +1397,10 @@ function Main_test( data , initial , search_filter) { ...@@ -1085,10 +1397,10 @@ function Main_test( data , initial , search_filter) {
// Any <th> defined here will end up in the 'columns' arg of ulWriter // Any <th> defined here will end up in the 'columns' arg of ulWriter
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// uncomment for column ngramId (here and in transformContent - l553) // uncomment for column ngramId (here and in transformContent - l.577)
div_table += "\t"+"\t"+'<th data-dynatable-column="ngramId" style="background-color:grey">ngramId</th>'+"\n"; // div_table += "\t"+"\t"+'<th data-dynatable-column="ngramId" style="background-color:grey">ngramId</th>'+"\n";
// uncomment for column stateId (here and in transformContent) // uncomment for column stateId (here and in transformContent - l.580)
// div_table += "\t"+"\t"+'<th data-dynatable-column="state" style="background-color:grey">State</th>'+"\n" ; // div_table += "\t"+"\t"+'<th data-dynatable-column="state" style="background-color:grey">State</th>'+"\n" ;
div_table += "\t"+"\t"+'<th data-dynatable-column="name">Terms</th>'+"\n"; div_table += "\t"+"\t"+'<th data-dynatable-column="name">Terms</th>'+"\n";
...@@ -1103,7 +1415,7 @@ function Main_test( data , initial , search_filter) { ...@@ -1103,7 +1415,7 @@ function Main_test( data , initial , search_filter) {
+ 'Map' + 'Map'
+ '<p class="note">' + '<p class="note">'
+ '<input type="checkbox" id="mapAll"' + '<input type="checkbox" id="mapAll"'
+ ' onclick="SelectAll(\'keep\',this)" title="Check to select all currently visible terms"></input>' + ' onclick="SelectPage(\'keep\',this)" title="Check to select all currently visible terms"></input>'
+ '<label>All</label>' + '<label>All</label>'
+ '</p>' + '</p>'
+ '</th>'+"\n" ; + '</th>'+"\n" ;
...@@ -1115,7 +1427,7 @@ function Main_test( data , initial , search_filter) { ...@@ -1115,7 +1427,7 @@ function Main_test( data , initial , search_filter) {
+ 'Del' + 'Del'
+ '<p class="note">' + '<p class="note">'
+ '<input type="checkbox" id="delAll"' + '<input type="checkbox" id="delAll"'
+ ' onclick="SelectAll(\'delete\',this)" title="Check to select all currently visible terms"></input>' + ' onclick="SelectPage(\'delete\',this)" title="Check to select all currently visible terms"></input>'
+ '<label>All</label>' + '<label>All</label>'
+ '</p>' + '</p>'
+ '</th>'+"\n" ; + '</th>'+"\n" ;
...@@ -1128,6 +1440,8 @@ function Main_test( data , initial , search_filter) { ...@@ -1128,6 +1440,8 @@ function Main_test( data , initial , search_filter) {
div_table += '</p>'; div_table += '</p>';
$("#div-table").html(div_table) $("#div-table").html(div_table)
// width of the table in columns
tableSpan = $("#div-table th").length ;
// indeterminate: only visual // indeterminate: only visual
$('#delAll').prop("indeterminate", true) $('#delAll').prop("indeterminate", true)
...@@ -1153,20 +1467,18 @@ function Main_test( data , initial , search_filter) { ...@@ -1153,20 +1467,18 @@ function Main_test( data , initial , search_filter) {
// console.log(data.ngrams[i]) // console.log(data.ngrams[i])
var le_ngram = data.ngrams[id] ; var le_ngram = data.ngrams[id] ;
// INIT records
// one record <=> one line in the table + ngram states
var rec_info = { var rec_info = {
"id" : le_ngram.id, "id" : le_ngram.id,
"name": le_ngram.name, "name": le_ngram.name,
"score": le_ngram.score, "score": le_ngram.score,
"flag":false, "flag":false,
"group_plus": true, // "state": 0
"group_blocked": false,
// "state": 0,
"state": (le_ngram.state)?le_ngram.state:0, "state": (le_ngram.state)?le_ngram.state:0,
// properties enabling to see old and new groups
// rl: 2 new columns showing 'state == map' and 'state == del' "group_exists": (le_ngram.id in NGrams.group.links || le_ngram.id in GroupsBuffer),
"will_be_map": null,
"will_be_stop": null
} }
// AjaxRecords.push(rec_info) // AjaxRecords.push(rec_info)
AjaxRecords[id] = rec_info AjaxRecords[id] = rec_info
...@@ -1194,13 +1506,13 @@ function Main_test( data , initial , search_filter) { ...@@ -1194,13 +1506,13 @@ function Main_test( data , initial , search_filter) {
} }
// console.clear() // console.clear()
// for(var i in DistributionList) { // for(var i in DistributionList) {
// // DistributionList[i].x_occ = Math.log( DistributionList[i].x_occ ) // // DistributionList[i].x_occ = Math.log( DistributionList[i].x_occ )
// // DistributionList[i].y_frec = Math.log( DistributionList[i].y_frec )+1 // // DistributionList[i].y_frec = Math.log( DistributionList[i].y_frec )+1
// console.log( DistributionList[i] ) // console.log( DistributionList[i] )
// } // }
// return; // return;
oldest = Number(min_occ); oldest = Number(min_occ);
latest = Number(max_occ); latest = Number(max_occ);
...@@ -1305,7 +1617,7 @@ function Main_test( data , initial , search_filter) { ...@@ -1305,7 +1617,7 @@ function Main_test( data , initial , search_filter) {
_rowWriter: ulWriter _rowWriter: ulWriter
// _cellWriter: customCellWriter // _cellWriter: customCellWriter
} }
}) })
// MyTable.data('dynatable').settings.dataset.records = [] // MyTable.data('dynatable').settings.dataset.records = []
// MyTable.data('dynatable').settings.dataset.originalRecords = [] // MyTable.data('dynatable').settings.dataset.originalRecords = []
...@@ -1321,11 +1633,10 @@ function Main_test( data , initial , search_filter) { ...@@ -1321,11 +1633,10 @@ function Main_test( data , initial , search_filter) {
MyTable.data('dynatable').process(); MyTable.data('dynatable').process();
// hook on page change // hook on page change
MyTable.bind('dynatable:page:set', function(){ MyTable.bind('dynatable:page:set', tidyAfterPageSetUpdate)
// we visually uncheck both 'all' boxes
$('input#mapAll').attr('checked', false); // hook on any type of update
$('input#delAll').attr('checked', false); MyTable.bind('dynatable:afterUpdate', tidyAfterUpdate)
})
// // // $("#score_column_id").children()[0].text = FirstScore // // // $("#score_column_id").children()[0].text = FirstScore
// // // // MyTable.data('dynatable').process(); // // // // MyTable.data('dynatable').process();
...@@ -1337,10 +1648,10 @@ function Main_test( data , initial , search_filter) { ...@@ -1337,10 +1648,10 @@ function Main_test( data , initial , search_filter) {
// Search // Search
// TODO : $("#filter_search").html( $("#filter_search").html().replace('selected="selected"') ); // TODO : $("#filter_search").html( $("#filter_search").html().replace('selected="selected"') );
$("#"+search_filter).attr( "selected" , "selected" ) $("#"+search_filter).attr( "selected" , "selected" )
var the_content = $("#filter_search").html(); var the_content = $("#filter_search").html();
$(""+the_content).insertAfter("#dynatable-query-search-my-ajax-table") $(""+the_content).insertAfter("#dynatable-query-search-my-ajax-table")
return "OK" return "OK"
} }
...@@ -1349,31 +1660,31 @@ function SearchFilters( elem ) { ...@@ -1349,31 +1660,31 @@ function SearchFilters( elem ) {
var MODE = elem.value; var MODE = elem.value;
if( MODE == "filter_all") { if( MODE == "filter_all") {
var result = Main_test( NGrams["main"] , NGrams["main"].scores.initial , MODE) var result = MainTableAndCharts( NGrams["main"] , NGrams["main"].scores.initial , MODE)
console.log( result ) console.log( result )
MyTable.data('dynatable').sorts.clear(); MyTable.data('dynatable').sorts.clear();
MyTable.data('dynatable').sorts.add('score', 0) // 1=ASCENDING, MyTable.data('dynatable').sorts.add('score', 0) // 1=ASCENDING,
MyTable.data('dynatable').process(); MyTable.data('dynatable').process();
} }
if( MODE == "filter_map-list") { if( MODE == "filter_map-list") {
console.log("ngrams_map:") console.log("ngrams_map:")
console.log(NGrams["map"]) console.log(NGrams["map"])
var sub_ngrams_data = { var sub_ngrams_data = {
"ngrams":[], "ngrams":[],
"scores": $.extend({}, NGrams["main"].scores) "scores": $.extend({}, NGrams["main"].scores)
} }
for(var r in NGrams["main"].ngrams) { for(var r in NGrams["main"].ngrams) {
if ( NGrams["map"][NGrams["main"].ngrams[r].id] ) { if ( NGrams["map"][NGrams["main"].ngrams[r].id] ) {
var a_ngram = NGrams["main"].ngrams[r] var a_ngram = NGrams["main"].ngrams[r]
a_ngram["state"] = System[0]["statesD"]["keep"] a_ngram["state"] = System[0]["statesD"]["keep"]
sub_ngrams_data["ngrams"].push( a_ngram ) sub_ngrams_data["ngrams"].push( a_ngram )
} }
} }
var result = Main_test(sub_ngrams_data , NGrams["main"].scores.initial , MODE) var result = MainTableAndCharts(sub_ngrams_data , NGrams["main"].scores.initial , MODE)
console.log( result ) console.log( result )
// MyTable.data('dynatable').sorts.clear(); // MyTable.data('dynatable').sorts.clear();
// MyTable.data('dynatable').sorts.add('score', 0) // 1=ASCENDING, // MyTable.data('dynatable').sorts.add('score', 0) // 1=ASCENDING,
...@@ -1382,38 +1693,112 @@ function SearchFilters( elem ) { ...@@ -1382,38 +1693,112 @@ function SearchFilters( elem ) {
if( MODE == "filter_stop-list") { if( MODE == "filter_stop-list") {
console.log( NGrams["stop"] ) console.log( NGrams["stop"] )
if(Object.keys(NGrams["stop"]).length>0) { if(Object.keys(NGrams["stop"]).length>0) {
var sub_ngrams_data = { var sub_ngrams_data = {
"ngrams":[], "ngrams":[],
"scores": $.extend({}, NGrams["main"].scores) "scores": $.extend({}, NGrams["main"].scores)
} }
for(var r in NGrams["stop"]) { for(var r in NGrams["stop"]) {
var a_ngram = NGrams["stop"][r] ; var a_ngram = NGrams["stop"][r] ;
// deletestateId = 2 // deletestateId = 2
var deletestateId = System[0]["statesD"]["delete"] ; var deletestateId = System[0]["statesD"]["delete"] ;
a_ngram["state"] = deletestateId ; a_ngram["state"] = deletestateId ;
sub_ngrams_data["ngrams"].push( a_ngram ) sub_ngrams_data["ngrams"].push( a_ngram )
} }
var result = Main_test(sub_ngrams_data , NGrams["main"].scores.initial , MODE) var result = MainTableAndCharts(sub_ngrams_data , NGrams["main"].scores.initial , MODE)
console.log( result ) console.log( result )
} }
} }
} }
// =============================================================================
// SUBROUTINES
// =============================================================================
/**
* tidyAfterUpdate:
* -----------
* Here we clean all our vars that become obsolete when any update occurs
* (this function is bound to the dynatable event "dynatable:afterUpdate")
*/
function tidyAfterUpdate(event) {
// debug:
// console.log("event") ;
// console.log(event) ;
// CLEAR ALL FLAGS AND GLOBAL VARS HERE
// currently nothing to do
}
/**
* tidyAfterPageSet:
* -------------
* Here we clean vars that become obsolete not at all updates, but only
* when page changes (bound to the dynatable event "dynatable:page:set")
*/
function tidyAfterPageSetUpdate() {
// (1)
// SelectPage keeps cache of column states but
// a new page is new ngrams in their own lists
// we visually uncheck both 'all' boxes
$('input#delAll').attr('checked', false);
$('input#mapAll').attr('checked', false);
// indeterminate: only visual
$('#delAll').prop("indeterminate", true)
$('#mapAll').prop("indeterminate", true)
// real checkAll states : SOME|ALL|NONE
$('#delAll').data("columnSelection", 'SOME')
$('#mapAll').data("columnSelection", 'SOME')
// (2)
// page change must've closed all group's minilists so we blank open states
vizopenGroup = {}
}
function pr(msg) {
console.log(msg)
}
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function getIDFromURL( item ) { function getIDFromURL( item ) {
var pageurl = window.location.href.split("/") var pageurl = window.location.href.split("/")
var cid; var cid;
for(var i in pageurl) { for(var i in pageurl) {
if(pageurl[i]==item) { if(pageurl[i]==item) {
cid=parseInt(i); cid=parseInt(i);
break; break;
} }
} }
return pageurl[cid+1]; return pageurl[cid+1];
} }
// For lists, only GET requests // For lists, only GET requests
...@@ -1423,7 +1808,7 @@ function GET_( url , callback ) { ...@@ -1423,7 +1808,7 @@ function GET_( url , callback ) {
url: url, url: url,
dataType: "json", dataType: "json",
success : function(data, textStatus, jqXHR) { success : function(data, textStatus, jqXHR) {
callback(data); callback(data);
}, },
error: function(exception) { error: function(exception) {
callback(false); callback(false);
...@@ -1431,15 +1816,18 @@ function GET_( url , callback ) { ...@@ -1431,15 +1816,18 @@ function GET_( url , callback ) {
}) })
} }
// ######################### AJAX && INIT #########################
// [ = = = = = = = = = = INIT = = = = = = = = = = ] // [ = = = = = = = = = = INIT = = = = = = = = = = ]
// http://localhost:8000/api/node/84592/ngrams?format=json&score=tfidf,occs&list=miam // http://localhost:8000/api/node/84592/ngrams?format=json&score=tfidf,occs&list=miam
var corpus_id = getIDFromURL( "corpora" ) var corpus_id = getIDFromURL( "corpora" )
var NGrams = { var NGrams = {
"group" : {}, "group" : {},
"stop" : {}, "stop" : {},
"main" : {}, "main" : {},
"map" : {}, "map" : {},
"scores" : {} "scores" : {}
} }
$("#corpusdisplayer").hide() $("#corpusdisplayer").hide()
...@@ -1458,7 +1846,6 @@ GET_(new_url, function(res) { ...@@ -1458,7 +1846,6 @@ GET_(new_url, function(res) {
main_ngrams_objects = {} main_ngrams_objects = {}
for (var ngram_id in res.ngraminfos) { for (var ngram_id in res.ngraminfos) {
var ngram_tuple = res.ngraminfos[ngram_id] var ngram_tuple = res.ngraminfos[ngram_id]
// TODO remove k
main_ngrams_objects[ngram_id] = { main_ngrams_objects[ngram_id] = {
'id' : ngram_id, // redundant but for backwards compat 'id' : ngram_id, // redundant but for backwards compat
'name' : ngram_tuple[0], 'name' : ngram_tuple[0],
...@@ -1467,32 +1854,37 @@ GET_(new_url, function(res) { ...@@ -1467,32 +1854,37 @@ GET_(new_url, function(res) {
} }
console.log("===> AJAX INIT <===\n" + "source: " + new_url) console.log("===> AJAX INIT <===\n" + "source: " + new_url)
// = = = = MIAM = = = = //
NGrams["main"] = { NGrams["main"] = {
"ngrams": main_ngrams_objects, "ngrams": main_ngrams_objects,
"scores": { "scores": {
"initial":"occs", "initial":"occs",
"nb_ngrams":Object.keys(main_ngrams_objects).length, "nb_ngrams":Object.keys(main_ngrams_objects).length,
} }
} ; } ;
// map & stop: 2x(array of ids) ==> 2x(lookup hash)
// = = MAP ALSO STOP = = //
// 2x(array of ids) ==> 2x(lookup hash)
NGrams["map"] = {} ; NGrams["map"] = {} ;
for (var i in res.listmembers.maplist) { for (var i in res.listmembers.maplist) {
var map_ng_id = res.listmembers.maplist[i] ; var map_ng_id = res.listmembers.maplist[i] ;
NGrams["map"][map_ng_id] = true ; NGrams["map"][map_ng_id] = true ;
} }
NGrams["stop"] = {} ; NGrams["stop"] = {} ;
for (var i in res.listmembers.stoplist) { for (var i in res.listmembers.stoplist) {
var stop_ng_id = res.listmembers.stoplist[i] ; var stop_ng_id = res.listmembers.stoplist[i] ;
NGrams["stop"][stop_ng_id] = true ; NGrams["stop"][stop_ng_id] = true ;
} }
NGrams["group"] = {"links" : res.links , "nodes" : {}};
for (var parent_ng_id in res.links) { // = = = = GROUP = = = = //
NGrams["group"]["nodes"][parent_ng_id] = false ; NGrams["group"] = {
for (var i in res.links[parent_ng_id]) { "links" : res.links ,
child_ng_id = res.links[parent_ng_id][i] // "nodesmemory" will be filled from "links" in AfterAjax()
NGrams["group"]["nodes"][child_ng_id] = false "nodesmemory" : {}
} };
}
} }
// console.log('after init NGrams["main"].ngrams') // console.log('after init NGrams["main"].ngrams')
// console.log(NGrams["main"].ngrams) // console.log(NGrams["main"].ngrams)
...@@ -1506,94 +1898,45 @@ GET_(new_url, function(res) { ...@@ -1506,94 +1898,45 @@ GET_(new_url, function(res) {
AfterAjax() ; AfterAjax() ;
}); });
// The AJAX's in cascade:
// GET_( url[0] , function(result) {
//
// // = = = = MIAM = = = = //
// if(result!=false) {
// NGrams["main"] = {
// "ngrams": [],
// "scores": {
// "initial":"occs",
// "nb_docs":result.length,
// "orig_nb_ngrams":1,
// "nb_ngrams":result.length,
// }
// }
//
// var occs_sum = 0
// for(var i in result) {
// NGrams["main"].ngrams.push(result[i])
// occs_sum += result[i].scores.occs
// }
// if(occs_sum==0)
// NGrams["main"]["scores"]["initial"] = "tfidf";
//
// }
// // = = = = /MIAM = = = = //
//
// GET_( url[1] , function(result) {
// // = = = = MAP = = = = //
// if(result!=false) {
// NGrams["map"] = result
// }
// // = = = = /MAP = = = = //
//
// GET_( url[2] , function(result) {
// // = = = = GROUP = = = = //
// if(result!=false) {
// NGrams["group"] = result
// }
// // = = = = /GROUP = = = = //
//
// AfterAjax()
// GET_( url[3] , function(result) {
// // = = = = STOP = = = = //
// for(var i in result) {
// NGrams["stop"][result[i].id] = result[i]
// }
// // = = = = /STOP = = = = //
// });
// });
// });
// });
function AfterAjax() { function AfterAjax() {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// dbg: Ngrams structure is too large
// console.log(JSON.stringify(NGrams)) // console.log(JSON.stringify(NGrams))
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Deleting subforms from the ngrams-table, clean start baby! // Deleting subforms from the ngrams-table, clean start baby!
if( Object.keys(NGrams["group"].links).length>0 ) { if( Object.keys(NGrams["group"].links).length>0 ) {
var _forms = { "main":{} , "sub":{} } // subforms inventory { "main":{ all mainform ids } , "sub":{ all subform ids} }
// subforms inventory var _forms = { "main":{} , "sub":{} }
for(var i in NGrams["group"].links) { for(var ngramId in NGrams["group"].links) {
_forms["main"][i] = true _forms["main"][ngramId] = true
for(var j in NGrams["group"].links[i]) { for(var i in NGrams["group"].links[ngramId]) {
// for each subform {subform_ngramid : true} var subformId = NGrams["group"].links[ngramId][i]
_forms["sub"][ NGrams["group"].links[i][j] ] = true // for each subform: true
} _forms["sub"][ subformId ] = true
} }
}
// console.log('_forms["sub"]') // debug:
// console.log( _forms["sub"] ) // console.log('~~~~~~~~~~~~~> (sub) _forms')
// console.log( _forms )
// ngrams_data_ will update NGrams.main (with subforms removed) // ------------------------------------------- MAINLIST
var ngrams_data_ = {} // ngrams_data_ will update NGrams.main.ngrams (with subforms removed)
for(var ngram_id in NGrams["main"].ngrams) { var ngrams_data_ = {}
for(var ngram_id in NGrams["main"].ngrams) {
// if ngram is subform of another // if ngram is subform of another
if(_forms["sub"][ngram_id]) { if(_forms["sub"][ngram_id]) {
// subform info storage into NGrams.group.nodes // move subform info into NGrams.group.nodesmemory
// --------------------------------------------- // ------------------------------------------
// (subform goes away from new list but info preserved) // (subform goes away from new list but info preserved)
// (useful if we want to see/revive subforms in future) // (useful if we want to see/revive subforms in future)
NGrams["group"]["nodes"][ngram_id] = NGrams["main"].ngrams[i] NGrams.group.nodesmemory[ngram_id] = NGrams["main"].ngrams[ngram_id]
// debug:
// console.log(ngram_id + " ("+NGrams["main"].ngrams[ngram_id].name+") is a subform")
} }
// normal case // normal case
else { else {
...@@ -1606,30 +1949,29 @@ function AfterAjax() { ...@@ -1606,30 +1949,29 @@ function AfterAjax() {
NGrams["main"].ngrams = ngrams_data_; NGrams["main"].ngrams = ngrams_data_;
} }
// console.log('NGrams["group"]["nodes"]') // NB: this miamlist will eventually become AjaxRecords
// console.log( NGrams["group"]["nodes"] ) // debug:
// console.log('NGrams["main"]')
// console.log( NGrams["main"] )
// console.log('after subforms deletion NGrams["main"].ngrams')
// console.log(NGrams["main"].ngrams)
// initialize state of maplist items // ----------------------------------------- MAPLIST
if( Object.keys(NGrams["map"]).length>0 ) { if( Object.keys(NGrams["map"]).length>0 ) {
for(var ngram_id in NGrams["main"].ngrams) { for(var ngram_id in NGrams["main"].ngrams) {
myMiamNgram = NGrams["main"].ngrams[ngram_id] myMiamNgram = NGrams["main"].ngrams[ngram_id]
if(NGrams["map"][ngram_id]) { if(NGrams["map"][ngram_id]) {
// keepstateId = 1 // keepstateId = 1
keepstateId = System[0]["statesD"]["keep"] keepstateId = System[0]["statesD"]["keep"]
// initialize state of maplist items
myMiamNgram["state"] = keepstateId ; myMiamNgram["state"] = keepstateId ;
} }
} }
} }
// console.log('NGrams["main"]')
// console.log( NGrams["main"] )
// Building the Score-Selector //NGrams["scores"] // Building the Score-Selector //NGrams["scores"]
var FirstScore = NGrams["main"].scores.initial var FirstScore = NGrams["main"].scores.initial
// £TODO scores_div // TODO scores_div
// Recreate possible_scores from some constants (tfidf, occs) // Recreate possible_scores from some constants (tfidf, occs)
// and not from ngrams[0], to keep each ngram's info smaller // and not from ngrams[0], to keep each ngram's info smaller
...@@ -1642,9 +1984,10 @@ function AfterAjax() { ...@@ -1642,9 +1984,10 @@ function AfterAjax() {
// } // }
// } // }
// Initializing the Charts and Table // Initializing the Charts and Table ---------------------------------------
var result = Main_test( NGrams["main"] , FirstScore , "filter_all") var result = MainTableAndCharts( NGrams["main"] , FirstScore , "filter_all")
console.log( result ) // OK console.log( result ) // OK
// -------------------------------------------------------------------------
// see TODO scores_div // see TODO scores_div
// Listener for onchange Score-Selector // Listener for onchange Score-Selector
...@@ -1652,7 +1995,7 @@ function AfterAjax() { ...@@ -1652,7 +1995,7 @@ function AfterAjax() {
// $("#ScoresBox").html(scores_div) // $("#ScoresBox").html(scores_div)
// $("#scores_selector").on('change', function() { // $("#scores_selector").on('change', function() {
// console.log( this.value ) // console.log( this.value )
// var result = Main_test( NGrams["main"] , this.value , "filter_all") // var result = MainTableAndCharts( NGrams["main"] , this.value , "filter_all")
// console.log( result ) // console.log( result )
// //
// }); // });
......
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