[WIP] JS lint and dead code removal (#1053)

* lint and dead code removal

* fix regressions
This commit is contained in:
Bruce Martin
2019-11-21 14:10:02 -08:00
committed by GitHub
parent 9a540a4f0a
commit ee62dd355f
16 changed files with 118 additions and 155 deletions

View File

@@ -44,7 +44,7 @@ class HistogramBrush extends React.PureComponent {
return varData.col(field);
}
calcHistogramCache = memoize((col, field) => {
calcHistogramCache = memoize(col => {
/*
recalculate expensive stuff, notably bins, summaries, etc.
*/
@@ -240,15 +240,23 @@ class HistogramBrush extends React.PureComponent {
};
}
drawHistogram(svgRef) {
const { field, world } = this.props;
const col = HistogramBrush.getColumn(world, field);
const histogramCache = this.calcHistogramCache(col, field);
const { x, y, bins } = histogramCache;
this._histogram = { x, y, bins, svgRef };
}
handleSetGeneAsScatterplotX = () => {
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot x",
data: field
});
};
handleColorAction() {
handleSetGeneAsScatterplotY = () => {
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot y",
data: field
});
};
handleColorAction = () => {
const { dispatch, field, world, ranges } = this.props;
if (world.obsAnnotations.hasCol(field)) {
@@ -260,9 +268,9 @@ class HistogramBrush extends React.PureComponent {
} else if (world.varData.hasCol(field)) {
dispatch(actions.requestSingleGeneExpressionCountsForColoringPOST(field));
}
}
};
removeHistogram() {
removeHistogram = () => {
const {
dispatch,
field,
@@ -291,26 +299,14 @@ class HistogramBrush extends React.PureComponent {
data: null
});
}
}
};
handleSetGeneAsScatterplotX() {
return () => {
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot x",
data: field
});
};
}
handleSetGeneAsScatterplotY() {
return () => {
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot y",
data: field
});
};
drawHistogram(svgRef) {
const { field, world } = this.props;
const col = HistogramBrush.getColumn(world, field);
const histogramCache = this.calcHistogramCache(col);
const { x, y, bins } = histogramCache;
this._histogram = { x, y, bins, svgRef };
}
renderAxesBrushBins(x, y, bins, svgRef, field) {
@@ -439,7 +435,7 @@ class HistogramBrush extends React.PureComponent {
<ButtonGroup style={{ marginRight: 7 }}>
<Button
data-testid={`plot-x-${field}`}
onClick={this.handleSetGeneAsScatterplotX(field).bind(this)}
onClick={this.handleSetGeneAsScatterplotX}
active={scatterplotXXaccessor === field}
intent={scatterplotXXaccessor === field ? "primary" : "none"}
>
@@ -447,7 +443,7 @@ class HistogramBrush extends React.PureComponent {
</Button>
<Button
data-testid={`plot-y-${field}`}
onClick={this.handleSetGeneAsScatterplotY(field).bind(this)}
onClick={this.handleSetGeneAsScatterplotY}
active={scatterplotYYaccessor === field}
intent={scatterplotYYaccessor === field ? "primary" : "none"}
>
@@ -459,7 +455,7 @@ class HistogramBrush extends React.PureComponent {
{isUserDefined ? (
<Button
minimal
onClick={this.removeHistogram.bind(this)}
onClick={this.removeHistogram}
style={{
color: globals.blue,
cursor: "pointer",
@@ -475,7 +471,7 @@ class HistogramBrush extends React.PureComponent {
hoverOpenDelay={globals.tooltipHoverOpenDelay}
>
<Button
onClick={this.handleColorAction.bind(this)}
onClick={this.handleColorAction}
active={colorAccessor === field}
intent={colorAccessor === field ? "primary" : "none"}
data-testclass="colorby"

View File

@@ -83,7 +83,7 @@ class Categories extends React.Component {
categoryNameErrorMessage = name => {
const err = this.categoryNameError(name);
if (err == "duplicate") {
if (err === "duplicate") {
return (
<span>
<span style={{ fontStyle: "italic" }}>{name}</span> already exists -
@@ -91,7 +91,7 @@ class Categories extends React.Component {
</span>
);
}
if (err == "characters") {
if (err === "characters") {
return (
<span>
<span style={{ fontStyle: "italic" }}>{name}</span> contains illegal

View File

@@ -149,7 +149,7 @@ class Category extends React.Component {
or return an error type.
*/
const { metadataField, universe } = this.props;
const obsByName = universe.schema.annotations.obsByName;
const { obsByName } = universe.schema.annotations;
if (obsByName[metadataField].categories.indexOf(name) !== -1) {
return "duplicate";
@@ -165,7 +165,7 @@ class Category extends React.Component {
labelNameErrorMessage = name => {
const { metadataField } = this.props;
const err = this.labelNameError(name);
if (err == "duplicate") {
if (err === "duplicate") {
return (
<span>
<span style={{ fontStyle: "italic" }}>{name}</span> already exists
@@ -174,7 +174,7 @@ class Category extends React.Component {
</span>
);
}
if (err == "characters") {
if (err === "characters") {
return (
<span>
<span style={{ fontStyle: "italic" }}>{name}</span> contains illegal
@@ -242,8 +242,7 @@ class Category extends React.Component {
colorAccessor,
categoricalSelection,
isUserAnno,
annotations,
universe
annotations
} = this.props;
const { isTruncated } = categoricalSelection[metadataField];
@@ -288,7 +287,6 @@ class Category extends React.Component {
type="checkbox"
/>
<span className="bp3-control-indicator" />
{""}
</label>
<span
data-testid={`category-expand-${metadataField}`}

View File

@@ -144,7 +144,9 @@ class Occupancy extends React.Component {
categoryIndex
} = this.props;
this.canvas?.getContext("2d").clearRect(0, 0, this._WIDTH, this._HEIGHT);
const { canvas } = this;
if (canvas)
canvas.getContext("2d").clearRect(0, 0, this._WIDTH, this._HEIGHT);
const colorByIsCatagoricalData = !!categoricalSelection[colorAccessor];

View File

@@ -9,13 +9,12 @@ import {
MenuItem,
Popover,
Position,
Icon,
PopoverInteractionKind
PopoverInteractionKind,
Tooltip
} from "@blueprintjs/core";
import Occupancy from "./occupancy";
import * as globals from "../../globals";
import styles from "./categorical.css";
import { Tooltip } from "@blueprintjs/core";
import { AnnotationsHelpers } from "../../util/stateManager";

View File

@@ -25,7 +25,7 @@ class Continuous extends React.Component {
componentDidUpdate() {}
handleColorAction(key) {
handleColorAction = key => {
return () => {
const { dispatch, obsAnnotations } = this.props;
const summary = obsAnnotations.col(key).summarize();
@@ -35,7 +35,7 @@ class Continuous extends React.Component {
rangeForColorAccessor: summary
});
};
}
};
render() {
const { obsAnnotations, schema } = this.props;
@@ -54,10 +54,11 @@ class Continuous extends React.Component {
<div>
{this.hasContinuous ? (
<p
style={Object.assign({}, globals.leftSidebarSectionHeading, {
style={{
...globals.leftSidebarSectionHeading,
marginTop: 40,
paddingLeft: globals.leftSidebarSectionPadding
})}
}}
>
Continuous metadata
</p>
@@ -84,7 +85,7 @@ class Continuous extends React.Component {
isObs
zebra={zebra % 2 === 0}
ranges={summary}
handleColorAction={this.handleColorAction(key).bind(this)}
handleColorAction={this.handleColorAction(key)}
/>
);
}

View File

@@ -1,16 +0,0 @@
/* https://github.com/palantir/blueprint/issues/2348 */
<defs>
<clipPath id="clip0">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
<g clip-path="url(#clip0)">
<rect width="16" height="16" fill="white"/>
<path d="M1.33415 8.75877C0.939491 8.36411 0.727699 7.82249 0.749957 7.2648L0.926361 2.84501C0.967947 1.80308 1.80308 0.967947 2.84501 0.926361L7.2648 0.749958C7.82249 0.727699 8.36411 0.939492 8.75877 1.33415L14.3595 6.93485C15.1405 7.7159 15.1405 8.98223 14.3595 9.76328L9.76328 14.3595C8.98223 15.1405 7.7159 15.1405 6.93485 14.3595L1.33415 8.75877Z" fill="black"/>
<circle cx="4.5" cy="4.5" r="1.5" fill="white"/>
<circle cx="4.5" cy="11.5" r="3.75" stroke="white" stroke-width="0.5"/>
<circle cx="4.5" cy="11.5" r="3.5" fill="black"/>
<line x1="4.5" y1="10" x2="4.5" y2="13" stroke="white"/>
<line x1="3" y1="11.5" x2="6" y2="11.5" stroke="white"/>
</g>

View File

@@ -24,7 +24,7 @@ import {
import { memoize } from "../../util/dataframe/util";
const renderGene = (fuzzySortResult, { handleClick, modifiers, query }) => {
const renderGene = (fuzzySortResult, { handleClick, modifiers }) => {
if (!modifiers.matchesPredicate) {
return null;
}
@@ -89,6 +89,59 @@ class GeneExpression extends React.Component {
// eslint-disable-next-line react/sort-comp
_memoGenesToUpper = memoize(this._genesToUpper, arr => arr);
handleBulkAddClick = () => {
const { world, dispatch, userDefinedGenes } = this.props;
const varIndexName = world.schema.annotations.var.index;
const { bulkAdd } = this.state;
/*
test:
Apod,,, Cd74,, ,,, Foo, Bar-2,,
*/
if (bulkAdd !== "") {
const genes = _.pull(_.uniq(bulkAdd.split(/[ ,]+/)), "");
if (genes.length === 0) {
return keepAroundErrorToast("Must enter a gene name.");
}
const worldGenes = world.varAnnotations.col(varIndexName).asArray();
// These gene lists are unique enough where memoization is useless
const upperGenes = this._genesToUpper(genes);
const upperUserDefinedGenes = this._genesToUpper(userDefinedGenes);
const upperWorldGenes = this._memoGenesToUpper(worldGenes);
dispatch({ type: "bulk user defined gene start" });
Promise.all(
[...upperGenes.keys()].map(upperGene => {
if (upperUserDefinedGenes.get(upperGene) !== undefined) {
return keepAroundErrorToast("That gene already exists");
}
const indexOfGene = upperWorldGenes.get(upperGene);
if (indexOfGene === undefined) {
return keepAroundErrorToast(
`${
genes[upperGenes.get(upperGene)]
} doesn't appear to be a valid gene name.`
);
}
return dispatch(
actions.requestUserDefinedGene(worldGenes[indexOfGene])
);
})
).then(
() => dispatch({ type: "bulk user defined gene complete" }),
() => dispatch({ type: "bulk user defined gene error" })
);
}
this.setState({ bulkAdd: "" });
return undefined;
};
placeholderGeneNames() {
/*
return a string containing gene name suggestions for use as a user hint.
@@ -145,58 +198,6 @@ class GeneExpression extends React.Component {
}
}
handleBulkAddClick() {
const { world, dispatch, userDefinedGenes } = this.props;
const varIndexName = world.schema.annotations.var.index;
const { bulkAdd } = this.state;
/*
test:
Apod,,, Cd74,, ,,, Foo, Bar-2,,
*/
if (bulkAdd !== "") {
const genes = _.pull(_.uniq(bulkAdd.split(/[ ,]+/)), "");
if (genes.length === 0) {
return keepAroundErrorToast("Must enter a gene name.");
}
const worldGenes = world.varAnnotations.col(varIndexName).asArray();
// These gene lists are unique enough where memoization is useless
const upperGenes = this._genesToUpper(genes);
const upperUserDefinedGenes = this._genesToUpper(userDefinedGenes);
const upperWorldGenes = this._memoGenesToUpper(worldGenes);
dispatch({ type: "bulk user defined gene start" });
Promise.all(
[...upperGenes.keys()].map(upperGene => {
if (upperUserDefinedGenes.get(upperGene) !== undefined) {
return keepAroundErrorToast("That gene already exists");
}
const indexOfGene = upperWorldGenes.get(upperGene);
if (indexOfGene === undefined) {
return keepAroundErrorToast(
`${
genes[upperGenes.get(upperGene)]
} doesn't appear to be a valid gene name.`
);
}
return dispatch(
actions.requestUserDefinedGene(worldGenes[indexOfGene])
);
})
).then(
() => dispatch({ type: "bulk user defined gene complete" }),
() => dispatch({ type: "bulk user defined gene error" })
);
}
this.setState({ bulkAdd: "" });
}
render() {
const {
world,
@@ -261,7 +262,7 @@ class GeneExpression extends React.Component {
}}
initialContent={<MenuItem disabled text="Enter a gene…" />}
inputProps={{ "data-testid": "gene-search" }}
inputValueRenderer={g => {
inputValueRenderer={() => {
return "";
}}
itemListPredicate={filterGenes}
@@ -276,7 +277,7 @@ class GeneExpression extends React.Component {
/>
<Button
className="bp3-button bp3-intent-primary"
data-testid={"add-gene"}
data-testid="add-gene"
loading={userDefinedGenesLoading}
onClick={() => this.handleClick(activeItem)}
>
@@ -308,7 +309,7 @@ class GeneExpression extends React.Component {
/>
<Button
intent="primary"
onClick={this.handleBulkAddClick.bind(this)}
onClick={this.handleBulkAddClick}
loading={userDefinedGenesLoading}
>
Add genes

View File

@@ -2,8 +2,6 @@
import React from "react";
import { connect } from "react-redux";
import Categorical from "../categorical/categorical";
import Continuous from "../continuous/continuous";
import GeneExpression from "../geneExpression";
import * as globals from "../../globals";
import DynamicScatterplot from "../scatterplot/scatterplot";
import TopLeftLogoAndTitle from "./topLeftLogoAndTitle";

View File

@@ -266,11 +266,10 @@ class MenuBar extends React.Component {
const haveBothCellSets =
!!differential.celllist1 && !!differential.celllist2;
const tipMessage =
"See top 10 differentially expressed genes" +
(diffexpMayBeSlow
? " (CAUTION: large dataset - may take longer or fail)"
: "");
const slowMsg = diffexpMayBeSlow
? " (CAUTION: large dataset - may take longer or fail)"
: "";
const tipMessage = `See top 10 differentially expressed genes${slowMsg}`;
return (
<div className="bp3-button-group" style={{ marginRight: 10 }}>
@@ -318,7 +317,6 @@ class MenuBar extends React.Component {
render() {
const {
dispatch,
differential,
crossfilter,
resettingInterface,
libraryVersions,

View File

@@ -12,17 +12,7 @@ import * as globals from "../../globals";
}))
class RightSidebar extends React.Component {
render() {
const {
responsive,
scatterplotXXaccessor,
scatterplotYYaccessor
} = this.props;
/*
this magic number should be made less fragile,
if cellxgene logo or tabs change, this must as well
*/
const logoRelatedPadding = 50;
const { responsive } = this.props;
return (
<div

View File

@@ -1,5 +1,3 @@
import calcCentroid from "../util/centroid";
const initialState = {
metadataField: "",
categoryIndex: -1,
@@ -8,7 +6,7 @@ const initialState = {
};
const CentroidLabel = (state = initialState, action, sharedNextState) => {
const { categoricalSelection, world, layoutChoice } = sharedNextState;
const { categoricalSelection } = sharedNextState;
const { metadataField, categoryIndex } = action;
const categoryField =
categoricalSelection?.[metadataField]?.categoryValues[categoryIndex];
@@ -19,12 +17,7 @@ const CentroidLabel = (state = initialState, action, sharedNextState) => {
metadataField,
categoryIndex,
categoryField,
centroidXY: null /* calcCentroid( This function call is computationally heavy and also leading to large GC. Before reimplementation, look into optimization and memoization
world,
metadataField,
categoryField,
layoutChoice.currentDimNames
) */
centroidXY: null
};
case "category value mouse hover end":

View File

@@ -55,7 +55,7 @@ const ColorsReducer = (
case "annotation: delete category": {
const { colorAccessor } = state;
if (action.metadataField != colorAccessor) {
if (action.metadataField !== colorAccessor) {
return state;
}
/* else reset */

View File

@@ -3,6 +3,8 @@ import quantile from "./quantile";
/*
Centroid coordinate calculation
*/
/* Unused - please cleanup
const calcMeanCentroid = (world, annoName, annoValue, layoutDimNames) => {
const centroid = { x: 0, y: 0, size: 0 };
const annoArray = world.obsAnnotations.col(annoName).asArray();
@@ -24,6 +26,7 @@ const calcMeanCentroid = (world, annoName, annoValue, layoutDimNames) => {
return [centroid.x, centroid.y];
};
*/
const calcMedianCentroid = (world, annoName, annoValue, layoutDimNames) => {
const centroidX = [];

View File

@@ -138,7 +138,7 @@ export function allHaveLabelByMask(df, colName, label, mask) {
const col = df.col(colName);
if (!col) return false;
if (df.length !== mask.length)
throw new InternalError("mismatch on mask length");
throw new RangeError("mismatch on mask length");
for (let i = 0; i < df.length; i += 1) {
if (mask[i]) {

View File

@@ -108,7 +108,7 @@ export default class ImmutableTypedCrossfilter {
};
return new ImmutableTypedCrossfilter(data, dimensions, {
bitArray: bitArray
bitArray
});
}
@@ -128,7 +128,7 @@ export default class ImmutableTypedCrossfilter {
}
return new ImmutableTypedCrossfilter(data, dimensions, {
bitArray: bitArray
bitArray
});
}