mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-07 07:48:12 +08:00
Continuous data in right sidebar (#985)
* Create right sidebar files, move histos over * restructure continuous legend + all padding * right sidebar file * proper graph positioning and resize * new lasso values since right sidebar * fix autosave position
This commit is contained in:
@@ -26,8 +26,8 @@ export const datasets = {
|
|||||||
cellsets: {
|
cellsets: {
|
||||||
lasso: [
|
lasso: [
|
||||||
{
|
{
|
||||||
"coordinates-as-percent": { x1: 0.05, y1: 0.25, x2: 0.15, y2: 0.35 },
|
"coordinates-as-percent": { x1: 0.1, y1: 0.25, x2: 0.7, y2: 0.75 },
|
||||||
count: "88"
|
count: "1181"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
categorical: [
|
categorical: [
|
||||||
@@ -97,8 +97,8 @@ export const datasets = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
lasso: {
|
lasso: {
|
||||||
"coordinates-as-percent": { x1: 0.45, y1: 0.05, x2: 0.65, y2: 0.15 },
|
"coordinates-as-percent": { x1: 0.25, y1: 0.05, x2: 0.75, y2: 0.55 },
|
||||||
count: "39"
|
count: "329"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scatter: {
|
scatter: {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { connect } from "react-redux";
|
|||||||
|
|
||||||
import Container from "./framework/container";
|
import Container from "./framework/container";
|
||||||
import LeftSideBar from "./leftSidebar";
|
import LeftSideBar from "./leftSidebar";
|
||||||
|
import RightSideBar from "./rightSidebar";
|
||||||
import Legend from "./continuousLegend";
|
import Legend from "./continuousLegend";
|
||||||
import Graph from "./graph/graph";
|
import Graph from "./graph/graph";
|
||||||
import MenuBar from "./menubar";
|
import MenuBar from "./menubar";
|
||||||
@@ -88,6 +89,7 @@ class App extends React.Component {
|
|||||||
) : null}
|
) : null}
|
||||||
<div>
|
<div>
|
||||||
{loading ? null : <LeftSideBar />}
|
{loading ? null : <LeftSideBar />}
|
||||||
|
{loading ? null : <RightSideBar />}
|
||||||
{loading ? null : <MenuBar />}
|
{loading ? null : <MenuBar />}
|
||||||
{loading ? null : <Graph key={graphRenderCounter} />}
|
{loading ? null : <Graph key={graphRenderCounter} />}
|
||||||
{loading ? null : <Autosave />}
|
{loading ? null : <Autosave />}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import * as globals from "../../globals";
|
||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
@@ -68,7 +68,7 @@ class Autosave extends React.Component {
|
|||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
display: "inherit",
|
display: "inherit",
|
||||||
right: 5,
|
right: globals.leftSidebarWidth + 5,
|
||||||
bottom: 5
|
bottom: 5
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import React from "react";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import { interpolateCool } from "d3-scale-chromatic";
|
import { interpolateCool } from "d3-scale-chromatic";
|
||||||
|
import * as globals from "../../globals";
|
||||||
|
|
||||||
// create continuous color legend
|
// create continuous color legend
|
||||||
// http://bl.ocks.org/syntagmatic/e8ccca52559796be775553b467593a9f
|
// http://bl.ocks.org/syntagmatic/e8ccca52559796be775553b467593a9f
|
||||||
@@ -142,7 +143,7 @@ class ContinuousLegend extends React.Component {
|
|||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
display: colorAccessor ? "inherit" : "none",
|
display: colorAccessor ? "inherit" : "none",
|
||||||
right: 0,
|
right: globals.leftSidebarWidth,
|
||||||
top: responsive.height / 2
|
top: responsive.height / 2
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class Graph extends React.PureComponent {
|
|||||||
super(props);
|
super(props);
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.graphPaddingTop = 0;
|
this.graphPaddingTop = 0;
|
||||||
this.graphPaddingRight = globals.leftSidebarWidth;
|
this.graphPaddingRightLeft = globals.leftSidebarWidth * 2;
|
||||||
this.renderCache = {
|
this.renderCache = {
|
||||||
X: null,
|
X: null,
|
||||||
Y: null,
|
Y: null,
|
||||||
@@ -412,7 +412,7 @@ class Graph extends React.PureComponent {
|
|||||||
handleEnd,
|
handleEnd,
|
||||||
handleCancel,
|
handleCancel,
|
||||||
responsive,
|
responsive,
|
||||||
this.graphPaddingRight,
|
this.graphPaddingRightLeft,
|
||||||
graphInteractionMode
|
graphInteractionMode
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -439,7 +439,7 @@ class Graph extends React.PureComponent {
|
|||||||
|
|
||||||
const newCentroidSVG = setupCentroidSVG(
|
const newCentroidSVG = setupCentroidSVG(
|
||||||
responsive,
|
responsive,
|
||||||
this.graphPaddingRight,
|
this.graphPaddingRightLeft,
|
||||||
centroidScreen,
|
centroidScreen,
|
||||||
centroidLabel.categoryField,
|
centroidLabel.categoryField,
|
||||||
colorAccessor
|
colorAccessor
|
||||||
@@ -539,7 +539,8 @@ class Graph extends React.PureComponent {
|
|||||||
const cameraInvTF = camera.invView();
|
const cameraInvTF = camera.invView();
|
||||||
|
|
||||||
/* screen -> gl */
|
/* screen -> gl */
|
||||||
const x = (2 * pin[0]) / (responsive.width - this.graphPaddingRight) - 1;
|
const x =
|
||||||
|
(2 * pin[0]) / (responsive.width - this.graphPaddingRightLeft) - 1;
|
||||||
const y = 2 * (1 - pin[1] / (responsive.height - this.graphPaddingTop)) - 1;
|
const y = 2 * (1 - pin[1] / (responsive.height - this.graphPaddingTop)) - 1;
|
||||||
|
|
||||||
const xy = vec2.fromValues(x, y);
|
const xy = vec2.fromValues(x, y);
|
||||||
@@ -566,7 +567,7 @@ class Graph extends React.PureComponent {
|
|||||||
|
|
||||||
const pin = [
|
const pin = [
|
||||||
Math.round(
|
Math.round(
|
||||||
((xy[0] + 1) * (responsive.width - this.graphPaddingRight)) / 2
|
((xy[0] + 1) * (responsive.width - this.graphPaddingRightLeft)) / 2
|
||||||
),
|
),
|
||||||
Math.round(
|
Math.round(
|
||||||
-((xy[1] + 1) / 2 - 1) * (responsive.height - this.graphPaddingTop)
|
-((xy[1] + 1) / 2 - 1) * (responsive.height - this.graphPaddingTop)
|
||||||
@@ -753,13 +754,13 @@ class Graph extends React.PureComponent {
|
|||||||
zIndex: -9999,
|
zIndex: -9999,
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
top: this.graphPaddingTop,
|
top: this.graphPaddingTop,
|
||||||
right: 0
|
right: globals.leftSidebarWidth
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div id="graphAttachPoint" />
|
<div id="graphAttachPoint" />
|
||||||
<div style={{ padding: 0, margin: 0 }}>
|
<div style={{ padding: 0, margin: 0 }}>
|
||||||
<canvas
|
<canvas
|
||||||
width={responsive.width - this.graphPaddingRight}
|
width={responsive.width - this.graphPaddingRightLeft}
|
||||||
height={responsive.height - this.graphPaddingTop}
|
height={responsive.height - this.graphPaddingTop}
|
||||||
data-testid="layout-graph"
|
data-testid="layout-graph"
|
||||||
ref={canvas => {
|
ref={canvas => {
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ const Lasso = () => {
|
|||||||
.append("rect")
|
.append("rect")
|
||||||
.attr("width", bbox.width)
|
.attr("width", bbox.width)
|
||||||
.attr("height", bbox.height)
|
.attr("height", bbox.height)
|
||||||
.attr("fill", "tomato")
|
|
||||||
.attr("opacity", 0);
|
.attr("opacity", 0);
|
||||||
|
|
||||||
const drag = d3
|
const drag = d3
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class LeftSideBar extends React.Component {
|
|||||||
position: "fixed",
|
position: "fixed",
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
/* x y blur spread color */
|
/* x y blur spread color */
|
||||||
boxShadow: "-3px 0px 6px 2px rgba(153,153,153,0.4)"
|
borderRight: `1px solid ${globals.lightGrey}`
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TopLeftLogoAndTitle />
|
<TopLeftLogoAndTitle />
|
||||||
@@ -47,8 +47,6 @@ class LeftSideBar extends React.Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Categorical />
|
<Categorical />
|
||||||
<GeneExpression />
|
|
||||||
<Continuous />
|
|
||||||
</div>
|
</div>
|
||||||
{scatterplotXXaccessor && scatterplotYYaccessor ? (
|
{scatterplotXXaccessor && scatterplotYYaccessor ? (
|
||||||
<DynamicScatterplot />
|
<DynamicScatterplot />
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
Position,
|
Position,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
Radio
|
Radio,
|
||||||
|
Icon
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import { World } from "../../util/stateManager";
|
import { World } from "../../util/stateManager";
|
||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
@@ -16,10 +17,7 @@ import CellSetButton from "./cellSetButtons";
|
|||||||
import InformationMenu from "./infoMenu";
|
import InformationMenu from "./infoMenu";
|
||||||
import UndoRedoReset from "./undoRedoReset";
|
import UndoRedoReset from "./undoRedoReset";
|
||||||
import Clip from "./clip";
|
import Clip from "./clip";
|
||||||
import {
|
import * as globals from "../../globals";
|
||||||
tooltipHoverOpenDelay,
|
|
||||||
tooltipHoverOpenDelayQuick
|
|
||||||
} from "../../globals";
|
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
universe: state.universe,
|
universe: state.universe,
|
||||||
@@ -282,7 +280,7 @@ class MenuBar extends React.Component {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content={tipMessage}
|
content={tipMessage}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelayQuick}
|
hoverOpenDelay={globals.tooltipHoverOpenDelayQuick}
|
||||||
>
|
>
|
||||||
<AnchorButton
|
<AnchorButton
|
||||||
disabled={!haveBothCellSets}
|
disabled={!haveBothCellSets}
|
||||||
@@ -293,9 +291,7 @@ class MenuBar extends React.Component {
|
|||||||
fill
|
fill
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.computeDiffExp}
|
onClick={this.computeDiffExp}
|
||||||
>
|
/>
|
||||||
Compute Differential Expression
|
|
||||||
</AnchorButton>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@@ -303,7 +299,7 @@ class MenuBar extends React.Component {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content="Remove differentially expressed gene list and clear cell selections"
|
content="Remove differentially expressed gene list and clear cell selections"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelayQuick}
|
hoverOpenDelay={globals.tooltipHoverOpenDelayQuick}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -352,7 +348,7 @@ class MenuBar extends React.Component {
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
right: 8,
|
right: globals.leftSidebarWidth + 8,
|
||||||
top: 8
|
top: 8
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -360,7 +356,7 @@ class MenuBar extends React.Component {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content="Show only metadata and cells which are currently selected"
|
content="Show only metadata and cells which are currently selected"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelay}
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
>
|
>
|
||||||
<AnchorButton
|
<AnchorButton
|
||||||
type="button"
|
type="button"
|
||||||
@@ -378,14 +374,14 @@ class MenuBar extends React.Component {
|
|||||||
dispatch({ type: "increment graph render counter" });
|
dispatch({ type: "increment graph render counter" });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
subset to current selection
|
<Icon icon="double-chevron-down" />
|
||||||
</AnchorButton>
|
</AnchorButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div className="bp3-button-group">
|
<div className="bp3-button-group">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={selectionTooltip}
|
content={selectionTooltip}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelay}
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -406,7 +402,7 @@ class MenuBar extends React.Component {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content="Drag to pan, scroll to zoom"
|
content="Drag to pan, scroll to zoom"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelay}
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -436,7 +432,7 @@ class MenuBar extends React.Component {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content="Select embedding for visualization"
|
content="Select embedding for visualization"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hoverOpenDelay={tooltipHoverOpenDelay}
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -63,9 +63,7 @@ function InformationMenu(props) {
|
|||||||
onClick={resetInterface}
|
onClick={resetInterface}
|
||||||
data-testid="reset"
|
data-testid="reset"
|
||||||
data-testclass={`resetting-${resettingInterface}`}
|
data-testclass={`resetting-${resettingInterface}`}
|
||||||
>
|
/>
|
||||||
reset
|
|
||||||
</AnchorButton>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// jshint esversion: 6
|
||||||
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import Continuous from "../continuous/continuous";
|
||||||
|
import GeneExpression from "../geneExpression";
|
||||||
|
import * as globals from "../../globals";
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
responsive: state.responsive,
|
||||||
|
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||||
|
scatterplotYYaccessor: state.controls.scatterplotYYaccessor
|
||||||
|
}))
|
||||||
|
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;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: "white",
|
||||||
|
/* x y blur spread color */
|
||||||
|
borderLeft: `1px solid ${globals.lightGrey}`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: responsive.height,
|
||||||
|
width: globals.leftSidebarWidth,
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<GeneExpression />
|
||||||
|
<Continuous />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RightSidebar;
|
||||||
@@ -26,7 +26,7 @@ export const blue = Colors.BLUE3;
|
|||||||
export const linkBlue = Colors.BLUE5;
|
export const linkBlue = Colors.BLUE5;
|
||||||
export const lightestGrey = "rgb(249,249,249)";
|
export const lightestGrey = "rgb(249,249,249)";
|
||||||
export const lighterGrey = "rgb(245,245,245)";
|
export const lighterGrey = "rgb(245,245,245)";
|
||||||
export const lightGrey = "rgb(211,211,211)";
|
export const lightGrey = Colors.LIGHT_GRAY1;
|
||||||
export const mediumGrey = "rgb(153,153,153)";
|
export const mediumGrey = "rgb(153,153,153)";
|
||||||
export const darkGrey = "rgb(102,102,102)";
|
export const darkGrey = "rgb(102,102,102)";
|
||||||
export const darkerGrey = "rgb(51,51,51)";
|
export const darkerGrey = "rgb(51,51,51)";
|
||||||
|
|||||||
Reference in New Issue
Block a user