started integrating more examples into the next.js app
parent
8afd272fbd
commit
dad45f61dd
|
@ -7,6 +7,10 @@
|
||||||
import mxDictionary from '../util/mxDictionary';
|
import mxDictionary from '../util/mxDictionary';
|
||||||
import mxPoint from '../util/mxPoint';
|
import mxPoint from '../util/mxPoint';
|
||||||
import mxGraphLayout from './mxGraphLayout';
|
import mxGraphLayout from './mxGraphLayout';
|
||||||
|
import mxCellPath from "../model/mxCellPath";
|
||||||
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
import mxUtils from "../util/mxUtils";
|
||||||
|
import WeightedCellSorter from "./WeightedCellSorter";
|
||||||
|
|
||||||
class mxCompactTreeLayout extends mxGraphLayout {
|
class mxCompactTreeLayout extends mxGraphLayout {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import mxShape from './mxShape';
|
import mxShape from './mxShape';
|
||||||
import mxPoint from '../util/mxPoint';
|
import mxPoint from '../util/mxPoint';
|
||||||
|
import mxUtils from "../util/mxUtils";
|
||||||
|
import mxConstants from "../util/mxConstants";
|
||||||
|
|
||||||
class mxRhombus extends mxShape {
|
class mxRhombus extends mxShape {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,9 @@ import mxEventObject from './mxEventObject';
|
||||||
import mxEventSource from './mxEventSource';
|
import mxEventSource from './mxEventSource';
|
||||||
import mxUtils from './mxUtils';
|
import mxUtils from './mxUtils';
|
||||||
import mxEvent from './mxEvent';
|
import mxEvent from './mxEvent';
|
||||||
|
import mxClient from "../mxClient";
|
||||||
|
import mxConstants from "./mxConstants";
|
||||||
|
|
||||||
|
|
||||||
class mxWindow extends mxEventSource {
|
class mxWindow extends mxEventSource {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import mxUtils from '../util/mxUtils';
|
import mxUtils from '../util/mxUtils';
|
||||||
import mxPoint from '../util/mxPoint';
|
import mxPoint from '../util/mxPoint';
|
||||||
|
import mxConstants from "../util/mxConstants";
|
||||||
|
|
||||||
const mxPerimeter = {
|
const mxPerimeter = {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
* Updated to ES9 syntax by David Morrissey 2021
|
* Updated to ES9 syntax by David Morrissey 2021
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import mxEventSource from "../util/mxEventSource";
|
||||||
|
import mxUtils from "../util/mxUtils";
|
||||||
|
import mxEvent from "../util/mxEvent";
|
||||||
|
import mxConstants from "../util/mxConstants";
|
||||||
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
|
||||||
class mxSwimlaneManager extends mxEventSource {
|
class mxSwimlaneManager extends mxEventSource {
|
||||||
/**
|
/**
|
||||||
* Variable: graph
|
* Variable: graph
|
||||||
|
|
|
@ -123,7 +123,7 @@ class DragSource extends React.Component {
|
||||||
const img = mxUtils.createImage('images/icons48/gear.png');
|
const img = mxUtils.createImage('images/icons48/gear.png');
|
||||||
img.style.width = '48px';
|
img.style.width = '48px';
|
||||||
img.style.height = '48px';
|
img.style.height = '48px';
|
||||||
document.body.appendChild(img);
|
this.el.appendChild(img);
|
||||||
|
|
||||||
// Creates the element that is being for the actual preview.
|
// Creates the element that is being for the actual preview.
|
||||||
const dragElt = document.createElement('div');
|
const dragElt = document.createElement('div');
|
||||||
|
|
|
@ -9,8 +9,10 @@ import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
import mxEvent from '../mxgraph/util/mxEvent';
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxUtils from "../mxgraph/util/mxUtils";
|
||||||
|
import mxGraphView from "../mxgraph/view/mxGraphView";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Perimeter extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -20,106 +22,109 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Perimeter example for mxGraph</h1>
|
<h1>Perimeter example for mxGraph</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
position: 'relative',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Redirects the perimeter to the label bounds if intersection
|
||||||
|
// between edge and label is found
|
||||||
|
const mxGraphViewGetPerimeterPoint =
|
||||||
|
mxGraphView.prototype.getPerimeterPoint;
|
||||||
|
mxGraphView.prototype.getPerimeterPoint = function(
|
||||||
|
terminal,
|
||||||
|
next,
|
||||||
|
orthogonal,
|
||||||
|
border
|
||||||
|
) {
|
||||||
|
let point = mxGraphViewGetPerimeterPoint.apply(this, arguments);
|
||||||
|
|
||||||
};
|
if (point != null) {
|
||||||
|
const perimeter = this.getPerimeterFunction(terminal);
|
||||||
|
|
||||||
|
if (terminal.text != null && terminal.text.boundingBox != null) {
|
||||||
|
// Adds a small border to the label bounds
|
||||||
|
const b = terminal.text.boundingBox.clone();
|
||||||
|
b.grow(3);
|
||||||
|
|
||||||
|
if (mxUtils.rectangleIntersectsSegment(b, point, next)) {
|
||||||
|
point = perimeter(b, terminal, next, orthogonal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return point;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
graph.setVertexLabelsMovable(true);
|
||||||
|
graph.setConnectable(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.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
const v1 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Label',
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
80,
|
||||||
|
30,
|
||||||
|
'verticalLabelPosition=bottom'
|
||||||
|
);
|
||||||
|
const v2 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Label',
|
||||||
|
200,
|
||||||
|
20,
|
||||||
|
80,
|
||||||
|
30,
|
||||||
|
'verticalLabelPosition=bottom'
|
||||||
|
);
|
||||||
|
const v3 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Label',
|
||||||
|
20,
|
||||||
|
150,
|
||||||
|
80,
|
||||||
|
30,
|
||||||
|
'verticalLabelPosition=bottom'
|
||||||
|
);
|
||||||
|
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||||
|
var e1 = graph.insertEdge(parent, null, '', v1, v3);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Perimeter;
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// Redirects the perimeter to the label bounds if intersection
|
|
||||||
// between edge and label is found
|
|
||||||
mxGraphViewGetPerimeterPoint = mxGraphView.prototype.getPerimeterPoint;
|
|
||||||
mxGraphView.prototype.getPerimeterPoint = function(terminal, next, orthogonal, border)
|
|
||||||
{
|
|
||||||
let point = mxGraphViewGetPerimeterPoint.apply(this, arguments);
|
|
||||||
|
|
||||||
if (point != null)
|
|
||||||
{
|
|
||||||
let perimeter = this.getPerimeterFunction(terminal);
|
|
||||||
|
|
||||||
if (terminal.text != null && terminal.text.boundingBox != null)
|
|
||||||
{
|
|
||||||
// Adds a small border to the label bounds
|
|
||||||
let b = terminal.text.boundingBox.clone();
|
|
||||||
b.grow(3)
|
|
||||||
|
|
||||||
if (mxUtils.rectangleIntersectsSegment(b, point, next))
|
|
||||||
{
|
|
||||||
point = perimeter(b, terminal, next, orthogonal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return point;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Creates the graph inside the given container
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
graph.setVertexLabelsMovable(true);
|
|
||||||
graph.setConnectable(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).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Label', 20, 20, 80, 30, 'verticalLabelPosition=bottom');
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'Label', 200, 20, 80, 30, 'verticalLabelPosition=bottom');
|
|
||||||
var v3 = graph.insertVertex(parent, null, 'Label', 20, 150, 80, 30, 'verticalLabelPosition=bottom');
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v3);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;position:relative;width:321px;height:241px;background:url('editors/images/grid.gif');cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,16 +1,32 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2006-2013, JGraph Ltd
|
* Copyright (c) 2006-2013, JGraph Ltd
|
||||||
|
|
||||||
Hello, World! example for mxGraph. This example demonstrates creating
|
Hello, World! example for mxGraph. This example demonstrates creating
|
||||||
permissions to define the available operations a the graph.
|
permissions to define the available operations a the graph.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxConnectionHandler from '../mxgraph/handler/mxConnectionHandler';
|
||||||
|
import mxKeyHandler from '../mxgraph/handler/mxKeyHandler';
|
||||||
|
import mxImage from '../mxgraph/util/mxImage';
|
||||||
|
import mxUtils from '../mxgraph/util/mxUtils';
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
function Permission(locked, createEdges, editEdges, editVertices, cloneCells) {
|
||||||
|
this.locked = locked != null ? locked : false;
|
||||||
|
this.createEdges = createEdges != null ? createEdges : true;
|
||||||
|
this.editEdges = editEdges != null ? editEdges : true;
|
||||||
|
this.editVertices = editVertices != null ? editVertices : true;
|
||||||
|
this.cloneCells = cloneCells != null ? cloneCells : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Permission.prototype.apply = function(graph) {
|
||||||
|
graph.setConnectable(this.createEdges);
|
||||||
|
graph.setCellsLocked(this.locked);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Permissions extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -25,246 +41,197 @@ class MYNAMEHERE extends React.Component {
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{}}
|
||||||
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Defines an icon for creating new connections in the connection handler.
|
||||||
|
// This will automatically disable the highlighting of the source vertex.
|
||||||
|
mxConnectionHandler.prototype.connectImage = new mxImage(
|
||||||
|
'images/connector.gif',
|
||||||
|
16,
|
||||||
|
16
|
||||||
|
);
|
||||||
|
|
||||||
};
|
// Creates the div for the graph
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.style.position = 'absolute';
|
||||||
|
container.style.overflow = 'hidden';
|
||||||
|
container.style.left = '00px';
|
||||||
|
container.style.top = '40px';
|
||||||
|
container.style.right = '0px';
|
||||||
|
container.style.bottom = '0px';
|
||||||
|
container.style.background = 'url("editors/images/grid.gif")';
|
||||||
|
|
||||||
|
this.el.appendChild(container);
|
||||||
|
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(container);
|
||||||
|
|
||||||
|
// Enable tooltips, disables mutligraphs, enable loops
|
||||||
|
graph.setMultigraph(false);
|
||||||
|
graph.setAllowLoops(true);
|
||||||
|
|
||||||
|
// Enables rubberband selection and key handling
|
||||||
|
const rubberband = new mxRubberband(graph);
|
||||||
|
const keyHandler = new mxKeyHandler(graph);
|
||||||
|
|
||||||
|
// Assigns the delete key
|
||||||
|
keyHandler.bindKey(46, function(evt) {
|
||||||
|
if (graph.isEnabled()) {
|
||||||
|
graph.removeCells();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shared variable between child function scopes
|
||||||
|
// aka "private" variable
|
||||||
|
let currentPermission = null;
|
||||||
|
|
||||||
|
const apply = function(permission) {
|
||||||
|
graph.clearSelection();
|
||||||
|
permission.apply(graph);
|
||||||
|
graph.setEnabled(true);
|
||||||
|
graph.setTooltips(true);
|
||||||
|
|
||||||
|
// Updates the icons on the shapes - rarely
|
||||||
|
// needed and very slow for large graphs
|
||||||
|
graph.refresh();
|
||||||
|
currentPermission = permission;
|
||||||
|
};
|
||||||
|
|
||||||
|
apply(new Permission());
|
||||||
|
|
||||||
|
let button = mxUtils.button('Allow All', function(evt) {
|
||||||
|
apply(new Permission());
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Connect Only', function(evt) {
|
||||||
|
apply(new Permission(false, true, false, false, true));
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Edges Only', function(evt) {
|
||||||
|
apply(new Permission(false, false, true, false, false));
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Vertices Only', function(evt) {
|
||||||
|
apply(new Permission(false, false, false, true, false));
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Select Only', function(evt) {
|
||||||
|
apply(new Permission(false, false, false, false, false));
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Locked', function(evt) {
|
||||||
|
apply(new Permission(true, false));
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
button = mxUtils.button('Disabled', function(evt) {
|
||||||
|
graph.clearSelection();
|
||||||
|
graph.setEnabled(false);
|
||||||
|
graph.setTooltips(false);
|
||||||
|
});
|
||||||
|
this.el.appendChild(button);
|
||||||
|
|
||||||
|
// Extends hook functions to use permission object. This could
|
||||||
|
// be done by assigning the respective switches (eg.
|
||||||
|
// setMovable), but this approach is more flexible, doesn't
|
||||||
|
// override any existing behaviour or settings, and allows for
|
||||||
|
// dynamic conditions to be used in the functions. See the
|
||||||
|
// specification for more functions to extend (eg.
|
||||||
|
// isSelectable).
|
||||||
|
const oldDisconnectable = graph.isCellDisconnectable;
|
||||||
|
graph.isCellDisconnectable = function(cell, terminal, source) {
|
||||||
|
return (
|
||||||
|
oldDisconnectable.apply(this, arguments) && currentPermission.editEdges
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldTerminalPointMovable = graph.isTerminalPointMovable;
|
||||||
|
graph.isTerminalPointMovable = function(cell) {
|
||||||
|
return (
|
||||||
|
oldTerminalPointMovable.apply(this, arguments) &&
|
||||||
|
currentPermission.editEdges
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldBendable = graph.isCellBendable;
|
||||||
|
graph.isCellBendable = function(cell) {
|
||||||
|
return oldBendable.apply(this, arguments) && currentPermission.editEdges;
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldLabelMovable = graph.isLabelMovable;
|
||||||
|
graph.isLabelMovable = function(cell) {
|
||||||
|
return (
|
||||||
|
oldLabelMovable.apply(this, arguments) && currentPermission.editEdges
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldMovable = graph.isCellMovable;
|
||||||
|
graph.isCellMovable = function(cell) {
|
||||||
|
return (
|
||||||
|
oldMovable.apply(this, arguments) && currentPermission.editVertices
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldResizable = graph.isCellResizable;
|
||||||
|
graph.isCellResizable = function(cell) {
|
||||||
|
return (
|
||||||
|
oldResizable.apply(this, arguments) && currentPermission.editVertices
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldEditable = graph.isCellEditable;
|
||||||
|
graph.isCellEditable = function(cell) {
|
||||||
|
return (
|
||||||
|
(oldEditable.apply(this, arguments) &&
|
||||||
|
this.getModel().isVertex(cell) &&
|
||||||
|
currentPermission.editVertices) ||
|
||||||
|
(this.getModel().isEdge(cell) && currentPermission.editEdges)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldDeletable = graph.isCellDeletable;
|
||||||
|
graph.isCellDeletable = function(cell) {
|
||||||
|
return (
|
||||||
|
(oldDeletable.apply(this, arguments) &&
|
||||||
|
this.getModel().isVertex(cell) &&
|
||||||
|
currentPermission.editVertices) ||
|
||||||
|
(this.getModel().isEdge(cell) && currentPermission.editEdges)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldCloneable = graph.isCellCloneable;
|
||||||
|
graph.isCellCloneable = function(cell) {
|
||||||
|
return (
|
||||||
|
oldCloneable.apply(this, arguments) && currentPermission.cloneCells
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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, 'Hello,', 200, 20, 80, 30);
|
||||||
|
const v3 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
||||||
|
const e1 = graph.insertEdge(parent, null, 'Connection', v1, v3);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Permissions;
|
||||||
|
|
||||||
|
|
||||||
function main()
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
// Defines an icon for creating new connections in the connection handler.
|
|
||||||
// This will automatically disable the highlighting of the source vertex.
|
|
||||||
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
|
|
||||||
|
|
||||||
// Creates the div for the graph
|
|
||||||
let container = document.createElement('div');
|
|
||||||
container.style.position = 'absolute';
|
|
||||||
container.style.overflow = 'hidden';
|
|
||||||
container.style.left = '00px';
|
|
||||||
container.style.top = '40px';
|
|
||||||
container.style.right = '0px';
|
|
||||||
container.style.bottom = '0px';
|
|
||||||
container.style.background = 'url("editors/images/grid.gif")';
|
|
||||||
|
|
||||||
document.body.appendChild(container);
|
|
||||||
|
|
||||||
// Creates the graph inside the given container
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Enable tooltips, disables mutligraphs, enable loops
|
|
||||||
graph.setMultigraph(false);
|
|
||||||
graph.setAllowLoops(true);
|
|
||||||
|
|
||||||
// Enables rubberband selection and key handling
|
|
||||||
let rubberband = new mxRubberband(graph);
|
|
||||||
let keyHandler = new mxKeyHandler(graph);
|
|
||||||
|
|
||||||
// Assigns the delete key
|
|
||||||
keyHandler.bindKey(46, function(evt)
|
|
||||||
{
|
|
||||||
if (graph.isEnabled())
|
|
||||||
{
|
|
||||||
graph.removeCells();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Shared variable between child function scopes
|
|
||||||
// aka "private" variable
|
|
||||||
let currentPermission = null;
|
|
||||||
|
|
||||||
let apply = function(permission)
|
|
||||||
{
|
|
||||||
graph.clearSelection();
|
|
||||||
permission.apply(graph);
|
|
||||||
graph.setEnabled(true);
|
|
||||||
graph.setTooltips(true);
|
|
||||||
|
|
||||||
// Updates the icons on the shapes - rarely
|
|
||||||
// needed and very slow for large graphs
|
|
||||||
graph.refresh();
|
|
||||||
currentPermission = permission;
|
|
||||||
};
|
|
||||||
|
|
||||||
apply(new Permission());
|
|
||||||
|
|
||||||
let button = mxUtils.button('Allow All', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission());
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Connect Only', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission(false, true, false, false, true));
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Edges Only', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission(false, false, true, false, false));
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Vertices Only', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission(false, false, false, true, false));
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Select Only', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission(false, false, false, false, false));
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Locked', function(evt)
|
|
||||||
{
|
|
||||||
apply(new Permission(true, false));
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
let button = mxUtils.button('Disabled', function(evt)
|
|
||||||
{
|
|
||||||
graph.clearSelection();
|
|
||||||
graph.setEnabled(false);
|
|
||||||
graph.setTooltips(false);
|
|
||||||
});
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
// Extends hook functions to use permission object. This could
|
|
||||||
// be done by assigning the respective switches (eg.
|
|
||||||
// setMovable), but this approach is more flexible, doesn't
|
|
||||||
// override any existing behaviour or settings, and allows for
|
|
||||||
// dynamic conditions to be used in the functions. See the
|
|
||||||
// specification for more functions to extend (eg.
|
|
||||||
// isSelectable).
|
|
||||||
let oldDisconnectable = graph.isCellDisconnectable;
|
|
||||||
graph.isCellDisconnectable = function(cell, terminal, source)
|
|
||||||
{
|
|
||||||
return oldDisconnectable.apply(this, arguments) &&
|
|
||||||
currentPermission.editEdges;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldTerminalPointMovable = graph.isTerminalPointMovable;
|
|
||||||
graph.isTerminalPointMovable = function(cell)
|
|
||||||
{
|
|
||||||
return oldTerminalPointMovable.apply(this, arguments) &&
|
|
||||||
currentPermission.editEdges;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldBendable = graph.isCellBendable;
|
|
||||||
graph.isCellBendable = function(cell)
|
|
||||||
{
|
|
||||||
return oldBendable.apply(this, arguments) &&
|
|
||||||
currentPermission.editEdges;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldLabelMovable = graph.isLabelMovable;
|
|
||||||
graph.isLabelMovable = function(cell)
|
|
||||||
{
|
|
||||||
return oldLabelMovable.apply(this, arguments) &&
|
|
||||||
currentPermission.editEdges;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldMovable = graph.isCellMovable;
|
|
||||||
graph.isCellMovable = function(cell)
|
|
||||||
{
|
|
||||||
return oldMovable.apply(this, arguments) &&
|
|
||||||
currentPermission.editVertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldResizable = graph.isCellResizable;
|
|
||||||
graph.isCellResizable = function(cell)
|
|
||||||
{
|
|
||||||
return oldResizable.apply(this, arguments) &&
|
|
||||||
currentPermission.editVertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldEditable = graph.isCellEditable;
|
|
||||||
graph.isCellEditable = function(cell)
|
|
||||||
{
|
|
||||||
return oldEditable.apply(this, arguments) &&
|
|
||||||
(this.getModel().isVertex(cell) &&
|
|
||||||
currentPermission.editVertices) ||
|
|
||||||
(this.getModel().isEdge(cell) &&
|
|
||||||
currentPermission.editEdges);
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldDeletable = graph.isCellDeletable;
|
|
||||||
graph.isCellDeletable = function(cell)
|
|
||||||
{
|
|
||||||
return oldDeletable.apply(this, arguments) &&
|
|
||||||
(this.getModel().isVertex(cell) &&
|
|
||||||
currentPermission.editVertices) ||
|
|
||||||
(this.getModel().isEdge(cell) &&
|
|
||||||
currentPermission.editEdges);
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldCloneable = graph.isCellCloneable;
|
|
||||||
graph.isCellCloneable = function(cell)
|
|
||||||
{
|
|
||||||
return oldCloneable.apply(this, arguments) &&
|
|
||||||
currentPermission.cloneCells;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Gets the default parent for inserting new cells. This
|
|
||||||
// is normally the first child of the root (ie. layer 0).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'Hello,', 200, 20, 80, 30);
|
|
||||||
var v3 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
|
||||||
var e1 = graph.insertEdge(parent, null, 'Connection', v1, v3);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function Permission(locked, createEdges, editEdges, editVertices, cloneCells)
|
|
||||||
{
|
|
||||||
this.locked = (locked != null) ? locked : false;
|
|
||||||
this.createEdges = (createEdges != null) ? createEdges : true;
|
|
||||||
this.editEdges = (editEdges != null) ? editEdges : true;;
|
|
||||||
this.editVertices = (editVertices != null) ? editVertices : true;;
|
|
||||||
this.cloneCells = (cloneCells != null) ? cloneCells : true;;
|
|
||||||
};
|
|
||||||
|
|
||||||
Permission.prototype.apply = function(graph)
|
|
||||||
{
|
|
||||||
graph.setConnectable(this.createEdges);
|
|
||||||
graph.setCellsLocked(this.locked);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main();">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -12,8 +12,16 @@ import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
import mxEvent from '../mxgraph/util/mxEvent';
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxConstraintHandler from '../mxgraph/handler/mxConstraintHandler';
|
||||||
|
import mxImage from '../mxgraph/util/mxImage';
|
||||||
|
import mxShape from '../mxgraph/shape/mxShape';
|
||||||
|
import mxTriangle from '../mxgraph/shape/mxTriangle';
|
||||||
|
import mxEdgeHandler from '../mxgraph/handler/mxEdgeHandler';
|
||||||
|
import mxConnectionConstraint from '../mxgraph/view/mxConnectionConstraint';
|
||||||
|
import mxPoint from '../mxgraph/util/mxPoint';
|
||||||
|
import mxConstants from '../mxgraph/util/mxConstants';
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class PortRefs extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -29,204 +37,237 @@ class MYNAMEHERE extends React.Component {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
position: 'relative',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Replaces the port image
|
||||||
|
mxConstraintHandler.prototype.pointImage = new mxImage(
|
||||||
|
'images/dot.gif',
|
||||||
|
10,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
};
|
const graph = new mxGraph(this.el);
|
||||||
}
|
graph.setConnectable(true);
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
// Disables automatic handling of ports. This disables the reset of the
|
||||||
|
// respective style in mxGraph.cellConnected. Note that this feature may
|
||||||
|
// be useful if floating and fixed connections are combined.
|
||||||
|
graph.setPortsEnabled(false);
|
||||||
|
|
||||||
|
// Enables rubberband selection
|
||||||
|
new mxRubberband(graph);
|
||||||
|
|
||||||
function main(container)
|
// Gets the default parent for inserting new cells. This
|
||||||
{
|
// is normally the first child of the root (ie. layer 0).
|
||||||
// Replaces the port image
|
const parent = graph.getDefaultParent();
|
||||||
mxConstraintHandler.prototype.pointImage = new mxImage('images/dot.gif', 10, 10);
|
|
||||||
|
|
||||||
let graph = new mxGraph(container);
|
// Ports are equal for all shapes...
|
||||||
graph.setConnectable(true);
|
const ports = new Array();
|
||||||
|
|
||||||
// Disables automatic handling of ports. This disables the reset of the
|
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
|
||||||
// respective style in mxGraph.cellConnected. Note that this feature may
|
ports.w = { x: 0, y: 0.5, perimeter: true, constraint: 'west' };
|
||||||
// be useful if floating and fixed connections are combined.
|
ports.e = { x: 1, y: 0.5, perimeter: true, constraint: 'east' };
|
||||||
graph.setPortsEnabled(false);
|
ports.n = { x: 0.5, y: 0, perimeter: true, constraint: 'north' };
|
||||||
|
ports.s = { x: 0.5, y: 1, perimeter: true, constraint: 'south' };
|
||||||
|
ports.nw = { x: 0, y: 0, perimeter: true, constraint: 'north west' };
|
||||||
|
ports.ne = { x: 1, y: 0, perimeter: true, constraint: 'north east' };
|
||||||
|
ports.sw = { x: 0, y: 1, perimeter: true, constraint: 'south west' };
|
||||||
|
ports.se = { x: 1, y: 1, perimeter: true, constraint: 'south east' };
|
||||||
|
|
||||||
// Enables rubberband selection
|
// ... except for triangles
|
||||||
new mxRubberband(graph);
|
const ports2 = new Array();
|
||||||
|
|
||||||
// Gets the default parent for inserting new cells. This
|
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
|
||||||
// is normally the first child of the root (ie. layer 0).
|
ports2.in1 = { x: 0, y: 0, perimeter: true, constraint: 'west' };
|
||||||
let parent = graph.getDefaultParent();
|
ports2.in2 = { x: 0, y: 0.25, perimeter: true, constraint: 'west' };
|
||||||
|
ports2.in3 = { x: 0, y: 0.5, perimeter: true, constraint: 'west' };
|
||||||
|
ports2.in4 = { x: 0, y: 0.75, perimeter: true, constraint: 'west' };
|
||||||
|
ports2.in5 = { x: 0, y: 1, perimeter: true, constraint: 'west' };
|
||||||
|
|
||||||
// Ports are equal for all shapes...
|
ports2.out1 = {
|
||||||
let ports = new Array();
|
x: 0.5,
|
||||||
|
y: 0,
|
||||||
|
perimeter: true,
|
||||||
|
constraint: 'north east',
|
||||||
|
};
|
||||||
|
ports2.out2 = { x: 1, y: 0.5, perimeter: true, constraint: 'east' };
|
||||||
|
ports2.out3 = {
|
||||||
|
x: 0.5,
|
||||||
|
y: 1,
|
||||||
|
perimeter: true,
|
||||||
|
constraint: 'south east',
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
|
// Extends shapes classes to return their ports
|
||||||
ports['w'] = {x: 0, y: 0.5, perimeter: true, constraint: 'west'};
|
mxShape.prototype.getPorts = function() {
|
||||||
ports['e'] = {x: 1, y: 0.5, perimeter: true, constraint: 'east'};
|
return ports;
|
||||||
ports['n'] = {x: 0.5, y: 0, perimeter: true, constraint: 'north'};
|
};
|
||||||
ports['s'] = {x: 0.5, y: 1, perimeter: true, constraint: 'south'};
|
|
||||||
ports['nw'] = {x: 0, y: 0, perimeter: true, constraint: 'north west'};
|
|
||||||
ports['ne'] = {x: 1, y: 0, perimeter: true, constraint: 'north east'};
|
|
||||||
ports['sw'] = {x: 0, y: 1, perimeter: true, constraint: 'south west'};
|
|
||||||
ports['se'] = {x: 1, y: 1, perimeter: true, constraint: 'south east'};
|
|
||||||
|
|
||||||
// ... except for triangles
|
mxTriangle.prototype.getPorts = function() {
|
||||||
var ports2 = new Array();
|
return ports2;
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
|
// Disables floating connections (only connections via ports allowed)
|
||||||
ports2['in1'] = {x: 0, y: 0, perimeter: true, constraint: 'west'};
|
graph.connectionHandler.isConnectableCell = function(cell) {
|
||||||
ports2['in2'] = {x: 0, y: 0.25, perimeter: true, constraint: 'west'};
|
return false;
|
||||||
ports2['in3'] = {x: 0, y: 0.5, perimeter: true, constraint: 'west'};
|
};
|
||||||
ports2['in4'] = {x: 0, y: 0.75, perimeter: true, constraint: 'west'};
|
mxEdgeHandler.prototype.isConnectableCell = function(cell) {
|
||||||
ports2['in5'] = {x: 0, y: 1, perimeter: true, constraint: 'west'};
|
return graph.connectionHandler.isConnectableCell(cell);
|
||||||
|
};
|
||||||
|
|
||||||
ports2['out1'] = {x: 0.5, y: 0, perimeter: true, constraint: 'north east'};
|
// Disables existing port functionality
|
||||||
ports2['out2'] = {x: 1, y: 0.5, perimeter: true, constraint: 'east'};
|
graph.view.getTerminalPort = function(state, terminal, source) {
|
||||||
ports2['out3'] = {x: 0.5, y: 1, perimeter: true, constraint: 'south east'};
|
return terminal;
|
||||||
|
};
|
||||||
|
|
||||||
// Extends shapes classes to return their ports
|
// Returns all possible ports for a given terminal
|
||||||
mxShape.prototype.getPorts = function()
|
graph.getAllConnectionConstraints = function(terminal, source) {
|
||||||
{
|
if (
|
||||||
return ports;
|
terminal != null &&
|
||||||
};
|
terminal.shape != null &&
|
||||||
|
terminal.shape.stencil != null
|
||||||
mxTriangle.prototype.getPorts = function()
|
) {
|
||||||
{
|
// for stencils with existing constraints...
|
||||||
return ports2;
|
if (terminal.shape.stencil != null) {
|
||||||
};
|
return terminal.shape.stencil.constraints;
|
||||||
|
|
||||||
// Disables floating connections (only connections via ports allowed)
|
|
||||||
graph.connectionHandler.isConnectableCell = function(cell)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
mxEdgeHandler.prototype.isConnectableCell = function(cell)
|
|
||||||
{
|
|
||||||
return graph.connectionHandler.isConnectableCell(cell);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Disables existing port functionality
|
|
||||||
graph.view.getTerminalPort = function(state, terminal, source)
|
|
||||||
{
|
|
||||||
return terminal;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns all possible ports for a given terminal
|
|
||||||
graph.getAllConnectionConstraints = function(terminal, source)
|
|
||||||
{
|
|
||||||
if (terminal != null && terminal.shape != null &&
|
|
||||||
terminal.shape.stencil != null)
|
|
||||||
{
|
|
||||||
// for stencils with existing constraints...
|
|
||||||
if (terminal.shape.stencil != null)
|
|
||||||
{
|
|
||||||
return terminal.shape.stencil.constraints;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (terminal != null && this.model.isVertex(terminal.cell))
|
} else if (terminal != null && this.model.isVertex(terminal.cell)) {
|
||||||
{
|
if (terminal.shape != null) {
|
||||||
if (terminal.shape != null)
|
const ports = terminal.shape.getPorts();
|
||||||
{
|
const cstrs = new Array();
|
||||||
let ports = terminal.shape.getPorts();
|
|
||||||
let cstrs = new Array();
|
|
||||||
|
|
||||||
for (var id in ports)
|
for (const id in ports) {
|
||||||
{
|
const port = ports[id];
|
||||||
let port = ports[id];
|
|
||||||
|
|
||||||
let cstr = new mxConnectionConstraint(new mxPoint(port.x, port.y), port.perimeter);
|
const cstr = new mxConnectionConstraint(
|
||||||
cstr.id = id;
|
new mxPoint(port.x, port.y),
|
||||||
cstrs.push(cstr);
|
port.perimeter
|
||||||
}
|
);
|
||||||
|
cstr.id = id;
|
||||||
return cstrs;
|
cstrs.push(cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return cstrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sets the port for the given connection
|
|
||||||
graph.setConnectionConstraint = function(edge, terminal, source, constraint)
|
|
||||||
{
|
|
||||||
if (constraint != null)
|
|
||||||
{
|
|
||||||
let key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
|
|
||||||
|
|
||||||
if (constraint == null || constraint.id == null)
|
|
||||||
{
|
|
||||||
this.setCellStyles(key, null, [edge]);
|
|
||||||
}
|
|
||||||
else if (constraint.id != null)
|
|
||||||
{
|
|
||||||
this.setCellStyles(key, constraint.id, [edge]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the port for the given connection
|
|
||||||
graph.getConnectionConstraint = function(edge, terminal, source)
|
|
||||||
{
|
|
||||||
let key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
|
|
||||||
let id = edge.style[key];
|
|
||||||
|
|
||||||
if (id != null)
|
|
||||||
{
|
|
||||||
let c = new mxConnectionConstraint(null, null);
|
|
||||||
c.id = id;
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the actual point for a port by redirecting the constraint to the port
|
|
||||||
graphGetConnectionPoint = graph.getConnectionPoint;
|
|
||||||
graph.getConnectionPoint = function(vertex, constraint)
|
|
||||||
{
|
|
||||||
if (constraint.id != null && vertex != null && vertex.shape != null)
|
|
||||||
{
|
|
||||||
let port = vertex.shape.getPorts()[constraint.id];
|
|
||||||
|
|
||||||
if (port != null)
|
|
||||||
{
|
|
||||||
constraint = new mxConnectionConstraint(new mxPoint(port.x, port.y), port.perimeter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return graphGetConnectionPoint.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'A', 20, 20, 100, 40);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'B', 80, 100, 100, 100,
|
|
||||||
'shape=ellipse;perimeter=ellipsePerimeter');
|
|
||||||
var v3 = graph.insertVertex(parent, null, 'C', 190, 30, 100, 60,
|
|
||||||
'shape=triangle;perimeter=trianglePerimeter;direction=south');
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2, 'sourcePort=s;targetPort=nw');
|
|
||||||
var e2 = graph.insertEdge(parent, null, '', v1, v3, 'sourcePort=e;targetPort=out3');
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comming soon... Integration with orthogonal edge style
|
return null;
|
||||||
// Sets default edge style to use port constraints (needs to be moved up when uncommented)
|
};
|
||||||
//graph.getStylesheet().getDefaultEdgeStyle()['edgeStyle'] = 'orthogonalEdgeStyle';
|
|
||||||
/*let mxUtilsGetPortConstraints = mxUtils.getPortConstraints;
|
// Sets the port for the given connection
|
||||||
|
graph.setConnectionConstraint = function(
|
||||||
|
edge,
|
||||||
|
terminal,
|
||||||
|
source,
|
||||||
|
constraint
|
||||||
|
) {
|
||||||
|
if (constraint != null) {
|
||||||
|
const key = source
|
||||||
|
? mxConstants.STYLE_SOURCE_PORT
|
||||||
|
: mxConstants.STYLE_TARGET_PORT;
|
||||||
|
|
||||||
|
if (constraint == null || constraint.id == null) {
|
||||||
|
this.setCellStyles(key, null, [edge]);
|
||||||
|
} else if (constraint.id != null) {
|
||||||
|
this.setCellStyles(key, constraint.id, [edge]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns the port for the given connection
|
||||||
|
graph.getConnectionConstraint = function(edge, terminal, source) {
|
||||||
|
const key = source
|
||||||
|
? mxConstants.STYLE_SOURCE_PORT
|
||||||
|
: mxConstants.STYLE_TARGET_PORT;
|
||||||
|
const id = edge.style[key];
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
const c = new mxConnectionConstraint(null, null);
|
||||||
|
c.id = id;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns the actual point for a port by redirecting the constraint to the port
|
||||||
|
const graphGetConnectionPoint = graph.getConnectionPoint;
|
||||||
|
graph.getConnectionPoint = function(vertex, constraint) {
|
||||||
|
if (constraint.id != null && vertex != null && vertex.shape != null) {
|
||||||
|
const port = vertex.shape.getPorts()[constraint.id];
|
||||||
|
|
||||||
|
if (port != null) {
|
||||||
|
constraint = new mxConnectionConstraint(
|
||||||
|
new mxPoint(port.x, port.y),
|
||||||
|
port.perimeter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphGetConnectionPoint.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adds cells to the model in a single step
|
||||||
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
const v1 = graph.insertVertex(parent, null, 'A', 20, 20, 100, 40);
|
||||||
|
const v2 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'B',
|
||||||
|
80,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
'shape=ellipse;perimeter=ellipsePerimeter'
|
||||||
|
);
|
||||||
|
const v3 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'C',
|
||||||
|
190,
|
||||||
|
30,
|
||||||
|
100,
|
||||||
|
60,
|
||||||
|
'shape=triangle;perimeter=trianglePerimeter;direction=south'
|
||||||
|
);
|
||||||
|
const e1 = graph.insertEdge(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'',
|
||||||
|
v1,
|
||||||
|
v2,
|
||||||
|
'sourcePort=s;targetPort=nw'
|
||||||
|
);
|
||||||
|
const e2 = graph.insertEdge(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'',
|
||||||
|
v1,
|
||||||
|
v3,
|
||||||
|
'sourcePort=e;targetPort=out3'
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comming soon... Integration with orthogonal edge style
|
||||||
|
// Sets default edge style to use port constraints (needs to be moved up when uncommented)
|
||||||
|
// graph.getStylesheet().getDefaultEdgeStyle()['edgeStyle'] = 'orthogonalEdgeStyle';
|
||||||
|
/* let mxUtilsGetPortConstraints = mxUtils.getPortConstraints;
|
||||||
mxUtils.getPortConstraints = function(terminal, edge, source, defaultValue)
|
mxUtils.getPortConstraints = function(terminal, edge, source, defaultValue)
|
||||||
{
|
{
|
||||||
let key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
|
let key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
|
||||||
|
@ -250,12 +291,7 @@ export default MYNAMEHERE;
|
||||||
return new mxCellState(this.graph.view, edge, this.graph.getCellStyle(edge));
|
return new mxCellState(this.graph.view, edge, this.graph.getCellStyle(edge));
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
};
|
}
|
||||||
</script>
|
}
|
||||||
</head>
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
export default PortRefs;
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;position:relative;width:321px;height:241px;background:url('editors/images/grid.gif');cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxPerimeter from '../mxgraph/view/mxPerimeter';
|
||||||
|
import mxConstants from '../mxgraph/util/mxConstants';
|
||||||
|
import mxRadialTreeLayout from '../mxgraph/layout/mxRadialTreeLayout';
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class RadialTreeLayout extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -21,120 +23,91 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Hierarchical Layout example for mxGraph</h1>
|
<h1>Hierarchical Layout example for mxGraph</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'auto',
|
||||||
|
height: '800px',
|
||||||
|
width: '1000px',
|
||||||
|
borderTop: 'gray 1px solid',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
|
||||||
};
|
// Adds rubberband selection
|
||||||
|
new mxRubberband(graph);
|
||||||
|
|
||||||
|
// Changes the default vertex style in-place
|
||||||
|
let style = graph.getStylesheet().getDefaultVertexStyle();
|
||||||
|
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
|
||||||
|
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
|
||||||
|
style[mxConstants.STYLE_PERIMETER_SPACING] = 6;
|
||||||
|
style[mxConstants.STYLE_ROUNDED] = true;
|
||||||
|
style[mxConstants.STYLE_SHADOW] = true;
|
||||||
|
|
||||||
|
style = graph.getStylesheet().getDefaultEdgeStyle();
|
||||||
|
style[mxConstants.STYLE_ROUNDED] = true;
|
||||||
|
|
||||||
|
// Creates a layout algorithm to be used
|
||||||
|
// with the graph
|
||||||
|
const layout = new mxRadialTreeLayout(graph);
|
||||||
|
|
||||||
|
const parent = graph.getDefaultParent();
|
||||||
|
|
||||||
|
// Load cells and layouts the graph
|
||||||
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
const v1 = graph.insertVertex(parent, null, '1', 500, 500, 80, 30);
|
||||||
|
const v2 = graph.insertVertex(parent, null, '2.1', 0, 0, 80, 30);
|
||||||
|
const v3 = graph.insertVertex(parent, null, '2.2', 0, 0, 80, 30);
|
||||||
|
const v4 = graph.insertVertex(parent, null, '3.1', 0, 0, 80, 30);
|
||||||
|
const v4_1 = graph.insertVertex(parent, null, '3.2', 0, 0, 80, 30);
|
||||||
|
const v4_2 = graph.insertVertex(parent, null, '3.3', 0, 0, 80, 30);
|
||||||
|
const v4_3 = graph.insertVertex(parent, null, '3.6', 0, 0, 80, 30);
|
||||||
|
const v4_4 = graph.insertVertex(parent, null, '3.7', 0, 0, 80, 30);
|
||||||
|
const v5 = graph.insertVertex(parent, null, '3.4', 0, 0, 80, 30);
|
||||||
|
const v6 = graph.insertVertex(parent, null, '2.3', 0, 0, 80, 30);
|
||||||
|
const v7 = graph.insertVertex(parent, null, '4.1', 0, 0, 80, 30);
|
||||||
|
const v7_1 = graph.insertVertex(parent, null, '4.2', 0, 0, 80, 30);
|
||||||
|
const v7_2 = graph.insertVertex(parent, null, '4.3', 0, 0, 80, 30);
|
||||||
|
const v7_3 = graph.insertVertex(parent, null, '4.4', 0, 0, 80, 30);
|
||||||
|
const v7_4 = graph.insertVertex(parent, null, '4.5', 0, 0, 80, 30);
|
||||||
|
const v7_5 = graph.insertVertex(parent, null, '4.6', 0, 0, 80, 30);
|
||||||
|
const v7_6 = graph.insertVertex(parent, null, '4.7', 0, 0, 80, 30);
|
||||||
|
|
||||||
|
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||||
|
const e2 = graph.insertEdge(parent, null, '', v1, v3);
|
||||||
|
const e3 = graph.insertEdge(parent, null, '', v3, v4);
|
||||||
|
const e3_1 = graph.insertEdge(parent, null, '', v3, v4_1);
|
||||||
|
const e3_2 = graph.insertEdge(parent, null, '', v3, v4_2);
|
||||||
|
const e3_3 = graph.insertEdge(parent, null, '', v3, v4_3);
|
||||||
|
const e3_4 = graph.insertEdge(parent, null, '', v3, v4_4);
|
||||||
|
const e4 = graph.insertEdge(parent, null, '', v2, v5);
|
||||||
|
const e5 = graph.insertEdge(parent, null, '', v1, v6);
|
||||||
|
const e6 = graph.insertEdge(parent, null, '', v4_3, v7);
|
||||||
|
var e6_1 = graph.insertEdge(parent, null, '', v4_4, v7_4);
|
||||||
|
var e6_2 = graph.insertEdge(parent, null, '', v4_4, v7_5);
|
||||||
|
var e6_3 = graph.insertEdge(parent, null, '', v4_4, v7_6);
|
||||||
|
var e6_1 = graph.insertEdge(parent, null, '', v4_3, v7_1);
|
||||||
|
var e6_2 = graph.insertEdge(parent, null, '', v4_3, v7_2);
|
||||||
|
var e6_3 = graph.insertEdge(parent, null, '', v4_3, v7_3);
|
||||||
|
|
||||||
|
// Executes the layout
|
||||||
|
layout.execute(parent);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default RadialTreeLayout;
|
||||||
|
|
||||||
function main(container)
|
|
||||||
{
|
|
||||||
// Checks if 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
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Adds rubberband selection
|
|
||||||
new mxRubberband(graph);
|
|
||||||
|
|
||||||
// Changes the default vertex style in-place
|
|
||||||
let style = graph.getStylesheet().getDefaultVertexStyle();
|
|
||||||
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
|
|
||||||
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
|
|
||||||
style[mxConstants.STYLE_PERIMETER_SPACING] = 6;
|
|
||||||
style[mxConstants.STYLE_ROUNDED] = true;
|
|
||||||
style[mxConstants.STYLE_SHADOW] = true;
|
|
||||||
|
|
||||||
style = graph.getStylesheet().getDefaultEdgeStyle();
|
|
||||||
style[mxConstants.STYLE_ROUNDED] = true;
|
|
||||||
|
|
||||||
// Creates a layout algorithm to be used
|
|
||||||
// with the graph
|
|
||||||
let layout = new mxRadialTreeLayout(graph);
|
|
||||||
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Load cells and layouts the graph
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, '1', 500, 500, 80, 30);
|
|
||||||
var v2 = graph.insertVertex(parent, null, '2.1', 0, 0, 80, 30);
|
|
||||||
var v3 = graph.insertVertex(parent, null, '2.2', 0, 0, 80, 30);
|
|
||||||
var v4 = graph.insertVertex(parent, null, '3.1', 0, 0, 80, 30);
|
|
||||||
var v4_1 = graph.insertVertex(parent, null, '3.2', 0, 0, 80, 30);
|
|
||||||
var v4_2 = graph.insertVertex(parent, null, '3.3', 0, 0, 80, 30);
|
|
||||||
var v4_3 = graph.insertVertex(parent, null, '3.6', 0, 0, 80, 30);
|
|
||||||
var v4_4 = graph.insertVertex(parent, null, '3.7', 0, 0, 80, 30);
|
|
||||||
var v5 = graph.insertVertex(parent, null, '3.4', 0, 0, 80, 30);
|
|
||||||
var v6 = graph.insertVertex(parent, null, '2.3', 0, 0, 80, 30);
|
|
||||||
var v7 = graph.insertVertex(parent, null, '4.1', 0, 0, 80, 30);
|
|
||||||
var v7_1 = graph.insertVertex(parent, null, '4.2', 0, 0, 80, 30);
|
|
||||||
var v7_2 = graph.insertVertex(parent, null, '4.3', 0, 0, 80, 30);
|
|
||||||
var v7_3 = graph.insertVertex(parent, null, '4.4', 0, 0, 80, 30);
|
|
||||||
var v7_4 = graph.insertVertex(parent, null, '4.5', 0, 0, 80, 30);
|
|
||||||
var v7_5 = graph.insertVertex(parent, null, '4.6', 0, 0, 80, 30);
|
|
||||||
var v7_6 = graph.insertVertex(parent, null, '4.7', 0, 0, 80, 30);
|
|
||||||
|
|
||||||
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
var e2 = graph.insertEdge(parent, null, '', v1, v3);
|
|
||||||
var e3 = graph.insertEdge(parent, null, '', v3, v4);
|
|
||||||
var e3_1 = graph.insertEdge(parent, null, '', v3, v4_1);
|
|
||||||
var e3_2 = graph.insertEdge(parent, null, '', v3, v4_2);
|
|
||||||
var e3_3 = graph.insertEdge(parent, null, '', v3, v4_3);
|
|
||||||
var e3_4 = graph.insertEdge(parent, null, '', v3, v4_4);
|
|
||||||
var e4 = graph.insertEdge(parent, null, '', v2, v5);
|
|
||||||
var e5 = graph.insertEdge(parent, null, '', v1, v6);
|
|
||||||
var e6 = graph.insertEdge(parent, null, '', v4_3, v7);
|
|
||||||
var e6_1 = graph.insertEdge(parent, null, '', v4_4, v7_4);
|
|
||||||
var e6_2 = graph.insertEdge(parent, null, '', v4_4, v7_5);
|
|
||||||
var e6_3 = graph.insertEdge(parent, null, '', v4_4, v7_6);
|
|
||||||
var e6_1 = graph.insertEdge(parent, null, '', v4_3, v7_1);
|
|
||||||
var e6_2 = graph.insertEdge(parent, null, '', v4_3, v7_2);
|
|
||||||
var e6_3 = graph.insertEdge(parent, null, '', v4_3, v7_3);
|
|
||||||
|
|
||||||
// Executes the layout
|
|
||||||
layout.execute(parent);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))" style="margin:4px;">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper. Make sure to define the position
|
|
||||||
and overflow attributes! See comments on the adding of the size-listener on line 54 ff! -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="position:absolute;overflow:auto;top:36px;bottom:0px;left:0px;right:0px;border-top:gray 1px solid;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -9,8 +9,9 @@ import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
import mxEvent from '../mxgraph/util/mxEvent';
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxClient from '../mxgraph/mxClient';
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Resources extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -26,74 +27,49 @@ class MYNAMEHERE extends React.Component {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Async indirection to load resources asynchronously (see above)
|
||||||
|
// Alternatively you can remove the line that sets mxLoadResources
|
||||||
|
// anove and change the code to not use this callback.
|
||||||
|
|
||||||
};
|
mxClient.loadResources(() => {
|
||||||
|
// Disables the built-in context menu
|
||||||
|
mxEvent.disableContextMenu(this.el);
|
||||||
|
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Resources;
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// Async indirection to load resources asynchronously (see above)
|
|
||||||
// Alternatively you can remove the line that sets mxLoadResources
|
|
||||||
// anove and change the code to not use this callback.
|
|
||||||
mxClient.loadResources(function()
|
|
||||||
{
|
|
||||||
// Disables the built-in context menu
|
|
||||||
mxEvent.disableContextMenu(container);
|
|
||||||
|
|
||||||
// Creates the graph inside the given container
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// 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).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="position:relative;overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif');cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2006-2013, JGraph Ltd
|
* Copyright (c) 2006-2013, JGraph Ltd
|
||||||
|
|
||||||
Second label example for mxGraph. This example demonstrates how to
|
Second label example for mxGraph. This example demonstrates how to
|
||||||
add another string label to vertices.
|
add another string label to vertices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxUtils from '../mxgraph/util/mxUtils';
|
||||||
|
import mxPoint from '../mxgraph/util/mxPoint';
|
||||||
|
import mxRectangle from '../mxgraph/util/mxRectangle';
|
||||||
|
import mxConstants from '../mxgraph/util/mxConstants';
|
||||||
|
import mxRectangleShape from '../mxgraph/shape/mxRectangleShape';
|
||||||
|
import mxText from "../mxgraph/shape/mxText";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class SecondLabel extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -26,34 +30,37 @@ class MYNAMEHERE extends React.Component {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
|
||||||
|
|
||||||
// Simple solution to add additional text to the rectangle shape definition:
|
// Simple solution to add additional text to the rectangle shape definition:
|
||||||
(function()
|
(function() {
|
||||||
{
|
const mxRectangleShapeIsHtmlAllowed =
|
||||||
let mxRectangleShapeIsHtmlAllowed = mxRectangleShape.prototype.isHtmlAllowed;
|
mxRectangleShape.prototype.isHtmlAllowed;
|
||||||
mxRectangleShape.prototype.isHtmlAllowed = function()
|
mxRectangleShape.prototype.isHtmlAllowed = function() {
|
||||||
{
|
return (
|
||||||
return mxRectangleShapeIsHtmlAllowed.apply(this, arguments) && this.state == null;
|
mxRectangleShapeIsHtmlAllowed.apply(this, arguments) &&
|
||||||
|
this.state == null
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
mxRectangleShapePaintForeground = mxRectangleShape.prototype.paintForeground;
|
const mxRectangleShapePaintForeground =
|
||||||
mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h)
|
mxRectangleShape.prototype.paintForeground;
|
||||||
{
|
mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h) {
|
||||||
if (this.state != null && this.state.cell.geometry != null && !this.state.cell.geometry.relative)
|
if (
|
||||||
{
|
this.state != null &&
|
||||||
|
this.state.cell.geometry != null &&
|
||||||
|
!this.state.cell.geometry.relative
|
||||||
|
) {
|
||||||
c.setFontColor('#a0a0a0');
|
c.setFontColor('#a0a0a0');
|
||||||
c.text(x + 2, y, 0, 0, this.state.cell.id, 'left', 'top');
|
c.text(x + 2, y, 0, 0, this.state.cell.id, 'left', 'top');
|
||||||
}
|
}
|
||||||
|
@ -62,171 +69,175 @@ export default MYNAMEHERE;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Program starts here. Creates a sample graph in the
|
// Creates the graph inside the given container
|
||||||
// DOM node with the specified ID. This function is invoked
|
const graph = new mxGraph(this.el);
|
||||||
// from the onLoad event handler of the document (see below).
|
|
||||||
function main(container)
|
// Disables the folding icon
|
||||||
{
|
graph.isCellFoldable = function(cell) {
|
||||||
// Checks if the browser is supported
|
return false;
|
||||||
if (!mxClient.isBrowserSupported())
|
};
|
||||||
{
|
|
||||||
// Displays an error message if the browser is not supported.
|
let secondLabelVisible = true;
|
||||||
mxUtils.error('Browser is not supported!', 200, false);
|
|
||||||
|
// Hook for returning shape number for a given cell
|
||||||
|
graph.getSecondLabel = function(cell) {
|
||||||
|
if (!this.model.isEdge(cell)) {
|
||||||
|
// Possible to return any string here
|
||||||
|
return `The ID of this cell is ${cell.id}`;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Creates the graph inside the given container
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Disables the folding icon
|
return null;
|
||||||
graph.isCellFoldable = function(cell)
|
};
|
||||||
{
|
|
||||||
return false;
|
let relativeChildVerticesVisible = true;
|
||||||
|
|
||||||
|
// Overrides method to hide relative child vertices
|
||||||
|
graph.isCellVisible = function(cell) {
|
||||||
|
return (
|
||||||
|
!this.model.isVertex(cell) ||
|
||||||
|
cell.geometry == null ||
|
||||||
|
!cell.geometry.relative ||
|
||||||
|
cell.geometry.relative == relativeChildVerticesVisible
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the shape for the shape number and puts it into the draw pane
|
||||||
|
const { redrawShape } = graph.cellRenderer;
|
||||||
|
graph.cellRenderer.redrawShape = function(state, force, rendering) {
|
||||||
|
const result = redrawShape.apply(this, arguments);
|
||||||
|
|
||||||
|
if (
|
||||||
|
result &&
|
||||||
|
secondLabelVisible &&
|
||||||
|
state.cell.geometry != null &&
|
||||||
|
!state.cell.geometry.relative
|
||||||
|
) {
|
||||||
|
const secondLabel = graph.getSecondLabel(state.cell);
|
||||||
|
|
||||||
|
if (
|
||||||
|
secondLabel != null &&
|
||||||
|
state.shape != null &&
|
||||||
|
state.secondLabel == null
|
||||||
|
) {
|
||||||
|
state.secondLabel = new mxText(
|
||||||
|
secondLabel,
|
||||||
|
new mxRectangle(),
|
||||||
|
mxConstants.ALIGN_LEFT,
|
||||||
|
mxConstants.ALIGN_BOTTOM
|
||||||
|
);
|
||||||
|
|
||||||
|
// Styles the label
|
||||||
|
state.secondLabel.color = 'black';
|
||||||
|
state.secondLabel.family = 'Verdana';
|
||||||
|
state.secondLabel.size = 8;
|
||||||
|
state.secondLabel.fontStyle = mxConstants.FONT_ITALIC;
|
||||||
|
state.secondLabel.background = 'yellow';
|
||||||
|
state.secondLabel.border = 'black';
|
||||||
|
state.secondLabel.valign = 'bottom';
|
||||||
|
state.secondLabel.dialect = state.shape.dialect;
|
||||||
|
state.secondLabel.dialect = mxConstants.DIALECT_STRICTHTML;
|
||||||
|
state.secondLabel.wrap = true;
|
||||||
|
graph.cellRenderer.initializeLabel(state, state.secondLabel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let secondLabelVisible = true;
|
if (state.secondLabel != null) {
|
||||||
|
const scale = graph.getView().getScale();
|
||||||
|
const bounds = new mxRectangle(
|
||||||
|
state.x + state.width - 8 * scale,
|
||||||
|
state.y + 8 * scale,
|
||||||
|
35,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
state.secondLabel.state = state;
|
||||||
|
state.secondLabel.value = graph.getSecondLabel(state.cell);
|
||||||
|
state.secondLabel.scale = scale;
|
||||||
|
state.secondLabel.bounds = bounds;
|
||||||
|
state.secondLabel.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
// Hook for returning shape number for a given cell
|
return result;
|
||||||
graph.getSecondLabel = function(cell)
|
};
|
||||||
{
|
|
||||||
if (!this.model.isEdge(cell))
|
|
||||||
{
|
|
||||||
// Possible to return any string here
|
|
||||||
return 'The ID of this cell is ' + cell.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
// Destroys the shape number
|
||||||
};
|
const { destroy } = graph.cellRenderer;
|
||||||
|
graph.cellRenderer.destroy = function(state) {
|
||||||
|
destroy.apply(this, arguments);
|
||||||
|
|
||||||
let relativeChildVerticesVisible = true;
|
if (state.secondLabel != null) {
|
||||||
|
state.secondLabel.destroy();
|
||||||
// Overrides method to hide relative child vertices
|
state.secondLabel = null;
|
||||||
graph.isCellVisible = function(cell)
|
|
||||||
{
|
|
||||||
return !this.model.isVertex(cell) || cell.geometry == null ||
|
|
||||||
!cell.geometry.relative ||
|
|
||||||
cell.geometry.relative == relativeChildVerticesVisible;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Creates the shape for the shape number and puts it into the draw pane
|
|
||||||
let redrawShape = graph.cellRenderer.redrawShape;
|
|
||||||
graph.cellRenderer.redrawShape = function(state, force, rendering)
|
|
||||||
{
|
|
||||||
let result = redrawShape.apply(this, arguments);
|
|
||||||
|
|
||||||
if (result && secondLabelVisible && state.cell.geometry != null && !state.cell.geometry.relative)
|
|
||||||
{
|
|
||||||
let secondLabel = graph.getSecondLabel(state.cell);
|
|
||||||
|
|
||||||
if (secondLabel != null && state.shape != null && state.secondLabel == null)
|
|
||||||
{
|
|
||||||
state.secondLabel = new mxText(secondLabel, new mxRectangle(),
|
|
||||||
mxConstants.ALIGN_LEFT, mxConstants.ALIGN_BOTTOM);
|
|
||||||
|
|
||||||
// Styles the label
|
|
||||||
state.secondLabel.color = 'black';
|
|
||||||
state.secondLabel.family = 'Verdana';
|
|
||||||
state.secondLabel.size = 8;
|
|
||||||
state.secondLabel.fontStyle = mxConstants.FONT_ITALIC;
|
|
||||||
state.secondLabel.background = 'yellow';
|
|
||||||
state.secondLabel.border = 'black';
|
|
||||||
state.secondLabel.valign = 'bottom';
|
|
||||||
state.secondLabel.dialect = state.shape.dialect;
|
|
||||||
state.secondLabel.dialect = mxConstants.DIALECT_STRICTHTML;
|
|
||||||
state.secondLabel.wrap = true;
|
|
||||||
graph.cellRenderer.initializeLabel(state, state.secondLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.secondLabel != null)
|
|
||||||
{
|
|
||||||
let scale = graph.getView().getScale();
|
|
||||||
let bounds = new mxRectangle(state.x + state.width - 8 * scale, state.y + 8 * scale, 35, 0);
|
|
||||||
state.secondLabel.state = state;
|
|
||||||
state.secondLabel.value = graph.getSecondLabel(state.cell);
|
|
||||||
state.secondLabel.scale = scale;
|
|
||||||
state.secondLabel.bounds = bounds;
|
|
||||||
state.secondLabel.redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Destroys the shape number
|
|
||||||
let destroy = graph.cellRenderer.destroy;
|
|
||||||
graph.cellRenderer.destroy = function(state)
|
|
||||||
{
|
|
||||||
destroy.apply(this, arguments);
|
|
||||||
|
|
||||||
if (state.secondLabel != null)
|
|
||||||
{
|
|
||||||
state.secondLabel.destroy();
|
|
||||||
state.secondLabel = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
graph.cellRenderer.getShapesForState = function(state)
|
|
||||||
{
|
|
||||||
return [state.shape, state.text, state.secondLabel, state.control];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Gets the default parent for inserting new cells. This
|
|
||||||
// is normally the first child of the root (ie. layer 0).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Hello,', 30, 40, 80, 30);
|
|
||||||
// Alternative solution of creating a second label by creating a realtive child vertex
|
|
||||||
// with size (0, 0). This will not be selectable and only the label colors can be used
|
|
||||||
// for coloring as the actual shape will have zero size.
|
|
||||||
var v11 = graph.insertVertex(v1, null, 'World', 1, 1, 0, 0, 'align=left;verticalAlign=top;labelBackgroundColor=red;labelBorderColor=black', true);
|
|
||||||
v11.geometry.offset = new mxPoint(-8, -8);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
|
||||||
// Another alternative solution of creating a second label as a relative child vertex
|
|
||||||
// but this time with an automatic size so that the cell is actually selectable and
|
|
||||||
// the background is painted as a shape.
|
|
||||||
var v21 = graph.insertVertex(v2, null, 'World', 1, 1, 0, 0, 'align=left;verticalAlign=top;fillColor=red;rounded=1;spacingLeft=4;spacingRight=4', true);
|
|
||||||
v21.geometry.offset = new mxPoint(-8, -8);
|
|
||||||
graph.updateCellSize(v21);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a button to execute the layout
|
|
||||||
document.body.insertBefore(mxUtils.button('Toggle Child Vertices',
|
|
||||||
function(evt)
|
|
||||||
{
|
|
||||||
relativeChildVerticesVisible = !relativeChildVerticesVisible;
|
|
||||||
graph.refresh();
|
|
||||||
}
|
|
||||||
), document.body.firstChild);
|
|
||||||
|
|
||||||
// Adds a button to execute the layout
|
|
||||||
document.body.insertBefore(mxUtils.button('Toggle IDs',
|
|
||||||
function(evt)
|
|
||||||
{
|
|
||||||
secondLabelVisible = !secondLabelVisible;
|
|
||||||
graph.refresh();
|
|
||||||
}
|
|
||||||
), document.body.firstChild);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
graph.cellRenderer.getShapesForState = function(state) {
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
return [state.shape, state.text, state.secondLabel, state.control];
|
||||||
|
};
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
// Gets the default parent for inserting new cells. This
|
||||||
<div id="graphContainer"
|
// is normally the first child of the root (ie. layer 0).
|
||||||
style="position:relative;overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif')">
|
const parent = graph.getDefaultParent();
|
||||||
</div>
|
|
||||||
</body>
|
// Adds cells to the model in a single step
|
||||||
</html>
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
const v1 = graph.insertVertex(parent, null, 'Hello,', 30, 40, 80, 30);
|
||||||
|
// Alternative solution of creating a second label by creating a realtive child vertex
|
||||||
|
// with size (0, 0). This will not be selectable and only the label colors can be used
|
||||||
|
// for coloring as the actual shape will have zero size.
|
||||||
|
const v11 = graph.insertVertex(
|
||||||
|
v1,
|
||||||
|
null,
|
||||||
|
'World',
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'align=left;verticalAlign=top;labelBackgroundColor=red;labelBorderColor=black',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
v11.geometry.offset = new mxPoint(-8, -8);
|
||||||
|
const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
||||||
|
// Another alternative solution of creating a second label as a relative child vertex
|
||||||
|
// but this time with an automatic size so that the cell is actually selectable and
|
||||||
|
// the background is painted as a shape.
|
||||||
|
const v21 = graph.insertVertex(
|
||||||
|
v2,
|
||||||
|
null,
|
||||||
|
'World',
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'align=left;verticalAlign=top;fillColor=red;rounded=1;spacingLeft=4;spacingRight=4',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
v21.geometry.offset = new mxPoint(-8, -8);
|
||||||
|
graph.updateCellSize(v21);
|
||||||
|
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a button to execute the layout
|
||||||
|
document.body.insertBefore(
|
||||||
|
mxUtils.button('Toggle Child Vertices', function(evt) {
|
||||||
|
relativeChildVerticesVisible = !relativeChildVerticesVisible;
|
||||||
|
graph.refresh();
|
||||||
|
}),
|
||||||
|
document.body.firstChild
|
||||||
|
);
|
||||||
|
|
||||||
|
// Adds a button to execute the layout
|
||||||
|
document.body.insertBefore(
|
||||||
|
mxUtils.button('Toggle IDs', function(evt) {
|
||||||
|
secondLabelVisible = !secondLabelVisible;
|
||||||
|
graph.refresh();
|
||||||
|
}),
|
||||||
|
document.body.firstChild
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SecondLabel;
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxConstants from '../mxgraph/util/mxConstants';
|
||||||
|
import mxCylinder from '../mxgraph/shape/mxCylinder';
|
||||||
|
import mxCellRenderer from "../mxgraph/view/mxCellRenderer";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Shape extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -26,22 +27,17 @@ class MYNAMEHERE extends React.Component {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The example shape is a "3D box" that looks like this:
|
The example shape is a "3D box" that looks like this:
|
||||||
____
|
____
|
||||||
|
@ -52,134 +48,93 @@ export default MYNAMEHERE;
|
||||||
|
|
||||||
The code below defines the shape. The BoxShape function
|
The code below defines the shape. The BoxShape function
|
||||||
it the constructor which creates a new object instance.
|
it the constructor which creates a new object instance.
|
||||||
*/
|
|
||||||
function BoxShape()
|
|
||||||
{
|
|
||||||
mxCylinder.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
The next lines use an mxCylinder instance to augment the
|
The next lines use an mxCylinder instance to augment the
|
||||||
prototype of the shape ("inheritance") and reset the
|
prototype of the shape ("inheritance") and reset the
|
||||||
constructor to the topmost function of the c'tor chain.
|
constructor to the topmost function of the c'tor chain.
|
||||||
*/
|
*/
|
||||||
mxUtils.extend(BoxShape, mxCylinder);
|
|
||||||
|
|
||||||
// Defines the extrusion of the box as a "static class variable"
|
class BoxShape extends mxCylinder {
|
||||||
BoxShape.prototype.extrude = 10;
|
// Defines the extrusion of the box as a "static class variable"
|
||||||
|
extrude = 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Next, the mxCylinder's redrawPath method is "overridden".
|
Next, the mxCylinder's redrawPath method is "overridden".
|
||||||
This method has a isForeground argument to separate two
|
This method has a isForeground argument to separate two
|
||||||
paths, one for the background (which must be closed and
|
paths, one for the background (which must be closed and
|
||||||
might be filled) and one for the foreground, which is
|
might be filled) and one for the foreground, which is
|
||||||
just a stroke.
|
just a stroke.
|
||||||
|
|
||||||
Foreground: /
|
Foreground: /
|
||||||
_____/
|
_____/
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
____
|
____
|
||||||
Background: / |
|
Background: / |
|
||||||
/ |
|
/ |
|
||||||
| /
|
| /
|
||||||
|____/
|
|____/
|
||||||
*/
|
*/
|
||||||
BoxShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
|
redrawPath(path, x, y, w, h, isForeground) {
|
||||||
{
|
const dy = this.extrude * this.scale;
|
||||||
let dy = this.extrude * this.scale;
|
const dx = this.extrude * this.scale;
|
||||||
let dx = this.extrude * this.scale;
|
|
||||||
|
|
||||||
if (isForeground)
|
if (isForeground) {
|
||||||
{
|
path.moveTo(0, dy);
|
||||||
path.moveTo(0, dy);
|
path.lineTo(w - dx, dy);
|
||||||
path.lineTo(w - dx, dy);
|
path.lineTo(w, 0);
|
||||||
path.lineTo(w, 0);
|
path.moveTo(w - dx, dy);
|
||||||
path.moveTo(w - dx, dy);
|
path.lineTo(w - dx, h);
|
||||||
path.lineTo(w - dx, h);
|
} else {
|
||||||
|
path.moveTo(0, dy);
|
||||||
|
path.lineTo(dx, 0);
|
||||||
|
path.lineTo(w, 0);
|
||||||
|
path.lineTo(w, h - dy);
|
||||||
|
path.lineTo(w - dx, h);
|
||||||
|
path.lineTo(0, h);
|
||||||
|
path.lineTo(0, dy);
|
||||||
|
path.lineTo(dx, 0);
|
||||||
|
path.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
path.moveTo(0, dy);
|
|
||||||
path.lineTo(dx, 0);
|
|
||||||
path.lineTo(w, 0);
|
|
||||||
path.lineTo(w, h - dy);
|
|
||||||
path.lineTo(w - dx, h);
|
|
||||||
path.lineTo(0, h);
|
|
||||||
path.lineTo(0, dy);
|
|
||||||
path.lineTo(dx, 0);
|
|
||||||
path.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mxCellRenderer.registerShape('box', BoxShape);
|
mxCellRenderer.registerShape('box', BoxShape);
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Example code -->
|
// Creates the graph inside the DOM node.
|
||||||
<script type="text/javascript">
|
const graph = new mxGraph(this.el);
|
||||||
|
|
||||||
// Program starts here. Creates a sample graph in the
|
// Disables basic selection and cell handling
|
||||||
// DOM node with the specified ID. This function is invoked
|
graph.setEnabled(false);
|
||||||
// from the onLoad event handler of the document (see below).
|
|
||||||
function main(container)
|
|
||||||
{
|
|
||||||
// Checks if 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 DOM node.
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Disables basic selection and cell handling
|
// Changes the default style for vertices "in-place"
|
||||||
graph.setEnabled(false);
|
// to use the custom shape.
|
||||||
|
const style = graph.getStylesheet().getDefaultVertexStyle();
|
||||||
|
style[mxConstants.STYLE_SHAPE] = 'box';
|
||||||
|
|
||||||
// Changes the default style for vertices "in-place"
|
// Adds a spacing for the label that matches the
|
||||||
// to use the custom shape.
|
// extrusion size
|
||||||
let style = graph.getStylesheet().getDefaultVertexStyle();
|
style[mxConstants.STYLE_SPACING_TOP] = BoxShape.prototype.extrude;
|
||||||
style[mxConstants.STYLE_SHAPE] = 'box';
|
style[mxConstants.STYLE_SPACING_RIGHT] = BoxShape.prototype.extrude;
|
||||||
|
|
||||||
// Adds a spacing for the label that matches the
|
// Adds a gradient and shadow to improve the user experience
|
||||||
// extrusion size
|
style[mxConstants.STYLE_GRADIENTCOLOR] = '#FFFFFF';
|
||||||
style[mxConstants.STYLE_SPACING_TOP] = BoxShape.prototype.extrude;
|
style[mxConstants.STYLE_SHADOW] = true;
|
||||||
style[mxConstants.STYLE_SPACING_RIGHT] = BoxShape.prototype.extrude;
|
|
||||||
|
|
||||||
// Adds a gradient and shadow to improve the user experience
|
// Gets the default parent for inserting new cells. This
|
||||||
style[mxConstants.STYLE_GRADIENTCOLOR] = '#FFFFFF';
|
// is normally the first child of the root (ie. layer 0).
|
||||||
style[mxConstants.STYLE_SHADOW] = true;
|
const parent = graph.getDefaultParent();
|
||||||
|
|
||||||
// Gets the default parent for inserting new cells. This
|
// Adds cells to the model in a single step
|
||||||
// is normally the first child of the root (ie. layer 0).
|
graph.getModel().beginUpdate();
|
||||||
let parent = graph.getDefaultParent();
|
try {
|
||||||
|
const v1 = graph.insertVertex(parent, null, 'Custom', 20, 20, 80, 60);
|
||||||
|
const v2 = graph.insertVertex(parent, null, 'Shape', 200, 150, 80, 60);
|
||||||
|
const e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
export default Shape;
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Custom', 20, 20, 80, 60);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'Shape', 200, 150, 80, 60);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif')">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2006-2013, JGraph Ltd
|
|
||||||
|
|
||||||
Standardsmode example for mxGraph. This example demonstrates using a DOCTYPE with
|
|
||||||
mxGraph. (The first line is required for this to use VML in all IE versions.)
|
|
||||||
|
|
||||||
To use the DOCTYPE and SVG in IE9, replace the content attribute of the first line
|
|
||||||
with IE=5,IE=9.
|
|
||||||
|
|
||||||
To use IE7 standards mode in IE 7,8 and 9, replace IE=5 with IE=7.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// A container for the graph
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>Standardsmode example for mxGraph</h1>
|
|
||||||
|
|
||||||
<div
|
|
||||||
ref={el => {
|
|
||||||
this.el = el;
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// 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).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prints the rendering mode and display dialect (VML or SVG) in use
|
|
||||||
// CSS1Compat means standard
|
|
||||||
mxLog.show();
|
|
||||||
let mode = (document.compatMode == 'CSS1Compat') ? 'standards' : 'quirks';
|
|
||||||
let disp = (mxClient.IS_SVG) ? 'svg' : 'vml';
|
|
||||||
mxLog.debug(mode + ' ' + disp);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif');cursor:default;position:relative;">
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
See also:<br>
|
|
||||||
<a href="ie9svg.html">IE9SVG</a><br>
|
|
||||||
<a href="../../docs/known-issues.html#Doctypes">docs/known-issues.html#Doctypes</a><br>
|
|
||||||
<a href="../../docs/known-issues.html#IE9">docs/known-issues.html#IE9</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -10,8 +10,19 @@ import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
import mxEvent from '../mxgraph/util/mxEvent';
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxUtils from "../mxgraph/util/mxUtils";
|
||||||
|
import mxConstants from "../mxgraph/util/mxConstants";
|
||||||
|
import mxPoint from "../mxgraph/util/mxPoint";
|
||||||
|
import mxStencilRegistry from "../mxgraph/shape/mxStencilRegistry";
|
||||||
|
import mxCellRenderer from "../mxgraph/view/mxCellRenderer";
|
||||||
|
import mxShape from "../mxgraph/shape/mxShape";
|
||||||
|
import mxVertexHandler from "../mxgraph/handler/mxVertexHandler";
|
||||||
|
import mxCellHighlight from "../mxgraph/handler/mxCellHighlight";
|
||||||
|
import mxEdgeHandler from "../mxgraph/handler/mxEdgeHandler";
|
||||||
|
import mxConnectionHandler from "../mxgraph/handler/mxConnectionHandler";
|
||||||
|
import mxStencil from "../mxgraph/shape/mxStencil";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Stencils extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -21,332 +32,372 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Stencils example for mxGraph</h1>
|
<h1>Stencils example for mxGraph</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '601px',
|
||||||
|
height: '401px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
|
cursor: 'default',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
ref={el => {
|
||||||
|
this.el2 = el;
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '601px',
|
||||||
|
height: '150px',
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Sets the global shadow color
|
||||||
|
mxConstants.SHADOWCOLOR = '#C0C0C0';
|
||||||
|
mxConstants.SHADOW_OPACITY = 0.5;
|
||||||
|
mxConstants.SHADOW_OFFSET_X = 4;
|
||||||
|
mxConstants.SHADOW_OFFSET_Y = 4;
|
||||||
|
mxConstants.HANDLE_FILLCOLOR = '#99ccff';
|
||||||
|
mxConstants.HANDLE_STROKECOLOR = '#0088cf';
|
||||||
|
mxConstants.VERTEX_SELECTION_COLOR = '#00a8ff';
|
||||||
|
|
||||||
};
|
// Enables connections along the outline
|
||||||
|
mxConnectionHandler.prototype.outlineConnect = true;
|
||||||
|
mxEdgeHandler.prototype.manageLabelHandle = true;
|
||||||
|
mxEdgeHandler.prototype.outlineConnect = true;
|
||||||
|
mxCellHighlight.prototype.keepOnTop = true;
|
||||||
|
|
||||||
|
// Enable rotation handle
|
||||||
|
mxVertexHandler.prototype.rotationEnabled = true;
|
||||||
|
|
||||||
|
// Uses the shape for resize previews
|
||||||
|
mxVertexHandler.prototype.createSelectionShape = function(bounds) {
|
||||||
|
const key = this.state.style[mxConstants.STYLE_SHAPE];
|
||||||
|
const stencil = mxStencilRegistry.getStencil(key);
|
||||||
|
let shape = null;
|
||||||
|
|
||||||
|
if (stencil != null) {
|
||||||
|
shape = new mxShape(stencil);
|
||||||
|
shape.apply(this.state);
|
||||||
|
} else {
|
||||||
|
shape = new this.state.shape.constructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
shape.outline = true;
|
||||||
|
shape.bounds = bounds;
|
||||||
|
shape.stroke = mxConstants.HANDLE_STROKECOLOR;
|
||||||
|
shape.strokewidth = this.getSelectionStrokeWidth();
|
||||||
|
shape.isDashed = this.isSelectionDashed();
|
||||||
|
shape.isShadow = false;
|
||||||
|
|
||||||
|
return shape;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Defines a custom stencil via the canvas API as defined here:
|
||||||
|
// http://jgraph.github.io/mxgraph/docs/js-api/files/util/mxXmlCanvas2D-js.html
|
||||||
|
|
||||||
|
class CustomShape extends mxShape {
|
||||||
|
paintBackground(c, x, y, w, h) {
|
||||||
|
c.translate(x, y);
|
||||||
|
|
||||||
|
// Head
|
||||||
|
c.ellipse(w / 4, 0, w / 2, h / 4);
|
||||||
|
c.fillAndStroke();
|
||||||
|
|
||||||
|
c.begin();
|
||||||
|
c.moveTo(w / 2, h / 4);
|
||||||
|
c.lineTo(w / 2, (2 * h) / 3);
|
||||||
|
|
||||||
|
// Arms
|
||||||
|
c.moveTo(w / 2, h / 3);
|
||||||
|
c.lineTo(0, h / 3);
|
||||||
|
c.moveTo(w / 2, h / 3);
|
||||||
|
c.lineTo(w, h / 3);
|
||||||
|
|
||||||
|
// Legs
|
||||||
|
c.moveTo(w / 2, (2 * h) / 3);
|
||||||
|
c.lineTo(0, h);
|
||||||
|
c.moveTo(w / 2, (2 * h) / 3);
|
||||||
|
c.lineTo(w, h);
|
||||||
|
c.end();
|
||||||
|
|
||||||
|
c.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replaces existing actor shape
|
||||||
|
mxCellRenderer.registerShape('customShape', CustomShape);
|
||||||
|
|
||||||
|
// Loads the stencils into the registry
|
||||||
|
const req = mxUtils.load('stencils.xml');
|
||||||
|
const root = req.getDocumentElement();
|
||||||
|
let shape = root.firstChild;
|
||||||
|
|
||||||
|
while (shape != null) {
|
||||||
|
if (shape.nodeType === mxConstants.NODETYPE_ELEMENT) {
|
||||||
|
mxStencilRegistry.addStencil(
|
||||||
|
shape.getAttribute('name'),
|
||||||
|
new mxStencil(shape)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape = shape.nextSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
mxEvent.disableContextMenu(this.el);
|
||||||
|
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
graph.setConnectable(true);
|
||||||
|
graph.setTooltips(true);
|
||||||
|
graph.setPanning(true);
|
||||||
|
|
||||||
|
graph.getTooltipForCell = function(cell) {
|
||||||
|
if (cell != null) {
|
||||||
|
return cell.style;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Changes default styles
|
||||||
|
let style = graph.getStylesheet().getDefaultEdgeStyle();
|
||||||
|
style[mxConstants.STYLE_EDGE] = 'orthogonalEdgeStyle';
|
||||||
|
style = graph.getStylesheet().getDefaultVertexStyle();
|
||||||
|
style[mxConstants.STYLE_FILLCOLOR] = '#adc5ff';
|
||||||
|
style[mxConstants.STYLE_GRADIENTCOLOR] = '#7d85df';
|
||||||
|
style[mxConstants.STYLE_SHADOW] = '1';
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
'A1',
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
80,
|
||||||
|
'shape=and'
|
||||||
|
);
|
||||||
|
const v2 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'A2',
|
||||||
|
20,
|
||||||
|
220,
|
||||||
|
40,
|
||||||
|
80,
|
||||||
|
'shape=and'
|
||||||
|
);
|
||||||
|
const v3 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'X1',
|
||||||
|
160,
|
||||||
|
110,
|
||||||
|
80,
|
||||||
|
80,
|
||||||
|
'shape=xor'
|
||||||
|
);
|
||||||
|
const e1 = graph.insertEdge(parent, null, '', v1, v3);
|
||||||
|
e1.geometry.points = [new mxPoint(90, 60), new mxPoint(90, 130)];
|
||||||
|
const e2 = graph.insertEdge(parent, null, '', v2, v3);
|
||||||
|
e2.geometry.points = [new mxPoint(90, 260), new mxPoint(90, 170)];
|
||||||
|
|
||||||
|
const v4 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'A3',
|
||||||
|
520,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
80,
|
||||||
|
'shape=customShape;flipH=1'
|
||||||
|
);
|
||||||
|
const v5 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'A4',
|
||||||
|
520,
|
||||||
|
220,
|
||||||
|
40,
|
||||||
|
80,
|
||||||
|
'shape=and;flipH=1'
|
||||||
|
);
|
||||||
|
const v6 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'X2',
|
||||||
|
340,
|
||||||
|
110,
|
||||||
|
80,
|
||||||
|
80,
|
||||||
|
'shape=xor;flipH=1'
|
||||||
|
);
|
||||||
|
const e3 = graph.insertEdge(parent, null, '', v4, v6);
|
||||||
|
e3.geometry.points = [new mxPoint(490, 60), new mxPoint(130, 130)];
|
||||||
|
const e4 = graph.insertEdge(parent, null, '', v5, v6);
|
||||||
|
e4.geometry.points = [new mxPoint(490, 260), new mxPoint(130, 170)];
|
||||||
|
|
||||||
|
const v7 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'O1',
|
||||||
|
250,
|
||||||
|
260,
|
||||||
|
80,
|
||||||
|
60,
|
||||||
|
'shape=or;direction=south'
|
||||||
|
);
|
||||||
|
const e5 = graph.insertEdge(parent, null, '', v6, v7);
|
||||||
|
e5.geometry.points = [new mxPoint(310, 150)];
|
||||||
|
const e6 = graph.insertEdge(parent, null, '', v3, v7);
|
||||||
|
e6.geometry.points = [new mxPoint(270, 150)];
|
||||||
|
|
||||||
|
const e7 = graph.insertEdge(parent, null, '', v7, v5);
|
||||||
|
e7.geometry.points = [new mxPoint(290, 370)];
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('FlipH', function() {
|
||||||
|
graph.toggleCellStyles(mxConstants.STYLE_FLIPH);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('FlipV', function() {
|
||||||
|
graph.toggleCellStyles(mxConstants.STYLE_FLIPV);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('Rotate', function() {
|
||||||
|
const cell = graph.getSelectionCell();
|
||||||
|
|
||||||
|
if (cell != null) {
|
||||||
|
let geo = graph.getCellGeometry(cell);
|
||||||
|
|
||||||
|
if (geo != null) {
|
||||||
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
// Rotates the size and position in the geometry
|
||||||
|
geo = geo.clone();
|
||||||
|
geo.x += geo.width / 2 - geo.height / 2;
|
||||||
|
geo.y += geo.height / 2 - geo.width / 2;
|
||||||
|
const tmp = geo.width;
|
||||||
|
geo.width = geo.height;
|
||||||
|
geo.height = tmp;
|
||||||
|
graph.getModel().setGeometry(cell, geo);
|
||||||
|
|
||||||
|
// Reads the current direction and advances by 90 degrees
|
||||||
|
const state = graph.view.getState(cell);
|
||||||
|
|
||||||
|
if (state != null) {
|
||||||
|
let dir =
|
||||||
|
state.style[mxConstants.STYLE_DIRECTION] ||
|
||||||
|
'east'; /* default */
|
||||||
|
|
||||||
|
if (dir === 'east') {
|
||||||
|
dir = 'south';
|
||||||
|
} else if (dir === 'south') {
|
||||||
|
dir = 'west';
|
||||||
|
} else if (dir === 'west') {
|
||||||
|
dir = 'north';
|
||||||
|
} else if (dir === 'north') {
|
||||||
|
dir = 'east';
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.setCellStyles(mxConstants.STYLE_DIRECTION, dir, [cell]);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('And', function() {
|
||||||
|
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'and');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('Or', function() {
|
||||||
|
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'or');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('Xor', function() {
|
||||||
|
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'xor');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
this.el2.appendChild(document.createTextNode('\u00a0'));
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('Style', function() {
|
||||||
|
const cell = graph.getSelectionCell();
|
||||||
|
|
||||||
|
if (cell != null) {
|
||||||
|
const style = mxUtils.prompt(
|
||||||
|
'Style',
|
||||||
|
graph.getModel().getStyle(cell)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (style != null) {
|
||||||
|
graph.getModel().setStyle(cell, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('+', function() {
|
||||||
|
graph.zoomIn();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.el2.appendChild(
|
||||||
|
mxUtils.button('-', function() {
|
||||||
|
graph.zoomOut();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Stencils;
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// Sets the global shadow color
|
|
||||||
mxConstants.SHADOWCOLOR = '#C0C0C0';
|
|
||||||
mxConstants.SHADOW_OPACITY = 0.5;
|
|
||||||
mxConstants.SHADOW_OFFSET_X = 4;
|
|
||||||
mxConstants.SHADOW_OFFSET_Y = 4;
|
|
||||||
mxConstants.HANDLE_FILLCOLOR = '#99ccff';
|
|
||||||
mxConstants.HANDLE_STROKECOLOR = '#0088cf';
|
|
||||||
mxConstants.VERTEX_SELECTION_COLOR = '#00a8ff';
|
|
||||||
|
|
||||||
// Enables connections along the outline
|
|
||||||
mxConnectionHandler.prototype.outlineConnect = true;
|
|
||||||
mxEdgeHandler.prototype.manageLabelHandle = true;
|
|
||||||
mxEdgeHandler.prototype.outlineConnect = true;
|
|
||||||
mxCellHighlight.prototype.keepOnTop = true;
|
|
||||||
|
|
||||||
// Enable rotation handle
|
|
||||||
mxVertexHandler.prototype.rotationEnabled = true;
|
|
||||||
|
|
||||||
// Uses the shape for resize previews
|
|
||||||
mxVertexHandler.prototype.createSelectionShape = function(bounds)
|
|
||||||
{
|
|
||||||
let key = this.state.style[mxConstants.STYLE_SHAPE];
|
|
||||||
let stencil = mxStencilRegistry.getStencil(key);
|
|
||||||
let shape = null;
|
|
||||||
|
|
||||||
if (stencil != null)
|
|
||||||
{
|
|
||||||
shape = new mxShape(stencil);
|
|
||||||
shape.apply(this.state);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shape = new this.state.shape.constructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
shape.outline = true;
|
|
||||||
shape.bounds = bounds;
|
|
||||||
shape.stroke = mxConstants.HANDLE_STROKECOLOR;
|
|
||||||
shape.strokewidth = this.getSelectionStrokeWidth();
|
|
||||||
shape.isDashed = this.isSelectionDashed();
|
|
||||||
shape.isShadow = false;
|
|
||||||
|
|
||||||
return shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defines a custom stencil via the canvas API as defined here:
|
|
||||||
// http://jgraph.github.io/mxgraph/docs/js-api/files/util/mxXmlCanvas2D-js.html
|
|
||||||
function CustomShape()
|
|
||||||
{
|
|
||||||
mxShape.call(this);
|
|
||||||
};
|
|
||||||
mxUtils.extend(CustomShape, mxShape);
|
|
||||||
CustomShape.prototype.paintBackground = function(c, x, y, w, h)
|
|
||||||
{
|
|
||||||
c.translate(x, y);
|
|
||||||
|
|
||||||
// Head
|
|
||||||
c.ellipse(w / 4, 0, w / 2, h / 4);
|
|
||||||
c.fillAndStroke();
|
|
||||||
|
|
||||||
c.begin();
|
|
||||||
c.moveTo(w / 2, h / 4);
|
|
||||||
c.lineTo(w / 2, 2 * h / 3);
|
|
||||||
|
|
||||||
// Arms
|
|
||||||
c.moveTo(w / 2, h / 3);
|
|
||||||
c.lineTo(0, h / 3);
|
|
||||||
c.moveTo(w / 2, h / 3);
|
|
||||||
c.lineTo(w, h / 3);
|
|
||||||
|
|
||||||
// Legs
|
|
||||||
c.moveTo(w / 2, 2 * h / 3);
|
|
||||||
c.lineTo(0, h);
|
|
||||||
c.moveTo(w / 2, 2 * h / 3);
|
|
||||||
c.lineTo(w, h);
|
|
||||||
c.end();
|
|
||||||
|
|
||||||
c.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Replaces existing actor shape
|
|
||||||
mxCellRenderer.registerShape('customShape', CustomShape);
|
|
||||||
|
|
||||||
// Loads the stencils into the registry
|
|
||||||
let req = mxUtils.load('stencils.xml');
|
|
||||||
let root = req.getDocumentElement();
|
|
||||||
let shape = root.firstChild;
|
|
||||||
|
|
||||||
while (shape != null)
|
|
||||||
{
|
|
||||||
if (shape.nodeType == mxConstants.NODETYPE_ELEMENT)
|
|
||||||
{
|
|
||||||
mxStencilRegistry.addStencil(shape.getAttribute('name'), new mxStencil(shape));
|
|
||||||
}
|
|
||||||
|
|
||||||
shape = shape.nextSibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxEvent.disableContextMenu(container);
|
|
||||||
|
|
||||||
// Creates the graph inside the given container
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
graph.setConnectable(true);
|
|
||||||
graph.setTooltips(true);
|
|
||||||
graph.setPanning(true);
|
|
||||||
|
|
||||||
graph.getTooltipForCell = function(cell)
|
|
||||||
{
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
return cell.style;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Changes default styles
|
|
||||||
let style = graph.getStylesheet().getDefaultEdgeStyle();
|
|
||||||
style[mxConstants.STYLE_EDGE] = 'orthogonalEdgeStyle';
|
|
||||||
style = graph.getStylesheet().getDefaultVertexStyle();
|
|
||||||
style[mxConstants.STYLE_FILLCOLOR] = '#adc5ff';
|
|
||||||
style[mxConstants.STYLE_GRADIENTCOLOR] = '#7d85df';
|
|
||||||
style[mxConstants.STYLE_SHADOW] = '1';
|
|
||||||
|
|
||||||
// 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).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'A1', 20, 20, 40, 80, 'shape=and');
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'A2', 20, 220, 40, 80, 'shape=and');
|
|
||||||
var v3 = graph.insertVertex(parent, null, 'X1', 160, 110, 80, 80, 'shape=xor');
|
|
||||||
var e1 = graph.insertEdge(parent, null, '', v1, v3);
|
|
||||||
e1.geometry.points = [new mxPoint(90, 60), new mxPoint(90, 130)];
|
|
||||||
var e2 = graph.insertEdge(parent, null, '', v2, v3);
|
|
||||||
e2.geometry.points = [new mxPoint(90, 260), new mxPoint(90, 170)];
|
|
||||||
|
|
||||||
var v4 = graph.insertVertex(parent, null, 'A3', 520, 20, 40, 80, 'shape=customShape;flipH=1');
|
|
||||||
var v5 = graph.insertVertex(parent, null, 'A4', 520, 220, 40, 80, 'shape=and;flipH=1');
|
|
||||||
var v6 = graph.insertVertex(parent, null, 'X2', 340, 110, 80, 80, 'shape=xor;flipH=1');
|
|
||||||
var e3 = graph.insertEdge(parent, null, '', v4, v6);
|
|
||||||
e3.geometry.points = [new mxPoint(490, 60), new mxPoint(130, 130)];
|
|
||||||
var e4 = graph.insertEdge(parent, null, '', v5, v6);
|
|
||||||
e4.geometry.points = [new mxPoint(490, 260), new mxPoint(130, 170)];
|
|
||||||
|
|
||||||
var v7 = graph.insertVertex(parent, null, 'O1', 250, 260, 80, 60, 'shape=or;direction=south');
|
|
||||||
var e5 = graph.insertEdge(parent, null, '', v6, v7);
|
|
||||||
e5.geometry.points = [new mxPoint(310, 150)];
|
|
||||||
var e6 = graph.insertEdge(parent, null, '', v3, v7);
|
|
||||||
e6.geometry.points = [new mxPoint(270, 150)];
|
|
||||||
|
|
||||||
var e7 = graph.insertEdge(parent, null, '', v7, v5);
|
|
||||||
e7.geometry.points = [new mxPoint(290, 370)];
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('FlipH', function()
|
|
||||||
{
|
|
||||||
graph.toggleCellStyles(mxConstants.STYLE_FLIPH);
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('FlipV', function()
|
|
||||||
{
|
|
||||||
graph.toggleCellStyles(mxConstants.STYLE_FLIPV);
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('Rotate', function()
|
|
||||||
{
|
|
||||||
let cell = graph.getSelectionCell();
|
|
||||||
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
let geo = graph.getCellGeometry(cell);
|
|
||||||
|
|
||||||
if (geo != null)
|
|
||||||
{
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Rotates the size and position in the geometry
|
|
||||||
geo = geo.clone();
|
|
||||||
geo.x += geo.width / 2 - geo.height / 2;
|
|
||||||
geo.y += geo.height / 2 - geo.width / 2;
|
|
||||||
let tmp = geo.width;
|
|
||||||
geo.width = geo.height;
|
|
||||||
geo.height = tmp;
|
|
||||||
graph.getModel().setGeometry(cell, geo);
|
|
||||||
|
|
||||||
// Reads the current direction and advances by 90 degrees
|
|
||||||
let state = graph.view.getState(cell);
|
|
||||||
|
|
||||||
if (state != null)
|
|
||||||
{
|
|
||||||
let dir = state.style[mxConstants.STYLE_DIRECTION] || 'east'/*default*/;
|
|
||||||
|
|
||||||
if (dir == 'east')
|
|
||||||
{
|
|
||||||
dir = 'south';
|
|
||||||
}
|
|
||||||
else if (dir == 'south')
|
|
||||||
{
|
|
||||||
dir = 'west';
|
|
||||||
}
|
|
||||||
else if (dir == 'west')
|
|
||||||
{
|
|
||||||
dir = 'north';
|
|
||||||
}
|
|
||||||
else if (dir == 'north')
|
|
||||||
{
|
|
||||||
dir = 'east';
|
|
||||||
}
|
|
||||||
|
|
||||||
graph.setCellStyles(mxConstants.STYLE_DIRECTION, dir, [cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('And', function()
|
|
||||||
{
|
|
||||||
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'and');
|
|
||||||
}));
|
|
||||||
document.body.appendChild(mxUtils.button('Or', function()
|
|
||||||
{
|
|
||||||
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'or');
|
|
||||||
}));
|
|
||||||
document.body.appendChild(mxUtils.button('Xor', function()
|
|
||||||
{
|
|
||||||
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'xor');
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
document.body.appendChild(document.createTextNode('\u00a0'));
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('Style', function()
|
|
||||||
{
|
|
||||||
let cell = graph.getSelectionCell();
|
|
||||||
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
let style = mxUtils.prompt('Style', graph.getModel().getStyle(cell));
|
|
||||||
|
|
||||||
if (style != null)
|
|
||||||
{
|
|
||||||
graph.getModel().setStyle(cell, style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.body.appendChild(mxUtils.button('+', function()
|
|
||||||
{
|
|
||||||
graph.zoomIn();
|
|
||||||
}));
|
|
||||||
document.body.appendChild(mxUtils.button('-', function()
|
|
||||||
{
|
|
||||||
graph.zoomOut();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="position:relative;overflow:hidden;width:601px;height:401px;background:url('editors/images/grid.gif');cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxConstants from '../mxgraph/util/mxConstants';
|
||||||
|
import mxEdgeStyle from '../mxgraph/view/mxEdgeStyle';
|
||||||
|
import mxPerimeter from "../mxgraph/view/mxPerimeter";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Stylesheet extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -22,146 +23,148 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Stylesheet example for mxGraph</h1>
|
<h1>Stylesheet example for mxGraph</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
position: 'relative',
|
||||||
|
width: '621px',
|
||||||
|
height: '311px',
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Creates the graph inside the DOM node.
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
|
||||||
};
|
// Disables basic selection and cell handling
|
||||||
|
graph.setEnabled(false);
|
||||||
|
|
||||||
|
// Returns a special label for edges. Note: This does
|
||||||
|
// a supercall to use the default implementation.
|
||||||
|
graph.getLabel = function(cell) {
|
||||||
|
const label = mxGraph.prototype.getLabel.apply(this, arguments);
|
||||||
|
|
||||||
|
if (this.getModel().isEdge(cell)) {
|
||||||
|
return `Transfer ${label}`;
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Installs a custom global tooltip
|
||||||
|
graph.setTooltips(true);
|
||||||
|
graph.getTooltip = function(state) {
|
||||||
|
const { cell } = state;
|
||||||
|
const model = this.getModel();
|
||||||
|
|
||||||
|
if (model.isEdge(cell)) {
|
||||||
|
const source = this.getLabel(model.getTerminal(cell, true));
|
||||||
|
const target = this.getLabel(model.getTerminal(cell, false));
|
||||||
|
|
||||||
|
return `${source} -> ${target}`;
|
||||||
|
}
|
||||||
|
return this.getLabel(cell);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the default style for vertices
|
||||||
|
let style = [];
|
||||||
|
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
|
||||||
|
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
|
||||||
|
style[mxConstants.STYLE_STROKECOLOR] = 'gray';
|
||||||
|
style[mxConstants.STYLE_ROUNDED] = true;
|
||||||
|
style[mxConstants.STYLE_FILLCOLOR] = '#EEEEEE';
|
||||||
|
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
|
||||||
|
style[mxConstants.STYLE_FONTCOLOR] = '#774400';
|
||||||
|
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
|
||||||
|
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
|
||||||
|
style[mxConstants.STYLE_FONTSIZE] = '12';
|
||||||
|
style[mxConstants.STYLE_FONTSTYLE] = 1;
|
||||||
|
graph.getStylesheet().putDefaultVertexStyle(style);
|
||||||
|
|
||||||
|
// Creates the default style for edges
|
||||||
|
style = [];
|
||||||
|
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
|
||||||
|
style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
|
||||||
|
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
|
||||||
|
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
|
||||||
|
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
|
||||||
|
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
|
||||||
|
style[mxConstants.STYLE_FONTSIZE] = '10';
|
||||||
|
graph.getStylesheet().putDefaultEdgeStyle(style);
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
'Interval 1',
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
180,
|
||||||
|
30
|
||||||
|
);
|
||||||
|
const v2 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Interval 2',
|
||||||
|
140,
|
||||||
|
80,
|
||||||
|
280,
|
||||||
|
30
|
||||||
|
);
|
||||||
|
const v3 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Interval 3',
|
||||||
|
200,
|
||||||
|
140,
|
||||||
|
360,
|
||||||
|
30
|
||||||
|
);
|
||||||
|
const v4 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Interval 4',
|
||||||
|
480,
|
||||||
|
200,
|
||||||
|
120,
|
||||||
|
30
|
||||||
|
);
|
||||||
|
const v5 = graph.insertVertex(
|
||||||
|
parent,
|
||||||
|
null,
|
||||||
|
'Interval 5',
|
||||||
|
60,
|
||||||
|
260,
|
||||||
|
400,
|
||||||
|
30
|
||||||
|
);
|
||||||
|
const e1 = graph.insertEdge(parent, null, '1', v1, v2);
|
||||||
|
e1.getGeometry().points = [{ x: 160, y: 60 }];
|
||||||
|
const e2 = graph.insertEdge(parent, null, '2', v1, v5);
|
||||||
|
e2.getGeometry().points = [{ x: 80, y: 60 }];
|
||||||
|
const e3 = graph.insertEdge(parent, null, '3', v2, v3);
|
||||||
|
e3.getGeometry().points = [{ x: 280, y: 120 }];
|
||||||
|
const e4 = graph.insertEdge(parent, null, '4', v3, v4);
|
||||||
|
e4.getGeometry().points = [{ x: 500, y: 180 }];
|
||||||
|
const e5 = graph.insertEdge(parent, null, '5', v3, v5);
|
||||||
|
e5.getGeometry().points = [{ x: 380, y: 180 }];
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Stylesheet;
|
||||||
|
|
||||||
|
|
||||||
function main(container)
|
|
||||||
{
|
|
||||||
// Checks if 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 DOM node.
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Disables basic selection and cell handling
|
|
||||||
graph.setEnabled(false);
|
|
||||||
|
|
||||||
// Returns a special label for edges. Note: This does
|
|
||||||
// a supercall to use the default implementation.
|
|
||||||
graph.getLabel = function(cell)
|
|
||||||
{
|
|
||||||
let label = mxGraph.prototype.getLabel.apply(this, arguments);
|
|
||||||
|
|
||||||
if (this.getModel().isEdge(cell))
|
|
||||||
{
|
|
||||||
return 'Transfer '+label;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Installs a custom global tooltip
|
|
||||||
graph.setTooltips(true);
|
|
||||||
graph.getTooltip = function(state)
|
|
||||||
{
|
|
||||||
let cell = state.cell;
|
|
||||||
let model = this.getModel();
|
|
||||||
|
|
||||||
if (model.isEdge(cell))
|
|
||||||
{
|
|
||||||
let source = this.getLabel(model.getTerminal(cell, true));
|
|
||||||
let target = this.getLabel(model.getTerminal(cell, false));
|
|
||||||
|
|
||||||
return source+' -> '+target;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.getLabel(cell);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Creates the default style for vertices
|
|
||||||
let style = [];
|
|
||||||
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
|
|
||||||
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
|
|
||||||
style[mxConstants.STYLE_STROKECOLOR] = 'gray';
|
|
||||||
style[mxConstants.STYLE_ROUNDED] = true;
|
|
||||||
style[mxConstants.STYLE_FILLCOLOR] = '#EEEEEE';
|
|
||||||
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
|
|
||||||
style[mxConstants.STYLE_FONTCOLOR] = '#774400';
|
|
||||||
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
|
|
||||||
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
|
|
||||||
style[mxConstants.STYLE_FONTSIZE] = '12';
|
|
||||||
style[mxConstants.STYLE_FONTSTYLE] = 1;
|
|
||||||
graph.getStylesheet().putDefaultVertexStyle(style);
|
|
||||||
|
|
||||||
// Creates the default style for edges
|
|
||||||
style = [];
|
|
||||||
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
|
|
||||||
style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
|
|
||||||
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
|
|
||||||
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
|
|
||||||
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
|
|
||||||
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
|
|
||||||
style[mxConstants.STYLE_FONTSIZE] = '10';
|
|
||||||
graph.getStylesheet().putDefaultEdgeStyle(style);
|
|
||||||
|
|
||||||
// Gets the default parent for inserting new cells. This
|
|
||||||
// is normally the first child of the root (ie. layer 0).
|
|
||||||
let parent = graph.getDefaultParent();
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var v1 = graph.insertVertex(parent, null, 'Interval 1', 20, 20, 180, 30);
|
|
||||||
var v2 = graph.insertVertex(parent, null, 'Interval 2', 140, 80, 280, 30);
|
|
||||||
var v3 = graph.insertVertex(parent, null, 'Interval 3', 200, 140, 360, 30);
|
|
||||||
var v4 = graph.insertVertex(parent, null, 'Interval 4', 480, 200, 120, 30);
|
|
||||||
var v5 = graph.insertVertex(parent, null, 'Interval 5', 60, 260, 400, 30);
|
|
||||||
var e1 = graph.insertEdge(parent, null, '1', v1, v2);
|
|
||||||
e1.getGeometry().points = [{x: 160, y: 60}];
|
|
||||||
var e2 = graph.insertEdge(parent, null, '2', v1, v5);
|
|
||||||
e2.getGeometry().points = [{x: 80, y: 60}];
|
|
||||||
var e3 = graph.insertEdge(parent, null, '3', v2, v3);
|
|
||||||
e3.getGeometry().points = [{x: 280, y: 120}];
|
|
||||||
var e4 = graph.insertEdge(parent, null, '4', v3, v4);
|
|
||||||
e4.getGeometry().points = [{x: 500, y: 180}];
|
|
||||||
var e5 = graph.insertEdge(parent, null, '5', v3, v5);
|
|
||||||
e5.getGeometry().points = [{x: 380, y: 180}];
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;position:relative;width:621px;height:311px;cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxUtils from "../mxgraph/util/mxUtils";
|
||||||
|
import mxCodec from "../mxgraph/io/mxCodec";
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Template extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -23,13 +24,17 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Hello, World!</h1>
|
<h1>Hello, World!</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
position: 'relative',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('/mxgraph/javascript/examples/editors/images/grid.gif')",
|
||||||
|
cursor: 'default'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -37,42 +42,19 @@ class MYNAMEHERE extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
let graph = new mxGraph(this.el);
|
||||||
|
|
||||||
|
// Adds rubberband selection to the graph
|
||||||
|
new mxRubberband(graph);
|
||||||
|
|
||||||
|
let doc = mxUtils.parseXml(xml);
|
||||||
|
let codec = new mxCodec(doc);
|
||||||
|
codec.decode(doc.documentElement, graph.getModel());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Template;
|
||||||
|
|
||||||
|
|
||||||
function main(container, xml)
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Adds rubberband selection to the graph
|
|
||||||
new mxRubberband(graph);
|
|
||||||
|
|
||||||
let doc = mxUtils.parseXml(xml);
|
|
||||||
let codec = new mxCodec(doc);
|
|
||||||
codec.decode(doc.documentElement, graph.getModel());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
|
||||||
<body onload="main(document.getElementById('graphContainer'), '%graph%');">
|
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
|
||||||
<div id="graphContainer" style="overflow:hidden;position:relative;width:321px;height:241px;background:url('/mxgraph/javascript/examples/editors/images/grid.gif');cursor:default;">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Thread extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -20,93 +18,62 @@ class MYNAMEHERE extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Thread example for mxGraph</h1>
|
<h1>Thread example for mxGraph</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={el => {
|
ref={el => {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '321px',
|
||||||
|
height: '241px',
|
||||||
|
background: "url('editors/images/grid.gif')",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Creates the graph inside the given container
|
||||||
|
const graph = new mxGraph(this.el);
|
||||||
|
|
||||||
};
|
// Disables basic selection and cell handling
|
||||||
}
|
graph.setEnabled(false);
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
// Gets the default parent for inserting new cells. This
|
||||||
|
// is normally the first child of the root (ie. layer 0).
|
||||||
|
const parent = graph.getDefaultParent();
|
||||||
|
let v1;
|
||||||
|
let v2;
|
||||||
|
let e1;
|
||||||
|
|
||||||
|
// Adds cells to the model in a single step
|
||||||
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
||||||
|
v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
||||||
|
e1 = graph.insertEdge(parent, null, '', v1, v2);
|
||||||
|
} finally {
|
||||||
|
// Updates the display
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
function main(container)
|
// Function to switch the overlay every 5 secs
|
||||||
{
|
const f = () => {
|
||||||
// Checks if browser is supported
|
const overlays = graph.getCellOverlays(v1);
|
||||||
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
|
|
||||||
let graph = new mxGraph(container);
|
|
||||||
|
|
||||||
// Disables basic selection and cell handling
|
if (overlays == null) {
|
||||||
graph.setEnabled(false);
|
graph.removeCellOverlays(v2);
|
||||||
|
graph.setCellWarning(v1, 'Tooltip');
|
||||||
// Gets the default parent for inserting new cells. This
|
} else {
|
||||||
// is normally the first child of the root (ie. layer 0).
|
graph.removeCellOverlays(v1);
|
||||||
let parent = graph.getDefaultParent();
|
graph.setCellWarning(v2, 'Tooltip');
|
||||||
var v1, v2, e1;
|
|
||||||
|
|
||||||
// Adds cells to the model in a single step
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
|
|
||||||
v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
|
|
||||||
e1 = graph.insertEdge(parent, null, '', v1, v2);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Updates the display
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to switch the overlay every 5 secs
|
|
||||||
let f = function()
|
|
||||||
{
|
|
||||||
let overlays = graph.getCellOverlays(v1);
|
|
||||||
|
|
||||||
if (overlays == null)
|
|
||||||
{
|
|
||||||
graph.removeCellOverlays(v2);
|
|
||||||
graph.setCellWarning(v1, 'Tooltip');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
graph.removeCellOverlays(v1);
|
|
||||||
graph.setCellWarning(v2, 'Tooltip');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.setInterval(f, 1000);
|
|
||||||
f();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Page passes the container for the graph to the program -->
|
window.setInterval(f, 1000);
|
||||||
<body onload="main(document.getElementById('graphContainer'))">
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Creates a container for the graph with a grid wallpaper -->
|
export default Thread;
|
||||||
<div id="graphContainer"
|
|
||||||
style="overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif')">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -6,11 +6,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mxEvent from '../mxgraph/util/mxEvent';
|
|
||||||
import mxGraph from '../mxgraph/view/mxGraph';
|
import mxGraph from '../mxgraph/view/mxGraph';
|
||||||
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
import mxRubberband from '../mxgraph/handler/mxRubberband';
|
||||||
|
import mxUtils from '../mxgraph/util/mxUtils';
|
||||||
|
import mxDragSource from '../mxgraph/util/mxDragSource';
|
||||||
|
import mxGraphModel from '../mxgraph/model/mxGraphModel';
|
||||||
|
import mxToolbar from '../mxgraph/util/mxToolbar';
|
||||||
|
import mxConnectionHandler from '../mxgraph/handler/mxConnectionHandler';
|
||||||
|
import mxImage from '../mxgraph/util/mxImage';
|
||||||
|
import mxGeometry from '../mxgraph/model/mxGeometry';
|
||||||
|
import mxCell from '../mxgraph/model/mxCell';
|
||||||
|
import mxKeyHandler from '../mxgraph/handler/mxKeyHandler';
|
||||||
|
|
||||||
class MYNAMEHERE extends React.Component {
|
class Toolbar extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -26,171 +34,158 @@ class MYNAMEHERE extends React.Component {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '600px',
|
||||||
|
height: '400px',
|
||||||
|
border: 'gray dotted 1px',
|
||||||
|
cursor: 'default',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Defines an icon for creating new connections in the connection handler.
|
||||||
|
// This will automatically disable the highlighting of the source vertex.
|
||||||
|
mxConnectionHandler.prototype.connectImage = new mxImage(
|
||||||
|
'images/connector.gif',
|
||||||
|
16,
|
||||||
|
16
|
||||||
|
);
|
||||||
|
|
||||||
};
|
// Creates the div for the toolbar
|
||||||
|
const tbContainer = document.createElement('div');
|
||||||
|
tbContainer.style.position = 'absolute';
|
||||||
|
tbContainer.style.overflow = 'hidden';
|
||||||
|
tbContainer.style.padding = '2px';
|
||||||
|
tbContainer.style.left = '0px';
|
||||||
|
tbContainer.style.top = '26px';
|
||||||
|
tbContainer.style.width = '24px';
|
||||||
|
tbContainer.style.bottom = '0px';
|
||||||
|
|
||||||
|
this.el.appendChild(tbContainer);
|
||||||
|
|
||||||
|
// Creates new toolbar without event processing
|
||||||
|
const toolbar = new mxToolbar(tbContainer);
|
||||||
|
toolbar.enabled = false;
|
||||||
|
|
||||||
|
// Creates the div for the graph
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.style.position = 'absolute';
|
||||||
|
container.style.overflow = 'hidden';
|
||||||
|
container.style.left = '24px';
|
||||||
|
container.style.top = '26px';
|
||||||
|
container.style.right = '0px';
|
||||||
|
container.style.bottom = '0px';
|
||||||
|
container.style.background = 'url("editors/images/grid.gif")';
|
||||||
|
|
||||||
|
this.el.appendChild(container);
|
||||||
|
|
||||||
|
// Creates the model and the graph inside the container
|
||||||
|
// using the fastest rendering available on the browser
|
||||||
|
const model = new mxGraphModel();
|
||||||
|
const graph = new mxGraph(container, model);
|
||||||
|
graph.dropEnabled = true;
|
||||||
|
|
||||||
|
// Matches DnD inside the graph
|
||||||
|
mxDragSource.prototype.getDropTarget = function(graph, x, y) {
|
||||||
|
let cell = graph.getCellAt(x, y);
|
||||||
|
if (!graph.isValidDropTarget(cell)) {
|
||||||
|
cell = null;
|
||||||
|
}
|
||||||
|
return cell;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enables new connections in the graph
|
||||||
|
graph.setConnectable(true);
|
||||||
|
graph.setMultigraph(false);
|
||||||
|
|
||||||
|
// Stops editing on enter or escape keypress
|
||||||
|
const keyHandler = new mxKeyHandler(graph);
|
||||||
|
const rubberband = new mxRubberband(graph);
|
||||||
|
|
||||||
|
const addVertex = (icon, w, h, style) => {
|
||||||
|
const vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
|
||||||
|
vertex.setVertex(true);
|
||||||
|
|
||||||
|
this.addToolbarItem(graph, toolbar, vertex, icon);
|
||||||
|
};
|
||||||
|
|
||||||
|
addVertex(
|
||||||
|
'editors/images/swimlane.gif',
|
||||||
|
120,
|
||||||
|
160,
|
||||||
|
'shape=swimlane;startSize=20;'
|
||||||
|
);
|
||||||
|
addVertex('editors/images/rectangle.gif', 100, 40, '');
|
||||||
|
addVertex('editors/images/rounded.gif', 100, 40, 'shape=rounded');
|
||||||
|
addVertex('editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
|
||||||
|
addVertex('editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
|
||||||
|
addVertex('editors/images/triangle.gif', 40, 40, 'shape=triangle');
|
||||||
|
addVertex('editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
|
||||||
|
addVertex('editors/images/actor.gif', 30, 40, 'shape=actor');
|
||||||
|
toolbar.addLine();
|
||||||
|
|
||||||
|
const button = mxUtils.button(
|
||||||
|
'Create toolbar entry from selection',
|
||||||
|
evt => {
|
||||||
|
if (!graph.isSelectionEmpty()) {
|
||||||
|
// Creates a copy of the selection array to preserve its state
|
||||||
|
const cells = graph.getSelectionCells();
|
||||||
|
const bounds = graph.getView().getBounds(cells);
|
||||||
|
|
||||||
|
// Function that is executed when the image is dropped on
|
||||||
|
// the graph. The cell argument points to the cell under
|
||||||
|
// the mousepointer if there is one.
|
||||||
|
const funct = (graph, evt, cell) => {
|
||||||
|
graph.stopEditing(false);
|
||||||
|
|
||||||
|
const pt = graph.getPointForEvent(evt);
|
||||||
|
const dx = pt.x - bounds.x;
|
||||||
|
const dy = pt.y - bounds.y;
|
||||||
|
|
||||||
|
graph.setSelectionCells(graph.importCells(cells, dx, dy, cell));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the image which is used as the drag icon (preview)
|
||||||
|
const img = toolbar.addMode(
|
||||||
|
null,
|
||||||
|
'editors/images/outline.gif',
|
||||||
|
funct
|
||||||
|
);
|
||||||
|
mxUtils.makeDraggable(img, graph, funct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
button.style.position = 'absolute';
|
||||||
|
button.style.left = '2px';
|
||||||
|
button.style.top = '2px';
|
||||||
|
|
||||||
|
document.body.appendChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
addToolbarItem(graph, toolbar, prototype, image) {
|
||||||
|
// Function that is executed when the image is dropped on
|
||||||
|
// the graph. The cell argument points to the cell under
|
||||||
|
// the mousepointer if there is one.
|
||||||
|
const funct = (graph, evt, cell) => {
|
||||||
|
graph.stopEditing(false);
|
||||||
|
|
||||||
|
const pt = graph.getPointForEvent(evt);
|
||||||
|
const vertex = graph.getModel().cloneCell(prototype);
|
||||||
|
vertex.geometry.x = pt.x;
|
||||||
|
vertex.geometry.y = pt.y;
|
||||||
|
|
||||||
|
graph.setSelectionCells(graph.importCells([vertex], 0, 0, cell));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the image which is used as the drag icon (preview)
|
||||||
|
const img = toolbar.addMode(null, image, funct);
|
||||||
|
mxUtils.makeDraggable(img, graph, funct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MYNAMEHERE;
|
export default Toolbar;
|
||||||
|
|
||||||
|
|
||||||
function main()
|
|
||||||
{
|
|
||||||
// Defines an icon for creating new connections in the connection handler.
|
|
||||||
// This will automatically disable the highlighting of the source vertex.
|
|
||||||
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
|
|
||||||
|
|
||||||
// Checks if 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 div for the toolbar
|
|
||||||
let tbContainer = document.createElement('div');
|
|
||||||
tbContainer.style.position = 'absolute';
|
|
||||||
tbContainer.style.overflow = 'hidden';
|
|
||||||
tbContainer.style.padding = '2px';
|
|
||||||
tbContainer.style.left = '0px';
|
|
||||||
tbContainer.style.top = '26px';
|
|
||||||
tbContainer.style.width = '24px';
|
|
||||||
tbContainer.style.bottom = '0px';
|
|
||||||
|
|
||||||
document.body.appendChild(tbContainer);
|
|
||||||
|
|
||||||
// Creates new toolbar without event processing
|
|
||||||
let toolbar = new mxToolbar(tbContainer);
|
|
||||||
toolbar.enabled = false
|
|
||||||
|
|
||||||
// Creates the div for the graph
|
|
||||||
container = document.createElement('div');
|
|
||||||
container.style.position = 'absolute';
|
|
||||||
container.style.overflow = 'hidden';
|
|
||||||
container.style.left = '24px';
|
|
||||||
container.style.top = '26px';
|
|
||||||
container.style.right = '0px';
|
|
||||||
container.style.bottom = '0px';
|
|
||||||
container.style.background = 'url("editors/images/grid.gif")';
|
|
||||||
|
|
||||||
document.body.appendChild(container);
|
|
||||||
|
|
||||||
// Creates the model and the graph inside the container
|
|
||||||
// using the fastest rendering available on the browser
|
|
||||||
let model = new mxGraphModel();
|
|
||||||
let graph = new mxGraph(container, model);
|
|
||||||
graph.dropEnabled = true;
|
|
||||||
|
|
||||||
// Matches DnD inside the graph
|
|
||||||
mxDragSource.prototype.getDropTarget = function(graph, x, y)
|
|
||||||
{
|
|
||||||
let cell = graph.getCellAt(x, y);
|
|
||||||
|
|
||||||
if (!graph.isValidDropTarget(cell))
|
|
||||||
{
|
|
||||||
cell = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enables new connections in the graph
|
|
||||||
graph.setConnectable(true);
|
|
||||||
graph.setMultigraph(false);
|
|
||||||
|
|
||||||
// Stops editing on enter or escape keypress
|
|
||||||
let keyHandler = new mxKeyHandler(graph);
|
|
||||||
let rubberband = new mxRubberband(graph);
|
|
||||||
|
|
||||||
let addVertex = function(icon, w, h, style)
|
|
||||||
{
|
|
||||||
let vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
|
|
||||||
vertex.setVertex(true);
|
|
||||||
|
|
||||||
addToolbarItem(graph, toolbar, vertex, icon);
|
|
||||||
};
|
|
||||||
|
|
||||||
addVertex('editors/images/swimlane.gif', 120, 160, 'shape=swimlane;startSize=20;');
|
|
||||||
addVertex('editors/images/rectangle.gif', 100, 40, '');
|
|
||||||
addVertex('editors/images/rounded.gif', 100, 40, 'shape=rounded');
|
|
||||||
addVertex('editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
|
|
||||||
addVertex('editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
|
|
||||||
addVertex('editors/images/triangle.gif', 40, 40, 'shape=triangle');
|
|
||||||
addVertex('editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
|
|
||||||
addVertex('editors/images/actor.gif', 30, 40, 'shape=actor');
|
|
||||||
toolbar.addLine();
|
|
||||||
|
|
||||||
let button = mxUtils.button('Create toolbar entry from selection', function(evt)
|
|
||||||
{
|
|
||||||
if (!graph.isSelectionEmpty())
|
|
||||||
{
|
|
||||||
// Creates a copy of the selection array to preserve its state
|
|
||||||
let cells = graph.getSelectionCells();
|
|
||||||
let bounds = graph.getView().getBounds(cells);
|
|
||||||
|
|
||||||
// Function that is executed when the image is dropped on
|
|
||||||
// the graph. The cell argument points to the cell under
|
|
||||||
// the mousepointer if there is one.
|
|
||||||
let funct = function(graph, evt, cell)
|
|
||||||
{
|
|
||||||
graph.stopEditing(false);
|
|
||||||
|
|
||||||
let pt = graph.getPointForEvent(evt);
|
|
||||||
let dx = pt.x - bounds.x;
|
|
||||||
let dy = pt.y - bounds.y;
|
|
||||||
|
|
||||||
graph.setSelectionCells(graph.importCells(cells, dx, dy, cell));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the image which is used as the drag icon (preview)
|
|
||||||
let img = toolbar.addMode(null, 'editors/images/outline.gif', funct);
|
|
||||||
mxUtils.makeDraggable(img, graph, funct);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
button.style.position = 'absolute';
|
|
||||||
button.style.left = '2px';
|
|
||||||
button.style.top = '2px';
|
|
||||||
|
|
||||||
document.body.appendChild(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addToolbarItem(graph, toolbar, prototype, image)
|
|
||||||
{
|
|
||||||
// Function that is executed when the image is dropped on
|
|
||||||
// the graph. The cell argument points to the cell under
|
|
||||||
// the mousepointer if there is one.
|
|
||||||
let funct = function(graph, evt, cell)
|
|
||||||
{
|
|
||||||
graph.stopEditing(false);
|
|
||||||
|
|
||||||
let pt = graph.getPointForEvent(evt);
|
|
||||||
let vertex = graph.getModel().cloneCell(prototype);
|
|
||||||
vertex.geometry.x = pt.x;
|
|
||||||
vertex.geometry.y = pt.y;
|
|
||||||
|
|
||||||
graph.setSelectionCells(graph.importCells([vertex], 0, 0, cell));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the image which is used as the drag icon (preview)
|
|
||||||
let img = toolbar.addMode(null, image, funct);
|
|
||||||
mxUtils.makeDraggable(img, graph, funct);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
|
|
||||||
<body onload="main();">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -22,9 +22,21 @@ import Tree from "./Tree";
|
||||||
import Validation from "./Validation";
|
import Validation from "./Validation";
|
||||||
import SwimLanes from "./SwimLanes";
|
import SwimLanes from "./SwimLanes";
|
||||||
import Wrapping from "./Wrapping";
|
import Wrapping from "./Wrapping";
|
||||||
import Windows from "./Windows";
|
//import Windows from "./Windows";
|
||||||
import Visibility from "./Visibility";
|
import Visibility from "./Visibility";
|
||||||
import UserObject from "./UserObject";
|
import UserObject from "./UserObject";
|
||||||
|
import Toolbar from "./Toolbar";
|
||||||
|
import Thread from "./Thread";
|
||||||
|
//import Template from "./Template";
|
||||||
|
import Stylesheet from "./Stylesheet";
|
||||||
|
import Stencils from "./Stencils";
|
||||||
|
import SecondLabel from "./SecondLabel";
|
||||||
|
import Shape from "./Shape";
|
||||||
|
import Resources from "./Resources";
|
||||||
|
import RadialTreeLayout from "./RadialTreeLayout";
|
||||||
|
import PortRefs from "./PortRefs";
|
||||||
|
import Permissions from "./Permissions";
|
||||||
|
import Perimeter from "./Perimeter";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
|
@ -53,13 +65,25 @@ export default function Home() {
|
||||||
<EdgeTolerance />
|
<EdgeTolerance />
|
||||||
<Editing />
|
<Editing />
|
||||||
|
|
||||||
|
<Perimeter />
|
||||||
|
<Permissions />
|
||||||
|
<PortRefs />
|
||||||
|
<RadialTreeLayout />
|
||||||
|
<Resources />
|
||||||
|
<SecondLabel />
|
||||||
|
<Shape />
|
||||||
|
{/*<Stencils />*/}
|
||||||
|
<Stylesheet />
|
||||||
<SwimLanes />
|
<SwimLanes />
|
||||||
|
{/*<Template />*/}
|
||||||
|
<Thread />
|
||||||
|
<Toolbar />
|
||||||
<Tree />
|
<Tree />
|
||||||
|
|
||||||
<UserObject />
|
<UserObject />
|
||||||
<Validation />
|
<Validation />
|
||||||
<Visibility />
|
<Visibility />
|
||||||
<Windows />
|
{/*<Windows />*/}
|
||||||
<Wrapping />
|
<Wrapping />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue