Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Building an SVG GUI with Perl YAPC::EU 2003
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Perl Freely available for download – Cross-platform –All major operating systems supported –Tested on Sun, Windows, Mac OSX, Cygwin, Linux, FreeBSD –Pure-perl: designed to avoid Huge user community
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com SVG.pm Freely available for download under Perl Artistic License Installable many ways: –PPM –FreeBSD –Make –CPAN installation through Perl Pure-Perl: –Root access not required to implement –Cross-platform –No dependencies on other languages or compilers
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Installing SVG.pm CPAN: perl –MCPAN –e `install SVG Perl Package Manager (win32): c:\ PPM PPM> set repository tmp PPM> install SVG PPM> quit c:\> Make: Gunzip svg-xx.xxx.tar.gz Tar –xvf svg-xx-xxx.tar Make Make test Make install More info:
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com SVG.pm Features Free – Perl Artistic License –Do what you want with it. You get what you pay for... –Its not perfect. –Optimized for speed. Limited DOM support. –But at least its stable and in use in several large organisations You can ask for special features... –Usually quick turn-around on requests & suggestions. –Bug reports welcome and encouraged
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com SVG.Pm Usage Examples Hello SVG World! Draw a line Navigating the DOM Tessalate YAPH Click on images to view as SVG
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Hello SVG World! #!/usr/bin/perl -w use strict; use SVG; print "Content-Type: image/svg+xml\n\n"; my $svg=new SVG(); $svg->rect(id=>'rect1',x=>'20px',y=>'55px', width=>10,height=>10,fill=>'yellow'); my $text = $svg->text(x=>20, y=>55, fill=>'red', stroke=>'black'); $text->cdata("Hello SVG world!"); #grab the fill element my $fill = $svg->getElementByID('rect1') ->getAttribute('fill'); #modify the fill attribute of the text element $text->setAttribute('fill',$fill); print $svg->render(); #xmlify
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Draw a Line #!/usr/bin/perl -w use strict; use SVG; print "Content-Type: image/svg+xml\n\n"; my $svg=new SVG(width=>60, height=>45); my $group1=$svg->group(id=>"outer_group"); my $group2=$group1->group(id=>"inner_group"); $group2->line(x1=>20, y1=>30, x2=>50, y2=>35, stroke=>"blue"); print $svg->render();
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Navigate the DOM...Part 1 #!/usr/bin/perl –w use strict; use SVG; print "Content-Type: image/svg+xml\n\n"; my $svg=new SVG(width=>60, height=>60); my $group1=$svg->group(id=>"outer_group"); $group1->rect(x=>10, y=>10, width=>40, height=>40, fill=>"yellow"); my $group2=$group1->group(id=>"inner_group", stroke=>"blue"); $group2->line(x1=>10, y1=>30, x2=>50, y2=>40); $group2->line(x1=>30, y1=>10, x2=>40, y2=>50); $group2->line(x1=>10, y1=>40, x2=>40, y2=>10); my $anchor = $group1->anchor(-href=>' my $circle = $anchor->circle(cx=>30, cy=>30, r=>6, fill=>"red"); $circle->set(begin=>"mouseover", end=>"mouseout", attributeName=>'fill', to=>'cyan'); print $svg->render(); #or xmlify or serialize
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Navigate the DOM...Part 2 iterate($svg); sub iterate { my $depth=0 unless defined $depth; my $child=$element->getFirstChild(); return unless $child; do { print "\t"x$depth, "Element $child is a ", $child->getElementName(), "\n"; iterate($child,$depth+1) if $child->hasChildren; } while ($child = $child->getNextSibling); }
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com #!/usr/bin/perl -w use strict; use SVG; my $svg = SVG->new(width=>"100%", height=>"100%"); my $g = $svg->group(style=>{"fill-rule"=>"evenodd","stroke- linejoin"=>"round", "stroke-linecap"=>"round"}); my $d1 = $g->defs(); my $path = $svg->get_path(-type=>"path", x=>[0,90,60], y=>[0,60,90], - closed=>1); my $d1g1p = $d1->group(id=>"Tess0p")->path(%$path); my $d1g0 = $d1->group( id=>"Tess0", fill=>"rgb(255,255,0)", stroke=>"none")->use(-href=>"#Tess0p"); Tessalate...Part 1
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Tessalate...Part 2 my $d1g1 = $d1->group(id=>"Tess1", fill=>"none", stroke=>"rgb(0,0,0)", "stroke-width"=>"2.413")->use(-href=>"#Tess0p"); $path = $svg->get_path(-type=>"path", x=>[15,75,50], y=>[15,50,75], -closed=>1); my $d1g2p = $d1->group( id=>"Tess2p")->path(%$path); my $d1g2 = $d1->group(id=>"Tess2", fill=>"rgb(255,170,255)", stroke=>"none")- >use(-href=>"#Tess2p"); my $d1g3 = $d1->group( id=>"Tess3", fill=>"none", stroke=>"rgb(0,0,0)", "stroke-width"=>"2.413")->use(-href=>"#Tess2p"); my $d2p2 = $g->defs()->pattern(id=>"TessPattern", patternUnits=>"userSpaceOnUse", x=>"0", y=>"0", width=>"100", height=>"100", viewBox=>" ", overflow=>"visible"); $d2p2->group()->use(-href=>"#Tess0"); $d2p2->group()->use(-href=>"#Tess1"); $d2p2->group()->use(-href=>"#Tess2"); $d2p2->group()->use(-href=>"#Tess3");
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Tessalate...Part 3 $svg->comment('Now let us define the polygon with the fill inside it refered to by url reference'); $svg->polygon(points=>" ,337.5 ".(140+rand(20)).",".(400+rand(60))." , , , , ,".(160+rand(60))." , , , , , ".(100+rand(10)).','.(200+rand(40))." , , , , , ",fill=>"url(#TessPattern)", stroke=>"black"); $svg->text(x=>100,y=>20)->cdata("Using A tessalated pattern to create a fill"); $svg->anchor(-href=>' >text(x=>50,y=>400, fill=>'red' )->cdata("View Script Source"); print "Content-type: image/svg+xml\n\n"; print $svg->xmlify;
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Minimize client-side functional requirements Keep business logic on the server Facilitate functional extension Require planing and vision Thin-client Applications
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Now: HTML-style form process model. –Render->modify->submit. –Familar with users. (Possibly) Later: XFORMS support in SVG. –Embedded form content within the XML vocabulary. –Problem: Not in 1.2. Not finalized. No processing model. –Too complex. Never worked with it... Forms Processing in SVG
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com HTML: –declarative form processing –Must submit all values and refresh page SVG : –No support for declarative information processing –Reliant on scripting HTML-Style Forms
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com HTML-style Architecture Concept Keep the widget a black box Wiget changes modify a text field Maintain state at server Use commit event to update state
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Examples Rotary control Sliding control Pull-down menu
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com How This Works... Commit button. Do_process_form. getURL (postURL). Callback_method – rendering commands. –Old: delete by id. –New: append to the workspace. –Message: server messages for the user.
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Script Components Do_set_string: Assign the interface values Do_process_form: Submit the form Show_callback: handle the result from getURL
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com do_set_string() // set a string function do_set_string(Doc, id, string) { Doc.getElementById(id).getFirstChild.setData(string); } Provides a single method for assigning values to the form interface. Required due to a shortcoming in SMIL which does not support declarative animation on text elements.
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com do_process_form() // submit the form for processing function do_process_form(IDArray,ValueArray) { var url = 'GISMax.cgi?edit=;act=processform;'; for (var i=0; i<IDArray.length; i++) { url = url + eval("'"+IDArray[i]+"'") + "= + getFormFieldValue(evt,eval("'"+ValueArray[i]+"'"))+';'; } getURL(url+';uid='+uid,show_callback); setCommand(evt,''); } Form handler for submit. Required due to a shortcoming in SMIL which does not support declarative animation on text elements.
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Show_callback()...Start function show_callback(test) { //handle the raw return and parse the data grp=parseXML(' '+test.content+' ',document); if (grp.hasChildNodes) { vp = document.getElementById('canvas'); //handle nodes engine = grp.getFirstChild(); xml = engine.getFirstChild(); //...continued next slide Form handler for submit. Required due to a shortcoming in SMIL which does not support declarative animation on text elements.
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Show_callback()...Old oldgroup = xml.getElementsByTagName('obj'); // I think this is now an array var length = oldgroup.getLength(); i=0; var oldId = "none"; while (i < length) { thisElement=oldgroup.item(i); oldId = thisElement.getAttribute("id"); myself = document.getElementById("g."+oldId); if (myself) { myself.parentNode.removeChild(myself); myself = null; } i++; do_set_string(document,'message',"Attached anchor "+oldId); } //...continued Dispose of old elements by ID that the server declares as deletable
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Show_callback()...msg //message handler //grab the message we recieved message_body = xml.getElementsByTagName('message'); if (message_body) { if (messageElement=message_body.item(0)) { message = messageElement.getAttribute('value'); do_set_string(SVGDoc,'message',message); } Message handler for feedback at the client side
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Show_callback()...News //handle new elements. Each element to be added is actually a group. news = xml.getElementsByTagName('new'); length = news.getLength(); if (length == 0) {return} var i=0; while (i<length) { xml = news.item(0); newgroup = xml.getElementsByTagName('g'); var groups = newgroup.getLength(); //catch error (2): missing tags in tag if (groups == 0) {return} var j = 0; while (j<length) { vp.appendChild(newgroup.item(j)); j++; } } //for completeness. End of subroutine Insert new SVG snippet into workspace
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com XML snippet result <rect width="100" y="20" fill="green" stroke="blue" x="10" height="60" /> Hey... you said: Dog Script function do_process_form causes a query to be called by getURL and to be parsed by parsXML Result of pulldown.svg server query bin/yapc_eu2003/gui_workshop/processor.pl?gui_for m_x_value=Dog
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Why this stuff is Good Keep the client-side functionality simple –Reduce implementation risk –Minimize cross-platform incompatibilities No large clientside codebase –Reduce user wait before getting started Obfuscates code base – some people like this –Client-side machine has minimal business logic –Applications can not be reverse-engineered by users Well suited for collaboration applications All data stored on centralized servers –Reduces workstation failure risk –Increases security –No user access to data unless explicitly enabled
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Down sides Must stay connected to the server – no standalone apps. –Not always on line. Bandwidth. –Mass-market sites not a good idea. –Better suited for intranet systems. –Distance to host affects user experience. Server load – Requires powerful hardware. –Server intensive. –Can be minimized by using caching.
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com Down sides...2 Lag: Round-tripping data takes time –Not suitabable for very fast response systems –Need to allow for communication failures Incomplete Browser support –Requires SVG and JS –Limited to Adobe 3+, Corel batik. –ASV3 is broken on Mozilla 1. –Native SVG support in Mozilla still experimental –JS/SVG has Issues on non-Windows platforms
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbHwww.roitsystems.com SVG & Perl Resources Sites –http// Serverside SVG portal – by RO IT systems.http// – SVG recommendation – Comprehensive SVG documentation with extensive examples. – SVG Open conference home – Repository of papers and presentations from past conferences dating back to SVG Open – Petra Kukofkas SVG design page – SVG cartoons and animations, discussions, SVG articles. – project: SVG Programmers' Application Resource Kit. Sponsored by SchemaSoft. – SVG page by Tobias rief in Berlin. – Foundation. – SVG wiki – excellent site for cross-reference. – an SVG discussion forum sponsored by EvolGrafiX. – A rich cartography-specific SVG site with a number of high quality academic papers and demos. – More links to selected SVG- and Perl- related siteshttp:// – Adobe SVG site. SVG plugin vendor 1. – Corel SVG site. SVG plugin vendor 2. Newsgroups SVG Developers – Gemeral, dominant SVG – SVG Coders – programmers newsgrouphttp://svg.ilog.fr/mailman/listinfo/svg-coders/ Manuals – SVG.pm manual. – Programming SVG With Perl - The first chapter of a book presenting the basics on SVG programming with Perlhttp:// – SVG Books listed on the SVG wikihttp://