diff --git a/README.md b/README.md index 6f7b72bd9b..d60c5a7768 100644 --- a/README.md +++ b/README.md @@ -129,16 +129,7 @@ You will see something like in the following _maxGraph panning_ demo: The maxGraph documentation is available on the [maxGraph website](https://maxgraph.github.io/maxGraph). > [!WARNING] -> This is a **work in progress**, the content of the original _mxGraph_ documentation will be progressively migrated there. -> For more details, see [#345](https://github.com/maxGraph/maxGraph/issues/345). - -Documentation partially migrated: -- https://maxgraph.github.io/maxGraph/docs/manual/ - -Documentation to be migrated: -- https://jgraph.github.io/mxgraph/docs/tutorial.html - -> Be aware that the maxGraph API doesn't fully match the mxGraph API (see the paragraph below about "[Migrating from mxGraph](#migrate-from-mxgraph)"). +> This is a **work in progress**, the content will be progressively improved. ## Examples diff --git a/packages/core/src/util/MaxXmlRequest.ts b/packages/core/src/util/MaxXmlRequest.ts index 2cd50a6738..8f5852f047 100644 --- a/packages/core/src/util/MaxXmlRequest.ts +++ b/packages/core/src/util/MaxXmlRequest.ts @@ -344,7 +344,7 @@ class MaxXmlRequest { const params = this.params; const pars = params.indexOf('&') > 0 ? params.split('&') : params.split(' '); - // Adds the parameters as textareas to the form + // Adds the parameters as text areas to the form for (let i = 0; i < pars.length; i += 1) { const pos = pars[i].indexOf('='); @@ -378,57 +378,51 @@ class MaxXmlRequest { } /** - * Loads the specified URL *synchronously* and returns the . - * Throws an exception if the file cannot be loaded. See {@link Utils#get} for - * an asynchronous implementation. + * Loads the specified URL *synchronously* and returns the {@link MaxXmlRequest}. + * Throws an exception if the file cannot be loaded. + * See {@link get} for an asynchronous implementation. * * Example: * * ```javascript - * try - * { - * let req = mxUtils.load(filename); - * let root = req.getDocumentElement(); + * try { + * const req = load(filename); + * cont root = req.getDocumentElement(); * // Process XML DOM... - * } - * catch (ex) - * { - * mxUtils.alert('Cannot load '+filename+': '+ex); + * } catch (e) { + * console.error(`Cannot load $filename`, e); * } * ``` * * @param url URL to get the data from. */ -export const load = (url: string) => { +export const load = (url: string): MaxXmlRequest => { const req = new MaxXmlRequest(url, null, 'GET', false); req.send(); return req; }; /** - * Loads the specified URL *asynchronously* and invokes the given functions - * depending on the request status. Returns the in use. Both - * functions take the as the only parameter. See - * {@link Utils#load} for a synchronous implementation. + * Loads the specified URL *asynchronously* and invokes the given functions depending on the request status. + * Returns the {@link MaxXmlRequest} in use. + * Both functions take the {@link MaxXmlRequest} as the only parameter. + * See {@link load} for a synchronous implementation. * * Example: * * ```javascript - * mxUtils.get(url, (req)=> - * { - * let node = req.getDocumentElement(); + * get(url, (req) => { + * const node = req.getDocumentElement(); * // Process XML DOM... * }); * ``` * - * So for example, to load a diagram into an existing graph model, the - * following code is used. + * So for example, to load a diagram into an existing graph model, the following code is used. * * ```javascript - * mxUtils.get(url, (req)=> - * { - * let node = req.getDocumentElement(); - * let dec = new Codec(node.ownerDocument); + * get(url, (req) => { + * const node = req.getDocumentElement(); + * const dec = new Codec(node.ownerDocument); * dec.decode(node, graph.getDataModel()); * }); * ``` diff --git a/packages/website/docs/development/_category_.json b/packages/website/docs/development/_category_.json index f0bc30e91e..92ba297833 100644 --- a/packages/website/docs/development/_category_.json +++ b/packages/website/docs/development/_category_.json @@ -1,6 +1,6 @@ { "label": "Development", - "position": 13, + "position": 21, "link": { "type": "generated-index", "description": "Everything you need to know when you are developing maxGraph." diff --git a/packages/website/docs/intro.md b/packages/website/docs/intro.md index 66562c1990..c999c8fab0 100644 --- a/packages/website/docs/intro.md +++ b/packages/website/docs/intro.md @@ -18,14 +18,6 @@ which requires finer-grained customization of functionality than off-the-shelf p ## About this documentation -:::warning - -This documentation is a **work in progress**. - -Please be patient, as content will be gradually updated, especially the content of the original `mxGraph` documentation. - -::: - :::tip The documentation hosted at https://maxgraph.github.io/maxGraph includes the latest development changes. diff --git a/packages/website/docs/known-issues.md b/packages/website/docs/known-issues.md index 527f7b8245..751211423a 100644 --- a/packages/website/docs/known-issues.md +++ b/packages/website/docs/known-issues.md @@ -1,5 +1,5 @@ --- -sidebar_position: 20 +sidebar_position: 100 --- # Known Issues diff --git a/packages/website/docs/tutorials/_category_.json b/packages/website/docs/tutorials/_category_.json new file mode 100644 index 0000000000..77b4fe8ba9 --- /dev/null +++ b/packages/website/docs/tutorials/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Tutorials", + "position": 12, + "link": { + "type": "generated-index", + "description": "Everything you need to know to use specific features of maxGraph." + } +} diff --git a/packages/website/old-mxgraph/images/editor.png b/packages/website/docs/tutorials/assets/graphs/editor.png similarity index 100% rename from packages/website/old-mxgraph/images/editor.png rename to packages/website/docs/tutorials/assets/graphs/editor.png diff --git a/packages/website/old-mxgraph/images/graph.png b/packages/website/docs/tutorials/assets/graphs/graph.png similarity index 100% rename from packages/website/old-mxgraph/images/graph.png rename to packages/website/docs/tutorials/assets/graphs/graph.png diff --git a/packages/website/old-mxgraph/images/model.png b/packages/website/docs/tutorials/assets/graphs/model.png similarity index 100% rename from packages/website/old-mxgraph/images/model.png rename to packages/website/docs/tutorials/assets/graphs/model.png diff --git a/packages/website/docs/tutorials/assets/hello-world-example.png b/packages/website/docs/tutorials/assets/hello-world-example.png new file mode 100644 index 0000000000..71cf6d0286 Binary files /dev/null and b/packages/website/docs/tutorials/assets/hello-world-example.png differ diff --git a/packages/website/docs/tutorials/editor-input-output.md b/packages/website/docs/tutorials/editor-input-output.md new file mode 100644 index 0000000000..793c03f4b6 --- /dev/null +++ b/packages/website/docs/tutorials/editor-input-output.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 4 +description: Learn how to save and open Editor data stored in a XML file. +--- + +# Editor Input/Output + +:::note + +This tutorial is licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). \ +It is adapted from the original [mxGraph tutorial](https://github.com/jgraph/mxgraph/blob/v4.2.2/docs/tutorial.html). + +> Copyright 2021-present The maxGraph project Contributors \ +Copyright (c) JGraph Ltd 2006-2017 + +::: + + +## Codecs + +See the dedicated [codecs page](../usage/codecs.md) for more information on how to use codecs. + +For encoding other objects, or if no editor instance is available, the [Codec](https://maxgraph.github.io/maxGraph/api-docs/classes/Codec.html) can be used to create and read XML data. + + + +## Files + +The `save`, `open`, `readGraphModel` and `writeGraphModel` functions implement a standard mechanism for handling files in [Editor](https://maxgraph.github.io/maxGraph/api-docs/classes/Editor.html). + +The default implementation of `Editor.save` is called with an argument to indicate if the save was triggered by the user or by the system. +It then uses the `urlPost` variable of the editor object to check if a post request should be issued. +If the variable is defined, the editor issues a post request to the specified URL passing the XML along as a POST variable called xml. + + + +## Post + +As an example, consider the following PHP file which is located in the same directory as the HTML page. +If the filename is `server.php` then the `urlPost` variable must be set to `server.php` on the editor in order to post the diagram to the server. +The PHP file will get the XML from the POST request and write it to a file called `diagram.xml`. + +```php + +``` + +To set the URL to post to, change the respective entry in the `Editor` node of the config file as follows: + +```xml + +``` + +Keep in mind that the JavaScript can only post to the server where it originated from, so we recommend to use relative URLs, e.g. `server.php`. + + +## Form Fields + +If you need to read/write the graph from/to a string (e.g. to fill a form-field), you can use the following methods: + +```javascript +const data = editor.writeGraphModel(); +editor.readGraphModel(xmlUtils.parseXml(data)); +``` diff --git a/packages/website/docs/tutorials/editor.md b/packages/website/docs/tutorials/editor.md new file mode 100644 index 0000000000..28a8b7db08 --- /dev/null +++ b/packages/website/docs/tutorials/editor.md @@ -0,0 +1,115 @@ +--- +sidebar_position: 3 +description: Learn how to use the maxGraph Editor. +--- + +# Editor + +:::warning + +The content of this page is a **work in progress**. +The original `mxGraph` tutorial was used to create this page which still contains `mxGraph` class diagrams to migrate to the maxGraph API. + +::: + +:::note + +This tutorial is licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). \ +It is adapted from the original [mxGraph tutorial](https://github.com/jgraph/mxgraph/blob/v4.2.2/docs/tutorial.html). + +> Copyright 2021-present The maxGraph project Contributors \ +Copyright (c) JGraph Ltd 2006-2017 + +::: + + +Instantiate [Editor](https://maxgraph.github.io/maxGraph/api-docs/classes/Editor.html) in order to create an editor. +This is the central class in the editor package. Everything else in this package is auxiliary. + +To create a new editor instance and configure it using a config file, you can pass the name of the config file to the +[Editor constructor](https://maxgraph.github.io/maxGraph/api-docs/classes/Editor.html). + +![Class diagram showing the Editor class hierarchy and its relationships](assets/graphs/editor.png) + +To create a new editor instance and configure it, the following code is used: + +```javascript +import { load } from '@maxgraph/core'; +const config = load('editors/config/keyhandler-commons.xml').getDocumentElement(); +const editor = new Editor(config); +``` + +The configuration file is an XML file that is passed to [Codec](https://maxgraph.github.io/maxGraph/api-docs/classes/Codec.html), +which in turn uses [EditorCodec](https://maxgraph.github.io/maxGraph/api-docs/classes/EditorCodec.html) and others to read the XML into the editor object hierarchy. + +This is normally done at startup time to configure the editor, graph, model, toolbar, popupmenus, etc. using the [I/O subsystem](./editor-input-output.md). + + + +## CSS + +The CSS stylesheet contains the style definitions for various elements of the user interface, such as the rubberband selection, +the in-place editor or the popup menu. + +Additional stylesheets may either be added via a stylesheet tag of the UI section in the editor configuration, e.g.: + + +```xml + + + + + +``` + + + +## Templates + +To add new cell types, create a template in the templates array section of the model in the config file (Editor/Graph/GraphDataModel/Array[as=templates]) as follows: + +```xml + + + + + + + + + + + + + +``` + +The `as`-attribute of the `add`-element contains the name under which the template will be accessible for later use. +The `Symbol`-child element is a custom (ie workflow) element, and can have any name and any number of child elements and custom attributes. + +The label attribute is a special one that is used for the textual representation of the cell in the graph. +The `Cell` element is another special child node which contains the graphical information for the cell, namely, the cell-type, -style, -size and -position. + +See `Graph.convertValueToString` if you would like to use another attribute or a combination of attributes for the textual representation, +and `Cell.valueChanged` to handle in-place editing by storing the new text value in the respective attribute(s). + + + +## Toolbar + + +To use the template in the graph, a toolbar item must be added which refers to the template in the `DefaultToolbar` section +of the config file (Editor/DefaultToolbar[as=toolbar]) as follows: + +```xml + +``` + +The `as` attribute specifies the tooltip to be displayed for the icon in the toolbar, the `template`-attribute refers to the name under which the template was previously added. +The `style`- attribute is optional, and may be used to override the style defined in the template definition. +Finally, the icon specifies the icon to be used for the toolbar item. + +Note that the `as` attribute is assumed to be the key for a language resource, in this case `symbolTool`. +If the resource is not defined in [Translations resources](https://maxgraph.github.io/maxGraph/api-docs/classes/Translations.html#resources), then the attribute value is used as the label. diff --git a/packages/website/docs/tutorials/graph.md b/packages/website/docs/tutorials/graph.md new file mode 100644 index 0000000000..ca9d5508b9 --- /dev/null +++ b/packages/website/docs/tutorials/graph.md @@ -0,0 +1,136 @@ +--- +sidebar_position: 2 +description: Learn how to instantiate your first Graph. +--- + +# Graph + +:::warning + +The content of this page is a **work in progress**. +The original `mxGraph` tutorial was used to create this page which still contains `mxGraph` class diagrams to migrate to the maxGraph API. + +::: + +:::note + +This tutorial is licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). \ +It is adapted from the original [mxGraph tutorial](https://github.com/jgraph/mxgraph/blob/v4.2.2/docs/tutorial.html). + +> Copyright 2021-present The maxGraph project Contributors \ +Copyright (c) JGraph Ltd 2006-2017 + +::: + + +Instantiate [Graph](https://maxgraph.github.io/maxGraph/api-docs/classes/Graph.html) in order to create a graph. This is the central class in the API. +Everything else is auxiliary. + +![The Graph class hierarchy](assets/graphs/graph.png) + +To create a new graph instance, a DOM node (typically a DIV) is required: + +```javascript +const node = document.getElementById('id-of-graph-container'); +const graph = new Graph(node); +``` + + +## Model + +[Cell](https://maxgraph.github.io/maxGraph/api-docs/classes/Cell.html) defines the elements of the graph model, which is implemented by [GraphDataModel](https://maxgraph.github.io/maxGraph/api-docs/classes/GraphDataModel.html). + +![Class diagram showing the relationship between Cell and GraphDataModel classes](assets/graphs/model.png) + +The graph model has the following properties: +* The root element of the graph contains the layers. The parent of each layer is the root element. +* A layer may contain elements of the graph model, namely vertices, edges and groups. +* Groups may contain elements of the graph model, recursively. + +The graph and structural information is stored in the cells, as well as the _user objects_, +which are used to store the _value_ associated with the cells (aka business objects). + +To create a new graph model with a root cell and a default layer (first child): + +```javascript +const root = new Cell(); +root.insert(new Cell()); +const model = new GraphDataModel(root); +``` + + + +## Stylesheet + +The appearance of the cells in a graph is defined by the stylesheet, which is an instance of [Stylesheet](https://maxgraph.github.io/maxGraph/api-docs/classes/Stylesheet.html). +The stylesheet maps from style names to styles. + +A style is a [CellStateStyle object ](https://maxgraph.github.io/maxGraph/api-docs/types/CellStateStyle.html), to be used with the cells. + +To modify the default styles for vertices and edges in an existing graph: +```javascript +const vertexStyle = graph.getStylesheet().getDefaultVertexStyle(); +vertexStyle.rounded = true; + +const edgeStyle = graph.getStylesheet().getDefaultEdgeStyle(); +edgeStyle.edgeStyle = EdgeStyle.TopToBottom; +``` + + + +## Styles + +The style information for a cell is stored in `cell.style`. +The style is part of the cell's state and is normally changed via `GraphDataModel.setStyle`, which will update all views. +The cell style is a [CellStateStyle object ](https://maxgraph.github.io/maxGraph/api-docs/types/CellStateStyle.html) which tells the graph to use the given named styles and override the specified keys. + +For example, use the [Stylesheet.putCellStyle](https://maxgraph.github.io/maxGraph/api-docs/classes/Stylesheet.html#putcellstyle) method to set to `rounded` style +and override the stroke and fill colors, the style would be defined as: + +```javascript +{ + baseStyleNames: ['rounded'], + strokeColor: 'red', + fillColor: 'green' +} +``` + +To use the above in Hello, World!, the style name would be passed to the insertVertex method as follows: + +[//]: # (TODO migrate to the new insertVertex method using a single object parameter) +```javascript +const v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, + { + baseStyleNames: ['rounded'], + strokeColor: 'red', + fillColor: 'green' + } +); +``` + + + +## Appearance + +In certain cases you may want to override specific attributes based on dynamic properties of a cell (i.e. it's value, aka. `UserObject`), such as +the image, indicator shape, -image, -color or -gradient color), in which case you can override +`getImage`, `getIndicatorShape`, `getIndicatorImage`, `getIndicatorColor` and `getIndicatorGradientColor` respectively. +Note that these methods take a cell state as an argument, which points to a "resolved" version of the cell's style. + +Hence, the default implementation for `getImage`looks as follows: + +```typescript +graph.getImage = function(state: CellState) { + if (state?.style) { + return state.style.image; + } + return null; +} +``` + +This method may be overridden to return any image for the given state. +Typically, the image is defined by either `state.cell`, which points to the graph cell associated with the state, or by `state.cell.value`, +which refers to the cell's user object. + +Due to the nature of the display, where all cells are created once and updated only if the model fires a notification for a change, +you must invoke `view.invalidate(cell)` for each cell whose image has changed, and call `view.validate` to update the display. diff --git a/packages/website/docs/tutorials/the-hello-world-example.md b/packages/website/docs/tutorials/the-hello-world-example.md new file mode 100644 index 0000000000..a2e8b8088b --- /dev/null +++ b/packages/website/docs/tutorials/the-hello-world-example.md @@ -0,0 +1,82 @@ +--- +sidebar_position: 1 +description: A step-by-step guide to display a simple Graph and understand the maxGraph concepts. +--- + +# The Hello World Example + +:::note + +This tutorial is licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). \ +It is adapted from the original [mxGraph tutorial](https://github.com/jgraph/mxgraph/blob/v4.2.2/docs/tutorial.html). + +> Copyright 2021-present The maxGraph project Contributors \ +Copyright (c) JGraph Ltd 2006-2017 + +::: + + +## Hello, World! + +The _Hello, World!_ example of `maxGraph` ships in a Storybook story called `HelloWorld` which is available in the `HelloWorld` page of the [maxGraph demo](https://maxgraph.github.io/maxGraph/demo/?path=/story/basic-helloworld--default). + +The source of the example is available in [HelloWorld.stories.js](https://github.com/maxGraph/maxGraph/blob/main/packages/html/stories/HelloWorld.stories.js). + +![Screenshot of the Hello World example](./assets/hello-world-example.png) + + +## Container + +For the JavaScript to actually render the graph, the page contains an DOM node which will display the graph. +This DOM node is either dynamically created or it is obtained via an ID using `document.getElementById` as in the _Hello, World!_ example. +The DOM node is passed to the main function and is used to construct the graph instance as shown below. + +If you want the container to have scrollbars, use the `overflow:auto` CSS directive instead of overflow:hidden in the style of the container. + + + +## Graph + +The code constructs an empty graph model and passes the container and the empty model to the graph constructor. +For this example, all default event handling is disabled in the last line. + +```javascript +const model = new GraphDataModel(); +const graph = new Graph(container, model); +``` + +If you want the graph to be read-only you can use `graph.setEnabled(false)`. + + + +## Vertices and Edges + +To insert vertices and edges, `beginUpdate` and `endUpdate` are used to create a transaction. +The `endUpdate` should always go into a finally-block to make sure it is always executed if the `beginUpdate` was executed. +However, the `beginUpdate` should not be part of the try-block to make sure `endUpdate` is never executed if `beginUpdate` fails. +This is required for the model to remain in a consistent state, that is, for each call to `beginUpdate` there should always be exactly one call to `endUpdate`. + +The part within the try-block creates the vertices and edges for the graph. +The default parent is obtained from the graph and is typically the first child of the root cell in the model, +which is created automatically when using the graph model constructor with no arguments. + +```javascript +// 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 +model.beginUpdate(); +try { + const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30); + const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30); + graph.insertEdge(parent, null, '', v1, v2); +} +finally { + // Updates the display + model.endUpdate(); +} +``` + +The use of `beginUpdate` and `endUpdate` does not only improve the display performance, +but it is also used to mark the boundaries for undoable changes when undo/redo is used. diff --git a/packages/website/docs/usage/_category_.json b/packages/website/docs/usage/_category_.json index 832aeaf284..69706e6416 100644 --- a/packages/website/docs/usage/_category_.json +++ b/packages/website/docs/usage/_category_.json @@ -1,6 +1,6 @@ { "label": "Usage", - "position": 12, + "position": 13, "link": { "type": "generated-index", "description": "Everything you need to know to use specific features of maxGraph." diff --git a/packages/website/docs/usage/migrate-from-mxgraph.md b/packages/website/docs/usage/migrate-from-mxgraph.md index aff1fcfa5a..1c2eef02aa 100644 --- a/packages/website/docs/usage/migrate-from-mxgraph.md +++ b/packages/website/docs/usage/migrate-from-mxgraph.md @@ -173,9 +173,12 @@ Here are a few examples of the methods that have been moved. - `convertPoint()`: Update your code to use `styleUtils.convertPoint()` instead of `mxUtils.convertPoint()`. #### `xmlUtils` -- `getXml`(): Update your code to use `xmlUtils.getXml()` instead of `mxUtils.getXml()`. +- `getXml()`: Update your code to use `xmlUtils.getXml()` instead of `mxUtils.getXml()`. - `createXmlDocument()`: Update your code to use `xmlUtils.createXmlDocument()` instead of `mxUtils.createXmlDocument()`. +#### In the default namespace +- `get()`: Update your code to use `get()` instead of `mxUtils.get()`. +- `load()`: Update your code to use `load()` instead of `mxUtils.load()`. ### Removed methods from `mxUtils` diff --git a/packages/website/docusaurus.config.ts b/packages/website/docusaurus.config.ts index 75cb79351e..9cf8f719fe 100644 --- a/packages/website/docusaurus.config.ts +++ b/packages/website/docusaurus.config.ts @@ -61,12 +61,12 @@ const config: Config = { themeConfig: { // Replace with your project's social card // image: 'img/docusaurus-social-card.jpg', - announcementBar: { - content: - '⚠️ This is a work in progress, the content of the original mxGraph documentation will be progressively migrated here ⚠️', - backgroundColor: 'rgb(255, 248, 230)', - isCloseable: false, - }, + // announcementBar: { + // content: + // '⚠️ This is a work in progress, the content of the original mxGraph documentation will be progressively migrated here ⚠️', + // backgroundColor: 'rgb(255, 248, 230)', + // isCloseable: false, + // }, docs: { sidebar: { hideable: true, diff --git a/packages/website/old-mxgraph/tutorial.html b/packages/website/old-mxgraph/tutorial.html deleted file mode 100644 index 2a49c1c3af..0000000000 --- a/packages/website/old-mxgraph/tutorial.html +++ /dev/null @@ -1,542 +0,0 @@ - - - mxGraph Tutorial - - - - - -

mxGraph Tutorial

-

Table Of Contents

-
-
-

Overview

-

- The mxGraph package contains a client software, written in JavaScript, and a series - of backends for various languages. The client software is a graph component with - an optional application wrapper that is integrated into an existing web interface. - The client requires a webserver to deliver the required files to the client or - can be run from the local filesystem without a webserver. The backends may be used - as is, or they may be embedded into an existing server application in one of the - supported languages. -

- -

- If a backend exists, then the client may be configured to use this backend in - various ways, such as: -

-
    -
  • Creating images
  • -
  • Storing and loading diagrams
  • -
  • Creating an object representation of a graph
  • -
-

- The above scenarios maybe combined in various ways, such as sending an XML - description of each change to the backend as it happens, or autosaving of - the diagram to avoid loss of data on the client. The client can also operate in - offline mode, where it does not require a backend or a webserver. -

-

- Please have a look at the index files in the respective directories for - information on the various backends. -

- -

Hello, World!

-

- The Hello, World! example of mxGraph ships in a - single HTML file, - which contains the required namespaces, the mxGraph library script - and the example code. The example can be viewed by pointing Firefox or - Internet Explorer to the link above either on the local - filesystem or on a webserver. To display the source of the example - press Control-U in Firefox or click Page, View Source in Internet Explorer. -

-

Library

-

- The HEAD part of the page contains the JavaScript code and dependencies. - The library is loaded using the following code. The mxBasePath - variable is used to define the path where the library loads its resources - from. This variable must be defined prior to loading the library code and - should not include a trailing slash. -

-
-<script type="text/javascript">
-  mxBasePath = 'javascript/src';
-</script>
-<script type="text/javascript" src="javascript/src/js/mxClient.js"></script>
-
-

- mxClient.min.js - contains all required code in a single, minified, file. This is the file you - should use in production. During development, if you wish to change mxGraph - sources, use the bootstrapped mxClient.js file. -

-

Browser Check

-

- The next script tag in the HEAD part of the page contains the - Hello, World! example code. The first part of the code checks if the - browser that is displaying the page is supported by the library. It is - recommended to do this as the first step of the program and - display an error message if the browser is not supported. In your - document you may also want to include a NOSCRIPT directive for - browsers that have JavaScript disabled, however, in our examples this - directive is not used. -

-

- There is no convention for the name of the main function. The function - is invoked from the onload handler in the page and may have any name - and arguments. In this case, the argument is a DOM node that will contain - the graph. Note that the DOM node may have any ID and that the code - is independent of this ID. -

-
-<script type="text/javascript";>
-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);
-  }
-  ...
-
-

