You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by "Aeberhard Marc (SECI)" <ma...@credit-suisse.com> on 2006/11/22 14:19:42 UTC

can't see svg chart

Hi all,
 
i like to render a pdf including a svg chart (directly via instream-foreign-objects and not with a prerendered svg and external-graphics)...
 
Now the problem is, i can't see the chart - there is only the legend and the border of the svg picture!
FOP gives no error output!!!
 
Can anyone give me some ideas?
 
My Environment:
 
FOP 0.92 Beta with distributed Batik
Win XP
 
Master File
----------------
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo=http://www.w3.org/1999/XSL/Format

xmlns:svg="http://www.w3.org/2000/svg">

<xsl:import href="chartsvg.xsl"/>

<xsl:output indent="yes"

doctype-public="-//W3C//DTD SVG 1.0//EN"

doctype-system="http://www.w3.org/TR/SVG/DTD/svg10.dtd"/>

<xsl:template match="/">

<fo:root>

<fo:layout-master-set>

<fo:simple-page-master master-name="document-master" margin="0.4in" page-height="210mm" page-width="297mm" >

<fo:region-body margin="0pt" padding="0pt"/>

</fo:simple-page-master>

</fo:layout-master-set>

<fo:page-sequence master-reference="document-master">

<fo:flow flow-name="xsl-region-body" padding="0pt">

<xsl:call-template name="start"/>

</fo:flow>

</fo:page-sequence>

</fo:root>

</xsl:template>

<xsl:template name="start">

<xsl:call-template name="chart_main"/>

</xsl:template>

</xsl:stylesheet>

reference file chartsvg
-------------------------------
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:fo="http://www.w3.org/1999/XSL/Format"

xmlns:svg="http://www.w3.org/2000/svg">

<xsl:import href="lib_axis.xsl"/>

<xsl:import href="lib_bar.xsl"/>

<xsl:import href="lib_line.xsl"/>

<xsl:import href="lib_pie.xsl"/>

<xsl:output indent="yes"

doctype-public="-//W3C//DTD SVG 1.0//EN"

doctype-system="http://www.w3.org/TR/SVG/DTD/svg10.dtd"

cdata-section-elements="style"/>

<!--

doctype-public="-//W3C//DTD SVG 1.0//EN"

doctype-system="http://www.w3.org/TR/SVG/DTD/svg10.dtd"

indent="yes"

cdata-section-elements="style"/>

--> 

<xsl:template name="chart_main">

<fo:block-container>

<fo:block>

<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">

<xsl:apply-templates select="." mode="svg"/>

</fo:instream-foreign-object>

</fo:block>

</fo:block-container>

</xsl:template>

<xsl:template match="xaxis/grid" mode="svg">

<xsl:call-template name="draw_x_grid">

<xsl:with-param name="pos_method">

<xsl:if test="/hsgraph/charttype = 'line'">1</xsl:if>

<xsl:if test="/hsgraph/charttype = 'bar'">0</xsl:if>

</xsl:with-param>

</xsl:call-template>

</xsl:template>

<xsl:template match="yaxis/grid" mode="svg">

<xsl:call-template name="draw_y_grid"/> 

</xsl:template>

<xsl:template match="series/serie" mode="svg">

<xsl:if test="/hsgraph/charttype = 'line'">

<xsl:call-template name="draw_line"/>

</xsl:if>

<xsl:if test="/hsgraph/charttype = 'bar'">

<xsl:call-template name="draw_bar"/>

</xsl:if>

</xsl:template>

<xsl:template match="series" mode="svg">

<xsl:if test="(/hsgraph/charttype = 'line') or (/hsgraph/charttype = 'bar')">

<xsl:apply-templates select="serie" mode="svg"/>

</xsl:if>

<xsl:if test="(/hsgraph/charttype = 'pie')">

<xsl:call-template name="draw_pie"/>

</xsl:if>

</xsl:template>

<xsl:template match="hsgraph" mode="svg">

<svg:svg width="5in" height="5in" viewBox="-60 -500 700 800">

<xsl:attribute name="viewBox">

<xsl:if test="showlegend and not(showlegend/@chartfitpos)">0 0 800 400</xsl:if>

<xsl:if test="not(showlegend) or showlegend/@chartfitpos">0 0 600 400</xsl:if>

</xsl:attribute>

