00001
00002
00003
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <values.h>
00007 #include <math.h>
00008 #include <string.h>
00009 #include <stdarg.h>
00010 #include <errno.h>
00011
00012 #define GDC_INCL
00013 #define GDC_LIB
00014 #include "gdc.h"
00015 #include "gdchart.h"
00016
00017
00018 #define HIGHSET 0
00019 #define LOWSET 1
00020 #define CLOSESET 2
00021
00022
00023 #define PX( x ) (int)( xorig + (setno*xdepth_3D) + (x)*xscl )
00024 #define PY( y ) (int)( yorig - (setno*ydepth_3D) + (y)*yscl )
00025 #define PV( y ) (int)( vyorig - (setno*ydepth_3D) + (y)*vyscl )
00026
00027 #define SET_RECT( gdp, x1, x2, y1, y2 ) gdp[0].x = gdp[3].x = x1, \
00028 gdp[0].y = gdp[1].y = y1, \
00029 gdp[1].x = gdp[2].x = x2, \
00030 gdp[2].y = gdp[3].y = y2
00031
00032
00033 #define EXTERND
00034 EXTERND char *GDC_ytitle;
00035 EXTERND char *GDC_xtitle;
00036 EXTERND char *GDC_ytitle2;
00037 EXTERND char *GDC_title;
00038
00039 #define EXTERND extern
00040 EXTERND enum GDC_font_size GDC_title_size DEFAULTO( GDC_MEDBOLD );
00041 EXTERND enum GDC_font_size GDC_ytitle_size DEFAULTO( GDC_MEDBOLD );
00042 EXTERND enum GDC_font_size GDC_xtitle_size DEFAULTO( GDC_MEDBOLD );
00043 EXTERND enum GDC_font_size GDC_yaxisfont_size DEFAULTO( GDC_SMALL );
00044 EXTERND enum GDC_font_size GDC_xaxisfont_size DEFAULTO( GDC_SMALL );
00045 EXTERND char *GDC_ylabel_fmt DEFAULTO( NULL );
00046 EXTERND char *GDC_ylabel2_fmt DEFAULTO( NULL );
00047 EXTERND short GDC_xlabel_spacing DEFAULTO( 5 );
00048 EXTERND char GDC_ylabel_density DEFAULTO( 80 );
00049 EXTERND float GDC_requested_ymin DEFAULTO( GDC_NOVALUE );
00050 EXTERND float GDC_requested_ymax DEFAULTO( GDC_NOVALUE );
00051 EXTERND float GDC_requested_yinterval DEFAULTO( GDC_NOVALUE );
00052 EXTERND char GDC_0Shelf DEFAULTO( TRUE );
00053 EXTERND char GDC_grid DEFAULTO( TRUE );
00054 EXTERND char GDC_xaxis DEFAULTO( TRUE );
00055 EXTERND char GDC_yaxis DEFAULTO( TRUE );
00056 EXTERND char GDC_yaxis2 DEFAULTO( TRUE );
00057 EXTERND char GDC_yval_style DEFAULTO( TRUE );
00058 EXTERND GDC_STACK_T GDC_stack_type DEFAULTO( GDC_STACK_DEPTH );
00059 EXTERND float GDC_3d_depth DEFAULTO( 5.0 );
00060 EXTERND unsigned char GDC_3d_angle DEFAULTO( 45 );
00061 EXTERND unsigned char GDC_bar_width DEFAULTO( 75 );
00062 EXTERND GDC_HLC_STYLE_T GDC_HLC_style DEFAULTO( GDC_HLC_CLOSE_CONNECTED );
00063 EXTERND unsigned char GDC_HLC_cap_width DEFAULTO( 25 );
00064 EXTERND GDC_ANNOTATION_T *GDC_annotation DEFAULTO( (GDC_ANNOTATION_T*)NULL );
00065 EXTERND enum GDC_font_size GDC_annotation_font DEFAULTO( GDC_SMALL );
00066 EXTERND int GDC_num_scatter_pts DEFAULTO( 0 );
00067 EXTERND GDC_SCATTER_T *GDC_scatter DEFAULTO( (GDC_SCATTER_T*)NULL );
00068 EXTERND char GDC_thumbnail DEFAULTO( FALSE );
00069 EXTERND char *GDC_thumblabel;
00070 EXTERND float GDC_thumbval DEFAULTO( -MAXFLOAT );
00071 EXTERND char GDC_border DEFAULTO( TRUE );
00072 EXTERND unsigned long GDC_BGColor DEFAULTO( 0x000000L );
00073 EXTERND unsigned long GDC_GridColor DEFAULTO( 0xA0A0A0L );
00074 EXTERND unsigned long GDC_LineColor DEFAULTO( GDC_DFLTCOLOR );
00075 EXTERND unsigned long GDC_PlotColor DEFAULTO( GDC_DFLTCOLOR );
00076 EXTERND unsigned long GDC_VolColor DEFAULTO( 0xA0A0FFL );
00077 EXTERND unsigned long GDC_TitleColor DEFAULTO( GDC_DFLTCOLOR );
00078 EXTERND unsigned long GDC_XTitleColor DEFAULTO( GDC_DFLTCOLOR );
00079 EXTERND unsigned long GDC_YTitleColor DEFAULTO( GDC_DFLTCOLOR );
00080 EXTERND unsigned long GDC_YTitle2Color DEFAULTO( GDC_DFLTCOLOR );
00081 EXTERND unsigned long GDC_XLabelColor DEFAULTO( GDC_DFLTCOLOR );
00082 EXTERND unsigned long GDC_YLabelColor DEFAULTO( GDC_DFLTCOLOR );
00083 EXTERND unsigned long GDC_YLabel2Color DEFAULTO( GDC_DFLTCOLOR );
00084
00085 EXTERND unsigned long *GDC_ExtVolColor DEFAULTO( (unsigned long*)NULL );
00086
00087 EXTERND unsigned long *GDC_SetColor DEFAULTO( (unsigned long*)NULL );
00088
00089 EXTERND unsigned long *GDC_ExtColor DEFAULTO( (unsigned long*)NULL );
00090 EXTERND char GDC_transparent_bg DEFAULTO( FALSE );
00091 EXTERND char *GDC_BGImage DEFAULTO( (char*)NULL );
00092
00093
00094
00095
00096
00097
00098 EXTERND char GDC_hard_size DEFAULTO( FALSE );
00099 EXTERND int GDC_hard_xorig DEFAULTO( 0 );
00100 EXTERND int GDC_hard_graphwidth DEFAULTO( 0 );
00101 EXTERND int GDC_hard_yorig DEFAULTO( 0 );
00102 EXTERND int GDC_hard_grapheight DEFAULTO( 0 );
00103
00104 #ifdef THUMB_VALS
00105
00106
00107
00108
00109 void
00110 smallarrow( gdImagePtr im,
00111 int x,
00112 int y,
00113 char up,
00114 int arrwclr )
00115 {
00116 gdImageLine( im, x+2, y, x+2, y+GDC_fontc[GDC_SMALL].h, arrwclr );
00117 gdImageLine( im, x+3, y, x+3, y+GDC_fontc[GDC_SMALL].h, arrwclr );
00118 if( up )
00119 {
00120 gdImageSetPixel( im, x, y+2, arrwclr );
00121 gdImageSetPixel( im, x+1, y+2, arrwclr );
00122 gdImageSetPixel( im, x+4, y+2, arrwclr );
00123 gdImageSetPixel( im, x+5, y+2, arrwclr );
00124 gdImageSetPixel( im, x+1, y+1, arrwclr );
00125 gdImageSetPixel( im, x+4, y+1, arrwclr );
00126 }
00127 else
00128 {
00129 gdImageSetPixel( im, x, y+(GDC_fontc[GDC_SMALL].h-2), arrwclr );
00130 gdImageSetPixel( im, x+1, y+(GDC_fontc[GDC_SMALL].h-2), arrwclr );
00131 gdImageSetPixel( im, x+4, y+(GDC_fontc[GDC_SMALL].h-2), arrwclr );
00132 gdImageSetPixel( im, x+5, y+(GDC_fontc[GDC_SMALL].h-2), arrwclr );
00133 gdImageSetPixel( im, x+1, y+(GDC_fontc[GDC_SMALL].h-1), arrwclr );
00134 gdImageSetPixel( im, x+4, y+(GDC_fontc[GDC_SMALL].h-1), arrwclr );
00135 }
00136 }
00137 #endif
00138
00139
00140 #define SET_3D_POLY( gdp, x1, x2, y1, y2, xoff, yoff ) \
00141 gdp[0].x = x1, gdp[0].y = y1, \
00142 gdp[1].x = x1+(xoff), gdp[1].y = y1-yoff, \
00143 gdp[2].x = x2+(xoff), gdp[2].y = y2-yoff, \
00144 gdp[3].x = x2, gdp[3].y = y2
00145
00146
00147
00148
00149
00150 struct YS { int y1; int y2; float slope; int lnclr; int shclr; };
00151 static int qcmpr( const void *a, const void *b )
00152 { if( ((struct YS*)a)->y2 < ((struct YS*)b)->y2 ) return 1;
00153 if( ((struct YS*)a)->y2 > ((struct YS*)b)->y2 ) return -1;
00154 return 0; }
00155 void
00156 draw_3d_line( gdImagePtr im,
00157 int y0,
00158 int x1,
00159 int x2,
00160 int y1[],
00161 int y2[],
00162 int xdepth,
00163 int ydepth,
00164 int num_sets,
00165 int clr[],
00166 int clrshd[] )
00167 {
00168 #define F(x,i) (int)( (float)((x)-x1)*slope[i]+(float)y1[i] )
00169 float depth_slope = xdepth==0? MAXFLOAT: (float)ydepth/(float)xdepth;
00170 #ifdef WIN32
00171 float slope[1000];
00172 int lnclr[1000],
00173 shclr[1000];
00174 #else
00175 float slope[num_sets];
00176 int lnclr[num_sets],
00177 shclr[num_sets];
00178
00179 #endif
00180 int i;
00181 int x;
00182 gdPoint poly[4];
00183
00184 #ifdef WIN32
00185 struct YS ypts[1000];
00186 #else
00187 struct YS ypts[num_sets];
00188 #endif
00189
00190 for( i=0; i<num_sets; ++i )
00191 {
00192
00193
00194 slope[i] = x2==x1? MAXFLOAT: (float)(y2[i]-y1[i])/(float)(x2-x1);
00195 }
00196
00197 for( x=x1+1; x<=x2; ++x )
00198 {
00199 for( i=0; i<num_sets; ++i )
00200 {
00201 ypts[i].y1 = F(x-1,i);
00202 ypts[i].y2 = F(x,i);
00203 ypts[i].lnclr = clr[i];
00204 ypts[i].shclr = clrshd[i];
00205 ypts[i].slope = slope[i];
00206 }
00207 qsort( ypts, num_sets, sizeof(struct YS), qcmpr );
00208
00209 for( i=0; i<num_sets; ++i )
00210 {
00211 SET_3D_POLY( poly, x-1, x, ypts[i].y1, ypts[i].y2, xdepth, ydepth );
00212 gdImageFilledPolygon( im, poly, 4,
00213 -ypts[i].slope>depth_slope? ypts[i].shclr: ypts[i].lnclr );
00214 if( x == x1+1 )
00215 gdImageLine( im,
00216 x-1, ypts[i].y2,
00217 x-1+xdepth, ypts[i].y2-ydepth,
00218 -ypts[i].slope<=depth_slope? ypts[i].shclr: ypts[i].lnclr );
00219 }
00220 }
00221 }
00222
00223
00224
00225
00226 void
00227 draw_3d_area( gdImagePtr im,
00228 int x1,
00229 int x2,
00230 int y0,
00231 int y1,
00232 int y2,
00233 int xdepth,
00234 int ydepth,
00235 int clr,
00236 int clrshd )
00237 {
00238
00239 gdPoint poly[4];
00240 int y_intercept = 0;
00241
00242 if( xdepth || ydepth )
00243 {
00244 float line_slope = x2==x1? MAXFLOAT: (float)-(y2-y1) / (float)(x2-x1);
00245 float depth_slope = xdepth==0? MAXFLOAT: (float)ydepth/(float)xdepth;
00246
00247 y_intercept = (y1 > y0 && y2 < y0) ||
00248 (y1 < y0 && y2 > y0)?
00249 (int)((1.0/ABS(line_slope))*(float)(ABS(y1-y0)))+x1:
00250 0;
00251
00252
00253 gdImageLine( im, x1+xdepth, y0-ydepth, x2+xdepth, y0-ydepth, clrshd );
00254
00255 SET_3D_POLY( poly, x1, x2, y1, y2, xdepth, ydepth );
00256 gdImageFilledPolygon( im, poly, 4, line_slope>depth_slope? clrshd: clr );
00257
00258 SET_3D_POLY( poly, x1, x2, y0, y0, xdepth, ydepth+1 );
00259 gdImageFilledPolygon( im, poly, 4, clr );
00260
00261 SET_3D_POLY( poly, x2, x2, y0, y2, xdepth, ydepth );
00262 gdImageFilledPolygon( im, poly, 4, clrshd );
00263
00264 if( y_intercept )
00265 gdImageLine( im, y_intercept, y0,
00266 y_intercept+xdepth, y0-ydepth, clrshd );
00267 gdImageLine( im, x1, y0, x1+xdepth, y0-ydepth, clrshd );
00268 gdImageLine( im, x2, y0, x2+xdepth, y0-ydepth, clrshd );
00269
00270
00271
00272
00273 gdImageLine( im, x1, y1, x1+xdepth, y1-ydepth, clrshd );
00274 gdImageLine( im, x2, y2, x2+xdepth, y2-ydepth, clrshd );
00275 }
00276
00277 if( y1 == y2 )
00278 SET_RECT( poly, x1, x2, y0, y1 );
00279 else
00280 {
00281 poly[0].x = x1; poly[0].y = y0;
00282 poly[1].x = x2; poly[1].y = y0;
00283 poly[2].x = x2; poly[2].y = y2;
00284 poly[3].x = x1; poly[3].y = y1;
00285 }
00286 gdImageFilledPolygon( im, poly, 4, clr );
00287
00288 gdImageLine( im, x1, y0, x2, y0, clrshd );
00289
00290 if( (xdepth || ydepth) &&
00291 (y1<y0 || y2<y0) )
00292 {
00293 if( y1 > y0 && y2 < y0 )
00294 gdImageLine( im, y_intercept, y0, x2, y2, clrshd );
00295 else
00296 if( y1 < y0 && y2 > y0 )
00297 gdImageLine( im, x1, y1, y_intercept, y0, clrshd );
00298 else
00299 gdImageLine( im, x1, y1, x2, y2, clrshd );
00300 }
00301 }
00302
00303
00304
00305
00306 void
00307 draw_3d_bar( gdImagePtr im,
00308 int x1,
00309 int x2,
00310 int y0,
00311 int yhigh,
00312 int xdepth,
00313 int ydepth,
00314 int clr,
00315 int clrshd )
00316 {
00317 #define SET_3D_BAR( gdp, x1, x2, y1, y2, xoff, yoff ) \
00318 gdp[0].x = x1, gdp[0].y = y1, \
00319 gdp[1].x = x1+(xoff), gdp[1].y = y1-yoff, \
00320 gdp[2].x = x2+(xoff), gdp[2].y = y2-yoff, \
00321 gdp[3].x = x2, gdp[3].y = y2
00322
00323 gdPoint poly[4];
00324 int usd = MIN( y0, yhigh );
00325
00326
00327 if( xdepth || ydepth )
00328 {
00329 if( y0 != yhigh )
00330 {
00331 SET_3D_BAR( poly, x2, x2, y0, yhigh, xdepth, ydepth );
00332 gdImageFilledPolygon( im, poly, 4, clrshd );
00333 }
00334
00335 SET_3D_BAR( poly, x1, x2, usd, usd, xdepth, ydepth );
00336 gdImageFilledPolygon( im, poly, 4, clr );
00337 }
00338
00339 SET_RECT( poly, x1, x2, y0, yhigh );
00340 gdImageFilledPolygon( im, poly, 4, clr );
00341
00342 if( xdepth || ydepth )
00343 gdImageLine( im, x1, usd, x2, usd, clrshd );
00344 }
00345
00346
00347 struct BS { float y1; float y2; int clr; int shclr; };
00348 static int barcmpr( const void *a, const void *b )
00349 { if( ((struct BS*)a)->y2 < ((struct BS*)b)->y2 ) return -1;
00350 if( ((struct BS*)a)->y2 > ((struct BS*)b)->y2 ) return 1;
00351 return 0; }
00352
00353
00354
00355
00356
00357
00358 int
00359 out_graph( short GIFWIDTH,
00360 short GIFHEIGHT,
00361 FILE *gif_fptr,
00362 GDC_CHART_T type,
00363 int num_points,
00364
00365 char *xlbl[],
00366 int num_sets,
00367 ... )
00368 {
00369 #ifndef WIN32
00370 va_list ap;
00371 int i, j, k;
00372
00373 int graphwidth;
00374 int grapheight;
00375 gdImagePtr im;
00376 gdImagePtr bg_img = NULL;
00377
00378 float xorig, yorig, vyorig;
00379 float yscl = 0.0;
00380 float vyscl = 0.0;
00381 float xscl = 0.0;
00382 float vhighest = -MAXFLOAT;
00383 float vlowest = MAXFLOAT;
00384 float highest = -MAXFLOAT;
00385 float lowest = MAXFLOAT;
00386 gdPoint volpoly[4];
00387
00388 char do_vol = ( type == GDC_COMBO_HLC_BAR ||
00389 type == GDC_COMBO_HLC_AREA ||
00390 type == GDC_COMBO_LINE_BAR ||
00391 type == GDC_COMBO_LINE_AREA ||
00392 type == GDC_3DCOMBO_HLC_BAR ||
00393 type == GDC_3DCOMBO_HLC_AREA||
00394 type == GDC_3DCOMBO_LINE_BAR||
00395 type == GDC_3DCOMBO_LINE_AREA );
00396 char threeD = ( type == GDC_3DAREA ||
00397 type == GDC_3DLINE ||
00398 type == GDC_3DBAR ||
00399 type == GDC_3DHILOCLOSE ||
00400 type == GDC_3DCOMBO_HLC_BAR ||
00401 type == GDC_3DCOMBO_HLC_AREA||
00402 type == GDC_3DCOMBO_LINE_BAR||
00403 type == GDC_3DCOMBO_LINE_AREA );
00404 char num_hlc_sets =
00405 ( type == GDC_COMBO_HLC_BAR ||
00406 type == GDC_COMBO_HLC_AREA ||
00407 type == GDC_3DCOMBO_HLC_BAR ||
00408 type == GDC_3DCOMBO_HLC_AREA||
00409 type == GDC_3DHILOCLOSE ||
00410 type == GDC_HILOCLOSE )? num_sets: 0;
00411 char do_bar = ( type == GDC_3DBAR ||
00412 type == GDC_BAR );
00413
00414 char do_ylbl_fractions =
00415 ( !GDC_ylabel_fmt ||
00416 strlen(GDC_ylabel_fmt) == strcspn(GDC_ylabel_fmt,"%geEfF") );
00417 float ylbl_interval = 0.0;
00418 int num_lf_xlbls = 0;
00419 int xdepth_3Dtotal = 0;
00420 int ydepth_3Dtotal = 0;
00421 int xdepth_3D = 0;
00422 int ydepth_3D = 0;
00423 int hlf_barwdth = 0;
00424 int hlf_hlccapwdth = 0;
00425 int annote_len = 0,
00426 annote_hgt = 0;
00427
00428
00429 int setno = 0;
00430
00431 #ifdef WIN32
00432 float *uvals[1000];
00433 #else
00434 float *uvals[ type == GDC_HILOCLOSE ||
00435 type == GDC_3DHILOCLOSE ||
00436 type == GDC_3DCOMBO_HLC_BAR ||
00437 type == GDC_3DCOMBO_HLC_AREA ||
00438 type == GDC_COMBO_HLC_BAR ||
00439 type == GDC_COMBO_HLC_AREA? num_sets *= 3:
00440 type == GDC_COMBO_LINE_BAR ||
00441 type == GDC_3DCOMBO_LINE_BAR ||
00442 type == GDC_3DCOMBO_LINE_AREA||
00443 type == GDC_COMBO_LINE_AREA? num_sets:
00444 num_sets ];
00445 #endif
00446 float *uvol;
00447
00448 int BGColor,
00449 LineColor,
00450 PlotColor,
00451 GridColor,
00452 VolColor,
00453 ExtVolColor[num_points],
00454 ThumbDColor,
00455 ThumbLblColor,
00456 ThumbUColor,
00457
00458
00459 AnnoteColor,
00460 ExtColor[num_sets][num_points];
00461
00462
00463 int ExtColorShd[num_sets][num_points];
00464
00465
00466 if( GIFWIDTH<=0 || GIFHEIGHT<=0 || (!gif_fptr && GDC_generate_gif) )
00467 return -1;
00468 if( num_points <= 0 )
00469 {
00470 out_err( GIFWIDTH, GIFHEIGHT, gif_fptr, GDC_BGColor, GDC_LineColor, "No Data Available" );
00471 return 1;
00472 }
00473
00474 load_font_conversions();
00475 if( GDC_thumbnail )
00476 {
00477 GDC_grid = FALSE;
00478 GDC_xaxis = FALSE;
00479 GDC_yaxis = FALSE;
00480 }
00481
00482
00483 va_start( ap, num_sets );
00484 for( i=0; i<num_sets; ++i )
00485 uvals[i] = va_arg(ap, float*);
00486 if( do_vol )
00487 uvol = va_arg(ap, float*);
00488 va_end(ap);
00489
00490
00491 if( GDC_stack_type == GDC_STACK_SUM )
00492 for( j=0; j<num_points; ++j )
00493 {
00494 float set_sum = 0.0;
00495 for( i=0; i<num_sets; ++i )
00496 if( uvals[i][j] != GDC_NOVALUE )
00497 {
00498 set_sum += uvals[i][j];
00499 highest = MAX( highest, set_sum );
00500 lowest = MIN( lowest, set_sum );
00501 }
00502 }
00503 else
00504 if( GDC_stack_type == GDC_STACK_LAYER )
00505 for( j=0; j<num_points; ++j )
00506 {
00507 float neg_set_sum = 0.0,
00508 pos_set_sum = 0.0;
00509 for( i=0; i<num_sets; ++i )
00510 if( uvals[i][j] != GDC_NOVALUE )
00511 if( uvals[i][j] < 0.0 )
00512 neg_set_sum += uvals[i][j];
00513 else
00514 pos_set_sum += uvals[i][j];
00515 lowest = MIN( lowest, MIN(neg_set_sum,pos_set_sum) );
00516 highest = MAX( highest, MAX(neg_set_sum,pos_set_sum) );
00517 }
00518 else
00519 for( i=0; i<num_sets; ++i )
00520 for( j=0; j<num_points; ++j )
00521 if( uvals[i][j] != GDC_NOVALUE )
00522 {
00523 highest = MAX( uvals[i][j], highest );
00524 lowest = MIN( uvals[i][j], lowest );
00525 }
00526 if( GDC_scatter )
00527 for( i=0; i<GDC_num_scatter_pts; ++i )
00528 {
00529 highest = MAX( (GDC_scatter+i)->val, highest );
00530 lowest = MIN( (GDC_scatter+i)->val, lowest );
00531 }
00532 if( do_vol )
00533 {
00534
00535
00536 for( j=0; j<num_points; ++j )
00537 if( uvol[j] != GDC_NOVALUE )
00538 {
00539 vhighest = MAX( uvol[j], vhighest );
00540 vlowest = MIN( uvol[j], vlowest );
00541 }
00542 if( vhighest == -MAXFLOAT )
00543 vhighest = 1.0;
00544 else
00545 if( vhighest < 0.0 )
00546 vhighest = 0.0;
00547 if( vlowest > 0.0 || vlowest == MAXFLOAT )
00548 vlowest = 0.0;
00549 }
00550
00551 if( lowest == MAXFLOAT )
00552 lowest = 0.0;
00553 if( highest == -MAXFLOAT )
00554 highest = 1.0;
00555 if( type == GDC_AREA ||
00556 type == GDC_BAR ||
00557 type == GDC_3DBAR ||
00558 type == GDC_3DAREA )
00559 if( highest < 0.0 )
00560 highest = 0.0;
00561 else
00562 if( lowest > 0.0 )
00563 lowest = 0.0;
00564
00565 if( GDC_requested_ymin != GDC_NOVALUE && GDC_requested_ymin < lowest )
00566 lowest = GDC_requested_ymin;
00567 if( GDC_requested_ymax != GDC_NOVALUE && GDC_requested_ymax > highest )
00568 highest = GDC_requested_ymax;
00569
00570
00571
00572
00573 {
00574 int title_hgt = GDC_title? 2
00575 + cnt_nl(GDC_title,(int*)NULL)*GDC_fontc[GDC_title_size].h
00576 + 2:
00577 2;
00578 int xlabel_hgt = 0;
00579 int xtitle_hgt = GDC_xtitle? 1+GDC_fontc[GDC_xtitle_size].h+1: 0;
00580 int ytitle_hgt = GDC_ytitle? 1+GDC_fontc[GDC_ytitle_size].h+1: 0;
00581 int vtitle_hgt = do_vol&&GDC_ytitle2? 1+GDC_fontc[GDC_ytitle_size].h+1: 0;
00582 int ylabel_wth = 0;
00583 int vlabel_wth = 0;
00584
00585 int xtics = GDC_grid||GDC_xaxis? 1+2: 0;
00586 int ytics = GDC_grid||GDC_yaxis? 1+3: 0;
00587 int vtics = GDC_yaxis&&do_vol? 3+1: 0;
00588
00589
00590 #define HYP_DEPTH ( (double)((GIFWIDTH+GIFHEIGHT)/2) * ((double)GDC_3d_depth)/100.0 )
00591 #define RAD_DEPTH ( (double)GDC_3d_angle*2*M_PI/360 )
00592 xdepth_3D = threeD? (int)( cos(RAD_DEPTH) * HYP_DEPTH ): 0;
00593 ydepth_3D = threeD? (int)( sin(RAD_DEPTH) * HYP_DEPTH ): 0;
00594 xdepth_3Dtotal = xdepth_3D*(GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
00595 num_sets:
00596 1 );
00597 ydepth_3Dtotal = ydepth_3D*(GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
00598 num_sets:
00599 1 );
00600 annote_hgt = GDC_annotation && *(GDC_annotation->note)?
00601 1 +
00602 (1+GDC_fontc[GDC_annotation_font].h) *
00603 cnt_nl(GDC_annotation->note,&annote_len) +
00604 1 +
00605 2: 0;
00606 annote_len *= GDC_fontc[GDC_annotation_font].w;
00607
00608 if( GDC_xaxis && xlbl )
00609 {
00610 int biggest = -MAXINT;
00611
00612 for( i=0; i<num_points; ++i )
00613 {
00614 int len = 0;
00615
00616 for( len=0, j=0; xlbl[i][j]; ++len, ++j )
00617 if( xlbl[i][j] == '\n' )
00618 {
00619 biggest = MAX( len, biggest );
00620 ++num_lf_xlbls;
00621 len = 0;
00622 }
00623 biggest = MAX( len, biggest );
00624 }
00625 xlabel_hgt = 1+ biggest*GDC_fontc[GDC_xaxisfont_size].w +1;
00626 }
00627
00628 grapheight = GIFHEIGHT - ( xtics +
00629 xtitle_hgt +
00630 xlabel_hgt +
00631 title_hgt +
00632 annote_hgt +
00633 ydepth_3Dtotal +
00634 2 );
00635 if( GDC_hard_size && GDC_hard_grapheight )
00636 grapheight = GDC_hard_grapheight;
00637 GDC_hard_grapheight = grapheight;
00638
00639
00640 {
00641 float tmp_highest;
00642
00643 float ypoints[] = { 1.0/64.0, 1.0/32.0, 1.0/16.0, 1.0/8.0, 1.0/4.0, 1.0/2.0,
00644 1.0, 2.0, 3.0, 5.0, 10.0, 25.0,
00645 50.0, 100.0, 250.0, 500.0, 1000.0, 2500, 5000.0,
00646 10000.0, 25000.0, 50000.0, 100000.0,500000.0,1000000, 5000000,
00647 10000000 };
00648 #define NUM_YPOINTS (sizeof(ypoints) / sizeof(float))
00649 int max_num_ylbls;
00650 int longest_ylblen = 0;
00651
00652 max_num_ylbls = grapheight / (3+GDC_fontc[GDC_yaxisfont_size==GDC_TINY? GDC_yaxisfont_size+1:
00653 GDC_yaxisfont_size].h);
00654 if( max_num_ylbls < 3 )
00655 {
00656
00657 out_err( GIFWIDTH, GIFHEIGHT,
00658 gif_fptr,
00659 GDC_BGColor, GDC_LineColor,
00660 "Insificient Height" );
00661 return 2;
00662 }
00663
00664
00665 for( i=1; i<NUM_YPOINTS; ++i )
00666
00667
00668 if( (highest-lowest)/ypoints[i] < ((float)max_num_ylbls-(1.0+1.0))
00669 * (float)GDC_ylabel_density/100.0 )
00670 break;
00671
00672
00673 ylbl_interval = GDC_requested_yinterval != GDC_NOVALUE &&
00674 GDC_requested_yinterval > ypoints[i-1]? GDC_requested_yinterval:
00675 ypoints[i-1];
00676
00677
00678
00679 if( lowest != 0.0 &&
00680 lowest != GDC_requested_ymin )
00681 {
00682 if( lowest < 0.0 )
00683 lowest -= ylbl_interval;
00684
00685
00686
00687 lowest = ylbl_interval * (float)(int)((lowest-ypoints[0])/ylbl_interval);
00688 }
00689
00690 tmp_highest = lowest;
00691 do
00692 {
00693 int nmrtr, dmntr, whole;
00694 char *price_to_str( float, int*, int*, int*, char* );
00695 int lbl_len;
00696 char foo[32];
00697
00698 if( GDC_yaxis )
00699 {
00700 sprintf( foo, do_ylbl_fractions? "%.0f": GDC_ylabel_fmt, tmp_highest );
00701 lbl_len = ylbl_interval<1.0? strlen( price_to_str(tmp_highest,
00702 &nmrtr,
00703 &dmntr,
00704 &whole,
00705 do_ylbl_fractions? NULL: GDC_ylabel_fmt) ):
00706 strlen( foo );
00707 longest_ylblen = MAX( longest_ylblen, lbl_len );
00708 }
00709 } while( (tmp_highest += ylbl_interval) <= highest );
00710 ylabel_wth = longest_ylblen * GDC_fontc[GDC_yaxisfont_size].w;
00711 highest = GDC_requested_ymax==GDC_NOVALUE? tmp_highest:
00712 MAX( GDC_requested_ymax, highest );
00713
00714 if( do_vol )
00715 {
00716 float num_yintrvls = (highest-lowest) / ylbl_interval;
00717
00718 if( vhighest != 0.0 )
00719 vhighest += (vhighest-vlowest) / (num_yintrvls*2.0);
00720 if( vlowest != 0.0 )
00721 vlowest -= (vhighest-vlowest) / (num_yintrvls*2.0);
00722
00723 if( GDC_yaxis2 )
00724 {
00725 char svlongest[32];
00726 int lbl_len_low = sprintf( svlongest, GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f", vlowest );
00727 int lbl_len_high = sprintf( svlongest, GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f", vhighest );
00728 vlabel_wth = 1
00729 + MAX( lbl_len_low,lbl_len_high ) * GDC_fontc[GDC_yaxisfont_size].w;
00730 }
00731 }
00732 }
00733
00734 graphwidth = GIFWIDTH - ( ( (GDC_hard_size && GDC_hard_xorig)? GDC_hard_xorig:
00735 ( ytitle_hgt +
00736 ylabel_wth +
00737 ytics ) )
00738 + vtics
00739 + vtitle_hgt
00740 + vlabel_wth
00741 + xdepth_3Dtotal );
00742 if( GDC_hard_size && GDC_hard_graphwidth )
00743 graphwidth = GDC_hard_graphwidth;
00744 GDC_hard_graphwidth = graphwidth;
00745
00746
00747
00748 xscl = (float)(graphwidth-xdepth_3Dtotal) / (float)(num_points + (do_bar?2:0));
00749 yscl = -((float)grapheight) / (float)(highest-lowest);
00750 if( do_vol )
00751 {
00752 float hilow_diff = vhighest-vlowest==0.0? 1.0: vhighest-vlowest;
00753
00754 vyscl = -((float)grapheight) / hilow_diff;
00755 vyorig = (float)grapheight
00756 + ABS(vyscl) * MIN(vlowest,vhighest)
00757 + ydepth_3Dtotal
00758 + title_hgt
00759 + annote_hgt;
00760 }
00761 xorig = (float)( GIFWIDTH - ( graphwidth +
00762 vtitle_hgt +
00763 vtics +
00764 vlabel_wth ) );
00765 if( GDC_hard_size && GDC_hard_xorig )
00766 xorig = GDC_hard_xorig;
00767 GDC_hard_xorig = xorig;
00768
00769 yorig = (float)grapheight
00770 + ABS(yscl) * MIN(lowest,highest)
00771 + ydepth_3Dtotal
00772 + title_hgt
00773 + annote_hgt;
00774
00775
00776 GDC_hard_yorig = yorig;
00777
00778 hlf_barwdth = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_bar_width/100.0)/2.0) );
00779 hlf_hlccapwdth = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_HLC_cap_width/100.0)/2.0) );
00780 }
00781
00782
00783
00784
00785 if( (GDC_hold_img & GDC_REUSE_IMAGE) &&
00786 GDC_image != NULL )
00787 im = (gdImage *)GDC_image;
00788 else
00789 im = gdImageCreate( GIFWIDTH, GIFHEIGHT );
00790
00791
00792 BGColor = gdImageColorAllocate( im, l2gdcal(GDC_BGColor) );
00793 LineColor = clrallocate( im, GDC_LineColor );
00794 PlotColor = clrallocate( im, GDC_PlotColor );
00795 GridColor = clrallocate( im, GDC_GridColor );
00796 if( do_vol )
00797 {
00798 VolColor = clrallocate( im, GDC_VolColor );
00799 for( i=0; i<num_points; ++i )
00800 if( GDC_ExtVolColor )
00801 ExtVolColor[i] = clrallocate( im, GDC_ExtVolColor[i] );
00802 else
00803 ExtVolColor[i] = VolColor;
00804 }
00805
00806
00807 if( GDC_annotation )
00808 AnnoteColor = clrallocate( im, GDC_annotation->color );
00809
00810
00811 if( GDC_BGImage )
00812 {
00813 FILE *in = fopen(GDC_BGImage, "rb");
00814 if( !in )
00815 {
00816 ;
00817 }
00818 else
00819 {
00820 if( bg_img = gdImageCreateFromGif(in) )
00821 {
00822 int bgxpos = gdImageSX(bg_img)<GIFWIDTH? GIFWIDTH/2 - gdImageSX(bg_img)/2: 0,
00823 bgypos = gdImageSY(bg_img)<GIFHEIGHT? GIFHEIGHT/2 - gdImageSY(bg_img)/2: 0;
00824
00825
00826 if( gdImageSX(bg_img) > GIFWIDTH ||
00827 gdImageSY(bg_img) > GIFHEIGHT )
00828 {
00829 gdImageCopyResized( im, bg_img,
00830 bgxpos, bgypos,
00831 0, 0,
00832 GIFWIDTH, GIFHEIGHT,
00833 GIFWIDTH, GIFHEIGHT );
00834 }
00835 else
00836 gdImageCopy( im, bg_img,
00837 bgxpos, bgypos,
00838 0, 0,
00839 GIFWIDTH, GIFHEIGHT );
00840 }
00841 fclose(in);
00842 }
00843 }
00844
00845 for( j=0; j<num_sets; ++j )
00846 for( i=0; i<num_points; ++i )
00847 if( GDC_ExtColor )
00848 {
00849 unsigned long ext_clr = *(GDC_ExtColor+num_points*j+i);
00850
00851 ExtColor[j][i] = clrallocate( im, ext_clr );
00852 if( threeD )
00853 ExtColorShd[j][i] = clrshdallocate( im, ext_clr );
00854 }
00855 else if( GDC_SetColor )
00856 {
00857 int set_clr = GDC_SetColor[j];
00858 ExtColor[j][i] = clrallocate( im, set_clr );
00859 if( threeD )
00860 ExtColorShd[j][i] = clrshdallocate( im, set_clr );
00861 }
00862 else
00863 {
00864 ExtColor[j][i] = PlotColor;
00865 if( threeD )
00866 ExtColorShd[j][i] = clrshdallocate( im, GDC_PlotColor );
00867 }
00868
00869
00870 if( GDC_transparent_bg )
00871 gdImageColorTransparent( im, BGColor );
00872
00873 if( GDC_title )
00874 {
00875 int tlen;
00876 int titlecolor = clrallocate( im, GDC_TitleColor );
00877
00878 cnt_nl( GDC_title, &tlen );
00879 GDCImageStringNL( im,
00880 &GDC_fontc[GDC_title_size],
00881 GIFWIDTH/2 - tlen*GDC_fontc[GDC_title_size].w/2,
00882 0,
00883 GDC_title,
00884 titlecolor,
00885 GDC_JUSTIFY_CENTER );
00886 }
00887 if( GDC_xtitle )
00888 {
00889 int titlecolor = GDC_XTitleColor==GDC_DFLTCOLOR?
00890 PlotColor: clrallocate( im, GDC_XTitleColor );
00891 gdImageString( im,
00892 GDC_fontc[GDC_xtitle_size].f,
00893 GIFWIDTH/2 - strlen(GDC_xtitle)*GDC_fontc[GDC_xtitle_size].w/2,
00894 GIFHEIGHT-GDC_fontc[GDC_xtitle_size].h-1,
00895 (unsigned char *)GDC_xtitle,
00896 titlecolor );
00897 }
00898
00899
00900
00901
00902 if( GDC_grid || GDC_yaxis )
00903 {
00904 float tmp_y = lowest;
00905 int labelcolor = GDC_YLabelColor==GDC_DFLTCOLOR?
00906 LineColor: clrallocate( im, GDC_YLabelColor );
00907 int label2color = GDC_YLabel2Color==GDC_DFLTCOLOR?
00908 VolColor: clrallocate( im, GDC_YLabel2Color );
00909
00910
00911
00912
00913 for( i=-1; i<=1; i+=2 )
00914 {
00915 if( i == -1 ) if( lowest >= 0.0 )
00916 continue;
00917 else
00918 tmp_y = MIN( 0, highest );
00919
00920 if( i == 1 ) if( highest <= 0.0 )
00921 continue;
00922 else
00923 tmp_y = MAX( 0, lowest );
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 do
00935 {
00936 int n, d, w;
00937 char *price_to_str( float, int*, int*, int*, char* );
00938 char nmrtr[3+1], dmntr[3+1], whole[8];
00939 char all_whole = ylbl_interval<1.0? FALSE: TRUE;
00940
00941 char *ylbl_str = price_to_str( tmp_y,&n,&d,&w,
00942 do_ylbl_fractions? NULL: GDC_ylabel_fmt );
00943 if( do_ylbl_fractions )
00944 {
00945 sprintf( nmrtr, "%d", n );
00946 sprintf( dmntr, "%d", d );
00947 sprintf( whole, "%d", w );
00948 }
00949
00950 if( GDC_grid )
00951 {
00952 int x1, x2, y1, y2;
00953
00954
00955 x1 = PX(0); y1 = PY(tmp_y);
00956 gdImageLine( im, x1-2, y1, x1, y1, GridColor );
00957 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
00958 num_sets:
00959 1;
00960 x2 = PX(0); y2 = PY(tmp_y);
00961 gdImageLine( im, x1, y1, x2, y2, GridColor );
00962 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, GridColor );
00963 setno = 0;
00964 }
00965 if( GDC_yaxis )
00966 if( do_ylbl_fractions )
00967 {
00968 if( w || (!w && !n && !d) )
00969 {
00970 gdImageString( im,
00971 GDC_fontc[GDC_yaxisfont_size].f,
00972 PX(0)-2-strlen(whole)*GDC_fontc[GDC_yaxisfont_size].w
00973 - ( (!all_whole)?
00974 (strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w +
00975 GDC_fontc[GDC_yaxisfont_size].w +
00976 strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w) :
00977 1 ),
00978 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2,
00979 (unsigned char *)whole,
00980 labelcolor );
00981 }
00982 if( n )
00983 {
00984 gdImageString( im,
00985 GDC_fontc[GDC_yaxisfont_size-1].f,
00986 PX(0)-2-strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w
00987 -GDC_fontc[GDC_yaxisfont_size].w
00988 -strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w + 1,
00989 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2 + 1,
00990 (unsigned char *)nmrtr,
00991 labelcolor );
00992 gdImageString( im,
00993 GDC_fontc[GDC_yaxisfont_size].f,
00994 PX(0)-2-GDC_fontc[GDC_yaxisfont_size].w
00995 -strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w,
00996 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2,
00997 (unsigned char *)"/",
00998 labelcolor );
00999 gdImageString( im,
01000 GDC_fontc[GDC_yaxisfont_size-1].f,
01001 PX(0)-2-strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w - 2,
01002 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2 + 3,
01003 (unsigned char *) dmntr,
01004 labelcolor );
01005 }
01006 }
01007 else
01008 gdImageString( im,
01009 GDC_fontc[GDC_yaxisfont_size].f,
01010 PX(0)-2-strlen(ylbl_str)*GDC_fontc[GDC_yaxisfont_size].w,
01011 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2,
01012 (unsigned char *)ylbl_str,
01013 labelcolor );
01014
01015
01016 if( do_vol && GDC_yaxis2 )
01017 {
01018 char vylbl[16];
01019
01020 sprintf( vylbl,
01021 GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f",
01022 ((float)(PY(tmp_y)+(setno*ydepth_3D)-vyorig))/vyscl );
01023
01024 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01025 num_sets:
01026 1;
01027 gdImageLine( im, PX(num_points-1+(do_bar?2:0)), PY(tmp_y),
01028 PX(num_points-1+(do_bar?2:0))+3, PY(tmp_y), GridColor );
01029 if( atof(vylbl) == 0.0 )
01030 strcpy( vylbl, "0" );
01031 gdImageString( im,
01032 GDC_fontc[GDC_yaxisfont_size].f,
01033 PX(num_points-1+(do_bar?2:0))+6,
01034 PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2,
01035 (unsigned char *)vylbl,
01036 label2color );
01037 setno = 0;
01038 }
01039 }
01040 while( ((i>0) && ((tmp_y += ylbl_interval) < highest)) ||
01041 ((i<0) && ((tmp_y -= ylbl_interval) > lowest)) );
01042 }
01043
01044
01045 if( GDC_grid && threeD )
01046 {
01047 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01048 num_sets:
01049 1;
01050 gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), GridColor );
01051 setno = 0;
01052 }
01053
01054
01055 if( do_vol && GDC_ytitle2 )
01056 {
01057 int titlecolor = GDC_YTitle2Color==GDC_DFLTCOLOR?
01058 VolColor: clrallocate( im, GDC_YTitle2Color );
01059 gdImageStringUp( im,
01060 GDC_fontc[GDC_ytitle_size].f,
01061 GIFWIDTH-(1+GDC_fontc[GDC_ytitle_size].h),
01062 strlen(GDC_ytitle2)*GDC_fontc[GDC_ytitle_size].w/2 +
01063 grapheight/2,
01064 (unsigned char *)GDC_ytitle2,
01065 titlecolor );
01066 }
01067
01068
01069 if( GDC_yaxis && GDC_ytitle )
01070 {
01071 int ytit_len = strlen(GDC_ytitle)*GDC_fontc[GDC_ytitle_size].w;
01072 int titlecolor = GDC_YTitleColor==GDC_DFLTCOLOR?
01073 PlotColor: clrallocate( im, GDC_YTitleColor );
01074 gdImageStringUp( im,
01075 GDC_fontc[GDC_ytitle_size].f,
01076 0,
01077 GIFHEIGHT/2 + ytit_len/2,
01078 (unsigned char *)GDC_ytitle,
01079 titlecolor );
01080 }
01081 }
01082
01083
01084
01085 if( GDC_grid && threeD )
01086 {
01087 for( setno=(GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets: 1) - 1;
01088 setno > 0;
01089 --setno )
01090 {
01091 gdImageLine( im, PX(0), PY(lowest), PX(0), PY(highest), GridColor );
01092 gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), GridColor );
01093 }
01094 setno = 0;
01095 }
01096
01097 if( ( GDC_grid || GDC_0Shelf ) &&
01098 ( (lowest < 0.0 && highest > 0.0) ||
01099 (lowest < 0.0 && highest > 0.0) ) )
01100 {
01101 int x1, x2, y1, y2;
01102
01103 x1 = PX(0); y1 = PY(0);
01104 gdImageLine( im, x1-2, y1, x1, y1, LineColor );
01105 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01106 num_sets:
01107 1;
01108 x2 = PX(0); y2 = PY(0);
01109 gdImageLine( im, x1, y1, x2, y2, LineColor );
01110 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, LineColor );
01111 setno = 0;
01112 }
01113
01114
01115
01116 if( GDC_grid || GDC_xaxis )
01117 {
01118 int num_xlbls =
01119
01120 graphwidth /
01121 ( (GDC_xlabel_spacing==MAXSHORT?0:GDC_xlabel_spacing)+GDC_fontc[GDC_xaxisfont_size].h +
01122 (num_lf_xlbls*(GDC_fontc[GDC_xaxisfont_size].h-1))/num_points );
01123 int labelcolor = GDC_XLabelColor==GDC_DFLTCOLOR?
01124 LineColor: clrallocate( im, GDC_XLabelColor );
01125
01126 for( i=0; i<num_points+(do_bar?2:0); ++i )
01127 if( (i%(1+num_points/num_xlbls) == 0) ||
01128 (num_xlbls >= num_points) ||
01129 GDC_xlabel_spacing == MAXSHORT )
01130 {
01131 int xi = do_bar? i-1: i;
01132
01133 if( GDC_grid )
01134 {
01135 int x1, x2, y1, y2;
01136
01137 x1 = PX(i); y1 = PY(lowest);
01138 gdImageLine( im, x1, y1, x1, y1+2, GridColor );
01139 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01140 num_sets:
01141 1;
01142 x2 = PX(i); y2 = PY(lowest);
01143 gdImageLine( im, x1, y1, x2, y2, GridColor );
01144 gdImageLine( im, x2, y2, x2, PY(highest), GridColor );
01145 setno = 0;
01146 }
01147
01148 if( !do_bar || (i>0 && xi<num_points) )
01149 if( GDC_xaxis && xlbl && xlbl[xi] && *(xlbl[xi]) )
01150 {
01151
01152 #define LBX GDC_fontc[GDC_xaxisfont_size]
01153 int xlen = 0;
01154 short xstrs_num = cnt_nl( xlbl[xi], &xlen );
01155 char sub_xlbl[xlen+1];
01156
01157 int xlbl_strt = -1+ PX(i) - (int)((float)(LBX.h-2)*((float)xstrs_num/2.0));
01158
01159 xlen = -1;
01160 xstrs_num = -1;
01161 j = -1;
01162 do
01163 {
01164 ++j;
01165 ++xlen;
01166 sub_xlbl[xlen] = xlbl[xi][j];
01167 if( xlbl[xi][j] == '\n' ||
01168 xlbl[xi][j] == '\0' )
01169 {
01170 sub_xlbl[xlen] = '\0';
01171 ++xstrs_num;
01172 gdImageStringUp( im,
01173 LBX.f,
01174 xlbl_strt + (LBX.h-1)*xstrs_num,
01175 PY(lowest) + 2 + 1 + LBX.w*xlen,
01176 (unsigned char *)sub_xlbl,
01177 labelcolor );
01178 xlen = -1;
01179 }
01180 } while( xlbl[xi][j] );
01181 #undef LBX
01182 }
01183 }
01184 }
01185
01186
01187
01188 if( do_vol )
01189 {
01190 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01191 num_sets:
01192 1;
01193 if( type == GDC_COMBO_HLC_BAR ||
01194 type == GDC_COMBO_LINE_BAR ||
01195 type == GDC_3DCOMBO_LINE_BAR ||
01196 type == GDC_3DCOMBO_HLC_BAR )
01197 {
01198 if( uvol[0] != GDC_NOVALUE )
01199 draw_3d_bar( im, PX(0), PX(0)+hlf_barwdth,
01200 PV(0), PV(uvol[0]),
01201 0, 0,
01202 ExtVolColor[0],
01203 ExtVolColor[0] );
01204 for( i=1; i<num_points-1; ++i )
01205 if( uvol[i] != GDC_NOVALUE )
01206 draw_3d_bar( im, PX(i)-hlf_barwdth, PX(i)+hlf_barwdth,
01207 PV(0), PV(uvol[i]),
01208 0, 0,
01209 ExtVolColor[i],
01210 ExtVolColor[i] );
01211 if( uvol[i] != GDC_NOVALUE )
01212 draw_3d_bar( im, PX(i)-hlf_barwdth, PX(i),
01213 PV(0), PV(uvol[i]),
01214 0, 0,
01215 ExtVolColor[i],
01216 ExtVolColor[i] );
01217 }
01218 else
01219 if( type == GDC_COMBO_HLC_AREA ||
01220 type == GDC_COMBO_LINE_AREA ||
01221 type == GDC_3DCOMBO_LINE_AREA||
01222 type == GDC_3DCOMBO_HLC_AREA )
01223 for( i=1; i<num_points; ++i )
01224 if( uvol[i-1] != GDC_NOVALUE && uvol[i] != GDC_NOVALUE )
01225 draw_3d_area( im, PX(i-1), PX(i),
01226 PV(0), PV(uvol[i-1]), PV(uvol[i]),
01227 0, 0,
01228 ExtVolColor[i],
01229 ExtVolColor[i] );
01230 setno = 0;
01231 }
01232
01233 if( GDC_annotation && threeD )
01234 {
01235 int x1 = PX(GDC_annotation->point+(do_bar?1:0)),
01236 y1 = PY(lowest);
01237 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01238 num_sets:
01239 1;
01240 gdImageLine( im, x1, y1, PX(GDC_annotation->point+(do_bar?1:0)), PY(lowest), AnnoteColor );
01241 gdImageLine( im, PX(GDC_annotation->point+(do_bar?1:0)), PY(lowest),
01242 PX(GDC_annotation->point+(do_bar?1:0)), PY(highest)-2, AnnoteColor );
01243 setno = 0;
01244 }
01245
01246
01247 switch( type )
01248 {
01249 case GDC_3DBAR:
01250 case GDC_BAR:
01251
01252 switch( GDC_stack_type )
01253 {
01254 case GDC_STACK_DEPTH:
01255 for( setno=num_sets-1; setno>=0; --setno )
01256 for( i=0; i<num_points; ++i )
01257 if( uvals[setno][i] != GDC_NOVALUE )
01258 draw_3d_bar( im, PX(i+(do_bar?1:0))-hlf_barwdth, PX(i+(do_bar?1:0))+hlf_barwdth,
01259 PY(0), PY(uvals[setno][i]),
01260 xdepth_3D, ydepth_3D,
01261 ExtColor[setno][i],
01262 threeD? ExtColorShd[setno][i]: ExtColor[setno][i] );
01263 setno = 0;
01264 break;
01265
01266 case GDC_STACK_LAYER:
01267 {
01268 float lasty[num_points];
01269 j = 0;
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 for( i=0; i<num_points; ++i )
01281 {
01282 struct BS barset[num_sets];
01283 float lasty_pos = 0.0;
01284 float lasty_neg = 0.0;
01285 int k;
01286
01287 for( j=0, k=0; j<num_sets; ++j )
01288 {
01289 if( uvals[j][i] != GDC_NOVALUE )
01290 {
01291 if( uvals[j][i] < 0.0 )
01292 {
01293 barset[k].y1 = lasty_neg;
01294 barset[k].y2 = uvals[j][i] + lasty_neg;
01295 lasty_neg = barset[k].y2;
01296 }
01297 else
01298 {
01299 barset[k].y1 = lasty_pos;
01300 barset[k].y2 = uvals[j][i] + lasty_pos;
01301 lasty_pos = barset[k].y2;
01302 }
01303 barset[k].clr = ExtColor[j][i];
01304 barset[k].shclr = threeD? ExtColorShd[j][i]: ExtColor[j][i];
01305 ++k;
01306 }
01307 }
01308 qsort( barset, k, sizeof(struct BS), barcmpr );
01309
01310 for( j=0; j<k; ++j )
01311 {
01312 draw_3d_bar( im,
01313 PX(i+(do_bar?1:0))-hlf_barwdth, PX(i+(do_bar?1:0))+hlf_barwdth,
01314 PY(barset[j].y1), PY(barset[j].y2),
01315 xdepth_3D, ydepth_3D,
01316 barset[j].clr,
01317 barset[j].shclr );
01318 }
01319 }
01320 }
01321 break;
01322
01323 case GDC_STACK_BESIDE:
01324 {
01325 int new_barwdth = (int)( (float)hlf_barwdth / ((float)num_sets/2.0) );
01326 for( i=0; i<num_points; ++i )
01327 for( j=0; j<num_sets; ++j )
01328 if( uvals[j][i] != GDC_NOVALUE )
01329 draw_3d_bar( im, PX(i+(do_bar?1:0))-hlf_barwdth+new_barwdth*j+1,
01330 PX(i+(do_bar?1:0))-hlf_barwdth+new_barwdth*(j+1),
01331 PY(0), PY(uvals[j][i]),
01332 xdepth_3D, ydepth_3D,
01333 ExtColor[j][i],
01334 threeD? ExtColorShd[j][i]: ExtColor[j][i] );
01335 }
01336 break;
01337 }
01338 break;
01339
01340 case GDC_LINE:
01341 case GDC_COMBO_LINE_BAR:
01342 case GDC_COMBO_LINE_AREA:
01343 for( j=num_sets-1; j>=0; --j )
01344 for( i=1; i<num_points; ++i )
01345 if( uvals[j][i-1] != GDC_NOVALUE && uvals[j][i] != GDC_NOVALUE )
01346 {
01347 gdImageLine( im, PX(i-1), PY(uvals[j][i-1]), PX(i), PY(uvals[j][i]), ExtColor[j][i] );
01348 gdImageLine( im, PX(i-1), PY(uvals[j][i-1])+1, PX(i), PY(uvals[j][i])+1, ExtColor[j][i] );
01349 }
01350 else
01351 {
01352 if( uvals[j][i-1] != GDC_NOVALUE )
01353 gdImageSetPixel( im, PX(i-1), PY(uvals[j][i-1]), ExtColor[j][i] );
01354 if( uvals[j][i] != GDC_NOVALUE )
01355 gdImageSetPixel( im, PX(i), PY(uvals[j][i]), ExtColor[j][i] );
01356 }
01357 break;
01358
01359 case GDC_3DLINE:
01360 case GDC_3DCOMBO_LINE_BAR:
01361 case GDC_3DCOMBO_LINE_AREA:
01362 {
01363 int y1[num_sets],
01364 y2[num_sets];
01365
01366 for( i=1; i<num_points; ++i )
01367 {
01368 if( GDC_stack_type == GDC_STACK_DEPTH )
01369 {
01370 for( j=num_sets-1; j>=0; --j )
01371 if( uvals[j][i-1] != GDC_NOVALUE &&
01372 uvals[j][i] != GDC_NOVALUE )
01373 {
01374 setno = j;
01375 y1[j] = PY(uvals[j][i-1]);
01376 y2[j] = PY(uvals[j][i]);
01377
01378 draw_3d_line( im,
01379 PY(0),
01380 PX(i-1), PX(i),
01381 &(y1[j]), &(y2[j]),
01382 xdepth_3D, ydepth_3D,
01383 1,
01384 &(ExtColor[j][i]),
01385 &(ExtColorShd[j][i]) );
01386 setno = 0;
01387 }
01388 }
01389 else
01390 if( GDC_stack_type == GDC_STACK_BESIDE ||
01391 GDC_stack_type == GDC_STACK_SUM )
01392 {
01393 int set;
01394 int clr[num_sets],
01395 clrshd[num_sets];
01396 float usey1 = 0.0,
01397 usey2 = 0.0;
01398 for( j=0,set=0; j<num_sets; ++j )
01399 if( uvals[j][i-1] != GDC_NOVALUE &&
01400 uvals[j][i] != GDC_NOVALUE )
01401 {
01402 if( GDC_stack_type == GDC_STACK_SUM )
01403 {
01404 usey1 += uvals[j][i-1];
01405 usey2 += uvals[j][i];
01406 }
01407 else
01408 {
01409 usey1 = uvals[j][i-1];
01410 usey2 = uvals[j][i];
01411 }
01412 y1[set] = PY(usey1);
01413 y2[set] = PY(usey2);
01414 clr[set] = ExtColor[j][i];
01415 clrshd[set] = ExtColorShd[j][i];
01416 ++set;
01417 }
01418 draw_3d_line( im,
01419 PY(0),
01420 PX(i-1), PX(i),
01421 y1, y2,
01422 xdepth_3D, ydepth_3D,
01423 set,
01424 clr,
01425 clrshd );
01426 }
01427 }
01428 }
01429 break;
01430
01431 case GDC_AREA:
01432 case GDC_3DAREA:
01433 switch( GDC_stack_type )
01434 {
01435 case GDC_STACK_SUM:
01436 {
01437 float lasty[num_points];
01438 j = 0;
01439 for( i=1; i<num_points; ++i )
01440 if( uvals[j][i] != GDC_NOVALUE )
01441 {
01442 lasty[i] = uvals[j][i];
01443 if( uvals[j][i-1] != GDC_NOVALUE )
01444 draw_3d_area( im, PX(i-1), PX(i),
01445 PY(0), PY(uvals[j][i-1]), PY(uvals[j][i]),
01446 xdepth_3D, ydepth_3D,
01447 ExtColor[j][i],
01448 threeD? ExtColorShd[j][i]: ExtColor[j][i] );
01449 }
01450 for( j=1; j<num_sets; ++j )
01451 for( i=1; i<num_points; ++i )
01452 if( uvals[j][i] != GDC_NOVALUE && uvals[j][i-1] != GDC_NOVALUE )
01453 {
01454 draw_3d_area( im, PX(i-1), PX(i),
01455 PY(lasty[i]), PY(lasty[i-1]+uvals[j][i-1]), PY(lasty[i]+uvals[j][i]),
01456 xdepth_3D, ydepth_3D,
01457 ExtColor[j][i],
01458 threeD? ExtColorShd[j][i]: ExtColor[j][i] );
01459 lasty[i] += uvals[j][i];
01460 }
01461 }
01462 break;
01463
01464 case GDC_STACK_BESIDE:
01465 for( j=num_sets-1; j>=0; --j )
01466 for( i=1; i<num_points; ++i )
01467 if( uvals[j][i-1] != GDC_NOVALUE && uvals[j][i] != GDC_NOVALUE )
01468 draw_3d_area( im, PX(i-1), PX(i),
01469 PY(0), PY(uvals[j][i-1]), PY(uvals[j][i]),
01470 xdepth_3D, ydepth_3D,
01471 ExtColor[j][i],
01472 threeD? ExtColorShd[j][i]: ExtColor[j][i] );
01473 break;
01474
01475 case GDC_STACK_DEPTH:
01476 default:
01477 for( setno=num_sets-1; setno>=0; --setno )
01478 for( i=1; i<num_points; ++i )
01479 if( uvals[setno][i-1] != GDC_NOVALUE && uvals[setno][i] != GDC_NOVALUE )
01480 draw_3d_area( im, PX(i-1), PX(i),
01481 PY(0), PY(uvals[setno][i-1]), PY(uvals[setno][i]),
01482 xdepth_3D, ydepth_3D,
01483 ExtColor[setno][i],
01484 threeD? ExtColorShd[setno][i]: ExtColor[setno][i] );
01485 setno = 0;
01486 }
01487 break;
01488
01489 case GDC_3DHILOCLOSE:
01490 case GDC_3DCOMBO_HLC_BAR:
01491 case GDC_3DCOMBO_HLC_AREA:
01492 {
01493 gdPoint poly[4];
01494 for( j=num_hlc_sets-1; j>=0; --j )
01495 {
01496 for( i=1; i<num_points+1; ++i )
01497 if( uvals[CLOSESET+j*3][i-1] != GDC_NOVALUE )
01498 {
01499 if( (GDC_HLC_style & GDC_HLC_I_CAP) &&
01500 uvals[LOWSET+j*3][i-1] != GDC_NOVALUE )
01501 {
01502 SET_3D_POLY( poly, PX(i-1)-hlf_hlccapwdth, PX(i-1)+hlf_hlccapwdth,
01503 PY(uvals[LOWSET+j*3][i-1]), PY(uvals[LOWSET+j*3][i-1]),
01504 xdepth_3D, ydepth_3D );
01505 gdImageFilledPolygon( im, poly, 4, ExtColor[LOWSET+j*3][i-1] );
01506 gdImagePolygon( im, poly, 4, ExtColorShd[LOWSET+j*3][i-1] );
01507 }
01508
01509 if( uvals[LOWSET+j*3][i-1] != GDC_NOVALUE )
01510 {
01511 SET_3D_POLY( poly, PX(i-1), PX(i-1),
01512 PY(uvals[LOWSET+j*3][i-1]), PY(uvals[CLOSESET+j*3][i-1]),
01513 xdepth_3D, ydepth_3D );
01514 gdImageFilledPolygon( im, poly, 4, ExtColor[LOWSET+j*3][i-1] );
01515 gdImagePolygon( im, poly, 4, ExtColorShd[LOWSET+j*3][i-1] );
01516 }
01517 if( uvals[HIGHSET+j*3][i-1] != GDC_NOVALUE )
01518 {
01519 SET_3D_POLY( poly, PX(i-1), PX(i-1),
01520 PY(uvals[CLOSESET+j*3][i-1]), PY(uvals[HIGHSET+j*3][i-1]),
01521 xdepth_3D, ydepth_3D );
01522 gdImageFilledPolygon( im, poly, 4, ExtColor[HIGHSET+j*3][i-1] );
01523 gdImagePolygon( im, poly, 4, ExtColorShd[HIGHSET+j*3][i-1] );
01524 }
01525
01526 gdImageLine( im, PX(i-1), PY(uvals[CLOSESET+j*3][i-1]),
01527 PX(i-1)+xdepth_3D, PY(uvals[CLOSESET+j*3][i-1])-ydepth_3D,
01528 ExtColorShd[CLOSESET+j*3][i-1] );
01529
01530 if( !( (GDC_HLC_style & GDC_HLC_DIAMOND) &&
01531 (PY(uvals[HIGHSET+j*3][i-1]) > PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth) ) &&
01532 uvals[HIGHSET+j*3][i-1] != GDC_NOVALUE )
01533 if( GDC_HLC_style & GDC_HLC_I_CAP )
01534 {
01535 SET_3D_POLY( poly, PX(i-1)-hlf_hlccapwdth, PX(i-1)+hlf_hlccapwdth,
01536 PY(uvals[HIGHSET+j*3][i-1]), PY(uvals[HIGHSET+j*3][i-1]),
01537 xdepth_3D, ydepth_3D );
01538 gdImageFilledPolygon( im, poly, 4, ExtColor[HIGHSET+j*3][i-1] );
01539 gdImagePolygon( im, poly, 4, ExtColorShd[HIGHSET+j*3][i-1] );
01540 }
01541
01542 if( i < num_points &&
01543 uvals[CLOSESET+j*3][i] != GDC_NOVALUE )
01544 {
01545 if( GDC_HLC_style & GDC_HLC_CLOSE_CONNECTED )
01546 {
01547 SET_3D_POLY( poly, PX(i-1), PX(i),
01548 PY(uvals[CLOSESET+j*3][i-1]), PY(uvals[CLOSESET+j*3][i-1]),
01549 xdepth_3D, ydepth_3D );
01550 gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i] );
01551 gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i] );
01552 }
01553 else
01554 if( GDC_HLC_style & GDC_HLC_CONNECTING )
01555 {
01556 int y1 = PY(uvals[CLOSESET+j*3][i-1]),
01557 y2 = PY(uvals[CLOSESET+j*3][i]);
01558 draw_3d_line( im,
01559 PY(0),
01560 PX(i-1), PX(i),
01561 &y1, &y2,
01562 xdepth_3D, ydepth_3D,
01563 1,
01564 &(ExtColor[CLOSESET+j*3][i]),
01565 &(ExtColorShd[CLOSESET+j*3][i]) );
01566
01567 gdImageLine( im, PX(i-1), PY(uvals[CLOSESET+j*3][i-1]),
01568 PX(i), PY(uvals[CLOSESET+j*3][i]),
01569 ExtColorShd[CLOSESET+j*3][i] );
01570 }
01571
01572 if( PY(uvals[CLOSESET+j*3][i-1]) <= PY(uvals[CLOSESET+j*3][i]) &&
01573 uvals[HIGHSET+j*3][i-1] != GDC_NOVALUE )
01574 if( GDC_HLC_style & GDC_HLC_I_CAP )
01575 {
01576 SET_3D_POLY( poly, PX(i-1)-hlf_hlccapwdth, PX(i-1)+hlf_hlccapwdth,
01577 PY(uvals[HIGHSET+j*3][i-1]), PY(uvals[HIGHSET+j*3][i-1]),
01578 xdepth_3D, ydepth_3D );
01579 gdImageFilledPolygon( im, poly, 4, ExtColor[HIGHSET+j*3][i-1] );
01580 gdImagePolygon( im, poly, 4, ExtColorShd[HIGHSET+j*3][i-1] );
01581 }
01582 }
01583 if( GDC_HLC_style & GDC_HLC_DIAMOND )
01584 {
01585 poly[0].x = PX(i-1)-hlf_hlccapwdth;
01586 poly[0].y = PY(uvals[CLOSESET+j*3][i-1]);
01587 poly[1].x = PX(i-1);
01588 poly[1].y = PY(uvals[CLOSESET+j*3][i-1])+hlf_hlccapwdth;
01589 poly[2].x = PX(i-1)+hlf_hlccapwdth;
01590 poly[2].y = PY(uvals[CLOSESET+j*3][i-1]);
01591 poly[3].x = PX(i-1);
01592 poly[3].y = PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth;
01593 gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] );
01594 gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] );
01595
01596 SET_3D_POLY( poly, PX(i-1), PX(i-1)+hlf_hlccapwdth,
01597 PY(uvals[CLOSESET+j*3][i-1])+hlf_hlccapwdth,
01598 PY(uvals[CLOSESET+j*3][i-1]),
01599 xdepth_3D, ydepth_3D );
01600 gdImageFilledPolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] );
01601
01602
01603 SET_3D_POLY( poly, PX(i-1), PX(i-1)+hlf_hlccapwdth,
01604 PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth,
01605 PY(uvals[CLOSESET+j*3][i-1]),
01606 xdepth_3D, ydepth_3D );
01607 gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] );
01608 gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] );
01609 }
01610 }
01611 }
01612 }
01613 break;
01614
01615 case GDC_HILOCLOSE:
01616 case GDC_COMBO_HLC_BAR:
01617 case GDC_COMBO_HLC_AREA:
01618 for( j=num_hlc_sets-1; j>=0; --j )
01619 {
01620 for( i=0; i<num_points; ++i )
01621 if( uvals[CLOSESET+j*3][i] != GDC_NOVALUE )
01622 {
01623 if( uvals[LOWSET+j*3][i] != GDC_NOVALUE )
01624 gdImageLine( im, PX(i), PY(uvals[CLOSESET+j*3][i]),
01625 PX(i), PY(uvals[LOWSET+j*3][i]),
01626 ExtColor[LOWSET+(j*3)][i] );
01627 if( uvals[HIGHSET+j*3][i] != GDC_NOVALUE )
01628 gdImageLine( im, PX(i), PY(uvals[HIGHSET+j*3][i]),
01629 PX(i), PY(uvals[CLOSESET+j*3][i]),
01630 ExtColor[HIGHSET+j*3][i] );
01631
01632 if( GDC_HLC_style & GDC_HLC_I_CAP )
01633 {
01634 if( uvals[LOWSET+j*3][i] != GDC_NOVALUE )
01635 gdImageLine( im, PX(i)-hlf_hlccapwdth, PY(uvals[LOWSET+j*3][i]),
01636 PX(i)+hlf_hlccapwdth, PY(uvals[LOWSET+j*3][i]),
01637 ExtColor[LOWSET+j*3][i] );
01638 if( uvals[HIGHSET+j*3][i] != GDC_NOVALUE )
01639 gdImageLine( im, PX(i)-hlf_hlccapwdth, PY(uvals[HIGHSET+j*3][i]),
01640 PX(i)+hlf_hlccapwdth, PY(uvals[HIGHSET+j*3][i]),
01641 ExtColor[HIGHSET+j*3][i] );
01642 }
01643 if( GDC_HLC_style & GDC_HLC_DIAMOND )
01644 {
01645 gdPoint cd[4];
01646
01647 cd[0].x = PX(i)-hlf_hlccapwdth; cd[0].y = PY(uvals[CLOSESET+j*3][i]);
01648 cd[1].x = PX(i); cd[1].y = PY(uvals[CLOSESET+j*3][i])+hlf_hlccapwdth;
01649 cd[2].x = PX(i)+hlf_hlccapwdth; cd[2].y = PY(uvals[CLOSESET+j*3][i]);
01650 cd[3].x = PX(i); cd[3].y = PY(uvals[CLOSESET+j*3][i])-hlf_hlccapwdth;
01651 gdImageFilledPolygon( im, cd, 4, ExtColor[CLOSESET+j*3][i] );
01652 }
01653 }
01654 for( i=1; i<num_points; ++i )
01655 if( uvals[CLOSESET+j*3][i-1] != GDC_NOVALUE && uvals[CLOSESET+j*3][i] != GDC_NOVALUE )
01656 {
01657 if( GDC_HLC_style & GDC_HLC_CLOSE_CONNECTED )
01658 gdImageLine( im, PX(i-1), PY(uvals[CLOSESET+j*3][i-1]),
01659 PX(i), PY(uvals[CLOSESET+j*3][i-1]),
01660 ExtColor[CLOSESET+j*3][i] );
01661 else
01662 if( GDC_HLC_style & GDC_HLC_CONNECTING )
01663 gdImageLine( im, PX(i-1), PY(uvals[CLOSESET+j*3][i-1]),
01664 PX(i), PY(uvals[CLOSESET+j*3][i]),
01665 ExtColor[CLOSESET+j*3][i] );
01666 }
01667 }
01668 break;
01669 }
01670 setno = 0;
01671
01672
01673
01674
01675
01676
01677 if( GDC_scatter )
01678 {
01679 int scatter_clr[GDC_num_scatter_pts];
01680 gdPoint ct[3];
01681
01682 for( i=0; i<GDC_num_scatter_pts; ++i )
01683 {
01684 int hlf_scatterwdth = (int)( (float)(PX(2)-PX(1))
01685 * (((float)((GDC_scatter+i)->width)/100.0)/2.0) );
01686 int scat_x = PX( (GDC_scatter+i)->point + (do_bar?1:0) ),
01687 scat_y = PY( (GDC_scatter+i)->val );
01688
01689 if( (GDC_scatter+i)->point >= num_points ||
01690 (GDC_scatter+i)->point < 0 )
01691 continue;
01692 scatter_clr[i] = clrallocate( im, (GDC_scatter+i)->color );
01693
01694 switch( (GDC_scatter+i)->ind )
01695 {
01696 case GDC_SCATTER_TRIANGLE_UP:
01697 ct[0].x = scat_x;
01698 ct[0].y = scat_y;
01699 ct[1].x = scat_x - hlf_scatterwdth;
01700 ct[1].y = scat_y + hlf_scatterwdth;;
01701 ct[2].x = scat_x + hlf_scatterwdth;
01702 ct[2].y = scat_y + hlf_scatterwdth;
01703 if( !do_bar )
01704 if( (GDC_scatter+i)->point == 0 )
01705 ct[1].x = scat_x;
01706 else
01707 if( (GDC_scatter+i)->point == num_points-1 )
01708 ct[2].x = scat_x;
01709 gdImageFilledPolygon( im, ct, 3, scatter_clr[i] );
01710 break;
01711 case GDC_SCATTER_TRIANGLE_DOWN:
01712 ct[0].x = scat_x;
01713 ct[0].y = scat_y;
01714 ct[1].x = scat_x - hlf_scatterwdth;
01715 ct[1].y = scat_y - hlf_scatterwdth;;
01716 ct[2].x = scat_x + hlf_scatterwdth;
01717 ct[2].y = scat_y - hlf_scatterwdth;
01718 if( !do_bar )
01719 if( (GDC_scatter+i)->point == 0 )
01720 ct[1].x = scat_x;
01721 else
01722 if( (GDC_scatter+i)->point == num_points-1 )
01723 ct[2].x = scat_x;
01724 gdImageFilledPolygon( im, ct, 3, scatter_clr[i] );
01725 break;
01726 }
01727 }
01728 }
01729
01730
01731
01732 #ifdef THUMB_VALS
01733
01734 if( thumbnail )
01735 {
01736 int n, d, w;
01737 char thmbl[32];
01738 char *price_to_str( float, int*, int*, int* );
01739 char nmrtr[3+1], dmntr[3+1], whole[8];
01740
01741 char *dbg = price_to_str( ABS(thumbval),&n,&d,&w );
01742 sprintf( nmrtr, "%d", n );
01743 sprintf( dmntr, "%d", d );
01744 sprintf( whole, "%d", w );
01745
01746 gdImageString( im,
01747 gdFontSmall,
01748 graphwidth/2-strlen(thumblabel)*SFONTWDTH/2,
01749 1,
01750 thumblabel,
01751 ThumbLblColor );
01752 if( w || n )
01753 {
01754 int chgcolor = thumbval>0.0? ThumbUColor: ThumbDColor;
01755 int thmbvalwidth = SFONTWDTH +
01756 (w?strlen(whole)*SFONTWDTH: 0) +
01757 (n?strlen(nmrtr)*TFONTWDTH +
01758 SFONTWDTH +
01759 strlen(dmntr)*TFONTWDTH:
01760 0);
01761
01762 smallarrow( im, graphwidth/2-thmbvalwidth/2, SFONTHGT, thumbval>0.0, chgcolor );
01763 if( w )
01764 {
01765 gdImageString( im,
01766 gdFontSmall,
01767 (graphwidth/2-thmbvalwidth/2)+SFONTWDTH,
01768 SFONTHGT+2,
01769 whole,
01770 chgcolor );
01771 }
01772 if( n )
01773 {
01774 gdImageString( im,
01775 gdFontTiny,
01776 (graphwidth/2-thmbvalwidth/2) +
01777 SFONTWDTH +
01778 (w? strlen(whole)*SFONTWDTH: 0) +
01779 2,
01780 SFONTHGT+2-2,
01781 nmrtr,
01782 chgcolor );
01783 gdImageChar ( im,
01784 gdFontSmall,
01785 (graphwidth/2-thmbvalwidth/2) +
01786 SFONTWDTH +
01787 (w? strlen(whole)*SFONTWDTH: 0) +
01788 strlen(nmrtr)*TFONTWDTH,
01789 SFONTHGT+2,
01790 '/',
01791 chgcolor );
01792 gdImageString( im,
01793 gdFontTiny,
01794 (graphwidth/2-thmbvalwidth/2) +
01795 SFONTWDTH +
01796 (w? strlen(whole)*SFONTWDTH: 0) +
01797 strlen(nmrtr)*TFONTWDTH +
01798 SFONTWDTH - 3,
01799 SFONTHGT+2+4,
01800 dmntr,
01801 chgcolor );
01802 }
01803 }
01804 }
01805 #endif
01806
01807
01808
01809 if( GDC_border )
01810 {
01811 gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), LineColor );
01812
01813 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets: 1;
01814 gdImageLine( im, PX(0), PY(highest), PX(num_points-1+(do_bar?2:0)), PY(highest), LineColor );
01815 setno = 0;
01816 }
01817 if( GDC_border )
01818 {
01819 int x1, y1, x2, y2;
01820
01821 x1 = PX(0);
01822 y1 = PY(highest);
01823 x2 = PX(num_points-1+(do_bar?2:0));
01824 y2 = PY(lowest);
01825 gdImageLine( im, x1, PY(lowest), x1, y1, LineColor );
01826
01827 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets: 1;
01828 gdImageLine( im, x1, y1, PX(0), PY(highest), LineColor );
01829
01830 {
01831 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), PY(lowest), LineColor );
01832 gdImageLine( im, PX(num_points-1+(do_bar?2:0)), PY(lowest),
01833 PX(num_points-1+(do_bar?2:0)), PY(highest), LineColor );
01834 }
01835 setno = 0;
01836 }
01837
01838 if( GDC_0Shelf && threeD &&
01839 ( (lowest < 0.0 && highest > 0.0) ||
01840 (lowest < 0.0 && highest > 0.0) ) )
01841 {
01842 int x2 = PX( num_points-1+(do_bar?2:0) ),
01843 y2 = PY( 0 );
01844
01845 gdImageLine( im, PX(0), PY(0), x2, y2, LineColor );
01846 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets:
01847 1;
01848
01849 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), PY(0), LineColor );
01850 setno = 0;
01851 }
01852
01853 if( GDC_annotation )
01854 {
01855 int x1 = PX(GDC_annotation->point+(do_bar?1:0)),
01856 y1 = PY(highest);
01857 int x2;
01858
01859 gdImageLine( im, x1, PY(lowest)+1, x1, y1, AnnoteColor );
01860 if( threeD )
01861 {
01862 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets: 1;
01863 x2 = PX(GDC_annotation->point+(do_bar?1:0));
01864
01865 gdImageLine( im, x1, y1, x2, PY(highest), AnnoteColor );
01866 }
01867 else
01868 {
01869 x2 = PX(GDC_annotation->point+(do_bar?1:0));
01870 gdImageLine( im, x1, y1, x1, y1-2, AnnoteColor );
01871 }
01872
01873 if( *(GDC_annotation->note) )
01874 {
01875 if( GDC_annotation->point >= (num_points/2) )
01876 {
01877 gdImageLine( im, x2, PY(highest)-2,
01878 x2-annote_hgt/2, PY(highest)-2-annote_hgt/2,
01879 AnnoteColor );
01880 GDCImageStringNL( im,
01881 &GDC_fontc[GDC_annotation_font],
01882 x2-annote_hgt/2-1-annote_len - 1,
01883 PY(highest)-annote_hgt+1,
01884 GDC_annotation->note,
01885 AnnoteColor,
01886 GDC_JUSTIFY_RIGHT );
01887 }
01888 else
01889 {
01890 gdImageLine( im, x2, PY(highest)-2,
01891 x2+annote_hgt/2, PY(highest)-2-annote_hgt/2,
01892 AnnoteColor );
01893 GDCImageStringNL( im,
01894 &GDC_fontc[GDC_annotation_font],
01895 x2+annote_hgt/2+1 + 1,
01896 PY(highest)-annote_hgt+1,
01897 GDC_annotation->note,
01898 AnnoteColor,
01899 GDC_JUSTIFY_LEFT );
01900 }
01901 }
01902 setno = 0;
01903 }
01904
01905
01906
01907 if( GDC_generate_gif )
01908 {
01909 fflush(gif_fptr);
01910 gdImageGif( im, gif_fptr );
01911 }
01912
01913 if( bg_img )
01914 gdImageDestroy(bg_img);
01915 if( GDC_hold_img & GDC_EXPOSE_IMAGE )
01916 GDC_image = (void*)im;
01917 else
01918 gdImageDestroy(im);
01919 return 0;
01920 #endif
01921 }