Merge pull request #195 from chanzuckerberg/layout-ui-changes

Layout changes
This commit is contained in:
Bruce Martin
2018-08-20 08:43:02 -07:00
committed by GitHub
6 changed files with 96 additions and 104 deletions
+18 -13
View File
@@ -18,7 +18,8 @@ import SectionHeader from "./framework/sectionHeader";
@connect(state => { @connect(state => {
return { return {
cells: state.cells cells: state.cells,
initialize: state.initialize
}; };
}) })
class App extends React.Component { class App extends React.Component {
@@ -60,27 +61,27 @@ class App extends React.Component {
} }
render() { render() {
// console.log('app:', this.props, this.state)
return ( return (
<Container> <Container>
<Helmet title="cellxgene" /> <Helmet title="cellxgene" />
{this.props.cells.loading ? ( {this.props.cells.loading || this.props.initialize.loading ? (
<div <div
style={{ position: "fixed", left: window.innerWidth / 2, top: 150 }} style={{
position: "fixed",
fontWeight: 500,
top: window.innerHeight / 2,
left: window.innerWidth / 2 - 50
}}
> >
{/*<PulseLoader color="rgb(0,0,0)" size="10px" margin="4px" />*/} loading cellxgene
<span
style={{ fontFamily: globals.accentFont, fontStyle: "italic" }}
>
loading cells
</span>
</div> </div>
) : null} ) : null}
{this.props.cells.error ? "Error loading cells" : null} {this.props.cells.error ? "Error loading cells" : null}
<div> <div>
<LeftSideBar /> {this.props.cells.loading || this.props.initialize.loading ? null : (
<LeftSideBar />
)}
<div <div
style={{ style={{
padding: 15, padding: 15,
@@ -88,7 +89,11 @@ class App extends React.Component {
marginLeft: 350 /* but responsive */ marginLeft: 350 /* but responsive */
}} }}
> >
<Graph /> {this.props.cells.loading ||
this.props.initialize.loading ? null : (
<Graph />
)}
<Legend /> <Legend />
{/*<Parallel/>*/} {/*<Parallel/>*/}
</div> </div>
@@ -33,17 +33,18 @@ class CellSetButton extends React.Component {
}} }}
onClick={this.set.bind(this)} onClick={this.set.bind(this)}
> >
<span style={{ fontSize: 24, fontWeight: 700 }}> <span style={{ fontSize: 14, fontWeight: 700 }}>
{" "} {" "}
{this.props.eitherCellSetOneOrTwo}{" "} {this.props.eitherCellSetOneOrTwo}
{": "}
</span> </span>
<span <span
style={{ style={{
fontFamily: "Georgia", fontFamily: "Georgia",
fontStyle: "italic", fontSize: 14,
marginLeft: 8, marginLeft: 8,
position: "relative", position: "relative",
top: -3 top: 0
}} }}
> >
{this.props.differential[ {this.props.differential[
@@ -244,30 +244,6 @@ class Heatmap extends React.Component {
return ( return (
<div> <div>
Color by any gene:
<ReactAutocomplete
items={this.props.allGeneNames}
shouldItemRender={(item, value) =>
item.toLowerCase().indexOf(value.toLowerCase()) > -1
}
getItemValue={item => item}
renderItem={(item, highlighted) => (
<div
key={item}
style={{ backgroundColor: highlighted ? "#eee" : "transparent" }}
>
{item}
</div>
)}
value={this.state.value}
onChange={e => this.setState({ value: e.target.value })}
onSelect={value => {
this.setState({ value });
this.props.dispatch(
actions.requestSingleGeneExpressionCountsForColoringPOST(value)
);
}}
/>
<div <div
style={{ style={{
display: "flex", display: "flex",
@@ -38,57 +38,46 @@ class Expression extends React.Component {
return null; return null;
} }
return ( return (
<div> <div style={{ marginRight: 10, marginBottom: 10 }}>
<div style={{ margin: 10 }}> <CellSetButton {...this.props} eitherCellSetOneOrTwo={1} />
<div style={{ marginBottom: 15, width: 300 }}> <CellSetButton {...this.props} eitherCellSetOneOrTwo={2} />
There are currently <button
{" " + style={{
(this.props.crossfilter fontSize: 14,
? this.props.crossfilter.cells.countFiltered() fontWeight: 400,
: 0) + color: "#FFF",
" "} padding: "0px 10px",
cells selected, click a cell set button to store them. height: 30,
</div> borderRadius: 2,
<CellSetButton {...this.props} eitherCellSetOneOrTwo={1} /> backgroundColor:
<CellSetButton {...this.props} eitherCellSetOneOrTwo={2} /> this.props.differential.celllist1 &&
</div> this.props.differential.celllist2
<div> ? globals.brightBlue
{this.props.differential.celllist1 && : globals.lightGrey,
this.props.differential.celllist2 ? ( border: "none",
<button cursor:
style={{ this.props.differential.celllist1 &&
fontSize: 18, this.props.differential.celllist2
margin: 10, ? "pointer"
fontWeight: 700, : "auto"
color: "#FFF", }}
padding: "12px 20px", onClick={this.computeDiffExp.bind(this)}
backgroundColor: globals.brightBlue, >
border: "none", Compute differential expression
cursor: "pointer" </button>
}}
onClick={this.computeDiffExp.bind(this)}
>
Compute differential expression
</button>
) : (
<button
style={{
fontSize: 18,
margin: 10,
fontWeight: 700,
color: "#FFF",
padding: "12px 20px",
backgroundColor: globals.mediumGrey,
border: "none"
}}
>
Compute differential expression
</button>
)}
</div>
</div> </div>
); );
} }
} }
export default Expression; export default Expression;
// <div style={{ marginBottom: 15, width: 300 }}>
// There are currently
// {" " +
// (this.props.crossfilter
// ? this.props.crossfilter.cells.countFiltered()
// : 0) +
// " "}
// cells selected, click a cell set button to store them.
// </div>
+22 -11
View File
@@ -36,6 +36,8 @@ class Graph extends React.Component {
this.count = 0; this.count = 0;
this.inverse = mat4.identity([]); this.inverse = mat4.identity([]);
this.graphPaddingTop = 100; this.graphPaddingTop = 100;
this.graphPaddingBottom = 45;
this.graphPaddingRight = 10;
this.renderCache = { this.renderCache = {
positions: null, positions: null,
colors: null colors: null
@@ -209,9 +211,12 @@ class Graph extends React.Component {
} }
if ( if (
/* invisibly handles the initial null vs integer case as well as resize events */
prevProps.responsive.height !== this.props.responsive.height || prevProps.responsive.height !== this.props.responsive.height ||
prevProps.responsive.width !== this.props.responsive.width prevProps.responsive.width !== this.props.responsive.width ||
/* first time */
(this.props.responsive.height &&
this.props.responsive.width &&
!this.state.svg)
) { ) {
/* clear out whatever was on the div, even if nothing, but usually the brushes etc */ /* clear out whatever was on the div, even if nothing, but usually the brushes etc */
d3.select("#graphAttachPoint") d3.select("#graphAttachPoint")
@@ -315,9 +320,10 @@ class Graph extends React.Component {
}} }}
style={{ style={{
fontSize: 14, fontSize: 14,
fontWeight: 700, fontWeight: 400,
color: "white", color: "white",
padding: "10px 20px", padding: "0px 10px",
height: 30,
marginRight: 10, marginRight: 10,
borderRadius: 2, borderRadius: 2,
backgroundColor: globals.brightBlue, backgroundColor: globals.brightBlue,
@@ -333,9 +339,10 @@ class Graph extends React.Component {
}} }}
style={{ style={{
fontSize: 14, fontSize: 14,
fontWeight: 700, fontWeight: 400,
color: "white", color: "white",
padding: "10px 20px", padding: "0px 10px",
height: 30,
marginRight: 10, marginRight: 10,
borderRadius: 2, borderRadius: 2,
backgroundColor: globals.brightBlue, backgroundColor: globals.brightBlue,
@@ -346,7 +353,7 @@ class Graph extends React.Component {
regraph selection regraph selection
</button> </button>
<div> <div>
<span style={{ position: "relative", top: 3 }}> <span>
<button <button
onClick={() => { onClick={() => {
this.setState({ mode: "brush" }); this.setState({ mode: "brush" });
@@ -359,6 +366,7 @@ class Graph extends React.Component {
: "1px solid white", : "1px solid white",
backgroundColor: "white", backgroundColor: "white",
padding: 5, padding: 5,
marginRight: 10,
borderRadius: 3 borderRadius: 3
}} }}
> >
@@ -379,6 +387,7 @@ class Graph extends React.Component {
: "1px solid white", : "1px solid white",
backgroundColor: "white", backgroundColor: "white",
padding: 5, padding: 5,
marginRight: 10,
borderRadius: 3 borderRadius: 3
}} }}
> >
@@ -391,9 +400,11 @@ class Graph extends React.Component {
<button <button
style={{ style={{
fontSize: 14, fontSize: 14,
fontWeight: 700, fontWeight: 400,
color: "white", color: "white",
padding: "10px 20px", padding: "0px 10px",
height: 30,
borderRadius: 2,
backgroundColor: globals.lightGrey, backgroundColor: globals.lightGrey,
border: "none", border: "none",
cursor: "pointer" cursor: "pointer"
@@ -410,8 +421,8 @@ class Graph extends React.Component {
marginTop: 50, marginTop: 50,
zIndex: -9999, zIndex: -9999,
position: "fixed", position: "fixed",
right: 20, right: this.graphPaddingRight,
bottom: 20 bottom: this.graphPaddingBottom
}} }}
> >
<div <div
+14 -4
View File
@@ -17,12 +17,14 @@ import DynamicScatterplot from "./scatterplot/scatterplot";
class LeftSideBar extends React.Component { class LeftSideBar extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.metadataSectionPadding = 300;
this.state = { this.state = {
currentTab: "metadata" currentTab: "metadata"
}; };
} }
render() { render() {
/* this magic number should be made less fragile, if cellxgene logo or tabs change, this must as well */
const metadataSectionPadding =
this.state.currentTab === "metadata" ? 88 : 450;
return ( return (
<div style={{ position: "fixed" }}> <div style={{ position: "fixed" }}>
<p <p
@@ -84,7 +86,7 @@ class LeftSideBar extends React.Component {
</div> </div>
<div <div
style={{ style={{
height: this.props.responsive.height - this.metadataSectionPadding, height: this.props.responsive.height - metadataSectionPadding,
width: 400, width: 400,
padding: 10, padding: 10,
overflowY: "auto", overflowY: "auto",
@@ -95,12 +97,20 @@ class LeftSideBar extends React.Component {
{this.state.currentTab === "metadata" ? <Continuous /> : null} {this.state.currentTab === "metadata" ? <Continuous /> : null}
{this.state.currentTab === "expression" ? <Heatmap /> : null} {this.state.currentTab === "expression" ? <Heatmap /> : null}
</div> </div>
<div style={{ position: "fixed", bottom: 0, left: 0 }}> <div
{this.state.currentTab === "metadata" ? <ExpressionButtons /> : null} style={{
position: "fixed",
bottom: 0,
left: 0
}}
>
{this.state.currentTab === "expression" ? ( {this.state.currentTab === "expression" ? (
<DynamicScatterplot /> <DynamicScatterplot />
) : null} ) : null}
</div> </div>
<div style={{ position: "fixed", bottom: 0, right: 0 }}>
{this.state.currentTab === "metadata" ? <ExpressionButtons /> : null}
</div>
</div> </div>
); );
} }