<svg:defs>

<svg:style type="text/css">

.axistitle

{

font-weight:bold;

font-size:14px;

font-family:Arial;

text-anchor:middle;

}

.xgrid, .ygrid, .legendtext

{

font-weight:normal;

font-size:11px;

font-family:Arial;

}

.xgrid {text-anchor:middle;}

.ygrid {text-anchor:end;}

.gridline

{

stroke:black;

stroke-width:1;

}

.values

{

fill:black;

stroke:none;

text-anchor:middle;

font-size:12px;

font-weight:bold;

}

</svg:style>

</svg:defs>

<xsl:if test="bgcolor">

<svg:rect x="0" y="0" height="400">

<xsl:attribute name="width">

<xsl:if test="showlegend and not(showlegend/@chartfitpos)">800</xsl:if>

<xsl:if test="not(showlegend) or showlegend/@chartfitpos">600</xsl:if>

</xsl:attribute>

<xsl:attribute name="stroke">none</xsl:attribute>

<xsl:attribute name="fill">

<xsl:value-of select="bgcolor"/>

</xsl:attribute>

</svg:rect>

</xsl:if>

 <svg:text class="axistitle" x="300" y="20"><xsl:value-of select="title"/></svg:text>

<xsl:if test="(/hsgraph/charttype = 'line') or (/hsgraph/charttype = 'bar')">

<xsl:apply-templates select="xaxis" mode="svg"/> 

<xsl:apply-templates select="yaxis" mode="svg"/>

<svg:svg id="graphzone" preserveAspectRatio="none" x="50" y="50" width="500" height="300" viewBox="0 0 500 300">

<xsl:if test="yaxis/margin">

<xsl:attribute name="x"><xsl:value-of select="50 + yaxis/margin"/></xsl:attribute>

<xsl:attribute name="width"><xsl:value-of select="500 - yaxis/margin"/></xsl:attribute>

</xsl:if>

<xsl:if test="showlegend and showlegend/@chartfitpos">

<xsl:call-template name="draw_legend">

<xsl:with-param name="x_offset">

<xsl:value-of select="(500 div xaxis/max) * showlegend/@chartfitpos"/>

</xsl:with-param>

<xsl:with-param name="y_offset">-15</xsl:with-param>

</xsl:call-template>

</xsl:if>

<xsl:apply-templates select="series"/>

</svg:svg>

</xsl:if>

<xsl:if test="(/hsgraph/charttype = 'pie')">

<svg:svg id="graphzone" preserveAspectRatio="xMidYMid meet" x="0" y="50" width="600" height="340" viewBox="0 0 500 300">

<xsl:if test="showlegend">

<xsl:call-template name="draw_legend"/>

</xsl:if>

<xsl:apply-templates select="series" mode="svg"/>

</svg:svg>

</xsl:if>

<svg:rect style="fill:none;stroke-width:1;stroke:black;" x="0" y="0" width="600" height="400"/>

<xsl:if test="showlegend and not(showlegend/@chartfitpos)">

<svg:svg id="legendzone" x="600" y="0" width="200" height="400" viewBox="0 0 200 400">

<svg:rect style="fill:none;stroke-width:1;stroke:black;" x="0" y="0" width="200" height="{(count(series/serie) + 2) * 15}"/> 

<xsl:call-template name="draw_legend"/>

</svg:svg>

</xsl:if>

</svg:svg>

</xsl:template>

<!-- NAMED TEMPLATES -->

<xsl:template name="draw_legend" mode="svg">

<xsl:param name="x_offset" select="0"/>

<xsl:param name="y_offset" select="0"/>

<xsl:variable name="total_y" select="sum(*/serie/point/@y)"/>

<xsl:for-each select="series/serie">

<xsl:variable name="ypos" select="(position() * 15) + $y_offset"/>

<svg:rect style="fill:{color};stroke-width:1;stroke:black;" x="{10 + $x_offset}" y="{$ypos}" width="10" height="10"/>

 <svg:text class="legendtext" x="{25 + $x_offset}" y="{$ypos + 10}">

<xsl:value-of select="name"/>

<xsl:if test="/hsgraph/showlegend/@showpercent">

(<xsl:value-of select="round((sum(point/@y) div $total_y) * 100)"/>%)

</xsl:if>

</svg:text>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

 
 
