Painting with SVG, a primer
Doubtless you've heard me going on and on about SVG in the past month or so. Why? Because I think it's an amazing addition to our skills toolbox. Until I learnt of SVG I would have said that creating data-driven graphics in a webpage is a costly/painful affair involving the likes of, the now defunct, Macromedia Generator Server. With SVG, it couldn't get much cheaper or easier. In fact, I just checked with a rocket scientist and he agrees, it isn't rocket science.
What is SVG:
Officialy, SVG is a language for describing two-dimensional graphics in XML. It is also described as an "XML application". What that means is up to you. To me, it makes more sense if you read is as "an application of XML". Indeed, SVG is merely XML and therefore plain text that you can write in any old text editor. This means we can get Domino to create it on the fly. Hence my excitement.
It may help you to think of SVG as an extension of the HTML that we already know so well. Think of it like this - In HTML we have a set of tags that we use to layout and present information in our pages. Things like <table> and <hr> and <ul> are all used to create a certain look. Think what it would be like if, in amongst all of this, there were extra tags like <circle>, <rect>, <line>, <polygon> and <path>. You can use combinations of these and other elements to draw a picture of absolutley anything. In other words:
Using SVG on your pages:
Because SVG is one of the W3C's Web standards, it's as much as part of the Web as XML and HTML are. It doesn't belong to a corporation who can pick and choose what they do with it. It's completely open. For this reason you can expect to see a variety of methods by which you can make it available in the browser and a variety of software environments you can use for its creation.
As hard as it is to try and predict the future of the internet, I like to think there will come a day where SVG lives alongside HTML as part of a page's source. In fact there is already a project underway within Mozilla to support inline SVG. Until the day that they all do we have to rely on the browser using a plugin that is capable of rendering the SVG in the page. At the moment the defacto is Adobe's and is currently in version 3.
If you haven't already, then download yourself the plugin as you'll find it hard to carry on without it. Now have a look at their section showing SVG "in action". You shouldn't need any more convincing after that. I was sold anyway, as was my boss.
To include an SVG image in your page you use an <embed> tag like below.
<embed src="simple.svg" width="300" height="300" type="image/svg+xml" />
No harder than adding a normal image to a page is it ...
There is a myriad of stuff out there so I won't bother to go in to much more detail as I'm sure you want me to get to the point. A good starting point for anything else you want to know is the SVG Wiki.
A nice little example:
The image on the left is of the SVG code from the boxed area below. I used this as I often see these three symbols used to represent a database and that's what Domino is, is it not. It's also a nice simple example of using three of the SVG elements. Click on the image or on this link to open the actual SVG in your browser.
<?xml version="1.0" encoding="utf-8"?>
<svg width="300" height="300">
<g id="db-symbol" style="stroke:#000000">
<rect x="20" y="130" width="140" height="140" fill="#41B8D4"/>
<circle cx="200" cy="200" r="70" fill="#FFFF5C"/>
<path d="M 150,60 L 60,180 L 240,180 Z" fill="#F555A8"/>
</g>
</svg>
So, what does it all mean? Well, the format of the code should look familiar to us all. After all it's in SGML format, the same as any HTML and XML is. The purpose of each element and its attributes should also be fairly obvious. Note that the order in which each object appears in the code dictates its z-index in the image.
The only element that may not be so obvious is the <g> element. This is used to group all the objects that it contains in to one component. It's then easier to do things like applying the same styling to lots of objects, as I've done in the above.
The most important of the above objects is the <path> element which is the most versatile. We can use it to draw pretty much any shape. The main paramater to it is "d" which takes a value in a format similar to:
M 150,60 L 60,180 L 240,180 Z
Where, M = Move to, L = Line to & Z = Close. So here we have - Move to the x,y coordinates 150,60. Draw a line from there to the x,y coordinate 60,180 and from there another line to 240,180. Finally, close the shape, to make a triangle. This is only a simple example and It's well worth learning how it works in more detail. Especially if you're interested in following any future article I write on this subject as the path object will feature heavily in all of it. Also get to know more about how the whole coordiante system works as it's not quite as straight-forward as it might appear.
Using it all with our old friend Domino:
Domino is a database and hence it stores data. Having racked my brains, the only logical application of SVG with Domino that I can think of is the graphical representation of this data, i.e charts. They may sound like the most boring of all the things we could use this new technology for but they are probably the most useful. If for nothing else, think of how happy they will make your boss. Bosses love charts, as do most end-users who have to deal with data on a day-to-day basis. If we can give them what makes them happy then that can't be bad can it.
To create a chart of any kind we simply have to take the data we have and turn it in to pieces of an SVG image. In the case of a chart this is simply a case of creating a path for each segment of data. Let's take an example of a bar chart and see how we would create it.
Imagine a database which contains documents that record the sales of each region per month. So, for a year, there are twelve documents, each with a field to record the sales in North, East, South and West regions. An example of the data in such a document would be:
North | East | South | West |
€30,000 | €20,000 | €40,000 | €15,000 |
To draw the chart we first have to find out which region has the largest sale. If the chart is 200 pixels high and the largest region is South with €40,000 then 40,000 is equivalent to 200 pixels as we want the largest bar to take up the maximmum height. Now we make all other regions relative to the heigh of this one. For example, the North region had sales of €30,000 so it will only be 3/4 the height of the largest - or (200*30,000)/40,000, which makes it 150 pixels high compared to the tallest bar which is 200 pixels. Likewise, the East region is half the height and the West is (200*15,000)/40,000, or 75 pixels high.
So, if x is the value we want to represent and max is the greatest of all the values then the height of any bar can be worked out using ((height*x)/max) where height is the available height of the chart.
You can see this simple theory in practice in the chart I used to represent the distribution of goals scored for each group of this year's World Cup in Japan & Korea. It's online here and I will describe how I achieved this using just simple @Formulae in a future article. Drawing chart like line and pie charts is a different matter but the theory is equally as simple and that too will be covered in future articles.
How can we actually do this:
All this is very well but it doesn't really prove much does it. The proof of the pudding, as they say, is in the eating. Well, you'll have to stay hungry for a little bit longer as this article is long enough as it is. Hopefully it's been enough to illustrate why I am so excited about it and why I think it's worth our time looking at it.
The way in which you actually create the chart that you require depends on how complicated it is and on how comforatable you feel with different technologies. The methods we have available to us as Domino develoeprs range from using simple @Functions or slightly more complex LotuScript to parsing the data as XML with XSL Transformations.
In the next group of articles I've got planned I want to try and talk about them all, starting with simple methods and moving on to the more powerful. Which one you choose to use is down to you.
Resources:
Whilst there are not nearly as many resources out there as there is with Flash, there is still quite a few and interest continues to grow. Here are a couple to get you started:
The SVG-Wiki - http://www.protocol7.com/svg-wiki/
Adobe's KnowledgeBase - http://support.adobe.com/devsup/devsup.nsf/svgkb.htm
In the same way that you would find the majority of Notes developers on the LDD you will find most SVG developers are at the SVG Developers Yahoo group. They are a very helpful bunch, as are those at LDD.
Applets
Jake
we have used kava charts with some success. I know java applets may be considered a bit cheesey these days but the kava ones are tiny and come with full full list of predefined charts with millions of customisation options. No plug ins, no fannying about required.
All you have to do is stick em on the page and point them at a notes field or two and bosh.
Whats more they work in the notes client too.
You may be interested in their servlet support too. You create the chart server side side and squirt it back to the browser as gif. Maybe tricky to work in domino but sure works in a J2EE environment.
Just my penneth. Sites great and keep up the good work.
Chiz
Richard
Reply
Re: Applets
Kava? Thought you'd typed Java wrong at first. Found their homepage:
http://www.ve.com/
I take it you mean them? They seemed moderately priced at $299 for the developer edition but they look a bit plain.
If I were to use applets then I think it would have to be those from Visual Mining:
http://www.visualmining.com
Have been using them for a few months now in my current contract and have to say I like them. They are a little more expensive than Kava but they look great.
So, yeah, if you don't mind the price and the fact that they are applets then go for it. They'll save you an awful lot of time as well.
There's also an option to do this in Flash as well with the GlobFX Chart Generator.
http://globfx.com/products/swfchartgen/
Still trying to get it to work in Domino.....
Jake -codestore
Reply
Great
Nice,
As always nice , I love the way you describe things , clear simple , easy to read, you should write a book really :)
I also discovered a DHTML Tag today thanks to you (the dotted attribute) , well each time I look at this site I discover something :)
Thank you for making us share your tests and knowledge.
Tom
Reply
Re: Great
What you don't know Tom, is that actually our dear Jake is writting a book!!!
BTW Jake, could you give us an update about it? ;-)
Alex YAJF (Yet Another Jake's Fan)
Reply
Show the rest of this thread
Is it practical?
Nice article! I'm quite excited about svg to begin with, and thanks to you, I'm pushing it at my work place. Unfortunately, most of the users of the db's that i build seem to be saticfied wih the data dumped into a spreadsheet, so that they can make their own graphs, etc. In excel, they are portable as well. So, for me, this begs the question of wheher or not svg is going to be practicle. I guess only time will tell (...and maybe sharpening my salemanship skill...ugh!)
Anyone else share this delema?
Reply
Re: Is it practical?
>>they can make their own graphs, etc. In excel
In this line you distinguish your users from most others.
If this is the case then, indeed, SVG isn't really practical. In cases where the user isn't happy making their own then it is practical.
Which you use depends on far too many factors for me to even start thnking about...
If only all users were as happy as yours, Jake -codestore.net
Reply
Show the rest of this thread
surely there's more to SVG than charts!?
Okay, so this might be a trivial example, but why not use SVG for creating graphic buttons/menus with dynamically generated text?
Or here's another trivial example: anti-aliased text. I just spent an entire day redoing the @#%$ graphics in the notes.net discussion database (which are "Image Resources": the %$@!#est thing Iris ever implemented, since once you put them into the database there's no decent way to get them out and edit them--much like HTML you put into a db, but I digress) so that they'd be transparent and not look crappy on a colored background, and I kept thinking to myself "why did they use graphics for dumb things like 'Preview: you must click Post to submit your comment.' and stuff like that. The answer must be that they wanted anti-aliased text. Well, SVG would be a much better way!
Reply
Here's a clock I built in SVG!
Okay, here's another non-chart thing. Again, not necessarily useful, but it might get some creative juices flowing.
I'll warn you that it starts out with all three hands on the nine, but if you wait, you'll see that they really do advance just like a clock's hands. ------------------------------------------------ <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="500" height="500" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" zoomAndPan="magnify">
<desc>A Clock, my first SVG ever, hacked together by hand. -Brandon Zylstra</desc> <!-- based on http://www.zvon.org/xxl/svgReference/ Standard/images/animate/animMotion01.svg --> <!-- Outline of clock, with indicators for 12, 3, 6, and 9. --> <path d="M 100,250 C 100,50 400,50 400,250 C 400,450 100,450 100,250" style="fill:none; stroke:black; stroke-width:7" /> <circle cx="100" cy="250" r="10" style="fill:black" /> <circle cx="250" cy="100" r="10" style="fill:black" /> <circle cx="400" cy="250" r="10" style="fill:black" /> <circle cx="250" cy="400" r="10" style="fill:black" />
<!-- plot clockface center--> <circle cx="250" cy="250" r="10" style="fill:black" />
<!-- Second hand --> <path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z" style="fill:black; stroke:white; stroke-width:1" > <!-- Define the motion path animation --> <animateMotion dur="60s" repeatCount="indefinite" path="M 200,250 C 200,182 300,182 300,250 C 300,318 200,318 200,250" rotate="auto" /> </path> <!-- Minute hand --> <path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z" style="fill:black; stroke:white; stroke-width:1" > <!-- Define the motion path animation --> <animateMotion dur="60m" repeatCount="indefinite" path="M 200,250 C 200,182 300,182 300,250 C 300,318 200,318 200,250" rotate="auto" /> </path> <!-- Hour hand --> <path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z" style="fill:black; stroke:white; stroke-width:1" > <!-- Define the motion path animation --> <animateMotion dur="12h" repeatCount="indefinite" path="M 200,250 C 200,182 300,182 300,250 C 300,318 200,318 200,250" rotate="auto" /> </path>
<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z" style="fill:black; stroke:white; stroke-width:1" />
<g id="guides" visibility="hidden"> <!-- plot key points for clockface circle path--> <circle cx="100" cy="50" r="5" style="fill:blue" /> <circle cx="400" cy="50" r="5" style="fill:blue" /> <circle cx="400" cy="250" r="5" style="fill:blue" /> <circle cx="400" cy="450" r="5" style="fill:blue" /> <circle cx="100" cy="450" r="5" style="fill:blue" /> <circle cx="100" cy="250" r="5" style="fill:blue" />
<!-- plot key points for hand path--> <circle cx="200" cy="182" r="5" style="fill:purple" /> <circle cx="300" cy="182" r="5" style="fill:purple" /> <circle cx="300" cy="250" r="5" style="fill:red" /> <circle cx="300" cy="318" r="5" style="fill:purple" /> <circle cx="200" cy="318" r="5" style="fill:purple" /> <circle cx="200" cy="250" r="5" style="fill:red" />
<!-- example of second hand --> <path d="M 10,0 L15,5 L 10,100 L 5,5 L 10,0 z" style="fill:black; stroke:white; stroke-width:1" /> </g> <!-- Things this needs:
1) an easy way to specify the starting time, so that the clock can start at an arbitrary time
2) the path for the hand is not perfectly circular. I assume its done with Bezier curves, but I don't know the formula for those, so I figured out roughly how it works and then basically eyeballed it until I got it pretty darn close. Make the guides visible to see where the key points are for calculating the path, if you find they help you. I couldn't have done it without them.
--> </svg>
Reply
Re: surely there's more to SVG than charts!?
I've chosen charts because they are extremely useful to us Domino developers AND are pretty tricky to achieve in any other way.
Obviously this isn't all that SVG can do but it's a HUGE strength. As soon as we digress and start to look at using it to replicate the functionality of HTML (buttons and text), or even Flash (animation), then it's only a matter of time until we get to the stage of:
http://www.svgspider.com
Why, why, why!??
If this is meant to promote SVG it's not doing it much justice.
Jake -codestore.net
Reply
Show the rest of this thread
P.S. a better resource for SVG
by the way, there's a much better resource than the SVG-Wiki, which had zippo information on the page (SVG Elements) that I checked out. (It had a list of elements, and under each one said "Place concise definition of this element here." and then had nothing at all for any of them.)
Check out http://www.zvon.org/xxl/svgReference/Output/index.html for all the elements with source code and lots of very cool examples.
Reply
Vertical alignment?
Great Thanks this certainly has made the boss happy :)
I have a question though, I can't seem to workout how to centre text vertically against an object (in this case a <rect> element), anyone got any ideas???
Reply
Re: Vertical alignment?
Try the W3C spec. Just about everything you could possibly want to know:
http://www.w3.org/TR/2000/CR-SVG-20000802/text.html#TextLayout
Try these three options:
<text x="10" y="20" transform="rotate(90,10,20)">Rotated 90</text> <text x="50" y="20" style="writing-mode: tb;">Writing Mode tb</text> <text x="90" y="20" style="writing-mode: tb; glyph-orientation-vertical: 0;">Vertical zero</text>
Jake -codestore.net
Reply
Show the rest of this thread
Notes Forms
Hi. After read this article i think svg is the tool i need, but...
I'm try to write the svg code at a form but it didn't work.
I need make graphics "dinamic" and i think make a form (saveoptions=0) with a queryopenagent who read the datas and fill some field at the form. At that form i think put static svg code, and paint all like "path true html"...
but, didn't work.
What i doing wrong?
Thanks for any help and sorry for my english.
Daniela
Reply
Re: Notes Forms
Sounds like you've got the right idea but I am not sure *exactly* what you're trying to do.
Have you put the SVG code on a form in with other normal HTML and form content? That won't work. At the moment there is little support for in-line SVG content.
What you need to do is have an <embed> tag on the form where you want the graphic to appear. The source ("src") of this should then point to the form where you create your SVG.
Another problem could be the way that browsers interpret the code and the way Domino serves it. Domino tells the browser that the SVG is content-type "text/html" whereas it would normally expect a content-type of "text/xml".
Hope that helps, Jake -codestore
Reply
Servlets
Sorry Jake,
I went off on a rant....
I am trying to display the data I return as a chart.
However when I view the output in a browser all I get is XML code.
I start off the output in the servlet with
res.setContentType("text/xml"); PrintWriter out = res.getWriter();
and then I call the code to draw the output (as I said in the last post, I am merely trying to output the example from this site as a starting point)
out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); out.println("<svg width=\"300\" height=\"300\">"); out.println("<g id=\"db-symbol\" style=\"stroke:#000000\">"); out.println("<rect x=\"20\" y=\"130\" width=\"140\" height=\"140\" fill=\"#41B8D4\"/>"); out.println("<circle cx=\"200\" cy=\"200\" r=\"70\" fill=\"#FFFF5C\"/>"); out.println("<path d=\"M 150,60 L 60,180 L 240,180 Z\" fill=\"#F555A8\"/>"); out.println("</g>"); out.println("</svg>");
As I say, all I get is the xml type output....so I am not sure where I am going wrong.
Thank for your quick reply.
Graeme
Reply
Re: Servlets
You need a page with an embed on it to cause the Adobe SVG Viewer to launch. Add this ass passthru to a form and go from there:
<embed src="/servlets/mychart" width="300" height="300" type="image/svg+xml" />
Jake -webmaster
Reply
Show the rest of this thread
quick start - aplication for download ?
hi,
does anyone have an example database available that is ready for use or demo so I can use it as a quick start ?
thanks in advance!
kind regards,
Patrick Kwinten
Reply
SVG with Domino R6
Are there any issues with using SVG on a Domino R6 server? I have some pie charts on our existing R5 server that work great, but now they won't display, or they time out, when I try to display the page on our test R6 server.
I don't know if it's a server configuration problem or something with the new security on agents in R6.
Currently I have a page with pass thru html to call the agent: <embed src="pie.svg?OpenAgent&type=month" width="80%" height="80%" type="image/svg+html">
Reply
Re: SVG with Domino R6
Karl,
There should be no reason for the change in R6. The fact that it's SVG should be irrelevant.
The only thing I can think of is the server setting "Web Agent Timeout". Not sure if this is new in 6 or not. Default value seems to be 600s.
Hope that helps, Jake
Reply
Show the rest of this thread
bar charts
Can you post an example of generating a bar chart with dynamic scaling if you are given a document with several values in it.
Reply
Re: bar charts
You might find this database useful:
http://www.codestore.net/store.nsf/unid/BLOG-20020611?OpenDocument
Reply
Show the rest of this thread
SVG & XSL Stylesheet
I am attempting to learn/understand how to properly utilize SVG in Notes. I am working on a sample obtained from IBM’s site. Problem is that the example is not helpful on how to integrate SVG with XSL stylesheets in Notes. I am using a page for simplicity. The styleheet (partial) code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" doctype-public="-//W3C//DTD SVG 1.1//EN" doctype-system= "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"/>
<!-- xpaths of note in our input format are: absolute xpath to street features /map/Streets/Feature absolute xpath to Land features /map/Land/Feature absolute xpath to Water features /map/Water/Feature
Relative xpaths within a feature: name of feature @name points in a feature: point X coords of feature point/@x Y coords of feature point/@y -->
<!-- our "main routine" --> <xsl:template match="/"> <!-- to save us having to do conversions of units, just set the viewbox so we can directly plot data points. That way the viewer does most of unit conversions. Our max x value is 650, our min x value is 0 Our max y value is 450, our min y value is 0 -->
----------------------------------- Data (partial) on a page I am attempting to render via the XSL stylesheet:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href ="Map_XSLSS.xsl"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" >
<svg xmlns="http://www.w3.org/2000/svg"> <map> <Streets> <Feature name="Beach Ave"> <point x="26" y="0"/> <point x="170" y="200"/> <point x="275" y="280"/> </Feature> <Feature name="Granville St"> <point x="75" y="450"/> <point x="557" y="40"/> ...etc.
I think my problem is in the stylesheet type declaration on the page that I am rendering. I get a blank page in the browser, so it is rendering without errors at least.
Render Pass thru and HTML content type are set on the page.
Any ideas? Thanks Tim
Reply