Solved

Creating SVG objects on the fly with JavaScript

Posted on 2006-07-18
11
958 Views
Last Modified: 2013-12-16
I've got a project with which I need to be able to draw objects (so far only ovals) in an XHTML (strict) page.
I can get the VML to work in IE6, but SVG is being a pain, and I can't seem to find any examples of creating SVG objects, only manipulating existing ones.

Here's a link to the code: http://www.baka.ca/test/polygon.htm
Here's the function:
----------------------------------------------------------------
      Polygon.oval = function(id,name,width,height,fillStyle,lineStyle) {
            var oval,fill;
            if (!fillStyle && !lineStyle) { return };
            
            oval = document.createElementNS(Polygon.svgNameSpace,"ellipse");
            oval.style.position = "absolute";
            oval.style.width = width +"px";
            oval.style.height = height +"px";
            
            
            if (fillStyle && fillStyle.colour && fillStyle.opacity > 0) {
                  oval.style.fill = fillStyle.colour;
            };
            if (lineStyle && lineStyle.weight > 0 && lineStyle.opacity > 0) {
                  oval.style.stroke = lineStyle.weight +"px solid "+ lineStyle.colour;
            };
            return oval;
      };
----------------------------------------------------------------
Note: Polygon.svgNameSpace = "http://www.w3.org/2000/svg"

I know I'm probably pretty far off, but if anyone can help me out or point me to some COMPLETE documentation, that would also be an acceptable answer.

tia!
0
Comment
Question by:zeroreality
  • 4
  • 4
  • 3
11 Comments
 
LVL 15

Expert Comment

by:bpmurray
ID: 17133466
It's difficult to see what's wrong when you don't show how you include the SVG stuff in the DOM. For more documentation, have you tried Kevin Lindsey's site on http://www.kevlindev.com/tutorials/basics/index.htm?
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17133498
Oh - I forgot to say that the dimensions should be set as attributes using oval.setAttributeNS, so for your example above, you'd use:
   
    oval.setAttributeNS(Polygon.svgNameSpace, "cx", 0);
    oval.setAttributeNS(Polygon.svgNameSpace, "cy", 0);
    oval.setAttributeNS(Polygon.svgNameSpace, "rx", width);
    oval.setAttributeNS(Polygon.svgNameSpace, "ry", height);
    oval.setAttributeNS(Polygon.svgNameSpace, "fill", fillColor);
0
 
LVL 2

Author Comment

by:zeroreality
ID: 17133877
The SVG isn't "included" in the DOM, it's "created" in the DOM on the fly.  I was using appendChild() to try to add the oval to the page.  The link I included is basically my test-case, if I can get a function that will draw an SVG oval in my XHTML page, I can take it from there.

The link you provided also doesn't give me any examples of working with SVG inside an XHTML document, only within an SVG document.

I tried adding the setAttributeNS() code to make things appear, but with no luck.  I don't even get any errors in the javascript console with Firefox.
0
 
LVL 28

Expert Comment

by:Pravin Asar
ID: 17134401
Look at interactive drawing example at my website.

http://www.asarconsultants.com/SVG/draw.html


0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17134467
OK - got it to work. Wow, it really is awkward to do this - you may find a slicker solution, but this works in any case. First, it appears you need an SVG document. I prefer to keep it separate & empty but it could be included in the html. I used the following in "empty.svg":

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
    <!ATTLIST svg
              xmlns:a3 CDATA #IMPLIED
              a3:scriptImplementation CDATA #IMPLIED>
    <!ATTLIST script
              a3:scriptImplementation CDATA #IMPLIED>
]>
<svg onload="setupSVG(evt)"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
     a3:scriptImplementation="Adobe">
<script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[
        function setupSVG(evt) {
         window.parent.svgDocument = evt.target.ownerDocument;
        }
    ]]></script>
</svg>

As you can see, this references the parent (containing) document, setting a variable to point to the SVG document. So, to contain it, rather than using your <DIV>, you could use an iframe which would contain your SVG canvas:
     <iframe id="pad" src="empty.svg" width="50" height="50" frameborder="0"></iframe>

Anyway, you also need a variable to hold the document:
     var svgDocument = null;

0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 28

Expert Comment

by:Pravin Asar
ID: 17137408
Thanks for the update here.

Since you mentioned about VML (it is just IE),

Are you looking for a way to create a graphics with Javascript only ?

Look at this one

http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm

I have used this stuff. Works great. I will put together some example, and post a link.

Thanks,

