centroid labels (#872)

* refactor reducer to no longer support hover state and hold many labels

* refactor to generate centroidCoordinates for all values of a category

* create hash for function and memoize export

* create button to display all labels for a category

* clear state

* create label for each thing

* calculate on each value

* change to in place modification of map

* switch to for loop with iterator instead of forEach

* use map from centroidLabel instead of creating copy

* adapt for map

* utilize tarrays

* begin documentation

* disable centroids if in zoom mode

* clean up

* persist uncalc coordinates

* document

* clean up and document

* cleanup and document

* fix

* fix undefined labels and document changes

* fix first element skip

* fix conditional recalc

* rename centroidLabel -> centroidLabels

* break out dilation on hover to new reducer

* numerous styling changes for readability

* change centroid icon

* remove colorAccessor from parameters

* recalc centroids on world change

* make label toggle undoable

* remove unused import

* highlight labels on hover

* remove special characters from svg id

* lighten backdrop

* only generate new centroids if they pre-exist

* fix issue with spaces in catagorical value name

* add label buttons to menubar

* change reducer to use colorAccessor and have single toggle

* fix check to see if svg should be rendered

* move svg overlays onto a single svg layer

* dilate on label hover

* remove logs

* allow centroid to update along side regl renders

* allow actions to pass through svg if in zoom mode

* remove artifact from circle

* remove comment

* remove disabling of centroid button

* fix conditional map to screen

* make styling label conditions stricter

* prettier

* refactor onto master

* refactor computePointFlags() to use pointDilation store

* notify when viewport changes

* move svg attributes out of lasso setup and prevent rerenders/writes

* begin playing with transform matrix

* first solution for camera interaction

* create transform using nested groups

* semi-working method using nested groups with transforms

* inversely scale text

* properly do final transform

* cleanup dead / test code

* reinstate original functionality

* breakout centroid labels labels into separate component

* default toggle on for testing

* separate lasso and centroid layers

* remove unnecessary attributes, working hover

* dilation on label hover

* fix dilation on scatterplot

* add dilation on label hover

* break overlay into separate component

* make overlay agnostic to children

* move label mouse actions to centroidlabels component, add overlay state

* remove lasso on switch to camera

* disallow user selection

* fix reducer

* fix subset with continuous color error

* reset labels on color by continuous

* revert centroids on by default

* refactor for nested restructuring

* remove update checking

* remove unused method

* readd deleted hover delay

* remove old centroid setup

* remove centroid from undoable

* cleanup dead code

* remove dead code

* rollback unnecessary changes

* begin adding annotation functionality

* add annotation functionality

* add reset and undo functionality

* change centroids on layout change

* don't create label for unassigned

* add comment pointing out POI for performance

* touch up matrix transform comment

* add comment explaining coordinate space and children's assumed space

* remove dead code

* switch to pure component

* connect centroidLabels to redux

* clean up camera check and null result

* tool tip change

* rename centroid toggle and the like

* fix the misalignment of buttons, also make blueprint use consistent

* fix comment spelling mistakes

* introduce variable for cleaner logic expressions and state assignment

* alter tooltip text to back color by interaction

* remove manual iterator manipulation for forEach()

* remove debounce

* nit fix

* tooltip wording fix

* lint
This commit is contained in:
Severiano Badajoz
2020-01-22 13:40:22 -08:00
committed by GitHub
parent 69c639b14d
commit 8d725b1ad9
18 changed files with 541 additions and 233 deletions
+76
View File
@@ -0,0 +1,76 @@
import calcCentroid from "../util/centroid";
const initialState = {
labels: [],
showLabels: false
};
const centroidLabels = (state = initialState, action, sharedNextState) => {
const {
world,
layoutChoice,
categoricalSelection,
colors: { colorAccessor }
} = sharedNextState;
const showLabels = action.showLabels ?? state.showLabels;
switch (action.type) {
case "annotation: label current cell selection":
case "annotation: label edited":
case "annotation: delete label":
case "set layout choice":
case "set World to current selection":
case "reset World to eq Universe":
return {
...state,
labels:
!!colorAccessor && showLabels && !!categoricalSelection[colorAccessor]
? calcCentroid(
world.obsAnnotations,
world.obsLayout,
colorAccessor,
layoutChoice.currentDimNames,
categoricalSelection,
world.schema.annotations.obsByName
)
: []
};
case "color by categorical metadata":
case "show centroid labels for category":
// If colorby is not enabled or labels are not toggled to show
// then clear the labels and make sure the toggle is off
if (!colorAccessor || !showLabels) {
return {
...state,
labels: [],
showLabels
};
}
return {
...state,
labels: calcCentroid(
world.obsAnnotations,
world.obsLayout,
colorAccessor,
layoutChoice.currentDimNames,
categoricalSelection,
world.schema.annotations.obsByName
),
showLabels
};
case "color by continuous metadata":
return { ...state, labels: [] };
case "reset centroid labels":
return initialState;
default:
return state;
}
};
export default centroidLabels;
+36 -33
View File
@@ -16,45 +16,48 @@ import layoutChoice from "./layoutChoice";
import responsive from "./responsive";
import controls from "./controls";
import resetCache from "./resetCache";
import centroidLabel from "./centroidLabel";
import annotations from "./annotations";
import autosave from "./autosave";
import centroidLabels from "./centroidLabels";
import pointDialation from "./pointDilation";
import undoableConfig from "./undoableConfig";
const Reducer = undoable(
cascadeReducers([
["config", config],
["universe", universe],
["world", world],
["annotations", annotations],
["layoutChoice", layoutChoice],
["categoricalSelection", categoricalSelection],
["continuousSelection", continuousSelection],
["graphSelection", graphSelection],
["crossfilter", crossfilter],
["colors", colors],
["controls", controls],
["differential", differential],
["responsive", responsive],
["centroidLabel", centroidLabel],
["autosave", autosave],
["resetCache", resetCache]
]),
[
"universe",
"world",
"categoricalSelection",
"continuousSelection",
"graphSelection",
"crossfilter",
"colors",
"controls",
"differential",
"layoutChoice",
"annotations"
],
undoableConfig
cascadeReducers([
["config", config],
["universe", universe],
["world", world],
["annotations", annotations],
["layoutChoice", layoutChoice],
["categoricalSelection", categoricalSelection],
["continuousSelection", continuousSelection],
["graphSelection", graphSelection],
["crossfilter", crossfilter],
["colors", colors],
["controls", controls],
["differential", differential],
["responsive", responsive],
["centroidLabels", centroidLabels],
["pointDilation", pointDialation],
["autosave", autosave],
["resetCache", resetCache]
]),
[
"universe",
"categoricalSelection",
"world",
"continuousSelection",
"graphSelection",
"crossfilter",
"layoutChoice",
"controls",
"differential",
"colors",
"centroidLabels",
"annotations"
],
undoableConfig
);
const store = createStore(Reducer, applyMiddleware(thunk));
@@ -1,29 +1,27 @@
const initialState = {
metadataField: "",
categoryIndex: -1,
categoryField: "",
centroidXY: [-1, -1]
categoryField: ""
};
const CentroidLabel = (state = initialState, action, sharedNextState) => {
const pointDialation = (state = initialState, action, sharedNextState) => {
const { categoricalSelection } = sharedNextState;
const { metadataField, categoryIndex } = action;
const categoryField =
action.categoryField ||
categoricalSelection?.[metadataField]?.categoryValues[categoryIndex];
switch (action.type) {
case "category value mouse hover start":
return {
...state,
metadataField,
categoryIndex,
categoryField,
centroidXY: null
categoryField
};
case "category value mouse hover end":
if (
metadataField === state.metadataField &&
categoryIndex === state.categoryIndex
categoryField === state.categoryField
) {
return initialState;
}
@@ -34,4 +32,4 @@ const CentroidLabel = (state = initialState, action, sharedNextState) => {
}
};
export default CentroidLabel;
export default pointDialation;
+3
View File
@@ -16,6 +16,7 @@ const skipOnActions = new Set([
"window resize",
"user reset start",
"reset colorscale",
"reset centroid labels",
"graph brush change",
"continuous metadata histogram brush",
@@ -68,6 +69,8 @@ const saveOnActions = new Set([
"color by continuous metadata",
"color by expression",
"show centroid labels for category",
"set scatterplot x",
"set scatterplot y",