logo

Pie Are Square - Charting with SVG

In previous articles, Jake introduced you to Scalable Vector Graphics, or SVG. Unlike other graphics formats, an SVG file is simply XML (text with angle brackets, for those who haven't been paying attention), which makes it particularly well suited to being generated on-the-fly by an agent. There are other ways to create graphics on demand, but none are anywhere near as simple, cheap and elegant as SVG.

There are currently a couple of drawbacks to SVG. These are not inherent to the SVG format, but are due to the current browser plugins required to view the file. They simply aren't as mature as, say, the Flash viewer, and are a wee bit on the slow side. That means that we need to keep the graphics fairly simple in order to produce reasonable render times. Since the main purpose of SVG elements in a Domino web application will be to produce graphs and charts, that shouldn't be a problem -- just try to avoid complex GIS maps in production until the viewers catch up.

In addition, we need to keep the Domino elements used to generate the code relatively simple and quick. People have gotten used to waiting for a page to download once in a while, but they tend not to wait forever for graphics. If your agent is too complex, the delay between the page being rendered and the graphic appearing will be too long for most users. (This will be less of a problem when we can safely use multiple XML namespaces in a single web document, since we will be able to serve the graphic and its host page at the same time. Realistically, that means waiting until Microsoft Internet Explorer supports multiple namespaces inline.) Depending on the data you want to present, this may mean using two separate agents: a scheduled agent to collect the data and save it in a document, and a second to serve the data to the web. (The web agent is needed pre-Domino 6 to ensure that the output has the correct content-type. Netscape/Mozilla is especially fussy about content-type.) Since pie charts will require some complex calculation, we will generally use two agents to create and serve the chart.

What we want to draw

First, we should take a look at the sort of result we want to achieve. This is a simple pie chart in SVG format:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<!-- Pie chart sample -->
<path d="M200,200 L200,20 A180,180 0 0,1 377,231 z"
	style="fill:#ff0000;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>
<path d="M200,200 L377,231 A180,180 0 0,1 138,369 z"
	style="fill:#00ff00;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>
<path d="M200,200 L138,369 A180,180 0 0,1 20,194 z"
	style="fill:#0000ff;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>
<path d="M200,200 L20,194 A180,180 0 0,1 75,71 z"
	style="fill:#ff00ff;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>
<path d="M200,200 L75,71 A180,180 0 0,1 200,20 z"
	style="fill:#ffff00;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>
</svg>

Copy the text and paste it into a text editor (Notepad will do just fine if you haven't got Textpad yet), then save it as a file with the extension ".svg". Open the file in an SVG viewer (download the Adobe SVG viewer if you don't have it yet) to take a look at the chart. What you should see is a top-on flat pie chart without labels or any other embellishments. In other words, this is as simple as it's going to get. If all has gone well, the chart should look something like this:

Simulated SVG Pie Chart

There are five segments to this chart, each of which is defined by one of the <path> elements in the SVG source text. Nothing to it, eh? So let's take a look at the <path> statement.

A Closer Look

<path d="M200,200 L200,20 A180,180 0 0,1 377,231 z"
	style="fill:#ff0000;
		fill-opacity: 1;
		stroke:black;
		stroke-width: 1"/>

The <path> is the most versatile of the SVG primitives, since it can contain or create any of the other basic SVG shapes and describe things that none of the other basic types can, sort of the way a variant variable relates to other data types in LotusScript. Like a variant, it is more "expensive" than other types, so it's best left to those occasions when simpler (read: faster-rendering) primitives can't describe the shape. Since there is no <slice-of-pie> element, we need to use a <path>.

The shape of the path is defined by the "d=" part. There are a whole host of options for the "d=", but we are only interested here in the "M", "L", "A" and "Z" options. Yes, I know it's kind of cryptic, but once you learn to think in terms of the names rather than the abbreviations, it's actually pretty easy to get a grip on.

"M" is moveTo, which allows us to move our imaginary pen anywhere on the "paper" without leaving a mark. In each of the pie slices, we start by moving to the centre of the circle. In the example, it is at the cooridinate (200,200) on a 400 by 400 "piece of paper".

Next is "L", or lineTo, which we will use to draw a line straight out from the centre to the appropriate spot on the circumference of the circle. The numbers following the "L" are the coordinates of the spot on the circumference that we want to go to.

Then we have "A" which is an elliptical arcTo. Because the arcTo is elliptical, it takes quite a few arguments, so we'll have to break them down into bite-sized chunks:

A180,180 0 0,1 377,231

The first pair of numbers after the A, "180,180", are the radii that the arc will use. Since a circle is essentially an ellipse with identical radii in the "x" and "y" dimensions, both of the numbers are the same here. When we get around to fancier things, we'll take advantage of the two radii.

The second "group" is a zero all by its lonesome. This represents a rotation of the path around the centre relative to the x-axis of the "host" co-ordinate system. Translated, that means you can create slanted ellipses — a loverly thing, but not overly useful for pie charts. Leave the value at zero.

The next group, "0,1", is a pair of "flags". The first number is the "long arc flag". Since the arc is drawn between two points and the centre is not defined, we need a way to tell how far the arc has to go, otherwise an arc that covers more than half of the ellipse/circle will "shortcut" across the shape. When the arc is less than half of the whole circle, use a zero to tell the arc to use the shortest path. When it's longer than half, use a one to tell it to go the long way round. The second flag is a directional control. Zero is counter-clockwise in the Americas, but anticlockwise elsewhere. (If you remember back to Cartesian geometry lessons in school, proper mathematical angles are measured anticlockwise.) Clockwise arcs are drawn using a one as the flag value, and since that is the way that the Latin-alphabet-using eye usually moves around a circle, we'll present our data that way.

The final pair of numbers, "377,231", is the coordinate point at which the arc ends. How we arrive at that number will be covered later.

Finally, we arrive at the zed. "Z" is the closePath command. It's not mnemonically helpful to call closePath "Z", but it is the last thing you'll do in a path and will at least be familiar to anyone who has used the ancient CTRL-Z end-of-file marker. Once the path is closed, it can be filled with a colour or pattern without any unexpected effects on the rest of the "page".

The style elements should be pretty much self-explanatory to anyone who has used CSS with HTML, or to anyone who has used a vector drawing program. Essentially, we are setting the colour that will fill the slice of pie (the "fill") and the colour and width of the outline (or "stroke").

Now it's simply a matter of creating the right number of these slices, making them the right size, and putting them in the right place.

The Maths

Anyone who has been out of school for more than a couple of weeks (and who doesn't work with trigonometry on a regular basis) may need a bit of a refresher course in basic trigonometry, radians, and Cartesian coordinates. We'll need all of these to create our pie charts.

Let's start with the co-ordinate system. Most of us have gotten rather used to working with pixels and starting at the upper-left-hand corner of whatever "space" we are working in. While SVG coordinates tend to work the same way, we'll have to go back to the old-school way of thinking when we build the pie. In the standard Cartesian system, we have a horizontal x-axis (with positive numbers to the right of centre and negative numbers to the left of centre) and a vertical y-axis (with positive numbers above centre and negative numbers below centre), which cross each other at a point marked (0,0).

Basic Cartesian Space

Okay, so that wasn't exactly higher maths -- but it gives us the space we need to work in to make the chart. Remember that we have to use an arc between two points to define the pie slice, so we have to figure out just what those two points will be. Since circles work on centres, radii and angles, while the SVG drawing space works on rectangular coordinates (how far across and how far down), we have to use trigonometry to convert between the two. Let's look at the whole circle in our co-ordinate space:

Circle in Cartesian Space

If that represents the total of our data set, and we want to show a "slice" of pie representing, say, one-third of the total, it's simply a matter of filling in one-third of the circle. One-third of 360 degrees is 120 degrees, so we just do this:

One-third Slice

(In case you'd forgotten, angles are measured starting on the positive x-axis and going anticlockwise.) And that's exactly what we'd like to do — except that we can't. First, in using an angle, we've used the circle's natural (polar) coordinates, where we have to use rectangular coordinates. Second, we've gone and used degrees to measure the angle — and darned few computer languages do that. Formula Language, Java and LotusScript all use radians, which is a measure of an angle's "subtended arc length proportional to the radius of the arc".

For those of you who came to Domino from somewhere other than the world of maths, engineering or physics, all this means is that we'll have to stop thinking about circles having 360 degrees, and start thinking about them having 2π radians instead. (Think about it — the radius of a circle will fit around the circumference 2π times, so an angle that includes the whole circle will "subtend" or "hold within itself" an arc that is 2π times the radius in length.) Same concept, different numbers.

Now we have to concern ourselves with converting from "how much of the circle" to "how far over" and "how far down". There are a lot of really neat uses for trigonometry, but all we need to concern ourselves with for this task are these two universal truths: the sine of an angle will answer the question "how far up from zero", and the cosine will answer "how far to the right of zero". By a happy coincidence, when the point needs to be to the left of or below the zero line, the corresponding sine or cosine value will be negative.

To create the first slice of pie, we need to know how much of the pie the slice will represent. That means having both the value that the slice represents and the total value for all slices. In keeping with the example above, let's say that the first slice represents one-third of the total. To find our angle, we multiply 1/3 by 2π radians. Taking the sine of the angle (using @Sin in Formula Language or the Sin function in LotusScript), we get approximately 0.866. The cosine (@Cos or Cos function) gives us -0.5. Our arcTo point, then, will lie 0.866 up from and 0.5 to the left of zero — which is exactly the same as we arrived at above. (When you create the actual agent, don't worry about rounding. Unlike a raster format like GIF or JPEG, SVG can deal with very exact mathematical coordinates.)

Trigonometry Basics

That would be absolutely amazing, if we only wanted a very small pie having just its lower-right quadrant visible, with pie slices that run "backwards" to the Western eye. Using our original chart as an example, we'll fix that little problem up in a jiffy. All we need to do is to determine how large the pie will be (its radius) and where its centre will lie on our SVG "page". In the example, we had a space of 400 by 400, and put the centre of the pie at the point (200,200) relative to the upper-left-hand corner. Then we made the radius of the pie 180 units, which gives us a little bit of "white space" around the pie.

Scaling the pie is easy. Since we want a radius of 180, and the values we calculated were for an imaginary circle of radius 1, we simply multiply the sine and cosine values we already calculated by 180. That makes the "pie" the right size, but it is still centred at (0,0), which is the upper-left-hand corner of the SVG space (with a default viewbox), and the slice would still be backwards if we drew it using these values.

An interesting thing happens, though, when we take our desired centre into account. When we subtract the new "scaled" values from the centre coordinates, up is still up (since subtracting positive values will leave us a "less down" value than the centre value, and subtracting negatives will give "more down"), but the pie is flipped left-to-right, and the order of the slices we build will be clockwise.

Let's build our first slice, then. First, we have to create the SVG space for the slice to live in:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">

Now we need to draw the slice in the space. We'll use a <path>, as discussed above. The first step is to move the "pen" to the centre of the pie (<path d="M200,200"/>). Then we'll draw a line out from the centre to an arbitrary starting point 180 units directly to the left of the pie's centre (<path d="M200,200 L20,200"/>). Now to find the point to arc to.

The horizontal (or "x") component is arrived at by multiplying the cosine value we calculated earlier by the radius, 180, then subtracting the lot from the centre value, 200, leaving us with 290 (or 200 - (-0.5*180)). The vertical ("y") component uses the sine value in the same way, giving us 44.12 (or 200 - (0.866*180)). Since we know we are drawing a circle, both of the radius values will be the same, 180. We also know that one-third is less than one-half (so we won't need to set the long arc flag to 1), and that we want to proceed clockwise (so we do need the direction flag set to 1), so our path becomes (<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12"/>). Adding a "Z" to bring us back to the centre will leave us with a black solid wedge of the appropriate size and shape (<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"/>). Functional, but not very pretty — and if all of our slices are solid black, the chart will be less than useful.

The final step to this slice, then, will be to give it some character and distinction with some style attributes. Let's make it green with a two-unit black outline. That will finally give us:

<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>

Don't forget to close off the SVG document or it won't render (SVG isn't forgiving of unclosed tags). That makes the whole SVG document:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
</svg>

Still Hungry?

Of course, one slice does not a pie make — but before you get carried away creating all your slices the way we've done it so far, think about what will happen. All of the slices will start at the zero point, and stop somewhere clockwise of that point. Unless you only have one massive slice, you'll never get a pie out of the deal.

So how do we bake a pie? The trick is to base our calculations on a running total rather than simply using the slice we are currently trying to create.

Let's say that our first slice represented 8,000 out of a total of 24,000. That still works out to one-third, so we can keep the calculations we've already made. What if our second slice was supposed to represent 6,000? We can't simply use 6,000 to calculate the arcTo point for this slice, but if we add it to the 8,000 we've already accounted for, that gives us a running total of 14,000. Now when we do the maths, we will be looking at a total angle of (14000/24000)*2π radians.

After much calculation (and I trust you are doing the calculations so you can plan your agent), I can almost hear you mutter, "Oh, great! Now we're going to completely obliterate the first slice!" Yes, Grasshopper, you would — if you started at the zero point again. Luckily, though, you remembered to keep track of the arcTo point in the first slice's path. When we create our path this time, we'll use the previous arcTo point as our lineTo point. Oh, and let's use a different colour while we're at it, since it would be nice to be able to tell the two slices apart.

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L290,44.12 A180,180 0 0,1 355.88,290 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
</svg>

Now, if the next slice represents 4,000, it will give us a running total of 18,000, making our pie look like this:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L290,44.12 A180,180 0 0,1 355.88,290 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L355.88,290 A180,180 0 0,1 200,380 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
</svg>

Now, let's say that in this case we have only one more slice to go. There is absolutely no need to calculate anything to create the last slice of the pie. Since the lineTo point of all slices except the first is the arcTo point of the previous slice, and we know that the pie has to end exactly where it started, we can simply go ahead and create the slice from data we already have:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L290,44.12 A180,180 0 0,1 355.88,290 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L355.88,290 A180,180 0 0,1 200,380 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L200,380 A180,180 0 0,1 20,200 Z"
	style="fill: #ff00ff;
		stroke: black;
		stroke-width: 2"/>
</svg>

As charts go, that's fairly usable. Just needs a bit of sprucing up is all. First, let's throw a drop-shadow under it. Rather than mucking about with pie slices (since we know what the whole pie will look like), we can just create the shadow as a blurred circle. A bit of a warning here, though: as simple as this is, the mere fact that we are using a Gaussian Blur filter to create the shadow will add considerably to the render time, even if the download time is virtually unaffected. Keep that in mind before you decide to use the shadow in a production environment, especially if you know you will be dealing with clients who may be using older, slower computers.

Note that we are creating the shadow first by drawing a solid circle and applying a basic Gaussian Blur filter (found in the defs section and referenced by URL in the circle's style attributes). That's because SVG renders items in the order they appear in the source. If we had saved the shadow till last, it would appear on top of the pie rather than "behind" and would obscure the chart.

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="400" height="400">
<defs>
<filter id="dropshadow" width="120%" height="120%">
<feGaussianBlur stdDeviation="4"/>
</filter>
</defs>
<circle cx="205" cy="205" r="180"
	style="fill: black; fill-opacity:0.6; stroke:none;
	filter:url(#dropshadow)"/>
<path d="M200,200 L20,200 A180,180 0 0,1 290,44.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L290,44.12 A180,180 0 0,1 355.88,290 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L355.88,290 A180,180 0 0,1 200,380 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,200 L200,380 A180,180 0 0,1 20,200 Z"
	style="fill: #ff00ff;
		stroke: black;
		stroke-width: 2"/>
</svg>

That's prettier, alright, but we still haven't given any meaning to the data we are displaying. We need some labels. Unfortunately, it isn't really practical to try labelling the slices directly. It would be far too much trouble to figure out where to put the label text, and to avoid "collisions" between labels. A far more practical approach would be to use a colour-keyed legend elsewhere on the SVG page. The actual layout is up to you and the look and feel you are trying to achieve. In any case, it means making the SVG area substantially bigger than the chart area itself to leave enough room for the labels you require.

In this example, we'll make use of the <rect> (rectangle) element to create the colour swatches and the <text> element to create both the chart title and the label text in the legend. To make room for the title text, we are going to move the centre of the pie down by 100, and we will make the whole SVG space 800 wide to make room for the legend on the right-hand side.

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="800" height="500">
<defs>
<filter id="dropshadow" width="120%" height="120%">
<feGaussianBlur stdDeviation="4"/>
</filter>
</defs>
<text x="150" y="50"
	style="font-family: verdana, arial, sans-serif;
			font-size: 36;
			font-weight: bold;
			fill: #0099ff;
			stroke: black;
			stroke-width: 1">
A Pretty-As-Pie Chart
</text>
<circle cx="205" cy="305" r="180"
	style="fill: black;
		fill-opacity:0.6;
		stroke:none;
		filter:url(#dropshadow)"/>
<path d="M200,300 L20,300 A180,180 0 0,1 290,144.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,300 L290,144.12 A180,180 0 0,1 355.88,390 Z"
	style="fill: #ff0000;
		stroke: black;
			stroke-width: 2"/>
<path d="M200,300 L355.88,390 A180,180 0 0,1 200,480 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,300 L200,480 A180,180 0 0,1 20,300 Z"
	style="fill: #ff00ff;
		stroke: black;
		stroke-width: 2"/>
<rect x="420" y="140" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #00ff00"/>
<text x="470" y="156"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The First Data Set - 33.3%
</text>
<rect x="420" y="180" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff0000"/>
<text x="470" y="196"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Second Data Set - 25%
</text>
<rect x="420" y="220" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #0000ff"/>
<text x="470" y="236"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Third Data Set - 16.7%
</text>
<rect x="420" y="260" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff00ff"/>
<text x="470" y="276"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Fourth Data Set - 25%
</text>
</svg>

There's a lot more you can add to this yet, like mouseover effects. You can have the appropriate pie slice cause a legend entry to be highlighted on mouseover of either element if you like, or you can have a separate details pane pop up. I tend not use use mouseovers in SVG because of the lag between mouseover/mouseout and the change in the image. Again, the fault there lies with the current crop of SVG viewers. When performance improves, I will happily return to using mouseovers.

If you use different radii in the x- and y-axes, both as multipliers when you do your calculations and as arguments in the path statements, you can create an elliptical chart in perspective. Echoing the arcs in reverse below the main chart will allow you to create the illusion of a cylinder. Ruediger Seiffert's public-access sample agent shows good examples of both of these techniques in use. It also uses mouseover effects. Like any other SVG, you can view the source code for the graphic to see what makes it tick.

Getting Tipsy

A top-on pie chart is more than adequate to display data, and it is the canonical pie chart. Still, people have come to expect a 3-D look from "professional" charting utilities. If you are presenting the chart for public consumption, you might want to consider going to the trouble of a perspective rendering. A warning here, though — the distortion of the relationship between the areas of the various slices might not be acceptable in a strict statistical implementation. If you want to use a pie chart in a professional (web) publication, either stick to the top-on display or alter your calculations to render strict area proportions. (That is higher maths, and we won't be getting anywhere near that subject here.)

Slanting the top of the chart is no trouble at all. Let's take another look at the path statement for our first slice:

<path d="M200,300 L20,300 A180,180 0 0,1 290,144.12 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>

Notice that there are two radii declared for the arcTo portion (A180,180 0 0,1 290,144.12). The arcTo is elliptical, after all — we've just used the same radius twice to create a circular shape. To create a perspective effect, we'll just use a smaller value for the y-radius (the second value). We can make the value as large or as small as we want, but there is a fairly small "band" of values that look right. Too large, and the chart won't appear tilted; too small, and the data represented won't be clear enough. I usually use a value two-thirds of the horizontal radius. In this case, that would be 120, making the arcTo portion "A180,120 0 0,1 290,144.12".

That leaves us with two problems. The first is that the point (290,144.12) will not lie on the ellipse we are trying to display. You'll get an arc alright, but it won't be the one you want. Remember that we got the y-value (144.12) by multiplying the sine of the angle by 180 and subtracting from 300 (the chart with labels has a 100-high area at the top for the title). We have to change the multiplier to 120 in order to put the point on the right ellipse. That will make our arcTo "A180,120 0 0,1 290,196.08"

I mentioned two problems. The one that remains is that since we've changed the y-radius to 120, the top of the ellipse now sits 60 units lower on the SVG space than our circle used to sit. White space is a good thing, but there is a difference between white space and a great gaping hole in your graphic. We can fix this by moving the centre of the ellipse up by the appropriate amount. That will make our chart look like this:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="800" height="500">
<defs>
<filter id="dropshadow" width="120%" height="120%">
<feGaussianBlur stdDeviation="4"/>
</filter>
</defs>
<text x="150" y="50"
	style="font-family: verdana, arial, sans-serif;
			font-size: 36;
			font-weight: bold;
			fill: #0099ff;
			stroke: black;
			stroke-width: 1">
A Pretty-As-Pie Chart
</text>
<ellipse cx="205" cy="245" rx="180" ry="120"
	style="fill: black;
		fill-opacity:0.6;
		stroke:none;
	filter:url(#dropshadow)"/>
<path d="M200,240 L20,240 A180,120 0 0,1 290,136.08 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L290,136.08 A180,120 0 0,1 355.88,300 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L355.88,300 A180,120 0 0,1 200,360 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L200,360 A180,120 0 0,1 20,240 Z"
	style="fill: #ff00ff;
		stroke: black;
		stroke-width: 2"/>
<rect x="420" y="140" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #00ff00"/>
<text x="470" y="156"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The First Data Set - 33.3%
</text>
<rect x="420" y="180" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff0000"/>
<text x="470" y="196"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Second Data Set - 25%
</text>
<rect x="420" y="220" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #0000ff"/>
<text x="470" y="236"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Third Data Set - 16.7%
</text>
<rect x="420" y="260" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff00ff"/>
<text x="470" y="276"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Fourth Data Set - 25%
</text>
</svg>

That's gotten us a squashed pie chart, but it's not quite 3-D yet. It will let you see the kind of data distortion I was talking about, though. The 3-D touches we will add will provide some relief, but the distortion in the top surface will remain. (For those of you who absolutely need to fudge your data, putting the "good news" data at the left and right and the "bad news" data at the top and bottom will make your bosses day a little brighter.)

Notice that we've changed the element that creates the shadow from a circle to an ellipse. Apart from having different radii in the x and y directions, they are pretty much the same.

To complete the 3-D effect, we need to create the side of the cylinder. We'll do this by determining first which of our slices are at the front of the pie. Not only is there much point in drawing the back, we also have to keep in mind the painting order in SVG. That which comes first will be obliterated by later elements. There's also the problem of actually creating the shapes we need.

Finding the "front slices" is mathematically easy. We are looking for the first path that has a y-value in its arcTo that is greater than the y-value of the ellipse's centre. That, and all subsequent slices, will be at least partially at the front side of the cylinder. In the example, that slice would be the second one:

<path d="M200,240 L290,136.08 A180,120 0 0,1 355.88,300 Z"
	style="fill: #ff0000; stroke: black; stroke-width: 2"/>

As is usual for the first "front" slice, it does not lie entirely below the centre of the ellipse. The representation of the side of the cylinder, though, can only use what's below the centre. Not a problem — we know where the centre point of the right-hand side of our pie lives. It is a point even with the centre in the y direction and 180 to the right of centre in the x direction: (380,240).

We start building the new shape, a path, by repeating the curve of the slice to which it corresponds. The starting point for this curve will be the extreme right side of the pie, and the curve will end at the same point the slice's arcTo ends. That gives us:

<path d="M380,240 A180,120 0 0,1 355.88,300"/>

Now, to add some thickness to the cylinder, we simply drop down a bit and repeat the curve, then close the shape. How thick you want the cylinder to appear is up to you. I'll use 100 units in this example, although 100 is probably too much for the size of the chart. It's just easy to work with in my wee noggin — your agent won't have to worry about things like that. Dropping down gives us:

<path d="M380,240 A180,120 0 0,1 355.88,300 L355.88,400"/>

Now to repeat the curve. Remember that we're going anticlockwise this time (since the "pen" never lifts), so we need to set the direction flag to zero. Our end point will be 100 units below the point where the original curve started. We'll also close the shape using Z:

<path d="M380,240 A180,120 0 0,1 355.88,300 
L355.88,400 A180,120 0 0,0 380,340 Z"/>

Each of the rest of the cylinder side pieces will start where the arc of the corresponding slice starts, but the construction proceeds in the same way. The style for each of these cylinder pieces should give a fill colour of roughly the same hue as the pie slice it goes with, but a little lighter or darker (again, up to your taste). If you want to use a drop shadow for the completed cylinder, you'll need to use a path to make it look right (elliptical arcs of slightly different sizes top and bottom joined by moderately diagonal lines). You'll probably find that the shadow can be dispensed with, and with it goes the performance-robbing Gaussian Blur filter. Without the shadow, the completed cylinder will look like this:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
	"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="800" height="500">
<text x="150" y="50"
	style="font-family: verdana, arial, sans-serif;
			font-size: 36;
			font-weight: bold;
			fill: #0099ff;
			stroke: black;
			stroke-width: 1">
A Pretty-As-Pie Chart
</text>
<path d="M200,240 L20,240 A180,120 0 0,1 290,136.08 Z"
	style="fill: #00ff00;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L290,136.08 A180,120 0 0,1 355.88,300 Z"
	style="fill: #ff0000;
		stroke: black;
		stroke-width: 2"/>
<path d="M380,240
		A180,120 0 0,1 355.88,300
		L355.88,400
		A180,120 0 0,0 380,340
		Z"
	style="fill: #ff6666;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L355.88,300 A180,120 0 0,1 200,360 Z"
	style="fill: #0000ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M355.88,300
		A180,120 0 0,1 200,360
		L200,460
		A180,120 0 0,0 355.88,400
		Z"
	style="fill: #6666ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,240 L200,360 A180,120 0 0,1 20,240 Z"
	style="fill: #ff00ff;
		stroke: black;
		stroke-width: 2"/>
<path d="M200,360
		A180,120 0 0,1 20,240
		L20,340
		A180,120 0 0,0 200,460
		Z"
	style="fill: #ff66ff;
		stroke: black;
		stroke-width: 2"/>
<rect x="420" y="140" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #00ff00"/>
<text x="470" y="156"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The First Data Set - 33.3%
</text>
<rect x="420" y="180" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff0000"/>
<text x="470" y="196"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Second Data Set - 25%
</text>
<rect x="420" y="220" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #0000ff"/>
<text x="470" y="236"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Third Data Set - 16.7%
</text>
<rect x="420" y="260" width="30" height="20"
	style="stroke-linejoin: mitre;
		stroke-width: 2;
		stroke: black;
		fill: #ff00ff"/>
<text x="470" y="276"
	style="font-family:verdana, arial, sans-serif;
			font-size: 14;
			fill: black;
			stroke: none">
The Fourth Data Set - 25%
</text>
</svg>

S is for Scalable

I can hear it already. "800 by 500? Are you out of your cotton-pickin' mind? I don't have room for that!"

You could build the graphic smaller if you wanted to — but there's no need to. Remember that these are Scalable Vector Graphics. Scalable means that we can change the size of the displayed image to meet our needs, and Vector means that we won't lose any resolution in the process. (Graphics means pictures, but if you needed help with that it's time to stop reading articles like this one.) It also means that the size of the coordinate space won't have an appreciable effect on the file size. (Adding an extra digit here and there does make the file bigger, but we're talking about the difference between 2100 bytes and 2200 bytes for a ten-times increase in the overall coordinate system. If 100 bytes will really be a show-stopper, don't use any pictures at all.) Changing the size of the SVG on your web page doesn't have the same kind of implications that resizing a GIF or JPEG would have.

Earlier on, I mentioned the concept of the viewbox. The viewbox is the magical property that allows us to separate the external visible dimensions of the graphic (the size at which it displays) from the internal coordinate space (the fixed units we need to use to describe the shapes and positions of things). Changing one line in the SVG document will allow us to keep the nice, roomy 800 by 500 layout space while displaying the resulting graphic at any size we want. Simply change:

<svg width="800" height="500">

to make it read:

<svg width="100%" height="100%" viewBox="0 0 800 500"
preserveAspectRatio="xMidYMax meet">

Setting the width and height to 100% now means that the graphic will take up as much room as you allow it to on your web page. The viewBox parameters give the upper-left and bottom-right corners of the displayed coordinate space. In this case we're telling the graphic to display everything in the original 800 by 500 coordinate space at whatever size is allowed. The preserveAspectRatio setting keeps the pie round. Without this, the graphic would distort to fit the space available. Telling it to preserve the aspect ratio keeps everything in proportion, so whichever measure (available width or available height) is most limiting will control the overall size of the display. The actual setting will depend on where the image is positioned on your page, and how you want it to shrink and grow. The setting given here (xMidYMax meet) is best for an image that is centred horizontally.

If the display area for the SVG on the web page is set in percentages (say it's centred with a width of 80%), the graphic will display at different sizes on monitors with different resolutions. It will also resize as the browser window is resized. Something like this will do quite nicely:

<html>
<head>
<title>Embedded SVG Test</title>
</head>
<body>
Some text above
<center>
<embed src="pie.svg" width="80%" height="80%" type="image/svg+xml">
</center>
Some text below
</body>
</html>

So, as it turns out, you can design a graphically-rich web page for more than one "optimum" resolution. Cool?


Stan RogersStan Rogers is an analyst with Groupe CGI Ltée, a worldwide IT consultancy based in Canada. He has been working with Lotus Notes and Domino for a little less than two years. Trained as an electronics technologist, and working for several years as an educator, his computing skills are mostly self-taught -- with a lot of help from sites like this.


Feedback

    • avatar
    • James Jennett
    • Fri 13 Sep 2002

    Pie-Eyed

    Stan,

    That was great. Thanks.

    I guess what I need to do to make this work in Domino is to write an agent to output the xml straight to the browser?

    Do it as a passthru <computed text> field on the form where the computed text = the xml?

    Or somehow have it (the agent/s) create a design element page called <whatever>.svg, and spit out the

    <embed src="pie.svg" width="80%" height="80%" type="image/svg+xml">

    tag when I need to see the graphic on the page?

      • avatar
      • Jake Howlett
      • Fri 13 Sep 2002

      Re: Pie-Eyed

      No need to worry James. There is an agent on its way that demonstrates this whole article in use.

      Bear with us on this. Jake

      Show the rest of this thread

      • avatar
      • Stan Rogers
      • Fri 13 Sep 2002

      Re: Pie-Eyed

      As Jake said, there's an agent in the works. Right now, I use agents to spit out the charts, but I've also been able to use forms in IE5. (A page -- at least as Domino uses the term -- would really be out of the question, since its content is too static, and the variable bits -- computed text-- are far too limiting.) In Domino 6, using a form would be both easy and cross-browser, since you will be able to use something other than HTML as the "Treat contents as" setting. This article dealt only with creating the SVG. (What? It wasn't long enough already?) Look for something about converting Notes data later. There's a whole bunch of methods...

    • avatar
    • Nat Wharton
    • Fri 13 Sep 2002

    Mozilla will support SVG

    If you didn't hear about it, Mozilla is working on native SVG support. (it doesn't work yet, except in a special build available on their site) I haven't tried it yet, but they'll update you to its current status at:

    http://www.mozilla.org/projects/svg/

    ps: I've been using Mozilla 1.1 for about a couple weeks now, and am really liking it... still has some bugs, but very cool & exciting stuff!

    Hope this helps someone. -Nat

      • avatar
      • Stan Rogers
      • Fri 13 Sep 2002

      Re: Mozilla will support SVG

      The Smiles browser and Batik have done it all along, of course. But that still leaves us with the wee problem of the 90% of web surfers who use IE. That's why I said that, realistically, in-line SVG will have to wait until IE supports it. Unless you are in a position to dictate which browser the user will have, you pretty much have to assume that most will be using IE. Both of the major user operating systems (Mac and Windows) come with IE, so it's not just more practical for home users, but for IT departments as well, to keep everything in the kit. Servers don't need to look at pictures, and the sort of people who actually like to tinker with Linux on their desktops will probably be more intrigued with the elegance of the text in the SVG file than with the picture it represents...

  1. Charting with DHTML

    On a slightly different note, if you are interested in charting with DHTML then this might be of interest to you:

    http://www.breakingpar.com/bkp/home.nsf/AllPages!OpenNavigator&87256B280015193F8 7256C17004B71A0

  2. OWC or VML

    These techniques allow you to create charts as well, although they require IE and OWC require Office 2000:

    OWC - Office Web Components http://msdn.microsoft.com/library/default.asp?url=/library/en-us/owcvba10/html/o ctocWhatsNew.asp?frame=true

    VML - Vector Markup Language http://msdn.microsoft.com/library/default.asp?url=/workshop/author/vml/default.a sp?frame=true

  3. readview entry

    would be nice to see an easy to implement solution to read viewentries and present them in the svg viewer :-)

    1. Re: readview entry

      Yeah, wouldn't it? Maybe you could write one.

    • avatar
    • rk
    • Thu 30 Sep 2004

    Thanks

    Thanks a lot. More than the SVG syntax, I learned a lot about how to draw pie slices programmatically.

  4. perspective correction..

    I want to know how to do the perspective correction on my elliptical pie charts. Do you know how to do it?

    Thanks,

    matt

    1. Re: perspective correction..

      You're kidding, right? You want me to do planar projections for you? For free?

  5. explorer printing problems

    When I print SVG files, they emerge from my laser printer squashed or stretched. I searched the web for solutions and all I can find are others with similar problems. Do you have any suggestions?

    1. Re: explorer printing problems

      embed the svg in an html page and the printing problem doesn't seem to occur.

      <object data="pie.svg" width="400" height="400" type="image/svg+xml"> <embed src="pie.svg" width="400" height="400" type="image/svg+xml" /> </object>

  6. Radii

    How can i control the size of pie , i mean the radii, how big or small it be?

    1. Re: Radii

      That's in the article. It was there when I wrote it nearly three years ago, and it's still there a little more than a month after you asked.

      Hide the rest of this thread

        • avatar
        • Dan
        • Fri 12 Aug 2005

        Cheers Fella

        I just wanted to say thanks on an excellently written and informative article. After a few days poring over the SVG specs for the path element and not getting very far, this has helped me no end. I'm still battling my way through adding the cylinder effect, but I'm sure I'll get there eventually. Good work :)

    • avatar
    • Raj
    • Thu 25 May 2006

    Does not render in Firefox 1.5.0.3

    Hello Stan: Thank you and Jake for the excellent information that you have posted on SVG. I am trying the code that you have listed above and the pie-chart does not render in Firefox 1.5.0.3. The following message is displayed " This XML file does not appear to have any style information associated with it. The document tree is shown below."

    It renders fine in IE. I think Firefox 1.5 and above have native SVG support and do not require a plug-in. Please let me know if I'm doing something wrong or should there be an explicit reference to a css file or xslt in the code?

    Thanks! Raj

    1. Re: Does not render in Firefox 1.5.0.3

      For anyone revisiting this, the SVG tag has to be altered to a namespaced version to work in Firefox (and probably elsewhere now). Make the tag look like this:

      &lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="100%" height="100%" viewBox="0 0 800 500" preserveAspectRatio="xMidYMax meet"&gt;

      (I hope the entities get translated. If not, you should know what I meant.)

  7. 3d pie charts using SVG

    Looking to see if anyone has an idea of how to create a 3d pie chart using SVG...

    1. Re: 3d pie charts using SVG

      yes, use PHP : http://www.aditus.nu/jpgraph/features_gallery.php

      it's the best chart class generation i know

      Polar Plots, gannt diagrams, stocks, fields, radar, odometer, etc.

      all type of outputs : gif, jpeg, svg, ...

  8. Drawing From Top

    I ran your example and found it starts drawing from the right side in the 3 o'clock position and then wraps counter-clockwise from there. How can I get it to start from the 12 o'clock position and make it wrap clockwise? Many stats that only show a total and one precentage item are displayed in 12 o'clock format.

    I've got PHP code below: <pre> function PieChart($bh, $lh, &$aS, $f) { $f = ($f == '') ? 'tmp' : $f; $tot = $i = $ly = $seg = 0; $rad = 150; $sx = 158; $sy = 158; $lx = $rad; $rx = 378; $ry = 8; $tx = 428; $ty = 28; $H2 = ''; $aC = array('#bb0000','#e0e0e0','#ffe700','#429e29','#39aace','#660000','#101073','#f7 82bd','#ff8200','#000000'); $colrcnt = count($aC); $tot = 0; foreach ($aS as $a) { $tot += $a[1]; } reset($aS); $tot = (($tot < 0) or ($tot > 100)) ? $tot = 100 : $tot; $H = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"; $H .= "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n"; $H .= " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"; $H .= "<svg width=\"32cm\" height=\"15cm\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n"; foreach ($aS as $a) { $l = trim($a[0]); $n = $a[1]; $arc = 0; $seg = $n / $tot * 360 + $seg; $arc = (($n / $tot * 360) > 180) ? 1 : $arc; $nx = intval(cos(deg2rad($seg)) * $rad); $ny = intval(sin(deg2rad($seg)) * $rad); $ly2 = (-($ly)); $nxlx = ($nx - $lx); $nyly = (-($ny - $ly)); $c = $aC[$i]; if (($n == 0) and ($arc == 0) and ($i == 1)) { continue; //$arc = 1; $sx = 8; $sy = 0; $lx = 0; $ly2 = 0; $nxlx = 0; $nyly = 0; } if (($n == 0) and ($arc == 0) and ($i == 0)) { $arc = 0; $ly2 = 0; $nxlx = 0; $nyly = 0; } if (($n == 100) and ($arc == 1)) { $arc = 1; $sx = 8; $sy = 178; $lx = 0; $ly2 = -1; $nxlx = 0; $nyly = -10; } $test .= " $arc $ly2 $nxlx $nyly - $n<BR>\n"; $H .= " <path d=\"M $sx,$sy l $lx,$ly2 a $rad,$rad 0 $arc,0 $nxlx,$nyly z\"\n"; $H .= " fill=\"$c\" stroke=\"black\" stroke-width=\"2\" />\n"; if ($l != '') { $H2 .= " <rect x=\"$rx\" y=\"$ry\" width=\"30\" height=\"20\" style=\"stroke-width: 2; stroke: black; fill: $c \"/>\n"; $H2 .= " <text x=\"$tx\" y=\"$ty\" style=\"font-family:arial, sans-serif, sans; font-size: 70pt;"; $H2 .= " fill: black; stroke: none\">\n$l : $n%\n</text>\n"; } $lx = $nx; $ly = $ny; $ry += 41; $ty += 41.3; ++$i; $i = ($i > $colrcnt) ? 0 : $i; } $H .= "$H2</svg>\n"; $svg = $f . '.svg'; $png = $f . '.png'; $fh = fopen ("/tmp/$svg",'wb'); fwrite($fh, $H); fclose($fh); $sCmd = "/usr/bin/convert -density 30 /tmp/$svg $png; rm -f '/tmp/$svg'"; `$sCmd`; echo "<p>\n"; $bh = isset($bh) ? "<font size=4><b>$bh</b></font></br>\n" : ''; $lh = isset($lh) ? "<font size=2><em>$lh</b></font></br>\n" : ''; echo "$bh$lh\n</p>"; echo "<img src='$png'>"; } </pre>

    • avatar
    • Richard
    • Tue 24 Oct 2006

    I love it so much

    I was wondering when people would start to do this. It really shows the potential of browsers like Opera, Mozilla and Amaya...

  9. what about two values??

    Hi!! First of all, congratulations!! This is a great article and it helped me so much with my final project.

    Now here comes my question. I didn't get really well this part: "We also know that one-third is less than one-half (so we won't need to set the long arc flag to 1), and that we want to proceed clockwise (so we do need the direction flag set to 1)"

    The thing is, that I managed to draw a pie with just two pieces, and the result was kind of weird. It has the shape of and eye, or similar. When I tried with more values (none exceding the half of the pie), it worked perfect.

    Can anyone hel me, please??

    1. Re: what about two values??

      Ok, solved.

      I used an IF sentence telling that if the size of the piece to draw is bigger than the half of the total, you must use: path d="M200,200 L20,200 A180,180 1 1,1 290,44.12" Otherwise, you must use: path d="M200,200 L20,200 A180,180 0 0,1 290,44.12"

      I hope this will be right. Greetings from Spain!!

  10. Thanks

    Excellent article, thank you very much regards from Costa Rica

    • avatar
    • Jens
    • Tue 3 Jul 2007

    Thanks great stuff works for xaml to

    thanks !

    • avatar
    • Divine
    • Thu 31 Jan 2008

    Thanks

    It is a great article. I found exactly what I was looking for :-) Thank you !

  11. Good Stuff

    This was a very good article. Thanks.

    • avatar
    • Tim
    • Tue 11 Aug 2009

    False slice in the pie

    Hi Stan

    Thanks for the article, it's great.

    I've only one problem: If I have 4 slice with this values (7000, 10000, 1000, 1000), the second slice will be drawing false.

    Could you reproduce that?

    Is this a error in the calculation?

    Thanks

  12. Excellent post!

    Thanks to you we now how some very stylish pie charts. =)

    Be careful though with slices larger than 50%. As @Christina pointed out the arc flags needs to be set to 1 for that slice or else it won't work.

  13. Hello. I was spring cleaning my website and saw that I referenced this article in one of mine:

    http://www.abcruz.com/Development/guhit_svg

    It's for an experiment: a PHP script that creates very simple SVG pie charts and line graphs. The script was written some time back in 2008.

    Cheers! =)

    • avatar
    • Karpagavalli
    • Mon 30 Aug 2010

    This is really very good article..I got all the details exactly what I want. Thanks..

    • avatar
    • saper
    • Sat 30 Apr 2011

    Thanks for good article. Helped me to improve PieChart function in my application.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:



Navigate other articles in the category "XML"

« Previous Article Next Article »
Painting with SVG, a primer   None Found

About This Article

Author: Stan Rogers
Category: XML
Keywords: SVG; Pie; chart;

Attachments

pie-files.zip (4 Kbytes)

Options

Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »