cleanups and bugfixes
parent
0b51e1da2a
commit
8fe52f4106
|
@ -789,6 +789,10 @@ class mxGraphHandler {
|
|||
return shape;
|
||||
}
|
||||
|
||||
createGuide() {
|
||||
return new mxGuide(this.graph, this.getGuideStates());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: start
|
||||
*
|
||||
|
@ -809,7 +813,7 @@ class mxGraphHandler {
|
|||
}
|
||||
|
||||
if (this.guidesEnabled) {
|
||||
this.guide = new mxGuide(this.graph, this.getGuideStates());
|
||||
this.guide = this.createGuide();
|
||||
const parent = this.graph.model.getParent(cell);
|
||||
const ignore = this.graph.model.getChildCount(parent) < 2;
|
||||
|
||||
|
|
|
@ -63,20 +63,6 @@ class mxMedianHybridCrossingReduction extends mxHierarchicalLayoutStage {
|
|||
*/
|
||||
function;
|
||||
|
||||
/**
|
||||
* Variable: medianValue
|
||||
*
|
||||
* The weighted value of the cell stored.
|
||||
*/
|
||||
medianValue = 0;
|
||||
|
||||
/**
|
||||
* Variable: cell
|
||||
*
|
||||
* The cell whose median value is being calculated
|
||||
*/
|
||||
cell = false;
|
||||
|
||||
/**
|
||||
* Class: mxMedianHybridCrossingReduction
|
||||
*
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* Updated to ES9 syntax by David Morrissey 2021
|
||||
*/
|
||||
import mxConstants from './mxConstants';
|
||||
import mxPoint from "./mxPoint";
|
||||
import mxPolyline from "../shape/mxPolyline";
|
||||
|
||||
/**
|
||||
* Class: mxGuide
|
||||
|
|
|
@ -39,82 +39,67 @@ class ContextIcons extends React.Component {
|
|||
};
|
||||
|
||||
componentDidMount = () => {
|
||||
// Defines a subclass for mxVertexHandler that adds a set of clickable
|
||||
// icons to every selected vertex.
|
||||
function mxVertexToolHandler(state) {
|
||||
mxVertexHandler.apply(this, arguments);
|
||||
}
|
||||
class mxVertexToolHandler extends mxVertexHandler {
|
||||
// Defines a subclass for mxVertexHandler that adds a set of clickable
|
||||
// icons to every selected vertex.
|
||||
|
||||
mxVertexToolHandler.prototype = new mxVertexHandler();
|
||||
mxVertexToolHandler.prototype.constructor = mxVertexToolHandler;
|
||||
domNode = null;
|
||||
|
||||
mxVertexToolHandler.prototype.domNode = null;
|
||||
init() {
|
||||
super.init();
|
||||
|
||||
mxVertexToolHandler.prototype.init = function() {
|
||||
mxVertexHandler.prototype.init.apply(this, arguments);
|
||||
// In this example we force the use of DIVs for images in IE. This
|
||||
// handles transparency in PNG images properly in IE and fixes the
|
||||
// problem that IE routes all mouse events for a gesture via the
|
||||
// initial IMG node, which means the target vertices
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.style.position = 'absolute';
|
||||
this.domNode.style.whiteSpace = 'nowrap';
|
||||
|
||||
// In this example we force the use of DIVs for images in IE. This
|
||||
// handles transparency in PNG images properly in IE and fixes the
|
||||
// problem that IE routes all mouse events for a gesture via the
|
||||
// initial IMG node, which means the target vertices
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.style.position = 'absolute';
|
||||
this.domNode.style.whiteSpace = 'nowrap';
|
||||
// Workaround for event redirection via image tag in quirks and IE8
|
||||
const createImage = src => {
|
||||
return mxUtils.createImage(src);
|
||||
};
|
||||
|
||||
// Workaround for event redirection via image tag in quirks and IE8
|
||||
function createImage(src) {
|
||||
return mxUtils.createImage(src);
|
||||
}
|
||||
|
||||
// Delete
|
||||
let img = createImage('images/delete2.png');
|
||||
img.setAttribute('title', 'Delete');
|
||||
img.style.cursor = 'pointer';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
mxEvent.addGestureListeners(
|
||||
img,
|
||||
mxUtils.bind(this, function(evt) {
|
||||
// Delete
|
||||
let img = createImage('images/delete2.png');
|
||||
img.setAttribute('title', 'Delete');
|
||||
img.style.cursor = 'pointer';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
mxEvent.addGestureListeners(img, evt => {
|
||||
// Disables dragging the image
|
||||
mxEvent.consume(evt);
|
||||
})
|
||||
);
|
||||
mxEvent.addListener(
|
||||
img,
|
||||
'click',
|
||||
mxUtils.bind(this, function(evt) {
|
||||
});
|
||||
mxEvent.addListener(img, 'click', evt => {
|
||||
this.graph.removeCells([this.state.cell]);
|
||||
mxEvent.consume(evt);
|
||||
})
|
||||
);
|
||||
this.domNode.appendChild(img);
|
||||
});
|
||||
this.domNode.appendChild(img);
|
||||
|
||||
// Size
|
||||
img = createImage('images/fit_to_size.png');
|
||||
img.setAttribute('title', 'Resize');
|
||||
img.style.cursor = 'se-resize';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
mxEvent.addGestureListeners(
|
||||
img,
|
||||
mxUtils.bind(this, function(evt) {
|
||||
// Size
|
||||
img = createImage('images/fit_to_size.png');
|
||||
img.setAttribute('title', 'Resize');
|
||||
img.style.cursor = 'se-resize';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
|
||||
mxEvent.addGestureListeners(img, evt => {
|
||||
this.start(mxEvent.getClientX(evt), mxEvent.getClientY(evt), 7);
|
||||
this.graph.isMouseDown = true;
|
||||
this.graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
|
||||
mxEvent.consume(evt);
|
||||
})
|
||||
);
|
||||
this.domNode.appendChild(img);
|
||||
});
|
||||
this.domNode.appendChild(img);
|
||||
|
||||
// Move
|
||||
img = createImage('images/plus.png');
|
||||
img.setAttribute('title', 'Move');
|
||||
img.style.cursor = 'move';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
mxEvent.addGestureListeners(
|
||||
img,
|
||||
mxUtils.bind(this, function(evt) {
|
||||
// Move
|
||||
img = createImage('images/plus.png');
|
||||
img.setAttribute('title', 'Move');
|
||||
img.style.cursor = 'move';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
|
||||
mxEvent.addGestureListeners(img, evt => {
|
||||
this.graph.graphHandler.start(
|
||||
this.state.cell,
|
||||
mxEvent.getClientX(evt),
|
||||
|
@ -124,19 +109,17 @@ class ContextIcons extends React.Component {
|
|||
this.graph.isMouseDown = true;
|
||||
this.graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
|
||||
mxEvent.consume(evt);
|
||||
})
|
||||
);
|
||||
this.domNode.appendChild(img);
|
||||
});
|
||||
this.domNode.appendChild(img);
|
||||
|
||||
// Connect
|
||||
img = createImage('images/check.png');
|
||||
img.setAttribute('title', 'Connect');
|
||||
img.style.cursor = 'pointer';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
mxEvent.addGestureListeners(
|
||||
img,
|
||||
mxUtils.bind(this, function(evt) {
|
||||
// Connect
|
||||
img = createImage('images/check.png');
|
||||
img.setAttribute('title', 'Connect');
|
||||
img.style.cursor = 'pointer';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
|
||||
mxEvent.addGestureListeners(img, evt => {
|
||||
const pt = mxUtils.convertPoint(
|
||||
this.graph.container,
|
||||
mxEvent.getClientX(evt),
|
||||
|
@ -146,89 +129,81 @@ class ContextIcons extends React.Component {
|
|||
this.graph.isMouseDown = true;
|
||||
this.graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
|
||||
mxEvent.consume(evt);
|
||||
})
|
||||
);
|
||||
this.domNode.appendChild(img);
|
||||
});
|
||||
this.domNode.appendChild(img);
|
||||
|
||||
this.graph.container.appendChild(this.domNode);
|
||||
this.redrawTools();
|
||||
};
|
||||
|
||||
mxVertexToolHandler.prototype.redraw = function() {
|
||||
mxVertexHandler.prototype.redraw.apply(this);
|
||||
this.redrawTools();
|
||||
};
|
||||
|
||||
mxVertexToolHandler.prototype.redrawTools = function() {
|
||||
if (this.state != null && this.domNode != null) {
|
||||
const dy = 4;
|
||||
this.domNode.style.left = `${this.state.x + this.state.width - 56}px`;
|
||||
this.domNode.style.top = `${this.state.y + this.state.height + dy}px`;
|
||||
this.graph.container.appendChild(this.domNode);
|
||||
this.redrawTools();
|
||||
}
|
||||
};
|
||||
|
||||
mxVertexToolHandler.prototype.destroy = function(sender, me) {
|
||||
mxVertexHandler.prototype.destroy.apply(this, arguments);
|
||||
|
||||
if (this.domNode != null) {
|
||||
this.domNode.parentNode.removeChild(this.domNode);
|
||||
this.domNode = null;
|
||||
redraw() {
|
||||
super.redraw();
|
||||
this.redrawTools();
|
||||
}
|
||||
};
|
||||
|
||||
// Program starts here. Creates a sample graph in the
|
||||
// DOM node with the specified ID. This function is invoked
|
||||
// from the onLoad event handler of the document (see below).
|
||||
function main(container) {
|
||||
// Checks if the browser is supported
|
||||
if (!mxClient.isBrowserSupported()) {
|
||||
// Displays an error message if the browser is not supported.
|
||||
mxUtils.error('Browser is not supported!', 200, false);
|
||||
} else {
|
||||
// Creates the graph inside the given container
|
||||
const graph = new mxGraph(container);
|
||||
graph.setConnectable(true);
|
||||
graph.connectionHandler.createTarget = true;
|
||||
redrawTools() {
|
||||
if (this.state != null && this.domNode != null) {
|
||||
const dy = 4;
|
||||
this.domNode.style.left = `${this.state.x + this.state.width - 56}px`;
|
||||
this.domNode.style.top = `${this.state.y + this.state.height + dy}px`;
|
||||
}
|
||||
}
|
||||
|
||||
graph.createHandler = function(state) {
|
||||
if (state != null && this.model.isVertex(state.cell)) {
|
||||
return new mxVertexToolHandler(state);
|
||||
}
|
||||
destroy(sender, me) {
|
||||
super.destroy(sender, me);
|
||||
|
||||
return mxGraph.prototype.createHandler.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Uncomment the following if you want the container
|
||||
// to fit the size of the graph
|
||||
// graph.setResizeContainer(true);
|
||||
|
||||
// Enables rubberband selection
|
||||
new mxRubberband(graph);
|
||||
|
||||
// Gets the default parent for inserting new cells. This
|
||||
// is normally the first child of the root (ie. layer 0).
|
||||
const parent = graph.getDefaultParent();
|
||||
|
||||
// Adds cells to the model in a single step
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
||||
const v2 = graph.insertVertex(
|
||||
parent,
|
||||
null,
|
||||
'World!',
|
||||
200,
|
||||
150,
|
||||
80,
|
||||
30
|
||||
);
|
||||
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||
} finally {
|
||||
// Updates the display
|
||||
graph.getModel().endUpdate();
|
||||
if (this.domNode != null) {
|
||||
this.domNode.parentNode.removeChild(this.domNode);
|
||||
this.domNode = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyCustomGraph extends mxGraph {
|
||||
createHandler(state) {
|
||||
if (state != null && this.model.isVertex(state.cell)) {
|
||||
return new mxVertexToolHandler(state);
|
||||
}
|
||||
return super.createHandler(state);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the graph inside the given container
|
||||
const graph = new MyCustomGraph(this.el);
|
||||
graph.setConnectable(true);
|
||||
graph.connectionHandler.createTarget = true;
|
||||
|
||||
// Uncomment the following if you want the container
|
||||
// to fit the size of the graph
|
||||
// graph.setResizeContainer(true);
|
||||
|
||||
// Enables rubberband selection
|
||||
new mxRubberband(graph);
|
||||
|
||||
// Gets the default parent for inserting new cells. This
|
||||
// is normally the first child of the root (ie. layer 0).
|
||||
const parent = graph.getDefaultParent();
|
||||
|
||||
// Adds cells to the model in a single step
|
||||
graph.batchUpdate(() => {
|
||||
const v1 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'Hello,',
|
||||
position: [20, 20],
|
||||
size: [80, 30],
|
||||
});
|
||||
const v2 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'World!',
|
||||
position: [200, 150],
|
||||
size: [80, 30],
|
||||
});
|
||||
const e1 = graph.insertEdge({
|
||||
parent,
|
||||
source: v1,
|
||||
target: v2,
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -162,9 +162,23 @@ class Control extends React.Component {
|
|||
// Adds cells to the model in a single step
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
||||
const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
||||
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||
const v1 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'Hello,',
|
||||
position: [20, 20],
|
||||
size: [80, 30],
|
||||
});
|
||||
const v2 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'World!',
|
||||
position: [200, 150],
|
||||
size: [80, 30],
|
||||
});
|
||||
const e1 = graph.insertEdge({
|
||||
parent,
|
||||
source: v1,
|
||||
target: v2,
|
||||
});
|
||||
} finally {
|
||||
// Updates the display
|
||||
graph.getModel().endUpdate();
|
||||
|
@ -173,13 +187,13 @@ class Control extends React.Component {
|
|||
graph.centerZoom = false;
|
||||
|
||||
this.el2.appendChild(
|
||||
mxUtils.button('Zoom In', function() {
|
||||
mxUtils.button('Zoom In', () => {
|
||||
graph.zoomIn();
|
||||
})
|
||||
);
|
||||
|
||||
this.el2.appendChild(
|
||||
mxUtils.button('Zoom Out', function() {
|
||||
mxUtils.button('Zoom Out', () => {
|
||||
graph.zoomOut();
|
||||
})
|
||||
);
|
||||
|
|
|
@ -38,16 +38,36 @@ class DragSource extends React.Component {
|
|||
};
|
||||
|
||||
componentDidMount = () => {
|
||||
// Enables guides
|
||||
mxGraphHandler.prototype.guidesEnabled = true;
|
||||
class MyCustomGuide extends mxGuide {
|
||||
isEnabledForEvent(evt) {
|
||||
// Alt disables guides
|
||||
return !mxEvent.isAltDown(evt);
|
||||
}
|
||||
}
|
||||
|
||||
// Alt disables guides
|
||||
mxGuide.prototype.isEnabledForEvent = function(evt) {
|
||||
return !mxEvent.isAltDown(evt);
|
||||
};
|
||||
class MyCustomGraphHandler extends mxGraphHandler {
|
||||
// Enables guides
|
||||
guidesEnabled = true;
|
||||
|
||||
// Enables snapping waypoints to terminals
|
||||
mxEdgeHandler.prototype.snapToTerminals = true;
|
||||
createGuide() {
|
||||
return new MyCustomGuide(this.graph, this.getGuideStates());
|
||||
}
|
||||
}
|
||||
|
||||
class MyCustomEdgeHandler extends mxEdgeHandler {
|
||||
// Enables snapping waypoints to terminals
|
||||
snapToTerminals = true;
|
||||
}
|
||||
|
||||
class MyCustomGraph extends mxGraph {
|
||||
createGraphHandler() {
|
||||
return new MyCustomGraphHandler(this);
|
||||
}
|
||||
|
||||
createEdgeHandler(state, edgeStyle) {
|
||||
return new MyCustomEdgeHandler(state, edgeStyle);
|
||||
}
|
||||
}
|
||||
|
||||
const graphs = [];
|
||||
|
||||
|
@ -63,7 +83,7 @@ class DragSource extends React.Component {
|
|||
|
||||
this.el.appendChild(container);
|
||||
|
||||
var graph = new mxGraph(container);
|
||||
const graph = new MyCustomGraph(container);
|
||||
graph.gridSize = 30;
|
||||
|
||||
// Uncomment the following if you want the container
|
||||
|
@ -78,28 +98,38 @@ class DragSource extends React.Component {
|
|||
const parent = graph.getDefaultParent();
|
||||
|
||||
// Adds cells to the model in a single step
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
||||
const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
||||
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||
} finally {
|
||||
// Updates the display
|
||||
graph.getModel().endUpdate();
|
||||
}
|
||||
graph.batchUpdate(() => {
|
||||
const v1 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'Hello,',
|
||||
position: [20, 20],
|
||||
size: [80, 30],
|
||||
});
|
||||
const v2 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'World!',
|
||||
position: [200, 150],
|
||||
size: [80, 30],
|
||||
});
|
||||
const e1 = graph.insertEdge({
|
||||
parent,
|
||||
source: v1,
|
||||
target: v2,
|
||||
});
|
||||
});
|
||||
|
||||
graphs.push(graph);
|
||||
}
|
||||
|
||||
// Returns the graph under the mouse
|
||||
const graphF = function(evt) {
|
||||
const graphF = evt => {
|
||||
const x = mxEvent.getClientX(evt);
|
||||
const y = mxEvent.getClientY(evt);
|
||||
const elt = document.elementFromPoint(x, y);
|
||||
|
||||
for (let i = 0; i < graphs.length; i++) {
|
||||
if (mxUtils.isAncestorNode(graphs[i].container, elt)) {
|
||||
return graphs[i];
|
||||
for (const graph of graphs) {
|
||||
if (mxUtils.isAncestorNode(graph.container, elt)) {
|
||||
return graph;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +137,7 @@ class DragSource extends React.Component {
|
|||
};
|
||||
|
||||
// Inserts a cell at the given location
|
||||
const funct = function(graph, evt, target, x, y) {
|
||||
const funct = (graph, evt, target, x, y) => {
|
||||
const cell = new mxCell('Test', new mxGeometry(0, 0, 120, 40));
|
||||
cell.vertex = true;
|
||||
const cells = graph.importCells([cell], x, y, target);
|
||||
|
@ -141,14 +171,14 @@ class DragSource extends React.Component {
|
|||
dragElt,
|
||||
null,
|
||||
null,
|
||||
graph.autoscroll,
|
||||
graphs[0].autoscroll,
|
||||
true
|
||||
);
|
||||
|
||||
// Redirects feature to global switch. Note that this feature should only be used
|
||||
// if the the x and y arguments are used in funct to insert the cell.
|
||||
ds.isGuidesEnabled = function() {
|
||||
return graph.graphHandler.guidesEnabled;
|
||||
ds.isGuidesEnabled = () => {
|
||||
return graphs[0].graphHandler.guidesEnabled;
|
||||
};
|
||||
|
||||
// Restores original drag icon while outside of graph
|
||||
|
|
|
@ -53,7 +53,7 @@ class Overlays extends React.Component {
|
|||
|
||||
// Installs a handler for click events in the graph
|
||||
// that toggles the overlay for the respective cell
|
||||
graph.addListener(mxEvent.CLICK, function(sender, evt) {
|
||||
graph.addListener(mxEvent.CLICK, (sender, evt) => {
|
||||
const cell = evt.getProperty('cell');
|
||||
|
||||
if (cell != null) {
|
||||
|
@ -67,7 +67,7 @@ class Overlays extends React.Component {
|
|||
);
|
||||
|
||||
// Installs a handler for clicks on the overlay
|
||||
overlay.addListener(mxEvent.CLICK, function(sender, evt2) {
|
||||
overlay.addListener(mxEvent.CLICK, (sender, evt2) => {
|
||||
mxUtils.alert('Overlay clicked');
|
||||
});
|
||||
|
||||
|
@ -81,7 +81,7 @@ class Overlays extends React.Component {
|
|||
|
||||
// Installs a handler for double click events in the graph
|
||||
// that shows an alert box
|
||||
graph.addListener(mxEvent.DOUBLE_CLICK, function(sender, evt) {
|
||||
graph.addListener(mxEvent.DOUBLE_CLICK, (sender, evt) => {
|
||||
const cell = evt.getProperty('cell');
|
||||
mxUtils.alert(`Doubleclick: ${cell != null ? 'Cell' : 'Graph'}`);
|
||||
evt.consume();
|
||||
|
@ -92,23 +92,25 @@ class Overlays extends React.Component {
|
|||
const parent = graph.getDefaultParent();
|
||||
|
||||
// Adds cells to the model in a single step
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
const v1 = graph.insertVertex(parent, null, 'Click,', 20, 20, 60, 40);
|
||||
const v2 = graph.insertVertex(
|
||||
graph.batchUpdate(() => {
|
||||
const v1 = graph.insertVertex({
|
||||
parent,
|
||||
null,
|
||||
'Doubleclick',
|
||||
200,
|
||||
150,
|
||||
100,
|
||||
40
|
||||
);
|
||||
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||
} finally {
|
||||
// Updates the display
|
||||
graph.getModel().endUpdate();
|
||||
}
|
||||
value: 'Click,',
|
||||
position: [20, 20],
|
||||
size: [60, 40],
|
||||
});
|
||||
const v2 = graph.insertVertex({
|
||||
parent,
|
||||
value: 'Doubleclick',
|
||||
position: [200, 150],
|
||||
size: [100, 40],
|
||||
});
|
||||
const e1 = graph.insertEdge({
|
||||
parent,
|
||||
source: v1,
|
||||
target: v2,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue