How to Zoom and Pan with SVG

This topic shows you how to use Scalable Vector Graphics (SVG) to zoom and pan, and ends with an example of a complex organizational chart that can be zoomed and panned. Basic HTML and JavaScript knowledge are assumed, as well as access to a browser that can render inline SVG in HTML5, such as Windows Internet Explorer 9 and later.

  • Introduction
  • Creating an SVG Test Graphic
  • Browser-Based SVG Zoom and Pan
  • JavaScript-Based SVG Zoom and Pan
    • JavaScript Zoom
    • JavaScript Pan
    • Putting It All Together
  • Creating a Complex SVG Organizational Chart
    • Using Excel to Create an Organizational Chart List
    • Using Visio 2010 to Create an Org Chart Graphic
  • Displaying a Stand-Alone SVG File in a Webpage
  • Summary
  • Related topics

Introduction

In this topic we’ll first discuss how to zoom and pan in SVG using a detailed SVG test graphic. We’ll then describe how to use Microsoft Excel and Microsoft Visio 2010 to create a complex SVG organizational (org) chart, which can be displayed by an SVG-enabled browser.

Creating an SVG Test Graphic

One of the key features of SVG is the ability to "infinitely" zoom in on a detailed graphic. To highlight this feature, we need to create a sufficiently detailed SVG test graphic appropriate for both zooming and panning. Panning becomes important when a user has zoomed in on a particular feature of the graphic and wants to explore adjacent areas of the feature by scrolling.

An acceptable SVG test graphic, appropriate for both zooming and panning, might resemble the following graphic.

This graphic was created using the following example: HTML5 Inline SVG Test Graphic.

Note  For Internet Explorer 9, to view the example’s markup, right-click the rendered page and click View source.

 

The following (incomplete) code fragment, from the HTML5 Inline SVG Test Graphic example, exemplifies how the previous graphic was created.

<!-- Define an SVG graphic which will be reduced in size and reused multiple times. -->

<g id="parentGraphic" style="stroke: blue; fill: blue;">
  <rect x="5%" y="5%" width="90%" height="90%" rx="10" ry="10" 
        style="fill: none; stroke-width: 2px;"/>
  <text x="50%" y="97.2%" style="text-anchor: middle;">
    This text is going to get extremely small.
  </text>
  <text x="95.4%" y="50%" style="writing-mode: tb; text-anchor: middle;">
    The <tspan style="stroke: red;">red</tspan> center dot is to the left.
  </text>
  <text x="3.3%" y="50%" style="writing-mode: tb; text-anchor: middle;">
    The <tspan style="stroke: red; fill: red;">red</tspan> center dot is to the right.
  </text>
</g>

In the HTML5 Inline SVG Test Graphic example, this grouped SVG graphic (<g id="parentGraphic" ...>) was reduced in size and reused multiple times to create the previously shown test graphic through multiple invocations of the use element. For example:

<use href="#parentGraphic" … />

The use element creates a copy of the referenced element (and any children contained within the referenced element).

Additionally, be aware of the SVG text-anchor: middle style to easily center text as well as writing-mode: tb to display text vertically.

Like recent CSS transforms, SVG has always supported that same concept including translate, scale, and rotate. To scale a graphic by a given factor around some center point, you can use the following pseudocode:

transform="translate( -centerX*(factor-1), -centerY*(factor-1) ) scale(factor)"

In this pseudocode, (centerX, centerY) represents the (x, y) coordinate of the center point and factor is the desired scaling factor.

In this example, the SVG viewport is 800 x 600 pixels, so the center of the viewport occurs at (400, 300). To reduce parentGraphic by 10% (equivalent to a scaling factor of 0.9), you can use (in pseudocode):

transform="translate( -400*(0.9-1), -300*(0.9-1) ) scale(0.9)"

This simplifies to the following non-pseudocode:

transform="translate(40, 30) scale(0.9)"

This then can be applied directly to the use element to obtain the desired effect:

<use href="#parentGraphic" transform="translate(40, 30) scale(0.9)"/>

This technique is used to reduce and center the remaining ten versions of parentGraphic.

We’ll now use this test graphic to demonstrate how to zoom and pan in SVG in two ways: browser-based and script-based.

Browser-Based SVG Zoom and Pan

The simplest way to zoom and pan an SVG graphic is to use the browser’s native zooming and scrolling functionality. In Internet Explorer 9, the following table describes zoom-related mouse and keyboard shortcuts.

User action Keyboard shortcut Mouse shortcut
Zoom in Ctrl + Plus Ctrl + <forward wheel rotation>
Zoom out Ctrl + Minus Ctrl + <backward wheel rotation>
Return to default zoom level Ctrl + 0 N/A

 

Panning within a zoomed graphic is a simple matter of using the browser's scroll bars.

