Commit 8593b1cb authored by Romain Loth's avatar Romain Loth

Merge branch 'new_db_json_specifies_type'

parents 231c96f6 54ed16c2
{ {
"data/gargistex": { "data/gargistex": {
"first" : "shale_and_ice.gexf", "first" : "shale_and_ice.gexf",
"gexfs": { "graphs":{
"shale_and_ice.gexf": { "shale_and_ice.gexf": {
"dbtype": "csv", "dbtype": "csv",
"semantic":["title","keywords","abstract"], "semantic":["title","keywords","abstract"],
"social":["authors"], "social":["authors"],
"dbfile": "shale_and_ice.csv" "dbfile": "shale_and_ice.csv",
"node0": { "name": "terms" }
},
"model_calibration.gexf": {
"dbtype": "csv",
"semantic":["title","keywords","abstract"],
"social":["authors"],
"dbfile": "model_calibration.csv",
"node0": { "name": "terms" }
} }
} }
}, },
"data/test": { "data/test": {
"first" : "mini_for_csv.gexf", "first" : "mini_for_csv.gexf",
"gexfs": { "graphs": {
"mini_for_csv.gexf": { "mini_for_csv.gexf": {
"_comment": "NB: underspecified for csv and for db.json !! so this is a prototype structure", "_comment": "NB: underspecified for csv and for db.json !! so this is a prototype structure",
"_comment": "POSS: weighted columns for matching importance", "_comment": "POSS: weighted columns for matching importance",
"dbtype": "csv", "dbtype": "csv",
"semantic":["title","keywords","text"], "semantic":["title","keywords","text"],
"social":["author"], "social":["author"],
"dbfile": "mini_for_csv.csv" "dbfile": "mini_for_csv.csv",
"node0": { "name": "term" },
"node1": { "name": "person" }
}, },
"test_with_various_atts.gexf": {} "test_with_various_atts.gexf": {}
} }
...@@ -30,12 +40,14 @@ ...@@ -30,12 +40,14 @@
"date":"2017", "date":"2017",
"abstract":"", "abstract":"",
"first" : "ProgrammeDesCandidats.enrichi.gexf", "first" : "ProgrammeDesCandidats.enrichi.gexf",
"gexfs": { "graphs": {
"ProgrammeDesCandidats.enrichi.gexf": { "ProgrammeDesCandidats.enrichi.gexf": {
"node0": { "name": "terms" },
"social": {}, "social": {},
"semantic": {} "semantic": {}
}, },
"ProgrammeDesCandidats.gexf": { "ProgrammeDesCandidats.gexf": {
"node0": { "name": "terms" },
"social": {}, "social": {},
"semantic": {} "semantic": {}
} }
...@@ -46,8 +58,9 @@ ...@@ -46,8 +58,9 @@
"title":"ISITITLE", "title":"ISITITLE",
"date":"ISIpubdate", "date":"ISIpubdate",
"abstract":"ISIABSTRACT", "abstract":"ISIABSTRACT",
"gexfs": { "graphs": {
"Maps_S_800.gexf": { "Maps_S_800.gexf": {
"node0": { "name": "ISItermsWhitelistV2Oct_5 & ISItermsWhitelistV2Oct_5" },
"social": { "table":"ISIAUTHOR" , "textCol":"data","forkeyCol":"id"}, "social": { "table":"ISIAUTHOR" , "textCol":"data","forkeyCol":"id"},
"semantic": { "table":"ISItermsWhitelistV2Oct_5" , "textCol":"data","forkeyCol":"id"} "semantic": { "table":"ISItermsWhitelistV2Oct_5" , "textCol":"data","forkeyCol":"id"}
} }
...@@ -55,8 +68,11 @@ ...@@ -55,8 +68,11 @@
}, },
"data/comexjsons": { "data/comexjsons": {
"first" : "graph_example.json", "first" : "graph_example.json",
"gexfs": { "graphs": {
"graph_example.json": {} "graph_example.json": {
"node0": { "name": "NGram" },
"node1": { "name": "Document" }
}
} }
} }
} }
...@@ -157,8 +157,9 @@ TW.conf = (function(TW){ ...@@ -157,8 +157,9 @@ TW.conf = (function(TW){
// Node typology: categories (resp. 0 and 1) will get these default labels // Node typology: categories (resp. 0 and 1) will get these default labels
TWConf.catSem = "NGram"; TWConf.catSem = "NGram";
TWConf.catSoc = "Document"; TWConf.catSoc = "Document";
// NB: these labels may be superseded by the input data's node types values // NB: these labels may be superseded by:
// cf. sortNodeTypes() // - the input data's node types values cf. sortNodeTypes()
// - in servermenu mode, by the node0 & node1 properties
// Modules path // Modules path
// ------------ // ------------
......
...@@ -64,7 +64,7 @@ Finally, to match the correct DB with the correct graph file: ...@@ -64,7 +64,7 @@ Finally, to match the correct DB with the correct graph file:
"title":"yourDocumentTitlesTable", "title":"yourDocumentTitlesTable",
"date":"yourDocumentPubDatesTable", "date":"yourDocumentPubDatesTable",
"abstract":"yourDocumentContentsTable", "abstract":"yourDocumentContentsTable",
"gexfs": { "graphs": {
"your.graph.gexf": { "your.graph.gexf": {
"semantic": { "table":"yourTableWithTerms"}, "semantic": { "table":"yourTableWithTerms"},
"social": { "table":"yourTableWithSocialNodes"} "social": { "table":"yourTableWithSocialNodes"}
......
...@@ -643,31 +643,22 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -643,31 +643,22 @@ var TinaWebJS = function ( sigmacanvas ) {
}); });
$("#changetype").click(function(){ $("#changetype").click(function(){
console.log("") console.log("changeTYPE click");
console.log(" ############ changeTYPE click");
if (TW.partialGraph.isForceAtlas2Running()) if (TW.partialGraph.isForceAtlas2Running())
sigma_utils.ourStopFA2(); sigma_utils.ourStopFA2();
console.log("DBG before changeType SystemState:", TW.SystemState())
changeType(); changeType();
setTimeout(function(){ setTimeout(function(){
$('.etabs a[href="#tabs1"]').trigger('click'); $('.etabs a[href="#tabs1"]').trigger('click');
},500) },500)
console.log(" ############ / changeTYPE click");
console.log("")
}); });
$("#changelevel").click(function(){ $("#changelevel").click(function(){
console.log("") console.log("changeLEVEL click");
console.log(" ############ changeLEVEL click");
if (TW.partialGraph.isForceAtlas2Running()) if (TW.partialGraph.isForceAtlas2Running())
sigma_utils.ourStopFA2(); sigma_utils.ourStopFA2();
changeLevel(); changeLevel();
console.log(" ############ / changeLEVEL click");
console.log("")
}); });
// sidepanel folding // sidepanel folding
......
...@@ -1040,8 +1040,8 @@ function createWaitIcon(idname, width) { ...@@ -1040,8 +1040,8 @@ function createWaitIcon(idname, width) {
} }
function jsActionOnGexfSelector(gexfBasename){ function jsActionOnGexfSelector(graphBasename){
let gexfPath = TW.gexfPaths[gexfBasename] || gexfBasename+".gexf" let graphPath = TW.gmenuPaths[graphBasename] || graphBasename+".gexf"
let serverPrefix = '' let serverPrefix = ''
var pathcomponents = window.location.pathname.split('/') var pathcomponents = window.location.pathname.split('/')
for (var i in pathcomponents) { for (var i in pathcomponents) {
...@@ -1049,13 +1049,19 @@ function jsActionOnGexfSelector(gexfBasename){ ...@@ -1049,13 +1049,19 @@ function jsActionOnGexfSelector(gexfBasename){
serverPrefix += '/'+pathcomponents[i] serverPrefix += '/'+pathcomponents[i]
} }
var newDataRes = AjaxSync({ "url": window.location.origin+serverPrefix+'/'+gexfPath }); var newDataRes = AjaxSync({ "url": window.location.origin+serverPrefix+'/'+graphPath });
// remove any previous instance and flags // remove any previous instance and flags
TW.resetGraph() TW.resetGraph()
// override default categories with the ones from db.json
if (TW.gmenuInfos[graphPath].nodetypes) {
TW.conf.catSem = TW.gmenuInfos[graphPath].nodetypes.node0
TW.conf.catSoc = TW.gmenuInfos[graphPath].nodetypes.node1
}
mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance) mainStartGraph(newDataRes["format"], newDataRes["data"], TW.instance)
writeLabel(gexfBasename) writeLabel(graphBasename)
TW.File = gexfPath TW.File = graphPath
} }
//============================= </OTHER ACTIONS > =============================// //============================= </OTHER ACTIONS > =============================//
...@@ -449,8 +449,8 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -449,8 +449,8 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
}); });
} }
else if (TW.conf.relatedDocsType == "wosLocalDB") { else if (TW.conf.relatedDocsType == "wosLocalDB") {
let gexfinfos = TW.relDocsInfos[TW.File] let thisRelDocsConf = TW.gmenuInfos[TW.File].relDocsConf
if (!gexfinfos || !gexfinfos[swType]) { if (!thisRelDocsConf || !thisRelDocsConf[swType]) {
resHTML = resHTML =
`<p>Your settings for relatedDocsType are set on a local wos database, `<p>Your settings for relatedDocsType are set on a local wos database,
but your servermenu file does not provide any information about but your servermenu file does not provide any information about
...@@ -460,7 +460,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -460,7 +460,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
return return
} }
else { else {
// /!\ documentation and specification needed for the php use cases /!\ // /!\ documentation and specification needed for the php use cases /!\
let joinedQ = JSON.stringify(qWords).split('&').join('__and__'); let joinedQ = JSON.stringify(qWords).split('&').join('__and__');
// cf. the php code for these url args: // cf. the php code for these url args:
...@@ -469,20 +468,20 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -469,20 +468,20 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
// or 'csv' (like gargantext exports) // or 'csv' (like gargantext exports)
// POSS object + join.map(join) // POSS object + join.map(join)
let urlParams = "type="+swType+"&query="+joinedQ+"&gexf="+TW.File+"&n="+TW.conf.relatedDocsMax+"&dbtype="+gexfinfos.dbtype let urlParams = "type="+swType+"&query="+joinedQ+"&gexf="+TW.File+"&n="+TW.conf.relatedDocsMax+"&dbtype="+thisRelDocsConf.dbtype
if (gexfinfos.dbtype == "sql") { if (thisRelDocsConf.dbtype == "sql") {
var qIndex = gexfinfos[swType] // a table var qIndex = thisRelDocsConf[swType] // a table
urlParams += `&index=${qIndex}` urlParams += `&index=${qIndex}`
} }
else { else {
// a list of csv columns to search in // a list of csv columns to search in
// ex: for semantic nodes matching we look in 'title', 'keywords' cols // ex: for semantic nodes matching we look in 'title', 'keywords' cols
// for social nodes matching we look in 'authors' col... etc. // for social nodes matching we look in 'authors' col... etc.
let joinedSearchCols = JSON.stringify(gexfinfos[swType]) let joinedSearchCols = JSON.stringify(thisRelDocsConf[swType])
urlParams += `&searchin=${joinedSearchCols}` urlParams += `&searchin=${joinedSearchCols}`
let joinedAllCols = JSON.stringify(gexfinfos) let joinedAllCols = JSON.stringify(thisRelDocsConf)
urlParams += `&toindex=${joinedAllCols}` urlParams += `&toindex=${joinedAllCols}`
// POSS use a direct access from php to db.json to avoid toindex // POSS use a direct access from php to db.json to avoid toindex
// POSS make it a REST array like: index[]=title&index[]=keywords // POSS make it a REST array like: index[]=title&index[]=keywords
...@@ -502,12 +501,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){ ...@@ -502,12 +501,6 @@ function topPapersFetcher(swType, qWords, priorHtml, cbNext){
cbNext(priorHtml + stockErrMsg) cbNext(priorHtml + stockErrMsg)
} }
}); });
} }
} }
} }
......
...@@ -12,15 +12,15 @@ TW.File = "" // remember the currently opened file ...@@ -12,15 +12,15 @@ TW.File = "" // remember the currently opened file
TW.partialGraph = null // will contain the sigma visible graph instance TW.partialGraph = null // will contain the sigma visible graph instance
TW.labels=[]; // fulltext search list TW.labels=[]; // fulltext search list
TW.gexfPaths={}; // for file selectors iff servermenu
TW.relDocsInfos={}; // map [graphsource => relatedDocs db fields or tables names]
// TODO requires specifications !!
// (iff servermenu && relatedDocsType == 'wosLocalDB')
TW.categories = []; // possible node types and their inverted map TW.categories = []; // possible node types and their inverted map
TW.catDict = {}; TW.catDict = {};
// used iff servermenu
TW.gmenuPaths={}; // map [graphname => graphsource] for file selectors
TW.gmenuInfos={}; // map [graphsource => { node0/1 categories
// + relatedDocs db fields names}]
// a system state is the summary of tina situation // a system state is the summary of tina situation
TW.initialSystemState = { TW.initialSystemState = {
activetypes: [], // <== filled from TW.categories activetypes: [], // <== filled from TW.categories
...@@ -259,58 +259,67 @@ function syncRemoteGraphData () { ...@@ -259,58 +259,67 @@ function syncRemoteGraphData () {
var files_selector = '<select onchange="jsActionOnGexfSelector(this.value);">' var files_selector = '<select onchange="jsActionOnGexfSelector(this.value);">'
for( var path in preRES.data ) { for( var path in preRES.data ) {
var theGexfs = preRES.data[path]["gexfs"] var theGraphs = preRES.data[path]["graphs"]
for(var aGexf in theGexfs) { for(var aGraph in theGraphs) {
var gexfBasename = aGexf.replace(/\.gexf$/, "") // more human-readable in the menu var graphBasename = aGraph.replace(/\.gexf$/, "") // more human-readable in the menu
TW.gexfPaths[gexfBasename] = path+"/"+aGexf TW.gmenuPaths[graphBasename] = path+"/"+aGraph
// ex : "RiskV2PageRank1000.gexf":data/AXA/RiskV2PageRank1000.gexf // ex : "RiskV2PageRank1000.gexf":data/AXA/RiskV2PageRank1000.gexf
// (we assume there's no duplicate basenames) // (we assume there's no duplicate basenames)
if (TW.conf.debug.logFetchers) if (TW.conf.debug.logFetchers)
console.log("\t\t\t"+gexfBasename) console.log("\t\t\t"+graphBasename)
// for associated wosLocalDBs sql queries // for associated wosLocalDBs sql queries
if (theGexfs[aGexf]) { if (theGraphs[aGraph]) {
let gSrcEntry = theGraphs[aGraph]
TW.gmenuInfos[path+"/"+aGraph] = {
"nodetypes": {"node0":'', "node1":''},
"relDocsConf": {
"semantic":null, "social":null, "dbtype": null
}
}
let gSrcEntry = theGexfs[aGexf] // shortcut
let thisInfos = TW.gmenuInfos[path+"/"+aGraph]
TW.relDocsInfos[path+"/"+aGexf] = {"semantic":null, "social":null, "dbtype": null} // db.json flat => 2 level structure: nodetype infos and relDocsConf
// POSS have this type attribute in db.json *for all the entries* // node types (no fallback here)
thisInfos.nodetypes.node0 = gSrcEntry.node0 ? gSrcEntry.node0.name : ''
thisInfos.nodetypes.node1 = gSrcEntry.node1 ? gSrcEntry.node1.name : ''
// TODO here settings + templates by type as per new specifications
// ----------------------------------------------------------------------------------
// choice: we'll keep a flat structure by source unless some use cases need otherwise
// ----------------------------------------------------------------------------------
// csv LocalDB ~ gargantext // csv LocalDB ~ gargantext
if(gSrcEntry["dbtype"] && gSrcEntry["dbtype"] == "csv") { if(gSrcEntry["dbtype"] && gSrcEntry["dbtype"] == "csv") {
TW.relDocsInfos[path+"/"+aGexf]['dbtype'] = "csv" thisInfos.relDocsConf.dbtype = "csv"
// it's CSV columns here // it's CSV columns here
TW.relDocsInfos[path+"/"+aGexf]['semantic'] = gSrcEntry["semantic"] thisInfos.relDocsConf.semantic = gSrcEntry["semantic"]
TW.relDocsInfos[path+"/"+aGexf]['social'] = gSrcEntry["social"] thisInfos.relDocsConf.social = gSrcEntry["social"]
} }
// sqlite LocalDB ~ wos // sqlite LocalDB ~ wos
else { else {
TW.relDocsInfos[path+"/"+aGexf]['dbtype'] = "sql" thisInfos.dbtype = "sql"
if (theGexfs[aGexf]["semantic"] && theGexfs[aGexf]["semantic"]["table"]) { if (theGraphs[aGraph]["semantic"] && theGraphs[aGraph]["semantic"]["table"]) {
TW.relDocsInfos[path+"/"+aGexf]['semantic'] = theGexfs[aGexf]["semantic"]["table"] thisInfos.relDocsConf.semantic = theGraphs[aGraph]["semantic"]["table"]
} }
if (theGexfs[aGexf]["social"] && theGexfs[aGexf]["social"]["table"]) { if (theGraphs[aGraph]["social"] && theGraphs[aGraph]["social"]["table"]) {
TW.relDocsInfos[path+"/"+aGexf]['social'] = theGexfs[aGexf]["social"]["table"] thisInfos.relDocsConf.social = theGraphs[aGraph]["social"]["table"]
} }
} }
} }
else { else {
TW.relDocsInfos[path+"/"+aGexf] = null TW.gmenuInfos[path+"/"+aGraph] = null
} }
// ^^^^^^ FIXME see if we got the expected behavior right // ^^^^^^ FIXME finish implementing new specifications
// (? specifications ?)
let cssFileSelected = (TW.File==(path+"/"+aGexf))?"selected":"" let cssFileSelected = (TW.File==(path+"/"+aGraph))?"selected":""
files_selector += '<option '+cssFileSelected+'>'+gexfBasename+'</option>' files_selector += '<option '+cssFileSelected+'>'+graphBasename+'</option>'
} }
// console.log( files_selector ) // console.log( files_selector )
} }
......
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