mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-03 17:18:12 +08:00
Merge pull request #56 from chanzuckerberg/responsive
adds basic responsive capability for graph and metadata
This commit is contained in:
@@ -39,6 +39,23 @@ class App extends React.Component {
|
|||||||
first request includes query straight off the url bar for now
|
first request includes query straight off the url bar for now
|
||||||
*/
|
*/
|
||||||
this.props.dispatch(actions.requestCells(window.location.search));
|
this.props.dispatch(actions.requestCells(window.location.search));
|
||||||
|
/* listen for resize events */
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
this.props.dispatch({
|
||||||
|
type: "window resize",
|
||||||
|
data: {
|
||||||
|
height: window.innerHeight,
|
||||||
|
width: window.innerWidth
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.props.dispatch({
|
||||||
|
type: "window resize",
|
||||||
|
data: {
|
||||||
|
height: window.innerHeight,
|
||||||
|
width: window.innerWidth
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ import FaSave from "react-icons/lib/fa/download";
|
|||||||
graphVec: state.controls.graphVec,
|
graphVec: state.controls.graphVec,
|
||||||
currentCellSelection: state.controls.currentCellSelection,
|
currentCellSelection: state.controls.currentCellSelection,
|
||||||
graphBrushSelection: state.controls.graphBrushSelection,
|
graphBrushSelection: state.controls.graphBrushSelection,
|
||||||
opacityForDeselectedCells: state.controls.opacityForDeselectedCells
|
opacityForDeselectedCells: state.controls.opacityForDeselectedCells,
|
||||||
|
responsive: state.responsive
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
class Graph extends React.Component {
|
class Graph extends React.Component {
|
||||||
@@ -53,6 +54,7 @@ class Graph extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.inverse = mat4.identity([]);
|
this.inverse = mat4.identity([]);
|
||||||
|
this.graphPaddingTop = 100;
|
||||||
this.state = {
|
this.state = {
|
||||||
drawn: false,
|
drawn: false,
|
||||||
svg: null,
|
svg: null,
|
||||||
@@ -95,7 +97,7 @@ class Graph extends React.Component {
|
|||||||
scale: viewportHeight / viewportWidth
|
scale: viewportHeight / viewportWidth
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({camera})
|
this.setState({ camera });
|
||||||
camera.tick();
|
camera.tick();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -165,7 +167,7 @@ class Graph extends React.Component {
|
|||||||
const inverse = mat4.invert([], this.state.camera.view());
|
const inverse = mat4.invert([], this.state.camera.view());
|
||||||
|
|
||||||
// transform screen coordinates -> cell coordinates
|
// transform screen coordinates -> cell coordinates
|
||||||
const invert = (pin) => {
|
const invert = pin => {
|
||||||
const x = 2 * pin[0] / globals.graphWidth - 1;
|
const x = 2 * pin[0] / globals.graphWidth - 1;
|
||||||
const y = 2 * (1 - pin[1] / globals.graphHeight) - 1;
|
const y = 2 * (1 - pin[1] / globals.graphHeight) - 1;
|
||||||
const pout = [x + inverse[12], y + inverse[13]];
|
const pout = [x + inverse[12], y + inverse[13]];
|
||||||
@@ -198,10 +200,7 @@ class Graph extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div
|
<div id="graphWrapper">
|
||||||
id="graphWrapper"
|
|
||||||
|
|
||||||
>
|
|
||||||
<div style={{ position: "fixed", right: 0, top: 0 }}>
|
<div style={{ position: "fixed", right: 0, top: 0 }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -287,7 +286,14 @@ class Graph extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{marginRight: 50, marginTop: 50, zIndex: -9999 }}
|
style={{
|
||||||
|
marginRight: 50,
|
||||||
|
marginTop: 50,
|
||||||
|
zIndex: -9999,
|
||||||
|
position: "fixed",
|
||||||
|
right: 20,
|
||||||
|
bottom: 20
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -297,8 +303,8 @@ class Graph extends React.Component {
|
|||||||
/>
|
/>
|
||||||
<div style={{ padding: 0, margin: 0 }}>
|
<div style={{ padding: 0, margin: 0 }}>
|
||||||
<canvas
|
<canvas
|
||||||
width={globals.graphWidth}
|
width={this.props.responsive.height - this.graphPaddingTop}
|
||||||
height={globals.graphHeight}
|
height={this.props.responsive.height - this.graphPaddingTop}
|
||||||
ref={canvas => {
|
ref={canvas => {
|
||||||
this.reglCanvas = canvas;
|
this.reglCanvas = canvas;
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import * as globals from "../globals";
|
|||||||
import DynamicScatterplot from "./scatterplot/scatterplot";
|
import DynamicScatterplot from "./scatterplot/scatterplot";
|
||||||
|
|
||||||
@connect(state => {
|
@connect(state => {
|
||||||
return {};
|
return {
|
||||||
|
responsive: state.responsive
|
||||||
|
};
|
||||||
})
|
})
|
||||||
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"
|
||||||
};
|
};
|
||||||
@@ -39,8 +42,7 @@ class LeftSideBar extends React.Component {
|
|||||||
padding: "none",
|
padding: "none",
|
||||||
outline: 0,
|
outline: 0,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight:
|
fontWeight: this.state.currentTab === "metadata" ? 700 : 400,
|
||||||
this.state.currentTab === "metadata" ? 700 : 400,
|
|
||||||
fontStyle:
|
fontStyle:
|
||||||
this.state.currentTab === "metadata" ? "inherit" : "italic",
|
this.state.currentTab === "metadata" ? "inherit" : "italic",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
@@ -49,7 +51,7 @@ class LeftSideBar extends React.Component {
|
|||||||
borderTop: "none",
|
borderTop: "none",
|
||||||
borderBottom: "none",
|
borderBottom: "none",
|
||||||
borderRight: "none",
|
borderRight: "none",
|
||||||
borderLeft: "none",
|
borderLeft: "none"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.setState({ currentTab: "metadata" });
|
this.setState({ currentTab: "metadata" });
|
||||||
@@ -62,8 +64,7 @@ class LeftSideBar extends React.Component {
|
|||||||
padding: "none",
|
padding: "none",
|
||||||
outline: 0,
|
outline: 0,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight:
|
fontWeight: this.state.currentTab === "expression" ? 700 : 400,
|
||||||
this.state.currentTab === "expression" ? 700 : 400,
|
|
||||||
fontStyle:
|
fontStyle:
|
||||||
this.state.currentTab === "expression" ? "inherit" : "italic",
|
this.state.currentTab === "expression" ? "inherit" : "italic",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
@@ -72,7 +73,7 @@ class LeftSideBar extends React.Component {
|
|||||||
borderTop: "none",
|
borderTop: "none",
|
||||||
borderBottom: "none",
|
borderBottom: "none",
|
||||||
borderRight: "none",
|
borderRight: "none",
|
||||||
borderLeft: "none",
|
borderLeft: "none"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.setState({ currentTab: "expression" });
|
this.setState({ currentTab: "expression" });
|
||||||
@@ -83,7 +84,7 @@ class LeftSideBar extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: 350,
|
height: this.props.responsive.height - this.metadataSectionPadding,
|
||||||
width: 400,
|
width: 400,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
overflowY: "auto",
|
overflowY: "auto",
|
||||||
|
|||||||
@@ -11,13 +11,15 @@ import cells from "./cells";
|
|||||||
import expression from "./expression";
|
import expression from "./expression";
|
||||||
import controls from "./controls";
|
import controls from "./controls";
|
||||||
import differential from "./differential";
|
import differential from "./differential";
|
||||||
|
import responsive from "./responsive";
|
||||||
|
|
||||||
const Reducer = combineReducers({
|
const Reducer = combineReducers({
|
||||||
initialize,
|
initialize,
|
||||||
cells,
|
cells,
|
||||||
expression,
|
expression,
|
||||||
controls,
|
controls,
|
||||||
differential
|
differential,
|
||||||
|
responsive
|
||||||
});
|
});
|
||||||
|
|
||||||
let store = createStore(
|
let store = createStore(
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ const Responsive = (
|
|||||||
action
|
action
|
||||||
) => {
|
) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "resize event":
|
case "window resize":
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
width: action.data,
|
width: action.data.width,
|
||||||
height: action.data
|
height: action.data.height
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
Reference in New Issue
Block a user