Commit fb15dba9 authored by Romain Loth's avatar Romain Loth

harmonize assumption node type 0 points to catSem as default

parent 9f94f18e
......@@ -38,8 +38,8 @@ This will still evolve but the main steps for any graph initialization messily u
#### About source data
- doc/sem typing: follows the node property "`type`" or if absent, "`category`"
- if the category name is "document" => catSoc (type 0)
- if the category name contains the str "term" => catSem (type 1)
- if the category name contains the str "term" => catSem (type 0)
- if the category name is "document" => catSoc (type 1)
- `somenode.attributes`: the `attributes` property is always an object
- any attribute listed in the sourcenode.attributes will be indexed if the TW.scanClusters flag is true
......
......@@ -201,7 +201,7 @@
</a></li>
<li class="weight-selectors for-nodecategory-0">
<!-- Create a subgraph over nodes from TW.categories[0] (docs or def nodes)-->
<!-- Create a subgraph over nodes from TW.categories[0] (terms or def nodes)-->
<table>
<tr>
<td class="slider-legend">
......@@ -220,7 +220,7 @@
</table>
</li>
<li class="weight-selectors for-nodecategory-1">
<!-- Create a subgraph over nodes from TW.categories[1] (terms)-->
<!-- Create a subgraph over nodes from TW.categories[1] (docs or people)-->
<table>
<tr class="weight-selector">
<td class="slider-legend">
......
......@@ -27,7 +27,7 @@ function changeGraphAppearanceByFacets( manualflag ) {
if( $( "#colorgraph-menu" ).length>0 ) {
var actypes = getActivetypes()
var actypes = getActivetypesNames()
for (var tid in actypes) {
let ty = actypes[tid]
......@@ -229,7 +229,7 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
$("#legend-for-clusters").html("")
if(daclass==null) return;
var actypes = getActivetypes()
var actypes = getActivetypesNames()
// we have no specifications yet for colors (and legends) on multiple types
if (actypes.length > 1) {
......@@ -697,7 +697,7 @@ function activateModules() {
// NB condition on dataType could be on an extended meta "attrType"
// cf. doc/developer_manual.md autodiagnose remark)
function fillAttrsInForm(menuId, optionalAttTypeConstraint) {
var actypes = getActivetypes()
var actypes = getActivetypesNames()
for (let tid in actypes) {
let ty = actypes[tid]
......
......@@ -146,13 +146,11 @@ TW.conf = (function(TW){
// TINA BEHAVIOR
// =============
// Node typology (searched in nodes data, overridden if data has other types)
// (FIXME cf. comment in sortNodeTypes and swActual functions
// about the limits of how these 2 values and
// TW.categories are used in older functions)
// Node typology: categories (resp. 0 and 1) will get these default labels
TWConf.catSem = "Terms";
TWConf.catSoc = "Document";
TWConf.catSem = "NGram";
// NB: these labels may be superseded by the input data's node types values
// cf. sortNodeTypes()
// Active modules
// --------------
......@@ -283,8 +281,8 @@ TW.conf = (function(TW){
// relative sizes (iff ChangeType == both nodetypes)
TWConf.sizeMult = [];
TWConf.sizeMult[0] = 3.0; // ie for node type 0
TWConf.sizeMult[1] = 1.0; // ie for node type 1
TWConf.sizeMult[0] = 1.0; // ie for node type 0 (<=> sem)
TWConf.sizeMult[1] = 3.0; // ie for node type 1 (<=> soc)
......
......@@ -371,6 +371,7 @@ var TinaWebJS = function ( sigmacanvas ) {
});
// register an index for nodes by type and size (<= origNode.size||origNode.weight)
// £TODO use it for type-constrained loops
sigmaModule.classes.graph.addIndex('nodesBySize', {
constructor: function() {
this.nodesBySize = {};
......@@ -384,6 +385,10 @@ var TinaWebJS = function ( sigmacanvas ) {
this.nodesBySize[n.type][sizekey] = {}
this.nodesBySize[n.type][sizekey][n.id] = true
}
else {
// should never happen
console.warn("warning: couldn't add node to index ?", n)
}
},
dropNode: function(n) {
if (n.type && n.size) {
......@@ -711,33 +716,6 @@ var TinaWebJS = function ( sigmacanvas ) {
TW.gui.circleSlider.setValue(0)
});
// //finished
// $("#slidercat1nodessize").freshslider({
// step:1,
// min:-20,
// max:20,
// value:0,
// bgcolor:"#FFA500",
// onchange:function(value){
// setTimeout(function (){
// // new sigma.js loop on nodes POSS optimize
// nds = TW.partialGraph.graph.nodes()
// console.log("init: slider resize")
// for(j=0 ; j<TW.partialGraph.nNodes ; j++){
// if (nds[j]
// && nds[j].type == TW.conf.catSem) {
// var n = nds[j]
// var newval = parseFloat(TW.Nodes[n.id].size) + parseFloat((value-1))*0.3
// n.size = (newval<1.0)?1:newval;
// sizeMult[TW.conf.catSem] = parseFloat(value-1)*0.3;
// }
// }
// partialGraph.render()
// },
// 100);
// }
// });
// costly entire refresh (~400ms) only after stopped resizing for 3s
// NB: rescale middleware already reacted and, except for large win size changes, it handles the resize fine
......@@ -776,6 +754,8 @@ var TinaWebJS = function ( sigmacanvas ) {
// args: @partialGraph = a sigma instance
this.initSigmaListeners = function(partialGraph, initialActivetypes) {
console.log("initSigmaListeners TW.categories", TW.categories)
var selInst = this.selNgn
// sigma events bindings
......@@ -958,15 +938,19 @@ var TinaWebJS = function ( sigmacanvas ) {
if (TW.conf.filterSliders) {
// the indice of the first cat to be active (ex: '1')
let activeId = initialActivetypes.indexOf(true)
// args: for display: target div ,
// for context: family/type prop value,
// for values: the property to filter
NodeWeightFilter ( "#slidercat0nodesweight" ,
TW.categories[0] ,
NodeWeightFilter ( `#slidercat${activeId}nodesweight` ,
TW.categories[activeId] ,
"size"
);
EdgeWeightFilter("#slidercat0edgesweight",
// ex: #slidercat1edgesweight
EdgeWeightFilter(`#slidercat${activeId}edgesweight`,
getActivetypesKey(),
"weight"
);
......@@ -1031,45 +1015,15 @@ var TinaWebJS = function ( sigmacanvas ) {
}
// our current choice: show only the last cat
// POSS make it a configuration settings
this.initialActivetypes = function( categories ) {
var firstActivetypes = []
for(var i=0; i<categories.length ; i++) {
if(i==0) firstActivetypes.push(true) // <==> show the cat stored in 0
else firstActivetypes.push(false) // <==> hide the cat stored in 1
if(i==categories.length-1) firstActivetypes.push(true)
else firstActivetypes.push(false)
}
return firstActivetypes;
}
this.allPossibleActivetypes = function (cats) {
if (TW.conf.debug.logSettings) console.debug(`allPossibleActivetypes(cats=${cats})`)
var possibleActivetypes = {}
var N=Math.pow(2 , cats.length);
for (var i = 0; i < N; i++) {
let bin = (i).toString(2)
let bin_splitted = []
for(var j in bin)
bin_splitted.push(bin[j])
let bin_array = [];
let toadd = cats.length-bin_splitted.length;
for (var k = 0; k < toadd; k++)
bin_array.push("0")
for(var j in bin)
bin_array.push(bin[j])
bin_array = bin_array.map(Number)
let sum = bin_array.reduce(function(a, b){return a+b;})
if( sum != 0 && sum < 3) {
let id = bin_array.join("|")
possibleActivetypes[id] = bin_array.map(Boolean)
}
}
return possibleActivetypes;
}
};
......@@ -610,8 +610,8 @@ function EdgeWeightFilter(sliderDivID , typestr , criteria) {
range: true,
step: 1,
min:0,
// green for docs, orange for terms
bgcolor: (typestr=="1|0" || typestr=="1")?"#27c470":"#FFA500" ,
// green for docs/people, orange for terms
bgcolor: (typestr=="1|0" || typestr=="1")?"#FFA500":"#27c470" ,
max:steps-1,
value:[0,steps-1],
onchange:function(low, high) {
......@@ -688,6 +688,7 @@ function EdgeWeightFilter(sliderDivID , typestr , criteria) {
// console.log("adding "+ids.join())
for(var i in eids) {
let eid = eids[i]
TW.Edges[eid].lock = false;
// global level case
......@@ -844,7 +845,7 @@ function NodeWeightFilter( sliderDivID , tgtNodeType , criteria) {
step: 1,
min:0,
max:steps-1,
bgcolor:( tgtNodeType==TW.categories[0] )?"#27c470":"#FFA500" ,
bgcolor:( tgtNodeType==TW.categories[0] )?"#FFA500":"#27c470" ,
value:[0,steps-1],
// handler
......
......@@ -359,7 +359,6 @@ function mainStartGraph(inFormat, inData, twInstance) {
// activetypes: the node categorie(s) that is (are) currently displayed
// ex: [true,false] = [nodes of type 0 shown ; nodes of type 1 not drawn]
var initialActivetypes = TW.instance.initialActivetypes( TW.categories )
var possibleActivetypes = TW.instance.allPossibleActivetypes( TW.categories )
// remember it
TW.pushState({'activetypes': initialActivetypes})
......@@ -381,38 +380,21 @@ function mainStartGraph(inFormat, inData, twInstance) {
if (inData.clusters) TW.Clusters = inData.clusters
// £TODO remove from parseCustom or start using
// TW.nodes1 = dicts.n1;//not used
// main console info
// ===================
console.info(`== new graph ${TW.nodeIds.length} nodes, ${TW.edgeIds.length} edges ==`)
console.info(`== new graph ${TW.nodeIds.length} nodes (${TW.categories.length > 1 ? 'bipartite': 'monopartite'}), ${TW.edgeIds.length} edges ==`)
// a posteriori categories diagnostic
// ----------------------------------
// by default TW.categories now match user-suggested catSoc/Sem if present
// so we just need to handle mismatches here (when user-suggested cats were absent)
if (TW.categories.length == 2) {
console.info("== 'bipartite' case ==")
if (TW.conf.catSoc != TW.categories[0]) {
console.warn(`Observed social category "${TW.categories[0]}" overwrites user-suggested TW.conf.catSoc ("${TW.conf.catSoc}")`)
TW.conf.catSoc = TW.categories[0]
}
if (TW.conf.catSem != TW.categories[1]) {
console.warn(`Observed semantic category "${TW.categories[1]}" overwrites user-suggested TW.conf.catSem "(${TW.conf.catSem})"`)
TW.conf.catSem = TW.categories[1]
}
if (TW.conf.catSem != TW.categories[0]) {
console.warn(`Observed semantic category "${TW.categories[0]}" overwrites user-suggested TW.conf.catSem "(${TW.conf.catSem})"`)
TW.conf.catSem = TW.categories[0]
}
else if (TW.categories.length == 1) {
console.info("== monopartite case ==")
// FIXME it would be more coherent with all tina usecases (like gargantext or tweetoscope) for the default category to be catSem instead of Soc
if (TW.conf.catSoc != TW.categories[0]) {
console.warn(`Observed unique category "${TW.categories[0]}" overwrites user-suggested TW.conf.catSoc ("${TW.conf.catSoc}")`)
TW.conf.catSoc = TW.categories[0]
}
}
else {
console.error("== currently unhandled categorization of node types ==", TW.categories)
if (TW.categories.length > 1 && TW.conf.catSoc != TW.categories[1]) {
console.warn(`Observed social category "${TW.categories[1]}" overwrites user-suggested TW.conf.catSoc ("${TW.conf.catSoc}")`)
TW.conf.catSoc = TW.categories[1]
}
// [ Poblating the Sigma-Graph ]
......
......@@ -48,24 +48,23 @@ TW.pushState = function( args ) {
|| typesKey != lastState.activetypes.map(Number).join("|"))) {
// terms
if(typesKey=="1|0") {
$(".for-nodecategory-0").show()
$(".for-nodecategory-1").hide();
NodeWeightFilter( "#slidercat0nodesweight" , TW.categories[0], "size");
EdgeWeightFilter("#slidercat0edgesweight", typesKey, "weight");
}
// docs
if(typesKey=="0|1") {
$(".for-nodecategory-0").hide()
$(".for-nodecategory-1").show();
NodeWeightFilter( "#slidercat1nodesweight" , TW.categories[1], "size");
EdgeWeightFilter("#slidercat1edgesweight", typesKey, "weight");
}
// docs
if(typesKey=="1|0") {
$(".for-nodecategory-0").show()
$(".for-nodecategory-1").hide();
NodeWeightFilter( "#slidercat0nodesweight" , TW.categories[0], "size");
EdgeWeightFilter("#slidercat0edgesweight", typesKey, "weight");
}
// terms and docs
if(typesKey=="1|1") {
$(".for-nodecategory-0").show()
......@@ -163,14 +162,13 @@ function cancelSelection (fromTagCloud, settings) {
// this area is quite underspecified so we assume here
// - that all typenames have a mapping to cat[0] (terms) or cat[1] (contexts)
// - that currentState.activetypes is an array of 2 bools for the currently displayed cat(s)
function getActivetypes() {
function getActivetypesNames() {
let currentTypes = []
let currentTypeIdx
let lastState = TW.states.slice(-1)[0]
for (var possType in TW.catDict) {
currentTypeIdx = TW.catDict[possType]
if (lastState.activetypes[currentTypeIdx]) {
if (TW.SystemState().activetypes[currentTypeIdx]) {
currentTypes.push(possType)
}
}
......@@ -195,12 +193,7 @@ function getActivetypesKey() {
// - 1st change: types described as type 0 and type 1 and possible default type
// - 2nd change default type of monopartite case changed from document to semantic
function swActual(aNodetype) {
if (TW.categories.length == 1) {
return 'semantic'
}
else if (TW.categories.length == 2) {
return (aNodetype == TW.categories[0]) ? 'social' : 'semantic'
}
return (aNodetype == TW.categories[0]) ? 'semantic' : 'social'
}
......@@ -329,7 +322,7 @@ function htmlfied_nodesatts(elems){
var id=elems[i]
var node = TW.Nodes[id]
if(node.type==TW.conf.catSoc){
if(swActual(node.type) == 'social'){
information += '<li><b>' + node.label + '</b></li>';
if(node.htmlCont==""){
if (!isUndef(node.level)) {
......@@ -341,7 +334,7 @@ function htmlfied_nodesatts(elems){
socnodes.push(information)
}
if(node.type==TW.conf.catSem){
if(swActual(node.type) == 'semantic'){
information += '<li><b>' + node.label + '</b></li>';
let google='<a href=http://www.google.com/#hl=en&source=hp&q=%20'+node.label.replace(" ","+")+'%20><img src="'+'img/google.png"></img></a>';
let wiki = '<a href=http://en.wikipedia.org/wiki/'+node.label.replace(" ","_")+'><img src="'+'img/wikipedia.png"></img></a>';
......@@ -452,7 +445,7 @@ function updateRelatedNodesPanel( sels , same, oppos ) {
$("#tips").html("");
if(TW.categories.length==1) getTopPapers("semantic");
else getTopPapers(swActual(getActivetypes()[0]));
else getTopPapers(swActual(getActivetypesNames()[0]));
}
// just css
......
......@@ -218,12 +218,11 @@ function sortNodeTypes(observedTypesDict) {
var nTypes = observedTypes.length
if(nTypes==0) {
observedTypes[0]="Document";
catDict["Document"] = 0;
observedTypes[0]="Terms";
catDict["Terms"] = 0;
}
if(nTypes==1) {
// if we have only one category, it gets the same code 0 as Document
// but in practice it's more often terms. anyways doesn't affect much
// if we have only one category, it gets code 0 as Terms
catDict[observedTypes[0]] = 0;
if (TW.conf.debug.logParsers)
......@@ -232,16 +231,17 @@ function sortNodeTypes(observedTypesDict) {
if(nTypes>1) {
var newcats = []
// POSSible: allow more than 2 cats
// NB: only 2 cat labels are allowed by this
for(var i in observedTypes) {
let c = observedTypes[i]
if(c == TW.conf.catSoc || (c != TW.conf.catSem && c.indexOf("term")==-1)) {// NOT a term-category
newcats[0] = c;
catDict[c] = 0;
if(c == TW.conf.catSoc) {// conf says that it's not a term-category
newcats[1] = c;
catDict[c] = 1;
}
// else: term-category is the new default
else {
newcats[1] = c; // IS a term-category
catDict[c] = 1;
newcats[0] = c;
catDict[c] = 0;
}
}
observedTypes = newcats;
......
......@@ -9,8 +9,10 @@ var SigmaUtils = function () {
console.log("FillGraph catDict",catDict)
// console.log("FillGraph nodes",nodes)
// console.log("FillGraph edges",edges)
for(var i in nodes) {
var n = nodes[i];
let i = 0
for(var nid in nodes) {
var n = nodes[nid];
// console.debug('tr >>> fgr node', n)
if(initialActivetypes[catDict[n.type]] || TW.conf.debug.initialShowAll) {
......@@ -36,6 +38,8 @@ var SigmaUtils = function () {
// fill the "labels" global variable
updateSearchLabels( n.id , n.label , n.type);
i++
}
}
......@@ -43,11 +47,10 @@ var SigmaUtils = function () {
// the typestring of the activetypes is the key to stored Relations (<=> edges)
var activetypesKey = initialActivetypes.map(Number).join("|")
for(var i in TW.Relations[activetypesKey]) {
let s = i;
for(var j in TW.Relations[activetypesKey][i]) {
let t = TW.Relations[activetypesKey][i][j]
let e = TW.Edges[s+";"+t]
for(let srcnid in TW.Relations[activetypesKey]) {
for(var j in TW.Relations[activetypesKey][srcnid]) {
let tgtnid = TW.Relations[activetypesKey][srcnid][j]
let e = TW.Edges[srcnid+";"+tgtnid]
if(e) {
if(e.source != e.target) {
graph.edges.push( e);
......@@ -280,7 +283,7 @@ var SigmaUtils = function () {
// NB cost of this condition seems small:
// - without: [11 - 30] ms for 23 nodes
// - with : [11 - 33] ms for 23 nodes
var catSemFlag = (TW.categories.length > 1 && node.type == TW.categories[0])
var catSocFlag = (node.type != TW.categories[0])
// mode variants 1: if a coloringFunction is active
......@@ -332,7 +335,7 @@ var SigmaUtils = function () {
context.fillStyle = borderColor
context.beginPath();
if (catSemFlag) {
if (catSocFlag) {
// (Square shape)
// thinner borderSize for squares looks better
// otherwise hb = (nodeSize + borderSize) / 2
......@@ -361,7 +364,7 @@ var SigmaUtils = function () {
context.beginPath();
if (catSemFlag) {
if (catSocFlag) {
// (Square shape)
let hn = nodeSize / 2
context.moveTo(X + hn, Y + hn);
......@@ -777,7 +780,7 @@ function repaintEdges() {
function heatmapColoring(daclass) {
var binColors
var doModifyLabel = false
var actypes = getActivetypes()
var actypes = getActivetypesNames()
// default value
let nColors = TW.conf.legendsBins || 5
......
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