/**
* Módulo red, utilizado crear y gestionar la red que es generada del resultado del analísis de comunidad ecológica.
*
* @module module_net
*/
var net_module = (function(verbose, url_zacatuche, map_module_net, utils_module, display_module) {
var _url_zacatuche = url_zacatuche;
var _map_module_net = map_module_net;
var _utils_module = utils_module
var _display_module = display_module
console.log(_display_module)
var _VERBOSE = verbose;
var _UMBRAL = 0.2;
var _toastr = toastr;
var iTrans;
var _language_module_net;
var _linkedByIndex = {};
var _color = d3.scale.category10();
var _highlight_color = "#B4FC00"; //"red"; //"#48D7D5";
var _highlight_linked_color = "#04C4FE"; //"red"; //"#48D7D5";
var _map_conected = d3.map([]);
var _legend_groups = [];
var _nodes_selected;
var _nodes;
var _analisis_level_selected_fuente
var _analisis_level_selected_sumidero
/**
* 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_net = languageModule;
_iTrans = _language_module_net.getI18();
}
function setUtilsModulo(languageModule) {
_language_module_net = languageModule;
_iTrans = _language_module_net.getI18();
}
function setRankValues(fuente, sumidero) {
_analisis_level_selected_fuente = fuente
_analisis_level_selected_sumidero = sumidero
}
/**
* Método setter de las las leyendas de los grupos de variables.
*
* @function setLegendGroup
* @public
*
* @param {array} legend_groups - Array con las leyendas de los grupos de variables seleccioandos en el analísis de comunidad ecológica.
*/
function setLegendGroup(legend_groups) {
_legend_groups = legend_groups;
}
/**
* Éste método inicializa variables y componentes que son necesarios para la creación de la red y asigna a una variable global una instancia del módulo de lenguaje.
*
* @function _netConfigure
* @private
*
* @param {object} languageModule - Módulo de internacionalización
* @param {type} s_filters - Array con los grupos de variables source utlizados en el analísis de comunidad ecológica.
* @param {type} t_filters - Array con los grupos de variables target utlizados en el analísis de comunidad ecológica.
*/
function _netConfigure(language_module, s_filters, t_filters) {
_VERBOSE ? console.log("_netConfigure") : _VERBOSE;
_toastr.options = {
"debug": false,
"onclick": null,
"fadeIn": 300,
"fadeOut": 1000,
"timeOut": 2000,
"extendedTimeOut": 2000,
"positionClass": "toast-bottom-center",
"preventDuplicates": true,
"progressBar": true
};
//TODO: ajustar a nueva estructura
$("#send_email").click(function(e) {
// _VERBOSE ? console.log($("#email_address")) : _VERBOSE;
_VERBOSE ? console.log($("#email_address")[0].validity["valid"]) : _VERBOSE;
if ($("#email_address")[0].validity["valid"]) {
email = $("#email_address").val();
milliseconds = new Date().getTime();
// d3.json(_url_trabajo + "t=" + milliseconds)
d3.json(_url_zacatuche + "t=" + milliseconds)
.header("Content-Type", "application/json")
.post(
JSON.stringify({
qtype: "getEdges",
download: true,
mail: email,
s_tfilters: s_filters,
t_tfilters: t_filters,
ep_th: 0.0
}),
function(error, d) {
$('#modalMail').modal('hide');
if (error) {
_VERBOSE ? console.log(error) : _VERBOSE;
toastr.error("Error al enviar el archivo");
throw error;
}
// _VERBOSE ? console.log(d) : _VERBOSE;
_toastr.success("Archivo enviado por correo electrónico");
});
}
else {
alert("Correo invalido")
}
});
_language_module_net = language_module;
_iTrans = _language_module_net.getI18();
}
/**
* Éste método genera una instancia de la red.
*
* @function createNet
* @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 createNet(json, display_obj) {
_VERBOSE ? console.log("createNet") : _VERBOSE;
console.log(json);
// si se desa agregar mas de una red añadir aqui
var graph_array = [
EpsilonGraph(json, display_obj).group(display_obj.group_eps_spname)
];
var graph_component = d3.selectAll(".graph")
.data(graph_array)
.each(function(graph) {
// _VERBOSE ? console.log(display_obj.renderAll) : _VERBOSE;
graph.on("brushend", display_obj.renderAll);
});
return graph_component;
}
/**
* Clase que genera instancias de tipo red así como interacción con el módulo de histograma y el modulo de tabla a través del controlador de comunidad ecológica.
*
* @function EpsilonGraph
* @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 EpsilonGraph(json, display_obj) {
_VERBOSE ? console.log("EpsilonGraph") : _VERBOSE;
_VERBOSE ? console.log(display_obj) : _VERBOSE;
$("#graph").empty();
$("#graph_controls").empty();
// var focus_node = null, highlight_node = null;
// var highlight_trans = 0.1;
var margin = {top: 5, right: 20, bottom: 30, left: 20};
// var width = $("#hist").width() - margin.left - margin.right;
// var height = $("#hist").height() - margin.top - margin.bottom;
var max_eps = d3.max(json.links, function(d) {
return d.value;
});
var min_eps = d3.min(json.links, function(d) {
return d.value;
});
var link_color = d3.scale.quantize().domain([-max_eps, max_eps]).range(colorbrewer.RdGy[11]);
var shiftKey, ctrlKey;
// var tip;
// var svg_g;
if (!EpsilonGraph.id) {
EpsilonGraph.id = 0;
}
var id = EpsilonGraph.id++,
brusher = d3.svg.brush(),
// xScale = d3.scale.linear().domain([0,width]).range([0,width]),
// yScale = d3.scale.linear().domain([0,height]).range([0, height]),
dimension, group, round;
var width = $("#graph").width(),
height = $("#graph").height(); //height = graphHeight;
var nodeGraph = json;
var xScale = d3.scale.linear().domain([0, width]).range([0, width]);
var yScale = d3.scale.linear().domain([0, height]).range([0, height]);
var force = d3.layout.force()
.size(100, 100)
.charge(-100) // default: -30, carga del nodo, negativos es repulsion, positivos atraccion, 0 desactiva algoritmo
.linkStrength(0.1)
// .gravity(0.05) // default: 0.1, concentra lso puntos en el centro al aumentar su valor, 0 elimina la gravedad hacia le centro del layout
.linkDistance(width / 5)
// .chargeDistance(500) // asigna el maximo valor de carga
// .linkStrength(function(d){
// return rango_eps(d.value);
// }) // establece la rigidez de los enlaces, rango: [0 - 1]
// .friction(0.5)
.size([width, height]);
/*********************** adding the node toolptip to the graph container */
// Define the div for the tooltip
var div_tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
/*********************** main container */
var svg_g = d3.select("#graph")
.attr("tabindex", 1)
// .attr("class", "brush_container")
.on("keydown.brush", keydown)
.on("keyup.brush", keyup)
// .each(function() { this.focus(); })
.append("svg")
.attr("id", "svg_container")
.attr("class", "svg_container")
.attr("width", "100%")
.attr("height", "100%")
// .on("click",function(){
// console.log("click svg");
// d3.selectAll("g.node").selectAll("circle").attr("stroke","white");
// d3.selectAll("g.node").selectAll("circle").attr("stroke-width",1);
// })
// TODO: Verificar el ajsute en altura del mensaje de selección
svg_g.append("text")
.attr("x", 100)
.attr("y", $("#graph").height() - margin.bottom - 45)
.append('svg:tspan')
.attr("id", "info_text_net")
.attr("x", "4%")
.text(_iTrans.prop('lb_info_net'));
svg_g.append("text")
.attr("x", 100)
.attr("y", $("#graph").height() - margin.bottom - 25)
.append('svg:tspan')
.attr("id", "info_text_slider")
.attr("x", "8%")
.text(_iTrans.prop('lb_info_slider'));
svg_g.append("text")
.attr("x", 100)
.attr("y", $("#graph").height() - 10)
.append('svg:tspan')
.attr("id", "lb_info_slider_left")
.attr("x", 10)
.text(_iTrans.prop('lb_info_slider_left'));
svg_g.append("text")
.attr("x", 100)
.attr("y", $("#graph").height() - 10)
.append('svg:tspan')
.attr("id", "lb_info_slider_right")
.attr("x", "29%")
.text(_iTrans.prop('lb_info_slider_right'));
d3.select("#graph")
.append("div")
.attr("id", "slider_charge")
.attr("class", "slider_charge")
$(function() {
$("#slider_charge").slider({
min: -200,
max: 5,
step: 1,
value: -100,
change: function(event, ui) {
_VERBOSE ? console.log(ui.value) : _VERBOSE;
force
.charge(ui.value)
.start();
}
});
});
$("#slider_charge .ui-slider-handle").text("ATR").width(30).height(20);
// var legend_div = d3.select("#graph")
// .append("div")
// .attr("id", "legend_div")
// .attr("class", "legend_div")
// var legend_svg = legend_div.append("svg")
// .attr("id", "legend_svg")
// .attr("class", "legend_svg");
// // .attr("width", "100%")
// // .attr("height", "100%");
var legend = svg_g.selectAll(".legend")
.data(_legend_groups)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
return "translate(0," + 10 + ")";
});
legend.append("rect")
.attr("x", function(d, i) {
return (width - 50) - (i * 120);
})
.attr("y", 3)
.attr("width", 20)
.attr("height", 20)
.style("fill", function(d, i) {
return _color(d.idgrp);
})
.style("opacity", 0.7);
legend.append("text")
.attr("x", function(d, i) {
return (width - 56) - (i * 120);
})
.attr("y", 15)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) {
if (d.side == 0) {
return "Src: " + d.label;
}
else {
return "Trg: " + d.label;
}
});
/*********************** zoomer */
var zoomer = d3.behavior.zoom().
// scaleExtent([0.5, 2]).
x(xScale).
y(yScale).
on("zoomstart", zoomstart).
on("zoom", redraw);
/* funciones zoomer */
// var redraw_done = false;
function zoomstart() {
_VERBOSE ? console.log("zoomstart") : _VERBOSE;
// if(!redraw_done){
d3.selectAll("g.node").selectAll("circle").attr("stroke", "white");
d3.selectAll("g.node").selectAll("circle").attr("stroke-width", 1);
// redraw_done = false;
// }
node.each(function(d) {
d.selected = false;
d.previouslySelected = false;
});
node.classed("selected", false);
}
function redraw() {
_VERBOSE ? console.log("redraw") : _VERBOSE;
// redraw_done = true;
vis.attr("transform",
"translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
var svg_graph = svg_g.append('svg:g')
.attr("class", "zoomer_svg")
.call(zoomer);
// .call(brusher)
/*********************** brusher */
var spids_node_selected = [];
brusher
.x(xScale)
.y(yScale);
/******************* contenedor secundario para sleccion de red */
var brush = svg_graph.append("g")
.datum(function() {
// _VERBOSE ? console.log("datum") : _VERBOSE;
return {selected: false, previouslySelected: false};
})
.attr("class", "brush");
brush.call(brusher)
.on("mousedown.brush", null)
.on("touchstart.brush", null)
.on("touchmove.brush", null)
.on("touchend.brush", null);
brush.select('.background').style('cursor', 'auto');
/******************* contenedor secundario para nodos y enlaces */
var vis = svg_graph.append("svg:g");
vis.attr("id", "vis")
.attr('fill', 'red')
.attr('stroke', 'black')
.attr('stroke-width', 1)
.attr('opacity', 1)
.attr('id', 'vis');
/******************* contenedor de enlaces */
var link_group = vis.append("g")
.attr("class", "link")
.selectAll("line");
/*** los enlaces se generan dinamicamente en la selección */
/******************* contenedor de nodos */
var node_group = vis.append("g")
.attr("class", "node")
.selectAll("circle");
/*** funcionamiento de nodos */
var node = node_group.data(json.nodes)
.enter().append("circle")
.attr("class", "node_item")
.attr("r", function(d) {
return 5 + Math.pow(d.occ / Math.PI, 0.5);
})
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.style("fill", function(d) {
return _color(d.group);
})
.on('mouseover', function(d) {
d3.select(this).attr("r", function(d) {
return 10 + Math.pow(d.occ / Math.PI, 0.5);
});
div_tip.transition()
.duration(200)
.style("opacity", .9);
var name_sp = ""
if(d.biotic){
name_sp = d.generovalido + " " + d.especieepiteto
}
else{
// console.log(d)
var label = d.label.replace(/[^a-zA-Z0-9]/g, "").replace(/ /g,'')
var range = d.tag.split(":")
var inf = parseFloat(range[0]).toFixed(2) * parseFloat(d.coeficiente)
var sup = parseFloat(range[1]).toFixed(2) * parseFloat(d.coeficiente)
name_sp = _iTrans.prop(label) + " " + inf + " " + d.unidad + " : " + sup + " " + d.unidad
}
div_tip.html(
"<strong>" + _iTrans.prop('lb_variable_name') + ":</strong> <span >" + name_sp + "</span><br/><br/>" +
"<strong>" + _iTrans.prop('lb_occ') + ":</strong> <span >" + d.occ + "</span>"
)
.style("left", (d3.event.pageX + 20) + "px")
.style("top", (d3.event.pageY - 38) + "px");
})
.on('mouseout', function(d) {
d3.select(this).attr("r", function(d) {
return 5 + Math.pow(d.occ / Math.PI, 0.5);
});
div_tip.transition()
.duration(500)
.style("opacity", 0);
})
.on("dblclick", function(d) {
d3.event.stopPropagation();
d.fixed = !d.fixed;
})
.on("click", function(d) {
_VERBOSE ? console.log("click") : _VERBOSE;
if (d3.event.defaultPrevented)
return;
// _VERBOSE ? console.log("Manda petición especie") : _VERBOSE;
console.log(d);
species_selected = {"id": d.spid, "label": d.label}
_nodes_selected = [d];
_nodes = json.nodes;
loadGridComunidad();
if (!shiftKey) {
node.classed("selected", function(p) {
return p.selected = p.previouslySelected = false;
})
}
d3.select(this).classed("selected", d.selected = !d.previouslySelected);
})
.call(d3.behavior.drag()
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended));
// asigna una posicion inicial en diagonal a los nodos, para que sea contante el numero de pasos para reacomodar la red
// var n = json.nodes.length;
// json.nodes.forEach(function(d, i) {
// d.x = d.y = width / n * i;
// });
/**********************************************/
function dragstarted(d) {
_VERBOSE ? console.log("dragstarted") : _VERBOSE;
d3.event.sourceEvent.stopPropagation();
if (!d.selected && !shiftKey) {
// if this node isn't selected, then we have to unselect every other node
node.classed("selected", function(p) {
return p.selected = p.previouslySelected = false;
});
}
d3.select(this).classed("selected", function(p) {
d.previouslySelected = d.selected;
return d.selected = true;
});
node.filter(function(d) {
return d.selected;
})
.each(function(d) {
d.fixed |= 2;
})
// a[0] |= b -> a[0] = a[0] | b
}
function dragged(d) {
// _VERBOSE ? console.log("dragged") : _VERBOSE;
node.filter(function(d) {
return d.selected;
})
.each(function(d) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d.px += d3.event.dx;
d.py += d3.event.dy;
})
force.resume();
}
function dragended(d) {
_VERBOSE ? console.log("dragended") : _VERBOSE;
//d3.select(self).classed("dragging", false);
node.filter(function(d) {
return d.selected;
})
.each(function(d) {
d.fixed = true;
})
// ~2 == -(2 + 1) == -3
}
function keydown() {
shiftKey = d3.event.shiftKey || d3.event.metaKey;
ctrlKey = d3.event.ctrlKey;
_VERBOSE ? console.log('keydown') : _VERBOSE;
if (d3.event.keyCode == 67) { //the 'c' key
_center_view();
}
if (shiftKey) {
_VERBOSE ? console.log('shiftKey') : _VERBOSE;
svg_graph.call(zoomer)
.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
//svg_graph.on('zoom', null);
vis.selectAll('g.gnode')
.on('mousedown.drag', null);
brush.select('.background').style('cursor', 'crosshair')
brush.call(brusher);
}
}
function keyup() {
_VERBOSE ? console.log("keyup") : _VERBOSE;
shiftKey = d3.event.shiftKey || d3.event.metaKey;
ctrlKey = d3.event.ctrlKey;
brush.call(brusher)
.on("mousedown.brush", null)
.on("touchstart.brush", null)
.on("touchmove.brush", null)
.on("touchend.brush", null);
brush.select('.background').style('cursor', 'auto')
svg_graph.call(zoomer);
// _VERBOSE ? console.log("keyup2") : _VERBOSE;
}
/***************** controles */
// Generación fuera de panel
d3.select("#graph_controls")
.append("div")
.attr("id", "play-stop-button-holder")
.attr("class", "div_btn stop_forces")
.append("button")
.attr("class", "btn btn-primary glyphicon glyphicon-stop")
.attr("id", "pararRed")
.attr("type", "button")
.attr("title", _iTrans.prop('lb_detener_net'))
.on("click", _stop_nodes);
d3.select("#graph_controls")
.append("div")
.attr("id", "center_view_holder")
.attr("class", "div_btn center")
.append("button")
.attr("class", "btn btn-primary glyphicon glyphicon-record")
.attr("id", "center_view_btn")
.attr("type", "button")
.attr("title", _iTrans.prop('lb_centrar_net'))
.on("click", _center_view);
d3.select("#graph_controls")
.append("div")
.attr("id", "div_search_holder")
.attr("class", "div_btn search_input")
.append("input")
.attr("class", "form-control")
.attr("id", "input_text_search")
.attr("type", "text")
.attr("placeholder", _iTrans.prop('lb_buscar_sp'))
.on("input", _search_node);
d3.select("#graph_controls")
.append("div")
.attr("id", "div_export_holder")
.attr("class", "div_btn export_btn")
.append("button")
.attr("class", "btn btn-primary glyphicon glyphicon-download-alt")
.attr("id", "export_btn")
.attr("type", "button")
.attr("title", _iTrans.prop('lb_exportar_net'))
.on("click", _export_graph);
// ******* extración de código para que la red no sea regenerada, solo filtrada
// evento llamado por render ****
function graph(div) {
_VERBOSE ? console.log("graph") : _VERBOSE;
div.each(function() {
_VERBOSE ? console.log("graph div.each") : _VERBOSE;
/*********************** init variables, and force object */
// console.log(display_obj.dim_node_state.top(Infinity));
var epsilonBySource = display_obj.nestByR.entries(display_obj.dim_node_state.top(Infinity));
var json_temp = []
var indexVisibleNodes = []
var nodes_related = d3.map([]);
epsilonBySource.sort(_compare_desc)
console.log(epsilonBySource);
console.log("epsilonBySource: " + epsilonBySource.length);
_linkedByIndex = {};
var max_link = display_obj.max_num_link
var link_counter = 0
console.log("net_module max_link: " + max_link)
console.log("net_module first_load: " + display_obj.hist_load)
// console.log(epsilonBySource)
epsilonBySource.forEach(function(bean, i) {
bean.values.forEach(function(val) {
if (Math.abs(val.value) > display_obj.ep_th) {
link_counter++
// console.log("link_counter: " + link_counter)
if(display_obj.hist_load || link_counter <= max_link){
// console.log("ADD element")
// display_obj.first_load = false
json_temp.push({"source": val.source, "target": val.target, "value": val.value});
nodes_related.set(val.source, parseInt(val.source));
nodes_related.set(val.target, parseInt(val.target));
_linkedByIndex[val.source + "," + val.target] = true;
}
}
});
});
_VERBOSE ? console.log("json_temp: " + json_temp.length) : _VERBOSE;
// obtiene el limite minimo del conjunto obtenido, para descartar lso valores seleccionados
display_obj.net_limit_eps = d3.min(json_temp.map(function(d) {return parseFloat(d.value) }));
// display_obj.net_max_eps = d3.max(json_temp.map(function(d) {return parseFloat(d.value) }));
_VERBOSE ? console.log("net_limit_eps: " + display_obj.net_limit_eps) : _VERBOSE;
// _VERBOSE ? console.log("net_max_eps: " + display_obj.net_max_eps) : _VERBOSE;
// TODO: Enlazar al histograma para que se depsliegue el brush cuando hace la primera carga
// if(display_obj.chart != null)
// display_obj.chart.drawBrush(min_eps, max_eps)
_VERBOSE ? console.log(nodes_related.keys()) : _VERBOSE;
for (var val in nodes_related.values()) {
indexVisibleNodes.push(val);
}
_VERBOSE ? console.log(indexVisibleNodes) : _VERBOSE;
_VERBOSE ? console.log(epsilonBySource) : _VERBOSE;
_VERBOSE ? console.log(json_temp) : _VERBOSE;
// _VERBOSE ? console.log(d3.selectAll("g.node").selectAll("circle")) : _VERBOSE;
d3.selectAll("g.node").selectAll("circle")
.each(function(d) {
d3.select(this).style("visibility", function(d) {
if (nodes_related.has((d.index).toString())) {
d.visible = true;
return "visible";
}
else {
d.visible = false;
return "hidden";
}
});
}
);
$("line.link").remove();
link = link_group.data(json_temp)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", 5)
.style("stroke", function(d) {
return link_color(d.value);
})
.style("opacity", 1);
// _VERBOSE ? console.log(force) : _VERBOSE;
force
.nodes(json.nodes)
.links(json_temp)
.start();
force.on("tick", function() {
link.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
// node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.attr('cx', function(d) {
return d.x;
}).attr('cy', function(d) {
return d.y;
});
});
for (var i = 0; i < json.nodes.length; ++i)
force.tick();
force.resume();
brusher
.on("brushstart", function(d) {
_VERBOSE ? console.log("brushstart") : _VERBOSE;
node.each(function(d) {
d.previouslySelected = shiftKey && d.selected;
});
})
.on("brush", function(e) {
_VERBOSE ? console.log("brush") : _VERBOSE;
indexNodes = [];
var extent = d3.event.target.extent();
index_selected_visible = [];
node.classed("selected", function(d) {
inside = extent[0][0] <= d.x && d.x < extent[1][0] && extent[0][1] <= d.y && d.y < extent[1][1]
indexNodes.push(d.previouslySelected ^ inside)
return d.selected = d.previouslySelected ^ inside;
});
// _VERBOSE ? console.log(indexNodes) : _VERBOSE;
// _VERBOSE ? console.log(indexNodes.length) : _VERBOSE;
// _VERBOSE ? console.log(nodes_related.keys()) : _VERBOSE;
// _VERBOSE ? console.log(nodes_related.keys().length) : _VERBOSE;
indexNodes.forEach(function(d, i) {
if (nodes_related.has(i.toString())) {
if (nodes_related.get(i.toString()) && d == 1) {
// _VERBOSE ? console.log(i) : _VERBOSE;
// _VERBOSE ? console.log(d) : _VERBOSE;
index_selected_visible.push(i);
}
}
});
// _VERBOSE ? console.log(nodes_selected) : _VERBOSE;
// _VERBOSE ? console.log(index_selected_visible) : _VERBOSE;
spids_node_selected = [];
$.each(index_selected_visible, function(index, value) {
// spids_node_selected.push(json.nodes[value].spid);
spids_node_selected.push(json.nodes[value]);
});
})
.on("brushend", function(e) {
_VERBOSE ? console.log("brushend...") : _VERBOSE;
// _VERBOSE ? console.log(spids_node_selected) : _VERBOSE;
// if(spids_node_selected.length > 0)
console.log(spids_node_selected)
_nodes_selected = spids_node_selected;
_nodes = json.nodes;
loadGridComunidad();
d3.event.target.clear();
d3.select(this).call(d3.event.target);
});
// asigna el foco al zoomer
brush.call(brusher)
.on("mousedown.brush", null)
.on("touchstart.brush", null)
.on("touchmove.brush", null)
.on("touchend.brush", null);
brush.select('.background').style('cursor', 'auto')
svg_graph.call(zoomer);
// center_view();
// force.stop();
// _stop_nodes();
});
}
// Activa el algoritmo de fuerzas entre los nodos que componen la red.
function _start_nodes() {
d3.selectAll("g.node").selectAll("circle")
.each(
function(d) {
d.fixed = false;
}
);
force.start();
d3.select("#iniciarRed")
.remove();
d3.select("#play-stop-button-holder")
.append("button")
.attr("class", "btn btn-primary glyphicon glyphicon-stop")
.attr("id", "pararRed")
.attr("type", "button")
.attr("title", "Detener red")
.on("click", _stop_nodes);
}
// Detiene el algoritmo de fuerzas entre los nodos que componen la red.
function _stop_nodes() {
force.stop();
d3.selectAll("g.node").selectAll("circle")
.each(
function(d) {
d.fixed = true;
}
);
d3.select("#pararRed")
.remove();
d3.select("#play-stop-button-holder")
.append("button")
.attr("class", "btn btn-primary glyphicon glyphicon-play")
.attr("id", "iniciarRed")
.attr("type", "button")
.attr("title", "Reiniciar red")
.on("click", _start_nodes);
}
// Resalta los nodos que coinciden con el nombre de la cadena introducida.
function _search_node(d) {
console.log(d)
_clean_highlight();
search_str = $("#input_text_search").val();
if (search_str.length <= 2) {
d3.selectAll("g.node").selectAll("circle")
.each(function(item) {
d3.select(this).attr("stroke", "white");
d3.select(this).attr("class", "no_path");
d3.select(this).style("stroke-dasharray", "none");
d3.select(this).attr("r", function(d) {
return 5 + Math.pow(d.occ / Math.PI, 0.5);
});
d3.select(this).style("stroke-width", 1);
});
return;
}
// _map_conected = d3.map([]);
// var nodes_selected = [];
d3.selectAll("g.node").selectAll("circle")
.each(function(item) {
// console.log(item)
var label = item.biotic ? item.generovalido + " " + item.especieepiteto : _iTrans.prop("a_item_" + item.layer) + " (" + parseFloat(item.tag.split(":")[0]).toFixed(2) + " : " + parseFloat(item.tag.split(":")[1]).toFixed(2) + ")"
if (label.toLowerCase().startsWith(search_str.toLowerCase())) {
// _VERBOSE ? console.log(item.label + " " + item.index) : _VERBOSE;
// _VERBOSE ? console.log(highlight_color) : _VERBOSE;
// nodes_selected.push(item);
d3.select(this).attr("class", "path");
d3.select(this).attr("stroke", function() {
return _highlight_color;
});
d3.select(this).style("stroke-width", 4);
// d3.select(this).style("outline", 4);
d3.select(this).style("stroke-dasharray", ("200"));
d3.select(this).style("stroke-linecap", "round");
d3.select(this).attr("r", function(d) {
return 10 + Math.pow(d.occ / Math.PI, 0.5);
});
}
else {
d3.select(this).attr("stroke", "white");
d3.select(this).attr("class", "nopath");
// d3.select(this).style("stroke-dasharray", "none");
d3.select(this).attr("r", function(d) {
return 5 + Math.pow(d.occ / Math.PI, 0.5);
});
d3.select(this).style("stroke-width", 1);
}
});
// $.each(nodes_selected, function(index, value_a){
// set_highlight(value_a);
// });
}
// Despliega el control para descargar la red.
function _export_graph() {
_VERBOSE ? console.log("export_graph") : _VERBOSE;
//TODO: Verficar por que en chrome no detecta el cambio
$("#lb_modal_red").text(_iTrans.prop('lb_modal_red'));
$("#lb_des_modal_red").text(_iTrans.prop('lb_des_modal_red'));
$("#red_download").text(_iTrans.prop('red_download'));
$("#cancel_red_csv").text(_iTrans.prop('cancel_red_csv'));
$('#modalMail').modal('show');
}
// TODO: enlazar con la red que se genra de forma dinámica....
function _center_view() {
_VERBOSE ? console.log("_center_view") : _VERBOSE;
if (nodeGraph === null)
return;
var nodes = nodeGraph.nodes;
//no molecules, nothing to do
if (nodes.length === 0)
return;
// Get the bounding box
min_x = d3.min(nodes.map(function(d) {
return d.x;
}));
min_y = d3.min(nodes.map(function(d) {
return d.y;
}));
max_x = d3.max(nodes.map(function(d) {
return d.x;
}));
max_y = d3.max(nodes.map(function(d) {
return d.y;
}));
// The width and the height of the graph
mol_width = max_x - min_x;
mol_height = max_y - min_y;
// how much larger the drawing area is than the width and the height
width_ratio = width / mol_width;
height_ratio = height / mol_height;
// we need to fit it in both directions, so we scale according to
// the direction in which we need to shrink the most
min_ratio = Math.min(width_ratio, height_ratio) * 0.8;
// the new dimensions of the molecule
new_mol_width = mol_width * min_ratio;
new_mol_height = mol_height * min_ratio;
// translate so that it's in the center of the window
x_trans = -(min_x) * min_ratio + (width - new_mol_width) / 2;
y_trans = -(min_y) * min_ratio + (height - new_mol_height) / 2;
// do the actual moving
vis.attr("transform",
"translate(" + [x_trans, y_trans] + ")" + " scale(" + min_ratio + ")");
// tell the zoomer what we did so that next we zoom, it uses the
// transformation we entered here
zoomer.translate([x_trans, y_trans]);
zoomer.scale(min_ratio);
}
graph.dimension = function(_) {
// _VERBOSE ? console.log("graph.dimension") : _VERBOSE;
// _VERBOSE ? console.log(_) : _VERBOSE;
if (!arguments.length)
return dimension;
dimension = _;
return graph;
};
graph.group = function(_) {
// _VERBOSE ? console.log("graph.group") : _VERBOSE;
// _VERBOSE ? console.log(_) : _VERBOSE;
if (!arguments.length)
return group;
group = _;
return graph;
};
return d3.rebind(graph, brusher, "on");
}
/**
* Éste método verifica si dos nodos se encuentran conectados a través del cálculo épsilon.
*
* @function _isConnected
* @private
*
* @param {object} a - Nodo source
* @param {object} b - Nodo target
*/
function _isConnected(a, b) {
return _linkedByIndex[a.index + "," + b.index] || _linkedByIndex[b.index + "," + a.index] || a.index == b.index;
}
/**
* Éste método verifica si nu nodo tiene vecinos a través del cálculo épsilon.
*
* @function hasConnections
* @private
*
* @param {object} a - Nodo source
*/
function hasConnections(a) {
for (var property in _linkedByIndex) {
s = property.split(",");
if ((s[0] == a.index || s[1] == a.index) && _linkedByIndex[property])
return true;
}
return false;
}
/**
* Éste método borra los componentes visuales e iniciliza parámetros para generar un nuevo análisis de comunidad ecológica.
*
* @function _clean_search
* @private
*
*/
function _clean_search() {
console.log("_clean_search");
$("#input_text_search").val("");
d3.selectAll("g.node").selectAll("circle")
.each(function(item) {
d3.select(this).attr("stroke", "white");
d3.select(this).attr("class", "no_path");
d3.select(this).style("stroke-dasharray", "none");
d3.select(this).attr("r", function(d) {
return 5 + Math.pow(d.occ / Math.PI, 0.5);
});
d3.select(this).style("stroke-width", 1);
});
}
/**
* Éste método limpia los nodos que fueron resaltados al verificar los vecinos de un nodo.
*
* @function _clean_highlight
* @private
*
*/
function _clean_highlight() {
console.log("_clean_highlight");
_map_conected = d3.map([]);
d3.selectAll("g.node").selectAll("circle").attr("stroke", "white");
d3.selectAll("g.node").selectAll("circle").style("stroke-width", 1);
}
/**
* Éste método resalta los nodos vecinos de un nodo source.
*
* @function _set_highlight
* @private
*
* @param {object} d - nodo source
*/
function _set_highlight(d) {
console.log("_set_highlight")
// console.log(d)
d3.selectAll("g.node").selectAll("circle").attr("stroke", function(o) {
// console.log(o)
if ((_isConnected(d, o) && d.id != o.id) || _map_conected.has(o.id)) {
_map_conected.set(o.id, true);
return _highlight_linked_color;
}
else {
return "white";
}
});
d3.selectAll("g.node").selectAll("circle").style("stroke-width", function(o) {
if ((_isConnected(d, o) && d.id != o.id) || _map_conected.has(o.id)) {
// console.log("4");
_map_conected.set(o.id, true);
return 4;
}
else {
return 1;
}
});
// link.style("stroke", function(o) {
// return o.source.index == d.index || o.target.index == d.index ? highlight_color : ((isNumber(o.score) && o.score>=0)?color(o.score):default_link_color);
}
function loadGridComunidad(){
_VERBOSE ? console.log("loadGridComunidad") : _VERBOSE;
// Actualemnte no existe proceso de validacion en comunidad
var val_process = false;
// Actualemnte no existe cambio de resolución en comunidad
var grid_res = parseInt($("#grid_resolution").val());
var footprint_region = parseInt($("#footprint_region_select").val());
_map_module_net.busca_especie_grupo([], footprint_region, val_process, grid_res);
// function busca_especie_grupo(taxones, region = 1, val_process = false, grid_res = 16) {
}
/**
* Éste método muestra las ocurrencias por celda del conjunto seleccionado en el mapa resultado del análisis de comunidad.
*
* @function showSpecieOcc
* @public
*
*/
function showSpecieOcc() {
_VERBOSE ? console.log("showSpecieOcc") : _VERBOSE;
var nodes = [];
var footprint_region = parseInt($("#footprint_region_select").val());
var grid_res = parseInt($("#grid_resolution").val());
// console.log(_nodes_selected)
$.each(_nodes_selected, function(index, value) {
var node = {}
console.log(value)
node.biotic = value.biotic
node.merge_vars = []
var temp_var = {}
if(value.biotic){
var rank = value.grp == 1 ? _analisis_level_selected_fuente : _analisis_level_selected_sumidero
console.log("rank: " + rank)
temp_var.rank = rank
temp_var.value = value.generovalido + " " + value.especieepiteto
}
else{
temp_var.rank = "bid"
temp_var.value = value.bid
}
node.merge_vars.push(temp_var)
nodes.push(node);
})
// console.log(nodes)
_map_conected = d3.map([]);
_clean_search();
$.each(_nodes_selected, function(index, value_a) {
_set_highlight(value_a);
});
var sdata = {
"nodes": nodes,
"region": footprint_region,
"grid_res": grid_res
};
console.log(sdata)
$('#map').loading({
stoppable: true
});
// guarda objeto de la ultima configuración con la que se genero el mapa
_map_module_net.setNodeSelectedConf(sdata);
$.ajax({
// url: _url_zacatuche + "/niche/especie/getCountGridid",
url: _url_zacatuche + "/niche/especie/getGroupCountGridid",
type: 'post',
data: sdata,
success: function(resp) {
$('#map').loading('stop');
// json = JSON.parse(json_file);
var json = resp.data;
_VERBOSE ? console.log(json) : _VERBOSE;
var arg_gridid = [];
var arg_count = [];
$.each(json, function(index, item) {
arg_gridid.push(item.gridid);
arg_count.push(parseInt(item.conteo));
});
var max_eps = d3.max(arg_count);
var min_eps = d3.min(arg_count);
_VERBOSE ? console.log(max_eps) : _VERBOSE;
_VERBOSE ? console.log(min_eps) : _VERBOSE;
var link_color;
if (max_eps === min_eps) {
link_color = d3.scale.quantize().domain([0, max_eps]).range(colorbrewer.YlOrRd[9]);
}
else {
link_color = d3.scale.quantize().domain([min_eps, max_eps]).range(colorbrewer.YlOrRd[9]);
}
_VERBOSE ? console.log(link_color(min_eps)) : _VERBOSE;
_VERBOSE ? console.log(link_color(max_eps)) : _VERBOSE;
// var dom = link_color.domain();
// var l = (dom[1] - dom[0])/link_color.range().length;
// var breaks = d3.range(0, link_color.range().length).map(function(i) { return i * l; });
_map_module_net.colorizeFeaturesNet(arg_gridid, arg_count, link_color);
},
error: function(jqXHR, textStatus, errorThrown) {
_VERBOSE ? console.log("error configureStyleMap: " + textStatus) : _VERBOSE;
// deleteStyle();
$('#map').loading('stop');
}
});
}
function getGridNet2Export(nodes, links){
_VERBOSE ? console.log("getGridNet2Export") : _VERBOSE;
var date = new Date();
var sufijo = "_Exp_"+date.getFullYear()+"_"+date.getMonth()+"_"+date.getDay()+"_"+date.getHours()+":"+date.getMinutes();
$("#red_download").attr("download","net" + sufijo + ".csv");
// nodes tienen index
// enlaces tienen source & target & epsilon
console.log(nodes);
console.log(links);
var grid_net_2export = "";
for (var i = 0; i < links.length; i++) {
var item = links[i];
if(parseFloat(item.value)>=_UMBRAL || parseFloat(item.value)<=-_UMBRAL){
// grid_net_2export += nodes[item.source].label + ","
// grid_net_2export += nodes[item.target].label + ","
grid_net_2export += nodes[item.source].generovalido + " " + nodes[item.source].especieepiteto + ","
grid_net_2export += nodes[item.target].generovalido + " " + nodes[item.target].especieepiteto + ","
grid_net_2export += parseFloat(item.value)
grid_net_2export += "\r\n"
}
}
// console.log(grid_net_2export);
return grid_net_2export;
}
function _compare(a, b) {
if (parseFloat(a.key) < parseFloat(b.key))
return -1;
if (parseFloat(a.key) > parseFloat(b.key))
return 1;
return 0;
}
function _compare_desc(a, b) {
// _VERBOSE ? console.log("_compare_desc") : _VERBOSE;
if (parseFloat(a.key) > parseFloat(b.key))
return -1;
if (parseFloat(a.key) < parseFloat(b.key))
return 1;
return 0;
}
/**
* Éste método realiza el llamado a la función que inicializa variables y componentes que son necesarios para la creación de la red.
*
* @function startNet
* @public
*
* @param {object} languageModule - Módulo de internacionalización
* @param {type} s_filters - Array con los grupos de variables source utlizados en el analísis de comunidad ecológica.
* @param {type} t_filters - Array con los grupos de variables target utlizados en el analísis de comunidad ecológica.
*/
function startNet(language_module, s_filters, t_filters) {
_VERBOSE ? console.log("startNet") : _VERBOSE;
_netConfigure(language_module, s_filters, t_filters);
}
return{
startNet: startNet,
createNet: createNet,
setLanguageModule: setLanguageModule,
setLegendGroup: setLegendGroup,
showSpecieOcc: showSpecieOcc,
getGridNet2Export: getGridNet2Export,
setRankValues: setRankValues
}
});