Keep fixing relatioship.

This commit is contained in:
Paulo Gustavo Veiga 2022-11-27 10:22:19 -08:00
parent c1dc4554d7
commit 2a9c79fe92
13 changed files with 203 additions and 223 deletions

View File

@ -17,6 +17,7 @@
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import { Point, CurvedLine, Rect } from '@wisemapping/web2d'; import { Point, CurvedLine, Rect } from '@wisemapping/web2d';
import PositionType from './PositionType';
import SizeType from './SizeType'; import SizeType from './SizeType';
import Topic from './Topic'; import Topic from './Topic';
@ -24,7 +25,7 @@ import Shape from './util/Shape';
import Workspace from './Workspace'; import Workspace from './Workspace';
class DragPivot { class DragPivot {
private _position: Point; private _position: PositionType;
private _isVisible: boolean; private _isVisible: boolean;
@ -41,7 +42,7 @@ class DragPivot {
private _size: SizeType; private _size: SizeType;
constructor() { constructor() {
this._position = new Point(); this._position = { x: 0, y: 0 };
this._size = DragPivot.DEFAULT_PIVOT_SIZE; this._size = DragPivot.DEFAULT_PIVOT_SIZE;
this._straightLine = this._buildStraightLine(); this._straightLine = this._buildStraightLine();

View File

@ -49,8 +49,8 @@ class DragTopic {
this._order = null; this._order = null;
this._draggedNode = draggedNode; this._draggedNode = draggedNode;
this._layoutManager = layoutManger; this._layoutManager = layoutManger;
this._position = new Point();
this._isInWorkspace = false; this._isInWorkspace = false;
this._position = new Point(0, 0);
} }
setOrder(order: number): void { setOrder(order: number): void {
@ -59,15 +59,14 @@ class DragTopic {
setPosition(x: number, y: number): void { setPosition(x: number, y: number): void {
// Update drag shadow position .... // Update drag shadow position ....
const position = { x, y }; this._position = { x, y };
this._position.setValue(position.x, position.y);
// Elements are positioned in the center. // Elements are positioned in the center.
// All topic element must be positioned based on the innerShape. // All topic element must be positioned based on the innerShape.
const draggedNode = this._draggedNode; const draggedNode = this._draggedNode;
const size = draggedNode.getSize(); const size = draggedNode.getSize();
const cx = position.x - (position.x > 0 ? 0 : size.width); const cx = x - (x > 0 ? 0 : size.width);
const cy = Math.ceil(position.y - size.height / 2); const cy = Math.ceil(y - size.height / 2);
this._elem2d.setPosition(cx, cy); this._elem2d.setPosition(cx, cy);
// In case is not free, pivot must be draw ... // In case is not free, pivot must be draw ...

View File

@ -123,9 +123,8 @@ class MainTopic extends Topic {
const isAtRight = Shape.isAtRight(targetPosition, pos); const isAtRight = Shape.isAtRight(targetPosition, pos);
const size = this.getSize(); const size = this.getSize();
let result: Point; let result: Point = { x: 0, y: 0 };
if (this.getShapeType() === TopicShape.LINE) { if (this.getShapeType() === TopicShape.LINE) {
result = new Point();
const groupPosition = this.get2DElement().getPosition(); const groupPosition = this.get2DElement().getPosition();
const innerShareSize = this.getInnerShape().getSize(); const innerShareSize = this.getInnerShape().getSize();
@ -150,7 +149,7 @@ class MainTopic extends Topic {
} else { } else {
result = Shape.calculateRectConnectionPoint(pos, size, isAtRight); result = Shape.calculateRectConnectionPoint(pos, size, isAtRight);
} }
return result; return new Point(result.x, result.y);
} }
} }

View File

@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import { Arrow, Point, ElementClass } from '@wisemapping/web2d'; import { Arrow, Point, CurvedLine } from '@wisemapping/web2d';
import ConnectionLine from './ConnectionLine'; import ConnectionLine from './ConnectionLine';
import RelationshipControlPoints from './RelationshipControlPoints'; import RelationshipControlPoints from './RelationshipControlPoints';
import RelationshipModel from './model/RelationshipModel'; import RelationshipModel from './model/RelationshipModel';
@ -26,7 +26,7 @@ import Shape from './util/Shape';
import Workspace from './Workspace'; import Workspace from './Workspace';
class Relationship extends ConnectionLine { class Relationship extends ConnectionLine {
private _focusShape: ElementClass; private _focusShape: CurvedLine;
private _onFocus: boolean; private _onFocus: boolean;
@ -53,23 +53,22 @@ class Relationship extends ConnectionLine {
const strokeColor = Relationship.getStrokeColor(); const strokeColor = Relationship.getStrokeColor();
// Build line ..
this._line2d.setIsSrcControlPointCustom(false); this._line2d.setIsSrcControlPointCustom(false);
this._line2d.setIsDestControlPointCustom(false); this._line2d.setIsDestControlPointCustom(false);
this._line2d.setCursor('pointer'); this._line2d.setCursor('pointer');
this._line2d.setStroke(1, 'solid', strokeColor); this._line2d.setStroke(1, 'solid', strokeColor);
this._line2d.setDashed(4, 2); this._line2d.setDashed(4, 2);
this._line2d.setTestId(`${model.getFromNode()}-${model.getToNode()}-relationship`); this._line2d.setTestId(`${model.getFromNode()}-${model.getToNode()}-relationship`);
// Build focus shape ...
this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED); this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED);
this._focusShape.setStroke(2, 'solid', '#3f96ff'); this._focusShape.setStroke(2, 'solid', '#3f96ff');
this._focusShape.setIsSrcControlPointCustom(false);
const ctrlPoints = this._line2d.getControlPoints(); this._focusShape.setIsDestControlPointCustom(false);
this._focusShape.setSrcControlPoint(ctrlPoints[0]);
this._focusShape.setDestControlPoint(ctrlPoints[1]);
this._focusShape.setVisibility(false); this._focusShape.setVisibility(false);
this._onFocus = false;
this._isInWorkspace = false;
this._controlPointsController = new RelationshipControlPoints(this);
// Build arrow ...
this._startArrow = new Arrow(); this._startArrow = new Arrow();
this._startArrow.setStrokeColor(strokeColor); this._startArrow.setStrokeColor(strokeColor);
this._startArrow.setStrokeWidth(2); this._startArrow.setStrokeWidth(2);
@ -81,6 +80,9 @@ class Relationship extends ConnectionLine {
this._endArrow.setStrokeColor(strokeColor); this._endArrow.setStrokeColor(strokeColor);
this._endArrow.setStrokeWidth(2); this._endArrow.setStrokeWidth(2);
} }
this._onFocus = false;
this._isInWorkspace = false;
this._controlPointsController = new RelationshipControlPoints(this);
// Position the line ... // Position the line ...
if (model.getSrcCtrlPoint()) { if (model.getSrcCtrlPoint()) {
@ -92,6 +94,10 @@ class Relationship extends ConnectionLine {
const destPoint = { ...model.getDestCtrlPoint() }; const destPoint = { ...model.getDestCtrlPoint() };
this.setDestControlPoint(destPoint); this.setDestControlPoint(destPoint);
} }
// Reposition all nodes ...
this._updatePositions();
this._controlPointsController = new RelationshipControlPoints(this);
} }
setStroke(color: string, style: string, opacity: number): void { setStroke(color: string, style: string, opacity: number): void {
@ -99,43 +105,44 @@ class Relationship extends ConnectionLine {
this._startArrow.setStrokeColor(color); this._startArrow.setStrokeColor(color);
} }
redraw(): void { private _updatePositions() {
const line2d = this._line2d; const line2d = this._line2d;
const sourceTopic = this._sourceTopic; const sourceTopic = this._sourceTopic;
const sourcePosition = sourceTopic.getPosition(); const sPos = sourceTopic.getPosition();
const targetTopic = this._targetTopic; const targetTopic = this._targetTopic;
let targetPosition = targetTopic.getPosition(); let tPos = targetTopic.getPosition();
if (targetTopic.getType() === 'CentralTopic') { if (targetTopic.getType() === 'CentralTopic') {
targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition); tPos = Shape.workoutIncomingConnectionPoint(targetTopic, sPos);
} }
this._line2d.setStroke(2); this._line2d.setStroke(2);
const ctrlPoints = this._line2d.getControlPoints(); let ctrlPoints: [Point, Point];
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
const defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
ctrlPoints[0].x = defaultPoints[0].x;
ctrlPoints[0].y = defaultPoints[0].y;
ctrlPoints[1].x = defaultPoints[1].x; // Position line ...
ctrlPoints[1].y = defaultPoints[1].y; if (!line2d.isDestControlPointCustom() && !line2d.isSrcControlPointCustom()) {
ctrlPoints = Shape.calculateDefaultControlPoints(sPos, tPos) as [PositionType, PositionType];
} else {
ctrlPoints = line2d.getControlPoints();
} }
const spoint = new Point(); const spointX = ctrlPoints[0].x + sPos.x;
spoint.x = parseInt(ctrlPoints[0].x, 10) + parseInt(sourcePosition.x, 10); const spointY = ctrlPoints[0].y + sPos.y;
spoint.y = parseInt(ctrlPoints[0].y, 10) + parseInt(sourcePosition.y, 10);
const tpoint = new Point(); const tpointX = ctrlPoints[1].x + tPos.x;
tpoint.x = parseInt(ctrlPoints[1].x, 10) + parseInt(targetPosition.x, 10); const tpointY = ctrlPoints[1].y + tPos.y;
tpoint.y = parseInt(ctrlPoints[1].y, 10) + parseInt(targetPosition.y, 10);
const sPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint); const nsPos = Shape.calculateRelationShipPointCoordinates(
const tPos = Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint); sourceTopic,
new Point(spointX, spointY),
);
const ntPos = Shape.calculateRelationShipPointCoordinates(
targetTopic,
new Point(tpointX, tpointY),
);
line2d.setFrom(sPos.x, sPos.y); line2d.setFrom(nsPos.x, nsPos.y);
line2d.setTo(tPos.x, tPos.y); line2d.setTo(ntPos.x, ntPos.y);
line2d.moveToFront();
// Positionate Arrows // Positionate Arrows
this._positionArrows(); this._positionArrows();
@ -143,11 +150,25 @@ class Relationship extends ConnectionLine {
// Add connector ... // Add connector ...
this._positionateConnector(targetTopic); this._positionateConnector(targetTopic);
if (this.isOnFocus()) { // Poisition refresh shape ...
this.refreshShape(); this._positionRefreshShape();
} }
this._focusShape.moveToBack();
redraw(): void {
this._updatePositions();
this._line2d.moveToFront();
this._startArrow.moveToBack();
if (this._endArrow) {
this._endArrow.moveToBack();
}
if (this._showEndArrow) {
this._endArrow.setVisibility(this.isVisible());
}
this._startArrow.setVisibility(this.isVisible() && this._showStartArrow);
this._focusShape.moveToBack();
this._controlPointsController.redraw(); this._controlPointsController.redraw();
} }
@ -156,11 +177,8 @@ class Relationship extends ConnectionLine {
const spos = this._line2d.getFrom(); const spos = this._line2d.getFrom();
this._startArrow.setFrom(spos.x, spos.y); this._startArrow.setFrom(spos.x, spos.y);
this._startArrow.moveToBack();
if (this._endArrow) { if (this._endArrow) {
this._endArrow.setFrom(tpos.x, tpos.y); this._endArrow.setFrom(tpos.x, tpos.y);
this._endArrow.moveToBack();
} }
if (this._line2d.getType() === 'CurvedLine') { if (this._line2d.getType() === 'CurvedLine') {
@ -175,14 +193,11 @@ class Relationship extends ConnectionLine {
this._endArrow.setControlPoint(this._line2d.getFrom()); this._endArrow.setControlPoint(this._line2d.getFrom());
} }
} }
if (this._showEndArrow) {
this._endArrow.setVisibility(this.isVisible());
}
this._startArrow.setVisibility(this.isVisible() && this._showStartArrow);
} }
addToWorkspace(workspace: Workspace): void { addToWorkspace(workspace: Workspace): void {
this._updatePositions();
workspace.append(this._focusShape); workspace.append(this._focusShape);
workspace.append(this._controlPointsController); workspace.append(this._controlPointsController);
@ -225,12 +240,11 @@ class Relationship extends ConnectionLine {
} }
setOnFocus(focus: boolean): void { setOnFocus(focus: boolean): void {
if (focus) {
this._positionRefreshShape();
}
// Change focus shape // Change focus shape
if (this.isOnFocus() !== focus) { if (this.isOnFocus() !== focus) {
if (focus) {
this.refreshShape();
}
this._focusShape.setVisibility(focus); this._focusShape.setVisibility(focus);
this._controlPointsController.setVisibility(focus); this._controlPointsController.setVisibility(focus);
this._onFocus = focus; this._onFocus = focus;
@ -238,17 +252,16 @@ class Relationship extends ConnectionLine {
} }
} }
refreshShape(): void { private _positionRefreshShape(): void {
const sPos = this._line2d.getFrom(); const sPos = this._line2d.getFrom();
const tPos = this._line2d.getTo(); const tPos = this._line2d.getTo();
const ctrlPoints = this._line2d.getControlPoints(); const ctrlPoints = this._line2d.getControlPoints();
this._focusShape.setFrom(sPos.x, sPos.y); this._focusShape.setFrom(sPos.x, sPos.y);
this._focusShape.setTo(tPos.x, tPos.y); this._focusShape.setTo(tPos.x, tPos.y);
const shapeCtrlPoints = this._focusShape.getControlPoints();
shapeCtrlPoints[0].x = ctrlPoints[0].x; this._focusShape.setSrcControlPoint(ctrlPoints[0]);
shapeCtrlPoints[0].y = ctrlPoints[0].y; this._focusShape.setDestControlPoint(ctrlPoints[1]);
shapeCtrlPoints[1].x = ctrlPoints[1].x;
shapeCtrlPoints[1].y = ctrlPoints[1].y;
this._focusShape.updateLine(); this._focusShape.updateLine();
} }
@ -302,12 +315,12 @@ class Relationship extends ConnectionLine {
} }
} }
setShowStartArrow(visible: boolean) { setShowStartArrow(visible: boolean): void {
this._showStartArrow = visible; this._showStartArrow = visible;
if (this._isInWorkspace) this.redraw(); if (this._isInWorkspace) this.redraw();
} }
setFrom(x: number, y: number) { setFrom(x: number, y: number): void {
$assert($defined(x), 'x must be defined'); $assert($defined(x), 'x must be defined');
$assert($defined(y), 'y must be defined'); $assert($defined(y), 'y must be defined');
@ -325,12 +338,16 @@ class Relationship extends ConnectionLine {
setSrcControlPoint(control: PositionType): void { setSrcControlPoint(control: PositionType): void {
this._line2d.setSrcControlPoint(control); this._line2d.setSrcControlPoint(control);
this._focusShape.setSrcControlPoint(control);
this._startArrow.setControlPoint(control); this._startArrow.setControlPoint(control);
} }
setDestControlPoint(control: PositionType) { setDestControlPoint(control: PositionType) {
this._line2d.setDestControlPoint(control); this._line2d.setDestControlPoint(control);
if (this._showEndArrow) this._endArrow.setControlPoint(control); this._focusShape.setSrcControlPoint(control);
if (this._showEndArrow) {
this._endArrow.setControlPoint(control);
}
} }
getControlPoints(): PositionType { getControlPoints(): PositionType {

View File

@ -23,7 +23,8 @@ import Workspace from './Workspace';
import PositionType from './PositionType'; import PositionType from './PositionType';
import Relationship from './Relationship'; import Relationship from './Relationship';
enum PivotType { // eslint-disable-next-line no-shadow
export enum PivotType {
Start = 0, Start = 0,
End = 1, End = 1,
} }
@ -41,21 +42,20 @@ class ControlPivotLine {
private _changeHander: () => void; private _changeHander: () => void;
private _moveRelHandler: ( private _moveRelHandler: (controlPointPosition: PositionType) => void;
relationPosition: PositionType,
controlPointPosition: PositionType,
) => void;
private _isVisible: boolean; private _isVisible: boolean;
private _mouseMoveHandler: (e: MouseEvent) => void; private _mouseMoveHandler: (e: MouseEvent) => void;
private _mousedUpHandler: () => void; private _mouseUpHandler: () => void;
private _mouseDownHandler: (event: MouseEvent) => void;
constructor( constructor(
pivotType: PivotType, pivotType: PivotType,
relationship: Relationship, relationship: Relationship,
mouseMoveHandler: (relationPosition: PositionType, controlPointPosition: PositionType) => void, mouseMoveHandler: (controlPointPosition: PositionType) => void,
changeHander: () => void, changeHander: () => void,
) { ) {
this._pivotType = pivotType; this._pivotType = pivotType;
@ -76,11 +76,6 @@ class ControlPivotLine {
// Build line ... // Build line ...
this._line = new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }); this._line = new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 });
// Register events ...
this._dot.addEvent('mousedown', (event: MouseEvent) => {
this._mouseDown(event);
});
const mouseClick = (event: MouseEvent): boolean => { const mouseClick = (event: MouseEvent): boolean => {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -91,32 +86,39 @@ class ControlPivotLine {
// Register handled ... // Register handled ...
this._mouseMoveHandler = (e: MouseEvent) => this.mouseMoveHandler(e); this._mouseMoveHandler = (e: MouseEvent) => this.mouseMoveHandler(e);
this._mousedUpHandler = () => this._mouseUpHandler(); this._mouseUpHandler = () => this.mouseUpHandler();
this._mouseDownHandler = (event: MouseEvent) => this.mouseDownHandler(event);
} }
private _mouseDown(event: MouseEvent) { private mouseDownHandler(event: MouseEvent) {
this.getWorkspace().getScreenManager().addEvent('mousemove', this._mouseMoveHandler); const screenManager = this.getWorkspace().getScreenManager();
this.getWorkspace().getScreenManager().addEvent('mouseup', this._mousedUpHandler); screenManager.addEvent('mousemove', this._mouseMoveHandler);
screenManager.addEvent('mouseup', this._mouseUpHandler);
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false;
} }
setVisibility(value: boolean) { setVisibility(value: boolean) {
this._isVisible = value; if (this._isVisible !== value) {
const screenManager = this.getWorkspace().getScreenManager();
if (!value) {
screenManager.removeEvent('mousemove', this._mouseMoveHandler);
screenManager.removeEvent('mouseup', this._mouseUpHandler);
this._dot.removeEvent('mousedown', this._mouseDownHandler);
} else {
// Register events ...
this._dot.addEvent('mousedown', this._mouseDownHandler);
}
const screenManager = this.getWorkspace().getScreenManager(); // Make it visible ...
if (!value) { this._dot.setVisibility(value);
screenManager.removeEvent('mousemove', this._mouseMoveHandler); this._line.setVisibility(value);
screenManager.removeEvent('mouseup', this._mouseUpHandler);
} }
// Make it visible ... this._isVisible = value;
this._dot.setVisibility(value);
this._line.setVisibility(value);
if (value) { if (value) {
// Register events ...
this.redraw(); this.redraw();
this._line.moveToFront(); this._line.moveToFront();
this._dot.moveToFront(); this._dot.moveToFront();
@ -132,15 +134,15 @@ class ControlPivotLine {
if (this._isVisible) { if (this._isVisible) {
const relationshipLine = this._relationship.getLine(); const relationshipLine = this._relationship.getLine();
const startPosition = const startPosition =
this._pivotType === PivotType.Start ? relationshipLine.getTo() : relationshipLine.getFrom(); this._pivotType === PivotType.End ? relationshipLine.getTo() : relationshipLine.getFrom();
const ctrPosition = relationshipLine.getControlPoints()[this._pivotType]; const ctrPosition = relationshipLine.getControlPoints()[this._pivotType];
this._line.setFrom(startPosition.x, startPosition.y); this._line.setFrom(startPosition.x, startPosition.y);
this._line.setTo(startPosition.x - ctrPosition.x - 5, startPosition.y - ctrPosition.y - 5); this._line.setTo(startPosition.x + ctrPosition.x - 5, startPosition.y + ctrPosition.y - 5);
this._dot.setPosition( this._dot.setPosition(
startPosition.x - ctrPosition.x - 8, startPosition.x + ctrPosition.x - 8,
startPosition.y - ctrPosition.y - 8, startPosition.y + ctrPosition.y - 8,
); );
} }
} }
@ -150,37 +152,24 @@ class ControlPivotLine {
const mousePosition = screen.getWorkspaceMousePosition(event); const mousePosition = screen.getWorkspaceMousePosition(event);
// Update relatioship position ... // Update relatioship position ...
let relationshipPosition: PositionType; const topic =
console.log(this._pivotType); this._pivotType === PivotType.Start
if (this._pivotType === PivotType.Start) { ? this._relationship.getSourceTopic()
relationshipPosition = Shape.calculateRelationShipPointCoordinates( : this._relationship.getTargetTopic();
this._relationship.getSourceTopic(),
mousePosition, const relPos = Shape.calculateRelationShipPointCoordinates(topic, mousePosition);
); const ctlPoint = { x: mousePosition.x - relPos.x, y: mousePosition.y - relPos.y };
this._moveRelHandler(relationshipPosition, { this._moveRelHandler(ctlPoint);
x: mousePosition.x - relationshipPosition.x,
y: mousePosition.y - relationshipPosition.y,
});
} else {
relationshipPosition = Shape.calculateRelationShipPointCoordinates(
this._relationship.getTargetTopic(),
mousePosition,
);
this._moveRelHandler(relationshipPosition, {
x: mousePosition.x - relationshipPosition.x,
y: mousePosition.y - relationshipPosition.y,
});
}
// Update pivot ... // Update pivot ...
this._dot.setPosition(mousePosition.x - 5, mousePosition.y - 3); this._dot.setPosition(mousePosition.x - 8, mousePosition.y - 8);
this._line.setTo(mousePosition.x - 2, mousePosition.y);
// Update controller ... // Update line ...
this._relationship.getLine().updateLine(this._pivotType); this._line.setTo(mousePosition.x - 5, mousePosition.y - 5);
this._line.setFrom(relPos.x, relPos.y);
} }
private _mouseUpHandler() { private mouseUpHandler() {
const screenManager = this.getWorkspace().getScreenManager(); const screenManager = this.getWorkspace().getScreenManager();
screenManager.removeEvent('mousemove', this._mouseMoveHandler); screenManager.removeEvent('mousemove', this._mouseMoveHandler);
screenManager.removeEvent('mouseup', this._mouseUpHandler); screenManager.removeEvent('mouseup', this._mouseUpHandler);
@ -222,12 +211,10 @@ class RelationshipControlPoints {
const startControlLine = new ControlPivotLine( const startControlLine = new ControlPivotLine(
PivotType.Start, PivotType.Start,
relationship, relationship,
(relationPosition, controlPointPosition) => { (controlPointPosition) => {
const line = this._relationship.getLine(); const line = this._relationship.getLine();
line.setFrom(relationPosition.x, relationPosition.y);
line.setSrcControlPoint(controlPointPosition); line.setSrcControlPoint(controlPointPosition);
relationship.redraw();
console.log(JSON.stringify(controlPointPosition));
}, },
() => { () => {
const actionDispatcher = ActionDispatcher.getInstance(); const actionDispatcher = ActionDispatcher.getInstance();
@ -240,12 +227,10 @@ class RelationshipControlPoints {
const endControlLine = new ControlPivotLine( const endControlLine = new ControlPivotLine(
PivotType.End, PivotType.End,
relationship, relationship,
(relationPosition, controlPointPosition) => { (controlPointPosition) => {
const line = this._relationship.getLine(); const line = this._relationship.getLine();
line.setTo(relationPosition.x, relationPosition.y);
line.setDestControlPoint(controlPointPosition); line.setDestControlPoint(controlPointPosition);
relationship.redraw();
console.log(JSON.stringify(controlPointPosition));
}, },
() => { () => {
const actionDispatcher = ActionDispatcher.getInstance(); const actionDispatcher = ActionDispatcher.getInstance();

View File

@ -152,11 +152,11 @@ class RelationshipPivot {
sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition); sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
} }
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition); const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
const point = new Point(
const spoint = new Point(); parseInt(controlPoint[0].x, 10) + sourcePosition.x,
spoint.x = parseInt(controlPoint[0].x, 10) + sourcePosition.x; parseInt(controlPoint[0].y, 10) + sourcePosition.y,
spoint.y = parseInt(controlPoint[0].y, 10) + sourcePosition.y; );
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint); return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, point);
} }
private _connectOnFocus(event: string, targetTopic: Topic): void { private _connectOnFocus(event: string, targetTopic: Topic): void {

View File

@ -16,6 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import flatten from 'lodash/flatten';
import Command from '../Command'; import Command from '../Command';
import CommandContext from '../CommandContext'; import CommandContext from '../CommandContext';
import NodeModel from '../model/NodeModel'; import NodeModel from '../model/NodeModel';
@ -169,7 +170,7 @@ class DeleteCommand extends Command {
const rels: Relationship[][] = children.map((t: Topic) => this._collectInDepthRelationships(t)); const rels: Relationship[][] = children.map((t: Topic) => this._collectInDepthRelationships(t));
// flatten and concact // flatten and concact
result.push(...rels.flat()); result.push(...flatten(rels));
if (result.length > 0) { if (result.length > 0) {
// Filter for unique ... // Filter for unique ...

View File

@ -16,17 +16,17 @@
* limitations under the License. * limitations under the License.
*/ */
import Command from '../Command'; import Command from '../Command';
import RelationshipControlPoints from '../RelationshipControlPoints'; import RelationshipControlPoints, { PivotType } from '../RelationshipControlPoints';
import PositionType from '../PositionType'; import PositionType from '../PositionType';
class MoveControlPointCommand extends Command { class MoveControlPointCommand extends Command {
private _controlPoints: RelationshipControlPoints; private _controlPoints: RelationshipControlPoints;
private _ctrPointPosition: PositionType; private _ctrIndex: PivotType;
private _endPosition: PositionType; private _oldCtrPoint: PositionType;
private _controlPointIndex: number; private _newCtrPoint: PositionType;
/** /**
* @classdesc This command handles do/undo of changing the control points of a relationship * @classdesc This command handles do/undo of changing the control points of a relationship
@ -34,72 +34,66 @@ class MoveControlPointCommand extends Command {
* influence how the arrow is drawn (not the source or the destination topic nor the arrow * influence how the arrow is drawn (not the source or the destination topic nor the arrow
* direction) * direction)
*/ */
constructor(controlPoints: RelationshipControlPoints, controlPointIndex: number) { constructor(controlPoints: RelationshipControlPoints, ctrIndex: PivotType) {
super(); super();
this._ctrPointPosition = controlPoints.getControlPointPosition(controlPointIndex); // New control points ...
this._controlPointIndex = controlPointIndex;
this._controlPoints = controlPoints; this._controlPoints = controlPoints;
this._ctrIndex = ctrIndex;
this._newCtrPoint = controlPoints.getControlPointPosition(ctrIndex);
const relLine = controlPoints.getRelationship().getLine(); // Backup previous control points ...
this._endPosition = controlPointIndex === 0 ? relLine.getFrom() : relLine.getTo(); const relationship = controlPoints.getRelationship();
const model = relationship.getModel();
this._oldCtrPoint =
PivotType.Start === ctrIndex ? model.getSrcCtrlPoint() : model.getDestCtrlPoint();
// New relationship ...
this._newCtrPoint = controlPoints.getControlPointPosition(ctrIndex);
} }
execute() { execute() {
const relationship = this._controlPoints.getRelationship(); const relationship = this._controlPoints.getRelationship();
const model = relationship.getModel(); const model = relationship.getModel();
switch (this._controlPointIndex) { switch (this._ctrIndex) {
case 0: case PivotType.Start:
model.setSrcCtrlPoint(this._ctrPointPosition); model.setSrcCtrlPoint(this._newCtrPoint);
relationship.setIsSrcControlPointCustom(true); relationship.setIsSrcControlPointCustom(true);
relationship.setSrcControlPoint(this._newCtrPoint);
relationship.setFrom(this._endPosition.x, this._endPosition.y);
relationship.setSrcControlPoint(this._ctrPointPosition);
break; break;
case 1: case PivotType.End:
model.setDestCtrlPoint(this._ctrPointPosition); model.setDestCtrlPoint(this._newCtrPoint);
relationship.setIsDestControlPointCustom(true); relationship.setIsDestControlPointCustom(true);
relationship.setDestControlPoint(this._newCtrPoint);
relationship.setTo(this._endPosition.x, this._endPosition.y);
relationship.setDestControlPoint(this._ctrPointPosition);
break; break;
default: default:
throw new Error('Illegal state exception'); throw new Error('Illegal state exception');
} }
if (relationship.isOnFocus()) { relationship.redraw();
relationship.refreshShape();
}
// this.relationship.getLine().updateLine(this._point);
} }
undoExecute() { undoExecute() {
// const line = this._line; const relationship = this._controlPoints.getRelationship();
// const model = line.getModel(); const model = relationship.getModel();
// switch (this._controlPointIndex) {
// case 0: const isCustom = this._oldCtrPoint != null;
// if ($defined(this._oldControlPoint)) { relationship.setIsDestControlPointCustom(isCustom);
// line.setFrom(this._oldRelEndpoint.x, this._oldRelEndpoint.y);
// model.setSrcCtrlPoint({ ...this._oldControlPoint }); switch (this._ctrIndex) {
// line.setSrcControlPoint({ ...this._oldControlPoint }); case PivotType.Start:
// line.setIsSrcControlPointCustom(this._isControlPointDefined); model.setSrcCtrlPoint(this._oldCtrPoint);
// } relationship.setSrcControlPoint(this._oldCtrPoint);
// break; break;
// case 1: case PivotType.End:
// if ($defined(this._oldControlPoint)) { model.setDestCtrlPoint(this._oldCtrPoint);
// line.setTo(this._oldRelEndpoint.x, this._oldRelEndpoint.y); relationship.setDestControlPoint(this._oldCtrPoint);
// model.setDestCtrlPoint({ ...this._oldControlPoint }); break;
// line.setDestControlPoint({ ...this._oldControlPoint }); default:
// line.setIsDestControlPointCustom(this._isControlPointDefined); throw new Error('Illegal state exception');
// } }
// break;
// default: console.log('undo ...');
// break; relationship.redraw();
// }
// // this._line.getLine().updateLine(this._point);
// // if (this._line.isOnFocus()) {
// // this._ctrlPointControler.setRelationshipLine(line);
// // line._refreshShape();
// // }
} }
} }

View File

@ -91,7 +91,7 @@ class MDExporter extends Exporter {
}); });
result = `${result}\n`; result = `${result}\n`;
if (node.getChildren().filter((n) => n.getText() !== undefined).length > 0) { if (node.getChildren().filter((n) => n.getText() !== null).length > 0) {
result += this.traverseBranch(`${prefix}\t`, node.getChildren()); result += this.traverseBranch(`${prefix}\t`, node.getChildren());
} }
}); });

View File

@ -32,18 +32,16 @@ const Shape = {
$assert(rectSize, 'rectSize can not be null'); $assert(rectSize, 'rectSize can not be null');
$assert($defined(isAtRight), 'isRight can not be null'); $assert($defined(isAtRight), 'isRight can not be null');
// Node is placed at the right ?
const result = new Point();
// This is used fix a minor difference ...z // This is used fix a minor difference ...z
const correctionHardcode = 2; const correctionHardcode = 2;
let result;
if (isAtRight) { if (isAtRight) {
result.setValue( result = new Point(
rectCenterPoint.x - rectSize.width / 2 + correctionHardcode, rectCenterPoint.x - rectSize.width / 2 + correctionHardcode,
rectCenterPoint.y, rectCenterPoint.y,
); );
} else { } else {
result.setValue( result = new Point(
parseFloat(rectCenterPoint.x) + rectSize.width / 2 - correctionHardcode, parseFloat(rectCenterPoint.x) + rectSize.width / 2 - correctionHardcode,
rectCenterPoint.y, rectCenterPoint.y,
); );

View File

@ -15,6 +15,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { $assert } from '@wisemapping/core-js';
class Point { class Point {
/** /**
@ -23,15 +24,9 @@ class Point {
* @param {Number} y coordinate * @param {Number} y coordinate
*/ */
constructor(x, y) { constructor(x, y) {
this.x = x; $assert(typeof x === 'number', `x is not a number: ${x}`);
this.y = y; $assert(typeof y === 'number', `x is not a number: ${y}`);
}
/**
* @param {Number} x coordinate
* @param {Number} y coordinate
*/
setValue(x, y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
@ -47,7 +42,7 @@ class Point {
Point.fromString = function pointFromString(point) { Point.fromString = function pointFromString(point) {
const values = point.split(','); const values = point.split(',');
return new Point(values[0], values[1]); return new Point(Number.parseInt(values[0], 10), Number.parseInt(values[1], 10));
}; };
export default Point; export default Point;

View File

@ -25,13 +25,10 @@ class ArrowPeer extends ElementPeer {
const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'path'); const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'path');
super(svgElement); super(svgElement);
this._style = {}; this._style = {};
this._controlPoint = new Point();
this._fromPoint = new Point();
} }
setFrom(x, y) { setFrom(x, y) {
this._fromPoint.x = x; this._fromPoint = new Point(x, y);
this._fromPoint.y = y;
this._redraw(); this._redraw();
} }
@ -71,12 +68,7 @@ class ArrowPeer extends ElementPeer {
let y; let y;
let xp; let xp;
let yp; let yp;
if ( if (this._fromPoint && this._controlPoint) {
$defined(this._fromPoint.x) &&
$defined(this._fromPoint.y) &&
$defined(this._controlPoint.x) &&
$defined(this._controlPoint.y)
) {
if (this._controlPoint.y === 0) this._controlPoint.y = 1; if (this._controlPoint.y === 0) this._controlPoint.y = 1;
const y0 = this._controlPoint.y; const y0 = this._controlPoint.y;
@ -100,8 +92,7 @@ class ArrowPeer extends ElementPeer {
const path = const path =
`M${this._fromPoint.x},${this._fromPoint.y} ` + `M${this._fromPoint.x},${this._fromPoint.y} ` +
`L${x + this._fromPoint.x},${y + this._fromPoint.y} M${this._fromPoint.x},${ `L${x + this._fromPoint.x},${y + this._fromPoint.y} M${this._fromPoint.x},${this._fromPoint.y
this._fromPoint.y
} ` + } ` +
`L${xp + this._fromPoint.x},${yp + this._fromPoint.y}`; `L${xp + this._fromPoint.x},${yp + this._fromPoint.y}`;
this._native.setAttribute('d', path); this._native.setAttribute('d', path);

View File

@ -27,8 +27,8 @@ class CurvedLinePeer extends ElementPeer {
this._updateStyle(); this._updateStyle();
this._customControlPoint_1 = false; this._customControlPoint_1 = false;
this._customControlPoint_2 = false; this._customControlPoint_2 = false;
this._control1 = new Point(); this._control1 = new Point(0, 0);
this._control2 = new Point(); this._control2 = new Point(0, 0);
this._lineStyle = true; this._lineStyle = true;
} }
@ -78,7 +78,7 @@ class CurvedLinePeer extends ElementPeer {
const change = this._x1 !== Number.parseFloat(x1, 10) || this._y1 !== Number.parseFloat(y1, 10); const change = this._x1 !== Number.parseFloat(x1, 10) || this._y1 !== Number.parseFloat(y1, 10);
this._x1 = Number.parseFloat(x1, 10); this._x1 = Number.parseFloat(x1, 10);
this._y1 = Number.parseFloat(y1, 10); this._y1 = Number.parseFloat(y1, 10);
if (change) this._updatePath(); if (change) { this._updatePath(); }
} }
setTo(x2, y2) { setTo(x2, y2) {
@ -149,16 +149,16 @@ class CurvedLinePeer extends ElementPeer {
if ($defined(this._x1) && $defined(this._y1) && $defined(this._x2) && $defined(this._y2)) { if ($defined(this._x1) && $defined(this._y1) && $defined(this._x2) && $defined(this._y2)) {
this._calculateAutoControlPoints(avoidControlPointFix); this._calculateAutoControlPoints(avoidControlPointFix);
const path = `M${this._x1.toFixed(2)},${this._y1.toFixed(2)} C${( const path = `M${this._x1.toFixed(2)},${this._y1.toFixed()} C${(
this._control1.x + this._x1 this._control1.x + this._x1
).toFixed(2)},${this._control1.y + this._y1} ${(this._control2.x + this._x2).toFixed(2)},${( ).toFixed(2)},${this._control1.y + this._y1} ${(this._control2.x + this._x2).toFixed()},${(
this._control2.y + this._y2 this._control2.y + this._y2
).toFixed(2)} ${this._x2.toFixed(2)},${this._y2.toFixed(2)}${this._lineStyle ).toFixed(2)} ${this._x2.toFixed(2)},${this._y2.toFixed()}${this._lineStyle
? ` ${(this._control2.x + this._x2).toFixed(2)},${( ? ` ${(this._control2.x + this._x2).toFixed()},${(
this._control2.y + this._control2.y +
this._y2 + this._y2 +
3 3
).toFixed(2)} ${(this._control1.x + this._x1).toFixed(2)},${( ).toFixed(2)} ${(this._control1.x + this._x1).toFixed()},${(
this._control1.y + this._control1.y +
this._y1 + this._y1 +
5 5