From b8c741595307ceb1e4d2b6b8dff5c6c5dc575916 Mon Sep 17 00:00:00 2001
From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com>
Date: Sat, 3 May 2025 10:43:41 +0200
Subject: [PATCH 1/2] refactor!: remove the ALIGN and RENDERING_HINT enums
BREAKING CHANGES:
- The `constants.ALIGN` enum has been removed, use `AlignValue` and `VAlignValue` types instead
- The `constants.RENDERING_HINT` enum has been removed without replacement because it wasn't used
---
CHANGELOG.md | 2 +
packages/core/src/editor/Editor.ts | 26 ++++-----
.../core/src/serialization/ObjectCodec.ts | 8 +--
packages/core/src/util/Constants.ts | 21 -------
packages/core/src/util/styleUtils.ts | 28 +++++-----
packages/core/src/view/GraphView.ts | 22 ++++----
packages/core/src/view/canvas/SvgCanvas2D.ts | 55 ++++++++-----------
packages/core/src/view/cell/CellRenderer.ts | 32 +++++------
packages/core/src/view/cell/CellState.ts | 4 +-
.../core/src/view/geometry/node/LabelShape.ts | 28 +++++-----
.../core/src/view/geometry/node/TextShape.ts | 34 +++++-------
.../src/view/geometry/stencil/StencilShape.ts | 5 +-
packages/core/src/view/mixins/CellsMixin.ts | 47 +++++++---------
.../core/src/view/mixins/CellsMixin.type.ts | 16 +++++-
.../src/view/plugins/CellEditorHandler.ts | 43 +++++----------
packages/core/src/view/style/Stylesheet.ts | 10 ++--
packages/html/stories/OrgChart.stories.js | 11 ++--
packages/html/stories/Scrollbars.stories.js | 2 +-
packages/html/stories/SecondLabel.stories.js | 7 +--
19 files changed, 174 insertions(+), 227 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 258e664216..35f7be08fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,9 +11,11 @@ _**Note:** Yet to be released breaking changes appear here._
**Breaking Changes**:
- Some enums have been removed. Use the string counterparts from related types:
+ - `constants.ALIGN` --> `AlignValue` and `VAlignValue`
- `constants.ARROW` --> `ArrowValue`
- `constants.EDGESTYLE` --> `EdgeStyleValue`
- `constants.PERIMETER` --> `PerimeterValue`
+ - `constants.RENDERING_HINT`: no replacement as it wasn't used
- `constants.SHAPE` --> `ShapeValue`
## 0.19.0
diff --git a/packages/core/src/editor/Editor.ts b/packages/core/src/editor/Editor.ts
index 4e23ce7096..36ff2e31b9 100644
--- a/packages/core/src/editor/Editor.ts
+++ b/packages/core/src/editor/Editor.ts
@@ -33,7 +33,7 @@ import MaxForm from '../gui/MaxForm';
import Outline from '../view/other/Outline';
import Cell from '../view/cell/Cell';
import Geometry from '../view/geometry/Geometry';
-import { ALIGN, FONT } from '../util/Constants';
+import { FONT } from '../util/Constants';
import type { AbstractGraph } from '../view/AbstractGraph';
import { Graph } from '../view/Graph';
import SwimlaneManager from '../view/layout/SwimlaneManager';
@@ -1158,71 +1158,71 @@ export class Editor extends EventSource {
this.addAction('alignCellsLeft', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.LEFT);
+ editor.graph.alignCells('left');
}
});
this.addAction('alignCellsCenter', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.CENTER);
+ editor.graph.alignCells('center');
}
});
this.addAction('alignCellsRight', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.RIGHT);
+ editor.graph.alignCells('right');
}
});
this.addAction('alignCellsTop', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.TOP);
+ editor.graph.alignCells('top');
}
});
this.addAction('alignCellsMiddle', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.MIDDLE);
+ editor.graph.alignCells('middle');
}
});
this.addAction('alignCellsBottom', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.alignCells(ALIGN.BOTTOM);
+ editor.graph.alignCells('bottom');
}
});
this.addAction('alignFontLeft', (editor: Editor) => {
- editor.graph.setCellStyles('align', ALIGN.LEFT);
+ editor.graph.setCellStyles('align', 'left');
});
this.addAction('alignFontCenter', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.setCellStyles('align', ALIGN.CENTER);
+ editor.graph.setCellStyles('align', 'center');
}
});
this.addAction('alignFontRight', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.setCellStyles('align', ALIGN.RIGHT);
+ editor.graph.setCellStyles('align', 'right');
}
});
this.addAction('alignFontTop', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.setCellStyles('verticalAlign', ALIGN.TOP);
+ editor.graph.setCellStyles('verticalAlign', 'top');
}
});
this.addAction('alignFontMiddle', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.setCellStyles('verticalAlign', ALIGN.MIDDLE);
+ editor.graph.setCellStyles('verticalAlign', 'middle');
}
});
this.addAction('alignFontBottom', (editor: Editor) => {
if (editor.graph.isEnabled()) {
- editor.graph.setCellStyles('verticalAlign', ALIGN.BOTTOM);
+ editor.graph.setCellStyles('verticalAlign', 'bottom');
}
});
diff --git a/packages/core/src/serialization/ObjectCodec.ts b/packages/core/src/serialization/ObjectCodec.ts
index f3f04900f8..d8b1f7a7ab 100644
--- a/packages/core/src/serialization/ObjectCodec.ts
+++ b/packages/core/src/serialization/ObjectCodec.ts
@@ -174,16 +174,16 @@ import { doEval, isElement } from '../internal/utils';
* For decoding JavaScript expressions, the add-node may be used with a text
* content that contains the JavaScript expression. For example, the following
* creates a field called foo in the enclosing object and assigns it the value
- * of {@link ALIGN.LEFT}.
+ * of `MyConstant.PROP`.
*
* ```javascript
*
* ```
*
- * The resulting object has a field called foo with the value "left". Its XML
- * representation looks as follows.
+ * The resulting object has a field called foo with the value "myValue" (assuming that `MyConstant.PROP=myValue`).
+ * Its XML representation looks as follows.
*
* ```javascript
*
diff --git a/packages/core/src/util/Constants.ts b/packages/core/src/util/Constants.ts
index 40cbd47f88..5d3abd18a6 100644
--- a/packages/core/src/util/Constants.ts
+++ b/packages/core/src/util/Constants.ts
@@ -41,12 +41,6 @@ export const MIN_HOTSPOT_SIZE = 8;
*/
export const MAX_HOTSPOT_SIZE = 0;
-export enum RENDERING_HINT {
- EXACT = 'exact',
- FASTER = 'faster',
- FASTEST = 'fastest',
-}
-
export enum DIALECT {
/** the SVG display dialect name. */
SVG = 'svg',
@@ -442,21 +436,6 @@ export enum FONT {
STRIKETHROUGH = 8,
}
-export enum ALIGN {
- /** left horizontal alignment. */
- LEFT = 'left',
- /** center horizontal alignment. */
- CENTER = 'center',
- /** right horizontal alignment. */
- RIGHT = 'right',
- /** top vertical alignment. */
- TOP = 'top',
- /** middle vertical alignment. */
- MIDDLE = 'middle',
- /** bottom vertical alignment. */
- BOTTOM = 'bottom',
-}
-
export enum DIRECTION {
NORTH = 'north',
SOUTH = 'south',
diff --git a/packages/core/src/util/styleUtils.ts b/packages/core/src/util/styleUtils.ts
index ec44c0d5db..0890c94fd1 100644
--- a/packages/core/src/util/styleUtils.ts
+++ b/packages/core/src/util/styleUtils.ts
@@ -17,20 +17,20 @@ limitations under the License.
*/
import Client from '../Client';
-import {
- ALIGN,
- DEFAULT_FONTFAMILY,
- DEFAULT_FONTSIZE,
- FONT,
- LINE_HEIGHT,
-} from './Constants';
+import { DEFAULT_FONTFAMILY, DEFAULT_FONTSIZE, FONT, LINE_HEIGHT } from './Constants';
import Point from '../view/geometry/Point';
import Dictionary from './Dictionary';
import CellPath from '../view/cell/CellPath';
import Rectangle from '../view/geometry/Rectangle';
import Cell from '../view/cell/Cell';
import GraphDataModel from '../view/GraphDataModel';
-import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../types';
+import type {
+ AlignValue,
+ CellStateStyle,
+ CellStyle,
+ NumericCellStateStyleKeys,
+ VAlignValue,
+} from '../types';
import { matchBinaryMask } from '../internal/utils';
/**
@@ -519,23 +519,23 @@ export const sortCells = (cells: Cell[], ascending = true): Cell[] => {
* X is -0.5 for center, -1 for right and 0 for left alignment.
* Y is -0.5 for middle, -1 for bottom and 0 for top alignment.
*
- * Default values for missing arguments is top, left.
+ * Default values for missing arguments is center and middle.
*/
-export const getAlignmentAsPoint = (align: string, valign: string) => {
+export const getAlignmentAsPoint = (align: AlignValue, valign: VAlignValue) => {
let dx = -0.5;
let dy = -0.5;
// Horizontal alignment
- if (align === ALIGN.LEFT) {
+ if (align === 'left') {
dx = 0;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
dx = -1;
}
// Vertical alignment
- if (valign === ALIGN.TOP) {
+ if (valign === 'top') {
dy = 0;
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
dy = -1;
}
diff --git a/packages/core/src/view/GraphView.ts b/packages/core/src/view/GraphView.ts
index f937c57105..62e732867f 100644
--- a/packages/core/src/view/GraphView.ts
+++ b/packages/core/src/view/GraphView.ts
@@ -22,7 +22,7 @@ import Dictionary from '../util/Dictionary';
import EventSource from './event/EventSource';
import EventObject from './event/EventObject';
import RectangleShape from './geometry/node/RectangleShape';
-import { ALIGN, NS_SVG } from '../util/Constants';
+import { NS_SVG } from '../util/Constants';
import Client from '../Client';
import InternalEvent from './event/InternalEvent';
import { convertPoint, getCurrentStyle, getOffset } from '../util/styleUtils';
@@ -1013,9 +1013,9 @@ export class GraphView extends EventSource {
* @param state {@link CellState} whose absolute offset should be updated.
*/
updateVertexLabelOffset(state: CellState): void {
- const h = state.style.labelPosition ?? ALIGN.CENTER;
+ const h = state.style.labelPosition ?? 'center';
- if (h === ALIGN.LEFT) {
+ if (h === 'left') {
let lw = state.style.labelWidth ?? null;
if (lw != null) {
@@ -1026,20 +1026,20 @@ export class GraphView extends EventSource {
// @ts-ignore
state.absoluteOffset.x -= lw;
- } else if (h === ALIGN.RIGHT) {
+ } else if (h === 'right') {
// @ts-ignore
state.absoluteOffset.x += state.width;
- } else if (h === ALIGN.CENTER) {
+ } else if (h === 'center') {
const lw = state.style.labelWidth ?? null;
if (lw != null) {
// Aligns text block with given width inside the vertex width
- const align = state.style.align ?? ALIGN.CENTER;
+ const align = state.style.align ?? 'center';
let dx = 0;
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
dx = 0.5;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
dx = 1;
}
@@ -1050,12 +1050,12 @@ export class GraphView extends EventSource {
}
}
- const v = state.style.verticalLabelPosition ?? ALIGN.MIDDLE;
+ const v = state.style.verticalLabelPosition ?? 'middle';
- if (v === ALIGN.TOP) {
+ if (v === 'top') {
// @ts-ignore
state.absoluteOffset.y -= state.height;
- } else if (v === ALIGN.BOTTOM) {
+ } else if (v === 'bottom') {
// @ts-ignore
state.absoluteOffset.y += state.height;
}
diff --git a/packages/core/src/view/canvas/SvgCanvas2D.ts b/packages/core/src/view/canvas/SvgCanvas2D.ts
index cfc43d5e52..e7798b4b9e 100644
--- a/packages/core/src/view/canvas/SvgCanvas2D.ts
+++ b/packages/core/src/view/canvas/SvgCanvas2D.ts
@@ -22,7 +22,6 @@ import { getAlignmentAsPoint } from '../../util/styleUtils';
import Client from '../../Client';
import {
ABSOLUTE_LINE_HEIGHT,
- ALIGN,
DEFAULT_FONTFAMILY,
DEFAULT_FONTSIZE,
DIRECTION,
@@ -228,7 +227,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
refCount = 0;
/**
- * Correction factor for {@link mxConstants.LINE_HEIGHT} in HTML output.
+ * Correction factor for {@link LINE_HEIGHT} in HTML output.
* @default 1
*/
lineHeightCorrection = 1;
@@ -260,7 +259,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
w: number,
h: number,
align: AlignValue,
- valign: string,
+ valign: VAlignValue,
wrap: boolean,
overflow: string,
clip: boolean,
@@ -279,7 +278,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
) => void
) => {
let item = `box-sizing: border-box; font-size: 0; text-align: ${
- align === ALIGN.LEFT ? 'left' : align === ALIGN.RIGHT ? 'right' : 'center'
+ align === 'left' ? 'left' : align === 'right' ? 'right' : 'center'
}; `;
const pt = getAlignmentAsPoint(align, valign);
let ofl = 'overflow: hidden; ';
@@ -461,9 +460,8 @@ class SvgCanvas2D extends AbstractCanvas2D {
const s = this.state;
if (!isNullish(text) && s.fontSize > 0) {
- const dy = valign === ALIGN.TOP ? 1 : valign === ALIGN.BOTTOM ? 0 : 0.3;
- const anchor =
- align === ALIGN.RIGHT ? 'end' : align === ALIGN.LEFT ? 'start' : 'middle';
+ const dy = valign === 'top' ? 1 : valign === 'bottom' ? 0 : 0.3;
+ const anchor = align === 'right' ? 'end' : align === 'left' ? 'start' : 'middle';
const alt = this.createElement('text');
alt.setAttribute('x', String(Math.round(x + s.dx)));
@@ -1277,18 +1275,10 @@ class SvgCanvas2D extends AbstractCanvas2D {
this.state.fontBackgroundColor != null ? this.state.fontBackgroundColor : null,
this.state.fontBorderColor != null ? this.state.fontBorderColor : null,
`display: flex; align-items: unsafe ${
- valign === ALIGN.TOP
- ? 'flex-start'
- : valign === ALIGN.BOTTOM
- ? 'flex-end'
- : 'center'
+ valign === 'top' ? 'flex-start' : valign === 'bottom' ? 'flex-end' : 'center'
}; ` +
`justify-content: unsafe ${
- align === ALIGN.LEFT
- ? 'flex-start'
- : align === ALIGN.RIGHT
- ? 'flex-end'
- : 'center'
+ align === 'left' ? 'flex-start' : align === 'right' ? 'flex-end' : 'center'
}; `,
this.getTextCss(),
s,
@@ -1522,16 +1512,16 @@ class SvgCanvas2D extends AbstractCanvas2D {
let cx = x;
let cy = y;
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
cx -= w / 2;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
cx -= w;
}
if (overflow !== 'fill') {
- if (valign === ALIGN.MIDDLE) {
+ if (valign === 'middle') {
cy -= h / 2;
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
cy -= h;
}
}
@@ -1565,8 +1555,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
}
// Default is left
- const anchor =
- align === ALIGN.RIGHT ? 'end' : align === ALIGN.CENTER ? 'middle' : 'start';
+ const anchor = align === 'right' ? 'end' : align === 'center' ? 'middle' : 'start';
// Text-anchor start is default in SVG
if (anchor !== 'start') {
@@ -1591,7 +1580,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
let cy = y + size - 1;
- if (valign === ALIGN.MIDDLE) {
+ if (valign === 'middle') {
if (overflow === 'fill') {
cy -= h / 2;
} else {
@@ -1601,7 +1590,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
: textHeight) / 2;
cy -= dy;
}
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
if (overflow === 'fill') {
cy -= h;
} else {
@@ -1687,15 +1676,15 @@ class SvgCanvas2D extends AbstractCanvas2D {
let bbox = null;
if (overflow === 'fill' || overflow === 'width') {
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
x -= w / 2;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
x -= w;
}
- if (valign === ALIGN.MIDDLE) {
+ if (valign === 'middle') {
y -= h / 2;
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
y -= h;
}
@@ -1743,15 +1732,15 @@ class SvgCanvas2D extends AbstractCanvas2D {
const h = div.offsetHeight;
document.body.removeChild(div);
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
x -= w / 2;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
x -= w;
}
- if (valign === ALIGN.MIDDLE) {
+ if (valign === 'middle') {
y -= h / 2;
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
y -= h;
}
diff --git a/packages/core/src/view/cell/CellRenderer.ts b/packages/core/src/view/cell/CellRenderer.ts
index e863a2428b..b6774e4aef 100644
--- a/packages/core/src/view/cell/CellRenderer.ts
+++ b/packages/core/src/view/cell/CellRenderer.ts
@@ -21,7 +21,6 @@ import ConnectorShape from '../geometry/edge/ConnectorShape';
import ImageShape from '../geometry/node/ImageShape';
import TextShape from '../geometry/node/TextShape';
import {
- ALIGN,
DEFAULT_FONTFAMILY,
DEFAULT_FONTSIZE,
DEFAULT_FONTSTYLE,
@@ -357,7 +356,7 @@ class CellRenderer {
state.text = new this.defaultTextShape(
value,
new Rectangle(),
- state.style.align ?? ALIGN.CENTER,
+ state.style.align ?? 'center',
state.getVerticalAlign(),
state.style.fontColor,
state.style.fontFamily,
@@ -1030,10 +1029,10 @@ class CellRenderer {
// Shape can modify its label bounds
if (state.shape != null) {
- const hpos = state.style.labelPosition ?? ALIGN.CENTER;
- const vpos = state.style.verticalLabelPosition ?? ALIGN.MIDDLE;
+ const hpos = state.style.labelPosition ?? 'center';
+ const vpos = state.style.verticalLabelPosition ?? 'middle';
- if (hpos === ALIGN.CENTER && vpos === ALIGN.MIDDLE) {
+ if (hpos === 'center' && vpos === 'middle') {
bounds = state.shape.getLabelBounds(bounds);
}
}
@@ -1059,42 +1058,39 @@ class CellRenderer {
* @param bounds {@link Rectangle} the rectangle to be rotated.
*/
rotateLabelBounds(state: CellState, bounds: Rectangle): void {
- bounds.y -= state.text!.margin!.y * bounds.height;
- bounds.x -= state.text!.margin!.x * bounds.width;
+ const textShape = state.text!;
+ bounds.y -= textShape.margin!.y * bounds.height;
+ bounds.x -= textShape.margin!.x * bounds.width;
if (
!this.legacySpacing ||
(state.style.overflow !== 'fill' && state.style.overflow !== 'width')
) {
const s = state.view.scale;
- const spacing = state.text!.getSpacing();
+ const spacing = textShape.getSpacing();
bounds.x += spacing.x * s;
bounds.y += spacing.y * s;
- const hpos = state.style.labelPosition ?? ALIGN.CENTER;
- const vpos = state.style.verticalLabelPosition ?? ALIGN.MIDDLE;
+ const hpos = state.style.labelPosition ?? 'center';
+ const vpos = state.style.verticalLabelPosition ?? 'middle';
const lw = state.style.labelWidth ?? null;
bounds.width = Math.max(
0,
bounds.width -
- (hpos === ALIGN.CENTER && lw == null
- ? // @ts-ignore
- state.text.spacingLeft * s + state.text.spacingRight * s
+ (hpos === 'center' && lw == null
+ ? textShape.spacingLeft * s + textShape.spacingRight * s
: 0)
);
bounds.height = Math.max(
0,
bounds.height -
- (vpos === ALIGN.MIDDLE
- ? // @ts-ignore
- state.text.spacingTop * s + state.text.spacingBottom * s
- : 0)
+ (vpos === 'middle' ? textShape.spacingTop * s + textShape.spacingBottom * s : 0)
);
}
// @ts-ignore
- const theta = state.text.getTextRotation();
+ const theta = textShape.getTextRotation();
// Only needed if rotated around another center
if (
diff --git a/packages/core/src/view/cell/CellState.ts b/packages/core/src/view/cell/CellState.ts
index 2dc00caecb..9da5d749dd 100644
--- a/packages/core/src/view/cell/CellState.ts
+++ b/packages/core/src/view/cell/CellState.ts
@@ -23,7 +23,7 @@ import type GraphView from '../../view/GraphView';
import Shape from '../geometry/Shape';
import TextShape from '../geometry/node/TextShape';
import Dictionary from '../../util/Dictionary';
-import { ALIGN, NONE } from '../../util/Constants';
+import { NONE } from '../../util/Constants';
import { CellStateStyle } from '../../types';
import RectangleShape from '../geometry/node/RectangleShape';
import CellOverlay from './CellOverlay';
@@ -400,7 +400,7 @@ class CellState extends Rectangle {
* property of {@link style}.
*/
getVerticalAlign() {
- return this.style.verticalAlign ?? ALIGN.MIDDLE;
+ return this.style.verticalAlign ?? 'middle';
}
/**
diff --git a/packages/core/src/view/geometry/node/LabelShape.ts b/packages/core/src/view/geometry/node/LabelShape.ts
index 92d376e25f..466dc9b47c 100644
--- a/packages/core/src/view/geometry/node/LabelShape.ts
+++ b/packages/core/src/view/geometry/node/LabelShape.ts
@@ -17,7 +17,7 @@ limitations under the License.
*/
import Rectangle from '../Rectangle';
-import { ALIGN, DEFAULT_IMAGESIZE, NONE } from '../../../util/Constants';
+import { DEFAULT_IMAGESIZE, NONE } from '../../../util/Constants';
import RectangleShape from './RectangleShape';
import { ColorValue } from '../../../types';
import AbstractCanvas2D from '../../canvas/AbstractCanvas2D';
@@ -160,24 +160,24 @@ class LabelShape extends RectangleShape {
* @param {number} h
*/
getImageBounds(x: number, y: number, w: number, h: number) {
- const align = this.style?.imageAlign ?? ALIGN.LEFT;
- const valign = this.style?.verticalAlign ?? ALIGN.MIDDLE;
+ const align = this.style?.imageAlign ?? 'left';
+ const valign = this.style?.verticalAlign ?? 'middle';
const width = this.style?.imageWidth ?? DEFAULT_IMAGESIZE;
const height = this.style?.imageHeight ?? DEFAULT_IMAGESIZE;
const spacing = this.style?.spacing ?? this.spacing + 5;
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
x += (w - width) / 2;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
x += w - width - spacing;
} // default is left
else {
x += spacing;
}
- if (valign === ALIGN.TOP) {
+ if (valign === 'top') {
y += spacing;
- } else if (valign === ALIGN.BOTTOM) {
+ } else if (valign === 'bottom') {
y += h - height - spacing;
} // default is middle
else {
@@ -189,7 +189,7 @@ class LabelShape extends RectangleShape {
/**
* Generic background painting implementation.
- * @param {mxAbstractCanvas2D} c
+ * @param {AbstractCanvas2D} c
* @param {number} x
* @param {number} y
* @param {number} w
@@ -223,24 +223,24 @@ class LabelShape extends RectangleShape {
* @returns {Rectangle}
*/
getIndicatorBounds(x: number, y: number, w: number, h: number) {
- const align = this.style?.imageAlign ?? ALIGN.LEFT;
- const valign = this.style?.verticalAlign ?? ALIGN.MIDDLE;
+ const align = this.style?.imageAlign ?? 'left';
+ const valign = this.style?.verticalAlign ?? 'middle';
const width = this.style?.indicatorWidth ?? this.indicatorSize;
const height = this.style?.indicatorHeight ?? this.indicatorSize;
const spacing = this.spacing + 5;
- if (align === ALIGN.RIGHT) {
+ if (align === 'right') {
x += w - width - spacing;
- } else if (align === ALIGN.CENTER) {
+ } else if (align === 'center') {
x += (w - width) / 2;
} // default is left
else {
x += spacing;
}
- if (valign === ALIGN.BOTTOM) {
+ if (valign === 'bottom') {
y += h - height - spacing;
- } else if (valign === ALIGN.TOP) {
+ } else if (valign === 'top') {
y += spacing;
} // default is middle
else {
diff --git a/packages/core/src/view/geometry/node/TextShape.ts b/packages/core/src/view/geometry/node/TextShape.ts
index 581b9f3776..53df8fd36a 100644
--- a/packages/core/src/view/geometry/node/TextShape.ts
+++ b/packages/core/src/view/geometry/node/TextShape.ts
@@ -19,7 +19,6 @@ limitations under the License.
import Client from '../../../Client';
import {
ABSOLUTE_LINE_HEIGHT,
- ALIGN,
DEFAULT_FONTFAMILY,
DEFAULT_FONTSIZE,
DEFAULT_FONTSTYLE,
@@ -66,8 +65,8 @@ class TextShape extends Shape {
constructor(
value: string | HTMLElement | SVGGElement,
bounds: Rectangle,
- align: AlignValue = ALIGN.CENTER,
- valign: VAlignValue = ALIGN.MIDDLE,
+ align: AlignValue = 'center',
+ valign: VAlignValue = 'middle',
color = 'black',
family = DEFAULT_FONTFAMILY,
size = DEFAULT_FONTSIZE,
@@ -91,8 +90,8 @@ class TextShape extends Shape {
this.value = value;
this.bounds = bounds;
this.color = color ?? 'black';
- this.align = align ?? ALIGN.CENTER;
- this.valign = valign ?? ALIGN.MIDDLE;
+ this.align = align ?? 'center';
+ this.valign = valign ?? 'middle';
this.family = family ?? DEFAULT_FONTFAMILY;
this.size = size ?? DEFAULT_FONTSIZE;
this.fontStyle = fontStyle ?? DEFAULT_FONTSTYLE;
@@ -344,8 +343,8 @@ class TextShape extends Shape {
super.resetStyles();
this.color = 'black';
- this.align = ALIGN.CENTER;
- this.valign = ALIGN.MIDDLE;
+ this.align = 'center';
+ this.valign = 'middle';
this.family = DEFAULT_FONTFAMILY;
this.size = DEFAULT_FONTSIZE;
this.fontStyle = DEFAULT_FONTSTYLE;
@@ -446,17 +445,14 @@ class TextShape extends Shape {
this.boundingBox = this.bounds.clone();
const rot = this.getTextRotation();
- const h = this.style?.labelPosition ?? ALIGN.CENTER;
- const v = this.style?.verticalLabelPosition ?? ALIGN.MIDDLE;
+ const h = this.style?.labelPosition ?? 'center';
+ const v = this.style?.verticalLabelPosition ?? 'middle';
if (
!this.ignoreStringSize &&
node &&
this.overflow !== 'fill' &&
- (!this.clipped ||
- !this.ignoreClippedStringSize ||
- h !== ALIGN.CENTER ||
- v !== ALIGN.MIDDLE)
+ (!this.clipped || !this.ignoreClippedStringSize || h !== 'center' || v !== 'middle')
) {
let ow = null;
let oh = null;
@@ -816,9 +812,9 @@ class TextShape extends Shape {
matchBinaryMask(this.fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && (style.textDecoration = txtDecor.join(' '));
- if (this.align === ALIGN.CENTER) {
+ if (this.align === 'center') {
style.textAlign = 'center';
- } else if (this.align === ALIGN.RIGHT) {
+ } else if (this.align === 'right') {
style.textAlign = 'right';
} else {
style.textAlign = 'left';
@@ -906,17 +902,17 @@ class TextShape extends Shape {
let dx = 0;
let dy = 0;
- if (this.align === ALIGN.CENTER) {
+ if (this.align === 'center') {
dx = (this.spacingLeft - this.spacingRight) / 2;
- } else if (this.align === ALIGN.RIGHT) {
+ } else if (this.align === 'right') {
dx = -this.spacingRight - this.baseSpacingRight;
} else {
dx = this.spacingLeft + this.baseSpacingLeft;
}
- if (this.valign === ALIGN.MIDDLE) {
+ if (this.valign === 'middle') {
dy = (this.spacingTop - this.spacingBottom) / 2;
- } else if (this.valign === ALIGN.BOTTOM) {
+ } else if (this.valign === 'bottom') {
dy = -this.spacingBottom - this.baseSpacingBottom;
} else {
dy = this.spacingTop + this.baseSpacingTop;
diff --git a/packages/core/src/view/geometry/stencil/StencilShape.ts b/packages/core/src/view/geometry/stencil/StencilShape.ts
index f13f7a7483..f7b230ce3b 100644
--- a/packages/core/src/view/geometry/stencil/StencilShape.ts
+++ b/packages/core/src/view/geometry/stencil/StencilShape.ts
@@ -20,7 +20,6 @@ import ConnectionConstraint from '../../other/ConnectionConstraint';
import Rectangle from '../Rectangle';
import Shape from '../Shape';
import {
- ALIGN,
DIRECTION,
NONE,
RECTANGLE_ROUNDING_FACTOR,
@@ -555,8 +554,8 @@ class StencilShape extends Shape {
0,
0,
str,
- (node.getAttribute('align') as AlignValue) || ALIGN.LEFT,
- (node.getAttribute('valign') as VAlignValue) || ALIGN.TOP,
+ (node.getAttribute('align') as AlignValue) ?? 'left',
+ (node.getAttribute('valign') as VAlignValue) ?? 'top',
false,
'',
'auto',
diff --git a/packages/core/src/view/mixins/CellsMixin.ts b/packages/core/src/view/mixins/CellsMixin.ts
index 9bd902ec34..86278df0d3 100644
--- a/packages/core/src/view/mixins/CellsMixin.ts
+++ b/packages/core/src/view/mixins/CellsMixin.ts
@@ -28,12 +28,7 @@ import {
setCellStyleFlags,
setCellStyles,
} from '../../util/styleUtils';
-import {
- ALIGN,
- DEFAULT_FONTSIZE,
- DEFAULT_IMAGESIZE,
- DIRECTION,
-} from '../../util/Constants';
+import { DEFAULT_FONTSIZE, DEFAULT_IMAGESIZE, DIRECTION } from '../../util/Constants';
import Geometry from '../geometry/Geometry';
import EventObject from '../event/EventObject';
import InternalEvent from '../event/InternalEvent';
@@ -380,26 +375,26 @@ export const CellsMixin: PartialType = {
if (state && !cell.isEdge()) {
if (param === null) {
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
param = state.x + state.width / 2;
break;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
param = state.x + state.width;
- } else if (align === ALIGN.TOP) {
+ } else if (align === 'top') {
param = state.y;
- } else if (align === ALIGN.MIDDLE) {
+ } else if (align === 'middle') {
param = state.y + state.height / 2;
break;
- } else if (align === ALIGN.BOTTOM) {
+ } else if (align === 'bottom') {
param = state.y + state.height;
} else {
param = state.x;
}
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
param = Math.max(param, state.x + state.width);
- } else if (align === ALIGN.TOP) {
+ } else if (align === 'top') {
param = Math.min(param, state.y);
- } else if (align === ALIGN.BOTTOM) {
+ } else if (align === 'bottom') {
param = Math.max(param, state.y + state.height);
} else {
param = Math.min(param, state.x);
@@ -424,15 +419,15 @@ export const CellsMixin: PartialType = {
if (geo != null && !cell.isEdge()) {
geo = geo.clone();
- if (align === ALIGN.CENTER) {
+ if (align === 'center') {
geo.x += (p - state.x - state.width / 2) / s;
- } else if (align === ALIGN.RIGHT) {
+ } else if (align === 'right') {
geo.x += (p - state.x - state.width) / s;
- } else if (align === ALIGN.TOP) {
+ } else if (align === 'top') {
geo.y += (p - state.y) / s;
- } else if (align === ALIGN.MIDDLE) {
+ } else if (align === 'middle') {
geo.y += (p - state.y - state.height / 2) / s;
- } else if (align === ALIGN.BOTTOM) {
+ } else if (align === 'bottom') {
geo.y += (p - state.y - state.height) / s;
} else {
geo.x += (p - state.x) / s;
@@ -904,19 +899,19 @@ export const CellsMixin: PartialType = {
this.getDataModel().setStyle(cell, cellStyle);
} else {
const state = this.getView().createState(cell);
- const align = state.style.align ?? ALIGN.CENTER;
+ const align = state.style.align ?? 'center';
- if (align === ALIGN.RIGHT) {
+ if (align === 'right') {
geo.x += geo.width - size.width;
- } else if (align === ALIGN.CENTER) {
+ } else if (align === 'center') {
geo.x += Math.round((geo.width - size.width) / 2);
}
const valign = state.getVerticalAlign();
- if (valign === ALIGN.BOTTOM) {
+ if (valign === 'bottom') {
geo.y += geo.height - size.height;
- } else if (valign === ALIGN.MIDDLE) {
+ } else if (valign === 'middle') {
geo.y += Math.round((geo.height - size.height) / 2);
}
@@ -958,11 +953,11 @@ export const CellsMixin: PartialType = {
// Adds dimension of image if shape is a label
if (state.getImageSrc() || style.image) {
if (style.shape === 'label') {
- if (style.verticalAlign === ALIGN.MIDDLE) {
+ if (style.verticalAlign === 'middle') {
dx += style.imageWidth || DEFAULT_IMAGESIZE;
}
- if (style.align !== ALIGN.CENTER) {
+ if (style.align !== 'center') {
dy += style.imageHeight || DEFAULT_IMAGESIZE;
}
}
diff --git a/packages/core/src/view/mixins/CellsMixin.type.ts b/packages/core/src/view/mixins/CellsMixin.type.ts
index 4c2fa2dc1f..255b6d7434 100644
--- a/packages/core/src/view/mixins/CellsMixin.type.ts
+++ b/packages/core/src/view/mixins/CellsMixin.type.ts
@@ -16,7 +16,13 @@ limitations under the License.
import type Cell from '../cell/Cell';
import type Rectangle from '../geometry/Rectangle';
-import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../../types';
+import type {
+ AlignValue,
+ CellStateStyle,
+ CellStyle,
+ NumericCellStateStyleKeys,
+ VAlignValue,
+} from '../../types';
import type Geometry from '../geometry/Geometry';
import type CellState from '../cell/CellState';
@@ -237,11 +243,15 @@ declare module '../AbstractGraph' {
/**
* Aligns the given cells vertically or horizontally according to the given alignment using the optional parameter as the coordinate.
*
- * @param align Specifies the alignment. Possible values are all entries of the {@link ALIGN} enum.
+ * @param align Specifies the alignment.
* @param cells Array of {@link Cell} to be aligned.
* @param param Optional coordinate for the alignment.
*/
- alignCells: (align: string, cells?: Cell[], param?: number | null) => void;
+ alignCells: (
+ align: AlignValue | VAlignValue,
+ cells?: Cell[],
+ param?: number | null
+ ) => void;
/**
* Returns the clone for the given cell. Uses {@link cloneCells}.
diff --git a/packages/core/src/view/plugins/CellEditorHandler.ts b/packages/core/src/view/plugins/CellEditorHandler.ts
index 8ba3542a4c..2ced9409be 100644
--- a/packages/core/src/view/plugins/CellEditorHandler.ts
+++ b/packages/core/src/view/plugins/CellEditorHandler.ts
@@ -22,7 +22,6 @@ import InternalEvent from '../event/InternalEvent';
import Client from '../../Client';
import {
ABSOLUTE_LINE_HEIGHT,
- ALIGN,
DEFAULT_FONTFAMILY,
DEFAULT_FONTSIZE,
DEFAULT_TEXT_DIRECTION,
@@ -49,7 +48,7 @@ import {
import EventSource from '../event/EventSource';
import type { AbstractGraph } from '../AbstractGraph';
-import type { GraphPlugin } from '../../types';
+import type { AlignValue, GraphPlugin } from '../../types';
import type TooltipHandler from './TooltipHandler';
/**
@@ -161,7 +160,7 @@ class CellEditorHandler implements GraphPlugin {
};
// Handling of deleted cells while editing
- this.changeHandler = (sender: EventSource) => {
+ this.changeHandler = (_sender: EventSource) => {
if (this.editingCell && !this.graph.getView().getState(this.editingCell, false)) {
this.stopEditing(true);
}
@@ -199,33 +198,28 @@ class CellEditorHandler implements GraphPlugin {
/**
* Reference to the that is currently being edited.
*/
- // editingCell: mxCell;
editingCell: Cell | null = null;
/**
* Reference to the event that was used to start editing.
*/
- // trigger: MouseEvent;
trigger: InternalMouseEvent | MouseEvent | null = null;
/**
* Specifies if the label has been modified.
*/
- // modified: boolean;
modified = false;
/**
* Specifies if the textarea should be resized while the text is being edited.
* Default is true.
*/
- // autoSize: boolean;
autoSize = true;
/**
* Specifies if the text should be selected when editing starts. Default is
* true.
*/
- // selectText: boolean;
selectText = true;
/**
@@ -235,7 +229,6 @@ class CellEditorHandler implements GraphPlugin {
* value is only displayed before the first keystroke and is never used as the
* actual editing value.
*/
- // emptyLabelText: ' ' | '';
emptyLabelText: string = Client.IS_FF ? ' ' : '';
/**
@@ -243,25 +236,21 @@ class CellEditorHandler implements GraphPlugin {
* value. Change this to false to accept the new value on escape, and cancel
* editing on Shift+Escape instead. Default is true.
*/
- // escapeCancelsEditing: boolean;
escapeCancelsEditing = true;
/**
* Reference to the label DOM node that has been hidden.
*/
- // textNode: string;
textNode: SVGGElement | null = null;
/**
* Specifies the zIndex for the textarea. Default is 5.
*/
- // zIndex: number;
zIndex = 5;
/**
* Defines the minimum width and height to be used in . Default is 0x20px.
*/
- // minResize: mxRectangle;
minResize: Rectangle = new Rectangle(0, 20);
/**
@@ -274,13 +263,11 @@ class CellEditorHandler implements GraphPlugin {
/**
* If should be called if |