UNPKG

mxgraph-map-fix

Version:

mxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.

1,163 lines (986 loc) 72.8 kB
<html> <head> <title>mxGraph User Manual - JavaScript Client</title> <link rel="stylesheet" href="css/manual-styles.css"> <link rel="stylesheet" href="css/manual-colors.css"> <script type="text/javascript" src="js/toc.js"></script> </head> <body onload="maketoc(document.getElementById('toc'));"> <h1>mxGraph User Manual &ndash; JavaScript Client</h1> <br/> <br/> <p>mxGraph Version 3.8.0 &ndash; 30. November 2017</p> <p>Copyright (c) JGraph Ltd 2006-2017</p> <br/> <p>All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without the prior written permission of the author.</p> <p>The programs in this book have been included for their instructional value. They have been tested with care but are not guaranteed for any particular purpose. The publisher does not offer any warranties or representations nor does it accept any liabilities with respect to the programs.</p> <p>Possession, use, or copying of the software described in this publication is authorized only pursuant to a valid written license from JGraph Ltd.</p> <p>Neither JGraph Ltd. nor its employees are responsible for any errors that may appear in this publication. The information in this publication is subject to change without notice.</p> <p>Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.</p> <br/> <h1>Table Of Contents</h1> <div id="toc"></div> <br/> <h1><a id="Introduction"></a>Introduction</h1> <h2><a id="mxGraph_Products"></a>Product Introduction</h2> <p>mxGraph is a JavaScript component that provides features aimed at applications that display interactive <a href="http://en.wikipedia.org/wiki/Diagram">diagrams</a> and graphs. Note by graphs we mean <a href="http://en.wikipedia.org/wiki/Graph_(mathematics)">mathematical graphs</a>, not necessarily <a href="http://en.wikipedia.org/wiki/Charts">charts</a> (although some charts are graphs). See later section &ldquo;What is a Graph?&rdquo; for more details.</p> <p>Being a developer library, mxGraph is not designed specifically to provide a ready to use application, although many of the examples are close to being usable applications. mxGraph provides all the commonly required functionality to draw, interact with and associate a context with a diagram. mxGraph comes with a number of examples that help explain how a basic application is put together and showcases individual features of the library.</p> <p>Developers integrating the library in their application should read the section &ldquo;Pre-requisites&rdquo; below. Given that mxGraph is a component part of your application, you must understand how JavaScript web applications are constructed at an architectural level, and how to program both in JavaScript, as well as any server-side languages used.</p> <p>mxGraph mainly comprises one JavaScript file that contains all of the mxGraph functionality. This is loaded into a HTML web page in a JavaScript section and executes in an HTML container in the browser. This is an incredibly simple architecture that only requires a web server capable of serving html pages and a JavaScript enabled web browser.</p> <p>The key advantages of this technology are:</p> <ul> <li>That no third-party plug-ins are required. This removes plug-in vendor dependence.</li> <li>The technologies involved are open and there are many open implementations, no one vendor can remove a product or technology that leaves your application unworkable in practise.</li> <li>Standardized technologies, meaning your application is deployable to the maximum number of browser users without need for additional configuration or installation at the client computer. Large corporate environments often dislike allowing individuals to install browser plug-ins and do not like to change the standard build rolled out to all machines.</li> </ul> <p><img src="images/mx_man_architecture.png" name="mxgraph_architecture" /> <br/> <em>The mxGraph components and their relationships</em></p> <h2><a id="mxgraph_applications"></a>What Applications can mxGraph be used for?</h2> <p>Example applications for a graph visualization library include: process diagrams, workflow and BPM visualization, flowcharts, traffic or water flow, database and WWW visualization, networks and telecommunications displays, mapping applications and GIS, UML diagrams, electronic circuits, VLSI, CAD, financial and social networks, data mining, biochemistry, ecological cycles, entity and cause-effect relationships and organisational charts.</p> <h2><a id="mxgraph_deployment"></a>How is mxGraph deployed?</h2> <p>In the typical thin-client environment, mxGraph is split into the client-side JavaScript library and a server-side library in one of the two supported languages, .NET and Java. The JavaScript library is contained as part of a larger web application that is delivered to the browser using a standard web server. All the browser needs is the ability to run JavaScript to be enabled.</p> <p>In the third part of this manual, you will see an example of an html page that embeds the mxGraph library, as well as a simple application to invoke the library's functionality.</p> <h2><a id="mxgraph_technologies"></a>mxGraph Technologies</h2> <p>mxGraph uses JavaScript for the client-side functionality on the browser. The JavaScript code in turn uses the underlying vector graphics language on the active browser to render the displayed diagram, currently SVG for all supported browsers. mxGraph also includes the feature to render entirely using html, this limits the range of functionality available, but is suitable for more simple diagrams.</p> <p>As a developer you are not exposed to browser specific features. As mentioned, the vector graphics language varies by browser, so mxGraph abstracts their features into a common class. Similarly, for event handling and DOMs. Browsers differ in their implementation of these two major browser functionalities, mxGraph exposes a constant API over all browsers and adapts to the inconsistencies behind the scenes.</p> <h2><a id="mxgraph_licensing"></a>mxGraph Licensing</h2> <p>The JavaScript client of mxGraph is licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0"> Apache 2.0 license</a> For detailed licensing questions you are always advised to consult a legal professional.</p> <h2><a id="what_graph"></a>What is a Graph?</h2> <p>Graph visualization is based on the mathematical theory of networks, graph theory. If you're seeking JavaScript bar <em>charts</em>, pie <em>charts</em>, Gantt <em>charts</em>, have a look at the <a href="http://code.google.com/apis/chart/">Google Charts</a> project instead, or similar</p> <p>A graph consists of vertices, also called nodes, and of edges (the connecting lines between the nodes). Exactly how a graph appears visually is not defined in graph theory. The term <em>cell</em> will be used throughout this manual to describe an element of a graph, either edges, vertices or groups.</p> <p><img src="images/mx_man_simple_graph.png" /><br/> <em>A simple Graph</em></p> <br/> <p>There are additional definitions in graph theory that provide useful background when dealing with graphs, they are listed in the Appendices if of interest to you.</p> <h3><a id="graph_visualization"></a>Graph Visualization</h3> <p>Visualization is the process of creating a useful visual representation of a graph. The scope of visualization functionality is one of mxGraphs' main strength. mxGraph supports a wide range of features to enable the display of cells to only be limited by the skill of the developer and the platform functionality available. Vertices may be shapes, images, vector drawing, animations, virtually any graphical operations available in browsers. You can also use HTML mark-up in both vertices and edges.</p> <p><img src="images/mx_man_graph_vis.png"><br/> <em>Graph Visualization of a transport system. (c) Tourizm Maps 2003, http://www.world-maps.co.uk</em></p> <br/> <h3><a id="graph_interaction"></a>Graph Interaction</h3> <p>Interaction is the way in which an application using mxGraph can alter the graph model through the web application GUI. mxGraph supports dragging and cloning cells, re-sizing and re-shaping, connecting and disconnecting, drag and dropping from external sources, editing cell labels in-place and more. One of the key benefits of mxGraph is the flexibility of how interaction can be programmed.</p> <p>Many complex graphical web applications rely on a round-trip to the server in order to form the display, not only the base display but also the interaction events. Although this is often given the title of AJAX functionality, such server reliance is not appropriate for interaction events. Visual feedback taking longer than about 0.2 seconds in an application generally seriously impacts the usability. By placing all of the interaction on the client, mxGraph provides the true feel of a application, rather than seeming like a dumb remote terminal. It also allows the possibility of off-line use.</p> <p><img src="images/mx_man_graph_interaction.png" /><br/> <em>Selection shading while selecting an area through mouse drag</em></p> <br/> <h3><a id="graph_layouts"></a>Graph Layouts</h3> <p>Graph cells can be drawn anywhere in a simple application, including on top of one another. Certain applications need to present their information in a generally ordered, or specifically ordered structure. This might involve ensuring cells do not overlap and stay at least a certain distance from one another, or that cells appear in specific positions relative to other cells, usually the cells they are connected to by edges. This activity, called the layout application, can be used in a number of ways to assist users in setting out their graph. For non-editable graphs, layout application is the process of applying a layout algorithm to the cells. For interactive graphs, meaning those that can be edited through the UI, layout application might involve only allowing users to make changes to certain cells in certain positions, to re-apply the layout algorithm after each change to the graph, or to apply the layout when editing is complete.</p> <p><img src="images/mx_man_graph_layout.png" /><br/> <em>Layout of a workflow using a horizontal hierarchical layout</em></p> <p>mxGraph supports a range of tree, force-directed and hierarchical layouts which will fit most layout needs. See the later section on using the layouts for more information.</p> <p>In a client-server architecture there are two options for how layouts can be run. The Javascript versions provide the ability to run the layouting entirely on the client, while the same layout implementation in Java on the server-side enables the option to offload some processing to the server, if required.</p> <h3><a id="graph_analysis"></a>Graph Analysis</h3> <p>Analysis of graphs involves the application of algorithms determining certain details about the graph structure, for example, determining all routes or the shortest path between two cells. There are more complex graph analysis algorithms, these being often applied in domain specific tasks. Techniques such as clustering, decomposition, and optimization tend to be targeted at certain fields of science and have not been implemented in the core mxGraph packages at the current time of writing.</p> <p><img src="images/mx_man_graph_analysis.jpg" name="shortest_path_analyis" /><br/> <em>Shortest Path Analysis</em></p> <br/> <h2><a id="about_manual"></a>About this Manual</h2> <h3><a id="pre_requisites"></a>Pre-requisites for mxGraph</h3> <p>To benefit fully from this manual you will need to have a reasonable understanding of web applications and of the server technology you wish to deploy using. Deployment examples are available for each of the server technologies supported, some familiarity with that server technology is obviously required.</p> <p>Basic XML knowledge is useful for changing the editor configuration files that describe the visual and behavioural aspects of the editor. You will need to understand and implement Javascript coding and be familiar with object orientated programming principles and modern software design.</p> <p>You do not need knowledge of the underlying vector graphics language that the browser uses, such as SVG or HTML canvas. mxGraph abstracts the description of the visual component into one API.</p> <h1><a id="Getting_Started"></a>Getting Started</h1> <h2><a id="mxgraph_site"></a>The mxGraph Package</h2> <h3><a id="obtaining_mxgraph"></a>Obtaining mxGraph</h3> <p> mxGraph is available from the <a href="https://github.com/jgraph/mxgraph">GitHub project</a>. Released versions are tagged "va.b.c", where a, b and c are version number parts following <a href="http://semver.org/">semantic versioning</a>. </p> <p> Each formal release is also available as .zip or .tar.gz on the <a href="https://github.com/jgraph/mxgraph/releases">mxGraph releases</a> page. </p> <h3><a id="project_structure"></a>Project structure and build options</h3> <p>Once unzipped you will be presented with a number of files and directories in the installation root.</p> <TABLE WIDTH=642 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0> <COL WIDTH=165> <COL WIDTH=459> <THEAD> <TR VALIGN=TOP> <TD WIDTH=165> <p>/doc</p> </TD> <TD WIDTH=459> <p>Documentation root, includes this user manual</p> </TD> </TR> </THEAD> <TBODY> <TR VALIGN=TOP> <TD WIDTH=165> <p>/dotnet</p> </TD> <TD WIDTH=459> <p>.NET server-side classes</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>/java</p> </TD> <TD WIDTH=459> <p>Java server-side classes</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>/javascript</p> </TD> <TD WIDTH=459> <p>JavaScript client functionality.</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>/javascript/examples</p> </TD> <TD WIDTH=459> <p>HTML examples demonstrating the use of mxGraph</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>ChangeLog</p> </TD> <TD WIDTH=459> <p>Details of the changes between releases</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>index.html</p> </TD> <TD WIDTH=459> <p>Basic introduction to the library</p> </TD> </TR> <TR VALIGN=TOP> <TD WIDTH=165> <p>license.txt</p> </TD> <TD WIDTH=459> <p>The licensing terms under which you must use the library</p> </TD> </TR> </TBODY> </TABLE> <p><em>Table: Project Directory Structure</em></p> <br/> <h3><a id="npm"></a>npm</h3> <p>mxGraph is also available via the npm package manager. To use mxGraph as a depedency, use <code>npm install</code>:</p> <pre>npm install mxgraph --save</pre> <p>The module can be loaded using <code>require()</code>. This returns a factory function that accepts an object of options. Options such as <code>mxBasePath</code> must be provided to the factory function, rather than specified as global variables.</p> <pre>var mxgraph = require("mxgraph")({ mxImageBasePath: "./src/images", mxBasePath: "./src" })</pre> <p>The factory function returns a 'namespace object' that provides access to all objects of the mxGraph package. For example, the <code>mxEvent</code> object is available at <code>mxgraph.mxEvent</code>.</p> <pre>var mxEvent = mxgraph.mxEvent; mxEvent.disableContextMenu(container);</pre> <h2><a id="web_applications"></a>JavaScript and Web Applications</h2> <p>Web applications, specifically the use of JavaScript to attempt to emulate desktop application-like behaviour in web browsers, is still a relatively new field of software engineering. There are three main issues with JavaScript that are perceived to be a barrier to producing high quality applications, performance, lack of native functionality available in desktop applications and inconsistent APIs between browsers.</p> <p>There has been considerable effort toward developing framework libraries to solve two of the problems, the functionality and API issues. The requirements of many of these libraries is driven by both improving web site design and usability, as well as to assist production of what we generally refer to as application features (menus, windows, dialogs, persistence, event handling, etc). They also provide certain base functionalities missing in JavaScript that desktop application developers take for granted, such as basic maths and collections functionality.</p> <p>Many of these JavaScript frameworks have IDE support for development nowadays and all of the major browsers now contain JavaScript debuggers, either natively or as a plug-in. There is no compilation phase with JavaScript (it is an interpreted language) so basic typographical errors are often only caught at runtime, unless you obtain a syntax checking tool in your IDE. So although there is not one complete package for your JavaScript development needs, there are a number of vendors providing the individual components you need to produce JavaScript applications effectively.</p> <h3><a id="js_frameworks"></a>Third-Party JavaScript Frameworks</h3> <h4><a id="native_js_frameworks"></a>Native JavaScript Frameworks and Libraries</h4> <p>Rather than list and compare every JavaScript framework, please see the wikipedia entries for <a href="http://en.wikipedia.org/wiki/List_of_JavaScript_libraries#JavaScript">web application frameworks</a> and the <a href="http://en.wikipedia.org/wiki/Comparison_of_JavaScript_frameworks">comparison of JavaScript</a>. The comparison should not be considered authoritative, more so it illustrates the types of features provided, such as event handling, animation, widgets, AJAX request support etc. <a href="http://javascriptlibraries.com/">This site</a> is also a useful list of JavaScript libraries, mostly being open/free source licensed.</p> <p>Be aware that many frameworks add implicit behaviours to make JavaScript appear more like an OO language and to increase the base functionality of the language. During the writing of the layout portion of mxGraph, it was found that this implicit behaviour broke an example in a very hard to debug manner. Be aware that this may cause problems and if you select a framework ensure you understand which implicit behaviours it introduces.</p> <p>When selecting a framework and/or libraries think about which frameworks tie you into certain functional behaviour and look for libraries that provide features such as animation as distinct, independent blocks, that you can use without being tied into the overall design.</p> <h4><a id="integration_js_frameworks"></a>Integration of mxGraph and JavaScript frameworks</h4> <p>This area is often misunderstood, put simply, there is no <em>integration</em> required. Web applications generally comprise one or more <a href="http://en.wikipedia.org/wiki/Span_and_div"><em>div</em></a> elements into which the HTML wrapping the JavaScript of the application is placed. If you create a div as a container for an mxGraph, that area is a stand-alone display for the mxGraph application. It can communicate itself with any back-end server, but there is no interdependence between that div and the rest of the page, other than the area each take up. This includes event handling, mxGraph can handle the events for its container, even if the rest of the web page used a completely different event model. As long as neither mxGraph nor the other libraries and frameworks on the page introduce implicit behaviours that break one part of the page, the issue of client integration is not something that needs analysis.</p> <p>Integration of the mxGraph back-end functionality, that which sits at the server-side is the subject of a later chapter.</p> <h4><a id="extending_mxgraph"></a>Extending mxGraph in JavaScript</h4> <p>In JavaScript, there are various ways of mapping the Object Oriented paradigm to language constructs. mxGraph uses a particular scheme throughout the project, with the following implicit rules:</p> <ul> <li>Do not change the built-in prototypes</li> <li>Donot try to limit the power of the JavaScript language.</li> </ul> <p>There are two types of &ldquo;classes&rdquo; in mxGraph; <EM>classes</em> and <EM>singletons</em> (where only one instance of the class exists). Singletons are mapped to global objects where the variable name is the same as the class name. For example, mxConstants is an object with all the constants defined as object fields. Normal classes are mapped to a constructor function and a prototype which defines the instance fields and methods. For example, mxEditor is a function and mxEditor.prototype is the prototype for the object that the mxEditor function creates. The <em>mx</em> prefix is a convention that is used for all classes in the mxGraph package to avoid conflicts with other objects in the global namespace.</p> <p>For subclassing, the superclass must provide a constructor that is either parameterless or handles an invocation with no arguments. Furthermore, the special constructor field must be redefined after extending the prototype. For example, the superclass of mxEditor is mxEventSource. This is represented in JavaScript by first &ldquo;inheriting&rdquo; all fields and methods from the superclass by assigning the prototype to an instance of the superclass, eg.</p> <pre>mxEditor.prototype = new mxEventSource()</pre> <p>and redefining the constructor field using:</p> <pre>mxEditor.prototype.constructor = mxEditor</pre> <p>The latter rule is applied so that the type of an object can be retrieved via the name of it&rsquo;s constructor using <EM>mxUtils.getFunctionName(obj.constructor)</em>.</p> <h5><a id="constructor"></a>Constructor</h5> <p>For subclassing in mxGraph, the same mechanism should be applied. For example, for subclassing the mxGraph class, first a constructor must be defined for the new class. The constructor calls the super constructor with any arguments that it may have using the <em>call</em> function on the mxGraph function object, passing along explicitly each argument:</p> <pre> function MyGraph(container) { mxGraph.call(this, container); } </pre> <p>The prototype of MyGraph inherits from mxGraph as follows. As usual, the constructor is redefined after extending the superclass:</p> <pre>MyGraph.prototype = new mxGraph(); MyGraph.prototype.constructor = MyGraph;</pre> <p>You may want to define the codec associated for the class after the above code (see I/O section of manual). This code will be executed at class loading time and makes sure the same codec is used to encode instances of mxGraph and MyGraph.</p> <pre> var codec = mxCodecRegistry.getCodec(mxGraph); codec.template = new MyGraph(); mxCodecRegistry.register(codec); </pre> <h5><a id="functions"></a>Functions</h5> <p>In the prototype for MyGraph, functions of mxGraph can be extended as follows.</p> <pre> MyGraph.prototype.isSelectable = function(cell) { var selectable = mxGraph.prototype.isSelectable.apply(this, arguments); var geo = this.model.getGeometry(cell); return selectable &amp;&amp;(geo == null || !geo.relative); } </pre> <p>The supercall in the first line is optional. It is done using the <em>apply</em> function on the <em>isSelectable</em> function object of the mxGraph prototype, using the special <em>this</em> andn <em>arguments</em> variables as parameters. Calls to the superclass function are only possible if the function is not replaced in the superclass as follows, which is another way of &ldquo;subclassing&rdquo; in JavaScript.</p> <pre> mxGraph.prototype.isSelectable = function(cell) { var geo = this.model.getGeometry(cell); return selectable &amp;&amp; (geo == null || !geo.relative); } </pre> <p>The above scheme is useful if a function definition needs to be replaced completely.</p> <p>In order to add new functions and fields to the subclass, the following code is used. The example below adds a new function to return the XML representation of the graph model:</p> <pre> MyGraph.prototype.getXml = function() { var enc = new mxCodec(); return enc.encode(this.getModel()); } </pre> <h5><a id="fields"></a>Fields</h5> <p>Likewise, a new field is declared and defined as follows:</p> <pre> MyGraph.prototype.myField = &lsquo;Hello, World!&rsquo;; </pre> <p>Note that the value assigned to myField is created only once, that is, all instances of MyGraph share the same value. If you require instance-specific values, then the field must be defined in the constructor instead. For example:</p> <pre> function MyGraph(container) { mxGraph.call(this, container); this.myField = []; } </pre> <p>Finally, a new instance of MyGraph is created using the following code, where container is a DOM node that acts as a container for the graph view:</p> <pre> var graph = new MyGraph(container); </pre> <br/> <h3><a id="general_javascript"></a>General JavaScript Development</h3> <h4><a id="javascript_obfuscation"></a>JavaScript Obfuscation</h4> <p>By default, when you deliver JavaScript to a browser client, you deliver the entire source to that JavaScript. That JavaScript is then interpreted and run on the browser. It is not possible to encrypt the JavaScript to any extent on the client at the point it is run, since the JavaScript source must be understood by the JavaScript interpretor and interpreted languages do not have a binary intermediate form.</p> <p>It would be possible to encrypt the JavaScript in transmission and have it decrypted and run on the client, but the client would still be able to access the source after decryption.</p> <p>We do not obfuscate because the method names form a public API and I/O would need to understand the obfuscation at both communication ends.</p> <h4><a id="namespaces"></a>Namespaces</h4> <p>The concept of namespaces does not exist in standised JavaScript, so take great care when creating new class names. In mxGraph, all of the classes begin with the prefix &ldquo;mx-&rdquo;, to avoid clashes or overriding prototypes unintentionally. <br/> <h2><a id="hello_world"></a>Hello World!</h2> <p>Hello World in mxGraph consists of a simple client-side example that displays two connected vertices with the labels &ldquo;Hello&rdquo; and &ldquo;World!&rdquo;. The example demonstrates the following things: </p> <ul> <li><strong>Creating an HTML page that links the mxGraph client JavaScript,</strong></li> <li><strong>Creating a container to place the mxGraph into,</strong></li> <li><strong>Adds the required cells to that graph.</strong></li> </ul> <p>The source code for the example, helloworld.html, can be found below and in the examples directory of both the evaluation and full versions of mxGraph. The HTML source contains two main sections, the head and the body. These contain the following main elements that you can consider a template for building a basic mxGraph application:</p> <ul> <li><strong>mxBasePath</strong>: This is a JavaScript variable that defines the directory within which the css, images, resources and js directories are expected to be found. It is JavaScript code and needs to be placed with in a <em>script</em> tag. This must come before the line loading mxClient.js and should not have a trailing slash.</li> <li><strong>mxClient.js</strong>: This is the path to mxGraph library. If the HTML file is executed locally, the path might be local to the computer or a public Internet path. If the html page were downloaded from a web server, the path would generally be a public Internet path.</li> <li><strong>Creation of the container</strong>: At the bottom of the code, in the body element, the function that is called on loading the web page is defined (the value of onload). It passes in a div container as a parameter, that is defined underneath. This div is the container the mxGraph component will be placed within. In this example a grid background is applied, as commonly used in diagramming applications. No other part of the graph visuals are described at container creation, other than the background and the container width and height. <p>Note that the overflow:hidden style should always be used if you want no scrollbars to appear.</p> </li> <li><strong>The entry function</strong>: The main code of the file is the entry method executed on page load in this case. This is JavaScript code and must be within a JavaScript <em>script</em> element. The first lines of any mxGraph application should be to check the browser is supported and exit appropriately if not. If the browser is supported, a mxGraph is created within the div container and three cells are added to the graph between the begin/end update calls.</li> </ul> <br/> <p><img src="images/mx_man_hello_world.png" name="ill_hello_world" /> <br/> <em>The mxGraph HelloWorld example</em></p> <br/> <pre> &lt;html&gt; &lt;head&gt; &lt;title&gt;Hello, World! example for mxGraph&lt;/title&gt; &lt;!-- Sets the <U>basepath</U> for the library if not in same directory --&gt; &lt;script type=<em>&quot;text/javascript&quot;</em>&gt; mxBasePath = '../src'; &lt;/script&gt; &lt;!-- Loads and <U>initializes</U> the library --&gt; &lt;script type=<em>&quot;text/javascript&quot;</em> src=<em>&quot;../src/js/mxClient.js&quot;</em>&gt;&lt;/script&gt; &lt;!-- Example code --&gt; &lt;script type=<em>&quot;text/javascript&quot;</em>&gt; // Program starts here. Creates a sample graph in the // DOM node with the specified ID. This function is invoked // from the onLoad event handler of the document (see below). function main(container) { // Checks if the browser is supported if (!mxClient.isBrowserSupported()) { mxUtils.error('Browser is not supported!', 200, false); } else { // Creates the graph inside the given container var graph = new mxGraph(container); // Enables rubberband selection new mxRubberband(graph); // Gets the default parent for inserting new cells. This // is normally the first child of the root (ie. layer 0). var parent = graph.getDefaultParent(); // Adds cells to the model in a single step graph.getModel().beginUpdate(); try { var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30); var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30); var e1 = graph.insertEdge(parent, null, '', v1, v2); } finally { // Updates the display graph.getModel().endUpdate(); } } }; &lt;/script&gt; &lt;/head&gt; &lt;!-- Page passes the container for the graph to the program --&gt; &lt;body onload=<em>&quot;main(document.getElementById('graphContainer'))&quot;</em>&gt; &lt;!-- Creates a container for the graph with a grid wallpaper --&gt; &lt;div id=<em>&quot;graphContainer&quot;</em> style=<em>&quot;overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif')&quot;</em>&gt; &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; </pre> <p>Important concepts to note in this exercise are:</p> <ul> <li>mxClient.js is a JavaScript file combining all of the JavaScript source code of mxGraph. When downloading from a web server, obtaining all the JavaScript as one file is much faster than as lots of separate files, due to the overhead of the requests/acknowledgements required for each file. The speed increase is usually at least x2, although it varies with the capacity of the server to have parallel sockets open with one client.</li> <li>The JavaScript code and its dependencies are all placed within the <em>head</em> element.</li> <li>Internet Explorer has, by default, security options enabled that cause a user prompt when attempting to run JavaScript from the local file system. This can be disabled in the options menu, but note that running from the local file system is not a deployment scenario of mxGraph, this would only happen during development.</li> <li>Your application can be written and linked into the application either within the HTML file, or in separate JavaScript source code that is linked into the html in the way the mxClient.js file is in the example.</li> </ul> <h2><a id="deployment"></a>mxGraph Deployment and Debugging</h2> <p>There are two versions of the mxclient.js file, one for production use and a second for development/debugging use. <em>javascript/src/js/mxClient.js</em> is the production version and <em>javascript/debug/js/mxClient.js</em> is for development. The first version has all linefeeds stripped to ensure the file is the minimal size possible. This has the side-effect of breaking most JavaScript debuggers. During development you are advised to use the debug version, which has the linefeeds in, enabling debugging in the supported browsers.</p> <p>Both mxClient.js files are the entire JavaScript source to mxGraph, with all of the whitespace and comments removed to reduce file size. Whilst debugging, it is easier to use the individual source files if you need to debug into the mxGraph library itself. The source code version of mxGraph contains the full source in the source.zip file in the <em>javascript/devel</em> directory. Unzipping this into the mxBasePath and removing the load of the complete mxClient.js file enables easier debugging of mxGraph. Note that the mxclient.js file in the source zip is a bootstrap file that loads all the other JavaScript source code.</p> <p>The download speed of the client source can be further improved by compressing the code. All modern browsers support receiving and uncompressing transmissions compressed at the server end and all good web servers support detection of those browser that do not support it and send the uncompressed version as a fallback.</p> <p>For example, on the Apache web server there is a mod_deflate module, details of its use can be found from a standard search. The jgraph.com server uses this module and there have been no reports of issues in any supported browser.</p> <p>The use of compression reduces the mxClient.js file size down from about 600KB to around 130KB. The difference is not noticed by the user on most modern networks, but there might be situations where the smaller version would be preferable.</p> <br/> <h1><a id="model_cells"></a>mxGraph Model and Cells</h1> <h2><a id="mxgraph_architecture"></a>Core mxGraph architecture</h2> <h3><a id="mxgraph_model"></a>The mxGraph Model</h3> <p>The mxGraph model is the core model that describes the structure of the graph, the class is called mxGraphModel and is found within the model package. Additions, changes and removals to and from the graph structure take place through the graph model API. The model also provides methods to determine the structure of the graph, as well as offering methods to set visual states such as visibility, grouping and style.</p> <p>However, although the transactions to the model are stored on the model, mxGraph is designed in such a way that the main public API is through the mxGraph class. The concept of &ldquo;add this cell to the graph&rdquo; is a more natural description of the action than &ldquo;add this cell to the model of the graph&rdquo;. Where it is intuitive, functions available on the model and cells are duplicated on the graph and those methods on the graph class are considered the main public API. Throughout the rest of this manual these key API methods are given a pink background:</p> <div id="coreapi"> <p>anExampleCoreAPIMethod()</p> </div> <p>So, though many of the main API calls are through the mxGraph class, keep in mind that mxGraphModel is the underlying object that stores the data structure of your graph.</p> <p>mxGraph uses a transactional system for making changes to the model. In the HelloWorld example we saw this code:</p> <pre> // Adds cells to the model in a single step graph.getModel().beginUpdate(); try { var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30); var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30); var e1 = graph.insertEdge(parent, null, '', v1, v2); } finally { // Updates the display graph.getModel().endUpdate(); } </pre> <p>to perform the insertion of the 2 vertices and 1 edge. For each change to the model you make a call to beginUpdate(), make the appropriate calls to change the model, then call endUpdate() to finalize the changes and have the change event notifications sent out.</p> <div id="coreapi"> <p><strong>Key API Methods:</strong></p> <ul> <li><strong>mxGraphModel.beginUpdate() </strong>- starts a new transaction or a sub-transaction.</li> <li><strong>mxGraphModel.endUpdate()</strong> - completes a transaction or a sub-transaction.</li> <li><strong>mxGraph.addVertex()</strong> - Adds a new vertex to the specified parent cell.</li> <li><strong>mxGraph.addEdge()</strong> - Adds a new edge to the specified parent cell.</li> </ul> </div> <p><strong>Note</strong> &ndash; Technically you do not have to surround your changes with the begin and end update calls. Changes made outside of this update scope take immediate effect and send out the notifications immediately. In fact, changes within the update scope enact on the model straight away, the update scope is there to control the timing and concatenation of event notifications. Unless the update wrapping causes code aesthetic issues, it is worth using it by habit to avoid possible problems with event and undo granularity.</p> <p>Note the way in which the model changes are wrapped in a try block and the endUpdate() in a finally block. This ensures the update is completed, even if there is an error in the model changes. You should use this pattern wherever you perform model changes for ease of debugging.</p> <p>Ignore the reference to the parent cell for now, that will be explained later in this chapter.</p> <h3><a id="transaction_model"></a>The Transaction Model</h3> <p>The sub-transaction in the blue block above refers to the fact that transactions can be nested. That is, there is a counter in the model that increments for every <em>beginUpdate</em> call and decrements for every <em>endUpdate</em> call. After increasing to at least 1, when this count reaches 0 again, the model transaction is considered complete and the event notifications of the model change are fired.</p> <p>This means that every sub-contained section of code can (and should) be surrounded by the begin/end combination. This provide the ability in mxGraph to create separate transactions that be used as &ldquo;library transactions&rdquo;, the ability to create compound changes and for one set of events to be fired for all the changes and only one undo created. Automatic layouting is a good example of where the functionality is required.</p> <p>In automatic layouting, the user makes changes to the graph, usually through the user interface, and the application automatically positions the result according to some rules. The automatic positioning, the layouting, is a self-contained algorithm between begin/end update calls that has no knowledge of the specifics of the change. Because all changes within the begin/end update are made directly to the graph model, the layout can act upon the state of the model as the change is in progress.</p> <p>It is important to distinguish between functionality that acts on the graph model as part of a compound change and functionality that reacts to atomic graph change events. In the first case, such as for automatic layouting, the functionality takes the model as-is and acts upon it. This method should only be used for parts of compound model changes. All other parts of the application should only react to model change events.</p> <p>Model change events are fired when the last endUpdate call reduces the counter back down to 0 and indicate that at least one atomic graph change has occurred. The change event contains complete information as to what has altered (see later section on <strong>Events</strong> for more details).</p> <h4><a id="model_change_methods"></a>The Model Change Methods</h4> <p>Below is a list of the methods that alter the graph model and should be placed, directly or indirectly, with the scope of an update:</p> <ul> <li>add(parent, child, index)</li> <li>remove(cell)</li> <li>setCollapsed(cell, collapsed)</li> <li>setGeometry(cell, geometry)</li> <li>setRoot(root)</li> <li>setStyle(cell, style)</li> <li>setTerminal(cell, terminal, isSource)</li> <li>setTerminals(edge,source,target)</li> <li>setValue(cell, value)</li> <li>setVisible(cell, visible)</li> </ul> <p>Initially, we will just concern ourselves with the add and remove, as well as the geometry and style editing methods. Note that these are not core API methods, as usual these methods are on the mxGraph class, where appropriate, and they perform the update encapsulation for you.</p> <p><em>Design Background</em> - Some people are confused by the presence of visual information being stored by the model. These attributes comprise cell positioning, visibility and collapsed state. The model stores the default state of these attributes, providing a common place to set them on a per-cell basis, whereas, views can override the values on a per-view basis. The model is simply the first common place in the architecture where these attributes can be set on a global basis. Remember, this is a graph <em>visualization</em> library, the visualization part is the core functionality.</p> <h5><a id="inserting_cells"></a>Inserting Cells</h5> <p>The three graph cells created in the <CODE>HelloWorld</CODE> application are two vertices and one edge connecting the vertices. If you are not familiar with basic graph theory and its terminology, please see the <a href="http://en.wikipedia.org/wiki/Graph_theory">wikipedia entry</a>.</p> <p>You can add vertices and edges using the add() method on the model. However, for the purposes of general usage of this library, learn that mxGraph.insertVertex() and mxGraph.insertEdge() are the core public API for adding cells. The function of the model requires that the cell to be added is already created, whereas the mxGraph.insertVertex() creates the cell for you.</p> <div id="coreapi"> <p><strong>Core API functions:</strong></p> <ul> <li><strong>mxGraph.insertVertex(</strong><strong>parent, id, value, x, y, width, height, style</strong><strong>)</strong> &ndash; creates and inserts a new vertex into the model, within a begin/end update call.</li> <li><strong>mxGraph.insertEdge(</strong><strong>parent, id, value, source, target, style</strong><strong>)</strong><strong> &ndash; </strong>creates and inserts a new edge into the model, within a begin/end update call.</li> </ul> </div> <p><code>mxGraph.insertVertex()</code> will create an mxCell object and return it from the method used. The parameters of the function are:</p> <ul> <li><strong>parent</strong> &ndash; the cell which is the immediate parent of the new cell in the group structure. We will address the group structure shortly, but for now use <code>graph.getDefaultParent();</code> as your default parent, as used in the HelloWorld example.</li> <li><strong>id</strong> &ndash; this is a global unique identifier that describes the cell, it is always a string. This is primarily for referencing the cells in the persistent output externally. If you do not wish to maintain ids yourself, pass null into this parameter and ensure that mxGraphModel.isCreateIds() returns true. This way the model will manage the ids and ensure they are unique.</li> <li><strong>value</strong> &ndash; this is the user object of the cell. User object are simply that, just objects, but form the objects that allow you to associate the business logic of an application with the visual representation of mxGraph. They will be described in more detail later in this manual, however, to start with if you use a string as the user object, this will be displayed as the label on the vertex or edge.</li> <li><strong>x, y, width, height</strong> &ndash; as the names suggest, these are the x and y position of the top left corner of the vertex and its width and height.</li> <li><strong>style</strong> &ndash; the style description to be applied to this vertex. Styles will be described in more detail shortly, but at a simple level this parameter is a string that follows a particular format. In the string appears zero or more style names and some number of key/value pairs that override the global style or set a new style. Until we create custom styles, we will just use those currently available.</li> </ul> <p>With the edge addition method, the identically named parameters perform the same function as in the vertex addition method. The source and target parameters define the vertices to which the edge is connected. Note that the source and target vertices should already have been inserted into the model.</p> <h3><a id="mxcell"></a>mxCell</h3> <p>mxCell is the cell object for both vertices and edges. mxCell duplicates many of the functions available in the model. The key difference in usage is that using the model methods creates the appropriate event notifications and undo, using the cell makes the change but there is no record of the change. This can be useful for temporary visual effects such as animations or changes on a mouse over, for example. As a general rule though, use the model editing API unless you encounter a specific problem with this mechanism.</p> <p>When creating a new cell, three things are required in the constructor, a value (user object), a geometry and a style. We will now explore these 3 concepts before returning to the cell.</p> <h4><a id="styles"></a>Styles</h4> <p>The concept of styles and stylesheets in conceptually similar to CSS stylesheets, though note that CSS are actually used in mxGraph, but only to affect global styles in the DOM of the HTML page. Open up the util.mxConstants.js file in your editor and search for the first match on &ldquo;STYLE_&rdquo;. If you scroll down you will see a large number of strings defined for all the various styles available with this prefix. Some of styles apply to vertices, some to edges and some to both. As you can see, these define visual attributes on the element they act upon.</p> <p>The mxStylesheet holds one object, styles, which is a hashtable mapping style names to an array of styles:</p> <p><img src="images/mx_man_styles.png" name="graphics5"/><br/> <em>Style arrays within the styles collection</em></p> <br/> <p>In the above image the blue box represents the styles hashtable in mxStyleSheet. The string 'defaultVertex' is the key to an array of string/value pairs, which are the actual styles. Note that mxGraph creates two default styles, one for vertices and one for edges. If you look back to the helloworld example, no style was passed into the optional style parameter of insertVertex or insertEdge. In this case the default style would be used for those cells.</p> <h5><a id="setting_cell_style"></a>Setting the Style of a Cell</h5> <p>If you wanted to specify a style other than the default for a cell, you must pass that new style either to the cell when it is created (mxGraph's insertVertex and insertEdge both have an optional parameter for this) or pass that style to the cell using model.setStyle().</p> <p>The style that you pass has the form stylename. ,note that the stylenames and key/value pairs may be in any order. Below are examples to demonstrate this concept, adapting the insertVertex call we saw in helloworld:</p> <ol> <li> <p>A new style called 'ROUNDED' has been created, to apply this to a vertex:</p> <pre>var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'ROUNDED');</pre> </li> <li> <p>To create a new vertex with the ROUNDED style, overriding the stroke and fill colors:</p> <pre>var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'ROUNDED;strokeColor=red;fillColor=green');</pre> </li> <li> <p>To create a new vertex with no global style, but with local stroke and fill colors:</p> <pre>var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, ';strokeColor=red;fillColor=green');</pre> </li> <li> <p>To create a vertex that uses the defaultVertex style, but a local value of the fill color:</p> <pre>var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'defaultVertex;fillColor=blue');</pre> </li> </ol> <br/> <p>Note that default style must be explicitly named in this case, missing the style out sets no global style on the cell when the semi-colon starts the string. If the string starts with no semi-colon, the default style is used.</p> <p>Again, the mxGraph class provides utility functions that form the core API for accessing and changing the styles of cells:</p> <div id="coreapi"> <p><strong>Core API functions:</strong></p> <ul> <li> <strong>mxGraph.setCellStyle(style, cells)</strong> &ndash; Sets the style for the array of cells, encapsulated in a begin/end update. </li> <li> <strong>mxGraph.getCellStyle(cell)</strong> &ndash; Returns the style for the specified cell, merging the styles from any local style and the default style for that cell type. </li> </ul> </div> <h5><a id="new_global_style"></a>Creating a New Global Style</h5> <p>To create the ROUNDED global style described above, you can follow this template to create a style and register it with mxStyleSheet:</p> <pre> v