Refactored everything...
parent
4316d4f5e5
commit
bdc50a9f48
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "mxgraph",
|
||||
"name": "maxgraph",
|
||||
"version": "4.2.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
|
|
28
package.json
28
package.json
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
"name": "mxgraph",
|
||||
"description": "mxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.",
|
||||
"version": "4.2.2",
|
||||
"homepage": "https://github.com/jgraph/mxgraph",
|
||||
"name": "maxgraph",
|
||||
"description": "max-graph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.",
|
||||
"version": "1.0.0",
|
||||
"homepage": "https://github.com/maxGraph/maxGraph",
|
||||
"author": {
|
||||
"name": "JGraph Ltd",
|
||||
"email": "support@jgraph.com"
|
||||
"name": "",
|
||||
"email": ""
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jgraph/mxgraph.git"
|
||||
"url": "git+https://github.com/maxGraph/maxGraph"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jgraph/mxgraph/issues"
|
||||
"url": "https://github.com/maxGraph/maxGraph/issues"
|
||||
},
|
||||
"main": "./javascript/dist/build.js",
|
||||
"scripts": {
|
||||
|
@ -23,21 +23,21 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.15",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/preset-env": "^7.13.15",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@lerna/filter-options": "4.0.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"css-loader": "^5.2.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"lerna": "^4.0.0",
|
||||
"@lerna/filter-options": "4.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"typescript": "^4.2.4",
|
||||
"url-loader": "^4.1.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"webpack": "^5.32.0",
|
||||
"webpack-cli": "^4.6.0",
|
||||
"webpack-merge": "^5.7.3",
|
||||
"typescript": "^4.2.4"
|
||||
"webpack-merge": "^5.7.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "@mxgraph/core",
|
||||
"name": "@maxgraph/core",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"module": "src/index.ts",
|
||||
"main": "dist/mxgraph.js",
|
||||
"types": "dist/mxgraph.d.ts",
|
||||
"module": "./src/index.ts",
|
||||
"main": "./dist/maxgraph.js",
|
||||
"types": "./dist/maxgraph.d.ts",
|
||||
"files": [
|
||||
"./dist"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "webpack --watch --mode=development",
|
||||
"build": "NODE_ENV=production webpack --mode=production",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import mxClient from '../mxClient';
|
||||
import mxToolbar from '../util/gui/mxToolbar';
|
||||
import Geometry from '../view/geometry/Geometry';
|
||||
import utils, { convertPoint } from '../util/Utils';
|
||||
import { convertPoint } from '../util/Utils';
|
||||
import InternalEvent from '../view/event/InternalEvent';
|
||||
import { getClientX, getClientY } from '../util/EventUtils';
|
||||
import { makeDraggable } from '../util/GestureUtils';
|
||||
|
@ -265,14 +265,7 @@ class mxDefaultToolbar {
|
|||
InternalEvent.consume(evt);
|
||||
};
|
||||
|
||||
const img = this.toolbar.addMode(
|
||||
title,
|
||||
icon,
|
||||
clickHandler,
|
||||
pressed,
|
||||
null,
|
||||
toggle
|
||||
);
|
||||
const img = this.toolbar.addMode(title, icon, clickHandler, pressed, null, toggle);
|
||||
|
||||
// Creates a wrapper function that calls the click handler without
|
||||
// the graph argument
|
||||
|
@ -307,10 +300,7 @@ class mxDefaultToolbar {
|
|||
!this.connectOnDrop ||
|
||||
!target.isConnectable()
|
||||
) {
|
||||
while (
|
||||
target != null &&
|
||||
!graph.isValidDropTarget(target, [vertex], evt)
|
||||
) {
|
||||
while (target != null && !graph.isValidDropTarget(target, [vertex], evt)) {
|
||||
target = target.getParent();
|
||||
}
|
||||
this.insert(vertex, evt, target);
|
||||
|
@ -337,10 +327,7 @@ class mxDefaultToolbar {
|
|||
const pt = convertPoint(graph.container, x, y);
|
||||
|
||||
// Splits the target edge or inserts into target group
|
||||
if (
|
||||
graph.isSplitEnabled() &&
|
||||
graph.isSplitTarget(target, [vertex], evt)
|
||||
) {
|
||||
if (graph.isSplitEnabled() && graph.isSplitTarget(target, [vertex], evt)) {
|
||||
return graph.splitEdge(target, [vertex], null, pt.x, pt.y);
|
||||
}
|
||||
return this.editor.addVertex(target, vertex, pt.x, pt.y);
|
||||
|
@ -428,7 +415,7 @@ class mxDefaultToolbar {
|
|||
sprite.setAttribute('src', img.getAttribute('src'));
|
||||
|
||||
// Handles delayed loading of the images
|
||||
const loader = evt => {
|
||||
const loader = (evt) => {
|
||||
// Preview uses the image node with double size. Later this can be
|
||||
// changed to use a separate preview and guides, but for this the
|
||||
// dropHandler must use the additional x- and y-arguments and the
|
||||
|
|
|
@ -1,348 +1,211 @@
|
|||
import mxClient from './mxClient';
|
||||
/* Graph mixins */
|
||||
import './view/ports/GraphPortsMixin';
|
||||
import './view/panning/GraphPanningMixin';
|
||||
import './view/zoom/GraphZoomMixin';
|
||||
import './view/event/GraphEventsMixin';
|
||||
import './view/image/GraphImageMixin';
|
||||
import './view/cell/GraphCellsMixin';
|
||||
import './view/selection/GraphSelectionMixin';
|
||||
import './view/connection/GraphConnectionsMixin';
|
||||
import './view/cell/edge/GraphEdgeMixin';
|
||||
import './view/cell/vertex/GraphVertexMixin';
|
||||
import './view/layout/GraphOverlaysMixin';
|
||||
import './view/editing/GraphEditingMixin';
|
||||
import './view/folding/GraphFoldingMixin';
|
||||
import './view/label/GraphLabelMixin';
|
||||
import './view/validation/GraphValidationMixin';
|
||||
import './view/snap/GraphSnapMixin';
|
||||
import './view/tooltip/GraphTooltipMixin';
|
||||
import './view/terminal/GraphTerminalMixin';
|
||||
import './view/drag_drop/GraphDragDropMixin';
|
||||
import './view/swimlane/GraphSwimlaneMixin';
|
||||
import './view/page_breaks/GraphPageBreaksMixin';
|
||||
import './view/grouping_ordering/GraphGroupingMixin';
|
||||
import './view/grouping_ordering/GraphOrderMixin';
|
||||
|
||||
import CellAttributeChange from './view/cell/CellAttributeChange';
|
||||
import ChildChange from './view/model/ChildChange';
|
||||
import CollapseChange from './view/folding/CollapseChange';
|
||||
import CurrentRootChange from './view/view/CurrentRootChange';
|
||||
import GeometryChange from './view/geometry/GeometryChange';
|
||||
import RootChange from './view/model/RootChange';
|
||||
import SelectionChange from './view/selection/SelectionChange';
|
||||
import StyleChange from './view/style/StyleChange';
|
||||
import TerminalChange from './view/cell/edge/TerminalChange';
|
||||
import ValueChange from './view/cell/ValueChange';
|
||||
import VisibleChange from './view/style/VisibleChange';
|
||||
export { Graph } from './view/Graph';
|
||||
|
||||
import mxDefaultKeyHandler from './editor/mxDefaultKeyHandler';
|
||||
import mxDefaultPopupMenu from './editor/mxDefaultPopupMenu';
|
||||
import mxDefaultToolbar from './editor/mxDefaultToolbar';
|
||||
import mxEditor from './editor/mxEditor';
|
||||
export { default as Model } from './view/model/Model';
|
||||
export { default as GraphView } from './view/view/GraphView';
|
||||
export { default as LayoutManager } from './view/layout/LayoutManager';
|
||||
export { default as Outline } from './view/Outline';
|
||||
export { default as PrintPreview } from './view/printing/PrintPreview';
|
||||
export { default as SwimlaneManager } from './view/layout/SwimlaneManager';
|
||||
export { default as mxClient } from './mxClient';
|
||||
|
||||
import CellHighlight from './view/selection/CellHighlight';
|
||||
import CellMarker from './view/cell/CellMarker';
|
||||
import CellTracker from './view/event/CellTracker';
|
||||
import ConnectionHandler from './view/connection/ConnectionHandler';
|
||||
import ConstraintHandler from './view/connection/ConstraintHandler';
|
||||
import EdgeHandler from './view/cell/edge/EdgeHandler';
|
||||
import EdgeSegmentHandler from './view/cell/edge/EdgeSegmentHandler';
|
||||
import ElbowEdgeHandler from './view/cell/edge/ElbowEdgeHandler';
|
||||
import GraphHandler from './view/GraphHandler';
|
||||
import VertexHandle from './view/cell/vertex/VertexHandle';
|
||||
import mxKeyHandler from './view/event/mxKeyHandler';
|
||||
import PanningHandler from './view/panning/PanningHandler';
|
||||
import PopupMenuHandler from './view/popups_menus/PopupMenuHandler';
|
||||
import RubberBand from './view/selection/RubberBand';
|
||||
import SelectionCellsHandler from './view/selection/SelectionCellsHandler';
|
||||
import TooltipHandler from './view/tooltip/TooltipHandler';
|
||||
import VertexHandler from './view/cell/vertex/VertexHandler';
|
||||
export { default as CellAttributeChange } from './view/cell/CellAttributeChange';
|
||||
export { default as ChildChange } from './view/model/ChildChange';
|
||||
export { default as CollapseChange } from './view/folding/CollapseChange';
|
||||
export { default as CurrentRootChange } from './view/view/CurrentRootChange';
|
||||
export { default as GeometryChange } from './view/geometry/GeometryChange';
|
||||
export { default as RootChange } from './view/model/RootChange';
|
||||
export { default as SelectionChange } from './view/selection/SelectionChange';
|
||||
export { default as StyleChange } from './view/style/StyleChange';
|
||||
export { default as TerminalChange } from './view/cell/edge/TerminalChange';
|
||||
export { default as ValueChange } from './view/cell/ValueChange';
|
||||
export { default as VisibleChange } from './view/style/VisibleChange';
|
||||
|
||||
import CircleLayout from './view/layout/layout/CircleLayout';
|
||||
import CompactTreeLayout from './view/layout/layout/CompactTreeLayout';
|
||||
import CompositeLayout from './view/layout/layout/CompositeLayout';
|
||||
import EdgeLabelLayout from './view/layout/layout/EdgeLabelLayout';
|
||||
import MxFastOrganicLayout from './view/layout/layout/FastOrganicLayout';
|
||||
import GraphLayout from './view/layout/layout/GraphLayout';
|
||||
import ParallelEdgeLayout from './view/layout/layout/ParallelEdgeLayout';
|
||||
import PartitionLayout from './view/layout/layout/PartitionLayout';
|
||||
import RadialTreeLayout from './view/layout/layout/RadialTreeLayout';
|
||||
import StackLayout from './view/layout/layout/StackLayout';
|
||||
export { default as mxDefaultKeyHandler } from './editor/mxDefaultKeyHandler';
|
||||
export { default as mxDefaultPopupMenu } from './editor/mxDefaultPopupMenu';
|
||||
export { default as mxDefaultToolbar } from './editor/mxDefaultToolbar';
|
||||
export { default as mxEditor } from './editor/mxEditor';
|
||||
|
||||
import HierarchicalEdgeStyle from './view/layout/layout/hierarchical/HierarchicalEdgeStyle';
|
||||
import mxHierarchicalLayout from './view/layout/layout/hierarchical/mxHierarchicalLayout';
|
||||
import SwimlaneLayout from './view/layout/layout/hierarchical/SwimlaneLayout';
|
||||
export { default as CellHighlight } from './view/selection/CellHighlight';
|
||||
export { default as CellMarker } from './view/cell/CellMarker';
|
||||
export { default as CellTracker } from './view/event/CellTracker';
|
||||
export { default as ConnectionHandler } from './view/connection/ConnectionHandler';
|
||||
export { default as ConstraintHandler } from './view/connection/ConstraintHandler';
|
||||
export { default as EdgeHandler } from './view/cell/edge/EdgeHandler';
|
||||
export { default as EdgeSegmentHandler } from './view/cell/edge/EdgeSegmentHandler';
|
||||
export { default as ElbowEdgeHandler } from './view/cell/edge/ElbowEdgeHandler';
|
||||
export { default as GraphHandler } from './view/GraphHandler';
|
||||
export { default as VertexHandle } from './view/cell/vertex/VertexHandle';
|
||||
export { default as mxKeyHandler } from './view/event/mxKeyHandler';
|
||||
export { default as PanningHandler } from './view/panning/PanningHandler';
|
||||
export { default as PopupMenuHandler } from './view/popups_menus/PopupMenuHandler';
|
||||
export { default as RubberBand } from './view/selection/RubberBand';
|
||||
export { default as SelectionCellsHandler } from './view/selection/SelectionCellsHandler';
|
||||
export { default as TooltipHandler } from './view/tooltip/TooltipHandler';
|
||||
export { default as VertexHandler } from './view/cell/vertex/VertexHandler';
|
||||
|
||||
import MxGraphAbstractHierarchyCell from './view/layout/layout/hierarchical/model/GraphAbstractHierarchyCell';
|
||||
import GraphHierarchyEdge from './view/layout/layout/hierarchical/model/GraphHierarchyEdge';
|
||||
import GraphHierarchyModel from './view/layout/layout/hierarchical/model/GraphHierarchyModel';
|
||||
import GraphHierarchyNode from './view/layout/layout/hierarchical/model/GraphHierarchyNode';
|
||||
import SwimlaneModel from './view/layout/layout/hierarchical/model/SwimlaneModel';
|
||||
export { default as CircleLayout } from './view/layout/layout/CircleLayout';
|
||||
export { default as CompactTreeLayout } from './view/layout/layout/CompactTreeLayout';
|
||||
export { default as CompositeLayout } from './view/layout/layout/CompositeLayout';
|
||||
export { default as EdgeLabelLayout } from './view/layout/layout/EdgeLabelLayout';
|
||||
export { default as MxFastOrganicLayout } from './view/layout/layout/FastOrganicLayout';
|
||||
export { default as GraphLayout } from './view/layout/layout/GraphLayout';
|
||||
export { default as ParallelEdgeLayout } from './view/layout/layout/ParallelEdgeLayout';
|
||||
export { default as PartitionLayout } from './view/layout/layout/PartitionLayout';
|
||||
export { default as RadialTreeLayout } from './view/layout/layout/RadialTreeLayout';
|
||||
export { default as StackLayout } from './view/layout/layout/StackLayout';
|
||||
|
||||
import CoordinateAssignment from './view/layout/layout/hierarchical/stage/CoordinateAssignment';
|
||||
import MxHierarchicalLayoutStage from './view/layout/layout/hierarchical/stage/HierarchicalLayoutStage';
|
||||
import MedianHybridCrossingReduction from './view/layout/layout/hierarchical/stage/MedianHybridCrossingReduction';
|
||||
import MinimumCycleRemover from './view/layout/layout/hierarchical/stage/MinimumCycleRemover';
|
||||
import mxSwimlaneOrdering from './view/layout/layout/hierarchical/stage/mxSwimlaneOrdering';
|
||||
export { default as HierarchicalEdgeStyle } from './view/layout/layout/hierarchical/HierarchicalEdgeStyle';
|
||||
export { default as mxHierarchicalLayout } from './view/layout/layout/hierarchical/mxHierarchicalLayout';
|
||||
export { default as SwimlaneLayout } from './view/layout/layout/hierarchical/SwimlaneLayout';
|
||||
|
||||
import mxCellCodec from './util/serialization/mxCellCodec';
|
||||
import mxChildChangeCodec from './util/serialization/mxChildChangeCodec';
|
||||
import mxCodec from './util/serialization/mxCodec';
|
||||
import mxCodecRegistry from './util/serialization/mxCodecRegistry';
|
||||
import mxDefaultKeyHandlerCodec from './util/serialization/mxDefaultKeyHandlerCodec';
|
||||
import mxDefaultPopupMenuCodec from './util/serialization/mxDefaultPopupMenuCodec';
|
||||
import mxDefaultToolbarCodec from './util/serialization/mxDefaultToolbarCodec';
|
||||
import mxEditorCodec from './util/serialization/mxEditorCodec';
|
||||
import mxGenericChangeCodec from './util/serialization/mxGenericChangeCodec';
|
||||
import mxGraphCodec from './util/serialization/mxGraphCodec';
|
||||
import mxGraphViewCodec from './util/serialization/mxGraphViewCodec';
|
||||
import mxModelCodec from './util/serialization/mxModelCodec';
|
||||
import mxObjectCodec from './util/serialization/mxObjectCodec';
|
||||
import mxRootChangeCodec from './util/serialization/mxRootChangeCodec';
|
||||
import mxStylesheetCodec from './util/serialization/mxStylesheetCodec';
|
||||
import mxTerminalChangeCodec from './util/serialization/mxTerminalChangeCodec';
|
||||
export { default as MxGraphAbstractHierarchyCell } from './view/layout/layout/hierarchical/model/GraphAbstractHierarchyCell';
|
||||
export { default as GraphHierarchyEdge } from './view/layout/layout/hierarchical/model/GraphHierarchyEdge';
|
||||
export { default as GraphHierarchyModel } from './view/layout/layout/hierarchical/model/GraphHierarchyModel';
|
||||
export { default as GraphHierarchyNode } from './view/layout/layout/hierarchical/model/GraphHierarchyNode';
|
||||
export { default as SwimlaneModel } from './view/layout/layout/hierarchical/model/SwimlaneModel';
|
||||
|
||||
import Actor from './view/geometry/shape/Actor';
|
||||
import Label from './view/geometry/shape/node/LabelShape';
|
||||
import Shape from './view/geometry/shape/Shape';
|
||||
import SwimlaneShape from './view/geometry/shape/node/SwimlaneShape';
|
||||
import TextShape from './view/geometry/shape/node/TextShape';
|
||||
import TriangleShape from './view/geometry/shape/node/TriangleShape';
|
||||
export { default as CoordinateAssignment } from './view/layout/layout/hierarchical/stage/CoordinateAssignment';
|
||||
export { default as MxHierarchicalLayoutStage } from './view/layout/layout/hierarchical/stage/HierarchicalLayoutStage';
|
||||
export { default as MedianHybridCrossingReduction } from './view/layout/layout/hierarchical/stage/MedianHybridCrossingReduction';
|
||||
export { default as MinimumCycleRemover } from './view/layout/layout/hierarchical/stage/MinimumCycleRemover';
|
||||
export { default as mxSwimlaneOrdering } from './view/layout/layout/hierarchical/stage/mxSwimlaneOrdering';
|
||||
|
||||
import Arrow from './view/geometry/shape/edge/Arrow';
|
||||
import ArrowConnector from './view/geometry/shape/edge/ArrowConnector';
|
||||
import Connector from './view/geometry/shape/edge/Connector';
|
||||
import Line from './view/geometry/shape/edge/Line';
|
||||
import Marker from './view/geometry/shape/edge/Marker';
|
||||
import Polyline from './view/geometry/shape/edge/Polyline';
|
||||
export { default as mxCellCodec } from './util/serialization/mxCellCodec';
|
||||
export { default as mxChildChangeCodec } from './util/serialization/mxChildChangeCodec';
|
||||
export { default as mxCodec } from './util/serialization/mxCodec';
|
||||
export { default as mxCodecRegistry } from './util/serialization/mxCodecRegistry';
|
||||
export { default as mxDefaultKeyHandlerCodec } from './util/serialization/mxDefaultKeyHandlerCodec';
|
||||
export { default as mxDefaultPopupMenuCodec } from './util/serialization/mxDefaultPopupMenuCodec';
|
||||
export { default as mxDefaultToolbarCodec } from './util/serialization/mxDefaultToolbarCodec';
|
||||
export { default as mxEditorCodec } from './util/serialization/mxEditorCodec';
|
||||
export { default as mxGenericChangeCodec } from './util/serialization/mxGenericChangeCodec';
|
||||
export { default as mxGraphCodec } from './util/serialization/mxGraphCodec';
|
||||
export { default as mxGraphViewCodec } from './util/serialization/mxGraphViewCodec';
|
||||
export { default as mxModelCodec } from './util/serialization/mxModelCodec';
|
||||
export { default as mxObjectCodec } from './util/serialization/mxObjectCodec';
|
||||
export { default as mxRootChangeCodec } from './util/serialization/mxRootChangeCodec';
|
||||
export { default as mxStylesheetCodec } from './util/serialization/mxStylesheetCodec';
|
||||
export { default as mxTerminalChangeCodec } from './util/serialization/mxTerminalChangeCodec';
|
||||
|
||||
import CloudShape from './view/geometry/shape/node/CloudShape';
|
||||
import CylinderShape from './view/geometry/shape/node/CylinderShape';
|
||||
import DoubleEllipseShape from './view/geometry/shape/node/DoubleEllipseShape';
|
||||
import EllipseShape from './view/geometry/shape/node/EllipseShape';
|
||||
import HexagonShape from './view/geometry/shape/node/HexagonShape';
|
||||
import ImageShape from './view/geometry/shape/node/ImageShape';
|
||||
import RectangleShape from './view/geometry/shape/node/RectangleShape';
|
||||
import RhombusShape from './view/geometry/shape/node/RhombusShape';
|
||||
import StencilShape from './view/geometry/shape/node/StencilShape';
|
||||
import StencilShapeRegistry from './view/geometry/shape/node/StencilShapeRegistry';
|
||||
export { default as Actor } from './view/geometry/shape/Actor';
|
||||
export { default as Label } from './view/geometry/shape/node/LabelShape';
|
||||
export { default as Shape } from './view/geometry/shape/Shape';
|
||||
export { default as SwimlaneShape } from './view/geometry/shape/node/SwimlaneShape';
|
||||
export { default as TextShape } from './view/geometry/shape/node/TextShape';
|
||||
export { default as TriangleShape } from './view/geometry/shape/node/TriangleShape';
|
||||
|
||||
import * as Constants from './util/Constants';
|
||||
import Guide from './util/Guide';
|
||||
import Resources from './util/Resources';
|
||||
import utils from './util/Utils';
|
||||
import * as CloneUtils from './util/CloneUtils';
|
||||
import * as DomUtils from './util/DomUtils';
|
||||
import * as EventUtils from './util/EventUtils';
|
||||
import * as GestureUtils from './util/GestureUtils';
|
||||
import * as StringUtils from './util/StringUtils';
|
||||
import * as XmlUtils from './util/XmlUtils';
|
||||
export { default as Arrow } from './view/geometry/shape/edge/Arrow';
|
||||
export { default as ArrowConnector } from './view/geometry/shape/edge/ArrowConnector';
|
||||
export { default as Connector } from './view/geometry/shape/edge/Connector';
|
||||
export { default as Line } from './view/geometry/shape/edge/Line';
|
||||
export { default as Marker } from './view/geometry/shape/edge/Marker';
|
||||
export { default as Polyline } from './view/geometry/shape/edge/Polyline';
|
||||
|
||||
import mxAnimation from './util/animate/mxAnimation';
|
||||
import mxEffects from './util/animate/mxEffects';
|
||||
import mxMorphing from './util/animate/mxMorphing';
|
||||
export { default as CloudShape } from './view/geometry/shape/node/CloudShape';
|
||||
export { default as CylinderShape } from './view/geometry/shape/node/CylinderShape';
|
||||
export { default as DoubleEllipseShape } from './view/geometry/shape/node/DoubleEllipseShape';
|
||||
export { default as EllipseShape } from './view/geometry/shape/node/EllipseShape';
|
||||
export { default as HexagonShape } from './view/geometry/shape/node/HexagonShape';
|
||||
export { default as ImageShape } from './view/geometry/shape/node/ImageShape';
|
||||
export { default as RectangleShape } from './view/geometry/shape/node/RectangleShape';
|
||||
export { default as RhombusShape } from './view/geometry/shape/node/RhombusShape';
|
||||
export { default as StencilShape } from './view/geometry/shape/node/StencilShape';
|
||||
export { default as StencilShapeRegistry } from './view/geometry/shape/node/StencilShapeRegistry';
|
||||
|
||||
import AbstractCanvas2D from './util/canvas/AbstractCanvas2D';
|
||||
import SvgCanvas2D from './util/canvas/SvgCanvas2D';
|
||||
import mxXmlCanvas2D from './util/canvas/mxXmlCanvas2D';
|
||||
export * as Constants from './util/Constants';
|
||||
export { default as Guide } from './util/Guide';
|
||||
export { default as Resources } from './util/Resources';
|
||||
export * as utils from './util/Utils';
|
||||
export * as CloneUtils from './util/CloneUtils';
|
||||
export * as DomUtils from './util/DomUtils';
|
||||
export * as EventUtils from './util/EventUtils';
|
||||
export * as GestureUtils from './util/GestureUtils';
|
||||
export * as StringUtils from './util/StringUtils';
|
||||
export * as XmlUtils from './util/XmlUtils';
|
||||
|
||||
import Dictionary from './util/Dictionary';
|
||||
import Geometry from './view/geometry/Geometry';
|
||||
import ObjectIdentity from './util/ObjectIdentity';
|
||||
import Point from './view/geometry/Point';
|
||||
import Rectangle from './view/geometry/Rectangle';
|
||||
export { default as mxAnimation } from './util/animate/mxAnimation';
|
||||
export { default as mxEffects } from './util/animate/mxEffects';
|
||||
export { default as mxMorphing } from './util/animate/mxMorphing';
|
||||
|
||||
import EdgeStyle from './view/style/EdgeStyle';
|
||||
import Perimeter from './view/style/Perimeter';
|
||||
import StyleRegistry from './view/style/StyleRegistry';
|
||||
import Stylesheet from './view/style/Stylesheet';
|
||||
export { default as AbstractCanvas2D } from './util/canvas/AbstractCanvas2D';
|
||||
export { default as SvgCanvas2D } from './util/canvas/SvgCanvas2D';
|
||||
export { default as mxXmlCanvas2D } from './util/canvas/mxXmlCanvas2D';
|
||||
|
||||
import mxDivResizer from './util/dom/mxDivResizer';
|
||||
import * as mxDomHelpers from './util/dom/mxDomHelpers';
|
||||
export { default as Dictionary } from './util/Dictionary';
|
||||
export { default as Geometry } from './view/geometry/Geometry';
|
||||
export { default as ObjectIdentity } from './util/ObjectIdentity';
|
||||
export { default as Point } from './view/geometry/Point';
|
||||
export { default as Rectangle } from './view/geometry/Rectangle';
|
||||
|
||||
import DragSource from './view/drag_drop/DragSource';
|
||||
import PanningManager from './view/panning/PanningManager';
|
||||
export { default as EdgeStyle } from './view/style/EdgeStyle';
|
||||
export { default as Perimeter } from './view/style/Perimeter';
|
||||
export { default as StyleRegistry } from './view/style/StyleRegistry';
|
||||
export { default as Stylesheet } from './view/style/Stylesheet';
|
||||
|
||||
import InternalEvent from './view/event/InternalEvent';
|
||||
import EventObject from './view/event/EventObject';
|
||||
import EventSource from './view/event/EventSource';
|
||||
import InternalMouseEvent from './view/event/InternalMouseEvent';
|
||||
export { default as mxDivResizer } from './util/dom/mxDivResizer';
|
||||
export * as mxDomHelpers from './util/dom/mxDomHelpers';
|
||||
|
||||
import mxForm from './util/gui/mxForm';
|
||||
import mxLog from './util/gui/mxLog';
|
||||
import PopupMenu from './util/gui/PopupMenu';
|
||||
import mxToolbar from './util/gui/mxToolbar';
|
||||
import mxWindow from './util/gui/mxWindow';
|
||||
export { default as DragSource } from './view/drag_drop/DragSource';
|
||||
export { default as PanningManager } from './view/panning/PanningManager';
|
||||
|
||||
import ImageBox from './view/image/ImageBox';
|
||||
import ImageBundle from './view/image/ImageBundle';
|
||||
import ImageExport from './view/image/ImageExport';
|
||||
export { default as InternalEvent } from './view/event/InternalEvent';
|
||||
export { default as EventObject } from './view/event/EventObject';
|
||||
export { default as EventSource } from './view/event/EventSource';
|
||||
export { default as InternalMouseEvent } from './view/event/InternalMouseEvent';
|
||||
|
||||
import mxUrlConverter from './util/network/mxUrlConverter';
|
||||
import mxXmlRequest from './util/network/mxXmlRequest';
|
||||
export { default as mxForm } from './util/gui/mxForm';
|
||||
export { default as mxLog } from './util/gui/mxLog';
|
||||
export { default as PopupMenu } from './util/gui/PopupMenu';
|
||||
export { default as mxToolbar } from './util/gui/mxToolbar';
|
||||
export { default as mxWindow } from './util/gui/mxWindow';
|
||||
|
||||
import mxAutoSaveManager from './util/storage/mxAutoSaveManager';
|
||||
import Clipboard from './util/storage/Clipboard';
|
||||
export { default as ImageBox } from './view/image/ImageBox';
|
||||
export { default as ImageBundle } from './view/image/ImageBundle';
|
||||
export { default as ImageExport } from './view/image/ImageExport';
|
||||
|
||||
import UndoableEdit from './view/model/UndoableEdit';
|
||||
import mxUndoManager from './util/mxUndoManager';
|
||||
export { default as mxUrlConverter } from './util/network/mxUrlConverter';
|
||||
export { default as mxXmlRequest } from './util/network/mxXmlRequest';
|
||||
|
||||
import Cell from './view/cell/datatypes/Cell';
|
||||
import CellEditor from './view/editing/CellEditor';
|
||||
import CellOverlay from './view/cell/CellOverlay';
|
||||
import CellPath from './view/cell/datatypes/CellPath';
|
||||
import CellRenderer from './view/cell/CellRenderer';
|
||||
import CellState from './view/cell/datatypes/CellState';
|
||||
import CellStatePreview from './view/cell/CellStatePreview';
|
||||
import TemporaryCellStates from './view/cell/TemporaryCellStates';
|
||||
export { default as mxAutoSaveManager } from './util/storage/mxAutoSaveManager';
|
||||
export { default as Clipboard } from './util/storage/Clipboard';
|
||||
|
||||
import ConnectionConstraint from './view/connection/ConnectionConstraint';
|
||||
import Multiplicity from './view/validation/Multiplicity';
|
||||
export { default as UndoableEdit } from './view/model/UndoableEdit';
|
||||
export { default as mxUndoManager } from './util/mxUndoManager';
|
||||
|
||||
import Graph from './view/Graph';
|
||||
import Model from './view/model/Model';
|
||||
import GraphView from './view/view/GraphView';
|
||||
import LayoutManager from './view/layout/LayoutManager';
|
||||
import Outline from './view/Outline';
|
||||
import PrintPreview from './view/printing/PrintPreview';
|
||||
import SwimlaneManager from './view/layout/SwimlaneManager';
|
||||
export { default as Cell } from './view/cell/datatypes/Cell';
|
||||
export { default as CellEditor } from './view/editing/CellEditor';
|
||||
export { default as CellOverlay } from './view/cell/CellOverlay';
|
||||
export { default as CellPath } from './view/cell/datatypes/CellPath';
|
||||
export { default as CellRenderer } from './view/cell/CellRenderer';
|
||||
export { default as CellState } from './view/cell/datatypes/CellState';
|
||||
export { default as CellStatePreview } from './view/cell/CellStatePreview';
|
||||
export { default as TemporaryCellStates } from './view/cell/TemporaryCellStates';
|
||||
export { default as ConnectionConstraint } from './view/connection/ConnectionConstraint';
|
||||
export { default as Multiplicity } from './view/validation/Multiplicity';
|
||||
|
||||
import '../css/common.css';
|
||||
|
||||
export default {
|
||||
mxClient,
|
||||
mxLog,
|
||||
ObjectIdentity,
|
||||
Dictionary,
|
||||
Resources,
|
||||
Point,
|
||||
Rectangle,
|
||||
mxEffects,
|
||||
utils,
|
||||
Constants,
|
||||
EventObject,
|
||||
InternalMouseEvent,
|
||||
EventSource,
|
||||
InternalEvent,
|
||||
mxXmlRequest,
|
||||
Clipboard,
|
||||
mxWindow,
|
||||
mxForm,
|
||||
Image,
|
||||
mxDivResizer,
|
||||
DragSource,
|
||||
mxToolbar,
|
||||
UndoableEdit,
|
||||
mxUndoManager,
|
||||
mxUrlConverter,
|
||||
PanningManager,
|
||||
PopupMenu,
|
||||
mxAutoSaveManager,
|
||||
mxAnimation,
|
||||
mxMorphing,
|
||||
ImageBox,
|
||||
ImageBundle,
|
||||
ImageExport,
|
||||
AbstractCanvas2D,
|
||||
mxXmlCanvas2D,
|
||||
SvgCanvas2D,
|
||||
Guide,
|
||||
Shape,
|
||||
StencilShape,
|
||||
StencilShapeRegistry,
|
||||
Marker,
|
||||
Actor,
|
||||
CloudShape,
|
||||
RectangleShape,
|
||||
EllipseShape,
|
||||
DoubleEllipseShape,
|
||||
RhombusShape,
|
||||
Polyline,
|
||||
Arrow,
|
||||
ArrowConnector,
|
||||
TextShape,
|
||||
TriangleShape,
|
||||
HexagonShape,
|
||||
Line,
|
||||
ImageShape,
|
||||
Label,
|
||||
CylinderShape,
|
||||
Connector,
|
||||
SwimlaneShape,
|
||||
GraphLayout,
|
||||
StackLayout,
|
||||
PartitionLayout,
|
||||
CompactTreeLayout,
|
||||
RadialTreeLayout,
|
||||
MxFastOrganicLayout,
|
||||
CircleLayout,
|
||||
ParallelEdgeLayout,
|
||||
CompositeLayout,
|
||||
EdgeLabelLayout,
|
||||
MxGraphAbstractHierarchyCell,
|
||||
GraphHierarchyNode,
|
||||
GraphHierarchyEdge,
|
||||
GraphHierarchyModel,
|
||||
SwimlaneModel,
|
||||
MxHierarchicalLayoutStage,
|
||||
MedianHybridCrossingReduction,
|
||||
MinimumCycleRemover,
|
||||
CoordinateAssignment,
|
||||
mxSwimlaneOrdering,
|
||||
mxHierarchicalLayout,
|
||||
SwimlaneLayout,
|
||||
Model,
|
||||
Cell,
|
||||
Geometry,
|
||||
CellPath,
|
||||
Perimeter,
|
||||
PrintPreview,
|
||||
Stylesheet,
|
||||
CellState,
|
||||
CellEditor,
|
||||
CellRenderer,
|
||||
EdgeStyle,
|
||||
StyleRegistry,
|
||||
GraphView,
|
||||
Graph,
|
||||
CellOverlay,
|
||||
Outline,
|
||||
Multiplicity,
|
||||
LayoutManager,
|
||||
SwimlaneManager,
|
||||
TemporaryCellStates,
|
||||
CellStatePreview,
|
||||
ConnectionConstraint,
|
||||
GraphHandler,
|
||||
PanningHandler,
|
||||
PopupMenuHandler,
|
||||
CellMarker,
|
||||
SelectionCellsHandler,
|
||||
ConnectionHandler,
|
||||
ConstraintHandler,
|
||||
RubberBand,
|
||||
VertexHandle,
|
||||
VertexHandler,
|
||||
EdgeHandler,
|
||||
ElbowEdgeHandler,
|
||||
EdgeSegmentHandler,
|
||||
mxKeyHandler,
|
||||
TooltipHandler,
|
||||
CellTracker,
|
||||
CellHighlight,
|
||||
mxDefaultKeyHandler,
|
||||
mxDefaultPopupMenu,
|
||||
mxDefaultToolbar,
|
||||
mxEditor,
|
||||
mxCodecRegistry,
|
||||
mxCodec,
|
||||
mxObjectCodec,
|
||||
mxCellCodec,
|
||||
mxModelCodec,
|
||||
mxRootChangeCodec,
|
||||
mxChildChangeCodec,
|
||||
mxTerminalChangeCodec,
|
||||
mxGenericChangeCodec,
|
||||
// mxGraphCodec,
|
||||
// mxGraphViewCodec,
|
||||
// mxStylesheetCodec,
|
||||
// mxDefaultKeyHandlerCodec,
|
||||
// mxDefaultToolbarCodec,
|
||||
// mxDefaultPopupMenuCodec,
|
||||
// mxEditorCodec,
|
||||
CloneUtils,
|
||||
DomUtils,
|
||||
EventUtils,
|
||||
GestureUtils,
|
||||
StringUtils,
|
||||
XmlUtils,
|
||||
mxDomHelpers,
|
||||
CellAttributeChange,
|
||||
ChildChange,
|
||||
CollapseChange,
|
||||
CurrentRootChange,
|
||||
GeometryChange,
|
||||
RootChange,
|
||||
SelectionChange,
|
||||
StyleChange,
|
||||
TerminalChange,
|
||||
ValueChange,
|
||||
VisibleChange,
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import type CellState from './view/cell/datatypes/CellState';
|
|||
import EventSource from './view/event/EventSource';
|
||||
import type InternalMouseEvent from './view/event/InternalMouseEvent';
|
||||
import type Shape from './view/geometry/shape/Shape';
|
||||
import type { MaxGraph } from './view/Graph';
|
||||
import type { Graph } from './view/Graph';
|
||||
import type ImageBox from './view/image/ImageBox';
|
||||
|
||||
export type CellMap = {
|
||||
|
@ -90,10 +90,12 @@ export type CellStateStyles = {
|
|||
labelBorderColor: ColorValue;
|
||||
labelPadding: number;
|
||||
labelPosition: AlignValue;
|
||||
labelWidth: number;
|
||||
loop: Function;
|
||||
margin: number;
|
||||
movable: boolean;
|
||||
noEdgeStyle: boolean;
|
||||
noLabel: boolean;
|
||||
opacity: number;
|
||||
orthogonal: boolean | null;
|
||||
overflow: OverflowValue;
|
||||
|
@ -217,7 +219,7 @@ export type GradientMap = {
|
|||
};
|
||||
|
||||
export interface GraphPluginConstructor {
|
||||
new (graph: MaxGraph): GraphPlugin;
|
||||
new (graph: Graph): GraphPlugin;
|
||||
pluginId: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import Polyline from '../view/geometry/shape/edge/Polyline';
|
|||
import CellState from '../view/cell/datatypes/CellState';
|
||||
import Shape from '../view/geometry/shape/Shape';
|
||||
import Rectangle from '../view/geometry/Rectangle';
|
||||
import { MaxGraph } from '../view/Graph';
|
||||
import { Graph } from '../view/Graph';
|
||||
import EventObject from '../view/event/EventObject';
|
||||
import GraphView from '../view/view/GraphView';
|
||||
import { ColorValue } from '../types';
|
||||
|
@ -26,7 +26,7 @@ import { ColorValue } from '../types';
|
|||
* Constructs a new guide object.
|
||||
*/
|
||||
class Guide {
|
||||
constructor(graph: MaxGraph, states: CellState[]) {
|
||||
constructor(graph: Graph, states: CellState[]) {
|
||||
this.graph = graph;
|
||||
this.setStates(states);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class Guide {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph> instance.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: states
|
||||
|
|
|
@ -40,9 +40,9 @@ import CellState from '../view/cell/datatypes/CellState';
|
|||
import Cell from '../view/cell/datatypes/Cell';
|
||||
import Model from '../view/model/Model';
|
||||
import CellArray from '../view/cell/datatypes/CellArray';
|
||||
import { Graph } from 'src/view/Graph';
|
||||
|
||||
import type { CellStateStyles, Properties, StyleValue } from '../types';
|
||||
import type { MaxGraph } from '../view/Graph';
|
||||
|
||||
/**
|
||||
* Class: mxUtils
|
||||
|
@ -736,7 +736,7 @@ export const getPortConstraints = (
|
|||
let rotation = 0;
|
||||
|
||||
if (constraintRotationEnabled == 1) {
|
||||
rotation = getValue(terminal.style, 'rotation', 0);
|
||||
rotation = terminal.style.rotation ?? 0;
|
||||
}
|
||||
|
||||
let quad = 0;
|
||||
|
@ -2072,7 +2072,7 @@ export const getSizeForString = (
|
|||
*/
|
||||
export const getScaleForPageCount = (
|
||||
pageCount: number,
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
pageFormat?: Rectangle,
|
||||
border = 0
|
||||
) => {
|
||||
|
@ -2209,7 +2209,7 @@ export const getScaleForPageCount = (
|
|||
* h - Optional height of the graph view.
|
||||
*/
|
||||
export const show = (
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
doc: Document,
|
||||
x0 = 0,
|
||||
y0 = 0,
|
||||
|
@ -2325,7 +2325,7 @@ export const show = (
|
|||
*
|
||||
* graph - <mxGraph> to be printed.
|
||||
*/
|
||||
export const printScreen = (graph: MaxGraph) => {
|
||||
export const printScreen = (graph: Graph) => {
|
||||
const wnd = window.open();
|
||||
|
||||
if (!wnd) return;
|
||||
|
@ -2353,52 +2353,17 @@ export const isNullish = (v: string | object | null | undefined | number) =>
|
|||
export const isNotNullish = (v: string | object | null | undefined | number) =>
|
||||
!isNullish(v);
|
||||
|
||||
export const copyPropertiesToPrototype = (source: any, sourceObj: any, target: any) => {
|
||||
Object.getOwnPropertyNames(sourceObj).forEach((name) => {
|
||||
// Merge a mixin into the destination
|
||||
export const mixInto = (dest: any) => (mixin: any) => {
|
||||
const keys = Reflect.ownKeys(mixin);
|
||||
try {
|
||||
Object.defineProperty(target, name, {
|
||||
...(Object.getOwnPropertyDescriptor(source, name) || Object.create(null)),
|
||||
value: sourceObj[name],
|
||||
for (const key of keys) {
|
||||
Object.defineProperty(dest.prototype, key, {
|
||||
value: mixin[key],
|
||||
writable: true,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const copyMethodsToPrototype = (source: any, target: any) => {
|
||||
Object.getOwnPropertyNames(source).forEach((name) => {
|
||||
try {
|
||||
if (name !== 'constructor') {
|
||||
Object.defineProperty(
|
||||
target,
|
||||
name,
|
||||
Object.getOwnPropertyDescriptor(source, name) || Object.create(null)
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.log('Error while mixing', e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Mixins support
|
||||
export const applyMixins = (derivedCtor: any, constructors: any[]) => {
|
||||
constructors.forEach((baseCtor) => {
|
||||
// Copy variables
|
||||
copyPropertiesToPrototype(baseCtor.prototype, new baseCtor(), derivedCtor.prototype);
|
||||
|
||||
// Copy methods
|
||||
copyMethodsToPrototype(baseCtor.prototype, derivedCtor.prototype);
|
||||
});
|
||||
|
||||
// Attach the derived prototype to each prototype.
|
||||
constructors.forEach((baseCtor) => {
|
||||
Object.setPrototypeOf(baseCtor.prototype, derivedCtor.prototype);
|
||||
});
|
||||
};
|
||||
|
||||
// Creates a class using a type
|
||||
export const autoImplement = <T>(): new () => T => class {} as any;
|
||||
|
||||
export default utils;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import utils, { setOpacity } from '../Utils';
|
||||
import { setOpacity } from '../Utils';
|
||||
import GeometryChange from '../../view/geometry/GeometryChange';
|
||||
import TerminalChange from '../../view/cell/edge/TerminalChange';
|
||||
import ValueChange from '../../view/cell/ValueChange';
|
||||
|
@ -56,17 +56,12 @@ class mxEffects {
|
|||
change instanceof ChildChange ||
|
||||
change instanceof StyleChange
|
||||
) {
|
||||
const state = graph
|
||||
.getView()
|
||||
.getState(change.cell || change.child, false);
|
||||
const state = graph.getView().getState(change.cell || change.child, false);
|
||||
|
||||
if (state != null) {
|
||||
isRequired = true;
|
||||
|
||||
if (
|
||||
change.constructor !== GeometryChange ||
|
||||
change.cell.isEdge()
|
||||
) {
|
||||
if (change.constructor !== GeometryChange || change.cell.isEdge()) {
|
||||
setOpacity(state.shape.node, (100 * step) / maxStep);
|
||||
} else {
|
||||
const { scale } = graph.getView();
|
||||
|
@ -74,10 +69,8 @@ class mxEffects {
|
|||
const dx = (change.geometry.x - change.previous.x) * scale;
|
||||
const dy = (change.geometry.y - change.previous.y) * scale;
|
||||
|
||||
const sx =
|
||||
(change.geometry.width - change.previous.width) * scale;
|
||||
const sy =
|
||||
(change.geometry.height - change.previous.height) * scale;
|
||||
const sx = (change.geometry.width - change.previous.width) * scale;
|
||||
const sy = (change.geometry.height - change.previous.height) * scale;
|
||||
|
||||
if (step === 0) {
|
||||
state.x -= dx;
|
||||
|
@ -94,11 +87,7 @@ class mxEffects {
|
|||
graph.cellRenderer.redraw(state);
|
||||
|
||||
// Fades all connected edges and children
|
||||
mxEffects.cascadeOpacity(
|
||||
graph,
|
||||
change.cell,
|
||||
(100 * step) / maxStep
|
||||
);
|
||||
mxEffects.cascadeOpacity(graph, change.cell, (100 * step) / maxStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -972,7 +972,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
|||
if (flipH ? !flipV : flipV) {
|
||||
theta *= -1;
|
||||
}
|
||||
|
||||
console.log('theta', theta);
|
||||
if (theta !== 0) {
|
||||
s.transform += `rotate(${this.format(theta)},${this.format(cx)},${this.format(
|
||||
cy
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import mxClient from '../../mxClient';
|
||||
import InternalEvent from '../../view/event/InternalEvent';
|
||||
import { getInnerHtml, write } from '../DomUtils';
|
||||
import utils from '../Utils';
|
||||
import mxWindow, { popup } from './mxWindow';
|
||||
|
||||
/**
|
||||
|
@ -146,10 +145,7 @@ class mxLog {
|
|||
const elt = mxLog.window.getElement();
|
||||
|
||||
const resizeHandler = (sender, evt) => {
|
||||
mxLog.textarea.style.height = `${Math.max(
|
||||
0,
|
||||
elt.offsetHeight - 70
|
||||
)}px`;
|
||||
mxLog.textarea.style.height = `${Math.max(0, elt.offsetHeight - 70)}px`;
|
||||
};
|
||||
|
||||
mxLog.window.addListener(InternalEvent.RESIZE_END, resizeHandler);
|
||||
|
@ -313,10 +309,7 @@ class mxLog {
|
|||
mxLog.textarea.value = mxLog.textarea.value + string;
|
||||
|
||||
// Workaround for no update in Presto 2.5.22 (Opera 10.5)
|
||||
if (
|
||||
navigator.userAgent != null &&
|
||||
navigator.userAgent.indexOf('Presto/2.5') >= 0
|
||||
) {
|
||||
if (navigator.userAgent != null && navigator.userAgent.indexOf('Presto/2.5') >= 0) {
|
||||
mxLog.textarea.style.visibility = 'hidden';
|
||||
mxLog.textarea.style.visibility = 'visible';
|
||||
}
|
||||
|
@ -344,6 +337,6 @@ class mxLog {
|
|||
|
||||
mxLog.write(`${string}\n`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default mxLog;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import Rectangle from '../../view/geometry/Rectangle';
|
||||
import EventObject from '../../view/event/EventObject';
|
||||
import EventSource from '../../view/event/EventSource';
|
||||
import utils, { fit, getCurrentStyle } from '../Utils';
|
||||
import { fit, getCurrentStyle } from '../Utils';
|
||||
import InternalEvent from '../../view/event/InternalEvent';
|
||||
import mxClient from '../../mxClient';
|
||||
import { NODETYPE_TEXT } from '../Constants';
|
||||
|
|
|
@ -230,5 +230,5 @@ class mxEditorCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxEditorCodec());
|
||||
// mxCodecRegistry.register(new mxEditorCodec());
|
||||
export default mxEditorCodec;
|
||||
|
|
|
@ -40,5 +40,5 @@ class mxGraphCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxGraphCodec());
|
||||
// mxCodecRegistry.register(new mxGraphCodec());
|
||||
export default mxGraphCodec;
|
||||
|
|
|
@ -155,11 +155,7 @@ class mxGraphViewCodec extends mxObjectCodec {
|
|||
}
|
||||
|
||||
for (let i = 0; i < childCount; i += 1) {
|
||||
const childNode = this.encodeCell(
|
||||
enc,
|
||||
view,
|
||||
cell.getChildAt(i)
|
||||
);
|
||||
const childNode = this.encodeCell(enc, view, cell.getChildAt(i));
|
||||
|
||||
if (childNode != null) {
|
||||
node.appendChild(childNode);
|
||||
|
@ -171,5 +167,5 @@ class mxGraphViewCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxGraphViewCodec());
|
||||
// mxCodecRegistry.register(new mxGraphViewCodec());
|
||||
export default mxGraphViewCodec;
|
||||
|
|
|
@ -74,5 +74,5 @@ class mxModelCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxModelCodec());
|
||||
// mxCodecRegistry.register(new mxModelCodec());
|
||||
export default mxModelCodec;
|
||||
|
|
|
@ -46,10 +46,7 @@ class mxRootChangeCodec extends mxObjectCodec {
|
|||
* using the respective decoder.
|
||||
*/
|
||||
beforeDecode(dec, node, obj) {
|
||||
if (
|
||||
node.firstChild != null &&
|
||||
node.firstChild.nodeType === NODETYPE_ELEMENT
|
||||
) {
|
||||
if (node.firstChild != null && node.firstChild.nodeType === NODETYPE_ELEMENT) {
|
||||
// Makes sure the original node isn't modified
|
||||
node = node.cloneNode(true);
|
||||
|
||||
|
@ -83,5 +80,5 @@ class mxRootChangeCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxRootChangeCodec());
|
||||
// mxCodecRegistry.register(new mxRootChangeCodec());
|
||||
export default mxRootChangeCodec;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import Stylesheet from '../../view/style/Stylesheet';
|
||||
import utils, { isNumeric } from '../Utils';
|
||||
import { isNumeric } from '../Utils';
|
||||
import mxCodecRegistry from './mxCodecRegistry';
|
||||
import { NODETYPE_ELEMENT } from '../Constants';
|
||||
import mxLog from '../gui/mxLog';
|
||||
|
@ -168,11 +168,7 @@ class mxStylesheetCodec extends mxObjectCodec {
|
|||
const text = getTextContent(entry);
|
||||
let value = null;
|
||||
|
||||
if (
|
||||
text != null &&
|
||||
text.length > 0 &&
|
||||
mxStylesheetCodec.allowEval
|
||||
) {
|
||||
if (text != null && text.length > 0 && mxStylesheetCodec.allowEval) {
|
||||
value = eval(text);
|
||||
} else {
|
||||
value = entry.getAttribute('value');
|
||||
|
@ -204,5 +200,5 @@ class mxStylesheetCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxStylesheetCodec());
|
||||
// mxCodecRegistry.register(new mxStylesheetCodec());
|
||||
export default mxStylesheetCodec;
|
||||
|
|
|
@ -43,5 +43,5 @@ class mxTerminalChangeCodec extends mxObjectCodec {
|
|||
}
|
||||
}
|
||||
|
||||
mxCodecRegistry.register(new mxTerminalChangeCodec());
|
||||
// mxCodecRegistry.register(new mxTerminalChangeCodec());
|
||||
export default mxTerminalChangeCodec;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import { MaxGraph } from '../../view/Graph';
|
||||
import { Graph } from '../../view/Graph';
|
||||
import CellArray from '../../view/cell/datatypes/CellArray';
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ class Clipboard {
|
|||
* @param graph - {@link graph} that contains the cells to be cut.
|
||||
* @param cells - Optional array of {@link mxCell} to be cut.
|
||||
*/
|
||||
static cut(graph: MaxGraph, cells?: CellArray) {
|
||||
static cut(graph: Graph, cells?: CellArray) {
|
||||
cells = Clipboard.copy(graph, cells);
|
||||
Clipboard.insertCount = 0;
|
||||
Clipboard.removeCells(graph, cells);
|
||||
|
@ -141,7 +141,7 @@ class Clipboard {
|
|||
* @param graph - {@link graph} that contains the cells to be cut.
|
||||
* @param cells - Array of {@link mxCell} to be cut.
|
||||
*/
|
||||
static removeCells(graph: MaxGraph, cells: CellArray) {
|
||||
static removeCells(graph: Graph, cells: CellArray) {
|
||||
graph.removeCells(cells);
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ class Clipboard {
|
|||
* @param graph - {@link graph} that contains the cells to be copied.
|
||||
* @param cells - Optional array of {@link mxCell} to be copied.
|
||||
*/
|
||||
static copy(graph: MaxGraph, cells?: CellArray) {
|
||||
static copy(graph: Graph, cells?: CellArray) {
|
||||
cells = cells || graph.getSelectionCells();
|
||||
const result = graph.getExportableCells(cells).getTopmostCells();
|
||||
Clipboard.insertCount = 1;
|
||||
|
@ -173,7 +173,7 @@ class Clipboard {
|
|||
*
|
||||
* @param graph - {@link graph} to paste the {@link cells} into.
|
||||
*/
|
||||
static paste(graph: MaxGraph) {
|
||||
static paste(graph: Graph) {
|
||||
let cells = null;
|
||||
|
||||
if (!Clipboard.isEmpty() && Clipboard.getCells()) {
|
||||
|
|
|
@ -21,15 +21,7 @@ import GraphView from './view/GraphView';
|
|||
import CellRenderer from './cell/CellRenderer';
|
||||
import CellEditor from './editing/CellEditor';
|
||||
import Point from './geometry/Point';
|
||||
import {
|
||||
applyMixins,
|
||||
autoImplement,
|
||||
copyMethodsToPrototype,
|
||||
copyPropertiesToPrototype,
|
||||
getCurrentStyle,
|
||||
hasScrollbars,
|
||||
parseCssNumber,
|
||||
} from '../util/Utils';
|
||||
import { getCurrentStyle, hasScrollbars, parseCssNumber } from '../util/Utils';
|
||||
import Cell from './cell/datatypes/Cell';
|
||||
import Model from './model/Model';
|
||||
import Stylesheet from './style/Stylesheet';
|
||||
|
@ -43,7 +35,6 @@ 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';
|
||||
|
@ -52,185 +43,6 @@ import ElbowEdgeHandler from './cell/edge/ElbowEdgeHandler';
|
|||
import Dictionary from '../util/Dictionary';
|
||||
|
||||
import type { GraphPlugin, GraphPluginConstructor } from '../types';
|
||||
import GraphPorts from './ports/GraphPorts';
|
||||
import GraphPanning from './panning/GraphPanning';
|
||||
import GraphZoom from './zoom/GraphZoom';
|
||||
import GraphEvents from './event/GraphEvents';
|
||||
import GraphImage from './image/GraphImage';
|
||||
import GraphCells from './cell/GraphCells';
|
||||
import GraphSelection from './selection/GraphSelection';
|
||||
import GraphConnections from './connection/GraphConnections';
|
||||
import GraphEdge from './cell/edge/GraphEdge';
|
||||
import GraphVertex from './cell/vertex/GraphVertex';
|
||||
import GraphOverlays from './layout/GraphOverlays';
|
||||
import GraphEditing from './editing/GraphEditing';
|
||||
import GraphFolding from './folding/GraphFolding';
|
||||
import GraphLabel from './label/GraphLabel';
|
||||
import GraphValidation from './validation/GraphValidation';
|
||||
import GraphSnap from './snap/GraphSnap';
|
||||
import GraphTooltip from './tooltip/GraphTooltip';
|
||||
import GraphTerminal from './terminal/GraphTerminal';
|
||||
import GraphDragDrop from './drag_drop/GraphDragDrop';
|
||||
import GraphSwimlane from './swimlane/GraphSwimlane';
|
||||
import GraphPageBreaks from './page_breaks/GraphPageBreaks';
|
||||
|
||||
type PartialEvents = Pick<
|
||||
GraphEvents,
|
||||
| 'sizeDidChange'
|
||||
| 'isNativeDblClickEnabled'
|
||||
| 'dblClick'
|
||||
| 'fireMouseEvent'
|
||||
| 'isMouseDown'
|
||||
| 'fireGestureEvent'
|
||||
| 'addMouseListener'
|
||||
| 'removeMouseListener'
|
||||
| 'isGridEnabledEvent'
|
||||
| 'isIgnoreTerminalEvent'
|
||||
| 'isCloneEvent'
|
||||
| 'isToggleEvent'
|
||||
| 'getEventTolerance'
|
||||
| 'isInvokesStopCellEditing'
|
||||
| 'getPointForEvent'
|
||||
| 'isConstrainedEvent'
|
||||
| 'isMouseTrigger'
|
||||
| 'isEnterStopsCellEditing'
|
||||
| 'getCursorForMouseEvent'
|
||||
>;
|
||||
type PartialSelection = Pick<
|
||||
GraphSelection,
|
||||
| 'clearSelection'
|
||||
| 'isCellSelected'
|
||||
| 'getSelectionCount'
|
||||
| 'selectCellForEvent'
|
||||
| 'setSelectionCell'
|
||||
| 'getSelectionCells'
|
||||
| 'updateSelection'
|
||||
| 'selectRegion'
|
||||
| 'cellAdded'
|
||||
| 'cellRemoved'
|
||||
| 'getUpdatingSelectionResource'
|
||||
| 'getDoneResource'
|
||||
| 'isSiblingSelected'
|
||||
| 'setSelectionCells'
|
||||
>;
|
||||
type PartialCells = Pick<
|
||||
GraphCells,
|
||||
| 'removeStateForCell'
|
||||
| 'getCellStyle'
|
||||
| 'getCellAt'
|
||||
| 'isCellBendable'
|
||||
| 'isCellsCloneable'
|
||||
| 'cloneCell'
|
||||
| 'setCellStyles'
|
||||
| 'isCellMovable'
|
||||
| 'isCellResizable'
|
||||
| 'getChildCells'
|
||||
| 'isCellRotatable'
|
||||
| 'getCellContainmentArea'
|
||||
| 'getCurrentCellStyle'
|
||||
| 'resizeCell'
|
||||
| 'removeStateForCell'
|
||||
| 'getMovableCells'
|
||||
| 'getCloneableCells'
|
||||
| 'isCellLocked'
|
||||
| 'moveCells'
|
||||
| 'removeCells'
|
||||
| 'isCellDeletable'
|
||||
| 'addCell'
|
||||
| 'getExportableCells'
|
||||
| 'cloneCells'
|
||||
| 'importCells'
|
||||
| 'getImportableCells'
|
||||
>;
|
||||
type PartialConnections = Pick<
|
||||
GraphConnections,
|
||||
| 'getConnectionConstraint'
|
||||
| 'setConnectionConstraint'
|
||||
| 'getConnectionPoint'
|
||||
| 'isCellDisconnectable'
|
||||
| 'getOutlineConstraint'
|
||||
| 'connectCell'
|
||||
| 'getConnections'
|
||||
| 'isConstrainChild'
|
||||
| 'isValidSource'
|
||||
| 'getAllConnectionConstraints'
|
||||
>;
|
||||
type PartialEditing = Pick<
|
||||
GraphEditing,
|
||||
'isEditing' | 'stopEditing' | 'labelChanged' | 'getEditingValue'
|
||||
>;
|
||||
type PartialTooltip = Pick<GraphTooltip, 'getTooltip'>;
|
||||
type PartialValidation = Pick<
|
||||
GraphValidation,
|
||||
'getEdgeValidationError' | 'validationAlert' | 'isEdgeValid'
|
||||
>;
|
||||
type PartialLabel = Pick<
|
||||
GraphLabel,
|
||||
'isLabelMovable' | 'isHtmlLabel' | 'isWrapping' | 'isLabelClipped' | 'getLabel'
|
||||
>;
|
||||
type PartialTerminal = Pick<GraphTerminal, 'isTerminalPointMovable' | 'getOpposites'>;
|
||||
type PartialSnap = Pick<
|
||||
GraphSnap,
|
||||
'snap' | 'getGridSize' | 'isGridEnabled' | 'getSnapTolerance' | 'snapDelta'
|
||||
>;
|
||||
type PartialEdge = Pick<
|
||||
GraphEdge,
|
||||
| 'isAllowDanglingEdges'
|
||||
| 'isResetEdgesOnConnect'
|
||||
| 'getEdges'
|
||||
| 'insertEdge'
|
||||
| 'addEdge'
|
||||
| 'splitEdge'
|
||||
| 'flipEdge'
|
||||
>;
|
||||
type PartialOverlays = Pick<GraphOverlays, 'getCellOverlays'>;
|
||||
type PartialFolding = Pick<
|
||||
GraphFolding,
|
||||
'getFoldingImage' | 'isFoldingEnabled' | 'foldCells'
|
||||
>;
|
||||
type PartialPanning = Pick<
|
||||
GraphPanning,
|
||||
| 'panGraph'
|
||||
| 'isUseScrollbarsForPanning'
|
||||
| 'getPanDx'
|
||||
| 'setPanDx'
|
||||
| 'getPanDy'
|
||||
| 'setPanDy'
|
||||
| 'isTimerAutoScroll'
|
||||
| 'isAllowAutoPanning'
|
||||
| 'scrollCellToVisible'
|
||||
>;
|
||||
type PartialZoom = Pick<GraphZoom, 'zoomTo'>;
|
||||
type PartialDragDrop = Pick<
|
||||
GraphDragDrop,
|
||||
'isDropEnabled' | 'isAutoScroll' | 'isAutoExtend' | 'isSplitEnabled' | 'isSplitTarget'
|
||||
>;
|
||||
type PartialSwimlane = Pick<GraphSwimlane, 'getDropTarget'>;
|
||||
type PartialPorts = Pick<
|
||||
GraphPorts,
|
||||
'isPort' | 'getTerminalForPort' | 'isPortsEnabled' | 'setPortsEnabled'
|
||||
>;
|
||||
type PartialClass = PartialEvents &
|
||||
PartialSelection &
|
||||
PartialCells &
|
||||
PartialConnections &
|
||||
PartialEditing &
|
||||
PartialTooltip &
|
||||
PartialValidation &
|
||||
PartialLabel &
|
||||
PartialTerminal &
|
||||
PartialSnap &
|
||||
PartialEdge &
|
||||
PartialOverlays &
|
||||
PartialFolding &
|
||||
PartialPanning &
|
||||
PartialZoom &
|
||||
PartialDragDrop &
|
||||
PartialSwimlane &
|
||||
PartialPorts &
|
||||
EventSource;
|
||||
|
||||
export type MaxGraph = Graph & PartialClass;
|
||||
|
||||
const defaultPlugins: GraphPluginConstructor[] = [
|
||||
CellEditor,
|
||||
|
@ -259,8 +71,7 @@ const defaultPlugins: GraphPluginConstructor[] = [
|
|||
* @class graph
|
||||
* @extends {EventSource}
|
||||
*/
|
||||
// @ts-ignore recursive reference error
|
||||
class Graph extends autoImplement<PartialClass>() {
|
||||
class Graph extends EventSource {
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
model?: Model,
|
||||
|
@ -291,7 +102,7 @@ class Graph extends autoImplement<PartialClass>() {
|
|||
|
||||
// Initiailzes plugins
|
||||
this.plugins.forEach((p: GraphPluginConstructor) => {
|
||||
this.pluginsMap.put(p.pluginId, new p(this));
|
||||
this.pluginsMap[p.pluginId] = new p(this);
|
||||
});
|
||||
|
||||
this.view.revalidate();
|
||||
|
@ -303,7 +114,7 @@ class Graph extends autoImplement<PartialClass>() {
|
|||
|
||||
destroyed: boolean = false;
|
||||
|
||||
getPlugin = (id: string) => this.pluginsMap.get(id) as unknown;
|
||||
getPlugin = (id: string) => this.pluginsMap[id] as unknown;
|
||||
|
||||
graphModelChangeListener: Function | null = null;
|
||||
paintBackground: Function | null = null;
|
||||
|
@ -318,7 +129,7 @@ class Graph extends autoImplement<PartialClass>() {
|
|||
model: Model;
|
||||
|
||||
plugins: GraphPluginConstructor[];
|
||||
pluginsMap: Dictionary<string, GraphPlugin> = new Dictionary();
|
||||
pluginsMap: Record<string, GraphPlugin> = {};
|
||||
|
||||
/**
|
||||
* Holds the {@link GraphView} that caches the {@link CellState}s for the cells.
|
||||
|
@ -658,7 +469,6 @@ class Graph extends autoImplement<PartialClass>() {
|
|||
|
||||
// TODO: Document me!!
|
||||
batchUpdate(fn: Function) {
|
||||
console.log(this.getModel, this.getModel());
|
||||
this.getModel().beginUpdate();
|
||||
try {
|
||||
fn();
|
||||
|
@ -1658,31 +1468,4 @@ class Graph extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
|
||||
applyMixins(Graph, [
|
||||
GraphCells,
|
||||
GraphConnections,
|
||||
GraphDragDrop,
|
||||
GraphEdge,
|
||||
GraphEditing,
|
||||
GraphEvents,
|
||||
GraphFolding,
|
||||
GraphImage,
|
||||
GraphLabel,
|
||||
GraphOverlays,
|
||||
GraphPageBreaks,
|
||||
GraphPanning,
|
||||
GraphPorts,
|
||||
GraphSelection,
|
||||
GraphSnap,
|
||||
GraphSwimlane,
|
||||
GraphTerminal,
|
||||
GraphTooltip,
|
||||
GraphValidation,
|
||||
GraphVertex,
|
||||
GraphZoom,
|
||||
]);
|
||||
|
||||
copyPropertiesToPrototype(EventSource.prototype, new EventSource(), Graph.prototype);
|
||||
copyMethodsToPrototype(EventSource.prototype, Graph.prototype);
|
||||
|
||||
export default Graph;
|
||||
export { Graph };
|
||||
|
|
|
@ -25,7 +25,7 @@ import Dictionary from '../util/Dictionary';
|
|||
import CellHighlight from './selection/CellHighlight';
|
||||
import Rectangle from './geometry/Rectangle';
|
||||
import { getClientX, getClientY, isAltDown, isMultiTouchEvent } from '../util/EventUtils';
|
||||
import { MaxGraph } from './Graph';
|
||||
import { Graph } from './Graph';
|
||||
import Guide from '../util/Guide';
|
||||
import Shape from './geometry/shape/Shape';
|
||||
import InternalMouseEvent from './event/InternalMouseEvent';
|
||||
|
@ -63,7 +63,7 @@ import ConnectionHandler from './connection/ConnectionHandler';
|
|||
class GraphHandler implements GraphPlugin {
|
||||
static pluginId = 'GraphHandler';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.graph = graph;
|
||||
this.graph.addMouseListener(this);
|
||||
|
||||
|
@ -166,7 +166,7 @@ class GraphHandler implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
panHandler: () => void;
|
||||
escapeHandler: (sender: EventSource, evt: EventObject) => void;
|
||||
|
|
|
@ -15,14 +15,14 @@ import {
|
|||
import Point from './geometry/Point';
|
||||
import Rectangle from './geometry/Rectangle';
|
||||
import RectangleShape from './geometry/shape/node/RectangleShape';
|
||||
import graph, { MaxGraph } from './Graph';
|
||||
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/ImageBox';
|
||||
import EventObject from './event/EventObject';
|
||||
import { getSource, isMouseEvent } from '../util/EventUtils';
|
||||
import EventSource from './event/EventSource';
|
||||
import { hasScrollbars } from '../util/Utils';
|
||||
|
||||
/**
|
||||
* @class Outline
|
||||
|
@ -71,7 +71,7 @@ import EventSource from './event/EventSource';
|
|||
* ```
|
||||
*/
|
||||
class Outline {
|
||||
constructor(source: MaxGraph, container: HTMLElement | null = null) {
|
||||
constructor(source: Graph, container: HTMLElement | null = null) {
|
||||
this.source = source;
|
||||
|
||||
if (container != null) {
|
||||
|
@ -132,7 +132,7 @@ class Outline {
|
|||
|
||||
// Refreshes the graph in the outline after a refresh of the main graph
|
||||
this.refreshHandler = (sender: any) => {
|
||||
const outline = <graph>this.outline;
|
||||
const outline = <Graph>this.outline;
|
||||
outline.setStylesheet(this.source.getStylesheet());
|
||||
outline.refresh();
|
||||
};
|
||||
|
@ -154,21 +154,21 @@ class Outline {
|
|||
// complete gesture on the event target. This is needed because all the events
|
||||
// are routed via the initial element even if that element is removed from the
|
||||
// DOM, which happens when we repaint the selection border and zoom handles.
|
||||
const handler = (evt: Event) => {
|
||||
const handler = (evt: MouseEvent) => {
|
||||
const t = getSource(evt);
|
||||
|
||||
const redirect = (evt: Event) => {
|
||||
const outline = <graph>this.outline;
|
||||
const outline = <Graph>this.outline;
|
||||
outline.fireMouseEvent(InternalEvent.MOUSE_MOVE, new InternalMouseEvent(evt));
|
||||
};
|
||||
|
||||
var redirect2 = (evt: Event) => {
|
||||
const outline = <graph>this.outline;
|
||||
const outline = <Graph>this.outline;
|
||||
InternalEvent.removeGestureListeners(t, null, redirect, redirect2);
|
||||
outline.fireMouseEvent(InternalEvent.MOUSE_UP, new InternalMouseEvent(evt));
|
||||
};
|
||||
|
||||
const outline = <graph>this.outline;
|
||||
const outline = <Graph>this.outline;
|
||||
InternalEvent.addGestureListeners(t, null, redirect, redirect2);
|
||||
outline.fireMouseEvent(InternalEvent.MOUSE_DOWN, new InternalMouseEvent(evt));
|
||||
};
|
||||
|
@ -224,12 +224,12 @@ class Outline {
|
|||
/**
|
||||
* Reference to the source {@link graph}.
|
||||
*/
|
||||
source: MaxGraph;
|
||||
source: Graph;
|
||||
|
||||
/**
|
||||
* Reference to the {@link graph} that renders the outline.
|
||||
*/
|
||||
outline: graph | null = null;
|
||||
outline: Graph | null = null;
|
||||
|
||||
/**
|
||||
* Renderhint to be used for the outline graph.
|
||||
|
@ -308,8 +308,8 @@ class Outline {
|
|||
/**
|
||||
* Creates the {@link graph} used in the outline.
|
||||
*/
|
||||
createGraph(container: HTMLElement): graph {
|
||||
const graph = new graph(
|
||||
createGraph(container: HTMLElement): Graph {
|
||||
const graph = new Graph(
|
||||
container,
|
||||
this.source.getModel(),
|
||||
this.graphRenderHint,
|
||||
|
@ -361,7 +361,7 @@ class Outline {
|
|||
*/
|
||||
// createSizer(): mxShape;
|
||||
createSizer(): RectangleShape {
|
||||
const outline = <graph>this.outline;
|
||||
const outline = <Graph>this.outline;
|
||||
if (this.sizerImage != null) {
|
||||
const sizer = new ImageShape(
|
||||
new Rectangle(0, 0, this.sizerImage.width, this.sizerImage.height),
|
||||
|
@ -599,8 +599,8 @@ class Outline {
|
|||
const sizerNode = <SVGGElement>sizer.node;
|
||||
const selectionBorder = <RectangleShape>this.selectionBorder;
|
||||
const selectionBorderNode = <SVGGElement>selectionBorder.node;
|
||||
const source = <graph>this.source;
|
||||
const outline = <graph>this.outline;
|
||||
const source = <Graph>this.source;
|
||||
const outline = <Graph>this.outline;
|
||||
|
||||
selectionBorderNode.style.display = this.showViewport ? '' : 'none';
|
||||
sizerNode.style.display = selectionBorderNode.style.display;
|
||||
|
@ -628,7 +628,7 @@ class Outline {
|
|||
source.panGraph(-dx - <number>this.dx0, -dy - <number>this.dy0);
|
||||
} else {
|
||||
// Does *not* preview zooming on the source graph
|
||||
const { container } = <graph>this.source;
|
||||
const { container } = <Graph>this.source;
|
||||
// @ts-ignore
|
||||
const viewRatio = container.clientWidth / container.clientHeight;
|
||||
dy = dx / viewRatio;
|
||||
|
@ -692,8 +692,8 @@ class Outline {
|
|||
const delta = this.getTranslateForEvent(me);
|
||||
let dx = delta.x;
|
||||
let dy = delta.y;
|
||||
const source = <graph>this.source;
|
||||
const outline = <graph>this.outline;
|
||||
const source = <Graph>this.source;
|
||||
const outline = <Graph>this.outline;
|
||||
const selectionBorder = <RectangleShape>this.selectionBorder;
|
||||
|
||||
if (Math.abs(dx) > 0 || Math.abs(dy) > 0) {
|
||||
|
|
|
@ -16,8 +16,8 @@ import {
|
|||
import CellHighlight from '../selection/CellHighlight';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import utils, { intersectsHotspot, isNumeric } from '../../util/Utils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { intersectsHotspot, isNumeric } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { ColorValue } from '../../types';
|
||||
import CellState from './datatypes/CellState';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
|
@ -65,7 +65,7 @@ import Cell from './datatypes/Cell';
|
|||
*/
|
||||
class CellMarker extends EventSource {
|
||||
constructor(
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
validColor: ColorValue = DEFAULT_VALID_COLOR,
|
||||
invalidColor: ColorValue = DEFAULT_INVALID_COLOR,
|
||||
hotspot: number = DEFAULT_HOTSPOT
|
||||
|
@ -84,7 +84,7 @@ class CellMarker extends EventSource {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: enabled
|
||||
|
|
|
@ -47,7 +47,7 @@ import {
|
|||
SHAPE_SWIMLANE,
|
||||
SHAPE_TRIANGLE,
|
||||
} from '../../util/Constants';
|
||||
import utils, {
|
||||
import {
|
||||
convertPoint,
|
||||
equalEntries,
|
||||
equalPoints,
|
||||
|
@ -67,12 +67,12 @@ import Point from '../geometry/Point';
|
|||
import Shape from '../geometry/shape/Shape';
|
||||
import CellState from './datatypes/CellState';
|
||||
import Cell from './datatypes/Cell';
|
||||
import Model from '../model/Model';
|
||||
import CellOverlay from './CellOverlay';
|
||||
import { getClientX, getClientY, getSource } from '../../util/EventUtils';
|
||||
import { isNode } from '../../util/DomUtils';
|
||||
import { CellStateStyles } from '../../types';
|
||||
import CellArray from './datatypes/CellArray';
|
||||
import SelectionCellsHandler from '../selection/SelectionCellsHandler';
|
||||
|
||||
/**
|
||||
* Class: mxCellRenderer
|
||||
|
@ -982,7 +982,7 @@ class CellRenderer {
|
|||
!state.text.bounds.equals(bounds)
|
||||
) {
|
||||
state.text.dialect = dialect;
|
||||
state.text.value = value;
|
||||
state.text.value = value as string;
|
||||
state.text.bounds = bounds;
|
||||
state.text.scale = nextScale;
|
||||
state.text.wrap = wrapping;
|
||||
|
@ -1135,8 +1135,8 @@ class CellRenderer {
|
|||
|
||||
// Shape can modify its label bounds
|
||||
if (state.shape != null) {
|
||||
const hpos = getValue(state.style, 'labelPosition', ALIGN_CENTER);
|
||||
const vpos = getValue(state.style, 'verticalLabelPosition', ALIGN_MIDDLE);
|
||||
const hpos = state.style.labelPosition ?? ALIGN_CENTER;
|
||||
const vpos = state.style.verticalLabelPosition ?? ALIGN_MIDDLE;
|
||||
|
||||
if (hpos === ALIGN_CENTER && vpos === ALIGN_MIDDLE) {
|
||||
bounds = state.shape.getLabelBounds(bounds);
|
||||
|
@ -1144,10 +1144,10 @@ class CellRenderer {
|
|||
}
|
||||
|
||||
// Label width style overrides actual label width
|
||||
const lw = getValue(state.style, 'labelWidth', null);
|
||||
const lw = state.style.labelWidth ?? null;
|
||||
|
||||
if (lw != null) {
|
||||
bounds.width = parseFloat(lw) * scale;
|
||||
bounds.width = lw * scale;
|
||||
}
|
||||
if (!isEdge) {
|
||||
this.rotateLabelBounds(state, bounds);
|
||||
|
@ -1304,16 +1304,14 @@ class CellRenderer {
|
|||
const bounds = this.getControlBounds(state, image.width, image.height);
|
||||
|
||||
const r = this.legacyControlPosition
|
||||
? getValue(state.style, 'rotation', 0)
|
||||
: // @ts-ignore
|
||||
state.shape.getTextRotation();
|
||||
? state.style.rotation ?? 0
|
||||
: state.shape!.getTextRotation();
|
||||
const s = state.view.scale;
|
||||
|
||||
if (
|
||||
forced ||
|
||||
state.control.scale !== s ||
|
||||
// @ts-ignore
|
||||
!state.control.bounds.equals(bounds) ||
|
||||
!state.control.bounds!.equals(bounds) ||
|
||||
state.control.rotation !== r
|
||||
) {
|
||||
state.control.rotation = r;
|
||||
|
@ -1556,8 +1554,10 @@ class CellRenderer {
|
|||
this.installListeners(state);
|
||||
|
||||
// Forces a refresh of the handler if one exists
|
||||
// @ts-ignore
|
||||
state.view.graph.selectionCellsHandler.updateHandler(state);
|
||||
const selectionCellsHandler = state.view.graph.getPlugin(
|
||||
'SelectionCellsHandler'
|
||||
) as SelectionCellsHandler;
|
||||
selectionCellsHandler.updateHandler(state);
|
||||
}
|
||||
} else if (
|
||||
!force &&
|
||||
|
@ -1568,8 +1568,10 @@ class CellRenderer {
|
|||
state.shape.resetStyles();
|
||||
this.configureShape(state);
|
||||
// LATER: Ignore update for realtime to fix reset of current gesture
|
||||
// @ts-ignore
|
||||
state.view.graph.selectionCellsHandler.updateHandler(state);
|
||||
const selectionCellsHandler = state.view.graph.getPlugin(
|
||||
'SelectionCellsHandler'
|
||||
) as SelectionCellsHandler;
|
||||
selectionCellsHandler.updateHandler(state);
|
||||
force = true;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
import Cell from './datatypes/Cell';
|
||||
import CellArray from './datatypes/CellArray';
|
||||
import Dictionary from '../../util/Dictionary';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
class TreeTraversal {
|
||||
dependencies = ['connections'];
|
||||
|
|
|
@ -31,7 +31,7 @@ import {
|
|||
OUTLINE_HIGHLIGHT_COLOR,
|
||||
OUTLINE_HIGHLIGHT_STROKEWIDTH,
|
||||
} from '../../../util/Constants';
|
||||
import utils, {
|
||||
import {
|
||||
contains,
|
||||
convertPoint,
|
||||
equalPoints,
|
||||
|
@ -56,14 +56,13 @@ import {
|
|||
isMouseEvent,
|
||||
isShiftDown,
|
||||
} from '../../../util/EventUtils';
|
||||
import { MaxGraph } from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellState from '../datatypes/CellState';
|
||||
import Shape from '../../geometry/shape/Shape';
|
||||
import { CellHandle, ColorValue, Listenable } from '../../../types';
|
||||
import InternalMouseEvent from '../../event/InternalMouseEvent';
|
||||
import Cell from '../datatypes/Cell';
|
||||
import ImageBox from '../../image/ImageBox';
|
||||
import Marker from '../../geometry/shape/edge/Marker';
|
||||
import EventSource from '../../event/EventSource';
|
||||
import GraphHandler from '../../GraphHandler';
|
||||
|
||||
|
@ -175,7 +174,7 @@ class EdgeHandler {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: state
|
||||
|
@ -672,7 +671,7 @@ class EdgeHandler {
|
|||
};
|
||||
}
|
||||
|
||||
return new MyMarker(this.graph);
|
||||
return new MyMarker(this.graph) as CellMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,7 @@ import Point from '../../geometry/Point';
|
|||
import EdgeStyle from '../../style/EdgeStyle';
|
||||
import Resources from '../../../util/Resources';
|
||||
import Rectangle from '../../geometry/Rectangle';
|
||||
import utils, { intersects } from '../../../util/Utils';
|
||||
import { intersects } from '../../../util/Utils';
|
||||
import mxClient from '../../../mxClient';
|
||||
import { isConsumed } from '../../../util/EventUtils';
|
||||
import CellState from '../datatypes/CellState';
|
||||
|
|
|
@ -1,88 +1,198 @@
|
|||
import Cell from '../datatypes/Cell';
|
||||
import CellArray from '../datatypes/CellArray';
|
||||
import { autoImplement, findNearestSegment, removeDuplicates } from '../../../util/Utils';
|
||||
import { findNearestSegment, mixInto, removeDuplicates } from '../../../util/Utils';
|
||||
import Geometry from '../../geometry/Geometry';
|
||||
import EventObject from '../../event/EventObject';
|
||||
import InternalEvent from '../../event/InternalEvent';
|
||||
import Dictionary from '../../../util/Dictionary';
|
||||
import { Graph } from '../../Graph';
|
||||
|
||||
import type Graph from '../../Graph';
|
||||
import type GraphCells from '../GraphCells';
|
||||
import type GraphConnections from '../../connection/GraphConnections';
|
||||
declare module '../../Graph' {
|
||||
interface Graph {
|
||||
resetEdgesOnResize: boolean;
|
||||
resetEdgesOnMove: false;
|
||||
resetEdgesOnConnect: boolean;
|
||||
connectableEdges: boolean;
|
||||
allowDanglingEdges: boolean;
|
||||
cloneInvalidEdges: boolean;
|
||||
alternateEdgeStyle: string | null;
|
||||
edgeLabelsMovable: boolean;
|
||||
|
||||
type PartialGraph = Pick<Graph, 'batchUpdate' | 'fireEvent' | 'getModel' | 'getView'>;
|
||||
type PartialCells = Pick<
|
||||
GraphCells,
|
||||
| 'cloneCell'
|
||||
| 'cellsMoved'
|
||||
| 'cellsAdded'
|
||||
| 'addCell'
|
||||
| 'isValidAncestor'
|
||||
isResetEdgesOnMove: () => boolean;
|
||||
isResetEdgesOnConnect: () => boolean;
|
||||
isResetEdgesOnResize: () => boolean;
|
||||
isEdgeLabelsMovable: () => boolean;
|
||||
setEdgeLabelsMovable: (value: boolean) => void;
|
||||
setAllowDanglingEdges: (value: boolean) => void;
|
||||
isAllowDanglingEdges: () => boolean;
|
||||
setConnectableEdges: (value: boolean) => void;
|
||||
isConnectableEdges: () => boolean;
|
||||
setCloneInvalidEdges: (value: boolean) => void;
|
||||
isCloneInvalidEdges: () => boolean;
|
||||
flipEdge: (edge: Cell) => Cell;
|
||||
splitEdge: (
|
||||
edge: Cell,
|
||||
cells: CellArray,
|
||||
newEdge: Cell | null,
|
||||
dx?: number,
|
||||
dy?: number,
|
||||
x?: number,
|
||||
y?: number,
|
||||
parent?: Cell | null
|
||||
) => Cell;
|
||||
insertEdge: (...args: any[]) => Cell;
|
||||
createEdge: (
|
||||
parent: Cell | null,
|
||||
id: string,
|
||||
value: any,
|
||||
source: Cell | null,
|
||||
target: Cell | null,
|
||||
style: any
|
||||
) => Cell;
|
||||
addEdge: (
|
||||
edge: Cell,
|
||||
parent: Cell | null,
|
||||
source: Cell | null,
|
||||
target: Cell | null,
|
||||
index?: number | null
|
||||
) => Cell;
|
||||
addAllEdges: (cells: CellArray) => CellArray;
|
||||
getAllEdges: (cells: CellArray | null) => CellArray;
|
||||
getIncomingEdges: (cell: Cell, parent: Cell | null) => CellArray;
|
||||
getOutgoingEdges: (cell: Cell, parent: Cell | null) => CellArray;
|
||||
getEdges: (
|
||||
cell: Cell,
|
||||
parent?: Cell | null,
|
||||
incoming?: boolean,
|
||||
outgoing?: boolean,
|
||||
includeLoops?: boolean,
|
||||
recurse?: boolean
|
||||
) => CellArray;
|
||||
getChildEdges: (parent: Cell) => CellArray;
|
||||
getEdgesBetween: (source: Cell, target: Cell, directed?: boolean) => CellArray;
|
||||
resetEdges: (cells: CellArray) => void;
|
||||
resetEdge: (edge: Cell) => Cell;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
| 'batchUpdate'
|
||||
| 'fireEvent'
|
||||
| 'getModel'
|
||||
| 'getView'
|
||||
| 'getChildCells'
|
||||
| 'isValidAncestor'
|
||||
| 'cellsAdded'
|
||||
| 'cellsMoved'
|
||||
| 'cloneCell'
|
||||
| 'addCell'
|
||||
| 'cellConnected'
|
||||
>;
|
||||
type PartialConnections = Pick<GraphConnections, 'cellConnected'>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialConnections;
|
||||
type PartialEdge = Pick<
|
||||
Graph,
|
||||
| 'resetEdgesOnResize'
|
||||
| 'resetEdgesOnMove'
|
||||
| 'resetEdgesOnConnect'
|
||||
| 'connectableEdges'
|
||||
| 'allowDanglingEdges'
|
||||
| 'cloneInvalidEdges'
|
||||
| 'alternateEdgeStyle'
|
||||
| 'edgeLabelsMovable'
|
||||
| 'isResetEdgesOnMove'
|
||||
| 'isResetEdgesOnConnect'
|
||||
| 'isResetEdgesOnResize'
|
||||
| 'isEdgeLabelsMovable'
|
||||
| 'setEdgeLabelsMovable'
|
||||
| 'setAllowDanglingEdges'
|
||||
| 'isAllowDanglingEdges'
|
||||
| 'setConnectableEdges'
|
||||
| 'isConnectableEdges'
|
||||
| 'setCloneInvalidEdges'
|
||||
| 'isCloneInvalidEdges'
|
||||
| 'flipEdge'
|
||||
| 'splitEdge'
|
||||
| 'insertEdge'
|
||||
| 'createEdge'
|
||||
| 'addEdge'
|
||||
| 'addAllEdges'
|
||||
| 'getAllEdges'
|
||||
| 'getIncomingEdges'
|
||||
| 'getOutgoingEdges'
|
||||
| 'getEdges'
|
||||
| 'getChildEdges'
|
||||
| 'getEdgesBetween'
|
||||
| 'resetEdges'
|
||||
| 'resetEdge'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialEdge;
|
||||
|
||||
// @ts-ignore recursive reference error
|
||||
class GraphEdge extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphEdgeMixin: PartialType = {
|
||||
/**
|
||||
* Specifies if edge control points should be reset after the resize of a
|
||||
* connected cell.
|
||||
* @default false
|
||||
*/
|
||||
resetEdgesOnResize = false;
|
||||
resetEdgesOnResize: false,
|
||||
|
||||
isResetEdgesOnResize = () => this.resetEdgesOnResize;
|
||||
isResetEdgesOnResize() {
|
||||
return this.resetEdgesOnResize;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edge control points should be reset after the move of a
|
||||
* connected cell.
|
||||
* @default false
|
||||
*/
|
||||
resetEdgesOnMove = false;
|
||||
resetEdgesOnMove: false,
|
||||
|
||||
isResetEdgesOnMove = () => this.resetEdgesOnMove;
|
||||
isResetEdgesOnMove() {
|
||||
return this.resetEdgesOnMove;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edge control points should be reset after the the edge has been
|
||||
* reconnected.
|
||||
* @default true
|
||||
*/
|
||||
resetEdgesOnConnect = true;
|
||||
resetEdgesOnConnect: true,
|
||||
|
||||
isResetEdgesOnConnect = () => this.resetEdgesOnConnect;
|
||||
isResetEdgesOnConnect() {
|
||||
return this.resetEdgesOnConnect;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edges are connectable. This overrides the connectable field in edges.
|
||||
* @default false
|
||||
*/
|
||||
connectableEdges = false;
|
||||
connectableEdges: false,
|
||||
|
||||
/**
|
||||
* Specifies if edges with disconnected terminals are allowed in the graph.
|
||||
* @default true
|
||||
*/
|
||||
allowDanglingEdges = true;
|
||||
allowDanglingEdges: true,
|
||||
|
||||
/**
|
||||
* Specifies if edges that are cloned should be validated and only inserted
|
||||
* if they are valid.
|
||||
* @default true
|
||||
*/
|
||||
cloneInvalidEdges = false;
|
||||
cloneInvalidEdges: false,
|
||||
|
||||
/**
|
||||
* Specifies the alternate edge style to be used if the main control point
|
||||
* on an edge is being double clicked.
|
||||
* @default null
|
||||
*/
|
||||
alternateEdgeStyle: string | null = null;
|
||||
alternateEdgeStyle: null,
|
||||
|
||||
/**
|
||||
* Specifies the return value for edges in {@link isLabelMovable}.
|
||||
* @default true
|
||||
*/
|
||||
edgeLabelsMovable = true;
|
||||
edgeLabelsMovable: true,
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph Behaviour
|
||||
|
@ -93,14 +203,14 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isEdgeLabelsMovable() {
|
||||
return this.edgeLabelsMovable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link edgeLabelsMovable}.
|
||||
*/
|
||||
setEdgeLabelsMovable(value: boolean) {
|
||||
setEdgeLabelsMovable(value) {
|
||||
this.edgeLabelsMovable = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if dangling edges are allowed, that is, if edges are allowed
|
||||
|
@ -108,32 +218,32 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param value Boolean indicating if dangling edges are allowed.
|
||||
*/
|
||||
setAllowDanglingEdges(value: boolean) {
|
||||
setAllowDanglingEdges(value) {
|
||||
this.allowDanglingEdges = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link allowDanglingEdges} as a boolean.
|
||||
*/
|
||||
isAllowDanglingEdges() {
|
||||
return this.allowDanglingEdges;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edges should be connectable.
|
||||
*
|
||||
* @param value Boolean indicating if edges should be connectable.
|
||||
*/
|
||||
setConnectableEdges(value: boolean) {
|
||||
setConnectableEdges(value) {
|
||||
this.connectableEdges = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link connectableEdges} as a boolean.
|
||||
*/
|
||||
isConnectableEdges() {
|
||||
return this.connectableEdges;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edges should be inserted when cloned but not valid wrt.
|
||||
|
@ -142,16 +252,16 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param value Boolean indicating if cloned invalid edges should be
|
||||
* inserted into the graph or ignored.
|
||||
*/
|
||||
setCloneInvalidEdges(value: boolean) {
|
||||
setCloneInvalidEdges(value) {
|
||||
this.cloneInvalidEdges = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link cloneInvalidEdges} as a boolean.
|
||||
*/
|
||||
isCloneInvalidEdges() {
|
||||
return this.cloneInvalidEdges;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Cell alignment and orientation
|
||||
|
@ -182,8 +292,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param edge {@link mxCell} whose style should be changed.
|
||||
*/
|
||||
// flipEdge(edge: mxCell): mxCell;
|
||||
flipEdge(edge: Cell) {
|
||||
flipEdge(edge) {
|
||||
if (this.alternateEdgeStyle) {
|
||||
this.batchUpdate(() => {
|
||||
const style = edge.getStyle();
|
||||
|
@ -200,7 +309,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
});
|
||||
}
|
||||
return edge;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: splitEdge
|
||||
|
@ -222,16 +331,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* parent - Optional parent to insert the cell. If null the parent of
|
||||
* the edge is used.
|
||||
*/
|
||||
splitEdge(
|
||||
edge: Cell,
|
||||
cells: CellArray,
|
||||
newEdge: Cell | null,
|
||||
dx = 0,
|
||||
dy = 0,
|
||||
x: number,
|
||||
y: number,
|
||||
parent: Cell | null = null
|
||||
) {
|
||||
splitEdge(edge, cells, newEdge, dx = 0, dy = 0, x, y, parent = null) {
|
||||
parent = parent ?? edge.getParent();
|
||||
const source = edge.getTerminal(true);
|
||||
|
||||
|
@ -282,8 +382,8 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
);
|
||||
});
|
||||
|
||||
return newEdge;
|
||||
}
|
||||
return newEdge as Cell;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new edge into the given parent {@link Cell} using value as the user
|
||||
|
@ -298,7 +398,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param target {@link mxCell} that defines the target of the edge.
|
||||
* @param style Optional string that defines the cell style.
|
||||
*/
|
||||
insertEdge(...args: any[]) {
|
||||
insertEdge(...args) {
|
||||
let parent: Cell;
|
||||
let id: string = '';
|
||||
let value: any; // note me - can be a string or a class instance!!!
|
||||
|
@ -323,7 +423,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
|
||||
const edge = this.createEdge(parent, id, value, source, target, style);
|
||||
return this.addEdge(edge, parent, source, target);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook method that creates the new edge for {@link insertEdge}. This
|
||||
|
@ -331,21 +431,14 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* are set when the edge is added to the model.
|
||||
*
|
||||
*/
|
||||
createEdge(
|
||||
parent: Cell | null = null,
|
||||
id: string,
|
||||
value: any,
|
||||
source: Cell | null = null,
|
||||
target: Cell | null = null,
|
||||
style: any
|
||||
) {
|
||||
createEdge(parent = null, id, value, source = null, target = null, style) {
|
||||
// Creates the edge
|
||||
const edge = new Cell(value, new Geometry(), style);
|
||||
edge.setId(id);
|
||||
edge.setEdge(true);
|
||||
(<Geometry>edge.geometry).relative = true;
|
||||
return edge;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the edge to the parent and connects it to the given source and
|
||||
|
@ -359,15 +452,9 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param target Optional {@link Cell} that represents the target terminal.
|
||||
* @param index Optional index to insert the cells at. Default is 'to append'.
|
||||
*/
|
||||
addEdge(
|
||||
edge: Cell,
|
||||
parent: Cell | null = null,
|
||||
source: Cell | null = null,
|
||||
target: Cell | null = null,
|
||||
index: number | null = null
|
||||
) {
|
||||
addEdge(edge, parent = null, source = null, target = null, index = null) {
|
||||
return this.addCell(edge, parent, index, source, target);
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Folding
|
||||
|
@ -377,15 +464,15 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* Returns an array with the given cells and all edges that are connected
|
||||
* to a cell or one of its descendants.
|
||||
*/
|
||||
addAllEdges(cells: CellArray) {
|
||||
addAllEdges(cells) {
|
||||
const allCells = cells.slice();
|
||||
return new CellArray(...removeDuplicates(allCells.concat(this.getAllEdges(cells))));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns all edges connected to the given cells or its descendants.
|
||||
*/
|
||||
getAllEdges(cells: CellArray | null) {
|
||||
getAllEdges(cells) {
|
||||
let edges: CellArray = new CellArray();
|
||||
|
||||
if (cells) {
|
||||
|
@ -402,7 +489,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the visible incoming edges for the given cell. If the optional
|
||||
|
@ -413,9 +500,9 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param parent Optional parent of the opposite end for an edge to be
|
||||
* returned.
|
||||
*/
|
||||
getIncomingEdges(cell: Cell, parent: Cell | null = null) {
|
||||
getIncomingEdges(cell, parent = null) {
|
||||
return this.getEdges(cell, parent, true, false, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the visible outgoing edges for the given cell. If the optional
|
||||
|
@ -426,9 +513,9 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param parent Optional parent of the opposite end for an edge to be
|
||||
* returned.
|
||||
*/
|
||||
getOutgoingEdges(cell: Cell, parent: Cell | null = null) {
|
||||
getOutgoingEdges(cell, parent = null) {
|
||||
return this.getEdges(cell, parent, false, true, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: getEdges
|
||||
|
@ -455,8 +542,8 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* Default is false
|
||||
*/
|
||||
getEdges(
|
||||
cell: Cell,
|
||||
parent: Cell | null = null,
|
||||
cell,
|
||||
parent = null,
|
||||
incoming = true,
|
||||
outgoing = true,
|
||||
includeLoops = true,
|
||||
|
@ -501,7 +588,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Cell retrieval
|
||||
|
@ -512,9 +599,9 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param parent {@link mxCell} whose child vertices should be returned.
|
||||
*/
|
||||
getChildEdges(parent: Cell) {
|
||||
getChildEdges(parent) {
|
||||
return this.getChildCells(parent, false, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the edges between the given source and target. This takes into
|
||||
|
@ -525,7 +612,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* target -
|
||||
* directed -
|
||||
*/
|
||||
getEdgesBetween(source: Cell, target: Cell, directed = false) {
|
||||
getEdgesBetween(source, target, directed = false) {
|
||||
const edges = this.getEdges(source);
|
||||
const result = new CellArray();
|
||||
|
||||
|
@ -549,7 +636,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Cell moving
|
||||
|
@ -562,7 +649,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
* @param cells Array of {@link Cell} for which the connected edges should be
|
||||
* reset.
|
||||
*/
|
||||
resetEdges(cells: CellArray) {
|
||||
resetEdges(cells) {
|
||||
// Prepares faster cells lookup
|
||||
const dict = new Dictionary();
|
||||
|
||||
|
@ -596,14 +683,14 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
} finally {
|
||||
this.getModel().endUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the control points of the given edge.
|
||||
*
|
||||
* @param edge {@link mxCell} whose points should be reset.
|
||||
*/
|
||||
resetEdge(edge: Cell) {
|
||||
resetEdge(edge) {
|
||||
let geo = edge.getGeometry();
|
||||
|
||||
// Resets the control points
|
||||
|
@ -614,7 +701,7 @@ class GraphEdge extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphEdge;
|
||||
mixInto(Graph)(GraphEdgeMixin);
|
|
@ -1,38 +1,77 @@
|
|||
import Cell from '../datatypes/Cell';
|
||||
import Geometry from '../../geometry/Geometry';
|
||||
import { autoImplement } from '../../../util/Utils';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellArray from '../datatypes/CellArray';
|
||||
import { mixInto } from '../../../util/Utils';
|
||||
|
||||
import type GraphCells from '../GraphCells';
|
||||
declare module '../../Graph' {
|
||||
interface Graph {
|
||||
vertexLabelsMovable: boolean;
|
||||
allowNegativeCoordinates: boolean;
|
||||
|
||||
type PartialCells = Pick<GraphCells, 'addCell' | 'getChildCells'>;
|
||||
type PartialClass = PartialCells;
|
||||
isAllowNegativeCoordinates: () => boolean;
|
||||
setAllowNegativeCoordinates: (value: boolean) => void;
|
||||
insertVertex: (...args: any[]) => Cell;
|
||||
createVertex: (
|
||||
parent: Cell,
|
||||
id: string,
|
||||
value: any,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
style: any,
|
||||
relative: boolean,
|
||||
geometryClass: typeof Geometry
|
||||
) => Cell;
|
||||
getChildVertices: (parent: Cell) => CellArray;
|
||||
isVertexLabelsMovable: () => boolean;
|
||||
setVertexLabelsMovable: (value: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
class GraphVertex extends autoImplement<PartialClass>() {
|
||||
type PartialGraph = Pick<Graph, 'addCell' | 'getChildCells'>;
|
||||
type PartialVertex = Pick<
|
||||
Graph,
|
||||
| 'vertexLabelsMovable'
|
||||
| 'allowNegativeCoordinates'
|
||||
| 'isAllowNegativeCoordinates'
|
||||
| 'setAllowNegativeCoordinates'
|
||||
| 'insertVertex'
|
||||
| 'createVertex'
|
||||
| 'getChildVertices'
|
||||
| 'isVertexLabelsMovable'
|
||||
| 'setVertexLabelsMovable'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialVertex;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphVertexMixin: PartialType = {
|
||||
/**
|
||||
* Specifies the return value for vertices in {@link isLabelMovable}.
|
||||
* @default false
|
||||
*/
|
||||
vertexLabelsMovable = false;
|
||||
vertexLabelsMovable: false,
|
||||
|
||||
/**
|
||||
* Specifies if negative coordinates for vertices are allowed.
|
||||
* @default true
|
||||
*/
|
||||
allowNegativeCoordinates = true;
|
||||
allowNegativeCoordinates: true,
|
||||
|
||||
/**
|
||||
* Returns {@link allowNegativeCoordinates}.
|
||||
*/
|
||||
isAllowNegativeCoordinates() {
|
||||
return this.allowNegativeCoordinates;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link allowNegativeCoordinates}.
|
||||
*/
|
||||
setAllowNegativeCoordinates(value: boolean) {
|
||||
setAllowNegativeCoordinates(value) {
|
||||
this.allowNegativeCoordinates = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: insertVertex
|
||||
|
@ -77,7 +116,7 @@ class GraphVertex extends autoImplement<PartialClass>() {
|
|||
* geometryClass - Optional class reference to a class derived from mxGeometry.
|
||||
* This can be useful for defining custom constraints.
|
||||
*/
|
||||
insertVertex = (...args: any[]) => {
|
||||
insertVertex(...args) {
|
||||
let parent;
|
||||
let id;
|
||||
let value;
|
||||
|
@ -124,7 +163,7 @@ class GraphVertex extends autoImplement<PartialClass>() {
|
|||
);
|
||||
|
||||
return this.addCell(vertex, parent);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: createVertex
|
||||
|
@ -132,16 +171,16 @@ class GraphVertex extends autoImplement<PartialClass>() {
|
|||
* Hook method that creates the new vertex for <insertVertex>.
|
||||
*/
|
||||
createVertex(
|
||||
parent: Cell,
|
||||
id: string,
|
||||
value: any,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
style: any,
|
||||
relative: boolean = false,
|
||||
geometryClass: typeof Geometry = Geometry
|
||||
parent,
|
||||
id,
|
||||
value,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
style,
|
||||
relative = false,
|
||||
geometryClass = Geometry
|
||||
) {
|
||||
// Creates the geometry for the vertex
|
||||
const geometry = new geometryClass(x, y, width, height);
|
||||
|
@ -154,16 +193,16 @@ class GraphVertex extends autoImplement<PartialClass>() {
|
|||
vertex.setConnectable(true);
|
||||
|
||||
return vertex;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the visible child vertices of the given parent.
|
||||
*
|
||||
* @param parent {@link mxCell} whose children should be returned.
|
||||
*/
|
||||
getChildVertices(parent: Cell) {
|
||||
getChildVertices(parent) {
|
||||
return this.getChildCells(parent, true, false);
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph Behaviour
|
||||
|
@ -174,14 +213,14 @@ class GraphVertex extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isVertexLabelsMovable() {
|
||||
return this.vertexLabelsMovable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link vertexLabelsMovable}.
|
||||
*/
|
||||
setVertexLabelsMovable(value: boolean) {
|
||||
setVertexLabelsMovable(value) {
|
||||
this.vertexLabelsMovable = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphVertex;
|
||||
mixInto(Graph)(GraphVertexMixin);
|
|
@ -25,7 +25,7 @@ import ImageBox from '../../image/ImageBox';
|
|||
import CellState from '../datatypes/CellState';
|
||||
import CellArray from '../datatypes/CellArray';
|
||||
|
||||
import type { MaxGraph } from '../../Graph';
|
||||
import type { Graph } from '../../Graph';
|
||||
import type { CellHandle, CellStateStyles } from '../../../types';
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ class VertexHandle implements CellHandle {
|
|||
this.init();
|
||||
}
|
||||
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
state: CellState;
|
||||
shape: Shape | ImageShape | null;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import Point from '../../geometry/Point';
|
|||
import { getRotatedPoint, intersects, mod, toRadians } from '../../../util/Utils';
|
||||
import mxClient from '../../../mxClient';
|
||||
import { isMouseEvent, isShiftDown } from '../../../util/EventUtils';
|
||||
import { MaxGraph } from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellState from '../datatypes/CellState';
|
||||
import Image from '../../image/ImageBox';
|
||||
import Cell from '../datatypes/Cell';
|
||||
|
@ -74,7 +74,7 @@ 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 = this.state.style.rotation ?? 0;
|
||||
this.selectionBorder.init(this.graph.getView().getOverlayPane());
|
||||
InternalEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
|
||||
|
||||
|
@ -193,7 +193,7 @@ class VertexHandler {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: state
|
||||
|
@ -2009,7 +2009,7 @@ class VertexHandler {
|
|||
}
|
||||
|
||||
if (this.selectionBorder != null) {
|
||||
this.selectionBorder.rotation = Number(this.state.style.rotation || '0');
|
||||
this.selectionBorder.rotation = this.state.style.rotation ?? 0;
|
||||
}
|
||||
|
||||
if (this.edgeHandlers != null) {
|
||||
|
@ -2096,7 +2096,7 @@ class VertexHandler {
|
|||
// 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 = pstate.style.rotation ?? 0;
|
||||
this.parentHighlight.init(this.graph.getView().getOverlayPane());
|
||||
this.parentHighlight.redraw();
|
||||
|
||||
|
@ -2122,7 +2122,7 @@ class VertexHandler {
|
|||
this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1);
|
||||
}
|
||||
|
||||
this.preview.rotation = Number(this.state.style.rotation || '0');
|
||||
this.preview.rotation = this.state.style.rotation ?? 0;
|
||||
this.preview.redraw();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,7 @@ import {
|
|||
TOOLTIP_VERTICAL_OFFSET,
|
||||
VALID_COLOR,
|
||||
} from '../../util/Constants';
|
||||
import utils, {
|
||||
convertPoint,
|
||||
getOffset,
|
||||
getRotatedPoint,
|
||||
getValue,
|
||||
toRadians,
|
||||
} from '../../util/Utils';
|
||||
import { convertPoint, getOffset, getRotatedPoint, getValue } from '../../util/Utils';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import ImageShape from '../geometry/shape/node/ImageShape';
|
||||
import CellMarker from '../cell/CellMarker';
|
||||
|
@ -42,10 +36,9 @@ import {
|
|||
isConsumed,
|
||||
isShiftDown,
|
||||
} from '../../util/EventUtils';
|
||||
import graph, { MaxGraph } from '../Graph';
|
||||
import Image from '../image/ImageBox';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import ConnectionConstraint from './ConnectionConstraint';
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
import { GraphPlugin, Listenable } from '../../types';
|
||||
|
@ -212,7 +205,7 @@ type FactoryMethod = (source: Cell | null, target: Cell | null, style?: string)
|
|||
class ConnectionHandler extends EventSource implements GraphPlugin {
|
||||
static pluginId = 'ConnectionHandler';
|
||||
|
||||
constructor(graph: MaxGraph, factoryMethod: FactoryMethod | null = null) {
|
||||
constructor(graph: Graph, factoryMethod: FactoryMethod | null = null) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -279,7 +272,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: factoryMethod
|
||||
|
|
|
@ -20,7 +20,7 @@ import Rectangle from '../geometry/Rectangle';
|
|||
import ImageShape from '../geometry/shape/node/ImageShape';
|
||||
import RectangleShape from '../geometry/shape/node/RectangleShape';
|
||||
import { isShiftDown } from '../../util/EventUtils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import ConnectionConstraint from './ConnectionConstraint';
|
||||
|
@ -35,7 +35,7 @@ import Cell from '../cell/datatypes/Cell';
|
|||
* @class ConstraintHandler
|
||||
*/
|
||||
class ConstraintHandler {
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.graph = graph;
|
||||
|
||||
// Adds a graph model listener to update the current focus on changes
|
||||
|
@ -66,7 +66,7 @@ class ConstraintHandler {
|
|||
/**
|
||||
* Reference to the enclosing {@link mxGraph}.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
resetHandler: () => void;
|
||||
|
||||
|
|
|
@ -4,59 +4,143 @@ import InternalMouseEvent from '../event/InternalMouseEvent';
|
|||
import ConnectionConstraint from './ConnectionConstraint';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import { DIRECTION_NORTH, DIRECTION_SOUTH, DIRECTION_WEST } from '../../util/Constants';
|
||||
import utils, {
|
||||
autoImplement,
|
||||
getRotatedPoint,
|
||||
getValue,
|
||||
toRadians,
|
||||
} from '../../util/Utils';
|
||||
import { getRotatedPoint, mixInto, toRadians } from '../../util/Utils';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Dictionary from '../../util/Dictionary';
|
||||
import Geometry from '../geometry/Geometry';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import ConnectionHandler from './ConnectionHandler';
|
||||
import GraphCells from '../cell/GraphCells';
|
||||
import GraphPorts from '../ports/GraphPorts';
|
||||
import GraphEdge from '../cell/edge/GraphEdge';
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getView' | 'getModel' | 'fireEvent'>;
|
||||
type PartialCells = Pick<GraphCells, 'setCellStyles' | 'isCellLocked'>;
|
||||
type PartialPorts = Pick<GraphPorts, 'isPortsEnabled' | 'isPort' | 'getTerminalForPort'>;
|
||||
type PartialEdge = Pick<
|
||||
GraphEdge,
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
connectionHandler: ConnectionHandler | null;
|
||||
constrainChildren: boolean;
|
||||
constrainRelativeChildren: boolean;
|
||||
disconnectOnMove: boolean;
|
||||
cellsDisconnectable: boolean;
|
||||
|
||||
getConnectionHandler: () => ConnectionHandler | null;
|
||||
setConnectionHandler: (connectionHandler: ConnectionHandler) => void;
|
||||
getOutlineConstraint: (
|
||||
point: Point,
|
||||
terminalState: CellState,
|
||||
me: InternalMouseEvent
|
||||
) => ConnectionConstraint | null;
|
||||
getAllConnectionConstraints: (
|
||||
terminal: CellState | null,
|
||||
source: boolean
|
||||
) => ConnectionConstraint[] | null;
|
||||
getConnectionConstraint: (
|
||||
edge: CellState,
|
||||
terminal: CellState | null,
|
||||
source: boolean
|
||||
) => ConnectionConstraint;
|
||||
setConnectionConstraint: (
|
||||
edge: Cell,
|
||||
terminal: Cell | null,
|
||||
source: boolean,
|
||||
constraint: ConnectionConstraint | null
|
||||
) => void;
|
||||
getConnectionPoint: (
|
||||
vertex: CellState,
|
||||
constraint: ConnectionConstraint,
|
||||
round?: boolean
|
||||
) => Point | null;
|
||||
connectCell: (
|
||||
edge: Cell,
|
||||
terminal: Cell | null,
|
||||
source: boolean,
|
||||
constraint?: ConnectionConstraint | null
|
||||
) => Cell;
|
||||
cellConnected: (
|
||||
edge: Cell,
|
||||
terminal: Cell | null,
|
||||
source: boolean,
|
||||
constraint?: ConnectionConstraint | null
|
||||
) => void;
|
||||
disconnectGraph: (cells: CellArray) => void;
|
||||
getConnections: (cell: Cell, parent: Cell | null) => CellArray;
|
||||
isConstrainChild: (cell: Cell) => boolean;
|
||||
isConstrainChildren: () => boolean;
|
||||
setConstrainChildren: (value: boolean) => void;
|
||||
isConstrainRelativeChildren: () => boolean;
|
||||
setConstrainRelativeChildren: (value: boolean) => void;
|
||||
isDisconnectOnMove: () => boolean;
|
||||
setDisconnectOnMove: (value: boolean) => void;
|
||||
isCellDisconnectable: (cell: Cell, terminal: Cell | null, source: boolean) => boolean;
|
||||
isCellsDisconnectable: () => boolean;
|
||||
setCellsDisconnectable: (value: boolean) => void;
|
||||
isValidSource: (cell: Cell | null) => boolean;
|
||||
isValidTarget: (cell: Cell | null) => boolean;
|
||||
isValidConnection: (source: Cell | null, target: Cell | null) => boolean;
|
||||
setConnectable: (connectable: boolean) => void;
|
||||
isConnectable: () => boolean;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getView' | 'getModel' | 'isPortsEnabled'>;
|
||||
type PartialConnections = Pick<
|
||||
Graph,
|
||||
| 'connectionHandler'
|
||||
| 'constrainChildren'
|
||||
| 'constrainRelativeChildren'
|
||||
| 'disconnectOnMove'
|
||||
| 'cellsDisconnectable'
|
||||
| 'getConnectionHandler'
|
||||
| 'setConnectionHandler'
|
||||
| 'getOutlineConstraint'
|
||||
| 'getAllConnectionConstraints'
|
||||
| 'getConnectionConstraint'
|
||||
| 'setConnectionConstraint'
|
||||
| 'getConnectionPoint'
|
||||
| 'connectCell'
|
||||
| 'cellConnected'
|
||||
| 'disconnectGraph'
|
||||
| 'getConnections'
|
||||
| 'isConstrainChild'
|
||||
| 'isConstrainChildren'
|
||||
| 'setConstrainChildren'
|
||||
| 'isConstrainRelativeChildren'
|
||||
| 'setConstrainRelativeChildren'
|
||||
| 'isDisconnectOnMove'
|
||||
| 'setDisconnectOnMove'
|
||||
| 'isCellDisconnectable'
|
||||
| 'isCellsDisconnectable'
|
||||
| 'setCellsDisconnectable'
|
||||
| 'isValidSource'
|
||||
| 'isValidTarget'
|
||||
| 'isValidConnection'
|
||||
| 'setConnectable'
|
||||
| 'isConnectable'
|
||||
| 'setCellStyles'
|
||||
| 'fireEvent'
|
||||
| 'isPort'
|
||||
| 'getTerminalForPort'
|
||||
| 'isResetEdgesOnConnect'
|
||||
| 'resetEdge'
|
||||
| 'getEdges'
|
||||
| 'isCellLocked'
|
||||
| 'isAllowDanglingEdges'
|
||||
| 'isConnectableEdges'
|
||||
>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialPorts & PartialEdge;
|
||||
type PartialType = PartialGraph & PartialConnections;
|
||||
|
||||
// @ts-ignore recursive reference error
|
||||
class GraphConnections extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphConnectionsMixin: PartialType = {
|
||||
/*****************************************************************************
|
||||
* Group: Cell connecting and connection constraints
|
||||
*****************************************************************************/
|
||||
|
||||
connectionHandler: ConnectionHandler | null = null;
|
||||
|
||||
getConnectionHandler() {
|
||||
return this.connectionHandler;
|
||||
}
|
||||
|
||||
setConnectionHandler(connectionHandler: ConnectionHandler) {
|
||||
this.connectionHandler = connectionHandler;
|
||||
}
|
||||
connectionHandler: null,
|
||||
|
||||
/**
|
||||
* Specifies if a child should be constrained inside the parent bounds after a
|
||||
* move or resize of the child.
|
||||
* @default true
|
||||
*/
|
||||
constrainChildren = true;
|
||||
constrainChildren: true,
|
||||
|
||||
/**
|
||||
* Specifies if child cells with relative geometries should be constrained
|
||||
|
@ -64,21 +148,29 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* {@link maximumGraphBounds}.
|
||||
* @default false
|
||||
*/
|
||||
constrainRelativeChildren = false;
|
||||
constrainRelativeChildren: false,
|
||||
|
||||
/**
|
||||
* Specifies if edges should be disconnected from their terminals when they
|
||||
* are moved.
|
||||
* @default true
|
||||
*/
|
||||
disconnectOnMove = true;
|
||||
disconnectOnMove: true,
|
||||
|
||||
cellsDisconnectable = true;
|
||||
cellsDisconnectable: true,
|
||||
|
||||
getConnectionHandler() {
|
||||
return this.connectionHandler;
|
||||
},
|
||||
|
||||
setConnectionHandler(connectionHandler) {
|
||||
this.connectionHandler = connectionHandler;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the constraint used to connect to the outline of the given state.
|
||||
*/
|
||||
getOutlineConstraint(point: Point, terminalState: CellState, me: InternalMouseEvent) {
|
||||
getOutlineConstraint(point, terminalState, me) {
|
||||
if (terminalState.shape) {
|
||||
const bounds = <Rectangle>this.getView().getPerimeterBounds(terminalState);
|
||||
const direction = terminalState.style.direction;
|
||||
|
@ -145,7 +237,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
return new ConnectionConstraint(new Point(x, y), false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of all {@link mxConnectionConstraints} for the given terminal. If
|
||||
|
@ -155,12 +247,12 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param terminal {@link mxCellState} that represents the terminal.
|
||||
* @param source Boolean that specifies if the terminal is the source or target.
|
||||
*/
|
||||
getAllConnectionConstraints(terminal: CellState | null, source: boolean) {
|
||||
getAllConnectionConstraints(terminal, source) {
|
||||
if (terminal && terminal.shape && terminal.shape.stencil) {
|
||||
return terminal.shape.stencil.constraints;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an {@link ConnectionConstraint} that describes the given connection
|
||||
|
@ -170,11 +262,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param terminal {@link mxCellState} that represents the terminal.
|
||||
* @param source Boolean indicating if the terminal is the source or target.
|
||||
*/
|
||||
getConnectionConstraint(
|
||||
edge: CellState,
|
||||
terminal: CellState | null,
|
||||
source: boolean = false
|
||||
) {
|
||||
getConnectionConstraint(edge, terminal, source = false) {
|
||||
let point: Point | null = null;
|
||||
|
||||
const x = edge.style[source ? 'exitX' : 'entryX'];
|
||||
|
@ -203,7 +291,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return new ConnectionConstraint(point, perimeter, null, dx, dy);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the {@link ConnectionConstraint} that describes the given connection point.
|
||||
|
@ -216,12 +304,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param constraint Optional {@link ConnectionConstraint} to be used for this
|
||||
* connection.
|
||||
*/
|
||||
setConnectionConstraint(
|
||||
edge: Cell,
|
||||
terminal: Cell | null,
|
||||
source: boolean = false,
|
||||
constraint: ConnectionConstraint | null = null
|
||||
) {
|
||||
setConnectionConstraint(edge, terminal, source = false, constraint = null) {
|
||||
if (constraint) {
|
||||
this.getModel().beginUpdate();
|
||||
|
||||
|
@ -277,7 +360,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
this.getModel().endUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the nearest point in the list of absolute points or the center
|
||||
|
@ -287,11 +370,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param constraint {@link mxConnectionConstraint} that represents the connection point
|
||||
* constraint as returned by {@link getConnectionConstraint}.
|
||||
*/
|
||||
getConnectionPoint(
|
||||
vertex: CellState,
|
||||
constraint: ConnectionConstraint,
|
||||
round: boolean = true
|
||||
) {
|
||||
getConnectionPoint(vertex, constraint, round = true) {
|
||||
let point: Point | null = null;
|
||||
|
||||
if (constraint.point) {
|
||||
|
@ -381,7 +460,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
point.y = Math.round(point.y);
|
||||
}
|
||||
return point;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Connects the specified end of the given edge to the given terminal
|
||||
|
@ -394,12 +473,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param constraint Optional {@link ConnectionConstraint} to be used for this
|
||||
* connection.
|
||||
*/
|
||||
connectCell(
|
||||
edge: Cell,
|
||||
terminal: Cell | null = null,
|
||||
source: boolean = false,
|
||||
constraint: ConnectionConstraint | null = null
|
||||
) {
|
||||
connectCell(edge, terminal = null, source = false, constraint = null) {
|
||||
this.getModel().beginUpdate();
|
||||
try {
|
||||
const previous = edge.getTerminal(source);
|
||||
|
@ -421,7 +495,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
this.getModel().endUpdate();
|
||||
}
|
||||
return edge;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the new terminal for the given edge and resets the edge points if
|
||||
|
@ -433,12 +507,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param source Boolean indicating if the new terminal is the source or target.
|
||||
* @param constraint {@link mxConnectionConstraint} to be used for this connection.
|
||||
*/
|
||||
cellConnected(
|
||||
edge: Cell,
|
||||
terminal: Cell | null,
|
||||
source: boolean = false,
|
||||
constraint: ConnectionConstraint | null = null
|
||||
) {
|
||||
cellConnected(edge, terminal, source = false, constraint = null) {
|
||||
this.getModel().beginUpdate();
|
||||
try {
|
||||
const previous = edge.getTerminal(source);
|
||||
|
@ -483,7 +552,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
} finally {
|
||||
this.getModel().endUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnects the given edges from the terminals which are not in the
|
||||
|
@ -491,7 +560,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cells Array of {@link Cell} to be disconnected.
|
||||
*/
|
||||
disconnectGraph(cells: CellArray) {
|
||||
disconnectGraph(cells) {
|
||||
this.getModel().beginUpdate();
|
||||
try {
|
||||
const { scale, translate: tr } = this.getView();
|
||||
|
@ -564,7 +633,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
} finally {
|
||||
this.getModel().endUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns all visible edges connected to the given cell without loops.
|
||||
|
@ -573,9 +642,9 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param parent Optional parent of the opposite end for a connection to be
|
||||
* returned.
|
||||
*/
|
||||
getConnections(cell: Cell, parent: Cell | null = null) {
|
||||
getConnections(cell, parent = null) {
|
||||
return this.getEdges(cell, parent, true, true, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell should be kept inside the bounds of its
|
||||
|
@ -585,41 +654,41 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} that should be constrained.
|
||||
*/
|
||||
isConstrainChild(cell: Cell) {
|
||||
isConstrainChild(cell) {
|
||||
return (
|
||||
this.isConstrainChildren() &&
|
||||
!!cell.getParent() &&
|
||||
!(<Cell>cell.getParent()).isEdge()
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link constrainChildren}.
|
||||
*/
|
||||
isConstrainChildren() {
|
||||
return this.constrainChildren;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link constrainChildren}.
|
||||
*/
|
||||
setConstrainChildren(value: boolean) {
|
||||
setConstrainChildren(value) {
|
||||
this.constrainChildren = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link constrainRelativeChildren}.
|
||||
*/
|
||||
isConstrainRelativeChildren() {
|
||||
return this.constrainRelativeChildren;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link constrainRelativeChildren}.
|
||||
*/
|
||||
setConstrainRelativeChildren(value: boolean) {
|
||||
setConstrainRelativeChildren(value) {
|
||||
this.constrainRelativeChildren = value;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -630,7 +699,7 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isDisconnectOnMove() {
|
||||
return this.disconnectOnMove;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if edges should be disconnected when moved. (Note: Cloned
|
||||
|
@ -639,9 +708,9 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param value Boolean indicating if edges should be disconnected
|
||||
* when moved.
|
||||
*/
|
||||
setDisconnectOnMove(value: boolean) {
|
||||
setDisconnectOnMove(value) {
|
||||
this.disconnectOnMove = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell is disconnectable from the source or
|
||||
|
@ -653,27 +722,23 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param source Boolean indicating if the source or target terminal is to be
|
||||
* disconnected.
|
||||
*/
|
||||
isCellDisconnectable(
|
||||
cell: Cell,
|
||||
terminal: Cell | null = null,
|
||||
source: boolean = false
|
||||
) {
|
||||
isCellDisconnectable(cell, terminal = null, source = false) {
|
||||
return this.isCellsDisconnectable() && !this.isCellLocked(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link cellsDisconnectable}.
|
||||
*/
|
||||
isCellsDisconnectable() {
|
||||
return this.cellsDisconnectable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link cellsDisconnectable}.
|
||||
*/
|
||||
setCellsDisconnectable(value: boolean) {
|
||||
setCellsDisconnectable(value) {
|
||||
this.cellsDisconnectable = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell is a valid source for new connections.
|
||||
|
@ -682,14 +747,14 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} that represents a possible source or null.
|
||||
*/
|
||||
isValidSource(cell: Cell | null) {
|
||||
isValidSource(cell) {
|
||||
return (
|
||||
(cell == null && this.isAllowDanglingEdges()) ||
|
||||
(cell != null &&
|
||||
(!cell.isEdge() || this.isConnectableEdges()) &&
|
||||
cell.isConnectable())
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link isValidSource} for the given cell. This is called by
|
||||
|
@ -697,9 +762,9 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} that represents a possible target or null.
|
||||
*/
|
||||
isValidTarget(cell: Cell | null): boolean {
|
||||
isValidTarget(cell) {
|
||||
return this.isValidSource(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given target cell is a valid target for source.
|
||||
|
@ -711,9 +776,9 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
* @param source {@link mxCell} that represents the source cell.
|
||||
* @param target {@link mxCell} that represents the target cell.
|
||||
*/
|
||||
isValidConnection(source: Cell | null, target: Cell | null): boolean {
|
||||
isValidConnection(source, target) {
|
||||
return this.isValidSource(source) && this.isValidTarget(target);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the graph should allow new connections. This implementation
|
||||
|
@ -721,16 +786,16 @@ class GraphConnections extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param connectable Boolean indicating if new connections should be allowed.
|
||||
*/
|
||||
setConnectable(connectable: boolean) {
|
||||
setConnectable(connectable) {
|
||||
(<ConnectionHandler>this.connectionHandler).setEnabled(connectable);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the {@link connectionHandler} is enabled.
|
||||
*/
|
||||
isConnectable() {
|
||||
return (<ConnectionHandler>this.connectionHandler).isEnabled();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphConnections;
|
||||
mixInto(Graph)(GraphConnectionsMixin);
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import CellHighlight from '../selection/CellHighlight';
|
||||
import utils, {
|
||||
import {
|
||||
getDocumentScrollOrigin,
|
||||
getOffset,
|
||||
getScrollOrigin,
|
||||
|
@ -28,15 +28,13 @@ import {
|
|||
} from '../../util/EventUtils';
|
||||
import EventSource from '../event/EventSource';
|
||||
import EventObject from '../event/EventObject';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { Graph } from '../Graph';
|
||||
import Guide from '../../util/Guide';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import { GraphPlugin } from '../../types';
|
||||
import GraphHandler from '../GraphHandler';
|
||||
|
||||
type DropHandler = (
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
evt: MouseEvent,
|
||||
cell: Cell | null,
|
||||
x?: number,
|
||||
|
@ -123,7 +121,7 @@ class DragSource {
|
|||
/**
|
||||
* Reference to the {@link mxGraph} that is the current drop target.
|
||||
*/
|
||||
currentGraph: MaxGraph | null = null;
|
||||
currentGraph: Graph | null = null;
|
||||
|
||||
/**
|
||||
* Holds the current drop target under the mouse.
|
||||
|
@ -241,7 +239,7 @@ class DragSource {
|
|||
* Returns the drop target for the given graph and coordinates. This
|
||||
* implementation uses {@link mxGraph.getCellAt}.
|
||||
*/
|
||||
getDropTarget(graph: MaxGraph, x: number, y: number, evt: MouseEvent) {
|
||||
getDropTarget(graph: Graph, x: number, y: number, evt: MouseEvent) {
|
||||
return graph.getCellAt(x, y);
|
||||
}
|
||||
|
||||
|
@ -257,7 +255,7 @@ class DragSource {
|
|||
* Creates and returns an element which can be used as a preview in the given
|
||||
* graph.
|
||||
*/
|
||||
createPreviewElement(graph: MaxGraph): HTMLElement | null {
|
||||
createPreviewElement(graph: Graph): HTMLElement | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -378,7 +376,7 @@ class DragSource {
|
|||
/**
|
||||
* Returns true if the given graph contains the given event.
|
||||
*/
|
||||
graphContainsEvent(graph: MaxGraph, evt: MouseEvent) {
|
||||
graphContainsEvent(graph: Graph, evt: MouseEvent) {
|
||||
const x = getClientX(evt);
|
||||
const y = getClientY(evt);
|
||||
const offset = getOffset(graph.container);
|
||||
|
@ -516,7 +514,7 @@ class DragSource {
|
|||
/**
|
||||
* Actives the given graph as a drop target.
|
||||
*/
|
||||
dragEnter(graph: MaxGraph, evt: MouseEvent) {
|
||||
dragEnter(graph: Graph, evt: MouseEvent) {
|
||||
graph.isMouseDown = true;
|
||||
graph.isMouseTrigger = isMouseEvent(evt);
|
||||
this.previewElement = this.createPreviewElement(graph);
|
||||
|
@ -542,7 +540,7 @@ class DragSource {
|
|||
/**
|
||||
* Deactivates the given graph as a drop target.
|
||||
*/
|
||||
dragExit(graph: MaxGraph, evt?: MouseEvent) {
|
||||
dragExit(graph: Graph, evt?: MouseEvent) {
|
||||
this.currentDropTarget = null;
|
||||
this.currentPoint = null;
|
||||
graph.isMouseDown = false;
|
||||
|
@ -573,7 +571,7 @@ class DragSource {
|
|||
* Implements autoscroll, updates the {@link currentPoint}, highlights any drop
|
||||
* targets and updates the preview.
|
||||
*/
|
||||
dragOver(graph: MaxGraph, evt: MouseEvent) {
|
||||
dragOver(graph: Graph, evt: MouseEvent) {
|
||||
const offset = getOffset(graph.container);
|
||||
const origin = getScrollOrigin(graph.container);
|
||||
let x = getClientX(evt) - offset.x + origin.x - graph.getPanDx();
|
||||
|
@ -646,7 +644,7 @@ class DragSource {
|
|||
* implementation uses {@link mxGraph.getCellAt}.
|
||||
*/
|
||||
drop(
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
evt: MouseEvent,
|
||||
dropTarget: Cell | null = null,
|
||||
x: number,
|
||||
|
|
|
@ -1,19 +1,49 @@
|
|||
import { autoImplement } from '../../util/Utils';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
import type GraphValidation from '../validation/GraphValidation';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
dropEnabled: boolean;
|
||||
splitEnabled: boolean;
|
||||
autoScroll: boolean;
|
||||
autoExtend: boolean;
|
||||
|
||||
type PartialValidation = Pick<GraphValidation, 'getEdgeValidationError'>;
|
||||
type PartialClass = PartialValidation;
|
||||
isAutoScroll: () => boolean;
|
||||
isAutoExtend: () => boolean;
|
||||
isDropEnabled: () => boolean;
|
||||
setDropEnabled: (value: boolean) => void;
|
||||
isSplitEnabled: () => boolean;
|
||||
setSplitEnabled: (value: boolean) => void;
|
||||
isSplitTarget: (target: Cell, cells: CellArray, evt: MouseEvent) => boolean;
|
||||
}
|
||||
}
|
||||
|
||||
class GraphDragDrop extends autoImplement<PartialClass>() {
|
||||
type PartialGraph = Pick<Graph, 'getEdgeValidationError'>;
|
||||
type PartialDragDrop = Pick<
|
||||
Graph,
|
||||
| 'dropEnabled'
|
||||
| 'splitEnabled'
|
||||
| 'autoScroll'
|
||||
| 'autoExtend'
|
||||
| 'isAutoScroll'
|
||||
| 'isAutoExtend'
|
||||
| 'isDropEnabled'
|
||||
| 'setDropEnabled'
|
||||
| 'isSplitEnabled'
|
||||
| 'setSplitEnabled'
|
||||
| 'isSplitTarget'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialDragDrop;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphDragDropMixin: PartialType = {
|
||||
/**
|
||||
* Specifies the return value for {@link isDropEnabled}.
|
||||
* @default false
|
||||
*/
|
||||
dropEnabled = false;
|
||||
dropEnabled: false,
|
||||
|
||||
/**
|
||||
* Specifies if dropping onto edges should be enabled. This is ignored if
|
||||
|
@ -21,7 +51,7 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* out the drop operation.
|
||||
* @default true
|
||||
*/
|
||||
splitEnabled = true;
|
||||
splitEnabled: true,
|
||||
|
||||
/**
|
||||
* Specifies if the graph should automatically scroll if the mouse goes near
|
||||
|
@ -33,9 +63,11 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* no scrollbars, the use of {@link allowAutoPanning} is recommended.
|
||||
* @default true
|
||||
*/
|
||||
autoScroll = true;
|
||||
autoScroll: true,
|
||||
|
||||
isAutoScroll = () => this.autoScroll;
|
||||
isAutoScroll() {
|
||||
return this.autoScroll;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the size of the graph should be automatically extended if the
|
||||
|
@ -43,9 +75,11 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* account if the container has scrollbars. See {@link autoScroll}.
|
||||
* @default true
|
||||
*/
|
||||
autoExtend = true;
|
||||
autoExtend: true,
|
||||
|
||||
isAutoExtend = () => this.autoExtend;
|
||||
isAutoExtend() {
|
||||
return this.autoExtend;
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -56,7 +90,7 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isDropEnabled() {
|
||||
return this.dropEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the graph should allow dropping of cells onto or into other
|
||||
|
@ -65,9 +99,9 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* @param dropEnabled Boolean indicating if the graph should allow dropping
|
||||
* of cells into other cells.
|
||||
*/
|
||||
setDropEnabled(value: boolean) {
|
||||
setDropEnabled(value) {
|
||||
this.dropEnabled = value;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Split behaviour
|
||||
|
@ -78,7 +112,7 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isSplitEnabled() {
|
||||
return this.splitEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the graph should allow dropping of cells onto or into other
|
||||
|
@ -87,9 +121,9 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* @param dropEnabled Boolean indicating if the graph should allow dropping
|
||||
* of cells into other cells.
|
||||
*/
|
||||
setSplitEnabled(value: boolean) {
|
||||
setSplitEnabled(value) {
|
||||
this.splitEnabled = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given edge may be splitted into two edges with the
|
||||
|
@ -99,7 +133,7 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
* @param cells {@link mxCell} that should split the edge.
|
||||
* @param evt Mouseevent that triggered the invocation.
|
||||
*/
|
||||
isSplitTarget(target: Cell, cells: CellArray, evt: MouseEvent) {
|
||||
isSplitTarget(target, cells, evt) {
|
||||
if (
|
||||
target.isEdge() &&
|
||||
cells.length === 1 &&
|
||||
|
@ -112,7 +146,7 @@ class GraphDragDrop extends autoImplement<PartialClass>() {
|
|||
return !cells[0].isAncestor(src) && !cells[0].isAncestor(trg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphDragDrop;
|
||||
mixInto(Graph)(GraphDragDropMixin);
|
|
@ -48,7 +48,7 @@ import {
|
|||
} from '../../util/EventUtils';
|
||||
import EventSource from '../event/EventSource';
|
||||
|
||||
import type { MaxGraph } from '../Graph';
|
||||
import type { Graph } from '../Graph';
|
||||
import type { GraphPlugin } from '../../types';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import TooltipHandler from '../tooltip/TooltipHandler';
|
||||
|
@ -162,7 +162,7 @@ import TooltipHandler from '../tooltip/TooltipHandler';
|
|||
class CellEditor implements GraphPlugin {
|
||||
static pluginId = 'CellEditor';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.graph = graph;
|
||||
|
||||
// Stops editing after zoom changes
|
||||
|
@ -202,7 +202,7 @@ class CellEditor implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: textarea
|
||||
|
|
|
@ -3,32 +3,62 @@ import { isMultiTouchEvent } from '../../util/EventUtils';
|
|||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type GraphSelection from '../selection/GraphSelection';
|
||||
import type GraphEvents from '../event/GraphEvents';
|
||||
import type Graph from '../Graph';
|
||||
import type GraphCells from '../cell/GraphCells';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
cellsEditable: boolean;
|
||||
|
||||
startEditing: (evt: MouseEvent) => void;
|
||||
startEditingAtCell: (cell: Cell | null, evt: MouseEvent) => void;
|
||||
getEditingValue: (cell: Cell, evt: MouseEvent | null) => string;
|
||||
stopEditing: (cancel: boolean) => void;
|
||||
labelChanged: (cell: Cell, value: any, evt: InternalMouseEvent | EventObject) => Cell;
|
||||
cellLabelChanged: (cell: Cell, value: any, autoSize: boolean) => void;
|
||||
isEditing: (cell?: Cell | null) => boolean;
|
||||
isCellEditable: (cell: Cell) => boolean;
|
||||
isCellsEditable: () => boolean;
|
||||
setCellsEditable: (value: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'getCellEditor' | 'convertValueToString' | 'batchUpdate' | 'getModel'
|
||||
| 'getCellEditor'
|
||||
| 'convertValueToString'
|
||||
| 'batchUpdate'
|
||||
| 'getModel'
|
||||
| 'getSelectionCell'
|
||||
| 'fireEvent'
|
||||
| 'isAutoSizeCell'
|
||||
| 'cellSizeUpdated'
|
||||
| 'getCurrentCellStyle'
|
||||
| 'isCellLocked'
|
||||
>;
|
||||
type PartialSelection = Pick<GraphSelection, 'getSelectionCell'>;
|
||||
type PartialEvents = Pick<GraphEvents, 'fireEvent'>;
|
||||
type PartialCells = Pick<
|
||||
GraphCells,
|
||||
'isAutoSizeCell' | 'cellSizeUpdated' | 'getCurrentCellStyle' | 'isCellLocked'
|
||||
type PartialEditing = Pick<
|
||||
Graph,
|
||||
| 'cellsEditable'
|
||||
| 'startEditing'
|
||||
| 'startEditingAtCell'
|
||||
| 'getEditingValue'
|
||||
| 'stopEditing'
|
||||
| 'labelChanged'
|
||||
| 'cellLabelChanged'
|
||||
| 'isEditing'
|
||||
| 'isCellEditable'
|
||||
| 'isCellsEditable'
|
||||
| 'setCellsEditable'
|
||||
>;
|
||||
type PartialClass = PartialGraph & PartialSelection & PartialEvents & PartialCells;
|
||||
type PartialType = PartialGraph & PartialEditing;
|
||||
|
||||
// @ts-ignore recursive reference error
|
||||
class GraphEditing extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphEditingMixin: PartialType = {
|
||||
/**
|
||||
* Specifies the return value for {@link isCellEditable}.
|
||||
* @default true
|
||||
*/
|
||||
cellsEditable = true;
|
||||
cellsEditable: true,
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Cell in-place editing
|
||||
|
@ -40,9 +70,9 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param evt Optional mouse event that triggered the editing.
|
||||
*/
|
||||
startEditing(evt: MouseEvent) {
|
||||
startEditing(evt) {
|
||||
this.startEditingAtCell(null, evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fires a {@link startEditing} event and invokes {@link CellEditor.startEditing}
|
||||
|
@ -52,7 +82,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} to start the in-place editor for.
|
||||
* @param evt Optional mouse event that triggered the editing.
|
||||
*/
|
||||
startEditingAtCell(cell: Cell | null = null, evt: MouseEvent) {
|
||||
startEditingAtCell(cell = null, evt) {
|
||||
if (!evt || !isMultiTouchEvent(evt)) {
|
||||
if (!cell) {
|
||||
cell = this.getSelectionCell();
|
||||
|
@ -70,7 +100,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the initial value for in-place editing. This implementation
|
||||
|
@ -81,9 +111,9 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} for which the initial editing value should be returned.
|
||||
* @param evt Optional mouse event that triggered the editor.
|
||||
*/
|
||||
getEditingValue(cell: Cell, evt: MouseEvent | null) {
|
||||
getEditingValue(cell, evt) {
|
||||
return this.convertValueToString(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the current editing and fires a {@link editingStopped} event.
|
||||
|
@ -91,10 +121,10 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param cancel Boolean that specifies if the current editing value
|
||||
* should be stored.
|
||||
*/
|
||||
stopEditing(cancel: boolean = false) {
|
||||
stopEditing(cancel = false) {
|
||||
this.getCellEditor().stopEditing(cancel);
|
||||
this.fireEvent(new EventObject(InternalEvent.EDITING_STOPPED, 'cancel', cancel));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the label of the specified cell to the given value using
|
||||
|
@ -105,7 +135,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param value New label to be assigned.
|
||||
* @param evt Optional event that triggered the change.
|
||||
*/
|
||||
labelChanged(cell: Cell, value: any, evt: InternalMouseEvent | EventObject) {
|
||||
labelChanged(cell, value, evt) {
|
||||
this.batchUpdate(() => {
|
||||
const old = cell.value;
|
||||
this.cellLabelChanged(cell, value, this.isAutoSizeCell(cell));
|
||||
|
@ -119,7 +149,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
);
|
||||
});
|
||||
return cell;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the new label for a cell. If autoSize is true then
|
||||
|
@ -148,7 +178,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param value New label to be assigned.
|
||||
* @param autoSize Boolean that specifies if {@link cellSizeUpdated} should be called.
|
||||
*/
|
||||
cellLabelChanged(cell: Cell, value: any, autoSize: boolean = false) {
|
||||
cellLabelChanged(cell, value, autoSize = false) {
|
||||
this.batchUpdate(() => {
|
||||
this.getModel().setValue(cell, value);
|
||||
|
||||
|
@ -156,7 +186,7 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
this.cellSizeUpdated(cell, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -169,10 +199,10 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} that should be checked.
|
||||
*/
|
||||
isEditing(cell: Cell | null = null) {
|
||||
isEditing(cell = null) {
|
||||
const editingCell = this.getCellEditor().getEditingCell();
|
||||
return !cell ? !!editingCell : cell === editingCell;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell is editable. This returns {@link cellsEditable} for
|
||||
|
@ -181,18 +211,18 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose editable state should be returned.
|
||||
*/
|
||||
isCellEditable(cell: Cell) {
|
||||
isCellEditable(cell) {
|
||||
const style = this.getCurrentCellStyle(cell);
|
||||
|
||||
return this.isCellsEditable() && !this.isCellLocked(cell) && style.editable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link cellsEditable}.
|
||||
*/
|
||||
isCellsEditable() {
|
||||
return this.cellsEditable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the graph should allow in-place editing for cell labels.
|
||||
|
@ -201,9 +231,9 @@ class GraphEditing extends autoImplement<PartialClass>() {
|
|||
* @param value Boolean indicating if the graph should allow in-place
|
||||
* editing.
|
||||
*/
|
||||
setCellsEditable(value: boolean) {
|
||||
setCellsEditable(value) {
|
||||
this.cellsEditable = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphEditing;
|
||||
mixInto(Graph)(GraphEditingMixin);
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import CellMarker from '../cell/CellMarker';
|
||||
import InternalMouseEvent from './InternalMouseEvent';
|
||||
import Graph, { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import EventSource from './EventSource';
|
||||
|
||||
|
@ -67,7 +67,7 @@ import EventSource from './EventSource';
|
|||
*/
|
||||
class CellTracker extends CellMarker {
|
||||
constructor(
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
color: string,
|
||||
funct: ((me: InternalMouseEvent) => Cell) | null = null
|
||||
) {
|
||||
|
|
|
@ -21,94 +21,248 @@ import Cell from '../cell/datatypes/Cell';
|
|||
import PanningHandler from '../panning/PanningHandler';
|
||||
import ConnectionHandler from '../connection/ConnectionHandler';
|
||||
import Point from '../geometry/Point';
|
||||
import { convertPoint, getValue, autoImplement } from '../../util/Utils';
|
||||
import { convertPoint, mixInto } from '../../util/Utils';
|
||||
import { NONE, SHAPE_SWIMLANE } from '../../util/Constants';
|
||||
import mxClient from '../../mxClient';
|
||||
import EventSource from './EventSource';
|
||||
import CellEditor from '../editing/CellEditor';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphCells from '../cell/GraphCells';
|
||||
import type GraphSelection from '../selection/GraphSelection';
|
||||
import type GraphEditing from '../editing/GraphEditing';
|
||||
import type GraphSnap from '../snap/GraphSnap';
|
||||
import { MouseEventListener, MouseListenerSet } from '../../types';
|
||||
import { Graph } from '../Graph';
|
||||
import TooltipHandler from '../tooltip/TooltipHandler';
|
||||
import GraphDragDrop from '../drag_drop/GraphDragDrop';
|
||||
import GraphPageBreaks from '../page_breaks/GraphPageBreaks';
|
||||
|
||||
import type { MouseEventListener, MouseListenerSet } from '../../types';
|
||||
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
mouseListeners: MouseListenerSet[];
|
||||
lastTouchEvent: MouseEvent | null;
|
||||
doubleClickCounter: number;
|
||||
lastTouchCell: Cell | null;
|
||||
fireDoubleClick: boolean | null;
|
||||
tapAndHoldThread: number | null;
|
||||
lastMouseX: number | null;
|
||||
lastMouseY: number | null;
|
||||
isMouseTrigger: boolean | null;
|
||||
ignoreMouseEvents: boolean | null;
|
||||
mouseMoveRedirect: MouseEventListener | null;
|
||||
mouseUpRedirect: MouseEventListener | null;
|
||||
lastEvent: any; // FIXME: Check if this can be more specific - DOM events or mxEventObjects!
|
||||
escapeEnabled: boolean;
|
||||
invokesStopCellEditing: boolean;
|
||||
enterStopsCellEditing: boolean;
|
||||
isMouseDown: boolean;
|
||||
nativeDblClickEnabled: boolean;
|
||||
doubleTapEnabled: boolean;
|
||||
doubleTapTimeout: number;
|
||||
doubleTapTolerance: number;
|
||||
lastTouchX: number;
|
||||
lastTouchY: number;
|
||||
lastTouchTime: number;
|
||||
tapAndHoldEnabled: boolean;
|
||||
tapAndHoldDelay: number;
|
||||
tapAndHoldInProgress: boolean;
|
||||
tapAndHoldValid: boolean;
|
||||
initialTouchX: number;
|
||||
initialTouchY: number;
|
||||
tolerance: number;
|
||||
|
||||
isNativeDblClickEnabled: () => boolean;
|
||||
getEventTolerance: () => number;
|
||||
escape: (evt: Event) => void;
|
||||
click: (me: InternalMouseEvent) => boolean;
|
||||
dblClick: (evt: MouseEvent, cell?: Cell | null) => void;
|
||||
tapAndHold: (me: InternalMouseEvent) => void;
|
||||
addMouseListener: (listener: MouseListenerSet) => void;
|
||||
removeMouseListener: (listener: MouseListenerSet) => void;
|
||||
updateMouseEvent: (me: InternalMouseEvent, evtName: string) => InternalMouseEvent;
|
||||
getStateForTouchEvent: (evt: MouseEvent) => CellState | null;
|
||||
isEventIgnored: (
|
||||
evtName: string,
|
||||
me: InternalMouseEvent,
|
||||
sender: EventSource
|
||||
) => boolean;
|
||||
isSyntheticEventIgnored: (
|
||||
evtName: string,
|
||||
me: InternalMouseEvent,
|
||||
sender: any
|
||||
) => boolean;
|
||||
isEventSourceIgnored: (evtName: string, me: InternalMouseEvent) => boolean;
|
||||
getEventState: (state: CellState) => CellState;
|
||||
fireMouseEvent: (
|
||||
evtName: string,
|
||||
me: InternalMouseEvent,
|
||||
sender?: EventSource
|
||||
) => void;
|
||||
consumeMouseEvent: (
|
||||
evtName: string,
|
||||
me: InternalMouseEvent,
|
||||
sender: EventSource
|
||||
) => void;
|
||||
fireGestureEvent: (evt: MouseEvent, cell?: Cell | null) => void;
|
||||
sizeDidChange: () => void;
|
||||
isCloneEvent: (evt: MouseEvent) => boolean;
|
||||
isTransparentClickEvent: (evt: MouseEvent) => boolean;
|
||||
isToggleEvent: (evt: MouseEvent) => boolean;
|
||||
isGridEnabledEvent: (evt: MouseEvent) => boolean;
|
||||
isConstrainedEvent: (evt: MouseEvent) => boolean;
|
||||
isIgnoreTerminalEvent: (evt: MouseEvent) => boolean;
|
||||
getPointForEvent: (evt: MouseEvent, addOffset?: boolean) => Point;
|
||||
isEscapeEnabled: () => boolean;
|
||||
setEscapeEnabled: (value: boolean) => void;
|
||||
isInvokesStopCellEditing: () => boolean;
|
||||
setInvokesStopCellEditing: (value: boolean) => void;
|
||||
isEnterStopsCellEditing: () => boolean;
|
||||
setEnterStopsCellEditing: (value: boolean) => void;
|
||||
getCursorForMouseEvent: (me: InternalMouseEvent) => string | null;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
| 'fireEvent'
|
||||
| 'isEnabled'
|
||||
| 'getView'
|
||||
| 'getGraphBounds'
|
||||
| 'getContainer'
|
||||
| 'paintBackground'
|
||||
| 'getCellAt'
|
||||
| 'isCellSelected'
|
||||
| 'selectCellForEvent'
|
||||
| 'clearSelection'
|
||||
| 'isCellEditable'
|
||||
| 'isEditing'
|
||||
| 'startEditingAtCell'
|
||||
| 'getPlugin'
|
||||
| 'getView'
|
||||
| 'getContainer'
|
||||
| 'getPanDx'
|
||||
| 'getPanDy'
|
||||
| 'getMinimumContainerSize'
|
||||
| 'getEventSource'
|
||||
| 'setEventSource'
|
||||
| 'isAutoScroll'
|
||||
| 'getGraphBounds'
|
||||
| 'scrollPointToVisible'
|
||||
| 'isIgnoreScrollbars'
|
||||
| 'isTranslateToScrollPosition'
|
||||
| 'isAutoExtend'
|
||||
| 'isEditing'
|
||||
| 'stopEditing'
|
||||
| 'getBorder'
|
||||
| 'getMinimumContainerSize'
|
||||
| 'isResizeContainer'
|
||||
| 'doResizeContainer'
|
||||
| 'isPreferPageSize'
|
||||
| 'isPageVisible'
|
||||
| 'getPreferredPageSize'
|
||||
| 'getMinimumGraphSize'
|
||||
| 'getGridSize'
|
||||
| 'snap'
|
||||
| 'getCursorForCell'
|
||||
| 'paintBackground'
|
||||
| 'updatePageBreaks'
|
||||
| 'isPageBreaksVisible'
|
||||
>;
|
||||
type PartialCells = Pick<GraphCells, 'getCellAt' | 'getCursorForCell'>;
|
||||
type PartialSelection = Pick<
|
||||
GraphSelection,
|
||||
'isCellSelected' | 'selectCellForEvent' | 'clearSelection'
|
||||
type PartialEvents = Pick<
|
||||
Graph,
|
||||
| 'mouseListeners'
|
||||
| 'lastTouchEvent'
|
||||
| 'doubleClickCounter'
|
||||
| 'lastTouchCell'
|
||||
| 'fireDoubleClick'
|
||||
| 'tapAndHoldThread'
|
||||
| 'lastMouseX'
|
||||
| 'lastMouseY'
|
||||
| 'isMouseTrigger'
|
||||
| 'ignoreMouseEvents'
|
||||
| 'mouseMoveRedirect'
|
||||
| 'mouseUpRedirect'
|
||||
| 'lastEvent'
|
||||
| 'escapeEnabled'
|
||||
| 'invokesStopCellEditing'
|
||||
| 'enterStopsCellEditing'
|
||||
| 'isMouseDown'
|
||||
| 'nativeDblClickEnabled'
|
||||
| 'doubleTapEnabled'
|
||||
| 'doubleTapTimeout'
|
||||
| 'doubleTapTolerance'
|
||||
| 'lastTouchX'
|
||||
| 'lastTouchY'
|
||||
| 'lastTouchTime'
|
||||
| 'tapAndHoldEnabled'
|
||||
| 'tapAndHoldDelay'
|
||||
| 'tapAndHoldInProgress'
|
||||
| 'tapAndHoldValid'
|
||||
| 'initialTouchX'
|
||||
| 'initialTouchY'
|
||||
| 'tolerance'
|
||||
| 'isNativeDblClickEnabled'
|
||||
| 'getEventTolerance'
|
||||
| 'escape'
|
||||
| 'click'
|
||||
| 'dblClick'
|
||||
| 'tapAndHold'
|
||||
| 'addMouseListener'
|
||||
| 'removeMouseListener'
|
||||
| 'updateMouseEvent'
|
||||
| 'getStateForTouchEvent'
|
||||
| 'isEventIgnored'
|
||||
| 'isSyntheticEventIgnored'
|
||||
| 'isEventSourceIgnored'
|
||||
| 'getEventState'
|
||||
| 'fireMouseEvent'
|
||||
| 'consumeMouseEvent'
|
||||
| 'fireGestureEvent'
|
||||
| 'sizeDidChange'
|
||||
| 'isCloneEvent'
|
||||
| 'isTransparentClickEvent'
|
||||
| 'isToggleEvent'
|
||||
| 'isGridEnabledEvent'
|
||||
| 'isConstrainedEvent'
|
||||
| 'isIgnoreTerminalEvent'
|
||||
| 'getPointForEvent'
|
||||
| 'isEscapeEnabled'
|
||||
| 'setEscapeEnabled'
|
||||
| 'isInvokesStopCellEditing'
|
||||
| 'setInvokesStopCellEditing'
|
||||
| 'isEnterStopsCellEditing'
|
||||
| 'setEnterStopsCellEditing'
|
||||
| 'getCursorForMouseEvent'
|
||||
>;
|
||||
type PartialEditing = Pick<
|
||||
GraphEditing,
|
||||
'isCellEditable' | 'isEditing' | 'startEditingAtCell' | 'stopEditing'
|
||||
>;
|
||||
type PartialSnap = Pick<GraphSnap, 'getGridSize' | 'snap'>;
|
||||
type PartialDragDrop = Pick<GraphDragDrop, 'isAutoScroll' | 'isAutoExtend'>;
|
||||
type PartialPageBreaks = Pick<GraphPageBreaks, 'updatePageBreaks'>;
|
||||
type PartialClass = PartialGraph &
|
||||
PartialCells &
|
||||
PartialSelection &
|
||||
PartialEditing &
|
||||
PartialSnap &
|
||||
PartialDragDrop &
|
||||
PartialPageBreaks &
|
||||
EventSource;
|
||||
type PartialType = PartialGraph & PartialEvents;
|
||||
|
||||
// @ts-ignore recursive reference error
|
||||
class GraphEvents extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphEventsMixin: PartialType = {
|
||||
/**
|
||||
* Holds the mouse event listeners. See {@link fireMouseEvent}.
|
||||
*/
|
||||
mouseListeners: MouseListenerSet[] = [];
|
||||
mouseListeners: [],
|
||||
|
||||
// TODO: Document me!
|
||||
lastTouchEvent: MouseEvent | null = null;
|
||||
doubleClickCounter: number = 0;
|
||||
lastTouchCell: Cell | null = null;
|
||||
fireDoubleClick: boolean | null = null;
|
||||
tapAndHoldThread: number | null = null;
|
||||
lastMouseX: number | null = null;
|
||||
lastMouseY: number | null = null;
|
||||
isMouseTrigger: boolean | null = null;
|
||||
ignoreMouseEvents: boolean | null = null;
|
||||
mouseMoveRedirect: MouseEventListener | null = null;
|
||||
mouseUpRedirect: MouseEventListener | null = null;
|
||||
lastEvent: any; // FIXME: Check if this can be more specific - DOM events or mxEventObjects!
|
||||
lastTouchEvent: null,
|
||||
|
||||
doubleClickCounter: 0,
|
||||
|
||||
lastTouchCell: null,
|
||||
|
||||
fireDoubleClick: null,
|
||||
|
||||
tapAndHoldThread: null,
|
||||
|
||||
lastMouseX: null,
|
||||
|
||||
lastMouseY: null,
|
||||
|
||||
isMouseTrigger: null,
|
||||
|
||||
ignoreMouseEvents: null,
|
||||
|
||||
mouseMoveRedirect: null,
|
||||
|
||||
mouseUpRedirect: null,
|
||||
|
||||
lastEvent: null, // FIXME: Check if this can be more specific - DOM events or mxEventObjects!
|
||||
|
||||
/**
|
||||
* Specifies if {@link mxKeyHandler} should invoke {@link escape} when the escape key
|
||||
* is pressed.
|
||||
* @default true
|
||||
*/
|
||||
escapeEnabled = true;
|
||||
escapeEnabled: true,
|
||||
|
||||
/**
|
||||
* If `true`, when editing is to be stopped by way of selection changing,
|
||||
|
@ -117,7 +271,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* {@link CellEditor}.
|
||||
* @default true
|
||||
*/
|
||||
invokesStopCellEditing = true;
|
||||
invokesStopCellEditing: true,
|
||||
|
||||
/**
|
||||
* If `true`, pressing the enter key without pressing control or shift will stop
|
||||
|
@ -125,98 +279,102 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* cell editing. Note: You can always use F2 and escape to stop editing.
|
||||
* @default false
|
||||
*/
|
||||
enterStopsCellEditing = false;
|
||||
enterStopsCellEditing: false,
|
||||
|
||||
/**
|
||||
* Holds the state of the mouse button.
|
||||
*/
|
||||
isMouseDown = false;
|
||||
isMouseDown: false,
|
||||
|
||||
/**
|
||||
* Specifies if native double click events should be detected.
|
||||
* @default true
|
||||
*/
|
||||
nativeDblClickEnabled = true;
|
||||
|
||||
isNativeDblClickEnabled = () => this.nativeDblClickEnabled;
|
||||
nativeDblClickEnabled: true,
|
||||
|
||||
/**
|
||||
* Specifies if double taps on touch-based devices should be handled as a
|
||||
* double click.
|
||||
* @default true
|
||||
*/
|
||||
doubleTapEnabled = true;
|
||||
doubleTapEnabled: true,
|
||||
|
||||
/**
|
||||
* Specifies the timeout in milliseconds for double taps and non-native double clicks.
|
||||
* @default 500
|
||||
*/
|
||||
doubleTapTimeout = 500;
|
||||
doubleTapTimeout: 500,
|
||||
|
||||
/**
|
||||
* Specifies the tolerance in pixels for double taps and double clicks in quirks mode.
|
||||
* @default 25
|
||||
*/
|
||||
doubleTapTolerance = 25;
|
||||
doubleTapTolerance: 25,
|
||||
|
||||
/**
|
||||
* Variable: lastTouchX
|
||||
*
|
||||
* Holds the x-coordinate of the last touch event for double tap detection.
|
||||
*/
|
||||
lastTouchX = 0;
|
||||
lastTouchX: 0,
|
||||
|
||||
/**
|
||||
* Holds the x-coordinate of the last touch event for double tap detection.
|
||||
*/
|
||||
lastTouchY = 0;
|
||||
lastTouchY: 0,
|
||||
|
||||
/**
|
||||
* Holds the time of the last touch event for double click detection.
|
||||
*/
|
||||
lastTouchTime = 0;
|
||||
lastTouchTime: 0,
|
||||
|
||||
/**
|
||||
* Specifies if tap and hold should be used for starting connections on touch-based
|
||||
* devices.
|
||||
* @default true
|
||||
*/
|
||||
tapAndHoldEnabled = true;
|
||||
tapAndHoldEnabled: true,
|
||||
|
||||
/**
|
||||
* Specifies the time in milliseconds for a tap and hold.
|
||||
* @default 500
|
||||
*/
|
||||
tapAndHoldDelay = 500;
|
||||
tapAndHoldDelay: 500,
|
||||
|
||||
/**
|
||||
* `True` if the timer for tap and hold events is running.
|
||||
*/
|
||||
tapAndHoldInProgress = false;
|
||||
tapAndHoldInProgress: false,
|
||||
|
||||
/**
|
||||
* `True` as long as the timer is running and the touch events
|
||||
* stay within the given {@link tapAndHoldTolerance}.
|
||||
*/
|
||||
tapAndHoldValid = false;
|
||||
tapAndHoldValid: false,
|
||||
|
||||
/**
|
||||
* Holds the x-coordinate of the initial touch event for tap and hold.
|
||||
*/
|
||||
initialTouchX = 0;
|
||||
initialTouchX: 0,
|
||||
|
||||
/**
|
||||
* Holds the y-coordinate of the initial touch event for tap and hold.
|
||||
*/
|
||||
initialTouchY = 0;
|
||||
initialTouchY: 0,
|
||||
|
||||
/**
|
||||
* Tolerance in pixels for a move to be handled as a single click.
|
||||
* @default 4
|
||||
*/
|
||||
tolerance = 4;
|
||||
tolerance: 4,
|
||||
|
||||
getEventTolerance = () => this.tolerance;
|
||||
isNativeDblClickEnabled() {
|
||||
return this.nativeDblClickEnabled;
|
||||
},
|
||||
|
||||
getEventTolerance() {
|
||||
return this.tolerance;
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Event processing
|
||||
|
@ -227,9 +385,9 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param evt Mouseevent that represents the keystroke.
|
||||
*/
|
||||
escape(evt: Event) {
|
||||
escape(evt) {
|
||||
this.fireEvent(new EventObject(InternalEvent.ESCAPE, 'event', evt));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes a singleclick on an optional cell and fires a {@link click} event.
|
||||
|
@ -257,7 +415,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param me {@link mxMouseEvent} that represents the single click.
|
||||
*/
|
||||
click(me: InternalMouseEvent) {
|
||||
click(me) {
|
||||
const evt = me.getEvent();
|
||||
let cell = me.getCell();
|
||||
const mxe = new EventObject(InternalEvent.CLICK, 'event', evt, 'cell', cell);
|
||||
|
@ -334,7 +492,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes a doubleclick on an optional cell and fires a {@link dblclick}
|
||||
|
@ -372,7 +530,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param evt Mouseevent that represents the doubleclick.
|
||||
* @param cell Optional {@link Cell} under the mousepointer.
|
||||
*/
|
||||
dblClick(evt: MouseEvent, cell: Cell | null = null) {
|
||||
dblClick(evt, cell = null) {
|
||||
const mxe = new EventObject(InternalEvent.DOUBLE_CLICK, { event: evt, cell: cell });
|
||||
this.fireEvent(mxe);
|
||||
|
||||
|
@ -388,7 +546,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
this.startEditingAtCell(cell, evt);
|
||||
InternalEvent.consume(evt);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles the {@link InternalMouseEvent} by highlighting the {@link CellState}.
|
||||
|
@ -396,7 +554,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param me {@link mxMouseEvent} that represents the touch event.
|
||||
* @param state Optional {@link CellState} that is associated with the event.
|
||||
*/
|
||||
tapAndHold(me: InternalMouseEvent) {
|
||||
tapAndHold(me) {
|
||||
const evt = me.getEvent();
|
||||
const mxe = new EventObject(
|
||||
InternalEvent.TAP_AND_HOLD,
|
||||
|
@ -443,7 +601,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph events
|
||||
|
@ -456,23 +614,23 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param listener Listener to be added to the graph event listeners.
|
||||
*/
|
||||
addMouseListener(listener: MouseListenerSet) {
|
||||
addMouseListener(listener) {
|
||||
this.mouseListeners.push(listener);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified graph listener.
|
||||
*
|
||||
* @param listener Listener to be removed from the graph event listeners.
|
||||
*/
|
||||
removeMouseListener(listener: MouseListenerSet) {
|
||||
removeMouseListener(listener) {
|
||||
for (let i = 0; i < this.mouseListeners.length; i += 1) {
|
||||
if (this.mouseListeners[i] === listener) {
|
||||
this.mouseListeners.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the graphX and graphY properties if the given {@link InternalMouseEvent} if
|
||||
|
@ -481,7 +639,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param me {@link mxMouseEvent} to be updated.
|
||||
* @param evtName Name of the mouse event.
|
||||
*/
|
||||
updateMouseEvent(me: InternalMouseEvent, evtName: string) {
|
||||
updateMouseEvent(me, evtName) {
|
||||
const pt = convertPoint(this.getContainer(), me.getX(), me.getY());
|
||||
|
||||
me.graphX = pt.x - this.getPanDx();
|
||||
|
@ -502,12 +660,12 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return me;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the state for the given touch event.
|
||||
*/
|
||||
getStateForTouchEvent(evt: MouseEvent) {
|
||||
getStateForTouchEvent(evt) {
|
||||
const x = getClientX(evt);
|
||||
const y = getClientY(evt);
|
||||
|
||||
|
@ -517,12 +675,12 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
const cell = this.getCellAt(pt.x, pt.y);
|
||||
|
||||
return cell ? this.getView().getState(cell) : null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the event should be ignored in {@link fireMouseEvent}.
|
||||
*/
|
||||
isEventIgnored(evtName: string, me: InternalMouseEvent, sender: EventSource) {
|
||||
isEventIgnored(evtName, me, sender) {
|
||||
const mouseEvent = isMouseEvent(me.getEvent());
|
||||
let result = false;
|
||||
|
||||
|
@ -559,19 +717,18 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
) {
|
||||
this.setEventSource(me.getSource());
|
||||
|
||||
this.mouseMoveRedirect = (evt: MouseEvent) => {
|
||||
(this.mouseMoveRedirect = (evt: MouseEvent) => {
|
||||
this.fireMouseEvent(
|
||||
InternalEvent.MOUSE_MOVE,
|
||||
new InternalMouseEvent(evt, this.getStateForTouchEvent(evt))
|
||||
);
|
||||
};
|
||||
this.mouseUpRedirect = (evt: MouseEvent) => {
|
||||
}),
|
||||
(this.mouseUpRedirect = (evt: MouseEvent) => {
|
||||
this.fireMouseEvent(
|
||||
InternalEvent.MOUSE_UP,
|
||||
new InternalMouseEvent(evt, this.getStateForTouchEvent(evt))
|
||||
);
|
||||
};
|
||||
|
||||
}),
|
||||
InternalEvent.addGestureListeners(
|
||||
eventSource,
|
||||
null,
|
||||
|
@ -621,13 +778,12 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook for ignoring synthetic mouse events after touchend in Firefox.
|
||||
*/
|
||||
// isSyntheticEventIgnored(evtName: string, me: mxMouseEvent, sender: mxEventSource): boolean;
|
||||
isSyntheticEventIgnored(evtName: string, me: InternalMouseEvent, sender: any): boolean {
|
||||
isSyntheticEventIgnored(evtName, me, sender) {
|
||||
let result = false;
|
||||
const mouseEvent = isMouseEvent(me.getEvent());
|
||||
|
||||
|
@ -639,7 +795,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
this.ignoreMouseEvents = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the event should be ignored in {@link fireMouseEvent}. This
|
||||
|
@ -650,7 +806,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param evtName The name of the event.
|
||||
* @param me {@link mxMouseEvent} that should be ignored.
|
||||
*/
|
||||
isEventSourceIgnored(evtName: string, me: InternalMouseEvent) {
|
||||
isEventSourceIgnored(evtName, me) {
|
||||
const source = me.getSource();
|
||||
|
||||
if (!source) return true;
|
||||
|
@ -676,7 +832,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
// @ts-ignore type could exist
|
||||
source.type !== 'file'))
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the {@link CellState} to be used when firing the mouse event for the
|
||||
|
@ -684,9 +840,9 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* {@link CellState} - State whose event source should be returned.
|
||||
*/
|
||||
getEventState(state: CellState) {
|
||||
getEventState(state) {
|
||||
return state;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatches the given event in the graph event dispatch loop. Possible
|
||||
|
@ -698,7 +854,9 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param me {@link mxMouseEvent} to be fired.
|
||||
* @param sender Optional sender argument. Default is `this`.
|
||||
*/
|
||||
fireMouseEvent(evtName: string, me: InternalMouseEvent, sender: EventSource = this) {
|
||||
fireMouseEvent(evtName, me, sender) {
|
||||
sender = sender ?? (this as Graph);
|
||||
|
||||
if (this.isEventSourceIgnored(evtName, me)) {
|
||||
const tooltipHandler = this.getPlugin('TooltipHandler') as TooltipHandler;
|
||||
|
||||
|
@ -902,17 +1060,19 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
|
||||
this.consumeMouseEvent(evtName, me, sender);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Consumes the given {@link InternalMouseEvent} if it's a touchStart event.
|
||||
*/
|
||||
consumeMouseEvent(evtName: string, me: InternalMouseEvent, sender: EventSource = this) {
|
||||
consumeMouseEvent(evtName, me, sender) {
|
||||
sender = sender ?? this;
|
||||
|
||||
// Workaround for duplicate click in Windows 8 with Chrome/FF/Opera with touch
|
||||
if (evtName === InternalEvent.MOUSE_DOWN && isTouchEvent(me.getEvent())) {
|
||||
me.consume(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatches a {@link InternalEvent.GESTURE} event. The following example will resize the
|
||||
|
@ -945,11 +1105,11 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param evt Gestureend event that represents the gesture.
|
||||
* @param cell Optional {@link Cell} associated with the gesture.
|
||||
*/
|
||||
fireGestureEvent(evt: MouseEvent, cell: Cell | null = null): void {
|
||||
fireGestureEvent(evt, cell = null) {
|
||||
// Resets double tap event handling when gestures take place
|
||||
this.lastTouchTime = 0;
|
||||
this.fireEvent(new EventObject(InternalEvent.GESTURE, 'event', evt, 'cell', cell));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the size of the graph has changed. This implementation fires
|
||||
|
@ -1009,7 +1169,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
this.updatePageBreaks(this.isPageBreaksVisible(), width, height);
|
||||
|
||||
this.fireEvent(new EventObject(InternalEvent.SIZE, 'bounds', bounds));
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph display
|
||||
|
@ -1019,49 +1179,49 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* Returns true if the given event is a clone event. This implementation
|
||||
* returns true if control is pressed.
|
||||
*/
|
||||
isCloneEvent(evt: MouseEvent) {
|
||||
isCloneEvent(evt) {
|
||||
return isControlDown(evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook for implementing click-through behaviour on selected cells. If this
|
||||
* returns true the cell behind the selected cell will be selected. This
|
||||
* implementation returns false;
|
||||
*/
|
||||
isTransparentClickEvent(evt: MouseEvent) {
|
||||
isTransparentClickEvent(evt) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given event is a toggle event. This implementation
|
||||
* returns true if the meta key (Cmd) is pressed on Macs or if control is
|
||||
* pressed on any other platform.
|
||||
*/
|
||||
isToggleEvent(evt: MouseEvent) {
|
||||
isToggleEvent(evt) {
|
||||
return mxClient.IS_MAC ? isMetaDown(evt) : isControlDown(evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given mouse event should be aligned to the grid.
|
||||
*/
|
||||
isGridEnabledEvent(evt: MouseEvent) {
|
||||
isGridEnabledEvent(evt) {
|
||||
return !isAltDown(evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given mouse event should be aligned to the grid.
|
||||
*/
|
||||
isConstrainedEvent(evt: MouseEvent) {
|
||||
isConstrainedEvent(evt) {
|
||||
return isShiftDown(evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given mouse event should not allow any connections to be
|
||||
* made. This implementation returns false.
|
||||
*/
|
||||
isIgnoreTerminalEvent(evt: MouseEvent) {
|
||||
isIgnoreTerminalEvent(evt) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an {@link Point} representing the given event in the unscaled,
|
||||
|
@ -1071,7 +1231,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
* @param addOffset Optional boolean that specifies if the position should be
|
||||
* offset by half of the {@link gridSize}. Default is `true`.
|
||||
*/
|
||||
getPointForEvent(evt: MouseEvent, addOffset = true) {
|
||||
getPointForEvent(evt, addOffset = true) {
|
||||
const p = convertPoint(this.getContainer(), getClientX(evt), getClientY(evt));
|
||||
const s = this.getView().scale;
|
||||
const tr = this.getView().translate;
|
||||
|
@ -1081,7 +1241,7 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
p.y = this.snap(p.y / s - tr.y - off);
|
||||
|
||||
return p;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -1092,44 +1252,44 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isEscapeEnabled() {
|
||||
return this.escapeEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link escapeEnabled}.
|
||||
*
|
||||
* @param enabled Boolean indicating if escape should be enabled.
|
||||
*/
|
||||
setEscapeEnabled(value: boolean) {
|
||||
setEscapeEnabled(value) {
|
||||
this.escapeEnabled = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link invokesStopCellEditing}.
|
||||
*/
|
||||
isInvokesStopCellEditing() {
|
||||
return this.invokesStopCellEditing;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link invokesStopCellEditing}.
|
||||
*/
|
||||
setInvokesStopCellEditing(value: boolean) {
|
||||
setInvokesStopCellEditing(value) {
|
||||
this.invokesStopCellEditing = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link enterStopsCellEditing}.
|
||||
*/
|
||||
isEnterStopsCellEditing() {
|
||||
return this.enterStopsCellEditing;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link enterStopsCellEditing}.
|
||||
*/
|
||||
setEnterStopsCellEditing(value: boolean) {
|
||||
setEnterStopsCellEditing(value) {
|
||||
this.enterStopsCellEditing = value;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph appearance
|
||||
|
@ -1141,10 +1301,10 @@ class GraphEvents extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param me {@link mxMouseEvent} whose cursor should be returned.
|
||||
*/
|
||||
getCursorForMouseEvent(me: InternalMouseEvent) {
|
||||
getCursorForMouseEvent(me) {
|
||||
const cell = me.getCell();
|
||||
return cell ? this.getCursorForCell(cell) : null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphEvents;
|
||||
mixInto(Graph)(GraphEventsMixin);
|
|
@ -7,7 +7,6 @@
|
|||
import InternalMouseEvent from './InternalMouseEvent';
|
||||
import mxClient from '../../mxClient';
|
||||
import { isConsumed, isMouseEvent } from '../../util/EventUtils';
|
||||
import graph from '../Graph';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import {
|
||||
EventCache,
|
||||
|
@ -16,6 +15,7 @@ import {
|
|||
Listenable,
|
||||
MouseEventListener,
|
||||
} from '../../types';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
// Checks if passive event listeners are supported
|
||||
// see https://github.com/Modernizr/Modernizr/issues/1894
|
||||
|
@ -230,7 +230,7 @@ class InternalEvent {
|
|||
*/
|
||||
static redirectMouseEvents(
|
||||
node: Listenable,
|
||||
graph: graph,
|
||||
graph: Graph,
|
||||
state: CellState | ((evt: Event) => CellState | null) | null = null,
|
||||
down: MouseEventListener | null = null,
|
||||
move: MouseEventListener | null = null,
|
||||
|
|
|
@ -6,13 +6,41 @@ import CellArray from '../cell/datatypes/CellArray';
|
|||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Geometry from '../geometry/Geometry';
|
||||
import { autoImplement, getValue, toRadians } from '../../util/Utils';
|
||||
import { getValue, mixInto, toRadians } from '../../util/Utils';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphCells from '../cell/GraphCells';
|
||||
import type GraphSelection from '../selection/GraphSelection';
|
||||
import type GraphEditing from '../editing/GraphEditing';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
options: GraphFoldingOptions;
|
||||
collapseExpandResource: string;
|
||||
|
||||
getCollapseExpandResource: () => string;
|
||||
isFoldingEnabled: () => boolean;
|
||||
getFoldableCells: (cells: CellArray, collapse: boolean) => CellArray | null;
|
||||
isCellFoldable: (cell: Cell, collapse: boolean) => boolean;
|
||||
getFoldingImage: (state: CellState) => Image | null;
|
||||
foldCells: (
|
||||
collapse: boolean,
|
||||
recurse: boolean,
|
||||
cells: CellArray | null,
|
||||
checkFoldable: boolean,
|
||||
evt: Event | null
|
||||
) => CellArray | null;
|
||||
cellsFolded: (
|
||||
cells: CellArray | null,
|
||||
collapse: boolean,
|
||||
recurse: boolean,
|
||||
checkFoldable?: boolean
|
||||
) => void;
|
||||
swapBounds: (cell: Cell, willCollapse: boolean) => void;
|
||||
updateAlternateBounds: (
|
||||
cell: Cell | null,
|
||||
geo: Geometry | null,
|
||||
willCollapse: boolean
|
||||
) => void;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GraphFoldingOptions
|
||||
|
@ -35,26 +63,42 @@ type GraphFoldingOptions = {
|
|||
collapseToPreferredSize: boolean;
|
||||
};
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getModel' | 'fireEvent'>;
|
||||
type PartialCells = Pick<
|
||||
GraphCells,
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
| 'getModel'
|
||||
| 'fireEvent'
|
||||
| 'getCurrentCellStyle'
|
||||
| 'isExtendParent'
|
||||
| 'extendParent'
|
||||
| 'constrainChild'
|
||||
| 'getPreferredSizeForCell'
|
||||
| 'getSelectionCells'
|
||||
| 'stopEditing'
|
||||
>;
|
||||
type PartialSelection = Pick<GraphSelection, 'getSelectionCells'>;
|
||||
type PartialEditing = Pick<GraphEditing, 'stopEditing'>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialSelection & PartialEditing;
|
||||
type PartialFolding = Pick<
|
||||
Graph,
|
||||
| 'options'
|
||||
| 'collapseExpandResource'
|
||||
| 'getCollapseExpandResource'
|
||||
| 'isFoldingEnabled'
|
||||
| 'getFoldableCells'
|
||||
| 'isCellFoldable'
|
||||
| 'getFoldingImage'
|
||||
| 'foldCells'
|
||||
| 'cellsFolded'
|
||||
| 'swapBounds'
|
||||
| 'updateAlternateBounds'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialFolding;
|
||||
|
||||
class GraphFolding extends autoImplement<PartialClass>() {
|
||||
options: GraphFoldingOptions = {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphFoldingMixin: PartialType = {
|
||||
options: {
|
||||
foldingEnabled: true,
|
||||
collapsedImage: new Image(`${mxClient.imageBasePath}/collapsed.gif`, 9, 9),
|
||||
expandedImage: new Image(`${mxClient.imageBasePath}/expanded.gif`, 9, 9),
|
||||
collapseToPreferredSize: true,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies the resource key for the tooltip on the collapse/expand icon.
|
||||
|
@ -62,11 +106,15 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
* the tooltip.
|
||||
* @default 'collapse-expand'
|
||||
*/
|
||||
collapseExpandResource: string = mxClient.language != 'none' ? 'collapse-expand' : '';
|
||||
collapseExpandResource: mxClient.language != 'none' ? 'collapse-expand' : '',
|
||||
|
||||
getCollapseExpandResource = () => this.collapseExpandResource;
|
||||
getCollapseExpandResource() {
|
||||
return this.collapseExpandResource;
|
||||
},
|
||||
|
||||
isFoldingEnabled = () => this.options.foldingEnabled;
|
||||
isFoldingEnabled() {
|
||||
return this.options.foldingEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -76,11 +124,11 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
/**
|
||||
* Returns the cells which are movable in the given array of cells.
|
||||
*/
|
||||
getFoldableCells(cells: CellArray, collapse: boolean = false): CellArray | null {
|
||||
getFoldableCells(cells, collapse = false) {
|
||||
return this.getModel().filterCells(cells, (cell: Cell) => {
|
||||
return this.isCellFoldable(cell, collapse);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell is foldable. This implementation
|
||||
|
@ -90,16 +138,16 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} whose foldable state should be returned.
|
||||
*/
|
||||
// isCellFoldable(cell: mxCell, collapse: boolean): boolean;
|
||||
isCellFoldable(cell: Cell, collapse: boolean = false): boolean {
|
||||
isCellFoldable(cell, collapse = false) {
|
||||
const style = this.getCurrentCellStyle(cell);
|
||||
return cell.getChildCount() > 0 && style.foldable;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the {@link Image} used to display the collapsed state of
|
||||
* the specified cell state. This returns null for all edges.
|
||||
*/
|
||||
getFoldingImage(state: CellState): Image | null {
|
||||
getFoldingImage(state) {
|
||||
if (state != null && this.options.foldingEnabled && !state.cell.isEdge()) {
|
||||
const tmp = (<Cell>state.cell).isCollapsed();
|
||||
|
||||
|
@ -108,7 +156,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Folding
|
||||
|
@ -131,12 +179,12 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
// foldCells(collapse: boolean, recurse: boolean, cells: mxCellArray, checkFoldable?: boolean, evt?: Event): mxCellArray;
|
||||
foldCells(
|
||||
collapse: boolean = false,
|
||||
recurse: boolean = false,
|
||||
cells: CellArray | null = null,
|
||||
checkFoldable: boolean = false,
|
||||
evt: Event | null = null
|
||||
): CellArray | null {
|
||||
collapse = false,
|
||||
recurse = false,
|
||||
cells = null,
|
||||
checkFoldable = false,
|
||||
evt = null
|
||||
) {
|
||||
if (cells == null) {
|
||||
cells = this.getFoldableCells(this.getSelectionCells(), collapse);
|
||||
}
|
||||
|
@ -161,7 +209,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
this.getModel().endUpdate();
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the collapsed state of the specified cells. This method fires
|
||||
|
@ -176,12 +224,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
* checked. Default is `false`.
|
||||
*/
|
||||
// cellsFolded(cells: mxCellArray, collapse: boolean, recurse: boolean, checkFoldable?: boolean): void;
|
||||
cellsFolded(
|
||||
cells: CellArray | null = null,
|
||||
collapse: boolean = false,
|
||||
recurse: boolean = false,
|
||||
checkFoldable: boolean = false
|
||||
): void {
|
||||
cellsFolded(cells = null, collapse = false, recurse = false, checkFoldable = false) {
|
||||
if (cells != null && cells.length > 0) {
|
||||
this.getModel().beginUpdate();
|
||||
try {
|
||||
|
@ -221,7 +264,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
this.getModel().endUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Swaps the alternate and the actual bounds in the geometry of the given
|
||||
|
@ -231,7 +274,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
* @param willCollapse Boolean indicating if the cell is going to be collapsed.
|
||||
*/
|
||||
// swapBounds(cell: mxCell, willCollapse: boolean): void;
|
||||
swapBounds(cell: Cell, willCollapse: boolean = false): void {
|
||||
swapBounds(cell, willCollapse = false) {
|
||||
let geo = cell.getGeometry();
|
||||
if (geo != null) {
|
||||
geo = <Geometry>geo.clone();
|
||||
|
@ -241,7 +284,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
|
||||
this.getModel().setGeometry(cell, geo);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates or sets the alternate bounds in the given geometry for the given
|
||||
|
@ -256,11 +299,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
* @param willCollapse Boolean indicating if the cell is going to be collapsed.
|
||||
*/
|
||||
// updateAlternateBounds(cell: mxCell, geo: mxGeometry, willCollapse: boolean): void;
|
||||
updateAlternateBounds(
|
||||
cell: Cell | null = null,
|
||||
geo: Geometry | null = null,
|
||||
willCollapse: boolean = false
|
||||
): void {
|
||||
updateAlternateBounds(cell = null, geo = null, willCollapse = false) {
|
||||
if (cell != null && geo != null) {
|
||||
const style = this.getCurrentCellStyle(cell);
|
||||
|
||||
|
@ -305,7 +344,7 @@ class GraphFolding extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphFolding;
|
||||
mixInto(Graph)(GraphFoldingMixin);
|
|
@ -1230,7 +1230,7 @@ class Shape {
|
|||
*/
|
||||
getShapeRotation() {
|
||||
let rot = this.getRotation();
|
||||
|
||||
console.log('rot', rot, this, this.rotation);
|
||||
if (this.direction === DIRECTION_NORTH) {
|
||||
rot += 270;
|
||||
} else if (this.direction === DIRECTION_WEST) {
|
||||
|
|
|
@ -1,16 +1,40 @@
|
|||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import { autoImplement, sortCells } from '../../util/Utils';
|
||||
import { mixInto, sortCells } from '../../util/Utils';
|
||||
import Geometry from '../geometry/Geometry';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import Point from '../geometry/Point';
|
||||
import Graph from '../Graph';
|
||||
import GraphSelection from '../selection/GraphSelection';
|
||||
import GraphCells from '../cell/GraphCells';
|
||||
import GraphSwimlane from '../swimlane/GraphSwimlane';
|
||||
import GraphEdge from '../cell/edge/GraphEdge';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
groupCells: (group: Cell, border: number, cells: CellArray) => Cell;
|
||||
getCellsForGroup: (cells: CellArray) => CellArray;
|
||||
getBoundsForGroup: (
|
||||
group: Cell,
|
||||
children: CellArray,
|
||||
border: number | null
|
||||
) => Rectangle | null;
|
||||
createGroupCell: (cells: CellArray) => Cell;
|
||||
ungroupCells: (cells: CellArray) => CellArray;
|
||||
getCellsForUngroup: () => CellArray;
|
||||
removeCellsAfterUngroup: (cells: CellArray) => void;
|
||||
removeCellsFromParent: (cells: CellArray) => CellArray;
|
||||
updateGroupBounds: (
|
||||
cells: CellArray,
|
||||
border: number,
|
||||
moveGroup: boolean,
|
||||
topBorder: number,
|
||||
rightBorder: number,
|
||||
bottomBorder: number,
|
||||
leftBorder: number
|
||||
) => CellArray;
|
||||
enterGroup: (cell: Cell) => void;
|
||||
exitGroup: () => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
|
@ -21,9 +45,6 @@ type PartialGraph = Pick<
|
|||
| 'batchUpdate'
|
||||
| 'isValidRoot'
|
||||
| 'getCurrentRoot'
|
||||
>;
|
||||
type PartialCells = Pick<
|
||||
GraphCells,
|
||||
| 'cellsAdded'
|
||||
| 'cellsMoved'
|
||||
| 'cellsResized'
|
||||
|
@ -31,23 +52,33 @@ type PartialCells = Pick<
|
|||
| 'cellsRemoved'
|
||||
| 'getChildCells'
|
||||
| 'moveCells'
|
||||
| 'addAllEdges'
|
||||
| 'getSelectionCells'
|
||||
| 'getSelectionCell'
|
||||
| 'clearSelection'
|
||||
| 'setSelectionCell'
|
||||
| 'isSwimlane'
|
||||
| 'getStartSize'
|
||||
| 'getActualStartSize'
|
||||
>;
|
||||
type PartialEdge = Pick<GraphEdge, 'addAllEdges'>;
|
||||
type PartialSelection = Pick<
|
||||
GraphSelection,
|
||||
'getSelectionCells' | 'getSelectionCell' | 'clearSelection' | 'setSelectionCell'
|
||||
type PartialGrouping = Pick<
|
||||
Graph,
|
||||
| 'groupCells'
|
||||
| 'getCellsForGroup'
|
||||
| 'getBoundsForGroup'
|
||||
| 'createGroupCell'
|
||||
| 'ungroupCells'
|
||||
| 'getCellsForUngroup'
|
||||
| 'removeCellsAfterUngroup'
|
||||
| 'removeCellsFromParent'
|
||||
| 'updateGroupBounds'
|
||||
| 'enterGroup'
|
||||
| 'exitGroup'
|
||||
>;
|
||||
type PartialSwimlane = Pick<
|
||||
GraphSwimlane,
|
||||
'isSwimlane' | 'getStartSize' | 'getActualStartSize'
|
||||
>;
|
||||
type PartialClass = PartialGraph &
|
||||
PartialCells &
|
||||
PartialEdge &
|
||||
PartialSelection &
|
||||
PartialSwimlane;
|
||||
type PartialType = PartialGraph & PartialGrouping;
|
||||
|
||||
class GraphGrouping extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphGroupingMixin: PartialType = {
|
||||
/*****************************************************************************
|
||||
* Group: Grouping
|
||||
*****************************************************************************/
|
||||
|
@ -66,13 +97,9 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
* @param cells Optional array of {@link Cell} to be grouped. If `null` is specified
|
||||
* then the selection cells are used.
|
||||
*/
|
||||
// groupCells(group: mxCell | null, border?: number, cells?: mxCellArray): mxCell;
|
||||
groupCells(
|
||||
group: Cell,
|
||||
border: number = 0,
|
||||
cells: CellArray = sortCells(this.getSelectionCells(), true)
|
||||
) {
|
||||
cells = this.getCellsForGroup(cells);
|
||||
groupCells(group, border = 0, cells) {
|
||||
if (!cells) cells = sortCells(this.getSelectionCells(), true);
|
||||
if (!cells) cells = this.getCellsForGroup(cells);
|
||||
|
||||
if (group == null) {
|
||||
group = this.createGroupCell(cells);
|
||||
|
@ -133,13 +160,13 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the cells with the same parent as the first cell
|
||||
* in the given array.
|
||||
*/
|
||||
getCellsForGroup(cells: CellArray): CellArray {
|
||||
getCellsForGroup(cells) {
|
||||
const result = new CellArray();
|
||||
if (cells != null && cells.length > 0) {
|
||||
const parent = cells[0].getParent();
|
||||
|
@ -153,16 +180,12 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the bounds to be used for the given group and children.
|
||||
*/
|
||||
getBoundsForGroup(
|
||||
group: Cell,
|
||||
children: CellArray,
|
||||
border: number | null
|
||||
): Rectangle | null {
|
||||
getBoundsForGroup(group, children, border) {
|
||||
const result = this.getBoundingBoxFromGeometry(children, true);
|
||||
if (result != null) {
|
||||
if (this.isSwimlane(group)) {
|
||||
|
@ -183,7 +206,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook for creating the group cell to hold the given array of {@link Cell} if
|
||||
|
@ -201,14 +224,13 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
* return group;
|
||||
* };
|
||||
*/
|
||||
// createGroupCell(cells: mxCellArray): mxCell;
|
||||
createGroupCell(cells: CellArray) {
|
||||
createGroupCell(cells) {
|
||||
const group = new Cell('');
|
||||
group.setVertex(true);
|
||||
group.setConnectable(false);
|
||||
|
||||
return group;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ungroups the given cells by moving the children the children to their
|
||||
|
@ -218,8 +240,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
* @param cells Array of cells to be ungrouped. If null is specified then the
|
||||
* selection cells are used.
|
||||
*/
|
||||
// ungroupCells(cells: mxCellArray): mxCellArray;
|
||||
ungroupCells(cells: CellArray) {
|
||||
ungroupCells(cells) {
|
||||
let result: CellArray = new CellArray();
|
||||
|
||||
if (cells == null) {
|
||||
|
@ -264,14 +285,14 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: getCellsForUngroup
|
||||
*
|
||||
* Returns the selection cells that can be ungrouped.
|
||||
*/
|
||||
getCellsForUngroup(): CellArray {
|
||||
getCellsForUngroup() {
|
||||
const cells = this.getSelectionCells();
|
||||
|
||||
// Finds the cells with children
|
||||
|
@ -283,16 +304,16 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook to remove the groups after {@link ungroupCells}.
|
||||
*
|
||||
* @param cells Array of {@link Cell} that were ungrouped.
|
||||
*/
|
||||
removeCellsAfterUngroup(cells: CellArray): void {
|
||||
removeCellsAfterUngroup(cells) {
|
||||
this.cellsRemoved(this.addAllEdges(cells));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified cells from their parents and adds them to the
|
||||
|
@ -300,7 +321,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cells Array of {@link Cell} to be removed from their parents.
|
||||
*/
|
||||
removeCellsFromParent(cells: CellArray): CellArray {
|
||||
removeCellsFromParent(cells) {
|
||||
if (cells == null) {
|
||||
cells = this.getSelectionCells();
|
||||
}
|
||||
|
@ -317,7 +338,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
this.getModel().endUpdate();
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateGroupBounds
|
||||
|
@ -340,14 +361,14 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
* leftBorder - Optional top border to be added in the group. Default is 0.
|
||||
*/
|
||||
updateGroupBounds(
|
||||
cells: CellArray,
|
||||
border: number = 0,
|
||||
moveGroup: boolean = false,
|
||||
topBorder: number = 0,
|
||||
rightBorder: number = 0,
|
||||
bottomBorder: number = 0,
|
||||
leftBorder: number = 0
|
||||
): CellArray {
|
||||
cells,
|
||||
border = 0,
|
||||
moveGroup = false,
|
||||
topBorder = 0,
|
||||
rightBorder = 0,
|
||||
bottomBorder = 0,
|
||||
leftBorder = 0
|
||||
) {
|
||||
if (cells == null) {
|
||||
cells = this.getSelectionCells();
|
||||
}
|
||||
|
@ -402,7 +423,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
}
|
||||
});
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Drilldown
|
||||
|
@ -416,25 +437,25 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
* @param cell Optional {@link Cell} to be used as the new root. Default is the
|
||||
* selection cell.
|
||||
*/
|
||||
enterGroup(cell: Cell): void {
|
||||
enterGroup(cell) {
|
||||
cell = cell || this.getSelectionCell();
|
||||
|
||||
if (cell != null && this.isValidRoot(cell)) {
|
||||
this.getView().setCurrentRoot(cell);
|
||||
this.clearSelection();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the current root to the next valid root in the displayed cell
|
||||
* hierarchy.
|
||||
*/
|
||||
exitGroup(): void {
|
||||
exitGroup() {
|
||||
const root = this.getModel().getRoot();
|
||||
const current = this.getCurrentRoot();
|
||||
|
||||
if (current != null) {
|
||||
let next = current.getParent();
|
||||
let next = current.getParent() as Cell;
|
||||
|
||||
// Finds the next valid root in the hierarchy
|
||||
while (next !== root && !this.isValidRoot(next) && next.getParent() !== root) {
|
||||
|
@ -456,7 +477,7 @@ class GraphGrouping extends autoImplement<PartialClass>() {
|
|||
this.setSelectionCell(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphGrouping;
|
||||
mixInto(Graph)(GraphGroupingMixin);
|
|
@ -1,15 +1,25 @@
|
|||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import { autoImplement, sortCells } from '../../util/Utils';
|
||||
import { mixInto, sortCells } from '../../util/Utils';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import Graph from '../Graph';
|
||||
import GraphSelection from '../selection/GraphSelection';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
type PartialGraph = Pick<Graph, 'fireEvent' | 'batchUpdate' | 'getModel'>;
|
||||
type PartialSelection = Pick<GraphSelection, 'getSelectionCells'>;
|
||||
type PartialClass = PartialGraph & PartialSelection;
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
orderCells: (back: boolean, cells: CellArray) => CellArray;
|
||||
cellsOrdered: (cells: CellArray, back: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
class GraphOrder extends autoImplement<PartialClass>() {
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'fireEvent' | 'batchUpdate' | 'getModel' | 'getSelectionCells'
|
||||
>;
|
||||
type PartialOrder = Pick<Graph, 'orderCells' | 'cellsOrdered'>;
|
||||
type PartialType = PartialGraph & PartialOrder;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphOrderMixin: PartialType = {
|
||||
/*****************************************************************************
|
||||
* Group: Order
|
||||
*****************************************************************************/
|
||||
|
@ -23,11 +33,9 @@ class GraphOrder extends autoImplement<PartialClass>() {
|
|||
* @param cells Array of {@link mxCell} to move to the background. If null is
|
||||
* specified then the selection cells are used.
|
||||
*/
|
||||
orderCells(
|
||||
back: boolean = false,
|
||||
cells: CellArray = this.getSelectionCells()
|
||||
): CellArray {
|
||||
if (cells == null) {
|
||||
orderCells(back = false, cells) {
|
||||
if (!cells) cells = this.getSelectionCells();
|
||||
if (!cells) {
|
||||
cells = sortCells(this.getSelectionCells(), true);
|
||||
}
|
||||
|
||||
|
@ -44,7 +52,7 @@ class GraphOrder extends autoImplement<PartialClass>() {
|
|||
});
|
||||
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Moves the given cells to the front or back. This method fires
|
||||
|
@ -53,7 +61,7 @@ class GraphOrder extends autoImplement<PartialClass>() {
|
|||
* @param cells Array of {@link mxCell} whose order should be changed.
|
||||
* @param back Boolean that specifies if the cells should be moved to back.
|
||||
*/
|
||||
cellsOrdered(cells: CellArray, back: boolean = false) {
|
||||
cellsOrdered(cells, back = false) {
|
||||
this.batchUpdate(() => {
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
const parent = cells[i].getParent();
|
||||
|
@ -69,7 +77,7 @@ class GraphOrder extends autoImplement<PartialClass>() {
|
|||
new EventObject(InternalEvent.CELLS_ORDERED, 'back', back, 'cells', cells)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphOrder;
|
||||
mixInto(Graph)(GraphOrderMixin);
|
|
@ -1,50 +0,0 @@
|
|||
import ImageBundle from './ImageBundle';
|
||||
|
||||
class GraphImage {
|
||||
/**
|
||||
* Holds the list of image bundles.
|
||||
*/
|
||||
imageBundles: ImageBundle[] = [];
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Image bundles
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Adds the specified {@link ImageBundle}.
|
||||
*/
|
||||
addImageBundle(bundle: ImageBundle) {
|
||||
this.imageBundles.push(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified {@link ImageBundle}.
|
||||
*/
|
||||
removeImageBundle(bundle: ImageBundle) {
|
||||
const tmp = [];
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
if (this.imageBundles[i] !== bundle) {
|
||||
tmp.push(this.imageBundles[i]);
|
||||
}
|
||||
}
|
||||
this.imageBundles = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (key) {
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
const image = this.imageBundles[i].getImage(key);
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default GraphImage;
|
|
@ -0,0 +1,65 @@
|
|||
import { mixInto } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import ImageBundle from './ImageBundle';
|
||||
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
imageBundles: ImageBundle[];
|
||||
|
||||
addImageBundle: (bundle: ImageBundle) => void;
|
||||
removeImageBundle: (bundle: ImageBundle) => void;
|
||||
getImageFromBundles: (key: string) => string | null;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Image bundles
|
||||
*****************************************************************************/
|
||||
|
||||
type PartialImage = Pick<
|
||||
Graph,
|
||||
'imageBundles' | 'addImageBundle' | 'removeImageBundle' | 'getImageFromBundles'
|
||||
>;
|
||||
type PartialType = PartialImage;
|
||||
|
||||
const GraphImageMixin: PartialType = {
|
||||
imageBundles: [],
|
||||
|
||||
/**
|
||||
* Adds the specified {@link ImageBundle}.
|
||||
*/
|
||||
addImageBundle(bundle) {
|
||||
this.imageBundles.push(bundle);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified {@link ImageBundle}.
|
||||
*/
|
||||
removeImageBundle(bundle) {
|
||||
const tmp: ImageBundle[] = [];
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
if (this.imageBundles[i] !== bundle) {
|
||||
tmp.push(this.imageBundles[i]);
|
||||
}
|
||||
}
|
||||
this.imageBundles = tmp;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (key) {
|
||||
for (let i = 0; i < this.imageBundles.length; i += 1) {
|
||||
const image = this.imageBundles[i].getImage(key);
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
mixInto(Graph)(GraphImageMixin);
|
|
@ -1,18 +1,48 @@
|
|||
import { mixInto } from '../../util/Utils';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import { autoImplement, getValue } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphCells from '../cell/GraphCells';
|
||||
import type GraphEdge from '../cell/edge/GraphEdge';
|
||||
import type GraphVertex from '../cell/vertex/GraphVertex';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
labelsVisible: boolean;
|
||||
htmlLabels: boolean;
|
||||
|
||||
type PartialGraph = Pick<Graph, 'convertValueToString'>;
|
||||
type PartialCells = Pick<GraphCells, 'getCurrentCellStyle' | 'isCellLocked'>;
|
||||
type PartialEdge = Pick<GraphEdge, 'isEdgeLabelsMovable'>;
|
||||
type PartialVertex = Pick<GraphVertex, 'isVertexLabelsMovable'>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialEdge & PartialVertex;
|
||||
getLabel: (cell: Cell) => string | null;
|
||||
isHtmlLabel: (cell: Cell) => boolean;
|
||||
isLabelsVisible: () => boolean;
|
||||
isHtmlLabels: () => boolean;
|
||||
setHtmlLabels: (value: boolean) => void;
|
||||
isWrapping: (cell: Cell) => boolean;
|
||||
isLabelClipped: (cell: Cell) => boolean;
|
||||
isLabelMovable: (cell: Cell) => boolean;
|
||||
}
|
||||
}
|
||||
|
||||
class GraphLabel extends autoImplement<PartialClass>() {
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
| 'convertValueToString'
|
||||
| 'getCurrentCellStyle'
|
||||
| 'isCellLocked'
|
||||
| 'isEdgeLabelsMovable'
|
||||
| 'isVertexLabelsMovable'
|
||||
>;
|
||||
type PartialLabel = Pick<
|
||||
Graph,
|
||||
| 'labelsVisible'
|
||||
| 'htmlLabels'
|
||||
| 'getLabel'
|
||||
| 'isHtmlLabel'
|
||||
| 'isLabelsVisible'
|
||||
| 'isHtmlLabels'
|
||||
| 'setHtmlLabels'
|
||||
| 'isWrapping'
|
||||
| 'isLabelClipped'
|
||||
| 'isLabelMovable'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialLabel;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphLabelMixin: PartialType = {
|
||||
/**
|
||||
* Returns a string or DOM node that represents the label for the given
|
||||
* cell. This implementation uses {@link convertValueToString} if {@link labelsVisible}
|
||||
|
@ -61,19 +91,19 @@ class GraphLabel extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose label should be returned.
|
||||
*/
|
||||
getLabel(cell: Cell) {
|
||||
getLabel(cell) {
|
||||
let result: string | null = '';
|
||||
|
||||
if (this.isLabelsVisible() && cell != null) {
|
||||
const style = this.getCurrentCellStyle(cell);
|
||||
|
||||
if (!getValue(style, 'noLabel', false)) {
|
||||
if (!(style.noLabel ?? false)) {
|
||||
result = this.convertValueToString(cell);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the label must be rendered as HTML markup. The default
|
||||
|
@ -81,37 +111,39 @@ class GraphLabel extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose label should be displayed as HTML markup.
|
||||
*/
|
||||
isHtmlLabel(cell: Cell): boolean {
|
||||
isHtmlLabel(cell) {
|
||||
return this.isHtmlLabels();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if labels should be visible. This is used in {@link getLabel}. Default
|
||||
* is true.
|
||||
*/
|
||||
labelsVisible: boolean = true;
|
||||
labelsVisible: true,
|
||||
|
||||
isLabelsVisible = () => this.labelsVisible;
|
||||
isLabelsVisible() {
|
||||
return this.labelsVisible;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies the return value for {@link isHtmlLabel}.
|
||||
* @default false
|
||||
*/
|
||||
htmlLabels: boolean = false;
|
||||
htmlLabels: false,
|
||||
|
||||
/**
|
||||
* Returns {@link htmlLabels}.
|
||||
*/
|
||||
isHtmlLabels(): boolean {
|
||||
isHtmlLabels() {
|
||||
return this.htmlLabels;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link htmlLabels}.
|
||||
*/
|
||||
setHtmlLabels(value: boolean): void {
|
||||
setHtmlLabels(value: boolean) {
|
||||
this.htmlLabels = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This enables wrapping for HTML labels.
|
||||
|
@ -154,9 +186,9 @@ class GraphLabel extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param state {@link mxCell} whose label should be wrapped.
|
||||
*/
|
||||
isWrapping(cell: Cell): boolean {
|
||||
isWrapping(cell) {
|
||||
return this.getCurrentCellStyle(cell).whiteSpace === 'wrap';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the overflow portion of labels should be hidden. If this
|
||||
|
@ -166,9 +198,9 @@ class GraphLabel extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param state {@link mxCell} whose label should be clipped.
|
||||
*/
|
||||
isLabelClipped(cell: Cell): boolean {
|
||||
isLabelClipped(cell) {
|
||||
return this.getCurrentCellStyle(cell).overflow === 'hidden';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given edges's label is moveable. This returns
|
||||
|
@ -177,13 +209,13 @@ class GraphLabel extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose label should be moved.
|
||||
*/
|
||||
isLabelMovable(cell: Cell): boolean {
|
||||
isLabelMovable(cell) {
|
||||
return (
|
||||
!this.isCellLocked(cell) &&
|
||||
((cell.isEdge() && this.isEdgeLabelsMovable()) ||
|
||||
(cell.isVertex() && this.isVertexLabelsMovable()))
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphLabel;
|
||||
mixInto(Graph)(GraphLabelMixin);
|
|
@ -4,10 +4,24 @@ import EventObject from '../event/EventObject';
|
|||
import InternalEvent from '../event/InternalEvent';
|
||||
import Image from '../image/ImageBox';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphSelection from '../selection/GraphSelection';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
addCellOverlay: (cell: Cell, overlay: CellOverlay) => CellOverlay;
|
||||
getCellOverlays: (cell: Cell) => CellOverlay[];
|
||||
removeCellOverlay: (cell: Cell, overlay: CellOverlay | null) => CellOverlay | null;
|
||||
removeCellOverlays: (cell: Cell) => CellOverlay[];
|
||||
clearCellOverlays: (cell: Cell | null) => void;
|
||||
setCellWarning: (
|
||||
cell: Cell,
|
||||
warning: string | null,
|
||||
img?: Image,
|
||||
isSelect?: boolean
|
||||
) => CellOverlay | null;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
|
@ -17,11 +31,21 @@ type PartialGraph = Pick<
|
|||
| 'isEnabled'
|
||||
| 'getWarningImage'
|
||||
| 'getCellRenderer'
|
||||
| 'setSelectionCell'
|
||||
>;
|
||||
type PartialSelection = Pick<GraphSelection, 'setSelectionCell'>;
|
||||
type PartialClass = PartialGraph & PartialSelection;
|
||||
type PartialOverlays = Pick<
|
||||
Graph,
|
||||
| 'addCellOverlay'
|
||||
| 'getCellOverlays'
|
||||
| 'removeCellOverlay'
|
||||
| 'removeCellOverlays'
|
||||
| 'clearCellOverlays'
|
||||
| 'setCellWarning'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialOverlays;
|
||||
|
||||
class GraphOverlays extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphOverlaysMixin: PartialType = {
|
||||
/*****************************************************************************
|
||||
* Group: Overlays
|
||||
*****************************************************************************/
|
||||
|
@ -33,7 +57,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} to add the overlay for.
|
||||
* @param overlay {@link mxCellOverlay} to be added for the cell.
|
||||
*/
|
||||
addCellOverlay(cell: Cell, overlay: CellOverlay): CellOverlay {
|
||||
addCellOverlay(cell, overlay) {
|
||||
cell.overlays.push(overlay);
|
||||
|
||||
// Immediately update the cell display if the state exists
|
||||
|
@ -47,7 +71,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
new EventObject(InternalEvent.ADD_OVERLAY, 'cell', cell, 'overlay', overlay)
|
||||
);
|
||||
return overlay;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the array of {@link mxCellOverlays} for the given cell or null, if
|
||||
|
@ -55,9 +79,9 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose overlays should be returned.
|
||||
*/
|
||||
getCellOverlays(cell: Cell) {
|
||||
getCellOverlays(cell) {
|
||||
return cell.overlays;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes and returns the given {@link CellOverlay} from the given cell. This
|
||||
|
@ -68,7 +92,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
* @param overlay Optional {@link CellOverlay} to be removed.
|
||||
*/
|
||||
// removeCellOverlay(cell: mxCell, overlay: mxCellOverlay): mxCellOverlay;
|
||||
removeCellOverlay(cell: Cell, overlay: CellOverlay | null = null) {
|
||||
removeCellOverlay(cell, overlay = null) {
|
||||
if (!overlay) {
|
||||
this.removeCellOverlays(cell);
|
||||
} else {
|
||||
|
@ -93,7 +117,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return overlay;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all {@link mxCellOverlays} from the given cell. This method
|
||||
|
@ -102,7 +126,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose overlays should be removed
|
||||
*/
|
||||
removeCellOverlays(cell: Cell) {
|
||||
removeCellOverlays(cell) {
|
||||
const { overlays } = cell;
|
||||
|
||||
cell.overlays = [];
|
||||
|
@ -127,7 +151,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return overlays;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all {@link mxCellOverlays} in the graph for the given cell and all its
|
||||
|
@ -138,7 +162,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
* @param cell Optional {@link Cell} that represents the root of the subtree to
|
||||
* remove the overlays from. Default is the root in the model.
|
||||
*/
|
||||
clearCellOverlays(cell: Cell | null = null) {
|
||||
clearCellOverlays(cell = null) {
|
||||
cell = cell ?? this.getModel().getRoot();
|
||||
|
||||
if (!cell) return;
|
||||
|
@ -152,7 +176,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
const child = cell.getChildAt(i);
|
||||
this.clearCellOverlays(child); // recurse
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates an overlay for the given cell using the warning and image or
|
||||
|
@ -173,12 +197,9 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
* @param isSelect Optional boolean indicating if a click on the overlay
|
||||
* should select the corresponding cell. Default is `false`.
|
||||
*/
|
||||
setCellWarning(
|
||||
cell: Cell,
|
||||
warning: string | null = null,
|
||||
img: Image = this.getWarningImage(),
|
||||
isSelect = false
|
||||
) {
|
||||
setCellWarning(cell, warning = null, img, isSelect = false) {
|
||||
img = img ?? this.getWarningImage();
|
||||
|
||||
if (warning && warning.length > 0) {
|
||||
// Creates the overlay with the image and warning
|
||||
const overlay = new CellOverlay(img, `<font color=red>${warning}</font>`);
|
||||
|
@ -201,7 +222,7 @@ class GraphOverlays extends autoImplement<PartialClass>() {
|
|||
this.removeCellOverlays(cell);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphOverlays;
|
||||
mixInto(Graph)(GraphOverlaysMixin);
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import EventSource from '../event/EventSource';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import utils, { convertPoint, sortCells } from '../../util/Utils';
|
||||
import { convertPoint, sortCells } from '../../util/Utils';
|
||||
import RootChange from '../model/RootChange';
|
||||
import ChildChange from '../model/ChildChange';
|
||||
import TerminalChange from '../cell/edge/TerminalChange';
|
||||
|
@ -16,12 +16,11 @@ import VisibleChange from '../style/VisibleChange';
|
|||
import StyleChange from '../style/StyleChange';
|
||||
import EventObject from '../event/EventObject';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import graph from '../Graph';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { getClientX, getClientY } from '../../util/EventUtils';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* @class LayoutManager
|
||||
|
@ -49,7 +48,7 @@ import Graph from '../Graph';
|
|||
* been passed to {@link layoutCells}.
|
||||
*/
|
||||
class LayoutManager extends EventSource {
|
||||
constructor(graph: graph) {
|
||||
constructor(graph: Graph) {
|
||||
super();
|
||||
|
||||
// Executes the layout before the changes are dispatched
|
||||
|
@ -83,7 +82,7 @@ class LayoutManager extends EventSource {
|
|||
/**
|
||||
* Reference to the enclosing {@link graph}.
|
||||
*/
|
||||
graph: graph | null = null;
|
||||
graph: Graph | null = null;
|
||||
|
||||
/**
|
||||
* Specifies if the layout should bubble along
|
||||
|
@ -150,7 +149,7 @@ class LayoutManager extends EventSource {
|
|||
/**
|
||||
* Returns the graph that this layout operates on.
|
||||
*/
|
||||
getGraph(): graph | null {
|
||||
getGraph(): Graph | null {
|
||||
return this.graph;
|
||||
}
|
||||
|
||||
|
@ -222,11 +221,11 @@ class LayoutManager extends EventSource {
|
|||
cellsMoved(cells: CellArray, evt: InternalMouseEvent): void {
|
||||
if (cells != null && evt != null) {
|
||||
const point = convertPoint(
|
||||
(<graph>this.getGraph()).container,
|
||||
(<Graph>this.getGraph()).container,
|
||||
getClientX(evt),
|
||||
getClientY(evt)
|
||||
);
|
||||
const model = (<graph>this.getGraph()).getModel();
|
||||
const model = (<Graph>this.getGraph()).getModel();
|
||||
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
const layout = this.getLayout(cells[i].getParent(), InternalEvent.MOVE_CELLS);
|
||||
|
@ -250,7 +249,7 @@ class LayoutManager extends EventSource {
|
|||
prev: CellArray | null = null
|
||||
): void {
|
||||
if (cells != null && bounds != null) {
|
||||
const model = (<graph>this.getGraph()).getModel();
|
||||
const model = (<Graph>this.getGraph()).getModel();
|
||||
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
const layout = this.getLayout(cells[i].getParent(), InternalEvent.RESIZE_CELLS);
|
||||
|
@ -318,7 +317,7 @@ class LayoutManager extends EventSource {
|
|||
}
|
||||
|
||||
if (this.isBubbling()) {
|
||||
const model = (<graph>this.getGraph()).getModel();
|
||||
const model = (<Graph>this.getGraph()).getModel();
|
||||
this.addAncestorsWithLayout(<Cell>cell.getParent(), result);
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +329,7 @@ class LayoutManager extends EventSource {
|
|||
*/
|
||||
addDescendantsWithLayout(cell: Cell, result: CellArray = new CellArray()): CellArray {
|
||||
if (cell != null && this.hasLayout(cell)) {
|
||||
const model = (<graph>this.getGraph()).getModel();
|
||||
const model = (<Graph>this.getGraph()).getModel();
|
||||
|
||||
for (let i = 0; i < cell.getChildCount(); i += 1) {
|
||||
const child = <Cell>cell.getChildAt(i);
|
||||
|
@ -359,7 +358,7 @@ class LayoutManager extends EventSource {
|
|||
layoutCells(cells: CellArray, bubble: boolean = false): void {
|
||||
if (cells.length > 0) {
|
||||
// Invokes the layouts while removing duplicates
|
||||
const model = (<graph>this.getGraph()).getModel();
|
||||
const model = (<Graph>this.getGraph()).getModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import GraphLayout from './GraphLayout';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ import Point from '../../geometry/Point';
|
|||
import GraphLayout from './GraphLayout';
|
||||
import CellPath from '../../cell/datatypes/CellPath';
|
||||
import Rectangle from '../../geometry/Rectangle';
|
||||
import utils, { sortCells } from '../../../util/Utils';
|
||||
import { sortCells } from '../../../util/Utils';
|
||||
import WeightedCellSorter from './WeightedCellSorter';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
|
||||
/**
|
||||
* @class CompactTreeLayout
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
import Point from '../../geometry/Point';
|
||||
import GraphLayout from './GraphLayout';
|
||||
import utils, { intersects } from '../../../util/Utils';
|
||||
import { intersects } from '../../../util/Utils';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
import CellState from '../../cell/datatypes/CellState';
|
||||
|
||||
|
@ -75,11 +75,7 @@ class EdgeLabelLayout extends GraphLayout {
|
|||
for (let i = 0; i < e.length; i += 1) {
|
||||
const edge = e[i];
|
||||
|
||||
if (
|
||||
edge != null &&
|
||||
edge.text != null &&
|
||||
edge.text.boundingBox != null
|
||||
) {
|
||||
if (edge != null && edge.text != null && edge.text.boundingBox != null) {
|
||||
for (let j = 0; j < v.length; j += 1) {
|
||||
const vertex = v[j];
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import ObjectIdentity from '../../../util/ObjectIdentity';
|
||||
import GraphLayout from './GraphLayout';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@ import Dictionary from '../../../util/Dictionary';
|
|||
import Rectangle from '../../geometry/Rectangle';
|
||||
import Geometry from '../../geometry/Geometry';
|
||||
import Point from '../../geometry/Point';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
|
||||
|
@ -134,7 +134,13 @@ class GraphLayout {
|
|||
* null for the first step of the traversal.
|
||||
* @param visited Optional {@link Dictionary} of cell paths for the visited cells.
|
||||
*/
|
||||
traverse(vertex: Cell, directed?: boolean, func?: Function, edge?: Cell, visited?: Dictionary<Cell, boolean>): void {
|
||||
traverse(
|
||||
vertex: Cell,
|
||||
directed?: boolean,
|
||||
func?: Function,
|
||||
edge?: Cell,
|
||||
visited?: Dictionary<Cell, boolean>
|
||||
): void {
|
||||
if (func != null && vertex != null) {
|
||||
directed = directed != null ? directed : true;
|
||||
visited = visited || new Dictionary();
|
||||
|
@ -320,11 +326,7 @@ class GraphLayout {
|
|||
if (this.useBoundingBox) {
|
||||
const state = this.graph.getView().getState(cell);
|
||||
|
||||
if (
|
||||
state != null &&
|
||||
state.text != null &&
|
||||
state.text.boundingBox != null
|
||||
) {
|
||||
if (state != null && state.text != null && state.text.boundingBox != null) {
|
||||
const { scale } = this.graph.getView();
|
||||
const box = state.text.boundingBox;
|
||||
|
||||
|
@ -376,20 +378,14 @@ class GraphLayout {
|
|||
if (this.useBoundingBox) {
|
||||
const state = this.graph.getView().getState(cell);
|
||||
|
||||
if (
|
||||
state != null &&
|
||||
state.text != null &&
|
||||
state.text.boundingBox != null
|
||||
) {
|
||||
if (state != null && state.text != null && state.text.boundingBox != null) {
|
||||
const { scale } = this.graph.getView();
|
||||
const tmp = state.text.boundingBox;
|
||||
|
||||
const dx0 = Math.max(state.x - tmp.x, 0) / scale;
|
||||
const dy0 = Math.max(state.y - tmp.y, 0) / scale;
|
||||
const dx1 =
|
||||
Math.max(tmp.x + tmp.width - (state.x + state.width), 0) / scale;
|
||||
const dy1 =
|
||||
Math.max(tmp.y + tmp.height - (state.y + state.height), 0) / scale;
|
||||
const dx1 = Math.max(tmp.x + tmp.width - (state.x + state.width), 0) / scale;
|
||||
const dy1 = Math.max(tmp.y + tmp.height - (state.y + state.height), 0) / scale;
|
||||
|
||||
geo = new Rectangle(
|
||||
geo.x - dx0,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import Point from '../../geometry/Point';
|
||||
import GraphLayout from './GraphLayout';
|
||||
import ObjectIdentity from '../../../util/ObjectIdentity';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Rectangle from '../../geometry/Rectangle';
|
||||
import GraphLayout from './GraphLayout';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,12 @@ import Cell from '../../cell/datatypes/Cell';
|
|||
* @class
|
||||
*/
|
||||
class PartitionLayout extends GraphLayout {
|
||||
constructor(graph: Graph, horizontal: boolean=true, spacing: number=0, border: number=0) {
|
||||
constructor(
|
||||
graph: Graph,
|
||||
horizontal: boolean = true,
|
||||
spacing: number = 0,
|
||||
border: number = 0
|
||||
) {
|
||||
super(graph);
|
||||
this.horizontal = horizontal != null ? horizontal : true;
|
||||
this.spacing = spacing || 0;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import CompactTreeLayout from './CompactTreeLayout';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
import Graph from '../../Graph';
|
||||
import { Graph } from '../../Graph';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
|
||||
/**
|
||||
|
@ -108,8 +108,7 @@ class RadialTreeLayout extends CompactTreeLayout {
|
|||
*/
|
||||
isVertexIgnored(vertex: Cell): boolean {
|
||||
return (
|
||||
super.isVertexIgnored(vertex) ||
|
||||
this.graph.getConnections(vertex).length === 0
|
||||
super.isVertexIgnored(vertex) || this.graph.getConnections(vertex).length === 0
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -166,8 +165,7 @@ class RadialTreeLayout extends CompactTreeLayout {
|
|||
|
||||
// Extend out row so they meet the maximum gradient and convert to polar co-ords
|
||||
for (let i = 0; i < this.row.length; i += 1) {
|
||||
const xLeftLimit =
|
||||
this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i];
|
||||
const xLeftLimit = this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i];
|
||||
const xRightLimit =
|
||||
this.centerX + this.nodeDistance + maxRightGrad * this.rowRadi[i];
|
||||
const fullWidth = xRightLimit - xLeftLimit;
|
||||
|
@ -221,12 +219,8 @@ class RadialTreeLayout extends CompactTreeLayout {
|
|||
const vertexBounds = this.getVertexBounds(node.cell);
|
||||
this.setVertexLocation(
|
||||
node.cell,
|
||||
this.centerX -
|
||||
vertexBounds.width / 2 +
|
||||
this.rowRadi[i] * Math.cos(node.theta),
|
||||
this.centerY -
|
||||
vertexBounds.height / 2 +
|
||||
this.rowRadi[i] * Math.sin(node.theta)
|
||||
this.centerX - vertexBounds.width / 2 + this.rowRadi[i] * Math.cos(node.theta),
|
||||
this.centerY - vertexBounds.height / 2 + this.rowRadi[i] * Math.sin(node.theta)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -272,8 +266,7 @@ class RadialTreeLayout extends CompactTreeLayout {
|
|||
vertexBounds.x + vertexBounds.width / 2,
|
||||
this.rowMaxCenX[rowNum]
|
||||
);
|
||||
this.rowRadi[rowNum] =
|
||||
vertexBounds.y - this.getVertexBounds(this.root).y;
|
||||
this.rowRadi[rowNum] = vertexBounds.y - this.getVertexBounds(this.root).y;
|
||||
|
||||
if (child.child != null) {
|
||||
rowHasChildren = true;
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
*/
|
||||
import GraphLayout from './GraphLayout';
|
||||
import Rectangle from '../../geometry/Rectangle';
|
||||
import utils, { getNumber, getValue } from '../../../util/Utils';
|
||||
import {
|
||||
DEFAULT_STARTSIZE,
|
||||
} from '../../../util/Constants';
|
||||
import Graph from '../../Graph';
|
||||
import { getNumber, getValue } from '../../../util/Utils';
|
||||
import { DEFAULT_STARTSIZE } from '../../../util/Constants';
|
||||
import { Graph } from '../../Graph';
|
||||
import Cell from '../../cell/datatypes/Cell';
|
||||
import Geometry from '../../geometry/Geometry';
|
||||
import CellArray from '../../cell/datatypes/CellArray';
|
||||
|
@ -151,11 +149,7 @@ class StackLayout extends GraphLayout {
|
|||
/**
|
||||
* Implements mxGraphLayout.moveCell.
|
||||
*/
|
||||
moveCell(
|
||||
cell: Cell,
|
||||
x: number,
|
||||
y: number
|
||||
): void {
|
||||
moveCell(cell: Cell, x: number, y: number): void {
|
||||
const model = this.graph.getModel();
|
||||
const parent = cell.getParent();
|
||||
const horizontal = this.isHorizontal();
|
||||
|
@ -299,11 +293,7 @@ class StackLayout extends GraphLayout {
|
|||
if (this.graph.isSwimlane(parent)) {
|
||||
// Uses computed style to get latest
|
||||
const style = this.graph.getCellStyle(parent);
|
||||
let start = getNumber(
|
||||
style,
|
||||
'startSize',
|
||||
DEFAULT_STARTSIZE
|
||||
);
|
||||
let start = getNumber(style, 'startSize', DEFAULT_STARTSIZE);
|
||||
const horz = getValue(style, 'horizontal', true) == 1;
|
||||
|
||||
if (pgeo != null) {
|
||||
|
@ -343,11 +333,9 @@ class StackLayout extends GraphLayout {
|
|||
if (this.wrap != null && last != null) {
|
||||
if (
|
||||
(horizontal &&
|
||||
last.x + last.width + geo.width + 2 * this.spacing >
|
||||
this.wrap) ||
|
||||
last.x + last.width + geo.width + 2 * this.spacing > this.wrap) ||
|
||||
(!horizontal &&
|
||||
last.y + last.height + geo.height + 2 * this.spacing >
|
||||
this.wrap)
|
||||
last.y + last.height + geo.height + 2 * this.spacing > this.wrap)
|
||||
) {
|
||||
last = null;
|
||||
|
||||
|
@ -375,32 +363,24 @@ class StackLayout extends GraphLayout {
|
|||
if (horizontal) {
|
||||
geo.x =
|
||||
this.snap(
|
||||
(this.allowGaps ? Math.max(temp, geo.x) : temp) -
|
||||
this.marginLeft
|
||||
(this.allowGaps ? Math.max(temp, geo.x) : temp) - this.marginLeft
|
||||
) + this.marginLeft;
|
||||
} else {
|
||||
geo.y =
|
||||
this.snap(
|
||||
(this.allowGaps ? Math.max(temp, geo.y) : temp) -
|
||||
this.marginTop
|
||||
(this.allowGaps ? Math.max(temp, geo.y) : temp) - this.marginTop
|
||||
) + this.marginTop;
|
||||
}
|
||||
} else if (!this.keepFirstLocation) {
|
||||
if (horizontal) {
|
||||
geo.x =
|
||||
this.allowGaps && geo.x > x0
|
||||
? Math.max(
|
||||
this.snap(geo.x - this.marginLeft) + this.marginLeft,
|
||||
x0
|
||||
)
|
||||
? Math.max(this.snap(geo.x - this.marginLeft) + this.marginLeft, x0)
|
||||
: x0;
|
||||
} else {
|
||||
geo.y =
|
||||
this.allowGaps && geo.y > y0
|
||||
? Math.max(
|
||||
this.snap(geo.y - this.marginTop) + this.marginTop,
|
||||
y0
|
||||
)
|
||||
? Math.max(this.snap(geo.y - this.marginTop) + this.marginTop, y0)
|
||||
: y0;
|
||||
}
|
||||
}
|
||||
|
@ -437,29 +417,14 @@ class StackLayout extends GraphLayout {
|
|||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.resizeParent &&
|
||||
pgeo != null &&
|
||||
last != null &&
|
||||
!parent.isCollapsed()
|
||||
) {
|
||||
if (this.resizeParent && pgeo != null && last != null && !parent.isCollapsed()) {
|
||||
this.updateParentGeometry(parent, pgeo, last);
|
||||
} else if (
|
||||
this.resizeLast &&
|
||||
pgeo != null &&
|
||||
last != null &&
|
||||
lastChild != null
|
||||
) {
|
||||
} else if (this.resizeLast && pgeo != null && last != null && lastChild != null) {
|
||||
if (horizontal) {
|
||||
last.width =
|
||||
pgeo.width -
|
||||
last.x -
|
||||
this.spacing -
|
||||
this.marginRight -
|
||||
this.marginLeft;
|
||||
pgeo.width - last.x - this.spacing - this.marginRight - this.marginLeft;
|
||||
} else {
|
||||
last.height =
|
||||
pgeo.height - last.y - this.spacing - this.marginBottom;
|
||||
last.height = pgeo.height - last.y - this.spacing - this.marginBottom;
|
||||
}
|
||||
|
||||
this.setChildGeometry(lastChild, last);
|
||||
|
@ -480,10 +445,7 @@ class StackLayout extends GraphLayout {
|
|||
* child - The given child of <mxCell>.
|
||||
* geo - The specific geometry of <mxGeometry>.
|
||||
*/
|
||||
setChildGeometry(
|
||||
child: Cell,
|
||||
geo: Geometry
|
||||
) {
|
||||
setChildGeometry(child: Cell, geo: Geometry) {
|
||||
const geo2 = child.getGeometry();
|
||||
|
||||
if (
|
||||
|
@ -508,11 +470,7 @@ class StackLayout extends GraphLayout {
|
|||
* pgeo - The new <mxGeometry> for parent.
|
||||
* last - The last <mxGeometry>.
|
||||
*/
|
||||
updateParentGeometry(
|
||||
parent: Cell,
|
||||
pgeo: Geometry,
|
||||
last: Geometry
|
||||
) {
|
||||
updateParentGeometry(parent: Cell, pgeo: Geometry, last: Geometry) {
|
||||
const horizontal = this.isHorizontal();
|
||||
const model = this.graph.getModel();
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import ObjectIdentity from '../../../../util/ObjectIdentity';
|
|||
import mxSwimlaneOrdering from './stage/mxSwimlaneOrdering';
|
||||
import MedianHybridCrossingReduction from './stage/MedianHybridCrossingReduction';
|
||||
import CoordinateAssignment from './stage/CoordinateAssignment';
|
||||
import Graph from '../../../Graph';
|
||||
import { Graph } from '../../../Graph';
|
||||
import Cell from '../../../cell/datatypes/Cell';
|
||||
import CellArray from '../../../cell/datatypes/CellArray';
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import utils from '../../../../../util/Utils';
|
||||
import GraphHierarchyNode from './GraphHierarchyNode';
|
||||
import GraphHierarchyEdge from './GraphHierarchyEdge';
|
||||
import CellPath from '../../../../cell/datatypes/CellPath';
|
||||
|
@ -487,13 +486,7 @@ class SwimlaneModel {
|
|||
// Only navigate in source->target direction within the same
|
||||
// swimlane, or from a lower index swimlane to a higher one
|
||||
if (root.swimlaneIndex < targetNode.swimlaneIndex) {
|
||||
this.maxChainDfs(
|
||||
root,
|
||||
targetNode,
|
||||
internalEdge,
|
||||
clone(seen, null, true),
|
||||
0
|
||||
);
|
||||
this.maxChainDfs(root, targetNode, internalEdge, clone(seen, null, true), 0);
|
||||
} else if (root.swimlaneIndex === targetNode.swimlaneIndex) {
|
||||
this.maxChainDfs(
|
||||
root,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
import MxHierarchicalLayoutStage from './HierarchicalLayoutStage';
|
||||
import utils, { remove } from '../../../../../util/Utils';
|
||||
import { remove } from '../../../../../util/Utils';
|
||||
import CellPath from '../../../../cell/datatypes/CellPath';
|
||||
import { clone } from '../../../../../util/CloneUtils';
|
||||
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
import Rectangle from '../geometry/Rectangle';
|
||||
import Point from '../geometry/Point';
|
||||
import Polyline from '../geometry/shape/edge/Polyline';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
horizontalPageBreaks: any[] | null;
|
||||
verticalPageBreaks: any[] | null;
|
||||
|
||||
updatePageBreaks: (visible: boolean, width: number, height: number) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
|
@ -16,11 +24,16 @@ type PartialGraph = Pick<
|
|||
| 'getDialect'
|
||||
| 'isPageBreakDashed'
|
||||
>;
|
||||
type PartialClass = PartialGraph;
|
||||
type PartialPageBreaks = Pick<
|
||||
Graph,
|
||||
'horizontalPageBreaks' | 'verticalPageBreaks' | 'updatePageBreaks'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialPageBreaks;
|
||||
|
||||
class GraphPageBreaks extends autoImplement<PartialClass>() {
|
||||
horizontalPageBreaks: any[] | null = null;
|
||||
verticalPageBreaks: any[] | null = null;
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphPageBreaksMixin: PartialType = {
|
||||
horizontalPageBreaks: null,
|
||||
verticalPageBreaks: null,
|
||||
|
||||
/**
|
||||
* Invokes from {@link sizeDidChange} to redraw the page breaks.
|
||||
|
@ -29,7 +42,7 @@ class GraphPageBreaks extends autoImplement<PartialClass>() {
|
|||
* @param width Specifies the width of the container in pixels.
|
||||
* @param height Specifies the height of the container in pixels.
|
||||
*/
|
||||
updatePageBreaks(visible: boolean, width: number, height: number): void {
|
||||
updatePageBreaks(visible, width, height) {
|
||||
const { scale, translate: tr } = this.getView();
|
||||
const fmt = this.getPageFormat();
|
||||
const ps = scale * this.getPageScale();
|
||||
|
@ -119,7 +132,7 @@ class GraphPageBreaks extends autoImplement<PartialClass>() {
|
|||
|
||||
drawPageBreaks(this.horizontalPageBreaks);
|
||||
drawPageBreaks(this.verticalPageBreaks);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphPageBreaks;
|
||||
mixInto(Graph)(GraphPageBreaksMixin);
|
|
@ -1,21 +1,65 @@
|
|||
import { autoImplement, hasScrollbars } from '../../util/Utils';
|
||||
import { hasScrollbars, mixInto } from '../../util/Utils';
|
||||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import PanningHandler from './PanningHandler';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import Point from '../geometry/Point';
|
||||
import GraphEvents from '../event/GraphEvents';
|
||||
import SelectionCellsHandler from '../selection/SelectionCellsHandler';
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getContainer' | 'getView' | 'getPlugin'>;
|
||||
type PartialEvents = Pick<GraphEvents, 'fireEvent'>;
|
||||
type PartialClass = PartialGraph & PartialEvents;
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
shiftPreview1: HTMLElement | null;
|
||||
shiftPreview2: HTMLElement | null;
|
||||
useScrollbarsForPanning: boolean;
|
||||
timerAutoScroll: boolean;
|
||||
allowAutoPanning: boolean;
|
||||
panDx: number;
|
||||
panDy: number;
|
||||
|
||||
class GraphPanning extends autoImplement<PartialClass>() {
|
||||
shiftPreview1: HTMLElement | null = null;
|
||||
shiftPreview2: HTMLElement | null = null;
|
||||
isUseScrollbarsForPanning: () => boolean;
|
||||
isTimerAutoScroll: () => boolean;
|
||||
isAllowAutoPanning: () => boolean;
|
||||
getPanDx: () => number;
|
||||
setPanDx: (dx: number) => void;
|
||||
getPanDy: () => number;
|
||||
setPanDy: (dy: number) => void;
|
||||
panGraph: (dx: number, dy: number) => void;
|
||||
scrollCellToVisible: (cell: Cell, center?: boolean) => void;
|
||||
scrollRectToVisible: (rect: Rectangle) => boolean;
|
||||
setPanning: (enabled: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getContainer' | 'getView' | 'getPlugin' | 'fireEvent'>;
|
||||
type PartialPanning = Pick<
|
||||
Graph,
|
||||
| 'shiftPreview1'
|
||||
| 'shiftPreview2'
|
||||
| 'useScrollbarsForPanning'
|
||||
| 'timerAutoScroll'
|
||||
| 'allowAutoPanning'
|
||||
| 'panDx'
|
||||
| 'panDy'
|
||||
| 'isUseScrollbarsForPanning'
|
||||
| 'isTimerAutoScroll'
|
||||
| 'isAllowAutoPanning'
|
||||
| 'getPanDx'
|
||||
| 'setPanDx'
|
||||
| 'getPanDy'
|
||||
| 'setPanDy'
|
||||
| 'panGraph'
|
||||
| 'scrollCellToVisible'
|
||||
| 'scrollRectToVisible'
|
||||
| 'setPanning'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialPanning;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphPanningMixin: PartialType = {
|
||||
shiftPreview1: null,
|
||||
shiftPreview2: null,
|
||||
|
||||
/**
|
||||
* Specifies if scrollbars should be used for panning in {@link panGraph} if
|
||||
|
@ -24,9 +68,11 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
* then no panning occurs if this is `true`.
|
||||
* @default true
|
||||
*/
|
||||
useScrollbarsForPanning = true;
|
||||
useScrollbarsForPanning: true,
|
||||
|
||||
isUseScrollbarsForPanning = () => this.useScrollbarsForPanning;
|
||||
isUseScrollbarsForPanning() {
|
||||
return this.useScrollbarsForPanning;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if autoscrolling should be carried out via mxPanningManager even
|
||||
|
@ -36,9 +82,11 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
* are visible and scrollable in all directions.
|
||||
* @default false
|
||||
*/
|
||||
timerAutoScroll = false;
|
||||
timerAutoScroll: false,
|
||||
|
||||
isTimerAutoScroll = () => this.timerAutoScroll;
|
||||
isTimerAutoScroll() {
|
||||
return this.timerAutoScroll;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if panning via {@link panGraph} should be allowed to implement autoscroll
|
||||
|
@ -47,27 +95,39 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
* positive value.
|
||||
* @default false
|
||||
*/
|
||||
allowAutoPanning = false;
|
||||
allowAutoPanning: false,
|
||||
|
||||
isAllowAutoPanning = () => this.allowAutoPanning;
|
||||
isAllowAutoPanning() {
|
||||
return this.allowAutoPanning;
|
||||
},
|
||||
|
||||
/**
|
||||
* Current horizontal panning value.
|
||||
* @default 0
|
||||
*/
|
||||
panDx = 0;
|
||||
panDx: 0,
|
||||
|
||||
getPanDx = () => this.panDx;
|
||||
setPanDx = (dx: number) => (this.panDx = dx);
|
||||
getPanDx() {
|
||||
return this.panDx;
|
||||
},
|
||||
|
||||
setPanDx(dx) {
|
||||
this.panDx = dx;
|
||||
},
|
||||
|
||||
/**
|
||||
* Current vertical panning value.
|
||||
* @default 0
|
||||
*/
|
||||
panDy = 0;
|
||||
panDy: 0,
|
||||
|
||||
getPanDy = () => this.panDy;
|
||||
setPanDy = (dy: number) => (this.panDy = dy);
|
||||
getPanDy() {
|
||||
return this.panDy;
|
||||
},
|
||||
|
||||
setPanDy(dy) {
|
||||
this.panDy = dy;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shifts the graph display by the given amount. This is used to preview
|
||||
|
@ -77,7 +137,7 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
* @param dx Amount to shift the graph along the x-axis.
|
||||
* @param dy Amount to shift the graph along the y-axis.
|
||||
*/
|
||||
panGraph(dx: number, dy: number) {
|
||||
panGraph(dx, dy) {
|
||||
const container = this.getContainer();
|
||||
|
||||
if (this.useScrollbarsForPanning && hasScrollbars(container)) {
|
||||
|
@ -175,7 +235,7 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
|
||||
this.fireEvent(new EventObject(InternalEvent.PAN));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pans the graph so that it shows the given cell. Optionally the cell may
|
||||
|
@ -192,7 +252,7 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} to be made visible.
|
||||
* @param center Optional boolean flag. Default is `false`.
|
||||
*/
|
||||
scrollCellToVisible(cell: Cell, center = false) {
|
||||
scrollCellToVisible(cell, center = false) {
|
||||
const x = -this.getView().translate.x;
|
||||
const y = -this.getView().translate.y;
|
||||
|
||||
|
@ -221,14 +281,14 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
this.getView().setTranslate(tr2.x, tr2.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pans the graph so that it shows the given rectangle.
|
||||
*
|
||||
* @param rect {@link mxRectangle} to be made visible.
|
||||
*/
|
||||
scrollRectToVisible(rect: Rectangle) {
|
||||
scrollRectToVisible(rect) {
|
||||
let isChanged = false;
|
||||
|
||||
const container = <HTMLElement>this.getContainer();
|
||||
|
@ -311,7 +371,7 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return isChanged;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -323,11 +383,11 @@ class GraphPanning extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param enabled Boolean indicating if panning should be enabled.
|
||||
*/
|
||||
setPanning(enabled: boolean) {
|
||||
setPanning(enabled) {
|
||||
const panningHandler = this.getPlugin('PanningHandler') as PanningHandler;
|
||||
|
||||
if (panningHandler) panningHandler.panningEnabled = enabled;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphPanning;
|
||||
mixInto(Graph)(GraphPanningMixin);
|
|
@ -20,7 +20,7 @@ import PanningManager from './PanningManager';
|
|||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
|
||||
import type { GraphPlugin, MouseEventListener } from '../../types';
|
||||
import type { MaxGraph } from '../Graph';
|
||||
import type { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* Class: mxPanningHandler
|
||||
|
@ -54,7 +54,7 @@ import type { MaxGraph } from '../Graph';
|
|||
class PanningHandler extends EventSource implements GraphPlugin {
|
||||
static pluginId = 'PanningHandler';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -117,7 +117,7 @@ class PanningHandler extends EventSource implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
panningManager: PanningManager;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import EventObject from '../event/EventObject';
|
|||
import EventSource from '../event/EventSource';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* Class: mxPanningManager
|
||||
|
@ -19,7 +19,7 @@ import { MaxGraph } from '../Graph';
|
|||
* Implements a handler for panning.
|
||||
*/
|
||||
class PanningManager {
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.thread = null;
|
||||
this.active = false;
|
||||
this.tdx = 0;
|
||||
|
|
|
@ -8,7 +8,7 @@ import PopupMenu from '../../util/gui/PopupMenu';
|
|||
import InternalEvent from '../event/InternalEvent';
|
||||
import { getScrollOrigin } from '../../util/Utils';
|
||||
import { getMainEvent, isMultiTouchEvent } from '../../util/EventUtils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { GraphPlugin, PopupMenuItem } from '../../types';
|
||||
import TooltipHandler from '../tooltip/TooltipHandler';
|
||||
|
@ -27,7 +27,7 @@ import EventObject from '../event/EventObject';
|
|||
class PopupMenuHandler extends PopupMenu implements GraphPlugin {
|
||||
static pluginId = 'PopupMenuHandler';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -53,7 +53,7 @@ class PopupMenuHandler extends PopupMenu implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: selectOnPopup
|
||||
|
|
|
@ -1,12 +1,31 @@
|
|||
import { mixInto } from '../../util/Utils';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
class GraphPorts {
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
portsEnabled: boolean;
|
||||
|
||||
isPort: (cell: Cell | null) => boolean;
|
||||
getTerminalForPort: (cell: Cell, source: boolean) => Cell | null;
|
||||
isPortsEnabled: () => boolean;
|
||||
setPortsEnabled: (value: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialPorts = Pick<
|
||||
Graph,
|
||||
'portsEnabled' | 'isPort' | 'getTerminalForPort' | 'isPortsEnabled' | 'setPortsEnabled'
|
||||
>;
|
||||
type PartialType = PartialPorts;
|
||||
|
||||
const GraphPortsMixin: PartialType = {
|
||||
/**
|
||||
* Specifies if ports are enabled. This is used in {@link cellConnected} to update
|
||||
* the respective style.
|
||||
* @default true
|
||||
*/
|
||||
portsEnabled: boolean = true;
|
||||
portsEnabled: true,
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Drilldown
|
||||
|
@ -33,9 +52,9 @@ class GraphPorts {
|
|||
*
|
||||
* @param cell {@link mxCell} that represents the port.
|
||||
*/
|
||||
isPort(cell: Cell | null) {
|
||||
isPort(cell) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the terminal to be used for a given port. This implementation
|
||||
|
@ -44,9 +63,9 @@ class GraphPorts {
|
|||
* @param cell {@link mxCell} that represents the port.
|
||||
* @param source If the cell is the source or target port.
|
||||
*/
|
||||
getTerminalForPort(cell: Cell, source: boolean = false): Cell | null {
|
||||
getTerminalForPort(cell, source = false) {
|
||||
return cell.getParent();
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -55,18 +74,18 @@ class GraphPorts {
|
|||
/**
|
||||
* Returns {@link portsEnabled} as a boolean.
|
||||
*/
|
||||
isPortsEnabled(): boolean {
|
||||
isPortsEnabled() {
|
||||
return this.portsEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the ports should be enabled.
|
||||
*
|
||||
* @param value Boolean indicating if the ports should be enabled.
|
||||
*/
|
||||
setPortsEnabled(value: boolean): void {
|
||||
setPortsEnabled(value) {
|
||||
this.portsEnabled = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphPorts;
|
||||
mixInto(Graph)(GraphPortsMixin);
|
|
@ -8,10 +8,10 @@ import Rectangle from '../geometry/Rectangle';
|
|||
import TemporaryCellStates from '../cell/TemporaryCellStates';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import mxClient from '../../mxClient';
|
||||
import utils, { intersects } from '../../util/Utils';
|
||||
import { intersects } from '../../util/Utils';
|
||||
import { DIALECT_SVG } from '../../util/Constants';
|
||||
import { write } from '../../util/DomUtils';
|
||||
import Graph from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* @class PrintPreview
|
||||
|
|
|
@ -198,7 +198,7 @@ class CellHighlight {
|
|||
this.state.width + 2 * this.spacing,
|
||||
this.state.height + 2 * this.spacing
|
||||
);
|
||||
this.shape.rotation = Number(this.state.style.rotation || '0');
|
||||
this.shape.rotation = this.state.style.rotation ?? 0;
|
||||
this.shape.strokeWidth = <number>this.getStrokeWidth() / this.state.view.scale;
|
||||
this.shape.outline = true;
|
||||
}
|
||||
|
|
|
@ -9,75 +9,192 @@ import InternalEvent from '../event/InternalEvent';
|
|||
import Dictionary from '../../util/Dictionary';
|
||||
import RootChange from '../model/RootChange';
|
||||
import ChildChange from '../model/ChildChange';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type GraphCells from '../cell/GraphCells';
|
||||
import type Graph from '../Graph';
|
||||
import type GraphEvents from '../event/GraphEvents';
|
||||
import type EventSource from '../event/EventSource';
|
||||
import { MaxGraph } from '../Graph';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
cells: CellArray;
|
||||
doneResource: string;
|
||||
updatingSelectionResource: string;
|
||||
singleSelection: boolean;
|
||||
selectionModel: any | null;
|
||||
|
||||
getDoneResource: () => string;
|
||||
getUpdatingSelectionResource: () => string;
|
||||
getSelectionModel: () => any;
|
||||
setSelectionModel: (selectionModel: any) => void;
|
||||
isSingleSelection: () => boolean;
|
||||
setSingleSelection: (singleSelection: boolean) => void;
|
||||
isSelected: (cell: Cell) => boolean;
|
||||
isEmpty: () => boolean;
|
||||
clear: () => void;
|
||||
setCell: (cell: Cell | null) => void;
|
||||
setCells: (cells: CellArray) => void;
|
||||
getFirstSelectableCell: (cells: CellArray) => Cell | null;
|
||||
addCellToSelection: (cell: Cell) => void;
|
||||
addCellsToSelection: (cells: CellArray) => void;
|
||||
removeCellFromSelection: (cell: Cell) => void;
|
||||
removeCellsFromSelection: (cells: CellArray) => void;
|
||||
changeSelection: (added: CellArray | null, removed: CellArray | null) => void;
|
||||
cellAdded: (cell: Cell) => void;
|
||||
cellRemoved: (cell: Cell) => void;
|
||||
isCellSelected: (cell: Cell) => boolean;
|
||||
isSelectionEmpty: () => boolean;
|
||||
clearSelection: () => void;
|
||||
getSelectionCount: () => number;
|
||||
getSelectionCell: () => Cell;
|
||||
getSelectionCells: () => CellArray;
|
||||
setSelectionCell: (cell: Cell | null) => void;
|
||||
setSelectionCells: (cells: CellArray) => void;
|
||||
addSelectionCell: (cell: Cell) => void;
|
||||
addSelectionCells: (cells: CellArray) => void;
|
||||
removeSelectionCell: (cell: Cell) => void;
|
||||
removeSelectionCells: (cells: CellArray) => void;
|
||||
selectRegion: (rect: Rectangle, evt: MouseEvent) => CellArray;
|
||||
selectNextCell: () => void;
|
||||
selectPreviousCell: () => void;
|
||||
selectParentCell: () => void;
|
||||
selectChildCell: () => void;
|
||||
selectCell: (isNext?: boolean, isParent?: boolean, isChild?: boolean) => void;
|
||||
selectAll: (parent?: Cell | null, descendants?: boolean) => void;
|
||||
selectVertices: (parent: Cell, selectGroups: boolean) => void;
|
||||
selectEdges: (parent: Cell) => void;
|
||||
selectCells: (
|
||||
vertices: boolean,
|
||||
edges: boolean,
|
||||
parent: Cell,
|
||||
selectGroups?: boolean
|
||||
) => void;
|
||||
selectCellForEvent: (cell: Cell, evt: MouseEvent) => void;
|
||||
selectCellsForEvent: (cells: CellArray, evt: MouseEvent) => void;
|
||||
isSiblingSelected: (cell: Cell) => boolean;
|
||||
getSelectionCellsForChanges: (changes: any[], ignoreFn: Function | null) => CellArray;
|
||||
updateSelection: () => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'fireEvent' | 'getDefaultParent' | 'getView' | 'getCurrentRoot' | 'getModel'
|
||||
| 'getModel'
|
||||
| 'getView'
|
||||
| 'isCellSelectable'
|
||||
| 'fireEvent'
|
||||
| 'getDefaultParent'
|
||||
| 'getCurrentRoot'
|
||||
| 'getCells'
|
||||
| 'isToggleEvent'
|
||||
>;
|
||||
type PartialCells = Pick<GraphCells, 'isCellSelectable' | 'getCells'>;
|
||||
type PartialEvents = Pick<GraphEvents, 'isToggleEvent'>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialEvents & EventSource;
|
||||
type PartialCells = Pick<
|
||||
Graph,
|
||||
| 'cells'
|
||||
| 'doneResource'
|
||||
| 'updatingSelectionResource'
|
||||
| 'singleSelection'
|
||||
| 'selectionModel'
|
||||
| 'getDoneResource'
|
||||
| 'getUpdatingSelectionResource'
|
||||
| 'getSelectionModel'
|
||||
| 'setSelectionModel'
|
||||
| 'isSingleSelection'
|
||||
| 'setSingleSelection'
|
||||
| 'isSelected'
|
||||
| 'isEmpty'
|
||||
| 'clear'
|
||||
| 'setCell'
|
||||
| 'setCells'
|
||||
| 'getFirstSelectableCell'
|
||||
| 'addCellToSelection'
|
||||
| 'addCellsToSelection'
|
||||
| 'removeCellFromSelection'
|
||||
| 'removeCellsFromSelection'
|
||||
| 'changeSelection'
|
||||
| 'cellAdded'
|
||||
| 'cellRemoved'
|
||||
| 'isCellSelected'
|
||||
| 'isSelectionEmpty'
|
||||
| 'clearSelection'
|
||||
| 'getSelectionCount'
|
||||
| 'getSelectionCell'
|
||||
| 'getSelectionCells'
|
||||
| 'setSelectionCell'
|
||||
| 'setSelectionCells'
|
||||
| 'addSelectionCell'
|
||||
| 'addSelectionCells'
|
||||
| 'removeSelectionCell'
|
||||
| 'removeSelectionCells'
|
||||
| 'selectRegion'
|
||||
| 'selectNextCell'
|
||||
| 'selectPreviousCell'
|
||||
| 'selectParentCell'
|
||||
| 'selectChildCell'
|
||||
| 'selectCell'
|
||||
| 'selectAll'
|
||||
| 'selectVertices'
|
||||
| 'selectEdges'
|
||||
| 'selectCells'
|
||||
| 'selectCellForEvent'
|
||||
| 'selectCellsForEvent'
|
||||
| 'isSiblingSelected'
|
||||
| 'getSelectionCellsForChanges'
|
||||
| 'updateSelection'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialCells;
|
||||
|
||||
// @ts-ignore recursive reference error
|
||||
class GraphSelection extends autoImplement<PartialClass>() {
|
||||
// TODO: Document me!!
|
||||
cells: CellArray = new CellArray();
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphSelectionMixin: PartialType = {
|
||||
cells: new CellArray(),
|
||||
|
||||
/**
|
||||
* 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 is 'done'.
|
||||
*/
|
||||
doneResource: string = mxClient.language !== 'none' ? 'done' : '';
|
||||
|
||||
getDoneResource = () => this.doneResource;
|
||||
doneResource: mxClient.language !== 'none' ? 'done' : '',
|
||||
|
||||
/**
|
||||
* Specifies the resource key for the status message while the selection is
|
||||
* being updated. If the resource for this key does not exist then the
|
||||
* value is used as the status message. Default is 'updatingSelection'.
|
||||
*/
|
||||
updatingSelectionResource: string =
|
||||
mxClient.language !== 'none' ? 'updatingSelection' : '';
|
||||
|
||||
getUpdatingSelectionResource = () => this.updatingSelectionResource;
|
||||
updatingSelectionResource: mxClient.language !== 'none' ? 'updatingSelection' : '',
|
||||
|
||||
/**
|
||||
* Specifies if only one selected item at a time is allowed.
|
||||
* Default is false.
|
||||
*/
|
||||
singleSelection: boolean = false;
|
||||
singleSelection: false,
|
||||
|
||||
// TODO: Document me!!
|
||||
selectionModel: GraphSelection | null = null;
|
||||
selectionModel: null,
|
||||
|
||||
getDoneResource() {
|
||||
return this.doneResource;
|
||||
},
|
||||
|
||||
getUpdatingSelectionResource() {
|
||||
return this.updatingSelectionResource;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the {@link mxGraphSelectionModel} that contains the selection.
|
||||
*/
|
||||
getSelectionModel() {
|
||||
return this.selectionModel;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the {@link mxSelectionModel} that contains the selection.
|
||||
*/
|
||||
setSelectionModel(selectionModel: GraphSelection) {
|
||||
setSelectionModel(selectionModel) {
|
||||
this.selectionModel = selectionModel;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link singleSelection} as a boolean.
|
||||
*/
|
||||
isSingleSelection() {
|
||||
return this.singleSelection;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the {@link singleSelection} flag.
|
||||
|
@ -85,23 +202,23 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param {boolean} singleSelection Boolean that specifies the new value for
|
||||
* {@link singleSelection}.
|
||||
*/
|
||||
setSingleSelection(singleSelection: boolean) {
|
||||
setSingleSelection(singleSelection) {
|
||||
this.singleSelection = singleSelection;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given {@link Cell} is selected.
|
||||
*/
|
||||
isSelected(cell: Cell) {
|
||||
isSelected(cell) {
|
||||
return this.cells.indexOf(cell) >= 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if no cells are currently selected.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this.cells.length === 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the selection and fires a {@link change} event if the selection was not
|
||||
|
@ -109,23 +226,23 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
clear() {
|
||||
this.changeSelection(null, this.cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the specified {@link Cell} using {@link setCells}.
|
||||
*
|
||||
* @param cell {@link mxCell} to be selected.
|
||||
*/
|
||||
setCell(cell: Cell | null) {
|
||||
setCell(cell) {
|
||||
this.setCells(cell ? new CellArray(cell) : new CellArray());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the given array of {@link Cell} and fires a {@link change} event.
|
||||
*
|
||||
* @param cells Array of {@link Cell} to be selected.
|
||||
*/
|
||||
setCells(cells: CellArray): void {
|
||||
setCells(cells) {
|
||||
if (this.singleSelection) {
|
||||
cells = new CellArray(<Cell>this.getFirstSelectableCell(cells));
|
||||
}
|
||||
|
@ -137,12 +254,12 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
this.changeSelection(tmp, this.cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the first selectable cell in the given array of cells.
|
||||
*/
|
||||
getFirstSelectableCell(cells: CellArray) {
|
||||
getFirstSelectableCell(cells) {
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
if (this.isCellSelectable(cells[i])) {
|
||||
return cells[i];
|
||||
|
@ -150,16 +267,16 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given {@link Cell} to the selection and fires a {@link select} event.
|
||||
*
|
||||
* @param cell {@link mxCell} to add to the selection.
|
||||
*/
|
||||
addCellToSelection(cell: Cell) {
|
||||
addCellToSelection(cell) {
|
||||
this.addCellsToSelection(new CellArray(cell));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given array of {@link Cell} to the selection and fires a {@link select}
|
||||
|
@ -167,7 +284,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cells Array of {@link Cell} to add to the selection.
|
||||
*/
|
||||
addCellsToSelection(cells: CellArray) {
|
||||
addCellsToSelection(cells) {
|
||||
let remove = null;
|
||||
if (this.singleSelection) {
|
||||
remove = this.cells;
|
||||
|
@ -185,7 +302,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
this.changeSelection(tmp, remove);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified {@link Cell} from the selection and fires a {@link select}
|
||||
|
@ -193,9 +310,9 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} to remove from the selection.
|
||||
*/
|
||||
removeCellFromSelection(cell: Cell) {
|
||||
removeCellFromSelection(cell) {
|
||||
this.removeCellsFromSelection(new CellArray(cell));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified {@link Cell} from the selection and fires a {@link select}
|
||||
|
@ -203,7 +320,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cells {@link mxCell}s to remove from the selection.
|
||||
*/
|
||||
removeCellsFromSelection(cells: CellArray) {
|
||||
removeCellsFromSelection(cells) {
|
||||
const tmp = new CellArray();
|
||||
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
|
@ -213,7 +330,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
this.changeSelection(null, tmp);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds/removes the specified arrays of {@link Cell} to/from the selection.
|
||||
|
@ -221,22 +338,22 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @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) {
|
||||
changeSelection(added = null, removed = null) {
|
||||
if (
|
||||
(added && added.length > 0 && added[0]) ||
|
||||
(removed && removed.length > 0 && removed[0])
|
||||
) {
|
||||
const change = new SelectionChange(
|
||||
this as MaxGraph,
|
||||
this as Graph,
|
||||
added || new CellArray(),
|
||||
removed || new CellArray()
|
||||
);
|
||||
change.execute();
|
||||
const edit = new UndoableEdit(this, false);
|
||||
const edit = new UndoableEdit(this as Graph, false);
|
||||
edit.add(change);
|
||||
this.fireEvent(new EventObject(InternalEvent.UNDO, 'edit', edit));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Inner callback to add the specified {@link Cell} to the selection. No event
|
||||
|
@ -246,11 +363,11 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} to add to the selection.
|
||||
*/
|
||||
cellAdded(cell: Cell) {
|
||||
cellAdded(cell) {
|
||||
if (!this.isSelected(cell)) {
|
||||
this.cells.push(cell);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Inner callback to remove the specified {@link Cell} from the selection. No
|
||||
|
@ -258,12 +375,12 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} to remove from the selection.
|
||||
*/
|
||||
cellRemoved(cell: Cell) {
|
||||
cellRemoved(cell) {
|
||||
const index = this.cells.indexOf(cell);
|
||||
if (index >= 0) {
|
||||
this.cells.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Selection
|
||||
|
@ -274,98 +391,98 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} for which the selection state should be returned.
|
||||
*/
|
||||
isCellSelected(cell: Cell) {
|
||||
isCellSelected(cell) {
|
||||
return this.isSelected(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the selection is empty.
|
||||
*/
|
||||
isSelectionEmpty() {
|
||||
return this.isEmpty();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the selection using {@link mxGraphSelectionModel.clear}.
|
||||
*/
|
||||
clearSelection() {
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the number of selected cells.
|
||||
*/
|
||||
getSelectionCount() {
|
||||
return this.cells.length;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the first cell from the array of selected {@link Cell}.
|
||||
*/
|
||||
getSelectionCell() {
|
||||
return this.cells[0];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the array of selected {@link Cell}.
|
||||
*/
|
||||
getSelectionCells() {
|
||||
return this.cells.slice();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the selection cell.
|
||||
*
|
||||
* @param cell {@link mxCell} to be selected.
|
||||
*/
|
||||
setSelectionCell(cell: Cell | null) {
|
||||
setSelectionCell(cell) {
|
||||
this.setCell(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the selection cell.
|
||||
*
|
||||
* @param cells Array of {@link Cell} to be selected.
|
||||
*/
|
||||
setSelectionCells(cells: CellArray) {
|
||||
setSelectionCells(cells) {
|
||||
this.setCells(cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given cell to the selection.
|
||||
*
|
||||
* @param cell {@link mxCell} to be add to the selection.
|
||||
*/
|
||||
addSelectionCell(cell: Cell) {
|
||||
addSelectionCell(cell) {
|
||||
this.addCellToSelection(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given cells to the selection.
|
||||
*
|
||||
* @param cells Array of {@link Cell} to be added to the selection.
|
||||
*/
|
||||
addSelectionCells(cells: CellArray) {
|
||||
addSelectionCells(cells) {
|
||||
this.addCellsToSelection(cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the given cell from the selection.
|
||||
*
|
||||
* @param cell {@link mxCell} to be removed from the selection.
|
||||
*/
|
||||
removeSelectionCell(cell: Cell) {
|
||||
removeSelectionCell(cell) {
|
||||
this.removeCellFromSelection(cell);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the given cells from the selection.
|
||||
*
|
||||
* @param cells Array of {@link Cell} to be removed from the selection.
|
||||
*/
|
||||
removeSelectionCells(cells: CellArray) {
|
||||
removeSelectionCells(cells) {
|
||||
this.removeCellsFromSelection(cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects and returns the cells inside the given rectangle for the
|
||||
|
@ -375,39 +492,39 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param evt Mouseevent that triggered the selection.
|
||||
*/
|
||||
// selectRegion(rect: mxRectangle, evt: Event): mxCellArray;
|
||||
selectRegion(rect: Rectangle, evt: MouseEvent) {
|
||||
selectRegion(rect, evt) {
|
||||
const cells = this.getCells(rect.x, rect.y, rect.width, rect.height);
|
||||
this.selectCellsForEvent(cells, evt);
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the next cell.
|
||||
*/
|
||||
selectNextCell() {
|
||||
this.selectCell(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the previous cell.
|
||||
*/
|
||||
selectPreviousCell() {
|
||||
this.selectCell();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the parent cell.
|
||||
*/
|
||||
selectParentCell() {
|
||||
this.selectCell(false, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the first child cell.
|
||||
*/
|
||||
selectChildCell() {
|
||||
this.selectCell(false, false, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the next, parent, first child or previous cell, if all arguments
|
||||
|
@ -460,7 +577,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
this.setSelectionCell(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects all children of the given parent cell or the children of the
|
||||
|
@ -472,7 +589,9 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param descendants Optional boolean specifying whether all descendants should be
|
||||
* selected. Default is `false`.
|
||||
*/
|
||||
selectAll(parent: Cell = this.getDefaultParent(), descendants: boolean = false) {
|
||||
selectAll(parent, descendants = false) {
|
||||
parent = parent ?? this.getDefaultParent();
|
||||
|
||||
const cells = descendants
|
||||
? parent.filterDescendants((cell: Cell) => {
|
||||
return cell !== parent && !!this.getView().getState(cell);
|
||||
|
@ -480,21 +599,21 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
: parent.getChildren();
|
||||
|
||||
this.setSelectionCells(cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Select all vertices inside the given parent or the default parent.
|
||||
*/
|
||||
selectVertices(parent: Cell, selectGroups = false) {
|
||||
selectVertices(parent, selectGroups = false) {
|
||||
this.selectCells(true, false, parent, selectGroups);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Select all vertices inside the given parent or the default parent.
|
||||
*/
|
||||
selectEdges(parent: Cell) {
|
||||
selectEdges(parent) {
|
||||
this.selectCells(false, true, parent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects all vertices and/or edges depending on the given boolean
|
||||
|
@ -509,12 +628,9 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param selectGroups Optional boolean that specifies if groups should be
|
||||
* selected. Default is `false`.
|
||||
*/
|
||||
selectCells(
|
||||
vertices = false,
|
||||
edges = false,
|
||||
parent: Cell = this.getDefaultParent(),
|
||||
selectGroups = false
|
||||
) {
|
||||
selectCells(vertices = false, edges = false, parent, selectGroups = false) {
|
||||
parent = parent ?? this.getDefaultParent();
|
||||
|
||||
const filter = (cell: Cell) => {
|
||||
const p = cell.getParent();
|
||||
|
||||
|
@ -531,7 +647,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
|
||||
const cells = parent.filterDescendants(filter);
|
||||
this.setSelectionCells(cells);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the given cell by either adding it to the selection or
|
||||
|
@ -541,7 +657,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} to be selected.
|
||||
* @param evt Optional mouseevent that triggered the selection.
|
||||
*/
|
||||
selectCellForEvent(cell: Cell, evt: MouseEvent) {
|
||||
selectCellForEvent(cell, evt) {
|
||||
const isSelected = this.isCellSelected(cell);
|
||||
|
||||
if (this.isToggleEvent(evt)) {
|
||||
|
@ -553,7 +669,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
} else if (!isSelected || this.getSelectionCount() !== 1) {
|
||||
this.setSelectionCell(cell);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the given cells by either adding them to the selection or
|
||||
|
@ -563,18 +679,18 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* @param cells Array of {@link Cell} to be selected.
|
||||
* @param evt Optional mouseevent that triggered the selection.
|
||||
*/
|
||||
selectCellsForEvent(cells: CellArray, evt: MouseEvent) {
|
||||
selectCellsForEvent(cells, evt) {
|
||||
if (this.isToggleEvent(evt)) {
|
||||
this.addSelectionCells(cells);
|
||||
} else {
|
||||
this.setSelectionCells(cells);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if any sibling of the given cell is selected.
|
||||
*/
|
||||
isSiblingSelected(cell: Cell) {
|
||||
isSiblingSelected(cell) {
|
||||
const parent = cell.getParent() as Cell;
|
||||
const childCount = parent.getChildCount();
|
||||
|
||||
|
@ -586,7 +702,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Selection state
|
||||
|
@ -603,7 +719,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
* change should be ignored.
|
||||
*
|
||||
*/
|
||||
getSelectionCellsForChanges(changes: any[], ignoreFn: Function | null = null) {
|
||||
getSelectionCellsForChanges(changes, ignoreFn = null) {
|
||||
const dict = new Dictionary();
|
||||
const cells: CellArray = new CellArray();
|
||||
|
||||
|
@ -640,7 +756,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes selection cells that are not in the model from the selection.
|
||||
|
@ -666,7 +782,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
this.removeSelectionCells(removed);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphSelection;
|
||||
mixInto(Graph)(GraphSelectionMixin);
|
|
@ -17,7 +17,7 @@ import mxClient from '../../mxClient';
|
|||
import Rectangle from '../geometry/Rectangle';
|
||||
import { isAltDown, isMultiTouchEvent } from '../../util/EventUtils';
|
||||
import { clearSelection } from '../../util/DomUtils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import { GraphPlugin } from '../../types';
|
||||
import EventObject from '../event/EventObject';
|
||||
import EventSource from '../event/EventSource';
|
||||
|
@ -30,7 +30,7 @@ import EventSource from '../event/EventSource';
|
|||
class RubberBand implements GraphPlugin {
|
||||
static pluginId = 'RubberBand';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.graph = graph;
|
||||
this.graph.addMouseListener(this);
|
||||
|
||||
|
@ -71,7 +71,7 @@ class RubberBand implements GraphPlugin {
|
|||
forceRubberbandHandler: Function;
|
||||
panHandler: Function;
|
||||
gestureHandler: Function;
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
first: Point | null = null;
|
||||
destroyed: boolean = false;
|
||||
dragHandler: ((evt: MouseEvent) => void) | null = null;
|
||||
|
|
|
@ -9,7 +9,7 @@ import Dictionary from '../../util/Dictionary';
|
|||
import EventObject from '../event/EventObject';
|
||||
import InternalEvent from '../event/InternalEvent';
|
||||
import { sortCells } from '../../util/Utils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import { GraphPlugin } from '../../types';
|
||||
|
@ -42,7 +42,7 @@ import InternalMouseEvent from '../event/InternalMouseEvent';
|
|||
class SelectionCellsHandler extends EventSource implements GraphPlugin {
|
||||
static pluginId = 'SelectionCellsHandler';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -71,7 +71,7 @@ class SelectionCellsHandler extends EventSource implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: enabled
|
||||
|
|
|
@ -4,7 +4,7 @@ import InternalEvent from '../event/InternalEvent';
|
|||
import CellArray from '../cell/datatypes/CellArray';
|
||||
|
||||
import type { UndoableChange } from '../../types';
|
||||
import type { MaxGraph } from '../Graph';
|
||||
import type { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* @class SelectionChange
|
||||
|
@ -12,7 +12,7 @@ import type { MaxGraph } from '../Graph';
|
|||
*/
|
||||
class SelectionChange implements UndoableChange {
|
||||
constructor(
|
||||
graph: MaxGraph,
|
||||
graph: Graph,
|
||||
added: CellArray = new CellArray(),
|
||||
removed: CellArray = new CellArray()
|
||||
) {
|
||||
|
@ -21,7 +21,7 @@ class SelectionChange implements UndoableChange {
|
|||
this.removed = removed.slice();
|
||||
}
|
||||
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
added: CellArray;
|
||||
|
||||
|
|
|
@ -1,29 +1,66 @@
|
|||
import { autoImplement } from '../../util/Utils';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
import Point from '../geometry/Point';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
snapTolerance: number;
|
||||
gridSize: number;
|
||||
gridEnabled: boolean;
|
||||
|
||||
getSnapTolerance: () => number;
|
||||
snap: (value: number) => number;
|
||||
snapDelta: (
|
||||
delta: Point,
|
||||
bounds: Rectangle,
|
||||
ignoreGrid: boolean,
|
||||
ignoreHorizontal: boolean,
|
||||
ignoreVertical: boolean
|
||||
) => Point;
|
||||
isGridEnabled: () => boolean;
|
||||
setGridEnabled: (value: boolean) => void;
|
||||
getGridSize: () => number;
|
||||
setGridSize: (value: number) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getView'>;
|
||||
type PartialClass = PartialGraph;
|
||||
type PartialSnap = Pick<
|
||||
Graph,
|
||||
| 'snapTolerance'
|
||||
| 'gridSize'
|
||||
| 'gridEnabled'
|
||||
| 'getSnapTolerance'
|
||||
| 'snap'
|
||||
| 'snapDelta'
|
||||
| 'isGridEnabled'
|
||||
| 'setGridEnabled'
|
||||
| 'getGridSize'
|
||||
| 'setGridSize'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialSnap;
|
||||
|
||||
class GraphSnap extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphSnapMixin: PartialType = {
|
||||
// TODO: Document me!
|
||||
snapTolerance: number = 0;
|
||||
snapTolerance: 0,
|
||||
|
||||
getSnapTolerance = () => this.snapTolerance;
|
||||
getSnapTolerance() {
|
||||
return this.snapTolerance;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies the grid size.
|
||||
* @default 10
|
||||
*/
|
||||
gridSize = 10;
|
||||
gridSize: 10,
|
||||
|
||||
/**
|
||||
* Specifies if the grid is enabled. This is used in {@link snap}.
|
||||
* @default true
|
||||
*/
|
||||
gridEnabled = true;
|
||||
gridEnabled: true,
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph display
|
||||
|
@ -34,12 +71,12 @@ class GraphSnap extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param value Numeric value to be snapped to the grid.
|
||||
*/
|
||||
snap(value: number) {
|
||||
snap(value) {
|
||||
if (this.gridEnabled) {
|
||||
value = Math.round(value / this.gridSize) * this.gridSize;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: snapDelta
|
||||
|
@ -47,8 +84,8 @@ class GraphSnap extends autoImplement<PartialClass>() {
|
|||
* Snaps the given delta with the given scaled bounds.
|
||||
*/
|
||||
snapDelta(
|
||||
delta: Point,
|
||||
bounds: Rectangle,
|
||||
delta,
|
||||
bounds,
|
||||
ignoreGrid = false,
|
||||
ignoreHorizontal = false,
|
||||
ignoreVertical = false
|
||||
|
@ -102,7 +139,7 @@ class GraphSnap extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -113,44 +150,30 @@ class GraphSnap extends autoImplement<PartialClass>() {
|
|||
*/
|
||||
isGridEnabled() {
|
||||
return this.gridEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the grid should be enabled.
|
||||
*
|
||||
* @param value Boolean indicating if the grid should be enabled.
|
||||
*/
|
||||
setGridEnabled(value: boolean) {
|
||||
setGridEnabled(value) {
|
||||
this.gridEnabled = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link gridSize}.
|
||||
*/
|
||||
getGridSize() {
|
||||
return this.gridSize;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets {@link gridSize}.
|
||||
*/
|
||||
setGridSize(value: number) {
|
||||
setGridSize(value) {
|
||||
this.gridSize = value;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns {@link tolerance}.
|
||||
*/
|
||||
getTolerance() {
|
||||
return this.snapTolerance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link tolerance}.
|
||||
*/
|
||||
setTolerance(value: number) {
|
||||
this.snapTolerance = value;
|
||||
}
|
||||
}
|
||||
|
||||
export default GraphSnap;
|
||||
mixInto(Graph)(GraphSnapMixin);
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import utils, {
|
||||
import {
|
||||
contains,
|
||||
getBoundingBox,
|
||||
getNumber,
|
||||
|
@ -129,8 +129,7 @@ class EdgeStyle {
|
|||
static EntityRelation(state, source, target, points, result) {
|
||||
const { view } = state;
|
||||
const { graph } = view;
|
||||
const segment =
|
||||
getValue(state.style, 'segment', ENTITY_SEGMENT) * view.scale;
|
||||
const segment = getValue(state.style, 'segment', ENTITY_SEGMENT) * view.scale;
|
||||
|
||||
const pts = state.absolutePoints;
|
||||
const p0 = pts[0];
|
||||
|
@ -145,8 +144,7 @@ class EdgeStyle {
|
|||
isSourceLeft = sourceGeometry.x <= 0.5;
|
||||
} else if (target != null) {
|
||||
isSourceLeft =
|
||||
(pe != null ? pe.x : target.x + target.width) <
|
||||
(p0 != null ? p0.x : source.x);
|
||||
(pe != null ? pe.x : target.x + target.width) < (p0 != null ? p0.x : source.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,12 +153,7 @@ class EdgeStyle {
|
|||
source.x = p0.x;
|
||||
source.y = p0.y;
|
||||
} else if (source != null) {
|
||||
const constraint = getPortConstraints(
|
||||
source,
|
||||
state,
|
||||
true,
|
||||
DIRECTION_MASK_NONE
|
||||
);
|
||||
const constraint = getPortConstraints(source, state, true, DIRECTION_MASK_NONE);
|
||||
|
||||
if (
|
||||
constraint !== DIRECTION_MASK_NONE &&
|
||||
|
@ -181,8 +174,7 @@ class EdgeStyle {
|
|||
isTargetLeft = targetGeometry.x <= 0.5;
|
||||
} else if (source != null) {
|
||||
isTargetLeft =
|
||||
(p0 != null ? p0.x : source.x + source.width) <
|
||||
(pe != null ? pe.x : target.x);
|
||||
(p0 != null ? p0.x : source.x + source.width) < (pe != null ? pe.x : target.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,12 +183,7 @@ class EdgeStyle {
|
|||
target.x = pe.x;
|
||||
target.y = pe.y;
|
||||
} else if (target != null) {
|
||||
const constraint = getPortConstraints(
|
||||
target,
|
||||
state,
|
||||
false,
|
||||
DIRECTION_MASK_NONE
|
||||
);
|
||||
const constraint = getPortConstraints(target, state, false, DIRECTION_MASK_NONE);
|
||||
|
||||
if (
|
||||
constraint !== DIRECTION_MASK_NONE &&
|
||||
|
@ -223,9 +210,7 @@ class EdgeStyle {
|
|||
|
||||
// Adds intermediate points if both go out on same side
|
||||
if (isSourceLeft === isTargetLeft) {
|
||||
const x = isSourceLeft
|
||||
? Math.min(x0, xe) - segment
|
||||
: Math.max(x0, xe) + segment;
|
||||
const x = isSourceLeft ? Math.min(x0, xe) - segment : Math.max(x0, xe) + segment;
|
||||
|
||||
result.push(new Point(x, y0));
|
||||
result.push(new Point(x, ye));
|
||||
|
@ -284,14 +269,8 @@ class EdgeStyle {
|
|||
let y = 0;
|
||||
let dy = 0;
|
||||
|
||||
const seg =
|
||||
getValue(state.style, 'segment', graph.gridSize) *
|
||||
view.scale;
|
||||
const dir = getValue(
|
||||
state.style,
|
||||
'direction',
|
||||
DIRECTION_WEST
|
||||
);
|
||||
const seg = getValue(state.style, 'segment', graph.gridSize) * view.scale;
|
||||
const dir = getValue(state.style, 'direction', DIRECTION_WEST);
|
||||
|
||||
if (dir === DIRECTION_NORTH || dir === DIRECTION_SOUTH) {
|
||||
x = view.getRoutingCenterX(source);
|
||||
|
@ -343,16 +322,10 @@ class EdgeStyle {
|
|||
if (source != null && target != null) {
|
||||
if (pt != null) {
|
||||
const left = Math.min(source.x, target.x);
|
||||
const right = Math.max(
|
||||
source.x + source.width,
|
||||
target.x + target.width
|
||||
);
|
||||
const right = Math.max(source.x + source.width, target.x + target.width);
|
||||
|
||||
const top = Math.min(source.y, target.y);
|
||||
const bottom = Math.max(
|
||||
source.y + source.height,
|
||||
target.y + target.height
|
||||
);
|
||||
const bottom = Math.max(source.y + source.height, target.y + target.height);
|
||||
|
||||
pt = state.view.transformControlPoint(state, pt);
|
||||
|
||||
|
@ -360,29 +333,20 @@ class EdgeStyle {
|
|||
horizontal = pt.x < left || pt.x > right;
|
||||
} else {
|
||||
const left = Math.max(source.x, target.x);
|
||||
const right = Math.min(
|
||||
source.x + source.width,
|
||||
target.x + target.width
|
||||
);
|
||||
const right = Math.min(source.x + source.width, target.x + target.width);
|
||||
|
||||
vertical = left === right;
|
||||
|
||||
if (!vertical) {
|
||||
const top = Math.max(source.y, target.y);
|
||||
const bottom = Math.min(
|
||||
source.y + source.height,
|
||||
target.y + target.height
|
||||
);
|
||||
const bottom = Math.min(source.y + source.height, target.y + target.height);
|
||||
|
||||
horizontal = top === bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!horizontal &&
|
||||
(vertical || state.style.elbow === ELBOW_VERTICAL)
|
||||
) {
|
||||
if (!horizontal && (vertical || state.style.elbow === ELBOW_VERTICAL)) {
|
||||
EdgeStyle.TopToBottom(state, source, target, points, result);
|
||||
} else {
|
||||
EdgeStyle.SideToSide(state, source, target, points, result);
|
||||
|
@ -437,34 +401,22 @@ class EdgeStyle {
|
|||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!contains(target, x, y1) &&
|
||||
!contains(source, x, y1)
|
||||
) {
|
||||
if (!contains(target, x, y1) && !contains(source, x, y1)) {
|
||||
result.push(new Point(x, y1));
|
||||
}
|
||||
|
||||
if (
|
||||
!contains(target, x, y2) &&
|
||||
!contains(source, x, y2)
|
||||
) {
|
||||
if (!contains(target, x, y2) && !contains(source, x, y2)) {
|
||||
result.push(new Point(x, y2));
|
||||
}
|
||||
|
||||
if (result.length === 1) {
|
||||
if (pt != null) {
|
||||
if (
|
||||
!contains(target, x, pt.y) &&
|
||||
!contains(source, x, pt.y)
|
||||
) {
|
||||
if (!contains(target, x, pt.y) && !contains(source, x, pt.y)) {
|
||||
result.push(new Point(x, pt.y));
|
||||
}
|
||||
} else {
|
||||
const t = Math.max(source.y, target.y);
|
||||
const b = Math.min(
|
||||
source.y + source.height,
|
||||
target.y + target.height
|
||||
);
|
||||
const b = Math.min(source.y + source.height, target.y + target.height);
|
||||
|
||||
result.push(new Point(x, t + (b - t) / 2));
|
||||
}
|
||||
|
@ -529,10 +481,7 @@ class EdgeStyle {
|
|||
|
||||
if (result.length === 1) {
|
||||
if (pt != null && result.length === 1) {
|
||||
if (
|
||||
!contains(target, pt.x, y) &&
|
||||
!contains(source, pt.x, y)
|
||||
) {
|
||||
if (!contains(target, pt.x, y) && !contains(source, pt.x, y)) {
|
||||
result.push(new Point(pt.x, y));
|
||||
}
|
||||
} else {
|
||||
|
@ -559,18 +508,9 @@ class EdgeStyle {
|
|||
* edge.
|
||||
*
|
||||
*/
|
||||
static SegmentConnector(
|
||||
state,
|
||||
sourceScaled,
|
||||
targetScaled,
|
||||
controlHints,
|
||||
result
|
||||
) {
|
||||
static SegmentConnector(state, sourceScaled, targetScaled, controlHints, result) {
|
||||
// Creates array of all way- and terminalpoints
|
||||
const pts = EdgeStyle.scalePointArray(
|
||||
state.absolutePoints,
|
||||
state.view.scale
|
||||
);
|
||||
const pts = EdgeStyle.scalePointArray(state.absolutePoints, state.view.scale);
|
||||
const source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale);
|
||||
const target = EdgeStyle.scaleCellState(targetScaled, state.view.scale);
|
||||
const tol = 1;
|
||||
|
@ -618,11 +558,7 @@ class EdgeStyle {
|
|||
let hints = [];
|
||||
|
||||
for (let i = 0; i < controlHints.length; i += 1) {
|
||||
const tmp = state.view.transformControlPoint(
|
||||
state,
|
||||
controlHints[i],
|
||||
true
|
||||
);
|
||||
const tmp = state.view.transformControlPoint(state, controlHints[i], true);
|
||||
|
||||
if (tmp != null) {
|
||||
hints.push(tmp);
|
||||
|
@ -671,10 +607,8 @@ class EdgeStyle {
|
|||
// Check for alignment with fixed points and with channels
|
||||
// at source and target segments only
|
||||
for (let i = 0; i < 2; i += 1) {
|
||||
const fixedVertAlign =
|
||||
currentPt != null && currentPt.x === currentHint.x;
|
||||
const fixedHozAlign =
|
||||
currentPt != null && currentPt.y === currentHint.y;
|
||||
const fixedVertAlign = currentPt != null && currentPt.x === currentHint.x;
|
||||
const fixedHozAlign = currentPt != null && currentPt.y === currentHint.y;
|
||||
|
||||
const inHozChan =
|
||||
currentTerm != null &&
|
||||
|
@ -692,10 +626,7 @@ class EdgeStyle {
|
|||
// of a floating port, or if the hint is exactly co-incident with a
|
||||
// fixed point, ignore the source and try to work out the orientation
|
||||
// from the target end
|
||||
if (
|
||||
i == 0 &&
|
||||
((hozChan && vertChan) || (fixedVertAlign && fixedHozAlign))
|
||||
) {
|
||||
if (i == 0 && ((hozChan && vertChan) || (fixedVertAlign && fixedHozAlign))) {
|
||||
} else {
|
||||
if (
|
||||
currentPt != null &&
|
||||
|
@ -826,11 +757,7 @@ class EdgeStyle {
|
|||
while (
|
||||
result.length > 1 &&
|
||||
result[result.length - 1] != null &&
|
||||
contains(
|
||||
target,
|
||||
result[result.length - 1].x,
|
||||
result[result.length - 1].y
|
||||
)
|
||||
contains(target, result[result.length - 1].x, result[result.length - 1].y)
|
||||
) {
|
||||
result.splice(result.length - 1, 1);
|
||||
}
|
||||
|
@ -967,11 +894,7 @@ class EdgeStyle {
|
|||
|
||||
if (value === 'auto') {
|
||||
// Computes the automatic jetty size
|
||||
const type = getValue(
|
||||
state.style,
|
||||
isSource ? 'startArrow' : 'endArrow',
|
||||
NONE
|
||||
);
|
||||
const type = getValue(state.style, isSource ? 'startArrow' : 'endArrow', NONE);
|
||||
|
||||
if (type !== NONE) {
|
||||
const size = getNumber(
|
||||
|
@ -980,10 +903,8 @@ class EdgeStyle {
|
|||
DEFAULT_MARKERSIZE
|
||||
);
|
||||
value =
|
||||
Math.max(
|
||||
2,
|
||||
Math.ceil((size + EdgeStyle.orthBuffer) / EdgeStyle.orthBuffer)
|
||||
) * EdgeStyle.orthBuffer;
|
||||
Math.max(2, Math.ceil((size + EdgeStyle.orthBuffer) / EdgeStyle.orthBuffer)) *
|
||||
EdgeStyle.orthBuffer;
|
||||
} else {
|
||||
value = 2 * EdgeStyle.orthBuffer;
|
||||
}
|
||||
|
@ -1070,21 +991,12 @@ class EdgeStyle {
|
|||
* edge.
|
||||
*
|
||||
*/
|
||||
static OrthConnector(
|
||||
state,
|
||||
sourceScaled,
|
||||
targetScaled,
|
||||
controlHints,
|
||||
result
|
||||
) {
|
||||
static OrthConnector(state, sourceScaled, targetScaled, controlHints, result) {
|
||||
const { graph } = state.view;
|
||||
const sourceEdge = source == null ? false : source.cell.isEdge();
|
||||
const targetEdge = target == null ? false : target.cell.isEdge();
|
||||
|
||||
const pts = EdgeStyle.scalePointArray(
|
||||
state.absolutePoints,
|
||||
state.view.scale
|
||||
);
|
||||
const pts = EdgeStyle.scalePointArray(state.absolutePoints, state.view.scale);
|
||||
let source = EdgeStyle.scaleCellState(sourceScaled, state.view.scale);
|
||||
let target = EdgeStyle.scaleCellState(targetScaled, state.view.scale);
|
||||
|
||||
|
@ -1126,19 +1038,11 @@ class EdgeStyle {
|
|||
|
||||
if (
|
||||
tooShort ||
|
||||
(EdgeStyle.orthPointsFallback &&
|
||||
controlHints != null &&
|
||||
controlHints.length > 0) ||
|
||||
(EdgeStyle.orthPointsFallback && controlHints != null && controlHints.length > 0) ||
|
||||
sourceEdge ||
|
||||
targetEdge
|
||||
) {
|
||||
EdgeStyle.SegmentConnector(
|
||||
state,
|
||||
sourceScaled,
|
||||
targetScaled,
|
||||
controlHints,
|
||||
result
|
||||
);
|
||||
EdgeStyle.SegmentConnector(state, sourceScaled, targetScaled, controlHints, result);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1150,13 +1054,8 @@ class EdgeStyle {
|
|||
let rotation = 0;
|
||||
|
||||
if (source != null) {
|
||||
portConstraint[0] = getPortConstraints(
|
||||
source,
|
||||
state,
|
||||
true,
|
||||
DIRECTION_MASK_ALL
|
||||
);
|
||||
rotation = getValue(source.style, 'rotation', 0);
|
||||
portConstraint[0] = getPortConstraints(source, state, true, DIRECTION_MASK_ALL);
|
||||
rotation = source.style.rotation ?? 0;
|
||||
|
||||
// console.log('source rotation', rotation);
|
||||
|
||||
|
@ -1173,13 +1072,8 @@ class EdgeStyle {
|
|||
}
|
||||
|
||||
if (target != null) {
|
||||
portConstraint[1] = getPortConstraints(
|
||||
target,
|
||||
state,
|
||||
false,
|
||||
DIRECTION_MASK_ALL
|
||||
);
|
||||
rotation = getValue(target.style, 'rotation', 0);
|
||||
portConstraint[1] = getPortConstraints(target, state, false, DIRECTION_MASK_ALL);
|
||||
rotation = target.style.rotation ?? 0;
|
||||
|
||||
// console.log('target rotation', rotation);
|
||||
|
||||
|
@ -1292,19 +1186,10 @@ class EdgeStyle {
|
|||
const sourceBottomDist = geo[1][1] - (geo[0][1] + geo[0][3]);
|
||||
const sourceRightDist = geo[1][0] - (geo[0][0] + geo[0][2]);
|
||||
|
||||
EdgeStyle.vertexSeperations[1] = Math.max(
|
||||
sourceLeftDist - totalBuffer,
|
||||
0
|
||||
);
|
||||
EdgeStyle.vertexSeperations[1] = Math.max(sourceLeftDist - totalBuffer, 0);
|
||||
EdgeStyle.vertexSeperations[2] = Math.max(sourceTopDist - totalBuffer, 0);
|
||||
EdgeStyle.vertexSeperations[4] = Math.max(
|
||||
sourceBottomDist - totalBuffer,
|
||||
0
|
||||
);
|
||||
EdgeStyle.vertexSeperations[3] = Math.max(
|
||||
sourceRightDist - totalBuffer,
|
||||
0
|
||||
);
|
||||
EdgeStyle.vertexSeperations[4] = Math.max(sourceBottomDist - totalBuffer, 0);
|
||||
EdgeStyle.vertexSeperations[3] = Math.max(sourceRightDist - totalBuffer, 0);
|
||||
|
||||
//= =============================================================
|
||||
// Start of source and target direction determination
|
||||
|
@ -1317,13 +1202,9 @@ class EdgeStyle {
|
|||
const vertPref = [];
|
||||
|
||||
horPref[0] =
|
||||
sourceLeftDist >= sourceRightDist
|
||||
? DIRECTION_MASK_WEST
|
||||
: DIRECTION_MASK_EAST;
|
||||
sourceLeftDist >= sourceRightDist ? DIRECTION_MASK_WEST : DIRECTION_MASK_EAST;
|
||||
vertPref[0] =
|
||||
sourceTopDist >= sourceBottomDist
|
||||
? DIRECTION_MASK_NORTH
|
||||
: DIRECTION_MASK_SOUTH;
|
||||
sourceTopDist >= sourceBottomDist ? DIRECTION_MASK_NORTH : DIRECTION_MASK_SOUTH;
|
||||
|
||||
horPref[1] = reversePortConstraints(horPref[0]);
|
||||
vertPref[1] = reversePortConstraints(vertPref[0]);
|
||||
|
@ -1359,10 +1240,7 @@ class EdgeStyle {
|
|||
|
||||
if (preferredVertDist > 0 && preferredHorizDist > 0) {
|
||||
// Possibility of two segment edge connection
|
||||
if (
|
||||
(horPref[0] & portConstraint[0]) > 0 &&
|
||||
(vertPref[1] & portConstraint[1]) > 0
|
||||
) {
|
||||
if ((horPref[0] & portConstraint[0]) > 0 && (vertPref[1] & portConstraint[1]) > 0) {
|
||||
prefOrdering[0][0] = horPref[0];
|
||||
prefOrdering[0][1] = vertPref[0];
|
||||
prefOrdering[1][0] = vertPref[1];
|
||||
|
@ -1455,8 +1333,7 @@ class EdgeStyle {
|
|||
targetIndex += 4;
|
||||
}
|
||||
|
||||
const routePattern =
|
||||
EdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1];
|
||||
const routePattern = EdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1];
|
||||
|
||||
// console.log('routePattern', routePattern);
|
||||
|
||||
|
@ -1495,8 +1372,7 @@ class EdgeStyle {
|
|||
|
||||
// Rotate the index of this direction by the quad
|
||||
// to get the real direction
|
||||
let directionIndex =
|
||||
nextDirection === DIRECTION_MASK_EAST ? 3 : nextDirection;
|
||||
let directionIndex = nextDirection === DIRECTION_MASK_EAST ? 3 : nextDirection;
|
||||
|
||||
directionIndex += quad;
|
||||
|
||||
|
@ -1517,10 +1393,8 @@ class EdgeStyle {
|
|||
// We can't base the new position on index - 1
|
||||
// because sometime elbows turn out not to exist,
|
||||
// then we'd have to rewind.
|
||||
EdgeStyle.wayPoints1[currentIndex][0] =
|
||||
EdgeStyle.wayPoints1[currentIndex - 1][0];
|
||||
EdgeStyle.wayPoints1[currentIndex][1] =
|
||||
EdgeStyle.wayPoints1[currentIndex - 1][1];
|
||||
EdgeStyle.wayPoints1[currentIndex][0] = EdgeStyle.wayPoints1[currentIndex - 1][0];
|
||||
EdgeStyle.wayPoints1[currentIndex][1] = EdgeStyle.wayPoints1[currentIndex - 1][1];
|
||||
}
|
||||
|
||||
const tar = (routePattern[i] & EdgeStyle.TARGET_MASK) > 0;
|
||||
|
@ -1564,11 +1438,9 @@ class EdgeStyle {
|
|||
} else if (center) {
|
||||
// Which center we're travelling to depend on the current direction
|
||||
EdgeStyle.wayPoints1[currentIndex][0] +=
|
||||
direction[0] *
|
||||
Math.abs(EdgeStyle.vertexSeperations[directionIndex] / 2);
|
||||
direction[0] * Math.abs(EdgeStyle.vertexSeperations[directionIndex] / 2);
|
||||
EdgeStyle.wayPoints1[currentIndex][1] +=
|
||||
direction[1] *
|
||||
Math.abs(EdgeStyle.vertexSeperations[directionIndex] / 2);
|
||||
direction[1] * Math.abs(EdgeStyle.vertexSeperations[directionIndex] / 2);
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Type definitions from the typed-mxgraph project
|
||||
*/
|
||||
|
||||
import utils, { intersection } from '../../util/Utils';
|
||||
import { intersection } from '../../util/Utils';
|
||||
import Point from '../geometry/Point';
|
||||
import {
|
||||
DIRECTION_EAST,
|
||||
|
@ -311,8 +311,7 @@ class Perimeter {
|
|||
orthogonal: boolean = false
|
||||
): Point | null {
|
||||
const direction = vertex != null ? vertex.style.direction : null;
|
||||
const vertical =
|
||||
direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
const vertical = direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
|
||||
const { x } = bounds;
|
||||
const { y } = bounds;
|
||||
|
@ -395,10 +394,7 @@ class Perimeter {
|
|||
cy = pt.y;
|
||||
}
|
||||
|
||||
if (
|
||||
(vertical && next.x <= x + w / 2) ||
|
||||
(!vertical && next.y <= y + h / 2)
|
||||
) {
|
||||
if ((vertical && next.x <= x + w / 2) || (!vertical && next.y <= y + h / 2)) {
|
||||
result = intersection(
|
||||
next.x,
|
||||
next.y,
|
||||
|
@ -410,16 +406,7 @@ class Perimeter {
|
|||
corner.y
|
||||
);
|
||||
} else {
|
||||
result = intersection(
|
||||
next.x,
|
||||
next.y,
|
||||
cx,
|
||||
cy,
|
||||
corner.x,
|
||||
corner.y,
|
||||
end.x,
|
||||
end.y
|
||||
);
|
||||
result = intersection(next.x, next.y, cx, cy, corner.x, corner.y, end.x, end.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,8 +447,7 @@ class Perimeter {
|
|||
vertex != null
|
||||
? Perimeter.getValue(vertex.style, 'direction', DIRECTION_EAST)
|
||||
: DIRECTION_EAST;
|
||||
const vertical =
|
||||
direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
const vertical = direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH;
|
||||
let a = new Point();
|
||||
let b = new Point();
|
||||
|
||||
|
@ -735,7 +721,11 @@ class Perimeter {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static getValue(style: CellStateStyles, direction: string, DIRECTION_EAST: string) {
|
||||
private static getValue(
|
||||
style: CellStateStyles,
|
||||
direction: string,
|
||||
DIRECTION_EAST: string
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Cell from '../cell/datatypes/Cell';
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import utils, { autoImplement, convertPoint, getValue, mod } from '../../util/Utils';
|
||||
import { convertPoint, getValue, mixInto, mod } from '../../util/Utils';
|
||||
import {
|
||||
DEFAULT_STARTSIZE,
|
||||
DIRECTION_EAST,
|
||||
|
@ -10,44 +10,94 @@ import {
|
|||
SHAPE_SWIMLANE,
|
||||
} from '../../util/Constants';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import { getClientX, getClientY } from '../../util/EventUtils';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import GraphCells from '../cell/GraphCells';
|
||||
import { CellStateStyles } from '../../types';
|
||||
import GraphDragDrop from '../drag_drop/GraphDragDrop';
|
||||
import GraphPanning from '../panning/GraphPanning';
|
||||
import { CellStateStyles, DirectionValue } from '../../types';
|
||||
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
swimlaneSelectionEnabled: boolean;
|
||||
swimlaneNesting: boolean;
|
||||
swimlaneIndicatorColorAttribute: string;
|
||||
|
||||
getSwimlane: (cell: Cell | null) => Cell | null;
|
||||
getSwimlaneAt: (x: number, y: number, parent?: Cell | null) => Cell | null;
|
||||
hitsSwimlaneContent: (swimlane: Cell, x: number, y: number) => boolean;
|
||||
getStartSize: (swimlane: Cell, ignoreState?: boolean) => Rectangle;
|
||||
getSwimlaneDirection: (style: CellStateStyles) => DirectionValue;
|
||||
getActualStartSize: (swimlane: Cell, ignoreState: boolean) => Rectangle;
|
||||
isSwimlane: (cell: Cell, ignoreState?: boolean) => boolean;
|
||||
isValidDropTarget: (cell: Cell, cells: CellArray, evt: MouseEvent) => boolean;
|
||||
getDropTarget: (
|
||||
cells: CellArray,
|
||||
evt: MouseEvent,
|
||||
cell: Cell | null,
|
||||
clone?: boolean
|
||||
) => Cell | null;
|
||||
isSwimlaneNesting: () => boolean;
|
||||
setSwimlaneNesting: (value: boolean) => void;
|
||||
isSwimlaneSelectionEnabled: () => boolean;
|
||||
setSwimlaneSelectionEnabled: (value: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'getDefaultParent' | 'getCurrentRoot' | 'getModel' | 'getView' | 'getContainer'
|
||||
| 'getDefaultParent'
|
||||
| 'getCurrentRoot'
|
||||
| 'getModel'
|
||||
| 'getView'
|
||||
| 'getContainer'
|
||||
| 'getCurrentCellStyle'
|
||||
| 'intersects'
|
||||
| 'isSplitEnabled'
|
||||
| 'isSplitTarget'
|
||||
| 'getPanDx'
|
||||
| 'getPanDy'
|
||||
>;
|
||||
type PartialCells = Pick<GraphCells, 'getCurrentCellStyle' | 'intersects'>;
|
||||
type PartialDragDrop = Pick<GraphDragDrop, 'isSplitEnabled' | 'isSplitTarget'>;
|
||||
type PartialPanning = Pick<GraphPanning, 'getPanDx' | 'getPanDy'>;
|
||||
type PartialClass = PartialGraph & PartialCells & PartialDragDrop & PartialPanning;
|
||||
type PartialSwimlane = Pick<
|
||||
Graph,
|
||||
| 'swimlaneSelectionEnabled'
|
||||
| 'swimlaneNesting'
|
||||
| 'swimlaneIndicatorColorAttribute'
|
||||
| 'getSwimlane'
|
||||
| 'getSwimlaneAt'
|
||||
| 'hitsSwimlaneContent'
|
||||
| 'getStartSize'
|
||||
| 'getSwimlaneDirection'
|
||||
| 'getActualStartSize'
|
||||
| 'isSwimlane'
|
||||
| 'isValidDropTarget'
|
||||
| 'getDropTarget'
|
||||
| 'isSwimlaneNesting'
|
||||
| 'setSwimlaneNesting'
|
||||
| 'isSwimlaneSelectionEnabled'
|
||||
| 'setSwimlaneSelectionEnabled'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialSwimlane;
|
||||
|
||||
class GraphSwimlane extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphSwimlaneMixin: PartialType = {
|
||||
/**
|
||||
* Specifies if swimlanes should be selectable via the content if the
|
||||
* mouse is released.
|
||||
* @default true
|
||||
*/
|
||||
swimlaneSelectionEnabled = true;
|
||||
swimlaneSelectionEnabled: true,
|
||||
|
||||
/**
|
||||
* Specifies if nesting of swimlanes is allowed.
|
||||
* @default true
|
||||
*/
|
||||
swimlaneNesting = true;
|
||||
swimlaneNesting: true,
|
||||
|
||||
/**
|
||||
* The attribute used to find the color for the indicator if the indicator
|
||||
* color is set to 'swimlane'.
|
||||
* @default {@link 'fillColor'}
|
||||
*/
|
||||
swimlaneIndicatorColorAttribute = 'fillColor';
|
||||
swimlaneIndicatorColorAttribute: 'fillColor',
|
||||
|
||||
/**
|
||||
* Returns the nearest ancestor of the given cell which is a swimlane, or
|
||||
|
@ -55,12 +105,12 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} for which the ancestor swimlane should be returned.
|
||||
*/
|
||||
getSwimlane(cell: Cell | null = null) {
|
||||
getSwimlane(cell = null) {
|
||||
while (cell && !this.isSwimlane(cell)) {
|
||||
cell = cell.getParent();
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the bottom-most swimlane that intersects the given point (x, y)
|
||||
|
@ -71,7 +121,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param parent {@link mxCell} that should be used as the root of the recursion.
|
||||
* Default is {@link defaultParent}.
|
||||
*/
|
||||
getSwimlaneAt(x: number, y: number, parent?: Cell | null): Cell | null {
|
||||
getSwimlaneAt(x, y, parent) {
|
||||
if (!parent) {
|
||||
parent = this.getCurrentRoot();
|
||||
|
||||
|
@ -103,7 +153,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given coordinate pair is inside the content
|
||||
|
@ -113,7 +163,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param x X-coordinate of the mouse event.
|
||||
* @param y Y-coordinate of the mouse event.
|
||||
*/
|
||||
hitsSwimlaneContent(swimlane: Cell, x: number, y: number) {
|
||||
hitsSwimlaneContent(swimlane, x, y) {
|
||||
const state = this.getView().getState(swimlane);
|
||||
const size = this.getStartSize(swimlane);
|
||||
|
||||
|
@ -130,7 +180,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph appearance
|
||||
|
@ -145,7 +195,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param swimlane {@link mxCell} whose start size should be returned.
|
||||
* @param ignoreState Optional boolean that specifies if cell state should be ignored.
|
||||
*/
|
||||
getStartSize(swimlane: Cell, ignoreState = false) {
|
||||
getStartSize(swimlane, ignoreState = false) {
|
||||
const result = new Rectangle();
|
||||
const style = this.getCurrentCellStyle(swimlane, ignoreState);
|
||||
const size = parseInt(getValue(style, 'startSize', DEFAULT_STARTSIZE));
|
||||
|
@ -156,12 +206,12 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
result.width = size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the direction for the given swimlane style.
|
||||
*/
|
||||
getSwimlaneDirection(style: CellStateStyles) {
|
||||
getSwimlaneDirection(style) {
|
||||
const dir = style.direction ?? DIRECTION_EAST;
|
||||
const flipH = style.flipH;
|
||||
const flipV = style.flipV;
|
||||
|
@ -186,8 +236,10 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
n += 2;
|
||||
}
|
||||
|
||||
return [DIRECTION_NORTH, DIRECTION_EAST, DIRECTION_SOUTH, DIRECTION_WEST][mod(n, 4)];
|
||||
}
|
||||
return [DIRECTION_NORTH, DIRECTION_EAST, DIRECTION_SOUTH, DIRECTION_WEST][
|
||||
mod(n, 4)
|
||||
] as DirectionValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the actual start size of the given swimlane taking into account
|
||||
|
@ -198,7 +250,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param swimlane {@link mxCell} whose start size should be returned.
|
||||
* @param ignoreState Optional boolean that specifies if cell state should be ignored.
|
||||
*/
|
||||
getActualStartSize(swimlane: Cell, ignoreState = false) {
|
||||
getActualStartSize(swimlane, ignoreState = false) {
|
||||
const result = new Rectangle();
|
||||
|
||||
if (this.isSwimlane(swimlane, ignoreState)) {
|
||||
|
@ -217,7 +269,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given cell is a swimlane in the graph. A swimlane is
|
||||
|
@ -227,12 +279,12 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} to be checked.
|
||||
* @param ignoreState Optional boolean that specifies if the cell state should be ignored.
|
||||
*/
|
||||
isSwimlane(cell: Cell, ignoreState = false) {
|
||||
isSwimlane(cell, ignoreState = false) {
|
||||
if (cell && cell.getParent() !== this.getModel().getRoot() && !cell.isEdge()) {
|
||||
return this.getCurrentCellStyle(cell, ignoreState).shape === SHAPE_SWIMLANE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -248,14 +300,14 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param cells {@link mxCell} that should be dropped into the target.
|
||||
* @param evt Mouseevent that triggered the invocation.
|
||||
*/
|
||||
isValidDropTarget(cell: Cell, cells: CellArray, evt: MouseEvent) {
|
||||
isValidDropTarget(cell, cells, evt) {
|
||||
return (
|
||||
cell &&
|
||||
((this.isSplitEnabled() && this.isSplitTarget(cell, cells, evt)) ||
|
||||
(!cell.isEdge() &&
|
||||
(this.isSwimlane(cell) || (cell.getChildCount() > 0 && !cell.isCollapsed()))))
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the given cell if it is a drop target for the given cells or the
|
||||
|
@ -271,12 +323,7 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} that is under the mousepointer.
|
||||
* @param clone Optional boolean to indicate of cells will be cloned.
|
||||
*/
|
||||
getDropTarget(
|
||||
cells: CellArray,
|
||||
evt: MouseEvent,
|
||||
cell: Cell | null = null,
|
||||
clone = false
|
||||
) {
|
||||
getDropTarget(cells, evt, cell = null, clone = false) {
|
||||
if (!this.isSwimlaneNesting()) {
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
if (this.isSwimlane(cells[i])) {
|
||||
|
@ -323,14 +370,14 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return !this.getModel().isLayer(<Cell>cell) && !parent ? cell : null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link swimlaneNesting} as a boolean.
|
||||
*/
|
||||
isSwimlaneNesting() {
|
||||
return this.swimlaneNesting;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if swimlanes can be nested by drag and drop. This is only
|
||||
|
@ -338,16 +385,16 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param value Boolean indicating if swimlanes can be nested.
|
||||
*/
|
||||
setSwimlaneNesting(value: boolean) {
|
||||
setSwimlaneNesting(value) {
|
||||
this.swimlaneNesting = value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns {@link swimlaneSelectionEnabled} as a boolean.
|
||||
*/
|
||||
isSwimlaneSelectionEnabled() {
|
||||
return this.swimlaneSelectionEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if swimlanes should be selected if the mouse is released
|
||||
|
@ -356,9 +403,9 @@ class GraphSwimlane extends autoImplement<PartialClass>() {
|
|||
* @param value Boolean indicating if swimlanes content areas
|
||||
* should be selected when the mouse is released over them.
|
||||
*/
|
||||
setSwimlaneSelectionEnabled(value: boolean) {
|
||||
setSwimlaneSelectionEnabled(value) {
|
||||
this.swimlaneSelectionEnabled = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphSwimlane;
|
||||
mixInto(Graph)(GraphSwimlaneMixin);
|
|
@ -1,14 +1,27 @@
|
|||
import CellArray from '../cell/datatypes/CellArray';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import Dictionary from '../../util/Dictionary';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
isTerminalPointMovable: (cell: Cell, source: boolean) => boolean;
|
||||
getOpposites: (
|
||||
edges: CellArray,
|
||||
terminal: Cell | null,
|
||||
sources?: boolean,
|
||||
targets?: boolean
|
||||
) => CellArray;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<Graph, 'getView'>;
|
||||
type PartialClass = PartialGraph;
|
||||
type PartialTerminal = Pick<Graph, 'isTerminalPointMovable' | 'getOpposites'>;
|
||||
type PartialType = PartialGraph & PartialTerminal;
|
||||
|
||||
class GraphTerminal extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphTerminalMixin: PartialType = {
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
*****************************************************************************/
|
||||
|
@ -23,9 +36,9 @@ class GraphTerminal extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} whose terminal point should be moved.
|
||||
* @param source Boolean indicating if the source or target terminal should be moved.
|
||||
*/
|
||||
isTerminalPointMovable(cell: Cell, source: boolean) {
|
||||
isTerminalPointMovable(cell, source) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Cell retrieval
|
||||
|
@ -44,12 +57,7 @@ class GraphTerminal extends autoImplement<PartialClass>() {
|
|||
* @param targets Optional boolean that specifies if targer terminals should be
|
||||
* included in the result. Default is `true`.
|
||||
*/
|
||||
getOpposites(
|
||||
edges: CellArray,
|
||||
terminal: Cell | null = null,
|
||||
sources = true,
|
||||
targets = true
|
||||
): CellArray {
|
||||
getOpposites(edges, terminal = null, sources = true, targets = true) {
|
||||
const terminals = new CellArray();
|
||||
|
||||
// Fast lookup to avoid duplicates in terminals array
|
||||
|
@ -84,7 +92,7 @@ class GraphTerminal extends autoImplement<PartialClass>() {
|
|||
}
|
||||
}
|
||||
return terminals;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphTerminal;
|
||||
mixInto(Graph)(GraphTerminalMixin);
|
|
@ -3,18 +3,33 @@ import { htmlEntities } from '../../util/StringUtils';
|
|||
import Resources from '../../util/Resources';
|
||||
import Shape from '../geometry/shape/Shape';
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphFolding from '../folding/GraphFolding';
|
||||
import { Graph } from '../Graph';
|
||||
import SelectionCellsHandler from '../selection/SelectionCellsHandler';
|
||||
import TooltipHandler from './TooltipHandler';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
type PartialGraph = Pick<Graph, 'convertValueToString' | 'getPlugin'>;
|
||||
type PartialFolding = Pick<GraphFolding, 'getCollapseExpandResource'>;
|
||||
type PartialClass = PartialGraph & PartialFolding;
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
getTooltip: (
|
||||
state: CellState,
|
||||
node: HTMLElement | SVGElement,
|
||||
x: number,
|
||||
y: number
|
||||
) => HTMLElement | string | null;
|
||||
getTooltipForCell: (cell: Cell) => HTMLElement | string;
|
||||
setTooltips: (enabled: boolean) => void;
|
||||
}
|
||||
}
|
||||
|
||||
class GraphTooltip extends autoImplement<PartialClass>() {
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'convertValueToString' | 'getPlugin' | 'getCollapseExpandResource'
|
||||
>;
|
||||
type PartialTooltip = Pick<Graph, 'getTooltip' | 'getTooltipForCell' | 'setTooltips'>;
|
||||
type PartialType = PartialGraph & PartialTooltip;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphTooltipMixin: PartialType = {
|
||||
/**
|
||||
* Returns the string or DOM node that represents the tooltip for the given
|
||||
* state, node and coordinate pair. This implementation checks if the given
|
||||
|
@ -30,7 +45,7 @@ class GraphTooltip extends autoImplement<PartialClass>() {
|
|||
* @param x X-coordinate of the mouse.
|
||||
* @param y Y-coordinate of the mouse.
|
||||
*/
|
||||
getTooltip(state: CellState, node: HTMLElement | SVGElement, x: number, y: number) {
|
||||
getTooltip(state, node, x, y) {
|
||||
let tip: HTMLElement | string | null = null;
|
||||
|
||||
// Checks if the mouse is over the folding icon
|
||||
|
@ -70,7 +85,7 @@ class GraphTooltip extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return tip;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the string or DOM node to be used as the tooltip for the given
|
||||
|
@ -90,7 +105,7 @@ class GraphTooltip extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} whose tooltip should be returned.
|
||||
*/
|
||||
getTooltipForCell(cell: Cell) {
|
||||
getTooltipForCell(cell) {
|
||||
let tip = null;
|
||||
|
||||
if (cell && 'getTooltip' in cell) {
|
||||
|
@ -101,7 +116,7 @@ class GraphTooltip extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return tip;
|
||||
}
|
||||
},
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph behaviour
|
||||
|
@ -113,11 +128,11 @@ class GraphTooltip extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param enabled Boolean indicating if tooltips should be enabled.
|
||||
*/
|
||||
setTooltips(enabled: boolean) {
|
||||
setTooltips(enabled) {
|
||||
const tooltipHandler = this.getPlugin('TooltipHandler') as TooltipHandler;
|
||||
|
||||
tooltipHandler.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphTooltip;
|
||||
mixInto(Graph)(GraphTooltipMixin);
|
|
@ -9,7 +9,7 @@ import { fit, getScrollOrigin } from '../../util/Utils';
|
|||
import { TOOLTIP_VERTICAL_OFFSET } from '../../util/Constants';
|
||||
import { getSource, isMouseEvent } from '../../util/EventUtils';
|
||||
import { isNode } from '../../util/DomUtils';
|
||||
import { MaxGraph } from '../Graph';
|
||||
import { Graph } from '../Graph';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||
import PopupMenuHandler from '../popups_menus/PopupMenuHandler';
|
||||
|
@ -44,7 +44,7 @@ import EventSource from '../event/EventSource';
|
|||
class TooltipHandler implements GraphPlugin {
|
||||
static pluginId = 'TooltipHandler';
|
||||
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
this.graph = graph;
|
||||
this.delay = 500;
|
||||
this.graph.addMouseListener(this);
|
||||
|
@ -90,7 +90,7 @@ class TooltipHandler implements GraphPlugin {
|
|||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* Variable: delay
|
||||
|
|
|
@ -3,12 +3,26 @@ import Resources from '../../util/Resources';
|
|||
import { isNode } from '../../util/DomUtils';
|
||||
import CellState from '../cell/datatypes/CellState';
|
||||
import Multiplicity from './Multiplicity';
|
||||
import { autoImplement } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
import { mixInto } from '../../util/Utils';
|
||||
|
||||
import type Graph from '../Graph';
|
||||
import type GraphEdge from '../cell/edge/GraphEdge';
|
||||
import type GraphConnections from '../connection/GraphConnections';
|
||||
import type GraphOverlays from '../layout/GraphOverlays';
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
multiplicities: Multiplicity[];
|
||||
|
||||
validationAlert: (message: string) => void;
|
||||
isEdgeValid: (edge: Cell | null, source: Cell, target: Cell) => boolean;
|
||||
getEdgeValidationError: (
|
||||
edge: Cell | null,
|
||||
source: Cell | null,
|
||||
target: Cell | null
|
||||
) => string | null;
|
||||
validateEdge: (edge: Cell, source: Cell, target: Cell) => string | null;
|
||||
validateGraph: (cell: Cell | null, context: any) => string | null;
|
||||
getCellValidationError: (cell: Cell) => string | null;
|
||||
validateCell: (cell: Cell, context: CellState) => string | null;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
|
@ -19,18 +33,30 @@ type PartialGraph = Pick<
|
|||
| 'isValidRoot'
|
||||
| 'getContainsValidationErrorsResource'
|
||||
| 'getAlreadyConnectedResource'
|
||||
| 'isAllowDanglingEdges'
|
||||
| 'isValidConnection'
|
||||
| 'setCellWarning'
|
||||
>;
|
||||
type PartialEdge = Pick<GraphEdge, 'isAllowDanglingEdges'>;
|
||||
type PartialConnections = Pick<GraphConnections, 'isValidConnection'>;
|
||||
type PartialOverlays = Pick<GraphOverlays, 'setCellWarning'>;
|
||||
type PartialClass = PartialGraph & PartialEdge & PartialConnections & PartialOverlays;
|
||||
type PartialValidation = Pick<
|
||||
Graph,
|
||||
| 'multiplicities'
|
||||
| 'validationAlert'
|
||||
| 'isEdgeValid'
|
||||
| 'getEdgeValidationError'
|
||||
| 'validateEdge'
|
||||
| 'validateGraph'
|
||||
| 'getCellValidationError'
|
||||
| 'validateCell'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialValidation;
|
||||
|
||||
class GraphValidation extends autoImplement<PartialClass>() {
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphValidationMixin: PartialType = {
|
||||
/**
|
||||
* An array of {@link Multiplicity} describing the allowed
|
||||
* connections in a graph.
|
||||
*/
|
||||
multiplicities: Multiplicity[] = [];
|
||||
multiplicities: [],
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Validation
|
||||
|
@ -40,9 +66,9 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* Displays the given validation error in a dialog. This implementation uses
|
||||
* mxUtils.alert.
|
||||
*/
|
||||
validationAlert(message: string) {
|
||||
validationAlert(message) {
|
||||
alert(message);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the return value of {@link getEdgeValidationError} for the given
|
||||
|
@ -52,9 +78,9 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* @param source {@link mxCell} that represents the source terminal.
|
||||
* @param target {@link mxCell} that represents the target terminal.
|
||||
*/
|
||||
isEdgeValid(edge: Cell | null, source: Cell, target: Cell) {
|
||||
isEdgeValid(edge, source, target) {
|
||||
return !this.getEdgeValidationError(edge, source, target);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the validation error message to be displayed when inserting or
|
||||
|
@ -93,11 +119,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* @param source {@link mxCell} that represents the source terminal.
|
||||
* @param target {@link mxCell} that represents the target terminal.
|
||||
*/
|
||||
getEdgeValidationError(
|
||||
edge: Cell | null = null,
|
||||
source: Cell | null = null,
|
||||
target: Cell | null = null
|
||||
) {
|
||||
getEdgeValidationError(edge = null, source = null, target = null) {
|
||||
if (edge && !this.isAllowDanglingEdges() && (!source || !target)) {
|
||||
return '';
|
||||
}
|
||||
|
@ -164,7 +186,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return this.isAllowDanglingEdges() ? null : '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook method for subclassers to return an error message for the given
|
||||
|
@ -174,10 +196,9 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* @param source {@link mxCell} that represents the source terminal.
|
||||
* @param target {@link mxCell} that represents the target terminal.
|
||||
*/
|
||||
// validateEdge(edge: mxCell, source: mxCell, target: mxCell): string | null;
|
||||
validateEdge(edge: Cell, source: Cell, target: Cell): void | null {
|
||||
validateEdge(edge, source, target) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates the graph by validating each descendant of the given cell or
|
||||
|
@ -193,7 +214,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* the graph root.
|
||||
* @param context Object that represents the global validation state.
|
||||
*/
|
||||
validateGraph(cell: Cell | null, context: any): string | null {
|
||||
validateGraph(cell, context) {
|
||||
cell = cell ?? this.getModel().getRoot();
|
||||
|
||||
if (!cell) {
|
||||
|
@ -261,7 +282,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
this.getView().validate();
|
||||
}
|
||||
return warning.length > 0 || !isValid ? warning : null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks all {@link multiplicities} that cannot be enforced while the graph is
|
||||
|
@ -270,7 +291,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
*
|
||||
* @param cell {@link mxCell} for which the multiplicities should be checked.
|
||||
*/
|
||||
getCellValidationError(cell: Cell) {
|
||||
getCellValidationError(cell) {
|
||||
const outCount = cell.getDirectedEdgeCount(true);
|
||||
const inCount = cell.getDirectedEdgeCount(false);
|
||||
const value = cell.getValue();
|
||||
|
@ -295,7 +316,7 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
}
|
||||
|
||||
return error.length > 0 ? error : null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hook method for subclassers to return an error message for the given
|
||||
|
@ -305,9 +326,9 @@ class GraphValidation extends autoImplement<PartialClass>() {
|
|||
* @param cell {@link mxCell} that represents the cell to validate.
|
||||
* @param context Object that represents the global validation state.
|
||||
*/
|
||||
validateCell(cell: Cell, context: CellState): string | null {
|
||||
validateCell(cell, context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphValidation;
|
||||
mixInto(Graph)(GraphValidationMixin);
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import Resources from '../../util/Resources';
|
||||
import { isNode } from '../../util/DomUtils';
|
||||
import Cell from "../cell/datatypes/Cell";
|
||||
import graph from "../Graph";
|
||||
import Cell from '../cell/datatypes/Cell';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
/**
|
||||
* @class Multiplicity
|
||||
|
@ -131,13 +131,14 @@ class Multiplicity {
|
|||
* @param sourceOut Number of outgoing edges from the source terminal.
|
||||
* @param targetIn Number of incoming edges for the target terminal.
|
||||
*/
|
||||
check(graph: graph,
|
||||
check(
|
||||
graph: Graph,
|
||||
edge: Cell,
|
||||
source: Cell,
|
||||
target: Cell,
|
||||
sourceOut: number,
|
||||
targetIn: number): string | null {
|
||||
|
||||
targetIn: number
|
||||
): string | null {
|
||||
let error = '';
|
||||
|
||||
if (
|
||||
|
@ -172,11 +173,7 @@ class Multiplicity {
|
|||
* Checks if there are any valid neighbours in {@link validNeighbors}. This is only
|
||||
* called if {@link validNeighbors} is a non-empty array.
|
||||
*/
|
||||
checkNeighbors(graph: graph,
|
||||
edge: Cell,
|
||||
source: Cell,
|
||||
target: Cell): boolean {
|
||||
|
||||
checkNeighbors(graph: Graph, edge: Cell, source: Cell, target: Cell): boolean {
|
||||
const sourceValue = source.getValue();
|
||||
const targetValue = target.getValue();
|
||||
let isValid = !this.validNeighborsAllowed;
|
||||
|
@ -200,9 +197,7 @@ class Multiplicity {
|
|||
* given cell is the source or target of the given edge, depending on
|
||||
* {@link source}. This implementation uses {@link checkType} on the terminal's value.
|
||||
*/
|
||||
checkTerminal(graph: graph,
|
||||
edge: Cell,
|
||||
terminal: Cell): boolean {
|
||||
checkTerminal(graph: Graph, edge: Cell, terminal: Cell): boolean {
|
||||
const value = terminal.getValue();
|
||||
|
||||
return this.checkType(graph, value, this.type, this.attr, this.value);
|
||||
|
@ -211,14 +206,19 @@ class Multiplicity {
|
|||
/**
|
||||
* Checks the type of the given value.
|
||||
*/
|
||||
checkType(graph: graph,
|
||||
checkType(
|
||||
graph: Graph,
|
||||
value: string | Element | Cell,
|
||||
type: string,
|
||||
attr?: string,
|
||||
attrValue?: any): boolean {
|
||||
|
||||
attrValue?: any
|
||||
): boolean {
|
||||
if (value != null) {
|
||||
if (typeof value !== 'string' && 'nodeType' in value && !Number.isNaN(value.nodeType)) {
|
||||
if (
|
||||
typeof value !== 'string' &&
|
||||
'nodeType' in value &&
|
||||
!Number.isNaN(value.nodeType)
|
||||
) {
|
||||
// Checks if value is a DOM node
|
||||
return isNode(value, type, attr, attrValue);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ import { getClientX, getClientY, getSource, isConsumed } from '../../util/EventU
|
|||
import { clone } from '../../util/CloneUtils';
|
||||
import CellArray from '../cell/datatypes/CellArray';
|
||||
|
||||
import type { MaxGraph } from '../Graph';
|
||||
import type { Graph } from '../Graph';
|
||||
import StyleRegistry from '../style/StyleRegistry';
|
||||
import TooltipHandler from '../tooltip/TooltipHandler';
|
||||
import { MouseEventListener } from '../../types';
|
||||
|
@ -98,7 +98,7 @@ import { MouseEventListener } from '../../types';
|
|||
* respectively.
|
||||
*/
|
||||
class GraphView extends EventSource {
|
||||
constructor(graph: MaxGraph) {
|
||||
constructor(graph: Graph) {
|
||||
super();
|
||||
|
||||
this.graph = graph;
|
||||
|
@ -159,7 +159,7 @@ class GraphView extends EventSource {
|
|||
/**
|
||||
* Reference to the enclosing {@link graph}.
|
||||
*/
|
||||
graph: MaxGraph;
|
||||
graph: Graph;
|
||||
|
||||
/**
|
||||
* {@link Cell} that acts as the root of the displayed cell hierarchy.
|
||||
|
|
|
@ -1,25 +1,59 @@
|
|||
import Rectangle from "../geometry/Rectangle";
|
||||
import {hasScrollbars} from "../../util/Utils";
|
||||
import Rectangle from '../geometry/Rectangle';
|
||||
import { hasScrollbars, mixInto } from '../../util/Utils';
|
||||
import { Graph } from '../Graph';
|
||||
|
||||
class GraphZoom {
|
||||
declare module '../Graph' {
|
||||
interface Graph {
|
||||
zoomFactor: number;
|
||||
keepSelectionVisibleOnZoom: boolean;
|
||||
centerZoom: boolean;
|
||||
zoomIn: () => void;
|
||||
zoomOut: () => void;
|
||||
zoomActual: () => void;
|
||||
zoomTo: (scale: number, center: boolean) => void;
|
||||
zoom: (factor: number, center?: boolean) => void;
|
||||
zoomToRect: (rect: Rectangle) => void;
|
||||
}
|
||||
}
|
||||
|
||||
type PartialGraph = Pick<
|
||||
Graph,
|
||||
'getView' | 'getSelectionCell' | 'getContainer' | 'scrollRectToVisible'
|
||||
>;
|
||||
type PartialZoom = Pick<
|
||||
Graph,
|
||||
| 'zoomFactor'
|
||||
| 'keepSelectionVisibleOnZoom'
|
||||
| 'centerZoom'
|
||||
| 'zoomIn'
|
||||
| 'zoomOut'
|
||||
| 'zoomActual'
|
||||
| 'zoomTo'
|
||||
| 'zoom'
|
||||
| 'zoomToRect'
|
||||
>;
|
||||
type PartialType = PartialGraph & PartialZoom;
|
||||
|
||||
// @ts-expect-error The properties of PartialGraph are defined elsewhere.
|
||||
const GraphZoomMixin: PartialType = {
|
||||
/**
|
||||
* Specifies the factor used for {@link zoomIn} and {@link zoomOut}.
|
||||
* @default 1.2 (120%)
|
||||
*/
|
||||
zoomFactor: number = 1.2;
|
||||
zoomFactor: 1.2,
|
||||
|
||||
/**
|
||||
* Specifies if the viewport should automatically contain the selection cells after a zoom operation.
|
||||
* @default false
|
||||
*/
|
||||
keepSelectionVisibleOnZoom: boolean = false;
|
||||
keepSelectionVisibleOnZoom: false,
|
||||
|
||||
/**
|
||||
* Specifies if the zoom operations should go into the center of the actual
|
||||
* diagram rather than going from top, left.
|
||||
* @default true
|
||||
*/
|
||||
centerZoom: boolean = true;
|
||||
centerZoom: true,
|
||||
|
||||
/*****************************************************************************
|
||||
* Group: Graph display
|
||||
|
@ -28,49 +62,51 @@ class GraphZoom {
|
|||
/**
|
||||
* Zooms into the graph by {@link zoomFactor}.
|
||||
*/
|
||||
zoomIn(): void {
|
||||
zoomIn() {
|
||||
this.zoom(this.zoomFactor);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Zooms out of the graph by {@link zoomFactor}.
|
||||
*/
|
||||
zoomOut(): void {
|
||||
zoomOut() {
|
||||
this.zoom(1 / this.zoomFactor);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the zoom and panning in the view.
|
||||
*/
|
||||
zoomActual(): void {
|
||||
if (this.view.scale === 1) {
|
||||
this.view.setTranslate(0, 0);
|
||||
zoomActual() {
|
||||
if (this.getView().scale === 1) {
|
||||
this.getView().setTranslate(0, 0);
|
||||
} else {
|
||||
this.view.translate.x = 0;
|
||||
this.view.translate.y = 0;
|
||||
this.getView().translate.x = 0;
|
||||
this.getView().translate.y = 0;
|
||||
|
||||
this.view.setScale(1);
|
||||
}
|
||||
this.getView().setScale(1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Zooms the graph to the given scale with an optional boolean center
|
||||
* argument, which is passd to {@link zoom}.
|
||||
*/
|
||||
zoomTo(scale: number, center: boolean = false): void {
|
||||
this.zoom(scale / this.view.scale, center);
|
||||
}
|
||||
zoomTo(scale, center = false) {
|
||||
this.zoom(scale / this.getView().scale, center);
|
||||
},
|
||||
|
||||
/**
|
||||
* Zooms the graph using the given factor. Center is an optional boolean
|
||||
* argument that keeps the graph scrolled to the center. If the center argument
|
||||
* is omitted, then {@link centerZoom} will be used as its value.
|
||||
*/
|
||||
zoom(factor: number, center: boolean = this.centerZoom): void {
|
||||
const scale = Math.round(this.view.scale * factor * 100) / 100;
|
||||
const state = this.view.getState(this.getSelectionCell());
|
||||
const container = <HTMLElement>this.container;
|
||||
factor = scale / this.view.scale;
|
||||
zoom(factor, center) {
|
||||
center = center ?? this.centerZoom;
|
||||
|
||||
const scale = Math.round(this.getView().scale * factor * 100) / 100;
|
||||
const state = this.getView().getState(this.getSelectionCell());
|
||||
const container = this.getContainer();
|
||||
factor = scale / this.getView().scale;
|
||||
|
||||
if (this.keepSelectionVisibleOnZoom && state != null) {
|
||||
const rect = new Rectangle(
|
||||
|
@ -81,16 +117,16 @@ class GraphZoom {
|
|||
);
|
||||
|
||||
// Refreshes the display only once if a scroll is carried out
|
||||
this.view.scale = scale;
|
||||
this.getView().scale = scale;
|
||||
|
||||
if (!this.scrollRectToVisible(rect)) {
|
||||
this.view.revalidate();
|
||||
this.getView().revalidate();
|
||||
|
||||
// Forces an event to be fired but does not revalidate again
|
||||
this.view.setScale(scale);
|
||||
this.getView().setScale(scale);
|
||||
}
|
||||
} else {
|
||||
const _hasScrollbars = hasScrollbars(this.container);
|
||||
const _hasScrollbars = hasScrollbars(this.getContainer());
|
||||
|
||||
if (center && !_hasScrollbars) {
|
||||
let dx = container.offsetWidth;
|
||||
|
@ -101,24 +137,24 @@ class GraphZoom {
|
|||
dx *= -f;
|
||||
dy *= -f;
|
||||
} else {
|
||||
const f = (1 / factor - 1) / (this.view.scale * 2);
|
||||
const f = (1 / factor - 1) / (this.getView().scale * 2);
|
||||
dx *= f;
|
||||
dy *= f;
|
||||
}
|
||||
|
||||
this.view.scaleAndTranslate(
|
||||
this.getView().scaleAndTranslate(
|
||||
scale,
|
||||
this.view.translate.x + dx,
|
||||
this.view.translate.y + dy
|
||||
this.getView().translate.x + dx,
|
||||
this.getView().translate.y + dy
|
||||
);
|
||||
} else {
|
||||
// Allows for changes of translate and scrollbars during setscale
|
||||
const tx = this.view.translate.x;
|
||||
const ty = this.view.translate.y;
|
||||
const tx = this.getView().translate.x;
|
||||
const ty = this.getView().translate.y;
|
||||
const sl = container.scrollLeft;
|
||||
const st = container.scrollTop;
|
||||
|
||||
this.view.setScale(scale);
|
||||
this.getView().setScale(scale);
|
||||
|
||||
if (_hasScrollbars) {
|
||||
let dx = 0;
|
||||
|
@ -130,15 +166,15 @@ class GraphZoom {
|
|||
}
|
||||
|
||||
container.scrollLeft =
|
||||
(this.view.translate.x - tx) * this.view.scale +
|
||||
(this.getView().translate.x - tx) * this.getView().scale +
|
||||
Math.round(sl * factor + dx);
|
||||
container.scrollTop =
|
||||
(this.view.translate.y - ty) * this.view.scale +
|
||||
(this.getView().translate.y - ty) * this.getView().scale +
|
||||
Math.round(st * factor + dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Zooms the graph to the specified rectangle. If the rectangle does not have same aspect
|
||||
|
@ -150,8 +186,8 @@ class GraphZoom {
|
|||
* @param rect The un-scaled and un-translated rectangluar region that should be just visible
|
||||
* after the operation
|
||||
*/
|
||||
zoomToRect(rect: Rectangle): void {
|
||||
const container = <HTMLElement>this.container;
|
||||
zoomToRect(rect) {
|
||||
const container = this.getContainer();
|
||||
const scaleX = container.clientWidth / rect.width;
|
||||
const scaleY = container.clientHeight / rect.height;
|
||||
const aspectFactor = scaleX / scaleY;
|
||||
|
@ -198,20 +234,20 @@ class GraphZoom {
|
|||
}
|
||||
|
||||
const scale = container.clientWidth / rect.width;
|
||||
const newScale = this.view.scale * scale;
|
||||
const newScale = this.getView().scale * scale;
|
||||
|
||||
if (!hasScrollbars(this.container)) {
|
||||
this.view.scaleAndTranslate(
|
||||
if (!hasScrollbars(this.getContainer())) {
|
||||
this.getView().scaleAndTranslate(
|
||||
newScale,
|
||||
this.view.translate.x - rect.x / this.view.scale,
|
||||
this.view.translate.y - rect.y / this.view.scale
|
||||
this.getView().translate.x - rect.x / this.getView().scale,
|
||||
this.getView().translate.y - rect.y / this.getView().scale
|
||||
);
|
||||
} else {
|
||||
this.view.setScale(newScale);
|
||||
this.getView().setScale(newScale);
|
||||
container.scrollLeft = Math.round(rect.x * scale);
|
||||
container.scrollTop = Math.round(rect.y * scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default GraphZoom;
|
||||
mixInto(Graph)(GraphZoomMixin);
|
|
@ -3,24 +3,22 @@
|
|||
"baseUrl": ".",
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "./dist",
|
||||
"declarationMap": false,
|
||||
"emitDeclarationOnly": true,
|
||||
"esModuleInterop": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"module": "umd",
|
||||
"module": "ES2020",
|
||||
"lib": ["dom"],
|
||||
"moduleResolution": "node",
|
||||
"noEmit": true,
|
||||
"outDir": "./dist",
|
||||
"strict": true,
|
||||
"target": "es5",
|
||||
"resolveJsonModule": true, // Required for JSON files
|
||||
"target": "ES2020",
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"e2e",
|
||||
"**/*.json", // Don't try and check JSON files
|
||||
"**/*.spec.ts"
|
||||
],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
||||
"exclude": ["node_modules", "e2e", "**/*.json", "**/*.spec.ts"],
|
||||
"include": ["**/*.ts", "**/*.tsx"]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@mxgraph/html",
|
||||
"name": "@maxgraph/html",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
@ -9,7 +9,7 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@mxgraph/core": "*"
|
||||
"@maxgraph/core": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.15",
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
import mxgraph from '@mxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
ConnectionHandler,
|
||||
ConnectionConstraint,
|
||||
Geometry,
|
||||
Polyline,
|
||||
Point,
|
||||
CellState,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -14,18 +24,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
ConnectionHandler,
|
||||
ConnectionConstraint,
|
||||
Geometry,
|
||||
Polyline,
|
||||
Point,
|
||||
CellState,
|
||||
} = mxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import { Graph, Point } from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -12,8 +12,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, Point } = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
Rubberband,
|
||||
InternalEvent,
|
||||
CellRenderer,
|
||||
EdgeHandler,
|
||||
mxHierarchicalLayout,
|
||||
Constants,
|
||||
CellOverlay,
|
||||
ImageBox,
|
||||
mxClient,
|
||||
mxMorphing,
|
||||
EventObject,
|
||||
EventUtils,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -18,23 +32,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const {
|
||||
Graph,
|
||||
Rubberband,
|
||||
InternalEvent,
|
||||
utils,
|
||||
CellRenderer,
|
||||
EdgeHandler,
|
||||
mxHierarchicalLayout,
|
||||
Constants,
|
||||
CellOverlay,
|
||||
ImageBox,
|
||||
mxClient,
|
||||
mxMorphing,
|
||||
EventObject,
|
||||
EventUtils,
|
||||
} = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
Point,
|
||||
GraphHandler,
|
||||
utils,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -18,8 +25,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, InternalEvent, Rubberband, Point, GraphHandler, utils } = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
mxClipboard,
|
||||
utils,
|
||||
EventUtils,
|
||||
mxClient,
|
||||
mxCodec,
|
||||
Model,
|
||||
mxStringUtils,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -18,19 +29,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
mxClipboard,
|
||||
utils,
|
||||
EventUtils,
|
||||
mxClient,
|
||||
mxCodec,
|
||||
GraphModel,
|
||||
mxStringUtils,
|
||||
} = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
@ -48,7 +46,7 @@ const Template = ({ label, ...args }) => {
|
|||
// Public helper method for shared clipboard.
|
||||
mxClipboard.cellsToString = function (cells) {
|
||||
const codec = new mxCodec();
|
||||
const model = new GraphModel();
|
||||
const model = new Model();
|
||||
const parent = model.getRoot().getChildAt(0);
|
||||
|
||||
for (let i = 0; i < cells.length; i++) {
|
||||
|
@ -183,7 +181,7 @@ const Template = ({ label, ...args }) => {
|
|||
const node = doc.documentElement;
|
||||
|
||||
if (node != null) {
|
||||
const model = new GraphModel();
|
||||
const model = new Model();
|
||||
const codec = new mxCodec(node.ownerDocument);
|
||||
codec.decode(node, model);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import { Graph, Rectangle } from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -10,8 +10,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, Rectangle } = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import { Graph, InternalEvent, GraphHandler, Rubberband } from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -18,8 +18,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, InternalEvent, GraphHandler, Rubberband } = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
EventUtils,
|
||||
utils,
|
||||
VertexHandler,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -14,8 +21,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, InternalEvent, Rubberband, EventUtils, utils, VertexHandler } = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
mxDomHelpers,
|
||||
ImageShape,
|
||||
Rectangle,
|
||||
CellRenderer,
|
||||
ImageBox,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -14,17 +23,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const {
|
||||
Graph,
|
||||
InternalEvent,
|
||||
Rubberband,
|
||||
mxDomHelpers,
|
||||
ImageShape,
|
||||
Rectangle,
|
||||
CellRenderer,
|
||||
ImageBox,
|
||||
} = maxgraph;
|
||||
|
||||
const div = document.createElement('div');
|
||||
|
||||
const container = document.createElement('div');
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
mxDomUtils,
|
||||
Rubberband,
|
||||
DragSource,
|
||||
utils,
|
||||
GestureUtils,
|
||||
EdgeHandler,
|
||||
GraphHandler,
|
||||
Guide,
|
||||
EventUtils,
|
||||
Cell,
|
||||
Geometry,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
|
||||
|
@ -14,21 +27,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const {
|
||||
Graph,
|
||||
mxDomUtils,
|
||||
Rubberband,
|
||||
DragSource,
|
||||
utils,
|
||||
GestureUtils,
|
||||
EdgeHandler,
|
||||
GraphHandler,
|
||||
Guide,
|
||||
EventUtils,
|
||||
Cell,
|
||||
Geometry,
|
||||
} = maxgraph;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'relative';
|
||||
container.style.overflow = 'hidden';
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import maxgraph from '@maxgraph/core';
|
||||
import {
|
||||
Graph,
|
||||
Rubberband,
|
||||
utils,
|
||||
EventUtils,
|
||||
InternalEvent,
|
||||
mxClient,
|
||||
} from '@maxgraph/core';
|
||||
|
||||
import { globalTypes } from '../.storybook/preview';
|
||||
import { getXml, parseXml } from '@maxgraph/core/util/XmlUtils';
|
||||
|
@ -19,8 +26,6 @@ export default {
|
|||
};
|
||||
|
||||
const Template = ({ label, ...args }) => {
|
||||
const { Graph, Rubberband, utils, EventUtils, InternalEvent, mxClient } = maxgraph;
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = 'Drag & drop your images below:<br>';
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue