Generating graphics

SVG output

At the end of the pipeline, different Serializers can generate different output formats, provided they're fed the right data (i.e. the required XML elements and namespaces).

Let's generate a simple graph out of of our request parameters. If your have an SVG plugin in your browser you can view the result: red/request.svg or blue/request.svg. If you don't have an SVG plugin see below for the bitmapped version of the same image.

Sitemap excerpt

<map:match id="svgRequest" pattern="*/request.svg">
<map:generate type="request"/>
<map:transform src="xsl/request-to-svg.xsl">
<map:parameter name="fillColor" value="{1}"/>
</map:transform>
<map:serialize type="svgxml"/>
</map:match>

XSL transformation

Here we show only the main template wich generates the SVG skeleton

<xsl:template name="main" match="/">
<svg width="800" height="500">
<defs>
<filter id="blur1">
<feGaussianBlur stdDeviation="3"/>
</filter>
<filter id="blur2">
<feGaussianBlur stdDeviation="1"/>
</filter>
</defs>
<g title="this is a tooltip">
<rect style="{concat('fill:',$fillColor,';stroke:#000000;stroke-width:4;filter:url(#blur1);')}" x="30" y="30" rx="20" ry="20" width="700" height="400"/>
<text style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);" x="65" y="80">
<xsl:value-of select="concat('color:',$fillColor)"/>
</text>
<xsl:apply-templates select="//h:header[position() < 5]"/>
</g>
</svg>
</xsl:template>

Typical output

<svg height="500" width="800">
<defs>
<filter id="blur1">
<feGaussianBlur stdDeviation="3"/>
</filter>
<filter id="blur2">
<feGaussianBlur stdDeviation="1"/>
</filter>
</defs>
<g title="this is a tooltip">
<rect height="400" width="700" ry="20" rx="20" y="30" x="30" style="fill:red;stroke:#000000;stroke-width:4;filter:url(#blur1);"/>
<text y="80" x="65" style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);"> color:red </text>
<svg:text y="120" x="65" style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);"> accept:*/* </svg:text>
<svg:text y="160" x="65" style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);"> user-agent:Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com) </svg:text>
<svg:text y="200" x="65" style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);"> accept-encoding:gzip, br, zstd, deflate </svg:text>
<svg:text y="240" x="65" style="fill:#FFFFFF;font-size:24;font-family:TrebuchetMS-Bold;filter:url(#blur2);"> host:digitalhumanities.org:8081 </svg:text>
</g>
</svg>

Bitmapped output

Post-processing the SVG output allows us to generate JPEG (cyan/request.jpeg) or PNG (black/request.png) images, simply by configuring a different serializer at the end of the pipeline.

Sitemap excerpts

Note the use of the cocoon:/ protocol to re-use the previous pipeline as input: when a request to blue/request.png is received, the output of the blue/request.svg is used as the input of the first pipeline shown below.

<map:match id="pngRequest" pattern="*/request.png">
<map:generate src="cocoon:/{1}/request.svg"/>
<map:serialize type="svg2png"/>
</map:match>
<map:match id="jpegRequest" pattern="*/request.jpeg">
<map:generate src="cocoon:/{1}/request.svg"/>
<map:serialize type="svg2jpeg"/>
</map:match>