/**
* Copyright (c) 2006-2013, JGraph Ltd
*/
import React from 'react';
import mxEvent from '../mxgraph/util/mxEvent';
import mxGraph from '../mxgraph/view/mxGraph';
import mxRubberband from '../mxgraph/handler/mxRubberband';
class Schema extends React.Component {
constructor(props) {
super(props);
}
render() {
// A container for the graph
return (
<>
{
this.el = el;
}}
style={{
}}
/>
>
);
};
componentDidMount() {
};
}
export default MYNAMEHERE;
function main(container, outline, toolbar, sidebar, status)
{
// 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
{
// Specifies shadow opacity, color and offset
mxConstants.SHADOW_OPACITY = 0.5;
mxConstants.SHADOWCOLOR = '#C0C0C0';
mxConstants.SHADOW_OFFSET_X = 5;
mxConstants.SHADOW_OFFSET_Y = 6;
// Table icon dimensions and position
mxSwimlane.prototype.imageSize = 20;
mxSwimlane.prototype.imageDx = 16;
mxSwimlane.prototype.imageDy = 4;
// Changes swimlane icon bounds
mxSwimlane.prototype.getImageBounds = function(x, y, w, h)
{
return new mxRectangle(x + this.imageDx, y + this.imageDy, this.imageSize, this.imageSize);
};
// 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);
// Prefetches all images that appear in colums
// to avoid problems with the auto-layout
let keyImage = new Image();
keyImage.src = "images/key.png";
let plusImage = new Image();
plusImage.src = "images/plus.png";
let checkImage = new Image();
checkImage.src = "images/check.png";
// Creates the graph inside the given container. The
// editor is used to create certain functionality for the
// graph, such as the rubberband selection, but most parts
// of the UI are custom in this example.
let editor = new mxEditor();
let graph = editor.graph;
let model = graph.model;
// Disables some global features
graph.setConnectable(true);
graph.setCellsDisconnectable(false);
graph.setCellsCloneable(false);
graph.swimlaneNesting = false;
graph.dropEnabled = true;
// Does not allow dangling edges
graph.setAllowDanglingEdges(false);
// Forces use of default edge in mxConnectionHandler
graph.connectionHandler.factoryMethod = null;
// Only tables are resizable
graph.isCellResizable = function(cell)
{
return this.isSwimlane(cell);
};
// Only tables are movable
graph.isCellMovable = function(cell)
{
return this.isSwimlane(cell);
};
// Sets the graph container and configures the editor
editor.setGraphContainer(container);
let config = mxUtils.load(
'editors/config/keyhandler-minimal.xml').
getDocumentElement();
editor.configure(config);
// Configures the automatic layout for the table columns
editor.layoutSwimlanes = true;
editor.createSwimlaneLayout = () =>
{
let layout = new mxStackLayout(this.graph, false);
layout.fill = true;
layout.resizeParent = true;
// Overrides the function to always return true
layout.isVertexMovable = function(cell)
{
return true;
};
return layout;
};
// Text label changes will go into the name field of the user object
graph.model.valueForCellChanged = function(cell, value)
{
if (value.name != null)
{
return mxGraphModel.prototype.valueForCellChanged.apply(this, arguments);
}
else
{
let old = cell.value.name;
cell.value.name = value;
return old;
}
};
// Columns are dynamically created HTML labels
graph.isHtmlLabel = function(cell)
{
return !this.isSwimlane(cell) &&
!cell.isEdge();
};
// Edges are not editable
graph.isCellEditable = function(cell)
{
return !cell.isEdge();
};
// Returns the name field of the user object for the label
graph.convertValueToString = function(cell)
{
if (cell.value != null && cell.value.name != null)
{
return cell.value.name;
}
return mxGraph.prototype.convertValueToString.apply(this, arguments); // "supercall"
};
// Returns the type as the tooltip for column cells
graph.getTooltip = function(state)
{
if (this.isHtmlLabel(state.cell))
{
return 'Type: '+state.cell.value.type;
}
else if (state.cell.isEdge())
{
let source = state.cell.getTerminal(true);
let parent = source.getParent();
return parent.value.name+'.'+source.value.name;
}
return mxGraph.prototype.getTooltip.apply(this, arguments); // "supercall"
};
// Creates a dynamic HTML label for column fields
graph.getLabel = function(cell)
{
if (this.isHtmlLabel(cell))
{
let label = '';
if (cell.value.primaryKey)
{
label += '
';
}
else
{
label += '
';
}
if (cell.value.autoIncrement)
{
label += '
';
}
else if (cell.value.unique)
{
label += '
';
}
else
{
label += '
';
}
return label + mxUtils.htmlEntities(cell.value.name, false) + ': ' +
mxUtils.htmlEntities(cell.value.type, false);
}
return mxGraph.prototype.getLabel.apply(this, arguments); // "supercall"
};
// Removes the source vertex if edges are removed
graph.addListener(mxEvent.REMOVE_CELLS, function(sender, evt)
{
let cells = evt.getProperty('cells');
for (let i = 0; i < cells.length; i++)
{
let cell = cells[i];
if (cell.isEdge())
{
let terminal = cell.getTerminal(true);
let parent = terminal.getParent();
this.model.remove(terminal);
}
}
});
// Disables drag-and-drop into non-swimlanes.
graph.isValidDropTarget = function(cell, cells, evt)
{
return this.isSwimlane(cell);
};
// Installs a popupmenu handler using local function (see below).
graph.popupMenuHandler.factoryMethod = function(menu, cell, evt)
{
createPopupMenu(editor, graph, menu, cell, evt);
};
// Adds all required styles to the graph (see below)
configureStylesheet(graph);
// Adds sidebar icon for the table object
let tableObject = new Table('TABLENAME');
let table = new mxCell(tableObject, new mxGeometry(0, 0, 200, 28), 'table');
table.setVertex(true);
addSidebarIcon(graph, sidebar, table, 'images/icons48/table.png');
// Adds sidebar icon for the column object
let columnObject = new Column('COLUMNNAME');
let column = new mxCell(columnObject, new mxGeometry(0, 0, 0, 26));
column.setVertex(true);
column.setConnectable(false);
addSidebarIcon(graph, sidebar, column, 'images/icons48/column.png');
// Adds primary key field into table
let firstColumn = column.clone();
firstColumn.value.name = 'TABLENAME_ID';
firstColumn.value.type = 'INTEGER';
firstColumn.value.primaryKey = true;
firstColumn.value.autoIncrement = true;
table.insert(firstColumn);
// Adds child columns for new connections between tables
graph.addEdge = function(edge, parent, source, target, index)
{
// Finds the primary key child of the target table
let primaryKey = null;
let childCount = target.getChildCount();
for (var i=0; i < childCount; i++)
{
let child = target.getChildAt(i);
if (child.value.primaryKey)
{
primaryKey = child;
break;
}
}
if (primaryKey == null)
{
mxUtils.alert('Target table must have a primary key');
return;
}
this.model.beginUpdate();
try
{
var col1 = this.model.cloneCell(column);
col1.value.name = primaryKey.value.name;
col1.value.type = primaryKey.value.type;
this.addCell(col1, source);
source = col1;
target = primaryKey;
return mxGraph.prototype.addEdge.apply(this, arguments); // "supercall"
}
finally
{
this.model.endUpdate();
}
return null;
};
// Displays useful hints in a small semi-transparent box.
let hints = document.createElement('div');
hints.style.position = 'absolute';
hints.style.overflow = 'hidden';
hints.style.width = '230px';
hints.style.bottom = '56px';
hints.style.height = '86px';
hints.style.right = '20px';
hints.style.background = 'black';
hints.style.color = 'white';
hints.style.fontFamily = 'Arial';
hints.style.fontSize = '10px';
hints.style.padding = '4px';
mxUtils.setOpacity(hints, 50);
mxUtils.writeln(hints, '- Drag an image from the sidebar to the graph');
mxUtils.writeln(hints, '- Doubleclick on a table or column to edit');
mxUtils.writeln(hints, '- Shift- or Rightclick and drag for panning');
mxUtils.writeln(hints, '- Move the mouse over a cell to see a tooltip');
mxUtils.writeln(hints, '- Click and drag a table to move and connect');
mxUtils.writeln(hints, '- Shift- or Rightclick to show a popup menu');
document.body.appendChild(hints);
// Creates a new DIV that is used as a toolbar and adds
// toolbar buttons.
let spacer = document.createElement('div');
spacer.style.display = 'inline';
spacer.style.padding = '8px';
addToolbarButton(editor, toolbar, 'properties', 'Properties', 'editors/images/properties.gif');
// Defines a new export action
editor.addAction('properties', function(editor, cell)
{
if (cell == null)
{
cell = graph.getSelectionCell();
}
if (graph.isHtmlLabel(cell))
{
showProperties(graph, cell);
}
});
addToolbarButton(editor, toolbar, 'delete', 'Delete', 'images/delete2.png');
toolbar.appendChild(spacer.cloneNode(true));
addToolbarButton(editor, toolbar, 'undo', '', 'images/undo.png');
addToolbarButton(editor, toolbar, 'redo', '', 'images/redo.png');
toolbar.appendChild(spacer.cloneNode(true));
addToolbarButton(editor, toolbar, 'show', 'Show', 'images/camera.png');
addToolbarButton(editor, toolbar, 'print', 'Print', 'images/printer.png');
toolbar.appendChild(spacer.cloneNode(true));
// Defines a create SQK action
editor.addAction('showSql', function(editor, cell)
{
let sql = createSql(graph);
if (sql.length > 0)
{
let textarea = document.createElement('textarea');
textarea.style.width = '400px';
textarea.style.height = '400px';
textarea.value = sql;
showModalWindow('SQL', textarea, 410, 440);
}
else
{
mxUtils.alert('Schema is empty');
}
});
addToolbarButton(editor, toolbar, 'showSql', 'Show SQL', 'images/export1.png');
// Defines export XML action
editor.addAction('export', function(editor, cell)
{
let textarea = document.createElement('textarea');
textarea.style.width = '400px';
textarea.style.height = '400px';
let enc = new mxCodec(mxUtils.createXmlDocument());
let node = enc.encode(editor.graph.getModel());
textarea.value = mxUtils.getPrettyXml(node);
showModalWindow('XML', textarea, 410, 440);
});
addToolbarButton(editor, toolbar, 'export', 'Export XML', 'images/export1.png');
// Adds toolbar buttons into the status bar at the bottom
// of the window.
addToolbarButton(editor, status, 'collapseAll', 'Collapse All', 'images/navigate_minus.png', true);
addToolbarButton(editor, status, 'expandAll', 'Expand All', 'images/navigate_plus.png', true);
status.appendChild(spacer.cloneNode(true));
addToolbarButton(editor, status, 'zoomIn', '', 'images/zoom_in.png', true);
addToolbarButton(editor, status, 'zoomOut', '', 'images/zoom_out.png', true);
addToolbarButton(editor, status, 'actualSize', '', 'images/view_1_1.png', true);
addToolbarButton(editor, status, 'fit', '', 'images/fit_to_size.png', true);
// Creates the outline (navigator, overview) for moving
// around the graph in the top, right corner of the window.
let outln = new mxOutline(graph, outline);
// Fades-out the splash screen after the UI has been loaded.
let splash = document.getElementById('splash');
if (splash != null)
{
try
{
mxEvent.release(splash);
mxEffects.fadeOut(splash, 100, true);
}
catch (e)
{
// mxUtils is not available (library not loaded)
splash.parentNode.removeChild(splash);
}
}
}
}
function addToolbarButton(editor, toolbar, action, label, image, isTransparent)
{
let button = document.createElement('button');
button.style.fontSize = '10';
if (image != null)
{
let img = document.createElement('img');
img.setAttribute('src', image);
img.style.width = '16px';
img.style.height = '16px';
img.style.verticalAlign = 'middle';
img.style.marginRight = '2px';
button.appendChild(img);
}
if (isTransparent)
{
button.style.background = 'transparent';
button.style.color = '#FFFFFF';
button.style.border = 'none';
}
mxEvent.addListener(button, 'click', function(evt)
{
editor.execute(action);
});
mxUtils.write(button, label);
toolbar.appendChild(button);
};
function showModalWindow(title, content, width, height)
{
let background = document.createElement('div');
background.style.position = 'absolute';
background.style.left = '0px';
background.style.top = '0px';
background.style.right = '0px';
background.style.bottom = '0px';
background.style.background = 'black';
mxUtils.setOpacity(background, 50);
document.body.appendChild(background);
let x = Math.max(0, document.body.scrollWidth/2-width/2);
let y = Math.max(10, (document.body.scrollHeight ||
document.documentElement.scrollHeight)/2-height*2/3);
let wnd = new mxWindow(title, content, x, y, width, height, false, true);
wnd.setClosable(true);
// Fades the background out after after the window has been closed
wnd.addListener(mxEvent.DESTROY, function(evt)
{
mxEffects.fadeOut(background, 50, true,
10, 30, true);
});
wnd.setVisible(true);
return wnd;
};
function addSidebarIcon(graph, sidebar, 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 parent = graph.getDefaultParent();
let model = graph.getModel();
let isTable = graph.isSwimlane(prototype);
let name = null;
if (!isTable)
{
parent = cell;
let pstate = graph.getView().getState(parent);
if (parent == null || pstate == null)
{
mxUtils.alert('Drop target must be a table');
return;
}
pt.x -= pstate.x;
pt.y -= pstate.y;
let columnCount = parent.getChildCount()+1;
name = mxUtils.prompt('Enter name for new column', 'COLUMN'+columnCount);
}
else
{
let tableCount = 0;
let childCount = parent.getChildCount();
for (var i=0; i
0)
{
for (var j=0; j