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

Please see the bundled license file for license terms.

This product contains software developed by the Dojo Foundation (http://dojofoundation.org/) 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 creating 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 for Java 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.

It is also possible to extract all files from the yFiles AJAX web application archive webapp/yfiles-ajax.war file in the distribution using an archive program or by using ant unzip-war in the main directory of the distribution. There are three 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 for Java 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.

With version 1.2 of yFiles AJAX a new framework for adding custom server side actions has been introduced. It also contains a client side part, the ServerAction class, which wraps a call to a custom server side action.

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.

The following classes and interfaces are used by the custom action framework. There are some support classes.

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 on the client side. The action framework introduced in yFiles AJAX 1.2 simplifies adding server side functionality. The next tutorial provides details on using the action framework. The third tutorial describes how to use a custom servlet for extending the server side. In this tutorial we start by just using the existing components for the client and the server side.

Information on writing web applications in general 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. See also the section Creating a yFiles AJAX Project in Eclipse.

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>
The src attribute describes the path to the basic Dojo Javascript file in the directory structure as described in the last step. If you move your HTML page to another directory, the path has to be adapted.

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.

The path used in dojo.registerModulePath is relative to the location of the dojo.js file loaded in Step 2. It does not depend on the location of the HTML page.

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: The graph canvas has an additional parameter baseURL=".." in the HTML page for this tutorial extracted from the distribution as described above. 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 "..". Moreover, the paths for including the dojo.js file and the Javascript files for yFiles AJAX in the header are adapted.

Tutorial: Treasure Hunt (Extending yFiles AJAX using the Action Framework)

Introduction

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. Using a custom servlet is part of the next tutorial.

In this tutorial we create a simple game, Treasure Hunt. A graph is displayed and a treasure is hidden at one of its nodes. If the player clicks a node, it will either be the right one with the treasure or it is another node without the treasure. If there is no treasure, the player gets a hint that the treasure is for example two nodes away.

There are of course several ways to implement this game. Just selecting a random node at the beginning and then checking whether it has been clicked can be done without any server call. Computing the distance to the node with the treasure would be rather complicated, since the graph structure (what are the neighbors of a node?) is not present at the client side.

yFiles for Java, which is available at the server side, does have access to the graph structure. Moreover, it offers an algorithm for computing the distance from one node to every other node in the graph. Let's just use that. We could wrap the call to the algorithm with a custom servlet. The next tutorial describes the approach of creating a custom servlet and calling it from the client side.

In this tutorial we'll use the action framework instead of writing a custom servlet. The action framework was introduced in yFiles AJAX 1.2. It simplifies adding custom server side behavior triggered by the client side to a web application with yFiles AJAX.

NOTE: This tutorial is based on the last tutorial. We assume that the HTML page is located in the main directory of the web application as in the last tutorial. If this is not the case some paths need to be adjusted.

Step 1: Change the Title and the Body of the Page

We want to display a graph and thus use a GraphCanvas as in the previous tutorial. We need a way to let the player pick a node. The graph canvas has some functions for mouse events related to nodes. They are called, if we tell the canvas that we are interested in node events. This can be done in the HTML markup of the canvas. We'll use a different graph this time and a larger canvas. Since we want to perform some code after the graph has been loaded (computing the distances for the first time), we do not specify the graph in the markup for the canvas, but set the path for the graph in Javascript code. In the body of the page we use the adapted canvas mentioned above and a placeholder for displaying hints for the player, an initially empty paragraph with the id hint.

<body>
<h1>Treasure Hunt</h1>

<p>
  There is a treasure hidden at one of the nodes!
</p>

<div style="width: 600px; height: 500px; border: solid blue;">
  <div dojoType="yfiles.client.tiles.widget.GraphCanvas" id="canvas" nodeEvents="true"></div>
</div>

<p id="hint"></p>

</body>

We also change the title of the page by replacing the previous title line in the head of the page with the following one.

  <title>Treasure Hunt</title>

Step 2: Add the Action (Client Side)

The action framework contains one class for the client side: ServerAction. An instance of ServerAction wraps the call to the server triggering a server side action. It sends some information about the client state to the server and takes care of the server response. This means that you do not have to create a new protocol to talk to your server side code. In order to use a ServerAction instance, we have to require the corresponding class. Add the following line in the header after the require call for the GraphCanvas class.

  dojo.require("yfiles.client.tiles.ServerAction");

Initially and every time the player has found the treasure we hide a new treasure at a random node and compute all the distances from all nodes to the node with the treasure on the server side. If the player clicks a node, we use the distance information to decide whether the treasure was found or to display a hint with the distance to the treasure. The client side of the action for hiding the treasure, the hideTreasureAction, is created as follows in a new Javascript block in the head of the page after the block with the require calls.

  <script type="text/javascript">
    var distances;
    var hideTreasureAction = new yfiles.client.tiles.ServerAction({
      id :        'yworks.demos.actions.hideTreasure',
      graphName : 'treasure-islands.graphml',
      postRun :   function() {
        distances = dojo.fromJson(this.getCustomResponse());
      }
    });
  </script>
The handler for the server side action is identified by the id yworks.demos.actions.hideTreasure. We tell the server side which graph to use by specifying the symbolic name of the graph. The graph file treasure-islands.graphml has to be added to the resources/graphs directory.

The function with the postRun key in the parameter object given to the ServerAction constructor is called whenever a response from the server arrives (and no error occurred). The function is called without any parameters, but it is called in the scope of the calling ServerAction instance, so we can use this inside the postRun function to access the calling action. The postRun function of the hideTreasureAction uses the access to the calling action for getting the response from the server side code: this.getCustomResponse(). The custom response from the server, which is always a string, is expected to be in JSON format and a JavaScript object distances is constructed from it.

Step 3: Initialize the Client Side Behavior

The canvas has the following functions dealing with node events. Since we enabled node events in Step 1, these functions will be called with the id of the node as the argument, if the corresponding events happen.

In order to run the hide treasure action initially and to set up the event handling, we use a function init, which should be executed once after the page is loaded and the canvas is constructed. In the init function we first set the path to the graph. This triggers loading the graph on the server. When the graph is loaded, we run the hide treasure action for the first time and connect the onClickNode and onMouseOutNode events of the graph canvas. Add the following functions to the Javasript block in the head of the page which already contains the hideTreasureAction variable.

    function init() {
      canvas = dijit.byId('canvas');
      hint = dojo.byId('hint');
      dojo.connect(canvas, 'pathSet', window, 'onPathSet');
      canvas.setPath('treasure-islands.graphml');
    }

    function onPathSet() {
      hideTreasureAction.run();
      dojo.connect(canvas, 'onClickNode', window, 'feedback');
      dojo.connect(canvas, 'onMouseOutNode', window, function() { hint.innerHTML = ''; } );
    }
The effect of a call like dojo.connect(canvas, 'onClickNode', window, 'feedback'); is that each time, when the onClickNode function of the canvas is called, the feedback function of the window (which means the global feedback function) gets called immediately afterwards with the same parameters. We'll define the feedback function in the next step. The parameter of the onClickNode function of the canvas is the id of the node which was clicked. We could also interpret the mouse enter event as searching for the treasure, but that would probably lead to too much accidental searching. We use the onMouseOut event to remove the hint, since if there really was a hint, then the mouse just left the node for which the hint was computed.

In order to run the init function initially we use dojo.addOnLoad. Insert the following Javascript block just before the end of the body of the page.

<script type="text/javascript">
  // Call init after page load.
  dojo.addOnLoad(init);
</script>

Step 4: Provide Feedback

For providing the feedback to the player we use the feedback function in the Javascript block in the header.

    function feedback(nodeId) {
      if(!distances) {
        return;
      }

      var distance = distances[nodeId];
      if(distance == 0) {
        // Hide another treasure.
        distances = null;
        hideTreasureAction.run();

        // Congratulations!
        // <Insert your favorite effect here.>
        alert('Congratulations! You found the treasure!\n\nThere is yet another treasure...');
      } else {
        // Display hint.
        var distStr = distance == 1 ? "one node" : distance + " nodes";
        hint.innerHTML = 'No, there is no treasure here, but it is only ' +
          distStr + ' away. Keep on searching!';
      }
    }
We get the distance from the node where the player is searching to the treasure from the distances object. We assume that it looks like the following JavaScript object (we'll take care of that assumption on the server side).
  {
    "n-0" : 1,
    "n-1" : 0,
    "n-2" : 1,
    "n-3" : 2
  }
For each member, the key is the id of a node of the graph and the value is the length of the shortest path from this node to the treasure or in other words the distance to the treasure. If the distance is 0, the player found the treasure, congratulations and the game starts again. Otherwise we tell the player the current distance to the treasure by populating the hint placeholder in the page. The complete client side page with the necessary dojo.require calls added looks like this (use the view source feature of your browser).

NOTE: The complete tutorial HTML page is located in the subdirectory Examples in the yFiles AJAX distribution. Therefore, some paths have to be adjusted. This is relevant for including the Javascript files for Dojo and yFiles AJAX in the header and for the calls to the server side made by the canvas and the server action instance. The canvas has a baseURL attribute for this purpose, which was already mentioned in the last tutorial. The server action has an optional parameter url which specifies the relative URL of the generic ActionServlet on the server which takes care of dispatching requests made by ServerAction instances on the client.

Step 5: Add the Action (Server Side)

As already mentioned you do not have to write your own servlet, if you use the action framework. You can write an action handler instead which implements the ActionHandler interface. There is just one method to be implemented in the action handler interface: handleAction. It takes two parameters. The first parameter, an ActionContext instance, describes the client side environment for the action (e.g. the graph to be considered). The second parameter, a ClientControl instance, allows to control the client side post-processing. The client control also offers a method for setting the custom response.

Create a new class implementing the ActionHandler interface, e.g. tutorials.HideTreasureAction.

  package tutorials;

  import com.yworks.yfiles.server.tiles.servlet.action.ActionHandler;
  import com.yworks.yfiles.server.tiles.servlet.action.ActionContext;
  import com.yworks.yfiles.server.tiles.servlet.action.ClientControl;

  public class HideTreasureAction implements ActionHandler {
    public void handleAction(ActionContext context, ClientControl control) {
    }
  }

In the implementation of the handleAction method for the hide treasure action, we first find out for which graph to hide a treasure. The action context provides the actual graph instance for the symbolic graph name sent from the client.

  public void handleAction(ActionContext context, ClientControl control) {
    // Get the graph specified by the client request.
    Graph2D graph = context.getGraph();
Note that the graph could be null depending on the parameters of the client side ServerAction instance, but for the hide treasure action this should not happen. The next step is to select a node for hiding the treasure.
    // Select a treasure node.
    Node treasureNode = chooseTreasureNode(graph);
Then we compute the distances to the treasure node by means of an algorithm provided by the y.algo.ShortestPaths class.
    // Compute the distances.
    double[] distances = new double[graph.N()];
    ShortestPaths.uniform(graph, treasureNode, false, distances);
Finally, we return the distances as a JSON string.
    // Send the distances to the client.
    control.setCustomResponse(createJSONDistancesString(graph, distances));
  }
Choosing a random node in the graph can be done by using a yFiles for Java node cursor and a random position in a separate private helper method of the HideTreasureAction.
  private Node chooseTreasureNode(Graph2D graph) {
    // Hide the treasure at a random node.
    Random random = new Random();
    int nodeCount = graph.N();
    int position = random.nextInt(nodeCount);
    int count = 0;
    for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
      if (count++ == position) {
        return nodeCursor.node();
      }
    }
    return null;
  }
For creating the JSON string containing the distances from the treasure node to the other nodes we use the JSONStringBuilder class, which was also introduced with yFiles AJAX 1.2, in a further private helper method.
  private String createJSONDistancesString(Graph2D graph, double[] distances) {
    // Create a string in JSON format containing the distances to the treasure node.
    JSONStringBuilder builder = new JSONStringBuilder();
    for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
      Node node = nodeCursor.node();
      builder.addMember(BaseServlet.getId(graph, node), (int) distances[node.index()]);
    }
    return builder.getJSONString();
  }
Note that the index of a node is not an id, if the graph is allowed to change. The index is unique, but it changes, if the graph changes. In the treasure hunt game the graph does not change, but since yFiles AJAX also allows changing the graph, the index cannot be used as an id for a node. yFiles AJAX uses ids which can be retrieved by using public static methods of the BaseServlet.

Step 6: Register the Action

Requests from client side ServerAction instances are handled by by the generic ActionServlet which is part of yFiles AJAX. It uses the id (e.g. yworks.demos.actions.hideTreasure), which is part of the request, to look up the right action handler. The action handler is registered with the ActionServlet by means of an initialization parameter in the web.xml file for the application. Add an entry for the ActionServlet and a corresponding servlet mapping to your web.xml file, if they are not already there (note that the entries in the web.xml file have to be ordered according to their types, e.g. mappings need to be declared after all servlet entries).

  <servlet>
    <servlet-name>ActionServlet</servlet-name>
    <display-name>Action Servlet</display-name>
    <description>handles custom actions</description>
    <servlet-class>com.yworks.yfiles.server.tiles.servlet.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>yworks.demos.actions.hideTreasure</param-name>
      <param-value>tutorials.HideTreasureAction</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>ActionServlet</servlet-name>
    <url-pattern>/yFilesAction</url-pattern>
  </servlet-mapping>
The name of the parameter is the id for the action (yworks.demos.actions.hideTreasure) and the value is the fully qualified class name of the class implementing the server side of the action (tutorials.HideTreasureAction). The name of the request is yFilesAction by default, but it can be configured in the client side ServerAction class and the web.xml file.

This concludes the second tutorial. The complete source code for the action handler can be found in the src folder of the yFiles AJAX web example application or in the src subdirectory of the tutorials directory, if you extracted it from the web archive as described above. However, the HideTreasureAction is part of the com.yworks.yfiles.server.tiles.demos package in these sources.

More information on the action framework is available in this section. The Swimlanes demo application also uses the action framework.

Tutorial: Extending yFiles AJAX using a Custom Servlet

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 for Java, 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 five demo applications, a Graph Viewer, a Swimlanes, 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 Swimlanes demo application uses two features introduced with yFiles AJAX 1.2: configuration of the server side views used for generating the image tiles of the graph and the action framework.

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.

The Swimlanes demo application showcases using server actions and view configurators.

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 and other Server Side Classes

The server side classes for yFiles AJAX including the servlets are packaged as a jar file, yfiles-ajax.jar. The server side code for the yFiles AJAX demos is packaged as a separate jar file, yfiles-ajax-demos.jar. The classes in the yfiles-ajax.jar rely on some other jar files, which ship with yFiles AJAX and the y.jar file from the lib subdirectory of your yFiles for Java distribution. 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 all of these jars except yfiles-ajax-demos.jar to the WEB-INF/lib subdirectory of your web application.

The yFiles AJAX distribution ships with the ySVG extension package for yFiles for Java, namely the two jar files ysvg.jar and batik.jar in the above mentioned lib directory. ySVG is optional. yFiles AJAX only needs it to render graphs with SVG nodes correctly. If your graphs do not use SVG you can safely omit the two jar files from your application. If your application includes SVG nodes and the ySVG jar files are not present, the SVG nodes will be rendered with a fallback style as simple rectangles.

The server side sources for the demo applications are located in the src directory of the unpacked web application archive yfiles-ajax.war.

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 license file to the WEB-INF subdirectory of your web application. The default name of the file is yfiles-ajax-license.xml. If you want to use another name, you can do so by specifying the alternative name as the value of the context parameter yfiles.ajax.license.file.name of your web application. If for example your license file is called myLicense.xml add the follwing XML snippet to your web.xml file between the display-name element and the first servlet element.

  <context-param>
    <param-name>yfiles.ajax.license.file.name</param-name>
    <param-value>myLicense.xml</param-value>
  </context-param>

JavaScript Sources

yFiles AJAX is deployed as a layered build on top of Dojo 1.4.0 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 here.

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.4. 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.4.0 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 it can be found here.

Note that highlighting nodes or edges in a graph canvas currently uses div elements which are invisible, if you do not use the yFiles AJAX style sheet or define your own CSS rule for div elements with the "yFilesGraphCanvasOverlay" class.

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.

View Configuration

yFiles for Java provides some display like adding drawables to the view and configuring the renderer to display edge crossings using bridges, which are configured using the y.view.Graph2DView instance used to display the graph or its renderer.

In a web application based on yFiles AJAX, you do not have access to a Graph2DView instance. In fact the Graph2DView class is used for rendering the graph on the server side of yFiles AJAX, but there is typically more than just one graph view instance and these instances are transient. In other words: the situation is not as easy as in a desktop application using yFiles for Java.

Since version 1.2 of yFiles AJAX there is a new feature, which enables using the view features described above in a straight forward way regardless of the more difficult setting. There is a new public static method addViewConfigurator at the BaseServlet. It takes an object which implements the ViewConfigurator interface. The interface has just one method configureView which is called with a Graph2DView immediately before the view is used to render a graph. Adding a view configurator in your server side code can be done as follows.

  BaseServlet.addViewConfigurator(graph, new ViewConfigurator() {
    public void configureView(Graph2DView view) {
      // do something with the view
    }
  });
View configurators can also be removed again. The ConfigureBridgesAction in the Swimlanes demo is an example for switching on or off displaying edge crossings as bridges.

Action Framework

Overview

With version 1.2 a new framework for adding custom actions to the server side of an application based on yFiles AJAX and handling them from the client side has been added. It removes the need to add new servlets on the server side and to do the housekeeping on the client side after graph changes on the server. The Swimlanes demo application is an example for using the framework.

There is a new generic servlet, the ActionServlet which dispatches requests for custom actions to implementations of the ActionHandler interface. The ActionHandler implementations are registered for an action id by means of initialization parameters of the ActionServlet.

On the client side there is a new ServerAction class which defines the context for a custom action, wraps the server call and takes care of updating client side data for the hit test and the hierarchy manager (configurable). It can also trigger the refresh of a canvas.

Instead of using new servlets, the server side functionality is implemented by custom ActionHandler instances. They are called from the ActionServlet with an ActionContext instance, which provides the context from the client, and a ClientControl instance which can be used by the action handler in order to control the client side post-processing after the server side action has been performed.

A custom action is identified by a unique id and implemented by a combination of a server side class implementing the com.yworks.yfiles.server.tiles.servlet.action.ActionHandler interface and a suitably configured instance of the client side yfiles.client.tiles.ServerAction class. The class implementing the ActionHandler interface additionally needs to have a no-arguments constructor.

The Server Side

The server side class implementing the action handler for the action identified by an id is registered with the ActionServlet by means of an initialization parameter specified in the web.xml file.

  ...
  <servlet>
    <servlet-name>ActionServlet</servlet-name>
    <display-name>Action Servlet</display-name>
    <description>handles custom actions</description>
    <servlet-class>com.yworks.yfiles.server.tiles.servlet.action.ActionServlet</servlet-class>

    <init-param>
      <param-name>yworks.demos.actions.swimlaneLayout</param-name>
      <param-value>com.yworks.yfiles.server.tiles.demos.SwimLaneLayoutAction</param-value>
    </init-param>
  </servlet>
  ...
The above snippet defines an action implemented by the class com.yworks.yfiles.server.tiles.demos.SwimLaneLayoutAction and identified by the id yworks.demos.actions.swimLaneLayout by using an initialization parameter of the ActionServlet. When the ActionServlet is initialized it creates instances of the action handlers specified as above using their no-arguments constructors and associates them with the corresponding ids. Later calls to the ActionServlet with the id yworks.demos.actions.swimLaneLayout will then be dispatched to the instance created at initialization time of the servlet.

The action handler instance which implements the custom action has access to the context of the action specified at the client side by means of an ActionContext instance which gets passed to it by the ActionServlet. Usually, a graph is available from the context. The client side can also specify sets of nodes and edges. In this case they are also available to the server side action from the context. Moreover, the context can be queried whether certain resources like a hit test or a hierarchy manager are available on the client side.

The action handler is also provided with a ClientControl instance. It is used to control the post-processing on the client side after the request to the ActionServlet has returned. While the ActionContext is an immutable object, the action handler can change the settings of the client control instance. For example, it can compute a new set of nodes and set it on the control to be returned to the client side. An example for such an action is the SelectReachableNodesAction used in the Swimlanes demo. The ClientControl is by default initialized to update the client side hit test data, if a hit test instance is available at the client side. The action can change this setting. Similar behavior is implemented for the hierarchy manager, the selection and the canvas. The following code is used in the action handler for selecting the nodes, which are reachable from a given node, which is used in the Swimlanes demo application.

  public void handleAction(ActionContext context, ClientControl control) {
    Graph2D graph = context.getGraph();
    NodeList nodesIn = context.getNodes();
    if (graph == null || nodesIn.size() != 1) {
      control.setUpdateSelection(false);
      return;
    }

    boolean[] reached = new boolean[graph.N()];
    Node startNode = nodesIn.firstNode();
    GraphConnectivity.reachable(graph, startNode, true, reached);

    NodeList nodesOut = control.getNodes();
    nodesOut.clear();
    for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
      Node node = nodeCursor.node();
      if (node != startNode && reached[node.index()]) {
        nodesOut.add(node);
      }
    }
  }
The graph and the nodes selected on the client side are fetched from the context, the reachable nodes are computed and set for the response using the control.

Another interesting feature of the action framework is used in the action handler for the action to configure bridges for the Swimlanes demo application. The corresponding ServerAction instance on the client specifies the canvas since the canvas needs to be refreshed when bridges are switched on or off. Bridges have no influence on the on the bounds of the nodes or the control points of the edges. Thus the hit test information does not need to be updated when running this action. Therefore the action handler switches off updating the client side hit test using control.setUpdateHitTest(false);.

The Client Side

The client side wrapper for a server side action is an instance of the class ServerAction. It has a key-word-arguments-style constructor like e.g. a dojo.xhrPut call. The following code snippet is a slightly simplified example for creating a ServerAction instance from the Swimlanes demo.

      selectReachableNodesAction = new yfiles.client.tiles.ServerAction({
        id :        'yworks.demos.actions.selectReachableNodes',
        graph :     graph,
        selection : editMode.getSelection()
      });
If you call the run() function on the above created action, it will send a request to the ActionServlet to perform the action registered with the id yworks.demos.actions.selectReachableNodes on the server. The selectReachableNodesAction on the client takes care of getting the currently selected objects from the GraphSelection instance obtained by editMode.getSelection() in order to send them to the server as part of the request. When the response for the request arrives from the server, the selectReachableNodesAction will update the GraphSelection according to the node ids, which are sent back from the server. Since neither a canvas, a hit test, nor a hierarchy manager is available for the selectReachableNodesAction, there will be no refresh of a canvas and no update of a hit test or hierarchy manager.

The ServerAction also provides hooks for functions to be called immediately before a request is sent to the server and immediately after a response has arrived. They can be specified with the preRun and postRun key words in the constructor, respectively. By the way, the key word-argument pairs recognized in the constructor also have corresponding getters and setters. The preRun and postRun functions will be executed in the scope of the ServerAction instance, i.e. the ServerAction instance is accessible using this inside these callbacks. The treasure hunt tutorial contains an example for using a custom response from the server side action.

    var distances;
    var hideTreasureAction = new yfiles.client.tiles.ServerAction({
      id :        'yworks.demos.actions.hideTreasure',
      graphName : 'treasure-islands.graphml',
      postRun :   function() {
        // Parse the custom response from the server as JSON string.
        distances = dojo.fromJson(this.getCustomResponse());
      }
    });
