commit
061ff34917
|
@ -119,8 +119,8 @@ import mxAnimation from './util/animate/mxAnimation';
|
|||
import mxEffects from './util/animate/mxEffects';
|
||||
import mxMorphing from './util/animate/mxMorphing';
|
||||
|
||||
import mxAbstractCanvas2D from './util/canvas/mxAbstractCanvas2D';
|
||||
import mxSvgCanvas2D from './util/canvas/mxSvgCanvas2D';
|
||||
import mxAbstractCanvas2D from './util/canvas/AbstractCanvas2D';
|
||||
import mxSvgCanvas2D from './util/canvas/SvgCanvas2D';
|
||||
import mxXmlCanvas2D from './util/canvas/mxXmlCanvas2D';
|
||||
|
||||
import Dictionary from './util/Dictionary';
|
||||
|
@ -151,7 +151,7 @@ import mxPopupMenu from './util/gui/mxPopupMenu';
|
|||
import mxToolbar from './util/gui/mxToolbar';
|
||||
import mxWindow from './util/gui/mxWindow';
|
||||
|
||||
import Image from './view/image/Image';
|
||||
import Image from './view/image/ImageBox';
|
||||
import ImageBundle from './view/image/ImageBundle';
|
||||
import ImageExport from './view/image/ImageExport';
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type Cell from './view/cell/datatypes/Cell';
|
||||
import Shape from './view/geometry/shape/Shape';
|
||||
|
||||
export type CellMap = {
|
||||
[id: string]: Cell;
|
||||
|
@ -23,19 +24,88 @@ export type Properties = {
|
|||
};
|
||||
|
||||
export type CellStateStyles = {
|
||||
[k: string]: string;
|
||||
absoluteArcSize: number;
|
||||
align: AlignValue;
|
||||
arcSize: number;
|
||||
backgroundColor: ColorValue;
|
||||
backgroundOutline: number;
|
||||
curved: boolean;
|
||||
dashed: boolean;
|
||||
dashPattern: string;
|
||||
direction: DirectionValue;
|
||||
endArrow: ArrowType;
|
||||
endFill: boolean;
|
||||
endSize: number;
|
||||
fillColor: ColorValue;
|
||||
fillOpacity: number;
|
||||
fixDash: boolean;
|
||||
flipH: boolean;
|
||||
flipV: boolean;
|
||||
fontColor: ColorValue;
|
||||
fontFamily: string;
|
||||
fontSize: number;
|
||||
fontStyle: number;
|
||||
glass: boolean;
|
||||
gradientColor: ColorValue;
|
||||
gradientDirection: DirectionValue;
|
||||
horizontal: boolean;
|
||||
image: string;
|
||||
imageAlign: AlignValue;
|
||||
imageAspect: boolean;
|
||||
imageBackground: ColorValue;
|
||||
imageBorder: ColorValue;
|
||||
imageHeight: number;
|
||||
imageWidth: number;
|
||||
indicatorColor: ColorValue;
|
||||
indicatorHeight: number;
|
||||
indicatorImage: string;
|
||||
indicatorShape: Shape;
|
||||
indicatorWidth: number;
|
||||
labelBorderColor: ColorValue;
|
||||
labelPosition: AlignValue;
|
||||
margin: number;
|
||||
opacity: number;
|
||||
pointerEvents: boolean;
|
||||
rotation: number;
|
||||
rounded: boolean;
|
||||
separatorColor: ColorValue;
|
||||
shadow: boolean;
|
||||
spacing: number;
|
||||
spacingBottom: number;
|
||||
spacingLeft: number;
|
||||
spacingRight: number;
|
||||
spacingTop: number;
|
||||
startArrow: ArrowType;
|
||||
startFill: boolean;
|
||||
startSize: number;
|
||||
strokeColor: ColorValue;
|
||||
strokeOpacity: number;
|
||||
strokeWidth: number;
|
||||
swimlaneFillColor: ColorValue;
|
||||
swimlaneLine: boolean;
|
||||
textDirection: TextDirectionValue;
|
||||
textOpacity: number;
|
||||
verticalAlign: VAlignValue;
|
||||
verticalLabelPosition: VAlignValue;
|
||||
};
|
||||
|
||||
export type ColorValue = string | null;
|
||||
export type DirectionValue = 'north' | 'south' | 'east' | 'west' | null;
|
||||
export type AlignValue =
|
||||
| 'left'
|
||||
| 'center'
|
||||
| 'right'
|
||||
| 'top'
|
||||
| 'middle'
|
||||
| 'bottom'
|
||||
| null;
|
||||
export type ColorValue = string;
|
||||
export type DirectionValue = 'north' | 'south' | 'east' | 'west';
|
||||
export type TextDirectionValue = '' | 'ltr' | 'rtl' | 'auto';
|
||||
export type AlignValue = 'left' | 'center' | 'right';
|
||||
export type VAlignValue = 'top' | 'middle' | 'bottom';
|
||||
export type OverflowValue = 'fill' | 'width' | 'auto' | 'hidden' | 'scroll' | 'visible';
|
||||
export type ArrowType =
|
||||
| 'none'
|
||||
| 'classic'
|
||||
| 'classicThin'
|
||||
| 'block'
|
||||
| 'blockThin'
|
||||
| 'open'
|
||||
| 'openThin'
|
||||
| 'oval'
|
||||
| 'diamond'
|
||||
| 'diamondThin';
|
||||
|
||||
export type CanvasState = {
|
||||
dx: number;
|
||||
|
@ -48,9 +118,9 @@ export type CanvasState = {
|
|||
gradientFillAlpha: number;
|
||||
gradientColor: ColorValue;
|
||||
gradientAlpha: number;
|
||||
gradientDirection: string | null;
|
||||
gradientDirection: DirectionValue;
|
||||
strokeColor: ColorValue;
|
||||
strokeWidth: number | null;
|
||||
strokeWidth: number;
|
||||
dashed: boolean;
|
||||
dashPattern: string;
|
||||
fixDash: boolean;
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import mxObjectIdentity from './mxObjectIdentity';
|
||||
import ObjectIdentity from './ObjectIdentity';
|
||||
|
||||
//type Dictionary<T, U> = {
|
||||
// [key: string]: U;
|
||||
//};
|
||||
|
||||
type Visitor<T, U> = (key: string, value: U) => void;
|
||||
type MapKey = string;
|
||||
|
||||
type Visitor<MapKey, U> = (key: MapKey, value: U) => void;
|
||||
|
||||
/**
|
||||
* Class: mxDictionary
|
||||
|
@ -33,7 +35,7 @@ class Dictionary<T, U> {
|
|||
*
|
||||
* Stores the (key, value) pairs in this dictionary.
|
||||
*/
|
||||
map: Dictionary<T, U> = {};
|
||||
map: Record<MapKey, U> = {};
|
||||
|
||||
/**
|
||||
* Function: clear
|
||||
|
@ -50,7 +52,7 @@ class Dictionary<T, U> {
|
|||
* Returns the value for the given key.
|
||||
*/
|
||||
get(key: T) {
|
||||
const id = mxObjectIdentity.get(key);
|
||||
const id = ObjectIdentity.get(key);
|
||||
|
||||
return this.map[id];
|
||||
}
|
||||
|
@ -62,7 +64,7 @@ class Dictionary<T, U> {
|
|||
* value for that key.
|
||||
*/
|
||||
put(key: T, value: U) {
|
||||
const id = mxObjectIdentity.get(key);
|
||||
const id = ObjectIdentity.get(key);
|
||||
const previous = this.map[id];
|
||||
this.map[id] = value;
|
||||
|
||||
|
@ -76,7 +78,7 @@ class Dictionary<T, U> {
|
|||
* has been removed.
|
||||
*/
|
||||
remove(key: T) {
|
||||
const id = mxObjectIdentity.get(key);
|
||||
const id = ObjectIdentity.get(key);
|
||||
const previous = this.map[id];
|
||||
delete this.map[id];
|
||||
|
||||
|
@ -124,7 +126,7 @@ class Dictionary<T, U> {
|
|||
*
|
||||
* visitor - A function that takes the key and value as arguments.
|
||||
*/
|
||||
visit(visitor: Visitor<string, U>) {
|
||||
visit(visitor: Visitor<MapKey, U>) {
|
||||
for (const key in this.map) {
|
||||
visitor(key, this.map[key]);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ type IdentityFunction = {
|
|||
*
|
||||
* The identity for an object does not change during its lifecycle.
|
||||
*/
|
||||
class mxObjectIdentity {
|
||||
class ObjectIdentity {
|
||||
/**
|
||||
* Name of the field to be used to store the object ID. Default is
|
||||
* <code>mxObjectId</code>.
|
||||
|
@ -48,9 +48,9 @@ class mxObjectIdentity {
|
|||
if (isNullish(obj[FIELD_NAME])) {
|
||||
if (typeof obj === 'object') {
|
||||
const ctor = getFunctionName(obj.constructor);
|
||||
obj[FIELD_NAME] = `${ctor}#${mxObjectIdentity.counter++}`;
|
||||
obj[FIELD_NAME] = `${ctor}#${ObjectIdentity.counter++}`;
|
||||
} else if (typeof obj === 'function') {
|
||||
obj[FIELD_NAME] = `Function#${mxObjectIdentity.counter++}`;
|
||||
obj[FIELD_NAME] = `Function#${ObjectIdentity.counter++}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,4 +65,4 @@ class mxObjectIdentity {
|
|||
}
|
||||
}
|
||||
|
||||
export default mxObjectIdentity;
|
||||
export default ObjectIdentity;
|
|
@ -41,13 +41,8 @@ import Cell from '../view/cell/datatypes/Cell';
|
|||
import Model from '../view/model/Model';
|
||||
import graph from '../view/Graph';
|
||||
|
||||
import type {
|
||||
CellStateStyles,
|
||||
Properties,
|
||||
StyleProperties,
|
||||
StyleValue,
|
||||
} from '../types';
|
||||
import CellArray from "../view/cell/datatypes/CellArray";
|
||||
import type { CellStateStyles, Properties, StyleProperties, StyleValue } from '../types';
|
||||
import CellArray from '../view/cell/datatypes/CellArray';
|
||||
|
||||
/**
|
||||
* Class: mxUtils
|
||||
|
@ -164,11 +159,7 @@ export const parseCssNumber = (value: string) => {
|
|||
* mxUtils.setPrefixedStyle(node.style, 'transformOrigin', '0% 0%');
|
||||
* (end)
|
||||
*/
|
||||
export const setPrefixedStyle = (
|
||||
style: StyleProperties,
|
||||
name: string,
|
||||
value: string
|
||||
) => {
|
||||
export const setPrefixedStyle = (style: StyleProperties, name: string, value: string) => {
|
||||
let prefix = null;
|
||||
|
||||
if (mxClient.IS_SF || mxClient.IS_GC) {
|
||||
|
@ -343,11 +334,7 @@ export const getValue = (array: any, key: string, defaultValue?: any) => {
|
|||
return value;
|
||||
};
|
||||
|
||||
export const getStringValue = (
|
||||
array: any,
|
||||
key: string,
|
||||
defaultValue: string
|
||||
) => {
|
||||
export const getStringValue = (array: any, key: string, defaultValue: string) => {
|
||||
let value = array != null ? array[key] : null;
|
||||
if (value == null) {
|
||||
value = defaultValue;
|
||||
|
@ -455,10 +442,7 @@ export const equalEntries = (a: Properties | null, b: Properties | null) => {
|
|||
for (var key in a) {
|
||||
count--;
|
||||
|
||||
if (
|
||||
(!Number.isNaN(a[key]) || !Number.isNaN(b[key])) &&
|
||||
a[key] !== b[key]
|
||||
) {
|
||||
if ((!Number.isNaN(a[key]) || !Number.isNaN(b[key])) && a[key] !== b[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -588,10 +572,7 @@ export const arcToCurves = (
|
|||
}
|
||||
|
||||
sds =
|
||||
seif *
|
||||
Math.sqrt(
|
||||
(r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd)
|
||||
);
|
||||
seif * Math.sqrt((r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd));
|
||||
}
|
||||
|
||||
const txd = (sds * r1 * ryd) / r2;
|
||||
|
@ -614,8 +595,7 @@ export const arcToCurves = (
|
|||
const sse = (dr * 2) / Math.PI;
|
||||
const seg = Math.ceil(sse < 0 ? -1 * sse : sse);
|
||||
const segr = dr / seg;
|
||||
const t =
|
||||
((8 / 3) * Math.sin(segr / 4) * Math.sin(segr / 4)) / Math.sin(segr / 2);
|
||||
const t = ((8 / 3) * Math.sin(segr / 4) * Math.sin(segr / 4)) / Math.sin(segr / 2);
|
||||
const cpsir1 = cpsi * r1;
|
||||
const cpsir2 = cpsi * r2;
|
||||
const spsir1 = spsi * r1;
|
||||
|
@ -679,10 +659,7 @@ export const getBoundingBox = (
|
|||
const cos = Math.cos(rad);
|
||||
const sin = Math.sin(rad);
|
||||
|
||||
cx =
|
||||
cx != null
|
||||
? cx
|
||||
: new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
|
||||
cx = cx != null ? cx : new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
|
||||
|
||||
let p1 = new Point(rect.x, rect.y);
|
||||
let p2 = new Point(rect.x + rect.width, rect.y);
|
||||
|
@ -708,12 +685,7 @@ export const getBoundingBox = (
|
|||
*
|
||||
* Rotates the given point by the given cos and sin.
|
||||
*/
|
||||
export const getRotatedPoint = (
|
||||
pt: Point,
|
||||
cos: number,
|
||||
sin: number,
|
||||
c = new Point()
|
||||
) => {
|
||||
export const getRotatedPoint = (pt: Point, cos: number, sin: number, c = new Point()) => {
|
||||
const x = pt.x - c.x;
|
||||
const y = pt.y - c.y;
|
||||
|
||||
|
@ -745,11 +717,7 @@ export const getPortConstraints = (
|
|||
const value = getValue(
|
||||
terminal.style,
|
||||
'portConstraint',
|
||||
getValue(
|
||||
edge.style,
|
||||
source ? 'sourcePortConstraint' : 'targetPortConstraint',
|
||||
null
|
||||
)
|
||||
getValue(edge.style, source ? 'sourcePortConstraint' : 'targetPortConstraint', null)
|
||||
);
|
||||
|
||||
if (isNullish(value)) {
|
||||
|
@ -758,11 +726,7 @@ export const getPortConstraints = (
|
|||
|
||||
const directions = value.toString();
|
||||
let returnValue = DIRECTION_MASK_NONE;
|
||||
const constraintRotationEnabled = getValue(
|
||||
terminal.style,
|
||||
'portConstraintRotation',
|
||||
0
|
||||
);
|
||||
const constraintRotationEnabled = getValue(terminal.style, 'portConstraintRotation', 0);
|
||||
let rotation = 0;
|
||||
|
||||
if (constraintRotationEnabled == 1) {
|
||||
|
@ -876,11 +840,7 @@ export const reversePortConstraints = (constraint: number) => {
|
|||
* Finds the index of the nearest segment on the given cell state for
|
||||
* the specified coordinate pair.
|
||||
*/
|
||||
export const findNearestSegment = (
|
||||
state: CellState,
|
||||
x: number,
|
||||
y: number
|
||||
) => {
|
||||
export const findNearestSegment = (state: CellState, x: number, y: number) => {
|
||||
let index = -1;
|
||||
|
||||
if (state.absolutePoints.length > 0) {
|
||||
|
@ -979,11 +939,7 @@ export const getDirectedBounds = (
|
|||
* Returns the intersection between the polygon defined by the array of
|
||||
* points and the line between center and point.
|
||||
*/
|
||||
export const getPerimeterPoint = (
|
||||
pts: Point[],
|
||||
center: Point,
|
||||
point: Point
|
||||
) => {
|
||||
export const getPerimeterPoint = (pts: Point[], center: Point, point: Point) => {
|
||||
let min = null;
|
||||
|
||||
for (let i = 0; i < pts.length - 1; i += 1) {
|
||||
|
@ -1023,11 +979,7 @@ export const getPerimeterPoint = (
|
|||
* p1 - <mxPoint> that represents the first point of the segment.
|
||||
* p2 - <mxPoint> that represents the second point of the segment.
|
||||
*/
|
||||
export const rectangleIntersectsSegment = (
|
||||
bounds: Rectangle,
|
||||
p1: Point,
|
||||
p2: Point
|
||||
) => {
|
||||
export const rectangleIntersectsSegment = (bounds: Rectangle, p1: Point, p2: Point) => {
|
||||
const top = bounds.y;
|
||||
const left = bounds.x;
|
||||
const bottom = top + bounds.height;
|
||||
|
@ -1286,8 +1238,7 @@ export const getDocumentScrollOrigin = (doc: Document) => {
|
|||
const y =
|
||||
wnd != null && window.pageYOffset !== undefined
|
||||
? window.pageYOffset
|
||||
: (document.documentElement || document.body.parentNode || document.body)
|
||||
.scrollTop;
|
||||
: (document.documentElement || document.body.parentNode || document.body).scrollTop;
|
||||
|
||||
return new Point(x, y);
|
||||
};
|
||||
|
@ -1378,7 +1329,7 @@ export const convertPoint = (container: HTMLElement, x: number, y: number) => {
|
|||
*
|
||||
* n - String representing the possibly numeric value.
|
||||
*/
|
||||
export const isNumeric = (n: string) => {
|
||||
export const isNumeric = (n: any) => {
|
||||
return (
|
||||
!Number.isNaN(parseFloat(n)) &&
|
||||
isFinite(+n) &&
|
||||
|
@ -1792,12 +1743,7 @@ export const removeAllStylenames = (style: string) => {
|
|||
* key - Key of the style to be changed.
|
||||
* value - New value for the given key.
|
||||
*/
|
||||
export const setCellStyles = (
|
||||
model: Model,
|
||||
cells: Cell[],
|
||||
key: string,
|
||||
value: any
|
||||
) => {
|
||||
export const setCellStyles = (model: Model, cells: Cell[], key: string, value: any) => {
|
||||
if (cells.length > 0) {
|
||||
model.beginUpdate();
|
||||
try {
|
||||
|
@ -1842,8 +1788,7 @@ export const setStyle = (style: string | null, key: string, value: any) => {
|
|||
if (isValue) {
|
||||
style = `${key}=${value}${next < 0 ? ';' : style.substring(next)}`;
|
||||
} else {
|
||||
style =
|
||||
next < 0 || next == style.length - 1 ? '' : style.substring(next + 1);
|
||||
style = next < 0 || next == style.length - 1 ? '' : style.substring(next + 1);
|
||||
}
|
||||
} else {
|
||||
const index = style.indexOf(`;${key}=`);
|
||||
|
@ -1861,8 +1806,7 @@ export const setStyle = (style: string | null, key: string, value: any) => {
|
|||
next < 0 ? ';' : style.substring(next)
|
||||
}`;
|
||||
} else {
|
||||
style =
|
||||
style.substring(0, index) + (next < 0 ? ';' : style.substring(next));
|
||||
style = style.substring(0, index) + (next < 0 ? ';' : style.substring(next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2128,9 +2072,7 @@ export const getScaleForPageCount = (
|
|||
}
|
||||
|
||||
pageFormat =
|
||||
pageFormat != null
|
||||
? pageFormat
|
||||
: new Rectangle(...PAGE_FORMAT_A4_PORTRAIT);
|
||||
pageFormat != null ? pageFormat : new Rectangle(...PAGE_FORMAT_A4_PORTRAIT);
|
||||
|
||||
const availablePageWidth = pageFormat.width - border * 2;
|
||||
const availablePageHeight = pageFormat.height - border * 2;
|
||||
|
@ -2202,8 +2144,7 @@ export const getScaleForPageCount = (
|
|||
roundRowDownProportion = Math.floor(numRowPages - 1) / numRowPages;
|
||||
}
|
||||
if (roundColumnDownProportion == 1) {
|
||||
roundColumnDownProportion =
|
||||
Math.floor(numColumnPages - 1) / numColumnPages;
|
||||
roundColumnDownProportion = Math.floor(numColumnPages - 1) / numColumnPages;
|
||||
}
|
||||
|
||||
// Check which rounding down is smaller, but in the case of very small roundings
|
||||
|
@ -2279,13 +2220,11 @@ export const show = (
|
|||
const dy = Math.ceil(y0 - bounds.y);
|
||||
|
||||
if (w == null) {
|
||||
w =
|
||||
Math.ceil(bounds.width + x0) + Math.ceil(Math.ceil(bounds.x) - bounds.x);
|
||||
w = Math.ceil(bounds.width + x0) + Math.ceil(Math.ceil(bounds.x) - bounds.x);
|
||||
}
|
||||
|
||||
if (h == null) {
|
||||
h =
|
||||
Math.ceil(bounds.height + y0) + Math.ceil(Math.ceil(bounds.y) - bounds.y);
|
||||
h = Math.ceil(bounds.height + y0) + Math.ceil(Math.ceil(bounds.y) - bounds.y);
|
||||
}
|
||||
|
||||
doc.writeln('<html><head>');
|
||||
|
|
|
@ -8,6 +8,7 @@ import { arcToCurves, getRotatedPoint } from '../Utils';
|
|||
import {
|
||||
DEFAULT_FONTFAMILY,
|
||||
DEFAULT_FONTSIZE,
|
||||
DIRECTION_EAST,
|
||||
NONE,
|
||||
SHADOWCOLOR,
|
||||
SHADOW_OFFSET_X,
|
||||
|
@ -18,7 +19,15 @@ import mxUrlConverter from '../network/mxUrlConverter';
|
|||
import Point from '../../view/geometry/Point';
|
||||
import { clone } from '../CloneUtils';
|
||||
|
||||
import type { CanvasState, ColorValue } from '../../types';
|
||||
import type {
|
||||
AlignValue,
|
||||
CanvasState,
|
||||
ColorValue,
|
||||
DirectionValue,
|
||||
OverflowValue,
|
||||
TextDirectionValue,
|
||||
VAlignValue,
|
||||
} from '../../types';
|
||||
|
||||
/**
|
||||
* Class: mxAbstractCanvas2D
|
||||
|
@ -30,7 +39,7 @@ import type { CanvasState, ColorValue } from '../../types';
|
|||
*
|
||||
* Constructs a new abstract canvas.
|
||||
*/
|
||||
class mxAbstractCanvas2D {
|
||||
class AbstractCanvas2D {
|
||||
constructor() {
|
||||
/**
|
||||
* Variable: converter
|
||||
|
@ -127,6 +136,9 @@ class mxAbstractCanvas2D {
|
|||
*/
|
||||
pointerEvents = false;
|
||||
|
||||
// from Polyline (maybe from other shapes also)
|
||||
pointerEventsValue: string | null = null;
|
||||
|
||||
/**
|
||||
* Function: createUrlConverter
|
||||
*
|
||||
|
@ -159,12 +171,12 @@ class mxAbstractCanvas2D {
|
|||
alpha: 1,
|
||||
fillAlpha: 1,
|
||||
strokeAlpha: 1,
|
||||
fillColor: null,
|
||||
fillColor: NONE,
|
||||
gradientFillAlpha: 1,
|
||||
gradientColor: null,
|
||||
gradientColor: NONE,
|
||||
gradientAlpha: 1,
|
||||
gradientDirection: null,
|
||||
strokeColor: null,
|
||||
gradientDirection: DIRECTION_EAST,
|
||||
strokeColor: NONE,
|
||||
strokeWidth: 1,
|
||||
dashed: false,
|
||||
dashPattern: '3 3',
|
||||
|
@ -173,8 +185,8 @@ class mxAbstractCanvas2D {
|
|||
lineJoin: 'miter',
|
||||
miterLimit: 10,
|
||||
fontColor: '#000000',
|
||||
fontBackgroundColor: null,
|
||||
fontBorderColor: null,
|
||||
fontBackgroundColor: NONE,
|
||||
fontBorderColor: NONE,
|
||||
fontSize: DEFAULT_FONTSIZE,
|
||||
fontFamily: DEFAULT_FONTFAMILY,
|
||||
fontStyle: 0,
|
||||
|
@ -291,13 +303,7 @@ class mxAbstractCanvas2D {
|
|||
*
|
||||
* Rotates the current state.
|
||||
*/
|
||||
rotate(
|
||||
theta: number,
|
||||
flipH: boolean,
|
||||
flipV: boolean,
|
||||
cx: number,
|
||||
cy: number
|
||||
) {
|
||||
rotate(theta: number, flipH: boolean, flipV: boolean, cx: number, cy: number) {
|
||||
// nop
|
||||
}
|
||||
|
||||
|
@ -334,10 +340,8 @@ class mxAbstractCanvas2D {
|
|||
* Sets the current fill color.
|
||||
*/
|
||||
setFillColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
|
||||
this.state.fillColor = v;
|
||||
this.state.gradientColor = null;
|
||||
this.state.fillColor = value;
|
||||
this.state.gradientColor = NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,7 +356,7 @@ class mxAbstractCanvas2D {
|
|||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
direction: string | null,
|
||||
direction: DirectionValue,
|
||||
alpha1 = 1,
|
||||
alpha2: number = 1
|
||||
) {
|
||||
|
@ -370,8 +374,7 @@ class mxAbstractCanvas2D {
|
|||
* Sets the current stroke color.
|
||||
*/
|
||||
setStrokeColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
this.state.strokeColor = v;
|
||||
this.state.strokeColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -379,7 +382,7 @@ class mxAbstractCanvas2D {
|
|||
*
|
||||
* Sets the current stroke width.
|
||||
*/
|
||||
setStrokeWidth(value: number | null) {
|
||||
setStrokeWidth(value: number) {
|
||||
this.state.strokeWidth = value;
|
||||
}
|
||||
|
||||
|
@ -435,8 +438,7 @@ class mxAbstractCanvas2D {
|
|||
* Sets the current font color.
|
||||
*/
|
||||
setFontColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
this.state.fontColor = v;
|
||||
this.state.fontColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -445,8 +447,7 @@ class mxAbstractCanvas2D {
|
|||
* Sets the current font background color.
|
||||
*/
|
||||
setFontBackgroundColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
this.state.fontBackgroundColor = v;
|
||||
this.state.fontBackgroundColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,8 +456,7 @@ class mxAbstractCanvas2D {
|
|||
* Sets the current font border color.
|
||||
*/
|
||||
setFontBorderColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
this.state.fontBorderColor = v;
|
||||
this.state.fontBorderColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -501,8 +501,7 @@ class mxAbstractCanvas2D {
|
|||
* Enables or disables and configures the current shadow.
|
||||
*/
|
||||
setShadowColor(value: ColorValue) {
|
||||
const v = value === NONE ? null : value;
|
||||
this.state.shadowColor = v;
|
||||
this.state.shadowColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,14 +566,7 @@ class mxAbstractCanvas2D {
|
|||
*
|
||||
* Adds a bezier curve to the current path.
|
||||
*/
|
||||
curveTo(
|
||||
x1: number,
|
||||
y1: number,
|
||||
x2: number,
|
||||
y2: number,
|
||||
x3: number,
|
||||
y3: number
|
||||
) {
|
||||
curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) {
|
||||
this.addOp(this.curveOp, x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
|
@ -624,14 +616,7 @@ class mxAbstractCanvas2D {
|
|||
*
|
||||
* Closes the current path.
|
||||
*/
|
||||
close(
|
||||
x1?: number,
|
||||
y1?: number,
|
||||
x2?: number,
|
||||
y2?: number,
|
||||
x3?: number,
|
||||
y3?: number
|
||||
) {
|
||||
close(x1?: number, y1?: number, x2?: number, y2?: number, x3?: number, y3?: number) {
|
||||
this.addOp(this.closeOp);
|
||||
}
|
||||
|
||||
|
@ -641,6 +626,59 @@ class mxAbstractCanvas2D {
|
|||
* Empty implementation for backwards compatibility. This will be removed.
|
||||
*/
|
||||
end() {}
|
||||
|
||||
stroke() {}
|
||||
|
||||
fill() {}
|
||||
|
||||
fillAndStroke() {}
|
||||
|
||||
rect(x: number, y: number, w: number, h: number) {}
|
||||
|
||||
roundrect(x: number, y: number, w: number, h: number, r1: number, r2: number) {}
|
||||
|
||||
ellipse(x: number, y: number, w: number, h: number) {}
|
||||
|
||||
image(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
src: string,
|
||||
aspect = true,
|
||||
flipH = false,
|
||||
flipV = false
|
||||
) {}
|
||||
|
||||
text(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
str: string,
|
||||
align: AlignValue,
|
||||
valign: VAlignValue,
|
||||
wrap: boolean,
|
||||
format: string,
|
||||
overflow: OverflowValue,
|
||||
clip: boolean,
|
||||
rotation = 0,
|
||||
dir: TextDirectionValue
|
||||
) {}
|
||||
|
||||
updateText(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
align: AlignValue,
|
||||
valign: VAlignValue,
|
||||
wrap: boolean,
|
||||
overflow: OverflowValue,
|
||||
clip: boolean,
|
||||
rotation = 0,
|
||||
node: SVGElement
|
||||
) {}
|
||||
}
|
||||
|
||||
export default mxAbstractCanvas2D;
|
||||
export default AbstractCanvas2D;
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import mxAbstractCanvas2D from './mxAbstractCanvas2D';
|
||||
import mxAbstractCanvas2D from './AbstractCanvas2D';
|
||||
import {
|
||||
DEFAULT_FONTFAMILY,
|
||||
DEFAULT_FONTSIZE,
|
||||
|
@ -916,21 +916,7 @@ class mxXmlCanvas2D extends mxAbstractCanvas2D {
|
|||
* rotation - Number that specifies the angle of the rotation around the anchor point of the text.
|
||||
* dir - Optional string that specifies the text direction. Possible values are rtl and lrt.
|
||||
*/
|
||||
text(
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
str,
|
||||
align,
|
||||
valign,
|
||||
wrap,
|
||||
format,
|
||||
overflow,
|
||||
clip,
|
||||
rotation,
|
||||
dir
|
||||
) {
|
||||
text(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir) {
|
||||
if (this.textEnabled && str != null) {
|
||||
if (isNode(str)) {
|
||||
str = getOuterHtml(str);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import Image from './image/Image';
|
||||
import Image from './image/ImageBox';
|
||||
import EventObject from './event/EventObject';
|
||||
import EventSource from './event/EventSource';
|
||||
import InternalEvent from './event/InternalEvent';
|
||||
|
@ -23,16 +23,16 @@ import CellRenderer from './cell/CellRenderer';
|
|||
import CellEditor from './editing/CellEditor';
|
||||
import Point from './geometry/Point';
|
||||
import {
|
||||
getBoundingBox, getCurrentStyle,
|
||||
getValue, hasScrollbars, parseCssNumber,
|
||||
getBoundingBox,
|
||||
getCurrentStyle,
|
||||
getValue,
|
||||
hasScrollbars,
|
||||
parseCssNumber,
|
||||
} from '../util/Utils';
|
||||
import Cell from './cell/datatypes/Cell';
|
||||
import Model from './model/Model';
|
||||
import Stylesheet from './style/Stylesheet';
|
||||
import {
|
||||
DIALECT_SVG,
|
||||
PAGE_FORMAT_A4_PORTRAIT,
|
||||
} from '../util/Constants';
|
||||
import { DIALECT_SVG, PAGE_FORMAT_A4_PORTRAIT } from '../util/Constants';
|
||||
|
||||
import ChildChange from './model/ChildChange';
|
||||
import GeometryChange from './geometry/GeometryChange';
|
||||
|
@ -42,12 +42,12 @@ import TerminalChange from './cell/edge/TerminalChange';
|
|||
import ValueChange from './cell/ValueChange';
|
||||
import CellState from './cell/datatypes/CellState';
|
||||
import { isNode } from '../util/DomUtils';
|
||||
import CellArray from "./cell/datatypes/CellArray";
|
||||
import EdgeStyle from "./style/EdgeStyle";
|
||||
import EdgeHandler from "./cell/edge/EdgeHandler";
|
||||
import VertexHandler from "./cell/vertex/VertexHandler";
|
||||
import EdgeSegmentHandler from "./cell/edge/EdgeSegmentHandler";
|
||||
import ElbowEdgeHandler from "./cell/edge/ElbowEdgeHandler";
|
||||
import CellArray from './cell/datatypes/CellArray';
|
||||
import EdgeStyle from './style/EdgeStyle';
|
||||
import EdgeHandler from './cell/edge/EdgeHandler';
|
||||
import VertexHandler from './cell/vertex/VertexHandler';
|
||||
import EdgeSegmentHandler from './cell/edge/EdgeSegmentHandler';
|
||||
import ElbowEdgeHandler from './cell/edge/ElbowEdgeHandler';
|
||||
|
||||
/**
|
||||
* Extends {@link EventSource} to implement a graph component for
|
||||
|
@ -83,9 +83,7 @@ class Graph extends EventSource {
|
|||
this.model = model != null ? model : new Model();
|
||||
this.cellRenderer = this.createCellRenderer();
|
||||
this.setSelectionModel(this.createSelectionModel());
|
||||
this.setStylesheet(
|
||||
stylesheet != null ? stylesheet : this.createStylesheet()
|
||||
);
|
||||
this.setStylesheet(stylesheet != null ? stylesheet : this.createStylesheet());
|
||||
this.view = this.createGraphView();
|
||||
|
||||
// Adds a graph model listener to update the view
|
||||
|
@ -673,10 +671,7 @@ class Graph extends EventSource {
|
|||
|
||||
// Handles two special cases where the shape does not need to be
|
||||
// recreated from scratch, it only needs to be invalidated.
|
||||
else if (
|
||||
change instanceof TerminalChange ||
|
||||
change instanceof GeometryChange
|
||||
) {
|
||||
else if (change instanceof TerminalChange || change instanceof GeometryChange) {
|
||||
// Checks if the geometry has changed to avoid unnessecary revalidation
|
||||
if (
|
||||
change instanceof TerminalChange ||
|
||||
|
@ -807,21 +802,13 @@ class Graph extends EventSource {
|
|||
|
||||
return new Rectangle(
|
||||
parseCssNumber(css.paddingLeft) +
|
||||
(css.borderLeftStyle != 'none'
|
||||
? parseCssNumber(css.borderLeftWidth)
|
||||
: 0),
|
||||
(css.borderLeftStyle != 'none' ? parseCssNumber(css.borderLeftWidth) : 0),
|
||||
parseCssNumber(css.paddingTop) +
|
||||
(css.borderTopStyle != 'none'
|
||||
? parseCssNumber(css.borderTopWidth)
|
||||
: 0),
|
||||
(css.borderTopStyle != 'none' ? parseCssNumber(css.borderTopWidth) : 0),
|
||||
parseCssNumber(css.paddingRight) +
|
||||
(css.borderRightStyle != 'none'
|
||||
? parseCssNumber(css.borderRightWidth)
|
||||
: 0),
|
||||
(css.borderRightStyle != 'none' ? parseCssNumber(css.borderRightWidth) : 0),
|
||||
parseCssNumber(css.paddingBottom) +
|
||||
(css.borderBottomStyle != 'none'
|
||||
? parseCssNumber(css.borderBottomWidth)
|
||||
: 0)
|
||||
(css.borderBottomStyle != 'none' ? parseCssNumber(css.borderBottomWidth) : 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -909,8 +896,7 @@ class Graph extends EventSource {
|
|||
if (this.container != null) {
|
||||
// Adds spacing and border from css
|
||||
const cssBorder = this.getBorderSizes();
|
||||
let w1: number =
|
||||
this.container.offsetWidth - cssBorder.x - cssBorder.width - 1;
|
||||
let w1: number = this.container.offsetWidth - cssBorder.x - cssBorder.width - 1;
|
||||
let h1: number =
|
||||
maxHeight != null
|
||||
? maxHeight
|
||||
|
@ -962,19 +948,13 @@ class Graph extends EventSource {
|
|||
const x0 =
|
||||
bounds.x != null
|
||||
? Math.floor(
|
||||
this.view.translate.x -
|
||||
bounds.x / s +
|
||||
border / s2 +
|
||||
margin / 2
|
||||
this.view.translate.x - bounds.x / s + border / s2 + margin / 2
|
||||
)
|
||||
: border;
|
||||
const y0 =
|
||||
bounds.y != null
|
||||
? Math.floor(
|
||||
this.view.translate.y -
|
||||
bounds.y / s +
|
||||
border / s2 +
|
||||
margin / 2
|
||||
this.view.translate.y - bounds.y / s + border / s2 + margin / 2
|
||||
)
|
||||
: border;
|
||||
|
||||
|
@ -1026,9 +1006,7 @@ class Graph extends EventSource {
|
|||
*
|
||||
* @param state {@link mxCellState} whose handler should be created.
|
||||
*/
|
||||
createHandler(
|
||||
state: CellState
|
||||
): mxEdgeHandler | VertexHandler | null {
|
||||
createHandler(state: CellState): mxEdgeHandler | VertexHandler | null {
|
||||
let result: mxEdgeHandler | VertexHandler | null = null;
|
||||
|
||||
if (state.cell.isEdge()) {
|
||||
|
@ -1242,7 +1220,6 @@ class Graph extends EventSource {
|
|||
cx: number = 0.5,
|
||||
cy: number = 0.5
|
||||
): void {
|
||||
|
||||
const container = <HTMLElement>this.container;
|
||||
const _hasScrollbars = hasScrollbars(this.container);
|
||||
const padding = 2 * this.getBorder();
|
||||
|
|
|
@ -19,10 +19,10 @@ import graph from './Graph';
|
|||
import ImageShape from './geometry/shape/node/ImageShape';
|
||||
import InternalEvent from './event/InternalEvent';
|
||||
import utils from '../util/Utils';
|
||||
import Image from './image/Image';
|
||||
import Image from './image/ImageBox';
|
||||
import EventObject from './event/EventObject';
|
||||
import { getSource, isMouseEvent } from '../util/EventUtils';
|
||||
import EventSource from "./event/EventSource";
|
||||
import EventSource from './event/EventSource';
|
||||
|
||||
/**
|
||||
* @class Outline
|
||||
|
@ -510,10 +510,8 @@ class Outline {
|
|||
);
|
||||
|
||||
// Adds the scrollbar offset to the finder
|
||||
this.bounds.x +=
|
||||
(this.source.container.scrollLeft * navView.scale) / scale;
|
||||
this.bounds.y +=
|
||||
(this.source.container.scrollTop * navView.scale) / scale;
|
||||
this.bounds.x += (this.source.container.scrollLeft * navView.scale) / scale;
|
||||
this.bounds.y += (this.source.container.scrollTop * navView.scale) / scale;
|
||||
|
||||
const selectionBorder = <RectangleShape>this.selectionBorder;
|
||||
let b = <Rectangle>selectionBorder.bounds;
|
||||
|
@ -567,12 +565,7 @@ class Outline {
|
|||
const tol = !isMouseEvent(me.getEvent()) ? this.source.tolerance : 0;
|
||||
const hit =
|
||||
tol > 0
|
||||
? new Rectangle(
|
||||
me.getGraphX() - tol,
|
||||
me.getGraphY() - tol,
|
||||
2 * tol,
|
||||
2 * tol
|
||||
)
|
||||
? new Rectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol)
|
||||
: null;
|
||||
this.zoom =
|
||||
me.isSource(this.sizer) ||
|
||||
|
@ -691,10 +684,7 @@ class Outline {
|
|||
* ```
|
||||
*/
|
||||
getTranslateForEvent(me: InternalMouseEvent): Point {
|
||||
return new Point(
|
||||
me.getX() - <number>this.startX,
|
||||
me.getY() - <number>this.startY
|
||||
);
|
||||
return new Point(me.getX() - <number>this.startX, me.getY() - <number>this.startY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -713,10 +703,7 @@ class Outline {
|
|||
if (!this.zoom) {
|
||||
// Applies the new translation if the source
|
||||
// has no scrollbars
|
||||
if (
|
||||
!source.useScrollbarsForPanning ||
|
||||
!utils.hasScrollbars(source.container)
|
||||
) {
|
||||
if (!source.useScrollbarsForPanning || !utils.hasScrollbars(source.container)) {
|
||||
source.panGraph(0, 0);
|
||||
dx /= outline.getView().scale;
|
||||
dy /= outline.getView().scale;
|
||||
|
@ -727,10 +714,7 @@ class Outline {
|
|||
// Applies the new zoom
|
||||
const w = (<Rectangle>selectionBorder.bounds).width;
|
||||
const { scale } = source.getView();
|
||||
source.zoomTo(
|
||||
Math.max(this.minScale, scale - (dx * scale) / w),
|
||||
false
|
||||
);
|
||||
source.zoomTo(Math.max(this.minScale, scale - (dx * scale) / w), false);
|
||||
}
|
||||
|
||||
this.update();
|
||||
|
@ -752,11 +736,7 @@ class Outline {
|
|||
this.source.removeListener(this.refreshHandler);
|
||||
this.source.getModel().removeListener(this.updateHandler);
|
||||
this.source.getView().removeListener(this.updateHandler);
|
||||
InternalEvent.removeListener(
|
||||
this.source.container,
|
||||
'scroll',
|
||||
this.updateHandler
|
||||
);
|
||||
InternalEvent.removeListener(this.source.container, 'scroll', this.updateHandler);
|
||||
// @ts-ignore
|
||||
this.source = null;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import CellHighlight from '../selection/CellHighlight';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import utils, { intersectsHotspot } from '../../util/Utils';
|
||||
import utils, { intersectsHotspot, isNumeric } from '../../util/Utils';
|
||||
import graph from '../Graph';
|
||||
import { ColorValue } from '../../types';
|
||||
import CellState from './datatypes/CellState';
|
||||
|
@ -274,9 +274,9 @@ class CellMarker extends EventSource {
|
|||
* Sets and marks the current valid state.
|
||||
*/
|
||||
setCurrentState(
|
||||
state: CellState,
|
||||
state: CellState | null,
|
||||
me: InternalMouseEvent,
|
||||
color: ColorValue = null
|
||||
color: ColorValue | null = null
|
||||
) {
|
||||
const isValid = state ? this.isValidState(state) : false;
|
||||
color = color ?? this.getMarkerColor(me.getEvent(), state, isValid);
|
||||
|
@ -305,8 +305,7 @@ class CellMarker extends EventSource {
|
|||
*
|
||||
* Marks the given cell using the given color, or <validColor> if no color is specified.
|
||||
*/
|
||||
markCell(cell: Cell,
|
||||
color: ColorValue) {
|
||||
markCell(cell: Cell, color: ColorValue) {
|
||||
const state = this.graph.getView().getState(cell);
|
||||
|
||||
if (state) {
|
||||
|
@ -353,9 +352,7 @@ class CellMarker extends EventSource {
|
|||
* Returns the valid- or invalidColor depending on the value of isValid.
|
||||
* The given <mxCellState> is ignored by this implementation.
|
||||
*/
|
||||
getMarkerColor(evt: Event,
|
||||
state: CellState,
|
||||
isValid: boolean): string {
|
||||
getMarkerColor(evt: Event, state: CellState | null, isValid: boolean) {
|
||||
return isValid ? this.validColor : this.invalidColor;
|
||||
}
|
||||
|
||||
|
@ -379,7 +376,7 @@ class CellMarker extends EventSource {
|
|||
* Returns the <mxCell> for the given event and cell. This returns the
|
||||
* given cell.
|
||||
*/
|
||||
getCell(me: InternalMouseEvent): Cell {
|
||||
getCell(me: InternalMouseEvent) {
|
||||
return me.getCell();
|
||||
}
|
||||
|
||||
|
@ -400,17 +397,21 @@ class CellMarker extends EventSource {
|
|||
* This returns true if the <hotspot> is 0 or the coordinates are inside
|
||||
* the hotspot for the given cell state.
|
||||
*/
|
||||
intersects(state: CellState, me: InternalMouseEvent): boolean {
|
||||
if (this.hotspotEnabled) {
|
||||
intersects(state: CellState, me: InternalMouseEvent) {
|
||||
const x = me.getGraphX();
|
||||
const y = me.getGraphY();
|
||||
|
||||
if (this.hotspotEnabled && isNumeric(x) && isNumeric(y)) {
|
||||
return intersectsHotspot(
|
||||
state,
|
||||
me.getGraphX(),
|
||||
me.getGraphY(),
|
||||
x as number,
|
||||
y as number,
|
||||
this.hotspot,
|
||||
MIN_HOTSPOT_SIZE,
|
||||
MAX_HOTSPOT_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -419,9 +420,7 @@ class CellMarker extends EventSource {
|
|||
*
|
||||
* Destroys the handler and all its resources and DOM nodes.
|
||||
*/
|
||||
destroy(): void {
|
||||
this.graph.getView().removeListener(this.resetHandler);
|
||||
this.graph.getModel().removeListener(this.resetHandler);
|
||||
destroy() {
|
||||
this.highlight.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import Point from '../geometry/Point';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import EventSource from '../event/EventSource';
|
||||
import Image from '../image/Image';
|
||||
import CellState from "./datatypes/CellState";
|
||||
import ImageBox from '../image/ImageBox';
|
||||
import CellState from './datatypes/CellState';
|
||||
|
||||
/**
|
||||
* Class: mxCellOverlay
|
||||
|
@ -66,12 +66,14 @@ import CellState from "./datatypes/CellState";
|
|||
* (default).
|
||||
*/
|
||||
class CellOverlay extends EventSource {
|
||||
constructor(image: Image,
|
||||
tooltip: string | null=null,
|
||||
align: string='right',
|
||||
verticalAlign: string='bottom',
|
||||
offset: Point=new Point(),
|
||||
cursor: string='help') {
|
||||
constructor(
|
||||
image: ImageBox,
|
||||
tooltip: string | null = null,
|
||||
align: string = 'right',
|
||||
verticalAlign: string = 'bottom',
|
||||
offset: Point = new Point(),
|
||||
cursor: string = 'help'
|
||||
) {
|
||||
super();
|
||||
|
||||
this.image = image;
|
||||
|
@ -85,14 +87,14 @@ class CellOverlay extends EventSource {
|
|||
*
|
||||
* Holds the <mxImage> to be used as the icon.
|
||||
*/
|
||||
image: Image | null = null;
|
||||
image: ImageBox;
|
||||
|
||||
/**
|
||||
* Variable: tooltip
|
||||
*
|
||||
* Holds the optional string to be used as the tooltip.
|
||||
*/
|
||||
tooltip?: string | null = null;
|
||||
tooltip?: string | null;
|
||||
|
||||
/**
|
||||
* Variable: align
|
||||
|
@ -118,14 +120,14 @@ class CellOverlay extends EventSource {
|
|||
* Holds the offset as an <mxPoint>. The offset will be scaled according to the
|
||||
* current scale.
|
||||
*/
|
||||
offset: Point = new Point();
|
||||
offset = new Point();
|
||||
|
||||
/**
|
||||
* Variable: cursor
|
||||
*
|
||||
* Holds the cursor for the overlay. Default is 'help'.
|
||||
*/
|
||||
cursor: string = 'help';
|
||||
cursor = 'help';
|
||||
|
||||
/**
|
||||
* Variable: defaultOverlap
|
||||
|
@ -133,7 +135,7 @@ class CellOverlay extends EventSource {
|
|||
* Defines the overlapping for the overlay, that is, the proportional distance
|
||||
* from the origin to the point defined by the alignment. Default is 0.5.
|
||||
*/
|
||||
defaultOverlap: number = 0.5;
|
||||
defaultOverlap = 0.5;
|
||||
|
||||
/**
|
||||
* Function: getBounds
|
||||
|
@ -173,7 +175,7 @@ class CellOverlay extends EventSource {
|
|||
const s = state.view.scale;
|
||||
let pt = null;
|
||||
|
||||
const image = <Image>this.image;
|
||||
const image = this.image;
|
||||
const w = image.width;
|
||||
const h = image.height;
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ class CellRenderer {
|
|||
|
||||
if (shape) {
|
||||
shape.apply(state);
|
||||
shape.image = state.getImage();
|
||||
shape.imageSrc = state.getImage();
|
||||
shape.indicatorColor = state.getIndicatorColor();
|
||||
shape.indicatorStrokeColor = state.style.indicatorStrokeColor;
|
||||
shape.indicatorGradientColor = state.getIndicatorGradientColor();
|
||||
|
@ -371,11 +371,7 @@ class CellRenderer {
|
|||
} else if (value === 'indicated' && state.shape != null) {
|
||||
// @ts-ignore
|
||||
shape[field] = state.shape.indicatorColor;
|
||||
} else if (
|
||||
key !== 'fillColor' &&
|
||||
value === 'fillColor' &&
|
||||
state.shape != null
|
||||
) {
|
||||
} else if (key !== 'fillColor' && value === 'fillColor' && state.shape != null) {
|
||||
// @ts-ignore
|
||||
shape[field] = state.style.fillColor;
|
||||
} else if (
|
||||
|
@ -465,9 +461,7 @@ class CellRenderer {
|
|||
);
|
||||
state.text.opacity =
|
||||
state.style.textOpacity == null ? 100 : state.style.textOpacity;
|
||||
state.text.dialect = isForceHtml
|
||||
? DIALECT_STRICTHTML
|
||||
: state.view.graph.dialect;
|
||||
state.text.dialect = isForceHtml ? DIALECT_STRICTHTML : state.view.graph.dialect;
|
||||
state.text.style = state.style;
|
||||
state.text.state = state;
|
||||
this.initializeLabel(state, state.text);
|
||||
|
@ -489,9 +483,7 @@ class CellRenderer {
|
|||
// Dispatches the drop event to the graph which
|
||||
// consumes and executes the source function
|
||||
const pt = convertPoint(graph.container, x, y);
|
||||
result = <CellState>(
|
||||
graph.view.getState(graph.getCellAt(pt.x, pt.y))
|
||||
);
|
||||
result = <CellState>graph.view.getState(graph.getCellAt(pt.x, pt.y));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
@ -506,8 +498,7 @@ class CellRenderer {
|
|||
new InternalMouseEvent(evt, state)
|
||||
);
|
||||
forceGetCell =
|
||||
graph.dialect !== DIALECT_SVG &&
|
||||
getSource(evt).nodeName === 'IMG';
|
||||
graph.dialect !== DIALECT_SVG && getSource(evt).nodeName === 'IMG';
|
||||
}
|
||||
},
|
||||
(evt: MouseEvent) => {
|
||||
|
@ -576,8 +567,7 @@ class CellRenderer {
|
|||
dict = new Dictionary();
|
||||
|
||||
for (let i = 0; i < overlays.length; i += 1) {
|
||||
const shape =
|
||||
state.overlays != null ? state.overlays.remove(overlays[i]) : null;
|
||||
const shape = state.overlays != null ? state.overlays.remove(overlays[i]) : null;
|
||||
|
||||
if (shape == null) {
|
||||
const tmp = new ImageShape(
|
||||
|
@ -645,7 +635,7 @@ class CellRenderer {
|
|||
}
|
||||
|
||||
overlay.fireEvent(
|
||||
new EventObject(InternalEvent.CLICK, {event: evt, cell: state.cell})
|
||||
new EventObject(InternalEvent.CLICK, { event: evt, cell: state.cell })
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -655,14 +645,17 @@ class CellRenderer {
|
|||
InternalEvent.consume(evt);
|
||||
},
|
||||
(evt: Event) => {
|
||||
graph.event.fireMouseEvent(InternalEvent.MOUSE_MOVE, new InternalMouseEvent(evt, state));
|
||||
graph.event.fireMouseEvent(
|
||||
InternalEvent.MOUSE_MOVE,
|
||||
new InternalMouseEvent(evt, state)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
if (mxClient.IS_TOUCH) {
|
||||
InternalEvent.addListener(shape.node, 'touchend', (evt: Event) => {
|
||||
overlay.fireEvent(
|
||||
new EventObject(InternalEvent.CLICK, {event: evt, cell: state.cell})
|
||||
new EventObject(InternalEvent.CLICK, { event: evt, cell: state.cell })
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -746,9 +739,7 @@ class CellRenderer {
|
|||
// should go into the graph container directly in order to be clickable. Otherwise
|
||||
// it is obscured by the HTML label that overlaps the cell.
|
||||
const isForceHtml =
|
||||
graph.isHtmlLabel(state.cell) &&
|
||||
mxClient.NO_FO &&
|
||||
graph.dialect === DIALECT_SVG;
|
||||
graph.isHtmlLabel(state.cell) && mxClient.NO_FO && graph.dialect === DIALECT_SVG;
|
||||
|
||||
if (isForceHtml) {
|
||||
control.dialect = DIALECT_PREFERHTML;
|
||||
|
@ -791,7 +782,10 @@ class CellRenderer {
|
|||
);
|
||||
},
|
||||
(evt: Event) => {
|
||||
graph.event.fireMouseEvent(InternalEvent.MOUSE_UP, new InternalMouseEvent(evt, state));
|
||||
graph.event.fireMouseEvent(
|
||||
InternalEvent.MOUSE_UP,
|
||||
new InternalMouseEvent(evt, state)
|
||||
);
|
||||
InternalEvent.consume(evt);
|
||||
}
|
||||
);
|
||||
|
@ -833,8 +827,7 @@ class CellRenderer {
|
|||
* state - <mxCellState> whose shape fired the event.
|
||||
* evt - Mouse event which was fired.
|
||||
*/
|
||||
isShapeEvent(state: CellState,
|
||||
evt: InternalMouseEvent | MouseEvent): boolean {
|
||||
isShapeEvent(state: CellState, evt: InternalMouseEvent | MouseEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -849,8 +842,7 @@ class CellRenderer {
|
|||
* state - <mxCellState> whose label fired the event.
|
||||
* evt - Mouse event which was fired.
|
||||
*/
|
||||
isLabelEvent(state: CellState,
|
||||
evt: InternalMouseEvent | MouseEvent): boolean {
|
||||
isLabelEvent(state: CellState, evt: InternalMouseEvent | MouseEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -938,15 +930,13 @@ class CellRenderer {
|
|||
*
|
||||
* state - <mxCellState> whose label should be redrawn.
|
||||
*/
|
||||
redrawLabel(state: CellState,
|
||||
forced: boolean): void {
|
||||
redrawLabel(state: CellState, forced: boolean): void {
|
||||
const { graph } = state.view;
|
||||
const value = this.getLabelValue(state);
|
||||
const wrapping = graph.isWrapping(state.cell);
|
||||
const clipping = graph.isLabelClipped(state.cell);
|
||||
const isForceHtml =
|
||||
state.view.graph.isHtmlLabel(state.cell) ||
|
||||
(value != null && isNode(value));
|
||||
state.view.graph.isHtmlLabel(state.cell) || (value != null && isNode(value));
|
||||
const dialect = isForceHtml ? DIALECT_STRICTHTML : state.view.graph.dialect;
|
||||
const overflow = state.style.overflow || 'visible';
|
||||
|
||||
|
@ -961,11 +951,7 @@ class CellRenderer {
|
|||
state.text = null;
|
||||
}
|
||||
|
||||
if (
|
||||
state.text == null &&
|
||||
value != null &&
|
||||
(isNode(value) || value.length > 0)
|
||||
) {
|
||||
if (state.text == null && value != null && (isNode(value) || value.length > 0)) {
|
||||
this.createLabel(state, value);
|
||||
} else if (state.text != null && (value == null || value.length == 0)) {
|
||||
state.text.destroy();
|
||||
|
@ -977,10 +963,7 @@ class CellRenderer {
|
|||
// result in getLabelBounds we apply the new style to the shape
|
||||
if (forced) {
|
||||
// Checks if a full repaint is needed
|
||||
if (
|
||||
state.text.lastValue != null &&
|
||||
this.isTextShapeInvalid(state, state.text)
|
||||
) {
|
||||
if (state.text.lastValue != null && this.isTextShapeInvalid(state, state.text)) {
|
||||
// Forces a full repaint
|
||||
state.text.lastValue = null;
|
||||
}
|
||||
|
@ -1035,8 +1018,7 @@ class CellRenderer {
|
|||
* state - <mxCellState> whose label should be checked.
|
||||
* shape - <mxText> shape to be checked.
|
||||
*/
|
||||
isTextShapeInvalid(state: CellState,
|
||||
shape: TextShape): boolean {
|
||||
isTextShapeInvalid(state: CellState, shape: TextShape): boolean {
|
||||
function check(property: string, stylename: string, defaultValue: any) {
|
||||
let result = false;
|
||||
|
||||
|
@ -1049,8 +1031,7 @@ class CellRenderer {
|
|||
) {
|
||||
result =
|
||||
// @ts-ignore
|
||||
parseFloat(String(shape[property])) -
|
||||
parseFloat(String(shape.spacing)) !==
|
||||
parseFloat(String(shape[property])) - parseFloat(String(shape.spacing)) !==
|
||||
(state.style[stylename] || defaultValue);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
|
@ -1119,10 +1100,7 @@ class CellRenderer {
|
|||
const { graph } = state.view;
|
||||
const { scale } = state.view;
|
||||
const isEdge = state.cell.isEdge();
|
||||
let bounds = new Rectangle(
|
||||
state.absoluteOffset.x,
|
||||
state.absoluteOffset.y
|
||||
);
|
||||
let bounds = new Rectangle(state.absoluteOffset.x, state.absoluteOffset.y);
|
||||
|
||||
if (isEdge) {
|
||||
// @ts-ignore
|
||||
|
@ -1273,8 +1251,7 @@ class CellRenderer {
|
|||
*
|
||||
* state - <mxCellState> whose overlays should be redrawn.
|
||||
*/
|
||||
redrawCellOverlays(state: CellState,
|
||||
forced: boolean = false): void {
|
||||
redrawCellOverlays(state: CellState, forced: boolean = false): void {
|
||||
this.createCellOverlays(state);
|
||||
|
||||
if (state.overlays != null) {
|
||||
|
@ -1329,8 +1306,7 @@ class CellRenderer {
|
|||
*
|
||||
* state - <mxCellState> whose control should be redrawn.
|
||||
*/
|
||||
redrawControl(state: CellState,
|
||||
forced: boolean = false): void {
|
||||
redrawControl(state: CellState, forced: boolean = false): void {
|
||||
const image = state.view.graph.getFoldingImage(state);
|
||||
|
||||
if (state.control != null && image != null) {
|
||||
|
@ -1364,11 +1340,7 @@ class CellRenderer {
|
|||
* Returns the bounds to be used to draw the control (folding icon) of the
|
||||
* given state.
|
||||
*/
|
||||
getControlBounds(
|
||||
state: CellState,
|
||||
w: number,
|
||||
h: number
|
||||
): Rectangle | null {
|
||||
getControlBounds(state: CellState, w: number, h: number): Rectangle | null {
|
||||
if (state.control != null) {
|
||||
const s = state.view.scale;
|
||||
let cx = state.getCenterX();
|
||||
|
@ -1471,10 +1443,7 @@ class CellRenderer {
|
|||
if (shapeNode.parentNode === state.view.graph.container) {
|
||||
let { canvas } = state.view;
|
||||
|
||||
while (
|
||||
canvas != null &&
|
||||
canvas.parentNode !== state.view.graph.container
|
||||
) {
|
||||
while (canvas != null && canvas.parentNode !== state.view.graph.container) {
|
||||
// @ts-ignore
|
||||
canvas = canvas.parentNode;
|
||||
}
|
||||
|
@ -1482,10 +1451,7 @@ class CellRenderer {
|
|||
if (canvas != null && canvas.nextSibling != null) {
|
||||
if (canvas.nextSibling !== shapeNode) {
|
||||
// @ts-ignore
|
||||
shapeNode.parentNode.insertBefore(
|
||||
shapeNode,
|
||||
canvas.nextSibling
|
||||
);
|
||||
shapeNode.parentNode.insertBefore(shapeNode, canvas.nextSibling);
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
|
@ -1497,10 +1463,7 @@ class CellRenderer {
|
|||
shapeNode.parentNode.firstChild != shapeNode
|
||||
) {
|
||||
// Inserts the node as the first child of the parent to implement the order
|
||||
shapeNode.parentNode.insertBefore(
|
||||
shapeNode,
|
||||
shapeNode.parentNode.firstChild
|
||||
);
|
||||
shapeNode.parentNode.insertBefore(shapeNode, shapeNode.parentNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1527,9 +1490,7 @@ class CellRenderer {
|
|||
*
|
||||
* state - <mxCellState> whose shapes should be returned.
|
||||
*/
|
||||
getShapesForState(
|
||||
state: CellState
|
||||
): [Shape | null, TextShape | null, Shape | null] {
|
||||
getShapesForState(state: CellState): [Shape | null, TextShape | null, Shape | null] {
|
||||
return [state.shape, state.text, state.control];
|
||||
}
|
||||
|
||||
|
@ -1549,11 +1510,7 @@ class CellRenderer {
|
|||
* be drawn into the DOM. If this is false then redraw and/or reconfigure
|
||||
* will not be called on the shape.
|
||||
*/
|
||||
redraw(
|
||||
state: CellState,
|
||||
force: boolean = false,
|
||||
rendering: boolean = true
|
||||
): void {
|
||||
redraw(state: CellState, force: boolean = false, rendering: boolean = true): void {
|
||||
const shapeChanged = this.redrawShape(state, force, rendering);
|
||||
|
||||
if (state.shape != null && rendering) {
|
||||
|
@ -1628,8 +1585,7 @@ class CellRenderer {
|
|||
// Updates indicator shape
|
||||
if (
|
||||
state.shape != null &&
|
||||
state.shape.indicatorShape !=
|
||||
this.getShape(state.getIndicatorShape())
|
||||
state.shape.indicatorShape != this.getShape(state.getIndicatorShape())
|
||||
) {
|
||||
if (state.shape.indicator != null) {
|
||||
state.shape.indicator.destroy();
|
||||
|
@ -1658,12 +1614,7 @@ class CellRenderer {
|
|||
state.shape.bounds = null;
|
||||
} else {
|
||||
state.shape.points = null;
|
||||
state.shape.bounds = new Rectangle(
|
||||
state.x,
|
||||
state.y,
|
||||
state.width,
|
||||
state.height
|
||||
);
|
||||
state.shape.bounds = new Rectangle(state.x, state.y, state.width, state.height);
|
||||
}
|
||||
|
||||
state.shape.scale = state.view.scale;
|
||||
|
@ -1700,8 +1651,7 @@ class CellRenderer {
|
|||
shape.bounds == null ||
|
||||
shape.scale !== state.view.scale ||
|
||||
(state.absolutePoints == null && !shape.bounds.equals(state)) ||
|
||||
(state.absolutePoints != null &&
|
||||
!equalPoints(shape.points, state.absolutePoints))
|
||||
(state.absolutePoints != null && !equalPoints(shape.points, state.absolutePoints))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,15 @@ import Dictionary from '../../util/Dictionary';
|
|||
import GraphView from '../view/GraphView';
|
||||
import Cell from './datatypes/Cell';
|
||||
import CellState from './datatypes/CellState';
|
||||
import Shape from "../geometry/shape/Shape";
|
||||
import graph from "../Graph";
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
import graph from '../Graph';
|
||||
import CellArray from './datatypes/CellArray';
|
||||
|
||||
class TemporaryCellStates {
|
||||
constructor(
|
||||
view: GraphView,
|
||||
scale: number = 1,
|
||||
cells: Cell[],
|
||||
cells: CellArray,
|
||||
isCellVisibleFn: Function | null = null,
|
||||
getLinkForCellState: Function | null = null
|
||||
) {
|
||||
|
@ -31,17 +32,17 @@ class TemporaryCellStates {
|
|||
this.oldBounds = view.getGraphBounds();
|
||||
this.oldStates = view.getStates();
|
||||
this.oldScale = view.getScale();
|
||||
this.oldDoRedrawShape = (<graph>view.graph).cellRenderer.doRedrawShape;
|
||||
this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape;
|
||||
|
||||
const self = this;
|
||||
|
||||
// Overrides doRedrawShape and paint shape to add links on shapes
|
||||
if (getLinkForCellState != null) {
|
||||
(<graph>view.graph).cellRenderer.doRedrawShape = (state: CellState) => {
|
||||
view.graph.cellRenderer.doRedrawShape = (state: CellState) => {
|
||||
const shape = <Shape>state?.shape;
|
||||
const oldPaint = shape.paint;
|
||||
|
||||
shape.paint = c => {
|
||||
shape.paint = (c) => {
|
||||
const link = getLinkForCellState(state);
|
||||
if (link != null) {
|
||||
c.setLink(link);
|
||||
|
@ -52,7 +53,7 @@ class TemporaryCellStates {
|
|||
}
|
||||
};
|
||||
|
||||
(<Function>self.oldDoRedrawShape).apply((<graph>view.graph).cellRenderer, [state]);
|
||||
(<Function>self.oldDoRedrawShape).apply(view.graph.cellRenderer, [state]);
|
||||
shape.paint = oldPaint;
|
||||
};
|
||||
}
|
||||
|
@ -66,10 +67,9 @@ class TemporaryCellStates {
|
|||
};
|
||||
|
||||
// Creates space for new states
|
||||
view.setStates(new mxDictionary());
|
||||
view.setStates(new Dictionary());
|
||||
view.setScale(scale);
|
||||
|
||||
if (cells != null) {
|
||||
view.resetValidationState();
|
||||
let bbox = null;
|
||||
|
||||
|
@ -82,54 +82,38 @@ class TemporaryCellStates {
|
|||
if (bbox == null) {
|
||||
bbox = bounds;
|
||||
} else {
|
||||
bbox.add(bounds);
|
||||
bbox.add(<Rectangle>bounds);
|
||||
}
|
||||
}
|
||||
view.setGraphBounds(bbox || new Rectangle());
|
||||
}
|
||||
}
|
||||
|
||||
oldValidateCellState: Function | null;
|
||||
|
||||
oldDoRedrawShape: Function | null;
|
||||
|
||||
/**
|
||||
* Holds the width of the rectangle.
|
||||
* @default 0
|
||||
*/
|
||||
// view: number;
|
||||
view: GraphView | null = null;
|
||||
view: GraphView;
|
||||
|
||||
/**
|
||||
* Holds the height of the rectangle.
|
||||
* @default 0
|
||||
* Holds the states of the rectangle.
|
||||
*/
|
||||
// oldStates: number;
|
||||
oldStates: Dictionary | null = null;
|
||||
oldStates: Dictionary<string, CellState>;
|
||||
|
||||
/**
|
||||
* Holds the height of the rectangle.
|
||||
* @default 0
|
||||
* Holds the bounds of the rectangle.
|
||||
*/
|
||||
// oldBounds: number;
|
||||
oldBounds: Rectangle | null = null;
|
||||
oldBounds: Rectangle;
|
||||
|
||||
/**
|
||||
* Holds the height of the rectangle.
|
||||
* @default 0
|
||||
* Holds the scale of the rectangle.
|
||||
*/
|
||||
oldScale: number = 0;
|
||||
oldScale: number;
|
||||
|
||||
/**
|
||||
* Holds the height of the rectangle.
|
||||
* @default 0
|
||||
*/
|
||||
// destroy(): void;
|
||||
destroy(): void {
|
||||
const view = <GraphView>this.view;
|
||||
const view = this.view;
|
||||
view.setScale(this.oldScale);
|
||||
view.setStates(this.oldStates);
|
||||
view.setGraphBounds(<Rectangle>this.oldBounds);
|
||||
view.setGraphBounds(this.oldBounds);
|
||||
// @ts-ignore
|
||||
view.validateCellState = <Function>this.oldValidateCellState;
|
||||
// @ts-ignore
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Cell from "./Cell";
|
||||
import Dictionary from "../../../util/Dictionary";
|
||||
import mxObjectIdentity from "../../../util/mxObjectIdentity";
|
||||
import Cell from './Cell';
|
||||
import Dictionary from '../../../util/Dictionary';
|
||||
import ObjectIdentity from '../../../util/ObjectIdentity';
|
||||
|
||||
class CellArray extends Array<Cell> {
|
||||
// @ts-ignore
|
||||
|
@ -25,12 +25,12 @@ class CellArray extends Array<Cell> {
|
|||
|
||||
// @ts-ignore
|
||||
map(arg0: any, ...args: any): CellArray {
|
||||
return new CellArray(...<Cell[]>super.map(arg0, ...args));
|
||||
return new CellArray(...(<Cell[]>super.map(arg0, ...args)));
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
filter(arg0: any, ...args: any): CellArray {
|
||||
return new CellArray(...<Cell[]>super.filter(arg0, ...args));
|
||||
return new CellArray(...(<Cell[]>super.filter(arg0, ...args)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,10 +59,11 @@ class CellArray extends Array<Cell> {
|
|||
* @param targets Boolean that specifies if target terminals should be contained
|
||||
* in the result. Default is true.
|
||||
*/
|
||||
getOpposites(terminal: Cell,
|
||||
sources: boolean=true,
|
||||
targets: boolean=true): CellArray {
|
||||
|
||||
getOpposites(
|
||||
terminal: Cell,
|
||||
sources: boolean = true,
|
||||
targets: boolean = true
|
||||
): CellArray {
|
||||
const terminals = new CellArray();
|
||||
|
||||
for (let i = 0; i < this.length; i += 1) {
|
||||
|
@ -72,24 +73,14 @@ class CellArray extends Array<Cell> {
|
|||
// Checks if the terminal is the source of
|
||||
// the edge and if the target should be
|
||||
// stored in the result
|
||||
if (
|
||||
source === terminal &&
|
||||
target != null &&
|
||||
target !== terminal &&
|
||||
targets
|
||||
) {
|
||||
if (source === terminal && target != null && target !== terminal && targets) {
|
||||
terminals.push(target);
|
||||
}
|
||||
|
||||
// Checks if the terminal is the taget of
|
||||
// the edge and if the source should be
|
||||
// stored in the result
|
||||
else if (
|
||||
target === terminal &&
|
||||
source != null &&
|
||||
source !== terminal &&
|
||||
sources
|
||||
) {
|
||||
else if (target === terminal && source != null && source !== terminal && sources) {
|
||||
terminals.push(source);
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +148,7 @@ class CellArray extends Array<Cell> {
|
|||
* with all descendants.
|
||||
* @param mapping Optional mapping for existing clones.
|
||||
*/
|
||||
cloneCells(includeChildren: boolean=true,
|
||||
mapping: any={}): CellArray {
|
||||
|
||||
cloneCells(includeChildren: boolean = true, mapping: any = {}): CellArray {
|
||||
const clones: CellArray = new CellArray();
|
||||
|
||||
for (const cell of this) {
|
||||
|
@ -179,11 +168,8 @@ class CellArray extends Array<Cell> {
|
|||
*
|
||||
* @private
|
||||
*/
|
||||
cloneCellImpl(cell: Cell,
|
||||
mapping: any={},
|
||||
includeChildren: boolean): Cell {
|
||||
|
||||
const ident = <string>mxObjectIdentity.get(cell);
|
||||
cloneCellImpl(cell: Cell, mapping: any = {}, includeChildren: boolean): Cell {
|
||||
const ident = ObjectIdentity.get(cell);
|
||||
let clone = mapping ? mapping[ident] : null;
|
||||
|
||||
if (clone == null) {
|
||||
|
@ -194,11 +180,7 @@ class CellArray extends Array<Cell> {
|
|||
const childCount = cell.getChildCount();
|
||||
|
||||
for (let i = 0; i < childCount; i += 1) {
|
||||
const cloneChild = this.cloneCellImpl(
|
||||
<Cell>cell.getChildAt(i),
|
||||
mapping,
|
||||
true
|
||||
);
|
||||
const cloneChild = this.cloneCellImpl(<Cell>cell.getChildAt(i), mapping, true);
|
||||
clone.insert(cloneChild);
|
||||
}
|
||||
}
|
||||
|
@ -212,14 +194,11 @@ class CellArray extends Array<Cell> {
|
|||
*
|
||||
* @private
|
||||
*/
|
||||
restoreClone(clone: Cell,
|
||||
cell: Cell,
|
||||
mapping: any): void {
|
||||
|
||||
restoreClone(clone: Cell, cell: Cell, mapping: any): void {
|
||||
const source = cell.getTerminal(true);
|
||||
|
||||
if (source != null) {
|
||||
const tmp = mapping[mxObjectIdentity.get(source)];
|
||||
const tmp = mapping[ObjectIdentity.get(source)];
|
||||
if (tmp != null) {
|
||||
tmp.insertEdge(clone, true);
|
||||
}
|
||||
|
@ -227,7 +206,7 @@ class CellArray extends Array<Cell> {
|
|||
|
||||
const target = cell.getTerminal(false);
|
||||
if (target != null) {
|
||||
const tmp = mapping[mxObjectIdentity.get(target)];
|
||||
const tmp = mapping[ObjectIdentity.get(target)];
|
||||
if (tmp != null) {
|
||||
tmp.insertEdge(clone, false);
|
||||
}
|
||||
|
@ -235,11 +214,7 @@ class CellArray extends Array<Cell> {
|
|||
|
||||
const childCount = clone.getChildCount();
|
||||
for (let i = 0; i < childCount; i += 1) {
|
||||
this.restoreClone(
|
||||
<Cell>clone.getChildAt(i),
|
||||
<Cell>cell.getChildAt(i),
|
||||
mapping
|
||||
);
|
||||
this.restoreClone(<Cell>clone.getChildAt(i), <Cell>cell.getChildAt(i), mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ import GraphView from '../../view/GraphView';
|
|||
import Shape from '../../geometry/shape/Shape';
|
||||
import TextShape from '../../geometry/shape/node/TextShape';
|
||||
import Dictionary from '../../../util/Dictionary';
|
||||
import { NONE } from '../../../util/Constants';
|
||||
|
||||
import type { CellStateStyles } from '../../../types';
|
||||
import Image from "../../image/Image";
|
||||
import {ALIGN_MIDDLE, NONE} from "../../../util/Constants";
|
||||
import {getValue} from "../../../util/Utils";
|
||||
|
||||
/**
|
||||
* Class: mxCellState
|
||||
|
@ -210,20 +208,11 @@ class CellState extends Rectangle {
|
|||
*/
|
||||
getPerimeterBounds(
|
||||
border: number = 0,
|
||||
bounds: Rectangle = new Rectangle(
|
||||
this.x,
|
||||
this.y,
|
||||
this.width,
|
||||
this.height
|
||||
)
|
||||
) {
|
||||
if (
|
||||
this.shape &&
|
||||
this.shape.stencil &&
|
||||
this.shape.stencil.aspect === 'fixed'
|
||||
bounds: Rectangle = new Rectangle(this.x, this.y, this.width, this.height)
|
||||
) {
|
||||
if (this.shape?.stencil?.aspect === 'fixed') {
|
||||
const aspect = this.shape.stencil.computeAspect(
|
||||
this.style,
|
||||
this.shape,
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
|
@ -455,6 +444,7 @@ class CellState extends Rectangle {
|
|||
isLoop(state: CellState) {
|
||||
const src = this.getVisibleTerminalState(true);
|
||||
const trg = this.getVisibleTerminalState(false);
|
||||
|
||||
return src && src === trg;
|
||||
}
|
||||
|
||||
|
@ -470,10 +460,8 @@ class CellState extends Rectangle {
|
|||
* @param state {@link mxCellState} whose vertical alignment should be
|
||||
* returned.
|
||||
*/
|
||||
getVerticalAlign(): string | null {
|
||||
return this.style != null
|
||||
? this.style.verticalAlign || ALIGN_MIDDLE
|
||||
: null;
|
||||
getVerticalAlign() {
|
||||
return this.style.verticalAlign;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -481,11 +469,14 @@ class CellState extends Rectangle {
|
|||
*
|
||||
* @param state {@link mxCellState} to check.
|
||||
*/
|
||||
isTransparentState(): boolean {
|
||||
isTransparentState() {
|
||||
let result = false;
|
||||
const stroke = getValue(this.style, 'strokeColor', NONE);
|
||||
const fill = getValue(this.style, 'fillColor', NONE);
|
||||
result = stroke === NONE && fill === NONE && this.getImage(state) == null;
|
||||
|
||||
const stroke = this.style.strokeColor;
|
||||
const fill = this.style.fillColor;
|
||||
|
||||
result = stroke === NONE && fill === NONE && !this.getImageSrc();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -496,10 +487,8 @@ class CellState extends Rectangle {
|
|||
*
|
||||
* @param state {@link mxCellState} whose image URL should be returned.
|
||||
*/
|
||||
getImage(): Image | null {
|
||||
return this.style != null
|
||||
? this.style.image
|
||||
: null;
|
||||
getImageSrc() {
|
||||
return this.style.image;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -510,10 +499,8 @@ class CellState extends Rectangle {
|
|||
* @param state {@link mxCellState} whose indicator color should be
|
||||
* returned.
|
||||
*/
|
||||
getIndicatorColor(): string | null {
|
||||
return this.style != null
|
||||
? this.style.indicatorColor
|
||||
: null;
|
||||
getIndicatorColor() {
|
||||
return this.style.indicatorColor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -524,10 +511,8 @@ class CellState extends Rectangle {
|
|||
* @param state {@link mxCellState} whose indicator gradient color should be
|
||||
* returned.
|
||||
*/
|
||||
getIndicatorGradientColor(): string | null {
|
||||
return this.style != null
|
||||
? this.style.gradientColor
|
||||
: null;
|
||||
getIndicatorGradientColor() {
|
||||
return this.style.gradientColor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -537,10 +522,8 @@ class CellState extends Rectangle {
|
|||
*
|
||||
* @param state {@link mxCellState} whose indicator shape should be returned.
|
||||
*/
|
||||
getIndicatorShape(): string | null {
|
||||
return this.style != null
|
||||
? this.style.indicatorShape
|
||||
: null;
|
||||
getIndicatorShape() {
|
||||
return this.style.indicatorShape;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -550,10 +533,8 @@ class CellState extends Rectangle {
|
|||
*
|
||||
* @param state {@link mxCellState} whose indicator image should be returned.
|
||||
*/
|
||||
getIndicatorImage(): Image | null {
|
||||
return this.style != null
|
||||
? this.style.indicatorImage
|
||||
: null;
|
||||
getIndicatorImageSrc() {
|
||||
return this.style.indicatorImage;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,11 +77,7 @@ class EdgeHandler {
|
|||
this.reset();
|
||||
|
||||
if (dirty) {
|
||||
this.graph.cellRenderer.redraw(
|
||||
this.state,
|
||||
false,
|
||||
state.view.isRendering()
|
||||
);
|
||||
this.graph.cellRenderer.redraw(this.state, false, state.view.isRendering());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -329,10 +325,7 @@ class EdgeHandler {
|
|||
this.parentHighlight.redraw();
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
pstate != null &&
|
||||
pstate.parentHighlight === this.parentHighlight
|
||||
) {
|
||||
if (pstate != null && pstate.parentHighlight === this.parentHighlight) {
|
||||
pstate.parentHighlight = null;
|
||||
}
|
||||
|
||||
|
@ -340,18 +333,12 @@ class EdgeHandler {
|
|||
this.parentHighlight = null;
|
||||
}
|
||||
} else if (this.parentHighlightEnabled && visible) {
|
||||
if (
|
||||
parent.isVertex() &&
|
||||
pstate != null &&
|
||||
pstate.parentHighlight == null
|
||||
) {
|
||||
if (parent.isVertex() && pstate != null && pstate.parentHighlight == null) {
|
||||
this.parentHighlight = this.createParentHighlightShape(pstate);
|
||||
// VML dialect required here for event transparency in IE
|
||||
this.parentHighlight.dialect = DIALECT_SVG;
|
||||
this.parentHighlight.pointerEvents = false;
|
||||
this.parentHighlight.rotation = Number(
|
||||
pstate.style.rotation || '0'
|
||||
);
|
||||
this.parentHighlight.rotation = Number(pstate.style.rotation || '0');
|
||||
this.parentHighlight.init(this.graph.getView().getOverlayPane());
|
||||
this.parentHighlight.redraw();
|
||||
|
||||
|
@ -390,8 +377,7 @@ class EdgeHandler {
|
|||
|
||||
// Updates preferHtml
|
||||
this.preferHtml =
|
||||
this.state.text != null &&
|
||||
this.state.text.node.parentNode === this.graph.container;
|
||||
this.state.text != null && this.state.text.node.parentNode === this.graph.container;
|
||||
|
||||
if (!this.preferHtml) {
|
||||
// Checks source terminal
|
||||
|
@ -429,10 +415,7 @@ class EdgeHandler {
|
|||
}
|
||||
|
||||
// Adds a rectangular handle for the label position
|
||||
this.label = new Point(
|
||||
this.state.absoluteOffset.x,
|
||||
this.state.absoluteOffset.y
|
||||
);
|
||||
this.label = new Point(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
|
||||
this.labelShape = this.createLabelHandleShape();
|
||||
this.initBend(this.labelShape);
|
||||
this.labelShape.setCursor(CURSOR_LABEL_HANDLE);
|
||||
|
@ -525,7 +508,7 @@ class EdgeHandler {
|
|||
null,
|
||||
this.getSelectionColor()
|
||||
);
|
||||
shape.strokewidth = this.getSelectionStrokeWidth();
|
||||
shape.strokeWidth = this.getSelectionStrokeWidth();
|
||||
shape.isDashed = this.isSelectionDashed();
|
||||
|
||||
return shape;
|
||||
|
@ -616,10 +599,7 @@ class EdgeHandler {
|
|||
let cell = super.getCell(me);
|
||||
|
||||
// Checks for cell at preview point (with grid)
|
||||
if (
|
||||
(cell === self.state.cell || cell == null) &&
|
||||
self.currentPoint != null
|
||||
) {
|
||||
if ((cell === self.state.cell || cell == null) && self.currentPoint != null) {
|
||||
cell = self.graph.getCellAt(self.currentPoint.x, self.currentPoint.y);
|
||||
}
|
||||
|
||||
|
@ -722,9 +702,7 @@ class EdgeHandler {
|
|||
});
|
||||
|
||||
if (this.isHandleEnabled(i)) {
|
||||
bend.setCursor(
|
||||
terminal ? CURSOR_TERMINAL_HANDLE : CURSOR_BEND_HANDLE
|
||||
);
|
||||
bend.setCursor(terminal ? CURSOR_TERMINAL_HANDLE : CURSOR_BEND_HANDLE);
|
||||
}
|
||||
|
||||
bends.push(bend);
|
||||
|
@ -842,12 +820,7 @@ class EdgeHandler {
|
|||
createLabelHandleShape() {
|
||||
if (this.labelHandleImage != null) {
|
||||
const shape = new ImageShape(
|
||||
new Rectangle(
|
||||
0,
|
||||
0,
|
||||
this.labelHandleImage.width,
|
||||
this.labelHandleImage.height
|
||||
),
|
||||
new Rectangle(0, 0, this.labelHandleImage.width, this.labelHandleImage.height),
|
||||
this.labelHandleImage.src
|
||||
);
|
||||
|
||||
|
@ -879,8 +852,7 @@ class EdgeHandler {
|
|||
bend.dialect = DIALECT_STRICTHTML;
|
||||
bend.init(this.graph.container);
|
||||
} else {
|
||||
bend.dialect =
|
||||
this.graph.dialect !== DIALECT_SVG ? DIALECT_MIXEDHTML : DIALECT_SVG;
|
||||
bend.dialect = this.graph.dialect !== DIALECT_SVG ? DIALECT_MIXEDHTML : DIALECT_SVG;
|
||||
bend.init(this.graph.getView().getOverlayPane());
|
||||
}
|
||||
|
||||
|
@ -913,12 +885,7 @@ class EdgeHandler {
|
|||
const tol = !isMouseEvent(me.getEvent()) ? this.tolerance : 1;
|
||||
const hit =
|
||||
this.allowHandleBoundsCheck && tol > 0
|
||||
? new Rectangle(
|
||||
me.getGraphX() - tol,
|
||||
me.getGraphY() - tol,
|
||||
2 * tol,
|
||||
2 * tol
|
||||
)
|
||||
? new Rectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol)
|
||||
: null;
|
||||
let minDistSq = null;
|
||||
|
||||
|
@ -928,8 +895,7 @@ class EdgeHandler {
|
|||
shape.node != null &&
|
||||
shape.node.style.display !== 'none' &&
|
||||
shape.node.style.visibility !== 'hidden' &&
|
||||
(me.isSource(shape) ||
|
||||
(hit != null && utils.intersects(shape.bounds, hit)))
|
||||
(me.isSource(shape) || (hit != null && utils.intersects(shape.bounds, hit)))
|
||||
) {
|
||||
const dx = me.getGraphX() - shape.bounds.getCenterX();
|
||||
const dy = me.getGraphY() - shape.bounds.getCenterY();
|
||||
|
@ -1019,11 +985,7 @@ class EdgeHandler {
|
|||
this.snapPoint = new Point(b.getCenterX(), b.getCenterY());
|
||||
}
|
||||
|
||||
if (
|
||||
this.addEnabled &&
|
||||
handle == null &&
|
||||
this.isAddPointEvent(me.getEvent())
|
||||
) {
|
||||
if (this.addEnabled && handle == null && this.isAddPointEvent(me.getEvent())) {
|
||||
this.addPoint(this.state, me.getEvent());
|
||||
me.consume();
|
||||
} else if (handle != null && !me.isConsumed() && this.graph.isEnabled()) {
|
||||
|
@ -1058,8 +1020,7 @@ class EdgeHandler {
|
|||
this.startY = y;
|
||||
|
||||
this.isSource = this.bends == null ? false : index === 0;
|
||||
this.isTarget =
|
||||
this.bends == null ? false : index === this.bends.length - 1;
|
||||
this.isTarget = this.bends == null ? false : index === this.bends.length - 1;
|
||||
this.isLabel = index === InternalEvent.LABEL_HANDLE;
|
||||
|
||||
if (this.isSource || this.isTarget) {
|
||||
|
@ -1067,8 +1028,7 @@ class EdgeHandler {
|
|||
const terminal = cell.getTerminal(this.isSource);
|
||||
|
||||
if (
|
||||
(terminal == null &&
|
||||
this.graph.isTerminalPointMovable(cell, this.isSource)) ||
|
||||
(terminal == null && this.graph.isTerminalPointMovable(cell, this.isSource)) ||
|
||||
(terminal != null &&
|
||||
this.graph.isCellDisconnectable(cell, terminal, this.isSource))
|
||||
) {
|
||||
|
@ -1189,10 +1149,7 @@ class EdgeHandler {
|
|||
const snapToTerminal = (terminal) => {
|
||||
if (terminal != null) {
|
||||
snapToPoint(
|
||||
new point(
|
||||
view.getRoutingCenterX(terminal),
|
||||
view.getRoutingCenterY(terminal)
|
||||
)
|
||||
new point(view.getRoutingCenterX(terminal), view.getRoutingCenterY(terminal))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1245,8 +1202,7 @@ class EdgeHandler {
|
|||
if (
|
||||
this.marker.highlight != null &&
|
||||
this.marker.highlight.state != null &&
|
||||
this.marker.highlight.state.cell ===
|
||||
this.constraintHandler.currentFocus.cell
|
||||
this.marker.highlight.state.cell === this.constraintHandler.currentFocus.cell
|
||||
) {
|
||||
// Direct repaint needed if cell already highlighted
|
||||
if (this.marker.highlight.shape.stroke !== 'transparent') {
|
||||
|
@ -1254,10 +1210,7 @@ class EdgeHandler {
|
|||
this.marker.highlight.repaint();
|
||||
}
|
||||
} else {
|
||||
this.marker.markCell(
|
||||
this.constraintHandler.currentFocus.cell,
|
||||
'transparent'
|
||||
);
|
||||
this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
|
||||
}
|
||||
|
||||
const model = this.graph.getModel();
|
||||
|
@ -1267,12 +1220,8 @@ class EdgeHandler {
|
|||
!this.isSource
|
||||
);
|
||||
const otherCell = other != null ? other.cell : null;
|
||||
const source = this.isSource
|
||||
? this.constraintHandler.currentFocus.cell
|
||||
: otherCell;
|
||||
const target = this.isSource
|
||||
? otherCell
|
||||
: this.constraintHandler.currentFocus.cell;
|
||||
const source = this.isSource ? this.constraintHandler.currentFocus.cell : otherCell;
|
||||
const target = this.isSource ? otherCell : this.constraintHandler.currentFocus.cell;
|
||||
|
||||
// Updates the error message of the handler
|
||||
this.error = this.validateConnection(source, target);
|
||||
|
@ -1282,10 +1231,7 @@ class EdgeHandler {
|
|||
result = this.constraintHandler.currentFocus;
|
||||
}
|
||||
|
||||
if (
|
||||
this.error != null ||
|
||||
(result != null && !this.isCellEnabled(result.cell))
|
||||
) {
|
||||
if (this.error != null || (result != null && !this.isCellEnabled(result.cell))) {
|
||||
this.constraintHandler.reset();
|
||||
}
|
||||
|
||||
|
@ -1367,11 +1313,7 @@ class EdgeHandler {
|
|||
const src = this.state.getVisibleTerminalState(true);
|
||||
|
||||
if (src != null) {
|
||||
const c = this.graph.getConnectionConstraint(
|
||||
this.state,
|
||||
src,
|
||||
true
|
||||
);
|
||||
const c = this.graph.getConnectionConstraint(this.state, src, true);
|
||||
|
||||
// Checks if point is not fixed
|
||||
if (c == null || this.graph.getConnectionPoint(src, c) == null) {
|
||||
|
@ -1385,11 +1327,7 @@ class EdgeHandler {
|
|||
const trg = this.state.getVisibleTerminalState(false);
|
||||
|
||||
if (trg != null) {
|
||||
const c = this.graph.getConnectionConstraint(
|
||||
this.state,
|
||||
trg,
|
||||
false
|
||||
);
|
||||
const c = this.graph.getConnectionConstraint(this.state, trg, false);
|
||||
|
||||
// Checks if point is not fixed
|
||||
if (c == null || this.graph.getConnectionPoint(trg, c) == null) {
|
||||
|
@ -1453,10 +1391,8 @@ class EdgeHandler {
|
|||
const left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||||
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||||
|
||||
const gridX =
|
||||
this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
|
||||
const gridY =
|
||||
this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
|
||||
const gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
|
||||
const gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
|
||||
|
||||
return (
|
||||
this.outlineConnect &&
|
||||
|
@ -1484,16 +1420,8 @@ class EdgeHandler {
|
|||
? terminalState
|
||||
: this.state.getVisibleTerminalState(false);
|
||||
|
||||
let sourceConstraint = this.graph.getConnectionConstraint(
|
||||
edge,
|
||||
sourceState,
|
||||
true
|
||||
);
|
||||
let targetConstraint = this.graph.getConnectionConstraint(
|
||||
edge,
|
||||
targetState,
|
||||
false
|
||||
);
|
||||
let sourceConstraint = this.graph.getConnectionConstraint(edge, sourceState, true);
|
||||
let targetConstraint = this.graph.getConnectionConstraint(edge, targetState, false);
|
||||
|
||||
let constraint = this.constraintHandler.currentConstraint;
|
||||
|
||||
|
@ -1528,13 +1456,11 @@ class EdgeHandler {
|
|||
this.marker.highlight.shape.stroke = outline
|
||||
? OUTLINE_HIGHLIGHT_COLOR
|
||||
: 'transparent';
|
||||
this.marker.highlight.shape.strokewidth =
|
||||
OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
this.marker.highlight.shape.strokewidth = OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
this.marker.highlight.repaint();
|
||||
} else if (this.marker.hasValidState()) {
|
||||
this.marker.highlight.shape.stroke =
|
||||
me.getCell().isConnectable() &&
|
||||
this.marker.getValidState() !== me.getState()
|
||||
me.getCell().isConnectable() && this.marker.getValidState() !== me.getState()
|
||||
? 'transparent'
|
||||
: DEFAULT_VALID_COLOR;
|
||||
this.marker.highlight.shape.strokewidth = HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
|
@ -1550,10 +1476,8 @@ class EdgeHandler {
|
|||
|
||||
if (this.isSource || this.isTarget) {
|
||||
if (constraint != null && constraint.point != null) {
|
||||
edge.style[this.isSource ? 'exitX' : 'entryX'] =
|
||||
constraint.point.x;
|
||||
edge.style[this.isSource ? 'exitY' : 'entryY'] =
|
||||
constraint.point.y;
|
||||
edge.style[this.isSource ? 'exitX' : 'entryX'] = constraint.point.x;
|
||||
edge.style[this.isSource ? 'exitY' : 'entryY'] = constraint.point.y;
|
||||
} else {
|
||||
delete edge.style[this.isSource ? 'exitX' : 'entryX'];
|
||||
delete edge.style[this.isSource ? 'exitY' : 'entryY'];
|
||||
|
@ -1564,21 +1488,11 @@ class EdgeHandler {
|
|||
edge.setVisibleTerminalState(targetState, false);
|
||||
|
||||
if (!this.isSource || sourceState != null) {
|
||||
edge.view.updateFixedTerminalPoint(
|
||||
edge,
|
||||
sourceState,
|
||||
true,
|
||||
sourceConstraint
|
||||
);
|
||||
edge.view.updateFixedTerminalPoint(edge, sourceState, true, sourceConstraint);
|
||||
}
|
||||
|
||||
if (!this.isTarget || targetState != null) {
|
||||
edge.view.updateFixedTerminalPoint(
|
||||
edge,
|
||||
targetState,
|
||||
false,
|
||||
targetConstraint
|
||||
);
|
||||
edge.view.updateFixedTerminalPoint(edge, targetState, false, targetConstraint);
|
||||
}
|
||||
|
||||
if ((this.isSource || this.isTarget) && terminalState == null) {
|
||||
|
@ -1625,12 +1539,8 @@ class EdgeHandler {
|
|||
this.index > InternalEvent.VIRTUAL_HANDLE
|
||||
) {
|
||||
if (this.customHandles != null) {
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].processEvent(
|
||||
me
|
||||
);
|
||||
this.customHandles[
|
||||
InternalEvent.CUSTOM_HANDLE - this.index
|
||||
].positionChanged();
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].processEvent(me);
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].positionChanged();
|
||||
|
||||
if (this.shape != null && this.shape.node != null) {
|
||||
this.shape.node.style.display = 'none';
|
||||
|
@ -1642,9 +1552,7 @@ class EdgeHandler {
|
|||
} else {
|
||||
this.points = this.getPreviewPoints(this.currentPoint, me);
|
||||
let terminalState =
|
||||
this.isSource || this.isTarget
|
||||
? this.getPreviewTerminalState(me)
|
||||
: null;
|
||||
this.isSource || this.isTarget ? this.getPreviewTerminalState(me) : null;
|
||||
|
||||
if (
|
||||
this.constraintHandler.currentConstraint != null &&
|
||||
|
@ -1655,9 +1563,7 @@ class EdgeHandler {
|
|||
} else if (this.outlineConnect) {
|
||||
// Need to check outline before cloning terminal state
|
||||
const outline =
|
||||
this.isSource || this.isTarget
|
||||
? this.isOutlineConnectEvent(me)
|
||||
: false;
|
||||
this.isSource || this.isTarget ? this.isOutlineConnectEvent(me) : false;
|
||||
|
||||
if (outline) {
|
||||
terminalState = this.marker.highlight.state;
|
||||
|
@ -1693,9 +1599,7 @@ class EdgeHandler {
|
|||
// Sets the color of the preview to valid or invalid, updates the
|
||||
// points of the preview and redraws
|
||||
const color =
|
||||
this.error == null
|
||||
? this.marker.validColor
|
||||
: this.marker.invalidColor;
|
||||
this.error == null ? this.marker.validColor : this.marker.invalidColor;
|
||||
this.setPreviewColor(color);
|
||||
this.abspoints = clone.absolutePoints;
|
||||
this.active = true;
|
||||
|
@ -1813,9 +1717,7 @@ class EdgeHandler {
|
|||
model.endUpdate();
|
||||
}
|
||||
} else if (this.graph.isAllowDanglingEdges()) {
|
||||
const pt = this.abspoints[
|
||||
this.isSource ? 0 : this.abspoints.length - 1
|
||||
];
|
||||
const pt = this.abspoints[this.isSource ? 0 : this.abspoints.length - 1];
|
||||
pt.x = this.roundLength(
|
||||
pt.x / this.graph.view.scale - this.graph.view.translate.x
|
||||
);
|
||||
|
@ -2074,12 +1976,7 @@ class EdgeHandler {
|
|||
geo = geo.clone();
|
||||
geo.setTerminalPoint(point, isSource);
|
||||
model.setGeometry(edge, geo);
|
||||
this.graph.connectCell(
|
||||
edge,
|
||||
null,
|
||||
isSource,
|
||||
new ConnectionConstraint()
|
||||
);
|
||||
this.graph.connectCell(edge, null, isSource, new ConnectionConstraint());
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
|
@ -2130,11 +2027,7 @@ class EdgeHandler {
|
|||
*/
|
||||
// addPoint(state: mxCellState, evt: Event): void;
|
||||
addPoint(state, evt) {
|
||||
const pt = utils.convertPoint(
|
||||
this.graph.container,
|
||||
getClientX(evt),
|
||||
getClientY(evt)
|
||||
);
|
||||
const pt = utils.convertPoint(this.graph.container, getClientX(evt), getClientY(evt));
|
||||
const gridEnabled = this.graph.isGridEnabledEvent(evt);
|
||||
this.convertPoint(pt, gridEnabled);
|
||||
this.addPointAt(state, pt.x, pt.y);
|
||||
|
@ -2215,8 +2108,7 @@ class EdgeHandler {
|
|||
let color = HANDLE_FILLCOLOR;
|
||||
|
||||
if (
|
||||
(terminal != null &&
|
||||
!this.graph.isCellDisconnectable(cell, terminal, isSource)) ||
|
||||
(terminal != null && !this.graph.isCellDisconnectable(cell, terminal, isSource)) ||
|
||||
(terminal == null && !this.graph.isTerminalPointMovable(cell, isSource))
|
||||
) {
|
||||
color = LOCKED_HANDLE_FILLCOLOR;
|
||||
|
@ -2278,10 +2170,7 @@ class EdgeHandler {
|
|||
|
||||
// Updates the handle for the label position
|
||||
let b = this.labelShape.bounds;
|
||||
this.label = new Point(
|
||||
this.state.absoluteOffset.x,
|
||||
this.state.absoluteOffset.y
|
||||
);
|
||||
this.label = new Point(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
|
||||
this.labelShape.bounds = new Rectangle(
|
||||
Math.round(this.label.x - b.width / 2),
|
||||
Math.round(this.label.y - b.height / 2),
|
||||
|
@ -2378,9 +2267,7 @@ class EdgeHandler {
|
|||
this.customHandles[i].shape.node.style.display = temp;
|
||||
|
||||
// Hides custom handles during text editing
|
||||
this.customHandles[
|
||||
i
|
||||
].shape.node.style.visibility = this.isCustomHandleVisible(
|
||||
this.customHandles[i].shape.node.style.visibility = this.isCustomHandleVisible(
|
||||
this.customHandles[i]
|
||||
)
|
||||
? ''
|
||||
|
@ -2395,9 +2282,7 @@ class EdgeHandler {
|
|||
* Returns true if the given custom handle is visible.
|
||||
*/
|
||||
isCustomHandleVisible(handle) {
|
||||
return (
|
||||
!this.graph.isEditing() && this.state.view.graph.getSelectionCount() === 1
|
||||
);
|
||||
return !this.graph.isEditing() && this.state.view.graph.getSelectionCount() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2527,16 +2412,13 @@ class EdgeHandler {
|
|||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.shape != null &&
|
||||
!utils.equalPoints(this.shape.points, this.abspoints)
|
||||
) {
|
||||
if (this.shape != null && !utils.equalPoints(this.shape.points, this.abspoints)) {
|
||||
this.shape.apply(this.state);
|
||||
this.shape.points = this.abspoints.slice();
|
||||
this.shape.scale = this.state.view.scale;
|
||||
this.shape.isDashed = this.isSelectionDashed();
|
||||
this.shape.stroke = this.getSelectionColor();
|
||||
this.shape.strokewidth =
|
||||
this.shape.strokeWidth =
|
||||
this.getSelectionStrokeWidth() / this.shape.scale / this.shape.scale;
|
||||
this.shape.isShadow = false;
|
||||
this.shape.redraw();
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
import InternalEvent from '../../event/InternalEvent';
|
||||
import Shape from '../../geometry/shape/Shape';
|
||||
import InternalMouseEvent from '../../event/InternalMouseEvent';
|
||||
import Image from '../../image/Image';
|
||||
import Image from '../../image/ImageBox';
|
||||
import Graph from '../../Graph';
|
||||
import CellState from '../datatypes/CellState';
|
||||
|
||||
|
@ -33,11 +33,12 @@ import CellState from '../datatypes/CellState';
|
|||
class VertexHandle {
|
||||
dependencies = ['snap', 'cells'];
|
||||
|
||||
constructor(state: CellState,
|
||||
constructor(
|
||||
state: CellState,
|
||||
cursor: string | null = 'default',
|
||||
image: Image | null = null,
|
||||
shape: Shape | null = null) {
|
||||
|
||||
shape: Shape | null = null
|
||||
) {
|
||||
this.graph = state.view.graph;
|
||||
this.state = state;
|
||||
this.cursor = cursor != null ? cursor : this.cursor;
|
||||
|
@ -221,12 +222,8 @@ class VertexHandle {
|
|||
const tr = this.graph.view.translate;
|
||||
const shapeBounds = <Rectangle>this.shape.bounds;
|
||||
|
||||
shapeBounds.x = Math.floor(
|
||||
(pt.x + tr.x) * scale - shapeBounds.width / 2
|
||||
);
|
||||
shapeBounds.y = Math.floor(
|
||||
(pt.y + tr.y) * scale - shapeBounds.height / 2
|
||||
);
|
||||
shapeBounds.x = Math.floor((pt.x + tr.x) * scale - shapeBounds.width / 2);
|
||||
shapeBounds.y = Math.floor((pt.y + tr.y) * scale - shapeBounds.height / 2);
|
||||
|
||||
// Needed to force update of text bounds
|
||||
this.shape.redraw();
|
||||
|
@ -240,8 +237,7 @@ class VertexHandle {
|
|||
*/
|
||||
isHtmlRequired(): boolean {
|
||||
return (
|
||||
this.state.text != null &&
|
||||
this.state.text.node.parentNode === this.graph.container
|
||||
this.state.text != null && this.state.text.node.parentNode === this.graph.container
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import mxClient from '../../../mxClient';
|
|||
import { isMouseEvent, isShiftDown } from '../../../util/EventUtils';
|
||||
import Graph from '../../Graph';
|
||||
import CellState from '../datatypes/CellState';
|
||||
import Image from '../../image/Image';
|
||||
import Image from '../../image/ImageBox';
|
||||
import Cell from '../datatypes/Cell';
|
||||
|
||||
/**
|
||||
|
@ -238,15 +238,9 @@ class VertexHandler {
|
|||
// VML dialect required here for event transparency in IE
|
||||
this.selectionBorder.dialect = DIALECT_SVG;
|
||||
this.selectionBorder.pointerEvents = false;
|
||||
this.selectionBorder.rotation = Number(
|
||||
this.state.style.rotation || '0'
|
||||
);
|
||||
this.selectionBorder.rotation = Number(this.state.style.rotation || '0');
|
||||
this.selectionBorder.init(this.graph.getView().getOverlayPane());
|
||||
InternalEvent.redirectMouseEvents(
|
||||
this.selectionBorder.node,
|
||||
this.graph,
|
||||
this.state
|
||||
);
|
||||
InternalEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
|
||||
|
||||
if (this.graph.isCellMovable(this.state.cell)) {
|
||||
this.selectionBorder.setCursor(CURSOR_MOVABLE_VERTEX);
|
||||
|
@ -357,9 +351,7 @@ class VertexHandler {
|
|||
*/
|
||||
// isConstrainedEvent(me: mxMouseEvent): boolean;
|
||||
isConstrainedEvent(me) {
|
||||
return (
|
||||
isShiftDown(me.getEvent()) || this.state.style.aspect === 'fixed'
|
||||
);
|
||||
return isShiftDown(me.getEvent()) || this.state.style.aspect === 'fixed';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -448,7 +440,7 @@ class VertexHandler {
|
|||
null,
|
||||
this.getSelectionColor()
|
||||
);
|
||||
shape.strokewidth = this.getSelectionStrokeWidth();
|
||||
shape.strokeWidth = this.getSelectionStrokeWidth();
|
||||
shape.isDashed = this.isSelectionDashed();
|
||||
|
||||
return shape;
|
||||
|
@ -560,17 +552,9 @@ class VertexHandler {
|
|||
return shape;
|
||||
}
|
||||
if (index === InternalEvent.ROTATION_HANDLE) {
|
||||
return new EllipseShape(
|
||||
bounds,
|
||||
fillColor || HANDLE_FILLCOLOR,
|
||||
HANDLE_STROKECOLOR
|
||||
);
|
||||
return new EllipseShape(bounds, fillColor || HANDLE_FILLCOLOR, HANDLE_STROKECOLOR);
|
||||
}
|
||||
return new RectangleShape(
|
||||
bounds,
|
||||
fillColor || HANDLE_FILLCOLOR,
|
||||
HANDLE_STROKECOLOR
|
||||
);
|
||||
return new RectangleShape(bounds, fillColor || HANDLE_FILLCOLOR, HANDLE_STROKECOLOR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -604,19 +588,12 @@ class VertexHandler {
|
|||
const tol = !isMouseEvent(me.getEvent()) ? this.tolerance : 1;
|
||||
const hit =
|
||||
this.allowHandleBoundsCheck && tol > 0
|
||||
? new Rectangle(
|
||||
me.getGraphX() - tol,
|
||||
me.getGraphY() - tol,
|
||||
2 * tol,
|
||||
2 * tol
|
||||
)
|
||||
? new Rectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol)
|
||||
: null;
|
||||
|
||||
const checkShape = (shape) => {
|
||||
const st =
|
||||
shape != null &&
|
||||
shape.constructor !== ImageShape &&
|
||||
this.allowHandleBoundsCheck
|
||||
shape != null && shape.constructor !== ImageShape && this.allowHandleBoundsCheck
|
||||
? shape.strokewidth + shape.svgStrokeTolerance
|
||||
: null;
|
||||
const real =
|
||||
|
@ -720,8 +697,7 @@ class VertexHandler {
|
|||
// start(x: number, y: number, index: number): void;
|
||||
start(x, y, index) {
|
||||
if (this.selectionBorder != null) {
|
||||
this.livePreviewActive =
|
||||
this.livePreview && this.state.cell.getChildCount() === 0;
|
||||
this.livePreviewActive = this.livePreview && this.state.cell.getChildCount() === 0;
|
||||
this.inTolerance = true;
|
||||
this.childOffsetX = 0;
|
||||
this.childOffsetY = 0;
|
||||
|
@ -752,10 +728,7 @@ class VertexHandler {
|
|||
this.preview = this.createSelectionShape(this.bounds);
|
||||
|
||||
if (
|
||||
!(
|
||||
mxClient.IS_SVG &&
|
||||
Number(this.state.style.rotation || '0') !== 0
|
||||
) &&
|
||||
!(mxClient.IS_SVG && Number(this.state.style.rotation || '0') !== 0) &&
|
||||
this.state.text != null &&
|
||||
this.state.text.node.parentNode === this.graph.container
|
||||
) {
|
||||
|
@ -774,8 +747,7 @@ class VertexHandler {
|
|||
const dx = pos.x - this.state.getCenterX();
|
||||
const dy = pos.y - this.state.getCenterY();
|
||||
|
||||
this.startAngle =
|
||||
dx !== 0 ? (Math.atan(dy / dx) * 180) / Math.PI + 90 : 0;
|
||||
this.startAngle = dx !== 0 ? (Math.atan(dy / dx) * 180) / Math.PI + 90 : 0;
|
||||
this.startDist = Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
|
@ -789,10 +761,7 @@ class VertexHandler {
|
|||
this.labelShape.node.style.display = '';
|
||||
} else if (this.sizers != null && this.sizers[index] != null) {
|
||||
this.sizers[index].node.style.display = '';
|
||||
} else if (
|
||||
index <= InternalEvent.CUSTOM_HANDLE &&
|
||||
this.customHandles != null
|
||||
) {
|
||||
} else if (index <= InternalEvent.CUSTOM_HANDLE && this.customHandles != null) {
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - index].setVisible(true);
|
||||
}
|
||||
|
||||
|
@ -801,9 +770,7 @@ class VertexHandler {
|
|||
this.edgeHandlers = [];
|
||||
|
||||
for (let i = 0; i < edges.length; i += 1) {
|
||||
const handler = this.graph.selectionCellsHandler.getHandler(
|
||||
edges[i]
|
||||
);
|
||||
const handler = this.graph.selectionCellsHandler.getHandler(edges[i]);
|
||||
|
||||
if (handler != null) {
|
||||
this.edgeHandlers.push(handler);
|
||||
|
@ -933,12 +900,8 @@ class VertexHandler {
|
|||
if (!this.inTolerance) {
|
||||
if (this.index <= InternalEvent.CUSTOM_HANDLE) {
|
||||
if (this.customHandles != null) {
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].processEvent(
|
||||
me
|
||||
);
|
||||
this.customHandles[
|
||||
InternalEvent.CUSTOM_HANDLE - this.index
|
||||
].active = true;
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].processEvent(me);
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - this.index].active = true;
|
||||
|
||||
if (this.ghostPreview != null) {
|
||||
this.ghostPreview.apply(this.state);
|
||||
|
@ -1010,9 +973,7 @@ class VertexHandler {
|
|||
}
|
||||
|
||||
const index =
|
||||
this.rotationShape != null
|
||||
? this.sizers.length - 2
|
||||
: this.sizers.length - 1;
|
||||
this.rotationShape != null ? this.sizers.length - 2 : this.sizers.length - 1;
|
||||
this.moveSizerTo(this.sizers[index], point.x, point.y);
|
||||
}
|
||||
|
||||
|
@ -1148,26 +1109,14 @@ class VertexHandler {
|
|||
this.unscaledBounds.y = max.y;
|
||||
}
|
||||
|
||||
if (
|
||||
this.unscaledBounds.x + this.unscaledBounds.width >
|
||||
max.x + max.width
|
||||
) {
|
||||
if (this.unscaledBounds.x + this.unscaledBounds.width > max.x + max.width) {
|
||||
this.unscaledBounds.width -=
|
||||
this.unscaledBounds.x +
|
||||
this.unscaledBounds.width -
|
||||
max.x -
|
||||
max.width;
|
||||
this.unscaledBounds.x + this.unscaledBounds.width - max.x - max.width;
|
||||
}
|
||||
|
||||
if (
|
||||
this.unscaledBounds.y + this.unscaledBounds.height >
|
||||
max.y + max.height
|
||||
) {
|
||||
if (this.unscaledBounds.y + this.unscaledBounds.height > max.y + max.height) {
|
||||
this.unscaledBounds.height -=
|
||||
this.unscaledBounds.y +
|
||||
this.unscaledBounds.height -
|
||||
max.y -
|
||||
max.height;
|
||||
this.unscaledBounds.y + this.unscaledBounds.height - max.y - max.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1211,12 +1160,8 @@ class VertexHandler {
|
|||
this.bounds.y += dy3;
|
||||
|
||||
// Rounds unscaled bounds to int
|
||||
this.unscaledBounds.x = this.roundLength(
|
||||
this.unscaledBounds.x + dx3 / scale
|
||||
);
|
||||
this.unscaledBounds.y = this.roundLength(
|
||||
this.unscaledBounds.y + dy3 / scale
|
||||
);
|
||||
this.unscaledBounds.x = this.roundLength(this.unscaledBounds.x + dx3 / scale);
|
||||
this.unscaledBounds.y = this.roundLength(this.unscaledBounds.y + dy3 / scale);
|
||||
this.unscaledBounds.width = this.roundLength(this.unscaledBounds.width);
|
||||
this.unscaledBounds.height = this.roundLength(this.unscaledBounds.height);
|
||||
|
||||
|
@ -1370,15 +1315,12 @@ class VertexHandler {
|
|||
this.customHandles[InternalEvent.CUSTOM_HANDLE - index] != null
|
||||
) {
|
||||
this.state.style = style;
|
||||
this.customHandles[
|
||||
InternalEvent.CUSTOM_HANDLE - index
|
||||
].positionChanged();
|
||||
this.customHandles[InternalEvent.CUSTOM_HANDLE - index].positionChanged();
|
||||
}
|
||||
}
|
||||
} else if (index === InternalEvent.ROTATION_HANDLE) {
|
||||
if (this.currentAlpha != null) {
|
||||
const delta =
|
||||
this.currentAlpha - (this.state.style.rotation || 0);
|
||||
const delta = this.currentAlpha - (this.state.style.rotation || 0);
|
||||
|
||||
if (delta !== 0) {
|
||||
this.rotateCell(this.state.cell, delta);
|
||||
|
@ -1388,9 +1330,7 @@ class VertexHandler {
|
|||
}
|
||||
} else {
|
||||
const gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
|
||||
const alpha = utils.toRadians(
|
||||
this.state.style.rotation || '0'
|
||||
);
|
||||
const alpha = utils.toRadians(this.state.style.rotation || '0');
|
||||
const cos = Math.cos(-alpha);
|
||||
const sin = Math.sin(-alpha);
|
||||
|
||||
|
@ -1579,20 +1519,14 @@ class VertexHandler {
|
|||
|
||||
if (geo != null) {
|
||||
if (index === InternalEvent.LABEL_HANDLE) {
|
||||
const alpha = -utils.toRadians(
|
||||
this.state.style.rotation || '0'
|
||||
);
|
||||
const alpha = -utils.toRadians(this.state.style.rotation || '0');
|
||||
const cos = Math.cos(alpha);
|
||||
const sin = Math.sin(alpha);
|
||||
const { scale } = this.graph.view;
|
||||
const pt = utils.getRotatedPoint(
|
||||
new Point(
|
||||
Math.round(
|
||||
(this.labelShape.bounds.getCenterX() - this.startX) / scale
|
||||
),
|
||||
Math.round(
|
||||
(this.labelShape.bounds.getCenterY() - this.startY) / scale
|
||||
)
|
||||
Math.round((this.labelShape.bounds.getCenterX() - this.startX) / scale),
|
||||
Math.round((this.labelShape.bounds.getCenterY() - this.startY) / scale)
|
||||
),
|
||||
cos,
|
||||
sin
|
||||
|
@ -1811,12 +1745,7 @@ class VertexHandler {
|
|||
height = Math.abs(height);
|
||||
}
|
||||
|
||||
const result = new Rectangle(
|
||||
left + tr.x * scale,
|
||||
top + tr.y * scale,
|
||||
width,
|
||||
height
|
||||
);
|
||||
const result = new Rectangle(left + tr.x * scale, top + tr.y * scale, width, height);
|
||||
|
||||
if (this.minBounds != null) {
|
||||
result.width = Math.max(
|
||||
|
@ -1924,18 +1853,13 @@ class VertexHandler {
|
|||
|
||||
// Hides custom handles during text editing
|
||||
this.customHandles[i].shape.node.style.visibility =
|
||||
this.handlesVisible &&
|
||||
this.isCustomHandleVisible(this.customHandles[i])
|
||||
this.handlesVisible && this.isCustomHandleVisible(this.customHandles[i])
|
||||
? ''
|
||||
: 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.sizers != null &&
|
||||
this.sizers.length > 0 &&
|
||||
this.sizers[0] != null
|
||||
) {
|
||||
if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null) {
|
||||
if (this.index == null && this.manageSizers && this.sizers.length >= 8) {
|
||||
// KNOWN: Tolerance depends on event type (eg. 0 for mouse events)
|
||||
const padding = this.getHandlePadding();
|
||||
|
@ -1990,9 +1914,7 @@ class VertexHandler {
|
|||
'w-resize',
|
||||
];
|
||||
|
||||
const alpha = utils.toRadians(
|
||||
this.state.style.rotation || '0'
|
||||
);
|
||||
const alpha = utils.toRadians(this.state.style.rotation || '0');
|
||||
const cos = Math.cos(alpha);
|
||||
const sin = Math.sin(alpha);
|
||||
const da = Math.round((alpha * 4) / Math.PI);
|
||||
|
@ -2062,36 +1984,25 @@ class VertexHandler {
|
|||
|
||||
if (this.rotationShape != null) {
|
||||
const alpha = utils.toRadians(
|
||||
this.currentAlpha != null
|
||||
? this.currentAlpha
|
||||
: this.state.style.rotation || '0'
|
||||
this.currentAlpha != null ? this.currentAlpha : this.state.style.rotation || '0'
|
||||
);
|
||||
const cos = Math.cos(alpha);
|
||||
const sin = Math.sin(alpha);
|
||||
|
||||
const ct = new Point(this.state.getCenterX(), this.state.getCenterY());
|
||||
const pt = utils.getRotatedPoint(
|
||||
this.getRotationHandlePosition(),
|
||||
cos,
|
||||
sin,
|
||||
ct
|
||||
);
|
||||
const pt = utils.getRotatedPoint(this.getRotationHandlePosition(), cos, sin, ct);
|
||||
|
||||
if (this.rotationShape.node != null) {
|
||||
this.moveSizerTo(this.rotationShape, pt.x, pt.y);
|
||||
|
||||
// Hides rotation handle during text editing
|
||||
this.rotationShape.node.style.visibility =
|
||||
this.state.view.graph.isEditing() || !this.handlesVisible
|
||||
? 'hidden'
|
||||
: '';
|
||||
this.state.view.graph.isEditing() || !this.handlesVisible ? 'hidden' : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (this.selectionBorder != null) {
|
||||
this.selectionBorder.rotation = Number(
|
||||
this.state.style.rotation || '0'
|
||||
);
|
||||
this.selectionBorder.rotation = Number(this.state.style.rotation || '0');
|
||||
}
|
||||
|
||||
if (this.edgeHandlers != null) {
|
||||
|
@ -2107,9 +2018,7 @@ class VertexHandler {
|
|||
* Returns true if the given custom handle is visible.
|
||||
*/
|
||||
isCustomHandleVisible(handle) {
|
||||
return (
|
||||
!this.graph.isEditing() && this.state.view.graph.getSelectionCount() === 1
|
||||
);
|
||||
return !this.graph.isEditing() && this.state.view.graph.getSelectionCount() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2162,10 +2071,7 @@ class VertexHandler {
|
|||
this.parentHighlight.redraw();
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
pstate != null &&
|
||||
pstate.parentHighlight === this.parentHighlight
|
||||
) {
|
||||
if (pstate != null && pstate.parentHighlight === this.parentHighlight) {
|
||||
pstate.parentHighlight = null;
|
||||
}
|
||||
|
||||
|
@ -2173,18 +2079,12 @@ class VertexHandler {
|
|||
this.parentHighlight = null;
|
||||
}
|
||||
} else if (this.parentHighlightEnabled && visible) {
|
||||
if (
|
||||
parent.isVertex() &&
|
||||
pstate != null &&
|
||||
pstate.parentHighlight == null
|
||||
) {
|
||||
if (parent.isVertex() && pstate != null && pstate.parentHighlight == null) {
|
||||
this.parentHighlight = this.createParentHighlightShape(pstate);
|
||||
// VML dialect required here for event transparency in IE
|
||||
this.parentHighlight.dialect = DIALECT_SVG;
|
||||
this.parentHighlight.pointerEvents = false;
|
||||
this.parentHighlight.rotation = Number(
|
||||
pstate.style.rotation || '0'
|
||||
);
|
||||
this.parentHighlight.rotation = Number(pstate.style.rotation || '0');
|
||||
this.parentHighlight.init(this.graph.getView().getOverlayPane());
|
||||
this.parentHighlight.redraw();
|
||||
|
||||
|
@ -2207,10 +2107,7 @@ class VertexHandler {
|
|||
|
||||
if (this.preview.node.parentNode === this.graph.container) {
|
||||
this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1);
|
||||
this.preview.bounds.height = Math.max(
|
||||
0,
|
||||
this.preview.bounds.height - 1
|
||||
);
|
||||
this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1);
|
||||
}
|
||||
|
||||
this.preview.rotation = Number(this.state.style.rotation || '0');
|
||||
|
|
|
@ -19,7 +19,13 @@ import {
|
|||
TOOLTIP_VERTICAL_OFFSET,
|
||||
VALID_COLOR,
|
||||
} from '../../util/Constants';
|
||||
import utils, { convertPoint, getOffset, getRotatedPoint, getValue, toRadians } from '../../util/Utils';
|
||||
import utils, {
|
||||
convertPoint,
|
||||
getOffset,
|
||||
getRotatedPoint,
|
||||
getValue,
|
||||
toRadians,
|
||||
} from '../../util/Utils';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import ImageShape from '../geometry/shape/node/ImageShape';
|
||||
import CellMarker from '../cell/CellMarker';
|
||||
|
@ -36,7 +42,7 @@ import {
|
|||
isShiftDown,
|
||||
} from '../../util/EventUtils';
|
||||
import graph from '../Graph';
|
||||
import Image from '../image/Image';
|
||||
import Image from '../image/ImageBox';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Graph from '../Graph';
|
||||
import ConnectionConstraint from './ConnectionConstraint';
|
||||
|
@ -201,8 +207,7 @@ type FactoryMethod = (source: Cell, target: Cell, style?: string) => Cell;
|
|||
* the <mxCell> that represents the new edge.
|
||||
*/
|
||||
class ConnectionHandler extends EventSource {
|
||||
constructor(graph: Graph,
|
||||
factoryMethod: FactoryMethod | null = null) {
|
||||
constructor(graph: Graph, factoryMethod: FactoryMethod | null = null) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -660,7 +665,7 @@ class ConnectionHandler extends EventSource {
|
|||
}
|
||||
|
||||
return cell;
|
||||
};
|
||||
}
|
||||
|
||||
// Sets the highlight color according to validateConnection
|
||||
isValidState(state: CellState) {
|
||||
|
@ -696,11 +701,7 @@ class ConnectionHandler extends EventSource {
|
|||
*
|
||||
* Starts a new connection for the given state and coordinates.
|
||||
*/
|
||||
start(state: CellState,
|
||||
x: number,
|
||||
y: number,
|
||||
edgeState: CellState): void {
|
||||
|
||||
start(state: CellState, x: number, y: number, edgeState: CellState): void {
|
||||
this.previous = state;
|
||||
this.first = new Point(x, y);
|
||||
this.edgeState = edgeState != null ? edgeState : this.createEdgeState(null);
|
||||
|
@ -733,8 +734,7 @@ class ConnectionHandler extends EventSource {
|
|||
* cell - <mxCell> that represents the source terminal.
|
||||
* me - <mxMouseEvent> that is associated with this call.
|
||||
*/
|
||||
isValidSource(cell: Cell,
|
||||
me: InternalMouseEvent): boolean {
|
||||
isValidSource(cell: Cell, me: InternalMouseEvent): boolean {
|
||||
return this.graph.isValidSource(cell);
|
||||
}
|
||||
|
||||
|
@ -765,8 +765,7 @@ class ConnectionHandler extends EventSource {
|
|||
* source - <mxCell> that represents the source terminal.
|
||||
* target - <mxCell> that represents the target terminal.
|
||||
*/
|
||||
validateConnection(source: Cell,
|
||||
target: Cell): string {
|
||||
validateConnection(source: Cell, target: Cell): string {
|
||||
if (!this.isValidTarget(target)) {
|
||||
return '';
|
||||
}
|
||||
|
@ -798,10 +797,7 @@ class ConnectionHandler extends EventSource {
|
|||
* state - <mxCellState> whose connect icons should be returned.
|
||||
*/
|
||||
isMoveIconToFrontForState(state: CellState): boolean {
|
||||
if (
|
||||
state.text != null &&
|
||||
state.text.node.parentNode === this.graph.container
|
||||
) {
|
||||
if (state.text != null && state.text.node.parentNode === this.graph.container) {
|
||||
return true;
|
||||
}
|
||||
return this.moveIconFront;
|
||||
|
@ -841,10 +837,7 @@ class ConnectionHandler extends EventSource {
|
|||
|
||||
// Move the icon back in the overlay pane
|
||||
if (this.moveIconBack && icon.node.previousSibling != null) {
|
||||
icon.node.parentNode.insertBefore(
|
||||
icon.node,
|
||||
icon.node.parentNode.firstChild
|
||||
);
|
||||
icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -886,8 +879,7 @@ class ConnectionHandler extends EventSource {
|
|||
*
|
||||
* icons - Optional array of <mxImageShapes> to be redrawn.
|
||||
*/
|
||||
redrawIcons(icons?: ImageShape[] | null,
|
||||
state?: CellState): void {
|
||||
redrawIcons(icons?: ImageShape[] | null, state?: CellState): void {
|
||||
if (icons != null && icons[0] != null && state != null) {
|
||||
const pos = this.getIconPosition(icons[0], state);
|
||||
icons[0].bounds.x = pos.x;
|
||||
|
@ -897,8 +889,7 @@ class ConnectionHandler extends EventSource {
|
|||
}
|
||||
|
||||
// TODO: Document me! ===========================================================================================================
|
||||
getIconPosition(icon: ImageShape,
|
||||
state: CellState): Point {
|
||||
getIconPosition(icon: ImageShape, state: CellState): Point {
|
||||
const { scale } = this.graph.getView();
|
||||
let cx = state.getCenterX();
|
||||
let cy = state.getCenterY();
|
||||
|
@ -909,9 +900,7 @@ class ConnectionHandler extends EventSource {
|
|||
cx = size.width !== 0 ? state.x + (size.width * scale) / 2 : cx;
|
||||
cy = size.height !== 0 ? state.y + (size.height * scale) / 2 : cy;
|
||||
|
||||
const alpha = toRadians(
|
||||
getValue(state.style, 'rotation') || 0
|
||||
);
|
||||
const alpha = toRadians(getValue(state.style, 'rotation') || 0);
|
||||
|
||||
if (alpha !== 0) {
|
||||
const cos = Math.cos(alpha);
|
||||
|
@ -1066,10 +1055,8 @@ class ConnectionHandler extends EventSource {
|
|||
const left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||||
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||||
|
||||
const gridX =
|
||||
this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
|
||||
const gridY =
|
||||
this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
|
||||
const gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
|
||||
const gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
|
||||
|
||||
return (
|
||||
this.outlineConnect &&
|
||||
|
@ -1089,15 +1076,12 @@ class ConnectionHandler extends EventSource {
|
|||
* Updates the current state for a given mouse move event by using
|
||||
* the <marker>.
|
||||
*/
|
||||
updateCurrentState(me: InternalMouseEvent,
|
||||
point: Point): void {
|
||||
updateCurrentState(me: InternalMouseEvent, point: Point): void {
|
||||
this.constraintHandler.update(
|
||||
me,
|
||||
this.first == null,
|
||||
false,
|
||||
this.first == null || me.isSource(this.marker.highlight.shape)
|
||||
? null
|
||||
: point
|
||||
this.first == null || me.isSource(this.marker.highlight.shape) ? null : point
|
||||
);
|
||||
|
||||
if (
|
||||
|
@ -1109,8 +1093,7 @@ class ConnectionHandler extends EventSource {
|
|||
if (
|
||||
this.marker.highlight != null &&
|
||||
this.marker.highlight.state != null &&
|
||||
this.marker.highlight.state.cell ===
|
||||
this.constraintHandler.currentFocus.cell
|
||||
this.marker.highlight.state.cell === this.constraintHandler.currentFocus.cell
|
||||
) {
|
||||
// Direct repaint needed if cell already highlighted
|
||||
if (this.marker.highlight.shape.stroke !== 'transparent') {
|
||||
|
@ -1118,10 +1101,7 @@ class ConnectionHandler extends EventSource {
|
|||
this.marker.highlight.repaint();
|
||||
}
|
||||
} else {
|
||||
this.marker.markCell(
|
||||
this.constraintHandler.currentFocus.cell,
|
||||
'transparent'
|
||||
);
|
||||
this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
|
||||
}
|
||||
|
||||
// Updates validation state
|
||||
|
@ -1137,8 +1117,7 @@ class ConnectionHandler extends EventSource {
|
|||
|
||||
if (
|
||||
this.error != null ||
|
||||
(this.currentState != null &&
|
||||
!this.isCellEnabled(this.currentState.cell))
|
||||
(this.currentState != null && !this.isCellEnabled(this.currentState.cell))
|
||||
) {
|
||||
this.constraintHandler.reset();
|
||||
}
|
||||
|
@ -1152,10 +1131,7 @@ class ConnectionHandler extends EventSource {
|
|||
this.currentState = this.marker.getValidState();
|
||||
}
|
||||
|
||||
if (
|
||||
this.currentState != null &&
|
||||
!this.isCellEnabled(this.currentState.cell)
|
||||
) {
|
||||
if (this.currentState != null && !this.isCellEnabled(this.currentState.cell)) {
|
||||
this.constraintHandler.reset();
|
||||
this.marker.reset();
|
||||
this.currentState = null;
|
||||
|
@ -1170,21 +1146,14 @@ class ConnectionHandler extends EventSource {
|
|||
point = new point(me.getGraphX(), me.getGraphY());
|
||||
}
|
||||
|
||||
const constraint = this.graph.getOutlineConstraint(
|
||||
point,
|
||||
this.currentState,
|
||||
me
|
||||
);
|
||||
const constraint = this.graph.getOutlineConstraint(point, this.currentState, me);
|
||||
this.constraintHandler.setFocus(me, this.currentState, false);
|
||||
this.constraintHandler.currentConstraint = constraint;
|
||||
this.constraintHandler.currentPoint = point;
|
||||
}
|
||||
|
||||
if (this.outlineConnect) {
|
||||
if (
|
||||
this.marker.highlight != null &&
|
||||
this.marker.highlight.shape != null
|
||||
) {
|
||||
if (this.marker.highlight != null && this.marker.highlight.shape != null) {
|
||||
const s = this.graph.view.scale;
|
||||
|
||||
if (
|
||||
|
@ -1192,7 +1161,7 @@ class ConnectionHandler extends EventSource {
|
|||
this.constraintHandler.currentFocus != null
|
||||
) {
|
||||
this.marker.highlight.shape.stroke = OUTLINE_HIGHLIGHT_COLOR;
|
||||
this.marker.highlight.shape.strokewidth =
|
||||
this.marker.highlight.shape.strokeWidth =
|
||||
OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
this.marker.highlight.repaint();
|
||||
} else if (this.marker.hasValidState()) {
|
||||
|
@ -1209,8 +1178,7 @@ class ConnectionHandler extends EventSource {
|
|||
this.marker.highlight.shape.stroke = DEFAULT_VALID_COLOR;
|
||||
}
|
||||
|
||||
this.marker.highlight.shape.strokewidth =
|
||||
HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
this.marker.highlight.shape.strokeWidth = HIGHLIGHT_STROKEWIDTH / s / s;
|
||||
this.marker.highlight.repaint();
|
||||
}
|
||||
}
|
||||
|
@ -1246,8 +1214,7 @@ class ConnectionHandler extends EventSource {
|
|||
* Called to snap the given point to the current preview. This snaps to the
|
||||
* first point of the preview if alt is not pressed.
|
||||
*/
|
||||
snapToPreview(me: MouseEvent,
|
||||
point: Point): void {
|
||||
snapToPreview(me: MouseEvent, point: Point): void {
|
||||
if (!isAltDown(me.getEvent()) && this.previous != null) {
|
||||
const tol = (this.graph.gridSize * this.graph.view.scale) / 2;
|
||||
const tmp =
|
||||
|
@ -1271,8 +1238,7 @@ class ConnectionHandler extends EventSource {
|
|||
* Handles the event by updating the preview edge or by highlighting
|
||||
* a possible source or target terminal.
|
||||
*/
|
||||
mouseMove(sender: MouseEvent,
|
||||
me: InternalMouseEvent): void {
|
||||
mouseMove(sender: MouseEvent, me: InternalMouseEvent): void {
|
||||
if (
|
||||
!me.isConsumed() &&
|
||||
(this.ignoreMouseDown || this.first != null || !this.graph.isMouseDown)
|
||||
|
@ -1344,10 +1310,7 @@ class ConnectionHandler extends EventSource {
|
|||
const h = this.selectedIcon.bounds.height;
|
||||
|
||||
if (this.currentState != null && this.targetConnectImage) {
|
||||
const pos = this.getIconPosition(
|
||||
this.selectedIcon,
|
||||
this.currentState
|
||||
);
|
||||
const pos = this.getIconPosition(this.selectedIcon, this.currentState);
|
||||
this.selectedIcon.bounds.x = pos.x;
|
||||
this.selectedIcon.bounds.y = pos.y;
|
||||
} else {
|
||||
|
@ -1402,10 +1365,7 @@ class ConnectionHandler extends EventSource {
|
|||
if (this.currentState == null && this.movePreviewAway) {
|
||||
let tmp = pt2;
|
||||
|
||||
if (
|
||||
this.edgeState != null &&
|
||||
this.edgeState.absolutePoints.length >= 2
|
||||
) {
|
||||
if (this.edgeState != null && this.edgeState.absolutePoints.length >= 2) {
|
||||
const tmp2 = this.edgeState.absolutePoints[
|
||||
this.edgeState.absolutePoints.length - 2
|
||||
];
|
||||
|
@ -1476,10 +1436,7 @@ class ConnectionHandler extends EventSource {
|
|||
me.consume();
|
||||
} else if (!this.isEnabled() || !this.graph.isEnabled()) {
|
||||
this.constraintHandler.reset();
|
||||
} else if (
|
||||
this.previous !== this.currentState &&
|
||||
this.edgeState == null
|
||||
) {
|
||||
} else if (this.previous !== this.currentState && this.edgeState == null) {
|
||||
this.destroyIcons();
|
||||
|
||||
// Sets the cursor on the current shape
|
||||
|
@ -1507,18 +1464,13 @@ class ConnectionHandler extends EventSource {
|
|||
me.consume();
|
||||
}
|
||||
|
||||
if (
|
||||
!this.graph.isMouseDown &&
|
||||
this.currentState != null &&
|
||||
this.icons != null
|
||||
) {
|
||||
if (!this.graph.isMouseDown && this.currentState != null && this.icons != null) {
|
||||
let hitsIcon = false;
|
||||
const target = me.getSource();
|
||||
|
||||
for (let i = 0; i < this.icons.length && !hitsIcon; i += 1) {
|
||||
hitsIcon =
|
||||
target === this.icons[i].node ||
|
||||
target.parentNode === this.icons[i].node;
|
||||
target === this.icons[i].node || target.parentNode === this.icons[i].node;
|
||||
}
|
||||
|
||||
if (!hitsIcon) {
|
||||
|
@ -1535,8 +1487,7 @@ class ConnectionHandler extends EventSource {
|
|||
*
|
||||
* Updates <edgeState>.
|
||||
*/
|
||||
updateEdgeState(current: CellState,
|
||||
constraint: CellState): void {
|
||||
updateEdgeState(current: CellState, constraint: CellState): void {
|
||||
// TODO: Use generic method for writing constraint to style
|
||||
if (this.sourceConstraint != null && this.sourceConstraint.point != null) {
|
||||
this.edgeState.style.exitX = this.sourceConstraint.point.x;
|
||||
|
@ -1551,10 +1502,7 @@ class ConnectionHandler extends EventSource {
|
|||
delete this.edgeState.style.entryY;
|
||||
}
|
||||
|
||||
this.edgeState.absolutePoints = [
|
||||
null,
|
||||
this.currentState != null ? null : current,
|
||||
];
|
||||
this.edgeState.absolutePoints = [null, this.currentState != null ? null : current];
|
||||
this.graph.view.updateFixedTerminalPoint(
|
||||
this.edgeState,
|
||||
this.previous,
|
||||
|
@ -1616,8 +1564,7 @@ class ConnectionHandler extends EventSource {
|
|||
* state - <mxCellState> that represents the target cell state.
|
||||
* me - <mxMouseEvent> that represents the mouse move.
|
||||
*/
|
||||
getTargetPerimeterPoint(state: CellState,
|
||||
me: MouseEvent): Point {
|
||||
getTargetPerimeterPoint(state: CellState, me: MouseEvent): Point {
|
||||
let result = null;
|
||||
const { view } = state;
|
||||
const targetPerimeter = view.getPerimeterFunction(state);
|
||||
|
@ -1656,9 +1603,7 @@ class ConnectionHandler extends EventSource {
|
|||
* next - <mxPoint> that represents the next point along the previewed edge.
|
||||
* me - <mxMouseEvent> that represents the mouse move.
|
||||
*/
|
||||
getSourcePerimeterPoint(state: CellState,
|
||||
next: Point,
|
||||
me: MouseEvent): Point {
|
||||
getSourcePerimeterPoint(state: CellState, next: Point, me: MouseEvent): Point {
|
||||
let result = null;
|
||||
const { view } = state;
|
||||
const sourcePerimeter = view.getPerimeterFunction(state);
|
||||
|
@ -1677,12 +1622,7 @@ class ConnectionHandler extends EventSource {
|
|||
);
|
||||
}
|
||||
|
||||
let tmp = sourcePerimeter(
|
||||
view.getPerimeterBounds(state),
|
||||
state,
|
||||
next,
|
||||
false
|
||||
);
|
||||
let tmp = sourcePerimeter(view.getPerimeterBounds(state), state, next, false);
|
||||
|
||||
if (tmp != null) {
|
||||
if (theta !== 0) {
|
||||
|
@ -1715,9 +1655,7 @@ class ConnectionHandler extends EventSource {
|
|||
* icons - Array of currently displayed icons.
|
||||
* me - <mxMouseEvent> that contains the mouse event.
|
||||
*/
|
||||
updateIcons(state: CellState,
|
||||
icons: string[],
|
||||
me: InternalMouseEvent): void {
|
||||
updateIcons(state: CellState, icons: string[], me: InternalMouseEvent): void {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -1739,11 +1677,7 @@ class ConnectionHandler extends EventSource {
|
|||
* Adds the waypoint for the given event to <waypoints>.
|
||||
*/
|
||||
addWaypointForEvent(me: InternalMouseEvent): void {
|
||||
let point = convertPoint(
|
||||
this.graph.container,
|
||||
me.getX(),
|
||||
me.getY()
|
||||
);
|
||||
let point = convertPoint(this.graph.container, me.getX(), me.getY());
|
||||
const dx = Math.abs(point.x - this.first.x);
|
||||
const dy = Math.abs(point.y - this.first.y);
|
||||
const addPoint =
|
||||
|
@ -1790,8 +1724,7 @@ class ConnectionHandler extends EventSource {
|
|||
*
|
||||
* Handles the event by inserting the new connection.
|
||||
*/
|
||||
mouseUp(sender: InternalMouseEvent,
|
||||
me: InternalMouseEvent): void {
|
||||
mouseUp(sender: InternalMouseEvent, me: InternalMouseEvent): void {
|
||||
if (!me.isConsumed() && this.isConnecting()) {
|
||||
if (this.waypointsEnabled && !this.isStopEvent(me)) {
|
||||
this.addWaypointForEvent(me);
|
||||
|
@ -1907,7 +1840,7 @@ class ConnectionHandler extends EventSource {
|
|||
* returned.
|
||||
*/
|
||||
updatePreview(valid: boolean): void {
|
||||
this.shape.strokewidth = this.getEdgeWidth(valid);
|
||||
this.shape.strokeWidth = this.getEdgeWidth(valid);
|
||||
this.shape.stroke = this.getEdgeColor(valid);
|
||||
}
|
||||
|
||||
|
@ -1955,15 +1888,8 @@ class ConnectionHandler extends EventSource {
|
|||
* dropTarget - <mxCell> that represents the cell under the mouse when it was
|
||||
* released.
|
||||
*/
|
||||
connect(source: Cell,
|
||||
target: Cell,
|
||||
evt: MouseEvent,
|
||||
dropTarget: Cell): void {
|
||||
if (
|
||||
target != null ||
|
||||
this.isCreateTarget(evt) ||
|
||||
this.graph.allowDanglingEdges
|
||||
) {
|
||||
connect(source: Cell, target: Cell, evt: MouseEvent, dropTarget: Cell): void {
|
||||
if (target != null || this.isCreateTarget(evt) || this.graph.allowDanglingEdges) {
|
||||
// Uses the common parent of source and target or
|
||||
// the default parent to insert the edge
|
||||
const model = this.graph.getModel();
|
||||
|
@ -2036,12 +1962,7 @@ class ConnectionHandler extends EventSource {
|
|||
|
||||
if (edge != null) {
|
||||
// Updates the connection constraints
|
||||
this.graph.setConnectionConstraint(
|
||||
edge,
|
||||
source,
|
||||
true,
|
||||
this.sourceConstraint
|
||||
);
|
||||
this.graph.setConnectionConstraint(edge, source, true, this.sourceConstraint);
|
||||
this.graph.setConnectionConstraint(
|
||||
edge,
|
||||
target,
|
||||
|
@ -2070,11 +1991,7 @@ class ConnectionHandler extends EventSource {
|
|||
tmp = tmp.getParent();
|
||||
}
|
||||
|
||||
if (
|
||||
tmp != null &&
|
||||
tmp.parent != null &&
|
||||
tmp.parent === edge.parent
|
||||
) {
|
||||
if (tmp != null && tmp.parent != null && tmp.parent === edge.parent) {
|
||||
model.add(parent, edge, tmp.parent.getIndex(tmp));
|
||||
}
|
||||
}
|
||||
|
@ -2110,10 +2027,7 @@ class ConnectionHandler extends EventSource {
|
|||
this.originalPoint.x / s - t.x,
|
||||
this.originalPoint.y / s - t.y
|
||||
)
|
||||
: new Point(
|
||||
this.currentPoint.x / s - t.x,
|
||||
this.currentPoint.y / s - t.y
|
||||
);
|
||||
: new Point(this.currentPoint.x / s - t.x, this.currentPoint.y / s - t.y);
|
||||
pt.x -= this.graph.panDx / this.graph.view.scale;
|
||||
pt.y -= this.graph.panDy / this.graph.view.scale;
|
||||
geo.setTerminalPoint(pt, false);
|
||||
|
@ -2154,8 +2068,7 @@ class ConnectionHandler extends EventSource {
|
|||
* Selects the given edge after adding a new connection. The target argument
|
||||
* contains the target vertex if one has been inserted.
|
||||
*/
|
||||
selectCells(edge: Cell,
|
||||
target: Cell): void {
|
||||
selectCells(edge: Cell, target: Cell): void {
|
||||
this.graph.setSelectionCell(edge);
|
||||
}
|
||||
|
||||
|
@ -2166,13 +2079,14 @@ class ConnectionHandler extends EventSource {
|
|||
* implementation does only use <createEdge> if <factoryMethod> is defined,
|
||||
* otherwise <mxGraph.insertEdge> will be used.
|
||||
*/
|
||||
insertEdge(parent: Cell,
|
||||
insertEdge(
|
||||
parent: Cell,
|
||||
id: string,
|
||||
value: any,
|
||||
source: Cell,
|
||||
target: Cell,
|
||||
style: string): Cell {
|
||||
|
||||
style: string
|
||||
): Cell {
|
||||
if (this.factoryMethod == null) {
|
||||
return this.graph.insertEdge(parent, id, value, source, target, style);
|
||||
}
|
||||
|
@ -2194,8 +2108,7 @@ class ConnectionHandler extends EventSource {
|
|||
* evt - Mousedown event of the connect gesture.
|
||||
* source - <mxCell> that represents the source terminal.
|
||||
*/
|
||||
createTargetVertex(evt: MouseEvent,
|
||||
source: Cell): Cell {
|
||||
createTargetVertex(evt: MouseEvent, source: Cell): Cell {
|
||||
// Uses the first non-relative source
|
||||
let geo = source.getGeometry();
|
||||
|
||||
|
@ -2267,10 +2180,7 @@ class ConnectionHandler extends EventSource {
|
|||
* target - <mxCell> that represents the target terminal.
|
||||
* style - Optional style from the preview edge.
|
||||
*/
|
||||
createEdge(value?: any,
|
||||
source?: Cell,
|
||||
target?: Cell,
|
||||
style?: string): Cell {
|
||||
createEdge(value?: any, source?: Cell, target?: Cell, style?: string): Cell {
|
||||
let edge = null;
|
||||
|
||||
// Creates a new edge using the factoryMethod
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import Image from '../image/Image';
|
||||
import Image from '../image/ImageBox';
|
||||
import mxClient from '../../mxClient';
|
||||
import {
|
||||
DEFAULT_VALID_COLOR,
|
||||
|
@ -240,11 +240,7 @@ class ConstraintHandler {
|
|||
this.reset();
|
||||
};
|
||||
|
||||
InternalEvent.addListener(
|
||||
this.graph.container,
|
||||
'mouseleave',
|
||||
this.resetHandler
|
||||
);
|
||||
InternalEvent.addListener(this.graph.container, 'mouseleave', this.resetHandler);
|
||||
}
|
||||
|
||||
const tol = this.getTolerance(me);
|
||||
|
@ -296,12 +292,7 @@ class ConstraintHandler {
|
|||
if (
|
||||
(this.intersects(this.focusIcons[i], mouse, source, existingEdge) ||
|
||||
(point != null &&
|
||||
this.intersects(
|
||||
this.focusIcons[i],
|
||||
grid,
|
||||
source,
|
||||
existingEdge
|
||||
))) &&
|
||||
this.intersects(this.focusIcons[i], grid, source, existingEdge))) &&
|
||||
(minDistSq == null || tmp < minDistSq)
|
||||
) {
|
||||
this.currentConstraint = this.constraints[i];
|
||||
|
@ -358,12 +349,7 @@ class ConstraintHandler {
|
|||
) {
|
||||
const state = this.graph.view.getState(this.currentFocus.cell);
|
||||
this.currentFocus = state;
|
||||
this.currentFocusArea = new Rectangle(
|
||||
state.x,
|
||||
state.y,
|
||||
state.width,
|
||||
state.height
|
||||
);
|
||||
this.currentFocusArea = new Rectangle(state.x, state.y, state.width, state.height);
|
||||
|
||||
for (let i = 0; i < this.constraints.length; i += 1) {
|
||||
const cp = this.graph.getConnectionPoint(state, this.constraints[i]);
|
||||
|
@ -391,9 +377,7 @@ class ConstraintHandler {
|
|||
// setFocus(me: mxMouseEvent, state: mxCellState, source: mxCell): void;
|
||||
setFocus(me, state, source) {
|
||||
this.constraints =
|
||||
state != null &&
|
||||
!this.isStateIgnored(state, source) &&
|
||||
state.cell.isConnectable()
|
||||
state != null && !this.isStateIgnored(state, source) && state.cell.isConnectable()
|
||||
? this.isEnabled()
|
||||
? this.graph.getAllConnectionConstraints(state, source) || []
|
||||
: []
|
||||
|
@ -402,12 +386,7 @@ class ConstraintHandler {
|
|||
// Only uses cells which have constraints
|
||||
if (this.constraints != null) {
|
||||
this.currentFocus = state;
|
||||
this.currentFocusArea = new Rectangle(
|
||||
state.x,
|
||||
state.y,
|
||||
state.width,
|
||||
state.height
|
||||
);
|
||||
this.currentFocusArea = new Rectangle(state.x, state.y, state.width, state.height);
|
||||
|
||||
if (this.focusIcons != null) {
|
||||
for (let i = 0; i < this.focusIcons.length; i += 1) {
|
||||
|
@ -440,10 +419,7 @@ class ConstraintHandler {
|
|||
|
||||
// Move the icon behind all other overlays
|
||||
if (icon.node.previousSibling != null) {
|
||||
icon.node.parentNode.insertBefore(
|
||||
icon.node,
|
||||
icon.node.parentNode.firstChild
|
||||
);
|
||||
icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
|
||||
}
|
||||
|
||||
const getState = () => {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
type EventProperties = Record<string, any>;
|
||||
|
||||
/**
|
||||
* Class: mxEventObject
|
||||
*
|
||||
|
@ -29,9 +31,9 @@
|
|||
* (end)
|
||||
*/
|
||||
class EventObject {
|
||||
constructor(name: string, ...args: any[]) {
|
||||
constructor(name = '', ...args: any[]) {
|
||||
this.name = name;
|
||||
this.properties = [];
|
||||
this.properties = {};
|
||||
|
||||
if (!!args[0] && args[0].constructor === Object) {
|
||||
// A literal object ({})
|
||||
|
@ -41,7 +43,7 @@ class EventObject {
|
|||
} else {
|
||||
// two-values [key, value, key, value, ...]
|
||||
for (let i = 0; i < args.length; i += 2) {
|
||||
if (args[i + 1] != null) {
|
||||
if (args[i + 1] !== null) {
|
||||
this.properties[args[i]] = args[i + 1];
|
||||
}
|
||||
}
|
||||
|
@ -53,14 +55,14 @@ class EventObject {
|
|||
*
|
||||
* Holds the name.
|
||||
*/
|
||||
name: string = '';
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Variable: properties
|
||||
*
|
||||
* Holds the properties as an associative array.
|
||||
*/
|
||||
properties: any = null;
|
||||
properties: EventProperties;
|
||||
|
||||
/**
|
||||
* Variable: consumed
|
||||
|
@ -74,7 +76,7 @@ class EventObject {
|
|||
*
|
||||
* Returns <name>.
|
||||
*/
|
||||
getName(): string {
|
||||
getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
@ -83,7 +85,7 @@ class EventObject {
|
|||
*
|
||||
* Returns <properties>.
|
||||
*/
|
||||
getProperties(): any {
|
||||
getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
|
@ -92,7 +94,7 @@ class EventObject {
|
|||
*
|
||||
* Returns the property for the given key.
|
||||
*/
|
||||
getProperty(key: string): any {
|
||||
getProperty(key: string) {
|
||||
return this.properties[key];
|
||||
}
|
||||
|
||||
|
@ -101,7 +103,7 @@ class EventObject {
|
|||
*
|
||||
* Returns true if the event has been consumed.
|
||||
*/
|
||||
isConsumed(): boolean {
|
||||
isConsumed() {
|
||||
return this.consumed;
|
||||
}
|
||||
|
||||
|
@ -110,7 +112,7 @@ class EventObject {
|
|||
*
|
||||
* Consumes the event.
|
||||
*/
|
||||
consume(): void {
|
||||
consume() {
|
||||
this.consumed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
import EventObject from './EventObject';
|
||||
|
||||
type EventListener = {
|
||||
funct: Function;
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class: mxEventSource
|
||||
*
|
||||
|
@ -30,7 +35,7 @@ import EventObject from './EventObject';
|
|||
* Constructs a new event source.
|
||||
*/
|
||||
class EventSource {
|
||||
constructor(eventSource: EventSource | null=null) {
|
||||
constructor(eventSource: EventSource | null = null) {
|
||||
this.eventSource = eventSource;
|
||||
}
|
||||
|
||||
|
@ -41,14 +46,14 @@ class EventSource {
|
|||
* contains the event name followed by the respective listener for each
|
||||
* registered listener.
|
||||
*/
|
||||
eventListeners: ({funct: Function, name: string})[] = [];
|
||||
eventListeners: EventListener[] = [];
|
||||
|
||||
/**
|
||||
* Variable: eventsEnabled
|
||||
*
|
||||
* Specifies if events can be fired. Default is true.
|
||||
*/
|
||||
eventsEnabled: boolean = true;
|
||||
eventsEnabled = true;
|
||||
|
||||
/**
|
||||
* Variable: eventSource
|
||||
|
@ -62,7 +67,7 @@ class EventSource {
|
|||
*
|
||||
* Returns <eventsEnabled>.
|
||||
*/
|
||||
isEventsEnabled(): boolean {
|
||||
isEventsEnabled() {
|
||||
return this.eventsEnabled;
|
||||
}
|
||||
|
||||
|
@ -71,7 +76,7 @@ class EventSource {
|
|||
*
|
||||
* Sets <eventsEnabled>.
|
||||
*/
|
||||
setEventsEnabled(value: boolean): void {
|
||||
setEventsEnabled(value: boolean) {
|
||||
this.eventsEnabled = value;
|
||||
}
|
||||
|
||||
|
@ -80,7 +85,7 @@ class EventSource {
|
|||
*
|
||||
* Returns <eventSource>.
|
||||
*/
|
||||
getEventSource(): EventSource | null {
|
||||
getEventSource() {
|
||||
return this.eventSource;
|
||||
}
|
||||
|
||||
|
@ -89,7 +94,7 @@ class EventSource {
|
|||
*
|
||||
* Sets <eventSource>.
|
||||
*/
|
||||
setEventSource(value: EventSource): void {
|
||||
setEventSource(value: EventSource) {
|
||||
this.eventSource = value;
|
||||
}
|
||||
|
||||
|
@ -101,13 +106,8 @@ class EventSource {
|
|||
*
|
||||
* The parameters of the listener are the sender and an <mxEventObject>.
|
||||
*/
|
||||
addListener(name: string,
|
||||
funct: (...args: any[]) => any): void {
|
||||
|
||||
if (this.eventListeners == null) {
|
||||
this.eventListeners = [];
|
||||
}
|
||||
this.eventListeners.push({name, funct});
|
||||
addListener(name: string, funct: (...args: any[]) => any) {
|
||||
this.eventListeners.push({ name, funct });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,8 +115,7 @@ class EventSource {
|
|||
*
|
||||
* Removes all occurrences of the given listener from <eventListeners>.
|
||||
*/
|
||||
removeListener(funct: (...args: any[]) => any): void {
|
||||
if (this.eventListeners != null) {
|
||||
removeListener(funct: (...args: any[]) => any) {
|
||||
let i = 0;
|
||||
|
||||
while (i < this.eventListeners.length) {
|
||||
|
@ -127,7 +126,6 @@ class EventSource {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: fireEvent
|
||||
|
@ -148,21 +146,21 @@ class EventSource {
|
|||
* sender - Optional sender to be passed to the listener. Default value is
|
||||
* the return value of <getEventSource>.
|
||||
*/
|
||||
fireEvent(evt: EventObject, sender: any = null): void {
|
||||
if (this.eventListeners != null && this.isEventsEnabled()) {
|
||||
if (evt == null) {
|
||||
fireEvent(evt: EventObject, sender: any = null) {
|
||||
if (this.isEventsEnabled()) {
|
||||
if (!evt) {
|
||||
evt = new EventObject('');
|
||||
}
|
||||
|
||||
if (sender == null) {
|
||||
if (!sender) {
|
||||
sender = this.getEventSource();
|
||||
}
|
||||
if (sender == null) {
|
||||
if (!sender) {
|
||||
sender = this;
|
||||
}
|
||||
|
||||
for (const eventListener of this.eventListeners) {
|
||||
if (eventListener.name == null || eventListener.name === evt.getName()) {
|
||||
if (eventListener.name === null || eventListener.name === evt.getName()) {
|
||||
eventListener.funct.apply(this, [sender, evt]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,13 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import {getClientX, getClientY, getSource, isMouseEvent, isPopupTrigger} from '../../util/EventUtils';
|
||||
import {
|
||||
getClientX,
|
||||
getClientY,
|
||||
getSource,
|
||||
isMouseEvent,
|
||||
isPopupTrigger,
|
||||
} from '../../util/EventUtils';
|
||||
import { isAncestorNode } from '../../util/DomUtils';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
|
@ -119,11 +125,8 @@ class InternalMouseEvent {
|
|||
*
|
||||
* Returns true if the given <mxShape> is the source of <evt>.
|
||||
*/
|
||||
isSource(shape: Shape): boolean {
|
||||
if (shape != null) {
|
||||
return isAncestorNode(shape.node, this.getSource());
|
||||
}
|
||||
return false;
|
||||
isSource(shape: Shape) {
|
||||
return shape ? isAncestorNode(shape.node, this.getSource()) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,7 +134,7 @@ class InternalMouseEvent {
|
|||
*
|
||||
* Returns <evt.clientX>.
|
||||
*/
|
||||
getX(): number {
|
||||
getX() {
|
||||
return getClientX(this.getEvent());
|
||||
}
|
||||
|
||||
|
@ -140,7 +143,7 @@ class InternalMouseEvent {
|
|||
*
|
||||
* Returns <evt.clientY>.
|
||||
*/
|
||||
getY(): number {
|
||||
getY() {
|
||||
return getClientY(this.getEvent());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import Image from "../image/Image";
|
||||
import mxClient from "../../mxClient";
|
||||
import Graph from "../Graph";
|
||||
import CellState from "../cell/datatypes/CellState";
|
||||
import Cell from "../cell/datatypes/Cell";
|
||||
import CellArray from "../cell/datatypes/CellArray";
|
||||
import EventObject from "../event/EventObject";
|
||||
import InternalEvent from "../event/InternalEvent";
|
||||
import Geometry from "../geometry/Geometry";
|
||||
import {getValue, toRadians} from "../../util/Utils";
|
||||
import Rectangle from "../geometry/Rectangle";
|
||||
import Image from '../image/ImageBox';
|
||||
import mxClient from '../../mxClient';
|
||||
import Graph from '../Graph';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Geometry from '../geometry/Geometry';
|
||||
import { getValue, toRadians } from '../../util/Utils';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
|
||||
/**
|
||||
* GraphFoldingOptions
|
||||
|
@ -25,21 +25,22 @@ import Rectangle from "../geometry/Rectangle";
|
|||
* a cell is first collapsed.
|
||||
*/
|
||||
type GraphFoldingOptions = {
|
||||
foldingEnabled: boolean,
|
||||
collapsedImage: Image,
|
||||
expandedImage: Image,
|
||||
collapseToPreferredSize: boolean,
|
||||
foldingEnabled: boolean;
|
||||
collapsedImage: Image;
|
||||
expandedImage: Image;
|
||||
collapseToPreferredSize: boolean;
|
||||
};
|
||||
|
||||
class GraphFolding {
|
||||
constructor(graph: Graph,
|
||||
constructor(
|
||||
graph: Graph,
|
||||
options: GraphFoldingOptions = {
|
||||
foldingEnabled: true,
|
||||
collapsedImage: new Image(`${mxClient.imageBasePath}/collapsed.gif`, 9, 9),
|
||||
expandedImage: new Image(`${mxClient.imageBasePath}/expanded.gif`, 9, 9),
|
||||
collapseToPreferredSize: true,
|
||||
}) {
|
||||
|
||||
}
|
||||
) {
|
||||
this.graph = graph;
|
||||
this.options = options;
|
||||
}
|
||||
|
@ -53,8 +54,7 @@ class GraphFolding {
|
|||
* the tooltip.
|
||||
* @default 'collapse-expand'
|
||||
*/
|
||||
collapseExpandResource: string =
|
||||
mxClient.language != 'none' ? 'collapse-expand' : '';
|
||||
collapseExpandResource: string = mxClient.language != 'none' ? 'collapse-expand' : '';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -64,10 +64,7 @@ class GraphFolding {
|
|||
/**
|
||||
* Returns the cells which are movable in the given array of cells.
|
||||
*/
|
||||
getFoldableCells(
|
||||
cells: CellArray,
|
||||
collapse: boolean = false
|
||||
): CellArray | null {
|
||||
getFoldableCells(cells: CellArray, collapse: boolean = false): CellArray | null {
|
||||
return this.graph.model.filterCells(cells, (cell: Cell) => {
|
||||
return this.isCellFoldable(cell, collapse);
|
||||
});
|
||||
|
@ -272,12 +269,7 @@ class GraphFolding {
|
|||
}
|
||||
}
|
||||
|
||||
geo.alternateBounds = new Rectangle(
|
||||
0,
|
||||
0,
|
||||
bounds.width,
|
||||
bounds.height
|
||||
);
|
||||
geo.alternateBounds = new Rectangle(0, 0, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
if (geo.alternateBounds != null) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Point from './Point';
|
||||
import Rectangle from './Rectangle';
|
||||
import utils, { equalPoints, getRotatedPoint, toRadians } from '../../util/Utils';
|
||||
import { equalPoints, getRotatedPoint, toRadians } from '../../util/Utils';
|
||||
import { clone } from '../../util/CloneUtils';
|
||||
|
||||
/**
|
||||
|
@ -74,12 +74,7 @@ import { clone } from '../../util/CloneUtils';
|
|||
* defines the absolute offset for the label inside the vertex or group.
|
||||
*/
|
||||
class Geometry extends Rectangle {
|
||||
constructor(
|
||||
x: number = 0,
|
||||
y: number = 0,
|
||||
width: number = 0,
|
||||
height: number = 0
|
||||
) {
|
||||
constructor(x = 0, y = 0, width = 0, height = 0) {
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
*/
|
||||
import Rectangle from '../Rectangle';
|
||||
import Shape from './Shape';
|
||||
import mxSvgCanvas2D from '../../../util/canvas/mxSvgCanvas2D';
|
||||
import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
import { NONE } from 'packages/core/src/util/Constants';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement an actor shape. If a custom shape with one
|
||||
|
@ -34,27 +36,21 @@ import mxSvgCanvas2D from '../../../util/canvas/mxSvgCanvas2D';
|
|||
class Actor extends Shape {
|
||||
constructor(
|
||||
bounds: Rectangle | null = null,
|
||||
fill: string | null = null,
|
||||
stroke: string | null = null,
|
||||
strokewidth: number = 1
|
||||
fill: ColorValue = NONE,
|
||||
stroke: ColorValue = NONE,
|
||||
strokeWidth: number = 1
|
||||
) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to redrawPath for subclasses to work.
|
||||
*/
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
paintVertexShape(c: SvgCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.translate(x, y);
|
||||
c.begin();
|
||||
this.redrawPath(c, x, y, w, h);
|
||||
|
@ -64,13 +60,7 @@ class Actor extends Shape {
|
|||
/**
|
||||
* Draws the path for this shape.
|
||||
*/
|
||||
redrawPath(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
redrawPath(c: SvgCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
const width = w / 3;
|
||||
c.moveTo(0, h);
|
||||
c.curveTo(0, (3 * h) / 5, 0, (2 * h) / 5, w / 2, (2 * h) / 5);
|
||||
|
|
|
@ -8,7 +8,6 @@ import Rectangle from '../Rectangle';
|
|||
import {
|
||||
getBoundingBox,
|
||||
getDirectedBounds,
|
||||
getValue,
|
||||
isNotNullish,
|
||||
mod,
|
||||
} from '../../../util/Utils';
|
||||
|
@ -24,30 +23,22 @@ import {
|
|||
SHADOW_OFFSET_Y,
|
||||
} from '../../../util/Constants';
|
||||
import Point from '../Point';
|
||||
import mxSvgCanvas2D from '../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from 'packages/core/src/util/canvas/AbstractCanvas2D';
|
||||
import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D';
|
||||
import InternalEvent from '../../event/InternalEvent';
|
||||
import mxClient from '../../../mxClient';
|
||||
import CellState from '../../cell/datatypes/CellState';
|
||||
import StencilShape from './node/StencilShape';
|
||||
import CellOverlay from '../../cell/CellOverlay';
|
||||
import ImageBox from '../../image/ImageBox';
|
||||
|
||||
import type {
|
||||
ArrowType,
|
||||
CellStateStyles,
|
||||
ColorValue,
|
||||
DirectionValue,
|
||||
GradientMap,
|
||||
} from '../../../types';
|
||||
import Image from '../../image/Image';
|
||||
|
||||
const toBool = (i: any) => {
|
||||
if (i === 0) return false;
|
||||
if (i === 1) return true;
|
||||
if (i === '0') return false;
|
||||
if (i === '1') return true;
|
||||
if (String(i).toLowerCase() === 'true') return true;
|
||||
if (String(i).toLowerCase() === 'false') return false;
|
||||
return !!i;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all shapes.
|
||||
|
@ -94,9 +85,14 @@ const toBool = (i: any) => {
|
|||
*/
|
||||
class Shape {
|
||||
constructor(stencil: StencilShape | null = null) {
|
||||
// `stencil` is not null when instantiated directly,
|
||||
// but can be null when instantiated through a child class.
|
||||
if (stencil) {
|
||||
this.stencil = stencil;
|
||||
}
|
||||
|
||||
// moved from init()
|
||||
this.node = this.create();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,15 +105,11 @@ class Shape {
|
|||
*
|
||||
* container - DOM node that will contain the shape.
|
||||
*/
|
||||
init(container: SVGElement | null = null) {
|
||||
if (!this.node) {
|
||||
this.node = this.create();
|
||||
|
||||
if (container) {
|
||||
init(container: SVGElement) {
|
||||
if (!this.node.parentNode) {
|
||||
container.appendChild(this.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: initStyles
|
||||
|
@ -125,7 +117,7 @@ class Shape {
|
|||
* Sets the styles to their default values.
|
||||
*/
|
||||
initStyles() {
|
||||
this.strokewidth = 1;
|
||||
this.strokeWidth = 1;
|
||||
this.rotation = 0;
|
||||
this.opacity = 100;
|
||||
this.fillOpacity = 100;
|
||||
|
@ -146,31 +138,31 @@ class Shape {
|
|||
opacity = 100;
|
||||
isDashed = false;
|
||||
|
||||
fill: string | null = null;
|
||||
fill: ColorValue = NONE;
|
||||
|
||||
gradient: string | null = null;
|
||||
gradient: ColorValue = NONE;
|
||||
|
||||
gradientDirection: string | null = null;
|
||||
gradientDirection: DirectionValue = DIRECTION_EAST;
|
||||
|
||||
fillOpacity = 100;
|
||||
|
||||
strokeOpacity: number | null = 100;
|
||||
strokeOpacity = 100;
|
||||
|
||||
stroke: string | null = null;
|
||||
stroke: ColorValue = NONE;
|
||||
|
||||
strokewidth: number | null = 1;
|
||||
strokeWidth = 1;
|
||||
|
||||
spacing: number | null = null;
|
||||
spacing = 0;
|
||||
|
||||
startSize: number | null = null;
|
||||
startSize = 1;
|
||||
|
||||
endSize: number | null = null;
|
||||
endSize = 1;
|
||||
|
||||
startArrow: string | null = null;
|
||||
startArrow: ArrowType = NONE;
|
||||
|
||||
endArrow: string | null = null;
|
||||
endArrow: ArrowType = NONE;
|
||||
|
||||
direction: DirectionValue | null = null;
|
||||
direction: DirectionValue = DIRECTION_EAST;
|
||||
|
||||
flipH = false;
|
||||
|
||||
|
@ -184,7 +176,7 @@ class Shape {
|
|||
|
||||
cursor = '';
|
||||
|
||||
verticalTextRotation: number | null = null;
|
||||
verticalTextRotation = 0;
|
||||
|
||||
oldGradients: GradientMap = {};
|
||||
|
||||
|
@ -238,7 +230,7 @@ class Shape {
|
|||
*
|
||||
* Holds the outermost DOM node that represents this shape.
|
||||
*/
|
||||
node: SVGGElement | null = null;
|
||||
node: SVGGElement;
|
||||
|
||||
/**
|
||||
* Variable: state
|
||||
|
@ -332,15 +324,15 @@ class Shape {
|
|||
*/
|
||||
useSvgBoundingBox = true;
|
||||
|
||||
image: Image | null = null;
|
||||
image: ImageBox | null = null;
|
||||
|
||||
indicatorColor: ColorValue = null;
|
||||
indicatorColor: ColorValue = NONE;
|
||||
|
||||
indicatorStrokeColor: ColorValue = null;
|
||||
indicatorStrokeColor: ColorValue = NONE;
|
||||
|
||||
indicatorGradientColor: ColorValue = null;
|
||||
indicatorGradientColor: ColorValue = NONE;
|
||||
|
||||
indicatorDirection: DirectionValue = null;
|
||||
indicatorDirection: DirectionValue = DIRECTION_EAST;
|
||||
|
||||
/**
|
||||
* Function: isHtmlAllowed
|
||||
|
@ -357,11 +349,11 @@ class Shape {
|
|||
*
|
||||
* Returns 0, or 0.5 if <strokewidth> % 2 == 1.
|
||||
*/
|
||||
getSvgScreenOffset() {
|
||||
getSvgScreenOffset(): number {
|
||||
const sw =
|
||||
this.stencil && this.stencil.strokewidth !== 'inherit'
|
||||
? Number(this.stencil.strokewidth)
|
||||
: this.strokewidth ?? 0;
|
||||
this.stencil && this.stencil.strokeWidthValue !== 'inherit'
|
||||
? Number(this.stencil.strokeWidthValue)
|
||||
: this.strokeWidth ?? 0;
|
||||
|
||||
return mod(Math.max(1, Math.round(sw * this.scale)), 2) === 1 ? 0.5 : 0;
|
||||
}
|
||||
|
@ -398,8 +390,6 @@ class Shape {
|
|||
* Creates and returns the SVG node(s) to represent this shape.
|
||||
*/
|
||||
redraw() {
|
||||
if (!this.node) return;
|
||||
|
||||
this.updateBoundsFromPoints();
|
||||
|
||||
if (this.visible && this.checkBounds()) {
|
||||
|
@ -419,8 +409,6 @@ class Shape {
|
|||
* Removes all child nodes and resets all CSS.
|
||||
*/
|
||||
clear() {
|
||||
if (!this.node) return;
|
||||
|
||||
while (this.node.lastChild) {
|
||||
this.node.removeChild(this.node.lastChild);
|
||||
}
|
||||
|
@ -435,18 +423,11 @@ class Shape {
|
|||
const pts = this.points;
|
||||
|
||||
if (pts.length > 0 && pts[0]) {
|
||||
this.bounds = new Rectangle(
|
||||
Math.round(pts[0].x),
|
||||
Math.round(pts[0].y),
|
||||
1,
|
||||
1
|
||||
);
|
||||
this.bounds = new Rectangle(Math.round(pts[0].x), Math.round(pts[0].y), 1, 1);
|
||||
|
||||
for (const pt of pts) {
|
||||
if (pt) {
|
||||
this.bounds.add(
|
||||
new Rectangle(Math.round(pt.x), Math.round(pt.y), 1, 1)
|
||||
);
|
||||
this.bounds.add(new Rectangle(Math.round(pt.x), Math.round(pt.y), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -460,7 +441,7 @@ class Shape {
|
|||
* change the rectangle in-place. This implementation returns the given rect.
|
||||
*/
|
||||
getLabelBounds(rect: Rectangle) {
|
||||
const d = getValue(this.style, 'direction', DIRECTION_EAST);
|
||||
const d = this.style?.direction ?? DIRECTION_EAST;
|
||||
let bounds = rect.clone();
|
||||
|
||||
// Normalizes argument for getLabelMargins hook
|
||||
|
@ -480,15 +461,11 @@ class Shape {
|
|||
if (labelMargins) {
|
||||
labelMargins = labelMargins.clone();
|
||||
|
||||
let flipH = toBool(getValue(this.style, 'flipH', false));
|
||||
let flipV = toBool(getValue(this.style, 'flipV', false));
|
||||
let flipH = this.style?.flipH ?? false;
|
||||
let flipV = this.style?.flipV ?? false;
|
||||
|
||||
// Handles special case for vertical labels
|
||||
if (
|
||||
this.state &&
|
||||
this.state.text &&
|
||||
this.state.text.isPaintBoundsInverted()
|
||||
) {
|
||||
if (this.state && this.state.text && this.state.text.isPaintBoundsInverted()) {
|
||||
const tmp = labelMargins.x;
|
||||
labelMargins.x = labelMargins.height;
|
||||
labelMargins.height = labelMargins.width;
|
||||
|
@ -540,8 +517,6 @@ class Shape {
|
|||
* Updates the SVG or VML shape.
|
||||
*/
|
||||
redrawShape() {
|
||||
if (!this.node) return;
|
||||
|
||||
const canvas = this.createCanvas();
|
||||
|
||||
if (canvas) {
|
||||
|
@ -552,7 +527,7 @@ class Shape {
|
|||
this.paint(canvas);
|
||||
this.afterPaint(canvas);
|
||||
|
||||
if (this.node !== canvas.root) {
|
||||
if (this.node !== canvas.root && canvas.root) {
|
||||
// Forces parsing in IE8 standards mode - slow! avoid
|
||||
this.node.insertAdjacentHTML('beforeend', canvas.root.outerHTML);
|
||||
}
|
||||
|
@ -570,7 +545,7 @@ class Shape {
|
|||
const canvas = this.createSvgCanvas();
|
||||
|
||||
if (canvas && this.outline) {
|
||||
canvas.setStrokeWidth(this.strokewidth);
|
||||
canvas.setStrokeWidth(this.strokeWidth);
|
||||
canvas.setStrokeColor(this.stroke);
|
||||
|
||||
if (this.isDashed) {
|
||||
|
@ -596,7 +571,7 @@ class Shape {
|
|||
createSvgCanvas() {
|
||||
if (!this.node) return null;
|
||||
|
||||
const canvas = new mxSvgCanvas2D(this.node, false);
|
||||
const canvas = new SvgCanvas2D(this.node, false);
|
||||
canvas.strokeTolerance = this.pointerEvents ? this.svgStrokeTolerance : 0;
|
||||
canvas.pointerEventsValue = this.svgPointerEvents;
|
||||
|
||||
|
@ -626,9 +601,9 @@ class Shape {
|
|||
* Destroys the given canvas which was used for drawing. This implementation
|
||||
* increments the reference counts on all shared gradients used in the canvas.
|
||||
*/
|
||||
destroyCanvas(canvas: mxSvgCanvas2D) {
|
||||
destroyCanvas(canvas: AbstractCanvas2D) {
|
||||
// Manages reference counts
|
||||
if (canvas instanceof mxSvgCanvas2D) {
|
||||
if (canvas instanceof SvgCanvas2D) {
|
||||
// Increments ref counts
|
||||
for (const key in canvas.gradients) {
|
||||
const gradient = canvas.gradients[key];
|
||||
|
@ -648,19 +623,19 @@ class Shape {
|
|||
*
|
||||
* Invoked before paint is called.
|
||||
*/
|
||||
beforePaint(c: mxSvgCanvas2D) {}
|
||||
beforePaint(c: AbstractCanvas2D) {}
|
||||
|
||||
/**
|
||||
* Function: afterPaint
|
||||
*
|
||||
* Invokes after paint was called.
|
||||
*/
|
||||
afterPaint(c: mxSvgCanvas2D) {}
|
||||
afterPaint(c: AbstractCanvas2D) {}
|
||||
|
||||
/**
|
||||
* Generic rendering code.
|
||||
*/
|
||||
paint(c: mxSvgCanvas2D) {
|
||||
paint(c: AbstractCanvas2D) {
|
||||
let strokeDrawn = false;
|
||||
|
||||
if (c && this.outline) {
|
||||
|
@ -705,20 +680,13 @@ class Shape {
|
|||
let bg = null;
|
||||
|
||||
if (
|
||||
(!this.stencil &&
|
||||
this.points.length === 0 &&
|
||||
this.shapePointerEvents) ||
|
||||
(!this.stencil && this.points.length === 0 && this.shapePointerEvents) ||
|
||||
(this.stencil && this.stencilPointerEvents)
|
||||
) {
|
||||
const bb = this.createBoundingBox();
|
||||
|
||||
if (bb && this.node) {
|
||||
bg = this.createTransparentSvgRectangle(
|
||||
bb.x,
|
||||
bb.y,
|
||||
bb.width,
|
||||
bb.height
|
||||
);
|
||||
bg = this.createTransparentSvgRectangle(bb.x, bb.y, bb.width, bb.height);
|
||||
this.node.appendChild(bg);
|
||||
}
|
||||
}
|
||||
|
@ -727,7 +695,7 @@ class Shape {
|
|||
this.stencil.drawShape(c, this, x, y, w, h);
|
||||
} else {
|
||||
// Stencils have separate strokewidth
|
||||
c.setStrokeWidth(this.strokewidth);
|
||||
c.setStrokeWidth(this.strokeWidth);
|
||||
|
||||
if (this.points.length > 0) {
|
||||
// Paints edge shape
|
||||
|
@ -763,49 +731,30 @@ class Shape {
|
|||
/**
|
||||
* Sets the state of the canvas for drawing the shape.
|
||||
*/
|
||||
// configureCanvas(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
configureCanvas(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
let dash = null;
|
||||
configureCanvas(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
let dash = NONE;
|
||||
|
||||
if (this.style != null) {
|
||||
if (this.style) {
|
||||
dash = this.style.dashPattern;
|
||||
}
|
||||
|
||||
c.setAlpha(<number>this.opacity / 100);
|
||||
c.setFillAlpha(<number>this.fillOpacity / 100);
|
||||
c.setStrokeAlpha(<number>this.strokeOpacity / 100);
|
||||
c.setAlpha(this.opacity / 100);
|
||||
c.setFillAlpha(this.fillOpacity / 100);
|
||||
c.setStrokeAlpha(this.strokeOpacity / 100);
|
||||
|
||||
// Sets alpha, colors and gradients
|
||||
if (this.isShadow != null) {
|
||||
if (this.isShadow) {
|
||||
c.setShadow(this.isShadow);
|
||||
}
|
||||
|
||||
// Dash pattern
|
||||
if (this.isDashed != null) {
|
||||
c.setDashed(
|
||||
this.isDashed,
|
||||
this.style != null
|
||||
? toBool(getValue(this.style, 'fixDash', false))
|
||||
: false
|
||||
);
|
||||
if (this.isDashed) {
|
||||
c.setDashed(this.isDashed, this.style?.fixDash ?? false);
|
||||
}
|
||||
|
||||
if (dash != null) {
|
||||
c.setDashPattern(dash);
|
||||
}
|
||||
|
||||
if (
|
||||
this.fill != null &&
|
||||
this.fill !== NONE &&
|
||||
this.gradient &&
|
||||
this.gradient !== NONE
|
||||
) {
|
||||
if (this.fill !== NONE && this.gradient !== NONE) {
|
||||
const b = this.getGradientBounds(c, x, y, w, h);
|
||||
c.setGradient(
|
||||
this.fill,
|
||||
|
@ -828,14 +777,7 @@ class Shape {
|
|||
*
|
||||
* Returns the bounding box for the gradient box for this shape.
|
||||
*/
|
||||
// getGradientBounds(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): mxRectangle;
|
||||
getGradientBounds(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
getGradientBounds(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return new Rectangle(x, y, w, h);
|
||||
}
|
||||
|
||||
|
@ -844,25 +786,12 @@ class Shape {
|
|||
*
|
||||
* Sets the scale and rotation on the given canvas.
|
||||
*/
|
||||
// updateTransform(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
updateTransform(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
updateTransform(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
// NOTE: Currently, scale is implemented in state and canvas. This will
|
||||
// move to canvas in a later version, so that the states are unscaled
|
||||
// and untranslated and do not need an update after zooming or panning.
|
||||
c.scale(this.scale);
|
||||
c.rotate(
|
||||
this.getShapeRotation(),
|
||||
this.flipH,
|
||||
this.flipV,
|
||||
x + w / 2,
|
||||
y + h / 2
|
||||
);
|
||||
c.rotate(this.getShapeRotation(), this.flipH, this.flipV, x + w / 2, y + h / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -870,21 +799,10 @@ class Shape {
|
|||
*
|
||||
* Paints the vertex shape.
|
||||
*/
|
||||
// paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
this.paintBackground(c, x, y, w, h);
|
||||
|
||||
if (
|
||||
!this.outline ||
|
||||
this.style == null ||
|
||||
toBool(getValue(this.style, 'backgroundOutline', 0) === false)
|
||||
) {
|
||||
if (!this.outline || !this.style || this.style.backgroundOutline === 0) {
|
||||
c.setShadow(false);
|
||||
this.paintForeground(c, x, y, w, h);
|
||||
}
|
||||
|
@ -895,55 +813,32 @@ class Shape {
|
|||
*
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
// paintBackground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintBackground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {}
|
||||
paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {}
|
||||
|
||||
/**
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
// paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintForeground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {}
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {}
|
||||
|
||||
/**
|
||||
* Function: paintEdgeShape
|
||||
*
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
// paintEdgeShape(c: mxAbstractCanvas2D, pts: mxPoint[]): void;
|
||||
paintEdgeShape(c: mxSvgCanvas2D, pts: Point[]): void {}
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]) {}
|
||||
|
||||
/**
|
||||
* Function: getArcSize
|
||||
*
|
||||
* Returns the arc size for the given dimension.
|
||||
*/
|
||||
// getArcSize(w: number, h: number): number;
|
||||
getArcSize(w: number, h: number): number {
|
||||
getArcSize(w: number, h: number) {
|
||||
let r = 0;
|
||||
|
||||
if (toBool(getValue(this.style, 'absoluteArcSize', 0))) {
|
||||
r = Math.min(
|
||||
w / 2,
|
||||
Math.min(h / 2, getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2)
|
||||
);
|
||||
if (this.style?.absoluteArcSize === 0) {
|
||||
r = Math.min(w / 2, Math.min(h / 2, (this.style?.arcSize ?? LINE_ARCSIZE) / 2));
|
||||
} else {
|
||||
const f = parseFloat(
|
||||
String(
|
||||
getValue(this.style, 'arcSize', RECTANGLE_ROUNDING_FACTOR * 100) / 100
|
||||
)
|
||||
);
|
||||
const f = (this.style?.arcSize ?? RECTANGLE_ROUNDING_FACTOR * 100) / 100;
|
||||
r = Math.min(w * f, h * f);
|
||||
}
|
||||
return r;
|
||||
|
@ -954,16 +849,15 @@ class Shape {
|
|||
*
|
||||
* Paints the glass gradient effect.
|
||||
*/
|
||||
// paintGlassEffect(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number, arc: number): void;
|
||||
paintGlassEffect(
|
||||
c: mxSvgCanvas2D,
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
arc: number
|
||||
) {
|
||||
const sw = Math.ceil((this.strokewidth ?? 0) / 2);
|
||||
const sw = Math.ceil((this.strokeWidth ?? 0) / 2);
|
||||
const size = 0.4;
|
||||
|
||||
c.setGradient('#ffffff', '#ffffff', x, y, w, h * 0.6, 'south', 0.9, 0.1);
|
||||
|
@ -994,7 +888,7 @@ class Shape {
|
|||
* Paints the given points with rounded corners.
|
||||
*/
|
||||
addPoints(
|
||||
c: mxSvgCanvas2D,
|
||||
c: AbstractCanvas2D,
|
||||
pts: Point[],
|
||||
rounded: boolean = false,
|
||||
arcSize: number,
|
||||
|
@ -1009,10 +903,7 @@ class Shape {
|
|||
if (close && rounded) {
|
||||
pts = pts.slice();
|
||||
const p0 = pts[0];
|
||||
const wp = new Point(
|
||||
pe.x + (p0.x - pe.x) / 2,
|
||||
pe.y + (p0.y - pe.y) / 2
|
||||
);
|
||||
const wp = new Point(pe.x + (p0.x - pe.x) / 2, pe.y + (p0.y - pe.y) / 2);
|
||||
pts.splice(0, 0, wp);
|
||||
}
|
||||
|
||||
|
@ -1096,15 +987,15 @@ class Shape {
|
|||
|
||||
this.spacing = 0;
|
||||
|
||||
this.fill = null;
|
||||
this.gradient = null;
|
||||
this.gradientDirection = null;
|
||||
this.stroke = null;
|
||||
this.startSize = null;
|
||||
this.endSize = null;
|
||||
this.startArrow = null;
|
||||
this.endArrow = null;
|
||||
this.direction = null;
|
||||
this.fill = NONE;
|
||||
this.gradient = NONE;
|
||||
this.gradientDirection = DIRECTION_EAST;
|
||||
this.stroke = NONE;
|
||||
this.startSize = 1;
|
||||
this.endSize = 1;
|
||||
this.startArrow = NONE;
|
||||
this.endArrow = NONE;
|
||||
this.direction = DIRECTION_EAST;
|
||||
|
||||
this.isShadow = false;
|
||||
this.isDashed = false;
|
||||
|
@ -1151,81 +1042,35 @@ class Shape {
|
|||
this.state = state;
|
||||
this.style = state.style;
|
||||
|
||||
const ifNotNullElse = (value: any, defaultValue: any) => {
|
||||
if (isNotNullish(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
if (this.style) {
|
||||
this.fill = ifNotNullElse(this.style.fillColor, this.fill);
|
||||
this.gradient = ifNotNullElse(this.style.gradientColor, this.gradient);
|
||||
this.gradientDirection = ifNotNullElse(
|
||||
this.style.gradientDirection,
|
||||
this.gradientDirection
|
||||
);
|
||||
this.opacity = ifNotNullElse(this.style.opacity, this.opacity);
|
||||
this.fillOpacity = ifNotNullElse(
|
||||
this.style.fillOpacity,
|
||||
this.fillOpacity
|
||||
);
|
||||
this.strokeOpacity = ifNotNullElse(
|
||||
this.style.strokeOpacity,
|
||||
this.strokeOpacity
|
||||
);
|
||||
this.stroke = ifNotNullElse(this.style.strokeColor, this.stroke);
|
||||
this.strokewidth = ifNotNullElse(
|
||||
this.style.strokeWidth,
|
||||
this.strokewidth
|
||||
);
|
||||
this.spacing = ifNotNullElse(this.style.spacing, this.spacing);
|
||||
this.startSize = ifNotNullElse(this.style.startSize, this.startSize);
|
||||
this.endSize = ifNotNullElse(this.style.endSize, this.endSize);
|
||||
this.startArrow = ifNotNullElse(this.style.startArrow, this.startArrow);
|
||||
this.endArrow = ifNotNullElse(this.style.endArrow, this.endArrow);
|
||||
this.rotation = ifNotNullElse(this.style.rotation, this.rotation);
|
||||
this.direction = ifNotNullElse(this.style.direction, this.direction);
|
||||
this.fill = this.style.fillColor;
|
||||
this.gradient = this.style.gradientColor;
|
||||
this.gradientDirection = this.style.gradientDirection;
|
||||
this.opacity = this.style.opacity;
|
||||
this.fillOpacity = this.style.fillOpacity;
|
||||
this.strokeOpacity = this.style.strokeOpacity;
|
||||
this.stroke = this.style.strokeColor;
|
||||
this.strokeWidth = this.style.strokeWidth;
|
||||
this.spacing = this.style.spacing;
|
||||
this.startSize = this.style.startSize;
|
||||
this.endSize = this.style.endSize;
|
||||
this.startArrow = this.style.startArrow;
|
||||
this.endArrow = this.style.endArrow;
|
||||
this.rotation = this.style.rotation;
|
||||
this.direction = this.style.direction;
|
||||
this.flipH = this.style.flipH;
|
||||
this.flipV = this.style.flipV;
|
||||
|
||||
this.flipH = toBool(ifNotNullElse(this.style.flipH, 0));
|
||||
this.flipV = toBool(ifNotNullElse(this.style.flipV, 0));
|
||||
|
||||
// Legacy support for stencilFlipH/V
|
||||
if (this.stencil) {
|
||||
this.flipH = toBool(
|
||||
ifNotNullElse(this.style.stencilFlipH, this.flipH || 0)
|
||||
);
|
||||
this.flipV = toBool(
|
||||
ifNotNullElse(this.style.stencilFlipV, this.flipV || 0)
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
this.direction === DIRECTION_NORTH ||
|
||||
this.direction === DIRECTION_SOUTH
|
||||
) {
|
||||
if (this.direction === DIRECTION_NORTH || this.direction === DIRECTION_SOUTH) {
|
||||
const tmp = this.flipH;
|
||||
this.flipH = this.flipV;
|
||||
this.flipV = tmp;
|
||||
}
|
||||
|
||||
this.isShadow = toBool(ifNotNullElse(this.style.shadow, this.isShadow));
|
||||
this.isDashed = toBool(ifNotNullElse(this.style.dashed, this.isDashed));
|
||||
this.isRounded = toBool(
|
||||
ifNotNullElse(this.style.rounded, this.isRounded)
|
||||
);
|
||||
this.glass = toBool(ifNotNullElse(this.style.glass, this.glass));
|
||||
|
||||
if (this.fill === NONE) {
|
||||
this.fill = null;
|
||||
}
|
||||
if (this.gradient === NONE) {
|
||||
this.gradient = null;
|
||||
}
|
||||
if (this.stroke === NONE) {
|
||||
this.stroke = null;
|
||||
}
|
||||
this.isShadow = this.style.shadow;
|
||||
this.isDashed = this.style.dashed;
|
||||
this.isRounded = this.style.rounded;
|
||||
this.glass = this.style.glass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1240,11 +1085,8 @@ class Shape {
|
|||
*/
|
||||
setCursor(cursor: string) {
|
||||
this.cursor = cursor;
|
||||
|
||||
if (this.node) {
|
||||
this.node.style.cursor = cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: getCursor
|
||||
|
@ -1258,7 +1100,7 @@ class Shape {
|
|||
/**
|
||||
* Hook for subclassers.
|
||||
*/
|
||||
isRoundable(c: mxSvgCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
isRoundable(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1271,7 +1113,7 @@ class Shape {
|
|||
updateBoundingBox() {
|
||||
// Tries to get bounding box from SVG subsystem
|
||||
// LATER: Use getBoundingClientRect for fallback in VML
|
||||
if (this.useSvgBoundingBox && this.node && this.node.ownerSVGElement) {
|
||||
if (this.useSvgBoundingBox && this.node.ownerSVGElement) {
|
||||
try {
|
||||
const b = this.node.getBBox();
|
||||
|
||||
|
@ -1279,7 +1121,7 @@ class Shape {
|
|||
this.boundingBox = new Rectangle(b.x, b.y, b.width, b.height);
|
||||
|
||||
// Adds strokeWidth
|
||||
this.boundingBox.grow(((this.strokewidth ?? 0) * this.scale) / 2);
|
||||
this.boundingBox.grow(((this.strokeWidth ?? 0) * this.scale) / 2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1316,8 +1158,7 @@ class Shape {
|
|||
const bb = this.bounds.clone();
|
||||
if (
|
||||
(this.stencil &&
|
||||
(this.direction === DIRECTION_NORTH ||
|
||||
this.direction === DIRECTION_SOUTH)) ||
|
||||
(this.direction === DIRECTION_NORTH || this.direction === DIRECTION_SOUTH)) ||
|
||||
this.isPaintBoundsInverted()
|
||||
) {
|
||||
bb.rotate90();
|
||||
|
@ -1334,8 +1175,9 @@ class Shape {
|
|||
bbox.width += Math.ceil(SHADOW_OFFSET_X * this.scale);
|
||||
bbox.height += Math.ceil(SHADOW_OFFSET_Y * this.scale);
|
||||
}
|
||||
|
||||
// Adds strokeWidth
|
||||
bbox.grow(((this.strokewidth ?? 0) * this.scale) / 2);
|
||||
bbox.grow(((this.strokeWidth ?? 0) * this.scale) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1368,7 +1210,7 @@ class Shape {
|
|||
getTextRotation() {
|
||||
let rot = this.getRotation();
|
||||
|
||||
if (!toBool(getValue(this.style, 'horizontal', 1))) {
|
||||
if (!(this.style?.horizontal ?? true)) {
|
||||
rot += this.verticalTextRotation || -90; // WARNING WARNING!!!! ===============================================================================================
|
||||
}
|
||||
|
||||
|
@ -1383,7 +1225,6 @@ class Shape {
|
|||
getShapeRotation() {
|
||||
let rot = this.getRotation();
|
||||
|
||||
if (this.direction) {
|
||||
if (this.direction === DIRECTION_NORTH) {
|
||||
rot += 270;
|
||||
} else if (this.direction === DIRECTION_WEST) {
|
||||
|
@ -1391,7 +1232,6 @@ class Shape {
|
|||
} else if (this.direction === DIRECTION_SOUTH) {
|
||||
rot += 90;
|
||||
}
|
||||
}
|
||||
|
||||
return rot;
|
||||
}
|
||||
|
@ -1413,6 +1253,8 @@ class Shape {
|
|||
return rect;
|
||||
}
|
||||
|
||||
redrawHtmlShape() {}
|
||||
|
||||
/**
|
||||
* Function: setTransparentBackgroundImage
|
||||
*
|
||||
|
@ -1450,15 +1292,13 @@ class Shape {
|
|||
* node associated with the shape using <mxEvent.release>.
|
||||
*/
|
||||
destroy() {
|
||||
if (this.node) {
|
||||
InternalEvent.release(this.node);
|
||||
|
||||
if (this.node.parentNode) {
|
||||
this.node.parentNode.removeChild(this.node);
|
||||
}
|
||||
|
||||
this.node = null;
|
||||
}
|
||||
this.node.innerHTML = '';
|
||||
|
||||
// Decrements refCount and removes unused
|
||||
this.releaseSvgGradients(this.oldGradients);
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
import Shape from '../Shape';
|
||||
import { ARROW_SIZE, ARROW_SPACING, ARROW_WIDTH } from '../../../../util/Constants';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Point from '../../Point';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement an arrow shape. The shape is used to represent edges, not vertices.
|
||||
|
@ -16,31 +17,41 @@ import Point from '../../Point';
|
|||
* This shape is registered under {@link mxConstants.SHAPE_ARROW} in {@link mxCellRenderer}.
|
||||
*/
|
||||
class Arrow extends Shape {
|
||||
constructor(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize) {
|
||||
constructor(
|
||||
points: Point[],
|
||||
fill: ColorValue,
|
||||
stroke: ColorValue,
|
||||
strokeWidth = 1,
|
||||
arrowWidth = ARROW_WIDTH,
|
||||
spacing = ARROW_SPACING,
|
||||
endSize = ARROW_SIZE
|
||||
) {
|
||||
super();
|
||||
this.points = points;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth != null ? strokewidth : 1;
|
||||
this.arrowWidth = arrowWidth != null ? arrowWidth : ARROW_WIDTH;
|
||||
this.spacing = spacing != null ? spacing : ARROW_SPACING;
|
||||
this.endSize = endSize != null ? endSize : ARROW_SIZE;
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.arrowWidth = arrowWidth;
|
||||
this.spacing = spacing;
|
||||
this.endSize = endSize;
|
||||
}
|
||||
|
||||
arrowWidth: number;
|
||||
|
||||
/**
|
||||
* Augments the bounding box with the edge width and markers.
|
||||
*/
|
||||
augmentBoundingBox(bbox: Rectangle): void {
|
||||
augmentBoundingBox(bbox: Rectangle) {
|
||||
super.augmentBoundingBox(bbox);
|
||||
|
||||
const w = Math.max(this.arrowWidth, this.endSize);
|
||||
bbox.grow((w / 2 + this.strokewidth) * this.scale);
|
||||
bbox.grow((w / 2 + this.strokeWidth) * this.scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintEdgeShape(c: mxAbstractCanvas2D, pts: Point[]): void {
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]) {
|
||||
// Geometry of arrow
|
||||
const spacing = ARROW_SPACING;
|
||||
const width = ARROW_WIDTH;
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
import Shape from '../Shape';
|
||||
import { ARROW_SIZE, ARROW_SPACING, ARROW_WIDTH, NONE } from '../../../../util/Constants';
|
||||
import utils, { getNumber, getValue, relativeCcw } from '../../../../util/Utils';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import { relativeCcw } from '../../../../util/Utils';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Point from '../../Point';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import CellState from '../../../cell/datatypes/CellState';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement an new rounded arrow shape with support for waypoints and double arrows. The
|
||||
|
@ -19,37 +20,48 @@ import CellState from '../../../cell/datatypes/CellState';
|
|||
* This shape is registered under {@link mxConstants.SHAPE_ARROW_CONNECTOR} in {@link mxCellRenderer}.
|
||||
*/
|
||||
class ArrowConnector extends Shape {
|
||||
constructor(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize) {
|
||||
constructor(
|
||||
points: Point[],
|
||||
fill: ColorValue,
|
||||
stroke: ColorValue,
|
||||
strokeWidth = 1,
|
||||
arrowWidth = ARROW_WIDTH,
|
||||
spacing = ARROW_SPACING,
|
||||
endSize = ARROW_SIZE / 5
|
||||
) {
|
||||
super();
|
||||
this.points = points;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth != null ? strokewidth : 1;
|
||||
this.arrowWidth = arrowWidth != null ? arrowWidth : ARROW_WIDTH;
|
||||
this.arrowSpacing = spacing != null ? spacing : ARROW_SPACING;
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.arrowWidth = arrowWidth;
|
||||
this.arrowSpacing = spacing;
|
||||
this.startSize = ARROW_SIZE / 5;
|
||||
this.endSize = endSize != null ? endSize : ARROW_SIZE / 5;
|
||||
this.endSize = endSize;
|
||||
}
|
||||
|
||||
arrowWidth: number;
|
||||
arrowSpacing: number;
|
||||
|
||||
/**
|
||||
* Allows to use the SVG bounding box in SVG.
|
||||
* @defaultValue `false` for performance reasons.
|
||||
*/
|
||||
useSvgBoundingBox: boolean = true;
|
||||
useSvgBoundingBox = true;
|
||||
|
||||
/**
|
||||
* Function: isRoundable
|
||||
*
|
||||
* Hook for subclassers.
|
||||
*/
|
||||
isRoundable(): boolean {
|
||||
isRoundable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides mxShape to reset spacing.
|
||||
*/
|
||||
resetStyles(): void {
|
||||
resetStyles() {
|
||||
super.resetStyles();
|
||||
this.arrowSpacing = ARROW_SPACING;
|
||||
}
|
||||
|
@ -60,9 +72,9 @@ class ArrowConnector extends Shape {
|
|||
apply(state: CellState): void {
|
||||
super.apply(state);
|
||||
|
||||
if (this.style != null) {
|
||||
this.startSize = getNumber(this.style, 'startSize', ARROW_SIZE / 5) * 3;
|
||||
this.endSize = getNumber(this.style, 'endSize', ARROW_SIZE / 5) * 3;
|
||||
if (this.style) {
|
||||
this.startSize = this.style.startSize * 3;
|
||||
this.endSize = this.style.endSize * 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,21 +94,18 @@ class ArrowConnector extends Shape {
|
|||
w = Math.max(w, this.getEndArrowWidth());
|
||||
}
|
||||
|
||||
bbox.grow((w / 2 + this.strokewidth) * this.scale);
|
||||
bbox.grow((w / 2 + this.strokeWidth) * this.scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintEdgeShape(c: mxAbstractCanvas2D, pts: Point[]): void {
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]): void {
|
||||
// Geometry of arrow
|
||||
let strokeWidth = this.strokewidth;
|
||||
let strokeWidth = this.strokeWidth;
|
||||
|
||||
if (this.outline) {
|
||||
strokeWidth = Math.max(
|
||||
1,
|
||||
utils.getNumber(this.style, 'strokeWidth', this.strokewidth)
|
||||
);
|
||||
strokeWidth = Math.max(1, this.style?.strokeWidth ?? 0);
|
||||
}
|
||||
|
||||
const startWidth = this.getStartArrowWidth() + strokeWidth;
|
||||
|
@ -226,7 +235,7 @@ class ArrowConnector extends Shape {
|
|||
// Higher strokewidths require a larger minimum bend, 0.35 covers all but the most extreme cases
|
||||
const strokeWidthFactor = Math.max(
|
||||
tmp,
|
||||
Math.min(this.strokewidth / 200 + 0.04, 0.35)
|
||||
Math.min(this.strokeWidth / 200 + 0.04, 0.35)
|
||||
);
|
||||
const angleFactor =
|
||||
pos !== 0 && isRounded
|
||||
|
@ -387,7 +396,18 @@ class ArrowConnector extends Shape {
|
|||
*
|
||||
* Paints the marker.
|
||||
*/
|
||||
paintMarker(c, ptX, ptY, nx, ny, size, arrowWidth, edgeWidth, spacing, initialMove) {
|
||||
paintMarker(
|
||||
c: AbstractCanvas2D,
|
||||
ptX: number,
|
||||
ptY: number,
|
||||
nx: number,
|
||||
ny: number,
|
||||
size: number,
|
||||
arrowWidth: number,
|
||||
edgeWidth: number,
|
||||
spacing: number,
|
||||
initialMove: boolean
|
||||
) {
|
||||
const widthArrowRatio = edgeWidth / arrowWidth;
|
||||
const orthx = (edgeWidth * ny) / 2;
|
||||
const orthy = (-edgeWidth * nx) / 2;
|
||||
|
@ -416,50 +436,50 @@ class ArrowConnector extends Shape {
|
|||
/**
|
||||
* @returns whether the arrow is rounded
|
||||
*/
|
||||
isArrowRounded(): boolean {
|
||||
isArrowRounded() {
|
||||
return this.isRounded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the width of the start arrow
|
||||
*/
|
||||
getStartArrowWidth(): number {
|
||||
getStartArrowWidth() {
|
||||
return ARROW_WIDTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the width of the end arrow
|
||||
*/
|
||||
getEndArrowWidth(): number {
|
||||
getEndArrowWidth() {
|
||||
return ARROW_WIDTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the width of the body of the edge
|
||||
*/
|
||||
getEdgeWidth(): number {
|
||||
getEdgeWidth() {
|
||||
return ARROW_WIDTH / 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns whether the ends of the shape are drawn
|
||||
*/
|
||||
isOpenEnded(): boolean {
|
||||
isOpenEnded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns whether the start marker is drawn
|
||||
*/
|
||||
isMarkerStart(): boolean {
|
||||
return getValue(this.style, 'startArrow', NONE) !== NONE;
|
||||
isMarkerStart() {
|
||||
return (this.style?.startArrow ?? NONE) !== NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns whether the end marker is drawn
|
||||
*/
|
||||
isMarkerEnd(): boolean {
|
||||
return getValue(this.style, 'endArrow', NONE) !== NONE;
|
||||
isMarkerEnd() {
|
||||
return (this.style?.endArrow ?? NONE) !== NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
import { DEFAULT_MARKERSIZE, NONE } from '../../../../util/Constants';
|
||||
import Polyline from './Polyline';
|
||||
import utils, { getNumber, getValue } from '../../../../util/Utils';
|
||||
import { getNumber } from '../../../../util/Utils';
|
||||
import Marker from './Marker';
|
||||
import Point from '../../Point';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Extends {@link mxShape} to implement a connector shape.
|
||||
|
@ -21,7 +22,7 @@ import Rectangle from '../../Rectangle';
|
|||
* @extends {Polyline}
|
||||
*/
|
||||
class Connector extends Polyline {
|
||||
constructor(points: Point[], stroke: string, strokewidth: number) {
|
||||
constructor(points: Point[], stroke: ColorValue, strokewidth: number) {
|
||||
super(points, stroke, strokewidth);
|
||||
}
|
||||
|
||||
|
@ -29,15 +30,15 @@ class Connector extends Polyline {
|
|||
* Updates the <boundingBox> for this shape using <createBoundingBox>
|
||||
* and augmentBoundingBox and stores the result in <boundingBox>.
|
||||
*/
|
||||
updateBoundingBox(): void {
|
||||
this.useSvgBoundingBox = this.style != null && this.style.curved === 1;
|
||||
updateBoundingBox() {
|
||||
this.useSvgBoundingBox = !!this.style?.curved;
|
||||
super.updateBoundingBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintEdgeShape(c: mxAbstractCanvas2D, pts: Point[]): void {
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]): void {
|
||||
// The indirection via functions for markers is needed in
|
||||
// order to apply the offsets before painting the line and
|
||||
// paint the markers after painting the line.
|
||||
|
@ -51,11 +52,11 @@ class Connector extends Polyline {
|
|||
c.setShadow(false);
|
||||
c.setDashed(false);
|
||||
|
||||
if (sourceMarker != null) {
|
||||
if (sourceMarker) {
|
||||
sourceMarker();
|
||||
}
|
||||
|
||||
if (targetMarker != null) {
|
||||
if (targetMarker) {
|
||||
targetMarker();
|
||||
}
|
||||
}
|
||||
|
@ -63,14 +64,17 @@ class Connector extends Polyline {
|
|||
/**
|
||||
* Prepares the marker by adding offsets in pts and returning a function to paint the marker.
|
||||
*/
|
||||
createMarker(c: mxAbstractCanvas2D, pts: Point[], source: boolean): Marker {
|
||||
createMarker(c: AbstractCanvas2D, pts: Point[], source: boolean) {
|
||||
if (!this.style) return null;
|
||||
|
||||
let result = null;
|
||||
const n = pts.length;
|
||||
const type = getValue(this.style, source ? 'startArrow' : 'endArrow');
|
||||
const type = source ? this.style.startArrow : this.style.endArrow;
|
||||
|
||||
let p0 = source ? pts[1] : pts[n - 2];
|
||||
const pe = source ? pts[0] : pts[n - 1];
|
||||
|
||||
if (type != null && p0 != null && pe != null) {
|
||||
if (type !== NONE && p0 !== null && pe !== null) {
|
||||
let count = 1;
|
||||
|
||||
// Uses next non-overlapping point
|
||||
|
@ -92,15 +96,11 @@ class Connector extends Polyline {
|
|||
const unitX = dx / dist;
|
||||
const unitY = dy / dist;
|
||||
|
||||
const size = getNumber(
|
||||
this.style,
|
||||
source ? 'startSize' : 'endSize',
|
||||
DEFAULT_MARKERSIZE
|
||||
);
|
||||
const size = source ? this.style.startSize : this.style.endSize;
|
||||
|
||||
// Allow for stroke width in the end point used and the
|
||||
// orthogonal vectors describing the direction of the marker
|
||||
const filled = this.style[source ? 'startFill' : 'endFill'] !== 0;
|
||||
const filled = source ? this.style.startFill : this.style.endFill;
|
||||
|
||||
result = Marker.createMarker(
|
||||
c,
|
||||
|
@ -111,7 +111,7 @@ class Connector extends Polyline {
|
|||
unitY,
|
||||
size,
|
||||
source,
|
||||
this.strokewidth,
|
||||
this.strokeWidth,
|
||||
filled
|
||||
);
|
||||
}
|
||||
|
@ -122,17 +122,19 @@ class Connector extends Polyline {
|
|||
/**
|
||||
* Augments the bounding box with the strokewidth and shadow offsets.
|
||||
*/
|
||||
augmentBoundingBox(bbox: Rectangle): void {
|
||||
augmentBoundingBox(bbox: Rectangle) {
|
||||
super.augmentBoundingBox(bbox);
|
||||
|
||||
if (!this.style) return;
|
||||
|
||||
// Adds marker sizes
|
||||
let size = 0;
|
||||
|
||||
if (getValue(this.style, 'startArrow', NONE) !== NONE) {
|
||||
if (this.style.startArrow !== NONE) {
|
||||
size = getNumber(this.style, 'startSize', DEFAULT_MARKERSIZE) + 1;
|
||||
}
|
||||
|
||||
if (getValue(this.style, 'endArrow', NONE) !== NONE) {
|
||||
if (this.style.endArrow !== NONE) {
|
||||
size = Math.max(size, getNumber(this.style, 'endSize', DEFAULT_MARKERSIZE)) + 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import Shape from '../Shape';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement a horizontal line shape.
|
||||
|
@ -15,12 +16,12 @@ import Rectangle from '../../Rectangle';
|
|||
* @extends {Shape}
|
||||
*/
|
||||
class Line extends Shape {
|
||||
constructor(bounds: Rectangle, stroke: string, strokewidth: number, vertical: boolean) {
|
||||
constructor(bounds: Rectangle, stroke: ColorValue, strokeWidth = 1, vertical = false) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth != null ? strokewidth : 1;
|
||||
this.vertical = vertical != null ? vertical : this.vertical;
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.vertical = vertical;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,23 +29,17 @@ class Line extends Shape {
|
|||
*
|
||||
* Whether to paint a vertical line.
|
||||
*/
|
||||
vertical = false;
|
||||
vertical: boolean;
|
||||
|
||||
/**
|
||||
* Redirects to redrawPath for subclasses to work.
|
||||
* @param {mxAbstractCanvas2D} c
|
||||
* @param {AbstractCanvas2D} c
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
paintVertexShape(
|
||||
c: mxAbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.begin();
|
||||
|
||||
if (this.vertical) {
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import { ArrowType } from 'packages/core/src/types';
|
||||
import AbstractCanvas2D from 'packages/core/src/util/canvas/AbstractCanvas2D';
|
||||
import {
|
||||
ARROW_CLASSIC,
|
||||
ARROW_CLASSIC_THIN,
|
||||
ARROW_DIAMOND,
|
||||
} from '../../../../util/Constants';
|
||||
import Point from '../../Point';
|
||||
import Shape from '../Shape';
|
||||
|
||||
/**
|
||||
* A static class that implements all markers for VML and SVG using a registry.
|
||||
|
@ -21,15 +25,13 @@ class Marker {
|
|||
*
|
||||
* Mapping: the attribute name on the object is the marker type, the associated value is the function to paint the marker
|
||||
*/
|
||||
// static markers: object;
|
||||
static markers = [];
|
||||
static markers: Record<string, Function> = {};
|
||||
|
||||
/**
|
||||
* Adds a factory method that updates a given endpoint and returns a
|
||||
* function to paint the marker onto the given canvas.
|
||||
*/
|
||||
// static addMarker(type: string, funct: Function): void;
|
||||
static addMarker(type, funct) {
|
||||
static addMarker(type: string, funct: Function) {
|
||||
Marker.markers[type] = funct;
|
||||
}
|
||||
|
||||
|
@ -38,9 +40,20 @@ class Marker {
|
|||
*
|
||||
* Returns a function to paint the given marker.
|
||||
*/
|
||||
static createMarker(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) {
|
||||
static createMarker(
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
type: ArrowType,
|
||||
pe: Point,
|
||||
unitX: number,
|
||||
unitY: number,
|
||||
size: number,
|
||||
source: boolean,
|
||||
sw: number,
|
||||
filled: boolean
|
||||
) {
|
||||
const funct = Marker.markers[type];
|
||||
return funct != null
|
||||
return funct
|
||||
? funct(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
|
||||
: null;
|
||||
}
|
||||
|
@ -50,10 +63,19 @@ class Marker {
|
|||
* Adds the classic and block marker factory method.
|
||||
*/
|
||||
(() => {
|
||||
function createArrow(widthFactor) {
|
||||
widthFactor = widthFactor != null ? widthFactor : 2;
|
||||
|
||||
return (canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) => {
|
||||
function createArrow(widthFactor = 2) {
|
||||
return (
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
type: ArrowType,
|
||||
pe: Point,
|
||||
unitX: number,
|
||||
unitY: number,
|
||||
size: number,
|
||||
source: boolean,
|
||||
sw: number,
|
||||
filled: boolean
|
||||
) => {
|
||||
// The angle of the forward facing arrow sides against the x axis is
|
||||
// 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
|
||||
// only half the strokewidth is processed ).
|
||||
|
@ -103,10 +125,19 @@ class Marker {
|
|||
Marker.addMarker('block', createArrow(2));
|
||||
Marker.addMarker('blockThin', createArrow(3));
|
||||
|
||||
function createOpenArrow(widthFactor) {
|
||||
widthFactor = widthFactor != null ? widthFactor : 2;
|
||||
|
||||
return (canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) => {
|
||||
function createOpenArrow(widthFactor = 2) {
|
||||
return (
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
type: ArrowType,
|
||||
pe: Point,
|
||||
unitX: number,
|
||||
unitY: number,
|
||||
size: number,
|
||||
source: boolean,
|
||||
sw: number,
|
||||
filled: boolean
|
||||
) => {
|
||||
// The angle of the forward facing arrow sides against the x axis is
|
||||
// 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
|
||||
// only half the strokewidth is processed ).
|
||||
|
@ -144,7 +175,18 @@ class Marker {
|
|||
|
||||
Marker.addMarker(
|
||||
'oval',
|
||||
(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) => {
|
||||
(
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
type: ArrowType,
|
||||
pe: Point,
|
||||
unitX: number,
|
||||
unitY: number,
|
||||
size: number,
|
||||
source: boolean,
|
||||
sw: number,
|
||||
filled: boolean
|
||||
) => {
|
||||
const a = size / 2;
|
||||
|
||||
const pt = pe.clone();
|
||||
|
@ -163,7 +205,18 @@ class Marker {
|
|||
}
|
||||
);
|
||||
|
||||
function diamond(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) {
|
||||
function diamond(
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
type: ArrowType,
|
||||
pe: Point,
|
||||
unitX: number,
|
||||
unitY: number,
|
||||
size: number,
|
||||
source: boolean,
|
||||
sw: number,
|
||||
filled: boolean
|
||||
) {
|
||||
// The angle of the forward facing arrow sides against the x axis is
|
||||
// 45 degrees, 1/sin(45) = 1.4142 / 2 = 0.7071 ( / 2 allows for
|
||||
// only half the strokewidth is processed ). Or 0.9862 for thin diamond.
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
import Shape from '../Shape';
|
||||
import { LINE_ARCSIZE } from '../../../../util/Constants';
|
||||
import utils, { getValue } from '../../../../util/Utils';
|
||||
import Point from '../../Point';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Class: mxPolyline
|
||||
|
@ -31,42 +31,42 @@ import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
|||
* 1. This is stored in <strokewidth>.
|
||||
*/
|
||||
class Polyline extends Shape {
|
||||
constructor(points: Point[], stroke: string, strokewidth: number) {
|
||||
constructor(points: Point[], stroke: ColorValue, strokeWidth = 1) {
|
||||
super();
|
||||
this.points = points;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth != null ? strokewidth : 1;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0.
|
||||
*/
|
||||
getRotation(): number {
|
||||
getRotation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0.
|
||||
*/
|
||||
getShapeRotation(): number {
|
||||
getShapeRotation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false.
|
||||
*/
|
||||
isPaintBoundsInverted(): boolean {
|
||||
isPaintBoundsInverted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintEdgeShape(c: mxAbstractCanvas2D, pts: Point[]): void {
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]) {
|
||||
const prev = c.pointerEventsValue;
|
||||
c.pointerEventsValue = 'stroke';
|
||||
|
||||
if (this.style == null || this.style.curved != 1) {
|
||||
if (!this.style || !this.style.curved) {
|
||||
this.paintLine(c, pts, this.isRounded);
|
||||
} else {
|
||||
this.paintCurvedLine(c, pts);
|
||||
|
@ -77,8 +77,9 @@ class Polyline extends Shape {
|
|||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintLine(c: mxAbstractCanvas2D, pts: Point[], rounded?: boolean): void {
|
||||
const arcSize = getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2;
|
||||
paintLine(c: AbstractCanvas2D, pts: Point[], rounded?: boolean) {
|
||||
const arcSize = this.style?.arcSize ?? LINE_ARCSIZE;
|
||||
|
||||
c.begin();
|
||||
this.addPoints(c, pts, rounded, arcSize, false);
|
||||
c.stroke();
|
||||
|
@ -87,7 +88,7 @@ class Polyline extends Shape {
|
|||
/**
|
||||
* Paints the line shape.
|
||||
*/
|
||||
paintCurvedLine(c: mxAbstractCanvas2D, pts: Point[]): void {
|
||||
paintCurvedLine(c: AbstractCanvas2D, pts: Point[]) {
|
||||
c.begin();
|
||||
|
||||
const pt = pts[0];
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import Actor from '../Actor';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
|
||||
/**
|
||||
|
@ -14,30 +14,18 @@ import Rectangle from '../../Rectangle';
|
|||
* This shape is registered under {@link mxConstants.SHAPE_CLOUD} in {@link cellRenderer}.
|
||||
*/
|
||||
class CloudShape extends Actor {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: string,
|
||||
stroke: string,
|
||||
strokewidth: number = 1
|
||||
) {
|
||||
constructor(bounds: Rectangle, fill: string, stroke: string, strokeWidth = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the path for this shape.
|
||||
*/
|
||||
// redrawPath(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
redrawPath(
|
||||
c: mxAbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
redrawPath(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.moveTo(0.25 * w, 0.25 * h);
|
||||
c.curveTo(0.05 * w, 0.25 * h, 0, 0.5 * h, 0.16 * w, 0.55 * h);
|
||||
c.curveTo(0, 0.66 * h, 0.18 * w, 0.9 * h, 0.31 * w, 0.8 * h);
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import Shape from '../Shape';
|
||||
import utils from '../../../../util/Utils';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import { NONE } from 'packages/core/src/util/Constants';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement an cylinder shape. If a custom shape with one filled area and an overlay path is
|
||||
|
@ -17,52 +16,34 @@ import Rectangle from '../../Rectangle';
|
|||
* This shape is registered under {@link mxConstants.SHAPE_CYLINDER} in {@link cellRenderer}.
|
||||
*/
|
||||
class CylinderShape extends Shape {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: string,
|
||||
stroke: string,
|
||||
strokewidth: number = 1
|
||||
) {
|
||||
constructor(bounds: Rectangle, fill: string, stroke: string, strokeWidth = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the maximum height of the top and bottom part of the cylinder shape.
|
||||
*/
|
||||
// maxHeight: number;
|
||||
maxHeight = 40;
|
||||
|
||||
/**
|
||||
* Sets stroke tolerance to 0 for SVG.
|
||||
*/
|
||||
// svgStrokeTolerance: number;
|
||||
svgStrokeTolerance = 0;
|
||||
|
||||
/**
|
||||
* Redirects to redrawPath for subclasses to work.
|
||||
*/
|
||||
// paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.translate(x, y);
|
||||
c.begin();
|
||||
this.redrawPath(c, x, y, w, h, false);
|
||||
c.fillAndStroke();
|
||||
|
||||
if (
|
||||
!this.outline ||
|
||||
this.style == null ||
|
||||
utils.getValue(this.style, 'backgroundOutline', 0) == 0
|
||||
) {
|
||||
if (!this.outline || !this.style || this.style.backgroundOutline === 0) {
|
||||
c.setShadow(false);
|
||||
c.begin();
|
||||
this.redrawPath(c, x, y, w, h, true);
|
||||
|
@ -73,17 +54,15 @@ class CylinderShape extends Shape {
|
|||
/**
|
||||
* Redirects to redrawPath for subclasses to work.
|
||||
*/
|
||||
// getCylinderSize(x: number, y: number, w: number, h: number): number;
|
||||
getCylinderSize(x: number, y: number, w: number, h: number): number {
|
||||
getCylinderSize(x: number, y: number, w: number, h: number) {
|
||||
return Math.min(this.maxHeight, Math.round(h / 5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the path for this shape.
|
||||
*/
|
||||
// redrawPath(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number, isForeground: boolean): void;
|
||||
redrawPath(
|
||||
c: mxSvgCanvas2D,
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
|
@ -92,10 +71,7 @@ class CylinderShape extends Shape {
|
|||
): void {
|
||||
const dy = this.getCylinderSize(x, y, w, h);
|
||||
|
||||
if (
|
||||
(isForeground && this.fill != null) ||
|
||||
(!isForeground && this.fill == null)
|
||||
) {
|
||||
if ((isForeground && this.fill !== NONE) || (!isForeground && this.fill === NONE)) {
|
||||
c.moveTo(0, dy);
|
||||
c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
import Rectangle from '../../Rectangle';
|
||||
import Shape from '../Shape';
|
||||
import utils from '../../../../util/Utils';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement a double ellipse shape.
|
||||
|
@ -39,32 +38,18 @@ import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
|||
* ```
|
||||
*/
|
||||
class DoubleEllipseShape extends Shape {
|
||||
strokewidth: number;
|
||||
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: string,
|
||||
stroke: string,
|
||||
strokewidth: number = 1
|
||||
) {
|
||||
constructor(bounds: Rectangle, fill: string, stroke: string, strokeWidth = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the background.
|
||||
*/
|
||||
// paintBackground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintBackground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.ellipse(x, y, w, h);
|
||||
c.fillAndStroke();
|
||||
}
|
||||
|
@ -72,20 +57,11 @@ class DoubleEllipseShape extends Shape {
|
|||
/**
|
||||
* Paints the foreground.
|
||||
*/
|
||||
// paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintForeground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
if (!this.outline) {
|
||||
const margin = utils.getValue(
|
||||
this.style,
|
||||
'margin',
|
||||
Math.min(3 + this.strokewidth, Math.min(w / 5, h / 5))
|
||||
);
|
||||
const margin =
|
||||
this.style?.margin ?? Math.min(3 + this.strokeWidth, Math.min(w / 5, h / 5));
|
||||
|
||||
x += margin;
|
||||
y += margin;
|
||||
w -= 2 * margin;
|
||||
|
@ -103,16 +79,12 @@ class DoubleEllipseShape extends Shape {
|
|||
/**
|
||||
* @returns the bounds for the label.
|
||||
*/
|
||||
// getLabelBounds(rect: mxRectangle): mxRectangle;
|
||||
getLabelBounds(rect: Rectangle) {
|
||||
const margin =
|
||||
utils.getValue(
|
||||
this.style,
|
||||
'margin',
|
||||
this.style?.margin ??
|
||||
Math.min(
|
||||
3 + this.strokewidth,
|
||||
3 + this.strokeWidth,
|
||||
Math.min(rect.width / 5 / this.scale, rect.height / 5 / this.scale)
|
||||
)
|
||||
) * this.scale;
|
||||
|
||||
return new Rectangle(
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import Shape from '../Shape';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
|
||||
/**
|
||||
|
@ -13,29 +13,18 @@ import Rectangle from '../../Rectangle';
|
|||
* This shape is registered under mxConstants.SHAPE_ELLIPSE in mxCellRenderer.
|
||||
*/
|
||||
class EllipseShape extends Shape {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: string,
|
||||
stroke: string,
|
||||
strokewidth: number = 1
|
||||
) {
|
||||
constructor(bounds: Rectangle, fill: string, stroke: string, strokeWidth = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the ellipse shape.
|
||||
*/
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
c.ellipse(x, y, w, h);
|
||||
c.fillAndStroke();
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
*/
|
||||
import Actor from '../Actor';
|
||||
import Point from '../../Point';
|
||||
import utils, { getValue } from '../../../../util/Utils';
|
||||
import { LINE_ARCSIZE } from '../../../../util/Constants';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Implementation of the hexagon shape.
|
||||
|
@ -28,8 +27,9 @@ class HexagonShape extends Actor {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
redrawPath(c: mxSvgCanvas2D, x: number, y: number, w: number, h: number): void {
|
||||
const arcSize = getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2;
|
||||
redrawPath(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
const arcSize = (this.style?.arcSize ?? LINE_ARCSIZE) / 2;
|
||||
|
||||
this.addPoints(
|
||||
c,
|
||||
[
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import utils from '../../../../util/Utils';
|
||||
import RectangleShape from './RectangleShape';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import CellState from '../../../cell/datatypes/CellState';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/SvgCanvas2D';
|
||||
import CellOverlay from '../../../cell/CellOverlay';
|
||||
import { NONE } from 'packages/core/src/util/Constants';
|
||||
|
||||
/**
|
||||
* Extends {@link mxShape} to implement an image shape.
|
||||
|
@ -22,24 +22,21 @@ import CellOverlay from '../../../cell/CellOverlay';
|
|||
class ImageShape extends RectangleShape {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
image: string,
|
||||
imageSrc: string,
|
||||
fill: string = '#FFFFFF',
|
||||
stroke: string = '#000000',
|
||||
strokewidth: number = 1
|
||||
strokeWidth: number = 1
|
||||
) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.image = image;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
super(bounds, fill, stroke, strokeWidth);
|
||||
|
||||
this.imageSrc = imageSrc;
|
||||
this.shadow = false;
|
||||
}
|
||||
|
||||
// TODO: Document me!!
|
||||
shadow: boolean;
|
||||
|
||||
image: string;
|
||||
imageSrc: string;
|
||||
|
||||
// Used in mxCellRenderer
|
||||
overlay: CellOverlay | null = null;
|
||||
|
@ -54,8 +51,7 @@ class ImageShape extends RectangleShape {
|
|||
/**
|
||||
* Disables offset in IE9 for crisper image output.
|
||||
*/
|
||||
// getSvgScreenOffset(): number;
|
||||
getSvgScreenOffset(): number {
|
||||
getSvgScreenOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -76,19 +72,12 @@ class ImageShape extends RectangleShape {
|
|||
apply(state: CellState) {
|
||||
super.apply(state);
|
||||
|
||||
this.fill = null;
|
||||
this.stroke = null;
|
||||
this.gradient = null;
|
||||
this.fill = NONE;
|
||||
this.stroke = NONE;
|
||||
this.gradient = NONE;
|
||||
|
||||
if (this.style != null) {
|
||||
this.preserveImageAspect =
|
||||
utils.getNumber(this.style, 'imageAspect', 1) == 1;
|
||||
|
||||
// Legacy support for imageFlipH/V
|
||||
this.flipH =
|
||||
this.flipH || utils.getValue(this.style, 'imageFlipH', 0) == 1;
|
||||
this.flipV =
|
||||
this.flipV || utils.getValue(this.style, 'imageFlipV', 0) == 1;
|
||||
if (this.style) {
|
||||
this.preserveImageAspect = this.style.imageAspect;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,8 +85,7 @@ class ImageShape extends RectangleShape {
|
|||
* Returns true if HTML is allowed for this shape. This implementation always
|
||||
* returns false.
|
||||
*/
|
||||
// isHtmlAllowed(): boolean;
|
||||
isHtmlAllowed(): boolean {
|
||||
isHtmlAllowed() {
|
||||
return !this.preserveImageAspect;
|
||||
}
|
||||
|
||||
|
@ -106,8 +94,7 @@ class ImageShape extends RectangleShape {
|
|||
* this shape. This implementation falls back to <createVml>
|
||||
* so that the HTML creation is optional.
|
||||
*/
|
||||
// createHtml(): HTMLElement;
|
||||
createHtml(): HTMLElement {
|
||||
createHtml() {
|
||||
const node = document.createElement('div');
|
||||
node.style.position = 'absolute';
|
||||
return node;
|
||||
|
@ -116,33 +103,19 @@ class ImageShape extends RectangleShape {
|
|||
/**
|
||||
* Disables inherited roundable support.
|
||||
*/
|
||||
// isRoundable(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): boolean;
|
||||
isRoundable(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): boolean {
|
||||
isRoundable(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic background painting implementation.
|
||||
*/
|
||||
// paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
if (this.image != null) {
|
||||
const fill = utils.getValue(this.style, 'imageBackground', null);
|
||||
let stroke = utils.getValue(this.style, 'imageBorder', null);
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
if (this.imageSrc && this.style) {
|
||||
const fill = this.style.imageBackground;
|
||||
const stroke = this.style.imageBorder;
|
||||
|
||||
if (fill != null) {
|
||||
if (fill !== NONE) {
|
||||
// Stroke rendering required for shadow
|
||||
c.setFillColor(fill);
|
||||
c.setStrokeColor(stroke);
|
||||
|
@ -151,9 +124,7 @@ class ImageShape extends RectangleShape {
|
|||
}
|
||||
|
||||
// FlipH/V are implicit via mxShape.updateTransform
|
||||
c.image(x, y, w, h, this.image, this.preserveImageAspect, false, false);
|
||||
|
||||
stroke = utils.getValue(this.style, 'imageBorder', null);
|
||||
c.image(x, y, w, h, this.imageSrc, this.preserveImageAspect, false, false);
|
||||
|
||||
if (stroke != null) {
|
||||
c.setShadow(false);
|
||||
|
|
|
@ -13,9 +13,11 @@ import {
|
|||
ALIGN_RIGHT,
|
||||
ALIGN_TOP,
|
||||
DEFAULT_IMAGESIZE,
|
||||
NONE,
|
||||
} from '../../../../util/Constants';
|
||||
import RectangleShape from './RectangleShape';
|
||||
import utils from '../../../../util/Utils';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
import AbstractCanvas2D from 'packages/core/src/util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Class: mxLabel
|
||||
|
@ -37,24 +39,29 @@ import utils from '../../../../util/Utils';
|
|||
* strokewidth - Optional integer that defines the stroke width. Default is
|
||||
* 1. This is stored in <strokewidth>.
|
||||
*/
|
||||
class Label extends RectangleShape {
|
||||
constructor(bounds, fill, stroke, strokewidth) {
|
||||
super(bounds, fill, stroke, strokewidth);
|
||||
class LabelShape extends RectangleShape {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: ColorValue,
|
||||
stroke: ColorValue,
|
||||
strokeWidth: number
|
||||
) {
|
||||
super(bounds, fill, stroke, strokeWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default width and height for the image.
|
||||
* @default mxConstants.DEFAULT_IMAGESIZE
|
||||
*/
|
||||
// imageSize: number;
|
||||
imageSize = DEFAULT_IMAGESIZE;
|
||||
|
||||
imageSrc: string | null = null;
|
||||
|
||||
/**
|
||||
* Default value for image spacing
|
||||
* @type {number}
|
||||
* @default 2
|
||||
*/
|
||||
// spacing: number;
|
||||
spacing = 2;
|
||||
|
||||
/**
|
||||
|
@ -62,7 +69,6 @@ class Label extends RectangleShape {
|
|||
* @type {number}
|
||||
* @default 10
|
||||
*/
|
||||
// indicatorSize: number;
|
||||
indicatorSize = 10;
|
||||
|
||||
/**
|
||||
|
@ -70,17 +76,17 @@ class Label extends RectangleShape {
|
|||
* @default 2
|
||||
* @type {number}
|
||||
*/
|
||||
// indicatorSpacing: number;
|
||||
indicatorSpacing = 2;
|
||||
|
||||
indicatorImageSrc: string | null = null;
|
||||
|
||||
/**
|
||||
* Initializes the shape and the <indicator>.
|
||||
*/
|
||||
// init(container: HTMLElement): void;
|
||||
init(container) {
|
||||
init(container: SVGElement) {
|
||||
super.init(container);
|
||||
|
||||
if (this.indicatorShape != null) {
|
||||
if (this.indicatorShape) {
|
||||
this.indicator = new this.indicatorShape();
|
||||
this.indicator.dialect = this.dialect;
|
||||
this.indicator.init(this.node);
|
||||
|
@ -91,9 +97,8 @@ class Label extends RectangleShape {
|
|||
* Reconfigures this shape. This will update the colors of the indicator
|
||||
* and reconfigure it if required.
|
||||
*/
|
||||
// redraw(): void;
|
||||
redraw() {
|
||||
if (this.indicator != null) {
|
||||
if (this.indicator) {
|
||||
this.indicator.fill = this.indicatorColor;
|
||||
this.indicator.stroke = this.indicatorStrokeColor;
|
||||
this.indicator.gradient = this.indicatorGradientColor;
|
||||
|
@ -107,13 +112,8 @@ class Label extends RectangleShape {
|
|||
* Returns true for non-rounded, non-rotated shapes with no glass gradient and
|
||||
* no indicator shape.
|
||||
*/
|
||||
// isHtmlAllowed(): boolean;
|
||||
isHtmlAllowed() {
|
||||
return (
|
||||
super.isHtmlAllowed() &&
|
||||
this.indicatorColor == null &&
|
||||
this.indicatorShape == null
|
||||
);
|
||||
return super.isHtmlAllowed() && this.indicatorColor === NONE && !!this.indicatorShape;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,8 +124,7 @@ class Label extends RectangleShape {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
// paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintForeground(c, x, y, w, h) {
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
this.paintImage(c, x, y, w, h);
|
||||
this.paintIndicator(c, x, y, w, h);
|
||||
super.paintForeground(c, x, y, w, h);
|
||||
|
@ -139,16 +138,15 @@ class Label extends RectangleShape {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
// paintImage(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintImage(c, x, y, w, h) {
|
||||
if (this.image != null) {
|
||||
paintImage(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
if (this.imageSrc) {
|
||||
const bounds = this.getImageBounds(x, y, w, h);
|
||||
c.image(
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
this.image,
|
||||
this.imageSrc,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
|
@ -163,26 +161,12 @@ class Label extends RectangleShape {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
// getImageBounds(x: number, y: number, w: number, h: number): mxRectangle;
|
||||
getImageBounds(x, y, w, h) {
|
||||
const align = utils.getValue(this.style, 'imageAlign', ALIGN_LEFT);
|
||||
const valign = utils.getValue(
|
||||
this.style,
|
||||
'verticalAlign',
|
||||
ALIGN_MIDDLE
|
||||
);
|
||||
const width = utils.getNumber(
|
||||
this.style,
|
||||
'imageWidth',
|
||||
DEFAULT_IMAGESIZE
|
||||
);
|
||||
const height = utils.getNumber(
|
||||
this.style,
|
||||
'imageHeight',
|
||||
DEFAULT_IMAGESIZE
|
||||
);
|
||||
const spacing =
|
||||
utils.getNumber(this.style, 'spacing', this.spacing) + 5;
|
||||
getImageBounds(x: number, y: number, w: number, h: number) {
|
||||
const align = this.style?.imageAlign ?? ALIGN_LEFT;
|
||||
const valign = this.style?.verticalAlign ?? ALIGN_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) {
|
||||
x += (w - width) / 2;
|
||||
|
@ -213,19 +197,18 @@ class Label extends RectangleShape {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
// paintIndicator(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintIndicator(c, x, y, w, h) {
|
||||
if (this.indicator != null) {
|
||||
paintIndicator(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
if (this.indicator) {
|
||||
this.indicator.bounds = this.getIndicatorBounds(x, y, w, h);
|
||||
this.indicator.paint(c);
|
||||
} else if (this.indicatorImage != null) {
|
||||
} else if (this.indicatorImageSrc) {
|
||||
const bounds = this.getIndicatorBounds(x, y, w, h);
|
||||
c.image(
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
this.indicatorImage,
|
||||
this.indicatorImageSrc,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
|
@ -241,24 +224,11 @@ class Label extends RectangleShape {
|
|||
* @param {number} h
|
||||
* @returns {Rectangle}
|
||||
*/
|
||||
// getIndicatorBounds(x: number, y: number, w: number, h: number): mxRectangle;
|
||||
getIndicatorBounds(x, y, w, h) {
|
||||
const align = utils.getValue(this.style, 'imageAlign', ALIGN_LEFT);
|
||||
const valign = utils.getValue(
|
||||
this.style,
|
||||
'verticalAlign',
|
||||
ALIGN_MIDDLE
|
||||
);
|
||||
const width = utils.getNumber(
|
||||
this.style,
|
||||
'indicatorWidth',
|
||||
this.indicatorSize
|
||||
);
|
||||
const height = utils.getNumber(
|
||||
this.style,
|
||||
'indicatorHeight',
|
||||
this.indicatorSize
|
||||
);
|
||||
getIndicatorBounds(x: number, y: number, w: number, h: number) {
|
||||
const align = this.style?.imageAlign ?? ALIGN_LEFT;
|
||||
const valign = this.style?.verticalAlign ?? ALIGN_MIDDLE;
|
||||
const width = this.style?.indicatorWidth ?? this.indicatorSize;
|
||||
const height = this.style?.indicatorHeight ?? this.indicatorSize;
|
||||
const spacing = this.spacing + 5;
|
||||
|
||||
if (align === ALIGN_RIGHT) {
|
||||
|
@ -285,16 +255,15 @@ class Label extends RectangleShape {
|
|||
/**
|
||||
* Generic background painting implementation.
|
||||
*/
|
||||
// redrawHtmlShape(): void;
|
||||
redrawHtmlShape() {
|
||||
super.redrawHtmlShape();
|
||||
|
||||
// Removes all children
|
||||
while (this.node.hasChildNodes()) {
|
||||
this.node.removeChild(this.node.lastChild);
|
||||
this.node.removeChild(this.node.lastChild as ChildNode);
|
||||
}
|
||||
|
||||
if (this.image != null) {
|
||||
if (this.imageSrc && this.bounds) {
|
||||
const node = document.createElement('img');
|
||||
node.style.position = 'relative';
|
||||
node.setAttribute('border', '0');
|
||||
|
@ -313,11 +282,11 @@ class Label extends RectangleShape {
|
|||
node.style.width = `${Math.round(bounds.width)}px`;
|
||||
node.style.height = `${Math.round(bounds.height)}px`;
|
||||
|
||||
node.src = this.image;
|
||||
node.src = this.imageSrc;
|
||||
|
||||
this.node.appendChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Label;
|
||||
export default LabelShape;
|
||||
|
|
|
@ -10,11 +10,10 @@ import {
|
|||
NONE,
|
||||
RECTANGLE_ROUNDING_FACTOR,
|
||||
} from '../../../../util/Constants';
|
||||
import utils from '../../../../util/Utils';
|
||||
import Shape from '../Shape';
|
||||
import mxAbstractCanvas2D from '../../../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement a rectangle shape.
|
||||
|
@ -24,84 +23,58 @@ import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
|||
*/
|
||||
class RectangleShape extends Shape {
|
||||
constructor(
|
||||
bounds: Rectangle | null = null,
|
||||
fill: string | null = '#FFFFFF',
|
||||
stroke: string | null = '#000000',
|
||||
strokewidth: number = 1
|
||||
bounds: Rectangle,
|
||||
fill: ColorValue,
|
||||
stroke: ColorValue,
|
||||
strokeWidth: number = 1
|
||||
) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
// TODO: Document me!
|
||||
strokewidth: number;
|
||||
|
||||
/**
|
||||
* Returns true for non-rounded, non-rotated shapes with no glass gradient.
|
||||
*/
|
||||
// isHtmlAllowed(): boolean;
|
||||
isHtmlAllowed(): boolean {
|
||||
isHtmlAllowed() {
|
||||
let events = true;
|
||||
|
||||
if (this.style != null) {
|
||||
events = utils.getValue(this.style, 'pointerEvents', '1') == '1';
|
||||
if (this.style) {
|
||||
events = this.style.pointerEvents;
|
||||
}
|
||||
|
||||
return (
|
||||
!this.isRounded &&
|
||||
!this.glass &&
|
||||
this.rotation === 0 &&
|
||||
(events || (this.fill != null && this.fill !== NONE))
|
||||
(events || this.fill !== NONE)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic background painting implementation.
|
||||
*/
|
||||
// paintBackground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintBackground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
let events = true;
|
||||
|
||||
if (this.style != null) {
|
||||
events = utils.getValue(this.style, 'pointerEvents', '1') == '1';
|
||||
if (this.style) {
|
||||
events = this.style.pointerEvents;
|
||||
}
|
||||
|
||||
if (
|
||||
events ||
|
||||
(this.fill != null && this.fill !== NONE) ||
|
||||
(this.stroke != null && this.stroke !== NONE)
|
||||
) {
|
||||
if (!events && (this.fill == null || this.fill === NONE)) {
|
||||
if (events || this.fill !== NONE || this.stroke !== NONE) {
|
||||
if (!events && this.fill === NONE) {
|
||||
c.pointerEvents = false;
|
||||
}
|
||||
|
||||
if (this.isRounded) {
|
||||
let r = 0;
|
||||
|
||||
if (utils.getValue(this.style, 'absoluteArcSize', 0) == '1') {
|
||||
r = Math.min(
|
||||
w / 2,
|
||||
Math.min(
|
||||
h / 2,
|
||||
utils.getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2
|
||||
)
|
||||
);
|
||||
if (this.style?.absoluteArcSize ?? false) {
|
||||
r = Math.min(w / 2, Math.min(h / 2, (this.style?.arcSize ?? LINE_ARCSIZE) / 2));
|
||||
} else {
|
||||
const f =
|
||||
utils.getValue(
|
||||
this.style,
|
||||
'arcSize',
|
||||
RECTANGLE_ROUNDING_FACTOR * 100
|
||||
) / 100;
|
||||
const f = (this.style?.arcSize ?? RECTANGLE_ROUNDING_FACTOR * 100) / 100;
|
||||
r = Math.min(w * f, h * f);
|
||||
}
|
||||
|
||||
|
@ -117,41 +90,22 @@ class RectangleShape extends Shape {
|
|||
/**
|
||||
* Adds roundable support.
|
||||
*/
|
||||
// isRoundable(c?: mxAbstractCanvas2D, x?: number, y?: number, w?: number, h?: number): boolean;
|
||||
isRoundable(
|
||||
c: mxAbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): boolean {
|
||||
isRoundable(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic background painting implementation.
|
||||
*/
|
||||
// paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintForeground(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
if (
|
||||
this.glass &&
|
||||
!this.outline &&
|
||||
this.fill != null &&
|
||||
this.fill !== NONE
|
||||
) {
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void {
|
||||
if (this.glass && !this.outline && this.fill !== NONE) {
|
||||
this.paintGlassEffect(
|
||||
c,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
this.getArcSize(w + this.strokewidth, h + this.strokewidth)
|
||||
this.getArcSize(w + this.strokeWidth, h + this.strokeWidth)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
*/
|
||||
import Shape from '../Shape';
|
||||
import Point from '../../Point';
|
||||
import utils from '../../../../util/Utils';
|
||||
import { LINE_ARCSIZE } from '../../../../util/Constants';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement a rhombus (aka diamond) shape.
|
||||
|
@ -18,17 +17,12 @@ import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
|||
* @extends {Shape}
|
||||
*/
|
||||
class RhombusShape extends Shape {
|
||||
constructor(
|
||||
bounds: Rectangle,
|
||||
fill: string,
|
||||
stroke: string,
|
||||
strokewidth: number = 1
|
||||
) {
|
||||
constructor(bounds: Rectangle, fill: string, stroke: string, strokewidth: number = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth;
|
||||
this.strokeWidth = strokewidth;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,19 +41,12 @@ class RhombusShape extends Shape {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
// paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintVertexShape(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
) {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
const hw = w / 2;
|
||||
const hh = h / 2;
|
||||
|
||||
const arcSize =
|
||||
utils.getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2;
|
||||
const arcSize = (this.style?.arcSize ?? LINE_ARCSIZE) / 2;
|
||||
|
||||
c.begin();
|
||||
this.addPoints(
|
||||
c,
|
||||
|
|
|
@ -9,18 +9,22 @@ import ConnectionConstraint from '../../../connection/ConnectionConstraint';
|
|||
import Rectangle from '../../Rectangle';
|
||||
import Shape from '../Shape';
|
||||
import Resources from '../../../../util/Resources';
|
||||
import utils, { getNumber, getValue, isNotNullish } from '../../../../util/Utils';
|
||||
import { getNumber, getValue, isNotNullish } from '../../../../util/Utils';
|
||||
import {
|
||||
ALIGN_LEFT,
|
||||
ALIGN_TOP,
|
||||
DIRECTION_NORTH,
|
||||
DIRECTION_SOUTH,
|
||||
NODETYPE_ELEMENT,
|
||||
NONE,
|
||||
RECTANGLE_ROUNDING_FACTOR,
|
||||
TEXT_DIRECTION_AUTO,
|
||||
} from '../../../../util/Constants';
|
||||
import StencilShapeRegistry from './StencilShapeRegistry';
|
||||
import { getChildNodes, getTextContent } from '../../../../util/DomUtils';
|
||||
import Point from '../../Point';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import { AlignValue, ColorValue, VAlignValue } from 'packages/core/src/types';
|
||||
|
||||
/**
|
||||
* Implements a generic shape which is based on a XML node as a description.
|
||||
|
@ -107,7 +111,7 @@ class StencilShape extends Shape {
|
|||
*
|
||||
* Holds the strokewidth direction from the description.
|
||||
*/
|
||||
strokeWidth: string | null = null;
|
||||
strokeWidthValue: string | null = null;
|
||||
|
||||
/**
|
||||
* Function: parseDescription
|
||||
|
@ -132,7 +136,7 @@ class StencilShape extends Shape {
|
|||
// user-defined stroke-width). Note that the strokewidth is scaled
|
||||
// by the minimum scaling that is used to draw the shape (sx, sy).
|
||||
const sw = this.desc.getAttribute('strokewidth');
|
||||
this.strokeWidth = isNotNullish(sw) ? sw : '1';
|
||||
this.strokeWidthValue = isNotNullish(sw) ? sw : '1';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,10 +148,10 @@ class StencilShape extends Shape {
|
|||
parseConstraints() {
|
||||
const conns = this.desc.getElementsByTagName('connections')[0];
|
||||
|
||||
if (conns != null) {
|
||||
if (conns) {
|
||||
const tmp = getChildNodes(conns);
|
||||
|
||||
if (tmp != null && tmp.length > 0) {
|
||||
if (tmp.length > 0) {
|
||||
this.constraints = [];
|
||||
|
||||
for (let i = 0; i < tmp.length; i += 1) {
|
||||
|
@ -165,7 +169,7 @@ class StencilShape extends Shape {
|
|||
parseConstraint(node: Element) {
|
||||
const x = Number(node.getAttribute('x'));
|
||||
const y = Number(node.getAttribute('y'));
|
||||
const perimeter = node.getAttribute('perimeter') == '1';
|
||||
const perimeter = node.getAttribute('perimeter') === '1';
|
||||
const name = node.getAttribute('name');
|
||||
|
||||
return new ConnectionConstraint(new Point(x, y), perimeter, name);
|
||||
|
@ -182,7 +186,7 @@ class StencilShape extends Shape {
|
|||
let result = this.evaluateAttribute(node, attribute, shape);
|
||||
const loc = node.getAttribute('localized');
|
||||
|
||||
if ((StencilShape.defaultLocalized && loc == null) || loc == '1') {
|
||||
if ((StencilShape.defaultLocalized && !loc) || loc === '1') {
|
||||
result = Resources.get(result);
|
||||
}
|
||||
|
||||
|
@ -200,10 +204,10 @@ class StencilShape extends Shape {
|
|||
evaluateAttribute(node: Element, attribute: string, shape: Shape) {
|
||||
let result = node.getAttribute(attribute);
|
||||
|
||||
if (result == null) {
|
||||
if (!result) {
|
||||
const text = getTextContent(node);
|
||||
|
||||
if (text != null && StencilShape.allowEval) {
|
||||
if (text && StencilShape.allowEval) {
|
||||
const funct = eval(text);
|
||||
|
||||
if (typeof funct === 'function') {
|
||||
|
@ -221,7 +225,7 @@ class StencilShape extends Shape {
|
|||
* Draws this stencil inside the given bounds.
|
||||
*/
|
||||
drawShape(
|
||||
canvas: mxSvgCanvas2D,
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
x: number,
|
||||
y: number,
|
||||
|
@ -240,34 +244,20 @@ class StencilShape extends Shape {
|
|||
const aspect = this.computeAspect(shape, x, y, w, h, direction);
|
||||
const minScale = Math.min(aspect.width, aspect.height);
|
||||
const sw =
|
||||
this.strokeWidth == 'inherit'
|
||||
this.strokeWidthValue === 'inherit'
|
||||
? Number(getNumber(shape.style, 'strokeWidth', 1))
|
||||
: Number(this.strokeWidth) * minScale;
|
||||
: Number(this.strokeWidthValue) * minScale;
|
||||
canvas.setStrokeWidth(sw);
|
||||
|
||||
// Draws a transparent rectangle for catching events
|
||||
if (
|
||||
shape.style != null &&
|
||||
getValue(shape.style, 'pointerEvents', '0') == '1'
|
||||
) {
|
||||
if (shape.style?.pointerEvents ?? false) {
|
||||
canvas.setStrokeColor(NONE);
|
||||
canvas.rect(x, y, w, h);
|
||||
canvas.stroke();
|
||||
canvas.setStrokeColor(shape.stroke);
|
||||
}
|
||||
|
||||
this.drawChildren(
|
||||
canvas,
|
||||
shape,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
this.bgNode,
|
||||
aspect,
|
||||
false,
|
||||
true
|
||||
);
|
||||
this.drawChildren(canvas, shape, x, y, w, h, this.bgNode, aspect, false, true);
|
||||
this.drawChildren(
|
||||
canvas,
|
||||
shape,
|
||||
|
@ -295,26 +285,26 @@ class StencilShape extends Shape {
|
|||
* Draws this stencil inside the given bounds.
|
||||
*/
|
||||
drawChildren(
|
||||
canvas: mxSvgCanvas2D,
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
node: Element | null,
|
||||
aspect: string,
|
||||
aspect: Rectangle,
|
||||
disableShadow: boolean,
|
||||
paint: boolean
|
||||
) {
|
||||
if (node != null && w > 0 && h > 0) {
|
||||
let tmp = node.firstChild;
|
||||
if (node && w > 0 && h > 0) {
|
||||
let tmp = node.firstChild as Element;
|
||||
|
||||
while (tmp != null) {
|
||||
while (tmp) {
|
||||
if (tmp.nodeType === NODETYPE_ELEMENT) {
|
||||
this.drawNode(canvas, shape, tmp, aspect, disableShadow, paint);
|
||||
}
|
||||
|
||||
tmp = tmp.nextSibling;
|
||||
tmp = tmp.nextSibling as Element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -345,8 +335,7 @@ class StencilShape extends Shape {
|
|||
let sx = w / this.w0;
|
||||
let sy = h / this.h0;
|
||||
|
||||
const inverse =
|
||||
direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
const inverse = direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
|
||||
if (inverse) {
|
||||
sy = w / this.h0;
|
||||
|
@ -381,7 +370,7 @@ class StencilShape extends Shape {
|
|||
* Draws this stencil inside the given bounds.
|
||||
*/
|
||||
drawNode(
|
||||
canvas: mxSvgCanvas2D,
|
||||
canvas: AbstractCanvas2D,
|
||||
shape: Shape,
|
||||
node: Element,
|
||||
aspect: Rectangle,
|
||||
|
@ -410,10 +399,10 @@ class StencilShape extends Shape {
|
|||
|
||||
const arcSize = Number(node.getAttribute('arcSize'));
|
||||
let pointCount = 0;
|
||||
const segs = [];
|
||||
const segs: Point[][] = [];
|
||||
|
||||
// Renders the elements inside the given path
|
||||
let childNode = node.firstChild;
|
||||
let childNode = node.firstChild as Element;
|
||||
|
||||
while (childNode != null) {
|
||||
if (childNode.nodeType === NODETYPE_ELEMENT) {
|
||||
|
@ -438,7 +427,7 @@ class StencilShape extends Shape {
|
|||
}
|
||||
}
|
||||
|
||||
childNode = childNode.nextSibling;
|
||||
childNode = childNode.nextSibling as Element;
|
||||
}
|
||||
|
||||
if (!parseRegularly && pointCount > 0) {
|
||||
|
@ -461,21 +450,14 @@ class StencilShape extends Shape {
|
|||
|
||||
if (parseRegularly) {
|
||||
// Renders the elements inside the given path
|
||||
let childNode = node.firstChild;
|
||||
let childNode = node.firstChild as Element;
|
||||
|
||||
while (childNode != null) {
|
||||
while (childNode) {
|
||||
if (childNode.nodeType === NODETYPE_ELEMENT) {
|
||||
this.drawNode(
|
||||
canvas,
|
||||
shape,
|
||||
childNode,
|
||||
aspect,
|
||||
disableShadow,
|
||||
paint
|
||||
);
|
||||
this.drawNode(canvas, shape, childNode, aspect, disableShadow, paint);
|
||||
}
|
||||
|
||||
childNode = childNode.nextSibling;
|
||||
childNode = childNode.nextSibling as Element;
|
||||
}
|
||||
}
|
||||
} else if (name === 'close') {
|
||||
|
@ -512,7 +494,7 @@ class StencilShape extends Shape {
|
|||
Number(node.getAttribute('ry')) * sy,
|
||||
Number(node.getAttribute('x-axis-rotation')),
|
||||
Boolean(node.getAttribute('large-arc-flag')),
|
||||
Number(node.getAttribute('sweep-flag')),
|
||||
Boolean(node.getAttribute('sweep-flag')),
|
||||
x0 + Number(node.getAttribute('x')) * sx,
|
||||
y0 + Number(node.getAttribute('y')) * sy
|
||||
);
|
||||
|
@ -552,7 +534,7 @@ class StencilShape extends Shape {
|
|||
);
|
||||
} else if (name === 'image') {
|
||||
if (!shape.outline) {
|
||||
const src = this.evaluateAttribute(node, 'src', shape);
|
||||
const src = this.evaluateAttribute(node, 'src', shape) as string;
|
||||
|
||||
canvas.image(
|
||||
x0 + Number(node.getAttribute('x')) * sx,
|
||||
|
@ -567,10 +549,10 @@ class StencilShape extends Shape {
|
|||
}
|
||||
} else if (name === 'text') {
|
||||
if (!shape.outline) {
|
||||
const str = this.evaluateTextAttribute(node, 'str', shape);
|
||||
const str = this.evaluateTextAttribute(node, 'str', shape) as string;
|
||||
let rotation = node.getAttribute('vertical') == '1' ? -90 : 0;
|
||||
|
||||
if (node.getAttribute('align-shape') == '0') {
|
||||
if (node.getAttribute('align-shape') === '0') {
|
||||
const dr = shape.rotation;
|
||||
|
||||
// Depends on flipping
|
||||
|
@ -586,7 +568,7 @@ class StencilShape extends Shape {
|
|||
}
|
||||
}
|
||||
|
||||
rotation -= node.getAttribute('rotation');
|
||||
rotation -= Number(node.getAttribute('rotation'));
|
||||
|
||||
canvas.text(
|
||||
x0 + Number(node.getAttribute('x')) * sx,
|
||||
|
@ -594,19 +576,22 @@ class StencilShape extends Shape {
|
|||
0,
|
||||
0,
|
||||
str,
|
||||
node.getAttribute('align') || 'left',
|
||||
node.getAttribute('valign') || 'top',
|
||||
(node.getAttribute('align') as AlignValue) || ALIGN_LEFT,
|
||||
(node.getAttribute('valign') as VAlignValue) || ALIGN_TOP,
|
||||
false,
|
||||
'',
|
||||
null,
|
||||
'auto',
|
||||
false,
|
||||
rotation
|
||||
rotation,
|
||||
TEXT_DIRECTION_AUTO
|
||||
);
|
||||
}
|
||||
} else if (name === 'include-shape') {
|
||||
const stencil = StencilShapeRegistry.getStencil(node.getAttribute('name'));
|
||||
const stencil = StencilShapeRegistry.getStencil(
|
||||
node.getAttribute('name') as string
|
||||
);
|
||||
|
||||
if (stencil != null) {
|
||||
if (stencil) {
|
||||
const x = x0 + Number(node.getAttribute('x')) * sx;
|
||||
const y = y0 + Number(node.getAttribute('y')) * sy;
|
||||
const w = Number(node.getAttribute('w')) * sx;
|
||||
|
@ -642,27 +627,27 @@ class StencilShape extends Shape {
|
|||
canvas.setDashPattern(value);
|
||||
}
|
||||
} else if (name === 'strokecolor') {
|
||||
canvas.setStrokeColor(node.getAttribute('color'));
|
||||
canvas.setStrokeColor(node.getAttribute('color') as ColorValue);
|
||||
} else if (name === 'linecap') {
|
||||
canvas.setLineCap(node.getAttribute('cap'));
|
||||
canvas.setLineCap(node.getAttribute('cap') as string);
|
||||
} else if (name === 'linejoin') {
|
||||
canvas.setLineJoin(node.getAttribute('join'));
|
||||
canvas.setLineJoin(node.getAttribute('join') as string);
|
||||
} else if (name === 'miterlimit') {
|
||||
canvas.setMiterLimit(Number(node.getAttribute('limit')));
|
||||
} else if (name === 'fillcolor') {
|
||||
canvas.setFillColor(node.getAttribute('color'));
|
||||
canvas.setFillColor(node.getAttribute('color') as ColorValue);
|
||||
} else if (name === 'alpha') {
|
||||
canvas.setAlpha(node.getAttribute('alpha'));
|
||||
canvas.setAlpha(Number(node.getAttribute('alpha')));
|
||||
} else if (name === 'fillalpha') {
|
||||
canvas.setAlpha(node.getAttribute('alpha'));
|
||||
canvas.setAlpha(Number(node.getAttribute('alpha')));
|
||||
} else if (name === 'strokealpha') {
|
||||
canvas.setAlpha(node.getAttribute('alpha'));
|
||||
canvas.setAlpha(Number(node.getAttribute('alpha')));
|
||||
} else if (name === 'fontcolor') {
|
||||
canvas.setFontColor(node.getAttribute('color'));
|
||||
canvas.setFontColor(node.getAttribute('color') as ColorValue);
|
||||
} else if (name === 'fontstyle') {
|
||||
canvas.setFontStyle(node.getAttribute('style'));
|
||||
canvas.setFontStyle(Number(node.getAttribute('style')));
|
||||
} else if (name === 'fontfamily') {
|
||||
canvas.setFontFamily(node.getAttribute('family'));
|
||||
canvas.setFontFamily(node.getAttribute('family') as string);
|
||||
} else if (name === 'fontsize') {
|
||||
canvas.setFontSize(Number(node.getAttribute('size')) * minScale);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ import {
|
|||
NONE,
|
||||
RECTANGLE_ROUNDING_FACTOR,
|
||||
} from '../../../../util/Constants';
|
||||
import utils from '../../../../util/Utils';
|
||||
import { ColorValue } from 'packages/core/src/types';
|
||||
import AbstractCanvas2D from 'packages/core/src/util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Extends {@link Shape} to implement a swimlane shape.
|
||||
|
@ -32,12 +33,12 @@ import utils from '../../../../util/Utils';
|
|||
* @extends {Shape}
|
||||
*/
|
||||
class SwimlaneShape extends Shape {
|
||||
constructor(bounds, fill, stroke, strokewidth) {
|
||||
constructor(bounds: Rectangle, fill: ColorValue, stroke: ColorValue, strokeWidth = 1) {
|
||||
super();
|
||||
this.bounds = bounds;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
this.strokewidth = strokewidth != null ? strokewidth : 1;
|
||||
this.strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,9 +48,10 @@ class SwimlaneShape extends Shape {
|
|||
* @type {number}
|
||||
* @default 16
|
||||
*/
|
||||
// imageSize: number;
|
||||
imageSize = 16;
|
||||
|
||||
imageSrc: string | null = null;
|
||||
|
||||
/**
|
||||
* Adds roundable support.
|
||||
* @param {mxAbstractCanvas2D} c
|
||||
|
@ -59,33 +61,27 @@ class SwimlaneShape extends Shape {
|
|||
* @param {number} h
|
||||
* @returns {boolean}
|
||||
*/
|
||||
// isRoundable(c?: mxAbstractCanvas2D, x?: number, y?: number, w?: number, h?: number): boolean;
|
||||
isRoundable(c, x, y, w, h) {
|
||||
isRoundable(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box for the gradient box for this shape.
|
||||
*/
|
||||
// getTitleSize(): number;
|
||||
getTitleSize() {
|
||||
return Math.max(
|
||||
0,
|
||||
utils.getValue(this.style, 'startSize', DEFAULT_STARTSIZE)
|
||||
);
|
||||
return Math.max(0, this.style?.startSize ?? DEFAULT_STARTSIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box for the gradient box for this shape.
|
||||
*/
|
||||
// getLabelBounds(rect: mxRectangle): mxRectangle;
|
||||
getLabelBounds(rect) {
|
||||
getLabelBounds(rect: Rectangle) {
|
||||
const start = this.getTitleSize();
|
||||
const bounds = new Rectangle(rect.x, rect.y, rect.width, rect.height);
|
||||
const horizontal = this.isHorizontal();
|
||||
|
||||
const flipH = utils.getValue(this.style, 'flipH', 0) == 1;
|
||||
const flipV = utils.getValue(this.style, 'flipV', 0) == 1;
|
||||
const flipH = this.style?.flipH ?? false;
|
||||
const flipV = this.style?.flipV ?? false;
|
||||
|
||||
// East is default
|
||||
const shapeVertical =
|
||||
|
@ -94,14 +90,10 @@ class SwimlaneShape extends Shape {
|
|||
|
||||
const realFlipH =
|
||||
!realHorizontal &&
|
||||
flipH !=
|
||||
(this.direction === DIRECTION_SOUTH ||
|
||||
this.direction === DIRECTION_WEST);
|
||||
flipH !== (this.direction === DIRECTION_SOUTH || this.direction === DIRECTION_WEST);
|
||||
const realFlipV =
|
||||
realHorizontal &&
|
||||
flipV !=
|
||||
(this.direction === DIRECTION_SOUTH ||
|
||||
this.direction === DIRECTION_WEST);
|
||||
flipV !== (this.direction === DIRECTION_SOUTH || this.direction === DIRECTION_WEST);
|
||||
|
||||
// Shape is horizontal
|
||||
if (!shapeVertical) {
|
||||
|
@ -128,8 +120,7 @@ class SwimlaneShape extends Shape {
|
|||
/**
|
||||
* Returns the bounding box for the gradient box for this shape.
|
||||
*/
|
||||
// getGradientBounds(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): mxRectangle;
|
||||
getGradientBounds(c, x, y, w, h) {
|
||||
getGradientBounds(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
let start = this.getTitleSize();
|
||||
|
||||
if (this.isHorizontal()) {
|
||||
|
@ -145,22 +136,11 @@ class SwimlaneShape extends Shape {
|
|||
*
|
||||
* Returns the arcsize for the swimlane.
|
||||
*/
|
||||
getSwimlaneArcSize(w, h, start) {
|
||||
if (utils.getValue(this.style, 'absoluteArcSize', 0) == '1') {
|
||||
return Math.min(
|
||||
w / 2,
|
||||
Math.min(
|
||||
h / 2,
|
||||
utils.getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2
|
||||
)
|
||||
);
|
||||
getSwimlaneArcSize(w: number, h: number, start: number) {
|
||||
if (this.style?.absoluteArcSize ?? false) {
|
||||
return Math.min(w / 2, Math.min(h / 2, this.style?.arcSize ?? LINE_ARCSIZE / 2));
|
||||
}
|
||||
const f =
|
||||
utils.getValue(
|
||||
this.style,
|
||||
'arcSize',
|
||||
RECTANGLE_ROUNDING_FACTOR * 100
|
||||
) / 100;
|
||||
const f = (this.style?.arcSize ?? RECTANGLE_ROUNDING_FACTOR * 100) / 100;
|
||||
|
||||
return start * f * 3;
|
||||
}
|
||||
|
@ -168,20 +148,17 @@ class SwimlaneShape extends Shape {
|
|||
/**
|
||||
* Paints the swimlane vertex shape.
|
||||
*/
|
||||
// isHorizontal(): boolean;
|
||||
isHorizontal() {
|
||||
return utils.getValue(this.style, 'horizontal', 1) == 1;
|
||||
return this.style?.horizontal ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the swimlane vertex shape.
|
||||
*/
|
||||
// paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void;
|
||||
paintVertexShape(c, x, y, w, h) {
|
||||
paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
let start = this.getTitleSize();
|
||||
const fill = utils.getValue(this.style, 'swimlaneFillColor', NONE);
|
||||
const swimlaneLine =
|
||||
utils.getValue(this.style, 'swimlaneLine', 1) == 1;
|
||||
const fill = this.style?.swimlaneFillColor ?? NONE;
|
||||
const swimlaneLine = this.style?.swimlaneLine ?? true;
|
||||
let r = 0;
|
||||
|
||||
if (this.isHorizontal()) {
|
||||
|
@ -200,17 +177,17 @@ class SwimlaneShape extends Shape {
|
|||
this.paintRoundedSwimlane(c, x, y, w, h, start, r, fill, swimlaneLine);
|
||||
}
|
||||
|
||||
const sep = utils.getValue(this.style, 'separatorColor', NONE);
|
||||
const sep = this.style?.separatorColor ?? NONE;
|
||||
this.paintSeparator(c, x, y, w, h, start, sep);
|
||||
|
||||
if (this.image != null) {
|
||||
if (this.imageSrc) {
|
||||
const bounds = this.getImageBounds(x, y, w, h);
|
||||
c.image(
|
||||
bounds.x - x,
|
||||
bounds.y - y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
this.image,
|
||||
this.imageSrc,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
|
@ -228,16 +205,25 @@ class SwimlaneShape extends Shape {
|
|||
*
|
||||
* Paints the swimlane vertex shape.
|
||||
*/
|
||||
paintSwimlane(c, x, y, w, h, start, fill, swimlaneLine) {
|
||||
paintSwimlane(
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
start: number,
|
||||
fill: ColorValue,
|
||||
swimlaneLine: boolean
|
||||
) {
|
||||
c.begin();
|
||||
|
||||
let events = true;
|
||||
|
||||
if (this.style != null) {
|
||||
events = utils.getValue(this.style, 'pointerEvents', '1') == '1';
|
||||
if (this.style) {
|
||||
events = this.style.pointerEvents;
|
||||
}
|
||||
|
||||
if (!events && (this.fill == null || this.fill === NONE)) {
|
||||
if (!events && this.fill === NONE) {
|
||||
c.pointerEvents = false;
|
||||
}
|
||||
|
||||
|
@ -309,16 +295,26 @@ class SwimlaneShape extends Shape {
|
|||
*
|
||||
* Paints the swimlane vertex shape.
|
||||
*/
|
||||
paintRoundedSwimlane(c, x, y, w, h, start, r, fill, swimlaneLine) {
|
||||
paintRoundedSwimlane(
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
start: number,
|
||||
r: number,
|
||||
fill: ColorValue,
|
||||
swimlaneLine: boolean
|
||||
) {
|
||||
c.begin();
|
||||
|
||||
let events = true;
|
||||
|
||||
if (this.style != null) {
|
||||
events = utils.getValue(this.style, 'pointerEvents', '1') == '1';
|
||||
if (this.style) {
|
||||
events = this.style.pointerEvents;
|
||||
}
|
||||
|
||||
if (!events && (this.fill == null || this.fill === NONE)) {
|
||||
if (!events && this.fill === NONE) {
|
||||
c.pointerEvents = false;
|
||||
}
|
||||
|
||||
|
@ -398,7 +394,15 @@ class SwimlaneShape extends Shape {
|
|||
*
|
||||
* Paints the divider between swimlane title and content area.
|
||||
*/
|
||||
paintDivider(c, x, y, w, h, start, shadow) {
|
||||
paintDivider(
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
start: number,
|
||||
shadow: boolean
|
||||
) {
|
||||
if (!shadow) {
|
||||
c.setShadow(false);
|
||||
}
|
||||
|
@ -421,7 +425,15 @@ class SwimlaneShape extends Shape {
|
|||
*
|
||||
* Paints the vertical or horizontal separator line between swimlanes.
|
||||
*/
|
||||
paintSeparator(c, x, y, w, h, start, color) {
|
||||
paintSeparator(
|
||||
c: AbstractCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
start: number,
|
||||
color: ColorValue
|
||||
) {
|
||||
if (color !== NONE) {
|
||||
c.setStrokeColor(color);
|
||||
c.setDashed(true);
|
||||
|
@ -443,15 +455,9 @@ class SwimlaneShape extends Shape {
|
|||
/**
|
||||
* Paints the swimlane vertex shape.
|
||||
*/
|
||||
// getImageBounds(x: number, y: number, w: number, h: number): mxRectangle;
|
||||
getImageBounds(x, y, w, h) {
|
||||
getImageBounds(x: number, y: number, w: number, h: number) {
|
||||
if (this.isHorizontal()) {
|
||||
return new Rectangle(
|
||||
x + w - this.imageSize,
|
||||
y,
|
||||
this.imageSize,
|
||||
this.imageSize
|
||||
);
|
||||
return new Rectangle(x + w - this.imageSize, y, this.imageSize, this.imageSize);
|
||||
}
|
||||
return new Rectangle(x, y, this.imageSize, this.imageSize);
|
||||
}
|
||||
|
|
|
@ -24,22 +24,31 @@ import {
|
|||
LINE_HEIGHT,
|
||||
NONE,
|
||||
TEXT_DIRECTION_AUTO,
|
||||
TEXT_DIRECTION_DEFAULT,
|
||||
TEXT_DIRECTION_LTR,
|
||||
TEXT_DIRECTION_RTL,
|
||||
WORD_WRAP,
|
||||
} from '../../../../util/Constants';
|
||||
import utils, {
|
||||
getAlignmentAsPoint,
|
||||
getBoundingBox,
|
||||
getValue,
|
||||
} from '../../../../util/Utils';
|
||||
import { getAlignmentAsPoint, getBoundingBox } from '../../../../util/Utils';
|
||||
import Point from '../../Point';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
|
||||
import Shape from '../Shape';
|
||||
import Rectangle from '../../Rectangle';
|
||||
import CellState from '../../../cell/datatypes/CellState';
|
||||
import { htmlEntities, replaceTrailingNewlines, trim } from '../../../../util/StringUtils';
|
||||
import {
|
||||
htmlEntities,
|
||||
replaceTrailingNewlines,
|
||||
trim,
|
||||
} from '../../../../util/StringUtils';
|
||||
import { isNode } from '../../../../util/DomUtils';
|
||||
import {
|
||||
AlignValue,
|
||||
ColorValue,
|
||||
OverflowValue,
|
||||
TextDirectionValue,
|
||||
VAlignValue,
|
||||
} from 'packages/core/src/types';
|
||||
import SvgCanvas2D from 'packages/core/src/util/canvas/SvgCanvas2D';
|
||||
|
||||
/**
|
||||
* Extends mxShape to implement a text shape.
|
||||
|
@ -56,28 +65,27 @@ class TextShape extends Shape {
|
|||
constructor(
|
||||
value: string,
|
||||
bounds: Rectangle,
|
||||
align: string = ALIGN_CENTER,
|
||||
valign: string | null = ALIGN_MIDDLE,
|
||||
color: string = 'black',
|
||||
family: string = DEFAULT_FONTFAMILY,
|
||||
size: number = DEFAULT_FONTSIZE,
|
||||
fontStyle: number = DEFAULT_FONTSTYLE,
|
||||
spacing: number = 2,
|
||||
spacingTop: number = 0,
|
||||
spacingRight: number = 0,
|
||||
spacingBottom: number = 0,
|
||||
spacingLeft: number = 0,
|
||||
horizontal: boolean = true,
|
||||
background: string | null = null,
|
||||
border: string | null = null,
|
||||
wrap: boolean = false,
|
||||
clipped: boolean = false,
|
||||
overflow: string = 'visible',
|
||||
labelPadding: number = 0,
|
||||
textDirection: string = DEFAULT_TEXT_DIRECTION
|
||||
align: AlignValue = ALIGN_CENTER,
|
||||
valign: VAlignValue = ALIGN_MIDDLE,
|
||||
color = 'black',
|
||||
family = DEFAULT_FONTFAMILY,
|
||||
size = DEFAULT_FONTSIZE,
|
||||
fontStyle = DEFAULT_FONTSTYLE,
|
||||
spacing = 2,
|
||||
spacingTop = 0,
|
||||
spacingRight = 0,
|
||||
spacingBottom = 0,
|
||||
spacingLeft = 0,
|
||||
horizontal = true,
|
||||
background = NONE,
|
||||
border = NONE,
|
||||
wrap = false,
|
||||
clipped = false,
|
||||
overflow: OverflowValue = 'visible',
|
||||
labelPadding = 0,
|
||||
textDirection: TextDirectionValue = DEFAULT_TEXT_DIRECTION
|
||||
) {
|
||||
super();
|
||||
valign = valign != null ? valign : ALIGN_MIDDLE;
|
||||
|
||||
this.value = value;
|
||||
this.bounds = bounds;
|
||||
|
@ -87,14 +95,11 @@ class TextShape extends Shape {
|
|||
this.family = family;
|
||||
this.size = size;
|
||||
this.fontStyle = fontStyle;
|
||||
this.spacing = parseInt(String(spacing || 2));
|
||||
this.spacingTop = parseInt(String(spacing || 2)) + parseInt(String(spacingTop || 0));
|
||||
this.spacingRight =
|
||||
parseInt(String(spacing || 2)) + parseInt(String(spacingRight || 0));
|
||||
this.spacingBottom =
|
||||
parseInt(String(spacing || 2)) + parseInt(String(spacingBottom || 0));
|
||||
this.spacingLeft =
|
||||
parseInt(String(spacing || 2)) + parseInt(String(spacingLeft || 0));
|
||||
this.spacing = spacing;
|
||||
this.spacingTop = spacing + spacingTop;
|
||||
this.spacingRight = spacing + spacingRight;
|
||||
this.spacingBottom = spacing + spacingBottom;
|
||||
this.spacingLeft = spacing + spacingLeft;
|
||||
this.horizontal = horizontal;
|
||||
this.background = background;
|
||||
this.border = border;
|
||||
|
@ -110,29 +115,29 @@ class TextShape extends Shape {
|
|||
// TODO: Document me!
|
||||
value: string | HTMLElement | SVGGElement | null;
|
||||
bounds: Rectangle;
|
||||
align: string = ALIGN_CENTER;
|
||||
valign: string = ALIGN_MIDDLE;
|
||||
color: string = 'black';
|
||||
family: string = DEFAULT_FONTFAMILY;
|
||||
size: number = DEFAULT_FONTSIZE;
|
||||
fontStyle: number = DEFAULT_FONTSTYLE;
|
||||
spacing: number = 2;
|
||||
spacingTop: number = 0;
|
||||
spacingRight: number = 0;
|
||||
spacingBottom: number = 0;
|
||||
spacingLeft: number = 0;
|
||||
horizontal: boolean = true;
|
||||
background: string | null = null;
|
||||
border: string | null = null;
|
||||
wrap: boolean = false;
|
||||
clipped: boolean = false;
|
||||
overflow: string = 'visible';
|
||||
labelPadding: number = 0;
|
||||
textDirection: string = DEFAULT_TEXT_DIRECTION;
|
||||
align: AlignValue;
|
||||
valign: VAlignValue;
|
||||
color: ColorValue;
|
||||
family: string;
|
||||
size: number;
|
||||
fontStyle: number;
|
||||
spacing: number;
|
||||
spacingTop: number;
|
||||
spacingRight: number;
|
||||
spacingBottom: number;
|
||||
spacingLeft: number;
|
||||
horizontal: boolean;
|
||||
background: ColorValue;
|
||||
border: ColorValue;
|
||||
wrap: boolean;
|
||||
clipped: boolean;
|
||||
overflow: OverflowValue;
|
||||
labelPadding: number;
|
||||
textDirection: TextDirectionValue;
|
||||
margin: Point | null = null;
|
||||
unrotatedBoundingBox: Rectangle | null = null;
|
||||
flipH: boolean = false;
|
||||
flipV: boolean = false;
|
||||
flipH = false;
|
||||
flipV = false;
|
||||
|
||||
/**
|
||||
* Variable: baseSpacingTop
|
||||
|
@ -140,7 +145,7 @@ class TextShape extends Shape {
|
|||
* Specifies the spacing to be added to the top spacing. Default is 0. Use the
|
||||
* value 5 here to get the same label positions as in mxGraph 1.x.
|
||||
*/
|
||||
baseSpacingTop: number = 0;
|
||||
baseSpacingTop = 0;
|
||||
|
||||
/**
|
||||
* Variable: baseSpacingBottom
|
||||
|
@ -148,21 +153,21 @@ class TextShape extends Shape {
|
|||
* Specifies the spacing to be added to the bottom spacing. Default is 0. Use the
|
||||
* value 1 here to get the same label positions as in mxGraph 1.x.
|
||||
*/
|
||||
baseSpacingBottom: number = 0;
|
||||
baseSpacingBottom = 0;
|
||||
|
||||
/**
|
||||
* Variable: baseSpacingLeft
|
||||
*
|
||||
* Specifies the spacing to be added to the left spacing. Default is 0.
|
||||
*/
|
||||
baseSpacingLeft: number = 0;
|
||||
baseSpacingLeft = 0;
|
||||
|
||||
/**
|
||||
* Variable: baseSpacingRight
|
||||
*
|
||||
* Specifies the spacing to be added to the right spacing. Default is 0.
|
||||
*/
|
||||
baseSpacingRight: number = 0;
|
||||
baseSpacingRight = 0;
|
||||
|
||||
/**
|
||||
* Variable: replaceLinefeeds
|
||||
|
@ -170,14 +175,14 @@ class TextShape extends Shape {
|
|||
* Specifies if linefeeds in HTML labels should be replaced with BR tags.
|
||||
* Default is true.
|
||||
*/
|
||||
replaceLinefeeds: boolean = true;
|
||||
replaceLinefeeds = true;
|
||||
|
||||
/**
|
||||
* Variable: verticalTextRotation
|
||||
*
|
||||
* Rotation for vertical text. Default is -90 (bottom to top).
|
||||
*/
|
||||
verticalTextRotation: number = -90;
|
||||
verticalTextRotation = -90;
|
||||
|
||||
/**
|
||||
* Variable: ignoreClippedStringSize
|
||||
|
@ -187,7 +192,7 @@ class TextShape extends Shape {
|
|||
* true, then the bounding box will be set to <bounds>. Default is true.
|
||||
* <ignoreStringSize> has precedence over this switch.
|
||||
*/
|
||||
ignoreClippedStringSize: boolean = true;
|
||||
ignoreClippedStringSize = true;
|
||||
|
||||
/**
|
||||
* Variable: ignoreStringSize
|
||||
|
@ -196,7 +201,7 @@ class TextShape extends Shape {
|
|||
* boundingBox will not ignore the actual size of the string, otherwise
|
||||
* <bounds> will be used instead. Default is false.
|
||||
*/
|
||||
ignoreStringSize: boolean = false;
|
||||
ignoreStringSize = false;
|
||||
|
||||
/**
|
||||
* Variable: lastValue
|
||||
|
@ -210,14 +215,14 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Specifies if caching for HTML labels should be enabled. Default is true.
|
||||
*/
|
||||
cacheEnabled: boolean = true;
|
||||
cacheEnabled = true;
|
||||
|
||||
/**
|
||||
* Function: getSvgScreenOffset
|
||||
*
|
||||
* Disables offset in IE9 for crisper image output.
|
||||
*/
|
||||
getSvgScreenOffset(): number {
|
||||
getSvgScreenOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -226,12 +231,12 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Returns true if the bounds are not null and all of its variables are numeric.
|
||||
*/
|
||||
checkBounds(): boolean {
|
||||
checkBounds() {
|
||||
return (
|
||||
!isNaN(this.scale) &&
|
||||
isFinite(this.scale) &&
|
||||
this.scale > 0 &&
|
||||
this.bounds != null &&
|
||||
this.bounds &&
|
||||
!isNaN(this.bounds.x) &&
|
||||
!isNaN(this.bounds.y) &&
|
||||
!isNaN(this.bounds.width) &&
|
||||
|
@ -244,7 +249,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Generic rendering code.
|
||||
*/
|
||||
paint(c: mxSvgCanvas2D, update: boolean = false): void {
|
||||
paint(c: AbstractCanvas2D, update = false): void {
|
||||
// Scale is passed-through to canvas
|
||||
const s = this.scale;
|
||||
const x = this.bounds.x / s;
|
||||
|
@ -292,14 +297,14 @@ class TextShape extends Shape {
|
|||
? (<string>val).replace(/\n/g, '<br/>')
|
||||
: val;
|
||||
|
||||
let dir: string | null = this.textDirection;
|
||||
let dir: TextDirectionValue = this.textDirection;
|
||||
|
||||
if (dir === TEXT_DIRECTION_AUTO && !realHtml) {
|
||||
dir = this.getAutoDirection();
|
||||
}
|
||||
|
||||
if (dir !== TEXT_DIRECTION_LTR && dir !== TEXT_DIRECTION_RTL) {
|
||||
dir = null;
|
||||
dir = TEXT_DIRECTION_DEFAULT;
|
||||
}
|
||||
|
||||
c.text(
|
||||
|
@ -333,13 +338,13 @@ class TextShape extends Shape {
|
|||
this.lastValue === this.value &&
|
||||
(isNode(this.value) || this.dialect === DIALECT_STRICTHTML)
|
||||
) {
|
||||
// @ts-ignore
|
||||
if (this.node.nodeName === 'DIV') {
|
||||
this.redrawHtmlShape();
|
||||
this.updateBoundingBox();
|
||||
} else {
|
||||
const canvas = this.createCanvas();
|
||||
|
||||
if (canvas) {
|
||||
// Specifies if events should be handled
|
||||
canvas.pointerEvents = this.pointerEvents;
|
||||
|
||||
|
@ -347,6 +352,7 @@ class TextShape extends Shape {
|
|||
this.destroyCanvas(canvas);
|
||||
this.updateBoundingBox();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.redraw();
|
||||
|
||||
|
@ -378,8 +384,8 @@ class TextShape extends Shape {
|
|||
this.spacingBottom = 2;
|
||||
this.spacingLeft = 2;
|
||||
this.horizontal = true;
|
||||
this.background = null;
|
||||
this.border = null;
|
||||
this.background = NONE;
|
||||
this.border = NONE;
|
||||
this.textDirection = DEFAULT_TEXT_DIRECTION;
|
||||
this.margin = null;
|
||||
}
|
||||
|
@ -397,31 +403,24 @@ class TextShape extends Shape {
|
|||
const old = this.spacing;
|
||||
super.apply(state);
|
||||
|
||||
if (this.style != null) {
|
||||
this.fontStyle = this.style.fontStyle || this.fontStyle;
|
||||
this.family = getValue(this.style, 'fontFamily', this.family);
|
||||
this.size = getValue(this.style, 'fontSize', this.size);
|
||||
this.color = getValue(this.style, 'fontColor', this.color);
|
||||
this.align = getValue(this.style, 'align', this.align);
|
||||
this.valign = getValue(this.style, 'verticalAlign', this.valign);
|
||||
this.spacing = parseInt(getValue(this.style, 'spacing', this.spacing));
|
||||
this.spacingTop =
|
||||
parseInt(getValue(this.style, 'spacingTop', this.spacingTop - old)) +
|
||||
this.spacing;
|
||||
this.spacingRight =
|
||||
parseInt(getValue(this.style, 'spacingRight', this.spacingRight - old)) +
|
||||
this.spacing;
|
||||
this.spacingBottom =
|
||||
parseInt(getValue(this.style, 'spacingBottom', this.spacingBottom - old)) +
|
||||
this.spacing;
|
||||
this.spacingLeft =
|
||||
parseInt(getValue(this.style, 'spacingLeft', this.spacingLeft - old)) +
|
||||
this.spacing;
|
||||
this.horizontal = getValue(this.style, 'horizontal', this.horizontal);
|
||||
this.background = getValue(this.style, 'backgroundColor', this.background);
|
||||
this.border = getValue(this.style, 'labelBorderColor', this.border);
|
||||
this.textDirection = getValue(this.style, 'textDirection', DEFAULT_TEXT_DIRECTION);
|
||||
this.opacity = getValue(this.style, 'textOpacity', 100);
|
||||
if (this.style) {
|
||||
this.fontStyle = this.style.fontStyle;
|
||||
this.family = this.style.fontFamily;
|
||||
this.size = this.style.fontSize;
|
||||
this.color = this.style.fontColor;
|
||||
this.align = this.style.align;
|
||||
this.valign = this.style.verticalAlign;
|
||||
this.spacing = this.style.spacing;
|
||||
this.spacingTop = this.style.spacingTop;
|
||||
this.spacingRight = this.style.spacingRight;
|
||||
this.spacingBottom = this.style.spacingBottom;
|
||||
this.spacingLeft = this.style.spacingLeft;
|
||||
this.horizontal = this.style.horizontal;
|
||||
this.background = this.style.backgroundColor;
|
||||
this.border = this.style.labelBorderColor;
|
||||
this.textDirection = this.style.textDirection;
|
||||
this.opacity = this.style.textOpacity;
|
||||
|
||||
this.updateMargin();
|
||||
}
|
||||
|
||||
|
@ -437,14 +436,14 @@ class TextShape extends Shape {
|
|||
* depending on the contents of <value>. This is not invoked for HTML, wrapped
|
||||
* content or if <value> is a DOM node.
|
||||
*/
|
||||
getAutoDirection(): string {
|
||||
getAutoDirection() {
|
||||
// Looks for strong (directional) characters
|
||||
const tmp = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(
|
||||
<string>this.value
|
||||
String(this.value)
|
||||
);
|
||||
|
||||
// Returns the direction defined by the character
|
||||
return tmp != null && tmp.length > 0 && tmp[0] > 'z'
|
||||
return tmp && tmp.length > 0 && tmp[0] > 'z'
|
||||
? TEXT_DIRECTION_RTL
|
||||
: TEXT_DIRECTION_LTR;
|
||||
}
|
||||
|
@ -457,9 +456,9 @@ class TextShape extends Shape {
|
|||
getContentNode() {
|
||||
let result = this.node;
|
||||
|
||||
if (result != null) {
|
||||
if (result) {
|
||||
// Rendered with no foreignObject
|
||||
if (result.ownerSVGElement == null) {
|
||||
if (!result.ownerSVGElement) {
|
||||
// @ts-ignore
|
||||
result = this.node.firstChild.firstChild;
|
||||
} else {
|
||||
|
@ -468,6 +467,7 @@ class TextShape extends Shape {
|
|||
result = result.firstChild.firstChild.firstChild.firstChild.firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -476,21 +476,17 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Updates the <boundingBox> for this shape using the given node and position.
|
||||
*/
|
||||
updateBoundingBox(): void {
|
||||
updateBoundingBox() {
|
||||
let { node } = this;
|
||||
this.boundingBox = this.bounds.clone();
|
||||
const rot = this.getTextRotation();
|
||||
|
||||
const h =
|
||||
this.style != null ? getValue(this.style, 'labelPosition', ALIGN_CENTER) : null;
|
||||
const v =
|
||||
this.style != null
|
||||
? getValue(this.style, 'verticalLabelPosition', ALIGN_MIDDLE)
|
||||
: null;
|
||||
const h = this.style?.labelPosition ?? ALIGN_CENTER;
|
||||
const v = this.style?.verticalLabelPosition ?? ALIGN_MIDDLE;
|
||||
|
||||
if (
|
||||
!this.ignoreStringSize &&
|
||||
node != null &&
|
||||
node &&
|
||||
this.overflow !== 'fill' &&
|
||||
(!this.clipped ||
|
||||
!this.ignoreClippedStringSize ||
|
||||
|
@ -501,8 +497,8 @@ class TextShape extends Shape {
|
|||
let oh = null;
|
||||
|
||||
if (
|
||||
node.firstChild != null &&
|
||||
node.firstChild.firstChild != null &&
|
||||
node.firstChild &&
|
||||
node.firstChild.firstChild &&
|
||||
node.firstChild.firstChild.nodeName === 'foreignObject'
|
||||
) {
|
||||
// Uses second inner DIV for font metrics
|
||||
|
@ -512,7 +508,6 @@ class TextShape extends Shape {
|
|||
oh = node.offsetHeight * this.scale;
|
||||
|
||||
if (this.overflow === 'width') {
|
||||
// @ts-ignore
|
||||
ow = this.boundingBox.width;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
|
@ -523,7 +518,7 @@ class TextShape extends Shape {
|
|||
const b = node.getBBox();
|
||||
|
||||
// Workaround for bounding box of empty string
|
||||
if (typeof this.value === 'string' && trim(this.value)?.length == 0) {
|
||||
if (typeof this.value === 'string' && trim(this.value)?.length === 0) {
|
||||
this.boundingBox = null;
|
||||
} else if (b.width === 0 && b.height === 0) {
|
||||
this.boundingBox = null;
|
||||
|
@ -537,12 +532,12 @@ class TextShape extends Shape {
|
|||
}
|
||||
}
|
||||
|
||||
if (ow != null && oh != null) {
|
||||
if (ow && oh) {
|
||||
this.boundingBox = new Rectangle(this.bounds.x, this.bounds.y, ow, oh);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.boundingBox != null) {
|
||||
if (this.boundingBox) {
|
||||
const margin = <Rectangle>this.margin;
|
||||
|
||||
if (rot !== 0) {
|
||||
|
@ -581,7 +576,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Returns 0 to avoid using rotation in the canvas via updateTransform.
|
||||
*/
|
||||
getShapeRotation(): number {
|
||||
getShapeRotation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -590,10 +585,8 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Returns the rotation for the text label of the corresponding shape.
|
||||
*/
|
||||
getTextRotation(): number {
|
||||
return this.state != null && this.state.shape != null
|
||||
? this.state.shape.getTextRotation()
|
||||
: 0;
|
||||
getTextRotation() {
|
||||
return this.state && this.state.shape ? this.state.shape.getTextRotation() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -602,13 +595,8 @@ class TextShape extends Shape {
|
|||
* Inverts the bounds if <mxShape.isBoundsInverted> returns true or if the
|
||||
* horizontal style is false.
|
||||
*/
|
||||
isPaintBoundsInverted(): boolean {
|
||||
return (
|
||||
!this.horizontal &&
|
||||
this.state != null &&
|
||||
// @ts-ignore
|
||||
this.state.cell.isVertex()
|
||||
);
|
||||
isPaintBoundsInverted() {
|
||||
return !this.horizontal && !!this.state && this.state.cell.isVertex();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -616,7 +604,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Sets the state of the canvas for drawing the shape.
|
||||
*/
|
||||
configureCanvas(c: mxSvgCanvas2D, x: number, y: number, w: number, h: number): void {
|
||||
configureCanvas(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void {
|
||||
super.configureCanvas(c, x, y, w, h);
|
||||
|
||||
c.setFontColor(this.color);
|
||||
|
@ -691,7 +679,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Updates the HTML node(s) to reflect the latest bounds and scale.
|
||||
*/
|
||||
redrawHtmlShape(): void {
|
||||
redrawHtmlShape() {
|
||||
const w = Math.max(0, Math.round(this.bounds.width / this.scale));
|
||||
const h = Math.max(0, Math.round(this.bounds.height / this.scale));
|
||||
const flex =
|
||||
|
@ -699,9 +687,9 @@ class TextShape extends Shape {
|
|||
`top: ${Math.round(this.bounds.y)}px; pointer-events: none; `;
|
||||
const block = this.getTextCss();
|
||||
const margin = <Point>this.margin;
|
||||
const node = <SVGGElement>this.node;
|
||||
const node = this.node;
|
||||
|
||||
mxSvgCanvas2D.createCss(
|
||||
SvgCanvas2D.createCss(
|
||||
w + 2,
|
||||
h,
|
||||
this.align,
|
||||
|
@ -709,8 +697,8 @@ class TextShape extends Shape {
|
|||
this.wrap,
|
||||
this.overflow,
|
||||
this.clipped,
|
||||
this.background != null ? htmlEntities(this.background, true) : null,
|
||||
this.border != null ? htmlEntities(this.border, true) : null,
|
||||
this.background !== NONE ? htmlEntities(this.background, true) : null,
|
||||
this.border !== NONE ? htmlEntities(this.border, true) : null,
|
||||
flex,
|
||||
block,
|
||||
this.scale,
|
||||
|
@ -745,7 +733,7 @@ class TextShape extends Shape {
|
|||
}
|
||||
}
|
||||
|
||||
if (<number>this.opacity < 100) {
|
||||
if (this.opacity < 100) {
|
||||
block += `opacity: ${<number>this.opacity / 100}; `;
|
||||
}
|
||||
|
||||
|
@ -756,7 +744,7 @@ class TextShape extends Shape {
|
|||
this.value.outerHTML
|
||||
: this.getHtmlValue();
|
||||
|
||||
if (node.firstChild == null) {
|
||||
if (!node.firstChild) {
|
||||
node.innerHTML = `<div><div>${html}</div></div>`;
|
||||
}
|
||||
|
||||
|
@ -773,7 +761,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Sets the inner HTML of the given element to the <value>.
|
||||
*/
|
||||
updateInnerHtml(elt: HTMLElement): void {
|
||||
updateInnerHtml(elt: HTMLElement) {
|
||||
if (isNode(this.value)) {
|
||||
// @ts-ignore
|
||||
elt.innerHTML = this.value.outerHTML;
|
||||
|
@ -782,7 +770,7 @@ class TextShape extends Shape {
|
|||
|
||||
if (this.dialect !== DIALECT_STRICTHTML) {
|
||||
// LATER: Can be cached in updateValue
|
||||
val = htmlEntities(<string>val, false);
|
||||
val = htmlEntities(val, false);
|
||||
}
|
||||
|
||||
// Handles trailing newlines to make sure they are visible in rendering output
|
||||
|
@ -799,8 +787,8 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Updates the HTML node(s) to reflect the latest bounds and scale.
|
||||
*/
|
||||
updateValue(): void {
|
||||
const node = <SVGGElement>this.node;
|
||||
updateValue() {
|
||||
const node = this.node;
|
||||
|
||||
if (isNode(this.value)) {
|
||||
node.innerHTML = '';
|
||||
|
@ -809,32 +797,31 @@ class TextShape extends Shape {
|
|||
let val = this.value as string;
|
||||
|
||||
if (this.dialect !== DIALECT_STRICTHTML) {
|
||||
val = htmlEntities(<string>val, false);
|
||||
val = htmlEntities(val, false);
|
||||
}
|
||||
|
||||
// Handles trailing newlines to make sure they are visible in rendering output
|
||||
val = replaceTrailingNewlines(val, '<div><br></div>');
|
||||
val = this.replaceLinefeeds ? val.replace(/\n/g, '<br/>') : val;
|
||||
const bg =
|
||||
this.background != null && this.background !== NONE ? this.background : null;
|
||||
const bd = this.border != null && this.border !== NONE ? this.border : null;
|
||||
const bg = this.background !== NONE ? this.background : null;
|
||||
const bd = this.border !== NONE ? this.border : null;
|
||||
|
||||
if (this.overflow === 'fill' || this.overflow === 'width') {
|
||||
if (bg != null) {
|
||||
if (bg) {
|
||||
node.style.backgroundColor = bg;
|
||||
}
|
||||
|
||||
if (bd != null) {
|
||||
if (bd) {
|
||||
node.style.border = `1px solid ${bd}`;
|
||||
}
|
||||
} else {
|
||||
let css = '';
|
||||
|
||||
if (bg != null) {
|
||||
if (bg) {
|
||||
css += `background-color:${htmlEntities(bg, true)};`;
|
||||
}
|
||||
|
||||
if (bd != null) {
|
||||
if (bd) {
|
||||
css += `border:1px solid ${htmlEntities(bd, true)};`;
|
||||
}
|
||||
|
||||
|
@ -873,7 +860,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Updates the HTML node(s) to reflect the latest bounds and scale.
|
||||
*/
|
||||
updateFont(node: HTMLElement | SVGGElement): void {
|
||||
updateFont(node: HTMLElement | SVGGElement) {
|
||||
const { style } = node;
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -923,7 +910,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Updates the HTML node(s) to reflect the latest bounds and scale.
|
||||
*/
|
||||
updateSize(node: HTMLElement, enableWrap: boolean = false): void {
|
||||
updateSize(node: HTMLElement, enableWrap = false) {
|
||||
const w = Math.max(0, Math.round(this.bounds.width / this.scale));
|
||||
const h = Math.max(0, Math.round(this.bounds.height / this.scale));
|
||||
const { style } = node;
|
||||
|
@ -992,7 +979,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Returns the spacing as an <mxPoint>.
|
||||
*/
|
||||
updateMargin(): void {
|
||||
updateMargin() {
|
||||
this.margin = getAlignmentAsPoint(this.align, this.valign);
|
||||
}
|
||||
|
||||
|
@ -1001,7 +988,7 @@ class TextShape extends Shape {
|
|||
*
|
||||
* Returns the spacing as an <mxPoint>.
|
||||
*/
|
||||
getSpacing(): Point {
|
||||
getSpacing() {
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
import Point from '../../Point';
|
||||
import Actor from '../Actor';
|
||||
import utils, { getValue } from '../../../../util/Utils';
|
||||
import { LINE_ARCSIZE } from '../../../../util/Constants';
|
||||
import mxSvgCanvas2D from '../../../../util/canvas/mxSvgCanvas2D';
|
||||
import AbstractCanvas2D from 'packages/core/src/util/canvas/AbstractCanvas2D';
|
||||
|
||||
/**
|
||||
* Implementation of the triangle shape.
|
||||
|
@ -25,7 +24,7 @@ class TriangleShape extends Actor {
|
|||
* Adds roundable support.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isRoundable(): boolean {
|
||||
isRoundable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -37,15 +36,8 @@ class TriangleShape extends Actor {
|
|||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
redrawPath(
|
||||
c: mxSvgCanvas2D,
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number
|
||||
): void {
|
||||
const arcSize: number =
|
||||
getValue(this.style, 'arcSize', LINE_ARCSIZE) / 2;
|
||||
redrawPath(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
const arcSize = (this.style?.arcSize ?? LINE_ARCSIZE) / 2;
|
||||
|
||||
this.addPoints(
|
||||
c,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import Graph from "../Graph";
|
||||
import ImageBundle from "../../util/image/ImageBundle";
|
||||
import ImageBundle from "./ImageBundle";
|
||||
import Graph from '../Graph';
|
||||
import ImageBundle from './ImageBundle';
|
||||
|
||||
class GraphImage {
|
||||
constructor(graph: Graph) {
|
||||
|
@ -19,14 +18,14 @@ class GraphImage {
|
|||
/**
|
||||
* Adds the specified {@link ImageBundle}.
|
||||
*/
|
||||
addImageBundle(bundle: ImageBundle): void {
|
||||
addImageBundle(bundle: ImageBundle) {
|
||||
this.imageBundles.push(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified {@link ImageBundle}.
|
||||
*/
|
||||
removeImageBundle(bundle: ImageBundle): void {
|
||||
removeImageBundle(bundle: ImageBundle) {
|
||||
const tmp = [];
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
if (this.imageBundles[i] !== bundle) {
|
||||
|
@ -40,11 +39,11 @@ class GraphImage {
|
|||
* Searches all {@link imageBundles} for the specified key and returns the value
|
||||
* for the first match or null if the key is not found.
|
||||
*/
|
||||
getImageFromBundles(key: string): string {
|
||||
if (key != null) {
|
||||
getImageFromBundles(key: string) {
|
||||
if (key) {
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
const image = this.imageBundles[i].getImage(key);
|
||||
if (image != null) {
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
*
|
||||
* Constructs a new image.
|
||||
*/
|
||||
class Image {
|
||||
constructor(src: string,
|
||||
width: number,
|
||||
height: number) {
|
||||
class ImageBox {
|
||||
constructor(src: string, width: number, height: number) {
|
||||
this.src = src;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
@ -28,21 +26,21 @@ class Image {
|
|||
*
|
||||
* String that specifies the URL of the image.
|
||||
*/
|
||||
src: string | null = null;
|
||||
src: string;
|
||||
|
||||
/**
|
||||
* Variable: width
|
||||
*
|
||||
* Integer that specifies the width of the image.
|
||||
*/
|
||||
width: number | null = null;
|
||||
width: number;
|
||||
|
||||
/**
|
||||
* Variable: height
|
||||
*
|
||||
* Integer that specifies the height of the image.
|
||||
*/
|
||||
height: number | null = null;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export default Image;
|
||||
export default ImageBox;
|
|
@ -5,6 +5,13 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
type ImageMap = {
|
||||
[key: string]: {
|
||||
value: string;
|
||||
fallback: Function;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Class: mxImageBundle
|
||||
*
|
||||
|
@ -51,9 +58,9 @@
|
|||
* all data URIs should be limited to 32 KB.
|
||||
*/
|
||||
class ImageBundle {
|
||||
constructor(alt) {
|
||||
this.images = [];
|
||||
this.alt = alt != null ? alt : false;
|
||||
constructor(alt = false) {
|
||||
this.images = {};
|
||||
this.alt = alt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,14 +68,14 @@ class ImageBundle {
|
|||
*
|
||||
* Maps from keys to images.
|
||||
*/
|
||||
images: { [key: string]: { value: string; fallback: Function } } | null = null;
|
||||
images: ImageMap;
|
||||
|
||||
/**
|
||||
* Variable: alt
|
||||
*
|
||||
* Specifies if the fallback representation should be returned.
|
||||
*/
|
||||
alt: boolean = null;
|
||||
alt: boolean;
|
||||
|
||||
/**
|
||||
* Function: putImage
|
||||
|
@ -87,13 +94,13 @@ class ImageBundle {
|
|||
* or fallback, depending on <alt>. The fallback is returned if
|
||||
* <alt> is true, the value is returned otherwise.
|
||||
*/
|
||||
getImage(key: string): string {
|
||||
getImage(key: string) {
|
||||
let result = null;
|
||||
|
||||
if (key != null) {
|
||||
if (key) {
|
||||
const img = this.images[key];
|
||||
|
||||
if (img != null) {
|
||||
if (img) {
|
||||
result = this.alt ? img.fallback : img.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import mxAbstractCanvas2D from '../../util/canvas/mxAbstractCanvas2D';
|
||||
import AbstractCanvas2D from '../../util/canvas/AbstractCanvas2D';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
|
||||
|
@ -41,13 +41,13 @@ class ImageExport {
|
|||
/**
|
||||
* Specifies if overlays should be included in the export. Default is false.
|
||||
*/
|
||||
includeOverlays: boolean = false;
|
||||
includeOverlays = false;
|
||||
|
||||
/**
|
||||
* Draws the given state and all its descendants to the given canvas.
|
||||
*/
|
||||
drawState(state: CellState, canvas: mxAbstractCanvas2D): void {
|
||||
if (state != null) {
|
||||
drawState(state: CellState, canvas: AbstractCanvas2D): void {
|
||||
if (state) {
|
||||
this.visitStatesRecursive(state, canvas, () => {
|
||||
this.drawCellState(state, canvas);
|
||||
});
|
||||
|
@ -66,8 +66,8 @@ class ImageExport {
|
|||
*
|
||||
* Visits the given state and all its descendants to the given canvas recursively.
|
||||
*/
|
||||
visitStatesRecursive(state: CellState, canvas: mxAbstractCanvas2D, visitor: Function) {
|
||||
if (state != null) {
|
||||
visitStatesRecursive(state: CellState, canvas: AbstractCanvas2D, visitor: Function) {
|
||||
if (state) {
|
||||
visitor(state, canvas);
|
||||
|
||||
const { graph } = state.view;
|
||||
|
@ -83,18 +83,18 @@ class ImageExport {
|
|||
/**
|
||||
* Returns the link for the given cell state and canvas. This returns null.
|
||||
*/
|
||||
getLinkForCellState(state: CellState, canvas: mxAbstractCanvas2D): any {
|
||||
getLinkForCellState(state: CellState, canvas: AbstractCanvas2D): any {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the given state to the given canvas.
|
||||
*/
|
||||
drawCellState(state: CellState, canvas: mxAbstractCanvas2D): void {
|
||||
drawCellState(state: CellState, canvas: AbstractCanvas2D): void {
|
||||
// Experimental feature
|
||||
const link = this.getLinkForCellState(state, canvas);
|
||||
|
||||
if (link != null) {
|
||||
if (link) {
|
||||
canvas.setLink(link);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ class ImageExport {
|
|||
this.drawShape(state, canvas);
|
||||
this.drawText(state, canvas);
|
||||
|
||||
if (link != null) {
|
||||
if (link) {
|
||||
canvas.setLink(null);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ class ImageExport {
|
|||
*
|
||||
* Draws the shape of the given state.
|
||||
*/
|
||||
drawShape(state: CellState, canvas: mxAbstractCanvas2D): void {
|
||||
drawShape(state: CellState, canvas: AbstractCanvas2D): void {
|
||||
if (state.shape instanceof Shape && state.shape.checkBounds()) {
|
||||
canvas.save();
|
||||
|
||||
|
@ -127,8 +127,8 @@ class ImageExport {
|
|||
/**
|
||||
* Draws the text of the given state.
|
||||
*/
|
||||
drawText(state: CellState, canvas: mxAbstractCanvas2D): void {
|
||||
if (state.text != null && state.text.checkBounds()) {
|
||||
drawText(state: CellState, canvas: AbstractCanvas2D): void {
|
||||
if (state.text && state.text.checkBounds()) {
|
||||
canvas.save();
|
||||
|
||||
state.text.beforePaint(canvas);
|
||||
|
@ -145,7 +145,7 @@ class ImageExport {
|
|||
* Draws the overlays for the given state. This is called if <includeOverlays>
|
||||
* is true.
|
||||
*/
|
||||
drawOverlays(state: CellState, canvas: mxAbstractCanvas2D): void {
|
||||
drawOverlays(state: CellState, canvas: AbstractCanvas2D): void {
|
||||
if (state.overlays != null) {
|
||||
state.overlays.visit((id, shape) => {
|
||||
if (shape instanceof Shape) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Cell from "../cell/datatypes/Cell";
|
||||
import CellOverlay from "../cell/CellOverlay";
|
||||
import EventObject from "../event/EventObject";
|
||||
import InternalEvent from "../event/InternalEvent";
|
||||
import Image from "../image/Image";
|
||||
import InternalMouseEvent from "../event/InternalMouseEvent";
|
||||
import Graph from "../Graph";
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellOverlay from '../cell/CellOverlay';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Image from '../image/ImageBox';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import Graph from '../Graph';
|
||||
|
||||
class Overlays {
|
||||
constructor(graph: Graph) {
|
||||
|
@ -82,13 +82,7 @@ class Overlays {
|
|||
}
|
||||
|
||||
this.fireEvent(
|
||||
new EventObject(
|
||||
InternalEvent.REMOVE_OVERLAY,
|
||||
'cell',
|
||||
cell,
|
||||
'overlay',
|
||||
overlay
|
||||
)
|
||||
new EventObject(InternalEvent.REMOVE_OVERLAY, 'cell', cell, 'overlay', overlay)
|
||||
);
|
||||
} else {
|
||||
overlay = null;
|
||||
|
@ -184,18 +178,18 @@ class Overlays {
|
|||
img = img != null ? img : this.warningImage;
|
||||
|
||||
// Creates the overlay with the image and warning
|
||||
const overlay = new CellOverlay(
|
||||
img,
|
||||
`<font color=red>${warning}</font>`
|
||||
);
|
||||
const overlay = new CellOverlay(img, `<font color=red>${warning}</font>`);
|
||||
|
||||
// Adds a handler for single mouseclicks to select the cell
|
||||
if (isSelect) {
|
||||
overlay.addListener(InternalEvent.CLICK, (sender: any, evt: InternalMouseEvent) => {
|
||||
overlay.addListener(
|
||||
InternalEvent.CLICK,
|
||||
(sender: any, evt: InternalMouseEvent) => {
|
||||
if (this.isEnabled()) {
|
||||
this.setSelectionCell(cell);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Sets and returns the overlay in the graph
|
||||
|
|
|
@ -72,7 +72,7 @@ class CellHighlight {
|
|||
}
|
||||
|
||||
// TODO: Document me!!
|
||||
highlightColor: ColorValue = null;
|
||||
highlightColor: ColorValue | null = null;
|
||||
|
||||
strokeWidth: number = 0;
|
||||
|
||||
|
@ -119,7 +119,7 @@ class CellHighlight {
|
|||
*
|
||||
* @param {string} color - String that represents the new highlight color.
|
||||
*/
|
||||
setHighlightColor(color: ColorValue) {
|
||||
setHighlightColor(color: ColorValue | null) {
|
||||
this.highlightColor = color;
|
||||
|
||||
if (this.shape) {
|
||||
|
@ -134,15 +134,10 @@ class CellHighlight {
|
|||
this.shape = this.createShape();
|
||||
this.repaint();
|
||||
|
||||
const node = this.shape?.node;
|
||||
if (
|
||||
!this.keepOnTop &&
|
||||
this.shape.node?.parentNode?.firstChild !== this.shape.node
|
||||
) {
|
||||
this.shape.node.parentNode.insertBefore(
|
||||
this.shape.node,
|
||||
this.shape.node.parentNode.firstChild
|
||||
);
|
||||
const node = this.shape.node;
|
||||
|
||||
if (!this.keepOnTop && node?.parentNode?.firstChild !== node) {
|
||||
node.parentNode.insertBefore(node, node.parentNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,20 +145,20 @@ class CellHighlight {
|
|||
* Creates and returns the highlight shape for the given state.
|
||||
*/
|
||||
createShape() {
|
||||
const shape = <Shape>(
|
||||
this.graph.cellRenderer.createShape(<CellState>this.state)
|
||||
);
|
||||
if (!this.state) return;
|
||||
|
||||
shape.svgStrokeTolerance = (<graph>this.graph).tolerance;
|
||||
shape.points = (<CellState>this.state).absolutePoints;
|
||||
shape.apply(<CellState>this.state);
|
||||
const shape = this.graph.cellRenderer.createShape(this.state);
|
||||
|
||||
shape.svgStrokeTolerance = this.graph.tolerance;
|
||||
shape.points = this.state.absolutePoints;
|
||||
shape.apply(this.state);
|
||||
shape.stroke = this.highlightColor;
|
||||
shape.opacity = this.opacity;
|
||||
shape.isDashed = this.dashed;
|
||||
shape.isShadow = false;
|
||||
|
||||
shape.dialect = DIALECT_SVG;
|
||||
shape.init((<graph>this.graph).getView().getOverlayPane());
|
||||
shape.init(this.graph.getView().getOverlayPane());
|
||||
InternalEvent.redirectMouseEvents(shape.node, this.graph, this.state);
|
||||
|
||||
if ((<graph>this.graph).dialect !== DIALECT_SVG) {
|
||||
|
@ -191,7 +186,7 @@ class CellHighlight {
|
|||
|
||||
// @ts-ignore
|
||||
if (this.graph.model.isEdge(this.state.cell)) {
|
||||
this.shape.strokewidth = this.getStrokeWidth();
|
||||
this.shape.strokeWidth = this.getStrokeWidth();
|
||||
this.shape.points = this.state.absolutePoints;
|
||||
this.shape.outline = false;
|
||||
} else {
|
||||
|
@ -202,8 +197,7 @@ class CellHighlight {
|
|||
this.state.height + 2 * this.spacing
|
||||
);
|
||||
this.shape.rotation = Number(this.state.style.rotation || '0');
|
||||
this.shape.strokewidth =
|
||||
<number>this.getStrokeWidth() / this.state.view.scale;
|
||||
this.shape.strokeWidth = <number>this.getStrokeWidth() / this.state.view.scale;
|
||||
this.shape.outline = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import Cell from "../cell/datatypes/Cell";
|
||||
import CellArray from "../cell/datatypes/CellArray";
|
||||
import Rectangle from "../geometry/Rectangle";
|
||||
import InternalMouseEvent from "../event/InternalMouseEvent";
|
||||
import graph from "../Graph";
|
||||
import mxClient from "../../mxClient";
|
||||
import SelectionChange from "./SelectionChange";
|
||||
import UndoableEdit from "../model/UndoableEdit";
|
||||
import EventObject from "../event/EventObject";
|
||||
import InternalEvent from "../event/InternalEvent";
|
||||
import EventSource from "../event/EventSource";
|
||||
import Dictionary from "../../util/Dictionary";
|
||||
import RootChange from "../model/RootChange";
|
||||
import ChildChange from "../model/ChildChange";
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import graph from '../Graph';
|
||||
import mxClient from '../../mxClient';
|
||||
import SelectionChange from './SelectionChange';
|
||||
import UndoableEdit from '../model/UndoableEdit';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import EventSource from '../event/EventSource';
|
||||
import Dictionary from '../../util/Dictionary';
|
||||
import RootChange from '../model/RootChange';
|
||||
import ChildChange from '../model/ChildChange';
|
||||
|
||||
class GraphSelection extends EventSource {
|
||||
constructor(graph: graph) {
|
||||
|
@ -50,25 +50,27 @@ class GraphSelection extends EventSource {
|
|||
*/
|
||||
singleSelection: boolean = false;
|
||||
|
||||
// TODO: Document me!!
|
||||
selectionModel: GraphSelection | null = null;
|
||||
|
||||
/**
|
||||
* Returns the {@link mxGraphSelectionModel} that contains the selection.
|
||||
*/
|
||||
getSelectionModel(): mxGraphSelectionModel {
|
||||
return <mxGraphSelectionModel>this.selectionModel;
|
||||
getSelectionModel() {
|
||||
return this.selectionModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link mxSelectionModel} that contains the selection.
|
||||
*/
|
||||
setSelectionModel(selectionModel: mxGraphSelectionModel): void {
|
||||
setSelectionModel(selectionModel: GraphSelection) {
|
||||
this.selectionModel = selectionModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link singleSelection} as a boolean.
|
||||
*/
|
||||
isSingleSelection(): boolean {
|
||||
isSingleSelection() {
|
||||
return this.singleSelection;
|
||||
}
|
||||
|
||||
|
@ -78,7 +80,7 @@ class GraphSelection extends EventSource {
|
|||
* @param {boolean} singleSelection Boolean that specifies the new value for
|
||||
* {@link singleSelection}.
|
||||
*/
|
||||
setSingleSelection(singleSelection: boolean): void {
|
||||
setSingleSelection(singleSelection: boolean) {
|
||||
this.singleSelection = singleSelection;
|
||||
}
|
||||
|
||||
|
@ -228,13 +230,19 @@ class GraphSelection extends EventSource {
|
|||
* @param added Array of {@link Cell} to add to the selection.
|
||||
* @param remove Array of {@link Cell} to remove from the selection.
|
||||
*/
|
||||
changeSelection(added: CellArray | null=null,
|
||||
removed: CellArray | null=null): void {
|
||||
changeSelection(
|
||||
added: CellArray | null = null,
|
||||
removed: CellArray | null = null
|
||||
): void {
|
||||
if (
|
||||
(added != null && added.length > 0 && added[0] != null) ||
|
||||
(removed != null && removed.length > 0 && removed[0] != null)
|
||||
) {
|
||||
const change = new SelectionChange(this, added || new CellArray(), removed || new CellArray());
|
||||
const change = new SelectionChange(
|
||||
this,
|
||||
added || new CellArray(),
|
||||
removed || new CellArray()
|
||||
);
|
||||
change.execute();
|
||||
const edit = new UndoableEdit(this, false);
|
||||
edit.add(change);
|
||||
|
@ -589,7 +597,6 @@ class GraphSelection extends EventSource {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if any sibling of the given cell is selected.
|
||||
*/
|
||||
|
@ -646,10 +653,7 @@ class GraphSelection extends EventSource {
|
|||
for (let i = 0; i < changes.length; i += 1) {
|
||||
const change = changes[i];
|
||||
|
||||
if (
|
||||
change.constructor !== RootChange &&
|
||||
(ignoreFn == null || !ignoreFn(change))
|
||||
) {
|
||||
if (change.constructor !== RootChange && (ignoreFn == null || !ignoreFn(change))) {
|
||||
let cell = null;
|
||||
|
||||
if (change instanceof ChildChange) {
|
||||
|
@ -666,7 +670,6 @@ class GraphSelection extends EventSource {
|
|||
return cells;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes selection cells that are not in the model from the selection.
|
||||
*/
|
||||
|
@ -695,5 +698,3 @@ class GraphSelection extends EventSource {
|
|||
}
|
||||
|
||||
export default GraphSelection;
|
||||
|
||||
|
||||
|
|
|
@ -40,21 +40,16 @@ import InternalMouseEvent from '../event/InternalMouseEvent';
|
|||
import StyleRegistry from '../style/StyleRegistry';
|
||||
import graph from '../Graph';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import Image from '../image/Image';
|
||||
import Image from '../image/ImageBox';
|
||||
import CurrentRootChange from './CurrentRootChange';
|
||||
import Model from '../model/Model';
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
import Geometry from '../geometry/Geometry';
|
||||
import ConnectionConstraint from '../connection/ConnectionConstraint';
|
||||
import PopupMenuHandler from '../popups_menus/PopupMenuHandler';
|
||||
import {
|
||||
getClientX,
|
||||
getClientY,
|
||||
getSource,
|
||||
isConsumed,
|
||||
} from '../../util/EventUtils';
|
||||
import { getClientX, getClientY, getSource, isConsumed } from '../../util/EventUtils';
|
||||
import { clone } from '../../util/CloneUtils';
|
||||
import CellArray from "../cell/datatypes/CellArray";
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
|
||||
/**
|
||||
* @class GraphView
|
||||
|
@ -135,8 +130,7 @@ class GraphView extends EventSource {
|
|||
* being updated. If the resource for this key does not exist then the
|
||||
* value is used as the status message. Default is 'updatingDocument'.
|
||||
*/
|
||||
updatingDocumentResource =
|
||||
mxClient.language !== 'none' ? 'updatingDocument' : '';
|
||||
updatingDocumentResource = mxClient.language !== 'none' ? 'updatingDocument' : '';
|
||||
|
||||
/**
|
||||
* Specifies if string values in cell styles should be evaluated using
|
||||
|
@ -178,7 +172,7 @@ class GraphView extends EventSource {
|
|||
*/
|
||||
translate = new Point();
|
||||
|
||||
states = new Dictionary<CellState>();
|
||||
states = new Dictionary<string, CellState>();
|
||||
|
||||
/**
|
||||
* Specifies if the style should be updated in each validation step. If this
|
||||
|
@ -243,13 +237,7 @@ class GraphView extends EventSource {
|
|||
}
|
||||
}
|
||||
this.fireEvent(
|
||||
new EventObject(
|
||||
InternalEvent.SCALE,
|
||||
'scale',
|
||||
value,
|
||||
'previousScale',
|
||||
previousScale
|
||||
)
|
||||
new EventObject(InternalEvent.SCALE, 'scale', value, 'previousScale', previousScale)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -289,13 +277,10 @@ class GraphView extends EventSource {
|
|||
}
|
||||
|
||||
this.fireEvent(
|
||||
new EventObject(
|
||||
InternalEvent.TRANSLATE,
|
||||
{
|
||||
new EventObject(InternalEvent.TRANSLATE, {
|
||||
translate: this.translate,
|
||||
previousTranslate: previousTranslate,
|
||||
}
|
||||
)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -417,11 +402,7 @@ class GraphView extends EventSource {
|
|||
const previousScale = this.scale;
|
||||
const previousTranslate = new Point(this.translate.x, this.translate.y);
|
||||
|
||||
if (
|
||||
this.scale != scale ||
|
||||
this.translate.x != dx ||
|
||||
this.translate.y != dy
|
||||
) {
|
||||
if (this.scale != scale || this.translate.x != dx || this.translate.y != dy) {
|
||||
this.scale = scale;
|
||||
|
||||
this.translate.x = dx;
|
||||
|
@ -433,15 +414,12 @@ class GraphView extends EventSource {
|
|||
}
|
||||
|
||||
this.fireEvent(
|
||||
new EventObject(
|
||||
InternalEvent.SCALE_AND_TRANSLATE,
|
||||
{
|
||||
new EventObject(InternalEvent.SCALE_AND_TRANSLATE, {
|
||||
scale: scale,
|
||||
previousScale: previousScale,
|
||||
translate: this.translate,
|
||||
previousTranslate: previousTranslate,
|
||||
}
|
||||
)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -559,8 +537,7 @@ class GraphView extends EventSource {
|
|||
validate(cell: Cell | null = null): void {
|
||||
const t0 = mxLog.enter('mxGraphView.validate');
|
||||
window.status =
|
||||
Resources.get(this.updatingDocumentResource) ||
|
||||
this.updatingDocumentResource;
|
||||
Resources.get(this.updatingDocumentResource) || this.updatingDocumentResource;
|
||||
|
||||
this.resetValidationState();
|
||||
|
||||
|
@ -579,9 +556,7 @@ class GraphView extends EventSource {
|
|||
)
|
||||
);
|
||||
|
||||
this.setGraphBounds(
|
||||
graphBounds != null ? graphBounds : this.getEmptyBounds()
|
||||
);
|
||||
this.setGraphBounds(graphBounds != null ? graphBounds : this.getEmptyBounds());
|
||||
this.validateBackground();
|
||||
|
||||
this.resetValidationState();
|
||||
|
@ -595,10 +570,7 @@ class GraphView extends EventSource {
|
|||
* {@link translate} with the size of 0 x 0.
|
||||
*/
|
||||
getEmptyBounds(): Rectangle {
|
||||
return new Rectangle(
|
||||
this.translate.x * this.scale,
|
||||
this.translate.y * this.scale
|
||||
);
|
||||
return new Rectangle(this.translate.x * this.scale, this.translate.y * this.scale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -634,9 +606,7 @@ class GraphView extends EventSource {
|
|||
const childCount = state.cell.getChildCount();
|
||||
|
||||
for (let i = 0; i < childCount; i += 1) {
|
||||
const bounds = this.getBoundingBox(
|
||||
this.getState(state.cell.getChildAt(i))
|
||||
);
|
||||
const bounds = this.getBoundingBox(this.getState(state.cell.getChildAt(i)));
|
||||
|
||||
if (bounds != null) {
|
||||
if (bbox == null) {
|
||||
|
@ -675,10 +645,7 @@ class GraphView extends EventSource {
|
|||
const bg = (<graph>this.graph).getBackgroundImage();
|
||||
|
||||
if (bg != null) {
|
||||
if (
|
||||
this.backgroundImage == null ||
|
||||
this.backgroundImage.image !== bg.src
|
||||
) {
|
||||
if (this.backgroundImage == null || this.backgroundImage.imageSrc !== bg.src) {
|
||||
if (this.backgroundImage != null) {
|
||||
this.backgroundImage.destroy();
|
||||
}
|
||||
|
@ -734,15 +701,15 @@ class GraphView extends EventSource {
|
|||
},
|
||||
(evt: Event) => {
|
||||
// Hides the tooltip if mouse is outside container
|
||||
if (
|
||||
graph.tooltipHandler != null &&
|
||||
graph.tooltipHandler.isHideOnHover()
|
||||
) {
|
||||
if (graph.tooltipHandler != null && graph.tooltipHandler.isHideOnHover()) {
|
||||
graph.tooltipHandler.hide();
|
||||
}
|
||||
|
||||
if (graph.isMouseDown && !isConsumed(evt)) {
|
||||
graph.fireMouseEvent(InternalEvent.MOUSE_MOVE, new InternalMouseEvent(evt));
|
||||
graph.fireMouseEvent(
|
||||
InternalEvent.MOUSE_MOVE,
|
||||
new InternalMouseEvent(evt)
|
||||
);
|
||||
}
|
||||
},
|
||||
(evt: Event) => {
|
||||
|
@ -859,9 +826,7 @@ class GraphView extends EventSource {
|
|||
state.invalid = false;
|
||||
|
||||
if (state.style == null || state.invalidStyle) {
|
||||
state.style = (<graph>this.graph).getCellStyle(
|
||||
<Cell>state.cell
|
||||
);
|
||||
state.style = (<graph>this.graph).getCellStyle(<Cell>state.cell);
|
||||
state.invalidStyle = false;
|
||||
}
|
||||
|
||||
|
@ -871,19 +836,13 @@ class GraphView extends EventSource {
|
|||
|
||||
state.setVisibleTerminalState(
|
||||
<CellState>(
|
||||
this.validateCellState(
|
||||
<Cell>this.getVisibleTerminal(cell, true),
|
||||
false
|
||||
)
|
||||
this.validateCellState(<Cell>this.getVisibleTerminal(cell, true), false)
|
||||
),
|
||||
true
|
||||
);
|
||||
state.setVisibleTerminalState(
|
||||
<CellState>(
|
||||
this.validateCellState(
|
||||
<Cell>this.getVisibleTerminal(cell, false),
|
||||
false
|
||||
)
|
||||
this.validateCellState(<Cell>this.getVisibleTerminal(cell, false), false)
|
||||
),
|
||||
false
|
||||
);
|
||||
|
@ -892,11 +851,7 @@ class GraphView extends EventSource {
|
|||
|
||||
// Repaint happens immediately after the cell is validated
|
||||
if (cell !== this.currentRoot && !state.invalid) {
|
||||
(<graph>this.graph).cellRenderer.redraw(
|
||||
state,
|
||||
false,
|
||||
this.isRendering()
|
||||
);
|
||||
(<graph>this.graph).cellRenderer.redraw(state, false, this.isRendering());
|
||||
|
||||
// Handles changes to invertex paintbounds after update of rendering shape
|
||||
state.updateCachedBounds();
|
||||
|
@ -943,9 +898,7 @@ class GraphView extends EventSource {
|
|||
origin.y += (<Point>pState.origin).y;
|
||||
}
|
||||
|
||||
let offset = (<graph>this.graph).getChildOffsetForCell(
|
||||
<Cell>state.cell
|
||||
);
|
||||
let offset = (<graph>this.graph).getChildOffsetForCell(<Cell>state.cell);
|
||||
|
||||
if (offset != null) {
|
||||
origin.x += offset.x;
|
||||
|
@ -956,9 +909,7 @@ class GraphView extends EventSource {
|
|||
|
||||
if (geo != null) {
|
||||
if (!state.cell.isEdge()) {
|
||||
offset = <Point>(
|
||||
(geo.offset != null ? geo.offset : this.EMPTY_POINT)
|
||||
);
|
||||
offset = <Point>(geo.offset != null ? geo.offset : this.EMPTY_POINT);
|
||||
|
||||
if (geo.relative && pState != null) {
|
||||
if (pState.cell.isEdge()) {
|
||||
|
@ -966,13 +917,9 @@ class GraphView extends EventSource {
|
|||
|
||||
if (origin != null) {
|
||||
origin.x +=
|
||||
origin.x / this.scale -
|
||||
(<Point>pState.origin).x -
|
||||
this.translate.x;
|
||||
origin.x / this.scale - (<Point>pState.origin).x - this.translate.x;
|
||||
origin.y +=
|
||||
origin.y / this.scale -
|
||||
(<Point>pState.origin).y -
|
||||
this.translate.y;
|
||||
origin.y / this.scale - (<Point>pState.origin).y - this.translate.y;
|
||||
}
|
||||
} else {
|
||||
origin.x += geo.x * <number>pState.unscaledWidth + offset.x;
|
||||
|
@ -1056,10 +1003,7 @@ class GraphView extends EventSource {
|
|||
|
||||
if (
|
||||
state.cell !== this.currentRoot &&
|
||||
(pts == null ||
|
||||
pts.length < 2 ||
|
||||
pts[0] == null ||
|
||||
pts[pts.length - 1] == null)
|
||||
(pts == null || pts.length < 2 || pts[0] == null || pts[pts.length - 1] == null)
|
||||
) {
|
||||
// This will remove edges with invalid points from the list of states in the view.
|
||||
// Happens if the one of the terminals and the corresponding terminal point is null.
|
||||
|
@ -1170,11 +1114,7 @@ class GraphView extends EventSource {
|
|||
* @param source {@link mxCellState} which represents the source terminal.
|
||||
* @param target {@link mxCellState} which represents the target terminal.
|
||||
*/
|
||||
updateFixedTerminalPoints(
|
||||
edge: CellState,
|
||||
source: CellState,
|
||||
target: CellState
|
||||
): void {
|
||||
updateFixedTerminalPoints(edge: CellState, source: CellState, target: CellState): void {
|
||||
this.updateFixedTerminalPoint(
|
||||
edge,
|
||||
source,
|
||||
|
@ -1234,11 +1174,7 @@ class GraphView extends EventSource {
|
|||
let pt = null;
|
||||
|
||||
if (constraint != null) {
|
||||
pt = (<graph>this.graph).getConnectionPoint(
|
||||
terminal,
|
||||
constraint,
|
||||
false
|
||||
); // FIXME Rounding introduced bugs when calculating label positions -> , this.graph.isOrthogonal(edge));
|
||||
pt = (<graph>this.graph).getConnectionPoint(terminal, constraint, false); // FIXME Rounding introduced bugs when calculating label positions -> , this.graph.isOrthogonal(edge));
|
||||
}
|
||||
|
||||
if (pt == null && terminal == null) {
|
||||
|
@ -1249,10 +1185,7 @@ class GraphView extends EventSource {
|
|||
pt = geo.getTerminalPoint(source);
|
||||
|
||||
if (pt != null) {
|
||||
pt = new Point(
|
||||
s * (tr.x + pt.x + orig.x),
|
||||
s * (tr.y + pt.y + orig.y)
|
||||
);
|
||||
pt = new Point(s * (tr.x + pt.x + orig.x), s * (tr.y + pt.y + orig.y));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1325,21 +1258,11 @@ class GraphView extends EventSource {
|
|||
|
||||
// Restores previous bounds
|
||||
if (srcBounds != null) {
|
||||
src.setRect(
|
||||
srcBounds.x,
|
||||
srcBounds.y,
|
||||
srcBounds.width,
|
||||
srcBounds.height
|
||||
);
|
||||
src.setRect(srcBounds.x, srcBounds.y, srcBounds.width, srcBounds.height);
|
||||
}
|
||||
|
||||
if (trgBounds != null) {
|
||||
trg.setRect(
|
||||
trgBounds.x,
|
||||
trgBounds.y,
|
||||
trgBounds.width,
|
||||
trgBounds.height
|
||||
);
|
||||
trg.setRect(trgBounds.x, trgBounds.y, trgBounds.width, trgBounds.height);
|
||||
}
|
||||
} else if (points != null) {
|
||||
for (let i = 0; i < points.length; i += 1) {
|
||||
|
@ -1388,16 +1311,8 @@ class GraphView extends EventSource {
|
|||
source: CellState | null = null,
|
||||
target: CellState | null = null
|
||||
): boolean {
|
||||
const sc = (<graph>this.graph).getConnectionConstraint(
|
||||
edge,
|
||||
source,
|
||||
true
|
||||
);
|
||||
const tc = (<graph>this.graph).getConnectionConstraint(
|
||||
edge,
|
||||
target,
|
||||
false
|
||||
);
|
||||
const sc = (<graph>this.graph).getConnectionConstraint(edge, source, true);
|
||||
const tc = (<graph>this.graph).getConnectionConstraint(edge, target, false);
|
||||
|
||||
if (
|
||||
(points == null || points.length < 2) &&
|
||||
|
@ -1516,16 +1431,9 @@ class GraphView extends EventSource {
|
|||
|
||||
let border = parseFloat(edge.style.perimeterSpacing || 0);
|
||||
border += parseFloat(
|
||||
edge.style[
|
||||
source ? 'sourcePerimeterSpacing' : 'targetPerimeterSpacing'
|
||||
] || 0
|
||||
);
|
||||
let pt = this.getPerimeterPoint(
|
||||
start,
|
||||
<Point>next,
|
||||
alpha === 0 && orth,
|
||||
border
|
||||
edge.style[source ? 'sourcePerimeterSpacing' : 'targetPerimeterSpacing'] || 0
|
||||
);
|
||||
let pt = this.getPerimeterPoint(start, <Point>next, alpha === 0 && orth, border);
|
||||
|
||||
if (alpha !== 0) {
|
||||
const cos = Math.cos(alpha);
|
||||
|
@ -1553,10 +1461,7 @@ class GraphView extends EventSource {
|
|||
const id = getValue(state.style, key);
|
||||
|
||||
if (id != null) {
|
||||
const tmp = this.getState(
|
||||
(<graph>this.graph).getModel().getCell(id),
|
||||
false
|
||||
);
|
||||
const tmp = this.getState((<graph>this.graph).getModel().getCell(id), false);
|
||||
|
||||
// Only uses ports where a cell state exists
|
||||
if (tmp != null) {
|
||||
|
@ -1641,8 +1546,7 @@ class GraphView extends EventSource {
|
|||
* Returns the x-coordinate of the center point for automatic routing.
|
||||
*/
|
||||
getRoutingCenterX(state: CellState): number {
|
||||
const f =
|
||||
state.style != null ? parseFloat(state.style.routingCenterX) || 0 : 0;
|
||||
const f = state.style != null ? parseFloat(state.style.routingCenterX) || 0 : 0;
|
||||
return state.getCenterX() + f * state.width;
|
||||
}
|
||||
|
||||
|
@ -1650,8 +1554,7 @@ class GraphView extends EventSource {
|
|||
* Returns the y-coordinate of the center point for automatic routing.
|
||||
*/
|
||||
getRoutingCenterY(state: CellState): number {
|
||||
const f =
|
||||
state.style != null ? parseFloat(state.style.routingCenterY) || 0 : 0;
|
||||
const f = state.style != null ? parseFloat(state.style.routingCenterY) || 0 : 0;
|
||||
return state.getCenterY() + f * state.height;
|
||||
}
|
||||
|
||||
|
@ -1986,8 +1889,7 @@ class GraphView extends EventSource {
|
|||
if (dotprod <= 0.0) {
|
||||
projlenSq = 0;
|
||||
} else {
|
||||
projlenSq =
|
||||
(dotprod * dotprod) / (xSegment * xSegment + ySegment * ySegment);
|
||||
projlenSq = (dotprod * dotprod) / (xSegment * xSegment + ySegment * ySegment);
|
||||
}
|
||||
|
||||
let projlen = Math.sqrt(projlenSq);
|
||||
|
@ -2139,11 +2041,7 @@ class GraphView extends EventSource {
|
|||
* @param cell {@link mxCell} for which a new {@link CellState} should be created.
|
||||
*/
|
||||
createState(cell: Cell): CellState {
|
||||
return new CellState(
|
||||
this,
|
||||
cell,
|
||||
(<graph>this.graph).getCellStyle(cell)
|
||||
);
|
||||
return new CellState(this, cell, (<graph>this.graph).getCellStyle(cell));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2290,9 +2188,7 @@ class GraphView extends EventSource {
|
|||
// Dispatches the drop event to the graph which
|
||||
// consumes and executes the source function
|
||||
const pt = convertPoint(container, x, y);
|
||||
state = (<GraphView>graph.view).getState(
|
||||
graph.getCellAt(pt.x, pt.y)
|
||||
);
|
||||
state = (<GraphView>graph.view).getState(graph.getCellAt(pt.x, pt.y));
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -2312,10 +2208,7 @@ class GraphView extends EventSource {
|
|||
|
||||
this.moveHandler = (evt: Event) => {
|
||||
// Hides the tooltip if mouse is outside container
|
||||
if (
|
||||
graph.tooltipHandler != null &&
|
||||
graph.tooltipHandler.isHideOnHover()
|
||||
) {
|
||||
if (graph.tooltipHandler != null && graph.tooltipHandler.isHideOnHover()) {
|
||||
graph.tooltipHandler.hide();
|
||||
}
|
||||
|
||||
|
@ -2368,26 +2261,17 @@ class GraphView extends EventSource {
|
|||
));
|
||||
|
||||
// For background image
|
||||
this.backgroundPane = document.createElementNS(
|
||||
'http://www.w3.org/2000/svg',
|
||||
'g'
|
||||
);
|
||||
this.backgroundPane = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
canvas.appendChild(this.backgroundPane);
|
||||
|
||||
// Adds two layers (background is early feature)
|
||||
this.drawPane = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
canvas.appendChild(this.drawPane);
|
||||
|
||||
this.overlayPane = document.createElementNS(
|
||||
'http://www.w3.org/2000/svg',
|
||||
'g'
|
||||
);
|
||||
this.overlayPane = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
canvas.appendChild(this.overlayPane);
|
||||
|
||||
this.decoratorPane = document.createElementNS(
|
||||
'http://www.w3.org/2000/svg',
|
||||
'g'
|
||||
);
|
||||
this.decoratorPane = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
canvas.appendChild(this.decoratorPane);
|
||||
|
||||
const root = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
|
|
Loading…
Reference in New Issue