Building SVG document Using DOM Interface Inside HTML Document

S

SMH

Normally an SVG document is loaded/parsed/interpreted inside an HTML
document using an 'object' (or 'embed') element, although there are
supposedly other ways too. The problem is, the SVG document must be
static this way.

I want to use the DOM interface to build SVG dynamically inside an HTML
document. I am guessing I can build it inside HTML within an 'object' (or
maybe 'iframe'?) element.

My intentions/goals:

In Javascript, I construct an object 'embedSVG' which has properties and
methods for creating valid SVG elements and setting their attributes and
attribute values.

During construction, the SVG document is created with its root element.
During debugging in FF 2.0 (I'll work on an MSIE-compatible format later),
I am using the Mozilla DOM Inspector and comparing nodes when the
'object' element is loading a valid external SVG document, and when I am
appending the child representing the SVG document created by the DOM
functions.

However the child node (#document) does not specify 'svg' as the root
element, but instead 'HTML'. Something is not working.

Here is the relevant code in 'ScriptTest.html' which is the HTML in which
the SVG is supposed to be embedded. Below it is the relevant code for
'svglib.js' which is supposed to contain code for building the SVG
dynamically.

What this code is supposed to do is load the HTML page and execute the
anonymous script, and draw a navy blue-bordered yellow rectangle on a
blank page. This is similar to the example in the SVG 1.1 W3C
Recommendation on page 202 of the 719-page PDF.

I am getting an exception when embedSVG object placeInHTML() method is
called: NS_ERROR_DOM_HIERARCHY_REQUEST_ERR. I find in DOM Inspector in
spite of or after the exception that a document is placed as a child of
the object element, but it is HTML, with a default 'head', 'title',
'body' elements placed.

Where am I blowing it?

===== start ScriptTest.html excerpt =====
..
..
..
<body>

<object id="insertSVG"></object>

<script type="text/javascript">
var svgHTMLnode = document.getElementById("insertSVG");
var svgObj = new embedSVG(400, 200);
svgObj.placeInHTML(svgHTMLnode);
svgObj.setFill("yellow");
svgObj.setStroke("navy");
svgObj.setStrokeWidth("10");
svgObj.drawRect(20, 20, 200, 100);
</script>
</body>
</html>
===== end ScriptTest.html excerpt =====

====== start svglib.js excerpt ======

function embedSVG (docWidth, docHeight )
{
//arg checking

var svgXMLdoc;
var namespaceURI = "http://www.w3.org/2000/svg";
var qualifiedName = "svg";
var doctype = null;
this.svgXMLdoc = svgXMLdoc =
document.implementation.createDocument(namespaceURI,
qualifiedName, doctype);

var rootElem = svgXMLdoc.firstChild;
rootElem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
rootElem.setAttribute("height", String(docHeight));
rootElem.setAttribute("width", String(docWidth));
this.rootElement = rootElem;
this.fill = "";
this.setFill = function (fillString) { this.fill = fillString; };
this.stroke = "";
this.setStroke = function (strokeString) {
this.stroke = strokeString; };
this.strokeWidth = "";
this.setStrokeWidth = function (strokeWidthString) {
this.strokeWidth = strokeWidthString;
};
this.placeInHTML = function (htmlNode) {
return ((htmlNode.appendChild(this.svgXMLdoc));
};
this.drawRect = function (left, top, width, height,
roundedXradius, roundedYradius) {
var docElem = this.svgXMLdoc.createElement("rect");

// arg checking
docElem.setAttribute("x", left);
docElem.setAttribute("y", top);
docElem.setAttribute("width", width);
docElem.setAttribute("height", height);
docElem.setAttribute("rx", roundedXradius);
docElem.setAttribute("ry", roundedYradius);
docElem.setAttribute("fill", this.fill);
docElem.setAttribute("stroke", this.stroke);
docElem.setAttribute("strokeWidth", this.strokeWidth);
this.rootElement.appendChild(docElem);
return (docElem);
};
}
====== end svglib.js excerpt ======



I am being guided by N.C. Zakas' Professional JavaScript for Web
Developers.
 
S

Spartanicus

SMH said:
Normally an SVG document is loaded/parsed/interpreted inside an HTML
document using an 'object' (or 'embed') element, although there are
supposedly other ways too.

Using mixed namespaces, this requires serving the document as XHTML.
Demo: http://www.spartanicus.utvinternet.ie/mixed_namespace.xhtml
(Note that MS IE does not support XHTML)
The problem is, the SVG document must be
static this way.

If by that you mean it has to have predefined dimensions, then you are
correct. That limitation does not exist for mixed namespace documents.
My intentions/goals:

In Javascript, I construct an object 'embedSVG' which has properties and
methods for creating valid SVG elements and setting their attributes and
attribute values.

During construction, the SVG document is created with its root element.
During debugging in FF 2.0 (I'll work on an MSIE-compatible format later),
I am using the Mozilla DOM Inspector and comparing nodes when the
'object' element is loading a valid external SVG document, and when I am
appending the child representing the SVG document created by the DOM
functions.

However the child node (#document) does not specify 'svg' as the root
element, but instead 'HTML'. Something is not working.

I'm guessing that you want to use JS to determine the size of the
viewport that the SVG will need, and then dynamically set that size on
the object or iframe element in the mother document?

The JS needed to determine the viewport size needed by the SVG has to
run in the SVG file, the resulting values should then be used in the
mother HTML document. I don't know enough about JS to say if that's
possible, but I doubt it.
 
S

SMH

Spartanicus said:
Using mixed namespaces, this requires serving the document as XHTML.
Demo: http://www.spartanicus.utvinternet.ie/mixed_namespace.xhtml
(Note that MS IE does not support XHTML)


If by that you mean it has to have predefined dimensions, then you are
correct. That limitation does not exist for mixed namespace documents.


I'm guessing that you want to use JS to determine the size of the
viewport that the SVG will need, and then dynamically set that size on
the object or iframe element in the mother document?

The JS needed to determine the viewport size needed by the SVG has to
run in the SVG file, the resulting values should then be used in the
mother HTML document. I don't know enough about JS to say if that's
possible, but I doubt it.

You're absolutely right that I didn't really explain my ultimate need for
this.

I have a very interactive HTML document that takes form entries
representing input data that will be statistically evaluated. The results
will be presented graphically through SVG (that is, the plot axes have to
be drawn, the plot scale will be rendered, the plot points (as a scatter
plot or maybe column chart). Of course, all these are unknown at "run
time" which is why the script has to write the SVG document content
dynamically. I decided to go with SVG because it is a W3C
"recommendation" (i.e., standard). I am aware of a lot of other hacks out
there (e.g., libraries of script manipulating CSS-controlled painted
DIVs), but without having used them, I am guessing that they don't always
work in every conceivable situation (without more hacking) and give hope
for wide cross-browser compatibility.

I have been running around Google and the Internet to see if I can stumble
upon something that someone has used.

I have seen the createElementNS() method mentioned before but never really
used it. Poster David Golightly mentions it also, so I will try to apply
his recommendations and report back.

After making it work in FF, I will try to make it work in IE (a must for
all the target users of this page interactivity). I am guessing that use
of ActiveXObjects often makes more things possible in the MS sort of way.
Yes, I know that working with MS scripting is beyond the standard, but
that is the one exception in scripting beyond the perimeter than I am
willing to make.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,299
Messages
2,571,546
Members
48,307
Latest member
BobbieLyke

Latest Threads

Top