SVG Support in ILOG JViews Component Suite

Technical

Emmanuel

Tissandier

Project Manager

Christophe

Jolif

Software Engineer

ILOG S.A.

9, rue de Verdun

Gentilly

France

94253

+33 (0) 1 49 08 35 00

+33 (0) 1 49 08 35 10

www.ilog.fr

Emmanuel Tissandier-Emmanuel Tissandier has been working for 10 years as a software engineer in object oriented environments. He started with the development of CASE tools at Rank Xerox and joined the Visualization R&D team at ILOG in 1995. Since 1997, he has been the R&D Project Manager for the ILOG JViews Component Suite, a product for delivering two-dimensional structured graphics, cartography, diagrams, and Gantt charts in Java.

Christophe Jolif-Christophe Jolif has been working for ILOG since 1997. Since January1999, he has been an R&D Software Engineer working on the ILOG JViews Component Suite. He is also currently representing ILOG at the SVG World Wide Web Consortium (W3C) Working Group and implementing SVG (Scalable Vector Graphics) import and export features in ILOG JViews.

As part of the SVG Working Group, ILOG is implementing SVG in the ILOG JViews Component Suite: ILOG's Java two-dimensional graphic library. This paper explains the technical considerations when importing and exporting SVG documents from a two-dimensional graphic framework in Java. It also explains how the Java 2D API helps you do this. We will also see how SVG can be generated on the server side to create thin client applications that include map displays or workflow and network diagrams. The benefits and limitations of this approach are also discussed.

Introduction

ILOG has been developing the JViews Component Suite since 1997. JViews is an object-oriented library written in Java that targets developers with advanced needs in two-dimensional graphics. Since last year, ILOG has been a member of the SVG (Scalable Vector Graphics) Working Group in the W3C and has started implementing SVG in the ILOG JViews Component Suite.

What is the ILOG JViews Component Suite?

The ILOG JViews Component Suite is composed of several packages addressing different types of application problems:

The Graphics Framework package is the base of all the JViews packages. It consists of a Java library that defines classes such as rectangles, polylines, polygons, circles, text, and images. These objects are called “graphic objects”. It also defines a Manager class—the data-structure that manages the graphic objects and allows fast selection, panning, and zooming.

The Maps package allows developers to create interfaces with custom screen objects on top of map data. The Maps package natively imports the most common raster and vector formats, and allows data from different sources to be combined seamlessly.

The Graph Layout package contains a broad set of algorithms for automatically rearranging diagram-like graphs to produce displays such as rings and star, bus-shaped layouts, hierarchical layouts, or radial layouts.

The Gantt Chart package provides complete support for viewing schedules—both resource and task oriented.

What is SVG?

SVG is a language for describing two-dimensional graphics in XML. SVG elements are used to describe objects such as rectangles, lines, polylines, polygons, text, paths (sets of lines and curves), and images. The SVG elements can be styled to change their graphic appearance (color, line width, and so on) and can be transformed, clipped, and manipulated in various ways.

Implementing SVG in JViews consists of:

  1. Exporting the graphic objects of the library into an SVG document.
  2. Importing SVG documents and translating the SVG elements into the graphic objects of JViews.

This paper is divided into the following parts:

Part 1: Exporting SVG from ILOG JViews

Part 2: Importing SVG into ILOG JViews

Part 3: Using JViews SVG Generation in a Thin-Client Context

Part 1: Exporting SVG from ILOG JViews

Like any graphic toolkit written in Java, ILOG JViews uses the AWT and Java 2D libraries of the Java platform to draw the graphic objects on screen. The Java 2D library allows developers writing a toolkit in Java to achieve complex drawing operations. This is done using complex shapes and advanced features such as alpha composition, gradient fill, affine transformation, and advanced text and font support. In order to reproduce these complex drawings in an XML format, the format must cover the advanced features of Java 2D. The SVG format has these features as well as some others. That is why SVG does not introduce any limitations when exporting two-dimensional graphics written in Java 2D. The difficulty resides in the choice of the technique to use to produce SVG documents that reflect the object-oriented structure of the toolkit and that are optimal in terms of size and usability.

Two possible approaches were available to translate drawings from the toolkit in SVG—the Drawing approach and the Object-oriented approach. These approaches were evaluated in order to choose the one most appropriate for ILOG JViews.

Part 1 of this paper is divided as follows:

The Drawing Approach

The Object-Oriented Approach

Advantages and Disadvantages of the Different Approaches

Generating SVG in ILOG JViews

Compression Techniques

The Drawing Approach

The Drawing approach consists of translating all drawings done with Java 2D into SVG. This technique consists of sub-classing the java.awt.Graphics2D class of the Java 2D library. It is through this class that all the drawings are performed in Java 2D. By sub-classing and implementing all the drawing primitives such that they produce SVG elements instead of drawing directly on the screen, it is possible (in theory) to transform any drawing done in Java into an SVG document.

This technique is very close to what the Java platform does when printing. In order to print in Java 2D, the Java platform substitutes the java.awt.graphics2D instance with an instance suitable to translate the drawing primitives into equivalent printer commands. An example of this technique is given here:

The following Java 2D code (where g is an instance of Graphics2D):

Rectangle rectangle = new Rectangle(10,10,100,100);

//sets the current color to red

g.setPaint(new Color(255, 0, 0));

// sets the line width to 10

g.setStroke(new BasicStroke(10));

// draws the outline of the rectangle

g.draw(rectangle);

// sets the color to blue

g.setPaint(new Color(0, 0, 255));

// fills the rectangle

g.fill(rectangle);

produces the following output:

(A blue-filled rectangle with a red outline of width 10).

If no smart technique is used to reduce the size of the SVG output, the produced SVG document will probably contain two SVG elements. This is because there is one call to the Graphics.draw method and one to the Graphics.fill method. The resulting SVG elements may look like this:

<rect x="10" y="10" width="100" height="100"

style="fill:none;stroke:red;stroke-width:10.0" />

<rect x="10" y="10" width="100" height="100" style="fill:blue" />

With this technique, exporting graphic objects from the toolkit into an SVG document consists of calling the Draw method of each graphic object instance with the specialized java.awt.Graphics parameter.

The Object-oriented Approach

The second approach is to take advantage of the object-oriented structure of the toolkit. The toolkit features Java classes such as rectangles, lines, polylines, polygons, text, and images. Instead of reusing the ‘draw’ method of each class, a specific translation method for each graphic object can be created.

Since the translation process is specific for each graphic object, the translation into SVG of a rectangle object will then consist of creating only one SVG <rect> element (since only one SVG element is required to draw a rectangle with SVG).

A rectangle filled with blue surrounded with a red line of thickness 10 will be translated into the following SVG element:

<rect x="10" y="10" width="100" height="100"

style="fill:blue;stroke:red;stroke-width:10.0" />

Advantages and Disadvantages of the Different Approaches

The advantages of the first technique are that it is not limited to a graphics toolkit such as JViews, and can be used for any type of Java tool that uses Java 2D for drawing. Since this technique does not need to know the classes of the toolkit, it allows users of the toolkit that define new classes to take advantage of the SVG generation.

However, this technique leads to several major drawbacks. One such drawback is that it is not possible to handle images using this technique. In SVG an image will be pointed to by its URL. In Java, images are handled with the java.awt.Image class. In many cases there is no URL associated with this image (because the image is created by some Java code) or there is no way to know the URL from which the image was loaded.

In addition to the problem of images, the resulting SVG document, when using the first approach, is likely to be larger in size and more complex than in the second technique. This is because the first approach does not take advantage of the notion of graphic objects of the toolkit. By taking advantage of this notion, you can produce the SVG elements that best fit the drawings you need. It may become crucial to get the best SVG when you need to associate scripting with the generated SVG document.

A grouping object can be used to illustrate these differences: Most 2D toolkits provide the ability to group graphic objects together using a grouping object. This grouping object does not draw anything itself but provides a way to logically group objects together so that a group of objects can be manipulated as a single object. If the first technique is used without any prior knowledge of the graphic objects, the grouping object will not produce any SVG elements. With the second technique we can produce an SVG grouping element (the <g> element) and thus mimic the object oriented structure of the toolkit and allow further scripting to manipulate objects of the group as a whole.

