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

Update makePath to fix curve for verticallly aligned ports #102

Open
wants to merge 1 commit into
base: feature/canvas-ext
Choose a base branch
from
Open
Changes from all 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
Update makePath to fix curve for verticallly aligned ports
joancc committed Dec 19, 2020
commit 9d3464bf474641e712f2be59929499ccaecaa27a
114 changes: 72 additions & 42 deletions docs/Links-Ports.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
### Ports

```js
import Diagram, { Canvas, createSchema, useSchema, useCanvas, CanvasControls } from 'beautiful-react-diagrams';
import Diagram, {
Canvas,
createSchema,
useSchema,
useCanvas,
CanvasControls,
} from 'beautiful-react-diagrams'

const initialSchema = createSchema({
nodes: [
{
content: 'Start',
coordinates: [100, 150],
disableDrag: true,
outputs: [
{ id: 'port-1', label: 'Source 1' },
outputs: [
{ id: 'port-1', label: 'Source 1' },
{ id: 'port-2', label: 'Source 2' },
],
outputsAlignment: 'right',
},
{
content: 'Middle',
coordinates: [300, 150],
inputs: [
{ id: 'port-3' },
{ id: 'port-4' },
],
outputs: [
{ id: 'port-5' },
{ id: 'port-6' },
],
inputs: [{ id: 'port-3' }, { id: 'port-4' }],
outputs: [{ id: 'port-5' }, { id: 'port-6' }],
inputsAlignment: 'left',
outputsAlignment: 'right',
},
{
content: 'StartDEBUG',
coordinates: [600, 50],
disableDrag: false,
outputs: [
{ id: 'portDEBUG-1', label: 'Source 1' },
{ id: 'portDEBUG-2', label: 'Source 2' },
],
outputsAlignment: 'bottom',
},
{
content: 'MiddleDEBUG',
coordinates: [750, 350],
inputs: [{ id: 'portDEBUG-3' }, { id: 'portDEBUG-4' }],
outputs: [{ id: 'portDEBUG-5' }, { id: 'portDEBUG-6' }],
inputsAlignment: 'top',
outputsAlignment: 'bottom',
},
/*{
content: 'End',
coordinates: [600, 150],
@@ -40,56 +58,68 @@ const initialSchema = createSchema({
},*/
],
links: [
{ input: 'port-1', output: 'port-4' },
]
});
{ input: 'port-1', output: 'port-4' },
{ input: 'portDEBUG-1', output: 'portDEBUG-4' },
],
})

const UncontrolledDiagram = () => {
const [canvasState, handlers] = useCanvas(); // creates canvas state
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema
const [canvasState, handlers] = useCanvas() // creates canvas state
const [schema, { onChange }] = useSchema(initialSchema) // creates diagrams schema

return (
<div style={{ height: '30rem' }}>
<Canvas {...canvasState} {...handlers}>
<Diagram schema={schema} onChange={onChange} />
<CanvasControls />
<Diagram schema={schema} onChange={onChange} />
<CanvasControls />
</Canvas>
</div>
);
};
)
}

<UncontrolledDiagram />
;<UncontrolledDiagram />
```

### Readonly Links

