Commit e9f27795 authored by Romain Loth's avatar Romain Loth

politoscope data and fix gexf cats parsing

various experiments around gexf parsing: take into account declared atts, trace comments for parseCustom, declarable @cluster_index equivalent, and separate function in sigma_tools for using stock gexf parser (unconnected now)
parent a0aa844c
<?php
# £TODO WTF ??? => move params to settings_explorerjs ???
$gexf_db = array();
# $gexf_db["data/terrorism/terrorism_bi.gexf"] = "data/terrorism/data.db";
......@@ -11,6 +13,10 @@ $gexf_db["data/AXA/RiskV2PageRank1000.gexf"] = "data/AXA/data.db";
$gexf_db["data/AXA/RiskV2PageRank2500.gexf"] = "data/AXA/data.db";
$gexf_db["data/AXA/RiskV2PageRank5000.gexf"] = "data/AXA/data.db";
// TESTS
$gexf_db["data/ProgrammeDesCandidats.gexf"] = "foobar";
$gexf= str_replace('"','',$_GET["gexf"]);
$mainpath=dirname(getcwd())."/";
......
{
"data/politoscope": {
"dbname":null,
"title":"Politoscope",
"date":"2017",
"abstract":"hello woerld",
"first" : "ProgrammeDesCandidats.gexf",
"gexfs": {
"ProgrammeDesCandidats.gexf": {
"social": {},
"semantic": {}
}
}
},
"data/AXA": {
"dbname":"data.db",
"title":"ISITITLE",
"date":"ISIpubdate",
"abstract":"ISIABSTRACT",
"first" : "RiskV2PageRank1000.gexf",
"first" : "RiskV2PageRank1000.gexf",
"gexfs": {
"RiskV2PageRank1000.gexf": {
"social": { "table":"ISIAUTHOR" , "textCol":"data","forkeyCol":"id"},
......
......@@ -587,10 +587,15 @@
<!-- new sigma 1.2 imports -->
<script src="tinawebJS/sigma_v1.2/sigma.min.js" type="text/javascript" language="javascript"></script>
<!-- <script src="tinawebJS/sigma_v1.2/sigma.js" type="text/javascript" language="javascript"></script> -->
<script src="tinawebJS/sigma_v1.2/plugins/sigma.layout.forceAtlas2/supervisor.js"></script>
<script src="tinawebJS/sigma_v1.2/plugins/sigma.layout.forceAtlas2/worker.js"></script>
<script src="tinawebJS/sigma_v1.2/plugins/sigma.renderers.snapshot/sigma.renderers.snapshot.js"></script>
<!-- Tested as replacement for parseCustom -->
<!-- <script src="tinawebJS/sigma_v1.2/plugins/sigma.parsers.gexf/gexf-parser.js"></script> -->
<!-- <script src="tinawebJS/sigma_v1.2/plugins/sigma.parsers.gexf/sigma.parsers.gexf.js"></script> -->
<!-- testing sigma 1.5 imports from linkurious src -->
<!-- <script src="tinawebJS/sigma_v1.5/sigma.js" type="text/javascript" language="javascript"></script>
<script src="tinawebJS/sigma_v1.5/plugins.js" type="text/javascript" language="javascript"></script> -->
......
......@@ -21,14 +21,12 @@ function ChangeGraphAppearanceByAtt( manualflag ) {
// Seeing all the possible attributes!
var AttsDict = {}
var Atts_2_Exclude = {}
var v_nodes = getVisibleNodes();
for (var i in v_nodes) {
if(!v_nodes[i].hidden) {
var id = v_nodes[i].id;
for(var a in TW.Nodes[id].attributes) {
var someatt = TW.Nodes[id].attributes[a]
for (var j in TW.nodeIds) {
let nid = TW.nodeIds[j]
let n = TW.partialGraph.graph.nodes(nid)
if(!n.hidden) {
for(var a in TW.Nodes[nid].attributes) {
var someatt = TW.Nodes[nid].attributes[a]
// Identifying the attribute datatype: exclude strings and objects
if ( ( typeof(someatt)=="string" && isNaN(Number(someatt)) ) || typeof(someatt)=="object" ) {
......@@ -38,10 +36,10 @@ function ChangeGraphAppearanceByAtt( manualflag ) {
}
var possible_atts = [];
if (!isUndef(TW.Nodes[id].attributes))
possible_atts = Object.keys(TW.Nodes[id].attributes)
if (!isUndef(TW.Nodes[nid].attributes))
possible_atts = Object.keys(TW.Nodes[nid].attributes)
if(!isUndef(v_nodes[i].degree))
if(!isUndef(n.degree))
possible_atts.push("degree")
possible_atts.push("clust_louvain")
......@@ -240,10 +238,15 @@ function set_ClustersLegend ( daclass ) {
var Type = raw[0]
var ClustType = raw[1]
var ClustID = raw[2]
var legTxt = "N/A"
if (TW.Clusters && TW.Clusters[Type] && TW.Clusters[Type][ClustType] && TW.Clusters[Type][ClustType][ClustID]) {
legTxt = TW.Clusters[Type][ClustType][ClustID]
}
var Color = ClustNB_CurrentColor[IDx]
pr ( Color+" : "+ TW.Clusters[Type][ClustType][ClustID] )
// console.log ( Color+" : ", Type, ClustType, ClustID )
pr ( Color+" : "+ legTxt )
var ColorDiv = '<span style="background:'+Color+';"></span>'
LegendDiv += '<li onclick=\'SomeEffect("'+IDx+'")\'>'+ColorDiv+ TW.Clusters[Type][ClustType][ClustID]+"</li>"+"\n"
LegendDiv += '<li onclick=\'SomeEffect("'+IDx+'")\'>'+ColorDiv+ legTxt+"</li>"+"\n"
}
} else {
for(var i in OrderedClustDicts) {
......
......@@ -101,7 +101,8 @@ var semanticConverged=false;
// ============ < / DEVELOPER OPTIONS > ============
var showLabelsIfZoom=1.0;
TW.nodeClusAtt = "modularity_class"
TW.edgeDefaultOpacity = 0.5 // opacity when true_color
TW.edgeGreyColor = "rgba(150, 150, 150, 0.2)";
TW.nodesGreyBorderColor = "rgba(100, 100, 100, 0.5)";
......@@ -111,6 +112,7 @@ TW.selectedColor = "node" // "node" for a background like the node's color,
TW.overSampling = true // costly hi-def rendering (true => pixelRatio x 2)
TW.deselectOnclickStage = false // will a click on the background remove selection ? (except when dragging)
var showLabelsIfZoom=1.0;
// ============ < / DEVELOPER OPTIONS > ============
......@@ -164,7 +166,7 @@ var twjs="tinawebJS/";
TW.categories = {};
TW.categoriesIndex = [];
var gexf;
var gexfFile;
//var zoom=0;
var checkBox=false;
......
......@@ -3,6 +3,18 @@
// always useful
var theHtml = document.getElementsByTagName('html')[0]
// overriding pixelRatio is possible if we need very high definition
// var realRatio = sigma.utils.getPixelRatio
// if (TW.overSampling) {
// sigma.utils.getPixelRatio = function() {
// return 2 * realRatio()
// }
// }
TW.anynodegoes = true
// TW.anynodegoes = true
//============================ < NEW BUTTONS > =============================//
......@@ -449,6 +461,11 @@ function changeLevel() {
// NB new sigma js: dropEdge is quite slow so we add a waiting cursor
function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
console.log("EdgeWeightFilter")
console.log("sliderDivID", sliderDivID)
console.log("type_attrb", type_attrb)
console.log("type", type)
console.log("criteria", criteria)
// if ($(sliderDivID).html()!="") {
// console.log("\t\t\t\t\t\t[[ algorithm not applied "+sliderDivID+" ]]")
// return;
......@@ -480,10 +497,16 @@ function EdgeWeightFilter(sliderDivID , type_attrb , type , criteria) {
var filterparams = AlgorithmForSliders ( TW.Edges , type_attrb , type , criteria) //OK
// TODO make an index
// console.log("EdgeWeightFilter: "+type)
// console.log(filterparams)
console.log("EdgeWeightFilter: "+type)
console.log(filterparams)
var steps = filterparams["steps"]
// TODO polito filterparams comes back like this {steps:0, finalarray:[]}
console.warn("overriding steps")
steps = 2
var finalarray = filterparams["finalarray"]
// if(steps<3) {
// $(sliderDivID).freshslider({
......
......@@ -34,7 +34,7 @@ var AjaxSync = (function(TYPE, URL, DATA, CT , DT) {
var Result = []
TYPE = (!TYPE)?"GET":"POST"
if(DT && (DT=="jsonp" || DT=="json")) CT="application/json";
// console.log(TYPE, URL, DATA, CT , DT)
console.log("---AjaxSync---\n", TYPE, URL, DATA, CT , DT, "\n--------------")
$.ajax({
type: TYPE,
url: URL,
......@@ -56,6 +56,7 @@ var AjaxSync = (function(TYPE, URL, DATA, CT , DT) {
Result = { "OK":true , "format":format , "data":data };
},
error: function(exception) {
console.log('now error')
Result = { "OK":false , "format":false , "data":exception.status };
}
});
......@@ -93,20 +94,27 @@ if(!isUndef(getUrlParam.mode)) { // if {db|api}.json
// RES == { OK: true, format: "json", data: Object }
var RES = AjaxSync({ URL: file });
console.log('RES', RES)
if(RES["OK"]) {
var fileparam;// = { db|api.json , somefile.json|gexf }
var the_data = RES["data"];
// console.log('initial AjaxSync result RES', RES)
console.log('initial AjaxSync result RES', RES)
// ===================
var the_file = "";
// ===================
if ( !isUndef(getUrlParam.mode) && getUrlParam.mode=="db.json") {
var first_file = "" , first_path = ""
for( var path in the_data ) {
console.log("db.json path", path)
first_file = the_data[path]["first"]
first_path = path
console.log("db.json first_file", first_path, first_file)
break;
}
......@@ -116,24 +124,23 @@ if(RES["OK"]) {
the_file = first_path+"/"+getUrlParam.file
}
fileparam = the_file;
var files_selector = '<select onchange="jsActionOnGexfSelector(this.value , true);">'
for( var path in the_data ) {
var the_gexfs = the_data[path]["gexfs"]
console.log("\t\tThese are the available Gexfs:")
for(var gexf in the_gexfs) {
var gexfBasename = gexf.replace(/\.gexf$/, "") // more human-readable in the menu
console.log("\t\t\t"+gexf+ " -> table:" +the_gexfs[gexf]["semantic"]["table"] )
console.log(the_gexfs)
for(var aGexf in the_gexfs) {
var gexfBasename = aGexf.replace(/\.gexf$/, "") // more human-readable in the menu
console.log("\t\t\t"+gexfBasename+ " -> table:" +the_gexfs[aGexf]["semantic"]["table"] )
TW.field[path+"/"+gexf] = the_gexfs[gexf]["semantic"]["table"]
TW.field[path+"/"+aGexf] = the_gexfs[aGexf]["semantic"]["table"]
// ex : data/AXA/RiskV2PageRank5000.gexf:"ISItermsAxa_2015"
TW.gexfDict[path+"/"+gexf] = gexf
TW.gexfDict[path+"/"+aGexf] = aGexf
// ex : data/AXA/RiskV2PageRank1000.gexf:"RiskV2PageRank1000.gexf"
var selected = (the_file==(path+"/"+gexf))?"selected":""
var selected = (the_file==(path+"/"+aGexf))?"selected":""
files_selector += '<option '+selected+'>'+gexfBasename+'</option>'
}
// console.log( files_selector )
......@@ -147,12 +154,15 @@ if(RES["OK"]) {
// console.log("\n============================\n")
// console.log(TW.field)
// console.log(TW.gexfDict)
var sub_RES = AjaxSync({ URL: fileparam });
var sub_RES = AjaxSync({ URL: the_file });
the_data = sub_RES["data"]
fileparam = sub_RES["format"]
// console.log(the_data.length)
// console.log(fileparam)
console.warn('@the_file', sub_RES["OK"], the_file)
// why now ???
getUrlParam.file=the_file;
console.log(" . .. . -. - .- . - -.")
console.log(getUrlParam.file)
......@@ -171,8 +181,8 @@ if(RES["OK"]) {
console.log("parsing the data")
var start = new ParseCustom( fileparam , the_data );
var categories = start.scanFile(); //user should choose the order of categories
// console.log("Categories: ")
// console.log(categories)
console.error("Categories: ")
console.log(categories)
if (! categories) {
console.warn ('ParseCustom scanFile found no categories!!')
......@@ -181,7 +191,11 @@ if(RES["OK"]) {
var possibleStates = makeSystemStates( categories )
var initialState = buildInitialState( categories ) //[true,false]//
var dicts = start.makeDicts(categories);
// XML parsing from ParseCustom
var dicts = start.makeDicts(categories); // > parseGexf, dictfyGexf
console.warn("parsing result:", dicts)
TW.Nodes = dicts.nodes;
TW.Edges = dicts.edges;
TW.nodeIds = Object.keys(dicts.nodes) // useful for loops
......@@ -195,10 +209,12 @@ if(RES["OK"]) {
if (the_data.clusters) TW.Clusters = the_data.clusters
// relations already copied in TW.Relations at this point
// TW.nodes1 = dicts.n1;//not used
var catDict = dicts.catDict
// console.log("CategoriesDict: ")
// console.log(catDict)
console.log("CategoriesDict: ")
console.log(catDict)
TW.categoriesIndex = categories;//to_remove
TW.catSoc = categories[0];//to_remove
......@@ -231,7 +247,40 @@ if(RES["OK"]) {
// preparing the data and settings
TW.graphData = {nodes: [], edges: []}
TW.graphData = sigma_utils.FillGraph( initialState , catDict , dicts.nodes , dicts.edges , TW.graphData );
TW.graphData = sigma_utils.FillGraph( initialState , catDict , TW.Nodes , TW.Edges , TW.graphData );
// // ----------- TEST stock parse gexf and use nodes to replace TW's ---------
// var gexfData = gexf.fetch('data/politoscope/ProgrammeDesCandidats.gexf')
//
// TW.graphData = sigmaTools.myGexfParserReplacement(
// gexfData.nodes,
// gexfData.edges
// )
// console.log ('ex in TW.graphData.nodes[0]', TW.graphData.nodes[0])
//
// // our holey id-indexed arrays
// TW.Nodes = {}
// TW.Edges = {}
// TW.nodeIds = []
// TW.edgeIds = []
// for (var j in TW.graphData.nodes) {
// var nid = TW.graphData.nodes[j].id
// TW.Nodes[nid] = TW.graphData.nodes[j]
// TW.nodeIds.push(nid)
// }
// for (var i in TW.graphData.edges) {
// var eid = TW.graphData.edges[i].id
// TW.Edges[eid] = TW.graphData.edges[i]
// TW.edgeIds.push(eid)
// }
//
//
// // -------------------------------------------------------------------------
if (TW.graphData.nodes.length == 0) console.error("empty graph")
if (TW.graphData.edges.length == 0) console.error("no edges in graph")
// cf github.com/jacomyal/sigma.js/wiki/Settings
var customSettings = Object.assign(
......@@ -324,10 +373,17 @@ if(RES["OK"]) {
TW.partialGraph.states[1] = TW.SystemStates;
TW.partialGraph.states[1].categories = categories
TW.partialGraph.states[1].categoriesDict = catDict;
console.log("!? initialState => states[1].type")
TW.partialGraph.states[1].type = initialState;
TW.partialGraph.states[1].LouvainFait = false;
// [ / Poblating the Sigma-Graph ]
// ex called for new selections with args like:
// (undefined, undefined, [268], undefined)
// ^^^^
// why type not used (monopart? deprecated?)
TW.partialGraph.states[1].setState = (function( type , level , sels , oppos ) {
var bistate=false, typestring=false;
console.log("IN THE SET STATE METHOD:")
......@@ -342,7 +398,7 @@ if(RES["OK"]) {
this.LouvainFait = false;
console.log("")
console.log(" % % % % % % % % % % ")
// console.log("type: "+thetype.map(Number));
console.log("setState type: ", type);
console.log("bistate: "+bistate)
console.log("level: "+level);
console.log("selections: ");
......@@ -476,7 +532,12 @@ if(RES["OK"]) {
// }
}
ChangeGraphAppearanceByAtt(true)
try {
ChangeGraphAppearanceByAtt(true)
}
catch (e) {
console.error(e)
}
set_ClustersLegend ( "clust_default" )
......
......@@ -9,8 +9,8 @@ ParseCustom = function ( format , data ) {
this.nbCats = 0;
// input = GEXFstring
this.getGEXFCategories = function(gexf) {
this.data = $.parseXML(gexf)
this.getGEXFCategories = function(aGexfFile) {
this.data = $.parseXML(aGexfFile) // <===================== (XML parse)
return scanGexf( this.data );
}// output = [ "cat1" , "cat2" , ...]
......@@ -86,26 +86,125 @@ ParseCustom.prototype.makeDicts = function(categories) {
};
function gexfCheckAttributesMap (someXMLContent) {
// excerpt from targeted XML:
// <graph defaultedgetype="undirected" mode="static">
// | <attributes class="node" mode="static">
// | <attribute id="0" title="category" type="string"></attribute>
// | <attribute id="1" title="country" type="float"></attribute>
// | </attributes>
// (...)
// THIS SEGMENT USED TO BE IN dictifyGexf
// Census of the conversions between attr and some attr name
var i, j, k;
var nodesAttributes = []; // The list of attributes of the nodes of the graph that we build in json
var edgesAttributes = []; // The list of attributes of the edges of the graph that we build in json
// In the gexf (that is an xml), the list of xml nodes 'attributes' (note the plural 's')
var attributesNodes = someXMLContent.getElementsByTagName('attributes');
for(i = 0; i<attributesNodes.length; i++){
var attributesNode = attributesNodes[i]; // attributesNode is each xml node 'attributes' (plural)
if(attributesNode.getAttribute('class') == 'node'){
var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's')
for(j = 0; j<attributeNodes.length; j++){
var attributeNode = attributeNodes[j]; // Each xml node 'attribute'
var id = attributeNode.getAttribute('id'),
title = attributeNode.getAttribute('title'),
type = attributeNode.getAttribute('type');
// ex: id = "in-degree" or "3" <= can be an int to be resolved into the title
// ex: title = "in-degree"
// ex: type = "string"
var attribute = {
id:id,
title:title,
type:type
};
nodesAttributes.push(attribute);
}
} else if(attributesNode.getAttribute('class') == 'edge'){
var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's')
for(j = 0; j<attributeNodes.length; j++){
var attributeNode = attributeNodes[j]; // Each xml node 'attribute'
var id = attributeNode.getAttribute('id'),
title = attributeNode.getAttribute('title'),
type = attributeNode.getAttribute('type');
var attribute = {
id:id,
title:title,
type:type
};
edgesAttributes.push(attribute);
}
}
} //out: nodesAttributes Array
console.debug('>>> tr: nodesAttributes', nodesAttributes)
console.debug('>>> tr: edgesAttributes', edgesAttributes)
return {nAttrs: nodesAttributes, eAttrs: edgesAttributes}
}
// Level-00
function scanGexf(gexf) {
console.log("ParseCustom : scanGexf")
function scanGexf(gexfContent) {
console.log("ParseCustom : scanGexf ======= ")
var categoriesDict={}, categories=[];
nodesNodes = gexf.getElementsByTagName('nodes');
for(i=0; i<nodesNodes.length; i++){
var nodesNode = nodesNodes[i]; // Each xml node 'nodes' (plural)
node = nodesNode.getElementsByTagName('node');
// adding gexfCheckAttributesMap call
// to create a map from nodes/node/@for values to declared attribute name (title)
var declaredAttrs = gexfCheckAttributesMap(gexfContent)
elsNodes = gexfContent.getElementsByTagName('nodes');
// console.debug('>>> tr: elsNodes', elsNodes) // <<<
for(i=0; i<elsNodes.length; i++){
var elNodes = elsNodes[i]; // Each xml node 'nodes' (plural)
node = elNodes.getElementsByTagName('node');
for(j=0; j<node.length; j++){
attvalueNodes = node[j].getElementsByTagName('attvalue');
for(k=0; k<attvalueNodes.length; k++){
attvalueNode = attvalueNodes[k];
attr = attvalueNode.getAttribute('for');
val = attvalueNode.getAttribute('value');
// some attrs are gexf-local indices refering to an <attributes> declaration
// so if it matches declared we translate their integer in title
// FIXME use a dict by id in gexfCheckAttributesMap for loop rm
if(Number.isInteger(Number(attr))) {
// mini loop inside declared node attrs (eg substitute 0 for 'centrality')
for (var l=0;l<declaredAttrs.nAttrs.length;l++) {
let declared = declaredAttrs.nAttrs[l]
if (declared.id == attr) {
attr = declared.title
}
}
}
// console.log('attr', attr)
// THIS WILL BECOME catDict (if ncats == 1 => monopart)
if (attr=="category") categoriesDict[val]=val;
}
}
}
for(var cat in categoriesDict)
// usually a just a few cats over entire node set
// ex: terms
// ex: ISItermsriskV2_140 & ISItermsriskV2_140
console.debug('>>> tr: cat', cat)
categories.push(cat);
var catDict = {}
......@@ -138,9 +237,11 @@ function scanGexf(gexf) {
// for {1,2}partite graphs
function dictfyGexf( gexf , categories ){
console.log("ParseCustom gexf 2nd loop, main data extraction")
console.log("ParseCustom gexf 2nd loop, main data extraction, with categories", categories)
// var catDict = {'terms':"0"}
var catDict = {}
var catCount = {}
for(var i in categories) catDict[categories[i]] = i;
......@@ -150,51 +251,17 @@ function dictfyGexf( gexf , categories ){
nodes2={}, bipartiteD2N={}, bipartiteN2D={}
}
var i, j, k;
var nodesAttributes = []; // The list of attributes of the nodes of the graph that we build in json
var edgesAttributes = []; // The list of attributes of the edges of the graph that we build in json
var attributesNodes = gexf.getElementsByTagName('attributes'); // In the gexf (that is an xml), the list of xml nodes 'attributes' (note the plural 's')
for(i = 0; i<attributesNodes.length; i++){
var attributesNode = attributesNodes[i]; // attributesNode is each xml node 'attributes' (plural)
if(attributesNode.getAttribute('class') == 'node'){
var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's')
for(j = 0; j<attributeNodes.length; j++){
var attributeNode = attributeNodes[j]; // Each xml node 'attribute'
var id = attributeNode.getAttribute('id'),
title = attributeNode.getAttribute('title'),
type = attributeNode.getAttribute('type');
var attribute = {
id:id,
title:title,
type:type
};
nodesAttributes.push(attribute);
}
} else if(attributesNode.getAttribute('class') == 'edge'){
var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's')
for(j = 0; j<attributeNodes.length; j++){
var attributeNode = attributeNodes[j]; // Each xml node 'attribute'
var id = attributeNode.getAttribute('id'),
title = attributeNode.getAttribute('title'),
type = attributeNode.getAttribute('type');
var attribute = {
id:id,
title:title,
type:type
};
edgesAttributes.push(attribute);
}
}
} //out: nodesAttributes Array
// --------------------8<-----------------------
// HERE REMOVED XML <attributes> parsing
// b/c a priori useless at this point ?
// (moved earlier to scanGexf)
//
// var atts = gexfCheckAttributesMap(gexf)
// var nodesAttributes = atts.nAttrs
// var edgesAttributes = atts.eAttrs
// --------------------8<-----------------------
var nodesNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural)
var elsNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural)
labels = [];
minNodeSize=999.00;
maxNodeSize=0.001;
......@@ -206,25 +273,30 @@ function dictfyGexf( gexf , categories ){
// let sumSizes = 0
// let sizeStats = {'mean':null, 'median':null, 'max':0, 'min':1000000000}
for(i=0; i<nodesNodes.length; i++) {
var nodesNode = nodesNodes[i]; // Each xml node 'nodes' (plural)
var nodeNodes = nodesNode.getElementsByTagName('node'); // The list of xml nodes 'node' (no 's')
// usually there is only 1 <nodes> element...
for(i=0; i<elsNodes.length; i++) {
var elNodes = elsNodes[i]; // Each xml element 'nodes' (plural)
var elsNode = elNodes.getElementsByTagName('node'); // The list of xml nodes 'node' (no 's')
for(j=0; j<elsNode.length; j++) {
for(j=0; j<nodeNodes.length; j++) {
var elNode = elsNode[j]; // Each xml node 'node' (no 's')
var nodeNode = nodeNodes[j]; // Each xml node 'node' (no 's')
// window.NODE = elNode;
window.NODE = nodeNode;
if (j == 0) {
console.debug('>>> tr: XML nodes/node (1 of'+elsNode.length+')', elNodes)
}
// [ get ID ]
var id = nodeNode.getAttribute('id');
var id = elNode.getAttribute('id');
// [ get Label ]
var label = nodeNode.getAttribute('label') || id;
var label = elNode.getAttribute('label') || id;
// [ get Size ]
var size=false;
sizeNodes = nodeNode.getElementsByTagName('size');
sizeNodes = sizeNodes.length ? sizeNodes : nodeNode.getElementsByTagName('viz:size');
sizeNodes = elNode.getElementsByTagName('size');
sizeNodes = sizeNodes.length ? sizeNodes : elNode.getElementsByTagName('viz:size');
if(sizeNodes.length>0){
sizeNode = sizeNodes[0];
size = parseFloat(sizeNode.getAttribute('value'));
......@@ -237,12 +309,13 @@ function dictfyGexf( gexf , categories ){
// --------------------------------------------
}// [ / get Size ]
// console.debug('>>> tr: node size', size)
// [ get Coordinates ]
var x = 100 - 200*Math.random();
var y = 100 - 200*Math.random();
var positionNodes = nodeNode.getElementsByTagName('position');
positionNodes = positionNodes.length ? positionNodes : nodeNode.getElementsByTagNameNS('*','position');
var positionNodes = elNode.getElementsByTagName('position');
positionNodes = positionNodes.length ? positionNodes : elNode.getElementsByTagNameNS('*','position');
if(positionNodes.length>0){
var positionNode = positionNodes[0];
x = parseFloat(positionNode.getAttribute('x'));
......@@ -252,8 +325,8 @@ function dictfyGexf( gexf , categories ){
y = y*-1 // aka -y
// [ get Colour ]
var colorNodes = nodeNode.getElementsByTagName('color');
colorNodes = colorNodes.length ? colorNodes : nodeNode.getElementsByTagNameNS('*','color');
var colorNodes = elNode.getElementsByTagName('color');
colorNodes = colorNodes.length ? colorNodes : elNode.getElementsByTagNameNS('*','color');
var color;
if(colorNodes.length>0){
colorNode = colorNodes[0];
......@@ -271,35 +344,61 @@ function dictfyGexf( gexf , categories ){
color:color
});
// console.debug('>>> tr: read node', node)
// Attribute values
var attributes = []
var attvalueNodes = nodeNode.getElementsByTagName('attvalue');
var attvalueNodes = elNode.getElementsByTagName('attvalue');
var atts={};
for(k=0; k<attvalueNodes.length; k++){
var attvalueNode = attvalueNodes[k];
var attr = attvalueNode.getAttribute('for');
var val = attvalueNode.getAttribute('value');
// TODO use here nodesAttributes
if(catDict[val]) atts["category"] = val;
else atts[attr]=val;
attributes = atts;
}
// nodew=parseInt(attributes["weight"]);
if ( attributes["category"] ) {
node_cat = attributes["category"];
node.type = node_cat;
if (!catCount[node_cat]) catCount[node_cat] = 0
catCount[node_cat]++;
node_cat = attributes["category"];
}
else {
node_cat = 0 // basic TW node type is 0 (~ terms)
}
// node.id = (node_cat==categories[0])? ("D:"+node.id) : ("N:"+node.id);
if(!node.size) console.log("node without size: "+node.id+" : "+node.label);
node.type = node_cat;
if (!catCount[node_cat]) catCount[node_cat] = 0
catCount[node_cat]++;
node.attributes = attributes;
nodes[node.id] = node
// node.id = (node_cat==categories[0])? ("D:"+node.id) : ("N:"+node.id);
if(!node.size) console.log("node without size: "+node.id+" : "+node.label);
node.attributes = attributes;
// console.log(node)
}
// save record
nodes[node.id] = node
if(parseInt(node.size) < parseInt(minNodeSize))
minNodeSize= node.size;
......@@ -310,6 +409,8 @@ function dictfyGexf( gexf , categories ){
}
}
console.warn ('parseCustom output nodes', nodes)
// -------------- debug: for local stats ----------------
// allSizes.sort();
// let N = allSizes.length
......@@ -336,6 +437,9 @@ function dictfyGexf( gexf , categories ){
if(attention) {
var t_type = nodes[it].type
var t_cnumber = nodes[it].attributes["cluster_index"]
if (!t_cnumber) {
t_cnumber = nodes[it].attributes[TW.nodeClusAtt]
}
nodes[it].attributes["clust_default"] = t_cnumber;
var t_label = (nodes[it].attributes["cluster_label"])?nodes[it].attributes["cluster_label"]:"cluster_"+nodes[it].attributes["cluster_index"]
if(!TW.Clusters[t_type]) {
......@@ -385,7 +489,10 @@ function dictfyGexf( gexf , categories ){
});
}
// console.debug('>>> tr: read edge', edge)
if ( nodes[source] && nodes[target] ) {
console.debug('>>> tr: new edge has matching source and target nodes')
idS=nodes[source].type;
idT=nodes[target].type;
......@@ -518,12 +625,15 @@ function dictfyGexf( gexf , categories ){
}
}
// ------------------------------- resDict <<<
resDict = {}
resDict.catDict = catDict;
resDict.catCount = catCount;
resDict.nodes = nodes;
// TODO unify catDict and catCount (dict is count.keys())
resDict.catDict = catDict; // ex : {'ISIterms':0}
resDict.catCount = catCount; // ex: {'ISIterms':1877} ie #nodes
resDict.nodes = nodes; // { nid1: {label:"...", size:"11.1", attributes:"...", color:"#aaa", etc}, nid2: ...}
resDict.edges = edges;
resDict.n1 = nodes1;
resDict.n1 = nodes1; // relations
if(nodes2) resDict.n2 = nodes2;
if(bipartiteD2N) resDict.D2N = bipartiteD2N;
if(bipartiteN2D) resDict.N2D = bipartiteN2D;
......
......@@ -7,11 +7,14 @@ SigmaUtils = function () {
this.FillGraph = function( initialState , catDict , nodes, edges , graph ) {
console.log("Filling the graaaaph:")
// console.log(catDict)
console.log("FillGraph catDict",catDict)
console.log("FillGraph nodes",nodes)
console.log("FillGraph edges",edges)
for(var i in nodes) {
var n = nodes[i];
// console.debug('tr >>> fgr node', n)
if(initialState[catDict[n.type]]) {
if(initialState[catDict[n.type]] || TW.anynodegoes) {
// var node = {
// id : n.id,
// label : n.label,
......@@ -30,7 +33,7 @@ SigmaUtils = function () {
// no attributes to remove: I use n directly
graph.nodes.push(n);
if(Number(n.id)==287) console.log("node 287:", n)
if(i==2) console.log("node 2 ("+n.id+")", n)
// fill the "labels" global variable
updateSearchLabels( n.id , n.label , n.type);
......
......@@ -5,6 +5,71 @@ var sigmaTools = {};
sigmaTools = (function(stools) {
// a simpler alternative to avoid parseCustom and prepareNodesRenderingProperties
// temporarily after using the new gexf stock parser
// (mostly to transform viz: attrs in real attrs)
stools.myGexfParserReplacement = function(rawGexfNodes, rawGexfEdges) {
// output, indexed by IDs
var newNodes = [],
newEdges = []
for (var j in rawGexfNodes) {
var rawNode = rawGexfNodes[j]
// pre-parse node rgb color
var rgbStr = rawNode.viz.color.match(/rgb\(([^\(]+)\)/)[1]
var newNode = {
id: rawNode.id,
label: rawNode.label,
x: rawNode.viz.position.x,
y: rawNode.viz.position.y,
color: rawNode.viz.color,
size: Math.round(rawNode.viz.size*1000)/1000,
active: false,
hidden: false,
customAttrs: {
grey: false,
highlight: false,
true_color: rawNode.viz.color,
defgrey_color : "rgba("+rgbStr+",.4)"
},
// for metrics like centrality
attributes: {
'clust_default': rawNode.attributes.modularity_class
}
}
newNodes[j] = newNode
}
for (var i in rawGexfEdges) {
var rawEdge = rawGexfEdges[i]
var rgbStr = sigmaTools.edgeRGB(rawEdge.source, rawEdge.target, newNodes)
var leColor = "rgba("+rgbStr+","+TW.edgeDefaultOpacity+")"
var newEid = rawEdge.source+";"+rawEdge.target;
var newEdge = {
id: newEid,
source: rawEdge.source,
target: rawEdge.target,
color: leColor,
weight: Math.round(rawEdge.weight*1000)/1000,
customAttrs: {
grey: false,
activeEdge: false,
true_color: leColor,
rgb: rgbStr
}
}
newEdges[i] = newEdge
}
return {nodes: newNodes, edges: newEdges}
};
stools.rgbToHex = function(R, G, B) {
return stools.toHex(R) + stools.toHex(G) + stools.toHex(B);
};
......@@ -21,26 +86,49 @@ sigmaTools = (function(stools) {
};
// TODO check duplicate functionalities with repaintEdges
stools.edgeRGB = function(src_id, tgt_id) {
//edge color will be the combination of the 2 node colors
var a = TW.Nodes[src_id]['color'];
var b = TW.Nodes[tgt_id]['color'];
stools.edgeRGB = function(src_id, tgt_id, nodeIndex) {
if (!nodeIndex) {
nodeIndex = TW.Nodes
}
if (!Object.keys(nodeIndex).length) {
console.warn('empty nodeIndex')
}
// console.log('edgeRGB, src_id', src_id)
// console.log('edgeRGB, tgt_id', tgt_id)
//
if (!nodeIndex[src_id] || !nodeIndex[tgt_id]) {
return '0,0,0'
}
//edge color will be the combination of the 2 node colors
var a = nodeIndex[src_id]['color'];
var b = nodeIndex[tgt_id]['color'];
var tmp
// console.log("color a", a)
// console.log("color b", b)
if(a.charAt(0)!="#") {
tmp = a.replace("rgba(","").replace(")","").split(",")
a = stools.rgbToHex( parseFloat( tmp[0] ) , parseFloat( tmp[1] ) , parseFloat( tmp[2] ) );
tmp = a.replace(/rgba?\(/,"").replace(")","").split(",")
// rgb array
a = [parseFloat( tmp[0] ) , parseFloat( tmp[1] ) , parseFloat( tmp[2] )];
}
else {
a = hex2rga(a);
}
if(b.charAt(0)!="#") {
tmp = b.replace("rgba(","").replace(")","").split(",")
b = stools.rgbToHex( parseFloat( tmp[0] ) , parseFloat( tmp[1] ) , parseFloat( tmp[2] ) );
tmp = b.replace(/rgba?\(/,"").replace(")","").split(",")
b = [parseFloat( tmp[0] ) , parseFloat( tmp[1] ) , parseFloat( tmp[2] )];
}
else {
b = hex2rga(b);
}
// console.log(source+" : "+a+"\t|\t"+target+" : "+b)
a = hex2rga(a);
b = hex2rga(b);
var r = (a[0] + b[0]) >> 1;
var g = (a[1] + b[1]) >> 1;
var b = (a[2] + b[2]) >> 1;
......
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