/**
* Módulo histograma, utilizado para crear y gestionar los histogramas en nicho ecológico y comunidad ecológica.
*
* @module module_histogram
*/
var histogram_module = (function (verbose) {
var _VERBOSE = verbose;
var _table_module_decil, _language_module_nicho, _display_module_nicho, _toast_module;
var _highlight_color = "#48D7D5";
var _iTrans;
var _NUM_DECIL = 10;
function setDisplayModule(displayModule) {
_display_module_nicho = displayModule;
}
/**
* Método setter del módulo table.
*
* @function setTableModule
* @public
*
* @param {object} tableModule - Módulo table
*/
function setTableModule(tableModule) {
_table_module_decil = tableModule;
}
/**
* Método setter del módulo de internacionalización.
*
* @function setLanguageModule
* @public
*
* @param {object} languageModule - Módulo de internacionalización.
*/
function setLanguageModule(languageModule) {
_language_module_nicho = languageModule;
_iTrans = _language_module_nicho.getI18();
}
/**
* Método setter del módulo de mensajes.
*
* @function setLanguageModule
* @public
* @memberof! toast_module
*
* @param {object} toast_module - Módulo de mensajes.
*/
function setToastModule(toast_module) {
_toast_module = toast_module
}
/**
* Éste método inicializa variables globales y componentes visuales que son necesarios para la creación de histogramas.
*
* @function _initilizeHistogram
* @public
*
*/
function _initilizeHistogram() {
_VERBOSE ? console.log("_initilizeHistogram") : _VERBOSE;
$('#lb_header_info').text(_iTrans.prop('lb_index_hist_decil'));
$('#lb_body_info').text(_iTrans.prop('lb_msg_graf_decil'));
}
function addTooltipBarChart(svg){
// POPUP DE
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
// console.log(d);
var var_group_label = "<strong>" + d.name + "</strong><br/>" +
"<strong>" + _iTrans.prop('lb_score_conjunto') + ":</strong> <span >" + parseFloat(d.avg).toFixed(2) + "</span><br/><br/>";
// "<strong>" + _iTrans.prop('lb_conformado') + ":</strong><br/><br/>";
//
// d.value.s.forEach(function (item, index) {
//
// if(d.name.p === "Total"){
// var_group_label += "<strong>" + _iTrans.prop('lb_grupo') + ":</strong> <span >" + d.name.s[index] + "</span><br/>" +
// "<strong>" + _iTrans.prop('tip_tbl_score') + ":</strong> <span >" + item + "</span><br/><br/>";
// }
// else{
// var_group_label += "<strong>" + _iTrans.prop('lb_grupo') + ":</strong> <span >" + d.name.s[index*10] + "</span><br/>" +
// "<strong>" + _iTrans.prop('tip_tbl_score') + ":</strong> <span >" + item + "</span><br/><br/>";
// }
//
// });
return var_group_label;
});
svg.call(tip);
return tip;
}
function addTooltipBarRectLegend(svg){
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
// console.log(d);
var var_group_label = _iTrans.prop('tip_grupodecil', d);
return var_group_label;
});
svg.call(tip);
return tip;
}
function addTooltipChkRectLegend(svg){
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
// console.log(d);
var var_group_label = _iTrans.prop('tip_grupodecil_2', d);
return var_group_label;
});
svg.call(tip);
return tip;
}
function groupDataByAtributte(json_decil){
_VERBOSE ? console.log("groupDataByAtributte") : _VERBOSE;
var verticalData = [];
var size = json_decil.length;
var num_decile = _NUM_DECIL;
for(var i=0; i<num_decile; i++){
for(var j=0; j<size; j++){
var decil_item = json_decil[j].data[i];
// console.log(decil_item);
if(!verticalData[i]){
verticalData.push({
decil: decil_item.decil,
value: [{ name: json_decil[j].gpo_name, avg:parseFloat(decil_item.avg), decil: decil_item.decil, children: json_decil[j].names }]
});
}
else{
// console.log(verticalData[i]);
verticalData[i].value.push({ name: json_decil[j].gpo_name, avg:parseFloat(decil_item.avg), decil: decil_item.decil, children: json_decil[j].names });
}
}
}
// console.log(verticalData);
return verticalData;
}
/**
* Éste método crea el histograma de score decil del sistema de nicho, genera la interacción de tooltips, genera la interacción con histogramas y genera un line chart cuando el proceso de validación esta activado. Además genera una tabla de información por decil.
*
* @function createMultipleBarChart
* @public
*
* @param {array} json_decil - Array con el resultado de los grupos de vartiables seleccionados por decil
* @param {array} array_recall - Contiene los resultados por grupo de variables por decil. Contiene verdaderos positivos, falsos negativos y recall. Este array solo es utilizado en el proceso de validación
* @param {String} idComponent - Id del contenedor del histograma
* @param {map} nameMap - Mapa de los grupos de variables seleccionados en el análisis de nicho ecológico
*/
function createMultipleBarChart(json_decil, array_recall, idComponent, nameMap) {
_VERBOSE ? console.log("createMultipleBarChart") : _VERBOSE;
// LIMPIA EL AREA DONDE SE ENCUENTRA EL HISTOGRAMA
$("#" + idComponent.id).empty();
// OBTIENE EL ESPACIO NECESARIO PARA EL CONTENEDOR DEL HISTOGRAMA
var margin = {top: 30, right: 40, bottom: 70, left: 40},
width = $(".myScrollableBlockEpsilonDecil").width() - margin.left - margin.right;
var height = $(".myScrollableBlockEpsilonDecil").height() - margin.top - margin.bottom - 15; // 10px del icono de info
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color_array = [];
// variable que sirve para conocer el decil donde ya existen valores para generar la gráfica
var value_decil_ready = 0;
var length_names = 0;
_VERBOSE ? console.log(json_decil) : _VERBOSE;
for (value_decil_ready = 0; value_decil_ready < _NUM_DECIL; value_decil_ready++) {
try {
length_names = json_decil.length;
break;
} catch (e) {
_VERBOSE ? console.log("sin valores decil: " + value_decil_ready) : _VERBOSE;
}
}
_VERBOSE ? console.log("value_decil_ready: " + value_decil_ready) : _VERBOSE;
_VERBOSE ? console.log("length_names: " + length_names) : _VERBOSE;
for (i = 0; i < length_names; i++) {
color_array.push(_randomColor());
}
// _VERBOSE ? console.log(color_array) : _VERBOSE;
var color = d3.scale.ordinal()
.range(color_array);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
// .ticks(10);
var svg = d3.select("#" + idComponent.id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("text")
.attr("id", idComponent.legend)
.attr("y", -22)
.attr("x", width / 2 + 40)
.attr("dy", ".71em")
.style("font-size", "20px")
.style("text-anchor", "end")
.text(_iTrans.prop('titulo_hist_score_decil'));
d3.select("#chartdiv_score_decil")
.append("input")
.attr("id", "btn_decil")
.attr("class", "btn btn-primary btn_decil_cp")
.attr("type", "button")
.attr("y", 0)
.attr("x", 0)
.attr("value", _iTrans.prop('btn_decil'))
.on("click",function(d,i) {
console.log("calculando valores")
// console.log(d)
var deciles = [], grupos = []
d3.selectAll(".lbdecil_chk .tick .selected")
.each(function (d, i) {
// console.log(d)
deciles.push(d)
})
d3.selectAll(".rect_legend.selected")
.each(function (d, i) {
// console.log(d)
grupos.push(d)
})
console.log(deciles)
console.log(grupos[0])
// TODO: validar que exista almenos un decil y un grupo seleccionado
if(deciles.length == 0 || grupos == 0){
console.log("Sin grupos o deciles seleccionados")
_toast_module.warning(_iTrans.prop('no_decilgrupo'));
return
}
// _display_module_nicho.loadDecilDataTable(d.decil, d.name, false, [], []);
_display_module_nicho.loadDecilDataTable(deciles, grupos[0], false, [], []);
})
var tip = addTooltipBarChart(svg);
// nameMap es mayor que 0 cuando se realiza el proceso de validación
var ageNames = []; //nameMap.values();
ageNames = json_decil.map(group => group.gpo_name)
// if(ageNames.length > 1) ageNames.push("root");
// _VERBOSE ? console.log(nameMap) : _VERBOSE;
_VERBOSE ? console.log(ageNames) : _VERBOSE;
$("#grupos_deciles").empty();
ageNames.forEach(function (item, index){
console.log(item)
$("#grupos_deciles").append(
'<div class="col-md-12">'+
'<div class="col-md-2 margin-top-five">'+
'<h5 class="summary_lb">'+ item +'</h5>'+
'</div>'+
'<div class="col-md-4 margin-top-five">'+
'<input id="gpodecil_'+ index +'" class="checkbox_item" type="checkbox" />'+
'</div>'+
'</div>');
})
// CREADO DATA VERTICAL.
// NOTA: LOS DATOS ANTES DE ESTE PUNTO ESTAN ALMACENADOS POR GRUPO DE VARIABLES, PARA GENERAR EL HISTOGRAMA
// ES NECESARIO AGRUPAR POR DECIL LOS DIFERENTES GRUPOS DE VARIABLES
var verticalData = groupDataByAtributte(json_decil);
// INICIA CONSTRUCCIÓN DEL HISTOGRAMA
var deciles = verticalData.map(item => item.decil);
// _VERBOSE ? console.log(deciles) : _VERBOSE;
x0.domain(deciles);
// _VERBOSE ? console.log(x0.rangeBand()) : _VERBOSE;
x1.domain(ageNames)
.rangeRoundBands([0, x0.rangeBand()]);
// console.log(x0.rangeBand());
// console.log(x0(10));
// console.log(x1("root"));
var totalmax_avg = d3.max(json_decil.map(function (d, index) {
if (value_decil_ready <= index) {
return d3.max(d.data, function (d) {
return parseFloat(d.avg)
});
}
}));
console.log("totalmax_avg: " + totalmax_avg);
var totalmin_avg = d3.min(json_decil.map(function (d, index) {
if (value_decil_ready <= index) {
return d3.min(d.data, function (d) {
return parseFloat(d.avg)
});
}
}));
console.log("totalmin_avg: " + totalmin_avg);
// que ocurre cuando min y max son iguales, no se esta generando la gráfica... cehcar validacion
if (totalmax_avg === totalmin_avg) {
if (totalmax_avg < 0) {
totalmax_avg = 0;
} else {
totalmin_avg = 0;
}
}
var totalmin_nice = Math.floor(totalmin_avg);
var totalmax_nice = Math.ceil(totalmax_avg);
var NEG_DECIL = 0;
// TODO: analizar cuando son solo positovos, solo negativos o combinación
// solo negativos
if (totalmax_avg < 0 && totalmin_avg < 0) {
NEG_DECIL = -1;
}
// combinado
else if (totalmin_avg < 0) {
NEG_DECIL = 0;
}
// solo positivos
else {
NEG_DECIL = 1;
}
console.log("** value_decil_ready: " + value_decil_ready);
// NOTA: En d3 el max de -0.12 y -0.86 es "-0.86", obtiene el minimo de los negativos
var maxmin_avg = 0;
var temp_maxmin_avg = d3.max(json_decil.map(function (d, index) {
if (value_decil_ready <= index) {
return d3.max(d.data, function (d) {
if (d.avg < 0){
return d.avg;
}
});
}
}));
maxmin_avg = temp_maxmin_avg === undefined ? maxmin_avg : temp_maxmin_avg
console.log("** maxmin_avg: " + maxmin_avg);
// si existen valores combinados el axis se divide de forma equitativa
if (NEG_DECIL === 0) {
if (Math.abs(totalmax_avg) < Math.abs(totalmax_avg)) {
y.domain([-totalmax_avg, totalmax_avg])
.nice([totalmin_nice, totalmax_nice]);
} else {
y.domain([totalmin_avg, -totalmin_avg])
.nice([totalmin_nice, totalmax_nice]);
}
} else {
y.domain([totalmin_avg, totalmax_avg])
.nice([totalmin_nice, totalmax_nice]);
}
console.log("** totalmax_avg: " + totalmax_avg);
console.log("** totalmin_avg: " + totalmin_avg);
var translate_axis = 0;
// set the x axis in middle of the chart when there are negative values.
// solo negativos
if (NEG_DECIL === -1) {
translate_axis = y(totalmax_avg); // valor de cero, ajusta en la parte superior del histograma
}
// combinado
else if (NEG_DECIL === 0) {
translate_axis = y(Math.max(0, maxmin_avg)); // ajusta en la parte superior del histograma
}
// solo positivos
else {
translate_axis = height; // valor maximos, ajusta en la parte inferior del histograma
}
console.log("** translate_axis: " + translate_axis)
// CREACIÓN DE EJES DEL HISTOGRAMA
svg.append("g")
.attr("class", "x axis lbdecil_chk")
.attr("transform", "translate(0," + translate_axis + ")")
.call(xAxis)
.append("text")
.attr("id", idComponent.xaxis)
.attr("y", margin.bottom - 10)
.attr("x", width / 2)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(_iTrans.prop('lb_xaxis_decil'))
var tip_chk_legend = addTooltipChkRectLegend(svg)
d3.selectAll(".lbdecil_chk .tick")
.append("rect")
.attr("y", 105)
.attr("x", function(d){
// console.log(d)
return -5;
})
.attr("width", 10)
.attr("height", 10)
.style("fill", "white")
.style("stroke", 1)
.style("stroke", "black")
.on("click",function(d,i) {
d3.select(this).classed("selected", d3.select(this).classed("selected") ? false : true);
if(d3.select(this).classed("selected")){
d3.select(this)
.style("fill", "black")
}
else{
d3.select(this)
.style("fill", "white")
}
})
.on('mouseover', function (d) {
// console.log(d)
// console.log(d3.select(this))
tip_chk_legend.show(d);
})
.on('mouseout', function (d) {
// console.log(d)
// console.log(d3.select(this))
tip_chk_legend.hide(d);
})
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("id", idComponent.yaxis)
.attr("y", -10)
.attr("x", margin.left - 40)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(_iTrans.prop('tip_tbl_score'));
console.log(verticalData)
// CREACION DE BARRAS DEL HISTOGRAMA
var state = svg.selectAll(".state")
.data(verticalData)
.enter().append("g")
.attr("class", "state")
.attr("transform", function (d) {
// console.log(d.decil);
return "translate(" + x0(d.decil) + ",0)";
});
state.selectAll(".rect")
.data(function (d) {
return d.value;
})
.enter().append("rect")
.attr("class", "bar")
.attr("width", x1.rangeBand())
.attr("x", function (d) {
console.log(d)
// console.log(x1(d.name))
// console.log(x1.rangeBand())
return x1(d.name);
})
.attr("y", function (d) {
// _VERBOSE ? console.log("decil_nulo: " + d.decil_nulo) : _VERBOSE;
if (d.decil_nulo)
return y(0);
// locate the bars in the chart correctly when there are negative values.
if (NEG_DECIL === -1) {
return y(totalmax_avg);
} else if (NEG_DECIL === 0) {
return y(Math.max(0, parseFloat(d.avg)));
} else {
return y(parseFloat(d.avg));
}
})
.attr("height", function (d) {
_VERBOSE ? console.log("decil_nulo: " + d.decil_nulo) : _VERBOSE;
var val_h = d.decil_nulo ? 0 : parseFloat(d.avg);
// locate the bars in the chart correctly when there are negative values.
if (NEG_DECIL == -1) {
return Math.abs(y(val_h) - y(totalmax_avg))
} else if (NEG_DECIL == 0) {
return Math.abs(y(val_h) - y(0))
} else {
return height - y(val_h);
}
})
.style("fill", function (d) {
return color(d.name);
})
.style("opacity", 0.7)
.on('mouseover', function (d) {
tip.show(d);
})
.on('mouseout', function (d) {
tip.hide(d);
})
// .on("click", function (d) {
// console.log(d);
// // state.selectAll("rect.bar").each(function (bar, i) {
// // d3.select(this).style("stroke", "none");
// // });
// // d3.select(this).style("stroke", "black");
// // d3.select(this).style("stroke-width", 3);
// // _display_module_nicho.loadDecilDataTable(d.decil, d.name, false, [], []);
// });
// CREACION DE LEYENDA INFERIOR DEL HISTOGRAMA
var tip_legend = addTooltipBarRectLegend(svg)
var yTextPadding = -5;
state.selectAll(".rect")
.data(function (d) {
return d.value;
})
.enter()
.append("text")
.style("font-size", "8px")
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("x", function (d) {
return x1(d.name) + 10;
})
.attr("y", function (d) {
if (d.decil_nulo)
return y(0) + yTextPadding;
// locate the bars in the chart correctly when there are negative values.
if (NEG_DECIL === -1) {
return y(totalmax_avg) + yTextPadding;
}
else if (NEG_DECIL === 0) {
return y(Math.max(0, parseFloat(d.avg))) + yTextPadding;
}
else {
return y(parseFloat(d.avg)) + yTextPadding;
}
})
.text(function (d) {
// console.log(d);
// if( parseFloat(d.value.p) == 0.0)
// return "";
// else
return parseFloat(d.avg);
});
var legend = svg.selectAll(".legend")
.data(ageNames.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d) {
return "translate(0," + (height + 20) + ")";
});
// var hoverColor= "#0000ff";
legend.append("rect")
.attr("x", function (d, i) {
return (width - 18) - (i * 130);
})
.attr("class", "rect_legend")
.attr("y", 3)
.attr("width", 20)
.attr("height", 20)
.style("fill", function (d, i) {
return color(d);
})
.style("opacity", 0.7)
.on("click",function(d,i) {
d3.selectAll(".rect_legend")
.each(function(d){
d3.select(this)
.attr("class", "rect_legend")
.style("stroke-width", 0)
})
d3.select(this)
.attr("class", "rect_legend selected")
.style("stroke", "black")
.style("stroke-width", 2)
.style("opacity",0.7)
.style("fill",function (d, i) {
return color(d);
});
})
.on('mouseover', function (d) {
// console.log(d)
// console.log(d3.select(this))
tip_legend.show(d);
d3.select(this)
.style("opacity",0.2)
.style("fill", "#0000ff");
})
.on('mouseout', function (d) {
// console.log(d)
// console.log(d3.select(this))
tip_legend.hide(d);
d3.select(this)
.style("opacity",0.7)
.style("fill",function (d, i) {
return color(d);
});
})
legend.append("text")
.attr("class", "legend")
.attr("x", function (d, i) {
return (width - 24) - (i * 130);
})
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) {
// console.log(d)
return d;
})
// Despliega grafica de resultados de validación
// if ($("#chkValidation").is(':checked')) {
var tip_recall = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
// console.log(d)
var fn_lb, tp_lb, null_lb
if ($("#chkValidation").is(':checked')) {
fn_lb = _iTrans.prop('lb_fn_avg')
tp_lb = _iTrans.prop('lb_vp_avg')
null_lb = _iTrans.prop('lb_nulos_avg')
}
else{
fn_lb = _iTrans.prop('lb_fn')
tp_lb = _iTrans.prop('lb_vp')
null_lb = _iTrans.prop('lb_nulos')
}
recall_values = "<strong>" + _iTrans.prop('lb_recall_avg') + ":</strong> <span >" + parseFloat(d.recall * 100).toFixed(2) + "%</span><br/><br/>" +
"<strong>" + tp_lb + ":</strong> <span >" + parseFloat(d.vp).toFixed(2) + "</span><br/>" +
"<strong>" + fn_lb + ":</strong> <span >" + parseFloat(d.fn).toFixed(2) + "</span><br/>" +
"<strong>" + null_lb + ":</strong> <span >" + parseFloat(d.recall_nulo).toFixed(2) + "</span><br/>"
return recall_values;
});
svg.call(tip_recall);
var y_right = d3.scale.linear()
.range([translate_axis, 0]);
y_right.domain([0, 1]);
var yRightAxis = d3.svg.axis()
.scale(y_right)
.orient("right")
.ticks(5, "%");
// ** si el label cambia, es necesario agregar id **
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + " ,0)")
.call(yRightAxis)
.append("text")
.attr("y", -10)
.attr("x", margin.right - 40)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(_iTrans.prop('lb_recall'));
// obtiene el numero de grupo analizados para generar la colección de elementos para desplegar el calculo de recall
var array_recall = [];
$.each(json_decil, function (index, item) {
var item_recall = [];
$.each(item.deciles, function (index, decil) {
var item_decil = {
"group_name": item.gpo_name,
"recall": decil.recall,
"vp": decil.vp,
"fn": decil.fn,
"decil": decil.decil,
"recall_nulo": decil.nulo
}
item_recall.push(item_decil);
})
array_recall.push(item_recall);
});
// adding recall line
_VERBOSE ? console.log(array_recall) : _VERBOSE;
$.each(array_recall, function (i, recall_item) {
console.log(recall_item);
var line = d3.svg.line()
.x(function (d) {
return x0(d.decil) + (x1.rangeBand() * (ageNames.length / 2));
})
.y(function (d) {
return y_right(d.recall);
});
// console.log(line);
svg.append("path")
.datum(recall_item)
.attr("class", "line")
.attr("d", line)
.style("stroke", function (d) {
// console.log(d);
// console.log("name: " + d[0].group_name);
// console.log("color: " + color(d[0].group_name));
return color(d[0].group_name);
})
svg.selectAll("dot")
.data(recall_item)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function (d, i) {
// return x0(recall_item.length - i) + (x1.rangeBand() * (ageNames.length / 2));
return x0(d.decil) + (x1.rangeBand() * (ageNames.length / 2));
})
.attr("cy", function (d) {
return y_right(d.recall);
})
.on('mouseover', function (d) {
d3.select(this).attr("r", function (d) {
return 8 + Math.pow(d.recall / Math.PI, 0.5);
});
tip_recall.show(d)
})
.on('mouseout', function (d) {
d3.select(this).attr("r", function (d) {
return 3.5;
});
tip_recall.hide(d)
})
.style("stroke", function (d) {
// console.log(d);
// console.log("name: " + d.group_name);
// console.log("color: " + color(d.group_name));
return color(d.group_name);
})
});
// }
}
/**
* Éste método crea el histograma de las ocurrencias que tiene la especie objetivo selecionada en el análisis de nicho ecológico.
*
* @function createBarChartFecha
* @public
*
* @param {array} distinctPoints - Array con las ocurrencias que tiene la especie objetivo selecionada en el análisis de nicho ecológico.
*/
function createBarChartFecha(data) {
var colectas = [];
var reg_sfecha = 0;
var reg_fosil = 0;
$.each(data, function (index, item) {
if (item.aniocolecta === 9999 && item.isfosil === 0) {
reg_sfecha = parseInt(item.occ)
}
else if (item.aniocolecta === 9999 && item.isfosil === 1) {
reg_fosil = parseInt(item.occ)
}
else{
colectas.push({
"fechacolecta": item.aniocolecta,
"cantidad": parseInt(item.occ)
});
}
});
// TODO: DESPLEGAR LEYENDA CON REGISTROS SIN FECHA
// if(colectas_zero.length == 0){
// $("#lb_regfecha").text("0");
// }
// else{
// $("#lb_regfecha").text(colectas_zero[0].cantidad);
// }
var max_fecha = d3.max(colectas.map(function (d) {
return d.fechacolecta;
}));
var min_fecha = d3.min(colectas.map(function (d) {
return d.fechacolecta;
}));
var NUM_BARS = d3.range(1, 21, 1);
var rangofechas = d3.scale.quantize().domain([min_fecha, max_fecha]).range(NUM_BARS);
var rango_fechas = d3.map([]);
$.each(NUM_BARS, function (index, item) {
var rango = parseInt(rangofechas.invertExtent(item)[0]) + " - " + parseInt(rangofechas.invertExtent(item)[1]);
rango_fechas.set(item, {"fechas": rango, "cantidad": 0});
})
$.each(colectas, function (index, item) {
if (rango_fechas.has(rangofechas(item.fechacolecta))) {
var it_temp = rango_fechas.get(rangofechas(item.fechacolecta));
it_temp.cantidad = it_temp.cantidad + item.cantidad;
}
});
var data = rango_fechas.values();
$("#hist_fecha_container").empty();
var margin = {top: 10, right: 10, bottom: 35, left: 30},
width = $("#hist_fecha_container").width() - margin.left - margin.right,
height = $("#hist_fecha_container").height() - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
x.domain(data.map(function (d) {
return d.fechas;
}));
y.domain([0, d3.max(data, function (d) {
return d.cantidad;
})]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
// .ticks(10)
// .tickSize(-width, 0)
.orient("left");
var svg = d3.select("#hist_fecha_container").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 10])
.html(function (d) {
return "<strong>" + _iTrans.prop('hist_occ_fecha') + ":</strong> <span >" + d.fechas + "</span><br/>" +
"<strong>" + _iTrans.prop('hist_occ_registros') + ":</strong> <span >" + d.cantidad + "</span>";
});
svg.call(tip);
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
// .text("Fecha colecta")
.selectAll("text")
.style("font-size", "0px")
svg.append("g")
.attr("class", "yaxis")
.call(yAxis)
// .ticks(5);
// .text("Registros")
.selectAll("text")
.style("font-size", "8px")
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) {
return x(d.fechas);
})
.attr("y", function (d) {
return y(d.cantidad);
})
.attr("height", function (d) {
return height - y(d.cantidad);
})
.attr("width", x.rangeBand())
.on("mouseover", function (d) {
tip.show(d);
})
.on("mouseout", function (d) {
tip.hide(d);
})
svg.append("text")
.attr("id", "hist_record")
.attr("y", 75)
.attr("x", 420)
.attr("dy", ".71em")
.style("font-size", "10px")
.style("text-anchor", "end")
.text(_iTrans.prop('lb_reg_fecha') + ": ");
svg.append("text")
.attr("id", "hist_record_number")
.attr("y", 75)
.attr("x", 440)
.attr("dy", ".71em")
.style("font-size", "10px")
.style("text-anchor", "end")
.text(reg_sfecha);
svg.append("text")
.attr("id", "hist_record_fosil")
.attr("y", 75)
.attr("x", 270)
.attr("dy", ".71em")
.style("font-size", "10px")
.style("text-anchor", "end")
// .text(_iTrans.prop('lb_reg_fecha') + ": ");
.text("fosiles: ");
svg.append("text")
.attr("id", "hist_record_number_fosil")
.attr("y", 75)
.attr("x", 290)
.attr("dy", ".71em")
.style("font-size", "10px")
.style("text-anchor", "end")
.text(reg_fosil);
}
/**
* Crea los histogramas de épsilon especie, score especie y score celda en el análisis de nicho ecológico.
*
* @function createBarChart
* @public
*
* @param {String} idComponent - Id del contenedor del histograma
* @param {array} data - Array con los resultados del histograma por especie y por celda en el análisis de nicho ecológico
* @param {String} f_legend - Título del histograma
*/
function createBarChart(idComponent, data, f_legend) {
_VERBOSE ? console.log("createBarChart") : _VERBOSE;
$("#" + idComponent.id).empty();
// _VERBOSE ? console.log($(window).width()) : _VERBOSE;
// _VERBOSE ? console.log($(".myScrollableBlockEpsilon").height()) : _VERBOSE;
var margin = {top: 40, right: 40, bottom: 80, left: 40},
width = $(".myScrollableBlockEpsilonSmallHist").width() - margin.left - margin.right,
height = $(".myScrollableBlockEpsilonSmallHist").height() - margin.top - margin.bottom;
// _VERBOSE ? console.log(width) : _VERBOSE;
// _VERBOSE ? console.log(height) : _VERBOSE;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
// .ticks(5);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10, "%");
var svg = d3.select("#" + idComponent.id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("text")
.attr("id", idComponent.legend)
.attr("y", -22)
.attr("x", width / 2 + 60)
.attr("dy", ".71em")
.style("font-size", "20px")
.style("text-anchor", "end")
.text(f_legend);
// svg.append("rect")
// .attr("y", -22)
// .attr("x", width/2 + 70)
// .attr("width", "20px")
// .attr("height", "20px")
// .attr("fill", "#3B6A93")
// .append("title")
// .text("test")
// .style("margin-left", "20px")
// svg.append("text")
// .attr("y", -8)
// .attr("x", width/2 + 77)
// .style("fontColor","white")
// .style("fontWeight","bold")
// .text("?")
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
return "<strong>" + _iTrans.prop('lb_rango') + ":</strong> <span >" + d.title + "</span><br/><br/>" +
"<strong>" + _iTrans.prop('lb_frecuencia') + ":</strong> <span >" + parseInt(d.frequency * 100) + " %</span>";
});
svg.call(tip);
x.domain(data.map(function (d) {
return d.bcenter;
}));
max_freq = d3.max(data.map(function (d) {
return parseFloat(d.frequency);
}));
// _VERBOSE ? console.log(max_freq) : _VERBOSE;
y.domain([0, max_freq]);
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("id", idComponent.xaxis)
.style("text-anchor", "end")
.style("font-size", "10px")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", function (d) {
return "rotate(-90)"
});
// .append("text")
// .attr("y", margin.bottom-10)
// .attr("x", width/2)
// .attr("dy", ".71em")
// .style("text-anchor", "end")
// .text(legend);
svg.append("g")
.attr("class", "yaxis")
.call(yAxis)
.append("text")
.attr("id", idComponent.yaxis)
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(_iTrans.prop('lb_frecuencia'));
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) {
return x(d.bcenter);
})
.attr("width", x.rangeBand())
.attr("y", function (d) {
return y(parseFloat(d.frequency));
})
.attr("height", function (d) {
return height - y(parseFloat(d.frequency));
})
.on('mouseover', function (d) {
tip.show(d)
})
.on('mouseout', function (d) {
tip.hide(d)
})
}
/**
* Genera colores aleatorios para asignarlo al histograma de decil en el análisis de nicho ecológico.
*
* @function _randomColor
* @public
*
*/
var _randomColor = (function () {
var golden_ratio_conjugate = 0.618033988749895;
var h = Math.random();
var hslToRgb = function (h, s, l) {
var r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
function hue2rgb(p, q, t) {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6)
return p + (q - p) * 6 * t;
if (t < 1 / 2)
return q;
if (t < 2 / 3)
return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return '#' + Math.round(r * 255).toString(16) + Math.round(g * 255).toString(16) + Math.round(b * 255).toString(16);
};
return function () {
h += golden_ratio_conjugate;
h %= 1;
return hslToRgb(h, 0.5, 0.60);
};
})();
/**
* Retorna un objeto de tipo Chart para generar el histograma en el anáisis de comunidad ecológica.
*
* @function createBarChartNet
* @public
*
* @param {json} json - Json que contiene los nodos y los enlaces resultado del análisis de communidad ecológica
* @param {object} display_obj - Referencia al controlador de comunidad ecológica
*/
function createBarChartNet(json, display_obj) {
_VERBOSE ? console.log("createBarChartNet") : _VERBOSE;
var chart_array = [
BarChart(json, display_obj)
.group(display_obj.group_eps_freq)
.x(display_obj.x)
];
// agrega listner cuando el brushend es ejecutado para mandar llamar las funciones de la red y la tabla
var chart_component = d3.selectAll(".chart")
.data(chart_array)
.each(function (chart) {
// chart.on("brushend", display_obj.renderAll);
})
$("#lb_body_info").text(_iTrans.prop('lb_msg_hist_epsilon'));
$('#lb_header_info').text(_iTrans.prop('titulo_hist_eps'));
return chart_component;
}
/**
* Clase tipo Chart para generar instacias que tienen interacción con el módulo de red.
*
* @function BarChart
* @public
*
* @param {json} json - Json que contiene los nodos y los enlaces resultado del análisis de communidad ecológica
* @param {object} display_obj - Referencia al controlador de comunidad ecológica
*/
function BarChart(json, display_obj) {
_VERBOSE ? console.log("BarChart") : _VERBOSE;
_VERBOSE ? console.log(json) : _VERBOSE;
// _VERBOSE ? console.log(display_obj.dim_eps_freq.top(Infinity)) : _VERBOSE;
var margin = {top: 5, right: 20, bottom: 85, left: 20};
var width = $("#hist").width() - margin.left - margin.right;
var height = $("#hist").height() - margin.top - margin.bottom;
var min_eps = display_obj.hist_min_eps
var max_eps = display_obj.hist_max_eps
var num_links = display_obj.num_links
// var max_value, min_value, step
var lim_izq, lim_der
var id_selected = $('input[type="radio"]:checked')[0].id;
console.log(id_selected);
$("#ep_izq").val(0)
$("#ep_der").val(0)
$("#ari_izq").val(0)
$("#ari_der").val(0)
$("#arip_izq").val(0)
$("#arip_der").val(0)
// min_value = min_eps
// max_value = max_eps
// step = 0.01
// console.log("min_value: " + min_value)
// console.log("max_value: " + max_value)
// console.log("step: " + step)
// $( "#sliderFecha" ).slider( "enable" );
// $( "#sliderFecha" ).slider( "option", "min", min_value );
// $( "#sliderFecha" ).slider( "option", "max", max_value );
// $( "#sliderFecha" ).slider( "option", "values", [min_value,max_value] );
// $( "#sliderFecha" ).slider( "option", "step", step );
// $( "#sliderFecha" ).on( "slidechange", function( event, ui ) {
// console.log("change slider")
// id_selected = $('input[type="radio"]:checked')[0].id;
// // console.log(id_selected);
// lim_izq = ui.values[0]
// lim_der = ui.values[1]
// $("#ep_izq").val(lim_izq)
// $("#ep_der").val(lim_der)
// var aizq = 0
// var ader = 0
// json.links.forEach(function (item){
// var item_eps = parseFloat(item.value)
// if(item_eps < lim_izq && item_eps > min_eps)
// aizq++
// if(item_eps > lim_der && item_eps < max_eps)
// ader++
// })
// $("#ari_izq").val(aizq)
// $("#ari_der").val(ader)
// $("#arip_izq").val(parseFloat(aizq/num_links*100).toFixed(2))
// $("#arip_der").val(parseFloat(ader/num_links*100).toFixed(2))
// })
$("#ep_izq").on("change", function(e){
console.log("cahnge izq")
if($("#ep_izq").is(":valid")){
console.log("valido izq")
var value = $("#ep_izq").val()
var aizq = 0
console.log("value: " + value)
// el valor metido no puede ser mayor al número de links totales
if(parseFloat(value) < min_eps){
value = min_eps;
$("#ep_izq").val(value);
_toast_module.warning(_iTrans.prop('emin_link_value',value));
}
display_obj.links.forEach(function (item){
var item_eps = parseFloat(item.value)
if(item_eps < value && item_eps > min_eps)
aizq++
})
$("#ari_izq").val(aizq)
$("#arip_izq").val(parseFloat(aizq/num_links*100).toFixed(2))
if(display_obj.hist_min_eps > value){
value = display_obj.hist_min_eps
$("#ep_izq").val(value)
}
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#ep_der").on("change", function(e){
console.log("cahnge izq2")
if($("#ep_der").is(":valid")){
var value = $("#ep_der").val()
var ader = 0
console.log("value: " + value)
// el valor metido no puede ser mayor al número de links totales
if(parseFloat(value) > max_eps){
value = max_eps;
$("#ep_der").val(value);
_toast_module.warning(_iTrans.prop('emax_link_value',value));
}
display_obj.links.forEach(function (item){
var item_eps = parseFloat(item.value)
if(item_eps > value && item_eps < max_eps)
ader++
})
$("#ari_der").val(ader)
$("#arip_der").val(parseFloat(ader/num_links*100).toFixed(2))
if( value > display_obj.hist_max_eps){
value = display_obj.hist_max_eps
$("#ep_der").val(value)
}
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#ari_izq").on("change", function(e){
if($("#ari_izq").is(":valid")){
var value = $("#ari_izq").val()
var value_der = $("#ari_der").val()
console.log("value: " + value)
console.log("value_der: " + value_der)
// el valor metido no puede ser mayor al número de links totales
if((parseFloat(value) + parseFloat(value_der)) > num_links){
value = num_links-value_der;
$("#ari_izq").val(value);
_toast_module.warning(_iTrans.prop('max_link_value',value));
}
// el valor insertado es cero,
else if(parseFloat(value) === 0){
$("#ep_izq").val(min_eps)
$("#arip_izq").val(0)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
return
}
$("#arip_izq").val(parseFloat(value/num_links*100).toFixed(2))
var eps_izq = 0
var count_izq = 0
// ordenando de forma creciente
var links_temp = jQuery.extend(true, [], display_obj.links);
// console.log(links_temp)
links_temp.sort(function(a, b) {
return parseFloat(a.value) - parseFloat(b.value);
});
for(var i = 0; i<links_temp.length; i++){
var item = links_temp[i];
count_izq++
if(count_izq == value){
eps_izq = item.value
break
}
}
$("#ep_izq").val(eps_izq)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#ari_der").on("change", function(e){
if($("#ari_der").is(":valid")){
var value = $("#ari_der").val()
var value_izq = $("#ari_izq").val()
console.log("value: " + value)
console.log("value_izq: " + value_izq)
// el valor metido no puede ser mayor al número de links totales
if((parseFloat(value) + parseFloat(value_izq)) > num_links){
value = num_links-value_izq;
$("#ari_der").val(value);
_toast_module.warning(_iTrans.prop('max_link_value',value));
}
// el valor insertado es cero,
else if(parseFloat(value) === 0){
$("#ep_der").val(max_eps)
$("#arip_der").val(0)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
return
}
var porcentaje = value/num_links*100;
// console.log("porcentaje: " + porcentaje)
$("#arip_der").val(parseFloat(porcentaje).toFixed(2))
var eps_der = 0
var count_der = 0
// ordenando de forma creciente
var links_temp = jQuery.extend(true, [], display_obj.links);
// console.log(links_temp)
links_temp.sort(function(a, b) {
return parseFloat(b.value) - parseFloat(a.value);
});
for(var i = 0; i<links_temp.length; i++){
var item = links_temp[i];
count_der++
if(count_der == value){
eps_der = item.value
break
}
}
$("#ep_der").val(eps_der)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#arip_izq").on("change", function(e){
if($("#arip_izq").is(":valid")){
var maxpercetage = 100
var value = parseFloat($("#arip_izq").val())
var value_der = $("#arip_der").val()
console.log("value: " + value)
console.log("value_der: " + value_der)
// el valor metido no puede ser mayor al número de links totales
if((parseFloat(value) + parseFloat(value_der)) > maxpercetage){
value = maxpercetage-value_der;
$("#arip_izq").val(value);
_toast_module.warning(_iTrans.prop('maxp_link_value',value));
}
// el valor insertado es cero,
else if(value === 0){
$("#ep_izq").val(min_eps)
$("#ari_izq").val(0)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
return
}
var aizq = parseInt(num_links*value/100)
$("#ari_izq").val(aizq)
var eps_izq = 0
var count_izq = 0
// ordenando de forma creciente
var links_temp = jQuery.extend(true, [], display_obj.links);
// console.log(links_temp)
links_temp.sort(function(a, b) {
return parseFloat(a.value) - parseFloat(b.value);
});
for(var i = 0; i<links_temp.length; i++){
var item = links_temp[i];
count_izq++
if(count_izq == aizq){
eps_izq = item.value
break
}
}
$("#ep_izq").val(eps_izq)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#arip_der").on("change", function(e){
if($("#arip_der").is(":valid")){
var maxpercetage = 100
var value = parseFloat($("#arip_der").val())
var value_izq = $("#arip_izq").val()
console.log("value: " + value)
console.log("value_izq: " + value_izq)
// el valor metido no puede ser mayor al número de links totales
if((parseFloat(value) + parseFloat(value_izq)) > maxpercetage){
value = maxpercetage-value_izq;
$("#arip_der").val(value);
_toast_module.warning(_iTrans.prop('maxp_link_value',value));
}
// el valor insertado es cero,
else if(value === 0){
$("#ep_der").val(max_eps)
$("#ari_der").val(0)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
return
}
var ader = parseInt(num_links*value/100)
$("#ari_der").val(ader)
var eps_der = 0
var count_der = 0
// ordenando de forma creciente
var links_temp = jQuery.extend(true, [], display_obj.links);
// console.log(links_temp)
links_temp.sort(function(a, b) {
return parseFloat(b.value) - parseFloat(a.value);
});
for(var i = 0; i<links_temp.length; i++){
var item = links_temp[i];
count_der++
if(count_der == ader){
eps_der = item.value
break
}
}
$("#ep_der").val(eps_der)
chart.drawBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
}
})
$("#update-hist").click(function(){
console.log("click");
module_net.loadingsNet(1);
chart.filterBrush(parseFloat($("#ep_izq").val()), parseFloat($("#ep_der").val()))
module_net.loadingsNet(0);
})
if (!BarChart.id)
BarChart.id = 0;
var y = d3.scale.linear()
.range([height, 0]);
// .domain([0, max_eps]);
var x = d3.scale.ordinal()
.rangeRoundBands([margin.left, width - margin.left], .1);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5, "%");
var id = BarChart.id++,
brush = d3.svg.brush(),
brushDirty, dimension, group, round;
//margin = {top: 10, right: 10, bottom: 20, left: 10}
var brushStart = 0;
var brushEnd = display_obj.NUM_BEANS - 1;
function chart(div) {
_VERBOSE ? console.log(div) : _VERBOSE;
height = y.range()[0];
data = group.all();
// _VERBOSE ? console.log(data) : _VERBOSE;
// it contains an array from 1 to 20, create key missing elements and set value to 0
display_obj.epsilon_beans.forEach(function (d) {
exists = false;
$.each(data, function (index, value) {
if (d == value.key) {
exists = true;
return false;
}
});
if (exists == false) {
data.push({key: parseInt(d), value: 0});
}
});
// Sort by key high to low
data.sort(_sort_by('key', false, parseInt));
_VERBOSE ? console.log(data) : _VERBOSE;
$.each(data, function (index, value) {
tvalue = value.value;
if (tvalue != 0)
value.value = tvalue / all.reduceCount().value();
});
// _VERBOSE ? console.log(display_obj.epsRange) : _VERBOSE;
// _VERBOSE ? console.log(epsRange) : _VERBOSE;
x.domain(data.map(function (d) {
avg = parseFloat((display_obj.epsRange.invertExtent(d.key)[0] + display_obj.epsRange.invertExtent(d.key)[1]) / 2).toFixed(2);
return avg;
}));
y.domain([0, group.top(1)[0].value]);
div.each(function () {
_VERBOSE ? console.log("div.each chart") : _VERBOSE;
var div = d3.select(this),
g = div.select("g");
// Create the skeletal chart.
if (g.empty()) {
_VERBOSE ? console.log("g.empty") : _VERBOSE;
g = div.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// legend
g.append("text")
.attr("id", "title_barnet")
.attr("y", height + 40)
.attr("x", width / 2 + 60)
.attr("dy", ".71em")
.style("font-size", "12px")
.style("text-anchor", "end")
.text(_iTrans.prop('titulo_hist_eps'));
g.append("clipPath")
.attr("id", "clip-" + id)
.append("rect")
.attr("width", width)
.attr("height", height);
g.selectAll(".foreground.bar")
.attr("clip-path", "url(#clip-" + id + ")");
// **** Axis
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.style("font-size", "10px")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", function (d) {
return "rotate(-90)"
});
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("id", 'yaxis_net')
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(_iTrans.prop('lb_frecuencia'));
// ** Adding bars
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) {
// _VERBOSE ? console.log(d) : _VERBOSE;
// _VERBOSE ? console.log( display_obj.epsRange.invertExtent(d.key)[0] ) : _VERBOSE;
// _VERBOSE ? console.log( display_obj.epsRange.invertExtent(d.key)[1] ) : _VERBOSE;
// _VERBOSE ? console.log( x(display_obj.epsRange.invertExtent(d.key)[0]) ) : _VERBOSE;
// _VERBOSE ? console.log( x(display_obj.epsRange.invertExtent(d.key)[1]) ) : _VERBOSE;
// _VERBOSE ? console.log( display_obj.epsRange(2.23) ) : _VERBOSE;
// _VERBOSE ? console.log( display_obj.epsRange(7.08) ) : _VERBOSE;
return x(parseFloat((display_obj.epsRange.invertExtent(d.key)[0] + display_obj.epsRange.invertExtent(d.key)[1]) / 2).toFixed(2));
})
.attr("width", x.rangeBand())
.attr("y", function (d) {
return y(parseFloat(d.value));
})
.attr("height", function (d) {
return height - y(parseFloat(d.value));
})
.attr("fill", function (d) {
left = display_obj.epsRange.invertExtent(d.key)[0]
right = display_obj.epsRange.invertExtent(d.key)[1]
// console.log("left: " + left)
// console.log("right: " + right)
if (left <= 0 && right > 0)
min_val = 0;
else {
min_val = Math.min(Math.abs(left), Math.abs(right));
}
if (display_obj.ep_th < min_val) {
// return d3.rgb(102, 184, 243);
return d3.rgb(36, 149, 229);
} else {
return d3.rgb(213, 215, 223);
}
});
// **** Initialize the brush component with pretty resize handles.
var gBrush = g.append("g")
.attr("class", "brush")
.call(brush);
gBrush.selectAll("rect")
.attr("height", height);
gBrush.selectAll(".resize")
.append("path")
.attr("d", resizePath);
// ***** agregando leyenda
var nosig = display_obj.no_mean
var legend = g.selectAll(".legend")
// .data(["Descartado", "Visualizado", "Filtrado"])
.attr("id", "legend_hist_net")
.data([_iTrans.prop('lb_hist_net_descartados'), _iTrans.prop('lb_hist_net_visualizados'), _iTrans.prop('lb_hist_net_nosginificativo')+": " + nosig])
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d) {
return "translate(0," + (height + 60) + ")";
});
legend.append("rect")
.attr("x", function (d, i) {
return (width - 50) - (i * 130);
})
.attr("y", 3)
.attr("width", 20)
.attr("height", 20)
.style("fill", function (d, i) {
if(i==0)
// return d3.rgb(213, 215, 223);
return "#d3e9fa"
if(i==1)
return d3.rgb(36, 149, 229);
if(i==2)
return "#fff";
})
// .style("stroke", function(d,i){
// if(i==2)
// return "#000";
// })
// .style("opacity", 0.7);
legend.append("text")
.attr("x", function(d, i) {
if(i==0)
return (width - 60) - (i * 120);
if(i==1)
return (width - 70) - (i * 120);
return (width - 40) - (i * 120);
})
.attr("y", 15)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) {
return d
});
// Segmento de código para costruir el sombreado del histograma y sus parametros al lanzar un nuevo análisis
var eps_izq = parseFloat(display_obj.hist_min_eps)
var eps_der = parseFloat(display_obj.net_limit_eps)
chart.drawBrush(eps_izq, eps_der)
$("#ep_izq").val(eps_izq)
$("#ep_der").val(eps_der)
var aizq = 0
var ader = 0
display_obj.links.forEach(function (item){
var item_eps = parseFloat(item.value)
if(item_eps < eps_izq && item_eps > display_obj.hist_min_eps)
aizq++
if(item_eps > eps_der && item_eps < display_obj.hist_max_eps)
ader++
})
$("#ari_izq").val(aizq)
$("#ari_der").val(ader)
$("#arip_izq").val(parseFloat(aizq/num_links*100).toFixed(2))
$("#arip_der").val(parseFloat(ader/num_links*100).toFixed(2))
}
});
function resizePath(d) {
_VERBOSE ? console.log("resizePath") : _VERBOSE;
// configure the values of the extent component, clips and shadow selection
var e = +(d == "e"),
x = e ? 1 : -1,
y = height / 3;
return "M" + (.5 * x) + "," + y
+ "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6)
+ "V" + (2 * y - 6)
+ "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y)
+ "Z"
+ "M" + (2.5 * x) + "," + (y + 8)
+ "V" + (2 * y - 8)
+ "M" + (4.5 * x) + "," + (y + 8)
+ "V" + (2 * y - 8);
}
} // function chart(div) closed
// funcion que realiza el filtrado de valores despues de la interacción con el histograma
brush.on("brush.chart", function (e) {
_VERBOSE ? console.log("brush.chart") : _VERBOSE;
// desactiva el bloqueo del número de enlaces a desplegar
display_obj.hist_load = true
var y = d3.scale.linear()
.domain([margin.left, width - margin.left])
.range([0, display_obj.NUM_BEANS]);
b = brush.extent();
// _VERBOSE ? console.log(b) : _VERBOSE;
var localBrushStart = (brush.empty()) ? brushStart : y(b[0]),
localBrushEnd = (brush.empty()) ? brushEnd : y(b[1]);
// Snap to rect edge
d3.select("g.brush").call((brush.empty()) ? brush.clear() : brush.extent([y.invert(localBrushStart), y.invert(localBrushEnd)]));
// Fade all years in the histogram not within the brush
d3.selectAll("rect.bar").style("opacity", function (d, i) {
// _VERBOSE ? console.log(d.key) : _VERBOSE;
if (d.key < localBrushStart || d.key >= localBrushEnd || brush.empty()) {
return "1";
} else {
return "0.4";
}
});
// dimension.filterRange([localBrushStart,localBrushEnd]);
});
brush.on("brushend.chart", function () {
_VERBOSE ? console.log("brushend.chart") : _VERBOSE;
// Realiza la conversión de la selección a los valores de epsilon y calcula valores para los controles del histograma
var y_brush = d3.scale.linear()
.domain([margin.left, width - margin.left])
.range([display_obj.hist_min_eps, display_obj.hist_max_eps]);
// console.log(brush.extent())
// console.log([margin.left, width - margin.left])
// console.log(brush.extent()[0])
// console.log(brush.extent()[1])
// console.log(localBrushEnd)
// console.log(y_brush(brush.extent()[0]))
var eps_izq = 0
var eps_der = 0
if(brush.extent()[0] == brush.extent()[1]){
$("#ep_izq").val(0)
$("#ep_der").val(0)
$("#ari_izq").val(0)
$("#ari_der").val(0)
$("#arip_izq").val(0)
$("#arip_der").val(0)
}
else{
var eps_izq = parseFloat(y_brush(brush.extent()[0])).toFixed(2)
var eps_der = parseFloat(y_brush(brush.extent()[1])).toFixed(2)
$("#ep_izq").val(eps_izq)
$("#ep_der").val(eps_der)
var aizq = 0
var ader = 0
display_obj.links.forEach(function (item){
var item_eps = parseFloat(item.value)
if(item_eps < eps_izq && item_eps > display_obj.hist_min_eps)
aizq++
if(item_eps > eps_der && item_eps < display_obj.hist_max_eps)
ader++
})
$("#ari_izq").val(aizq)
$("#ari_der").val(ader)
$("#arip_izq").val(parseFloat(aizq/num_links*100).toFixed(2))
$("#arip_der").val(parseFloat(ader/num_links*100).toFixed(2))
}
// Asigna opacidad a las barras alcanzadas por el arrastre del brush
var y = d3.scale.linear()
.domain([margin.left, width - margin.left])
.range([0, display_obj.NUM_BEANS]);
b = brush.extent();
var localBrushStart = (brush.empty()) ? brushStart : y(b[0]),
localBrushEnd = (brush.empty()) ? brushEnd : y(b[1]);
d3.select("g.brush").call((brush.empty()) ? brush.clear() : brush.extent([y.invert(localBrushStart), y.invert(localBrushEnd)]));
// Asigna opacidad a las barras alzanzadas por la extensión del brush
if (brush.empty()) {
// dim_eps_freq.filterAll();
d3.selectAll("rect.bar").style("opacity", function (d, i) {
return "1";
});
} else {
if (d3.round(localBrushStart, 0) == 0)
left_extent = 1
else
left_extent = d3.round(localBrushStart, 0)
if (d3.round(localBrushEnd, 0) == 21)
rigth_extent = 20
else
rigth_extent = d3.round(localBrushEnd, 0)
// No esta dando los valores correctos!!!
_VERBOSE ? console.log(display_obj.epsRange.invertExtent(left_extent)[0]) : _VERBOSE;
_VERBOSE ? console.log(display_obj.epsRange.invertExtent(rigth_extent)[1]) : _VERBOSE;
// Activa el filtrado de la red
// display_obj.dim_eps_freq.filterFunction(function (d) {
// // if (d > display_obj.epsRange.invertExtent(left_extent)[0] && d < display_obj.epsRange.invertExtent(rigth_extent)[1] + 0.1){
// // if (d > display_obj.epsRange.invertExtent(left_extent)[0] && d < display_obj.epsRange.invertExtent(rigth_extent)[1] ){
// // COMMENT 19/08/19: Se invierte filtrado, ahora los valores que estan fuera de rango del brush son visualizados
// if (d < display_obj.epsRange.invertExtent(left_extent)[0] || d > display_obj.epsRange.invertExtent(rigth_extent)[1] ){
// // _VERBOSE ? console.log(d) : _VERBOSE;
// return true;
// }
// });
// Fade all years in the histogram not within the brush
d3.selectAll("rect.bar").style("opacity", function (d, i) {
if (d.key < localBrushStart || d.key > localBrushEnd) {
return "1";
} else {
return "0.4";
}
});
}
// d3.event.sourceEvent.stopPropagation();
});
// genera brush con los datos recibidos
chart.drawBrush = function(lim_izq, lim_der) {
console.log("chart.drawBrush")
// var id_selected = $('input[type="radio"]:checked')[0].id;
console.log(lim_izq);
console.log(lim_der);
d3.selectAll("rect.bar").style("opacity", function (d, i) {
return "1";
});
// como pasar del epsilon al width real del brush
var y = d3.scale.linear()
.domain([margin.left, width - margin.left])
.range([display_obj.hist_min_eps, display_obj.hist_max_eps]);
// console.log("y.invert: " + y.invert(lim_izq))
// console.log("y.invert: " + y.invert(lim_der))
brush.extent([y.invert(lim_izq), y.invert(lim_der)])
brush(d3.select(".brush").transition());
}
chart.filterBrush = function(lim_izq, lim_der) {
console.log("chart.filterBrush")
// var id_selected = $('input[type="radio"]:checked')[0].id;
console.log(lim_izq);
console.log(lim_der);
d3.selectAll("rect.bar").style("opacity", function (d, i) {
return "1";
});
// como pasar del epsilon al width real del brush
var y = d3.scale.linear()
.domain([margin.left, width - margin.left])
.range([display_obj.hist_min_eps, display_obj.hist_max_eps]);
// console.log("y.invert: " + y.invert(lim_izq))
// console.log("y.invert: " + y.invert(lim_der))
brush.extent([y.invert(lim_izq), y.invert(lim_der)])
brush(d3.select(".brush").transition());
// console.log(lim_izq)
// console.log(lim_der)
display_obj.dim_eps_freq.filterFunction(function (d) {
// _VERBOSE ? console.log(d) : _VERBOSE;
// COMMENT 19/08/19: Se invierte filtrado, ahora los valores que estan fuera de rango del brush son visualizados
if (d < lim_izq || d > lim_der ){
// _VERBOSE ? console.log(d) : _VERBOSE;
return true;
}
});
display_obj.renderAll()
// brush.event(d3.select(".brush").transition().delay(1000));
}
chart.margin = function (_) {
_VERBOSE ? console.log("chart.margin") : _VERBOSE;
if (!arguments.length)
return margin;
margin = _;
return chart;
};
chart.x = function (_) {
_VERBOSE ? console.log("chart.x") : _VERBOSE;
if (!arguments.length)
return x;
x = _;
xAxis.scale(x);
brush.x(x);
return chart;
};
chart.y = function (_) {
_VERBOSE ? console.log("chart.y") : _VERBOSE;
if (!arguments.length)
return y;
y = _;
return chart;
};
chart.dimension = function (_) {
_VERBOSE ? console.log("chart.dimension") : _VERBOSE;
// _VERBOSE ? console.log(_) : _VERBOSE;
if (!arguments.length)
return dimension;
dimension = _;
return chart;
};
chart.filter = function (_) {
_VERBOSE ? console.log("chart.filter") : _VERBOSE;
if (_) {
brush.extent(_);
dimension.filterRange(_);
} else {
brush.clear();
dimension.filterAll();
}
brushDirty = true;
return chart;
};
chart.group = function (_) {
_VERBOSE ? console.log("chart.group") : _VERBOSE;
// _VERBOSE ? console.log(_) : _VERBOSE;
if (!arguments.length)
return group;
group = _;
return chart;
};
chart.round = function (_) {
_VERBOSE ? console.log("chart.round") : _VERBOSE;
if (!arguments.length)
return round;
round = _;
return chart;
};
return d3.rebind(chart, brush, "on");
}
/**
* Realiza el ordenamiento de un objeto tipo Json por un atributo específico.
*
* @function _sort_by
* @public
*
* @param {String} field - Nombre del parámetro para hacer el ordenamiento
* @param {boolean} reverse - Bandera para hacer el ordenameinto descendiente o ascendente
* @param {function} primer - Función para realizar el ordenamiento
*/
function _sort_by(field, reverse, primer) {
var key = primer ?
function (x) {
return primer(x[field])
} :
function (x) {
return x[field]
};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
}
}
/**
* Función que inicializa las variables necesarias para la creación de histogramas.
*
* @function startHistogramModule
* @public
*
*/
function startHistogramModule() {
_VERBOSE ? console.log("startHistogramModule") : _VERBOSE;
_initilizeHistogram();
}
// Añadir los miembros públicos
return{
startHistogramModule: startHistogramModule,
createMultipleBarChart: createMultipleBarChart,
setTableModule: setTableModule,
setLanguageModule: setLanguageModule,
// updateLabels: updateLabels,
createBarChart: createBarChart,
createBarChartNet: createBarChartNet,
createBarChartFecha: createBarChartFecha,
setDisplayModule: setDisplayModule,
setToastModule: setToastModule
}
});