Skip to content

Commit

Permalink
[dagit] Align terminology and data structures in asset / op graph lay…
Browse files Browse the repository at this point in the history
…out (#7372)

* connections => edges

* [dagit] Align terminology and data structures in asset / op graph layout
  • Loading branch information
bengotow committed Apr 12, 2022
1 parent 3f5011b commit bdb8126
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 407 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import * as React from 'react';

import {OpNameOrPath} from '../ops/OpNameOrPath';

import {PipelineGraph} from './PipelineGraph';
import {OpGraph} from './OpGraph';
import {SVGViewport} from './SVGViewport';
import {getFullOpLayout} from './asyncGraphLayout';
import {PipelineGraphOpFragment} from './types/PipelineGraphOpFragment';
import {OpGraphOpFragment} from './types/OpGraphOpFragment';

// eslint-disable-next-line import/no-default-export
export default {
title: 'PipelineGraph',
component: PipelineGraph,
title: 'OpGraph',
component: OpGraph,
} as Meta;

const IO_TYPE = {
Expand All @@ -36,7 +36,7 @@ function buildEdge(descriptor: string): Edge {
}

function buildGraphSolidFragment(sname: string, ins: string[], outs: string[], edges: Edge[]) {
const result: PipelineGraphOpFragment = {
const result: OpGraphOpFragment = {
__typename: 'Solid',
name: sname,
definition: {
Expand Down Expand Up @@ -89,7 +89,7 @@ function buildGraphSolidFragment(sname: string, ins: string[], outs: string[], e
function buildBasicDAG() {
const edges = ['A:out=>B:in', 'B:out1=>C:in', 'B:out2=>D:in1', 'C:out=>D:in2'].map(buildEdge);

const ops: PipelineGraphOpFragment[] = [
const ops: OpGraphOpFragment[] = [
buildGraphSolidFragment('A', [], ['out'], edges),
buildGraphSolidFragment('B', ['in'], ['out1', 'out2'], edges),
buildGraphSolidFragment('C', ['in'], ['out'], edges),
Expand All @@ -103,7 +103,7 @@ export const Basic = () => {
const ops = buildBasicDAG();

return (
<PipelineGraph
<OpGraph
pipelineName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
Expand All @@ -123,15 +123,15 @@ export const FanOut = () => {
edges.push(buildEdge(`A:out=>B${ii}:in`));
edges.push(buildEdge(`B${ii}:out=>C:in`));
}
const ops: PipelineGraphOpFragment[] = [];
const ops: OpGraphOpFragment[] = [];
ops.push(buildGraphSolidFragment('A', ['in'], ['out'], edges));
ops.push(buildGraphSolidFragment('C', ['in'], ['out'], edges));
for (let ii = 0; ii < 60; ii++) {
ops.push(buildGraphSolidFragment(`B${ii}`, ['in'], ['out'], edges));
}

return (
<PipelineGraph
<OpGraph
pipelineName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
Expand All @@ -156,7 +156,7 @@ export const Tagged = () => {
);

return (
<PipelineGraph
<OpGraph
pipelineName="Test Pipeline"
ops={ops}
layout={getFullOpLayout(ops)}
Expand Down Expand Up @@ -212,7 +212,7 @@ export const Composite = () => {
const parentOp = ops.find((s) => s.name === parentOpName);

return (
<PipelineGraph
<OpGraph
pipelineName="Test Pipeline"
ops={parentOp ? childOps : ops}
parentOp={parentOp}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ import {ParentOpNode, SVGLabeledParentRect} from './ParentOpNode';
import {DETAIL_ZOOM, SVGViewport, SVGViewportInteractor} from './SVGViewport';
import {OpGraphLayout, OpLayout, ILayout} from './asyncGraphLayout';
import {Edge, isHighlighted, isOpHighlighted} from './highlighting';
import {PipelineGraphOpFragment} from './types/PipelineGraphOpFragment';
import {OpGraphOpFragment} from './types/OpGraphOpFragment';

const NoOp = () => {};

interface IPipelineGraphProps {
interface OpGraphProps {
pipelineName: string;
layout: OpGraphLayout;
ops: PipelineGraphOpFragment[];
focusOps: PipelineGraphOpFragment[];
ops: OpGraphOpFragment[];
focusOps: OpGraphOpFragment[];
parentHandleID?: string;
parentOp?: PipelineGraphOpFragment;
parentOp?: OpGraphOpFragment;
selectedHandleID?: string;
selectedOp?: PipelineGraphOpFragment;
highlightedOps: Array<PipelineGraphOpFragment>;
selectedOp?: OpGraphOpFragment;
highlightedOps: Array<OpGraphOpFragment>;
interactor?: SVGViewportInteractor;
onClickOp?: (arg: OpNameOrPath) => void;
onDoubleClickOp?: (arg: OpNameOrPath) => void;
Expand All @@ -33,7 +33,7 @@ interface IPipelineGraphProps {
onClickBackground?: () => void;
}

interface IPipelineContentsProps extends IPipelineGraphProps {
interface OpGraphContentsProps extends OpGraphProps {
minified: boolean;
layout: OpGraphLayout;
bounds: {top: number; left: number; right: number; bottom: number};
Expand All @@ -48,15 +48,15 @@ function computeOpPrefixBoundingBoxes(layout: OpGraphLayout) {
const groups: {[base: string]: ILayout[]} = {};
let maxDepth = 0;

for (const key of Object.keys(layout.ops)) {
for (const key of Object.keys(layout.nodes)) {
const parts = key.split('.');
if (parts.length === 1) {
continue;
}
for (let ii = 1; ii < parts.length; ii++) {
const base = parts.slice(0, ii).join('.');
groups[base] = groups[base] || [];
groups[base].push(layout.ops[key].boundingBox);
groups[base].push(layout.nodes[key].bounds);
maxDepth = Math.max(maxDepth, ii);
}
}
Expand All @@ -80,7 +80,7 @@ function computeOpPrefixBoundingBoxes(layout: OpGraphLayout) {
return boxes;
}

const PipelineGraphContents: React.FC<IPipelineContentsProps> = React.memo((props) => {
const OpGraphContents: React.FC<OpGraphContentsProps> = React.memo((props) => {
const [highlighted, setHighlighted] = React.useState<Edge[]>(() => []);

const {
Expand Down Expand Up @@ -125,15 +125,15 @@ const PipelineGraphContents: React.FC<IPipelineContentsProps> = React.memo((prop
ops={ops}
layout={layout}
color={Colors.KeylineGray}
connections={layout.connections}
edges={layout.edges}
onHighlight={setHighlighted}
/>
<OpLinks
ops={ops}
layout={layout}
color={Colors.Blue500}
onHighlight={setHighlighted}
connections={layout.connections.filter(({from, to}) =>
edges={layout.edges.filter(({from, to}) =>
isHighlighted(highlighted, {
a: from.opName,
b: to.opName,
Expand All @@ -152,7 +152,7 @@ const PipelineGraphContents: React.FC<IPipelineContentsProps> = React.memo((prop
<foreignObject width={layout.width} height={layout.height} style={{pointerEvents: 'none'}}>
{ops
.filter((op) => {
const box = layout.ops[op.name].boundingBox;
const box = layout.nodes[op.name].bounds;
return (
box.x + box.width >= bounds.left &&
box.y + box.height >= bounds.top &&
Expand All @@ -170,7 +170,7 @@ const PipelineGraphContents: React.FC<IPipelineContentsProps> = React.memo((prop
onDoubleClick={() => onDoubleClickOp({name: op.name})}
onEnterComposite={() => onEnterSubgraph({name: op.name})}
onHighlightEdges={setHighlighted}
layout={layout.ops[op.name]}
layout={layout.nodes[op.name]}
selected={selectedOp === op}
focused={focusOps.includes(op)}
highlightedEdges={
Expand All @@ -184,26 +184,26 @@ const PipelineGraphContents: React.FC<IPipelineContentsProps> = React.memo((prop
);
});

PipelineGraphContents.displayName = 'PipelineGraphContents';
OpGraphContents.displayName = 'OpGraphContents';

// This is a specific empty array we pass to represent the common / empty case
// so that OpNode can use shallow equality comparisons in shouldComponentUpdate.
const EmptyHighlightedArray: never[] = [];

export class PipelineGraph extends React.Component<IPipelineGraphProps> {
export class OpGraph extends React.Component<OpGraphProps> {
viewportEl: React.RefObject<SVGViewport> = React.createRef();

resolveOpPosition = (
arg: OpNameOrPath,
cb: (cx: number, cy: number, layout: OpLayout) => void,
) => {
const lastName = 'name' in arg ? arg.name : arg.path[arg.path.length - 1];
const opLayout = this.props.layout.ops[lastName];
const opLayout = this.props.layout.nodes[lastName];
if (!opLayout) {
return;
}
const cx = opLayout.boundingBox.x + opLayout.boundingBox.width / 2;
const cy = opLayout.boundingBox.y + opLayout.boundingBox.height / 2;
const cx = opLayout.bounds.x + opLayout.bounds.width / 2;
const cy = opLayout.bounds.y + opLayout.bounds.height / 2;
cb(cx, cy, opLayout);
};

Expand All @@ -226,10 +226,10 @@ export class PipelineGraph extends React.Component<IPipelineGraphProps> {
return;
}

const current = layout.ops[selectedOp.name];
const current = layout.nodes[selectedOp.name];
const center = (op: OpLayout): {x: number; y: number} => ({
x: op.boundingBox.x + op.boundingBox.width / 2,
y: op.boundingBox.y + op.boundingBox.height / 2,
x: op.bounds.x + op.bounds.width / 2,
y: op.bounds.y + op.bounds.height / 2,
});

/* Sort all the ops in the graph based on their attractiveness
Expand All @@ -254,8 +254,8 @@ export class PipelineGraph extends React.Component<IPipelineGraphProps> {
return Number.NaN;
};

const closest = Object.keys(layout.ops)
.map((name) => ({name, score: score(layout.ops[name])}))
const closest = Object.keys(layout.nodes)
.map((name) => ({name, score: score(layout.nodes[name])}))
.filter((e) => e.name !== selectedOp.name && !Number.isNaN(e.score))
.sort((a, b) => b.score - a.score)
.pop();
Expand Down Expand Up @@ -286,7 +286,7 @@ export class PipelineGraph extends React.Component<IPipelineGraphProps> {
e.stopPropagation();
};

componentDidUpdate(prevProps: IPipelineGraphProps) {
componentDidUpdate(prevProps: OpGraphProps) {
if (prevProps.parentOp !== this.props.parentOp) {
this.viewportEl.current!.cancelAnimations();
this.viewportEl.current!.autocenter();
Expand Down Expand Up @@ -316,7 +316,7 @@ export class PipelineGraph extends React.Component<IPipelineGraphProps> {
>
{({scale}, bounds) => (
<SVGContainer width={layout.width} height={layout.height + 200}>
<PipelineGraphContents
<OpGraphContents
{...this.props}
layout={layout}
minified={scale < DETAIL_ZOOM - 0.01}
Expand All @@ -330,8 +330,8 @@ export class PipelineGraph extends React.Component<IPipelineGraphProps> {
}
}

export const PIPELINE_GRAPH_OP_FRAGMENT = gql`
fragment PipelineGraphOpFragment on Solid {
export const OP_GRAPH_OP_FRAGMENT = gql`
fragment OpGraphOpFragment on Solid {
name
...OpNodeInvocationFragment
definition {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {OpNameOrPath} from '../ops/OpNameOrPath';
import {LoadingNotice} from '../pipelines/GraphNotices';
import {GraphExplorerSolidHandleFragment} from '../pipelines/types/GraphExplorerSolidHandleFragment';

import {PipelineGraph} from './PipelineGraph';
import {OpGraph} from './OpGraph';
import {useOpLayout} from './asyncGraphLayout';
import {PipelineGraphOpFragment} from './types/PipelineGraphOpFragment';
import {OpGraphOpFragment} from './types/OpGraphOpFragment';

interface Props {
pipelineName: string;
ops: PipelineGraphOpFragment[];
focusOps: PipelineGraphOpFragment[];
highlightedOps: PipelineGraphOpFragment[];
ops: OpGraphOpFragment[];
focusOps: OpGraphOpFragment[];
highlightedOps: OpGraphOpFragment[];
selectedHandle?: GraphExplorerSolidHandleFragment;
parentHandle?: GraphExplorerSolidHandleFragment;
onClickOp?: (arg: OpNameOrPath) => void;
Expand All @@ -21,7 +21,7 @@ interface Props {
onClickBackground?: () => void;
}

export const PipelineGraphContainer: React.FC<Props> = (props) => {
export const OpGraphContainer: React.FC<Props> = (props) => {
const {
pipelineName,
ops,
Expand All @@ -42,7 +42,7 @@ export const PipelineGraphContainer: React.FC<Props> = (props) => {
}

return (
<PipelineGraph
<OpGraph
pipelineName={pipelineName}
ops={ops}
focusOps={focusOps}
Expand Down

0 comments on commit bdb8126

Please sign in to comment.