mxgraph
Version:
mxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.
1,582 lines (1,464 loc) • 338 kB
JavaScript
/**
* Copyright (c) 2006-2015, JGraph Ltd
* Copyright (c) 2006-2015, Gaudenz Alder
*/
/**
* Class: mxGraph
*
* Extends <mxEventSource> to implement a graph component for
* the browser. This is the main class of the package. To activate
* panning and connections use <setPanning> and <setConnectable>.
* For rubberband selection you must create a new instance of
* <mxRubberband>. The following listeners are added to
* <mouseListeners> by default:
*
* - <tooltipHandler>: <mxTooltipHandler> that displays tooltips
* - <panningHandler>: <mxPanningHandler> for panning and popup menus
* - <connectionHandler>: <mxConnectionHandler> for creating connections
* - <graphHandler>: <mxGraphHandler> for moving and cloning cells
*
* These listeners will be called in the above order if they are enabled.
*
* Background Images:
*
* To display a background image, set the image, image width and
* image height using <setBackgroundImage>. If one of the
* above values has changed then the <view>'s <mxGraphView.validate>
* should be invoked.
*
* Cell Images:
*
* To use images in cells, a shape must be specified in the default
* vertex style (or any named style). Possible shapes are
* <mxConstants.SHAPE_IMAGE> and <mxConstants.SHAPE_LABEL>.
* The code to change the shape used in the default vertex style,
* the following code is used:
*
* (code)
* var style = graph.getStylesheet().getDefaultVertexStyle();
* style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
* (end)
*
* For the default vertex style, the image to be displayed can be
* specified in a cell's style using the <mxConstants.STYLE_IMAGE>
* key and the image URL as a value, for example:
*
* (code)
* image=http://www.example.com/image.gif
* (end)
*
* For a named style, the the stylename must be the first element
* of the cell style:
*
* (code)
* stylename;image=http://www.example.com/image.gif
* (end)
*
* A cell style can have any number of key=value pairs added, divided
* by a semicolon as follows:
*
* (code)
* [stylename;|key=value;]
* (end)
*
* Labels:
*
* The cell labels are defined by <getLabel> which uses <convertValueToString>
* if <labelsVisible> is true. If a label must be rendered as HTML markup, then
* <isHtmlLabel> should return true for the respective cell. If all labels
* contain HTML markup, <htmlLabels> can be set to true. NOTE: Enabling HTML
* labels carries a possible security risk (see the section on security in
* the manual).
*
* If wrapping is needed for a label, then <isHtmlLabel> and <isWrapping> must
* return true for the cell whose label should be wrapped. See <isWrapping> for
* an example.
*
* If clipping is needed to keep the rendering of a HTML label inside the
* bounds of its vertex, then <isClipping> should return true for the
* respective cell.
*
* By default, edge labels are movable and vertex labels are fixed. This can be
* changed by setting <edgeLabelsMovable> and <vertexLabelsMovable>, or by
* overriding <isLabelMovable>.
*
* In-place Editing:
*
* In-place editing is started with a doubleclick or by typing F2.
* Programmatically, <edit> is used to check if the cell is editable
* (<isCellEditable>) and call <startEditingAtCell>, which invokes
* <mxCellEditor.startEditing>. The editor uses the value returned
* by <getEditingValue> as the editing value.
*
* After in-place editing, <labelChanged> is called, which invokes
* <mxGraphModel.setValue>, which in turn calls
* <mxGraphModel.valueForCellChanged> via <mxValueChange>.
*
* The event that triggers in-place editing is passed through to the
* <cellEditor>, which may take special actions depending on the type of the
* event or mouse location, and is also passed to <getEditingValue>. The event
* is then passed back to the event processing functions which can perform
* specific actions based on the trigger event.
*
* Tooltips:
*
* Tooltips are implemented by <getTooltip>, which calls <getTooltipForCell>
* if a cell is under the mousepointer. The default implementation checks if
* the cell has a getTooltip function and calls it if it exists. Hence, in order
* to provide custom tooltips, the cell must provide a getTooltip function, or
* one of the two above functions must be overridden.
*
* Typically, for custom cell tooltips, the latter function is overridden as
* follows:
*
* (code)
* graph.getTooltipForCell = function(cell)
* {
* var label = this.convertValueToString(cell);
* return 'Tooltip for '+label;
* }
* (end)
*
* When using a config file, the function is overridden in the mxGraph section
* using the following entry:
*
* (code)
* <add as="getTooltipForCell"><![CDATA[
* function(cell)
* {
* var label = this.convertValueToString(cell);
* return 'Tooltip for '+label;
* }
* ]]></add>
* (end)
*
* "this" refers to the graph in the implementation, so for example to check if
* a cell is an edge, you use this.getModel().isEdge(cell)
*
* For replacing the default implementation of <getTooltipForCell> (rather than
* replacing the function on a specific instance), the following code should be
* used after loading the JavaScript files, but before creating a new mxGraph
* instance using <mxGraph>:
*
* (code)
* mxGraph.prototype.getTooltipForCell = function(cell)
* {
* var label = this.convertValueToString(cell);
* return 'Tooltip for '+label;
* }
* (end)
*
* Shapes & Styles:
*
* The implementation of new shapes is demonstrated in the examples. We'll assume
* that we have implemented a custom shape with the name BoxShape which we want
* to use for drawing vertices. To use this shape, it must first be registered in
* the cell renderer as follows:
*
* (code)
* mxCellRenderer.registerShape('box', BoxShape);
* (end)
*
* The code registers the BoxShape constructor under the name box in the cell
* renderer of the graph. The shape can now be referenced using the shape-key in
* a style definition. (The cell renderer contains a set of additional shapes,
* namely one for each constant with a SHAPE-prefix in <mxConstants>.)
*
* Styles are a collection of key, value pairs and a stylesheet is a collection
* of named styles. The names are referenced by the cellstyle, which is stored
* in <mxCell.style> with the following format: [stylename;|key=value;]. The
* string is resolved to a collection of key, value pairs, where the keys are
* overridden with the values in the string.
*
* When introducing a new shape, the name under which the shape is registered
* must be used in the stylesheet. There are three ways of doing this:
*
* - By changing the default style, so that all vertices will use the new
* shape
* - By defining a new style, so that only vertices with the respective
* cellstyle will use the new shape
* - By using shape=box in the cellstyle's optional list of key, value pairs
* to be overridden
*
* In the first case, the code to fetch and modify the default style for
* vertices is as follows:
*
* (code)
* var style = graph.getStylesheet().getDefaultVertexStyle();
* style[mxConstants.STYLE_SHAPE] = 'box';
* (end)
*
* The code takes the default vertex style, which is used for all vertices that
* do not have a specific cellstyle, and modifies the value for the shape-key
* in-place to use the new BoxShape for drawing vertices. This is done by
* assigning the box value in the second line, which refers to the name of the
* BoxShape in the cell renderer.
*
* In the second case, a collection of key, value pairs is created and then
* added to the stylesheet under a new name. In order to distinguish the
* shapename and the stylename we'll use boxstyle for the stylename:
*
* (code)
* var style = new Object();
* style[mxConstants.STYLE_SHAPE] = 'box';
* style[mxConstants.STYLE_STROKECOLOR] = '#000000';
* style[mxConstants.STYLE_FONTCOLOR] = '#000000';
* graph.getStylesheet().putCellStyle('boxstyle', style);
* (end)
*
* The code adds a new style with the name boxstyle to the stylesheet. To use
* this style with a cell, it must be referenced from the cellstyle as follows:
*
* (code)
* var vertex = graph.insertVertex(parent, null, 'Hello, World!', 20, 20, 80, 20,
* 'boxstyle');
* (end)
*
* To summarize, each new shape must be registered in the <mxCellRenderer> with
* a unique name. That name is then used as the value of the shape-key in a
* default or custom style. If there are multiple custom shapes, then there
* should be a separate style for each shape.
*
* Inheriting Styles:
*
* For fill-, stroke-, gradient-, font- and indicatorColors special keywords
* can be used. The inherit keyword for one of these colors will inherit the
* color for the same key from the parent cell. The swimlane keyword does the
* same, but inherits from the nearest swimlane in the ancestor hierarchy.
* Finally, the indicated keyword will use the color of the indicator as the
* color for the given key.
*
* Scrollbars:
*
* The <containers> overflow CSS property defines if scrollbars are used to
* display the graph. For values of 'auto' or 'scroll', the scrollbars will
* be shown. Note that the <resizeContainer> flag is normally not used
* together with scrollbars, as it will resize the container to match the
* size of the graph after each change.
*
* Multiplicities and Validation:
*
* To control the possible connections in mxGraph, <getEdgeValidationError> is
* used. The default implementation of the function uses <multiplicities>,
* which is an array of <mxMultiplicity>. Using this class allows to establish
* simple multiplicities, which are enforced by the graph.
*
* The <mxMultiplicity> uses <mxCell.is> to determine for which terminals it
* applies. The default implementation of <mxCell.is> works with DOM nodes (XML
* nodes) and checks if the given type parameter matches the nodeName of the
* node (case insensitive). Optionally, an attributename and value can be
* specified which are also checked.
*
* <getEdgeValidationError> is called whenever the connectivity of an edge
* changes. It returns an empty string or an error message if the edge is
* invalid or null if the edge is valid. If the returned string is not empty
* then it is displayed as an error message.
*
* <mxMultiplicity> allows to specify the multiplicity between a terminal and
* its possible neighbors. For example, if any rectangle may only be connected
* to, say, a maximum of two circles you can add the following rule to
* <multiplicities>:
*
* (code)
* graph.multiplicities.push(new mxMultiplicity(
* true, 'rectangle', null, null, 0, 2, ['circle'],
* 'Only 2 targets allowed',
* 'Only shape targets allowed'));
* (end)
*
* This will display the first error message whenever a rectangle is connected
* to more than two circles and the second error message if a rectangle is
* connected to anything but a circle.
*
* For certain multiplicities, such as a minimum of 1 connection, which cannot
* be enforced at cell creation time (unless the cell is created together with
* the connection), mxGraph offers <validate> which checks all multiplicities
* for all cells and displays the respective error messages in an overlay icon
* on the cells.
*
* If a cell is collapsed and contains validation errors, a respective warning
* icon is attached to the collapsed cell.
*
* Auto-Layout:
*
* For automatic layout, the <getLayout> hook is provided in <mxLayoutManager>.
* It can be overridden to return a layout algorithm for the children of a
* given cell.
*
* Unconnected edges:
*
* The default values for all switches are designed to meet the requirements of
* general diagram drawing applications. A very typical set of settings to
* avoid edges that are not connected is the following:
*
* (code)
* graph.setAllowDanglingEdges(false);
* graph.setDisconnectOnMove(false);
* (end)
*
* Setting the <cloneInvalidEdges> switch to true is optional. This switch
* controls if edges are inserted after a copy, paste or clone-drag if they are
* invalid. For example, edges are invalid if copied or control-dragged without
* having selected the corresponding terminals and allowDanglingEdges is
* false, in which case the edges will not be cloned if the switch is false.
*
* Output:
*
* To produce an XML representation for a diagram, the following code can be
* used.
*
* (code)
* var enc = new mxCodec(mxUtils.createXmlDocument());
* var node = enc.encode(graph.getModel());
* (end)
*
* This will produce an XML node than can be handled using the DOM API or
* turned into a string representation using the following code:
*
* (code)
* var xml = mxUtils.getXml(node);
* (end)
*
* To obtain a formatted string, mxUtils.getPrettyXml can be used instead.
*
* This string can now be stored in a local persistent storage (for example
* using Google Gears) or it can be passed to a backend using mxUtils.post as
* follows. The url variable is the URL of the Java servlet, PHP page or HTTP
* handler, depending on the server.
*
* (code)
* var xmlString = encodeURIComponent(mxUtils.getXml(node));
* mxUtils.post(url, 'xml='+xmlString, function(req)
* {
* // Process server response using req of type mxXmlRequest
* });
* (end)
*
* Input:
*
* To load an XML representation of a diagram into an existing graph object
* mxUtils.load can be used as follows. The url variable is the URL of the Java
* servlet, PHP page or HTTP handler that produces the XML string.
*
* (code)
* var xmlDoc = mxUtils.load(url).getXml();
* var node = xmlDoc.documentElement;
* var dec = new mxCodec(node.ownerDocument);
* dec.decode(node, graph.getModel());
* (end)
*
* For creating a page that loads the client and a diagram using a single
* request please refer to the deployment examples in the backends.
*
* Functional dependencies:
*
* (see images/callgraph.png)
*
* Resources:
*
* resources/graph - Language resources for mxGraph
*
* Group: Events
*
* Event: mxEvent.ROOT
*
* Fires if the root in the model has changed. This event has no properties.
*
* Event: mxEvent.ALIGN_CELLS
*
* Fires between begin- and endUpdate in <alignCells>. The <code>cells</code>
* and <code>align</code> properties contain the respective arguments that were
* passed to <alignCells>.
*
* Event: mxEvent.FLIP_EDGE
*
* Fires between begin- and endUpdate in <flipEdge>. The <code>edge</code>
* property contains the edge passed to <flipEdge>.
*
* Event: mxEvent.ORDER_CELLS
*
* Fires between begin- and endUpdate in <orderCells>. The <code>cells</code>
* and <code>back</code> properties contain the respective arguments that were
* passed to <orderCells>.
*
* Event: mxEvent.CELLS_ORDERED
*
* Fires between begin- and endUpdate in <cellsOrdered>. The <code>cells</code>
* and <code>back</code> arguments contain the respective arguments that were
* passed to <cellsOrdered>.
*
* Event: mxEvent.GROUP_CELLS
*
* Fires between begin- and endUpdate in <groupCells>. The <code>group</code>,
* <code>cells</code> and <code>border</code> arguments contain the respective
* arguments that were passed to <groupCells>.
*
* Event: mxEvent.UNGROUP_CELLS
*
* Fires between begin- and endUpdate in <ungroupCells>. The <code>cells</code>
* property contains the array of cells that was passed to <ungroupCells>.
*
* Event: mxEvent.REMOVE_CELLS_FROM_PARENT
*
* Fires between begin- and endUpdate in <removeCellsFromParent>. The
* <code>cells</code> property contains the array of cells that was passed to
* <removeCellsFromParent>.
*
* Event: mxEvent.ADD_CELLS
*
* Fires between begin- and endUpdate in <addCells>. The <code>cells</code>,
* <code>parent</code>, <code>index</code>, <code>source</code> and
* <code>target</code> properties contain the respective arguments that were
* passed to <addCells>.
*
* Event: mxEvent.CELLS_ADDED
*
* Fires between begin- and endUpdate in <cellsAdded>. The <code>cells</code>,
* <code>parent</code>, <code>index</code>, <code>source</code>,
* <code>target</code> and <code>absolute</code> properties contain the
* respective arguments that were passed to <cellsAdded>.
*
* Event: mxEvent.REMOVE_CELLS
*
* Fires between begin- and endUpdate in <removeCells>. The <code>cells</code>
* and <code>includeEdges</code> arguments contain the respective arguments
* that were passed to <removeCells>.
*
* Event: mxEvent.CELLS_REMOVED
*
* Fires between begin- and endUpdate in <cellsRemoved>. The <code>cells</code>
* argument contains the array of cells that was removed.
*
* Event: mxEvent.SPLIT_EDGE
*
* Fires between begin- and endUpdate in <splitEdge>. The <code>edge</code>
* property contains the edge to be splitted, the <code>cells</code>,
* <code>newEdge</code>, <code>dx</code> and <code>dy</code> properties contain
* the respective arguments that were passed to <splitEdge>.
*
* Event: mxEvent.TOGGLE_CELLS
*
* Fires between begin- and endUpdate in <toggleCells>. The <code>show</code>,
* <code>cells</code> and <code>includeEdges</code> properties contain the
* respective arguments that were passed to <toggleCells>.
*
* Event: mxEvent.FOLD_CELLS
*
* Fires between begin- and endUpdate in <foldCells>. The
* <code>collapse</code>, <code>cells</code> and <code>recurse</code>
* properties contain the respective arguments that were passed to <foldCells>.
*
* Event: mxEvent.CELLS_FOLDED
*
* Fires between begin- and endUpdate in cellsFolded. The
* <code>collapse</code>, <code>cells</code> and <code>recurse</code>
* properties contain the respective arguments that were passed to
* <cellsFolded>.
*
* Event: mxEvent.UPDATE_CELL_SIZE
*
* Fires between begin- and endUpdate in <updateCellSize>. The
* <code>cell</code> and <code>ignoreChildren</code> properties contain the
* respective arguments that were passed to <updateCellSize>.
*
* Event: mxEvent.RESIZE_CELLS
*
* Fires between begin- and endUpdate in <resizeCells>. The <code>cells</code>
* and <code>bounds</code> properties contain the respective arguments that
* were passed to <resizeCells>.
*
* Event: mxEvent.CELLS_RESIZED
*
* Fires between begin- and endUpdate in <cellsResized>. The <code>cells</code>
* and <code>bounds</code> properties contain the respective arguments that
* were passed to <cellsResized>.
*
* Event: mxEvent.MOVE_CELLS
*
* Fires between begin- and endUpdate in <moveCells>. The <code>cells</code>,
* <code>dx</code>, <code>dy</code>, <code>clone</code>, <code>target</code>
* and <code>event</code> properties contain the respective arguments that
* were passed to <moveCells>.
*
* Event: mxEvent.CELLS_MOVED
*
* Fires between begin- and endUpdate in <cellsMoved>. The <code>cells</code>,
* <code>dx</code>, <code>dy</code> and <code>disconnect</code> properties
* contain the respective arguments that were passed to <cellsMoved>.
*
* Event: mxEvent.CONNECT_CELL
*
* Fires between begin- and endUpdate in <connectCell>. The <code>edge</code>,
* <code>terminal</code> and <code>source</code> properties contain the
* respective arguments that were passed to <connectCell>.
*
* Event: mxEvent.CELL_CONNECTED
*
* Fires between begin- and endUpdate in <cellConnected>. The
* <code>edge</code>, <code>terminal</code> and <code>source</code> properties
* contain the respective arguments that were passed to <cellConnected>.
*
* Event: mxEvent.REFRESH
*
* Fires after <refresh> was executed. This event has no properties.
*
* Event: mxEvent.CLICK
*
* Fires in <click> after a click event. The <code>event</code> property
* contains the original mouse event and <code>cell</code> property contains
* the cell under the mouse or null if the background was clicked.
*
* Event: mxEvent.DOUBLE_CLICK
*
* Fires in <dblClick> after a double click. The <code>event</code> property
* contains the original mouse event and the <code>cell</code> property
* contains the cell under the mouse or null if the background was clicked.
*
* Event: mxEvent.GESTURE
*
* Fires in <fireGestureEvent> after a touch gesture. The <code>event</code>
* property contains the original gesture end event and the <code>cell</code>
* property contains the optional cell associated with the gesture.
*
* Event: mxEvent.TAP_AND_HOLD
*
* Fires in <tapAndHold> if a tap and hold event was detected. The <code>event</code>
* property contains the initial touch event and the <code>cell</code> property
* contains the cell under the mouse or null if the background was clicked.
*
* Event: mxEvent.FIRE_MOUSE_EVENT
*
* Fires in <fireMouseEvent> before the mouse listeners are invoked. The
* <code>eventName</code> property contains the event name and the
* <code>event</code> property contains the <mxMouseEvent>.
*
* Event: mxEvent.SIZE
*
* Fires after <sizeDidChange> was executed. The <code>bounds</code> property
* contains the new graph bounds.
*
* Event: mxEvent.START_EDITING
*
* Fires before the in-place editor starts in <startEditingAtCell>. The
* <code>cell</code> property contains the cell that is being edited and the
* <code>event</code> property contains the optional event argument that was
* passed to <startEditingAtCell>.
*
* Event: mxEvent.EDITING_STARTED
*
* Fires after the in-place editor starts in <startEditingAtCell>. The
* <code>cell</code> property contains the cell that is being edited and the
* <code>event</code> property contains the optional event argument that was
* passed to <startEditingAtCell>.
*
* Event: mxEvent.EDITING_STOPPED
*
* Fires after the in-place editor stops in <stopEditing>.
*
* Event: mxEvent.LABEL_CHANGED
*
* Fires between begin- and endUpdate in <cellLabelChanged>. The
* <code>cell</code> property contains the cell, the <code>value</code>
* property contains the new value for the cell, the <code>old</code> property
* contains the old value and the optional <code>event</code> property contains
* the mouse event that started the edit.
*
* Event: mxEvent.ADD_OVERLAY
*
* Fires after an overlay is added in <addCellOverlay>. The <code>cell</code>
* property contains the cell and the <code>overlay</code> property contains
* the <mxCellOverlay> that was added.
*
* Event: mxEvent.REMOVE_OVERLAY
*
* Fires after an overlay is removed in <removeCellOverlay> and
* <removeCellOverlays>. The <code>cell</code> property contains the cell and
* the <code>overlay</code> property contains the <mxCellOverlay> that was
* removed.
*
* Constructor: mxGraph
*
* Constructs a new mxGraph in the specified container. Model is an optional
* mxGraphModel. If no model is provided, a new mxGraphModel instance is
* used as the model. The container must have a valid owner document prior
* to calling this function in Internet Explorer. RenderHint is a string to
* affect the display performance and rendering in IE, but not in SVG-based
* browsers. The parameter is mapped to <dialect>, which may
* be one of <mxConstants.DIALECT_SVG> for SVG-based browsers,
* <mxConstants.DIALECT_STRICTHTML> for fastest display mode,
* <mxConstants.DIALECT_PREFERHTML> for faster display mode,
* <mxConstants.DIALECT_MIXEDHTML> for fast and <mxConstants.DIALECT_VML>
* for exact display mode (slowest). The dialects are defined in mxConstants.
* The default values are DIALECT_SVG for SVG-based browsers and
* DIALECT_MIXED for IE.
*
* The possible values for the renderingHint parameter are explained below:
*
* fast - The parameter is based on the fact that the display performance is
* highly improved in IE if the VML is not contained within a VML group
* element. The lack of a group element only slightly affects the display while
* panning, but improves the performance by almost a factor of 2, while keeping
* the display sufficiently accurate. This also allows to render certain shapes as HTML
* if the display accuracy is not affected, which is implemented by
* <mxShape.isMixedModeHtml>. This is the default setting and is mapped to
* DIALECT_MIXEDHTML.
* faster - Same as fast, but more expensive shapes are avoided. This is
* controlled by <mxShape.preferModeHtml>. The default implementation will
* avoid gradients and rounded rectangles, but more significant shapes, such
* as rhombus, ellipse, actor and cylinder will be rendered accurately. This
* setting is mapped to DIALECT_PREFERHTML.
* fastest - Almost anything will be rendered in Html. This allows for
* rectangles, labels and images. This setting is mapped to
* DIALECT_STRICTHTML.
* exact - If accurate panning is required and if the diagram is small (up
* to 100 cells), then this value should be used. In this mode, a group is
* created that contains the VML. This allows for accurate panning and is
* mapped to DIALECT_VML.
*
* Example:
*
* To create a graph inside a DOM node with an id of graph:
* (code)
* var container = document.getElementById('graph');
* var graph = new mxGraph(container);
* (end)
*
* Parameters:
*
* container - Optional DOM node that acts as a container for the graph.
* If this is null then the container can be initialized later using
* <init>.
* model - Optional <mxGraphModel> that constitutes the graph data.
* renderHint - Optional string that specifies the display accuracy and
* performance. Default is mxConstants.DIALECT_MIXEDHTML (for IE).
* stylesheet - Optional <mxStylesheet> to be used in the graph.
*/
function mxGraph(container, model, renderHint, stylesheet)
{
// Initializes the variable in case the prototype has been
// modified to hold some listeners (which is possible because
// the createHandlers call is executed regardless of the
// arguments passed into the ctor).
this.mouseListeners = null;
// Converts the renderHint into a dialect
this.renderHint = renderHint;
if (mxClient.IS_SVG)
{
this.dialect = mxConstants.DIALECT_SVG;
}
else if (renderHint == mxConstants.RENDERING_HINT_EXACT && mxClient.IS_VML)
{
this.dialect = mxConstants.DIALECT_VML;
}
else if (renderHint == mxConstants.RENDERING_HINT_FASTEST)
{
this.dialect = mxConstants.DIALECT_STRICTHTML;
}
else if (renderHint == mxConstants.RENDERING_HINT_FASTER)
{
this.dialect = mxConstants.DIALECT_PREFERHTML;
}
else // default for VML
{
this.dialect = mxConstants.DIALECT_MIXEDHTML;
}
// Initializes the main members that do not require a container
this.model = (model != null) ? model : new mxGraphModel();
this.multiplicities = [];
this.imageBundles = [];
this.cellRenderer = this.createCellRenderer();
this.setSelectionModel(this.createSelectionModel());
this.setStylesheet((stylesheet != null) ? stylesheet : this.createStylesheet());
this.view = this.createGraphView();
// Adds a graph model listener to update the view
this.graphModelChangeListener = mxUtils.bind(this, function(sender, evt)
{
this.graphModelChanged(evt.getProperty('edit').changes);
});
this.model.addListener(mxEvent.CHANGE, this.graphModelChangeListener);
// Installs basic event handlers with disabled default settings.
this.createHandlers();
// Initializes the display if a container was specified
if (container != null)
{
this.init(container);
}
this.view.revalidate();
};
/**
* Installs the required language resources at class
* loading time.
*/
if (mxLoadResources)
{
mxResources.add(mxClient.basePath + '/resources/graph');
}
else
{
mxClient.defaultBundles.push(mxClient.basePath + '/resources/graph');
}
/**
* Extends mxEventSource.
*/
mxGraph.prototype = new mxEventSource();
mxGraph.prototype.constructor = mxGraph;
/**
* Group: Variables
*/
/**
* Variable: mouseListeners
*
* Holds the mouse event listeners. See <fireMouseEvent>.
*/
mxGraph.prototype.mouseListeners = null;
/**
* Variable: isMouseDown
*
* Holds the state of the mouse button.
*/
mxGraph.prototype.isMouseDown = false;
/**
* Variable: model
*
* Holds the <mxGraphModel> that contains the cells to be displayed.
*/
mxGraph.prototype.model = null;
/**
* Variable: view
*
* Holds the <mxGraphView> that caches the <mxCellStates> for the cells.
*/
mxGraph.prototype.view = null;
/**
* Variable: stylesheet
*
* Holds the <mxStylesheet> that defines the appearance of the cells.
*
*
* Example:
*
* Use the following code to read a stylesheet into an existing graph.
*
* (code)
* var req = mxUtils.load('stylesheet.xml');
* var root = req.getDocumentElement();
* var dec = new mxCodec(root.ownerDocument);
* dec.decode(root, graph.stylesheet);
* (end)
*/
mxGraph.prototype.stylesheet = null;
/**
* Variable: selectionModel
*
* Holds the <mxGraphSelectionModel> that models the current selection.
*/
mxGraph.prototype.selectionModel = null;
/**
* Variable: cellEditor
*
* Holds the <mxCellEditor> that is used as the in-place editing.
*/
mxGraph.prototype.cellEditor = null;
/**
* Variable: cellRenderer
*
* Holds the <mxCellRenderer> for rendering the cells in the graph.
*/
mxGraph.prototype.cellRenderer = null;
/**
* Variable: multiplicities
*
* An array of <mxMultiplicities> describing the allowed
* connections in a graph.
*/
mxGraph.prototype.multiplicities = null;
/**
* Variable: renderHint
*
* RenderHint as it was passed to the constructor.
*/
mxGraph.prototype.renderHint = null;
/**
* Variable: dialect
*
* Dialect to be used for drawing the graph. Possible values are all
* constants in <mxConstants> with a DIALECT-prefix.
*/
mxGraph.prototype.dialect = null;
/**
* Variable: gridSize
*
* Specifies the grid size. Default is 10.
*/
mxGraph.prototype.gridSize = 10;
/**
* Variable: gridEnabled
*
* Specifies if the grid is enabled. This is used in <snap>. Default is
* true.
*/
mxGraph.prototype.gridEnabled = true;
/**
* Variable: portsEnabled
*
* Specifies if ports are enabled. This is used in <cellConnected> to update
* the respective style. Default is true.
*/
mxGraph.prototype.portsEnabled = true;
/**
* Variable: nativeDoubleClickEnabled
*
* Specifies if native double click events should be detected. Default is true.
*/
mxGraph.prototype.nativeDblClickEnabled = true;
/**
* Variable: doubleTapEnabled
*
* Specifies if double taps on touch-based devices should be handled as a
* double click. Default is true.
*/
mxGraph.prototype.doubleTapEnabled = true;
/**
* Variable: doubleTapTimeout
*
* Specifies the timeout for double taps and non-native double clicks. Default
* is 500 ms.
*/
mxGraph.prototype.doubleTapTimeout = 500;
/**
* Variable: doubleTapTolerance
*
* Specifies the tolerance for double taps and double clicks in quirks mode.
* Default is 25 pixels.
*/
mxGraph.prototype.doubleTapTolerance = 25;
/**
* Variable: lastTouchX
*
* Holds the x-coordinate of the last touch event for double tap detection.
*/
mxGraph.prototype.lastTouchY = 0;
/**
* Variable: lastTouchX
*
* Holds the y-coordinate of the last touch event for double tap detection.
*/
mxGraph.prototype.lastTouchY = 0;
/**
* Variable: lastTouchTime
*
* Holds the time of the last touch event for double click detection.
*/
mxGraph.prototype.lastTouchTime = 0;
/**
* Variable: tapAndHoldEnabled
*
* Specifies if tap and hold should be used for starting connections on touch-based
* devices. Default is true.
*/
mxGraph.prototype.tapAndHoldEnabled = true;
/**
* Variable: tapAndHoldDelay
*
* Specifies the time for a tap and hold. Default is 500 ms.
*/
mxGraph.prototype.tapAndHoldDelay = 500;
/**
* Variable: tapAndHoldInProgress
*
* True if the timer for tap and hold events is running.
*/
mxGraph.prototype.tapAndHoldInProgress = false;
/**
* Variable: tapAndHoldValid
*
* True as long as the timer is running and the touch events
* stay within the given <tapAndHoldTolerance>.
*/
mxGraph.prototype.tapAndHoldValid = false;
/**
* Variable: initialTouchX
*
* Holds the x-coordinate of the intial touch event for tap and hold.
*/
mxGraph.prototype.initialTouchX = 0;
/**
* Variable: initialTouchY
*
* Holds the y-coordinate of the intial touch event for tap and hold.
*/
mxGraph.prototype.initialTouchY = 0;
/**
* Variable: tolerance
*
* Tolerance for a move to be handled as a single click.
* Default is 4 pixels.
*/
mxGraph.prototype.tolerance = 4;
/**
* Variable: defaultOverlap
*
* Value returned by <getOverlap> if <isAllowOverlapParent> returns
* true for the given cell. <getOverlap> is used in <constrainChild> if
* <isConstrainChild> returns true. The value specifies the
* portion of the child which is allowed to overlap the parent.
*/
mxGraph.prototype.defaultOverlap = 0.5;
/**
* Variable: defaultParent
*
* Specifies the default parent to be used to insert new cells.
* This is used in <getDefaultParent>. Default is null.
*/
mxGraph.prototype.defaultParent = null;
/**
* Variable: alternateEdgeStyle
*
* Specifies the alternate edge style to be used if the main control point
* on an edge is being doubleclicked. Default is null.
*/
mxGraph.prototype.alternateEdgeStyle = null;
/**
* Variable: backgroundImage
*
* Specifies the <mxImage> to be returned by <getBackgroundImage>. Default
* is null.
*
* Example:
*
* (code)
* var img = new mxImage('http://www.example.com/maps/examplemap.jpg', 1024, 768);
* graph.setBackgroundImage(img);
* graph.view.validate();
* (end)
*/
mxGraph.prototype.backgroundImage = null;
/**
* Variable: pageVisible
*
* Specifies if the background page should be visible. Default is false.
* Not yet implemented.
*/
mxGraph.prototype.pageVisible = false;
/**
* Variable: pageBreaksVisible
*
* Specifies if a dashed line should be drawn between multiple pages. Default
* is false. If you change this value while a graph is being displayed then you
* should call <sizeDidChange> to force an update of the display.
*/
mxGraph.prototype.pageBreaksVisible = false;
/**
* Variable: pageBreakColor
*
* Specifies the color for page breaks. Default is 'gray'.
*/
mxGraph.prototype.pageBreakColor = 'gray';
/**
* Variable: pageBreakDashed
*
* Specifies the page breaks should be dashed. Default is true.
*/
mxGraph.prototype.pageBreakDashed = true;
/**
* Variable: minPageBreakDist
*
* Specifies the minimum distance for page breaks to be visible. Default is
* 20 (in pixels).
*/
mxGraph.prototype.minPageBreakDist = 20;
/**
* Variable: preferPageSize
*
* Specifies if the graph size should be rounded to the next page number in
* <sizeDidChange>. This is only used if the graph container has scrollbars.
* Default is false.
*/
mxGraph.prototype.preferPageSize = false;
/**
* Variable: pageFormat
*
* Specifies the page format for the background page. Default is
* <mxConstants.PAGE_FORMAT_A4_PORTRAIT>. This is used as the default in
* <mxPrintPreview> and for painting the background page if <pageVisible> is
* true and the pagebreaks if <pageBreaksVisible> is true.
*/
mxGraph.prototype.pageFormat = mxConstants.PAGE_FORMAT_A4_PORTRAIT;
/**
* Variable: pageScale
*
* Specifies the scale of the background page. Default is 1.5.
* Not yet implemented.
*/
mxGraph.prototype.pageScale = 1.5;
/**
* Variable: enabled
*
* Specifies the return value for <isEnabled>. Default is true.
*/
mxGraph.prototype.enabled = true;
/**
* Variable: escapeEnabled
*
* Specifies if <mxKeyHandler> should invoke <escape> when the escape key
* is pressed. Default is true.
*/
mxGraph.prototype.escapeEnabled = true;
/**
* Variable: invokesStopCellEditing
*
* If true, when editing is to be stopped by way of selection changing,
* data in diagram changing or other means stopCellEditing is invoked, and
* changes are saved. This is implemented in a focus handler in
* <mxCellEditor>. Default is true.
*/
mxGraph.prototype.invokesStopCellEditing = true;
/**
* Variable: enterStopsCellEditing
*
* If true, pressing the enter key without pressing control or shift will stop
* editing and accept the new value. This is used in <mxCellEditor> to stop
* cell editing. Note: You can always use F2 and escape to stop editing.
* Default is false.
*/
mxGraph.prototype.enterStopsCellEditing = false;
/**
* Variable: useScrollbarsForPanning
*
* Specifies if scrollbars should be used for panning in <panGraph> if
* any scrollbars are available. If scrollbars are enabled in CSS, but no
* scrollbars appear because the graph is smaller than the container size,
* then no panning occurs if this is true. Default is true.
*/
mxGraph.prototype.useScrollbarsForPanning = true;
/**
* Variable: exportEnabled
*
* Specifies the return value for <canExportCell>. Default is true.
*/
mxGraph.prototype.exportEnabled = true;
/**
* Variable: importEnabled
*
* Specifies the return value for <canImportCell>. Default is true.
*/
mxGraph.prototype.importEnabled = true;
/**
* Variable: cellsLocked
*
* Specifies the return value for <isCellLocked>. Default is false.
*/
mxGraph.prototype.cellsLocked = false;
/**
* Variable: cellsCloneable
*
* Specifies the return value for <isCellCloneable>. Default is true.
*/
mxGraph.prototype.cellsCloneable = true;
/**
* Variable: foldingEnabled
*
* Specifies if folding (collapse and expand via an image icon in the graph
* should be enabled). Default is true.
*/
mxGraph.prototype.foldingEnabled = true;
/**
* Variable: cellsEditable
*
* Specifies the return value for <isCellEditable>. Default is true.
*/
mxGraph.prototype.cellsEditable = true;
/**
* Variable: cellsDeletable
*
* Specifies the return value for <isCellDeletable>. Default is true.
*/
mxGraph.prototype.cellsDeletable = true;
/**
* Variable: cellsMovable
*
* Specifies the return value for <isCellMovable>. Default is true.
*/
mxGraph.prototype.cellsMovable = true;
/**
* Variable: edgeLabelsMovable
*
* Specifies the return value for edges in <isLabelMovable>. Default is true.
*/
mxGraph.prototype.edgeLabelsMovable = true;
/**
* Variable: vertexLabelsMovable
*
* Specifies the return value for vertices in <isLabelMovable>. Default is false.
*/
mxGraph.prototype.vertexLabelsMovable = false;
/**
* Variable: dropEnabled
*
* Specifies the return value for <isDropEnabled>. Default is false.
*/
mxGraph.prototype.dropEnabled = false;
/**
* Variable: splitEnabled
*
* Specifies if dropping onto edges should be enabled. This is ignored if
* <dropEnabled> is false. If enabled, it will call <splitEdge> to carry
* out the drop operation. Default is true.
*/
mxGraph.prototype.splitEnabled = true;
/**
* Variable: cellsResizable
*
* Specifies the return value for <isCellResizable>. Default is true.
*/
mxGraph.prototype.cellsResizable = true;
/**
* Variable: cellsBendable
*
* Specifies the return value for <isCellsBendable>. Default is true.
*/
mxGraph.prototype.cellsBendable = true;
/**
* Variable: cellsSelectable
*
* Specifies the return value for <isCellSelectable>. Default is true.
*/
mxGraph.prototype.cellsSelectable = true;
/**
* Variable: cellsDisconnectable
*
* Specifies the return value for <isCellDisconntable>. Default is true.
*/
mxGraph.prototype.cellsDisconnectable = true;
/**
* Variable: autoSizeCells
*
* Specifies if the graph should automatically update the cell size after an
* edit. This is used in <isAutoSizeCell>. Default is false.
*/
mxGraph.prototype.autoSizeCells = false;
/**
* Variable: autoSizeCellsOnAdd
*
* Specifies if autoSize style should be applied when cells are added. Default is false.
*/
mxGraph.prototype.autoSizeCellsOnAdd = false;
/**
* Variable: autoScroll
*
* Specifies if the graph should automatically scroll if the mouse goes near
* the container edge while dragging. This is only taken into account if the
* container has scrollbars. Default is true.
*
* If you need this to work without scrollbars then set <ignoreScrollbars> to
* true. Please consult the <ignoreScrollbars> for details. In general, with
* no scrollbars, the use of <allowAutoPanning> is recommended.
*/
mxGraph.prototype.autoScroll = true;
/**
* Variable: ignoreScrollbars
*
* Specifies if the graph should automatically scroll regardless of the
* scrollbars. This will scroll the container using positive values for
* scroll positions (ie usually only rightwards and downwards). To avoid
* possible conflicts with panning, set <translateToScrollPosition> to true.
*/
mxGraph.prototype.ignoreScrollbars = false;
/**
* Variable: translateToScrollPosition
*
* Specifies if the graph should automatically convert the current scroll
* position to a translate in the graph view when a mouseUp event is received.
* This can be used to avoid conflicts when using <autoScroll> and
* <ignoreScrollbars> with no scrollbars in the container.
*/
mxGraph.prototype.translateToScrollPosition = false;
/**
* Variable: timerAutoScroll
*
* Specifies if autoscrolling should be carried out via mxPanningManager even
* if the container has scrollbars. This disables <scrollPointToVisible> and
* uses <mxPanningManager> instead. If this is true then <autoExtend> is
* disabled. It should only be used with a scroll buffer or when scollbars
* are visible and scrollable in all directions. Default is false.
*/
mxGraph.prototype.timerAutoScroll = false;
/**
* Variable: allowAutoPanning
*
* Specifies if panning via <panGraph> should be allowed to implement autoscroll
* if no scrollbars are available in <scrollPointToVisible>. To enable panning
* inside the container, near the edge, set <mxPanningManager.border> to a
* positive value. Default is false.
*/
mxGraph.prototype.allowAutoPanning = false;
/**
* Variable: autoExtend
*
* Specifies if the size of the graph should be automatically extended if the
* mouse goes near the container edge while dragging. This is only taken into
* account if the container has scrollbars. Default is true. See <autoScroll>.
*/
mxGraph.prototype.autoExtend = true;
/**
* Variable: maximumGraphBounds
*
* <mxRectangle> that specifies the area in which all cells in the diagram
* should be placed. Uses in <getMaximumGraphBounds>. Use a width or height of
* 0 if you only want to give a upper, left corner.
*/
mxGraph.prototype.maximumGraphBounds = null;
/**
* Variable: minimumGraphSize
*
* <mxRectangle> that specifies the minimum size of the graph. This is ignored
* if the graph container has no scrollbars. Default is null.
*/
mxGraph.prototype.minimumGraphSize = null;
/**
* Variable: minimumContainerSize
*
* <mxRectangle> that specifies the minimum size of the <container> if
* <resizeContainer> is true.
*/
mxGraph.prototype.minimumContainerSize = null;
/**
* Variable: maximumContainerSize
*
* <mxRectangle> that specifies the maximum size of the container if
* <resizeContainer> is true.
*/
mxGraph.prototype.maximumContainerSize = null;
/**
* Variable: resizeContainer
*
* Specifies if the container should be resized to the graph size when
* the graph size has changed. Default is false.
*/
mxGraph.prototype.resizeContainer = false;
/**
* Variable: border
*
* Border to be added to the bottom and right side when the container is
* being resized after the graph has been changed. Default is 0.
*/
mxGraph.prototype.border = 0;
/**
* Variable: keepEdgesInForeground
*
* Specifies if edges should appear in the foreground regardless of their order
* in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
* both true then the normal order is applied. Default is false.
*/
mxGraph.prototype.keepEdgesInForeground = false;
/**
* Variable: keepEdgesInBackground
*
* Specifies if edges should appear in the background regardless of their order
* in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
* both true then the normal order is applied. Default is false.
*/
mxGraph.prototype.keepEdgesInBackground = false;
/**
* Variable: allowNegativeCoordinates
*
* Specifies if negative coordinates for vertices are allowed. Default is true.
*/
mxGraph.prototype.allowNegativeCoordinates = true;
/**
* Variable: constrainChildren
*
* Specifies if a child should be constrained inside the parent bounds after a
* move or resize of the child. Default is true.
*/
mxGraph.prototype.constrainChildren = true;
/**
* Variable: constrainRelativeChildren
*
* Specifies if child cells with relative geometries should be constrained
* inside the parent bounds, if <constrainChildren> is true, and/or the
* <maximumGraphBounds>. Default is false.
*/
mxGraph.prototype.constrainRelativeChildren = false;
/**
* Variable: extendParents
*
* Specifies if a parent should contain the child bounds after a resize of
* the child. Default is true. This has precedence over <constrainChildren>.
*/
mxGraph.prototype.extendParents = true;
/**
* Variable: extendParentsOnAdd
*
* Specifies if parents should be extended according to the <extendParents>
* switch if cells are added. Default is true.
*/
mxGraph.prototype.extendParentsOnAdd = true;
/**
* Variable: extendParentsOnAdd
*
* Specifies if parents should be extended according to the <extendParents>
* switch if cells are added. Default is false for backwards compatiblity.
*/
mxGraph.prototype.extendParentsOnMove = false;
/**
* Variable: recursiveResize
*
* Specifies the return value for <isRecursiveResize>. Default is
* false for backwards compatiblity.
*/
mxGraph.prototype.recursiveResize = false;
/**
* Variable: collapseToPreferredSize
*
* Specifies if the cell size should be changed to the preferred size when
* a cell is first collapsed. Default is true.
*/
mxGraph.prototype.collapseToPreferredSize = true;
/**
* Variable: zoomFactor
*
* Specifies the factor used for <zoomIn> and <zoomOut>. Default is 1.2
* (120%).
*/
mxGraph.prototype.zoomFactor = 1.2;
/**
* Variable: keepSelectionVisibleOnZoom
*
* Specifies if the viewport should automatically contain the selection cells
* after a zoom operation. Default is false.
*/
mxGraph.prototype.keepSelectionVisibleOnZoom = false;
/**
* Variable: centerZoom
*
* Specifies if the zoom operations should go into the center of the actual
* diagram rather than going from top, left. Default is true.
*/
mxGraph.prototype.centerZoom = true;
/**
* Variable: resetViewOnRootChange
*
* Specifies if the scale and translate should be reset if the root changes in
* the model. Default is true.
*/
mxGraph.prototype.resetViewOnRootChange = true;
/**
* Variable: resetEdgesOnResize
*
* Specifies if edge control points should be reset after the resize of a
* connected cell. Default is false.
*/
mxGraph.prototype.resetEdgesOnResize = false;
/**
* Variable: resetEdgesOnMove
*
* Specifies if edge control points should be reset after the move of a
* connected cell. Default is false.
*/
mxGraph.prototype.resetEdgesOnMove = false;
/**
* Variable: resetEdgesOnConnect
*
* Specifies if edge control points should be reset after the the edge has been
* reconnected. Default is true.
*/
mxGraph.prototype.resetEdgesOnConnect = true;
/**
* Variable: allowLoops
*
* Specifies if loops (aka self-references) are allowed. Default is false.
*/
mxGraph.prototype.allowLoops = false;
/**
* Variable: defaultLoopStyle
*
* <mxEdgeStyle> to be used for loops. This is a fallback for loops if the
* <mxConstants.STYLE_LOOP> is undefined. Default is <mxEdgeStyle.Loop>.
*/
mxGraph.prototype.defaultLoopStyle = mxEdgeStyle.Loop;
/**
* Variable: multigraph
*
* Specifies if multiple edges in the same direction between the same pair of
* vertices are allowed. Default is true.
*/
mxGraph.prototype.multigraph = true;
/**
* Variable: connectableEdges
*
* Specifies if edges are connectable. Default is false. This overrides the
* connectable field in edges.
*/
mxGraph.prototype.connectableEdges = false;
/**
* Variable: allowDanglingEdges
*
* Specifies if edges with disconnected terminals are allowed in the graph.
* Default is true.
*/
mxGraph.prototype.allowDanglingEdges = true;
/**
* Variable: cloneInvalidEdges
*
* Specifies if edges that are cloned should be validated and only inserted
* if they are valid. Default is true.
*/
mxGraph.prototype.cloneInvalidEdges = false;
/**
* Variable: disconnectOnMove
*
* Specifies if edges should be disconnected from their terminals when they
* are moved. Default is true.
*/
mxGraph.prototype.disconnectOnMove = true;
/**
* Variable: labelsVisible
*
* Specifies if labels should be visible. This is used in <getLabel>. Default
* is true.
*/
mxGraph.prototype.labelsVisible = true;
/**
* Variable: htmlLabels
*
* Specifies the return value for <isHtmlLabel>. Default is false.
*/
mxGraph.prototype.htmlLabels = false;
/**
* Variable: swimlaneSelectionEnabled
*
* Specifies if swimlanes should be selectable via the content if the
* mouse is released. Default is true.
*/
mxGraph.prototype.swimlaneSelectionEnabled = true;
/**
* Variable: swimlaneNesting
*
* Specifies if nesting of swimlanes is allowed. Default is true.
*/
mxGraph.prototype.swimlaneNesting = true;
/**
* Variable: swimlaneIndicatorColorAttribute
*
* The attribute used to find the color for the indicator if the indicator
* color is set to 'swimlane'. Default is <mxConstants.STYLE_FILLCOLOR>.
*/
mxGraph.prototype.swimlaneIndicatorColorAttribute = mxConstants.STYLE_FILLCOLOR;
/**
* Variable: imageBundles
*
* Holds the list of image bundles.
*/
mxGraph.prototype.imageBundles = null;
/**
* Variable: minFitScale
*
* Specifies the minimum scale to be applied in <fit>. Default is 0.1. Set this
* to null to allow any value.
*/
mxGraph.prototype.minFitScale = 0.1;
/**
* Variable: maxFitScale
*
* Specifies the maximum scale to be applied in <fit>. Defau