Fixed the 'Anchors' example.

development
Junsik Shim 2022-01-22 12:54:58 +09:00
parent 3494d0fb8a
commit b2bb10ea7e
9 changed files with 154 additions and 98 deletions

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}

1
packages/core/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module '*.gif';

View File

@ -42,7 +42,7 @@ export type CellStateStyles = {
defaultVertex?: CellStateStyles; defaultVertex?: CellStateStyles;
deletable?: boolean; deletable?: boolean;
direction?: DirectionValue; direction?: DirectionValue;
edge?: string; edgeStyle?: string;
editable?: boolean; editable?: boolean;
elbow?: string; elbow?: string;
endArrow?: ArrowType; endArrow?: ArrowType;

View File

@ -14,17 +14,8 @@ import RectangleShape from './geometry/node/RectangleShape';
import { ALIGN } from '../util/Constants'; import { ALIGN } from '../util/Constants';
import Client from '../Client'; import Client from '../Client';
import InternalEvent from './event/InternalEvent'; import InternalEvent from './event/InternalEvent';
import { import { convertPoint, getCurrentStyle, getOffset } from '../util/styleUtils';
convertPoint, import { getRotatedPoint, ptSegDistSq, relativeCcw, toRadians } from '../util/mathUtils';
getCurrentStyle,
getOffset,
} from '../util/styleUtils';
import {
getRotatedPoint,
ptSegDistSq,
relativeCcw,
toRadians,
} from '../util/mathUtils';
import MaxLog from '../gui/MaxLog'; import MaxLog from '../gui/MaxLog';
import Translations from '../util/Translations'; import Translations from '../util/Translations';
import CellState from './cell/CellState'; import CellState from './cell/CellState';
@ -49,7 +40,6 @@ import { MouseEventListener } from '../types';
import ObjectCodec from '../serialization/ObjectCodec'; import ObjectCodec from '../serialization/ObjectCodec';
import CodecRegistry from '../serialization/CodecRegistry'; import CodecRegistry from '../serialization/CodecRegistry';
/** /**
* @class GraphView * @class GraphView
* @extends {EventSource} * @extends {EventSource}
@ -236,9 +226,7 @@ export class GraphView extends EventSource {
this.viewStateChanged(); this.viewStateChanged();
} }
} }
this.fireEvent( this.fireEvent(new EventObject(InternalEvent.SCALE, { scale: value, previousScale }));
new EventObject(InternalEvent.SCALE, { scale: value, previousScale })
);
} }
/** /**
@ -1320,15 +1308,17 @@ export class GraphView extends EventSource {
let edgeStyle = this.isLoopStyleEnabled(edge, points, source, target) let edgeStyle = this.isLoopStyleEnabled(edge, points, source, target)
? edge.style.loop ?? this.graph.defaultLoopStyle ? edge.style.loop ?? this.graph.defaultLoopStyle
: !edge.style.noEdgeStyle ?? false : !edge.style.noEdgeStyle ?? false
? edge.style.edge ? edge.style.edgeStyle
: null; : null;
// Converts string values to objects // Converts string values to objects
if (typeof edgeStyle === 'string') { if (typeof edgeStyle === 'string') {
let tmp = StyleRegistry.getValue(edgeStyle); let tmp = StyleRegistry.getValue(edgeStyle);
if (!tmp && this.isAllowEval()) { if (!tmp && this.isAllowEval()) {
tmp = eval(edgeStyle); tmp = eval(edgeStyle);
} }
edgeStyle = tmp; edgeStyle = tmp;
} }
@ -2288,7 +2278,7 @@ export class GraphView extends EventSource {
container.appendChild(this.canvas); container.appendChild(this.canvas);
this.updateContainerStyle(container); this.updateContainerStyle(container);
} }
}; }
/** /**
* Function: updateHtmlCanvasSize * Function: updateHtmlCanvasSize
@ -2312,7 +2302,7 @@ export class GraphView extends EventSource {
this.canvas.style.height = '100%'; this.canvas.style.height = '100%';
} }
} }
}; }
/** /**
* Function: createHtmlPane * Function: createHtmlPane
@ -2329,12 +2319,11 @@ export class GraphView extends EventSource {
pane.style.width = width; pane.style.width = width;
pane.style.height = height; pane.style.height = height;
} else { } else {
pane.style.position = 'relative'; pane.style.position = 'relative';
} }
return pane; return pane;
}; }
/** /**
* Updates the style of the container after installing the SVG DOM elements. * Updates the style of the container after installing the SVG DOM elements.
@ -2357,7 +2346,7 @@ export class GraphView extends EventSource {
* Destroys the view and all its resources. * Destroys the view and all its resources.
*/ */
destroy() { destroy() {
let root: SVGElement | HTMLElement | null=null; let root: SVGElement | HTMLElement | null = null;
if (this.canvas && this.canvas instanceof SVGElement) { if (this.canvas && this.canvas instanceof SVGElement) {
root = this.canvas.ownerSVGElement as SVGElement; root = this.canvas.ownerSVGElement as SVGElement;

View File

@ -610,7 +610,6 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
* Starts a new connection for the given state and coordinates. * Starts a new connection for the given state and coordinates.
*/ */
start(state: CellState, x: number, y: number, edgeState: CellState) { start(state: CellState, x: number, y: number, edgeState: CellState) {
console.log("ConnectionHandler start");
this.previous = state; this.previous = state;
this.first = new Point(x, y); this.first = new Point(x, y);
this.edgeState = edgeState ?? this.createEdgeState(); this.edgeState = edgeState ?? this.createEdgeState();
@ -1191,9 +1190,8 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
// Uses edge state to compute the terminal points // Uses edge state to compute the terminal points
if (this.edgeState) { if (this.edgeState) {
this.updateEdgeState(current, constraint); this.updateEdgeState(current, constraint);
current = this.edgeState.absolutePoints[ current =
this.edgeState.absolutePoints.length - 1 this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 1];
];
pt2 = this.edgeState.absolutePoints[0]; pt2 = this.edgeState.absolutePoints[0];
} else { } else {
if (this.currentState) { if (this.currentState) {
@ -1225,9 +1223,8 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
let tmp = pt2; let tmp = pt2;
if (this.edgeState && this.edgeState.absolutePoints.length >= 2) { if (this.edgeState && this.edgeState.absolutePoints.length >= 2) {
const tmp2 = this.edgeState.absolutePoints[ const tmp2 =
this.edgeState.absolutePoints.length - 2 this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 2];
];
if (tmp2) { if (tmp2) {
tmp = tmp2; tmp = tmp2;

View File

@ -26,6 +26,8 @@ import ConnectionConstraint from '../other/ConnectionConstraint';
import Point from '../geometry/Point'; import Point from '../geometry/Point';
import Cell from '../cell/Cell'; import Cell from '../cell/Cell';
import pointImg from '../../../images/point.gif';
/** /**
* Handles constraints on connection targets. This class is in charge of * Handles constraints on connection targets. This class is in charge of
* showing fixed points when the mouse is over a vertex and handles constraints * showing fixed points when the mouse is over a vertex and handles constraints
@ -38,7 +40,7 @@ class ConstraintHandler {
* {@link Image} to be used as the image for fixed connection points. * {@link Image} to be used as the image for fixed connection points.
*/ */
// pointImage: mxImage; // pointImage: mxImage;
pointImage = new Image(`${Client.imageBasePath}/point.gif`, 5, 5); pointImage = new Image(pointImg, 5, 5);
/** /**
* Reference to the enclosing {@link mxGraph}. * Reference to the enclosing {@link mxGraph}.
@ -81,8 +83,8 @@ class ConstraintHandler {
// Adds a graph model listener to update the current focus on changes // Adds a graph model listener to update the current focus on changes
this.resetHandler = () => { this.resetHandler = () => {
if ( if (
this.currentFocus != null && this.currentFocus &&
this.graph.view.getState(this.currentFocus.cell) == null !this.graph.view.getState(this.currentFocus.cell)
) { ) {
this.reset(); this.reset();
} else { } else {
@ -211,15 +213,15 @@ class ConstraintHandler {
// Gets cell under actual point if different from event location // Gets cell under actual point if different from event location
if ( if (
cell == null && !cell &&
point != null && point &&
(me.getGraphX() !== point.x || me.getGraphY() !== point.y) (me.getGraphX() !== point.x || me.getGraphY() !== point.y)
) { ) {
cell = this.graph.getCellAt(point.x, point.y); cell = this.graph.getCellAt(point.x, point.y);
} }
// Uses connectable parent vertex if one exists // Uses connectable parent vertex if one exists
if (cell != null && !cell.isConnectable()) { if (cell && !cell.isConnectable()) {
const parent = cell.getParent(); const parent = cell.getParent();
if (parent && parent.isVertex() && parent.isConnectable()) { if (parent && parent.isVertex() && parent.isConnectable()) {
@ -246,7 +248,7 @@ class ConstraintHandler {
) { ) {
if (this.isEnabled() && !this.isEventIgnored(me)) { if (this.isEnabled() && !this.isEventIgnored(me)) {
// Lazy installation of mouseleave handler // Lazy installation of mouseleave handler
if (this.mouseleaveHandler == null && this.graph.container != null) { if (!this.mouseleaveHandler && this.graph.container ) {
this.mouseleaveHandler = () => { this.mouseleaveHandler = () => {
this.reset(); this.reset();
}; };
@ -255,8 +257,8 @@ class ConstraintHandler {
} }
const tol = this.getTolerance(me); const tol = this.getTolerance(me);
const x = point != null ? point.x : me.getGraphX(); const x = point ? point.x : me.getGraphX();
const y = point != null ? point.y : me.getGraphY(); const y = point ? point.y : me.getGraphY();
const grid = new Rectangle(x - tol, y - tol, 2 * tol, 2 * tol); const grid = new Rectangle(x - tol, y - tol, 2 * tol, 2 * tol);
const mouse = new Rectangle( const mouse = new Rectangle(
me.getGraphX() - tol, me.getGraphX() - tol,
@ -270,8 +272,8 @@ class ConstraintHandler {
// Keeps focus icons visible while over vertex bounds and no other cell under mouse or shift is pressed // Keeps focus icons visible while over vertex bounds and no other cell under mouse or shift is pressed
if ( if (
!this.isKeepFocusEvent(me) && !this.isKeepFocusEvent(me) &&
(this.currentFocusArea == null || (!this.currentFocusArea ||
this.currentFocus == null || !this.currentFocus ||
state || state ||
!this.currentFocus.cell.isVertex() || !this.currentFocus.cell.isVertex() ||
!intersects(this.currentFocusArea, mouse)) && !intersects(this.currentFocusArea, mouse)) &&
@ -289,9 +291,9 @@ class ConstraintHandler {
let tmp; let tmp;
if ( if (
this.focusIcons != null && this.focusIcons.length > 0 &&
this.constraints != null && this.constraints &&
(state == null || this.currentFocus === state) (!state || this.currentFocus === state)
) { ) {
const cx = mouse.getCenterX(); const cx = mouse.getCenterX();
const cy = mouse.getCenterY(); const cy = mouse.getCenterY();
@ -303,9 +305,9 @@ class ConstraintHandler {
if ( if (
(this.intersects(this.focusIcons[i], mouse, source, existingEdge) || (this.intersects(this.focusIcons[i], mouse, source, existingEdge) ||
(point != null && (point &&
this.intersects(this.focusIcons[i], grid, source, existingEdge))) && this.intersects(this.focusIcons[i], grid, source, existingEdge))) &&
(minDistSq == null || tmp < minDistSq) (minDistSq === null || tmp < minDistSq)
) { ) {
this.currentConstraint = this.constraints[i]; this.currentConstraint = this.constraints[i];
this.currentPoint = this.focusPoints[i]; this.currentPoint = this.focusPoints[i];
@ -316,7 +318,7 @@ class ConstraintHandler {
tmp.width -= 1; tmp.width -= 1;
tmp.height -= 1; tmp.height -= 1;
if (this.focusHighlight == null) { if (!this.focusHighlight) {
const hl = this.createHighlightShape(); const hl = this.createHighlightShape();
hl.dialect = DIALECT.SVG; hl.dialect = DIALECT.SVG;
hl.pointerEvents = false; hl.pointerEvents = false;
@ -325,7 +327,7 @@ class ConstraintHandler {
this.focusHighlight = hl; this.focusHighlight = hl;
const getState = () => { const getState = () => {
return this.currentFocus != null ? this.currentFocus : state; return this.currentFocus ? this.currentFocus : state;
}; };
InternalEvent.redirectMouseEvents(hl.node, this.graph, getState); InternalEvent.redirectMouseEvents(hl.node, this.graph, getState);
@ -337,7 +339,7 @@ class ConstraintHandler {
} }
} }
if (this.currentConstraint == null) { if (!this.currentConstraint) {
this.destroyFocusHighlight(); this.destroyFocusHighlight();
} }
} else { } else {
@ -354,9 +356,9 @@ class ConstraintHandler {
*/ */
redraw() { redraw() {
if ( if (
this.currentFocus != null && this.currentFocus &&
this.constraints != null && this.constraints &&
this.focusIcons != null this.focusIcons.length > 0
) { ) {
const state = this.graph.view.getState(this.currentFocus.cell) as CellState; const state = this.graph.view.getState(this.currentFocus.cell) as CellState;
this.currentFocus = state; this.currentFocus = state;
@ -423,12 +425,12 @@ class ConstraintHandler {
icon.init(this.graph.getView().getDecoratorPane()); icon.init(this.graph.getView().getDecoratorPane());
// Move the icon behind all other overlays // Move the icon behind all other overlays
if (icon.node.previousSibling != null) { if (icon.node.previousSibling) {
icon.node.parentNode?.insertBefore(icon.node, icon.node.parentNode.firstChild); icon.node.parentNode?.insertBefore(icon.node, icon.node.parentNode.firstChild);
} }
const getState = () => { const getState = () => {
return this.currentFocus != null ? this.currentFocus : state; return this.currentFocus ? this.currentFocus : state;
}; };
icon.redraw(); icon.redraw();
@ -480,7 +482,7 @@ class ConstraintHandler {
this.graph.view.removeListener(this.resetHandler); this.graph.view.removeListener(this.resetHandler);
this.graph.removeListener(this.resetHandler); this.graph.removeListener(this.resetHandler);
if (this.mouseleaveHandler != null && this.graph.container != null) { if (this.mouseleaveHandler && this.graph.container) {
InternalEvent.removeListener( InternalEvent.removeListener(
this.graph.container, this.graph.container,
'mouseleave', 'mouseleave',

View File

@ -577,6 +577,7 @@ export const CellsMixin: PartialType = {
if (!style) { if (!style) {
style = {} as CellStateStyles; style = {} as CellStateStyles;
} }
return style; return style;
}, },
@ -2009,7 +2010,9 @@ export const CellsMixin: PartialType = {
this.resetEdges(cells); this.resetEdges(cells);
} }
this.fireEvent(new EventObject(InternalEvent.CELLS_MOVED, { cells, dx, dy, disconnect })); this.fireEvent(
new EventObject(InternalEvent.CELLS_MOVED, { cells, dx, dy, disconnect })
);
}); });
} }
}, },
@ -2755,9 +2758,8 @@ export const CellsMixin: PartialType = {
*/ */
isCellResizable(cell) { isCellResizable(cell) {
const style = this.getCurrentCellStyle(cell); const style = this.getCurrentCellStyle(cell);
const r = this.isCellsResizable() && const r =
!this.isCellLocked(cell) && this.isCellsResizable() && !this.isCellLocked(cell) && (style.resizable ?? true);
(style.resizable ?? true);
return r; return r;
}, },

View File

@ -113,7 +113,13 @@ class EdgeStyle {
* @param result Array of <Point> that represent the actual points of the * @param result Array of <Point> that represent the actual points of the
* edge. * edge.
*/ */
static EntityRelation(state: CellState, source: CellState, target: CellState, points: Point[], result: Point[]) { static EntityRelation(
state: CellState,
source: CellState,
target: CellState,
points: Point[],
result: Point[]
) {
const { view } = state; const { view } = state;
const { graph } = view; const { graph } = view;
const segment = getValue(state.style, 'segment', ENTITY_SEGMENT) * view.scale; const segment = getValue(state.style, 'segment', ENTITY_SEGMENT) * view.scale;
@ -218,7 +224,13 @@ class EdgeStyle {
/** /**
* Implements a self-reference, aka. loop. * Implements a self-reference, aka. loop.
*/ */
static Loop(state: CellState, source: CellState, target: CellState, points: Point[], result: Point[]) { static Loop(
state: CellState,
source: CellState,
target: CellState,
points: Point[],
result: Point[]
) {
const pts = state.absolutePoints; const pts = state.absolutePoints;
const p0 = pts[0]; const p0 = pts[0];
@ -295,7 +307,13 @@ class EdgeStyle {
* unspecified. See <EntityRelation> for a description of the * unspecified. See <EntityRelation> for a description of the
* parameters. * parameters.
*/ */
static ElbowConnector(state: CellState, source: CellState, target: CellState, points: Point[], result: Point[]) { static ElbowConnector(
state: CellState,
source: CellState,
target: CellState,
points: Point[],
result: Point[]
) {
let pt = points != null && points.length > 0 ? points[0] : null; let pt = points != null && points.length > 0 ? points[0] : null;
let vertical = false; let vertical = false;
@ -312,7 +330,6 @@ class EdgeStyle {
pt = <Point>state.view.transformControlPoint(state, pt); pt = <Point>state.view.transformControlPoint(state, pt);
vertical = pt.y < top || pt.y > bottom; vertical = pt.y < top || pt.y > bottom;
horizontal = pt.x < left || pt.x > right; horizontal = pt.x < left || pt.x > right;
} else { } else {
const left = Math.max(source.x, target.x); const left = Math.max(source.x, target.x);
const right = Math.min(source.x + source.width, target.x + target.width); const right = Math.min(source.x + source.width, target.x + target.width);
@ -338,7 +355,13 @@ class EdgeStyle {
* Implements a vertical elbow edge. See <EntityRelation> for a description * Implements a vertical elbow edge. See <EntityRelation> for a description
* of the parameters. * of the parameters.
*/ */
static SideToSide(state: CellState, source: CellState, target: CellState, points: Point[], result: Point[]) { static SideToSide(
state: CellState,
source: CellState,
target: CellState,
points: Point[],
result: Point[]
) {
const { view } = state; const { view } = state;
let pt = points != null && points.length > 0 ? points[0] : null; let pt = points != null && points.length > 0 ? points[0] : null;
const pts = state.absolutePoints; const pts = state.absolutePoints;
@ -407,7 +430,13 @@ class EdgeStyle {
* Implements a horizontal elbow edge. See <EntityRelation> for a * Implements a horizontal elbow edge. See <EntityRelation> for a
* description of the parameters. * description of the parameters.
*/ */
static TopToBottom(state: CellState, source: CellState, target: CellState, points: Point[], result: Point[]) { static TopToBottom(
state: CellState,
source: CellState,
target: CellState,
points: Point[],
result: Point[]
) {
const { view } = state; const { view } = state;
let pt = points != null && points.length > 0 ? points[0] : null; let pt = points != null && points.length > 0 ? points[0] : null;
const pts = state.absolutePoints; const pts = state.absolutePoints;
@ -482,11 +511,23 @@ class EdgeStyle {
* @param result Array of <Point> that represent the actual points of the * @param result Array of <Point> that represent the actual points of the
* edge. * edge.
*/ */
static SegmentConnector(state: CellState, sourceScaled: CellState, targetScaled: CellState, controlHints: Point[], result: Point[]) { static SegmentConnector(
state: CellState,
sourceScaled: CellState,
targetScaled: CellState,
controlHints: Point[],
result: Point[]
) {
// Creates array of all way- and terminalpoints // Creates array of all way- and terminalpoints
// TODO: Figure out what to do when there are nulls in `pts`! // TODO: Figure out what to do when there are nulls in `pts`!
const pts = <Point[]><unknown>EdgeStyle.scalePointArray(<Point[]><unknown>state.absolutePoints, state.view.scale); const pts = <Point[]>(
(<unknown>(
EdgeStyle.scalePointArray(
<Point[]>(<unknown>state.absolutePoints),
state.view.scale
)
))
);
const source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale); const source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale);
const target = EdgeStyle.scaleCellState(targetScaled, state.view.scale); const target = EdgeStyle.scaleCellState(targetScaled, state.view.scale);
const tol = 1; const tol = 1;
@ -952,10 +993,19 @@ class EdgeStyle {
* @param result Array of <Point> that represent the actual points of the * @param result Array of <Point> that represent the actual points of the
* edge. * edge.
*/ */
static OrthConnector(state: CellState, sourceScaled: CellState, targetScaled: CellState, controlHints: Point[], result: Point[]) { static OrthConnector(
state: CellState,
sourceScaled: CellState,
targetScaled: CellState,
controlHints: Point[],
result: Point[]
) {
// TODO: Figure out what to do when there are nulls in `pts`! // TODO: Figure out what to do when there are nulls in `pts`!
const pts = <Point[]><unknown>EdgeStyle.scalePointArray(<Point[]>state.absolutePoints, state.view.scale); const pts = <Point[]>(
(<unknown>(
EdgeStyle.scalePointArray(<Point[]>state.absolutePoints, state.view.scale)
))
);
let source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale); let source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale);
let target = EdgeStyle.scaleCellState(targetScaled, state.view.scale); let target = EdgeStyle.scaleCellState(targetScaled, state.view.scale);
@ -1022,9 +1072,11 @@ class EdgeStyle {
// console.log('source rotation', rotation); // console.log('source rotation', rotation);
if (rotation !== 0) { if (rotation !== 0) {
const newRect = <Rectangle>getBoundingBox( const newRect = <Rectangle>(
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), getBoundingBox(
rotation new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
rotation
)
); );
sourceX = newRect.x; sourceX = newRect.x;
sourceY = newRect.y; sourceY = newRect.y;
@ -1040,9 +1092,11 @@ class EdgeStyle {
// console.log('target rotation', rotation); // console.log('target rotation', rotation);
if (rotation !== 0) { if (rotation !== 0) {
const newRect = <Rectangle>getBoundingBox( const newRect = <Rectangle>(
new Rectangle(targetX, targetY, targetWidth, targetHeight), getBoundingBox(
rotation new Rectangle(targetX, targetY, targetWidth, targetHeight),
rotation
)
); );
targetX = newRect.x; targetX = newRect.x;
targetY = newRect.y; targetY = newRect.y;
@ -1464,7 +1518,12 @@ class EdgeStyle {
} }
} }
static getRoutePattern(dir: number[], quad: number, dx: number, dy: number): number[] | null { static getRoutePattern(
dir: number[],
quad: number,
dx: number,
dy: number
): number[] | null {
let sourceIndex = dir[0] === DIRECTION_MASK.EAST ? 3 : dir[0]; let sourceIndex = dir[0] === DIRECTION_MASK.EAST ? 3 : dir[0];
let targetIndex = dir[1] === DIRECTION_MASK.EAST ? 3 : dir[1]; let targetIndex = dir[1] === DIRECTION_MASK.EAST ? 3 : dir[1];
@ -1478,7 +1537,8 @@ class EdgeStyle {
targetIndex += 4; targetIndex += 4;
} }
let result: number[] | null = EdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1]; let result: number[] | null =
EdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1];
if (dx === 0 || dy === 0) { if (dx === 0 || dy === 0) {
if (EdgeStyle.inlineRoutePatterns[sourceIndex - 1][targetIndex - 1] != null) { if (EdgeStyle.inlineRoutePatterns[sourceIndex - 1][targetIndex - 1] != null) {

View File

@ -44,16 +44,17 @@ const Template = ({ label, ...args }) => {
class MyCustomGraph extends Graph { class MyCustomGraph extends Graph {
getAllConnectionConstraints(terminal, source) { getAllConnectionConstraints(terminal, source) {
// Overridden to define per-shape connection points // Overridden to define per-geometry connection points
if (terminal != null && terminal.shape != null) { if (terminal && terminal.cell) {
if (terminal.shape.stencil != null) { if (terminal.shape.stencil) {
if (terminal.shape.stencil.constraints != null) { if (terminal.shape.stencil.constraints) {
return terminal.shape.stencil.constraints; return terminal.shape.stencil.constraints;
} }
} else if (terminal.shape.constraints != null) { } else if (terminal.cell.geometry.constraints) {
return terminal.shape.constraints; return terminal.cell.geometry.constraints;
} }
} }
return null; return null;
} }
@ -116,8 +117,8 @@ const Template = ({ label, ...args }) => {
const e1 = graph.insertEdge({ const e1 = graph.insertEdge({
parent, parent,
value: '', value: '',
position: v1, source: v1,
size: v2, target: v2,
}); });
}); });