Compiling Adaptive Diagrams into SVG

Keywords: adaptation , layout , constraints , authoring

Cameron McCormack
PhD Candidate
Monash University
Wellington Road
Clayton
Victoria
Australia
Cameron.McCormack@infotech.monash.edu.au

Kim Marriott
Monash University
Wellington Road
Clayton
Victoria
Australia
Kim.Marriott@infotech.monash.edu.au

Bernd Meyer
Monash University
Wellington Road
Clayton
Victoria
Australia
Bernd.Meyer@infotech.monash.edu.au


Abstract


Research into adaptive documents has focussed almost exclusively on text and multimedia content. It has largely ignored adaptation of diagrammatic content, treating these as a kind of image. This is unfortunate since charts, maps, plans, networks and other diagrammatic notations are an important, commonly used vehicle for communication. We believe that interactive media and the web requires a new kind of diagram, one that can adapt its content and presentation to suit the viewing context by taking into account the viewing device and the needs of the viewer, and which supports user interaction.

It is not reasonable to expect web developers to have to write explicit script to encode adaptive behaviour. High-level diagram authoring tools are required that hide this away from all but the most expert web developer. There are two important design requirements for such an authoring tool. First, it should be general enough to support common kinds of adaptive behaviour on a wide variety of different kinds of diagrams. Second, the resulting adaptive diagrams should be able to be compiled into a reasonably compact representation supported by current or proposed standards.

In this paper, we enumerate some commonly found types of diagram adaptation, identify a number of requirements that are necessarily imposed on an adaptive diagram model, compare possible techniques for compiling adaptive diagrams into a form usable by web browsers, and discuss what additional features SVG might have to better support adaptive diagrams.


Table of Contents


1. Introduction
2. Types of adaptation
3. Adaptive diagram model requirements
4. Compilation targets
     4.1 Alignments and distributions
     4.2 Multiple configurations
     4.3 Style adaptation
     4.4 Text adaptation
     4.5 Higher level layout
5. Conclusion
Bibliography
Footnotes

1. Introduction

Since the advent of the Web, there has been widespread recognition that this new communication medium requires intelligent, adaptive documents whose appearance and content adapts to the viewing context and which support user interaction. [Mal05] The desire to support such adaptive documents has been a major concern underlying the design of web document standards such as HTML, CSS, XSL and SMIL as well as the development of document authoring tools. [BLM00][JLS97]

Research into adaptive documents has focussed almost exclusively on text and multimedia content. It has largely ignored adaptation of diagrammatic content, treating these as a kind of image. This is unfortunate since charts, maps, plans, networks and other diagrammatic notations are an important, commonly used vehicle for communication. We believe that interactive media and the web requires a new kind of diagram, one that can adapt its content and presentation to suit the viewing context by taking into account the viewing device and the needs of the viewer, and which supports user interaction.

It is not reasonable to expect web developers to have to write explicit script to encode adaptive behaviour. High-level diagram authoring tools are required that hide this away from all but the most expert web developer. There are two important design requirements for such an authoring tool. First, it should be general enough to support common kinds of adaptive behaviour on a wide variety of different kinds of diagrams. Second, the resulting adaptive diagrams should be able to be compiled into a reasonably compact representation supported by current or proposed standards.

In this paper, we enumerate some commonly found types of diagram adaptation, identify a number of requirements that are necessarily imposed on an adaptive diagram model, compare possible techniques for compiling adaptive diagrams into a form usable by web browsers, and discuss what additional features SVG might have to better support adaptive diagrams.

2. Types of adaptation

A necessary first step in designing a tool for authoring adaptive diagrams is to identify and understand the kinds of adaptive behaviour that diagrams can usefully exhibit. We examined nearly 200 diagrams from a wide variety of application areas and detailed how each type of diagram could be sensibly adapted to different viewing environments. This allowed us to identify a number of distinct kinds of adaptive behaviour. The five most important are listed below:

We present a motivating example, consisting of an original diagram from our diagram survey and two adapted versions of the diagram which utilise several of the types of adaptation listed above. Figure 1(a) is a diagram from a biology textbook, which depicts the four steps involved in the process of cell division. Arrows are used to indicate progression between the steps. Text is used for both describing what happens at each step and also to label the parts of the cell in the first step. For the first adaptation, let us assume that the diagram is to be presented in a space that will not fit this vertical orientation, but that there is enough space to present the steps horizontally. The diagram could thus be adapted to the available space to look like Figure 1(b).

cell.png

Figure 1: Cell division diagram: (a) original diagram, (b) horizontal adaptation, (c) narrower version of horizontal adaptation, (d) interactive step-by-step adaptation.

There are some aspects of the original diagram that are important to keep in the adapted diagram, mostly for reasons of aesthetics and clarity. First, the lengths of the arrows are all equal and the space taken up by all four steps are equal. In the adapted version, these properties are kept, but because the arrows now run horizontally, in the same direction as the text, the arrows must be long enough to accommodate the widest label. To ensure that the labels describing the parts of the cell in the first step do not unnecessarily cause that step to take up more space, the layout of the labels is slightly different from those in the original diagram, where they are vertically left aligned.

The second adaptation is shown in Figure 1(c), which is the horizontal orientation of the diagram adapted to a narrower viewport and a larger desired font size. In response, the arrows have been shortened (effectively collapsing the whitespace between the cells) and the text labels on the arrows have been replaced with shorter, equivalent text.

The third adaptation of this diagram, Figure 1(d), demonstrates adapting to even less available rendering space and also the ability of a medium (in this case, a PDA-based browser) to provide user interaction. The smaller rendering space is insufficient to show all four steps at once. Since this adaptation is targetting a PDA-based browser, we can use zooming controlled by user interaction to allow a reader to navigate through the steps of the cell division process, thereby reducing the size of diagram needing to be displayed at the one time. The figure shows views of the rendering zoomed to each step. Since nagivation between the steps requires some form of on-screen control, each view has hyperlinks at the bottom of the diagram to move to the next and previous step, as appropriate. The steps of the cell division could also be shown with animation.

3. Adaptive diagram model requirements

The desire to support the above kinds of adaptation imposes a number of requirements on any authoring model for adaptive diagrams. First, adaptation does not always involve simply perturbing existing presentations; it can also use fundamentally different layouts or representations. Thus, the model must allow the specification of different configurations of the diagram that correspond to these fundamentally different layouts. These configurations can be used to represent different layouts chosen in response to available rendering space, or ones chosen as a result of focussing on certain areas of the diagram. To support the positioning of objects within the configurations, common layout tools such as guidelines and distributions are needed.

Second, to be able to adapt the form of an item in a diagram, the model must allow multiple versions to be specified as alternatives. In the degenerate case, this could be handled by the configuration mechanism, but without some way to factor out form changes, this would result in a combinatorial explosion of the number of configurations in a diagram. This then leads to a requirement on the model to have reusable objects that can be embedded in diagram configurations and which can be grouped together as alternate representations of the one item.

Third, in order to adapt the styles of objects within a diagram, the model will need to allow grouping common styles together, in much the same way as CSS allows, so that changes to the styles can be specified in one place.

Fourth, to allow adaptation of text string content in a diagram, the model must allow the assignment of lists of text strings that are equivalent and can be used interchangeably, one list for each language supported by the diagram.

Finally, to avoid having to specify these adaptations repeatedly for different conditions, they must be represented orthogonally in the model, but allow for specialisation where appropriate. For example, adapting a diagram from full colour to a red-green colour blind version may require only changes to be specified in the style classes. However, adapting to a monochrome medium could require changes to the objects that are presented in the configurations. Thus, a configuration could be specialised for use in the case of a monochrome output medium, but would use the general configuration for all other colour modes.

4. Compilation targets

One of the design goals of the authoring tool is that it should allow compilation of adaptive diagrams into a form that is suitable for delivery to a web browser. Simply creating a new XML language corresponding to the high level adaptive diagram model to deliver to the browser would not be feasible for a number of reasons. First, such a radical departure of the model from existing support for diagrammatic graphics on the client would likely lead it to be unimplemented, as incremental improvements tend to have more traction with implementors. Since we want adaptive diagrams to be usable in regular web browsers, this leads us to believe that serving the diagram to the client in a simpler form would be more appropriate. Second, implementing the model would be computationally more complex than implementing a compiled version specific for a particular diagram instance. Especially if we wish to consider more constrained clients, such as PDAs and other mobile devices, it is important to require the browser to compute only what is necessary.

Currently, there is low-level support for adaptive diagrams. Scalable Vector Graphics (SVG) [SVG11] supports zooming and uniform rescaling of diagrams, simple restyling through style sheets, and allows alternate versions of document elements for different languages. Support for more sophisticated adaptation and interactive behaviour can be achieved using scripting, and in the future XBL [XBL2] will allow the modularisation of such behaviour. There have been a number of proposals to extend SVG with more sophisticated layout capabilities based on linear arithmetic constraints [BTM01] or one-way constraints [MMT02][MMM04].

Here, we contrast two feasible compilation targets – plain SVG plus script, and CSVG plus script – to demonstrate the strengths and weaknesses of each as a choice for a viable platform for viewing adaptive diagrams in a browser. First, however, let us review the basic functionality of CSVG.

CSVG provides the ability for an author to give a one-way constraint system for computed values of element attributes and properties in an SVG document. Basically, the one-way constraint system is a set of assignments of values to attributes and properties that the user agent must evaluate when necessary. A typical use of CSVG would be to place graphical elements in a document relatively, such as in Figure 2. <c:constraint> elements in the document provide an expression to be evaluated to give the value of the attribute specified with the attributeName attribute.

csvg-simple.png
<svg xmlns="http://www.w3.org/2000/svg" xmlns:c="http://mcc.id.au/2004/csvg" …>

  <rect stroke="#478" stoke-width="1" fill="#cef">
    <c:variable name="extent" value="c:bbox(id(’t’))"/>
    <c:constraint attributeName="x" value="c:x($extent) - 5"/>
    <c:constraint attributeName="y" value="c:y($extent) - 5"/>
    <c:constraint attributeName="width" value="c:width($extent) + 10"/>
    <c:constraint attributeName="height" value="c:height($extent) + 10"/>
  </rect>
  <text id="t" x="300" y="50" text-anchor="middle">
    Text enclosed by a rectangle
  </text>

</svg>

Figure 2: A simple CSVG fragment showing a rectangle positioned to enclose the text, regardless of what size the text will be due to user font preferences.

Being a one-way constraint system, the set of all constraints in the document must not form any cycles. That is, the graph of dependencies between constrained attributes in the document must be a directed acyclic graph.

4.1 Alignments and distributions

We first look at how alignments and distributions within a diagram configuration can be compiled. Figure 3 shows two rectangles centred horizontally within the diagram by way of a fixed proportion distribution. As the width of the canvas changes, the positions of the two rectangles will follow. While the attachments of the horizontal centres of the rectangles to the distribution’s middle guideline are inherently multi-way relationships (that is, moving the rectangles should result in moving the distribution’s position, and vice versa), being ultimately attached to the immovable edges of the canvas results in only a single direction being allowed: resizing the canvas will reposition the rectangles. Thus, the relationship can be represented with one-way constraints. A possible compilation into CSVG is shown in Figure 4.

dist.png

Figure 3: Rectangles centred horizontally using a distribution.

<svg …>
  <rect y='60' width='100' height='50'>
    <c:constraint attributeName='x' value='c:width(c:viewport()) div 2 - @width div 2'/>
  </rect>
  <rect y='130' width='80' height='50'>
    <c:constraint attributeName='x' value='c:width(c:viewport()) div 2 - @width div 2'/>
  </rect>
