bugfix for geometry properties not being modified in e.g. translate()

development
mcyph 2021-03-23 11:13:09 +11:00
parent 978b0eb111
commit ff2f1c49ce
6 changed files with 119 additions and 72 deletions

View File

@ -6,6 +6,7 @@
import mxPoint from '../util/mxPoint'; import mxPoint from '../util/mxPoint';
import mxRectangle from '../util/mxRectangle'; import mxRectangle from '../util/mxRectangle';
import mxUtils from '../util/mxUtils';
class mxGeometry extends mxRectangle { class mxGeometry extends mxRectangle {
/** /**
@ -162,7 +163,7 @@ class mxGeometry extends mxRectangle {
* calling this method and setting the geometry of the cell using * calling this method and setting the geometry of the cell using
* <mxGraphModel.setGeometry>. * <mxGraphModel.setGeometry>.
*/ */
swap = () => { swap() {
if (this.alternateBounds != null) { if (this.alternateBounds != null) {
const old = new mxRectangle(this.x, this.y, this.width, this.height); const old = new mxRectangle(this.x, this.y, this.width, this.height);
@ -186,7 +187,7 @@ class mxGeometry extends mxRectangle {
* isSource - Boolean that specifies if the source or target point * isSource - Boolean that specifies if the source or target point
* should be returned. * should be returned.
*/ */
getTerminalPoint = isSource => { getTerminalPoint(isSource) {
return isSource ? this.sourcePoint : this.targetPoint; return isSource ? this.sourcePoint : this.targetPoint;
}; };
@ -202,7 +203,7 @@ class mxGeometry extends mxRectangle {
* isSource - Boolean that specifies if the source or target point * isSource - Boolean that specifies if the source or target point
* should be set. * should be set.
*/ */
setTerminalPoint = (point, isSource) => { setTerminalPoint(point, isSource) {
if (isSource) { if (isSource) {
this.sourcePoint = point; this.sourcePoint = point;
} else { } else {
@ -225,7 +226,7 @@ class mxGeometry extends mxRectangle {
* angle - Number that specifies the rotation angle in degrees. * angle - Number that specifies the rotation angle in degrees.
* cx - <mxPoint> that specifies the center of the rotation. * cx - <mxPoint> that specifies the center of the rotation.
*/ */
rotate = (angle, cx) => { rotate(angle, cx) {
const rad = mxUtils.toRadians(angle); const rad = mxUtils.toRadians(angle);
const cos = Math.cos(rad); const cos = Math.cos(rad);
const sin = Math.sin(rad); const sin = Math.sin(rad);
@ -265,6 +266,30 @@ class mxGeometry extends mxRectangle {
} }
}; };
get width() {
return this._width || 0;
}
set width(width) {
width = parseFloat(width);
if (Number.isNaN(width)) {
throw new Error('Invalid width supplied');
}
this._width = width;
}
get height() {
return this._height || 0;
}
set height(height) {
height = parseFloat(height);
if (Number.isNaN(height)) {
throw new Error('Invalid height supplied');
}
this._height = height;
}
/** /**
* Function: translate * Function: translate
* *
@ -279,34 +304,34 @@ class mxGeometry extends mxRectangle {
* dx - Number that specifies the x-coordinate of the translation. * dx - Number that specifies the x-coordinate of the translation.
* dy - Number that specifies the y-coordinate of the translation. * dy - Number that specifies the y-coordinate of the translation.
*/ */
translate = (dx, dy) => { translate(dx, dy) {
dx = parseFloat(dx); dx = parseFloat(dx);
dy = parseFloat(dy); dy = parseFloat(dy);
// Translates the geometry // Translates the geometry
if (!this.relative) { if (!this.relative) {
this.x = parseFloat(this.x) + dx; this.x = this.x + dx;
this.y = parseFloat(this.y) + dy; this.y = this.y + dy;
} }
// Translates the source point // Translates the source point
if (this.sourcePoint != null) { if (this.sourcePoint != null) {
this.sourcePoint.x = parseFloat(this.sourcePoint.x) + dx; this.sourcePoint.x = this.sourcePoint.x + dx;
this.sourcePoint.y = parseFloat(this.sourcePoint.y) + dy; this.sourcePoint.y = this.sourcePoint.y + dy;
} }
// Translates the target point // Translates the target point
if (this.targetPoint != null) { if (this.targetPoint != null) {
this.targetPoint.x = parseFloat(this.targetPoint.x) + dx; this.targetPoint.x = this.targetPoint.x + dx;
this.targetPoint.y = parseFloat(this.targetPoint.y) + dy; this.targetPoint.y = this.targetPoint.y + dy;
} }
// Translate the control points // Translate the control points
if (this.TRANSLATE_CONTROL_POINTS && this.points != null) { if (this.TRANSLATE_CONTROL_POINTS && this.points != null) {
for (let i = 0; i < this.points.length; i += 1) { for (let i = 0; i < this.points.length; i += 1) {
if (this.points[i] != null) { if (this.points[i] != null) {
this.points[i].x = parseFloat(this.points[i].x) + dx; this.points[i].x = this.points[i].x + dx;
this.points[i].y = parseFloat(this.points[i].y) + dy; this.points[i].y = this.points[i].y + dy;
} }
} }
} }
@ -327,43 +352,43 @@ class mxGeometry extends mxRectangle {
* sy - Number that specifies the vertical scale factor. * sy - Number that specifies the vertical scale factor.
* fixedAspect - Optional boolean to keep the aspect ratio fixed. * fixedAspect - Optional boolean to keep the aspect ratio fixed.
*/ */
scale = (sx, sy, fixedAspect) => { scale(sx, sy, fixedAspect) {
sx = parseFloat(sx); sx = parseFloat(sx);
sy = parseFloat(sy); sy = parseFloat(sy);
// Translates the source point // Translates the source point
if (this.sourcePoint != null) { if (this.sourcePoint != null) {
this.sourcePoint.x = parseFloat(this.sourcePoint.x) * sx; this.sourcePoint.x = this.sourcePoint.x * sx;
this.sourcePoint.y = parseFloat(this.sourcePoint.y) * sy; this.sourcePoint.y = this.sourcePoint.y * sy;
} }
// Translates the target point // Translates the target point
if (this.targetPoint != null) { if (this.targetPoint != null) {
this.targetPoint.x = parseFloat(this.targetPoint.x) * sx; this.targetPoint.x = this.targetPoint.x * sx;
this.targetPoint.y = parseFloat(this.targetPoint.y) * sy; this.targetPoint.y = this.targetPoint.y * sy;
} }
// Translate the control points // Translate the control points
if (this.points != null) { if (this.points != null) {
for (let i = 0; i < this.points.length; i += 1) { for (let i = 0; i < this.points.length; i += 1) {
if (this.points[i] != null) { if (this.points[i] != null) {
this.points[i].x = parseFloat(this.points[i].x) * sx; this.points[i].x = this.points[i].x * sx;
this.points[i].y = parseFloat(this.points[i].y) * sy; this.points[i].y = this.points[i].y * sy;
} }
} }
} }
// Translates the geometry // Translates the geometry
if (!this.relative) { if (!this.relative) {
this.x = parseFloat(this.x) * sx; this.x = this.x * sx;
this.y = parseFloat(this.y) * sy; this.y = this.y * sy;
if (fixedAspect) { if (fixedAspect) {
sy = sx = Math.min(sx, sy); sy = sx = Math.min(sx, sy);
} }
this.width = parseFloat(this.width) * sx; this.width = this.width * sx;
this.height = parseFloat(this.height) * sy; this.height = this.height * sy;
} }
}; };
@ -372,7 +397,7 @@ class mxGeometry extends mxRectangle {
* *
* Returns true if the given object equals this geometry. * Returns true if the given object equals this geometry.
*/ */
equals = obj => { equals(obj) {
return ( return (
super.equals(obj) && super.equals(obj) &&
this.relative === obj.relative && this.relative === obj.relative &&

View File

@ -159,8 +159,8 @@ class mxArrowConnector extends mxShape {
while ( while (
i0 < pts.length - 1 && i0 < pts.length - 1 &&
pts[i0].x == pts[0].x && pts[i0].x === pts[0].x &&
pts[i0].y == pts[0].y pts[i0].y === pts[0].y
) { ) {
i0++; i0++;
} }
@ -169,7 +169,7 @@ class mxArrowConnector extends mxShape {
const dy = pts[i0].y - pts[0].y; const dy = pts[i0].y - pts[0].y;
const dist = Math.sqrt(dx * dx + dy * dy); const dist = Math.sqrt(dx * dx + dy * dy);
if (dist == 0) { if (dist === 0) {
return; return;
} }
@ -249,7 +249,7 @@ class mxArrowConnector extends mxShape {
dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
if (dist1 != 0) { if (dist1 !== 0) {
nx1 = dx1 / dist1; nx1 = dx1 / dist1;
ny1 = dy1 / dist1; ny1 = dy1 / dist1;
@ -262,7 +262,7 @@ class mxArrowConnector extends mxShape {
const dist2 = Math.sqrt(nx2 * nx2 + ny2 * ny2); const dist2 = Math.sqrt(nx2 * nx2 + ny2 * ny2);
if (dist2 != 0) { if (dist2 !== 0) {
nx2 /= dist2; nx2 /= dist2;
ny2 /= dist2; ny2 /= dist2;
@ -272,7 +272,7 @@ class mxArrowConnector extends mxShape {
Math.min(this.strokewidth / 200 + 0.04, 0.35) Math.min(this.strokewidth / 200 + 0.04, 0.35)
); );
const angleFactor = const angleFactor =
pos != 0 && isRounded pos !== 0 && isRounded
? Math.max(0.1, strokeWidthFactor) ? Math.max(0.1, strokeWidthFactor)
: Math.max(tmp, 0.06); : Math.max(tmp, 0.06);
@ -281,7 +281,7 @@ class mxArrowConnector extends mxShape {
const inX = pts[i + 1].x - (ny2 * edgeWidth) / 2 / angleFactor; const inX = pts[i + 1].x - (ny2 * edgeWidth) / 2 / angleFactor;
const inY = pts[i + 1].y + (nx2 * edgeWidth) / 2 / angleFactor; const inY = pts[i + 1].y + (nx2 * edgeWidth) / 2 / angleFactor;
if (pos == 0 || !isRounded) { if (pos === 0 || !isRounded) {
// If the two segments are aligned, or if we're not drawing curved sections between segments // If the two segments are aligned, or if we're not drawing curved sections between segments
// just draw straight to the intersection point // just draw straight to the intersection point
c.lineTo(outX, outY); c.lineTo(outX, outY);
@ -291,7 +291,7 @@ class mxArrowConnector extends mxShape {
c.lineTo(x, y); c.lineTo(x, y);
}); });
})(inX, inY); })(inX, inY);
} else if (pos == -1) { } else if (pos === -1) {
const c1x = inX + ny * edgeWidth; const c1x = inX + ny * edgeWidth;
const c1y = inY - nx * edgeWidth; const c1y = inY - nx * edgeWidth;
const c2x = inX + ny1 * edgeWidth; const c2x = inX + ny1 * edgeWidth;
@ -526,7 +526,7 @@ class mxArrowConnector extends mxShape {
this.style, this.style,
mxConstants.STYLE_STARTARROW, mxConstants.STYLE_STARTARROW,
mxConstants.NONE mxConstants.NONE
) != mxConstants.NONE ) !== mxConstants.NONE
); );
}; };
@ -541,7 +541,7 @@ class mxArrowConnector extends mxShape {
this.style, this.style,
mxConstants.STYLE_ENDARROW, mxConstants.STYLE_ENDARROW,
mxConstants.NONE mxConstants.NONE
) != mxConstants.NONE ) !== mxConstants.NONE
); );
}; };
} }

View File

@ -10,6 +10,7 @@ import mxUtils from '../util/mxUtils';
import mxPoint from '../util/mxPoint'; import mxPoint from '../util/mxPoint';
import mxSvgCanvas2D from '../util/mxSvgCanvas2D'; import mxSvgCanvas2D from '../util/mxSvgCanvas2D';
import mxShape from './mxShape'; import mxShape from './mxShape';
import mxRectangle from "../util/mxRectangle";
class mxText extends mxShape { class mxText extends mxShape {
/** /**

View File

@ -39,6 +39,30 @@ class mxPoint {
} }
} }
get x() {
return this._x || 0;
}
set x(x) {
x = parseFloat(x);
if (Number.isNaN(x)) {
throw new Error('Invalid x supplied');
}
this._x = x;
}
get y() {
return this._y || 0;
}
set y(y) {
y = parseFloat(y);
if (Number.isNaN(y)) {
throw new Error('Invalid y supplied');
}
this._y = y;
}
/** /**
* Function: equals * Function: equals
* *

View File

@ -10,6 +10,15 @@ import mxConstants from './mxConstants';
import mxObjectIdentity from './mxObjectIdentity'; import mxObjectIdentity from './mxObjectIdentity';
import mxPoint from './mxPoint'; import mxPoint from './mxPoint';
import mxDictionary from './mxDictionary'; import mxDictionary from './mxDictionary';
import mxCellPath from '../model/mxCellPath';
import mxRectangle from './mxRectangle';
import mxTemporaryCellStates from '../view/mxTemporaryCellStates';
import mxCodec from '../io/mxCodec';
import mxWindow from './mxWindow';
import mxResources from './mxResources';
import mxEvent from './mxEvent';
import mxDragSource from './mxDragSource';
import mxLog from './mxLog';
const mxUtils = { const mxUtils = {
/** /**
@ -216,7 +225,6 @@ const mxUtils = {
findNode: (node, attr, value) => { findNode: (node, attr, value) => {
if (node.nodeType === mxConstants.NODETYPE_ELEMENT) { if (node.nodeType === mxConstants.NODETYPE_ELEMENT) {
const tmp = node.getAttribute(attr); const tmp = node.getAttribute(attr);
if (tmp != null && tmp == value) { if (tmp != null && tmp == value) {
return node; return node;
} }
@ -226,14 +234,11 @@ const mxUtils = {
while (node != null) { while (node != null) {
const result = mxUtils.findNode(node, attr, value); const result = mxUtils.findNode(node, attr, value);
if (result != null) { if (result != null) {
return result; return result;
} }
node = node.nextSibling; node = node.nextSibling;
} }
return null; return null;
}, },

View File

@ -6047,6 +6047,8 @@ class mxGraph extends mxEventSource {
dy = dy != null ? dy : 0; dy = dy != null ? dy : 0;
clone = clone != null ? clone : false; clone = clone != null ? clone : false;
//alert(`moveCells: ${cells} ${dx} ${dy} ${clone} ${target}`)
if (cells != null && (dx !== 0 || dy !== 0 || clone || target != null)) { if (cells != null && (dx !== 0 || dy !== 0 || clone || target != null)) {
// Removes descendants with ancestors in cells to avoid multiple moving // Removes descendants with ancestors in cells to avoid multiple moving
cells = this.model.getTopmostCells(cells); cells = this.model.getTopmostCells(cells);
@ -6149,18 +6151,12 @@ class mxGraph extends mxEventSource {
this.fireEvent( this.fireEvent(
new mxEventObject( new mxEventObject(
mxEvent.MOVE_CELLS, mxEvent.MOVE_CELLS,
'cells', 'cells', cells,
cells, 'dx', dx,
'dx', 'dy', dy,
dx, 'clone', clone,
'dy', 'target', target,
dy, 'event', evt
'clone',
clone,
'target',
target,
'event',
evt
) )
); );
} finally { } finally {
@ -6205,14 +6201,10 @@ class mxGraph extends mxEventSource {
this.fireEvent( this.fireEvent(
new mxEventObject( new mxEventObject(
mxEvent.CELLS_MOVED, mxEvent.CELLS_MOVED,
'cells', 'cells', cells,
cells, 'dx', dx,
'dx', 'dy', dy,
dx, 'disconnect', disconnect
'dy',
dy,
'disconnect',
disconnect
) )
); );
} finally { } finally {
@ -6228,24 +6220,24 @@ class mxGraph extends mxEventSource {
* translated geometry in the model as an atomic change. * translated geometry in the model as an atomic change.
*/ */
translateCell = (cell, dx, dy) => { translateCell = (cell, dx, dy) => {
let geo = this.model.getGeometry(cell); let geometry = this.model.getGeometry(cell);
if (geo != null) { if (geometry != null) {
dx = parseFloat(dx); dx = parseFloat(dx);
dy = parseFloat(dy); dy = parseFloat(dy);
geo = geo.clone(); geometry = geometry.clone();
geo.translate(dx, dy); geometry.translate(dx, dy);
if ( if (
!geo.relative && !geometry.relative &&
this.model.isVertex(cell) && this.model.isVertex(cell) &&
!this.isAllowNegativeCoordinates() !this.isAllowNegativeCoordinates()
) { ) {
geo.x = Math.max(0, parseFloat(geo.x)); geometry.x = Math.max(0, geometry.x);
geo.y = Math.max(0, parseFloat(geo.y)); geometry.y = Math.max(0, geometry.y);
} }
if (geo.relative && !this.model.isEdge(cell)) { if (geometry.relative && !this.model.isEdge(cell)) {
const parent = this.model.getParent(cell); const parent = this.model.getParent(cell);
let angle = 0; let angle = 0;
@ -6268,15 +6260,15 @@ class mxGraph extends mxEventSource {
dy = pt.y; dy = pt.y;
} }
if (geo.offset == null) { if (geometry.offset == null) {
geo.offset = new mxPoint(dx, dy); geometry.offset = new mxPoint(dx, dy);
} else { } else {
geo.offset.x = parseFloat(geo.offset.x) + dx; geometry.offset.x = parseFloat(geometry.offset.x) + dx;
geo.offset.y = parseFloat(geo.offset.y) + dy; geometry.offset.y = parseFloat(geometry.offset.y) + dy;
} }
} }
this.model.setGeometry(cell, geo); this.model.setGeometry(cell, geometry);
} }
}; };