GD-Chart
view release on metacpan or search on metacpan
gdchart0.11.4dev/gdchart.c view on Meta::CPAN
if( xdepth || ydepth )
gdImageLine( im, x1, usd, x2, usd, clrshd );
}
/* ------------------------------------------------------------------------- */
struct BS { float y1; float y2; int clr; int shclr; };
static int barcmpr( const void *a, const void *b )
{ if( ((struct BS*)a)->y2 < ((struct BS*)b)->y2 ) return -1;
if( ((struct BS*)a)->y2 > ((struct BS*)b)->y2 ) return 1;
return 0; }
/* ------------------------------------------------------------------------- */
/* simple two-point linear interpolation */
/* attempts between first, then nearest */
void
do_interpolations( int num_points,
int interp_point,
float vals[] )
{
int i, j;
float v1 = GDC_NOVALUE,
v2 = GDC_NOVALUE;
int p1 = -1,
p2 = -1;
/* find backwards */
for( i=interp_point-1; i>=0 && p1==-1; --i )
if( vals[i] != GDC_NOVALUE && vals[i] != GDC_INTERP_VALUE )
{
v1 = vals[i];
p1 = i;
}
/* find forwards */
for( j=interp_point+1; j<num_points && p2==-1; ++j )
if( vals[j] != GDC_NOVALUE && vals[j] != GDC_INTERP_VALUE )
{
v2 = vals[j];
p2 = j;
}
/* no forward sample, find backwards */
for( ; i>=0 && p2==-1; --i )
if( vals[i] != GDC_NOVALUE && vals[i] != GDC_INTERP_VALUE )
{
v2 = vals[i];
p2 = i;
}
/* no backwards sample, find forwards */
for( ; j<num_points && p1==-1; ++j )
if( vals[j] != GDC_NOVALUE && vals[j] != GDC_INTERP_VALUE )
{
v1 = vals[j];
p1 = j;
}
if( p1==-1 || p2==-1 || /* need both */
p1 == p2 ) /* idiot */
{
vals[interp_point] = GDC_NOVALUE;
return;
}
/* Point-slope formula */
vals[interp_point] = ((v2-v1)/(float)(p2-p1)) * (float)(interp_point-p1) + v1;
return;
}
/* ========================================================================= */
/* little error checking 0: ok, */
/* -ret: error no graph output */
/* ret: error graph out */
/* watch out for # params and array sizes==num_points */
/* ------------------------------------------------------------------------- */
/* original var arg interface */
int
out_graph( short IMGWIDTH, /* no check for a image that's too small to fit */
short IMGHEIGHT, /* needed info (labels, etc), could core dump */
FILE *img_fptr, /* open file pointer (img out) */
GDC_CHART_T type,
int num_points, /* points along x axis (even iterval) */
/* all arrays dependant on this */
char *xlbl[], /* array of xlabels */
int num_sets,
... )
{
char do_hlc = ( type == GDC_HILOCLOSE ||
type == GDC_3DHILOCLOSE ||
type == GDC_3DCOMBO_HLC_BAR ||
type == GDC_3DCOMBO_HLC_AREA ||
type == GDC_COMBO_HLC_BAR ||
type == GDC_COMBO_HLC_AREA );
char do_fb = ( type == GDC_FLOATINGBAR ||
type == GDC_3DFLOATINGBAR );
char do_vol = ( type == GDC_COMBO_HLC_BAR ||
type == GDC_COMBO_HLC_AREA ||
type == GDC_COMBO_LINE_BAR ||
type == GDC_COMBO_LINE_AREA ||
type == GDC_COMBO_LINE_LINE ||
type == GDC_3DCOMBO_HLC_BAR ||
type == GDC_3DCOMBO_HLC_AREA||
type == GDC_3DCOMBO_LINE_BAR||
type == GDC_3DCOMBO_LINE_AREA ||
type == GDC_3DCOMBO_LINE_LINE );
int num_arrays = num_sets * (do_hlc? 3:
do_fb? 2: 1);
CREATE_ARRAY1( data, float, num_arrays*num_points ); /* float data[num_arrays*num_points] */
float *combo_data = (float*)NULL;
va_list ap;
int i,
rtn;
va_start( ap, num_sets );
for( i=0; i<num_arrays; ++i )
memcpy( data+i*num_points, va_arg(ap, float*), num_points*sizeof(float) );
if( do_vol )
combo_data = va_arg(ap, float*);
va_end(ap);
( run in 0.940 second using v1.01-cache-2.11-cpan-39bf76dae61 )