</svg>

Figure 4: A possible compilation of Figure 3 into CSVG.

No script is required, as dynamic changes to the one-way constraints in the constraint graph are not needed. An equivalent compilation into plain SVG with script is shown in Figure 5

<svg … onload='reposition()' onresize='reposition()'>
  <script>
    function reposition() {
      var r1 = document.getElementById('r1');
      var r2 = document.getElementById('r2');
      var viewportWidth = document.documentElement.viewport.width / 2;
      r1.x.baseVal.value = viewportWidth - r1.width.baseVal.value / 2;
      r2.x.baseVal.value = viewportWidth - r2.width.baseVal.value / 2;
    }
  </script>

  <rect id='r1' y='60' width='100' height='50'/>
  <rect id='r2' y='130' width='80' height='50'/>
</svg>

Figure 5: A possible compilation of Figure 3 into plain SVG.

An event listener is just required for changes to the canvas size, and the rectangles are repositioned in response to that event. Here, compiling to CSVG has a distinct advantage over compiling to SVG plus script, since the attribute updates are specified completely declaratively.

Consider, however, an alignment of two rectangles whose positions are not ultimately determined by the size of the canvas. Figure 6 shows such a diagram, where the rectangles’ positions are not fixed, but are constrained to be vertically aligned. It may be that interaction is to be added to the diagram such that it may move one of the rectangles. Since moving the top rectangle must result in moving the bottom rectangle, and vice versa, this is a multi-way relationship that cannot be represented just by one-way constraints. Thus, if the diagram is to be compiled into CSVG, dynamic changes to the constraint graph must be made according to which rectangle is being moved, as shown in Figure 7.

align.png

Figure 6: Rectangles aligned vertically using a guideline.

<svg … onload='init()'>
  <script>
    var r1 = document.getElementById('r1');
    var r2 = document.getElementById('r2');
    var c1 = document.getElementById('c1');
    var c2 = document.getElementById('c2');

    function init() {
      r1.removeChild(c1);
      r2.removeChild(c2);
    }

    function beginDrag(evt) {
      if (evt.target == r1) {
        r2.appendChild(c2);
      } else if (evt.target == r2) {
        r1.appendChild(c1);
      }

      // Drag specific code...
    }

    function doDrag(evt) {
      if (dragging) {
        // Drag specific code...
      }
    }

    function endDrag(evt) {
      if (evt.target == r1) {
        r2.removeChild(c2);
      } else if (evt.target == r2) {
        r1.removeChild(c1);
      }

      // Drag specific code...
    }
  </script>

  <rect id='r1' x='50' y='60' width='80' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'>
    <c:constraint id='c1' attributeName='x' value='id("r2")/@x + id("r2")/@width div 2 - @width div 2'/>
  </rect>
  <rect id='r2' x='40' y='130' width='100' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'>
    <c:constraint id='c2' attributeName='x' value='id("r1")/@x + id("r1")/@width div 2 - @width div 2'/>
  </rect>
</svg>

Figure 7: A possible compilation of Figure 6 into CSVG.

In plain SVG with script, a similar technique must be used. When one of the rectangles is moved, the other’s position is updated, as shown in Figure 8.

<svg …>
  <script>
    var r1 = document.getElementById('r1');
    var r2 = document.getElementById('r2');

    function beginDrag(evt) {
      // Drag specific code...
    }

    function doDrag(evt) {
      if (dragging) {
        // Drag specific code...

        if (draggingR1) {
          r2.x.baseVal.value = r1.x.baseVal.value + r1.width.baseVal.value / 2 - r2.width.baseVal.value / 2;
        } else if (draggingR2) {
          r1.x.baseVal.value = r2.x.baseVal.value + r2.width.baseVal.value / 2 - r1.width.baseVal.value / 2;
        }
      }
    }

    function endDrag(evt) {
      // Drag specific code...
    }
  </script>

  <rect id='r1' x='50' y='60' width='80' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'/>
  <rect id='r2' x='40' y='130' width='100' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'/>
</svg>

Figure 8: A possible compilation of Figure 6 into plain SVG.

Since in the CSVG example the two constraints must be swapped in and out depending on which rectangle is being moved, the benefit of not having to attach explicit listeners to perform updates is lost. An improvement to CSVG would be to allow the two constraint elements to be in the document at all times, but to be able to disable them when desired. This would prevent unnecessary reparsing of the expressions and recomputation of the constraint graph.

Another possible extension to CSVG to avoid this problem would be to allow the <c:constraint> elements to have SMIL-like begin and end attributes, which determine when the constraints are enforced. This would allow the elimination of all script relating to the constraint elements in the above CSVG example, as shown in Figure 9.

<svg …>
  <script>
    function beginDrag(evt) {
      // Drag specific code...
    }

    function doDrag(evt) {
      if (dragging) {
        // Drag specific code...
      }
    }

    function endDrag(evt) {
      // Drag specific code...
    }
  </script>

  <rect id='r1' x='50' y='60' width='80' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'>
    <c:constraint id='c1' attributeName='x' value='id("r2")/@x + id("r2")/@width div 2 - @width div 2' begin='r2.mousedown' end='r2.mouseup'/>
  </rect>
  <rect id='r2' x='40' y='130' width='100' height='50' onmousedown='beginDrag(evt)' onmousemove='doDrag(evt)' onmouseup='endDrag(evt)'>
    <c:constraint id='c2' attributeName='x' value='id("r1")/@x + id("r1")/@width div 2 - @width div 2' begin='r1.mousedown' end='r2.mouseup'/>
  </rect>
</svg>

Figure 9: A possible compilation of Figure 6 into CSVG using SMIL attribute extensions.

Note however that most diagrams, given a choice of configuration, will have their layout ultimately determined by text size and window size. This means that for layouts within a single configuration, constraints enforced due to the layout tools will mostly result in one-way relationships that can be represented easily with CSVG without the need to modify the constraint graph using script.