The preRun callback is expected to return a boolean. If it returns false, the action is canceled immediately. No request is sent to the server. There is an example for canceling the run call in the Swimlanes demo.
    selectReachableNodesAction = new yfiles.client.tiles.ServerAction({
      id :        'yworks.demos.actions.selectReachableNodes',
      graph :     graph,
      selection : editMode.getSelection(),
      preRun :  function() {
        // Cancel the action, if the selection does not contain exactly one node.
        return this.getSelection().getSize() == 1;
      }
    });

The Swimlanes demo application uses four different ServerAction instances for performing a complete layout, an incremental layout, configuring bridges and selecting the nodes reachable from a given node. These actions demonstrate different aspects of the action framework. The following code snippet shows the creation of the action for doing an incremental layout which is triggered when the user moves some nodes.

    changeLaneAction = new yfiles.client.tiles.ServerAction({
      id :        'yworks.demos.actions.changeLane',
      canvas :    canvas,
      selection : editMode.getSelection()
    });
The canvas is specified which automatically triggers a refresh of the canvas after the action was performed. Since a canvas always has a hit test, the hit test data is also updated. Otherwise you could not select a node which changed its position after performing the layout. The nodes which were moved are those nodes which the user selected before. Thus the selection maintained by the edit mode is used to specify the nodes which need to change their lane for the server side. Note that editMode.getSelection() returns a GraphSelection instance not the currently selected set of nodes. This instance is queried for the current selection whenever the action runs.

For more details on the possibilities of the action framework please consider the Server Side API Documentation and the Client Side API Documentation.

Creating a yFiles AJAX Project in Eclipse

In order to debug the yFiles AJAX demo applications, or for creating custom yFiles AJAX applications, a web project has to be created in a IDE that supports the development of Java web applications. As an example, this section explains how to set up a web project that uses the yFiles AJAX libraries in Eclipse (J2EE edition).

Note that this section focuses on setting up a project for debugging the server-side part of a yFiles AJAX web application. It does not cover how to set up client-side debugging in a IDE.

  1. Extract the yFiles AJAX web archive using the "unzip-war" target of the Ant buildfile. The resulting war-contents directory will contain all files that are necessary for creating a yFiles AJAX web application.
  2. Create a new "Dynamic Web Project" in Eclipse.
    Create a Dynamic Web Project
  3. Configure the Dynamic Web Project:

    1. Project-Name: yfiles-ajax
    2. Contents: Use default
    3. Target Runtime: Configure the Servlet Container, choosing its installation directory
    4. Hit "Next" to configure the web module.
    Configure the Dynamic Web Project
  4. Configure the Web Module:

    1. Context-Root: yfiles-ajax
    2. Content Directory: WebContent
    3. Java Source Directory:
      WebContent/src
    4. Uncheck "Generate deployment descriptor"
    5. Hit "Finish"
    Configure the Dynamic Web Project
  5. Copy the content of the web-content directory that was created in the yFiles AJAX distribution folder by the unzip-war Ant target to the directory that was chosen as the web content directory in the previous step (WebContent). Confirm to replace any folders/files that have already been automatically created by Eclipse in the web content directory.

  6. Refresh the Eclipse project (select the project and click File > Refresh).

  7. In the "Servers" view, create a server for running/debugging the yFiles AJAX applications.
    Create a server
  8. Choose the servlet container.
    Create a server
  9. Simply add the yfiles-ajax module to the configured modules of the server.
    Add the module
  10. You can now run/debug the server in Eclipse, accessing the yFiles AJAX web applications on localhost
    (e.g. http://localhost:8080/yfiles-ajax/).
    Run the server

Copyright © 2006-2010 yWorks. All Rights Reserved.