mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-24 06:28:12 +08:00
* icons, partway * redux for values * onChange * cancel * annotations lifecycle for category names * copy categorical * edit category * add Dataframe.withColsFrom * render user annotations; default add/delete annotation category * add label name to actions * category name edit * error checking improvements * change schema field isUserAnnotation to writable * always have an unassigned label; implement delete label * implement add new label and edit label name * label current cell selection * fix select exact bug in crossfilter * clean up categorical reducer * fix tests * remove debugging printf * implement subset/reset for user annotations * undo redo support for user annotations * remove duplicate button from categories * add modal * remove obsolete duplicate annotation reducers * remove old debugging printf * connect modal to annotation create and dup * initial full-stack wiring * finish up end-to-end wiring * fix existing unit tests * fix pytests to match new schema API * remove debugging printfs * add label file rotation * remove obsolete comment * add fbs encode/decode tests * add tests for writable annotations * simplify code * fix hashing bug with FBS encoding * lint * fix smoke tests * improve error checking in Dataframe.withColsFrom * add unit test for Dataframe.withColsFrom * add unit test for Dataframe.columns and Dataframe.renameCol * fix bug in FBS encode, add better error checks, refactor * add FBS encode/decode test * add clarifying comment * clean up action type names; fix state inconsistency in crossfilter update * change autosave timer to 2.5sec * sort categorical metadata render order so it remains consistent * add temporary autogenerated label for add-new-label operation * fix hover-over label menu interference with cell highlighting * remove debugging code * add missing reducer cases & fix typo * make dataframe memoize more general purpose * add dev mode for annos * fix error on select duplicate * handle zero occupancy categories * correctly maintain unclipped AND clipped world * correctly handle zero length FBS matrix and label files * ensure all writable categorical schema contains an unassigned category * handle case where building occupancy stack for category with no members * dialog for creating label, disable button if duplicate or empty * visually separate writeable * edit category * fix edit category name * remove debugging code * fix edit annotation label * visually define unassigned, change options * Pull in requirements.txt from `master` * label currently selected cells * duplicate label * lint * fix pytest merge issues * rename --label-file to --experimental-label-file * remove debugging console log * spelling error fix; fix bug found in PR review. * lint
191 lines
4.7 KiB
JavaScript
191 lines
4.7 KiB
JavaScript
// jshint esversion: 6
|
|
|
|
import _ from "lodash";
|
|
|
|
import { WorldUtil } from "../util/stateManager";
|
|
|
|
const Controls = (
|
|
state = {
|
|
// data loading flag
|
|
loading: true,
|
|
error: null,
|
|
|
|
// all of the data + selection state
|
|
userDefinedGenes: [],
|
|
userDefinedGenesLoading: false,
|
|
diffexpGenes: [],
|
|
|
|
resettingInterface: false,
|
|
graphInteractionMode: "select",
|
|
opacityForDeselectedCells: 0.2,
|
|
scatterplotXXaccessor: null, // just easier to read
|
|
scatterplotYYaccessor: null,
|
|
graphRenderCounter: 0 /* integer as <Component key={graphRenderCounter} - a change in key forces a remount */,
|
|
__storedStateForCelllist1__: null /* will need procedural control of brush ie., brush.extent https://bl.ocks.org/micahstubbs/3cda05ca68cba260cb81 */,
|
|
__storedStateForCelllist2__: null
|
|
},
|
|
action,
|
|
nextSharedState,
|
|
prevSharedState
|
|
) => {
|
|
/*
|
|
For now, log anything looking like an error to the console.
|
|
*/
|
|
if (action.error || /error/i.test(action.type)) {
|
|
console.error(action.error);
|
|
}
|
|
|
|
switch (action.type) {
|
|
/*****************************************************
|
|
Initialization, World/Universe management
|
|
and data loading.
|
|
******************************************************/
|
|
case "initial data load start": {
|
|
return { ...state, loading: true };
|
|
}
|
|
case "initial data load complete (universe exists)": {
|
|
/* first light - create world & other data-driven defaults */
|
|
WorldUtil.clearCaches();
|
|
return {
|
|
...state,
|
|
loading: false,
|
|
error: null,
|
|
resettingInterface: false
|
|
};
|
|
}
|
|
case "reset World to eq Universe": {
|
|
WorldUtil.clearCaches();
|
|
return {
|
|
...state,
|
|
resettingInterface: false
|
|
};
|
|
}
|
|
case "set World to current selection": {
|
|
WorldUtil.clearCaches();
|
|
return {
|
|
...state,
|
|
loading: false,
|
|
error: null
|
|
};
|
|
}
|
|
case "request user defined gene started": {
|
|
return {
|
|
...state,
|
|
userDefinedGenesLoading: true
|
|
};
|
|
}
|
|
case "request user defined gene error": {
|
|
return {
|
|
...state,
|
|
userDefinedGenesLoading: false
|
|
};
|
|
}
|
|
case "request user defined gene success": {
|
|
const { userDefinedGenes } = state;
|
|
const _userDefinedGenes = _.uniq(
|
|
userDefinedGenes.concat(action.data.genes)
|
|
);
|
|
return {
|
|
...state,
|
|
userDefinedGenes: _userDefinedGenes,
|
|
userDefinedGenesLoading: false
|
|
};
|
|
}
|
|
case "request differential expression success": {
|
|
const { world } = prevSharedState;
|
|
const varIndexName = world.schema.annotations.var.index;
|
|
const _diffexpGenes = [];
|
|
action.data.forEach(d => {
|
|
_diffexpGenes.push(world.varAnnotations.at(d[0], varIndexName));
|
|
});
|
|
return {
|
|
...state,
|
|
diffexpGenes: _diffexpGenes
|
|
};
|
|
}
|
|
case "clear differential expression": {
|
|
return {
|
|
...state,
|
|
diffexpGenes: []
|
|
};
|
|
}
|
|
case "clear user defined gene": {
|
|
const { userDefinedGenes } = state;
|
|
const newUserDefinedGenes = _.filter(
|
|
userDefinedGenes,
|
|
d => d !== action.data
|
|
);
|
|
return {
|
|
...state,
|
|
userDefinedGenes: newUserDefinedGenes
|
|
};
|
|
}
|
|
case "clear all user defined genes": {
|
|
return {
|
|
...state,
|
|
userDefinedGenes: []
|
|
};
|
|
}
|
|
case "expression load error":
|
|
case "initial data load error": {
|
|
return {
|
|
...state,
|
|
loading: false,
|
|
error: action.error
|
|
};
|
|
}
|
|
|
|
/*******************************
|
|
User Events
|
|
*******************************/
|
|
case "change graph interaction mode":
|
|
return {
|
|
...state,
|
|
graphInteractionMode: action.data
|
|
};
|
|
case "change opacity deselected cells in 2d graph background":
|
|
return {
|
|
...state,
|
|
opacityForDeselectedCells: action.data
|
|
};
|
|
case "increment graph render counter": {
|
|
const c = state.graphRenderCounter + 1;
|
|
return {
|
|
...state,
|
|
graphRenderCounter: c
|
|
};
|
|
}
|
|
case "interface reset started": {
|
|
return {
|
|
...state,
|
|
resettingInterface: true
|
|
};
|
|
}
|
|
|
|
/*******************************
|
|
Scatterplot
|
|
*******************************/
|
|
case "set scatterplot x":
|
|
return {
|
|
...state,
|
|
scatterplotXXaccessor: action.data
|
|
};
|
|
case "set scatterplot y":
|
|
return {
|
|
...state,
|
|
scatterplotYYaccessor: action.data
|
|
};
|
|
case "clear scatterplot":
|
|
return {
|
|
...state,
|
|
scatterplotXXaccessor: null,
|
|
scatterplotYYaccessor: null
|
|
};
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
export default Controls;
|