4.2 Multiple configurations

Next, let us consider Figure 10, a diagram with two configurations: one, where three image objects are distributed horizontally across the canvas with arrows connecting them, in the style of a flow diagram, and another which presents a simple textual equivalent. The second configuration would be shown if canvas is not wide or tall enough to fit all three image elements without them overlapping. In CSVG, this can be achieved by using a variable (canFitConfig1) to compute whether the canvas is wide and high enough, and based on that value, show and hide the relevant objects in the diagram, as shown in Figure 11.

multiple.png

Figure 10: A diagram with two configurations.

<svg …>
  <c:variable name='canFitConfig1' value='c:width(c:viewport()) &gt;= 340 and (c:height(c:viewport()) &gt;= 100)'/>

  <g>
    <!-- Configuration 1 -->
    <c:constraint attributeName='display' value='c:if($canFitConfig1, "inline", "none")'/>

    <image id='monkey' xlink:href='monkey.svg' x='10' width='100' height='80'>
      <c:constraint attributeName='y' value='c:height(c:viewport()) div 2 - 40'/>
    </image>
    <line x1='110' marker-end='url(#arrowhead)'>
      <c:constraint attributeName='x2' value='id("banana")/@x'/>
      <c:constraint attributeName='y1' value='c:height(c:viewport()) div 2'/>
      <c:constraint attributeName='y2' value='@y1'/>
    </line>
    <image id='banana' xlink:href='banana.svg' width='100' height='80'>
      <c:constraint attributeName='x' value='c:width(c:viewport()) div 2 - 50'/>
      <c:constraint attributeName='y' value='c:height(c:viewport()) div 2 - 40'/>
    </image>
    <line marker-end='url(#arrowhead)'>
      <c:constraint attributeName='x1' value='id("banana")/@x + id("banana")/@width'/>
      <c:constraint attributeName='x2' value='id("smiley")/@x'/>
      <c:constraint attributeName='y1' value='c:height(c:viewport()) div 2'/>
      <c:constraint attributeName='y2' value='@y1'/>
    </line>
    <image id='smiley' xlink:href='smiley.svg' width='100' height='80'>
      <c:constraint attributeName='x' value='c:width(c:viewport()) - 110'/>
      <c:constraint attributeName='y' value='c:height(c:viewport()) div 2 - 40'/>
    </image>
  </g>

  <g>
    <!-- Configuration 2 -->
    <c:constraint attributeName='display' value='c:if($canFitConfig1, "none", "inline")'/>

    <textArea x='10' y='10'>
      <c:constraint attributeName='width' value='c:width(c:viewport()) - 20'/>
      <c:constraint attributeName='height' value='c:height(c:viewport()) - 20'/>

      If you give a monkey a banana, he will be happy.
    </textArea>
  </g>
</svg>

Figure 11: A possible compilation of Figure 10 into CSVG.

A compilation of this diagram with SVG plus script must do much the same, but with event listeners to capture the canvas resize events, as shown in Figure 12.

<svg … onload='update()' onresize='update()'>
  <script><![CDATA[
    var canFitConfig1 = true;

    function update() {
      var viewport = document.documentElement.viewport;

      // Check to see if the configuration needs switching.
      var canFit = viewport.width > 340 && viewport.height < 330;
      if (canFitConfig1 && !canFit) {
        canFitConfig1 = false;
        document.getElementById('config1').setAttribute('display', 'none');
        document.getElementById('config2').setAttribute('display', 'inline');
      } else if (!canFitConfig1 && canFit) {
        canFitConfig1 = true;
        document.getElementById('config1').setAttribute('display', 'inline');
        document.getElementById('config2').setAttribute('display', 'none');
      }

      // Reposition the elements.
      if (canFitConfig1) {
        var monkey = document.getElementById('monkey');
        monkey.y.baseVal.value = viewport.height / 2 - 40;

        var banana = document.getElementById('banana');
        banana.x.baseVal.value = viewport.width / 2 - 50;
        banana.y.baseVal.value = viewport.height / 2 - 40;

        var smiley = document.getElementById('smiley');
        smiley.x.baseVal.value = viewport.width - 110;
        smiley.y.baseVal.value = viewport.height / 2 - 40;

        var line1 = document.getElementById('line1');
        line1.x2.baseVal.value = banana.x.baseVal.value;
        line1.y1.baseVal.value = viewport.height / 2;
        line1.y2.baseVal.value = viewport.height / 2;

        var line2 = document.getElementById('line2');
        line2.x1.baseVal.value = banana.x.baseVal.value + banana.width.baseVal.value;
        line2.x2.baseVal.value = smiley.x.baseVal.value;
        line2.y1.baseVal.value = viewport.height / 2;
        line2.y2.baseVal.value = viewport.height / 2;
      } else {
        var text = document.getElementById('text');
        text.width.baseVal.value = viewport.width - 20;
        text.height.baseVal.value = viewport.height - 20;
      }
    }
  ]]></script>

  <g id='config1'>
    <!-- Configuration 1 -->
    <image id='monkey' xlink:href='monkey.svg' x='10' width='100' height='80'/>
    <line id='line1' x1='110' marker-end='url(#arrowhead)'/>
    <image id='banana' xlink:href='banana.svg' width='100' height='80'/>
    <line id='line2' marker-end='url(#arrowhead)'/>
    <image id='smiley' xlink:href='smiley.svg' width='100' height='80'/>
  </g>

  <g id='config2' display='none'>
    <!-- Configuration 2 -->
    <textArea id='text' x='10' y='10'>
      If you give a monkey a banana, he will be happy.
    </textArea>
  </g>
</svg>

Figure 12: A possible compilation of Figure 10 into plain SVG.

