Skip to content

Commit

Permalink
fix: Action Flow gradual left alignment (#2909)
Browse files Browse the repository at this point in the history
* gradual left alignment of StepFlow

* put shared branch sizes to ElementSizes

* more accurate branching layout width calculation

* fix UT

Co-authored-by: Chris Whitten <christopher.whitten@microsoft.com>
  • Loading branch information
yeze322 and cwhitten authored May 6, 2020
1 parent 52a54a4 commit e65569b
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import {
calculateForeachBoundary,
} from '../../src/layouters/calculateNodeBoundary';
import { Boundary } from '../../src/models/Boundary';
import { ElementInterval, LoopEdgeMarginLeft } from '../../src/constants/ElementSizes';
import {
ElementInterval,
BranchIntervalX,
BranchIntervalY,
LoopEdgeMarginLeft,
} from '../../src/constants/ElementSizes';

const boundary = new Boundary();
const BranchIntervalX = ElementInterval.x;
const BranchIntervalY = ElementInterval.y / 2;
describe('calculateSequenceBoundary', () => {
let boundaries;
beforeEach(() => {
Expand Down Expand Up @@ -74,7 +77,7 @@ describe('calculateSwitchCaseBoundary', () => {
});
it('should return a box whose property be calcalated by conditionBoundary, choiceBoundary, branchBoundaries', () => {
const returnBoundary = {
width: 580 + BranchIntervalX * 2,
width: 580 + BranchIntervalX,
height: 180 + BranchIntervalY * 3,
axisX: 140,
axisY: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ export const ElementInterval = {
y: 60,
};

export const BranchIntervalMinX = 150;
export const BranchIntervalX = ElementInterval.x;
export const BranchIntervalY = ElementInterval.y / 2;

// Preserve enough space for condition label text on edges.
export const BranchAxisXIntervalMin = 150;

export const EdgeAddButtonSize = {
width: 16,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,8 @@ import { SVGContainer } from '../components/lib/SVGContainer';
import { drawSVGEdge } from '../components/lib/EdgeUtil';
import { ObiColors } from '../constants/ElementColors';

const HeadSize = {
width: TriggerSize.width,
height: TriggerSize.height + ElementInterval.y / 2,
};
const TailSize = {
width: TerminatorSize.width,
height: TerminatorSize.height + ElementInterval.y / 2 + 5,
};
const HeadSize = new Boundary(TriggerSize.width, TriggerSize.height + ElementInterval.y / 2);
const TailSize = new Boundary(TerminatorSize.width, TerminatorSize.height + ElementInterval.y / 2 + 5);

export const StepEditor = ({ id, data, onEvent, trigger }): JSX.Element => {
const [stepGroupBoundary, setStepGroupBoundary] = useState<Boundary>(measureJsonBoundary(data));
Expand Down Expand Up @@ -56,18 +50,26 @@ export const StepEditor = ({ id, data, onEvent, trigger }): JSX.Element => {
);
const contentBoundary = hasNoSteps ? new Boundary(TerminatorSize.width, TerminatorSize.height) : stepGroupBoundary;

const editorAxisX = Math.max(0, HeadSize.axisX, TailSize.axisX, contentBoundary.axisX);
const editorWidth =
Math.min(
Math.max(0, HeadSize.width / 2, TailSize.width / 2, contentBoundary.axisX),
Math.max(0, HeadSize.width / 2, TailSize.width / 2, contentBoundary.width - contentBoundary.axisX)
) * 2;
editorAxisX +
Math.max(
0,
HeadSize.width - HeadSize.axisX,
TailSize.width - TailSize.axisX,
contentBoundary.width - contentBoundary.axisX
);
const editorHeight = HeadSize.height + TailSize.height + contentBoundary.height;
const editorAxisX = editorWidth / 2;

return (
<div
className="step-editor"
css={{ position: 'relative', width: editorWidth, height: editorHeight }}
/**
* `maxWith: 100%` is important here. (refs https://developer.mozilla.org/en-US/docs/Web/CSS/align-items)
* If the cross-size of an item is larger than the flex container, it will overflow equally in both directions.
* Limit the max width to parent width to avoid left overfow.
*/
css={{ position: 'relative', width: editorWidth, height: editorHeight, maxWidth: '100%' }}
aria-label="step-editor"
>
<SVGContainer width={editorWidth} height={editorHeight}>
Expand All @@ -89,7 +91,7 @@ export const StepEditor = ({ id, data, onEvent, trigger }): JSX.Element => {
strokeWidth="2"
/>
</SVGContainer>
<OffsetContainer offset={{ x: editorAxisX - HeadSize.width / 2, y: 0 }}>
<OffsetContainer offset={{ x: editorAxisX - HeadSize.axisX, y: 0 }}>
<div className="step-editor__head" css={{ ...HeadSize, position: 'relative' }}>
<OffsetContainer offset={{ x: 0, y: 0 }}>{trigger}</OffsetContainer>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import { Boundary } from '../models/Boundary';
import {
ElementInterval,
BranchIntervalX,
BranchIntervalY,
LoopEdgeMarginLeft,
BranchIntervalMinX,
DiamondSize,
IconBrickSize,
BoxMargin,
} from '../constants/ElementSizes';

const BranchIntervalX = ElementInterval.x;
const BranchIntervalY = ElementInterval.y / 2;
import { calculateBranchNodesIntervalX } from './sharedLayouterUtils';

export function calculateSequenceBoundary(
boundaries: Boundary[],
Expand Down Expand Up @@ -92,10 +92,9 @@ function measureBranchingContainerBoundary(
const firstBranchBoundary = branchBoundaries[0] || new Boundary();

const branchGroupBoundary = new Boundary();
branchGroupBoundary.width = branchBoundaries.reduce(
(acc, x) => acc + Math.max(x.width + BranchIntervalX, BranchIntervalMinX),
0
);
branchGroupBoundary.width = branchBoundaries.reduce((acc, x, currentIndex) => {
return acc + x.width + calculateBranchNodesIntervalX(x, branchBoundaries[currentIndex + 1]);
}, 0);
branchGroupBoundary.height = Math.max(...branchBoundaries.map(x => x.height));
branchGroupBoundary.axisX = firstBranchBoundary.axisX;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ElementInterval } from '../constants/ElementSizes';
import { BranchIntervalX, BranchIntervalY } from '../constants/ElementSizes';
import { GraphNode } from '../models/GraphNode';
import { GraphLayout } from '../models/GraphLayout';
import { Edge, EdgeDirection } from '../models/EdgeData';

import { calculateIfElseBoundary } from './calculateNodeBoundary';

const BranchIntervalX = ElementInterval.x;
const BranchIntervalY = ElementInterval.y / 2;

export function ifElseLayouter(
conditionNode: GraphNode | null,
choiceNode: GraphNode | null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { BranchIntervalX, BranchAxisXIntervalMin } from '../constants/ElementSizes';
import { Boundary } from '../models/Boundary';

/**
* Inputs two adjacent branch nodes, output their minimum interval x which satisfies two requirements:
* 1. distance from leftNode's right broder to rightNode's left border >= ${BranchIntervalX}
* 2. distance from leftNode's axis X to rightNode's axis X >= ${BranchAxisXIntervalMin}
*/
export const calculateBranchNodesIntervalX = (leftNodeBound: Boundary, rightNodeBound?: Boundary) => {
if (!rightNodeBound) return 0;

return Math.max(
BranchIntervalX,
BranchAxisXIntervalMin - getRightWidth(leftNodeBound) - getLeftWidth(rightNodeBound)
);
};

export const getLeftWidth = (bound?: Boundary): number => (bound ? bound.axisX : 0);

export const getRightWidth = (bound?: Boundary): number => (bound ? bound.width - bound.axisX : 0);
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ElementInterval, BranchIntervalMinX } from '../constants/ElementSizes';
import { BranchIntervalY } from '../constants/ElementSizes';
import { GraphNode } from '../models/GraphNode';
import { GraphLayout } from '../models/GraphLayout';
import { Edge, EdgeDirection } from '../models/EdgeData';

import { calculateSwitchCaseBoundary } from './calculateNodeBoundary';

const BranchIntervalX = ElementInterval.x;
const BranchIntervalY = ElementInterval.y / 2;
import { calculateBranchNodesIntervalX } from './sharedLayouterUtils';

/**
* [switch]
Expand Down Expand Up @@ -45,12 +43,14 @@ export function switchCaseLayouter(
const BottomelinePositionY = containerBoundary.height;

const firstBranchNode = branchNodes[0] || new GraphNode();
branchNodes.reduce((accOffsetX, x) => {
branchNodes.reduce((accOffsetX, x, currentIndex) => {
x.offset = {
x: accOffsetX,
y: choiceNode.offset.y + choiceNode.boundary.height + BranchIntervalY,
};
return accOffsetX + Math.max(BranchIntervalX + x.boundary.width, BranchIntervalMinX);
return (
accOffsetX + x.boundary.width + calculateBranchNodesIntervalX(x.boundary, branchNodes[currentIndex + 1]?.boundary)
);
}, containerBoundary.axisX - firstBranchNode.boundary.axisX);

/** Calculate edges */
Expand Down

0 comments on commit e65569b

Please sign in to comment.