Commit 71507331 authored by Romain Loth's avatar Romain Loth

much better bins and clusters (in testing)

factor in binning we had for legends to a much earlier stage in parsing, thus creating value facets with reverse index accessed via TW.Clusters.type.facet[facetvalue].nids
parent 4fb19e2f
This diff is collapsed.
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
z-index: 5; z-index: 5;
/* width: we set it equal or smaller than #lefttopbox width */ /* width: we set it equal or smaller than #lefttopbox width */
width:18%; width:18%;
max-height: 40%; max-height: 25%;
overflow-y:scroll; overflow-y:scroll;
bottom:5px; bottom:5px;
left:5px; left:5px;
......
...@@ -67,8 +67,8 @@ html, body { ...@@ -67,8 +67,8 @@ html, body {
#twbrand { #twbrand {
font-family: "Gurajada" ; font-family: "Gurajada", "Droid Sans", sans-serif ;
font-size: 28px; font-size: 24px;
width: 50px !important; width: 50px !important;
} }
......
...@@ -118,6 +118,14 @@ TW.overSampling = true // costly hi-def rendering (true => pixelRatio x 2) ...@@ -118,6 +118,14 @@ TW.overSampling = true // costly hi-def rendering (true => pixelRatio x 2)
TW.deselectOnclickStage = true // will a click on the background remove selection ? (except when dragging) TW.deselectOnclickStage = true // will a click on the background remove selection ? (except when dragging)
var showLabelsIfZoom=1.0; var showLabelsIfZoom=1.0;
// for continuous attrvalues/colors (cf. clustersBy), how many levels in legend?
TW.legendsBins = 7 ;
// some specific attributes may have other number of levels
TW.customLegendsBins = {
'age': 8,
'growth_rate': 12
}
// ============ < / DEVELOPER OPTIONS > ============ // ============ < / DEVELOPER OPTIONS > ============
...@@ -147,7 +155,8 @@ var sigmaJsDrawingProperties = { ...@@ -147,7 +155,8 @@ var sigmaJsDrawingProperties = {
twNodeRendBorderColor: "#222", twNodeRendBorderColor: "#222",
// twNodeRendBorderColor: "#eee", // twNodeRendBorderColor: "#eee",
font: "Crete Round", font: "Droid Sans",
// font: "Crete Round",
// font: "Ubuntu Condensed", // font: "Ubuntu Condensed",
fontStyle: "bold", fontStyle: "bold",
}; };
...@@ -210,17 +219,22 @@ TW.Nodes = []; ...@@ -210,17 +219,22 @@ TW.Nodes = [];
TW.Edges = []; TW.Edges = [];
TW.Clusters = []; TW.Clusters = [];
// new dev properties
TW.scanClusters = true // build TW.Clusters in an (attr+val => nodes) reverse index (aka facets)
TW.maxDiscreteValues = 40 // max discrete levels in facet legend (aka bins)
// new TW.Clusters structure // new TW.Clusters structure
// -------------------------- // --------------------------
// was: built in separate loop from read of all attr values // was: built in separate loop from read of all attr values
// TW.Clusters[nodeType][clusterType][possibleValue] = clst_idx_of_possible_value // TW.Clusters[nodeType][clusterType][possibleValue] = clst_idx_of_possible_value
// from now on (WIP): // from now on:
// built in parseCustom (when reading all nodes attributes anyway) // still built in ChangeGraphAppearanceByAtt
// if discrete attrvalues with < 15 classes (colorsBy, clustersBy) // POSS: build in parseCustom (when reading all nodes attributes anyway)
// => TW.Clusters[nodeType][clusterType][possibleValue] = number of nodes with this value // if discrete attrvalues with <= 30 classes (colorsBy, clustersBy)
// if continuous or many possible values (clustersBy, colorsRelByBins) // => TW.Clusters[nodeType][clusterType].classes.[possibleValue] = list of ids with the value
// => TW.Clusters[nodeType][clusterType][interval] = number of nodes in interval // if continuous or many possible values (>30) (clustersBy, colorsRelByBins)
// => TW.Clusters[nodeType][clusterType].ranges.[interval] = list of ids in the interval
var nodeslength=0; var nodeslength=0;
......
...@@ -34,6 +34,7 @@ function changeType() { ...@@ -34,6 +34,7 @@ function changeType() {
// types eg [true] <=> '1' // types eg [true] <=> '1'
// [true, true] <=> '1|1' // [true, true] <=> '1|1'
// [true, false] <=> '1|0'
// Complement of the received state ~[X\Y] ) // Complement of the received state ~[X\Y] )
var type_t1 = [] var type_t1 = []
......
...@@ -554,12 +554,9 @@ if(RES["OK"]) { ...@@ -554,12 +554,9 @@ if(RES["OK"]) {
// } // }
} }
try {
ChangeGraphAppearanceByAtt(true) // TEST new strategy: TW.Clusters were prepared in parseCustom
} changeGraphAppearanceByFacets(true)
catch (e) {
console.error(e)
}
// set the default legend // set the default legend
set_ClustersLegend ( "clust_default" ) set_ClustersLegend ( "clust_default" )
......
...@@ -83,6 +83,27 @@ function cancelSelection (fromTagCloud, settings) { ...@@ -83,6 +83,27 @@ function cancelSelection (fromTagCloud, settings) {
} }
} }
function getCurrentType() {
// type grammar overly complicated: it's absurd to have to do 10 lines
// to retrieve the tina type when other times
// there's so many window-scoped vars !!!
// TODO expose current type more accessibly
let currentTypeName
let currentTypeIdx
let typeIdxs = Object.keys(TW.partialGraph.states.slice(-1)[0].type)
for (var m in typeIdxs) {
if (TW.partialGraph.states.slice(-1)[0].type[m]) {
currentTypeIdx = m
break
}
}
currentTypeName = window.categories[currentTypeIdx]
return currentTypeName
}
function highlightSelectedNodes(flag){ function highlightSelectedNodes(flag){
console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" selEmpty:"+is_empty(selections)) console.log("\t***methods.js:highlightSelectedNodes(flag)"+flag+" selEmpty:"+is_empty(selections))
if(!is_empty(selections)){ if(!is_empty(selections)){
......
This diff is collapsed.
...@@ -691,6 +691,7 @@ function getArrSubkeys(arr,id) { ...@@ -691,6 +691,7 @@ function getArrSubkeys(arr,id) {
return result; return result;
} }
function clustersBy(daclass) { function clustersBy(daclass) {
cancelSelection(false); cancelSelection(false);
...@@ -716,7 +717,6 @@ function clustersBy(daclass) { ...@@ -716,7 +717,6 @@ function clustersBy(daclass) {
var real_min = 1000000; var real_min = 1000000;
var real_max = -1; var real_max = -1;
var themult = Math.pow(10,min_pow); var themult = Math.pow(10,min_pow);
// console.log('themult', themult) // console.log('themult', themult)
for(var j in TW.nodeIds) { for(var j in TW.nodeIds) {
...@@ -731,26 +731,28 @@ function clustersBy(daclass) { ...@@ -731,26 +731,28 @@ function clustersBy(daclass) {
if (round_number>real_max) real_max = round_number; if (round_number>real_max) real_max = round_number;
} }
console.log("NodeID_Val", NodeID_Val) // console.log("NodeID_Val", NodeID_Val)
console.log(" - - - - - - - - -- - - ") // console.log(" - - - - - - - - -- - - ")
console.log(real_min) // console.log(real_min)
console.log(real_max) // console.log(real_max)
console.log("10^"+min_pow) // console.log("10^"+min_pow)
console.log("the mult: "+themult) // console.log("the mult: "+themult)
console.log(" - - - - - - - - -- - - ") // console.log(" - - - - - - - - -- - - ")
// [ Scaling node colours(0-255) and sizes(3-5) ] // [ Scaling node colours(0-255) and sizes(2-7) ]
var Min_color = 0; var Min_color = 0;
var Max_color = 255; var Max_color = 255;
var Min_size = 2; var Min_size = 1;
var Max_size= 6; var Max_size= 8;
for(var nid in NodeID_Val) { for(var nid in NodeID_Val) {
var newval_color = Math.round( ( Min_color+(NodeID_Val[nid]["round"]-real_min)*((Max_color-Min_color)/(real_max-real_min)) ) ); var newval_color = Math.round( ( Min_color+(NodeID_Val[nid]["round"]-real_min)*((Max_color-Min_color)/(real_max-real_min)) ) );
var hex_color = rgbToHex(255, (255-newval_color) , 0) var hex_color = rgbToHex(255, (255-newval_color) , 0)
TW.partialGraph.graph.nodes(nid).color = hex_color TW.partialGraph.graph.nodes(nid).color = hex_color
TW.partialGraph.graph.nodes(nid).customAttrs.alt_color = hex_color TW.partialGraph.graph.nodes(nid).customAttrs.alt_color = hex_color
// FIXME not used ?
TW.partialGraph.graph.nodes(nid).customAttrs.altgrey_color = false TW.partialGraph.graph.nodes(nid).customAttrs.altgrey_color = false
var newval_size = Math.round( ( Min_size+(NodeID_Val[nid]["round"]-real_min)*((Max_size-Min_size)/(real_max-real_min)) ) ); var newval_size = Math.round( ( Min_size+(NodeID_Val[nid]["round"]-real_min)*((Max_size-Min_size)/(real_max-real_min)) ) );
...@@ -759,19 +761,19 @@ function clustersBy(daclass) { ...@@ -759,19 +761,19 @@ function clustersBy(daclass) {
TW.partialGraph.graph.nodes(nid).label = "("+NodeID_Val[nid]["real"].toFixed(min_pow)+") "+TW.Nodes[nid].label TW.partialGraph.graph.nodes(nid).label = "("+NodeID_Val[nid]["real"].toFixed(min_pow)+") "+TW.Nodes[nid].label
} }
// [ / Scaling node colours(0-255) and sizes(3-5) ] // [ / Scaling node colours(0-255) and sizes(2-7) ]
// Edge precompute alt_rgb by new source-target nodes-colours combination // Edge precompute alt_rgb by new source-target nodes-colours combination
repaintEdges() repaintEdges()
set_ClustersLegend ( daclass ) // NB legend will group different possible values using
// precomputed ticks from TW.Clusters.terms[daclass]
set_ClustersLegend ( daclass)
TW.partialGraph.render(); TW.partialGraph.render();
} }
// for debug of colorsRelByBins
var totalsPerBinMin = {}
// Edge-colour: precompute alt_rgb by source-target node.alt_color combination // Edge-colour: precompute alt_rgb by source-target node.alt_color combination
function repaintEdges() { function repaintEdges() {
...@@ -799,8 +801,113 @@ function repaintEdges() { ...@@ -799,8 +801,113 @@ function repaintEdges() {
} }
// rewrite of clustersBy with binning and for attributes that can have negative float values // rewrite of clustersBy with binning and for attributes that can have negative float values
// /!\ age and growth_rate attributes referred to by name
// NB - binning is done at parseCustom
// - number of bins can be specified by attribute name in TW.customLegendsBins
function colorsRelByBins(daclass) { function colorsRelByBins(daclass) {
var binColors
var doModifyLabel = false
var ty = getCurrentType()
// our binning
var tickThresholds = TW.Clusters[ty][daclass]
// for debug of colorsRelByBins
var totalsPerBinMin = {}
// let's go
cancelSelection(false);
// global flag
TW.handpickedcolor = true
if (daclass == 'age') {
// 9 colors
binColors = [
"#F9F588",//epsilon
"#f9f008", //yel
"#f9da08",
"#fab207",
"#fa9607",
"#fa6e07",
"#fa4607",
"#ff0000" // red binMin 125
];
}
else if (daclass == 'growth_rate') {
doModifyLabel = true
// 12 colors
binColors = [
"#005197", //blue binMin -∞
"#3c76fb", // binMin -75
"#5c8af2", // binMin -50
"#64c5f2", // binMin -25
"#F9F7ED",//epsilon binMin -15
"#bae64f", // binMin 15
"#f9f008", // binMin 25
"#fab207", // binMin 50
"#fa9607", // binMin 75
"#fa6e07", // binMin 100
"#fa4607", // red binMin 125
"#991B1E" // binMin 150
];
}
// verification
if (tickThresholds.length != binColors.length) {
console.warn (`colorsRelByBins setup mismatch: TW.Clusters ticks ${tickThresholds} should == nColors ${binColors.length}`)
}
// use our valueclass => ids mapping
for (var k in tickThresholds) {
// console.debug('tick infos', tickThresholds[k])
// ex: {labl: "terms||growth_rate||[0 ; 0.583]", nids: Array(99), range: [0 ; 0.583210]}
totalsPerBinMin[tickThresholds[k].range[0]] = tickThresholds[k].nids.length
// color the referred nodes
for (var j in tickThresholds[k].nids) {
let n = TW.partialGraph.graph.nodes(tickThresholds[k].nids[j])
n.color = binColors[k]
n.customAttrs.alt_color = binColors[k]
n.customAttrs.altgrey_color = false
var originalLabel = TW.Nodes[n.id].label
if (doModifyLabel) {
var valSt = n.attributes[daclass]
n.label = `(${valSt}) ${originalLabel}`
}
else {
n.label = originalLabel
}
}
}
// console.debug(valArray)
console.info('coloring distribution per tick thresholds' , totalsPerBinMin)
// Edge precompute alt_rgb by new source-target nodes-colours combination
repaintEdges()
set_ClustersLegend ( daclass )
TW.partialGraph.render();
}
// KEPT FOR REFERENCE, BINNING NOW PRECOMPUTED in parseCustom
// rewrite of clustersBy with binning and for attributes that can have negative float values
// /!\ age and growth_rate attributes referred to by name
function colorsRelByBins_old(daclass) {
cancelSelection(false); cancelSelection(false);
var binColors var binColors
...@@ -808,6 +915,10 @@ function colorsRelByBins(daclass) { ...@@ -808,6 +915,10 @@ function colorsRelByBins(daclass) {
TW.handpickedcolor = true TW.handpickedcolor = true
// for debug of colorsRelByBins
var totalsPerBinMin = {}
// should be = binColors.length // should be = binColors.length
var nTicksParam = (daclass == 'age') ? 8 : 12 var nTicksParam = (daclass == 'age') ? 8 : 12
// do first loop entirely to get percentiles => bins, then modify alt_color // do first loop entirely to get percentiles => bins, then modify alt_color
......
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