_PA
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17137676
Here's a sample using the ideas I mentioned above, althought I've included the empty.svg contents in the iframe ...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Polygon.oval()</title>
<script type="text/javascript">
var svgns = "http://www.w3.org/2000/svg";
var svgDocument = null;

function oval(id,name,width,height,fillStyle,lineStyle) {
   var foo = svgDocument;
   var oval = svgDocument.createElementNS(svgns, "ellipse");
   oval.setAttributeNS(null, "cx", 200);
   oval.setAttributeNS(null, "cy", 200);
   oval.setAttributeNS(null, "rx", width);
   oval.setAttributeNS(null, "ry", height);
   oval.setAttributeNS(null, "fill", "yellow");
         
   svgDocument.documentElement.appendChild(oval);
}

</script>
<style type="text/css">
#pad {
   position: absolute;
   top: 20px;
   left: 20px;
   width: 400px;
   height: 400px;
   border: 1px solid #000;
}
</style>
</head>
<body onload='oval("test","yo",100,100,"Polygon.defaultFill");'>

   <!-- Canvas for SVG graphics -->
   <iframe id="pad" src="empty.svg" width="50" height="50" frameborder="0">
      <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
      <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
          <!ATTLIST svg
              xmlns:a3 CDATA #IMPLIED
              a3:scriptImplementation CDATA #IMPLIED>
          <!ATTLIST script
              a3:scriptImplementation CDATA #IMPLIED>
      ]>
      <svg onload="setupSVG(evt)"
           xmlns="http://www.w3.org/2000/svg"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
           a3:scriptImplementation="Adobe">
      <script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[
           function setupSVG(evt) {
              window.parent.svgDocument = evt.target.ownerDocument;
           }
          ]]></script>
      </svg>
   </iframe>

</body>
</html>
0
 
LVL 2

Author Comment

by:zeroreality
ID: 17139098
I surprized I've gotten so many examples and responses to this.  I would've figured this to be a niche problem no one ever really tried to tackle.  Thank you!

However, these solutions aren't going to work in my implementation.  I think it would do everyone some good if I explained what I need further.  If you look at http://maps.google.ca/ and plana route, the API uses SVG/VML to draw the line from one point to another.  Firefox/Opera/Safari use SVG, and IE uses VML.  The SVG isn't in an iframe, its not in an SVG document, its drawn on the map.  I've been told that the google developers had an easy time implmenting SVG and a hell of a time getting VML to work... whereas I have had a pointedly opposite experience as my VML was up and running inside 4 hours.
I'm actually writing a web-app that uses the Google Maps API, but I need richer drawing tools than just GPolyline().  I found the XMaps (http://xmaps.busmonster.com/) library, but it hasn't been updated in a year and is not compatible with GMaps v2.57 (and 2.58).

This is the closest thing I've found to what I need, however it only provides examples of manipulating SVG elements within a single HTML document.  I want to be able to create SVG elements.
http://www.croczilla.com/svg/samples/dom1.xml
http://www.croczilla.com/svg/samples/dom2.xml

Thanks again for everyone's input, I'm still looking for a solution myself.
0
 
LVL 2

Author Comment

by:zeroreality
ID: 17140804
Is it possible to overlay SVG into an XHTML file if the XHTML is served with a text/xml mime?
0
 
LVL 28

Accepted Solution

by:
Pravin Asar earned 250 total points
ID: 17150539
Yes , you can.

Also look at (one of my accepted post about SVG)

http://www.experts-exchange.com/Web/Web_Languages/JavaScript/Q_21883241.html
0
 
LVL 2

Author Comment

by:zeroreality
ID: 17154479
Eureka!

The solution to your problem is almost exactly what I needed.  More importantly it provided the missing piece of the puzzle... the <?xml?> shebang.  Once I figured it out in an XML file, I simply went back to ASP and set the Response.ContentType = "text/xml".

Of course its not working in IE this way, so I do a UserAgent sniff to figure out if I should serve the page as text/html or text/xml.

Thanks for everyone's input, I appreciate it very much.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL (http://www.experts-exchange.com/articles/201/Handling-Date-and-Time-in-PHP-and-MySQL.html) several years ago, it seemed like now was a good time to updat…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
The purpose of this video is to demonstrate how to prevent comment spam on a WordPress Website. This will be demonstrated using a Windows 8 PC. Plugin Akismet will be used. Go to your WordPress login page. This will look like the following: myw…
The purpose of this video is to demonstrate how to set up the permalinks on a WordPress Website. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp-login.php : Go t…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now