|
|
@@ -13,7 +13,8 @@ const panConstant = 0.8;
|
|
|
|
|
|
type PropsType = {
|
|
|
components: ResourceType[],
|
|
|
- isExpanded: boolean
|
|
|
+ isExpanded: boolean,
|
|
|
+ setSidebar: (x: boolean) => void
|
|
|
};
|
|
|
|
|
|
type StateType = {
|
|
|
@@ -34,9 +35,10 @@ type StateType = {
|
|
|
preventBgDrag: boolean, // Prevents bg drag when moving selected with mouse down
|
|
|
relocateAllowed: boolean, // Suppresses movement of selected when drawing select region
|
|
|
scale: number,
|
|
|
- showKind: boolean,
|
|
|
+ showKindLabels: boolean,
|
|
|
currentNode: NodeType | null,
|
|
|
- currentEdge: EdgeType | null
|
|
|
+ currentEdge: EdgeType | null,
|
|
|
+ isExpanded: boolean
|
|
|
};
|
|
|
|
|
|
// TODO: region-based unselect, shift-click, multi-region
|
|
|
@@ -58,10 +60,11 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
dragBg: false,
|
|
|
preventBgDrag: false,
|
|
|
scale: 0.5,
|
|
|
- showKind: true,
|
|
|
+ showKindLabels: true,
|
|
|
currentNode: null as (NodeType | null),
|
|
|
currentEdge: null as (EdgeType | null),
|
|
|
- relocateAllowed: false
|
|
|
+ relocateAllowed: false,
|
|
|
+ isExpanded: false
|
|
|
}
|
|
|
|
|
|
spaceRef: any = React.createRef();
|
|
|
@@ -112,18 +115,6 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
document.removeEventListener("keyup", this.handleKeyUp);
|
|
|
}
|
|
|
|
|
|
- // Update origin when expanding/collapsing (can improve w/ resize listener)
|
|
|
- componentDidUpdate(prevProps: PropsType) {
|
|
|
- if (this.props.isExpanded !== prevProps.isExpanded) {
|
|
|
- let height = this.spaceRef.offsetHeight;
|
|
|
- let width = this.spaceRef.offsetWidth;
|
|
|
- this.setState({
|
|
|
- originX: Math.round(width / 2),
|
|
|
- originY: Math.round(height / 2)
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// Handle shift key for multi-select
|
|
|
handleKeyDown = (e: any) => {
|
|
|
if (e.key === 'Shift') {
|
|
|
@@ -221,6 +212,24 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ toggleExpanded = () => {
|
|
|
+ this.setState({ isExpanded: !this.state.isExpanded }, () => {
|
|
|
+ this.props.setSidebar(!this.state.isExpanded);
|
|
|
+
|
|
|
+ // Update origin on expand/collapse
|
|
|
+ let height = this.spaceRef.offsetHeight;
|
|
|
+ let width = this.spaceRef.offsetWidth;
|
|
|
+ let nudge = 0;
|
|
|
+ if (!this.state.isExpanded) {
|
|
|
+ nudge = 100;
|
|
|
+ }
|
|
|
+ this.setState({
|
|
|
+ originX: Math.round(width / 2) - nudge,
|
|
|
+ originY: Math.round(height / 2)
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
// Pass origin to node for offset
|
|
|
renderNodes = () => {
|
|
|
let { activeIds, originX, originY, cursorX, cursorY, scale, panX, panY, anchorX, anchorY, relocateAllowed } = this.state;
|
|
|
@@ -260,7 +269,7 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
nodeMouseDown={() => this.handleClickNode(node.id)}
|
|
|
nodeMouseUp={this.handleReleaseNode}
|
|
|
isActive={activeIds.includes(node.id)}
|
|
|
- showKind={this.state.showKind}
|
|
|
+ showKindLabels={this.state.showKindLabels}
|
|
|
setCurrentNode={(node: NodeType) => this.setState({ currentNode: node })}
|
|
|
/>
|
|
|
);
|
|
|
@@ -303,17 +312,43 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
render() {
|
|
|
return (
|
|
|
<StyledGraphDisplay
|
|
|
+ isExpanded={this.state.isExpanded}
|
|
|
ref={element => this.spaceRef = element}
|
|
|
onMouseMove={this.handleMouseMove}
|
|
|
- onMouseDown={() => this.setState({ dragBg: true })}
|
|
|
- onMouseUp={() => this.setState({ dragBg: false })}
|
|
|
+ onMouseDown={() => this.setState({
|
|
|
+ dragBg: true,
|
|
|
+
|
|
|
+ // Suppress drifting on repeated click
|
|
|
+ deltaX: null,
|
|
|
+ deltaY: null,
|
|
|
+ panX: null,
|
|
|
+ panY: null,
|
|
|
+ scale: 1
|
|
|
+ })}
|
|
|
+ onMouseUp={() => this.setState({ dragBg: false, activeIds: [] })}
|
|
|
onWheel={this.handleWheel}
|
|
|
- onClick={() => this.setState({ activeIds: [] })}
|
|
|
>
|
|
|
{this.renderNodes()}
|
|
|
{this.renderEdges()}
|
|
|
{this.renderSelectRegion()}
|
|
|
|
|
|
+ <ButtonSection>
|
|
|
+ <ToggleLabel
|
|
|
+ onClick={() => this.setState({ showKindLabels: !this.state.showKindLabels })}
|
|
|
+ >
|
|
|
+ <Checkbox checked={this.state.showKindLabels}>
|
|
|
+ <i className="material-icons">done</i>
|
|
|
+ </Checkbox>
|
|
|
+ Show Type
|
|
|
+ </ToggleLabel>
|
|
|
+ <ExpandButton
|
|
|
+ onClick={this.toggleExpanded}
|
|
|
+ >
|
|
|
+ <i className="material-icons">
|
|
|
+ {this.state.isExpanded ? 'close_fullscreen' : 'open_in_full'}
|
|
|
+ </i>
|
|
|
+ </ExpandButton>
|
|
|
+ </ButtonSection>
|
|
|
<InfoPanel
|
|
|
currentNode={this.state.currentNode}
|
|
|
currentEdge={this.state.currentEdge}
|
|
|
@@ -323,10 +358,81 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const StyledGraphDisplay = styled.div`
|
|
|
+const Checkbox = styled.div`
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ border: 1px solid #ffffff44;
|
|
|
+ margin: 0px 8px 0px 3px;
|
|
|
+ border-radius: 3px;
|
|
|
+ background: ${(props: { checked: boolean }) => props.checked ? '#ffffff22' : ''};
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: #ffffff;
|
|
|
+
|
|
|
+ > i {
|
|
|
+ font-size: 12px;
|
|
|
+ padding-left: 0px;
|
|
|
+ display: ${(props: { checked: boolean }) => props.checked ? '' : 'none'};
|
|
|
+ }
|
|
|
+`;
|
|
|
+
|
|
|
+const ToggleLabel = styled.div`
|
|
|
+ font: 12px 'Work Sans';
|
|
|
+ color: #ffffff;
|
|
|
position: relative;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
+ height: 24px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ border-radius: 3px;
|
|
|
+ padding-right: 5px;
|
|
|
+ cursor: pointer;
|
|
|
+ border: 1px solid #ffffff44;
|
|
|
+ :hover {
|
|
|
+ background: #ffffff22;
|
|
|
+
|
|
|
+ > div {
|
|
|
+ background: #ffffff22;
|
|
|
+ }
|
|
|
+ }
|
|
|
+`;
|
|
|
+
|
|
|
+const ButtonSection = styled.div`
|
|
|
+ position: absolute;
|
|
|
+ top: 17px;
|
|
|
+ right: 15px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+`;
|
|
|
+
|
|
|
+const ExpandButton = styled.div`
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-left: 10px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ border-radius: 3px;
|
|
|
+ border: 1px solid #ffffff44;
|
|
|
+
|
|
|
+ :hover {
|
|
|
+ background: #ffffff44;
|
|
|
+ }
|
|
|
+
|
|
|
+ > i {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+`;
|
|
|
+
|
|
|
+const StyledGraphDisplay = styled.div`
|
|
|
overflow: hidden;
|
|
|
cursor: move;
|
|
|
+ width: ${(props: { isExpanded: boolean }) => props.isExpanded ? '100vw' : '100%'};
|
|
|
+ height: ${(props: { isExpanded: boolean }) => props.isExpanded ? '100vh' : '100%'};
|
|
|
+ background: #202227;
|
|
|
+ position: ${(props: { isExpanded: boolean }) => props.isExpanded ? 'fixed' : 'relative'};
|
|
|
+ top: ${(props: { isExpanded: boolean }) => props.isExpanded ? '-25px' : ''};
|
|
|
+ right: ${(props: { isExpanded: boolean }) => props.isExpanded ? '-25px' : ''};
|
|
|
`;
|