-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from phac-nml/asset/update
Updating ArborView to v0.0.7-rc1
- Loading branch information
Showing
2 changed files
with
106 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,6 +101,9 @@ | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/bootstrap5-toggle.min.css" rel="stylesheet"> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/js/bootstrap5-toggle.jquery.min.js"></script> | ||
|
||
<!-- Sweet Alerts 2 --> | ||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> | ||
|
||
|
||
|
||
<script type="text/javascript"> | ||
|
@@ -1332,6 +1335,8 @@ | |
|
||
let drawTree = (newick_) => { | ||
$("#tree-splash").remove() | ||
$("#tree-selector").remove() | ||
$("#tree-upload-button").remove() | ||
let tree = kn_parse(newick_); | ||
if(tree_root != null){ | ||
console.error("A tree is already drawn"); | ||
|
@@ -1382,6 +1387,9 @@ | |
|
||
|
||
let CreateTable = (parsed_data, table_id, table_headers) => { | ||
$("#table-splash").remove(); | ||
$("#metadata-selector-input").remove(); | ||
$("#metadata-selector").remove(); | ||
let headers = table_headers; | ||
let table_head = ""; | ||
let table_body = []; | ||
|
@@ -1430,11 +1438,10 @@ | |
|
||
for(const item of array_tuples){ //[field_value, hex_colour] | ||
let row_legend_node = $(`<div class="d-flex p-1 border-bottom flex-nowrap align-items-center legend-element"></div>`) | ||
console.log(item[0]) | ||
let field_value=item[0] | ||
if(field_value === ''){field_value="Not defined"} | ||
row_legend_node.append(` | ||
<input type="color" value="${item[1]}" data-sampleID="${value2samples[item[0]].join(',')}" onchange="changeLengedItemColour(this)" | ||
<input type="color" value="${item[1]}" data-sampleID="${value2samples[item[0]].join(',')}" onchange="changeLegendItemColour(this)" | ||
style="width: 20px; height:20px; padding: 1px; border: 1px solid black"></input>\n | ||
<small onclick="select_deselect_nodes_by_field_value(this, ${column_index})" | ||
style="padding-left:5px">${field_value}</small>`) | ||
|
@@ -1445,16 +1452,18 @@ | |
|
||
}; | ||
|
||
let changeLengedItemColour = (div) => { | ||
|
||
let changeLegendItemColour = (div) => { | ||
let prevColourValueHex = div.getAttribute("value"); | ||
let newColourValueHex = `${div.value}` | ||
div.setAttribute("value",newColourValueHex); | ||
let legend_update = div.nextElementSibling.innerText; | ||
div.dataset.sampleid.split(',').forEach( sample_id => { | ||
let ele = document.querySelector(`#TreeSVG [id="${sample_id}"]`); | ||
if(ele !== null){ | ||
let [elem, circle, text] = SelectedNodes.getNodeData(ele); | ||
if(SelectedNodes.nodes.has(text.textContent)){ | ||
delete circle.dataset.oldfill | ||
// if selected old fill value needs to be updated | ||
circle.dataset.oldfill = newColourValueHex; | ||
}else{ | ||
circle.style.fill = newColourValueHex; | ||
|
@@ -1466,8 +1475,12 @@ | |
} | ||
|
||
let PopulateGroups = (json_groups, query_key) => { | ||
|
||
ORIGINAL_DATA.forEach((value, key) => { | ||
json_groups[value[query_key]].push(key); | ||
if (value[query_key] in json_groups) { | ||
json_groups[value[query_key]].push(key); | ||
} | ||
|
||
}); | ||
return json_groups; | ||
}; | ||
|
@@ -1524,11 +1537,14 @@ | |
|
||
let col_index = ele.id; | ||
$("#legend_toggle").bootstrapToggle('on') | ||
// TODO add a list of headers somewhere to select colouring from | ||
let unq_data = data_table.column(col_index).data().unique(); | ||
|
||
let unq_data = new Set(); | ||
ORIGINAL_DATA.forEach((value, key) => { | ||
unq_data.add(value[col_index]) | ||
}) | ||
|
||
// Need to create groupings of the each set of ID's belonging to each value grouping | ||
let break_down_values = unq_data.toArray(); | ||
let break_down_values = Array.from(unq_data); | ||
break_down_values.sort() | ||
|
||
// Instead of searching the array for ID's using the datatable, I am just going to use a linear look up | ||
|
@@ -1543,13 +1559,10 @@ | |
try{ | ||
let current_item = document.querySelector(`[id='${x}']`); | ||
let [elem, circle, text] = SelectedNodes.getNodeData(current_item); | ||
if(circle.style.fill == SelectedNodes.getSelectedColour()){ | ||
delete circle.dataset.oldfill; | ||
if(SelectedNodes.nodes.has(x)){ | ||
circle.dataset.oldfill = colours[colour_idx]; | ||
}else{ | ||
circle.style.fill = colours[colour_idx]; | ||
//current_item.setAttribute('data-color-hex', colours[colour_idx]) | ||
|
||
} | ||
|
||
}catch(error){ | ||
|
@@ -1586,7 +1599,7 @@ | |
reset_zoom_slider() | ||
return true; | ||
} | ||
console.log("No tree to redraw"); | ||
console.error("No tree to redraw"); | ||
}); | ||
|
||
// ! Below disables the right click menu for the page | ||
|
@@ -1683,11 +1696,12 @@ | |
METADATA = null; | ||
initialize_legend_menu(); | ||
$("#dropdown_legend").append(create_legend_elements(TABLE_HEADERS)); | ||
$("#table-splash").remove(); | ||
//$("#table-splash").remove(); | ||
//$("#table-splash").remove(); | ||
//$("#table-splash").remove(); | ||
} | ||
|
||
$("#metadata-selector").change((event) => { | ||
$("#table-splash").remove(); | ||
let reader = new FileReader(); | ||
let metadata_file = event.target.files[0]; | ||
|
||
|
@@ -1767,7 +1781,7 @@ | |
if(DEBUG){ | ||
console.log("Selected element", identified_point) | ||
} | ||
identified_point.childNodes[2].style.fill = "DodgerBlue"; | ||
identified_point.childNodes[2].style.fill = clicked_color; | ||
} | ||
|
||
let rect = identified_point.getBBox(); | ||
|
@@ -1784,7 +1798,9 @@ | |
}); | ||
|
||
$("#TreeData").on('scroll', '#TreeSVG', (evt) => { | ||
console.log("scrolling"); | ||
if(DEBUG){ | ||
console.log("scrolling"); | ||
} | ||
}); | ||
|
||
}); | ||
|
@@ -1879,15 +1895,8 @@ | |
document.querySelector('#zoom_slider').value = 1 | ||
} | ||
|
||
select_deselect_nodes_by_field_value = function(legend_node, column_index){ | ||
// TODO on deselect event not everything deselects alwasys | ||
let selected = false; | ||
if(legend_node.dataset.selected){ | ||
delete legend_node.dataset.selected | ||
}else{ | ||
selected = true; | ||
legend_node.dataset.selected = true | ||
} | ||
let select_deselect_nodes_by_field_value = (legend_node, column_index) => { | ||
|
||
//find indices of filtered data in a metadata table | ||
let indexes = data_table.rows( (idx, data, node) => { | ||
if(data[column_index] === `${legend_node.textContent}` ){ | ||
|
@@ -1896,34 +1905,39 @@ | |
return false | ||
} | ||
} ).indexes() | ||
|
||
let selected = legend_node.classList.contains('fw-bold') ? true : false | ||
|
||
if(!selected){ | ||
legend_node.classList.add('fw-bold'); | ||
}else{ | ||
legend_node.classList.remove('fw-bold'); | ||
} | ||
|
||
let selected_node_ids = data_table.cells(indexes,0).data(); | ||
for(var i = 0; i < selected_node_ids.length; i++) { | ||
|
||
// TODO need to batch select and deselct from this | ||
let tree_node = document.querySelector( `[id='${selected_node_ids[i]}']`) | ||
//let text = tree_node.lastChild | ||
//let circle = tree_node.querySelector('circle') | ||
let [ele, circle, text] = SelectedNodes.getNodeData(tree_node); | ||
//focus view on the last node in selection | ||
if(i === selected_node_ids.length-1 ){ | ||
tree_node.scrollIntoView({block: "center", inline:"center"}) | ||
} | ||
|
||
if(selected){ | ||
SelectedNodes.addNodes(tree_node); | ||
legend_node.classList.add('fw-bold') | ||
if(!selected){ | ||
if(circle.dataset.oldfill){ | ||
circle.dataset.oldfill = circle.style.fill; | ||
} | ||
SelectedNodes.addNodes(text); | ||
}else{ | ||
SelectedNodes.unselectNode(tree_node); | ||
legend_node.classList.remove('fw-bold') | ||
SelectedNodes.unselectNode(text); | ||
} | ||
} | ||
// Bring the terminal node into frame | ||
terminal_node = document.querySelector(`[id=${selected_node_ids[selected_node_ids.length-1]}`); | ||
terminal_node.scrollIntoView({block: "center", inline: "center"}) | ||
SelectedNodes.drawSelectedNodes(); | ||
|
||
} | ||
|
||
remove_selected_node = function(node_id){ | ||
let trg_node = SelectedNodes.nodes.get(node_id); | ||
console.log(trg_node); | ||
SelectedNodes.unselectNode(trg_node); | ||
SelectedNodes.drawSelectedNodes(); | ||
} | ||
|
@@ -1950,9 +1964,14 @@ | |
|
||
export_metadata_table = function(e){ | ||
// Export updated metadata | ||
|
||
console.log(e.id) | ||
if(!ORIGINAL_DATA){ | ||
console.error("No contextual data imported yet"); | ||
Swal.fire({ | ||
title: "Error", | ||
text: "No metadata table imported yet. Please upload data first!", | ||
icon: "error" | ||
}); | ||
return false; | ||
} | ||
let headers = Array.from(TABLE_HEADERS); | ||
|
@@ -1985,6 +2004,11 @@ | |
document.body.removeChild(elem); | ||
window.URL.revokeObjectURL(elem.href); // revoke object url as it wont be cleared till after the browser is closed otherwise | ||
} | ||
Swal.fire({ | ||
title: "Exported Metadata", | ||
text: `Exported ${output_text.length-1} rows of metadata saved in ${updated_metadata}`, | ||
icon: "info" | ||
}) | ||
return true; | ||
|
||
} | ||
|
@@ -2072,7 +2096,7 @@ | |
let pngUrl = canvas.toDataURL('image/png').replace('image/png', 'octet/stream'); | ||
//create download link | ||
let downloadLink = document.createElement("a"); | ||
downloadLink.download = 'tree_snapshot_png'; | ||
downloadLink.download = 'tree_snapshot.png'; | ||
downloadLink.href = pngUrl; | ||
downloadLink.click(); | ||
downloadLink.remove(); | ||
|
@@ -2127,6 +2151,7 @@ | |
clear_selected_nodes = function(){ | ||
// Clear selected nodes and un-bold legend text | ||
SelectedNodes.deselectNodes(); // deselect nodes | ||
SelectedNodes.clearNodes(); | ||
// a way to de colour all of these nodes probably exists | ||
$(".legend-element > .fw-bold").each((it, ele) => { | ||
ele.classList.remove("fw-bold"); | ||
|
@@ -2138,12 +2163,16 @@ | |
let text2copyArray=[] | ||
|
||
document.querySelectorAll('#SelectedNodes div>div:first-child').forEach(node => { | ||
console.log(node.textContent) | ||
if(DEBUG){ | ||
console.log(node.textContent) | ||
} | ||
text2copyArray.push(node.textContent) | ||
}) | ||
let text2copy = text2copyArray.join('\n'); | ||
let success_msg = `copied ${text2copyArray.length} sample IDs to the clipboard` | ||
console.log(text2copy) | ||
if(DEBUG){ | ||
console.log(text2copy); | ||
} | ||
let file = new File(["\ufeff"+text2copy], 'selectedNodes.txt', {type: "text/plain:charset=UTF-8"}) | ||
//create a ObjectURL in order to download the created file | ||
url = window.URL.createObjectURL(file); | ||
|
@@ -2220,13 +2249,13 @@ | |
<div id="tree_menu_buttons" class="row m-0"> | ||
<div class="d-flex flex-row align-items-center p-0 text-left mt-1"> | ||
<button class="h-100 flex-grow-1 me-1 btn-sm btn-primary text-break" data-toggle="tooltip" data-placement="top" | ||
title="Select a newick file" onclick="document.getElementById('tree-selector').click();" name="newick" id="copy-ids-button"> | ||
title="Select a newick file" onclick="document.getElementById('tree-selector').click();" name="newick" id="tree-upload-button"> | ||
<i class="bi bi-upload me-1"></i>Newick <i class="bi bi-tree ml-1"></i> | ||
</button> | ||
<input type="file" id="tree-selector" name="tree-selector" accept=".nwk, .newick, .treefile" hidden> | ||
<button class="h-100 flex-grow-1 btn-sm btn-primary text-break" data-toggle="tooltip" data-placement="top" | ||
title="Select a tab delimited metadata file" onclick="document.getElementById('metadata-selector').click();" | ||
id="export-tree-to-svg" id="metadata-selector" name="metadata-selector"> | ||
id="metadata-selector-input" name="metadata-selector-input"> | ||
<i class="bi bi-upload me-1"></i>Meta <i class="bi bi-file-spreadsheet ml-1"></i> | ||
</button> | ||
<input type="file" id="metadata-selector" | ||
|
@@ -2249,15 +2278,34 @@ | |
<i class="bi bi-download m-1"></i> PNG | ||
</button> | ||
</div> | ||
|
||
<button data-toggle="tooltip" data-placement="top" title="Export the entire metadata table below." | ||
class="flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" id="export-metadata-table"> | ||
<i class="bi bi-download me-1"></i> Export Full Table | ||
</button> | ||
<button data-toggle="tooltip" data-placement="top" title="Export the currently selected metadata." class="flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" id="export-metadata-view"> | ||
<i class="bi bi-download me-1"></i> Export Filtered Table | ||
</button> | ||
|
||
<div class="dropdown p-0"> | ||
<button class="w-100 flex-grow-1 mb-1 btn-sm btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> | ||
<i class="bi bi-download me-1"></i> Export Meta Table | ||
</button> | ||
<ul class="dropdown-menu"> | ||
<li><a id="export-metadata-view" data-toggle="tooltip" data-placement="top" title="Export the currently selected metadata." | ||
class="dropdown-item flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" id="export-metadata-view"> | ||
<i class="bi bi-download me-1"></i> Export Filtered Table | ||
</a> | ||
</li> | ||
<li><a id="export-metadata-table" data-toggle="tooltip" data-placement="top" title="Export the currently selected metadata." | ||
class="dropdown-item flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" id="export-metadata-view"> | ||
<i class="bi bi-download me-1"></i> Export Full Table | ||
</a> | ||
</li> | ||
</ul> | ||
|
||
<!--button data-toggle="tooltip" data-placement="top" title="Export the entire metadata table below." | ||
class="flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" id="export-metadata-table"> | ||
<i class="bi bi-download me-1"></i> Export Full Table | ||
</button> | ||
<button data-toggle="tooltip" data-placement="top" | ||
title="Export the currently selected metadata." | ||
class="flex-grow-1 me-1 btn-sm btn-primary text-break mb-1" onclick="export_metadata_table(this)" | ||
id="export-metadata-view"> | ||
<i class="bi bi-download me-1"></i> Export Filtered Table | ||
</button--> | ||
</div> | ||
<!--Tree layout slider--> | ||
<div class="d-flex flex-row align-items-center p-0 text-left"> | ||
<button data-toggle="tooltip" data-placement="top" title="Redraw the entire tree undoing any changes." | ||
|
@@ -2362,4 +2410,3 @@ | |
|
||
</body> | ||
</html> | ||
|