Monday, October 20, 2008

Dynamic svg graphics using PHP

If you have ever used Inkscape, I am sure you must have loved the power of the software. Besides nice and easy to use interface, what makes it a really powerful tool is the graphics standard that it follows - SVG or Scalable Vector Graphics.

The SVG format is an XML based open standard for Vector Graphics. The XML format makes SVG a powerful resource for dynamic graphics with the help of some programming or scripting language. Many web browsers now support SVG format. All you have to do is include the following header:
header('Content-Type: image/svg+xml');

Let me present a small demo to give you a glimpse of what can be done with SVG and PHP together. I have used a very simple example with minimum graphical components to make it easy to illustrate the concept. Though, there is huge possibility of making things better.

Say, if marks of a student in various subjects were to be presented in the format shown below, where the name of the subject and the marks are fetched from a database table, you would probably have used a complete graphics library package.
You would notice that the color intensity of the bar graph for various subjects are different. I have chosen 40 to be pass marks. Anything below it would be rendered in red with highest intensity for 0 marks and lowest for 39. And anything above it would be rendered green with lighest intensity for 40 and it gets darkest at 100. The number of subjects are also dynamic.

This task can easily be performed using svg graphics and php. So, where do I begin?

Well, writing the complete xml script for svg by yourself may be difficult if not impossible. The best way is to draw the initial framework using Inkscape or any other Vector graphics tool. I drew something like this.
Don't worry about the accuracy of color intensity and percentage. We will leave the mathematics for PHP. And you don't need to be accurate about positioning and other stuffs. You can always edit them later. All you have to do is prepare basic framework.

If you notice properly, you would identify that there are 4 components that are dynamic for our purpose. The text that writes "Maths" (it will be fetched from database), the container for the bar (it will have to be replicated for all the subjects), the bar itself (besides being replicated, it will have varying color and width) and the percentage text of course. Note down the id of these components from the graphics tool you are using.

Now, open your svg file in some xml editor (almost text editor would open it). Copy the whole script. Create a PHP file as follows:

<?php
header('Content-Type: image/svg+xml');

mysql_connect(HOST,USERNAME,PASSWORD);
mysql_select_db(DB_NAME);
$query="SELECT * from TABLE"; //TABLE has two fields: subject and marks
$result=mysql_query($query);
$count=mysql_affected_rows();

echo 'PASTE THE COPIED TEXT HERE';
?>


The code above should be self explanatory. Now, locate the section of the dynamic components and keep them in loop as:

for($i=0;$i<$count;$i++){ $subject=mysql_result($result,$i,subject); $marks=mysql_result($result,$i,marks);

.................................
}


Now, the tasks that you will have to undergo are as follows:

1> Make the y value of all those components dynamic as every subject will appear at different value of y. Something like this:

y="'.(405.21936-$i*60).'"

2> Replace the static text 'Maths' with $subject and '23' with $marks.

3> Vary the width of bar component.

width="'.($marks*5).'"

4> Now all we have to do is vary the color of the bar to meet our requirement.
It was done as follows:

style="opacity:1;fill:';
if($marks>=40)
echo '#00'.(dechex(210-2*($marks-40))).'00;';
else
echo '#f82d00;';

echo 'fill-opacity:';
if($marks>=40)
echo '1';
else
echo (1-$marks*195/(255*39));
echo ';stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"


While I chose a certain sort of colors to depict on the graph, you can choose your own sets of color. If you go through the above code carefully, you would easily realize how the colors were generated.

While this should have given you an idea about the power of svg, you can refer to more resource on integrating svg with php at svg.org's wiki with complete source code.

So, if you are a nice designer with good programming skills, you have both your hands in a pool of treasure now!!!

This article has also been published in the first issue of 'The init Magazine' released by IOE FOSS. The magazine can be downloaded from http://ioefoss.ioelive.com

6 comments:

Ruud Steltenpool said...

See how broad the spectrum of SVG applications is via svg.startpagina.nl

Jitendra Harlalka said...

Hi stelt, thanks for the nice link. Well compiled list of resources for SVG.

Unknown said...

hi can i get the full working code as i get lost when you get to the bit

style="opacity:1;fill:';
if($marks>=40)
echo '#00'.(dechex(210-2*($marks-40))).'00;';
else
echo '#f82d00;';

echo 'fill-opacity:';
if($marks>=40)
echo '1';
else
echo (1-$marks*195/(255*39));
echo ';stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" dont know where it goes

Jitendra Harlalka said...

Hi Robert, you can obtain the full working code from http://implements.java.googlepages.com/dynamic_chart.php

Replace HOST, USER, PASSWORD, DATABASE AND TABLE for your data.

Unknown said...

hi im trying to make a family tree using svg any help would be appreciated

Jitendra Harlalka said...

I would love to help you in anyway within my capacity. But I need more information for that.

We can communicate via twitter if you like. You can follow me on twitter: jitendra_