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 * - * constants.ALIGN.LEFT + * MyConstant.PROP * * ``` * - * 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