mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-07 13:08:11 +08:00
Handle loading state when rendering categories with one label (#1393)
* refactor & loading state * truncate * fix minor PR review issues * lint Co-authored-by: bkmartinjr <bruce@chanzuckerberg.com>
This commit is contained in:
co-authored by
bkmartinjr
parent
7d4d360e52
commit
ea434fc46f
+18
-18
@@ -1,37 +1,37 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import AnnoDialog from "./annoDialog";
|
import AnnoDialog from "../annoDialog";
|
||||||
import LabelInput from "./labelInput";
|
import LabelInput from "../labelInput";
|
||||||
import { labelPrompt, isLabelErroneous } from "./labelUtil";
|
import { labelPrompt, isLabelErroneous } from "../labelUtil";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect((state) => ({
|
||||||
colorAccessor: state.colors.colorAccessor,
|
colorAccessor: state.colors.colorAccessor,
|
||||||
categoricalSelection: state.categoricalSelection,
|
categoricalSelection: state.categoricalSelection,
|
||||||
annotations: state.annotations,
|
annotations: state.annotations,
|
||||||
universe: state.universe,
|
universe: state.universe,
|
||||||
ontology: state.ontology,
|
ontology: state.ontology,
|
||||||
crossfilter: state.crossfilter
|
crossfilter: state.crossfilter,
|
||||||
}))
|
}))
|
||||||
class Category extends React.PureComponent {
|
class Category extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
newLabelText: ""
|
newLabelText: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
disableAddNewLabelMode = e => {
|
disableAddNewLabelMode = (e) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
newLabelText: ""
|
newLabelText: "",
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "annotation: disable add new label mode"
|
type: "annotation: disable add new label mode",
|
||||||
});
|
});
|
||||||
if (e) e.preventDefault();
|
if (e) e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAddNewLabelToCategory = e => {
|
handleAddNewLabelToCategory = (e) => {
|
||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
const { newLabelText } = this.state;
|
const { newLabelText } = this.state;
|
||||||
|
|
||||||
@@ -40,12 +40,12 @@ class Category extends React.PureComponent {
|
|||||||
type: "annotation: add new label to category",
|
type: "annotation: add new label to category",
|
||||||
metadataField,
|
metadataField,
|
||||||
newLabelText,
|
newLabelText,
|
||||||
assignSelectedCells: false
|
assignSelectedCells: false,
|
||||||
});
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
addLabelAndAssignCells = e => {
|
addLabelAndAssignCells = (e) => {
|
||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
const { newLabelText } = this.state;
|
const { newLabelText } = this.state;
|
||||||
|
|
||||||
@@ -54,21 +54,21 @@ class Category extends React.PureComponent {
|
|||||||
type: "annotation: add new label to category",
|
type: "annotation: add new label to category",
|
||||||
metadataField,
|
metadataField,
|
||||||
newLabelText,
|
newLabelText,
|
||||||
assignSelectedCells: true
|
assignSelectedCells: true,
|
||||||
});
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
labelNameError = name => {
|
labelNameError = (name) => {
|
||||||
const { metadataField, ontology, universe } = this.props;
|
const { metadataField, ontology, universe } = this.props;
|
||||||
return isLabelErroneous(name, metadataField, ontology, universe.schema);
|
return isLabelErroneous(name, metadataField, ontology, universe.schema);
|
||||||
};
|
};
|
||||||
|
|
||||||
instruction = label => {
|
instruction = (label) => {
|
||||||
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
|
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChangeOrSelect = label => {
|
handleChangeOrSelect = (label) => {
|
||||||
this.setState({ newLabelText: label });
|
this.setState({ newLabelText: label });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ class Category extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
inputProps={{ "data-testid": `${metadataField}:create-label-dialog` }}
|
inputProps={{ "data-testid": `${metadataField}:create-label-dialog` }}
|
||||||
primaryButtonProps={{
|
primaryButtonProps={{
|
||||||
"data-testid": `${metadataField}:submit-label`
|
"data-testid": `${metadataField}:submit-label`,
|
||||||
}}
|
}}
|
||||||
title="Add new label to category"
|
title="Add new label to category"
|
||||||
instruction={this.instruction(newLabelText)}
|
instruction={this.instruction(newLabelText)}
|
||||||
@@ -107,7 +107,7 @@ class Category extends React.PureComponent {
|
|||||||
"data-testid": `${metadataField}:new-label-name`,
|
"data-testid": `${metadataField}:new-label-name`,
|
||||||
leftIcon: "tag",
|
leftIcon: "tag",
|
||||||
intent: "none",
|
intent: "none",
|
||||||
autoFocus: true
|
autoFocus: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
+17
-17
@@ -1,41 +1,41 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import AnnoDialog from "./annoDialog";
|
import AnnoDialog from "../annoDialog";
|
||||||
import LabelInput from "./labelInput";
|
import LabelInput from "../labelInput";
|
||||||
import { labelPrompt } from "./labelUtil";
|
import { labelPrompt } from "../labelUtil";
|
||||||
|
|
||||||
import { AnnotationsHelpers } from "../../util/stateManager";
|
import { AnnotationsHelpers } from "../../../util/stateManager";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect((state) => ({
|
||||||
categoricalSelection: state.categoricalSelection,
|
categoricalSelection: state.categoricalSelection,
|
||||||
annotations: state.annotations,
|
annotations: state.annotations,
|
||||||
universe: state.universe,
|
universe: state.universe,
|
||||||
ontology: state.ontology
|
ontology: state.ontology,
|
||||||
}))
|
}))
|
||||||
class AnnoDialogEditCategoryName extends React.PureComponent {
|
class AnnoDialogEditCategoryName extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
newCategoryText: props.metadataField
|
newCategoryText: props.metadataField,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeOrSelect = name => {
|
handleChangeOrSelect = (name) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
newCategoryText: name
|
newCategoryText: name,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
disableEditCategoryMode = () => {
|
disableEditCategoryMode = () => {
|
||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "annotation: disable category edit mode"
|
type: "annotation: disable category edit mode",
|
||||||
});
|
});
|
||||||
this.setState({ newCategoryText: metadataField });
|
this.setState({ newCategoryText: metadataField });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditCategory = e => {
|
handleEditCategory = (e) => {
|
||||||
const { dispatch, metadataField, categoricalSelection } = this.props;
|
const { dispatch, metadataField, categoricalSelection } = this.props;
|
||||||
const { newCategoryText } = this.state;
|
const { newCategoryText } = this.state;
|
||||||
|
|
||||||
@@ -54,12 +54,12 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
|
|||||||
type: "annotation: category edited",
|
type: "annotation: category edited",
|
||||||
metadataField,
|
metadataField,
|
||||||
newCategoryText,
|
newCategoryText,
|
||||||
data: newCategoryText
|
data: newCategoryText,
|
||||||
});
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
editedCategoryNameError = name => {
|
editedCategoryNameError = (name) => {
|
||||||
const { metadataField, categoricalSelection } = this.props;
|
const { metadataField, categoricalSelection } = this.props;
|
||||||
|
|
||||||
/* check for syntax errors in category name */
|
/* check for syntax errors in category name */
|
||||||
@@ -80,7 +80,7 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
instruction = name => {
|
instruction = (name) => {
|
||||||
return labelPrompt(
|
return labelPrompt(
|
||||||
this.editedCategoryNameError(name),
|
this.editedCategoryNameError(name),
|
||||||
"New, unique category name",
|
"New, unique category name",
|
||||||
@@ -101,10 +101,10 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
|
|||||||
annotations.categoryBeingEdited === metadataField
|
annotations.categoryBeingEdited === metadataField
|
||||||
}
|
}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
"data-testid": `${metadataField}:edit-category-name-dialog`
|
"data-testid": `${metadataField}:edit-category-name-dialog`,
|
||||||
}}
|
}}
|
||||||
primaryButtonProps={{
|
primaryButtonProps={{
|
||||||
"data-testid": `${metadataField}:submit-category-edit`
|
"data-testid": `${metadataField}:submit-category-edit`,
|
||||||
}}
|
}}
|
||||||
title="Edit category name"
|
title="Edit category name"
|
||||||
instruction={this.instruction(newCategoryText)}
|
instruction={this.instruction(newCategoryText)}
|
||||||
@@ -124,7 +124,7 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
|
|||||||
"data-testid": `${metadataField}:edit-category-name-text`,
|
"data-testid": `${metadataField}:edit-category-name-text`,
|
||||||
leftIcon: "tag",
|
leftIcon: "tag",
|
||||||
intent: "none",
|
intent: "none",
|
||||||
autoFocus: true
|
autoFocus: true,
|
||||||
}}
|
}}
|
||||||
newLabelMessage="New category"
|
newLabelMessage="New category"
|
||||||
/>
|
/>
|
||||||
+9
-9
@@ -3,11 +3,11 @@ import _ from "lodash";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Flipper, Flipped } from "react-flip-toolkit";
|
import { Flipper, Flipped } from "react-flip-toolkit";
|
||||||
|
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../../globals";
|
||||||
import Value from "./value";
|
import Value from "../value";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect((state) => ({
|
||||||
categoricalSelection: state.categoricalSelection
|
categoricalSelection: state.categoricalSelection,
|
||||||
}))
|
}))
|
||||||
class Category extends React.Component {
|
class Category extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -21,7 +21,7 @@ class Category extends React.Component {
|
|||||||
return _.map(optTuples, (tuple, i) => {
|
return _.map(optTuples, (tuple, i) => {
|
||||||
return (
|
return (
|
||||||
<Flipped key={tuple[1]} flipId={tuple[1]}>
|
<Flipped key={tuple[1]} flipId={tuple[1]}>
|
||||||
{flippedProps => (
|
{(flippedProps) => (
|
||||||
<Value
|
<Value
|
||||||
isUserAnno={isUserAnno}
|
isUserAnno={isUserAnno}
|
||||||
optTuples={optTuples}
|
optTuples={optTuples}
|
||||||
@@ -42,17 +42,17 @@ class Category extends React.Component {
|
|||||||
metadataField,
|
metadataField,
|
||||||
categoricalSelection,
|
categoricalSelection,
|
||||||
children,
|
children,
|
||||||
isExpanded
|
isExpanded,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { isTruncated } = categoricalSelection[metadataField];
|
const { isTruncated } = categoricalSelection[metadataField];
|
||||||
const cat = categoricalSelection[metadataField];
|
const cat = categoricalSelection[metadataField];
|
||||||
const optTuples = [...cat.categoryValueIndices];
|
const optTuples = [...cat.categoryValueIndices];
|
||||||
const optTuplesAsKey = _.map(optTuples, t => t[0]).join(""); // animation
|
const optTuplesAsKey = _.map(optTuples, (t) => t[0]).join(""); // animation
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
maxWidth: globals.maxControlsWidth
|
maxWidth: globals.maxControlsWidth,
|
||||||
}}
|
}}
|
||||||
data-testclass="category"
|
data-testclass="category"
|
||||||
data-testid={`category-${metadataField}`}
|
data-testid={`category-${metadataField}`}
|
||||||
@@ -61,7 +61,7 @@ class Category extends React.Component {
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "baseline"
|
alignItems: "baseline",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
+49
-29
@@ -7,27 +7,31 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Icon,
|
Icon,
|
||||||
Position
|
Position,
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import CategoryFlipperLayout from "./categoryFlipperLayout";
|
import CategoryFlipperLayout from "./categoryFlipperLayout";
|
||||||
import AnnoMenu from "./annoMenuCategory";
|
import AnnoMenu from "./annoMenuCategory";
|
||||||
import AnnoDialogEditCategoryName from "./annoDialogEditCategoryName";
|
import AnnoDialogEditCategoryName from "./annoDialogEditCategoryName";
|
||||||
import AnnoDialogAddLabel from "./annoDialogAddLabel";
|
import AnnoDialogAddLabel from "./annoDialogAddLabel";
|
||||||
|
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../../globals";
|
||||||
import maybeTruncateString from "../../util/maybeTruncateString";
|
import maybeTruncateString from "../../../util/maybeTruncateString";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect((state, ownProps) => {
|
||||||
colorAccessor: state.colors.colorAccessor,
|
const { metadataField } = ownProps;
|
||||||
categoricalSelection: state.categoricalSelection,
|
return {
|
||||||
annotations: state.annotations,
|
isColorAccessor: state.colors.colorAccessor === metadataField,
|
||||||
universe: state.universe
|
categoricalSelection: state.categoricalSelection,
|
||||||
}))
|
annotations: state.annotations,
|
||||||
|
universe: state.universe,
|
||||||
|
schema: state.world?.schema,
|
||||||
|
};
|
||||||
|
})
|
||||||
class Category extends React.Component {
|
class Category extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isChecked: true
|
isChecked: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +51,7 @@ class Category extends React.Component {
|
|||||||
cat.categoryValueSelected,
|
cat.categoryValueSelected,
|
||||||
(res, cond) => (cond ? res + 1 : res),
|
(res, cond) => (cond ? res + 1 : res),
|
||||||
0
|
0
|
||||||
)
|
),
|
||||||
};
|
};
|
||||||
if (categoryCount.selectedCatCount === categoryCount.totalCatCount) {
|
if (categoryCount.selectedCatCount === categoryCount.totalCatCount) {
|
||||||
/* everything is on, so not indeterminate */
|
/* everything is on, so not indeterminate */
|
||||||
@@ -69,7 +73,7 @@ class Category extends React.Component {
|
|||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "color by categorical metadata",
|
type: "color by categorical metadata",
|
||||||
colorAccessor: metadataField
|
colorAccessor: metadataField,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,7 +81,7 @@ class Category extends React.Component {
|
|||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "categorical metadata filter all of these",
|
type: "categorical metadata filter all of these",
|
||||||
metadataField
|
metadataField,
|
||||||
});
|
});
|
||||||
this.setState({ isChecked: true });
|
this.setState({ isChecked: true });
|
||||||
}
|
}
|
||||||
@@ -86,7 +90,7 @@ class Category extends React.Component {
|
|||||||
const { dispatch, metadataField } = this.props;
|
const { dispatch, metadataField } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "categorical metadata filter none of these",
|
type: "categorical metadata filter none of these",
|
||||||
metadataField
|
metadataField,
|
||||||
});
|
});
|
||||||
this.setState({ isChecked: false });
|
this.setState({ isChecked: false });
|
||||||
}
|
}
|
||||||
@@ -114,25 +118,25 @@ class Category extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
maxWidth: globals.maxControlsWidth
|
maxWidth: globals.maxControlsWidth,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "baseline"
|
alignItems: "baseline",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "flex-start",
|
justifyContent: "flex-start",
|
||||||
alignItems: "flex-start"
|
alignItems: "flex-start",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<label className="bp3-control bp3-checkbox">
|
<label className="bp3-control bp3-checkbox">
|
||||||
<input disabled checked={true} type="checkbox" />
|
<input disabled checked type="checkbox" />
|
||||||
<span className="bp3-control-indicator" />
|
<span className="bp3-control-indicator" />
|
||||||
</label>
|
</label>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@@ -143,13 +147,13 @@ class Category extends React.Component {
|
|||||||
usePortal
|
usePortal
|
||||||
modifiers={{
|
modifiers={{
|
||||||
preventOverflow: { enabled: false },
|
preventOverflow: { enabled: false },
|
||||||
hide: { enabled: false }
|
hide: { enabled: false },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
display: "inline-block"
|
display: "inline-block",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{truncatedString || metadataField}
|
{truncatedString || metadataField}
|
||||||
@@ -169,11 +173,11 @@ class Category extends React.Component {
|
|||||||
const {
|
const {
|
||||||
metadataField,
|
metadataField,
|
||||||
categoricalSelection,
|
categoricalSelection,
|
||||||
colorAccessor,
|
isColorAccessor,
|
||||||
isUserAnno,
|
|
||||||
annotations,
|
annotations,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
onExpansionChange
|
onExpansionChange,
|
||||||
|
schema,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const isStillLoading = !(categoricalSelection?.[metadataField] ?? false);
|
const isStillLoading = !(categoricalSelection?.[metadataField] ?? false);
|
||||||
@@ -181,6 +185,8 @@ class Category extends React.Component {
|
|||||||
return this.renderIsStillLoading();
|
return this.renderIsStillLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isUserAnno =
|
||||||
|
schema?.annotations?.obsByName[metadataField]?.writable ?? false;
|
||||||
const isTruncated = _.get(
|
const isTruncated = _.get(
|
||||||
categoricalSelection,
|
categoricalSelection,
|
||||||
[metadataField, "isTruncated"],
|
[metadataField, "isTruncated"],
|
||||||
@@ -192,6 +198,20 @@ class Category extends React.Component {
|
|||||||
globals.categoryDisplayStringMaxLength
|
globals.categoryDisplayStringMaxLength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!isUserAnno &&
|
||||||
|
schema?.annotations?.obsByName[metadataField]?.categories?.length === 1
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: 10, marginTop: 4 }}>
|
||||||
|
<span style={{ fontWeight: 700 }}>
|
||||||
|
{truncatedString ? truncatedString : metadataField}
|
||||||
|
</span>
|
||||||
|
: {schema.annotations.obsByName[metadataField].categories[0]}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CategoryFlipperLayout
|
<CategoryFlipperLayout
|
||||||
metadataField={metadataField}
|
metadataField={metadataField}
|
||||||
@@ -202,7 +222,7 @@ class Category extends React.Component {
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "flex-start",
|
justifyContent: "flex-start",
|
||||||
alignItems: "flex-start"
|
alignItems: "flex-start",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<label className="bp3-control bp3-checkbox">
|
<label className="bp3-control bp3-checkbox">
|
||||||
@@ -210,7 +230,7 @@ class Category extends React.Component {
|
|||||||
data-testclass="category-select"
|
data-testclass="category-select"
|
||||||
data-testid={`${metadataField}:category-select`}
|
data-testid={`${metadataField}:category-select`}
|
||||||
onChange={this.handleToggleAllClick.bind(this)}
|
onChange={this.handleToggleAllClick.bind(this)}
|
||||||
ref={el => {
|
ref={(el) => {
|
||||||
this.checkbox = el;
|
this.checkbox = el;
|
||||||
return el;
|
return el;
|
||||||
}}
|
}}
|
||||||
@@ -227,14 +247,14 @@ class Category extends React.Component {
|
|||||||
usePortal
|
usePortal
|
||||||
modifiers={{
|
modifiers={{
|
||||||
preventOverflow: { enabled: false },
|
preventOverflow: { enabled: false },
|
||||||
hide: { enabled: false }
|
hide: { enabled: false },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
data-testid={`${metadataField}:category-expand`}
|
data-testid={`${metadataField}:category-expand`}
|
||||||
style={{
|
style={{
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
display: "inline-block"
|
display: "inline-block",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const editingCategory =
|
const editingCategory =
|
||||||
@@ -288,8 +308,8 @@ class Category extends React.Component {
|
|||||||
data-testclass="colorby"
|
data-testclass="colorby"
|
||||||
data-testid={`colorby-${metadataField}`}
|
data-testid={`colorby-${metadataField}`}
|
||||||
onClick={this.handleColorChange}
|
onClick={this.handleColorChange}
|
||||||
active={colorAccessor === metadataField}
|
active={isColorAccessor}
|
||||||
intent={colorAccessor === metadataField ? "primary" : "none"}
|
intent={isColorAccessor ? "primary" : "none"}
|
||||||
disabled={isTruncated}
|
disabled={isTruncated}
|
||||||
icon="tint"
|
icon="tint"
|
||||||
/>
|
/>
|
||||||
+25
-77
@@ -119,57 +119,6 @@ class Categories extends React.Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
maybeRenderSingleLabel = (allCategoryNames, schema) => {
|
|
||||||
return allCategoryNames.map((catName) =>
|
|
||||||
!schema.annotations.obsByName[catName].writable &&
|
|
||||||
schema.annotations.obsByName[catName].categories.length === 1 ? (
|
|
||||||
<div style={{ marginBottom: 10 }}>
|
|
||||||
<span style={{ fontWeight: 700 }}>{catName}</span>:{" "}
|
|
||||||
{schema.annotations.obsByName[catName].categories[0]}
|
|
||||||
</div>
|
|
||||||
) : null
|
|
||||||
);
|
|
||||||
};
|
|
||||||
maybeRenderReadOnly = (
|
|
||||||
allCategoryNames,
|
|
||||||
schema,
|
|
||||||
expandedCats,
|
|
||||||
createAnnoModeActive
|
|
||||||
) => {
|
|
||||||
return allCategoryNames.map((catName) =>
|
|
||||||
!schema.annotations.obsByName[catName].writable &&
|
|
||||||
schema.annotations.obsByName[catName].categories.length > 1 ? (
|
|
||||||
<Category
|
|
||||||
key={catName}
|
|
||||||
metadataField={catName}
|
|
||||||
onExpansionChange={this.onExpansionChange}
|
|
||||||
isExpanded={expandedCats.has(catName)}
|
|
||||||
createAnnoModeActive={createAnnoModeActive}
|
|
||||||
isUserAnno={false}
|
|
||||||
/>
|
|
||||||
) : null
|
|
||||||
);
|
|
||||||
};
|
|
||||||
maybeRenderAnnotations = (
|
|
||||||
allCategoryNames,
|
|
||||||
schema,
|
|
||||||
expandedCats,
|
|
||||||
createAnnoModeActive
|
|
||||||
) => {
|
|
||||||
return allCategoryNames.map((catName) =>
|
|
||||||
schema.annotations.obsByName[catName].writable ? (
|
|
||||||
<Category
|
|
||||||
key={catName}
|
|
||||||
metadataField={catName}
|
|
||||||
onExpansionChange={this.onExpansionChange}
|
|
||||||
isExpanded={expandedCats.has(catName)}
|
|
||||||
createAnnoModeActive={createAnnoModeActive}
|
|
||||||
isUserAnno
|
|
||||||
/>
|
|
||||||
) : null
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
createAnnoModeActive,
|
createAnnoModeActive,
|
||||||
@@ -227,32 +176,31 @@ class Categories extends React.Component {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div style={{ marginLeft: 0 }}>
|
{/* READ ONLY CATEGORICAL FIELDS */}
|
||||||
{
|
{/* this is duplicative but flat, could be abstracted */}
|
||||||
this.maybeRenderSingleLabel(
|
{allCategoryNames.map((catName) =>
|
||||||
allCategoryNames,
|
!schema.annotations.obsByName[catName].writable ? (
|
||||||
schema,
|
<Category
|
||||||
expandedCats,
|
key={catName}
|
||||||
createAnnoModeActive
|
metadataField={catName}
|
||||||
) /* Categories with only one label */
|
onExpansionChange={this.onExpansionChange}
|
||||||
}
|
isExpanded={expandedCats.has(catName)}
|
||||||
</div>
|
createAnnoModeActive={createAnnoModeActive}
|
||||||
{
|
/>
|
||||||
this.maybeRenderReadOnly(
|
) : null
|
||||||
allCategoryNames,
|
)}
|
||||||
schema,
|
{/* WRITEABLE FIELDS */}
|
||||||
expandedCats,
|
{allCategoryNames.map((catName) =>
|
||||||
createAnnoModeActive
|
schema.annotations.obsByName[catName].writable ? (
|
||||||
) /* Read only categorical fields, ostensibly 'normal' mode */
|
<Category
|
||||||
}
|
key={catName}
|
||||||
{
|
metadataField={catName}
|
||||||
this.maybeRenderAnnotations(
|
onExpansionChange={this.onExpansionChange}
|
||||||
allCategoryNames,
|
isExpanded={expandedCats.has(catName)}
|
||||||
schema,
|
createAnnoModeActive={createAnnoModeActive}
|
||||||
expandedCats,
|
/>
|
||||||
createAnnoModeActive
|
) : null
|
||||||
) /* Writable fields, ie., anno */
|
)}
|
||||||
}
|
|
||||||
|
|
||||||
{writableCategoriesEnabled ? (
|
{writableCategoriesEnabled ? (
|
||||||
<div>
|
<div>
|
||||||
+40
-40
@@ -8,16 +8,16 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
Position,
|
Position,
|
||||||
PopoverInteractionKind,
|
PopoverInteractionKind,
|
||||||
Tooltip
|
Tooltip,
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import Occupancy from "./occupancy";
|
import Occupancy from "./occupancy";
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../../globals";
|
||||||
import styles from "./categorical.css";
|
import styles from "../categorical.css";
|
||||||
import AnnoDialog from "./annoDialog";
|
import AnnoDialog from "../annoDialog";
|
||||||
import LabelInput from "./labelInput";
|
import LabelInput from "../labelInput";
|
||||||
|
|
||||||
import { AnnotationsHelpers } from "../../util/stateManager";
|
import { AnnotationsHelpers } from "../../../util/stateManager";
|
||||||
import { labelPrompt, isLabelErroneous } from "./labelUtil";
|
import { labelPrompt, isLabelErroneous } from "../labelUtil";
|
||||||
|
|
||||||
/* this is defined outside of the class so we can use it in connect() */
|
/* this is defined outside of the class so we can use it in connect() */
|
||||||
function _currentLabel(ownProps, categoricalSelection) {
|
function _currentLabel(ownProps, categoricalSelection) {
|
||||||
@@ -29,7 +29,7 @@ function _currentLabel(ownProps, categoricalSelection) {
|
|||||||
|
|
||||||
@connect((state, ownProps) => {
|
@connect((state, ownProps) => {
|
||||||
const { pointDilation, categoricalSelection } = state;
|
const { pointDilation, categoricalSelection } = state;
|
||||||
const { metadataField, categoryField } = ownProps;
|
const { metadataField } = ownProps;
|
||||||
const isDilated =
|
const isDilated =
|
||||||
pointDilation.metadataField === metadataField &&
|
pointDilation.metadataField === metadataField &&
|
||||||
pointDilation.categoryField ===
|
pointDilation.categoryField ===
|
||||||
@@ -43,14 +43,14 @@ function _currentLabel(ownProps, categoricalSelection) {
|
|||||||
world: state.world,
|
world: state.world,
|
||||||
crossfilter: state.crossfilter,
|
crossfilter: state.crossfilter,
|
||||||
ontology: state.ontology,
|
ontology: state.ontology,
|
||||||
isDilated
|
isDilated,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
class CategoryValue extends React.Component {
|
class CategoryValue extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
editedLabelText: this.currentLabel()
|
editedLabelText: this.currentLabel(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ class CategoryValue extends React.Component {
|
|||||||
prevProps.categoryIndex !== categoryIndex
|
prevProps.categoryIndex !== categoryIndex
|
||||||
) {
|
) {
|
||||||
this.setState({
|
this.setState({
|
||||||
editedLabelText: this.currentLabel()
|
editedLabelText: this.currentLabel(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "annotation: delete label",
|
type: "annotation: delete label",
|
||||||
metadataField,
|
metadataField,
|
||||||
label
|
label,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,11 +85,11 @@ class CategoryValue extends React.Component {
|
|||||||
type: "annotation: label current cell selection",
|
type: "annotation: label current cell selection",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex,
|
categoryIndex,
|
||||||
label
|
label,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditValue = e => {
|
handleEditValue = (e) => {
|
||||||
const { dispatch, metadataField, categoryIndex } = this.props;
|
const { dispatch, metadataField, categoryIndex } = this.props;
|
||||||
const { editedLabelText } = this.state;
|
const { editedLabelText } = this.state;
|
||||||
const label = this.getLabel();
|
const label = this.getLabel();
|
||||||
@@ -99,12 +99,12 @@ class CategoryValue extends React.Component {
|
|||||||
editedLabel: editedLabelText,
|
editedLabel: editedLabelText,
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex,
|
categoryIndex,
|
||||||
label
|
label,
|
||||||
});
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCreateArbitraryLabel = txt => {
|
handleCreateArbitraryLabel = (txt) => {
|
||||||
const { dispatch, metadataField, categoryIndex } = this.props;
|
const { dispatch, metadataField, categoryIndex } = this.props;
|
||||||
const label = this.getLabel();
|
const label = this.getLabel();
|
||||||
this.cancelEditMode();
|
this.cancelEditMode();
|
||||||
@@ -113,17 +113,17 @@ class CategoryValue extends React.Component {
|
|||||||
metadataField,
|
metadataField,
|
||||||
editedLabel: txt,
|
editedLabel: txt,
|
||||||
categoryIndex,
|
categoryIndex,
|
||||||
label
|
label,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
labelNameError = name => {
|
labelNameError = (name) => {
|
||||||
const { metadataField, ontology, schema } = this.props;
|
const { metadataField, ontology, schema } = this.props;
|
||||||
if (name === this.currentLabel()) return false;
|
if (name === this.currentLabel()) return false;
|
||||||
return isLabelErroneous(name, metadataField, ontology, schema);
|
return isLabelErroneous(name, metadataField, ontology, schema);
|
||||||
};
|
};
|
||||||
|
|
||||||
instruction = label => {
|
instruction = (label) => {
|
||||||
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
|
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,19 +132,19 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "annotation: activate edit label mode",
|
type: "annotation: activate edit label mode",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
cancelEditMode = () => {
|
cancelEditMode = () => {
|
||||||
const { dispatch, metadataField, categoryIndex } = this.props;
|
const { dispatch, metadataField, categoryIndex } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
editedLabelText: this.currentLabel()
|
editedLabelText: this.currentLabel(),
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "annotation: cancel edit label mode",
|
type: "annotation: cancel edit label mode",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "categorical metadata filter deselect",
|
type: "categorical metadata filter deselect",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "categorical metadata filter select",
|
type: "categorical metadata filter select",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "category value mouse hover start",
|
type: "category value mouse hover start",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,15 +221,15 @@ class CategoryValue extends React.Component {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: "category value mouse hover end",
|
type: "category value mouse hover end",
|
||||||
metadataField,
|
metadataField,
|
||||||
categoryIndex
|
categoryIndex,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleTextChange = text => {
|
handleTextChange = (text) => {
|
||||||
this.setState({ editedLabelText: text });
|
this.setState({ editedLabelText: text });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChoice = e => {
|
handleChoice = (e) => {
|
||||||
/* Blueprint Suggest format */
|
/* Blueprint Suggest format */
|
||||||
this.setState({ editedLabelText: e.target });
|
this.setState({ editedLabelText: e.target });
|
||||||
};
|
};
|
||||||
@@ -290,7 +290,7 @@ class CategoryValue extends React.Component {
|
|||||||
// flippedProps is potentially brittle, their docs want {...flippedProps} on our div,
|
// flippedProps is potentially brittle, their docs want {...flippedProps} on our div,
|
||||||
// our lint doesn't like jsx spread, we are version pinned to prevent api change on their part
|
// our lint doesn't like jsx spread, we are version pinned to prevent api change on their part
|
||||||
flippedProps,
|
flippedProps,
|
||||||
isDilated
|
isDilated,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const ontologyEnabled = ontology?.enabled ?? false;
|
const ontologyEnabled = ontology?.enabled ?? false;
|
||||||
|
|
||||||
@@ -359,7 +359,7 @@ class CategoryValue extends React.Component {
|
|||||||
alignItems: "baseline",
|
alignItems: "baseline",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
marginBottom: "2px",
|
marginBottom: "2px",
|
||||||
borderRadius: "2px"
|
borderRadius: "2px",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={this.handleMouseEnter}
|
onMouseEnter={this.handleMouseEnter}
|
||||||
onMouseLeave={this.handleMouseExit}
|
onMouseLeave={this.handleMouseExit}
|
||||||
@@ -371,7 +371,7 @@ class CategoryValue extends React.Component {
|
|||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
width: globals.leftSidebarWidth - 145,
|
width: globals.leftSidebarWidth - 145,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between"
|
justifyContent: "space-between",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ display: "flex", alignItems: "baseline" }}>
|
<div style={{ display: "flex", alignItems: "baseline" }}>
|
||||||
@@ -397,7 +397,7 @@ class CategoryValue extends React.Component {
|
|||||||
usePortal
|
usePortal
|
||||||
modifiers={{
|
modifiers={{
|
||||||
preventOverflow: { enabled: false },
|
preventOverflow: { enabled: false },
|
||||||
hide: { enabled: false }
|
hide: { enabled: false },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -417,7 +417,7 @@ class CategoryValue extends React.Component {
|
|||||||
lineHeight: "1.1em",
|
lineHeight: "1.1em",
|
||||||
height: "1.1em",
|
height: "1.1em",
|
||||||
wordBreak: "break-all",
|
wordBreak: "break-all",
|
||||||
verticalAlign: "middle"
|
verticalAlign: "middle",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{truncatedString || displayString}
|
{truncatedString || displayString}
|
||||||
@@ -428,10 +428,10 @@ class CategoryValue extends React.Component {
|
|||||||
<AnnoDialog
|
<AnnoDialog
|
||||||
isActive={editModeActive}
|
isActive={editModeActive}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
"data-testid": `${metadataField}:edit-label-name-dialog`
|
"data-testid": `${metadataField}:edit-label-name-dialog`,
|
||||||
}}
|
}}
|
||||||
primaryButtonProps={{
|
primaryButtonProps={{
|
||||||
"data-testid": `${metadataField}:${displayString}:submit-label-edit`
|
"data-testid": `${metadataField}:${displayString}:submit-label-edit`,
|
||||||
}}
|
}}
|
||||||
title="Edit label"
|
title="Edit label"
|
||||||
instruction={this.instruction(editedLabelText)}
|
instruction={this.instruction(editedLabelText)}
|
||||||
@@ -452,7 +452,7 @@ class CategoryValue extends React.Component {
|
|||||||
"data-testid": `${metadataField}:${displayString}:edit-label-name`,
|
"data-testid": `${metadataField}:${displayString}:edit-label-name`,
|
||||||
leftIcon: "tag",
|
leftIcon: "tag",
|
||||||
intent: "none",
|
intent: "none",
|
||||||
autoFocus: true
|
autoFocus: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -483,7 +483,7 @@ class CategoryValue extends React.Component {
|
|||||||
fontStyle:
|
fontStyle:
|
||||||
displayString === globals.unassignedCategoryLabel
|
displayString === globals.unassignedCategoryLabel
|
||||||
? "italic"
|
? "italic"
|
||||||
: "auto"
|
: "auto",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{count}
|
{count}
|
||||||
@@ -498,7 +498,7 @@ class CategoryValue extends React.Component {
|
|||||||
backgroundColor:
|
backgroundColor:
|
||||||
isColorBy && categories
|
isColorBy && categories
|
||||||
? colorScale(categories.indexOf(value))
|
? colorScale(categories.indexOf(value))
|
||||||
: "inherit"
|
: "inherit",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{isUserAnno ? (
|
{isUserAnno ? (
|
||||||
@@ -526,7 +526,7 @@ class CategoryValue extends React.Component {
|
|||||||
displayString ===
|
displayString ===
|
||||||
globals.unassignedCategoryLabel
|
globals.unassignedCategoryLabel
|
||||||
? "italic"
|
? "italic"
|
||||||
: "auto"
|
: "auto",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{` ${displayString}`}
|
{` ${displayString}`}
|
||||||
@@ -566,7 +566,7 @@ class CategoryValue extends React.Component {
|
|||||||
marginLeft: 0,
|
marginLeft: 0,
|
||||||
position: "relative",
|
position: "relative",
|
||||||
top: -1,
|
top: -1,
|
||||||
minHeight: 16
|
minHeight: 16,
|
||||||
}}
|
}}
|
||||||
data-testclass="seeActions"
|
data-testclass="seeActions"
|
||||||
data-testid={`${metadataField}:${displayString}:see-actions`}
|
data-testid={`${metadataField}:${displayString}:see-actions`}
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import Categorical from "../categorical/categorical";
|
import Categorical from "../categorical";
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../globals";
|
||||||
import DynamicScatterplot from "../scatterplot/scatterplot";
|
import DynamicScatterplot from "../scatterplot/scatterplot";
|
||||||
import TopLeftLogoAndTitle from "./topLeftLogoAndTitle";
|
import TopLeftLogoAndTitle from "./topLeftLogoAndTitle";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect((state) => ({
|
||||||
responsive: state.responsive,
|
responsive: state.responsive,
|
||||||
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor
|
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
|
||||||
}))
|
}))
|
||||||
class LeftSideBar extends React.Component {
|
class LeftSideBar extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
responsive,
|
responsive,
|
||||||
scatterplotXXaccessor,
|
scatterplotXXaccessor,
|
||||||
scatterplotYYaccessor
|
scatterplotYYaccessor,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -31,7 +31,7 @@ class LeftSideBar extends React.Component {
|
|||||||
position: "fixed",
|
position: "fixed",
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
/* x y blur spread color */
|
/* x y blur spread color */
|
||||||
borderRight: `1px solid ${globals.lightGrey}`
|
borderRight: `1px solid ${globals.lightGrey}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TopLeftLogoAndTitle />
|
<TopLeftLogoAndTitle />
|
||||||
@@ -41,7 +41,7 @@ class LeftSideBar extends React.Component {
|
|||||||
marginTop: logoRelatedPadding,
|
marginTop: logoRelatedPadding,
|
||||||
width: globals.leftSidebarWidth,
|
width: globals.leftSidebarWidth,
|
||||||
overflowY: "auto",
|
overflowY: "auto",
|
||||||
overflowX: "hidden"
|
overflowX: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Categorical />
|
<Categorical />
|
||||||
|
|||||||
Reference in New Issue
Block a user