...
 
Commits (4)
......@@ -125,6 +125,27 @@ height: 37px;
font-size: 1.5em;
}
.network-button-container {
display: flex;
flex-wrap: wrap;
}
.network-button-container .network-select {
border: 1px solid #CCCCCC;
border-radius: 5px;
margin: 0em 1em 1em 0;
padding: 10px;
}
.network-button-container .network-select.selected {
background-color: #2d9b2e;
color: white;
}
.network-button-container .network-select.active {
border: 1px solid red;
}
.network-control {
flex-basis: 49%;
display: flex;
......@@ -140,7 +161,7 @@ height: 37px;
.network-container {
flex-basis: 100%;
border: 1px solid #CCCCCC;
height: 500px;
height: 700px;
}
.network-table-wrapper {
......
......@@ -46,17 +46,15 @@
<div class="network-input">
<label for="sink1">Genes</label>
<textarea name="sp1genes" rows="6" id="sink1"></textarea>
<label for="sp_1">Network 1</label>
<select class="sel" name="sp1" id="sp_1"></select>
<label for="sp_2">Network 2</label>
<select class="sel" name="sp2" id="sp_2"></select>
<label for="network-buttons">Networks</label>
<div id="network-buttons" class="network-button-container"></div>
</div>
<div class="network-control">
<label for="th1">Co-expression threshold: <span id="th1_span">(>=0.990)</label>
<input type="range" min="0.95" max="1" step="0.001" value="0.99" id="th1" name="th1">
<button id="align_to_species_button" class="btn btn-4 btn-4c"></button>
<button id="align_to_species_button" class="btn btn-4 btn-4c">Align</button>
</div>
</div>
......
......@@ -34,13 +34,57 @@ function populate_select_options(data, element, selected_option) {
})
}
function populateNetworkSelect(data, element) {
$(data).each(function(i, val) {
var $div = $(`<div/>`, {
class: 'network-select',
'data-species': val.shortname,
'data-network': val.id,
id: `network${val.id}-select`,
on: {
click: function(event) {
$(this).toggleClass('selected');
// Currently we don't support same species network comparison
$(`.network-select[data-species = ${this.dataset.species}].selected`)
.not(`#${this.id}`)
.removeClass('selected');
// If this is the first to be selected, then also set it to active
if ($('.network-select.selected').length === 1 & $(this).hasClass('selected')) {
$(this).children('.network-radio').prop('checked', true).change();
}
// If it is active, don't allow it to be deselected
if ($(this).hasClass('active') & !$(this).hasClass('selected')) {
$(this).addClass('selected');
}
}
}
});
$div.append(`<input class="network-radio" type="radio" name="network-radio">`);
$div.append(`<label>${val.name}</label>`);
$(element).append($div);
});
$('.network-radio').on('change', function() {
if (!$(this).parent('.network-select').hasClass('selected')) {
$(this).parent('.network-select').addClass('selected');
}
$('.network-select.active').removeClass('active');
$(this).parent('.network-select').addClass('active');
});
}
/*
* Return the selected networks
*
* Returns: an array of network IDs
*/
function getSelectedNetworks() {
return [$('#sp_1').val(), $('#sp_2').val()];
return $('.network-select.selected').map(function() {
return parseInt(this.dataset.network);
}).toArray();
}
/*
......@@ -49,7 +93,7 @@ function getSelectedNetworks() {
* Returns: the ID of the currently active network
*/
function getActiveNetwork() {
return $('#sp_1').val();
return $('.network-select.active').data('network');
}
/*
......@@ -240,7 +284,7 @@ function visibilitychange() {
function loadexample(e) {
var t = e.toString();
switch ($("#sp_" + t).find(":selected").data("species")) {
switch ($('.network-select.active').data("species")) {
case "potra":
$("#sink" + t).val("Potra000167g00627, Potra000342g01183, Potra000393g01809, Potra000740g05836, Potra000779g06142, Potra001021g08534, Potra001047g08885, Potra001066g09183, Potra001242g10676, Potra001542g12785, Potra001630g13406, Potra002004g15732, Potra002246g17253, Potra002409g18324, Potra002484g18790, Potra002574g19365, Potra002846g20119, Potra002888g20235, Potra002914g20296, Potra003265g21167, Potra003469g21770, Potra003868g23243, Potra003935g23615, Potra003972g23875, Potra004051g24387");
break;
......@@ -329,6 +373,7 @@ window.onload = init(function(d) {
populate_select_options(network_data, "#sp_1", 1);
populate_select_options(network_data, "#sp_2");
populateNetworkSelect(network_data, '#network-buttons');
view1 = new TableNetwork('#active-network-table', '#other-network-table', '#cytoscapeweb1');
......@@ -359,7 +404,6 @@ window.onload = init(function(d) {
$("#span_l_sp2").html(r);
$("#species_span_1").html(n);
$("#species_span_2").html(r);
$("#align_to_species_button").html("Align " + $("#sp_1 option:selected").text() + " with " + $("#sp_2 option:selected").text());
$("#compare_with_species_button").html("Compare " + $("#sp_1 option:selected").text() + " and " + $("#sp_2 option:selected").text());
$("#sink1").keyup(function() {
if (basic_validation_function(1) == false) {
......
......@@ -78,7 +78,28 @@ function TableNetwork(active_table_element, other_table_element, network_element
style: {
'line-style': 'dashed',
'label': 'data(conservation_pvalue)',
'display': 'none'
'display': 'none',
'curve-style': 'bezier',
'target-arrow-shape': 'triangle',
'arrow-scale': 2
}
}, {
selector: 'edge.orthology[support = "ORTHO"]',
style: {
'line-color': '#45ADFF',
'target-arrow-color': '#45ADFF'
}
}, {
selector: 'edge.orthology[support = "BHIF"]',
style: {
'line-color': '#FC784C',
'target-arrow-color': '#FC784C'
}
}, {
selector: 'edge.orthology[support = "TROG"]',
style: {
'line-color': '#1AC620',
'target-arrow-color': '#1AC620'
}
}
],
......@@ -86,6 +107,8 @@ function TableNetwork(active_table_element, other_table_element, network_element
boxSelectionEnabled: true
});
this.cy.nodes().unselectify();
this.cy.panzoom({
});
......@@ -95,39 +118,110 @@ function TableNetwork(active_table_element, other_table_element, network_element
var self = this;
var networkSelect = false;
var tableSelect = false;
var propagateSelection = true;
this.cy.on('select', 'node', function(e) {
if (tableSelect) {
tableSelect = true;
return;
}
networkSelect = true;
var nodeId = e.target.data('id');
if (e.target.data('parent') === `network${self.activeNetworkID}`) {
self.activeTable.row(`#${nodeId}`).select();
this.deselectAll = function() {
this.cy.nodes().selectify().deselect().unselectify();
this.cy.edges('.orthology').style('display', 'none');
}
var selectNode = function(node) {
// Display orthology edges
node.selectify().select().unselectify();
node.connectedEdges('.orthology').style('display', 'element');
// Select the orthologs in the connected networks
if (node.data('parent') === `network${self.activeNetworkID}`) {
node.connectedEdges('.orthology')
.targets()
.selectify()
.select()
.unselectify();
} else {
self.otherTable.row(`#${nodeId}`).select();
node.connectedEdges('.orthology')
.sources()
.selectify()
.select()
.unselectify();
}
}
var deselectNode = function(node) {
// TODO: don't deselect orthologous nodes that still have
// orthology edges connected to them. This could be done by
// simply deselct all of them and then reselect those that
// are still connected.
node.selectify().deselect().unselectify();
console.log('deselect edges');
node.connectedEdges('.orthology').style('display', 'none');
node.connectedEdges('.orthology')
.targets()
.selectify()
.deselect()
.unselectify();
}
this.getActiveSelected = function() {
return self.cy
.nodes(`#network${self.activeNetworkID}`)
.children(':selected');
}
this.cy.on('tap', 'node', function(e) {
var nSelected = self.getActiveSelected().length;
if (e.target.selected() & nSelected === 1) {
deselectNode(e.target);
} else if (e.target.selected() & nSelected > 1 & !e.originalEvent.shiftKey) {
self.deselectAll();
selectNode(e.target);
} else if (e.target.selected() & nSelected > 1 & e.originalEvent.shiftKey) {
deselectNode(e.target);
} else if (!e.target.selected() & e.originalEvent.shiftKey) {
selectNode(e.target);
} else if (!e.target.selected() & !e.originalEvent.shiftKey) {
self.deselectAll();
selectNode(e.target);
}
return;
if (!propagateSelection) {
//propagateSelection = true;
return;
}
// Display orthology edges
e.target.connectedEdges('.orthology').style('display', 'element');
});
// Select the orthologs in the connected networks
propagateSelection = false;
if (e.target.data('parent') === `network${self.activeNetworkID}`) {
e.target.connectedEdges('.orthology')
.targets()
.selectify()
.select()
.unselectify();
} else {
e.target.connectedEdges('.orthology')
.sources()
.selectify()
.select()
.unselectify();
}
return;
this.cy.on('unselect', 'node', function(e) {
if (tableSelect) {
tableSelect = false;
tableSelect = true;
return;
}
networkSelect = true;
var nodeId = e.target.data('id');
if (e.target.data('parent') === `network${self.activeNetworkID}`) {
self.activeTable.row(`#${nodeId}`).deselect();
self.activeTable.row(`#${nodeId}`).select();
} else {
self.otherTable.row(`#${nodeId}`).deselect();
self.otherTable.row(`#${nodeId}`).select();
}
// Hide ortholog edges
e.target.connectedEdges('.orthology').style('display', 'none');
});
var networkSelectionFromTable = function(e, dt, type, fromActiveTable) {
......@@ -138,11 +232,7 @@ function TableNetwork(active_table_element, other_table_element, network_element
tableSelect = true;
if (type === "row") {
var nodeIds = dt.rows({selected: true}).ids().toArray();
if (fromActiveTable) {
self.cy.nodes(`[id = "network${self.activeNetworkID}"]`).children().deselect();
} else {
self.cy.nodes(`[id != "network${self.activeNetworkID}"]`).children().deselect();
}
self.cy.nodes().deselect();
self.cy.nodes().filter(function(x) {
return $.inArray(x.data('id'), nodeIds) !== -1;
}).select();
......
......@@ -73,9 +73,13 @@ function get_network($network_ids, $active_id, $gene_names, $threshold) {
LEFT OUTER JOIN orthology AS o2
ON o2.gene_id1 = c.gene_id2 AND o2.gene_id2 = c.gene_id1
WHERE c.network_id2 = :network_id
AND c.network_id1 = :active_network_id
AND c.gene_id1 IN ('.prepare_in('gene', $gene_ids).')';
$params = array_merge(array(':network_id' => $id), build_in_array('gene', $gene_ids));
$params = array_merge(
array(':network_id' => $id, ':active_network_id' => $active_id),
build_in_array('gene', $gene_ids)
);
$stmt = $db->prepare($ortho_query);
$stmt->execute($params);
......@@ -86,16 +90,19 @@ function get_network($network_ids, $active_id, $gene_names, $threshold) {
'gene_id' => $or['g2'],
'gene_name' => $or['g2_name']
);
$ortholog_edges[] = array(
'group' => 'edges',
'data' => array(
'source' => $or['g1'],
'target' => $or['g2'],
'conservation_pvalue' => $or['pvalue'],
'support' => $or['support']
),
'classes' => 'orthology'
);
$ortho_methods = explode(',', $or['support']);
foreach ($ortho_methods as $om) {
$ortholog_edges[] = array(
'group' => 'edges',
'data' => array(
'source' => $or['g1'],
'target' => $or['g2'],
'conservation_pvalue' => $or['pvalue'],
'support' => $om
),
'classes' => 'orthology'
);
}
}
}
......