referenced lib_axis
---------------------------
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:svg="http://www.w3.org/2000/svg">

<xsl:output indent="yes"

doctype-public="-//W3C//DTD SVG 1.0//EN"

doctype-system="http://www.w3.org/TR/SVG/DTD/svg10.dtd"/>

<!--

indent="yes"/>

-->

<xsl:template match="xaxis" mode="svg">

<svg:g id="x_axis">

<xsl:if test="../yaxis/margin">

<xsl:attribute name="transform">translate(<xsl:value-of select="../yaxis/margin"/>,0)</xsl:attribute>

</xsl:if>

<svg:line class="histframe" x1="50" x2="550" y1="350" y2="350">

<xsl:if test="../yaxis/margin">

<xsl:attribute name="x2"><xsl:value-of select="550 - ../yaxis/margin"/></xsl:attribute>

</xsl:if>

</svg:line>

<svg:text class="axistitle" x="300" y="395">

<xsl:value-of select="title"/>

</svg:text>

<xsl:apply-templates select="grid"/>

</svg:g>

</xsl:template>

<xsl:template match="yaxis" mode="svg">

<svg:text class="axistitle" writing-mode="tb" glyph-orientation-vertical="0" x="10" y="200">

<xsl:value-of select="title"/>

</svg:text>

<svg:g id="y_axis">

<xsl:if test="margin">

<xsl:attribute name="transform">translate(<xsl:value-of select="margin"/>,0)</xsl:attribute>

</xsl:if>

<svg:line class="histframe" x1="50" x2="50" y1="50" y2="350"/>

<xsl:apply-templates select="grid"/>

</svg:g>

</xsl:template>

<!-- NAMED TEMPLATES -->

<xsl:template name="draw_x_grid" mode="svg">

<xsl:param name="pos_method" select="0"/> <!-- 0 = The line goes in the middle of the space allowed for it. 1 = The line goes at the start of that space -->

<xsl:variable name="axis_width">

<xsl:if test="../../yaxis/margin"><xsl:value-of select="500 - ../../yaxis/margin"/></xsl:if>

<xsl:if test="not(../../yaxis/margin)">500</xsl:if>

</xsl:variable>

<xsl:variable name="gridcount" select="count(line)"/>

<xsl:variable name="mywidth">

<xsl:if test="$pos_method = 0"><xsl:value-of select="$axis_width div $gridcount"/></xsl:if>

<xsl:if test="$pos_method = 1"><xsl:value-of select="$axis_width div ($gridcount - 1)"/></xsl:if> 

</xsl:variable>

<xsl:for-each select="line">

<xsl:variable name="lineno" select="position() - 1"/>

<xsl:variable name="xpos_tmp">

<xsl:choose>

<xsl:when test="@value"><xsl:value-of select="50 + ((@value div ../../max) * $axis_width)"/></xsl:when>

<xsl:when test="../valuepositioning"><xsl:value-of select="50 + ((number() div ../../max) * $axis_width)"/></xsl:when>

<xsl:otherwise><xsl:value-of select="50 + ($lineno * $mywidth)"/></xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:variable name="xpos">

<xsl:if test="$pos_method = 0"><xsl:value-of select="$xpos_tmp + ($mywidth div 2)"/></xsl:if>

<xsl:if test="$pos_method = 1"><xsl:value-of select="$xpos_tmp"/></xsl:if> 

</xsl:variable>

<svg:line class="gridline" x1="{$xpos}" x2="{$xpos}" y1="350" y2="360"/>

<svg:text class="xgrid" x="{$xpos}" y="370">

<xsl:if test="((../longstrfit) and ((position() mod 2) = 0)) or (@lowered)">

<xsl:attribute name="y">382</xsl:attribute>

</xsl:if>

<xsl:value-of select="."/>

</svg:text>

</xsl:for-each>

</xsl:template>

<xsl:template name="draw_y_grid" mode="svg">

<xsl:variable name="gridcount" select="count(line)"/>

<xsl:variable name="mywidth" select="300 div $gridcount"/>

<xsl:variable name="indicator_width" select="500 - ../margin"/>

<xsl:variable name="ymax" select="../max"/>

<xsl:variable name="ymin" select="sum(../min)"/> <!-- A hack to make the script work even if there is no min element -->

<xsl:variable name="ydelta" select="$ymax - $ymin"/>

