@maxgraph/core
Version:
maxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.
671 lines (670 loc) • 27.6 kB
TypeScript
import Point from './geometry/Point.js';
import Rectangle from './geometry/Rectangle.js';
import EventSource from './event/EventSource.js';
import RectangleShape from './shape/node/RectangleShape.js';
import CellState from './cell/CellState.js';
import ImageShape from './shape/node/ImageShape.js';
import Cell from './cell/Cell.js';
import Image from './image/ImageBox.js';
import Shape from './shape/Shape.js';
import Geometry from './geometry/Geometry.js';
import ConnectionConstraint from './other/ConnectionConstraint.js';
import type { AbstractGraph } from './AbstractGraph.js';
import type { EdgeStyleFunction, MouseEventListener } from '../types.js';
/**
* @class GraphView
* @extends {EventSource}
*
* Extends {@link EventSource} to implement a view for a graph. This class is in
* charge of computing the absolute coordinates for the relative child
* geometries, the points for perimeters and edge styles and keeping them
* cached in {@link CellState}s for faster retrieval. The states are updated
* whenever the model or the view state (translate, scale) changes. The scale
* and translate are honoured in the bounds.
*
* #### Event: mxEvent.UNDO
*
* Fires after the root was changed in {@link setCurrentRoot}. The `edit`
* property contains the {@link UndoableEdit} which contains the
* {@link CurrentRootChange}.
*
* #### Event: mxEvent.SCALE_AND_TRANSLATE
*
* Fires after the scale and translate have been changed in {@link scaleAndTranslate}.
* The `scale`, `previousScale`, `translate`
* and `previousTranslate` properties contain the new and previous
* scale and translate, respectively.
*
* #### Event: mxEvent.SCALE
*
* Fires after the scale was changed in {@link setScale}. The `scale` and
* `previousScale` properties contain the new and previous scale.
*
* #### Event: mxEvent.TRANSLATE
*
* Fires after the translate was changed in {@link setTranslate}. The
* `translate` and `previousTranslate` properties contain
* the new and previous value for translate.
*
* #### Event: mxEvent.DOWN and mxEvent.UP
*
* Fire if the current root is changed by executing an {@link CurrentRootChange}.
* The event name depends on the location of the root in the cell hierarchy
* with respect to the current root. The `root` and
* `previous` properties contain the new and previous root,
* respectively.
*/
export declare class GraphView extends EventSource {
constructor(graph: AbstractGraph);
backgroundImage: ImageShape | null;
backgroundPageShape: Shape | null;
EMPTY_POINT: Point;
canvas: SVGElement | HTMLElement;
backgroundPane: SVGElement | HTMLElement;
drawPane: SVGElement | HTMLElement;
overlayPane: SVGElement | HTMLElement;
decoratorPane: SVGElement | HTMLElement;
/**
* Specifies the resource key for the status message after a long operation.
* If the resource for this key does not exist then the value is used as
* the status message.
* @default 'done'
*/
doneResource: string;
/**
* Specifies the resource key for the status message while the document is
* being updated. If the resource for this key does not exist then the
* value is used as the status message.
* @default 'updatingSelection'
*/
updatingDocumentResource: string;
/**
* Specifies if string values in cell styles should be evaluated using {@link eval}.
*
* This will only be used if the string values can't be mapped to objects using {@link EdgeStyleRegistry} or {@link PerimeterRegistry} when resolving {@link CellStateStyle.edgeStyle} and {@link CellStateStyle.perimeter} respectively.
*
* **WARNING**: Enabling this switch carries a possible security risk.
*
* @default false
*/
allowEval: boolean;
/**
* Specifies if a gesture should be captured when it goes outside of the
* graph container. Default is true.
*/
captureDocumentGesture: boolean;
/**
* Specifies if shapes should be created, updated and destroyed using the
* methods of {@link cellRenderer} in {@link graph}. Default is true.
*/
rendering: boolean;
/**
* Reference to the enclosing {@link AbstractGraph}.
*/
graph: AbstractGraph;
/**
* {@link Cell} that acts as the root of the displayed cell hierarchy.
*/
currentRoot: Cell | null;
graphBounds: Rectangle;
scale: number;
/**
* {@link Point} that specifies the current translation. Default is a new
* empty {@link Point}.
*/
translate: Point;
states: Map<Cell, CellState>;
/**
* Specifies if the style should be updated in each validation step. If this
* is false then the style is only updated if the state is created or if the
* style of the cell was changed. Default is false.
*/
updateStyle: boolean;
/**
* During validation, this contains the last DOM node that was processed.
*/
lastNode: HTMLElement | SVGElement | null;
/**
* During validation, this contains the last HTML DOM node that was processed.
*/
lastHtmlNode: HTMLElement | SVGElement | null;
/**
* During validation, this contains the last edge's DOM node that was processed.
*/
lastForegroundNode: HTMLElement | SVGElement | null;
/**
* During validation, this contains the last edge HTML DOM node that was processed.
*/
lastForegroundHtmlNode: HTMLElement | SVGElement | null;
/**
* Returns {@link graphBounds}.
*/
getGraphBounds(): Rectangle;
/**
* Sets {@link graphBounds}.
*/
setGraphBounds(value: Rectangle): void;
/**
* Returns the {@link scale}.
*/
getScale(): number;
/**
* Sets the scale and fires a {@link scale} event before calling {@link revalidate} followed
* by {@link AbstractGraph.sizeDidChange}.
*
* @param value Decimal value that specifies the new scale (1 is 100%).
*/
setScale(value: number): void;
/**
* Returns the {@link translate}.
*/
getTranslate(): Point;
isRendering(): boolean;
setRendering(value: boolean): void;
/**
* Sets the translation and fires a {@link translate} event before calling
* {@link revalidate} followed by {@link AbstractGraph.sizeDidChange}. The translation is the
* negative of the origin.
*
* @param dx X-coordinate of the translation.
* @param dy Y-coordinate of the translation.
*/
setTranslate(dx: number, dy: number): void;
/**
* Returns {@link allowEval}.
*/
isAllowEval(): boolean;
/**
* Sets {@link allowEval}.
*/
setAllowEval(value: boolean): void;
/**
* Returns {@link states}.
*/
getStates(): Map<Cell, CellState>;
/**
* Sets {@link states}.
*/
setStates(value: Map<Cell, CellState>): void;
/**
* Returns the DOM node that contains the background-, draw-, overlay- and decorator- panes.
*/
getCanvas(): HTMLElement | SVGElement;
/**
* Returns the DOM node that represents the background layer.
*/
getBackgroundPane(): HTMLElement | SVGElement;
/**
* Returns the DOM node that represents the main drawing layer.
*/
getDrawPane(): HTMLElement | SVGElement;
/**
* Returns the DOM node that represents the layer above the drawing layer.
*/
getOverlayPane(): HTMLElement | SVGElement;
/**
* Returns the DOM node that represents the topmost drawing layer.
*/
getDecoratorPane(): HTMLElement | SVGElement;
/**
* Returns the union of all {@link CellState}s for the given array of {@link Cell}.
*
* @param cells Array of {@link Cell} whose bounds should be returned.
*/
getBounds(cells: Cell[]): Rectangle | null;
/**
* Sets and returns the current root and fires an {@link undo} event before
* calling {@link AbstractGraph.sizeDidChange}.
*
* @param root {@link Cell} that specifies the root of the displayed cell hierarchy.
*/
setCurrentRoot(root: Cell | null): Cell | null;
/**
* Sets the scale and translation and fires a {@link scale} and {@link translate} event
* before calling {@link revalidate} followed by {@link AbstractGraph.sizeDidChange}.
*
* @param scale Decimal value that specifies the new scale (1 is 100%).
* @param dx X-coordinate of the translation.
* @param dy Y-coordinate of the translation.
*/
scaleAndTranslate(scale: number, dx: number, dy: number): void;
/**
* Invoked after {@link scale} and/or {@link translate} has changed.
*/
viewStateChanged(): void;
/**
* Clears the view if {@link currentRoot} is not null and revalidates.
*/
refresh(): void;
/**
* Revalidates the complete view with all cell states.
*/
revalidate(): void;
/**
* Removes the state of the given cell and all descendants if the given cell is not the current root.
*
* @param cell Optional {@link Cell} for which the state should be removed. Default is the root of the model.
* @param force Optional boolean indicating if the current root should be ignored for recursion. Default is `false`.
* @param recurse Optional boolean indicating if the descendants should be cleared as well. Default is `true`.
*/
clear(cell?: Cell | null, force?: boolean, recurse?: boolean): void;
/**
* Invalidates the state of the given cell, all its descendants and
* connected edges.
*
* @param cell Optional {@link Cell} to be invalidated. Default is the root of the
* model.
*/
invalidate(cell?: Cell | null, recurse?: boolean, includeEdges?: boolean): void;
/**
* Calls {@link validateCell} and {@link validateCellState} and updates the {@link graphBounds}
* using {@link getBoundingBox}. Finally, the background is validated using
* {@link validateBackground}.
*
* @param cell Optional {@link Cell} to be used as the root of the validation.
* Default is {@link currentRoot} or the root of the model.
*/
validate(cell?: Cell | null): void;
/**
* Returns the bounds for an empty graph. This returns a rectangle at
* {@link translate} with the size of 0 x 0.
*/
getEmptyBounds(): Rectangle;
/**
* Returns the bounding box of the shape and the label for the given
* {@link CellState} and its children if recurse is true.
*
* @param state {@link CellState} whose bounding box should be returned.
* @param recurse Optional boolean indicating if the children should be included.
* Default is true.
*/
getBoundingBox(state?: CellState | null, recurse?: boolean): Rectangle | null;
/**
* Creates and returns the shape used as the background page.
*
* @param bounds {@link Rectangle} that represents the bounds of the shape.
*/
createBackgroundPageShape(bounds: Rectangle): RectangleShape;
/**
* Calls {@link validateBackgroundImage} and {@link validateBackgroundPage}.
*/
validateBackground(): void;
/**
* Validates the background image.
*/
validateBackgroundImage(): void;
/**
* Validates the background page.
*/
validateBackgroundPage(): void;
/**
* Returns the bounds for the background page.
*/
getBackgroundPageBounds(): Rectangle;
/**
* Updates the bounds and redraws the background image.
*
* Example:
*
* If the background image should not be scaled, this can be replaced with
* the following.
*
* @example
* ```javascript
* redrawBackground(backgroundImage, bg)
* {
* backgroundImage.bounds.x = this.translate.x;
* backgroundImage.bounds.y = this.translate.y;
* backgroundImage.bounds.width = bg.width;
* backgroundImage.bounds.height = bg.height;
*
* backgroundImage.redraw();
* };
* ```
*
* @param backgroundImage {@link ImageShape} that represents the background image.
* @param bg {@link Image} that specifies the image and its dimensions.
*/
redrawBackgroundImage(backgroundImage: ImageShape, bg: Image): void;
/**
* Recursively creates the cell state for the given cell if visible is true and
* the given cell is visible. If the cell is not visible but the state exists
* then it is removed using {@link removeState}.
*
* @param cell {@link Cell} whose {@link CellState} should be created.
* @param visible Optional boolean indicating if the cell should be visible. Default
* is true.
*/
validateCell(cell: Cell, visible?: boolean): Cell;
/**
* Validates and repaints the {@link CellState} for the given {@link Cell}.
*
* @param cell {@link Cell} whose {@link CellState} should be validated.
* @param recurse Optional boolean indicating if the children of the cell should be
* validated. Default is true.
*/
validateCellState(cell: Cell | null, recurse?: boolean): CellState | null;
/**
* Updates the given {@link CellState}.
*
* @param state {@link CellState} to be updated.
*/
updateCellState(state: CellState): void;
/**
* Validates the given cell state.
*/
updateVertexState(state: CellState, geo: Geometry): void;
/**
* Validates the given cell state.
*/
updateEdgeState(state: CellState, geo: Geometry): void;
/**
* Updates the absoluteOffset of the given vertex cell state. This takes
* into account the label position styles.
*
* @param state {@link CellState} whose absolute offset should be updated.
*/
updateVertexLabelOffset(state: CellState): void;
/**
* Resets the current validation state.
*/
resetValidationState(): void;
/**
* Invoked when a state has been processed in {@link validatePoints}. This is used
* to update the order of the DOM nodes of the shape.
*
* @param state {@link CellState} that represents the cell state.
*/
stateValidated(state: CellState): void;
/**
* Sets the initial absolute terminal points in the given state before the edge
* style is computed.
*
* @param edge {@link CellState} whose initial terminal points should be updated.
* @param source {@link CellState} which represents the source terminal.
* @param target {@link CellState} which represents the target terminal.
*/
updateFixedTerminalPoints(edge: CellState, source: CellState | null, target: CellState | null): void;
/**
* Sets the fixed source or target terminal point on the given edge.
*
* @param edge {@link CellState} whose terminal point should be updated.
* @param terminal {@link CellState} which represents the actual terminal.
* @param source Boolean that specifies if the terminal is the source.
* @param constraint {@link ConnectionConstraint} that specifies the connection.
*/
updateFixedTerminalPoint(edge: CellState, terminal: CellState | null, source: boolean, constraint: ConnectionConstraint): void;
/**
* Returns the fixed source or target terminal point for the given edge.
*
* @param edge {@link CellState} whose terminal point should be returned.
* @param terminal {@link CellState} which represents the actual terminal.
* @param source Boolean that specifies if the terminal is the source.
* @param constraint {@link ConnectionConstraint} that specifies the connection.
*/
getFixedTerminalPoint(edge: CellState, terminal: CellState | null, source: boolean, constraint: ConnectionConstraint | null): Point | null;
/**
* Updates the bounds of the given cell state to reflect the bounds of the stencil
* if it has a fixed aspect and returns the previous bounds as an {@link Rectangle} if
* the bounds have been modified or null otherwise.
*
* @param state {@link CellState} whose bounds should be updated.
*/
updateBoundsFromStencil(state: CellState | null): Rectangle | null;
/**
* Updates the absolute points in the given state using the specified array
* of {@link Point} as the relative points.
*
* @param edge {@link CellState} whose absolute points should be updated.
* @param points Array of {@link Point} that constitute the relative points.
* @param source {@link CellState} that represents the source terminal.
* @param target {@link CellState} that represents the target terminal.
*/
updatePoints(edge: CellState, points: Point[], source: CellState | null, target: CellState | null): void;
/**
* Transforms the given control point to an absolute point.
*/
transformControlPoint(state: CellState, pt: Point, ignoreScale?: boolean): Point | null;
/**
* Returns `true` if the given edge should be routed with {@link AbstractGraph.defaultLoopStyle}
* or the {@link CellStateStyle.orthogonalLoop} defined for the given edge.
* This implementation returns `true` if the given edge is a loop and does not
*/
isLoopStyleEnabled(edge: CellState, points?: Point[], source?: CellState | null, target?: CellState | null): boolean;
/**
* Returns the edge style function to be used to render the given edge state.
*/
getEdgeStyle(edge: CellState, points?: Point[], source?: CellState | null, target?: CellState | null): EdgeStyleFunction | null;
/**
* Updates the terminal points in the given state after the edge style was
* computed for the edge.
*
* @param state {@link CellState} whose terminal points should be updated.
* @param source {@link CellState} that represents the source terminal.
* @param target {@link CellState} that represents the target terminal.
*/
updateFloatingTerminalPoints(state: CellState, source: CellState | null, target: CellState | null): void;
/**
* Updates the absolute terminal point in the given state for the given
* start and end state, where start is the source if source is true.
*
* @param edge {@link CellState} whose terminal point should be updated.
* @param start {@link CellState} for the terminal on "this" side of the edge.
* @param end {@link CellState} for the terminal on the other side of the edge.
* @param source Boolean indicating if start is the source terminal state.
*/
updateFloatingTerminalPoint(edge: CellState, start: CellState, end: CellState | null, source: boolean): void;
/**
* Returns the floating terminal point for the given edge, start and end
* state, where start is the source if source is true.
*
* @param edge {@link CellState} whose terminal point should be returned.
* @param start {@link CellState} for the terminal on "this" side of the edge.
* @param end {@link CellState} for the terminal on the other side of the edge.
* @param source Boolean indicating if start is the source terminal state.
*/
getFloatingTerminalPoint(edge: CellState, start: CellState, end: CellState | null, source: boolean): Point | null;
/**
* Returns an {@link CellState} that represents the source or target terminal or
* port for the given edge.
*
* @param state {@link CellState} that represents the state of the edge.
* @param terminal {@link CellState} that represents the terminal.
* @param source Boolean indicating if the given terminal is the source terminal.
*/
getTerminalPort(state: CellState, terminal: CellState, source?: boolean): CellState;
/**
* Returns an {@link Point} that defines the location of the intersection point between
* the perimeter and the line between the center of the shape and the given point.
*
* @param terminal {@link CellState} for the source or target terminal.
* @param next {@link Point} that lies outside the given terminal.
* @param orthogonal Boolean that specifies if the orthogonal projection onto
* the perimeter should be returned. If this is false then the intersection
* of the perimeter and the line between the next and the center point is
* returned.
* @param border Optional border between the perimeter and the shape.
*/
getPerimeterPoint(terminal: CellState, next: Point, orthogonal: boolean, border?: number): Point | null;
/**
* Returns the x-coordinate of the center point for automatic routing.
*/
getRoutingCenterX(state: CellState): number;
/**
* Returns the y-coordinate of the center point for automatic routing.
*/
getRoutingCenterY(state: CellState): number;
/**
* Returns the perimeter bounds for the given terminal, edge pair as an
* {@link Rectangle}.
*
* If you have a model where each terminal has a relative child that should
* act as the graphical endpoint for a connection from/to the terminal, then
* this method can be replaced as follows:
*
* @example
* ```javascript
* var oldGetPerimeterBounds = getPerimeterBounds;
* getPerimeterBounds(terminal, edge, isSource)
* {
* var model = this.graph.getDataModel();
* var childCount = model.getChildCount(terminal.cell);
*
* if (childCount > 0)
* {
* var child = model.getChildAt(terminal.cell, 0);
* var geo = model.getGeometry(child);
*
* if (geo != null &&
* geo.relative)
* {
* var state = this.getState(child);
*
* if (state != null)
* {
* terminal = state;
* }
* }
* }
*
* return oldGetPerimeterBounds.apply(this, arguments);
* };
* ```
*
* @param terminal CellState that represents the terminal.
* @param border Number that adds a border between the shape and the perimeter.
*/
getPerimeterBounds(terminal: CellState, border?: number): Rectangle;
/**
* Returns the perimeter function for the given state.
*/
getPerimeterFunction(state: CellState): import("../types.js").PerimeterFunction | null;
/**
* Returns the nearest point in the list of absolute points or the center
* of the opposite terminal.
*
* @param edge {@link CellState} that represents the edge.
* @param opposite {@link CellState} that represents the opposite terminal.
* @param source Boolean indicating if the next point for the source or target
* should be returned.
*/
getNextPoint(edge: CellState, opposite: CellState | null, source?: boolean): Point;
/**
* Returns the nearest ancestor terminal that is visible. The edge appears
* to be connected to this terminal on the display. The result of this method
* is cached in {@link CellState.getVisibleTerminalState}.
*
* @param edge {@link Cell} whose visible terminal should be returned.
* @param source Boolean that specifies if the source or target terminal
* should be returned.
*/
getVisibleTerminal(edge: Cell, source: boolean): Cell | null;
/**
* Updates the given state using the bounding box of the absolute points.
* Also updates {@link CellState.terminalDistance}, {@link CellState.length} and
* {@link CellState.segments}.
*
* @param state {@link CellState} whose bounds should be updated.
*/
updateEdgeBounds(state: CellState): void;
/**
* Returns the absolute point on the edge for the given relative
* {@link Geometry} as an {@link Point}. The edge is represented by the given
* {@link CellState}.
*
* @param state {@link CellState} that represents the state of the parent edge.
* @param geometry {@link Geometry} that represents the relative location.
*/
getPoint(state: CellState, geometry?: Geometry | null): Point;
/**
* Gets the relative point that describes the given, absolute label
* position for the given edge state.
*
* @param edgeState {@link CellState} that represents the state of the parent edge.
* @param x Specifies the x-coordinate of the absolute label location.
* @param y Specifies the y-coordinate of the absolute label location.
*/
getRelativePoint(edgeState: CellState, x: number, y: number): Point;
/**
* Updates {@link CellState.absoluteOffset} for the given state. The absolute
* offset is normally used for the position of the edge label. It is
* calculated from the geometry as an absolute offset from the center
* between the two endpoints if the geometry is absolute, or as the
* relative distance between the center along the line and the absolute
* orthogonal distance if the geometry is relative.
*
* @param state {@link CellState} whose absolute offset should be updated.
*/
updateEdgeLabelOffset(state: CellState): void;
/**
* Returns the {@link CellState} for the given cell. If create is true, then
* the state is created if it does not yet exist.
*
* @param cell {@link Cell} for which the {@link CellState} should be returned.
* @param create Optional boolean indicating if a new state should be created if it does not yet exist. Default is false.
*/
getState(cell: Cell, create?: boolean): CellState | null;
/**
* Returns the {@link CellState}s for the given array of {@link Cell}.
*
* The array contains all states that are not null, that is, the returned array may have fewer elements than the given array.
*
* If no argument is given, then this returns the {@link CellState} of {@link states}.
*/
getCellStates(cells?: Cell[] | null): CellState[];
/**
* Removes and returns the {@link CellState} for the given cell.
*
* @param cell {@link Cell} for which the {@link CellState} should be removed.
*/
removeState(cell: Cell): CellState | null;
/**
* Creates and returns an {@link CellState} for the given cell and initializes
* it using {@link cellRenderer.initialize}.
*
* @param cell {@link Cell} for which a new {@link CellState} should be created.
*/
createState(cell: Cell): CellState;
/**
* Returns true if the event origin is one of the drawing panes or
* containers of the view.
*/
isContainerEvent(evt: MouseEvent): any;
isScrollEvent(evt: MouseEvent | TouchEvent): boolean;
/**
* Initializes the graph event dispatch loop for the specified container
* and invokes {@link create} to create the required DOM nodes for the display.
*/
init(): void;
/**
* Installs the required listeners in the container.
*/
installListeners(): void;
/**
* Creates and returns the DOM nodes for the SVG display.
*/
createSvg(): void;
/**
* Creates the DOM nodes for the HTML display.
*/
createHtml(): void;
/**
* Updates the size of the HTML canvas.
*/
updateHtmlCanvasSize(width: number, height: number): void;
/**
* Creates and returns a drawing pane in HTML (DIV).
*/
createHtmlPane(width: string, height: string): HTMLElement;
/**
* Updates the style of the container after installing the SVG DOM elements.
*/
updateContainerStyle(container: HTMLElement): void;
/**
* Destroys the view and all its resources.
*/
destroy(): void;
endHandler: MouseEventListener | null;
moveHandler: MouseEventListener | null;
}
export default GraphView;