Undo selection appends genes from differential expression to user gene list (#1183)

* Undo selection appends diffExp genes to user gene list

Fixes https://github.com/chanzuckerberg/cellxgene/issues/1171

Need: When a user performs a differential expression from within
a sub-selection (world) of the data and then resets the selection to all
cells (universe), the differential expression results are no longer
valid.

Approach:
* When the selection is reset, move the top (maxUserDefinedGenes
- len(userDefinedGenes) from the differential expression results to the
list of user defined genes
* Raise maxUserDefinedGenes to 25 to give users more room and
accommodate the extra genes transferred in from differential expression

Other commits:
* Choose different button icons
* Add diff exp genes to user defined genes on subset too
* Respond to feedback from @liaprins-czi and @bkmartinjr
This commit is contained in:
Matt Weiden
2020-03-02 12:07:12 -08:00
committed by GitHub
parent 87efcc0e99
commit 05323ae643
15 changed files with 231 additions and 246 deletions
+46 -17
View File
@@ -1,5 +1,6 @@
import {DEBUG, DEV} from "./config";
import puppeteer from "puppeteer";
import { strict as assert } from "assert";
export const puppeteerUtils = puppeteerPage => ({
async waitByID(testid, props = {}) {
@@ -16,7 +17,7 @@ export const puppeteerUtils = puppeteerPage => ({
);
},
async waitForAllByIds(testids, props = {}) {
async waitForAllByIds(testids) {
await Promise.all(
testids.map(testid =>
puppeteerPage.waitForSelector(`[data-testid='${testid}']`)
@@ -24,19 +25,16 @@ export const puppeteerUtils = puppeteerPage => ({
);
},
async getAllByClass(testclass, props = {}) {
async getAllByClass(testclass) {
const elements = await puppeteerPage.$$eval(
`[data-testclass=${testclass}]`,
els => {
return els.map(el => {
return el.dataset.testid;
});
}
eles => eles.map(ele => ele.dataset.testid)
);
return elements;
},
async typeInto(testid, text) {
// blueprint's typeahead is treating typing weird, clicking & waiting first solves this
// only works for text without special characters
await this.waitByID(testid);
const selector = `[data-testid='${testid}']`;
@@ -80,6 +78,7 @@ export const puppeteerUtils = puppeteerPage => ({
});
export const cellxgeneActions = puppeteerPage => ({
async drag(testid, start, end, lasso = false) {
const layout = await puppeteerUtils(puppeteerPage).waitByID(testid);
const elBox = await layout.boxModel();
@@ -116,7 +115,7 @@ export const cellxgeneActions = puppeteerPage => ({
testclass
);
return allHistograms.map(hist =>
hist.substr("histogram_".length, hist.length)
hist.substr("histogram-".length, hist.length)
);
},
@@ -196,9 +195,7 @@ export const cellxgeneActions = puppeteerPage => ({
await puppeteerUtils(puppeteerPage).clickOn(`${category}:category-expand`);
await puppeteerUtils(puppeteerPage).clickOn(`${category}:category-select`);
for (const val of values) {
await puppeteerUtils(puppeteerPage).clickOn(
`categorical-value-select-${category}-${val}`
);
await puppeteerUtils(puppeteerPage).clickOn(`categorical-value-select-${category}-${val}`);
}
},
@@ -210,12 +207,6 @@ export const cellxgeneActions = puppeteerPage => ({
}
},
async reset() {
await puppeteerUtils(puppeteerPage).clickOn("reset");
// loading state never actually happens, reset is too fast
await page.waitFor(200);
},
async clip(min = 0, max = 100) {
await puppeteerUtils(puppeteerPage).clickOn("visualization-settings");
await puppeteerUtils(puppeteerPage).clearInputAndTypeInto(
@@ -269,6 +260,44 @@ export const cellxgeneActions = puppeteerPage => ({
newLabelName
);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:${oldLabelName}:submit-label-edit`);
},
async addGeneToSearch(geneName) {
await puppeteerUtils(puppeteerPage).typeInto("gene-search", geneName);
await puppeteerPage.keyboard.press("Enter");
await puppeteerPage.waitForSelector(
`[data-testid='histogram-${geneName}']`
);
},
async subset(coordinatesAsPercent) {
// In order to deselect the selection after the subset, make sure we have some clear part
// of the scatterplot we can click on
assert(coordinatesAsPercent.x2 < 0.99 || coordinatesAsPercent.y2 < 0.99);
const lassoSelection = await this.calcDragCoordinates( "layout-graph", coordinatesAsPercent);
await this.drag("layout-graph", lassoSelection.start, lassoSelection.end, true );
await puppeteerUtils(puppeteerPage).clickOn("subset-button");
const clearCoordinate = await this.calcCoordinate(
"layout-graph",
0.5,
0.99
);
await this.clickOnCoordinate("layout-graph", clearCoordinate);
},
async setSellSet(cellSet, cellSetNum) {
for (const selection of cellSet) {
if (selection.kind === "categorical") {
await this.selectCategory(selection.metadata, selection.values, true);
}
}
await this.cellSet(cellSetNum);
},
async runDiffExp(cellSet1, cellSet2) {
await this.setSellSet(cellSet1, 1);
await this.setSellSet(cellSet2, 2);
await puppeteerUtils(puppeteerPage).clickOn("diffexp-button");
}
});