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 )