mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-04 16:08:11 +08:00
toggle and scale dotplot
This commit is contained in:
@@ -79,11 +79,12 @@ class App extends React.Component {
|
|||||||
<Autosave />
|
<Autosave />
|
||||||
<TermsOfServicePrompt />
|
<TermsOfServicePrompt />
|
||||||
<Legend viewportRef={viewportRef} />
|
<Legend viewportRef={viewportRef} />
|
||||||
{layoutChoice.dotplot ? (
|
{layoutChoice.dotplot && <Dotplot viewportRef={viewportRef} />}
|
||||||
<Dotplot viewportRef={viewportRef} />
|
<Graph
|
||||||
) : (
|
key={graphRenderCounter}
|
||||||
<Graph key={graphRenderCounter} viewportRef={viewportRef} />
|
dotplotMode={layoutChoice.dotplot}
|
||||||
)}
|
viewportRef={viewportRef}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<RightSideBar />
|
<RightSideBar />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class Dotplot extends React.Component {
|
|||||||
this.dotplotTopPadding = 120;
|
this.dotplotTopPadding = 120;
|
||||||
this.dotplotLeftPadding = 170;
|
this.dotplotLeftPadding = 170;
|
||||||
this.rowColumnSize = 15;
|
this.rowColumnSize = 15;
|
||||||
|
this.dotplotBrowserScalingFactor = 0.65;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
viewport,
|
viewport,
|
||||||
@@ -23,10 +24,13 @@ class Dotplot extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
window.addEventListener("resize", this.handleResize);
|
window.addEventListener("resize", this.handleResize);
|
||||||
|
/* chrome only, which is support matrix as of 2021 */
|
||||||
|
document.body.style.zoom = `${this.dotplotBrowserScalingFactor * 100}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener("resize", this.handleResize);
|
window.removeEventListener("resize", this.handleResize);
|
||||||
|
document.body.style.zoom = "100%";
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewportDimensions = () => {
|
getViewportDimensions = () => {
|
||||||
@@ -56,6 +60,7 @@ class Dotplot extends React.Component {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
zIndex: -9999,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -66,8 +71,8 @@ class Dotplot extends React.Component {
|
|||||||
left: 0,
|
left: 0,
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
}}
|
}}
|
||||||
width={viewport.width}
|
width={viewport.width * (1 + this.dotplotBrowserScalingFactor)}
|
||||||
height={viewport.height}
|
height={viewport.height * (1 + this.dotplotBrowserScalingFactor)}
|
||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="dotplot_help_text"
|
id="dotplot_help_text"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { getDiscreteCellEmbeddingRowIndex } from "../../util/stateManager/viewSt
|
|||||||
layoutChoice: state.layoutChoice, // TODO: really should clean up naming, s/layout/embedding/g
|
layoutChoice: state.layoutChoice, // TODO: really should clean up naming, s/layout/embedding/g
|
||||||
schema: state.annoMatrix?.schema,
|
schema: state.annoMatrix?.schema,
|
||||||
crossfilter: state.obsCrossfilter,
|
crossfilter: state.obsCrossfilter,
|
||||||
|
dotplot: state.layoutChoice.dotplot,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
class Embedding extends React.PureComponent {
|
class Embedding extends React.PureComponent {
|
||||||
@@ -34,16 +35,16 @@ class Embedding extends React.PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { layoutChoice, schema, crossfilter } = this.props;
|
const { layoutChoice, schema, crossfilter, dotplot } = this.props;
|
||||||
const { annoMatrix } = crossfilter;
|
const { annoMatrix } = crossfilter;
|
||||||
return (
|
return (
|
||||||
<ButtonGroup
|
<ButtonGroup
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
display: "inherit",
|
|
||||||
left: 8,
|
left: 8,
|
||||||
bottom: 8,
|
bottom: 8,
|
||||||
zIndex: 9999,
|
zIndex: 9999,
|
||||||
|
display: dotplot ? "none" : "inherit",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Popover
|
<Popover
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import AddGeneToGenesetDialogue from "./addGeneToGenesetDialogue";
|
|||||||
genesetsUI: state.genesetsUI,
|
genesetsUI: state.genesetsUI,
|
||||||
colorAccessor: state.colors.colorAccessor,
|
colorAccessor: state.colors.colorAccessor,
|
||||||
dotplot: state.layoutChoice.dotplot,
|
dotplot: state.layoutChoice.dotplot,
|
||||||
|
dotplotColumns: state.dotplot.column,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
class GenesetMenus extends React.PureComponent {
|
class GenesetMenus extends React.PureComponent {
|
||||||
@@ -75,9 +76,11 @@ class GenesetMenus extends React.PureComponent {
|
|||||||
createText,
|
createText,
|
||||||
colorAccessor,
|
colorAccessor,
|
||||||
dotplot,
|
dotplot,
|
||||||
|
dotplotColumns,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const isColorBy = geneset === colorAccessor;
|
const isColorBy = geneset === colorAccessor;
|
||||||
|
const isDotplotColumns = geneset === dotplotColumns;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -138,8 +141,8 @@ class GenesetMenus extends React.PureComponent {
|
|||||||
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
>
|
>
|
||||||
<AnchorButton
|
<AnchorButton
|
||||||
active={isColorBy}
|
active={isColorBy || isDotplotColumns}
|
||||||
intent={isColorBy ? "primary" : "none"}
|
intent={isColorBy || isDotplotColumns ? "primary" : "none"}
|
||||||
style={{ marginLeft: 0 }}
|
style={{ marginLeft: 0 }}
|
||||||
onClick={this.handleColorByEntireGeneset}
|
onClick={this.handleColorByEntireGeneset}
|
||||||
data-testclass="colorby-entire-geneset"
|
data-testclass="colorby-entire-geneset"
|
||||||
|
|||||||
@@ -833,6 +833,7 @@ class Graph extends React.Component {
|
|||||||
layoutChoice,
|
layoutChoice,
|
||||||
pointDilation,
|
pointDilation,
|
||||||
crossfilter,
|
crossfilter,
|
||||||
|
dotplotMode,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { modelTF, projectionTF, camera, viewport, regl } = this.state;
|
const { modelTF, projectionTF, camera, viewport, regl } = this.state;
|
||||||
const cameraTF = camera?.view()?.slice();
|
const cameraTF = camera?.view()?.slice();
|
||||||
@@ -844,6 +845,7 @@ class Graph extends React.Component {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
display: dotplotMode ? "none" : "inherit",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GraphOverlayLayer
|
<GraphOverlayLayer
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Color By UI state
|
|||||||
const ColorsReducer = (
|
const ColorsReducer = (
|
||||||
state = {
|
state = {
|
||||||
/* TODO(colinmegill) #632 remove hardcode for dev */
|
/* TODO(colinmegill) #632 remove hardcode for dev */
|
||||||
colorMode: "color by dotplot columns" /* by continuous, by expression */,
|
colorMode: null /* by continuous, by expression */,
|
||||||
colorAccessor: null /* tissue, Apod */,
|
colorAccessor: null /* tissue, Apod */,
|
||||||
},
|
},
|
||||||
action
|
action
|
||||||
@@ -52,7 +52,17 @@ const ColorsReducer = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "color by dotplot columns":
|
case "toggle dotplot": {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
colorMode:
|
||||||
|
state.colorMode === "color by dotplot columns"
|
||||||
|
? null
|
||||||
|
: "color by dotplot columns",
|
||||||
|
colorAccessor: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
case "color by categorical metadata":
|
case "color by categorical metadata":
|
||||||
case "color by continuous metadata": {
|
case "color by continuous metadata": {
|
||||||
/* toggle between this mode and reset */
|
/* toggle between this mode and reset */
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ const Dotplot = (
|
|||||||
...state,
|
...state,
|
||||||
column: action.data,
|
column: action.data,
|
||||||
};
|
};
|
||||||
|
case "toggle dotplot":
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
row: null,
|
||||||
|
column: null,
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function setToDefaultLayout(schema) {
|
|||||||
const LayoutChoice = (
|
const LayoutChoice = (
|
||||||
state = {
|
state = {
|
||||||
available: [], // all available choices
|
available: [], // all available choices
|
||||||
dotplot: true, // is the dotplot toggled on, or not
|
dotplot: false, // is the dotplot toggled on, or not
|
||||||
current: undefined, // name of the current layout, eg, 'umap'
|
current: undefined, // name of the current layout, eg, 'umap'
|
||||||
currentDimNames: [], // dimension name
|
currentDimNames: [], // dimension name
|
||||||
},
|
},
|
||||||
@@ -42,7 +42,6 @@ const LayoutChoice = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "toggle dotplot": {
|
case "toggle dotplot": {
|
||||||
console.log("toggle: state, newstate", state.dotplot, !state.dotplot);
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dotplot: !state.dotplot,
|
dotplot: !state.dotplot,
|
||||||
|
|||||||
Reference in New Issue
Block a user