started integrating more examples into the next.js app

development
mcyph 2021-03-25 11:21:31 +11:00
parent 8afd272fbd
commit dad45f61dd
20 changed files with 1669 additions and 1819 deletions

View File

@ -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 {
/** /**

View File

@ -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 {
/** /**

View File

@ -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 {
/** /**

View File

@ -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 = {
/** /**

View File

@ -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

View File

@ -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');

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>
); );