Skip to content

Commit

Permalink
[dagit] Add arrow key and double click interactions to asset graph #6407
Browse files Browse the repository at this point in the history
  • Loading branch information
bengotow committed Apr 13, 2022
1 parent ec89e79 commit 94f7984
Show file tree
Hide file tree
Showing 17 changed files with 277 additions and 292 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// eslint-disable-next-line no-restricted-imports
import {GraphData} from '../../src/asset-graph/Utils';
import {layoutAssetGraph} from '../../src/asset-graph/layout';
import {ILayoutOp, layoutOpGraph} from '../../src/graph/layout';
import {GraphData} from '../../src/workspace/asset-graph/Utils';
import {layoutAssetGraph} from '../../src/workspace/asset-graph/layout';

type WorkerMessageData =
| {type: 'layoutOpGraph'; ops: ILayoutOp[]; parentOp: ILayoutOp}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {LaunchAssetExecutionButton} from '../assets/LaunchAssetExecutionButton';
import {AssetKey} from '../assets/types';
import {SVGViewport} from '../graph/SVGViewport';
import {useAssetLayout} from '../graph/asyncGraphLayout';
import {closestNodeInDirection, isNodeOffscreen} from '../graph/common';
import {useDocumentTitle} from '../hooks/useDocumentTitle';
import {
GraphExplorerOptions,
Expand Down Expand Up @@ -165,7 +166,11 @@ const AssetGraphExplorerWithData: React.FC<
: Object.values(assetGraphData.nodes).filter((a) => !isSourceAsset(a.definition));

const onSelectNode = React.useCallback(
async (e: React.MouseEvent<any>, assetKey: {path: string[]}, node: GraphNode | null) => {
async (
e: React.MouseEvent<any> | React.KeyboardEvent<any>,
assetKey: {path: string[]},
node: GraphNode | null,
) => {
e.stopPropagation();

const token = tokenForAssetKey(assetKey);
Expand Down Expand Up @@ -219,6 +224,21 @@ const AssetGraphExplorerWithData: React.FC<
viewportEl.current?.autocenter();
}, [layout, viewportEl]);

const onClickBackground = () =>
onChangeExplorerPath(
{...explorerPath, pipelineName: explorerPath.pipelineName, opNames: []},
'replace',
);

const onArrowKeyDown = (e: React.KeyboardEvent<any>, dir: string) => {
const nextId = layout && closestNodeInDirection(layout, lastSelectedNode.id, dir);
const node = nextId && assetGraphData.nodes[nextId];
if (node && viewportEl.current) {
onSelectNode(e, node.assetKey, node);
viewportEl.current.smoothZoomToSVGBox(layout.nodes[nextId].bounds);
}
};

return (
<SplitPanelContainer
identifier="explorer"
Expand All @@ -241,13 +261,12 @@ const AssetGraphExplorerWithData: React.FC<
interactor={SVGViewport.Interactors.PanAndZoom}
graphWidth={layout.width}
graphHeight={layout.height}
onKeyDown={() => {}}
onClick={() =>
onChangeExplorerPath(
{...explorerPath, pipelineName: explorerPath.pipelineName, opNames: []},
'replace',
)
}
onClick={onClickBackground}
onArrowKeyDown={onArrowKeyDown}
onDoubleClick={(e) => {
viewportEl.current?.autocenter(true);
e.stopPropagation();
}}
maxZoom={1.2}
maxAutocenterZoom={1.0}
>
Expand Down Expand Up @@ -275,6 +294,10 @@ const AssetGraphExplorerWithData: React.FC<
{...bounds}
key={id}
onClick={(e) => onSelectNode(e, {path}, graphNode)}
onDoubleClick={(e) => {
viewportEl.current?.smoothZoomToSVGBox(bounds, 1.2);
e.stopPropagation();
}}
style={{overflow: 'visible'}}
>
{!graphNode || !graphNode.definition.opName ? (
Expand Down Expand Up @@ -387,18 +410,6 @@ const SVGContainer = styled.svg`

// Helpers

const isNodeOffscreen = (
layoutNode: {x: number; y: number; width: number; height: number},
bounds: {top: number; left: number; right: number; bottom: number},
) => {
return (
layoutNode.x + layoutNode.width < bounds.left ||
layoutNode.y + layoutNode.height < bounds.top ||
layoutNode.x > bounds.right ||
layoutNode.y > bounds.bottom
);
};

const graphDirectionOf = ({
graph,
from,
Expand Down
6 changes: 3 additions & 3 deletions js_modules/dagit/packages/core/src/asset-graph/layout.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as dagre from 'dagre';

import {ILayout, IPoint} from '../graph/layout';
import {IBounds, IPoint} from '../graph/common';

import {GraphData, GraphNode, GraphId, displayNameForAssetKey} from './Utils';

interface AssetLayout {
export interface AssetLayout {
id: GraphId;

// Overall frame of the box relative to 0,0 on the graph
bounds: ILayout;
bounds: IBounds;
}

export type AssetLayoutEdge = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import styled from 'styled-components/macro';

import {Edge} from './OpEdges';
import {SVGMonospaceText} from './SVGComponents';
import {IPoint} from './asyncGraphLayout';
import {isHighlighted} from './highlighting';
import {IPoint, isHighlighted} from './common';

interface ExternalConnectionNodeProps {
layout: IPoint;
Expand Down
3 changes: 1 addition & 2 deletions js_modules/dagit/packages/core/src/graph/MappingLine.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as React from 'react';

import {Edge} from './OpEdges';
import {IPoint} from './asyncGraphLayout';
import {isHighlighted} from './highlighting';
import {IPoint, isHighlighted} from './common';

interface MappingLineProps {
source: IPoint;
Expand Down
12 changes: 6 additions & 6 deletions js_modules/dagit/packages/core/src/graph/OpGraph.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const Basic = () => {

return (
<OpGraph
pipelineName="Test Pipeline"
jobName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
interactor={SVGViewport.Interactors.PanAndZoom}
Expand Down Expand Up @@ -132,7 +132,7 @@ export const FanOut = () => {

return (
<OpGraph
pipelineName="Test Pipeline"
jobName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
interactor={SVGViewport.Interactors.PanAndZoom}
Expand All @@ -157,7 +157,7 @@ export const Tagged = () => {

return (
<OpGraph
pipelineName="Test Pipeline"
jobName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
interactor={SVGViewport.Interactors.PanAndZoom}
Expand All @@ -169,7 +169,7 @@ export const Tagged = () => {
};

export const Composite = () => {
const [focusOps, setsetFocusOps] = React.useState<string[]>([]);
const [focusOps, setFocusOps] = React.useState<string[]>([]);
const [parentOpName, setParentOpName] = React.useState<string | undefined>();
const ops = buildBasicDAG();
const composite = ops.find((s) => s.name === 'C')!;
Expand Down Expand Up @@ -213,15 +213,15 @@ export const Composite = () => {

return (
<OpGraph
pipelineName="Test Pipeline"
jobName="Test Pipeline"
ops={parentOp ? childOps : ops}
parentOp={parentOp}
parentHandleID={parentOpName}
layout={parentOp ? getFullOpLayout(childOps, parentOp) : getFullOpLayout(ops)}
interactor={SVGViewport.Interactors.PanAndZoom}
focusOps={ops.filter((s) => focusOps.includes(s.name))}
highlightedOps={[]}
onClickOp={(nameOrPath) => setsetFocusOps([toName(nameOrPath)])}
onClickOp={(nameOrPath) => setFocusOps([toName(nameOrPath)])}
onEnterSubgraph={(nameOrPath) => setParentOpName(toName(nameOrPath))}
onLeaveSubgraph={() => setParentOpName(undefined)}
onDoubleClickOp={(nameOrPath) => {
Expand Down

0 comments on commit 94f7984

Please sign in to comment.