Tangled in the Threads

Jon Udell, June 14, 2000

Scalable Vector Graphics

SVG is about to become "PostScript for the Web"

In January's column, Simple Charting for the Web, we looked at ways to rasterize charts but concluded with a down-to-earth example that used nothing fancier than an HTML table to form a bar chart. The HTML approach wasn't just simpler, it was arguably better. For example, each of its datapoints could trivially be linked to detail reports. It's much harder to achieve this drill-down effect in raster space.

I mentioned then that SVG (Scalable Vector Graphics) was poised to become, among other things, the next incarnation of this Web-native approach to charting. Last week, with the release of the 1.0 version of Adobe's SVG viewer, that option began to look imminent. Here's a picture of an SVG version of the chart from the January column, viewed in MSIE with the Adobe SVG plug-in.

Example 1: SVG version of chart, viewed in the Adobe plug-in

SVG source for the chart

Creating the SVG version of the chart is a lot like creating the HTML version -- and that's a very good thing. As with HTML, there are all sorts of construction techniques: you can write the stuff by hand in a text editor, you can write scripts to automate parts of that process, or you can use WYSIWYG editors to build it interactively. Web developers already familiar with CSS styling and scripted, template-driven HTML construction will find themselves immediately productive with SVG.

For example, I started building this week's example in Jasc Software's Trajectory Pro, a new WYSIWYG vector-illustration tool (still in beta) whose native format is SVG. But for a simple example like this one, using none of SVG's advanced effects -- paths, gradients, filters -- the WYSIWYG tool was overkill. It was almost easier for me to write the SVG code by hand. Here's a chunk of SVG for a label and its associated pair of bars:

Example 2: SVG fragment for element cluster

<g transform="translate(1in,100)">

<text style="text-anchor:end; font-size:15; 
  font-family:Arial" x="0" y="20">retail</text>

<rect style="stroke:#000000; fill:lightgray" 
  x="70" y="0" width="400" height="20"/>

<text style="text-anchor:end; font-family:Arial; 
  font-weight:bold" x="60" y="15">275104</text>

<rect style="stroke:#000000; fill:#ccffcc" x="70" y="20" 
  width="147" height="20"/>

<text style="text-anchor:end; font-family:Arial; 
  font-weight:bold" x="60" y="35">101141</text>

</g>

A chunk of SVG like the one in Example 2, whether tool-written or hand-written, wants to be parameterized so you can automatically repeat it with variations. That's a job for a script. The familiar idiom I've used so often to automate HTML construction -- templatize a chunk of markup, then loop through a data structure populating instances of the template -- works equally well in SVG. Here's the Perl script that wrote the SVG for Example 1:

Example 3: Perl script to generate Example 1

#! perl -w
use strict;

my $data = 
	{
	retail => [275104, 101141],
	pub	   => [97282, 77483],
	meroma => [56320, 43893],
	comm   => [20480, 18341],
	book   => [76800, 11460],
	scanner => [5120, 794],
	};

my $maxWidth = 500;
my $maxHeight = 200 + ( scalar (keys %$data) * 50 );
my $halfMaxHeight = $maxHeight / 2;

my @sorted = sort { $data->{$b}->[0] <=> $data->{$a}->[0] } keys %$data;
my $maxMB = $data->{$sorted[0]}->[0];
my $scale = ($maxWidth * .8) / $maxMB;

my $header = <<"EOH";
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN" 
 "http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd">

<svg width="$maxWidth" height="$maxHeight">

<g transform="translate($halfMaxHeight,.25in)">

<g transform="translate(0,.25in)">
<text style="text-anchor:middle; font-size:24; 
  font-family:Arial; font-weight:bold">
Current disk quota usage by team
</text>
</g>

<g transform="translate(0,.5in)">
<text style="text-anchor:middle; font-size:16; font-family:Arial">
Production Volume (/dev/vx/rdsk/production/vol01)
</text>
</g>

</g>
EOH

