This document describes extentions to the SVG specification to allow data driven binding of SVG content to application data in real time. In short, this is achieved through connection of SVG animations to application data using XPath syntax. Bound SVG animations reflect the state of data dynamically, and additionally new SVG animation input types allow setting the value of bound data. The new document content is refered to as SVGDDG throughout this document
The SVG specification provides dynamic manipulation of document content through several methods, namely SVG animations, raw access to the SVG DOM from the implementing application, and embedded scripting. None of these methods are attractive for the needs of data driven graphics:
SVGDDG aims to provided data driven graphics capibilities to SVG with the following objectives:
SVGDDG makes extentions to the animation syntax of SVG, but does not change in any way the syntax of SVG for static graphics. So if all SVG animations are removed from the SVGDDG document, the resulting document will be pure SVG, and viewable on any compliant SVG implementation
Data driven graphics are achieved through extentions to SVG animations. All base SVG animations are avaliable to SVGDDG, and in addition new SVG animation types may be added by the SVGDDG implementation, to meet the needs of the problem domain SVGDDG is being applied to.
SVG provides a powerful symbolic content model through use of the <symbol/>,
<use/> elements. SVGDDG provides an equally powerful method of addressing and
binding referenced SVG symbolic content to application data
SVGDDG has the concept of data servers to direct the action of data driven graphics. A data server is a hierarchically structured database of IO and control information, which an SVGDDG document may address and bind animation data to using XPath syntax. The SVGDDG implementation is responsible for providing a data server for the SVGDDG document content. Note the following:
'/{rootname}' in XPath syntax. All IO data appears under the
root node of the data serverAn example snapshot of a data server exported as XML:
<lightcontroller>
<lights>
<light id="light A" state="Off"/>
<light id="light B" state="On"/>
<light id="light C" state="Off"/>
<light id="light D" state="Off"/>
</lights>
<switchs state="Off On Off Off"/>
</lightcontroller>
Base SVG animations with additional syntax are used for data driven bindings. All base animations as described in the SVG specification without additional syntax will operate as normal.
All active SVG animations have a current position value, which by default is bound to time (since the document entered animated state or was reset). The current position value is a real number, in the case of time starting at '0.0' and incrementing linearly by '1.0' each second. SVGDDG allows this current position value to be bound to a value in the SVGDDG documents related data server refered to by XPath syntax
'binding' AttributeWhen present, the 'binding' attribute of an SVG animation is an XPath reference to a data value in the
SVGDDG documents related data server. When present and the SVGDDG document is in the animated state, the animations
current position will be taken from the element value referenced in data server, rather than from the time since the
document entered the animated state. The SVGDDG implementation is responsible for converting the referenced elements
value from whatever internal format it may be to a real number. So for example, a boolean data type would have a real
number value of:
<svg>
<circle stroke-width="2" cx="20" cy="20" r="10" stroke="darkred" fill="darkred">
<animateColor attributeName="fill" from="darkred"
to="red" begin="0.0" end="1.0" fill="freeze"
binding="/lightcontroller/light[0]/@state"/>
</circle>
<circle stroke-width="2" cx="60" cy="20" r="10" stroke="darkred" fill="darkred">
<animateColor attributeName="fill" from="darkred"
to="red" begin="0.0" end="1.0" fill="freeze"
binding="/lightcontroller/light[1]/@state"/>
</circle>
<circle stroke-width="2" cx="100" cy="20" r="10" stroke="darkred" fill="darkred">
<animateColor attributeName="fill" from="darkred"
to="red" begin="0.0" end="1.0" fill="freeze"
binding="/lightcontroller/light[2]/@state"/>
</circle>
<circle stroke-width="2" cx="140" cy="20" r="10" stroke="darkred" fill="darkred">
<animateColor attributeName="fill" from="darkred"
to="red" begin="0.0" end="1.0" fill="freeze"
binding="/lightcontroller/light[3]/@state"/>
</circle>
</svg>
The XPath binding expression must evaluate to a single real number (with the exception of a binding in the
<bind/> SVGDDG animation, see later). Specifically this means that XPath expressions which
address a node set of greater than a single node are not meaningful.
XPath expressions operations (arithmetic and logical) may be used to manipulate the result before being passed to the animation current value, for example:
/lightcontoller/lights/light[0]/@state
not(/lightcontoller/lights/light[0]/@state)
/lightcontoller/lights/light[0]/@state=On
count(/lightcontoller/lights)
count(/lightcontoller/lights) * 10
/lightcontroller/lights[0]/@state=On and /lightcontroller/lights[1]/@state=On
The SVGDDG document content may use extened XPath addressing if the SVGDDG XPath implementation supports it. This allows content within a referenced element attribute (Array element and index) to be addressed. For example:
/lightcontoller/switches/@value[1]
/palette/@colour[2].red
<bind/> ElementSVGDDG binding applied to base SVG animations is always the resulting real number (the animation current position),
evaluated from the XPath reference. The <bind/> element is a non base SVG animation which allows a more
direct binding of a data server value to an SVG attribute. For example:
<svg>
<text font-family="Arial" font-size="12" x="10" y="10">
<bind attributeName="text" binding="/lightcontroller/lights/light[0]/@id"/>
</text>
<circle stroke-width="2" cx="20" cy="20" r="10" stroke="darkred" fill="darkred">
<animateColor attributeName="fill" from="darkred"
to="red" begin="0.0" end="1.0" fill="freeze"
binding="/lightcontroller/light[0]/@state"/>
</circle>
</svg>
The SVG element attribute will reflect the data server value directly, without further translation or evaluation of the XPath reference
<use/> ElementIn addition to being bound to application data, animations within SVG symbols may be exported as parameters, and their data connection bound dynamcially when the symbol is referenced in the SVGDDG document. This creates three levels of SVG animation binding:
'binding'attribute<use/> element
<svg>
<defs>
<symbol id="lightbulb">
<ellipse stroke="black" fill="white" cx="20" cy="20" rx="-20" ry="-20">
<animateColor attributeName="fill" begin="1" dur="1" fill="freeze"
from="yellow" to="yellow" binding="."/>
</ellipse>
<polyline stroke-width="1" stroke="grey" fill="none"
points="12,16 16,12 20,16 24,12 28,16 28,16">
<animateColor attributeName="stroke" begin="1" dur="1" fill="freeze"
from="orange" to="orange" binding="."/>
<animate attributeName="stroke-width" begin="1" dur="1" fill="freeze"
from="1" to="3" binding="."/>
</polyline>
<rect stroke="black" fill="lightcoral" x="8" y="32" width="24" height="32" rx="0" ry="0"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="44" x2="36" y2="40"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="48" x2="36" y2="44"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="52" x2="36" y2="48"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="56" x2="36" y2="52"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="60" x2="36" y2="56"/>
<line stroke="black" fill="white" stroke-width="3" x1="4" y1="64" x2="36" y2="60"/>
<line stroke="black" fill="white" x1="16" y1="32" x2="12" y2="12"/>
<line stroke="black" fill="white" x1="24" y1="32" x2="28" y2="12"/>
</symbol>
</defs>
<use xlink:href="#lightbulb" symbolPath="/lightcontroller/lights/light[0]/@state"/>
<use transform="translate(50)" xlink:href="#lightbulb"
symbolPath="/lightcontroller/lights/light[1]/@state"/>
<use transform="translate(100)" xlink:href="#lightbulb"
symbolPath="/lightcontroller/lights/light[2]/@state"/>
<use transform="translate(150)" xlink:href="#lightbulb"
symbolPath="/lightcontroller/lights/light[3]/@state"/>
</svg>
'symbolPath' attribute)Animations may use a full XPath reference to reference content in the data server. In addition, each instance of a symbol
(SVG <use/> element) has a current path, which may be used as part of a relative data binding address for an
animation in the symbol.
The 'symbolPath' attribute of a <use/> element, when present, specifies the current path for that
instance of the symbol. For example:
<svg>
<defs>
<symbol id="lightbulb">
<ellipse stroke="black" fill="white" cx="20" cy="20" rx="-20" ry="-20">
<animateColor attributeName="fill" begin="1" dur="1" fill="freeze"
from="yellow" to="yellow" binding="@state"/>
</ellipse>
</symbol>
</defs>
<use xlink:href="#lightbulb" symbolPath="/lightcontroller/lights/light[0]"/>
<use transform="translate(50)" xlink:href="#lightbulb" symbolPath="/lightcontroller/lights/light[1]"/>
<use transform="translate(100)" xlink:href="#lightbulb" symbolPath="/lightcontroller/lights/light[2]"/>
<use transform="translate(150)" xlink:href="#lightbulb" symbolPath="/lightcontroller/lights/light[3]"/>
</svg>
Here, the 'symbolPath' attribute of the <use/> element specifies a current path of
'/lightcontroller/lights/light[x]', inside the symbol, the relitive path of '@state' is used. When rendered, the
full path will resolve to:
/lightcontroller/lights/light[x]/@state
where 'x' is the light number (0-3)
The 'symbolPath' attribute may itself be a relative path, if the <use/> element references a symbol
within a symbol
Parametised symbols provide a much more powerful and flexible means of assigning data bindings to SVG animations in symbols
dynamically. A paramitised symbol provides a list of parameters which the <use/> element may reference and provide
the final data binding for.
'exportName' attributeAll SVGDDG animations may bind to data by use the the 'binding' attribute, described earlier. In addition, for an
animation within a symbol, the animation may be marked as an exported parameter with the 'exportName' attribute.
When preset, the animation may be referenced by this name by the
<use/> element which instances the symbol. If the
animation defines both a 'binding' attribute and a 'exportName' attribute, only the 'binding'
attribute will be used
<svg>
<defs>
<symbol id="lightbulb">
<ellipse stroke="black" fill="white" cx="20" cy="20" rx="-20" ry="-20">
<animateColor attributeName="fill" begin="1" dur="1" fill="freeze"
from="yellow" to="yellow" exportName="on"/>
</ellipse>
</symbol>
</defs>
</svg>
<parameters/> elementThe SVG <use/> element may define a list of mapped paramters inside it's <parameters/> child.
with the <parameter/> element. Each parameter has two attributes:
'name' is the parameter name as declared by the 'exportName' attribute in the symbol animation'binding' is an XPath reference which the mapped animation will be bound to
<svg>
<defs>
<symbol id="lightbulb">
<ellipse stroke="black" fill="white" cx="20" cy="20" rx="-20" ry="-20">
<animateColor attributeName="fill" begin="1" dur="1" fill="freeze"
from="yellow" to="yellow" exportName="on"/>
</ellipse>
</symbol>
</defs>
<use xlink:href="#lightbulb">
<parameters>
<parameter name="on" binding="/lightcontroller/lights/light[0]/@state"/>
</parameters>
</use>
</svg>
<use/> elements may use a full xlink reference to reference content in another SVG file, as well
as inside the current SVG document. For example:
<svg>
<use xlink:href="symbols.svg#lightbulb">
<parameters>
<parameter name="on" binding="/lightcontroller/lights/light[0]/@state"/>
</parameters>
</use>
</svg>
SVG animations allow manipulation of the SVG document contents over time, or in the case of SVGDDG by connection to application data. Input animations are SVGDDG specific, and allow bound application data to be modified by inputs events fired from the SVG document. Input events are generated by user input (keyboard and mouse). Input animation have the same basic syntax as SVG animations, though they do not modify their parent SVG object
The event has the following attributes:
'binding' An XPath reference to the application data which will be modified.'event' The SVG event name which will trigger the input animation (eg 'click')'value' Value to assign to application data referenced by binding when the animation is triggered
<svg>
<defs>
<symbol id="switch">
<rect stroke="red" fill="brown" x="0" y="0" width="25" height="50" rx="0" ry="0"/>
<line stroke="lightcoral" x1="5" y1="5" x2="20" y2="5"/>
<line stroke="lightcoral" x1="5" y1="10" x2="20" y2="10"/>
<line stroke="lightcoral" x1="5" y1="15" x2="20" y2="15"/>
<line stroke="lightcoral" x1="5" y1="20" x2="20" y2="20"/>
<line stroke="lightcoral" x1="5" y1="25" x2="20" y2="25"/>
<line stroke="lightcoral" x1="5" y1="30" x2="20" y2="30"/>
<line stroke="lightcoral" x1="5" y1="35" x2="20" y2="35"/>
<line stroke="lightcoral" x1="5" y1="40" x2="20" y2="40"/>
<line stroke="lightcoral" x1="5" y1="45" x2="20" y2="45"/>
<rect stroke="none" fill="#000000" x="10" y="20" width="5" height="10" rx="0" ry="0"/>
<g visiblity="hidden">
<bind attributeName="visibility" binding="."/>
<animateInputEvent binding=".=0" event="click"/>
<rect stroke="red" fill="white" x="5" y="5" width="5" height="20" rx="0" ry="0"/>
<rect stroke="red" fill="white" x="15" y="5" width="5" height="20" rx="0" ry="0"/>
<rect stroke="red" fill="yellow" x="5" y="5" width="15" height="5" rx="0" ry="0"/>
</g>
<g visiblity="hidden">
<bind attributeName="visibility" binding="not(.)"/>
<animateInputEvent binding=".=1" event="click"/>
<rect stroke="red" fill="white" x="5" y="25" width="5" height="20" rx="0" ry="0"/>
<rect stroke="red" fill="white" x="15" y="25" width="5" height="20" rx="0" ry="0"/>
<rect stroke="red" fill="yellow" x="5" y="40" width="15" height="5" rx="0" ry="0"/>
</g>
<rect stroke="none" fill="#000000" x="20" y="20" width="5" height="10" rx="0" ry="0"/>
<rect stroke="none" fill="#000000" x="0" y="20" width="5" height="10" rx="0" ry="0"/>
</symbol>
</defs>
<use transform="translate(0)" xlink:href="#lightbulb"/>
<use transform="translate(50)" xlink:href="#lightbulb"/>
<use transform="translate(100)" xlink:href="#lightbulb"/>
<use transform="translate(150)" xlink:href="#lightbulb"/>
<use transform="translate(8,100)" xlink:href="symbols.svg#switch"/>
<use transform="translate(58,100)" xlink:href="symbols.svg#switch"/>
<use transform="translate(108,100)" xlink:href="symbols.svg#switch"/>
<use transform="translate(158,100)" xlink:href="symbols.svg#switch"/>
</svg>