This document explains how to use yFiles AJAX for integrating the sophisticated yFiles graph visualization framework into state of the art web applications. yFiles AJAX is a product of yWorks GmbH, creator of yFiles and other fine products.

Please see the bundled license file for license terms.

This product contains software developed by the dojo foundation (http://dojotoolkit.org/foundation) distributed under the terms of the Academic Free License v2.1.

This product contains software developed by the Apache Software Foundation (http://www.apache.org/) distributed under the terms of the Apache License, Version 2.0.

This product contains Nuvola icons developed by David Vignoni (http://icon-king.com/) distributed under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.

This product contains software developed by Jason Hunter and Brett McLaughlin (http://www.jdom.org/) distributed under the terms of this license.

yFiles AJAX Developer's Guide

Contents

Introduction

Web Applications and AJAX

Web applications are client/server applications consisting of a standard web browser for the client side which is served by a dedicated server component over a network like the internet or an intranet. Web applications have become more and more popular, since deployment, updates and maintenance are much easier than for desktop applications.

AJAX enables web applications that feel similar to desktop applications. This is achieved by dynamically exchanging parts of the displayed web page instead of (re-)loading web pages as a result of user interactions.

On the downside, more effort needs to be spent for achieving a suitable client using only a standard web browser and JavaScript compared to a desktop application. Moreover, the underlying technology for dynamically changing the appearance of a displayed web page is not (yet?) fully standardized across different browsers. There are different frameworks available which ease the development of AJAX applications by dealing with browser differences and providing components which provide a higher level of functionality.

yFiles AJAX

yFiles AJAX provides a basis for web applications that need to visualize and edit graphs, diagrams or networks. It consists of client and server side components. The server side is based on the successful yFiles library. The client side is realized in JavaScript. It is based on the dojo toolkit and uses the AJAX approach.

From a high-level perspective yFiles AJAX can be described as follows.

yFiles AJAX ships with demo applications illustrating how to use it and how to add application specific functionality.

There are tutorials for using and extending yFiles AJAX in this document.

The following is a simplified overview of the logical components of yFiles AJAX.

yFiles AJAX Overview
yFiles AJAX Components

yFiles AJAX Components

Client Side Components

The client side of yFiles AJAX is based on the dojo toolkit. The client side components can be grouped with respect to their roles with respect to the Model View Controller Pattern (MVC), since the architecture is similar to the yFiles y.view package.

Model Component

yFiles AJAX Model Component
yFiles AJAX Model Component

View Component

yFiles AJAX View Component
yFiles AJAX View Component

Controller Component

yFiles AJAX Controller Component
yFiles AJAX Controller Component

The controller part in the MVC pattern varies the most depending on the specific application. yFiles AJAX provides the building blocks for a specific controller with the basic InputMode class, some specific "one-shot" input modes which get activated for a narrow task (like creating an edge or zooming to an area of interest) and immediately finish after the task has been done. There is a main input mode which handles some input directly and dispatches other input to specialized input handlers.

Graph Editor

demos.widget.GraphEditor is a demo application for editing graphs realized as a single dojo widget. It combines most of yFiles AJAX features with a GUI with a toolbar, a context menu and floating tool windows. It has an online help page which describes its usage. The source is available in the javascript/demos/widget directory. Note that the sources are not available online, i.e. you cannot get them from live.yworks.com.

Server Side

yFiles AJAX Server Component
yFiles AJAX Server Component

yFiles AJAX uses standard servlet technology for the server side. It provides the following servlets.

Tutorials

Extracting the Tutorial Files

All files needed for the tutorials are contained in the web application archive yfiles-ajax.war which ships with yFiles AJAX. You can extract those files from the archive with an archiver, which can handle the ZIP format. Alternatively, you can let Ant do the job for you, which is described in the following. Ant can be obtained from here.

Tutorial: Using yFiles AJAX

Using yFiles AJAX means writing a web application using yFiles AJAX servlets on the server side and yFiles AJAX JavaScript classes and custom dojo widgets on the client side. Information on writing web applications can be found in this tutorial. General information on using dojo can be found in the documentation section of the dojo website.

The source code for the demos which ship with yFiles AJAX is included (the HTML files reside in the top level directory and the "Examples" subdirectory of the deployed yFiles AJAX web application, the JavaScript source files can be found in the "javascript/demos" subdirectory). Note that the sources are not available online, i.e. you cannot get them from live.yworks.com. The demo source code demonstrates some of the possibilities of yFiles AJAX. In the following, we describe how to use yFiles AJAX and how to extend it using simpler examples which are derived step by step in order to explain the basics.

The following describes the steps to set up a basic web application using yFiles AJAX as a tutorial. We want to achieve this result (opens in another window or tab, note that this only works, if you opened the yFiles AJAX Developer's Guide from a deployed yFiles AJAX web application).

  1. There is one GraphCanvas displaying a fixed graph.
  2. It supports panning, i.e., dragging the graph with the mouse.
  3. It supports zooming with the mouse wheel and provides additional zoom buttons.

We assume some basic knowledge on writing web applications. Modern IDEs like Eclipse or IDEA provide useful tools for doing this.

Step 1: Setting Up the Server Side

The resulting directory structure of your web application should look like this.

Step 2: Creating a dojo-Enabled Web Page

Create a new HTML page in the main directory of your web application. There is some basic JavaScript code which needs to be loaded into an HTML page in order to use dojo with it. Add the following to the head of your HTML page.

<script type="text/javascript" src="javascript/dojo/dojo.js" djConfig="parseOnLoad: true"></script>

Step 3: Adding the GraphCanvas

The core dojo code loaded in Step 2 contains the dojo package system which provides the dojo.require() function for loading dojo sources. Now we add the layers (dojo term for packaged JavaScript sources, more information can be found in this section), which contain the yFiles AJAX client side components. Therefore we load two additional JavaScript files by adding the following lines below the line for adding dojo itself.

<script type="text/javascript" src="javascript/dojo/yfiles-ajax-prerequisites.js"></script>
<script type="text/javascript" src="javascript/dojo/yfiles-ajax-base.js"></script>
The GraphCanvas uses the dojo packaging system, but it does not belong to the dojo namespace. We have to register the yfiles namespace to which GraphCanvas belongs with a call to registerModulePath. This is done by adding the following lines to the head of the page after the lines just added.
<script type="text/javascript">
  dojo.registerModulePath("yfiles", "../yfiles");
  dojo.require("yfiles.client.tiles.widget.GraphCanvas");
</script>
The source code for yFiles AJAX widgets and classes is not shipped, thus there is no javascript/yfiles directory. The yFiles AJAX widgets are provided by the layer files we included above.

Now you can add the GraphCanvas to the body of the page. The widget uses the space provided by its parent element. In this case we use a div with 400 pixels width and height as the frame for the graph canvas.

<div style="width: 400px; height: 400px; border: solid blue;">
  <div dojoType="yfiles.client.tiles.widget.GraphCanvas" id="canvas" path="computers.ygf"></div>
</div>
The id attribute of the GraphCanvas is needed to identify the widget in custom JavaScript code. This will be used in the next step of this tutorial. The path attribute tells the canvas which graph to display. It is not mandatory, because there is also a function for setting the graph to be displayed any time after the widget was created.

Step 4: Adding the Zoom Buttons

Zooming with the mouse wheel and panning are default features of the graph canvas, thus there is no need for configuration or additional code to handle that. In order to demonstrate how to talk to the graph canvas using custom JavaScript code we add two zoom buttons to the page.

<div>
  <button onclick="dijit.byId('canvas').setZoom(2.0 * dijit.byId('canvas').zoom);">
    Zoom In
  </button>
  <button onclick="dijit.byId('canvas').setZoom(0.5 * dijit.byId('canvas').zoom);">
    Zoom Out
  </button>
</div>
You can get a reference to a specific dojo widget with a known id by using dijit.byId(). The graph canvas has a readonly attribute zoom holding the current zoom factor and a function setZoom() for setting a new zoom factor. We use the onclick event handlers of the buttons to increase or decrease the zoom factor which results in zooming in or zooming out, respectively.

This concludes the tutorial. The complete source code of the HTML page can be viewed by using the view source feature of your browser for this page. The file is also available at tutorials/Examples/basic.html, if you extracted the tutorial files as described above. Note that the graph canvas has an additional parameter baseURL="..". The baseURL attribute is needed, if the HTML page does not reside in the main directory of the web application, because the server requests from the graph canvas always use relative URLs. The example resides in the subdirectory Examples. Thus the baseURL attribute has the value "..".

Tutorial: Extending yFiles AJAX

You can extend yFiles AJAX both on the client and on the server side. On the client side, you can for example add new widgets which react to events provided by existing yFiles AJAX widgets. An example for this is the ViewPortMarker widget, which adds new functionality on the basis of two GraphCanvas instances.

Another example for a client side extension is the GraphInfo widget which displays information on the graph as a whole or on parts of it like a single node. It relies on information provided from the server side. This information is produced by the InfoServlet, which is an example of a server side extension.

In this tutorial we want to extend the basic example developed in the first tutorial in order to be able to collapse and expand subtrees of a rooted tree, if the user clicks a node label showing either a + or a - sign depending on the collapsed/expanded state of the subtree rooted at that node. The graph resulting from an expand or collapse operation should be redrawn to display the additional nodes after an expand operation and to show a more compact drawing after a collapse operation, respectively. Initially, a graph should be displayed, which hides most of the nodes.

This time we want to have a different layout. The graph canvas should use the whole page and adapt itself to page resizes.

From a high level perspective we have the following new requirements.

Step 1: Extend the Server Side

Extending the server side typically means adding new servlets and servlet mappings to the web application. In this case we add a TreeCollapserServlet to the server side.

Since this is not a tutorial on yFiles, we will not go into all the details of the new servlet (the source code is commented, too), but just mention some important points.

Add the servlet and mappings for "initialize" and "toggleNode" to the web deployment descriptor.

...
<servlet>
  <servlet-name>TreeCollapserServlet</servlet-name>
  <display-name>Tree Collapser Servlet</display-name>
  <description>collapses and expands subtress of a tree</description>
  <servlet-class>com.yworks.yfiles.server.tiles.demos.TreeCollapserServlet</servlet-class>
</servlet>
...
<servlet-mapping>
  <servlet-name>TreeCollapserServlet</servlet-name>
  <url-pattern>/TreeCollapser/toggleNode</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>TreeCollapserServlet</servlet-name>
  <url-pattern>/TreeCollapser/initialize</url-pattern>
</servlet-mapping>
...

Step 2: Writing a Controller for the Client Side

On the client side, it is possible to react on graph events by connecting to the interesting graph events fired by the graph canvas like onClickNodeLabel. Have a look at the TutorialGraphListener. It uses the dojo packaging system, such that it can be included into an HTML page using dojo.require(). Copy the file TutorialGraphListener.js to a subdirectory examples of the javascript directory of your web application. Using dojo.registerModulePath you can tell dojo that there is a new package to consider for serving dojo.require calls. The details are given in the next step.

The TutorialGraphListener is defined using dojo.declare(). This a convenience function for defining classes in dojo. The constructor for a new instance is the constructor function. The TutorialGraphListener caches the canvas and calls _initializeGraph() in order to set up the initial graph. As a third step it connects the onClickNodeLabel of the canvas with its own onClickNodeLabel function. After doing so, the onClickNodeLabel function of the TutorialGraphListener will be called once after each call to onClickNodeLabel on the canvas with the same arguments. The first argument given to onClickNodeLabel is the id of the clicked node label.

In _initializeGraph() an "initialize" request is sent to the servlet defined in step 1. Additionally, the canvas is set to the graph created as a result of the "initialize" request. The second step depends on the first one. It can only succeed, if the graph is already cached. Note that dojo.xhrPost() is asynchronous by default. Calling setPath() as a separate statement after the dojo.xhrPost() call would thus fail sometimes. dojo.xhrPost() can be made synchronous, but that locks the browser GUI and thus is not advisable. If the server request initiated by dojo.xhrPost() succeeds, dojo calls the "load" function from the anonymous parameter object supplied to the call. Using the load function is a nice possibility to synchronize code depending on the outcome of a former server call without using synchronous server calls.

We add our custom click behavior in the onClickNodeLabel() function of the TutorialGraphListener. If the user clicks a node label, we send a request to the new servlet, "toggleNode" in this case, and refresh the canvas once the server side operation has succeeded.

The response for the "toggleNode" request is an object encoded with JSON (JavaScript Object Notation) additionally embedded surrounded by a comment. dojo supports this encoding and returns the evaluated string as a JavaScript object to the load function as the first parameter. The JSON object is surrounded by a comment for security reasons.

The response of the "toggleNode" is an object with two attributes, bounds and shift. bounds contains the new graph bounds after the toggle node operation and shift describes the displacement of the given node as a result of the server side operation (which includes redrawing the tree). There is a refresh function on the graph canvas which can be supplied with the bounds and the shift, such that the graph display is refreshed and the node which was clicked by the user remains at the same position. This helps the user in visually understanding the difference resulting from the "toggleNode" operation.

Step 3: Adapting the HTML Page

As a final step we have to adapt the HTML page from the previous tutorial, such that the graph listener from step 2 is used. Copy your previous HTML file and remove everything in the body (between <body> and </body>). First, we change the requires section in the head of the page as follows.

<script type="text/javascript">
  dojo.registerModulePath("yfiles", "../yfiles");
  dojo.require("yfiles.client.tiles.widget.GraphCanvas");

  dojo.registerModulePath("examples", "../examples");
  dojo.require("examples.TutorialGraphListener");
</script>
Now we want to use the listener. We cannot create the listener in a script section in the head, because it depends on the canvas which is probably not yet constructed. We create the listener on page load using dojo.addOnLoad(). This way, we can be sure that the canvas widget is already constructed. Therefore, we add a JavaScript section to the end of the body of the page which creates an instance of the listener.
<script type="text/javascript">
  dojo.addOnLoad(function() {
    var canvas = dijit.byId('canvas');
    new examples.TutorialGraphListener(canvas);
  });
</script>
Next we change the canvas such that it no longer loads the graph from the previous tutorial by removing the path attribute. Additionally, we enable reporting of node label events by setting nodeLabelEvents to true.
<div dojoType="yfiles.client.tiles.widget.GraphCanvas" id="canvas" nodeLabelEvents="true"></div>

Disabling scroll bars and using the whole visible area can be achieved by removing the div enclosing the graph canvas and adding the following style section to the head of the HTML page.

<style type="text/css">
  html, body, #canvas {
    width: 100%; /* fill the visible area */
    height: 100%;
    overflow: hidden; /* erase scrollbars */
    padding: 0 0 0 0;
    margin: 0 0 0 0;
  }
</style>

That's it! The complete source code of the HTML page can be viewed by using the view source feature of your browser for this page. Note that the listener is included directly from its

On Adding Controller Code

In order to wire GUI events to application specific functionality, you have to add some controller code. In the first tutorial for example, if the user presses the "Zoom In" button, we increased the zoom factor of a GraphCanvas widget.

The tutorial uses the easy solution to just call the desired function setZoom() directly from the HTML markup of the event source, the button in the example. This may compromise the readability and maintainability of the HTML code for larger applications, while it is certainly ok for small applications like the tutorial.

You can extract the code from the onclick attribute into a global JavaScript function (e.g., zoomIn()) defined in the header of the HTML page or in an external JavaScript file loaded in the header. This shortens the value of the onclick attribute to just the call of that function. Moreover, you can call this function from other places like a menu entry as well.

With dojo it is also possible to use the dojo event system to connect an event to calling a function on another object without adding an event handler attribute directly in the HTML code. The following is an example from the GraphViewer demo.

dojo.connect(dojo.byId('graphMenu'), 'onchange', window, 'graphSelected');
This connects a standard select element with id "graphMenu" to a global JavaScript function graphSelected(). Note that the elements to be connected have to exist already at the time of execution of dojo.connect(), thus code like this is typically invoked from a function called on load of the HTML page using dojo.addOnLoad(), since the select element might not yet exist when JavaScript code in the head of a page is executed.

In the demos which ship with yFiles AJAX there is an explicit controller object, an instance of a JavaScript class GraphClient. The GraphClient class has a function zoomIn() which can be called from any event source, once the GraphClient instance is initialized.

Although the controller code is highly dependent on the specific application, the GraphClient class tries to be generic. It assumes that there is a main GraphCanvas and optionally a RubberBand for the main GraphCanvas, a second GraphCanvas serving as an overview and a GraphInfo widget (part of the demos). If any of the optional widgets is not there, the corresponding functionality is simply not initialized or executed. The GraphClient code ships with yFiles AJAX, so you can adapt it to the needs of your application. Note that the sources are not available online, i.e. you cannot get them from live.yworks.com.

The GraphClient is initialized and assigned to a global variable in a function called on load of the HTML page (using dojo.addOnLoad()). This is important, since the widgets may not yet exist, if the client is initialized directly from the head of the HTML page.

If you want to dynamically change the controller code, which is a natural requirement in more complex application like a graph editor, you can also use the infrastructure provided by the yfiles.client.tiles.InputMode and its subclasses. An example for using input modes is the Graph Editor demo.

Demo Applications

yFiles AJAX ships with four demo applications, a Graph Viewer, a Grouped Graph, a Graph Editor and a Collapsible Tree demo application.

Like the tutorials the demo applications also shed some light on using and extending yFiles AJAX. The Graph Viewer demo application adds a new widget called GraphInfo for displaying additional information on certain aspects of a graph like the graph as a whole or a specific node. This widget is used "statically" as part of the initial GUI and dynamically for displaying tooltips for the nodes of the graph. There is a corresponding servlet, the InfoServlet, for providing the information to be displayed by the GraphInfo from the server side. In addition, the Graph Viewer demo shows how to set up an overview canvas.

The Grouped Graph demo shows how to combine navigation in a grouped graph which is provided by the GroupNavigationMode with incremental changes of the layout. This is a scenario for applications, which want to provide a drill-down feature. The incremental layout is realized by a custom servlet, the GroupedGraphServlet which inherits from the UpdateServlet. Note that the sources are not available online, i.e. you cannot get them from live.yworks.com. In order to execute customized actions on the graph, if a group node is opened for example, the demo uses custom request URIs like /incremental/closeGroup which are mapped to the customized servlet. Note that /closeGroup is still available and maps to the standard UpdateServlet.

The Graph Editor demo application shows that it is possible to encapsulate a complex HTML DOM structure into a single custom dojo widget, the GraphEditor widget which uses several child widgets. Its uncompressed source code is available in the javascript/demos/widget subdirectory of the deployed yFiles AJAX web application. Note that the sources are not available online, i.e. you cannot get them from live.yworks.com. Among several other things the source code shows how to connect events in the GUI to actions on the graph and vice versa. It also uses a hierarchy manager and an edit mode. The template for the Graph Editor widget can be found in a separate HTML file.

The Collapsible Tree demo application is similar to the application for the second tutorial. It uses the same server side, but a more complex client. This demo features another kind of drill-down for the special case of tree-shaped graphs, whereas the drill-down in the Grouped Graph demo can be used for any graph.

Building Applications with yFiles AJAX

The yFiles AJAX web application archive contains all the resources you need to run a web application using yFiles AJAX except for the y.jar file containing yFiles (for Java) and possibly your yFiles AJAX license file. These can be added manually or by using ant as described in the installation instructions. You can unpack the complete yFiles AJAX web application using ant in the top level directory of the distribution with the target unzip-war. Most archiving tools should also be able to unpack the web application archive yfiles-ajax.war which is located in the subdirectory webapp.

Servlets

The servlets for yFiles AJAX are packaged as a jar file, yfiles-ajax.jar. It relies on some other jar files, which ship with yFiles AJAX and the y.jar file from your yFiles (for Java) library. If you installed the yFiles AJAX web application containing the tutorials, the demos and so on, all of the needed jar files can be found in the WEB-INF/lib subdirectory of the deployed web application. Deploy these jars to the WEB-INF/lib subdirectory of your web application.

A complete example for the entries in the web.xml file of your application can be found in the WEB-INF subdirectory of the deployed yFiles AJAX web application. Merge the needed entries into your own WEB-INF/web.xml file.

The yFiles AJAX servlets are implemented in a way which allows you to put them into a virtual subdirectory of your web application, if this is desirable. You can for example add the prefix /yfiles to all yFiles AJAX requests in the web.xml file, such that /getImage becomes /yfiles/getImage, /createNode becomes /yfiles/createNode and so on. In this case you have to adjust the yFiles AJAX components you are using on the client accordingly, e.g. for an HTML page in the root directory of your web application, which uses a yFiles AJAX GraphCanvas, add the baseUrl="yfiles" attribute to the HTML markup of the div with the dojoType="yfiles.client.tiles.widget.GraphCanvas" attribute.

License

Deploy your yfiles-ajax-license.xml to the WEB-INF subdirectory of your web application. Do not change its name.

JavaScript Sources

yFiles AJAX is deployed as a layered build on top of dojo 1.0.2 with the provided build tool using this profile. Details on the dojo build tool can be found at the dojo website. At the time of this writing they can be found in "documentation" >> "The Book of Dojo, 1.0" >> "Part 4: Testing, Tuning and Debugging" >> "The Package System and Custom Builds".

The profile defines three layers, yfiles-ajax-prerequisites.js, yfiles-ajax-base.js and yfiles-ajax-complete.js.

You can use the yfiles-ajax-base.js layer on top of your custom dojo layers, if they are also based on dojo 1.0.2. In addition to just copying the layer files to your dojo directory, please do also copy the yfiles-ajax*.js files from the nls subdirectory, which are generated by the build tool, to your dojo/nls directory.

If you are using a newer version of dojo for your build or patched dojo 1.0.2 you may also be able to use yFiles AJAX on top of that, if there are no incompatibilities.

Styles

Styles for yFiles AJAX widgets have been separated into necessary style (e.g. positioning of tiles in the graph canvas) and optional style (e.g. color of selected graph elements in the graph canvas). The latter can be customized by changing the centralized yfiles AJAX style sheet or adding custom rules for the classes used for yFiles AJAX to your own style sheet. The style sheet for yFiles AJAX can be found here. There is a separate style sheet for the client side classes in the demos namespace including the Graph Editor.

Note that the style sheets for yFiles AJAX follow the theme approach as found in dojo. All rules only apply, if the yfiles class is present at the target DOM element. This is the so-called theme in dojo terminology. Thus, the rules can be switched on or off by adding or removing the yfiles class to or from the body tag of the HTML page, since all DOM elements inherit the class from their ancestors and eventually from the body tag. By defining similar rules with a different common class like myCompany you can also switch the appearance back and forth. More information on this topic is also available at the dojo website. At the time of this writing they can be found in "documentation" >> "The Book of Dojo, 1.0" >> "Part 2: Dijit" >> "Themes and Design".

Working with Custom Graphs

In order to display and interact with a graph on the client side in a web application using yFiles AJAX, the graph needs to be cached for the session of the client in the first place. As a second step a GraphCanvas widget can actually be configured to display the cached graph via its setPath function. There are two steps involved in order to allow for customization of the first step.

Using Saved Graphs

In the easiest case, the graphs are known in advance. In this case they can be saved as files to the /resources/graphs/ and thus can be provided by the resource loading mechanism implemented in the LoaderServlet. This is done in the Graph Viewer and Graph Editor demos. In this case a call to the setPath of the GraphCanvas with the base name of the graph file, like e.g. "computers.ygf", suffices. The GraphCanvas calls the load function of its underlying graph, which sends a loadGraph request to the server. In the standard configuration this request is handled by the LoaderServlet, which checks whether a graph with the given name is already cached for the session of the request. If this is not the case, it tries to load the graph as a resource from the /resources/graphs/ directory. There is an optional parameter for reloading graphs from the file system, if they are already cached.

Using Dynamically Created Graphs

The Collapsible Tree demo is an example for working with a dynamically created graph. The client sends an initializeGraph request to the server which is handled by the initializeGraph method in the TreeCollapserServlet. It creates a graph and caches the graph for the session of the request using the cacheGraph method inherited from the BaseServlet. When the request returns to the client the GraphCanvas widget is configured to display this graph by using the setPath function.


Copyright © 2006-2008 yWorks. All Rights Reserved.