Container

-

- For the JavaScript to actually render the graph, the page - contains an DOM node which will display the graph. This - DOM node is either dynamically created or it is obtained via - an ID using document.getElementById as in the - Hello, World! example. The DOM node is passed to the main - function and is used to construct the graph instance as shown - below. -

-

- If you want the container to have scrollbars, use the overflow:auto CSS - directive instead of overflow:hidden in the style of the container. -

-

Graph

-

- The code constructs an empty graph model and passes the container - and the empty model to the graph constructor. For this example, - all default event handling is disabled in the last line. -

-
-let model = new mxGraphModel();
-let graph = new mxGraph(container, model);
-
-

- If you want the graph to be read-only you can use graph.setEnabled(false). -

-

Vertices and Edges

-

- To insert vertices and edges, beginUpdate and endUpdate - are used to create a transaction. The endUpdate should always go - into a finally-block to make sure it is always executed if the beginUpdate - was executed. However, the beginUpdate should not be part of the - try-block to make sure endUpdate is never executed if beginUpdate - fails. This is required for the model to remain in a consistent state, that is, for - each call to beginUpdate there should always be exactly one call to - endUpdate. -

-

- The part within the try-block creates the vertices and edges for the graph. - The default parent is obtained from the graph and is typically the first - child of the root cell in the model, which is created automatically when - using the graph model c'tor with no arguments. -

