view release on metacpan or search on metacpan
# programmable fonts
# added chart_type_map to permit external
# type specs for parameterized datasources
# add BORDER property
#
# 0.73 2002-Sep-11 D. Arnold
# fix error reporting from ::Plot
# fix the SYNOPSIS
#
# 0.72 2002-Aug-17 D. Arnold
# fix legend placement
#
# 0.71 2002-Aug-12 D. Arnold
# fix LINEWIDTH property to be local
# add ANCHORED property
# fixed VERSION value
#
# 0.70 2002-Jun-01 D. Arnold
# added quadtree plots
# added cumulative (aka stacked) barcharts
# fix for individual graph SHOWVALUES
$sth->{chart_colormap} = 0;
return scalar @$col1;
}
#
# now we can safely process and render
#
my $img;
my $xdomain;
my $ydomain;
my $zdomain;
my @legends = ();
#
# need to determine domain type prior to adding points
my $is_symbolic = undef;
for ($i = 0; $i < scalar(@$dtypes); $i++) {
$is_symbolic = 1, last
if (($$dtypes[$i] eq 'BARCHART') ||
($$dtypes[$i] eq 'HISTOGRAM') ||
($$dtypes[$i] eq 'CANDLESTICK'));
}
$propstr .= ' stack '
if ($$props{STACK});
#
# default x-axis label orientation is vertical for candlesticks
# and symbollic domains
#
$img->setOptions(
'xAxisVert' => ($$props{X_ORIENT} ? ($$props{X_ORIENT} ne 'HORIZONTAL') : 1))
if ((! $numtype{$$types[0]}) || ($$dtypes[$i] eq 'CANDLESTICK'));
#
# force a legend if more than 1 range or plot
# complicated algorithm here;
# if multirange or composite {
# if multirange {
# push each column name onto legends array, prepended with
# current query name if available
# }
# } else { must be a composite
# push query name (default PLOTn) onto legends array
# }
#
if (! $$props{Z_AXIS}) {
if ((($$dtypes[$i] ne 'CANDLESTICK') && (scalar(@$data) > 2)) ||
(($$dtypes[$i] eq 'BOXCHART') && (scalar(@$data) > 1)) ||
(scalar(@$data) > 3)) {
# its multirange
my $incr = ($$dtypes[$i] ne 'CANDLESTICK') ? 1 : 2;
# if stacked, we need an arrayref of legends
my $legary = ($$props{STACK}) ? [ ] : \@legends;
push(@legends, $legary) if ($$props{STACK});
for (my $c = 0; $c <= $#colnames; $c += $incr) {
#
# if floating bar/histo, ignore last column name
last if ((! $$props{ANCHORED}) && ($c == $#colnames) &&
(($$dtypes[$i] eq 'BARCHART') ||
($$dtypes[$i] eq 'HISTOGRAM')));
#
# prepend query names if provided for composites
push(@$legary, ($$dnames[$i] . '.' . $colnames[$c])),
next
if ($$dnames[$i]);
push(@$legary, $colnames[$c]);
}
}
elsif ($#$dtypes > 1) {
#
# single range, composite
push(@legends, ($$dnames[$i] ? $$dnames[$i] : "PLOT$i"));
}
}
#
# establish icon list if any
#
my @icons = ();
my $iconlist = $$props{ICON};
if ($$props{ICON}) {
for ($k = 1, $j = 0; $k <= $#$data; $k++) {
push(@icons, $$iconlist[$j++]);
'fill ' . $colors[$k-1] ;
$tprops .= ' ' . $shapes[$k-1]
if ($$props{SHOWPOINTS} || $$props{SHAPE});
$tprops .= ' width:' . ($$props{LINEWIDTH} ? $$props{LINEWIDTH} : 1);
$tprops .= ' float' unless $$props{ANCHORED};
return $sth->DBI::set_err(-1, $img->{errmsg}, 'S1000')
unless $img->setPoints($$data[0], $$data[$k], $tprops);
}
}
#
# if we have a legend, add it before plotting
$img->setOptions( legend => \@legends)
if ($#legends >= 0);
#
# all the image data loaded, now plot it
#
$sth->{chart_image} = $img->plot($dprops->[0]->{FORMAT});
return $sth->DBI::set_err(-1, $img->{errmsg}, 'S1000')
unless $sth->{chart_image};
$sth->{chart_imagemap} =
($sth->{chart_imagemap}) ? $img->getMap() : undef;
return $sth->DBI::set_err(-1, $img->{errmsg}, 'S1000')
Chart/Plot.pm view on Meta::CPAN
# fix all plots with single data point
# add axis labels for 3-D bars
# improve error reporting for iconic too wide,
# icon format unsupported
# fix for odd segmented quadtrees
# fix scaling for 3-D bars when KEEPORIGIN=1
# fix SHOWVALUES for 3-D bars when clipped from origin
#
# 0.72 2002-Aug-17 D. Arnold
# fix showvalues for nonstacked bars/histos/candles
# fix legend placement
#
# 0.71 2002-Aug-12 D. Arnold
# add float property for bars/histos/areas
# fix linewidth to be local property
# fix bug in stacked areagraphs
#
# 0.70 2002-Jun-10 D. Arnold
# add stacked bar, histo, area, and candlestick graphs
# add quadtree graph
# support new property keywords stack, showvalues
Chart/Plot.pm view on Meta::CPAN
horizMargin 1
vertMargin 1
xAxisLabel 1
yAxisLabel 1
zAxisLabel 1
xLog 1
yLog 1
zLog 1
title 1
signature 1
legend 1
horizGrid 1
vertGrid 1
xAxisVert 1
keepOrigin 1
bgColor 1
threed 1
icons 1
symDomain 1
timeDomain 1
gridColor 1
Chart/Plot.pm view on Meta::CPAN
# title - title string
# xLog, yLog, zLog - 1 => assoc axis is logarithmic
# errmsg - last error msg
# keepOrigin - force (0,0[,0]) into graph
# imgMap - HTML imagemap text
# symDomain - 1 => domain is symbolic
# timeDomain - 1 => domain is temporal
# icon - name of icon image file for iconic barcharts/points
# logo - name of background logo image file
# mapModifier - ref to callback to modify imagemap entries
# _legends - arrayref to hold legend info til we render it
#
sub init {
my ($obj, $w, $h, $colormap) = @_;
$w = 400 unless $w;
$h = 300 unless $h;
my $img = new GD::Image($w, $h);
#
# if a colormap supplied, copy it into our color list
#
Chart/Plot.pm view on Meta::CPAN
$obj->{xAxisLabel} = '';
$obj->{yAxisLabel} = '';
$obj->{zAxisLabel} = '';
$obj->{xLog} = 0; # 1 => log10 scaling
$obj->{yLog} = 0;
$obj->{zLog} = 0;
$obj->{title} = '';
$obj->{signature} = '';
$obj->{legend} = 0; # 1 => render legend
$obj->{horizGrid} = 0; # 1 => print y-axis gridlines
$obj->{vertGrid} = 0; # 1 => print x-axis gridlines
$obj->{xAxisVert} = 0; # 1 => print x-axis label vertically
$obj->{errmsg} = ''; # error result of last operation
$obj->{keepOrigin} = 0; # 1 => force origin into graph
$obj->{threed} = 0; # 1 => use 3-D effect
$obj->{logo} = undef;
$obj->{icons} = [ ]; # array of icon filenames
Chart/Plot.pm view on Meta::CPAN
$obj->{bgColor} = $white; # background color
$obj->{gridColor} = $black;
$obj->{textColor} = $black;
$obj->{border} = 1;
$obj->{mapModifier} = undef;
# for now these aren't used, but someday we'll let them be configured
$obj->{font} = 'gd';
$obj->{_legends} = [ ];
# set image basic properties
$img->transparent($obj->{transparent});
$img->interlaced('true');
# $img->rectangle( 0, 0, $w-1, $h-1, $obj->{black});
}
#
# compare function for numeric sort
#
Chart/Plot.pm view on Meta::CPAN
}
my $plotcnt = $#{$obj->{props}} + 1;
#
# hueristically render plots in "best" visible order
#
if ($obj->{zAxisLabel} || $obj->{threed}) {
return undef # since 3-D only compatible with 3-D
if (! $obj->plot3DBars);
return undef
unless (($#{$obj->{_legends}} < 0) || $obj->drawLegend);
$obj->plot3DTicks;
return (($format) && $obj->{img}->$format);
}
return undef # since quadtree must be solo
if (($plottypes & QUADTREE) && (! $obj->plotQuadtree(\@proptypes)));
return undef # since histo only compatible with histo
if (($plottypes & HISTO) && (! $obj->plot2DBars(HISTO, \@proptypes)));
Chart/Plot.pm view on Meta::CPAN
return undef
if (($plottypes & BOX) && (! $obj->plotBox(\@proptypes)));
return undef
if (($plottypes & LINE) && (! $obj->plotAll(LINE,\@proptypes)));
return undef
if (($plottypes & POINT) && (! $obj->plotAll(POINT,\@proptypes)));
#
# add any accumulated legends
#
return undef
unless (($#{$obj->{_legends}} < 0) || $obj->drawLegend);
#
# now render it in the requested format
#
return (($format) && $obj->{img}->$format);
}
sub getMap {
my ($obj) = @_;
my $mapname = $obj->{genMap};
Chart/Plot.pm view on Meta::CPAN
my $j = 1;
$datastack->[$j]->[0] = $yl, $j += 3
while ($j <= $#$datastack);
}
}
#
# heuristically adjust image margins to fit labels
#
my ($botmargin, $topmargin, $ltmargin, $rtmargin) = (40, 40, 0, 5*$sfw);
$botmargin += (3 * $tfh) if $obj->{legend};
#
# compute space needed for X axis labels
#
my $maxlen = 0;
my ($tl, $th) = (0, 0);
($tl, $th) = ($obj->{xLog}) ? (10**$xl, 10**$xh) : ($xl, $xh)
unless $obj->{symDomain};
$maxlen = $obj->{symDomain} ? $obj->{xMaxLen} :
$obj->{timeDomain} ? length($obj->{timeDomain}) :
(length($th) > length($tl)) ? length($th) : length($tl);
Chart/Plot.pm view on Meta::CPAN
}
sub plot2DBars {
my ($obj, $type, $typeary) = @_;
my ($i, $j, $k, $x, $n, $ary, $pxl, $pxr, $py, $pyt, $pyb);
my ($color, $prop, $s, $colorcnt);
my @barcolors = ();
my @brushes = ();
my @markers = ();
my @props = ();
my $legend = $obj->{legend};
my ($xl, $xh, $yl, $yh) = ($obj->{xl}, $obj->{xh}, $obj->{yl},
$obj->{yh});
my ($brush, $ci, $t);
my ($useicon, $marker);
my $img = $obj->{img};
my $plottypes = $obj->{plotTypes};
my @tary = ();
my $bars = $obj->{barCount};
my $boff = int($obj->{brushWidth}/2);
my $ttlw = int($bars * $boff);
Chart/Plot.pm view on Meta::CPAN
# load each icon we're using
#
foreach (0..$#markers) {
next unless $markers[$_];
$markers[$_] = ($valid_shapes{$markers[$_]} && ($markers[$_] ne 'null')) ?
$obj->make_marker($markers[$_], $barcolors[$_]) :
$obj->getIcon($markers[$_], 1);
return undef unless $markers[$_];
}
#
# render legend if requested
# (a bit confusing here for multicolor single range charts?)
$obj->addLegend($barcolors[0], $markers[0], $$legend[$k], undef)
if ((! $stacked) && $legend && $$legend[$k]);
if ($stacked && $legend && $$legend[$k]) {
#
# there may be alignment problems here, due to the
# possibility of drawing multiple stacked bars in the same image
#
$obj->addLegend($barcolors[$_], $markers[$_], $$legend[$k]->[$_], undef)
foreach (0..$#{$$legend[$k]});
}
#
# heuristically determine whether to print Y values vert or horiz.
my $yorient = (length($yl) > length($yh)) ? length($yl) : length($yh);
$yorient *= $tfw;
#
# compute the center data point, then
# adjust horizontal location based on brush width
# and data set number
#
Chart/Plot.pm view on Meta::CPAN
$uex = $uq + ($iqr*1.5);
$lex = $$ary[0] if ($lex < $$ary[0]);
$uex = $$ary[$#$ary] if ($uex > $$ary[$#$ary]);
return ($median, $lq, $uq, $lex, $uex);
}
sub plotBox {
my ($obj, $typeary) = @_;
my $legend = $obj->{legend};
my ($i, $j, $k, $n, $x);
my @tary = ();
for ($i = 0; $i <= $#$typeary; $i++) {
next unless ($$typeary[$i] == BOX);
push @tary, $i;
}
#
# compute the height of each box based range max and min
my $boxht = ($obj->{yh} - $obj->{yl})/($i+1);
Chart/Plot.pm view on Meta::CPAN
my $showvals;
foreach (@props) {
$showvals = $1, next if /^showvalues:(\d+)/i;
$color = $_
if ($colors{$_});
}
$obj->{$color} = $obj->{img}->colorAllocate(@{$colors{$color}})
unless $obj->{$color};
$obj->addLegend($color, undef, $$legend[$k], undef)
if (($legend) && ($$legend[$k]));
#
# compute median, quartiles, and extremes
#
my ($median, $lq, $uq, $lex, $uex) = $obj->computeBox($k);
#
# compute box bounds
my $ytop = $obj->{yl} + ($boxht * ($n + 1));
my $ybot = $ytop - $boxht;
my $dumy = ($ytop + $ybot)/2;
my $py = 0;
Chart/Plot.pm view on Meta::CPAN
my $t = $obj->{props}->[$n];
$t=~s/\s+/ /g;
# $t = lc $t;
my @props = split (' ', $t);
my $color = 'black';
my $marker = undef;
my $line = 'line';
my @areacolors = ();
my $stacked = 0;
my $coloridx = 0;
my $legend;
my $lwidth = 1;
my $anchor = 1;
my $showvals = 0;
foreach (@props) {
#
# if its iconic, load the icon image
#
$marker = $1,
next
if /^icon:(\S+)/i;
Chart/Plot.pm view on Meta::CPAN
my $looplim = ($anchor ? 0 : 1);
my $ylo = $obj->{yl};
$ylo = 0 if ($ylo < 0);
for (; $j >= $looplim; $j--) {
@newary = ();
$color = $areacolors[$j-$looplim];
$i = 0;
push(@newary, $$ary[$i], ($anchor ? $ylo : $ary->[$i+1]->[0]), $ary->[$i+1]->[$j]),
$i += 2
while ($i <= $#$ary);
$legend = $obj->{legend} ? $obj->{legend}->[$n]->[$j] : undef;
return undef unless $obj->plotData($n, \@newary, $color, 'fill', $marker,
$legend, $lwidth, $anchor, $showvals);
}
next;
}
$legend = $obj->{legend} ? $obj->{legend}->[$n] : undef;
if (($line eq 'fill') && $anchor) {
#
# if its anchored, then add the origin points
#
my @newary = ();
$i = 0;
my $yl = $obj->{yl};
my $yh = $obj->{yh};
my $yaxpt = ((! $obj->{yLog}) && ($yl < 0) && ($yh > 0)) ? 0 : $yl;
push(@newary, $$ary[$i], $yaxpt, $$ary[$i+1]), $i += 2
while ($i <= $#$ary);
return undef unless $obj->plotData($n, \@newary,
$areacolors[$coloridx], $line, $marker,
$obj->{legend}->[$n], $lwidth, $anchor, $showvals);
}
else {
return undef unless $obj->plotData($n, $ary, $areacolors[$coloridx], $line, $marker,
$obj->{legend}->[$n], $lwidth, $anchor, $showvals);
}
$coloridx++;
$coloridx = 0 if ($coloridx = $#areacolors);
}
return 1;
}
# draws the specified dataset in $obj->{data}
sub plotData {
my ($obj, $k, $ary, $color, $line, $marker, $legend, $lw, $anchor, $showvals) = @_;
my ($i, $n, $px, $py, $prevpx, $prevpy, $pyt, $pyb);
my ($img, $prop, $s, $voff);
my @props = ();
# legend is left justified underneath
my ($xl, $xh, $yl, $yh) = ($obj->{xl}, $obj->{xh}, $obj->{yl},
$obj->{yh});
my ($markw, $markh, $yoff, $wdelta, $hdelta);
$img = $obj->{img};
$color = 'black' unless $color;
$obj->{$color} = $obj->{img}->colorAllocate(@{$colors{$color}})
unless $obj->{$color};
if ($marker) {
$marker = ($valid_shapes{$marker} && ($marker ne 'null')) ?
$obj->make_marker($marker, $color) :
$obj->getIcon($marker);
return undef unless $marker;
($markw, $markh) = $marker->getBounds();
$wdelta = $markw>>1;
$hdelta = $markh>>1;
}
$yoff = ($marker) ? $markh : 2;
#
# render legend if requested
#
$obj->addLegend($color, $marker, $legend, ($line eq 'line')) if $legend;
#
# line/point/area charts
#
# we need to heuristically sort data sets to optimize the view of
# overlapping areagraphs...for now the user will need to be smart
# about the order of registering the datasets
#
$obj->fill_region($obj->{$color}, $ary, $anchor)
if ($line eq 'fill');
Chart/Plot.pm view on Meta::CPAN
$voff = (length($s) * $tfw)>>1,
$obj->string($showvals,0,$px-$voff,$py-$yoff, $s, $tfw)
if $showvals;
}
return 1;
}
sub addLegend {
my ($obj, $color, $shape, $text, $line) = @_;
#
# add the dataset to the legend
#
push @{$obj->{_legends}}, [ $color, $shape, $text, $line ] ;
return 1;
}
sub drawLegend {
my ($obj) = @_;
#
# add the dataset to the legend using current color
# and shape (if any)
#
my ($color, $shape, $text, $line, $props);
my $legary = $obj->{_legends};
my $xadj = 30;
my $xoff = $obj->{horizEdge};
my $maxyoff = $obj->{height} - 40;
my $yoff = $obj->{height} - 40 - 20 - (2 * $tfh);
my ($w, $h);
while (@$legary) {
$props = shift @$legary;
($color, $shape, $text, $line) = @$props;
Chart/Plot.pm view on Meta::CPAN
my $img = $obj->{img};
my $numRanges = scalar @{$obj->{data}};
my ($xoff, $zcard) = ($obj->{zAxisLabel}) ?
(1.0, $obj->{Zcard}) : (0.9, 1);
my $xbarw = $xoff/$numRanges;
my $zbarw = ($obj->{zh} - $obj->{zl})/($zcard*2);
my ($xvals, $zvals) = ($obj->{xValues}, $obj->{zValues});
my @fronts = ();
my @tops = ();
my @sides = ();
my $legend = $obj->{legend};
my $k = 0;
my $color = 'black';
my $ary;
my $showvals;
my $ys;
my $t;
my $numPts = $#{$obj->{data}->[0]};
my @props;
my $stacked = undef;
my @barcolors = ();
Chart/Plot.pm view on Meta::CPAN
push(@barcolors, $_),
$obj->{$color} = $img->colorAllocate(@{$colors{$_}}),
push(@{$tops[$k]}, $obj->{$color}),
push(@{$fronts[$k]}, $img->colorAllocate(int($colors{$_}->[0] * 0.8),
int($colors{$_}->[1] * 0.8), int($colors{$_}->[2] * 0.8))),
push(@{$sides[$k]}, $img->colorAllocate(int($colors{$_}->[0] * 0.6),
int($colors{$_}->[1] * 0.6), int($colors{$_}->[2] * 0.6))),
if ($colors{$_});
}
if (($legend) && ($$legend[$k])) {
$obj->addLegend($color, undef, $$legend[$k], undef), next
unless $stacked;
$obj->addLegend($barcolors[$_], undef, $$legend[$k]->[$_], undef)
foreach (0..$#{$$legend[$k]});
}
}
#
# draw each bar
# WE NEED A BETTER CONTROL VALUE HERE!!! since different plots may not
# have the exact same domain!!!
#
my ($i, $j) = (0,0);
unless (($numRanges > 1) || $stacked) {
#
Chart/Plot.pm view on Meta::CPAN
=item - line graphs, areagraphs, scatter graphs, linegraphs w/ points,
candlestick graphs, barcharts (2-D, 3-D, and 3-axis), histograms,
piecharts, box & whisker charts (aka boxcharts), and Gantt charts
=item - optional iconic barcharts or datapoints
=item - a wide selection of colors, and point shapes
=item - optional horizontal and/or vertical gridlines
=item - optional legend
=item - auto-sizing of axes based in input dataset ranges
=item - optional symbolic and temproal (i.e., non-numeric) domain values
=item - automatic sorting of numeric and temporal input datasets to assure
proper order of plotting
=item - optional X, Y, and Z axis labels
Chart/Plot.pm view on Meta::CPAN
$img->setOptions (_title => 'My Graph Title',
xAxisLabel => 'my X label',
yAxisLabel => 'my Y label',
xLog => 0,
yLog => 0,
horizMargin => $numHorPixels,
vertMargin => $numvertPixels,
horizGrid => 1,
vertGrid => 1,
showValues => 1,
legend => \@plotnames,
genMap => 'a_valid_HTML_anchor_name',
mapURL => 'http://some.website.com/cgi-bin/cgi.pl',
icon => [ 'redstar.png', 'bluestar.png' ]
symDomain => 0
);
As many (or few) of the options may be specified as desired.
=item width, height
Chart/Plot.pm view on Meta::CPAN
=item title
Sets a title string to be rendered at the bottom center of the image
in bold text.
=item signature
Sets a string to be rendered in tiny font at the lower right corner of the
image, e.g., 'Copyright(C) 2001, Presicient Corp.'.
=item legend
Set to an array ref of domain names to be displayed in a legend
for the various plots.
The legend is displayed below the chart, left justified and placed
above the chart title string.
The legend for each plot is
printed in the same color as the plot. If a point shape or icon has been specified
for a plot, then the point shape is printed with the label; otherwise, a small
line segment is printed with the label. Due to space limitations,
the number of datasets plotted should be limited to 8 or less.
=item showValues
When set to a non-zero value, causes the data points for each
plotted element to be displayed next to hte plot point.
README.plot view on Meta::CPAN
DBD::Chart::Plot supports the following:
- multiple data set plots
- line graphs, areagraphs, scatter graphs, linegraphs w/ points,
candlestick graphs, barcharts (2-D, 3-D, and 3-axis), histograms,
piecharts, box & whisker charts (aka boxcharts), and Gantt charts
- optional iconic barcharts or datapoints
- a wide selection of colors, and point shapes
- optional horizontal and/or vertical gridlines
- optional legend
- auto-sizing of axes based in input dataset ranges
- optional symbolic and temproal (i.e., non-numeric) domain values
- automatic sorting of numeric and temporal input datasets to assure
proper order of plotting
- optional X, Y, and Z axis labels
- optional X and/or Y logarithmic scaling
- optional title
- optional adjustment of horizontal and vertical margins
- optional HTML or Perl imagemap generation
- composite images from multiple graphs
README.plot view on Meta::CPAN
$img->setOptions (_title => 'My Graph Title',
xAxisLabel => 'my X label',
yAxisLabel => 'my Y label',
xLog => 0,
yLog => 0,
horizMargin => $numHorPixels,
vertMargin => $numvertPixels,
horizGrid => 1,
vertGrid => 1,
showValues => 1,
legend => \@plotnames,
genMap => 'a_valid_HTML_anchor_name',
mapURL => 'http://some.website.com/cgi-bin/cgi.pl',
icon => [ 'redstar.png', 'bluestar.png' ]
symDomain => 0
);
As many (or few) of the options may be specified as desired.
width, height
The width and height of the image in pixels. Default is 400 and 300,
README.plot view on Meta::CPAN
so no zLog is supported.
title
Sets a title string to be rendered at the bottom center of the image
in bold text.
signature
Sets a string to be rendered in tiny font at the lower right corner
of the image, e.g., 'Copyright(C) 2001, Presicient Corp.'.
legend
Set to an array ref of domain names to be displayed in a legend for
the various plots. The legend is displayed below the chart, left
justified and placed above the chart title string. The legend for
each plot is printed in the same color as the plot. If a point shape
or icon has been specified for a plot, then the point shape is
printed with the label; otherwise, a small line segment is printed
with the label. Due to space limitations, the number of datasets
plotted should be limited to 8 or less.
showValues
When set to a non-zero value, causes the data points for each
plotted element to be displayed next to hte plot point.
dbdchart.html view on Meta::CPAN
<ul>
<li>piecharts, Gantt charts, quadtrees, and 3-axis barcharts/histograms must be used alone (i.e., a single graph composite).
<li>histograms are only compatible with other histograms
<li>3-d barcharts are only compatible with other 3-d barcharts
<li>all other types are compatible with one another
</ul>
<li>The domain types for the individual graphs in a composite image
must be compatible, i.e., numeric with numeric, temporal with temporal, and
symbolic with symbolic.
<li>Named derived table queries cause the specified name to be used to identify the
associated plot in any legend
generated for the composite image. If no name is given for a derived table query,
the default name "PLOTn", where n is the sequence number of the query in the image,
will be used.
<li>As of version 0.61, syntax has been modified to more closely adhere to standard SQL.
The following changes were made:
<ul>
<li>Hyphenated property names (X-LOG, Y-LOG, X-AXIS, Y-AXIS, Z-AXIS, X-ORIENT, 3-D) have
replaced the hyphen with an underscore; in addition, '3-D' has been replaced with THREE_D.
<li>Color and shape names are now treated as string values and should be quoted.
<li>The IN operator is now supported when specifying a value list for the COLOR, SHAPE,
dbdchart.html view on Meta::CPAN
<li>improved scaling for sine-point line/point graphs, barchart
<li>fix to propagate icon-related error msgs up to DBI
<li>fixed runaway recursion for quadtrees
<li>fixed divide-by-zero error on quadtrees with single intensity
<li>corrected pod SYNOPSIS section
</ul>
<p>
Release 0.72:
<ul>
<li>fixed SHOWVALUES for bars/histos when clipped origin
<li>improved legend placement
</ul>
<p>
Release 0.71:
<ul>
<li>added ANCHORED property
<li>fixed SHOWVALUES for line/point/areagraphs
<li>fixed LINEWIDTH to be a local, rather than global, property
</ul>
<p>
Release 0.70: