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

fix: Action Flow gradual left alignment #2909

Merged
merged 5 commits into from
May 6, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -17,14 +17,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, addCoachMarkRef }): JSX.Element => {
const [stepGroupBoundary, setStepGroupBoundary] = useState<Boundary>(measureJsonBoundary(data));
Expand Down Expand Up @@ -52,18 +46,26 @@ export const StepEditor = ({ id, data, onEvent, trigger, addCoachMarkRef }): JSX
);
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 @@ -85,7 +87,7 @@ export const StepEditor = ({ id, data, onEvent, trigger, addCoachMarkRef }): JSX
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