-
-// 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
-model.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
-  model.endUpdate();
-}
-
-

- The use of beginUpdate and endUpdate does not - only improve the display performance, but it is also used to mark the - boundaries for undoable changes when undo/redo is used. -

-

Graphs

-

- Instantiate mxGraph - in order to create a graph. This is the central class in the API. - Everything else is auxiliary. -

- -

- To create a new graph instance, a DOM node (typically a DIV) is - required: -

-
-let node = document.getElementById('id-of-graph-container');
-let graph = new mxGraph(node);
-
-

Model

-

- mxCell defines the - elements of the graph model, which is implemented by - mxGraphModel. -

- -

- The graph model has the following properties: -

-
    -
  • - The root element of the graph contains the layers. - The parent of each layer is the root element. -
  • -
  • - A layer may contain elements of the graph model, - namely vertices, edges and groups. -
  • -
  • - Groups may contain elements of the graph model, - recursively. -
  • -
-

- The graph and structural information is stored in the cells, as well as the - user objects, which are used to store the value associated with - the cells (aka business objects). -

-

- To create a new graph model with a root cell and a default layer (first child): -

-
-let root = new mxCell();
-root.insert(new mxCell());
-let model = new mxGraphModel(root);
-
-

Stylesheet

-

- The appearance of the cells in a graph is defined by the - stylesheet, which is an instance of - - mxStylesheet. - The stylesheet maps from stylenames to styles. - A style is an array of key, value pairs to be - used with the cells. The keys are defined in - - mxConstants and the values may be - strings and numbers or JavaScript objects or functions. -

