NAME

DBD::Chart - Perl DBI Driver interface For Rendering Charts and Graphs

SYNOPSIS


    use DBI;
    my $dbh = DBI->connect('dbi:Chart:');
        or die "Cannot connect\n";
    #
    #    example: create a pie chart
    #
    $dbh->do('CREATE TABLE pie (region CHAR(20), sales FLOAT)');
    $sth = $dbh->prepare('INSERT INTO pie VALUES( ?, ?)');
    $sth->execute('East', 2756.34);
    $sth->execute('Southeast', 3456.78);
    $sth->execute('Midwest', 1234.56);
    $sth->execute('Southwest', 4569.78);
    $sth->execute('Northwest', 33456.78);

    $rsth = $dbh->prepare(
    "SELECT PIECHART FROM pie
        WHERE WIDTH=400 AND HEIGHT=400 AND
        TITLE = \'Sales By Region\' AND 
        COLOR=(red, green, blue, lyellow, lpurple) AND
        BACKGROUND=lgray AND 
        SIGNATURE=\'Copyright(C) 2001, GOWI Systems, Inc.\'");
    $rsth->execute;
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Simple Pie Chart

    #
    # multi-range 3-D bar chart
    #
    $dbh->do('CREATE TABLE bars (quarter SMALLINT, East FLOAT, '.
    'Southeast FLOAT, Midwest FLOAT, Southwest FLOAT, Northwest FLOAT)');
    $sth = $dbh->prepare('INSERT INTO bars VALUES(?, ?, ?, ?, ?, ?)');
    $sth->execute(1, -2756.34, 3456.78, 1234.56, -4569.78, 33456.78);
    $sth->execute(2, 2756.34, 3456.78, 1234.56, 4569.78, 33456.78);
    $sth->execute(3, 2756.34, 3456.78, -1234.56, 4569.78, 33456.78);
    $sth->execute(4, 2756.34, -3456.78, 1234.56, 4569.78, 33456.78);

    $rsth = $dbh->prepare(
    "SELECT BARCHART FROM bars
    	WHERE WIDTH=600 AND HEIGHT=400 AND X-AXIS=\'Quarter\' AND
    	Y-AXIS=\'Revenue\' AND TITLE = \'Quarterly Revenue By Region\' AND
    	3-D=1 AND SHOWVALUES=1 AND COLOR=(red, green, blue, yellow, dbrown)");
    $rsth->execute;
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Bar Chart

    #
    # scatter graph
    #
    $dbh->do('CREATE CHART line (Month SMALLINT, sales FLOAT)');
    $sth = $dbh->prepare('INSERT INTO line VALUES( ?, ?)');
    $sth->execute(1, 2756.34);
    $sth->execute(2, 3456.78);
            ...insert some more rows.....
    $sth->execute(12, 90.57);

    $rsth = $dbh->prepare(
    "SELECT POINTGRAPH FROM line
        WHERE WIDTH=500 AND HEIGHT=300 AND X-AXIS=\'Sales\' AND
        TITLE = \'Sales By Region\' AND COLOR=black AND SHOWGRID=0 AND
        SHAPE=filldiamond AND SHOWVALUES=1");
    $rsth->execute;
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Scatter Graph

    #
    # multi-range line w/ points, bkground image, and signature
    #
    $dbh->do('DROP CHART line');
    $dbh->do('CREATE CHART line (Month SMALLINT, East FLOAT, ' .
    'Southeast float, Midwest float, Southwest float, Northwest float)');
    $sth = $dbh->prepare('INSERT INTO line VALUES( ?, ?, ?, ?, ?, ?)');
    $sth->execute(1, 2756.34, 3456.90, 1234.99, 1005.34, 2876.34);
    $sth->execute(2, 3456.78, undef, 4321.25, 9001.34, 997.68);
            ...insert some more rows.....
    $sth->execute(12, 90.57,3456.90, 1234.99, undef, 2876.34);

    $rsth = $dbh->prepare(
    "SELECT LINEGRAPH FROM line
        WHERE WIDTH=? AND HEIGHT=? AND X-AXIS=? AND Y-AXIS=? AND
        TITLE = \'Monthly Sales By Region\' AND 
        COLOR=(red, green, blue, yellow, lbrown) AND
        SHOWPOINTS=1 AND SHOWGRID=1 AND 
        SHAPE=(fillcircle, fillsquare, filldiamond, horizcross, diagcross) AND
        LOGO=\'gowilogo.png\' AND BACKGROUND=lgray AND 
        X-ORIENT=\'VERTICAL\' AND 
        SIGNATURE=\'Copyright(C) 2001, GOWI Systems, Inc.\'");
    $rsth->execute(400, 400, 'Month', 'Sales');
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Multiline Graph

    $dbh->do('CREATE CHART line (Month SMALLINT, East FLOAT, ' .
    'Southeast float, Midwest float, Southwest float, Northwest float)');
    $sth = $dbh->prepare('INSERT INTO line VALUES( ?, ?, ?, ?, ?, ?)');

    @month = (1,2,3,4,5,6,7,8,9,10,11,12);
    @east = ( 2756.34, 3456.90, 1234.99, 1005.34, 2876.34, 3456.78, undef, 
    	4321.25, 9001.34, 997.68, 1234.56, 7783.20);
    @seast = ( 5321.11, 3333.33, 876.10, 4569.78, 4326.3,  -7895.44, 4444.44, 
    	12345.29, 3456.78, 12094.5, 6666.66, 3322.11);
    @midwest = ( 9090.90, 908.57, -2367.4, 3399.55, 5555.55, 887.3, 756.34, 
    	1111.11, 2222.22, 8888.88, 9456.3, undef);
    @swest = ( 7783.20, 5321.11, 3333.33, 876.10, 12349.56, 12094.5, 6666.66,
    	3322.11, 9090.90, 4569.78, 3456.99, 4321.25);
    @nwest = ( 9001.34, 997.68, 13456.78, 2367.4, 3399.55, 5555.55, 887.3,
    	90.57, 3456.90, 1234.99, undef, 2876.34);
	
    $sth->func(1, \@month, chart_bind_param_array);
    $sth->func(2, \@east, chart_bind_param_array);
    $sth->func(3, \@seast, chart_bind_param_array);
    $sth->func(4, \@midwest, chart_bind_param_array);
    $sth->func(5, \@swest, chart_bind_param_array);
    $sth->func(6, \@nwest, chart_bind_param_array);

    %stsary = ();
    $sth->func(\%stsary, chart_bind_param_status);

    $sth->execute;

    $rsth = $dbh->prepare(
    "SELECT AREAGRAPH FROM line
        WHERE WIDTH=400 AND HEIGHT=400 AND X-AXIS=\'Month\' AND
        Y-AXIS=\'Sales\' AND TITLE = \'Monthly Sales By Region\' AND
        COLOR=(red, green, blue, yellow, lbrown) AND
        SHOWPOINTS=1 AND SHOWGRID=1 AND
        SHAPE=(fillcircle, fillsquare, filldiamond, horizcross, diagcross)");
    $rsth->execute;
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Area Graph

    #
    # log-log line graph
    #
    $dbh->do('CREATE CHART line (Month FLOAT, sales FLOAT)');
    $sth = $dbh->prepare('INSERT INTO line VALUES( ?, ?)');
    for ($i = -3; $i < 13; $i++) {
	    $sth->execute(5**$i, exp($i));
    }

    $rsth = $dbh->prepare(
    "SELECT LINEGRAPH FROM line
        WHERE WIDTH=450 AND HEIGHT=450 AND X-AXIS=\'5**X\' AND 
        Y-AXIS=\'e**X\' AND Y-LOG=1 AND X-LOG=1 AND 
        SHOWVALUES=0 AND TITLE = \'Sample Log-Log Linegraph\' AND
        COLOR=lred AND SHOWGRID=1 AND SHOWPOINTS=1");
    $rsth->execute;
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Log-Log Graph

    #
    # simple candle graph, directly from another statement handle
    #
    $tddbh = DBI->connect('dbi:Teradata:dbc', 'dbitst', 'dbitst',
        { PrintError => 1, RaiseError => 0, AutoCommit => 1 });
    $tdsth = $tddbh->prepare(
    "SELECT TradeDay(VARCHAR(18)), lowprice, highprice
        FROM candle ORDER BY TradeDay");
    $tdsth->execute;

    $rsth = $dbh->prepare(
    "SELECT CANDLESTICK FROM ?
        WHERE WIDTH=? AND HEIGHT=? AND X-AXIS=? AND Y-AXIS=? AND
        TITLE = \'Daily Price Range\' AND COLOR=red AND SHOWGRID=1 AND
        SHAPE=filldiamond AND SHOWPOINTS=1 AND SHOWVALUES=0");
    $rsth->execute($tdsth, 300,400, 'Date', 'Price');
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Candlestick Graph

    #
    #	use same data to render linegraph with symbolic domain
    #
    $tdsth->execute;
    
    $rsth = $dbh->prepare(
    "SELECT LINEGRAPH FROM ?
        WHERE WIDTH=400 AND HEIGHT=400 AND X-AXIS=\'Date\' AND
        Y-AXIS=\'Price\' AND TITLE = \'Daily Price Range\' AND
        COLOR=(red, blue) AND SHOWGRID=1 AND
        SHAPE=(filldiamond, fillsquare) AND SHOWPOINTS=1");

    $rsth->execute($tdsth);
    $rsth->bind_col(1, \$buf);
    $rsth->fetch;

produces the image

Non-numeric Graph

DESCRIPTION

DBI driver abstraction for rendering pie charts, bar charts, line, point, area, and candlestick graphs. The default output format is PNG; JPEG and GIF format can be generated by setting the FORMAT property (see below), assuming the appropriate supporting libraries and modules are installed.
BE ADVISED: This is BETA software, and subject to change at the whim of the author(s).

Why DBD::Chart ? Basically, the idea is to make chart rendering easy for us database geeks...and maybe for other folks, as well. Being able to render a chart from a rowset by simply binding output column buffers as input parameter buffers for a simple INSERT, then just SELECT'ing to get the image, seemed like a nice abstraction.

BTW: This driver is 100% pure Perl.

CURRENT VERSION

Release 0.43

ZIP version
.tar.gz version

CHANGE HISTORY

Release 0.43:

Release 0.42: Release 0.41: Release 0.40:

Release 0.30:

Release 0.20:

Release 0.10:

DRIVER-SPECIFIC BEHAVIOR

DATA-SOURCE NAME

The dsn string passed to DBI->connect() is simply 'dbi:Chart:'. No username or password is required.

DATA TYPES

Range (i.e., Y-axis) values must be defined as numbers. INTEGER, FLOAT, SMALLINT, TINYINT, and DECIMAL are all acceptable number types. Domain (i.e., X-axis) values may be either numeric or non-numeric (including CHAR, VARCHAR, DATE, TIME, TIMESTAMP, etc.). A non-numeric (i.e., "symbolic") domain will result in a uniformly distributed mapping of values to the X-axis. For pie and barcharts, and candlestick graphs, all domain types are treated as symbolic; for all other graph types, a numeric domain will be mapped using the actual (scaled) numeric values.

Date, Time, and Timestamp Types

Obviously, handling these data types is important for temporal graphs. For now, however, we just treat them as symbolic values, the same as CHAR or VARCHAR.

SQL DIALECT

DBD::Chart uses a small subset of SQL to create, populate, render, and discard chart data:

ERROR HANDLING

Any errors generated from improper SQL usage are flagged with an error value of -1, and appropriate text in the errstr. Errors emanating from the GD::Graph or DBD::Chart::Plot modules will be flagged in err and errstr with whatever info is returned by those modules.

DIAGNOSTICS

DBI provides the trace() function to enable various levels of trace information. DBD::Chart currently doesn't add any traces to this.

DRIVER-SPECIFIC ATTRIBUTES

DRIVER-SPECIFIC FUNCTIONS

The following functions are provided to optimize data movement:
Note:generalized versions of these functions are currently under consideration for addition to the DBI specification.

Note: array binding of output values is not supported, since SELECT only returns a single value at a time, namely, the chart image.

PREREQUISITES AND CONFORMANCE

DBD::Chart requires the following (versions are recommended only, cuz they're the version I built with...if you're feeling frisky, you can try older or newer versions.):

Be advised that these modules require the following (non-Perl) libraries:

The following DBI functions are not supported:

DBI->data_sources()
$dbh->prepare_cached()
$sth->table_info()
$dbh->tables()
$dbh->type_info_all()
$dbh->type_info()

KNOWN BUGS

Bug Number Report
Date
Release
Reported in
Description Status Fix
Release
1 2001-Mar-16 0.20 SQL statements with newlines won't prepare() Fixed 0.30
2 2001-May-09 0.30 INTEGER column definition as last column in CREATE TABLE causes an error Fixed 0.40
3 2001-May-09 0.30 FORMAT property not properly handled as string property Fixed 0.40
4 2001-Jun-01 0.40 Y-axis ticks not properly aligned when grid disabled Fixed 0.41
5 2001-Jun-01 0.40 INSERT of string literal value kept quote mark Fixed 0.41
6 2001-Jun-01 0.40 INSERT of string literal used bad column index variable Fixed 0.41
7 2001-Oct-01 0.41 X-ORIENT='HORIZONTAL' didn't work with symbolic domains, candlesticks Fixed 0.42

TO DO List

ACKNOWLEDGEMENTS

Many thanks to all the authors of the various GD, PNG,JPEG, and zlib modules. Special thanks to all the initial victims, er, users for their comments, complaints, and suggestions.

Special thanks to Peter Scott for the GIF support and a few other fixes!

REFERENCES

AUTHOR

Dean Arnold

COPYRIGHT

Copyright (c) 2001, Dean Arnold, USA
Affiliations:

Permission is granted to use this software according to the terms of the GNU General Public License. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Please note that this license prohibits the incorporation of the source code of this product in publicly distributed, but proprietary products (e.g., something you're trying to sell, as opposed to selling support for). However, proprietary products may invoke DBD::Chart.

I'm offering the software AS IS, and ACCEPT NO LIABILITY FOR ANY ERRORS OR OMMISSIONS IN, OR LOSSES INCURRED AS A RESULT OF USING DBD::Chart.

I reserve the right to provide support for this software to individual sites under a separate (possibly fee-based) agreement.

Last updated October 11, 2001