Commit c4a93fb1 authored by Romain Loth's avatar Romain Loth

make dynamic colors work with facet options user modal

parent 1f5510ed
...@@ -66,11 +66,11 @@ TW.conf = (function(TW){ ...@@ -66,11 +66,11 @@ TW.conf = (function(TW){
// (values overridden by data/myproject/project_conf.json "facets" if present) // (values overridden by data/myproject/project_conf.json "facets" if present)
TWConf.defaultFacetOptions = { TWConf.defaultFacetOptions = {
// attr title coloring fun nbins binning strategy // attr title coloring fun nbins binning strategy label in menus
'auto-size' : {'col': "heatmap", 'n': 5, 'binmode': 'samerange' }, 'auto-size' : {'col': "gradient", 'n': 6, 'binmode': 'samerange' },
'auto-degree' : {'col': "gradient", 'n': 7, 'binmode': 'samepop' }, 'auto-degree' : {'col': "heatmap", 'n': 7, 'binmode': 'samepop' },
'auto-indegree' : {'col': "gradient", 'n': 7, 'binmode': 'samepop' }, 'auto-indegree' : {'col': "heatmap", 'n': 7, 'binmode': 'samepop' },
'auto-outdegree' : {'col': "gradient", 'n': 7, 'binmode': 'samepop' }, 'auto-outdegree' : {'col': "heatmap", 'n': 7, 'binmode': 'samepop' },
'cluster_index' : {'col': "cluster" , 'binmode': 'off' }, 'cluster_index' : {'col': "cluster" , 'binmode': 'off' },
'clust_louvain' : {'col': "cluster" , 'binmode': 'off', 'clust_louvain' : {'col': "cluster" , 'binmode': 'off',
'legend':'Louvain clustering' }, 'legend':'Louvain clustering' },
......
...@@ -20,39 +20,41 @@ TW.sigmaAttributes = { ...@@ -20,39 +20,41 @@ TW.sigmaAttributes = {
} }
// £TODO: allow updating only one of them for user-setup
// update the Auto-Facets // update the Auto-Facets
// (bins over dynamic sigma attributes like degree, // (bins over dynamic sigma attributes like degree,
// available since we initialized the sigma instance) // available since we initialized the sigma instance)
function updateDynamicFacets() { function updateDynamicFacets(optionalFilter) {
let autoVals = {} let autoVals = {}
for (var icat in TW.categories) { for (var icat in TW.categories) {
let nodecat = TW.categories[icat] let nodecat = TW.categories[icat]
autoVals[nodecat] = {} autoVals[nodecat] = {}
for (var autoAttr in TW.sigmaAttributes) { for (var autoAttr in TW.sigmaAttributes) {
autoVals[nodecat][autoAttr] = {'map':{},'vals':{'vstr':[],'vnum':[]}} if (!optionalFilter || autoAttr == optionalFilter) {
let getVal = TW.sigmaAttributes[autoAttr](TW.partialGraph) autoVals[nodecat][autoAttr] = {'map':{},'vals':{'vstr':[],'vnum':[]}}
for (var nid of TW.ByType[icat]) { let getVal = TW.sigmaAttributes[autoAttr](TW.partialGraph)
let nd = TW.partialGraph.graph.nodes(nid) for (var nid of TW.ByType[icat]) {
if (nd) { let nd = TW.partialGraph.graph.nodes(nid)
let val = getVal(TW.partialGraph.graph.nodes(nid)) if (nd) {
if (! (val in autoVals[nodecat][autoAttr].map)) let val = getVal(TW.partialGraph.graph.nodes(nid))
autoVals[nodecat][autoAttr].map[val] = [] if (! (val in autoVals[nodecat][autoAttr].map))
autoVals[nodecat][autoAttr].map[val].push(nid) autoVals[nodecat][autoAttr].map[val] = []
autoVals[nodecat][autoAttr].vals.vnum.push(val) autoVals[nodecat][autoAttr].map[val].push(nid)
autoVals[nodecat][autoAttr].vals.vnum.push(val)
}
} }
} }
} }
} }
// console.log("reparse dynamic attr, raw result", autoVals)
let autoFacets = facetsBinning(autoVals) let autoFacets = facetsBinning(autoVals)
// merge them into clusters // merge them into clusters
for (var icat in TW.categories) { for (var icat in TW.categories) {
let nodecat = TW.categories[icat] let nodecat = TW.categories[icat]
for (var autoAttr in TW.sigmaAttributes) { for (var autoAttr in TW.sigmaAttributes) {
for (var facet in autoFacets[nodecat]) { for (var facet in autoFacets[nodecat]) {
TW.Clusters[nodecat][facet] = autoFacets[nodecat][facet] TW.Facets[nodecat][facet] = autoFacets[nodecat][facet]
} }
} }
} }
...@@ -316,13 +318,10 @@ function set_ClustersLegend ( daclass, groupedByTicks ) { ...@@ -316,13 +318,10 @@ function set_ClustersLegend ( daclass, groupedByTicks ) {
// valueclasses (values or intervals or classes) are already sorted in TW.Facets // valueclasses (values or intervals or classes) are already sorted in TW.Facets
for (var l in legendInfo) { for (var l in legendInfo) {
// get a sample node color for each bin/class
var nMatchedNodes = legendInfo[l]['nids'].length var nMatchedNodes = legendInfo[l]['nids'].length
// console.log("legendInfo, nMatchedNodes", legendInfo, nMatchedNodes) // get a sample node color for each bin/class
let theColor = legendInfo[l].col || "#777" // grey if empty
let theColor = legendInfo[l].col || "#111" // black if empty
// create the legend item // create the legend item
var preparedLabel = legendInfo[l]['labl'] var preparedLabel = legendInfo[l]['labl']
...@@ -1104,32 +1103,41 @@ function newAttrConfAndColor() { ...@@ -1104,32 +1103,41 @@ function newAttrConfAndColor() {
'titlingNTerms': document.getElementById('attr-titling-n').value || 1 'titlingNTerms': document.getElementById('attr-titling-n').value || 1
} }
// find the corresponding types // dynamic attribute case
let relevantTypes = {} if (attrTitle in TW.sigmaAttributes) {
for (let ty in TW.Facets) { updateDynamicFacets(attrTitle) // all-in-one function
if (TW.Facets[ty][attrTitle]) {
relevantTypes[ty] = true
}
} }
// reparse values (avoids keeping them in RAM since parseCustom) // classic data-driven attribute case
tmpVals = {} else {
for (let nid in TW.Nodes) {
let n = TW.Nodes[nid] // 1 - find the corresponding types
if (relevantTypes[n.type]) { let relevantTypes = {}
tmpVals = updateValueFacets(tmpVals, n, attrTitle) for (let ty in TW.Facets) {
if (TW.Facets[ty][attrTitle]) {
relevantTypes[ty] = true
}
} }
}
let newClustering = facetsBinning (tmpVals) // 2 - reparse values (avoids keeping them in RAM since parseCustom)
tmpVals = {}
for (let nid in TW.Nodes) {
let n = TW.Nodes[nid]
if (relevantTypes[n.type]) {
tmpVals = updateValueFacets(tmpVals, n, attrTitle)
}
}
// write result to global TW.Facets let newClustering = facetsBinning (tmpVals)
for (let ty in newClustering) {
TW.Facets[ty][attrTitle] = newClustering[ty][attrTitle] // 3 - write result to global TW.Facets
} for (let ty in newClustering) {
TW.Facets[ty][attrTitle] = newClustering[ty][attrTitle]
}
// console.log("reparse raw result", tmpVals) // console.log("reparse raw result", tmpVals)
// console.log("reparse binned result", newClustering) // console.log("reparse binned result", newClustering)
}
// update the GUI menu // update the GUI menu
changeGraphAppearanceByFacets() changeGraphAppearanceByFacets()
......
...@@ -760,7 +760,7 @@ function gradientColoring(daclass) { ...@@ -760,7 +760,7 @@ function gradientColoring(daclass) {
if (nidList.length) { if (nidList.length) {
// we take first non null exemplar from last in the range // we take first non null exemplar from last in the range
// (possible skip due to changeLevel or filters) // (possible skip due to changeLevel or filters)
for (var k = nidList.length-1 ; k-- ; k >= 0) { for (var k = nidList.length-1 ; k >= 0 ; k--) {
let nd = TW.partialGraph.graph.nodes(nidList[k]) let nd = TW.partialGraph.graph.nodes(nidList[k])
if (nd) { if (nd) {
bins.invIdx[i].col = nd.color bins.invIdx[i].col = nd.color
...@@ -769,7 +769,7 @@ function gradientColoring(daclass) { ...@@ -769,7 +769,7 @@ function gradientColoring(daclass) {
} }
} }
else { else {
bins.invIdx[i].col = "#111" // empty bin bins.invIdx[i].col = "#777" // empty bin
} }
} }
else { else {
......
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