Another example that illustrates the differences between the two approaches is the definition of objects that do not zoom. If an object must always keep the same size in SVG regardless of the zoom level, its coordinates may be expressed in pixels. This tells the SVG viewer not to zoom the object. Such behavior cannot be achieved using the first technique, since you need to understand the internal logic of the graphic object.

Generating SVG in ILOG JViews

The second approach has been chosen for the ILOG JViews Component Suite. That is, we take advantage of the notion of graphic objects to produce the most suitable SVG for each graphic object class.

Exporting a JViews drawing in SVG is implemented as a type of output stream called the SVGOutputStream. To create an SVG document from the toolkit the user simply creates an SVGOutputStream and writes the contents of the manager (the JViews data structure that contains the graphic objects) to this stream.

Compression Techniques

When generating SVG documents, the JViews SVGOutputStream uses several techniques to reduce the size of the SVG documents. The size of the resulting SVG document is crucial because a small size will allow a fast download. Two techniques to reduce the size of the SVG document will be discussed:

Compression of Path Data

Reusing Styles

Compression of Path Data

The ‘path’ element of SVG allows you to define any type of shape. The shape is defined by the ‘d’ attribute of the ‘path’ element. The following example (taken from the SVG W3C Draft Recommendation) specifies a path in the shape of a triangle. (The shape is expressed by a set of command letters; the M corresponds to a moveto, the L’s indicate a lineto, and the z a closepath).

<path d=”M 100 100 L 140 100 L 120 140 z”/>

Compression of the ‘path’ element can take place in the definition of the path data. There are several techniques to compress the size of the path data.

First, all non-necessary spaces can be removed. The data is then expressed as “M100 100L140 100L120 140z”. Then, the letter for the command can be removed when it is the same as the previous command letter, which leads to “M100 100L140 100 120 140z”. This does not make a big difference since a space must then be added.

The most important point for compression is to use the command letter that will generate the smallest path. The SVG format provides relative versions of each command (upper case means absolute coordinates, lower case means relative coordinates). Therefore, when the coordinates are very large but the bounding area of the shape is small, it is more interesting to use relative coordinates.

The following examples display the same triangle:

<path d=”M10000 10000L10004 10004L9996 10004z”/>

<path d=”M10000 10000l4 4l-8 0z”/>

Another easy way to compress the path data is to use special command letters for the horizontal and vertical lines (H and V command letters). This leads to the following:

<path d=”M10000 10000l4 4h-8z”/>

This optimization is interesting in JViews when translating map data with coordinates that can be expressed as ‘large’ latitudes and longitudes and that displays only a small area of the world.

These compression techniques are not possible when using the ‘polyline’ element of SVG because the control points of this element are expressed as a list of absolute points. However, since the ‘polyline’ element can be easily expressed with a ‘path’ element, another way to compress is to translate JViews polyline objects into SVG ‘path’ elements.

Reusing Styles

In many two-dimensional displays we may find graphic objects that have the same styling parameters, for example, the same color. In these cases, the style can be reused and placed in the definition section of the SVG document.

For example, the following SVG document containing two rectangles that have the same style:

<svg>

<defs />

<rect x="210" y="10" width="100" height="100"

style="fill:blue;stroke:red;stroke-width:2" />

<rect x="10" y="10" width="100" height="100"

style="fill:blue;stroke:red;stroke-width:2" />

</svg>

can be replaced with this one:

<svg>

<defs>

<style>

<![CDATA[

.C0 {fill:blue;stroke:red;stroke-width:2.0}

]]>

</style>

</defs>

<rect x="210" y="10" width="100" height="100" class="C0" />

<rect x="10" y="10" width="100" height="100" class="C0" />

</svg>

This reduces the size of the resulting SVG file when many objects have the same style. Of course, this operation is optional since re-using the same style may not be appropriate in all cases.