ExtGraph - Graph Component and Framework
About Related projects Case studies Docs


ExtGraph project pages

updated 12.11.2004


Project is hosted by

SourceForge.net Logo

How to create new dynamic SVG object

ExtGraph is based on SVG and XPascal.Even though both technologies are feature-rich and powerful, they can be very simple to explain. SVG is Scalable Vector Graphics defined by W3C consortium. XPascal is scripting language using Pascal syntax and implementing large subset of Delphi objects, libraries and components.
Tip: XPascal has one hidden virtue. While syntax is the same as in Object Pascal, you can edit and debug code in Delphi. If you are not proud Delphi owner, you can try Free Pascal and its IDE Lazarus, which is open source and so free as a bird.

If you already know SVG and Delphi, you know most of what is necessary in order to create dynamic graphs. If not there are many good tutorials available on the web.

Learning SVG

If you want to understand SVG more thoroughly, you can look at W3C SVG reference. A good tutorial can be found at w3schools svg pages.

Learning Object Pascal

Behind SVG graphics is Object Pascal scripting language. Some good sources are at Pascal language basics or About.com.

There are also many other sources as well as books on both SVG and Pascal/Delphi.

What we want to achieve?

We want to draw an analog clock and make it display the current time.

We will start with simple SVG object and display it on the graph canvas. Then we will add some other SVG objects to create clock shape. Once satisfied with the clock's graphical design, we will write pascal code that will animate the SVG picture.

Creating clock

Step 1 - download XGraph demo application

First you will need XGraph application, only windows version is available so far.
Download zipped pre-alpha XGraph (1.5 Megs) and unzip it to some directory (temp will be fine). Find XGraph.exe and start it. At this point you should see empty graph canvas:

Step 2 - create SVG object

We will make it simple. Because svg is xml and xml is text, create text document with an .svg extension, for example clock.svg. You can use any standard plain text editor like Notepad.exe. Fill it with following content and save it.

<svg viewBox="0 0 400 400">
<circle cx="200" cy="200" r="200" fill="beige"/>
<line x1="200" y1="200" x2="200" y2="10" stroke="red"/>
</svg>

This code will draw beige circle with red line in "twelve" position. Go to main menu and select menu item Objects-SVG, select svg file, you have just created and place it somewhere on canvas. Now you should see something like this:

Now let's enhance our clock a little. Add second line that will be shorter and just for fun will be thicker and in a slightly different color. We will also add 'id tags' to lines, so that later we can tell which line is short and which long. The modified svg file will now contain (changes are marked with red):

<svg viewBox="0 0 400 400">
<circle cx="200" cy="200" r="200" fill="beige"/>
<line id="long" x1="200" y1="200" x2="200" y2="10" stroke="red"/>
<line id="short" x1="200" y1="200" x2="350" y2="200" stroke-width="2" stroke="crimson"/>
</svg>

Do not forget to save your changes, clear graph and re-open changed svg. Now you should see:

Tip: Double-click on clock will display internal xml editor, where you can edit svg code. After closing this editor, your graph will be regenerated, so you will see changes immediately.

Step 3 - Adding logic.

We have a static svg picture and canvas that displays the vector graphics based on xml code. To make clock dynamic, we have to have read current time, and change coordinates of lines accordingly. We will use XPascal, especially its xml (remember? svg is xml), time and trigonometric routines.

Let's start simple again. Now, we will programmatically rotate long line to a new position, say to quarter to three. XGraph executes the XPascal script as a part of the redraw process, so we will add some Pascal code into our clock.svg file. Code is stored in script element comment, similar to what Javascript does.

<svg viewBox="0 0 400 400">
<circle cx="200" cy="200" r="200" fill="beige"/>
<line id="long" x1="200" y1="200" x2="200" y2="10" stroke="red"/>
<line id="short" x1="200" y1="200" x2="350" y2="200" stroke-width="2" stroke="crimson"/>
<script type="text/xpascal">
<!--
var XLine:TXMLElement;
begin
if (this<>nil) // if svg element exists, just to be sure
then begin
XLine:=this.FirstTag('line'); // find first line element (child of this svg element)
if XLine<>nil
then begin
XLine.setAttributeValue('x2','10'); //change x and y coordinates
XLine.setAttributeValue('y2','200');
end; // if line element exists
end;
end;
-->
</script>

</svg>

After you will re-open clock.svg you should see something like this.

Tip: You can edit XPascal code in integrated XML editor, even with syntax hi-lighting:

If everything works let's take one final step. Enhance the code so that it shows current time. Code:

<svg viewBox="0 0 400 400">
<circle cx="200" cy="200" r="200" fill="beige"/>
<line id="long" x1="200" y1="200" x2="200" y2="10" stroke="red"/>
<line id="short" x1="200" y1="200" x2="350" y2="200" stroke-width="2" stroke="crimson"/>
<script type="text/xpascal">
<!--
var XLine:TXMLElement;
mx,my,hx,hy:Integer;
sid:String;
Pi:Real;
begin
Pi:=3.14159; //define pi
if (this<>nil) // if svg element exists, just to be sure
then begin
XLine:=this.FirstTag('line'); //find first line element (child of this svg element)
while XLine<>nil //while next line do
do begin
sid:=XLine.getAttributeValue('id'); //get value of id attribute
if sid='long' //check if it is long minute line
then begin
mx:=Round(sin(MinuteOf(Now)*2*Pi/60)*190)+200; //calculate x coordinate
my:=200-Round(cos(MinuteOf(Now)*2*Pi/60)*190); //calculate y coordinate
XLine.setAttributeValue('x2',IntToStr(mx)); //change line x coordinate to new value
XLine.setAttributeValue('y2',IntToStr(my)); //change line y coordinate to new value
end
else if sid='short' //check if it is long hour line
then begin
//do the same for current hour
mx:=Round(sin((HourOf(Now)+MinuteOf(Now)/60)*2*Pi/12)*150)+200;
my:=200-Round(cos((HourOf(Now)+MinuteOf(Now)/60)*2*Pi/12)*150);
XLine.setAttributeValue('x2',IntToStr(mx));
XLine.setAttributeValue('y2',IntToStr(my));
end;
XLine:=XLine.NextTag('line'); //find next element with tag line
end; //for all lines
end; //main svg xml element is not nil
end; //end of procedure
-->
</script>
</svg>

Final picture will show current time:

Tips for homework

  • Add digital time. Hint: use svg 'text' element.
  • Change clock background color during day from dark in the night to light colors during day. Hint: color can be written also in RGB syntax.

Send us your homework, if it will be good, we would like to publish your design and code here.

Comments

Your comments are welcomed. Feel free to send them to my email: Pavel Vrecion.


 

©2004 Extgraph developers About Related projectsCase studiesDocs