Transform generic Measures into SVG Speedometer Graph
The stylesheet buildSVGSpeedometer.xsl will take a source document in the proper format – with a graphData root element, sets- and set-child elements and finally measure-elements that contain the actual graphdata – and transform it to a SVG object: a proper Digital Gauge chart. Here I will show a few sections from this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:math="http://xml.apache.org/xslt/java/java.lang.Math"
xmlns:xlink="http://www.w3.org/2000/xlink/namespace/"
>
<!-- for oracle XDK: xmlns:math="http://www.oracle.com/XSL/Transform/java/java.lang.Math"
for Xalan: xmlns:math="http://xml.apache.org/xslt/java/java.lang.Math"
-->
<!-- center of the dial: cx="2160" cy="2720" -->
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="graphData">
<xsl:variable name="degrees"> <!-- how far should the gauge extend; default is 180 degrees, a semi-circle -->
<xsl:choose>
<xsl:when test="degrees">
<xsl:value-of select="degrees"/>
</xsl:when>
<xsl:otherwise>180</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="max">
<xsl:value-of select="maxy"/>
</xsl:variable>
<xsl:variable name="min">
<xsl:value-of select="miny"/>
</xsl:variable>
<xsl:variable name="maxx">
<xsl:value-of select="maxx"/>
</xsl:variable>
<xsl:variable name="minx">
<xsl:value-of select="minx"/>
</xsl:variable>
<svg width="1100px" height="1850px" onload="getSVGDoc(evt)" onzoom="ZoomControl()">
<defs>
<script type="text/javascript">
<![CDATA[
/* this code was largely reused from the excellent website SVG - Learning by Coding (http://svglbc.datenverdrahten.de/) */
var svgdoc,svgroot;
function getSVGDoc(load_evt)
{
svgdoc=load_evt.target.ownerDocument;
svgroot=svgdoc.documentElement;
texte=svgdoc.getElementById("tooltip").getElementsByTagName("text");
}
function ShowTooltip(mousemove_event,txt)
{
var ttrelem,tttelem,posx,posy,curtrans,ctx,cty,txt;
var sollbreite,maxbreite,ges,anz,tmp,txl,neu,i,k,l
ttrelem=svgdoc.getElementById("ttr");
tttelem=svgdoc.getElementById("ttt");
posx=mousemove_event.clientX;
posy=mousemove_event.clientY;
for(i=1;i<=5;i++)texte.item(i).firstChild.data="";
sollbreite=150;
tttelem.childNodes.item(0).data=txt;
ges=tttelem.getComputedTextLength();
tttelem.childNodes.item(0).data="";
anz=Math.ceil(ges/sollbreite);
tmp=txt.split(" ");
txl=new Array(tmp.length);
neu=new Array(anz);
for(i=0;i<tmp.length;i++)
{
tttelem.childNodes.item(0).data=tmp[i];
txl[i]=tttelem.getComputedTextLength();
}
k=0;
maxbreite=0;
for(i=0;i<anz;i++)
{
l=0,neu[i]="";
while(l+txl[k]<1.1*sollbreite && k<tmp.length)
{
l+=txl[k];
neu[i]+=tmp[k]+" ";
k++;
if(maxbreite<l)maxbreite=l;
}
}
curtrans=svgroot.currentTranslate;
ctx=curtrans.x;
cty=curtrans.y;
ttrelem.setAttribute("x",posx-ctx+10);
ttrelem.setAttribute("y",posy-cty-20+10);
ttrelem.setAttribute("width",maxbreite+2*(maxbreite-sollbreite)+110);
ttrelem.setAttribute("height",anz*15+3);
ttrelem.setAttribute("style","fill: #FFC; stroke: #000; stroke-width: 0.5px");
for(i=1;i<=anz;i++)
{
texte.item(i).firstChild.data=neu[i-1];
texte.item(i).setAttribute("x",posx-ctx+15);
texte.item(i).setAttribute("y",parseInt(i-1)*15+posy-cty+3);
texte.item(i).setAttribute("style","fill: #00C; font-size: 11px");
}
svgdoc.getElementById("tooltip").style.setProperty("visibility","visible");
}
function HideTooltip()
{
svgdoc.getElementById("tooltip").style.setProperty("visibility","hidden");
}
function ZoomControl()
{
var curzoom;
curzoom=svgroot.currentScale;
svgdoc.getElementById("tooltip").setAttribute("transform","scale("+1/curzoom+")");
}
]]>
</script>
<radialGradient id="GR63" gradientUnits="userSpaceOnUse" cx="2160" cy="2720" r="1940" >
<stop offset="0.1" stop-color="#E7EAE9"/>
<stop offset="0.95" stop-color="#9DACA8"/>
</radialGradient>
</defs>
<g id='all' transform="scale(0.2)">
<!-- create the background in gray -->
<g stroke-width="12" stroke="#000000" fill="#556475">
<rect x="40" y="40" width="4240" height="4160" rx="60" />
</g>
<g id="Heading" fill="#FFFF82" font-family="Arial" font-weight="bold" font-size="180" text-anchor="middle" pointer-events="none">
<text x="2160" y="256"><xsl:value-of select="title"/></text>
</g>
<g id="Subhead" fill="#FFFF82" font-family="Times New Roman" font-size="100" text-anchor="middle" pointer-events="none">
<text x="2160" y="451">
<xsl:value-of select="subtitle"/>
</text>
</g>
<!-- generate the markerareas or zones around the speedometer; each zone spans a certain value-range has a color and a tooltip -->
<xsl:for-each select="markerarea">
<xsl:call-template name="markerArea">
<xsl:with-param name="startvalue" select="startvalue"/>
<xsl:with-param name="endvalue" select="endvalue"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="degrees" select="$degrees" />
<xsl:with-param name="color" select="color"/>
<xsl:with-param name="title" select="title" />
</xsl:call-template>
</xsl:for-each>
<defs>
<!-- define the gray gradient on the inside of the speedometer -->
<radialGradient id="GR64" gradientUnits="userSpaceOnUse" cx="2160" cy="2720" r="1649" >
<stop offset="0.1" stop-color="#E7EAE9"/>
<stop offset="0.95" stop-color="#9DACA8"/>
</radialGradient>
</defs>
<!-- inner axis area (gray semicircle)-->
<g stroke="#FFFF82" stroke-width="0" stroke-linejoin="round" fill="url(#GR64)">
<xsl:variable name="markerAngle" select="math:toRadians((180 - $degrees) div 2 + $degrees)"/>
<xsl:variable name="x1" select="math:cos($markerAngle) * -1* 1649 + 2160 "/>
<xsl:variable name="y1" select="math:sin($markerAngle) * 1649 * -1 + 2720"/>
<xsl:variable name="x2" select="math:cos($markerAngle) * 1* 1649 +2160 "/>
<path>
<xsl:attribute name="d"><xsl:text>M </xsl:text><xsl:value-of select="$x1"/><xsl:text> </xsl:text>
<xsl:value-of select="$y1"/>
<xsl:text> A 1649 1649 0 </xsl:text>
<xsl:choose><xsl:when test="$degrees > 180">1</xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose>
<xsl:text> 0 </xsl:text>
<xsl:value-of select="$x2"/><xsl:text> </xsl:text><xsl:value-of select="$y1"/>
<xsl:text> L 2160 2720 </xsl:text>
</xsl:attribute>
</path>
</g> <!-- inner area -->
<!-- draw markers and values around the outline of the speedometer -->
<xsl:for-each select="yvalues">
<xsl:for-each select="yvalue">
<xsl:call-template name="axisMarker">
<xsl:with-param name="markerValue" select="value"/>
<xsl:with-param name="markerLabel" select="label"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="degrees" select="$degrees"/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="ymarkers">
<!-- draw y-markers on the axis -->
<xsl:call-template name="ymarker">
<xsl:with-param name="start" select="minvalue"/>
<xsl:with-param name="n" select="steps"/>
<xsl:with-param name="stepsize"
select="(maxvalue - minvalue) div steps"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="gridline" select="gridline"/>
<xsl:with-param name="degrees" select="$degrees"/>
<xsl:with-param name="submarkers" select="submarkers"/>
<xsl:with-param name="showsubmarkervalue" select="showsubmarkervalue"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each> <!-- yvalues -->
<!-- display the counter in the middle of the speedometer -->
<xsl:if test="counter">
<g id="counter" onmouseout="HideTooltip(evt)">
<xsl:attribute name="onmouseover">ShowTooltip(evt,'<xsl:value-of select="counterlabel"/>')</xsl:attribute>
<rect x="1910" y="2100" width="500" height="120" fill="black" />
<text stroke="ivory" fill="ivory" font="Helvetica" text-anchor="middle" font-size="100" x="2160" y="2200">
<xsl:value-of select="counter"/>
</text>
<text stroke="steelblue" fill="steelblue" font="Helvetica" text-anchor="middle" font-size="70" x="2160" y="2295">
<xsl:value-of select="counterunits"/>
</text>
</g>
</xsl:if>
<!-- display the daycounter in the middle of the speedometer -->
<xsl:if test="daycounter">
<g id="daycounter" onmouseout="HideTooltip(evt)">
<xsl:attribute name="onmouseover">ShowTooltip(evt,'<xsl:value-of select="daycounterlabel"/>')</xsl:attribute>
<rect x="1970" y="1500" width="380" height="120" fill="black" />
<text stroke="ivory" fill="ivory" font="Helvetica" text-anchor="middle" font-size="100" x="2160" y="1600">
<xsl:value-of select="daycounter"/>
</text>
<text stroke="steelblue" fill="steelblue" font="Helvetica" text-anchor="middle" font-size="70" x="2160" y="1690">
<xsl:value-of select="daycounterunits"/>
</text>
</g>
</xsl:if>
<!-- Draw a dial for each set in the source document -->
<xsl:for-each select="sets/set">
<xsl:variable name="color">
<xsl:choose>
<xsl:when test="@color"><xsl:value-of select="@color"/></xsl:when>
<!-- if no color was defined, assign a color -->
<xsl:when test="position()=1">#000080</xsl:when>
<xsl:when test="position()=2">#800000</xsl:when>
<xsl:when test="position()=3">green</xsl:when>
<xsl:when test="position()=3">ivory</xsl:when>
</xsl:choose>
</xsl:variable>
<g onmouseout="HideTooltip(evt)">
<xsl:attribute name="onmouseover">ShowTooltip(evt,'<xsl:value-of select="measure[1]/label"/>')</xsl:attribute>
<xsl:attribute name="transform">rotate(<xsl:value-of select="(180 - $degrees) div 2 + (measure[1]/xvalue - $min) div ($max - $min) * $degrees"/> ,2160, 2720)</xsl:attribute>
<line fill="none" stroke-width="44" x1="2160" y1="2720" y2="2720">
<xsl:attribute name="stroke"><xsl:value-of select="$color"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="297 + (position() -1 ) * 550"/></xsl:attribute>
</line>
<g stroke-width="42" >
<xsl:attribute name="stroke"><xsl:value-of select="$color"/></xsl:attribute>
<xsl:attribute name="fill"><xsl:value-of select="$color"/></xsl:attribute>
<path >
<xsl:attribute name="d">
<xsl:text>M </xsl:text>
<xsl:value-of select="297 + (position() -1 ) * 550"/>
<xsl:text> 2720 L </xsl:text>
<xsl:value-of select="414 + (position() -1 ) * 550"/>
<xsl:text> 2804 </xsl:text>
<xsl:value-of select="363 + (position() -1 ) * 550"/>
<xsl:text> 2720 </xsl:text>
<xsl:value-of select="414 + (position() -1 ) * 550"/>
<xsl:text> 2636 z </xsl:text>
</xsl:attribute>
</path>
</g>
</g>
</xsl:for-each><!-- end dials -->
<!-- the outline for the gauge -->
<g stroke="#000000" stroke-width="30" stroke-linejoin="round" fill="none">
<xsl:variable name="markerAngle" select="math:toRadians((180 - $degrees) div 2 + $degrees)"/>
<xsl:variable name="x1" select="math:cos($markerAngle) * -1* 1940 + 2160 "/>
<xsl:variable name="y1" select="math:sin($markerAngle) * 1940 * -1 + 2720"/>
<xsl:variable name="x2" select="math:cos($markerAngle) * 1* 1940 +2160 "/>
<path>
<xsl:attribute name="d"><xsl:text>M </xsl:text><xsl:value-of select="$x1"/><xsl:text> </xsl:text>
<xsl:value-of select="$y1"/>
<xsl:text> A 1940 1940 0 </xsl:text>
<xsl:choose><xsl:when test="$degrees>180">1</xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose>
<xsl:text> 0 </xsl:text>
<xsl:value-of select="$x2"/><xsl:text> </xsl:text><xsl:value-of select="$y1"/></xsl:attribute>
</path>
</g>
<!-- the inner circle ; the centre where the dials are 'connected'-->
<g fill="#000000" stroke="#000000" stroke-width="12" >
<circle cx="2160" cy="2720" r="60"/>
</g>
</g>
<g id="tooltip" style="visibility: hidden">
<!-- Tooltip - Beginn (ttr=Tooltip-Rechteck, ttt=Tooltip-Text) -->
<rect id="ttr" x="0" y="0" rx="5" ry="5" width="150" height="16"/>
<text id="ttt" x="0" y="0" style="visibility: hidden">dyn. Text</text>
<text x="-10" y="-10">dyn. Text</text>
<text x="-10" y="-10">dyn. Text</text>
<text x="-10" y="-10">dyn. Text</text>
<text x="-10" y="-10">dyn. Text</text>
<text x="-10" y="-10">dyn. Text</text>
</g>
<!-- Tooltip - End -->
</svg>
</xsl:template>
<!-- draw markers along the outside of the speedometer; also display labels (usually values) -->
<xsl:template name="axisMarker">
<xsl:param name="markerValue"/>
<xsl:param name="markerLabel"><xsl:value-of select="$markerValue"/></xsl:param>
<xsl:param name="max"/>
<xsl:param name="min"/>
<xsl:param name="degrees">180</xsl:param>
<xsl:param name="sub">0</xsl:param>
<xsl:variable name="markerAngle" select="math:toRadians((180 - $degrees) div 2 + ($markerValue - $min) div ($max - $min) * $degrees)"/>
<!-- if submarker then value should be more pushed out -->
<xsl:variable name="x1">
<xsl:choose>
<xsl:when test="$sub = 1">
<xsl:value-of select="math:cos($markerAngle) * -1* 1640 + 2160 "/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="math:cos($markerAngle) * -1* 1580 + 2160 "/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="y1">
<xsl:choose>
<xsl:when test="$sub = 1">
<xsl:value-of select="math:sin($markerAngle) * 1500 * -1 + 2735 "/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="math:sin($markerAngle) * 1480 * -1 + 2755 "/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<text font-family="Arial" font-weight="bold" >
<xsl:attribute name="font-size">
<xsl:choose>
<xsl:when test="$sub = 1">100</xsl:when>
<xsl:otherwise>160</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="text-anchor">
<xsl:choose>
<xsl:when test="$markerAngle < 1 ">start</xsl:when>
<xsl:when test="($markerAngle > 2) ">end</xsl:when>
<xsl:otherwise>middle</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="x"><xsl:value-of select="$x1"/></xsl:attribute>
<xsl:attribute name="y"><xsl:value-of select="$y1"/></xsl:attribute>
<xsl:value-of select="$markerLabel"/>
</text>
<g fill="blue" stroke="#000000" >
<xsl:attribute name="stroke-width">
<xsl:choose>
<xsl:when test="$sub = 1">15</xsl:when>
<xsl:otherwise>22</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="transform">rotate(<xsl:value-of select="(180- $degrees) div 2 + ($markerValue - $min) div ($max - $min) * $degrees"/>, 2160, 2720)</xsl:attribute>
<line x1="220" y1="2720" y2="2720">
<xsl:attribute name="x2">
<xsl:choose>
<xsl:when test="$sub = 1">350</xsl:when>
<xsl:otherwise>558</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</line>
</g>
</xsl:template><!-- axisMarker -->
<xsl:template name="ymarker">
<xsl:param name="n"/>
<xsl:param name="i">0</xsl:param>
<xsl:param name="stepsize"/>
<xsl:param name="min"/>
<xsl:param name="max"/>
<xsl:param name="gridline">false</xsl:param>
<xsl:param name="start">
<xsl:value-of select="$min"/>
</xsl:param>
<xsl:param name="axis">1</xsl:param>
<xsl:param name="degrees">180</xsl:param>
<xsl:param name="submarkers">0</xsl:param>
<xsl:param name="showsubmarkervalue">no</xsl:param>
<xsl:variable name="value">
<xsl:value-of select="(($start + $i* $stepsize ) )"/>
</xsl:variable>
<xsl:call-template name="axisMarker">
<xsl:with-param name="markerValue" select="$value"/>
<xsl:with-param name="markerLabel" select="$value"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="degrees" select="$degrees"/>
</xsl:call-template>
<xsl:if test="$i < $n">
<xsl:call-template name="ymarker">
<xsl:with-param name="i" select="$i+1"/>
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="stepsize" select="$stepsize"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="start" select="$start"/>
<xsl:with-param name="gridline" select="$gridline"/>
<xsl:with-param name="axis" select="$axis"/>
<xsl:with-param name="submarkers" select="$submarkers"/>
<xsl:with-param name="showsubmarkervalue" select="$showsubmarkervalue"/>
<xsl:with-param name="degrees" select="$degrees"/>
</xsl:call-template>
<!-- if so desired and still within the range set up by the y-markers then draw submarkers -->
<xsl:if test="$submarkers > 0">
<xsl:call-template name="submarkers">
<xsl:with-param name="i" select="1"/>
<xsl:with-param name="n" select="$submarkers"/>
<xsl:with-param name="stepsize" select="$stepsize div ($submarkers +1)"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="start" select="$value"/>
<xsl:with-param name="gridline" select="$gridline"/>
<xsl:with-param name="axis" select="$axis"/>
<xsl:with-param name="showsubmarkervalue" select="$showsubmarkervalue"/>
<xsl:with-param name="degrees" select="$degrees"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- ymarker -->
<!-- show the smaller markers (submarkers) -->
<xsl:template name="submarkers">
<xsl:param name="n"/>
<xsl:param name="i">0</xsl:param>
<xsl:param name="stepsize"/>
<xsl:param name="min"/>
<xsl:param name="max"/>
<xsl:param name="gridline">false</xsl:param>
<xsl:param name="start">
<xsl:value-of select="$min"/>
</xsl:param>
<xsl:param name="axis">1</xsl:param>
<xsl:param name="degrees">180</xsl:param>
<xsl:param name="submarkers">0</xsl:param>
<xsl:param name="showsubmarkervalue">no</xsl:param>
<xsl:variable name="value">
<xsl:value-of select="(($start + $stepsize ) )"/>
</xsl:variable>
<xsl:call-template name="axisMarker">
<xsl:with-param name="markerValue" select="$value"/>
<xsl:with-param name="markerLabel">
<xsl:choose>
<xsl:when test="showsubmarkervalue='yes'"><xsl:value-of select="$value" />
</xsl:when>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="degrees" select="$degrees"/>
<xsl:with-param name="sub">1</xsl:with-param>
</xsl:call-template>
<!-- if submarkers > 0
then substepsize = divide stepsize by submarkers;
-->
<xsl:if test="$i < $n">
<xsl:call-template name="submarkers">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="stepsize" select="$stepsize"/>
<xsl:with-param name="min" select="$min"/>
<xsl:with-param name="max" select="$max"/>
<xsl:with-param name="start" select="$value"/>
<xsl:with-param name="gridline" select="$gridline"/>
<xsl:with-param name="axis" select="$axis"/>
<xsl:with-param name="submarkers" select="$submarkers"/>
<xsl:with-param name="showsubmarkervalue" select="$showsubmarkervalue"/>
<xsl:with-param name="degrees" select="$degrees"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- submarkers -->
<!-- draw the markerareas - the zones on the outside of the speedometer -->
<xsl:template name="markerArea">
<xsl:param name="startvalue" />
<xsl:param name="endvalue" />
<xsl:param name="min" />
<xsl:param name="max" />
<xsl:param name="degrees">180</xsl:param>
<xsl:param name="color">blue</xsl:param>
<xsl:param name="title">myArea</xsl:param>
<!-- startvalue to endvalue -->
<g stroke-width="0" stroke-linejoin="round" onmouseout="HideTooltip(evt)">
<xsl:attribute name="onmouseover">ShowTooltip(evt,'<xsl:value-of select="$title"/>')</xsl:attribute>
<xsl:attribute name="stroke"><xsl:value-of select="$color"/></xsl:attribute>
<xsl:attribute name="fill"><xsl:value-of select="$color"/></xsl:attribute>
<xsl:variable name="startvalue" select="$startvalue"/>
<xsl:variable name="endvalue" select="$endvalue"/>
<xsl:variable name="firstAngle" select="math:toRadians((180 - $degrees) div 2 + ($endvalue - $min) div ($max - $min) * $degrees)"/>
<xsl:variable name="secondAngle" select="math:toRadians((180 - $degrees) div 2 + ($startvalue - $min) div ($max - $min) * $degrees)"/>
<xsl:variable name="x1" select="math:cos($firstAngle) * -1* 1940 +2160 "/>
<xsl:variable name="y1" select="math:sin($firstAngle) * 1940 * -1 + 2720"/>
<xsl:variable name="x2" select="math:cos($secondAngle) * -1* 1940 +2160 "/>
<xsl:variable name="y2" select="math:sin($secondAngle) * 1940 * -1 + 2720"/>
<path >
<xsl:attribute name="angle"><xsl:value-of select="$firstAngle"/></xsl:attribute>
<xsl:attribute name="d"><xsl:text>M 2160 2720 L </xsl:text><xsl:value-of select="$x1"/><xsl:text> </xsl:text>
<xsl:value-of select="$y1"/>
<xsl:text> A 1940 1940 0 </xsl:text>
<xsl:choose><xsl:when test="($secondAngle - $firstAngle) > 180">1</xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose>
<xsl:text> 0 </xsl:text>
<xsl:value-of select="$x2"/><xsl:text> </xsl:text><xsl:value-of select="$y2"/>
<xsl:text> z </xsl:text>
</xsl:attribute>
</path>
</g>
</xsl:template>
</xsl:stylesheet>
The result of the transformation with this stylesheet to the SVG object can be downloaded here:DepSalSpeedometer.svg. The graph that is displayed as a result from these transformations:

I can understand the report in PDF,XML,HTML.
I want to do the report in XL.How I can proceed please give a idea.
all information resides here are good.i need some information regardingg migration.i.e, can i get sorce code & front end design for migrating data from excel to oracle.reply soon…plz…
I have drawn up a list of to do’s: new features I would like to add to the Speedometer chart:
– animation (show the movement of the dials over time)
– support for multiple axes
– better markersupport: set markercolor, markerdash and markerlength; gridlines
– display images (icons) as (part of) markervalues
– display a legend indicating the meaning of each dial
– implement a clock using the speedometer stylesheet as demonstration
I hope to add these features in the new couple of weeks and update the post accordingly.