my $legend = <<"EOL";
<g transform="translate($maxWidth,$maxHeight)">

<g transform="translate(-100,-70)">
<text style="text-anchor:end; font-size:12; 
  font-family:Arial" x="0" y="20">
Max MB =
</text>
<rect style="stroke:#000000; fill:lightgray" 
  x="5" y="5" width="40" height="20"/>
</g>

<g transform="translate(-100,-40)">
<text style="text-anchor:end; font-size:12; 
  font-family:Arial" x="0" y="20">
MB Used = 
</text>
<rect style="stroke:#000000; fill:#ccffcc" 
  x="5" y="5" width="40" height="20"/>
</g>

</g>
EOL

my $item = <<"EOI";

<g transform="translate(1in,ITEMOFFSET)">

<text style="text-anchor:end; font-size:15; 
  font-family:Arial" x="0" y="20">
<a xlink:href="details#ITEMTEXT">ITEMTEXT</a>
</text>

<a xlink:href="details#ITEMTEXT_AVAIL">
<rect style="stroke:#000000; fill:lightgray" 
  x="70" y="0" width="SCALED_MAXMB" height="20"/>
</a>

<text style="text-anchor:end; font-family:Arial;
   font-weight:bold" x="60" y="15">ORIG_MAXMB</text>

<a xlink:href="details#ITEMTEXT_USED">
<rect style="stroke:#000000; fill:#ccffcc" 
  x="70" y="20" width="SCALED_MBUSED" height="20"/>
</a>

<text style="text-anchor:end; font-family:Arial; 
  font-weight:bold" x="60" y="35">ORIG_MBUSED</text>

</g>
EOI

print $header;

my $itemoffset = 100;

foreach my $cluster (@sorted)
	{
	my $orig_maxmb = $data->{$cluster}->[0];
	my $scaled_maxmb = $orig_maxmb * $scale;

	my $orig_mbused = $data->{$cluster}->[1];
	my $scaled_mbused = $orig_mbused * $scale;

	my $tempitem = $item;
	$tempitem =~ s/ITEMOFFSET/$itemoffset/g;
	$tempitem =~ s/ITEMTEXT/$cluster/g;

	$tempitem =~ s/ORIG_MAXMB/$orig_maxmb/g;
	$tempitem =~ s/SCALED_MAXMB/$scaled_maxmb/g;

	$tempitem =~ s/ORIG_MBUSED/$orig_mbused/g;
	$tempitem =~ s/SCALED_MBUSED/$scaled_mbused/g;

	print $tempitem;
	$itemoffset += 50;
	}

print $legend;

print "</svg>\n";

Can I use SVG right away?

For a website I run, I'm again facing that vexing problem of how to display illustrations. We've got rasterized thumbnails, but rasterizing illustrations into readable full-sized GIFS/JPEGs is one of those horribly labor-intensive and ultimately unsatisfactory tasks. When I ran BYTE.com, production ace Joy Blake sometimes went so far as to edit the rasterized images, remove unreadable text, and replace it with readable text. But, in general, life's just too short for that kind of thing.

Even though it's still a bit ahead of the curve, I got to wondering whether we might continue to produce thumbnails of illustrations, and then make SVG files available behind them. True, this would mean that to view them you'd need to acquire the SVG plugin (or another viewer). In general I don't like to impose such a requirement on a website visitor, and in fact never previously have done so.

But I'm sorely tempted by SVG. With the Adobe viewer, you've got a true scalable vector image. You can zoom in and out, pan around in it, and will eventually be able to print with high fidelity.

True, the Adobe SVG viewer is available for Windows and Mac only. But an SVG-enabled Mozilla is coming. Here's an early look:

Example 4: SVG-enabled Mozilla

There are also standalone SVG viewers. Java viewers include CSIRO's SVG Toolkit and IBM's SVGView. Native Linux viewers include Raph Levien's Gill and Lauris Kaplinski's SodiPodi. The latter, noted s_ramawsamy in a newsgroup posting, "can in fact embed SVG in applications like Gnumeric through Bonobo controls."

