Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

centroid label overlay UX improvements #1141

Merged
merged 10 commits into from
Feb 12, 2020
30 changes: 29 additions & 1 deletion client/src/components/graph/overlays/centroidLabels.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
/* 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,
dilatedValue: state.pointDilation.categoryField,
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,
Expand All @@ -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
Expand Down Expand Up @@ -62,7 +90,7 @@ class CentroidLabels extends PureComponent {
}
pointerEvents="visiblePainted"
>
{key.length > 20 ? `${key.substr(0, 20)}...` : key}
{label}
</text>
</g>
);
Expand Down
37 changes: 31 additions & 6 deletions client/src/components/graph/overlays/graphOverlayLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -53,15 +71,24 @@ 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
className={styles.graphSVG}
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"
Expand All @@ -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>
Expand Down