<xsl:for-each select="line">

<xsl:variable name="lineno" select="position()"/>

<xsl:variable name="ypos">

<xsl:choose>

<xsl:when test="@value"><xsl:value-of select="350 - (((@value - $ymin) div $ydelta) * 300)"/></xsl:when>

<xsl:when test="../valuepositioning"><xsl:value-of select="350 - (((number() - $ymin) div $ydelta) * 300)"/></xsl:when>

<xsl:otherwise><xsl:value-of select="300 - ($lineno * $mywidth)"/></xsl:otherwise>

</xsl:choose>

</xsl:variable>

<svg:line class="gridline" x1="40" x2="50" y1="{$ypos}" y2="{$ypos}"/>

<svg:text class="ygrid" x="39" y="{($ypos+4)}"><xsl:value-of select="."/></svg:text>

<xsl:if test="@indicator">

<svg:line class="gridline" style="stroke:{@indicator}" x1="50" x2="{50 + $indicator_width}" y1="{$ypos}" y2="{$ypos}"/> 

</xsl:if>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

 

referenced lib_bar
--------------------------

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:svg="http://www.w3.org/2000/svg"> <!-- exclude-result-prefixes="#default"-->

<xsl:output indent="yes"

doctype-public="-//W3C//DTD SVG 1.0//EN"

doctype-system="http://www.w3.org/TR/SVG/DTD/svg10.dtd"/>

<!--

indent="yes"/>

-->

<xsl:template name="draw_bar" mode="svg"> <!-- This is called when the man script processes a 'serie' -->

<svg:g style="stroke:black;stroke-width:1;fill:{color}">

<xsl:variable name="serieno" select="count(preceding-sibling::*)"/>

<xsl:variable name="xmax" select="/hsgraph/xaxis/max"/>

<xsl:variable name="ymax" select="/hsgraph/yaxis/max"/>

<xsl:variable name="ymin" select="sum(/hsgraph/yaxis/min)"/> <!-- A hack to make the script work even if there is no min element -->

<xsl:variable name="ydelta" select="$ymax - $ymin"/>

<xsl:variable name="xwidth" select="100 div $xmax"/>

<xsl:variable name="ywidth" select="100 div $ydelta"/>

<xsl:variable name="scount" select="count(../*)"/>

<xsl:variable name="xunit" select="($xwidth div 2) div $scount"/>

<xsl:for-each select="point">

<xsl:variable name="xpos" select="(@x * $xwidth) + ($xunit div 2) + ($xunit * $serieno)"/>

<xsl:variable name="myheight" select="(@y - $ymin) * $ywidth"/>

<xsl:variable name="ypos" select="100 - $myheight"/>

<svg:rect y="{$ypos}%" x="{$xpos}%" height="{$myheight}%" width="{$xwidth div 2}%"/>

</xsl:for-each> 

<xsl:if test="../@showvalues">

<xsl:for-each select="point">

<xsl:variable name="xpos" select="(@x * $xwidth) + ($xunit div 2) + ($xunit * $serieno)"/>

<xsl:variable name="myheight" select="(@y - $ymin) * $ywidth"/>

<xsl:variable name="ypos" select="100 - $myheight"/>

<svg:text class="values" x="{$xpos + ($xwidth div 4)}%" y="{$ypos - 1}%">

<xsl:if test="../@valuecolor">

<xsl:attribute name="style">

<xsl:text>fill:</xsl:text><xsl:value-of select="../@valuecolor"/><xsl:text>;</xsl:text>

</xsl:attribute>

</xsl:if>

<xsl:value-of select="@y"/>

</svg:text>

</xsl:for-each>

</xsl:if>

</svg:g>

</xsl:template>

</xsl:stylesheet>

 

XML File
-------------

<?xml version="1.0"?>

<hsgraph><!-- Every ChartSVG data file must start with this tag -->

<title>ChartSVG example</title> <!-- The title that will be displayed in the top of the chart -->

<charttype>bar</charttype> <!-- The type of chart that is going to be produced. Right now 'line','bar' and 'pie' are supported -->

<showlegend chartfitpos="1" showpercent="y"/> <!-- If this tag is there, a legend section will be added to the chart. If a "chartfitpos" attribute is present, The legend will be fitted in the chart instead of adding a new section. The legend will be aligned with the Nth column, N being the chartfitpos value. -->