In this case, CSVG provides a natural declarative mechanism for selecting which configuration of the diagram to show. The plain SVG plus script version again must attach event listeners explicitly to perform the adaptation. For cases when the configuration to display can be selected just based on medium size and capabilities, using CSS3 Media Queries [CSSMQ] to show and hide objects representing the configurations or DISelect [DIS] to include/exclude the relevant object would be sufficient. However, since it is often the case that computations of available space are in terms of a user selected font, these could not be used without extensions except in limited cases.

Note that in the plain SVG version, the ordering of the statements in the script to perform the element repositioning needed to match the topological sorted order of the constraints in the diagram. While this is no problem for a compiling authoring tool, for an author constructing the SVG document by hand it is somewhat trickier.

In terms of compilation, multiple configurations for one diagram is just a special case of alternate forms for diagram elements. Figure 13 shows a network diagram, where the sub-network of computers connected to the router (beyond the first) has two possible representations, outlined in red: the first shows the full complement of three computers, while the second shows an ellipsis.

net.png

Figure 13: Network diagram using alternate representations of a component.

As with the compilations for the multiple configuration diagram above, there is little difference between the CSVG and plain SVG compilations for this network diagram. The CSVG version is shown in Figure 14. (The plain SVG version is omitted for brevity.)

<svg …>
  <c:variable name='canFitComputers' value='c:width(c:viewport()) &gt;= 560'/>

  <!-- One configuration... -->

  <image xlink:href='cloud.svg' x='10' y='10' width='100' height='50'/>
  <line x1='60' y1='60' x2='60' y2='100'/>

  <image xlink:href='router.svg' x='10' y='100' width='100' height='100'/>

  <line x1='110' y1='150' x2='250' y2='150'/>
  <line x1='200' y1='150' x2='200' y2='180'/>
  <image xlink:href='computer.svg' x='150' y='180' width='100' height='100'/>

  <!-- Two alternatives for the remaining computers on the network -->
  <g>
    <c:constraint attributeName='display' value='c:if($canFitComputers, "inline", "none")'/>
    <line x1='250' y1='150' x2='550' y2='150'/>

    <line x1='300' y1='150' x2='300' y2='180'/>
    <image xlink:href='computer.svg' x='250' y='180' width='100' height='100'/>

    <line x1='300' y1='150' x2='300' y2='180'/>
    <image xlink:href='computer.svg' x='350' y='180' width='100' height='100'/>

    <line x1='300' y1='150' x2='300' y2='180'/>
    <image xlink:href='computer.svg' x='450' y='180' width='100' height='100'/>
  </g>
  <g>
    <c:constraint attributeName='display' value='c:if($canFitComputers, "none", "inline")'/>
    <image xlink:href='ellipsis.svg' x='250' y='140' width='20' height='20'/>
  </g>
</svg>

Figure 14: A possible compilation of Figure 13 into CSVG.

4.3 Style adaptation

A lot of the work involved style adaptations can be performed by the CSS engine in an SVG user agent. It is just the style selection mechanism which needs to be implemented in the document. For example, consider a simple bar chart as shown in Figure 15. The first view is the chart shown with colours, and the second is a version adapted to a monochromatic medium. Our adaptive diagram model requirements state that this styling should be able to be performed orthogonally from the actual configuration of the diagram, and this is indeed possible. Compiling this diagram to CSVG or SVG plus script would be virtually identical, since neither has the ability to determine whether the target medium supports colours or not. Instead, this would need to be a variable whose value is given from outside the document somehow. This variable would then determine either what CSS classes the rectangles representing the bars would be members of, or what entire stylesheet to apply to the document. For example, using CSVG to affect the class names would result in a document like the one in Figure 16, assuming the existence of a hypothetical c:colourMode function that returns the bits-per-pixel of the colour mode supported.

bar.png

Figure 15: A bar chart adapted to a monochromatic medium.