-

- To modify the default styles for vertices and edges in an existing graph: -

-
-let vertexStyle = graph.getStylesheet().getDefaultVertexStyle();
-vertexStyle[mxConstants.STYLE_ROUNDED] = true;
-
-let edgeStyle = graph.getStylesheet().getDefaultEdgeStyle();
-edgeStyle[mxConstants.STYLE_EDGE] = mxEdgeStyle.TopToBottom;
-
-

Styles

-

- The style information for a cell is stored in cell.style. - The style is part of the cell's state and is normally changed via - mxGraphModel.setStyle, which will update all views. - The cell style is a string of the form -

-
-[stylename;|key=value;]
-
-

- which tells the graph to use the given named styles and override the - specified key, value pairs in the given order. For example, to use the - rounded - style and override the stroke- and fillColor, the style would be defined as: -

-
-rounded;strokeColor=red;fillColor=green
-
-

- To use the above in Hello, World!, the stylename would be passed to the - insertVertex method as follows: -

-
-var v1 = graph.insertVertex(parent, null, 'Hello',
-  20, 20, 80, 30, 'rounded;strokeColor=red;fillColor=green');
-
-

Appearance

-

- In certain cases you may want to override specific attributes based on - dynamic properties of a cell (ie. it's value, aka. userobject), such as - the image, indicator shape, -image, -color or -gradient color), in - which case you can override getImage, - getIndicatorShape, getIndicatorImage, - getIndicatorColor and getIndicatorGradientColor - respectively. Note that these methods take a cell state as an argument, - which points to a "resolved" (that is, an array) version of the - cell's style. Hence, the default implementation for getImage - looks as follows: -

-
-mxGraph.prototype.getImage = function(state)
-{
-  if (state != null && state.style != null)
-  {
-    return state.style[mxConstants.STYLE_IMAGE];
-  }
-  return null;
-}
-
-

- This method may be overridden to return any image for the given state. - Typically, the image is defined by either state.cell, - which points to the graph cell associated with the state, or by - state.cell.value, which refers to the cell's user object. -

-

- Due to the nature of the display, where all cells are created once and - updated only if the model fires a notification for a change, you must - invoke view.invalidate(cell) for each cell who's image - has changed, and call view.validate to update the display. -

-

Editors

-

- Instantiate mxEditor in - order to create an editor. This is the central class in the editor - package. Everything else in this package is auxiliary. - To create a new editor instance and configure it using a config - file, you can pass the name of the config file to the - mxEditor constructor. -

- -

- To create a new editor instance and configure it, the following code is used: -

-
-let config = mxUtils.load('editors/config/keyhandler-commons.xml').getDocumentElement();
-let editor = new mxEditor(config);
-
-

- TODO add link to the codecs page - The configuration file is an XML file that is passed to - mxCodec, which in - turn uses mxEditorCodec - and others to read the XML into the editor object hierarchy. This is normally - done at startup time to configure the editor, graph, model, toolbar, popupmenus - etc using the I/O subsystem. -

-

CSS

-

- The CSS stylesheet contains the style definitions for various - elements of the user interface, such as the rubberband selection, - the in-place editor or the popup menu. It also contains the directives - required to enable VML support in Internet Explorer, so it is substantial - that the stylesheet is included in the page. -

-

- Additional stylesheets may either be added programmatically using - mxClient.link('stylesheet', filename) or - via a stylesheet tag of the UI section in the editor configuration, eg.: -

-
-<mxEditor>
-  <ui>
-    <stylesheet name="examples/editors/css/process.css"/>
-    ...
-
-

Templates

-

- To add new cell types, create a template in the templates array section of - the model in the config file (mxEditor/mxGraph/mxGraphModel/Array[as=templates]) - as follows: -

-
-<add as="symbol">
-  <Symbol label="Symbol" customAttribute="whatever">
-    <mxCell vertex="1" connectable="1" style="symbol;image=images/event.png">
-      <mxGeometry as="geometry" width="32" height="32"/>
-    </mxCell>
-    <CustomChild customAttribute="whatever"/>
-  </Symbol>
-</add>
-
-

- The as-attribute of the add-element contains the - name under which the template will be accessible for later use. The - Symbol-child element is a custom (ie workflow) element, and - can have any name and any number of child elements and custom attributes. - The label attribute is a special one that is used for the textual - representation of the cell in the graph. The mxCell element - is another special child node which contains the graphical information for - the cell, namely, the cell-type, -style, -size and -position. -

-

- See mxGraph.convertValueToString if you would like to use another - attribute or a combination of attributes for the textual representation, - and mxCell.valueChanged to handle in-place editing by storing - the new text value in the respective attribute(s). -

-

Toolbar

-

- To use the template in the graph, a toolbar item must be added which refers - to the template in the mxDefaultToolbar section of the config file - (mxEditor/mxDefaultToolbar[as=toolbar]) as follows: -

-
-<add as="symbolTool" template="symbol"
-  style="symbol;image=wf/images/bpmn/special_event.png"
-  icon="wf/images/bpmn/small_event.gif"/>
-
-

- The as attribute specifies the tooltip to be displayed for the - icon in the toolbar, the template-attribute refers to the name - under which the template was previously added. The style- - attribute is optional, and may be used to override the style defined in the - template definition. Finally, the icon specifies the icon to be used for the - toolbar item. -

-

- Note that the as attribute is assumed to be the key for a language - resource, in this case symbolTool. If the resource is not defined - in mxResources, then the - attribute value is used as the label. -

- - - - - -

Input/Output

- - -TODO add link to the codecs page - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Files

-

- The save, open, readGraphModel and writeGraphModel functions - implement a standard mechanism for handling files in - mxEditor. -

-

- The default implementation of mxEditor.save is called - with an argument to indicate if the save was triggered by the user or - by the system. It then uses the urlPost variable of - the editor object to check if a post request should be issued. If - the variable is defined, the editor issues a post request to the - specified URL passing the XML along as a POST variable called xml. -

-

Post

-

- As an example, consider the following PHP file which is located - in the same directory as the HTML page. If the filename is server.php - then the urlPost variable must be set to server.php on the editor - in order to post the diagram to the server. The PHP file will get - the XML from the POST request and write it to a file called - diagram.xml. -

-
-<?php
-$xml = $HTTP_POST_VARS['xml'];
-if ($xml != null) {
-  $fh=fopen("diagram.xml","w");
-  fputs($fh, stripslashes($xml));
-  fclose($fh);
-}
-?>
-
-

- To set the URL to post to, change the respective entry in the mxEditor node of the config file as follows: -

-
-<mxEditor urlPost="http://www.example.com/server.php" ... >
-
-

- Keep in mind that the JavaScript can only post to the server where it originated from, so we recommend - to use relative URLs, eg. server.php. -

-

Form Fields

-

- If you need to read/write the graph from/to a string (eg. to fill a form-field), you can use the - following methods: -

-
-let data = editor.writeGraphModel();
-editor.readGraphModel(mxUtils.parseXml(data));
-
-

Codecs

-

- For encoding other objects, or if no editor instance is available, - the mxCodec can be - used to create and read XML data. -

-
-© 2006-2017 by JGraph Ltd. - -