JavaScript-Based SVG Zoom and Pan

Because the user interface for zooming, panning, or both may vary from browser to browser (or for other reasons), it can be useful to implement your own JavaScript-based zooming and panning functionality. Examples of both follow.

JavaScript Zoom

This example uses two buttons and the mouse wheel to zoom in and out of the test graphic: currentScale SVG Zoom.

Although the sample is well documented through comments, there are a few items to be aware of:

  • The technique used to adjust the test graphic size (or zoom level) is the svg element’s currentScale attribute.
  • The mousewheel event was hooked to the window element (as opposed to the svg or body element) so that the mouse wheel is active over the entire webpage, regardless of zoom level.
  • The svg element's viewBox attribute is required to avoid a zoom-related rendering issue (try it without the viewBox attribute to observe the issue).

JavaScript Pan

After a particular SVG graphic is zoomed in, it may be useful then to be able to move (pan) the graphic to view various zoomed-in features. The following example uses the arrow keys to pan a simple SVG graphic (blue circle): SVG Pan.

In this example, panning (and zooming in the next example) is implemented by manipulating the value of the svg element’s viewBox attribute. The value of the viewBox attribute (a string of four numbers) specifies a rectangle in user space that is mapped to the bounds of the viewport (as established by the svg element). Using pedagogically useful but non-stand lexis, the viewBox syntax can be described as follows:

viewBox="ULCx ULCy UUwidth UUheight"

Note  ULCx and ULCy stand for "upper left corner x" and "upper left corner y", respectively. UUwidth and UUheight stand for "user unit width" and "user unit height", respectively.

 

Normally, SVG graphical objects are drawn relative to (that is, within) this user space (that is, user coordinate system). For zooming and panning with relatively static graphics, SVG graphical objects are generally never moved within their user coordinate system; instead, the user coordinate system itself is moved (along with all of its “attached” graphics) within (relative to) the SVG viewport. Thus from the viewport’s perspective, the graphical objects have moved. Stated another way, you generally move or transform the user coordinate system that graphical objects are “attached” to, not the graphical objects themselves.

With the above in mind, the four numbers, ULCx, ULCy, UUwidth, and UUheight, can be interpreted as follows:

  • ULCx and ULCy - The origin of the user coordinate system (that graphical objects are drawn within) is moved such that the point (ULCxULCy) occurs in the upper left corner of the defined SVG viewport. That is, visualize moving the user coordinate system within the viewport such that the user coordinate point (ULCxULCy) occurs in the upper left corner of the SVG viewport. This ends up moving, relative to the viewport, the origin of the user coordinate system along with all "attached" graphical objects.

    In the follow example, the user coordinate system is equivalent to the implicit viewport coordinate system.

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>  <!-- For intranet rendering only, remove when page is placed in production. -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="0 0 300 200"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html>
    

    This can be seen in the following screenshot with the user coordinate system superimposed over the viewport.

    In the next example, ULCx and ULCy are -50 and -25 respectively.

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>  <!-- For intranet rendering only, remove when page is placed in production. -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="-50 -25 300 200"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html> 
    

    This moves the user coordinate system such that the user coordinate point (-50, -25) occurs in the upper left corner of the viewport.

    This ends up "panning" the SVG graphic down and to the right. If UCLx and UCLy were both positive values, the graphic would move up and to the left (clipping off part of the graphic).

  • UUwidth and UUheight - These values determine the number of viewport pixels per user unit in the horizontal and vertical directions, respectively. Consider the following code snippet:

    <svg width="300px" height="200px" viewBox="0 0 300 200">

    In this case, there are 300 pixels per 300 user units horizontally and 200 pixels per 200 user units vertically. In other words, each user unit equals one pixel. However, in the following, there are 300 pixels per 600 user units (or 0.5 pixels per user unit) horizontally and 200 pixels per 400 user units (or 0.5 pixels per user unit) vertically. Notice that this change caused all graphical objects to be reduced in size by half, as shown in the following example.

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>  <!-- For intranet rendering only, remove when page is placed in production. -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="-50 -25 600 400"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html> 
    

    This scaling (or resizing) effect is shown in the following screenshot.

Putting It All Together

In this example, the value of the viewBox attribute (as described above) is used to both pan and zoom the SVG test graphic: SVG Zoom & Pan.

Keep in mind that, as opposed to programmatically modifying the svg element’s currentScale attribute value, this example implements zooming functionality by modifying the last two (width and height) values of the svg element’s viewBox attribute.

Creating a Complex SVG Organizational Chart

Excel (or another application) in combination with Visio 2010 can be used to create complex and highly detailed SVG organizational (org) charts, which can then be displayed by an SVG-enabled browser. We’ll describe this process by breaking it into its constituent components:

  • Using Excel to create a hierarchal organizational chart list.
  • Using Visio 2010 to create an SVG organizational chart graphic from an Excel list.
  • Displaying a stand-alone SVG file in a webpage.