```js
import Diagram, { Canvas, createSchema, useSchema, useCanvas, CanvasControls } from 'beautiful-react-diagrams';
import Diagram, {
Canvas,
createSchema,
useSchema,
useCanvas,
CanvasControls,
} from 'beautiful-react-diagrams'

// the diagram model
const initialSchema = createSchema({
nodes: [
{ id: 'node-1', content: 'Hey Jude', coordinates: [312, 27], },
{ id: 'node-2', content: 'Don\'t', coordinates: [330, 90], },
{ id: 'node-3', content: 'be afraid', coordinates: [100, 320], },
{ id: 'node-4', content: 'let me down', coordinates: [306, 332], },
{ id: 'node-5', content: 'make it bad', coordinates: [515, 330], },
{ id: 'node-6', content: 'Take a sad song', coordinates: [295, 460], },
{ id: 'node-1', content: 'Hey Jude', coordinates: [312, 27] },
{ id: 'node-2', content: "Don't", coordinates: [330, 90] },
{ id: 'node-3', content: 'be afraid', coordinates: [100, 320] },
{ id: 'node-4', content: 'let me down', coordinates: [306, 332] },
{ id: 'node-5', content: 'make it bad', coordinates: [515, 330] },
{ id: 'node-6', content: 'Take a sad song', coordinates: [295, 460] },
],
links: [
{ input: 'node-1', output: 'node-2', readonly: true, className: 'my-custom-link-class' },
{ input: 'node-2', output: 'node-3', readonly: true },
{ input: 'node-2', output: 'node-4', readonly: true },
{ input: 'node-2', output: 'node-5', readonly: true },
{ input: 'node-3', output: 'node-6', readonly: true },
{ input: 'node-4', output: 'node-6', readonly: true },
{ input: 'node-5', output: 'node-6', readonly: true },
]
});
{
input: 'node-1',
output: 'node-2',
readonly: true,
className: 'my-custom-link-class',
},
{ input: 'node-2', output: 'node-3', readonly: true },
{ input: 'node-2', output: 'node-4', readonly: true },
{ input: 'node-2', output: 'node-5', readonly: true },
{ input: 'node-3', output: 'node-6', readonly: true },
{ input: 'node-4', output: 'node-6', readonly: true },
{ input: 'node-5', output: 'node-6', readonly: true },
],
})

const DiagramExample = () => {
const [ canvasStates, canvasStateHandlers] = useCanvas(); // creates canvas states
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema
const [canvasStates, canvasStateHandlers] = useCanvas() // creates canvas states
const [schema, { onChange }] = useSchema(initialSchema) // creates diagrams schema

return (
<div style={{ height: '35rem' }}>
@@ -98,8 +128,8 @@ const DiagramExample = () => {
<CanvasControls />
</Canvas>
</div>
);
};
)
}

<DiagramExample />
;<DiagramExample />
```
24 changes: 21 additions & 3 deletions src/components/Segment/makePath.js
Original file line number Diff line number Diff line change
@@ -25,10 +25,28 @@ const makePath = (from, to, inputEntityType, outputEntityType, inputAlignment, o
// if both ports are vertically aligned
// TODO: this formula is wrong, needs to be fixed
if (isVerticalAlignment(inputAlignment) || isVerticalAlignment(outputAlignment)) {
const sourceCurve = sourceX + Math.abs(targetX - sourceX) * offsetCurve;
const targetCurve = targetX - Math.abs(targetX - sourceX) * offsetCurve;
// ********************** Solution with original naming convention *********************
// Need to identify which element has the lowest Y
// const sourceCurve = targetY - Math.abs(targetY - sourceY) * offsetCurve;
// const targetCurve = sourceY + Math.abs(targetY - sourceY) * offsetCurve;

return `M ${sourceX} ${sourceY} C ${sourceCurve} ${sourceY} ${targetCurve} ${targetY} ${targetX} ${targetY}`;
// return `M ${sourceX} ${sourceY} C ${sourceX} ${sourceCurve} ${targetX} ${targetCurve} ${targetX} ${targetY}`;

// ********************** Solution with proposed naming convention *********************
// Proposal to rename variables
// C accepts two control points and a target to draw the bezier.
let controlOffset = Math.abs(targetY - sourceY) * offsetCurve;
// The initial implementation assumes a source is above the target, the same
// goes for horizontal alignment, it assume the source is to the left of the target
if (targetY < sourceY) {
controlOffset = -controlOffset;
}
const control1X = sourceX;
const control1Y = targetY - controlOffset;
const control2X = targetX;
const control2Y = sourceY + controlOffset;

return `M ${sourceX} ${sourceY} C ${control1X} ${control1Y} ${control2X} ${control2Y} ${targetX} ${targetY}`;
}

// if input is vertical and output is horizontal