mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-07 21:38:13 +08:00
graph overlay improvements (#1141)
* check to see if display state has changed * add display state * create onDisplayChange * check to see if displaying anything and add opacity drop * pass callback down to children * add middle truncation to labels * remove unused import * add a bit of documentation * make prop addition more clear * rename onDisplayChange -> overlayToggled for readability
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
|
/* eslint-disable max-classes-per-file */
|
||||||
/* eslint-disable jsx-a11y/mouse-events-have-key-events */
|
/* eslint-disable jsx-a11y/mouse-events-have-key-events */
|
||||||
import React, { PureComponent } from "react";
|
import React, { PureComponent } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
import { categoryLabelDisplayStringLongLength } from "../../../globals";
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
colorAccessor: state.colors.colorAccessor,
|
colorAccessor: state.colors.colorAccessor,
|
||||||
@@ -9,6 +12,21 @@ export default
|
|||||||
labels: state.centroidLabels.labels
|
labels: state.centroidLabels.labels
|
||||||
}))
|
}))
|
||||||
class CentroidLabels extends PureComponent {
|
class CentroidLabels extends PureComponent {
|
||||||
|
// Check to see if centroids have either just been displayed or removed from the overlay
|
||||||
|
componentDidUpdate = prevProps => {
|
||||||
|
const { labels, overlayToggled } = this.props;
|
||||||
|
const prevSize = prevProps.labels.size;
|
||||||
|
const { size } = labels;
|
||||||
|
|
||||||
|
const displayChangeOff = prevSize > 0 && size === undefined;
|
||||||
|
const displayChangeOn = prevSize === undefined && size > 0;
|
||||||
|
|
||||||
|
if (displayChangeOn || displayChangeOff) {
|
||||||
|
// Notify overlay layer of display change
|
||||||
|
overlayToggled("centroidLabels", displayChangeOn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
labels,
|
labels,
|
||||||
@@ -28,6 +46,16 @@ class CentroidLabels extends PureComponent {
|
|||||||
fontSize = "18px";
|
fontSize = "18px";
|
||||||
fontWeight = "800";
|
fontWeight = "800";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mirror LSB middle truncation
|
||||||
|
let label = key;
|
||||||
|
if (label.length > categoryLabelDisplayStringLongLength) {
|
||||||
|
label = `${key.slice(
|
||||||
|
0,
|
||||||
|
categoryLabelDisplayStringLongLength / 2
|
||||||
|
)}…${key.slice(-categoryLabelDisplayStringLongLength / 2)}`;
|
||||||
|
}
|
||||||
|
|
||||||
labelSVGS.push(
|
labelSVGS.push(
|
||||||
<g
|
<g
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
@@ -62,7 +90,7 @@ class CentroidLabels extends PureComponent {
|
|||||||
}
|
}
|
||||||
pointerEvents="visiblePainted"
|
pointerEvents="visiblePainted"
|
||||||
>
|
>
|
||||||
{key.length > 20 ? `${key.substr(0, 20)}...` : key}
|
{label}
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,8 +12,16 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
This component takes its children (assumed in the data coordinate space ([0, 1] range, origin in bottom left corner))
|
This component takes its children (assumed in the data coordinate space ([0, 1] range, origin in bottom left corner))
|
||||||
and transforms itself multiple times resulting in screen space ([0, screenWidth/Height] range, origin in top left corner)
|
and transforms itself multiple times resulting in screen space ([0, screenWidth/Height] range, origin in top left corner)
|
||||||
|
|
||||||
Children are assigned in the graph component
|
Children are assigned in the graph component and must implement onDisplayChange()
|
||||||
*/
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
display: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
matrixToTransformString = m => {
|
matrixToTransformString = m => {
|
||||||
/*
|
/*
|
||||||
Translates the gl-matrix mat3 to SVG matrix transform style
|
Translates the gl-matrix mat3 to SVG matrix transform style
|
||||||
@@ -30,6 +38,13 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
return `matrix(${1 / m[0]} 0 0 ${1 / m[4]} 0 0)`;
|
return `matrix(${1 / m[0]} 0 0 ${1 / m[4]} 0 0)`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is passed to all children, should be called when an overlay's display state is toggled along with the overlay name and its new display state in boolean form
|
||||||
|
overlayToggled = (overlay, displaying) => {
|
||||||
|
this.setState(state => {
|
||||||
|
return { ...state, display: { ...state.display, [overlay]: displaying } };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
cameraTF,
|
cameraTF,
|
||||||
@@ -43,6 +58,9 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
|
|
||||||
if (!cameraTF) return null;
|
if (!cameraTF) return null;
|
||||||
|
|
||||||
|
const { display } = this.state;
|
||||||
|
const displaying = Object.values(display).some(value => value); // check to see if at least one overlay is currently displayed
|
||||||
|
|
||||||
const inverseTransform = `${this.reverseMatrixScaleTransformString(
|
const inverseTransform = `${this.reverseMatrixScaleTransformString(
|
||||||
modelTF
|
modelTF
|
||||||
)} ${this.reverseMatrixScaleTransformString(
|
)} ${this.reverseMatrixScaleTransformString(
|
||||||
@@ -53,7 +71,13 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
-(responsive.height - graphPaddingTop)}) scale(2 1) scale(${1 /
|
-(responsive.height - graphPaddingTop)}) scale(2 1) scale(${1 /
|
||||||
(responsive.width - graphPaddingRightLeft)} 1)`;
|
(responsive.width - graphPaddingRightLeft)} 1)`;
|
||||||
|
|
||||||
const newChildren = React.Children.toArray(children);
|
// Copy the children passed with the overlay and add the inverse transform and onDisplayChange props
|
||||||
|
const newChildren = React.Children.map(children, child =>
|
||||||
|
cloneElement(child, {
|
||||||
|
inverseTransform,
|
||||||
|
overlayToggled: this.overlayToggled
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
@@ -61,7 +85,10 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
width={responsive.width - graphPaddingRightLeft}
|
width={responsive.width - graphPaddingRightLeft}
|
||||||
height={responsive.height}
|
height={responsive.height}
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
style={{ zIndex: 99 }}
|
style={{
|
||||||
|
zIndex: 99,
|
||||||
|
backgroundColor: displaying ? "rgba(255, 255, 255, 0.55)" : ""
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="canvas-transformation-group-x"
|
id="canvas-transformation-group-x"
|
||||||
@@ -86,9 +113,7 @@ class GraphOverlayLayer extends PureComponent {
|
|||||||
id="model-transformation-group"
|
id="model-transformation-group"
|
||||||
transform={this.matrixToTransformString(modelTF)}
|
transform={this.matrixToTransformString(modelTF)}
|
||||||
>
|
>
|
||||||
{newChildren.map(child =>
|
{newChildren}
|
||||||
cloneElement(child, { inverseTransform })
|
|
||||||
)}
|
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
Reference in New Issue
Block a user