ul>

<h3>Updating the SVG document</h3>

<p>SVG Salamander parallels the DOM model internally, and can be interactively updated at runtime.  That is, you can change colors, positions and other aspects of a loaded SVGDiagram.</p>

<b>Tree Navigation</b>

<p>Use SVGDiagram.getRoot() to get an instance of SVGRoot.  The SVGRoot coresponds to the &lt;SVG&gt; element of an SVG document.  You can then get a list of it's children by calling SVGRoot.getChildren(null).  The tree can be further navigated at deeper depths by calling the getChildren() method.</p>

<b>Adding and Editing Attributes</b>

<p>SVG Salamander stores attributes as strings and parses them into values at runtime to draw the SVG elements.  This allows for the rich variety of types of values that the SVG specification defines.  Attributes can also be either style attribtes or presentation attributes.  Style attributes are defined in the'style' attribute of an SVG element.  Presentation attributes are the attributes defined as attributes outside of the'style' attribute.  If both style and presentation attributes are present, the style attribute overrides the presentation attribute.  For example:</p>

<p><code>
&lt;ellipse id="myCircle" style="fill:red; stroke:black; stroke-width:5;" cx="30" cy="80" rx="10" ry="20"/&gt;
</code></p>

<p>In the above, the style attributes are fill, stroke and stroke-width while the presentation attributes are cx, cy, rx and ry.</p>

<p>SVG Salamander distinguishes between the two types of attributes by using the AnimationElement.AT_CSS and AnimationElement.AT_XML constants.  AnimationElement.AT_CSS represents style attributes, and AnimationElement.AT_XML represents presentation attributes.  If both style and presentation attributes exist for the same attribute name, the style attribute takes precedence.</p>

<p>To check if an attribute is defined</p>

<code>svgElement.hasAttribute("x", AnimationElement.AT_XML);</code>

<p>To add a new attribute attribute, call your element with the name of the attribute, a constant representing whether this attribute should be a style or presentation attribute, and a valid string representing the value of this attribute.  If this attribute is already defined, this will throw a RuntimeException, so make sure to call hasAttribute() first if you're not sure if this attribute exists.  The following adds a new style attribute to the given SVG element:</p>

<code>svgElement.addAttribute("fill-opacity", AnimationElement.AT_CSS, "0.5");</code>

<p>To setting an attribute, call the set function with the string representation of the value to set the attribute to.  Make sure that the element already exists, or this will throw an exception:</p>

<code>svgElement.setAttribute("x", AnimationElement.AT_XML, "0.5");</code>

<p>Sometimes after setting an attribute, it will be necessary to take an animation step to update the element to reflect it's current state.  For example, after setting the 'r' attribute of a circle, it will be necessary to call updateTime(timeInSeconds) on the circle or on one of the circle's ancestors to update the circle's shape.  If your SVG diagram isn't using animation, you can pass any value in as the time.  Not all attributes will require updateTime() to be called, but calling this will not hurt.  Typically, atributes that alter shape will require an update while attributes that alter fills and colors do not.  For convenience, you might want to update all the elements in a diagram, and then call svgDiagram.updateTime() to update the entire document at once.</p>

<code>
circle.setAttribute("r", AnimationElement.AT_XML, "10");<br/>
circle.updateTime(0f);
</code>

<p>At the moment, you can only set the text of tspan elements.  You can do this by calling setText() on the tspan element.  After doing this, you need to call rebuild() on the text element that contains the tspan element to update the caching data.</p>

<p>To get the value of an attribute, you can create an empty attribute and pass it to getStyle().  This will overwrite the value in the passed style attribute with the element's value of the attribute.</p>

<code>
StyleAttribute attrib = new StyleAttribute();<br/>
svgElement.getStyle("fill", attrib);<br/>
double value = attrib.getDoubleValue();
</code>

<p>Note that getting the value of a style attribute will first check to see if this attribute has a style set.  If not, it checks to find the closest ancestor that may have this style set.  If no ancestor has this attribute set, it then checks to see if a presentation attribute with the same name is set on this element.  This is in keeping with the SVG convetion that style attributes override first ancestors and then presentation attributes.  To get the value of only the style attribute of this element, call getStyleAbsolute() instead. getPresAbsolute() will check for the local presentation attribute.</p>


<b>Adding and removing children</b>

<p>To add a new element, create an instance of the element you wish to add, set it's attributes, and then add it to it's parent elemnt in the scene graph:</p>

<code>
SVGDiagram diagram = SVGCache.getSVGUniverse().getDiagram(uri); <br/>
Group group = (Group)diagram.getElement("parentGroup");<br/>
<br/>
Circle circle = new Circle();<br/>
try<br/>
{<br/>
    circle.addAttribute("cx", AnimationElement.AT_XML, "80");<br/>
    circle.addAttribute("cy", AnimationElement.AT_XML, "80");<br/>
    circle.addAttribute("r", AnimationElement.AT_XML, "10");<br/>
<br/>
    group.loaderAddChild(null, circle);<br/>

    //Update animation state for group and it's decendants so that it reflects new animation values.<br/>
    // We could also call diagram.update(0.0) or SVGCache.getSVGUniverse().update().  Note that calling<br/>
    // circle.update(0.0) won't display anything since even though it will update the circle's state,<br/>
    // it won't update the parent group's state.<br/>
    group.updateTime(0.0);<br/>
}<br/>
catch (SVGException e)<br/>
{<br/>
    e.printStackTrace();<br/>
}
</code>


<p>To remove an element, call removeChild() on an element capable of having children:</p>

<code>
SVGDiagram diagram = SVGCache.getSVGUniverse().getDiagram(uri);<br/>
Group group = (Group)diagram.getElement("circleGroup");<br/>
Circle circle = (Circle)diagram.getElement("circleToRemove");<br/>
<br/>
try<br/>
{<br/>
    group.removeChild(circle);<br/>
}<br/>
catch (SVGException e)<br/>
{<br/>
    e.printStackTrace();<br/>
}<br/>
</code>

<h3>Picking</h3>

<p>To pick shapes within an SVGDiagram, use the pick() method.</p>

<code>
SVGDiagram diagram = SVGCache.getSVGUniverse().getDiagram(uri);<br/>
Point pickPoint = new Point(20, 80);<br/>
Vector pickedElements = diagram.pick(pickPoint, null);<br/>
</code>

<p>The pick method will return a vector of vectors of SVGElements.  Each vector contains the path from the root of the diagram to the picked RenderableElement.</p>

<h3>Ant Task</h3>

<p>The SVG Salamander Ant task allows you to easily convert SVG documents to images from an Ant script.  To use it, include the SVGSalamander.jar in your class path and write an Ant target similar to:</p>

<pre>
    &lt;target name="testAntTask"&gt;
        &lt;typedef name="SVGToImage" classname="com.kitfox.svg.app.ant.SVGToImageAntTask" classpath="