-
Notifications
You must be signed in to change notification settings - Fork 302
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 #568 from camicroscope/develop
For 3.10.0
- Loading branch information
Showing
11 changed files
with
302 additions
and
31 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 |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<script src="../../core/Store.js"></script> | ||
<title>Export Results [caMicroscope]</title> | ||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous"> | ||
<style> | ||
body{ | ||
padding:20px; | ||
} | ||
#output{ | ||
padding: 20px; | ||
} | ||
span{ | ||
display:inline-block; | ||
} | ||
.form-check-input{ | ||
padding:5px !important; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h1>Export Results</h1> | ||
<div class="form"> | ||
<label for="slide_id">Slide Ids (exact matches, comma delimited):</label> | ||
<input type="text" id="slide_id" name="slide_id"><br> | ||
|
||
<button id="populate_btn" onclick="populateList()" type="button">Get List of Results</button> | ||
|
||
</div> | ||
<br><br> | ||
<h3>Select Results</h3> | ||
<div id="output"></div> | ||
<button id="convert_btn" onclick="downloadResults()" type="button">Download Selected Results</button> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script> | ||
<script src="//code.jquery.com/jquery.min.js"></script> | ||
<script src="./tree_table.js"></script> | ||
<script src="./export.js"></script> | ||
</body> | ||
</html> |
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 |
---|---|---|
@@ -0,0 +1,158 @@ | ||
const store = new Store('../../data/'); | ||
|
||
async function populateList() { | ||
// clear any previous | ||
document.getElementById('output').innerHTML = ''; | ||
console.log('populating list...'); | ||
nameField = 'name'; | ||
// get slide and associated result information | ||
let slides = []; | ||
let results = {}; | ||
let slideList = document.getElementById('slide_id').value; | ||
slideList = slideList.replace(/\s+/g, ''); | ||
slideList = slideList.split(','); | ||
for (let id of slideList) { | ||
let slide = await store.getSlide(id); | ||
slide = slide[0]; | ||
if (slide && slide['_id']) { | ||
let s = {'id': slide['_id']['$oid'], 'name': slide['name'], 'type': 'slide', 'raw': slide}; | ||
console.log(s); | ||
slides.push(s); | ||
// get associated result types | ||
r = []; | ||
for (let a of await store.findMarkTypes(slide['_id']['$oid'], 'computer')) { | ||
console.log(a); | ||
r.push({'id': a['execution_id'], 'name': a['name'], 'type': 'computer mark'}); | ||
} | ||
for (let a of await store.findMarkTypes(slide['_id']['$oid'], 'human')) { | ||
console.log(a); | ||
r.push({'id': a['_id']['analysis']['execution_id'], 'name': a['_id']['analysis']['name'], 'type': 'human mark'}); | ||
} | ||
// todo -- is this right for heatmapType results? | ||
for (let a of await store.findHeatmapType(slide['_id']['$oid'])) { | ||
r.push({'id': a['provenance']['analysis']['execution_id'], | ||
'name': a['provenance']['analysis']['execution_id'], 'type': 'heatmap'}); | ||
} | ||
results[slide['_id']['$oid']] = r; | ||
} | ||
} | ||
|
||
let headers = ['name', 'id', 'type']; | ||
let t = document.createElement('table'); | ||
t.id = 'tree-table'; | ||
t.classList.add('table', 'table-hover', 'table-bordered'); | ||
// add headers | ||
let table = document.createElement('tbody'); | ||
let headerTr = document.createElement('tr'); | ||
for (let z of headers) { | ||
let th = document.createElement('th'); | ||
th.innerText = z || '?'; | ||
headerTr.appendChild(th); | ||
} | ||
// add select header special | ||
let selectTh = document.createElement('th'); | ||
selectTh.innerText = 'Select'; | ||
headerTr.appendChild(selectTh); | ||
table.append(headerTr); | ||
// populate results | ||
for (let x of slides) { | ||
let parent = document.createElement('tr'); | ||
parent.setAttribute('data-id', x.id); | ||
parent.setAttribute('data-parent', 0); | ||
parent.setAttribute('data-level', 1); | ||
for (let z of headers) { | ||
let d = document.createElement('td'); | ||
d.innerText = x[z] || '?'; | ||
if (z==nameField) { | ||
d.setAttribute('data-column', 'name'); | ||
} | ||
parent.appendChild(d); | ||
} | ||
// add special checkbox | ||
parentCheck = document.createElement('input'); | ||
parentCheck.classList.add('form-check-input'); | ||
parentCheck.type = 'checkbox'; | ||
parentCheck.indeterminate = true; // cool! | ||
// TODO -- finish this. you'd want to add logic that sets this checkbox to true, false or indeterminate | ||
// depending on children selection. also select/deselect all children on change of this. | ||
// parent.appendChild(parentCheck); | ||
table.appendChild(parent); | ||
for (let y of results[x.id]) { | ||
console.log(x.raw); | ||
let child = document.createElement('tr'); | ||
child.setAttribute('data-id', x.id+'-'+y.id); | ||
child.setAttribute('data-parent', x.id); | ||
child.setAttribute('data-level', 2); | ||
for (let z of headers) { | ||
let d = document.createElement('td'); | ||
d.innerText = y[z] || '?'; | ||
if (z==nameField) { | ||
d.setAttribute('data-column', 'name'); | ||
} | ||
child.appendChild(d); | ||
} | ||
// special checkbox | ||
childCheck = document.createElement('input'); | ||
childCheck.type = 'checkbox'; | ||
childCheck.classList.add('form-check-input'); | ||
childCheck.classList.add('result'); | ||
childCheck.setAttribute('data-target', x.id); | ||
childCheck.setAttribute('data-self', y.id); | ||
childCheck.setAttribute('data-slideInfo', JSON.stringify(x.raw)); | ||
childCheck.setAttribute('data-type', y.type); | ||
childCheck.checked = true; | ||
child.appendChild(childCheck); | ||
table.appendChild(child); | ||
} | ||
} | ||
t.appendChild(table); | ||
document.getElementById('output').appendChild(t); | ||
makeTreeTable('tree-table'); | ||
} | ||
|
||
async function downloadResults() { | ||
let checks = document.querySelectorAll('.result:checked'); | ||
let marks = []; | ||
let heatmaps = []; | ||
for (let c of checks) { | ||
console.log(c.dataset); | ||
let parentSlide = JSON.parse(checks[0].dataset.slideinfo); | ||
if (c.dataset.type == 'human mark' || c.dataset.type == 'human mark') { | ||
let mark = await store.getMarkByIds([c.dataset.self], c.dataset.target); | ||
for (m of mark) { | ||
m.provenance.image = parentSlide; | ||
marks.push(m); | ||
} | ||
console.log(mark); | ||
} else if (c.dataset.type == 'heatmap' ) { | ||
let hm = await store.getHeatmap(c.dataset.parent, c.dataset.target); | ||
for (h of hm) { | ||
h.provenance.image = parentSlide; | ||
heatmaps.push(h); | ||
} | ||
} | ||
} | ||
console.log(marks, heatmaps); | ||
if (marks.length) { | ||
var element = document.createElement('a'); | ||
element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(marks))); | ||
element.setAttribute('download', 'camic_export_marks.json'); | ||
element.style.display = 'none'; | ||
document.body.appendChild(element); | ||
element.click(); | ||
document.body.removeChild(element); | ||
} | ||
if (heatmaps.length) { | ||
var element = document.createElement('a'); | ||
element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(heatmaps))); | ||
element.setAttribute('download', 'camic_export_heatmaps.json'); | ||
element.style.display = 'none'; | ||
document.body.appendChild(element); | ||
element.click(); | ||
document.body.removeChild(element); | ||
} | ||
// tell the user that data is missing | ||
if (!heatmaps.length && !marks.length) { | ||
alert('No data selected for download.'); | ||
} | ||
} |
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
File renamed without changes.
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 |
---|---|---|
@@ -0,0 +1,64 @@ | ||
function makeTreeTable(id) { | ||
var | ||
$table = $('#' + id); | ||
var rows = $table.find('tr'); | ||
|
||
rows.each(function(index, row) { | ||
var | ||
$row = $(row); | ||
var level = $row.data('level'); | ||
var id = $row.data('id'); | ||
var $columnName = $row.find('td[data-column="name"]'); | ||
var children = $table.find('tr[data-parent="' + id + '"]'); | ||
|
||
if (children.length) { | ||
var expander = $columnName.prepend('' + | ||
'<span class="treegrid-expander glyphicon glyphicon-chevron-right">▼</span>' + | ||
''); | ||
|
||
children.hide(); | ||
|
||
expander.on('click', function(e) { | ||
var $target = $(e.target); | ||
if ($target.hasClass('glyphicon-chevron-right')) { | ||
$target | ||
.removeClass('glyphicon-chevron-right') | ||
.addClass('glyphicon-chevron-down'); | ||
|
||
children.show(); | ||
} else { | ||
$target | ||
.removeClass('glyphicon-chevron-down') | ||
.addClass('glyphicon-chevron-right'); | ||
|
||
reverseHide($table, $row); | ||
} | ||
}); | ||
} | ||
|
||
$columnName.prepend('' + | ||
'<span class="treegrid-indent" style="width:' + 25 * level + 'px"></span>' + | ||
''); | ||
}); | ||
|
||
// Reverse hide all elements | ||
reverseHide = function(table, element) { | ||
var | ||
$element = $(element); | ||
var id = $element.data('id'); | ||
var children = table.find('tr[data-parent="' + id + '"]'); | ||
|
||
if (children.length) { | ||
children.each(function(i, e) { | ||
reverseHide(table, e); | ||
}); | ||
|
||
$element | ||
.find('.glyphicon-chevron-down') | ||
.removeClass('glyphicon-chevron-down') | ||
.addClass('glyphicon-chevron-right'); | ||
|
||
children.hide(); | ||
} | ||
}; | ||
} |
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 |
---|---|---|
|
@@ -64,6 +64,9 @@ | |
<li class="nav-item link"> | ||
<a class="nav-link" href="./dev-workbench/workbench.html"> <i class="fas fa-pencil-ruler"></i> Workbench</a> | ||
</li> | ||
<li class="nav-item link"> | ||
<a class="nav-link" href="./port/export.html"> <i class="fas fa-solid fa-file-export"></i> Export</a> | ||
</li> | ||
<li class="nav-item link" style="font-family: sans-serif;"> | ||
<a class="nav-link" href="./signup/signup.html"> <i class="fas fa-user-plus"></i> Signup</a> | ||
</li> | ||
|
@@ -136,7 +139,7 @@ <h1 class="h1">caMicroscope</h1> | |
onclick="(()=>{location.reload();return false;})()"> <i class="fas fa-sync-alt"></i> | ||
Reload</button> | ||
</div> | ||
<div> | ||
<div> | ||
<div id="slideUploadButton" class="btn-group float-right pl-md-2 pt-2"> | ||
<button type="button" class="btn btn-primary " data-bs-toggle="modal" | ||
data-bs-target="#upload-dialog" onclick="hidePostButton(); hideCheckButton(); resetUploadForm();" > <i class="fas fa-upload"></i> Upload</button> | ||
|
@@ -149,12 +152,12 @@ <h1 class="h1">caMicroscope</h1> | |
</div> | ||
</div> | ||
</div> | ||
|
||
|
||
</div> | ||
</div> | ||
</div> | ||
|
||
|
||
|
||
<div class="modal fade" id="upload-dialog" tabindex="-1" role="dialog" | ||
|
@@ -285,7 +288,7 @@ <h5 class="modal-title" id="slideNameChangeModalLabel">Slide name change confirm | |
</div> | ||
</div> | ||
</div> | ||
<!-- popup --> | ||
<!-- popup --> | ||
<div id="popup-container"></div> | ||
</div> | ||
|
||
|
@@ -295,7 +298,7 @@ <h5 class="modal-title" id="slideNameChangeModalLabel">Slide name change confirm | |
<footer class="text-center text-white bg-dark p-3"> | ||
<p class="p">Copyright © 2021 caMicroscope</p> | ||
</footer> | ||
|
||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script> | ||
<script src="./table.js"></script> | ||
</body> | ||
|
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
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
Oops, something went wrong.