Fired up with the SVG vision, I put the question to the newsgroup:

What do you think? If you hit a website, clicked on an illustration thumbnail, and were then invited to acquire the Adobe SVG plugin, or download a standalone viewer, would that be more trouble than it was worth?

Cooler heads prevailed, tempering my enthusiasm somewhat.

Alan Shutko:

Probably would be [too much trouble] for me, since being invited to download a plugin or standalone viewer never actually gets you one on Linux, and I'd have to go hunting for one.

Randy Switt:

Personally, I'm pretty selective about the plug-ins I will install, but ones from Adobe I wouldn't mind at all, they have been robust and useful in the past. Alan makes a good point though, you would be risking alienating your alternate O/S audience.

Franck Arnaud:

Life is too short for plugins. The rest of the (useful) web does not need plugins.

You could use PDF. In the short term, PDF viewers are much more common than SVG. What about making both automatically rasterized (full size) bitmaps (for access) and vector format(s) available?

I think that in the short run, Franck's right. Despite my objections, pre-rasterized images really are the easiest thing for people to grab and view. To solve the problem of unreadable text, I may just relax the size constraints on the bitmaps and let them grow as large as needed. While I could in principle make each illustration available as a standalone PDF, I think I'm going hold off until SVG is a bit more cooked. It's simmering along nicely, though, and -- as is also true of the MathML technology discussed in last week's column -- SVG isn't just something stuck onto a Web page (like a PDF), it's woven right into the fabric of the page. You can search for text anywhere. You can link from SVG elements to other content. Example 1 in fact does that, and the xlink syntax in Example 3 shows how. Or you can link to SVG elements from elsewhere. Like an HTML page with many named regions, a chunk of SVG can export a namespace that defines entry points to multiple views.

Do we need really need XML editors?

In a thought-provoking essay, Jan Christian Herlitz, R&D manager for ExcoSoft, notes that a spreadsheet can be represented in XML like this:

<CELL id="B40">262</CELL>

Argues Jan:

Does this mean that Excel is an XML editor because it stores data in XML? Will today's XML editors be spreadsheet tools if they can read Excel files? The answer to both questions is an emphatic no! A spreadsheet editor must map the XML code onto a spreadsheet data structure with cells and formulas, calculate results, and present the results in the typical spreadsheet manner.

The next generation of editors will read and present XML-based information, whether it be paragraphs, tables, drawings, e-mails or spreadsheets. Everything will be done in one user interface. Behind the scene, different software components from different vendors will be activated to handle different parts of the information. Integration will be achieved through "styling". An element will be styled as, for example, a spreadsheet. A spreadsheet component will be fetched to calculate and present the information. As everything is basically XML, the user will experience a much simpler and more natural user interface. All types of information can be stored in one document (separate entities are not needed). Text is handled in a uniform manner. Everything can be searched. Everything can be styled. Everything can be inside everything else; an equation inside a table which is inside a drawing which is inside a spreadsheet.

The next generation of editors will be both editors and browsers, but they will not in a meaningful sense be XML editors. They will simply be clients!

To repeat the point of last week's column: everything's converging on universal data representation in XML. We're headed beyond OLE-style (or Bonobo-style) embedding, into a realm where datatypes blend more intimately and where standard tools and techniques apply to heterogenous mixtures of these datatypes. SVG may not be quite ready for prime time yet, but it's the right thing for the Web in all the ways that PDF is not, and I'm convinced it will become a major force.


Jon Udell (http://udell.roninhouse.com/) was BYTE Magazine's executive editor for new media, the architect of the original www.byte.com, and author of BYTE's Web Project column. He's now an independent Web/Internet consultant, and is the author of Practical Internet Groupware, from O'Reilly and Associates. His recent BYTE.com columns are archived at http://www.byte.com/index/threads

Creative Commons License
This work is licensed under a Creative Commons License.