mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-23 02:58:11 +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 */
|
||||
import React, { PureComponent } from "react";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { categoryLabelDisplayStringLongLength } from "../../../globals";
|
||||
|
||||
export default
|
||||
@connect(state => ({
|
||||
colorAccessor: state.colors.colorAccessor,
|
||||
@@ -9,6 +12,21 @@ export default
|
||||
labels: state.centroidLabels.labels
|
||||
}))
|
||||
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() {
|
||||
const {
|
||||
labels,
|
||||
@@ -28,6 +46,16 @@ class CentroidLabels extends PureComponent {
|
||||
fontSize = "18px";
|
||||
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(
|
||||
<g
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
@@ -62,7 +90,7 @@ class CentroidLabels extends PureComponent {
|
||||
}
|
||||
pointerEvents="visiblePainted"
|
||||
>
|
||||
{key.length > 20 ? `${key.substr(0, 20)}...` : key}
|
||||
{label}
|
||||
</text>
|
||||
</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))
|
||||
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 => {
|
||||
/*
|
||||
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)`;
|
||||
};
|
||||
|
||||
// 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() {
|
||||
const {
|
||||
cameraTF,
|
||||
@@ -43,6 +58,9 @@ class GraphOverlayLayer extends PureComponent {
|
||||
|
||||
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(
|
||||
modelTF
|
||||
)} ${this.reverseMatrixScaleTransformString(
|
||||
@@ -53,7 +71,13 @@ class GraphOverlayLayer extends PureComponent {
|
||||
-(responsive.height - graphPaddingTop)}) scale(2 1) scale(${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 (
|
||||
<svg
|
||||
@@ -61,7 +85,10 @@ class GraphOverlayLayer extends PureComponent {
|
||||
width={responsive.width - graphPaddingRightLeft}
|
||||
height={responsive.height}
|
||||
pointerEvents="none"
|
||||
style={{ zIndex: 99 }}
|
||||
style={{
|
||||
zIndex: 99,
|
||||
backgroundColor: displaying ? "rgba(255, 255, 255, 0.55)" : ""
|
||||
}}
|
||||
>
|
||||
<g
|
||||
id="canvas-transformation-group-x"
|
||||
@@ -86,9 +113,7 @@ class GraphOverlayLayer extends PureComponent {
|
||||
id="model-transformation-group"
|
||||
transform={this.matrixToTransformString(modelTF)}
|
||||
>
|
||||
{newChildren.map(child =>
|
||||
cloneElement(child, { inverseTransform })
|
||||
)}
|
||||
{newChildren}
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
Reference in New Issue
Block a user