NAME
SVG::Template::Graph - Perl extension for generating template-driven graphs with SVG
SYNOPSIS
use SVG::Template::Graph;
$data = [
{
barGraph=>1,#<barGraph|[lineGraph]>
barSpace=>20,
'title'=> '1: Trace 1',
'data' => #hash ref containing x-val and y-val array refs
{
'x_val' =>
[50,100,150,200,250,
300,350,400,450,500,550],
'y_val' =>
[100,150,100,126,100,
175,100,150,120,125,100],
},
'format' =>
{ #note that these values could change for *each* trace
'lineGraph' => 1,
'x_min' => 0,
'x_max' => 600,
'y_min' => 50,
'y_max' => 200,
'x_axis' => 1, #draw x-axis
'y_axis' => 1, #draw y-axis
#define the labels that provide the data context.
'labels' =>
{
#for year labels, we have to center the axis markers
'x_ticks' =>
{
'label' =>[2002,2003,2004],
'position'=>[100,300,500],
},
'y_ticks' =>
{
#tick mark labels
'label' => [ -250, 0, 250, 500],
#tick mark location in the data space
'position' => [50, 100, 150, 200],
},
},
},
},
];
#construct a new SVG::Template::Graph object with a file handle
my $tt = SVG::Template::Graph->new($file);
#set up the titles for the graph
$tt->setGraphTitle(['Hello svg graphing world','I am a subtitle']);
#generate the traces.
$tt->drawTraces($data,$anchor_rectangle_id);
#serialize and print
print $tt->burn();
DESCRIPTION
Template::Graph:SVG is a module for the generation of template-driven graphs using Scalable Vector Graphics (SVG). Using this module, it is possible to define a template SVG document with containers which are populated with correctly scaled plot images.
EXPORT
None by default.
EXAMPLES
Refer to the examples directory inside this distribution for working examples.
new()
#construct a new SVG::Template::Graph object with a file handle
my $tt = SVG::Template::Graph->new($file);
The constructor for the class. Takes a template file name as an argument
burn()
serialise the image. See SVG::xmlify for more details
setGraphTitle
my $svg_element_ref = $tt->setGraphTitle ($string|\@strings, %attributes)
Generate the text for the Graph Title Returns the reference to the text element
setTraceTitle
set the title of a trace
$tt->setTraceTitle( $string|\@strings, %attributes )
setXAxisTitle
Generate the text for the Graph X-Axis Titles Returns the reference to the text element
$tt->setXAxisTitle($axis_number, $string, %attributes)
$tt->setXAxisTitle($axis_number, \@strings, %attributes)
setYAxisTitle
Generate the text for the Graph Y-Axis Titles Returns the reference to the text element
$tt->setYAxisTitle($axis_number, $string,%attributes)
$tt->setYAxisTitle($axis_number, \@strings,%attributes)
_gg
Check that a group exists (is a valid, defined group in the SVG DOM) and create a group in the document if id does not exist. Return the group element This ensures that even if a designer failed to generate a group ID in the drawing, you will get a drawing with the right group names. If type is defined, an element of $type with %attributes is defined.
my $svg_element = $tt->_gg ($id)
my $svg_element = $tt->_gg ($id,'rect',width=>10,height=>10,
x=>10,y=>10,fill=>'none',stroke=>'red')
_setAxisText
Internal method called by setGraphTitle and setAxisTitle to do the actual work. Not really intended to be accessed from the outside but available for advanced users.
$tt->_setAxisText ($id,$text|\@text,%attributes)
struct $struct
the input structure required by sub drawTraces to generate the graph. Refer to the examples included in this distribution in the examples directory for working samples.
$struct = [{
'tracetype' => 'linegraph',
'title'=> '1: Trace 1',
'data' => #hash ref containing x-val and y-val array refs
{
'x_val' =>
[0, 2, 4,
6, 8, 10,
12,14,16,
18,20],
'y_val' =>
[4, 2, 5,
3, 7, 4 ,
9, 9, 2,
4, 3],
},
'format' =>
{
'x_max' => 600, #or for your case, the date value of the 1st point
'x_min' => 0, #or for your case, the date value of the last point
'y_max' => 0.35,
'y_min' => -0.1,
'x_title' => 'Calendar Year',
'y_title' => '% Annual Performance',
'x_axis' => 0, # do not automatically draw an x-axis
'y_axis' => 1, #automatically draw a y-axis
#define the labels that provide
#the data context.
'labels' =>
{
#for year labels, we have to center the axis markers
'x_ticks' =>
{
'label' =>[2002,2003,2004],
'position' =>[100,300,500],
},
y_ticks =>
{
#tick mark label
'label' => [ '-10.00%', '-5.00%', '0.00%',
'5.00%', '10.00%', '15.00%',
'20.00%', '25.00%', '30.00%',
'35.00%' ],
#tick mark location in the data space
'position' => [-0.10,-0.5,0,
-.5,.10,.15,
.20,.25,.30,
.35],
},
},
},
legend_title => 'Some Interesting Data',
},
];
getCanvasBoxBoundaries()
if $id_anchor_data is an array reference, then it uses it to describe the extents of the viewbox into which the current drawing will happen. If $id_anchor_data is a string then its associated xml element is assumed to be a rectangle and getCanvasBoxBoundaries uses the rectangle geometry.to define the plot bounding box. hash references are not supported.
Action: set the boundary box data in the object and returns the array reference:
[xmin, ymin, xmax, ymax]
getDataBoxBoundaries (\%struct)
returns the value of the boundary box of the data set which places the graph in the image as an array reference:
[xmin, ymin, xmax, ymax]
drawAxis(<target_group_id>,[x|y|undef]))
draw one or both of axes (zero-value line) of the drawing data space. Draws both axes unless one of the axes is passed as a string.
drawAxis('somegroupid','x') draws the x-axis line into group 'somegroupid'.
drawAxis('somegroupid','y') draws the y-axis line indo group 'somegroupid'
drawAxis('somegroupid') draws both x- and y- axis lines into group 'somegroupid'
construction detail: draws the content into a group.
drawTraces ($data_structure,$insertion_anchor_id)
given a structure describing the incoming drawing parameters, generates the SVG lines, axes, and ticks and returns the number of traces that were handled. If $anchor_id is defined and is a rectangle ID, then the drawing will take place in id.if $anchor_point is defined and it is an array of 4 real numbers, then this will be taken to be the location where the insertion box goes.
The format for the array is: [x0 y0 x1 y1]. in canvas dimension
getTracePointMap $index, polyline|[path]|polygon, $p, $anchor_data, %args
scales the points for lines appropriately and generates the correct polyline or path or polygon element, scaled and inverted to match paper space.
if $anchor_data is defined, then it is either the id of a rectangle whose geometry will contain the results, or it is an array reference which contains the viewbox defilition [x0,y0,x1,y1] where the graph is to be placed.
this is the method in which the generation of the graph is handled
returns the reference of the polyline/path/polygon tag that was generated.
lineGraph index, type, [\@x,\@y], $canvas, %styling_attributes
draw a line graph trace
barGraph()
$g->barGraph( $index, [\@x,\@y], \@canvas, $barSpace, %styling_attributes)
draw a bar graph trace
drawGridLines()
$p->drawGridLines ($target_svg_element_ref,$transformation_ref,$format_structure_ref)
draw the gridlines for a graph as defined in the formatting data structure for each trace.
handleFurnishings()
$p->handleFurnishings( $orientation, $format, \%anchor_refs);
single point for handling grid lines, gridline lables, and gridline tickmarks this method is a factory method for generating vertical or horizontal furnishings for the trace the anchor hash reference contains the following keys:
line
label
tick
parameters
gridline orientation
$orientation = 'x' or 'y'
Gridline context-format hash reference
$format - hash reference
defines what is shown and what is not.
whose values are svg element object references where the respective entities are to be appended as children.
drawGridLine()
draw a single grid line
drawTick()
$p->drawTick( ['x'|'y'], $index, $tick, $args, %attrs);
tickmark-generation handler
drawGridLabel()
grid lable generator
getTick($label_ref $oation)
return the front and back extensions to lines based on the definition (or lack of) tickmarks in the label construct
Example of a label definition:
$label = {
'y_ticks' => {
'style' => {
'right' => '10'
},
'position' => [
'150',
'100',
'0',
'-75'
],
'label' => [
'Much',
'Some',
'None',
'Lost'
]
},
'x_ticks' => {}
};
D
$self->D()
returns the SVG Document object
T($name)
$self->T($name)
returns the currently invoked transformation object. Returns transformation object $name if requested by name
setGraphTarget $targetid, $elementType <rect>, %element_attributes
define the graph target (currently only rectangles are accepted) on top of which the data will be drawn
getGraphTarget
returns the current graph target
autoGrid (int $min, int $max, int $count)
generates a reference to an array of $count+1 evenly distributed values ranging between $min and $max
$tt->autoGrid(0,100,10);
Format
format an array of values according to formatting rules
$tt->Format \@array,$format,$format_attribute[,@more_format_attributes]
$format can be 'time' or 'printf'
for 'time', uses the Time::localtime
example 1: formatting to print the verbose date
$a = [
'0',
'2.75',
'5.5',
'8.25',
'11'
];
my $b = $tt->Format($a,'time',"%a %b %e %H:%M:%S %Y");
returns
$b = [
'Thu Jan 1 01:00:00 1970',
'Thu Jan 1 01:00:02 1970',
'Thu Jan 1 01:00:05 1970',
'Thu Jan 1 01:00:08 1970',
'Thu Jan 1 01:00:11 1970'
];
Format uses POSIX function b<strftime> Refer to POSIX for more information on time formating.
example 2: formatting to print to three decimal places using sprintf
$tt->Format([1.123,2.1234,3.12345,4.123456],'sprintf','%.3f');
example 3: formatting to print a percent sign
$tt->Format([1.123,2.1234,3.12345,4.123456],'sprintf','%%');
mapTemplateId string $id
setTemplateIdMap hash template_pairs
assign the definitions between the internal keys and the ids in the template at hand. This method need not be called as all IDs automatically get run through if the default IDs specified below are used.
simpleGraph string $id, string $type, hash %attrs
TEMPLATE
To draw a graph, a template is required which contains two key datasets: a rectangle which will contain the inserted graph data and a group containing child group elements with the IDs expected by SVG::Template::Graph
REQUIRED RECT ELEMENT
REQUIRED GRAPH TRACE HANDLER
The svg snippet below provides the required groups for the generation of the first trace (trace intex 0)
Because SVG uses the Painter's model, the image rendering order follows the XML document order. For the snippet below, the rendering order is the following:
data,grid,ticks,
axes:x,y,
axes values:
x,y,
axes text:
x,y,
axes titles:
x,y
Trace generation snippet
<!-- trace insertion takes place here -->
<g id="group.trace.1" fill="none"
stroke="black" stroke-width="2">
<!-- draw the data below the gridlines -->
<g id="group.trace.data.1"
stroke="#333333" stroke-width="0.5"
fill="#411DA4"/>
<g id="group.trace.grid.1"
stroke="gray" stroke-width="1"/>
<g id="group.trace.tick.1"
stroke="black" stroke-width="1.5"/>
<g id="group.trace.axes.1"
stroke="none" fill="black">
<g id="group.trace.axes.x.1" stroke="gray"
fill="none" stroke-width="1"/>
<g id="group.trace.axes.y.1" stroke="gray"
fill="none" stroke-width="1"/>
<g id="group.trace.axes.values.x.1" text-anchor="middle"
stroke="none" fill="black" transform="translate(0,265)"/>
<g id="group.trace.axes.values.y.1" stroke="none"
fill="black" text-anchor="start" transform="translate(-40,0)"/>
<g id="group.trace.axes.title.x.1" text-anchor="middle"
transform="translate(365,370)" font-size="12"
fill="#411DA4" font-weight="Bold"/>
<g id="group.trace.axes.title.y.1.c" text-anchor="end"
transform="translate(40,200)">
<g id="group.trace.axes.title.y.1"
transform="rotate(-90)" font-weight="Bold"
font-size="12" fill="#411DA4"/>
</g>
</g>
</g>
<!-- end of trace insertion 1 -->
In order to show the trace in front of the gridlines, the above snippet changes to:
<!-- trace insertion takes place here -->
<g id="group.trace.1" fill="none"
stroke="black" stroke-width="2">
<g id="group.trace.grid.1"
stroke="gray" stroke-width="1"/>
<g id="group.trace.tick.1"
stroke="black" stroke-width="1.5"/>
<g id="group.trace.axes.1"
stroke="none" fill="black">
<g id="group.trace.axes.x.1" stroke="gray"
fill="none" stroke-width="1"/>
<g id="group.trace.axes.y.1" stroke="gray"
fill="none" stroke-width="1"/>
<g id="group.trace.axes.values.x.1" text-anchor="middle"
stroke="none" fill="black" transform="translate(0,265)"/>
<g id="group.trace.axes.values.y.1" stroke="none"
fill="black" text-anchor="start" transform="translate(-40,0)"/>
<g id="group.trace.axes.title.x.1" text-anchor="middle"
transform="translate(365,370)" font-size="12"
fill="#411DA4" font-weight="Bold"/>
<g id="group.trace.axes.title.y.1.c" text-anchor="end"
transform="translate(40,200)">
<g id="group.trace.axes.title.y.1"
transform="rotate(-90)" font-weight="Bold"
font-size="12" fill="#411DA4"/>
</g>
</g>
<!-- draw the data on top of the gridlines -->
<g id="group.trace.data.1" stroke="#333333" stroke-width="0.5" fill="#411DA4"/>
</g>
<!-- end of trace insertion 1 -->
EXAMPLES
Refer to the examples directory inside this distribution for working examples.
SEE ALSO
SVG::Parser SVG::Manual Expat SAX SVG::TT:Graph Tramsform::Canvas http://www.roitsystems.com http://www.roitsystems.com
AUTHOR
Ronan Oger, <ronan.oger@roitsystems.com<gt> http://www.roitsystems.com http://www.roitsystems.com
CREDITS
This library was developed and written by Ronan Oger, ROIT Systems Gmbh, under contract to Digital Craftsmen.
COPYRIGHT
Copyright (C) 2004 by Ronan Oger, ROIT Systems GmbH, Zurich, Switzerland
Copyright (C) 2004 by Digital Craftsmen Ltd, London, UK
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.3 or, at your option, any later version of Perl 5 you may have available.