Skip to content

Commit

Permalink
First attempt at aces#316 - very preliminary annotation interface. Pr…
Browse files Browse the repository at this point in the history
…ovides only very basic text annotations at specific positions. Adds each text to a selection box, so that users may jump to individual annotation locations. Ctrl-A adds an annotation at the current cursor, Ctrl-B downloads the annotations.
  • Loading branch information
Robert D. Vincent committed Oct 3, 2016
1 parent 3286157 commit b42cd5b
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 3 deletions.
5 changes: 4 additions & 1 deletion examples/volume-viewer-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
<span class="slice-series-button button" data-axis="zspace">Transverse</span>
</div>

<span class="control-heading">Annotations:</span>
<select id='anno-list-{{VOLID}}'>
</select>
</div>
</script>
<script id="overlay-ui-template" type="x-volume-ui-template">
Expand Down Expand Up @@ -186,7 +189,6 @@
<input type="checkbox" class="button" id="sync-volumes"><label for="sync-volumes">Synchronize</label>
</span>
<span id="screenshot" class="button">Screenshot</span>

<div id="volume-file" class="file-select">
<h3><u>For MINC file:</u></h3>
<div>
Expand Down Expand Up @@ -236,6 +238,7 @@ <h3><u>For MGH file:</u></h3>
<script src="js/brainbrowser/volume-viewer/lib/utils.js"></script>
<script src="js/brainbrowser/volume-viewer/modules/loading.js"></script>
<script src="js/brainbrowser/volume-viewer/modules/rendering.js"></script>
<script src="js/brainbrowser/volume-viewer/modules/annotate.js"></script>
<script src="js/brainbrowser/volume-viewer/volume-loaders/overlay.js"></script>
<script src="js/brainbrowser/volume-viewer/volume-loaders/minc.js"></script>
<script src="js/brainbrowser/volume-viewer/volume-loaders/nifti1.js"></script>
Expand Down
3 changes: 1 addition & 2 deletions src/brainbrowser/volume-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,8 @@

// Space
if (key === 32) {
event.preventDefault();

if (volume.header.time) {
event.preventDefault();
if (event.shiftKey) {
time = Math.max(0, volume.current_time - 1);
} else {
Expand Down
176 changes: 176 additions & 0 deletions src/brainbrowser/volume-viewer/modules/annotate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* BrainBrowser: Web-based Neurological Visualization Tools
* (https://brainbrowser.cbrain.mcgill.ca)
*
* Copyright (C) 2011
* The Royal Institution for the Advancement of Learning
* McGill University
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Author: Robert D. Vincent <[email protected]>
*/

BrainBrowser.VolumeViewer.modules.annotate = function(viewerP) {
"use strict";
var viewer = viewerP;

console.log("Annotation module is loaded.");

// Add keyboard controls
addKeyboardControls();

// We use this for triggering downloads.
var elem = document.createElement('a');
elem.id = 'anno-download';
elem.style.display = 'none';
document.body.appendChild(elem);

function triggerUpdate(volume) {
volume.display.forEach(function(panel) {
panel.updateSlice();
});
}

function closeAnnotation() {
console.log('close');
var elem = document.getElementById('anno-box');
if (elem) {
document.body.removeChild(elem);
}
}

function saveAnnotation(text) {
if (!viewer.active_panel)
return;
var panel = viewer.active_panel;
var volume = panel.volume;
var annotation = {
position: volume.getWorldCoords(),
content: text
};
console.log('save');
if (typeof volume.annotations === "undefined") {
volume.annotations = []
}
volume.annotations.push(annotation);

var select = document.getElementById('anno-list-' + panel.volume_id);
var option = document.createElement('option');
option.text = text;
option.value = panel.volume_id + ':' + (volume.annotations.length - 1);
select.add(option);
}

function makeAnnotation() {
if (!viewer.active_panel)
return;
var panel = viewer.active_panel;
var canvas = panel.canvas;
var cursor = panel.getCursorPosition();
var newbox = document.createElement('div');
var x = cursor.x + canvas.offsetLeft;
var y = cursor.y + canvas.offsetTop;

newbox.style.backgroundColor = 'beige';
newbox.style.border = 'thin solid gray';
newbox.id = "anno-box";
newbox.style.position = "absolute";
newbox.style.top = y + 'px';
newbox.style.left = x + 'px';

var textarea = document.createElement('textarea');
textarea.id = 'anno-body';
//textarea.value = "x: " + x + " y: " + y;
textarea.style.width = '180pt';
textarea.style.display = 'block';
newbox.appendChild(textarea);

document.body.appendChild(newbox);

var elem = document.createElement('a');
elem.setAttribute('href', '#save');
elem.id = 'anno-save';
elem.style.display = 'inline-block';
elem.style.width = (newbox.offsetWidth / 2) + 'px';
elem.innerHTML = 'Save';
newbox.appendChild(elem);

elem = document.createElement('a');
elem.setAttribute('href', '#cancel');
elem.id = 'anno-cancel';
elem.style.display = 'inline-block';
elem.style.width = (newbox.offsetWidth / 2) + 'px';
elem.innerHTML = 'Cancel';
newbox.appendChild(elem);

// Save the note.
$('#anno-save').click(function() {
saveAnnotation(textarea.value);
closeAnnotation();
});

// Just close the note.
$('#anno-cancel').click(function() {
closeAnnotation();
});

$('#anno-list-' + panel.volume_id).click(function(e) {
console.log('click: ' + e.target.value);
var array = e.target.value.split(':');
var volume_id = parseInt(array[0]);
var n_anno = parseInt(array[1]);
var volume = viewer.volumes[volume_id];
var anno = volume.annotations[n_anno];
volume.setWorldCoords(anno.position.x, anno.position.y, anno.position.z);
triggerUpdate(volume);
});

$('#anno-list').change(function(e) {
console.log('change: ' + e.target.value);
});
}

function addKeyboardControls() {
document.addEventListener("keydown", function(event) {
var key = event.which;

var keys = {
65: function() {
makeAnnotation();
},
66: function() {
if (!viewer.active_panel)
return;
var panel = viewer.active_panel;
var volume = panel.volume;
var anno_str = JSON.stringify(volume.annotations, null, 2);
var data = "data:text/json;charset=utf-8," +
encodeURIComponent(anno_str);
var elem = document.getElementById('anno-download');
elem.setAttribute("href", data);
elem.setAttribute("download", "annotation.json");
elem.click();
}
};

if (typeof keys[key] === "function" && event.ctrlKey) {
event.preventDefault();
keys[key]();
}
});
}
}

0 comments on commit b42cd5b

Please sign in to comment.