<svg …>

  <defs>
    <!-- Monochrome <pattern> definitions go here. -->
  </defs>

  <style>
    .bar1Colour { fill: #c44 }
    .bar2Colour { fill: #4c4 }
    .bar3Colour { fill: #44c }

    .bar1Mono { fill: url(#dots) }
    .bar2Mono { fill: url(#diagonals) }
    .bar3Mono { fill: url(#verticals) }
  </style>

  <g stroke='black' stroke-width='1'>
    <!-- Axes -->
    <line x1='50' y1='160' x2='50' y2='40'/>
    <line x1='50' y1='40' x2='45' y2='45'/>
    <line x1='50' y1='40' x2='55' y2='45'/>
    <line x1='50' y1='160' x2='270' y2='160'/>
    <line x1='270' y1='160' x2='265' y2='155'/>
    <line x1='270' y1='160' x2='265' y2='165'/>

    <!-- Bars -->
    <c:variable name='classSuffix' value='c:if(c:colourMode() = 1, "Mono", "Colour")'/>
    <rect x='77' y='75' width='27.5' height='85'>
      <c:constraint attributeName='class' value='concat("bar1", $classSuffix)'/>
    </rect>
    <rect x='132' y='115' width='27.5' height='45'>
      <c:constraint attributeName='class' value='concat("bar2", $classSuffix)'/>
    </rect>
    <rect x='187' y='95' width='27.5' height='65'>
      <c:constraint attributeName='class' value='concat("bar3", $classSuffix)'/>
    </rect>
  </g>

</svg>

Figure 16: A possible compilation of Figure 15 into CSVG.

Choosing to use plain SVG to switch the whole stylesheet would result in the document in Figure 17.

<svg …>

  <defs>
    <!-- Monochrome <pattern> definitions go here. -->
  </defs>

  <style id='colour'>
    .bar1 { fill: #c44 }
    .bar2 { fill: #4c4 }
    .bar3 { fill: #44c }
  </style>

  <style id='mono'>
    .bar1 { fill: url(#dots) }
    .bar2 { fill: url(#diagonals) }
    .bar3 { fill: url(#verticals) }
  </style>

  <script>
    // We assume that there is a colourMode property exposed on SVGSVGElement,
    // with the same behaviour as the hypothetical c:colourMode() function used
    // in the CSVG example.

    var svg = document.documentElement;
    if (svg.colourMode == 1) {
      svg.removeChild(document.getElementById('colour'));
    } else {
      svg.removeChild(document.getElementById('mono'));
    }
  </script>

  <g stroke='black' stroke-width='1'>
    <!-- Axes -->
    <line x1='50' y1='160' x2='50' y2='40'/>
    <line x1='50' y1='40' x2='45' y2='45'/>
    <line x1='50' y1='40' x2='55' y2='45'/>
    <line x1='50' y1='160' x2='270' y2='160'/>
    <line x1='270' y1='160' x2='265' y2='155'/>
    <line x1='270' y1='160' x2='265' y2='165'/>

    <!-- Bars -->
    <rect x='77' y='75' width='27.5' height='85' class='bar1'/>
    <rect x='132' y='115' width='27.5' height='45' class='bar2'/>
    <rect x='187' y='95' width='27.5' height='65' class='bar3'/>
  </g>

</svg>

Figure 17: A possible compilation of Figure 15 into plain SVG.

Since the style changes are a global decision, it obviously is simpler to switch the whole stylesheet depending on the value of the SVGSVGElement.colourMode property. CSVG provides no advantage here, since it does not have any way of exposing the abilities of the medium to the expressions used in the constraints, nor of disabling a stylesheet. These are both certainly possible extensions to CSVG that would be worth adding – a function that returns the colour mode could be used in a condition attribute on the <style> element that determines whether to apply the stylesheet or not.

CSS3 Media Queries, in this case, would provide an even better and more succinct solution. Figure 18 shows that no script is required if the media queries are used to select the relevant stylesheet rules.

<svg …>

  <defs>
    <!-- Monochrome <pattern> definitions go here. -->
  </defs>

  <style>
    @media all and (color) {
      .bar1 { fill: #c44 }
      .bar2 { fill: #4c4 }
      .bar3 { fill: #44c }
    }

    @media all and (monochrome) {
    .bar1 { fill: url(#dots) }
    .bar2 { fill: url(#diagonals) }
    .bar3 { fill: url(#verticals) }
    }
  </style>

  <g stroke='black' stroke-width='1'>
    <!-- Axes -->
    <line x1='50' y1='160' x2='50' y2='40'/>
    <line x1='50' y1='40' x2='45' y2='45'/>
    <line x1='50' y1='40' x2='55' y2='45'/>
    <line x1='50' y1='160' x2='270' y2='160'/>
    <line x1='270' y1='160' x2='265' y2='155'/>
    <line x1='270' y1='160' x2='265' y2='165'/>

    <!-- Bars -->
    <rect x='77' y='75' width='27.5' height='85' class='bar1'/>
    <rect x='132' y='115' width='27.5' height='45' class='bar2'/>
    <rect x='187' y='95' width='27.5' height='65' class='bar3'/>
  </g>

</svg>

Figure 18: A possible compilation of Figure 15 into plain SVG plus CSS3 Media Queries.

Media queries work well here because it is only the styling of objects that needs to be adapted according to the colour-ability of the target medium. If further specialisation of the adaptation were required, for example a change of the position of the objects or the introduction of new ones, something more powerful would be required.

Given that CSS3 Media Queries has already been published, it would be wise if extensions to CSVG and the DOM that exposed information about the target medium used the same syntax.

4.4 Text adaptation

Finally, consider an example diagram whose text strings change to accommodate the available space and also the viewer’s desired language. Figure 19 shows a version of the bar chart from the previous example that can adapt to two different languages (German and English) and also provides shorter alternatives for the text strings in the English version.

text.png

Figure 19: A bar chart with adapted text.

As with the colour mode, CSVG does not expose the user’s desired language to the expressions in the document. If it were, expressions could be used to set the xlink:href attribute of <tref> elements so that they reference the desired text string, based on the language and some bounding box computations to ensure there is enough space. A CSVG example using a hypothetical c:userLanguage function is as shown in Figure 20.

<svg …>

  <!-- Elements representing the axes -->
  <line ...>
    <c:constraint .../>
  </line>
  ...

  <!-- Elements representing the bars -->
  <rect id='bar1'>
    <c:constraint .../>
    ...
  </rect>
  <rect id='bar2'>
    <c:constraint .../>
  </rect>
  <rect id='bar3'>
    <c:constraint .../>
    ...
  </rect>

  <!-- Text labels -->
  <c:variable name='spaceBetweenBars' value='id("bar2")/@x - id("bar1")/@x'/>

  <defs>
    <text id='ena1'>First</text>
    <text id='ena2'>Second</text>
    <text id='ena3'>Third</text>
    <text id='enb1'>1st</text>
    <text id='enb2'>2nd</text>
    <text id='enb3'>3rd</text>
    <text id='de1'>Erste</text>
    <text id='de2'>Zweite</text>
    <text id='de3'>Dritte</text>
  </defs>

  <c:variable name='enaFits' value='c:width(c:bbox(id("en1a"))) &lt;= $spaceBetweenBars
                                and c:width(c:bbox(id("en2a"))) &lt;= $spaceBetweenBars
                                and c:width(c:bbox(id("en3a"))) &lt;= $spaceBetweenBars'/>

  <c:variable name='prefix' value='c:if(c:userLanguage() = "en", c:if($enaFits, "ena", "enb"), "de")'/>

  <g text-anchor='middle'>
    <text>
      <c:constraint attributeName='x' value='id("bar1")/@x + id("bar1")/@width div 2'/>
      <c:constraint attributeName='y' value='id("bar1")/@y + id("bar1")/@height + c:height(c:bbox(.))'/>
      <tref>
        <c:constraint attributeName='xlink:href' value='concat("#", $prefix, "1")'/>
      </tref>
    </text>
    <text>
      <c:constraint attributeName='x' value='id("bar2")/@x + id("bar2")/@width div 2'/>
      <c:constraint attributeName='y' value='id("bar2")/@y + id("bar2")/@height + c:height(c:bbox(.))'/>
      <tref>
        <c:constraint attributeName='xlink:href' value='concat("#", $prefix, "2")'/>
      </tref>
    </text>
    <text>
      <c:constraint attributeName='x' value='id("bar3")/@x + id("bar3")/@width div 2'/>
      <c:constraint attributeName='y' value='id("bar3")/@y + id("bar3")/@height + c:height(c:bbox(.))'/>
      <tref>
        <c:constraint attributeName='xlink:href' value='concat("#", $prefix, "3")'/>
      </tref>
    </text>
  </g>
</svg>

Figure 20: A possible compilation of Figure 19 into CSVG.

SVG provides some basic adaptation to language using the <switch> element, however this only selects languages based on whether the user has specified in the user agent’s preferences that they have some level of understanding of a given language. In particular, it does not allow for the selection of the language the user has the most understanding of, as is commonly used in content negotiation with the HTTP Accept-Language header. Assuming that the restricted behaviour of the <switch> element is sufficient, the plain SVG example in Figure 21 demonstrates the text string adaptation desired:

<svg … onload='update()' onresize='update()'>

  <!-- Elements representing the axes -->
  <line .../>
  ...

  <!-- Elements representing the bars -->
  <rect id='bar1'/>
  <rect id='bar2'/>
  <rect id='bar3'/>

  <script><![CDATA[
    function update() {
      // Reposition axis and bar elements according to the viewport size...

      var bar1 = document.getElementById('bar1');
      var bar2 = document.getElementById('bar2');
      var spaceBetweenBars = bar2.x.baseVal.value - bar1.x.baseVal.value;

      var text1 = document.getElementById('text1');
      text1.x.baseVal.value = bar1.x.baseVal.value + bar1.width.baseVal.value / 2;
      text1.y.baseVal.value = bar1.y.baseVal.value + bar1.height.baseVal.value + text1.getBBox().height;

      var text2 = document.getElementById('text2');
      text2.x.baseVal.value = bar2.x.baseVal.value + bar2.width.baseVal.value / 2;
      text2.y.baseVal.value = bar2.y.baseVal.value + bar2.height.baseVal.value + text2.getBBox().height;

      var text3 = document.getElementById('text3');
      text3.x.baseVal.value = bar3.x.baseVal.value + bar3.width.baseVal.value / 2;
      text3.y.baseVal.value = bar3.y.baseVal.value + bar3.height.baseVal.value + text3.getBBox().height;

      var enaFits = document.getElementById('en1a').getBBox().width <= spaceBetweenBars
                 && document.getElementById('en2a').getBBox().width <= spaceBetweenBars
                 && document.getElementById('en3a').getBBox().width <= spaceBetweenBars;

      var tref1 = document.getElementById('tref1');
      var tref2 = document.getElementById('tref2');
      var tref3 = document.getElementById('tref3');
      if (enaFits) {
        tref1.href.baseVal = '#ena1';
        tref2.href.baseVal = '#ena2';
        tref3.href.baseVal = '#ena3';
      } else {
        tref1.href.baseVal = '#enb1';
        tref2.href.baseVal = '#enb2';
        tref3.href.baseVal = '#enb3';
      }
    }
   ]]></script>

  <!-- Text labels -->

  <defs>
    <text id='de1'>Erste</text>
    <text id='de2'>Zweite</text>
    <text id='de3'>Dritte</text>
    <text id='ena1'>First</text>
    <text id='ena2'>Second</text>
    <text id='ena3'>Third</text>
    <text id='enb1'>1st</text>
    <text id='enb2'>2nd</text>
    <text id='enb3'>3rd</text>
  </defs>

  <g text-anchor='middle'>
    <text id='text1'>
      <switch>
        <g systemLanguage='en'>
          <tref id='tref1' xlink:href='#ena1'/>
        </g>
        <g systemLanguage='de'>
          <tref xlink:href='#de1'/>
        </g>
      </switch>
    </text>
    <text id='text2'>
      <switch>
        <g systemLanguage='en'>
          <tref id='tref2' xlink:href='#ena2'/>
        </g>
        <g systemLanguage='de'>
          <tref xlink:href='#de2'/>
        </g>
      </switch>
    </text>
    <text>
      <switch>
        <g systemLanguage='en'>
          <tref id='tref3' xlink:href='#ena3'/>
        </g>
        <g systemLanguage='de'>
          <tref xlink:href='#de3'/>
        </g>
      </switch>
    </text>
  </g>
</svg>

Figure 21: A possible compilation of Figure 19 into plain SVG.

While the <switch> element can do the language-based selection, it cannot select the text string based on the available space. Thus, similarly to the CSVG version, the <tref> elements are modified to select the text string to be used.

4.5 Higher level layout

While the combination of distributions and guidelines can be used to implement most of the layouts found in our diagram survey, the use of CSVG is not always the best approach. For example, it is possible to implement a grid using one-way constraints (as demonstrated at [1]), but it is somewhat complex. High level layouts such as flow, tree, grid and general graph layout occurred commonly enough in our diagram survey that they deserve particular attention.

Although the complex set of one-way constraints required for setting up high level layouts of SVG objects can certainly be computed by the authoring tool during its diagram compilation process, there are a couple of arguments for having such high level layout functionality in the language extension that is supporting adaptive diagrams. First, dynamically generated diagrams, such as those created by a web application in response to a database query, will not be able to use the statically generated set of constraints that the authoring tool computed during compilation. Second, certain high level layouts are simple and useful enough that their inclusion in the language would be a viable first step towards including general layout capabilities in SVG.

High level layouts come in a number of forms. Widget layout functionality, such as that provided by XUL[2] and Swing[3], typically work on a box-containment model, where the layout generates a number of rectangular spaces, within which a widget or a nested box-containment layout may be placed. There have been a number of requests for this kind of layout functionality in SVG, dating back to 2004[4]. In addition, it has been shown that it is possible to integrate layout managers into SVG’s rendering model. [RoE05] Tree and general graph layouts are another kind, where each item to be laid out is positioned on the canvas according to some heuristic usually designed to encapsulate some aesthetic requirements.

Given that the box-containment model is such a common layout technique, applicable to a wide variety of diagrams and applications, it makes sense to include a number of these layouts in the language. General graph layouts tend to be specialised and domain specific, and thus would not be as beneficial for inclusion in the language. However, with careful design of the layout model such that it could be extensible by script within the document (for example by implementing a particular DOM interface), these layouts would not need to be excluded.

The inclusion of high level layouts does not completely obviate the need for one-way constraints (or equivalent script to implement the same behaviour), however. Take Figure 1(c) for example: the layout within this configuration could be obtained by a horizontal and vertical distribution tool, but it may be easier to think of it as being positioned by a single (hypothetical) grid layout tool, as shown in Figure 22. The positions of the cell images and the arrows can be set by placing those objects within the grid cells.

cellgrid2.png

Figure 22: A hypothetical grid layout tool positioning the components of the horizontal cell division diagram from Figure 1.

The arrow labels and the labels on the left of the diagram do not fit well within the grid cells, though. Since the grid cell positions will change according to the canvas size, these labels still need to have their position constrained. The grid layout tool could then be seen to be an input to some one-way constraints, which would position the labels appropriately.

5. Conclusion

In this paper we have outlined some requirements on an adaptive diagram model and detailed how aspects of that model could be compiled down to two target languages: CSVG, and plain SVG. Based on the comparison of the two outputs, we find that neither is the best choice as a complete target language for adaptive diagrams. Certain aspects of the model, such as simple configuration switching and style adaptation, can be handled by existing adaptation technologies not yet integrated into SVG, such as CSS3 Media Queries and content selection through DISelect. Text adaptation and form changing can be achieved in plain SVG with little benefit from using CSVG features. Layout adaptation is better suited to one-way constraints in CSVG, and could benefit from a speed advantage over script based layout, although the obvious drawback with CSVG is that it is just a proposal and is not implemented anywhere but in a single prototype.

It is more likely that a near future version of SVG would include some select high level layouts, such as the box-containment ones, than general layout capabilities such as provided by CSVG. However, since these box-containment layouts can be represented using one-way constraints, if a far future version of SVG were to include constraints there would be sufficient consistency in the model for the layouts and the constraints to work together. An advantage of one-way constraints is that layouts within the diagram can be treated as a “black box” if necessary, which means that even though general graph layout algorithms may not be able to be converted into a set of one-way constraints, the graph node positions that are outputs of the algorithm can still be used as inputs into the constraint graph being used to lay out the rest of the diagram.

The combination of some high level layout mechanisms, one-way constraints, content selection and stylesheet language media queries would seem to provide the best set of features for SVG to support adaptive diagrams. High level layouts are the least developed of these features, and would benefit from further discussion and specification.

Bibliography

[BLM00]
Alan Borning, Richard Lin and Kim Marriott. Constraint-based document layout for the Web. ACM/Springer Verlag Multimedia Systems Journal, 8(3):177–189, 2000.
[BTM01]
Greg Badros, Jojada Tirtowidjojo, Kim Marriott, Bernd Meyer, Will Portnoy and Alan Borning. A constraint extension to scalable vector graphics. Proceedings of the 10th World Wide Web Conference, 2001.
[CSSMQ]
Håkon Wium Lie, Tantek Çelik and Daniel Glazman. Media Queries. June 2007. http://www.w3.org/TR/css3-mediaqueries/.
[DIS]
Rhys Lewis, Roland Merrick and Max Froumentin. Content Selection for Device Independence (DISelect) 1.0. July 2007. http://www.w3.org/TR/cselection/.
[JLS97]
Muriel Jourdan, Nabil Layaïda, Cécile Roisin, Loay Sabry-Ismail and Laurent Tardif. MADEUS: An Authoring Environment for Interactive Multimedia Documents. Proceedings of the 6th ACM International Conference on Multimedia, 267–272, 1998.
[MMM04]
Cameron McCormack, Kim Marriott and Bernd Meyer. Adaptive layout using one-way constraints in SVG. Proceedings of the 3rd Annual Conference on Scalable Vector Graphics, September 2004. http://www.svgopen.org/2004/papers/ConstraintSVG/.
[MMT02]
Kim Marriott, Bernd Meyer and Laurent Tardif. Fast and Efficient Client-side Adaptivity for SVG. Proceedings of the 11th World Wide Web Conference, 2002.
[Mal05]
Tom Malloy. The future of documents. Proceedings of the 2005 ACM Symposium on Document Engineering, May 2005.
[RoE05]
Martin Rotard and Thomas Ertl. Layout managers for Scalable Vector Graphics. Proceedings of the 4th Annual Conference on Scalable Vector Graphics, August 2005. http://www.svgopen.org/2005/papers/LayoutManagersForSVG/.
[SVG11]
Jon Ferraiolo, Fujisawa Jun and Dean Jackson. Scalable Vector Graphics (SVG) 1.1 Specification. January 2003. http://www.w3.org/TR/2003/REC-SVG11-20030114/.
[XBL2]
Ian Hickson. XML Binding Language (XBL) 2.0. March 2007. http://www.w3.org/TR/2007/CR-xbl-20070316/.

Footnotes

  1. http://www.csse.monash.edu.au/~clm/csvg/templates.html#e11

  2. http://www.mozilla.org/projects/xul/layout.html

  3. http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html

  4. http://lists.w3.org/Archives/Public/www-svg/2004Jul/0005.html

XHTML rendition made possible by SchemaSoft's Document Interpreter™ technology.