<bgcolor>white</bgcolor> <!-- This element specifies a background color for the whole graph. If it is missing, the background is transparent -->

<xaxis> <!-- X axis settings -->

<title>Months</title> <!-- The title under the X axis -->

<max>12</max> <!-- The maximum value of the X Axis. Max should be higher than the highest x values of all series -->

<grid> <!-- The grid lines. Each line node in this node will result in a grid line in the chart -->

<longstrfit/> <!-- Automatically aternate the grid titles' y values so the long strings don't overlap -->

<line>January</line>

<line>February</line>

<line>March</line>

<line>April</line>

<line>May</line>

<line>June</line>

<line>July</line>

<line>August</line>

<line>September</line>

<line>October</line>

<line>November</line>

<line>December</line>

</grid>

</xaxis>

<yaxis> <!-- Y axis settings -->

<title>Visitors</title>

<max>200</max>

<margin>28</margin> <!-- This element will give more space to the Y Axis (If the text on the grid lines are too large to fit) -->

<grid>

<valuepositioning/> <!-- This option will place every grid line according to it's value instead of ditributing the lines evenly on the axis -->

<line>50</line>

<line>100</line>

<line>150</line>

<line>200</line>

<line value="130" indicator="blue">Objective</line> <!-- If the "indicator" attribue is set, a line will go through the whole graphic, having the color specified by this attribute -->

<line value="60" indicator="red">Disaster</line>

</grid>

</yaxis>

<series> <!-- Chart series. A "showvalues" attribute is possible, but recommended only if just one serie is present. -->

<serie> <!-- In the bar chart, every serie is overlapped and has a small offset between each rect -->

<name>Serie 1</name> <!-- The name that appears in the legend -->

<color>#6699cc</color> <!-- Color of the rectangles associated with this serie -->

<point x="0" y="20"/> <!-- each point node will result in a rectangle in the bar chart -->

<point x="1" y="40"/>

<point x="2" y="90"/>

<point x="3" y="124"/>

<point x="4" y="81"/>

<point x="5" y="102"/>

<point x="6" y="200"/>

<point x="7" y="108"/>

<point x="8" y="38"/>

<point x="9" y="67"/>

<point x="10" y="94"/>

<point x="11" y="5"/>

</serie>

<serie>

<name>Serie 2</name>

<color>red</color>

<point x="0" y="100"/>

<point x="1" y="80"/>

<point x="2" y="60"/>

<point x="3" y="40"/>

<point x="4" y="20"/>

<point x="5" y="10"/>

<point x="6" y="60"/>

<point x="7" y="80"/>

<point x="8" y="100"/>

<point x="9" y="110"/>

<point x="10" y="130"/>

<point x="11" y="150"/>

</serie>

<serie>

<name>Serie 3</name>

<color>yellow</color>

<point x="0" y="10"/>

<point x="1" y="30"/>

<point x="2" y="50"/>

<point x="3" y="90"/>

<point x="4" y="80"/>

<point x="5" y="60"/>

<point x="6" y="180"/>

<point x="7" y="160"/>

<point x="8" y="140"/>

<point x="9" y="120"/>

<point x="10" y="100"/>

<point x="11" y="80"/>

</serie>

</series>

</hsgraph>

 
 
 
 
Thanks a lot,
 
Marc

Re: can't see svg chart

Posted by Jeremias Maerki <de...@jeremias-maerki.ch>.
Please don't send XSLT files, only FO files. And please don't inline
them in the text. All sorts of bad things can happen to the XML like
this. You can save us a lot of time.

What I'd do is modifying the stylesheet so you can generate a pure SVG
file for testing. Then I'd check that the SVG is correct with an SVG
viewer before running it through FOP.

On 22.11.2006 14:19:42 Aeberhard Marc \(SECI\) wrote:
> Hi all,
>  
> i like to render a pdf including a svg chart (directly via instream-foreign-objects and not with a prerendered svg and external-graphics)...
>  
> Now the problem is, i can't see the chart - there is only the legend and the border of the svg picture!
> FOP gives no error output!!!
>  
> Can anyone give me some ideas?
>  
> My Environment:
>  
> FOP 0.92 Beta with distributed Batik
> Win XP
>  
<snip/>


Jeremias Maerki


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org