Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move outline to glsl #92

Merged
merged 24 commits into from
May 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion minerva_analysis/client/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
data/
data/
.editorconfig
.eslintignore
.eslintrc.json
tsconfig.json
18 changes: 3 additions & 15 deletions minerva_analysis/client/dist/vendor_bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion minerva_analysis/client/src/css/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,4 @@
#gating_controls_panel input {
height: 11px;
margin: 1px 10px 0 5px;
}
}
37 changes: 23 additions & 14 deletions minerva_analysis/client/src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ d3.json(`/config?t=${Date.now()}`).then(function (config) {
async function init(conf) {

config = conf;
//maximum selections
config.maxSelections = 4;
config.extraZoomLevels = 3;
//channel information
for (let idx = 0; idx < config["imageData"].length; idx++) {
imageChannels[config["imageData"][idx].fullname] = idx;
Expand All @@ -57,24 +60,25 @@ async function init(conf) {
dataLayer = new DataLayer(config, imageChannels);
await dataLayer.init();

//init color scheme
colorScheme = new ColorScheme(dataLayer);
await colorScheme.init();

//init channel panel
channelList = new ChannelList(config, dataLayer, eventHandler);
await channelList.init();

//create image viewer
seaDragonViewer = new ImageViewer(config, dataLayer, channelList, eventHandler, colorScheme);

//init gating panel
csv_gatingList = new CSVGatingList(config, dataLayer, eventHandler);
await csv_gatingList.init();

//init color scheme
colorScheme = new ColorScheme(dataLayer);
await colorScheme.init();

//init image viewer
seaDragonViewer = new ImageViewer(config, dataLayer, eventHandler, colorScheme);
seaDragonViewer.init();
seaDragonViewer.init(csv_gatingList);
}


//EVENT HANDLING

/**
Expand All @@ -88,7 +92,6 @@ const actionColorTransferChange = (d) => {
// d3.select('body').style('cursor', 'progress');
seaDragonViewer.updateChannelColors(d.name, d.color, d.type);
// d3.select('body').style('cursor', 'default');
seaDragonViewer.csvGatingOverlay.draw();
}
eventHandler.bind(ChannelList.events.COLOR_TRANSFER_CHANGE, actionColorTransferChange);

Expand All @@ -112,7 +115,8 @@ const actionChannelsToRenderChange = (d) => {
d.name = dataLayer.getFullChannelName(d.name);

//send to image viewer
seaDragonViewer.updateActiveChannels(d.name, d.selections, d.status);
const action = ["remove", "add"][+d.status];
seaDragonViewer.updateActiveChannels(d.name, action);

d3.select('body').style('cursor', 'default');
}
Expand Down Expand Up @@ -140,19 +144,21 @@ eventHandler.bind(ImageViewer.events.imageClickedMultiSel, actionImageClickedMul
* @param {package object} d The selected/deselected channels
*/
const channelSelect = async (sels) => {
// pause new rendering until data loads
const resume = seaDragonViewer.sleep();
let channelCells = await dataLayer.getChannelCellIds(sels);
dataLayer.addAllToCurrentSelection(channelCells);
updateSeaDragonSelection(false);
updateSeaDragonSelection();
resume();
}
eventHandler.bind(ChannelList.events.CHANNEL_SELECT, channelSelect);

/**
* Listens to and updates based on selection changes (specific for seadragon)
* @param {boolean} d Whether to repaint
*/
function updateSeaDragonSelection(repaint = true) {
seaDragonViewer.updateSelection(dataLayer.getCurrentSelection(), repaint);
seaDragonViewer.csvGatingOverlay.evaluate();
function updateSeaDragonSelection() {
seaDragonViewer.updateSelection(dataLayer.getCurrentSelection());
}

/**
Expand All @@ -168,6 +174,8 @@ const gatingBrushEnd = async (packet) => {
this.config[datasource].featureData[0].xCoordinate,
this.config[datasource].featureData[0].yCoordinate
];
// pause new rendering until data loads
const resume = seaDragonViewer.sleep();
// Toggle these methods with centroids on/off ui
if (csv_gatingList.eval_mode === 'and') {
// AND
Expand All @@ -180,6 +188,7 @@ const gatingBrushEnd = async (packet) => {
dataLayer.addAllToCurrentSelection(gatedCells);
// Update view
updateSeaDragonSelection();
resume();
}
eventHandler.bind(CSVGatingList.events.GATING_BRUSH_END, gatingBrushEnd);

Expand Down Expand Up @@ -207,4 +216,4 @@ const add_scalebar = () => {
seaDragonViewer.addScaleBar();
seaDragonViewer.forceRepaint();
}
eventHandler.bind(ImageViewer.events.addScaleBar, add_scalebar);
eventHandler.bind(ImageViewer.events.addScaleBar, add_scalebar);
2 changes: 0 additions & 2 deletions minerva_analysis/client/src/js/vendor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import 'viawebgl'
import * as viaWebGL from 'viawebgl';
import {ViewerManager} from './views/viewerManager';
import Dropzone from 'dropzone';
import {CsvGatingOverlay} from './views/CsvGatingOverlay';

window.convert = convert;
window.$ = $;
Expand All @@ -32,7 +31,6 @@ window.Sortable = Sortable;
window.Mark = Mark;
window.OpenSeadragon = viaWebGL.OpenSeadragon;
window.Dropzone = Dropzone;
window.CsvGatingOverlay = CsvGatingOverlay;
window.viaWebGL = viaWebGL;
window.ViewerManager = ViewerManager;

4 changes: 2 additions & 2 deletions minerva_analysis/client/src/js/views/channelList.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ class ChannelList {
*/
constructor(config, dataLayer, eventHandler) {
this.config = config;
this.maxSelections = config.maxSelections;
this.eventHandler = eventHandler;
this.dataLayer = dataLayer;
this.selections = [];
this.maxSelections = 4;
this.ranges = {};
this.sliders = new Map();
var that = this;
Expand Down Expand Up @@ -713,4 +713,4 @@ ChannelList.events = {
CHANNELS_CHANGE: "CHANNELS_CHANGE",
CHANNEL_SELECT: "CHANNEL_SELECT",
RESET_LISTS: "RESET_LISTS"
};
};
2 changes: 1 addition & 1 deletion minerva_analysis/client/src/js/views/channelMatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,4 @@ function swapNodes(n1, n2) {
}
p1.insertBefore(n2, p1.children[i1]);
p2.insertBefore(n1, p2.children[i2]);
}
}
54 changes: 29 additions & 25 deletions minerva_analysis/client/src/js/views/csvGatingList.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ class CSVGatingList {
*/
constructor(config, dataLayer, eventHandler) {
this.config = config;
this.waiting = Promise.resolve(true);
this.maxSelections = config.maxSelections;
this.eventHandler = eventHandler;
this.dataLayer = dataLayer;
this.selections = {};
this.maxSelections = 4;
this.ranges = {};
this.hasGatingGMM = {};
this.gatingIDs = {};
Expand All @@ -40,18 +41,11 @@ class CSVGatingList {
* @param name - the channel to set and display as selected
*/
selectChannel(name) {
// For overlay (and query incrementor)
// seaDragonViewer.csvGatingOverlay.run_balancer++;

if (!(name in this.hasGatingGMM)) {
let channelTrace = this.getAndDrawGatingGMM(name);
}

// Add
this.selections[this.dataLayer.getFullChannelName(name)] = this.sliders.get(name).value();

// Trigger
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
this.awaitGatingGMM(name).then(() => {
const fullName = this.dataLayer.getFullChannelName(name);
this.selections[fullName] = this.sliders.get(name).value();
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
});
}

/**
Expand Down Expand Up @@ -169,7 +163,11 @@ class CSVGatingList {
autoBtn.classList.add('auto-btn');
autoBtn.setAttribute('id', "auto-btn_" + channelID);
autoBtn.textContent = "auto";
autoBtn.addEventListener("click", async function() { await self.autoGate(fullName) });
autoBtn.addEventListener("click", async () => {
const shortName = self.dataLayer.getShortChannelName(fullName);
await self.awaitGatingGMM(shortName);
self.autoGate(shortName);
});

autoCol.appendChild(autoBtn);
autoBtn.addEventListener("click", e => e.stopPropagation());
Expand Down Expand Up @@ -303,22 +301,20 @@ class CSVGatingList {
* @function autoGate - applies thresholds based on Gaussian Mixture Model
* @param name - the name of the channel to apply it to
*/
async autoGate(name) {
autoGate(shortName) {
const self = this;
let shortName = self.dataLayer.getShortChannelName(name);

let gate = this.hasGatingGMM[shortName]['gate']
let gate = this.hasGatingGMM[shortName].gate;
if (!this.dataLayer.isTransformed()) {
gate = parseInt(gate)
} else {
gate = gate.toFixed(7);
}
// For interaction
self.selections[name][0] = gate;
let gate_end = self.selections[name][1]
self.selections[shortName][0] = gate;
let gate_end = self.selections[shortName][1]
self.sliders.get(shortName).value([gate, gate_end]);
// For records
this.gating_channels[name] = [gate, gate_end];
this.gating_channels[shortName] = [gate, gate_end];

this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, self.selections);
}
Expand Down Expand Up @@ -506,6 +502,7 @@ class CSVGatingList {
// Toggle outlined / filled cell selections
gating_controls_outlines.addEventListener('change', e => {
seaDragonViewer.viewerManagerVMain.sel_outlines = e.target.checked;
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
})

// Toggle outlined / filled cell selections
Expand All @@ -521,8 +518,7 @@ class CSVGatingList {
this.eval_mode = 'and';
}

// Update overlay centroid (will also trigger event)
seaDragonViewer.csvGatingOverlay.control(e.target.checked);
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
})

}
Expand Down Expand Up @@ -741,6 +737,14 @@ class CSVGatingList {
this.drawGatingGMM(name);
}

awaitGatingGMM(name) {
if (!(name in this.hasGatingGMM)) {
const waiting = this.getAndDrawGatingGMM(name)
this.waiting = Promise.all([this.waiting, waiting]);
}
return this.waiting;
}

drawGatingGMM(name){
let fullname = this.dataLayer.getFullChannelName(name);
let channelID = this.gatingIDs[name];
Expand Down Expand Up @@ -849,7 +853,7 @@ window.addEventListener("resize", function () {
csv_gatingList.addSlider(name, document.getElementById("csv_gating_list").getBoundingClientRect().width,
sliderRange, slider.value());
if (csv_gatingList.hasGatingGMM[name]) {
let channelTrace = csv_gatingList.drawGatingGMM(name);
csv_gatingList.drawGatingGMM(name);
}
});
}
Expand Down Expand Up @@ -878,4 +882,4 @@ CSVGatingList
GATING_COLOR_TRANSFER_CHANGE_MOVE: "GATING_TRANSFER_CHANGE_MOVE",
GATING_COLOR_TRANSFER_CHANGE: "GATING_TRANSFER_CHANGE",
GATING_CHANNELS_CHANGE: "GATING_CHANNELS_CHANGE"
};
};
Loading