Using Excel to Create an Organizational Chart List

The format of an organizational chart list is straightforward. For example, in the follow spreadsheet fragment, each employee of a hypothetical company lists their name, who they report to, as well as other useful information to be displayed on the chart.

Name Report To Title Department Telephone
Employee Name 1 VP Executive x5555
Employee Name 2 Employee Name 1 VP Executive x5556
Employee Name 3 Employee Name 1 VP Executive x5557
. . . . .
. . . . .
. . . . .
Employee Name 100 Employee Name 22 Individual Contributor Cafe Services x5654

 

The above table can be as long as reasonably desired and contain additional information, as necessary.

Note  Excel is not required to create an organizational chart list. Other applications (including a simple text file) can be used to define your organization’s hierarchy. For example, the following link provides the CSV version of the Excel file: 100 Employee Org Chart List (CSV format).

 

For more information, see the "Automatically create an organization chart by using an existing data source" section in the "Create an organization chart" topic of Visio 2010Help documentation.

After your organizational chart list is complete, you can import it into Visio 2010 as described in the next section.

Using Visio 2010 to Create an Org Chart Graphic

The importation of an organizational chart list is relatively straightforward. In Visio 2010, complete the following steps:

  1. Click the File tab.
  2. Click New, click Business, and then double-click Organization Chart Wizard.
  3. On the first page of the wizard, select Information that's already stored in a file or database.
  4. Click Next, and follow the remaining steps of the wizard.

Note  If you want your organizational chart to be on a single Visio 2010 page, choose I want to specify how much of my organization to display on each page as you work through the wizard.

 

For more information, see the "Automatically create an organization chart by using an existing data source" section in the "Create an organization chart" topic of Visio 2010Help documentation.

After the wizard has completed, adjust the resulting Visio 2010 organizational chart layout as necessary (possibly reducing font size) and then save the organizational chart in Scalable Vector Graphics (*.svg) format via the Save As dialog box. This SVG file can now be displayed in a supporting web browser as described in the next section.

Displaying a Stand-Alone SVG File in a Webpage

After an application such as Visio 2010 or InkScape has produced a stand-alone SVG file, you can display the SVG file in a supporting browser in a number of ways.

One of the easiest ways to display a stand-alone SVG file is simply to open it in a browser that supports stand-alone SVG. For example, clicking the following link opens the 100-employee Visio 2010 organizational chart, as described previously, that was saved in stand-alone SVG format: orgChart.svg.

You can then use the browser’s native zooming and scrolling (panning) functionality, as necessary, to explore this SVG graphic. In Internet Explorer 9 you can zoom in and out as described in the above table. Panning is accomplished by simply moving the scroll bars (when present).

After you have created the stand-alone SVG file, there are a number of ways to embed it into an existing or new webpage. For example, the iframe, embed, object, and img elements and CSS background-image style can be used. In particular, the object element is relatively helpful because it supports easy fallback functionality if the user’s browser does not support SVG. In the following markup, the stand-alone organizational chart SVG file is displayed by using the object element in an HTML webpage.

<!DOCTYPE html>
<html>
<head>  
  <title>100 Employee SVG Org Chart</title>
  <meta http-equiv="X-UA-Compatible" content="IE=9"/>  <!-- For intranet rendering only, remove when page is placed in production! -->
</head>

<body>
  <h1>Embedding SVG in a HTML Document</h1>
  <p>Embedding the file <em>orgChart.svg</em> using the <strong>object</strong> element:</p>
  <object data="orgChart.svg" width="800px" height="600px" type="image/svg+xml">
    <img src="orgChart.png" alt="PNG Image of 100 Employee SVG Org Chart" />
  </object>
</body>

</html>

Notice that a PNG image file (of the SVG organizational chart) is displayed if the user’s browser does not support SVG.

The following link extends this HTML <object> sample to include JavaScript-based zooming and panning (using the viewBox technique as described previously): SVG Org Chart with Zoom & Pan.

The SVG Org Chart with Zoom & Pan example uses the same techniques as previously discussed. However, one unique difference is that the script must access an svg element contained in a separate file – orgChart.svg. The following code snippet shows how this was done.

var theSvgDocument = document.getElementById('objectElement').getSVGDocument();
theSvgElement = theSvgDocument.documentElement;

In other words, the external SVG document object is accessed through the local object element. The SVG document object then provides access to the external svg element.

Summary

SVG’s vector nature lends itself perfectly to graphics that require a high degree of detail, such as complex organizational charts, architectural drawings, maps, and other similar media. This topic should help you to utilize one of SVG’s core features – scalable vector graphics.

How to Add SVG to a Webpage

SVG

SVG Reference

SVG Specification