gdchart.h File Reference

#include "gdc.h"

Go to the source code of this file.

Data Structures

struct  GDC_ANNOTATION_T
struct  GDC_SCATTER_T

Defines

#define MAX_NOTE_LEN   19
#define EXTERND   extern

Enumerations

enum  GDC_CHART_T {
  GDC_LINE, GDC_AREA, GDC_BAR, GDC_HILOCLOSE,
  GDC_COMBO_LINE_BAR, GDC_COMBO_HLC_BAR, GDC_COMBO_LINE_AREA, GDC_COMBO_HLC_AREA,
  GDC_3DHILOCLOSE, GDC_3DCOMBO_LINE_BAR, GDC_3DCOMBO_LINE_AREA, GDC_3DCOMBO_HLC_BAR,
  GDC_3DCOMBO_HLC_AREA, GDC_3DBAR, GDC_3DAREA, GDC_3DLINE
}
enum  GDC_STACK_T { GDC_STACK_DEPTH, GDC_STACK_SUM, GDC_STACK_BESIDE, GDC_STACK_LAYER }
enum  GDC_HLC_STYLE_T { GDC_HLC_DIAMOND = 1, GDC_HLC_CLOSE_CONNECTED = 2, GDC_HLC_CONNECTING = 4, GDC_HLC_I_CAP = 8 }
enum  GDC_SCATTER_IND_T { GDC_SCATTER_TRIANGLE_DOWN, GDC_SCATTER_TRIANGLE_UP }

Functions

EXTERND enum GDC_font_size
GDC_title_size 
DEFAULTO (GDC_MEDBOLD)
EXTERND enum GDC_font_size
GDC_yaxisfont_size 
DEFAULTO (GDC_SMALL)
EXTERND char *GDC_ylabel_fmt DEFAULTO (NULL)
EXTERND short GDC_xlabel_spacing DEFAULTO (5)
EXTERND char GDC_ylabel_density DEFAULTO (80)
EXTERND float GDC_requested_ymin DEFAULTO (0)
EXTERND char GDC_0Shelf DEFAULTO (TRUE)
EXTERND GDC_STACK_T GDC_stack_type DEFAULTO (GDC_STACK_DEPTH)
EXTERND float GDC_3d_depth DEFAULTO (5.0)
EXTERND unsigned char GDC_3d_angle DEFAULTO (45)
EXTERND unsigned char GDC_bar_width DEFAULTO (75)
EXTERND GDC_HLC_STYLE_T GDC_HLC_style DEFAULTO (GDC_HLC_CLOSE_CONNECTED)
EXTERND unsigned char GDC_HLC_cap_width DEFAULTO (25)
EXTERND GDC_ANNOTATION_T
*GDC_annotation 
DEFAULTO ((GDC_ANNOTATION_T *) NULL)
EXTERND GDC_SCATTER_T *GDC_scatter DEFAULTO ((GDC_SCATTER_T *) NULL)
EXTERND char GDC_thumbnail DEFAULTO (FALSE)
EXTERND float GDC_thumbval DEFAULTO (-100000)
EXTERND unsigned long GDC_BGColor DEFAULTO (0x000000L)
EXTERND unsigned long GDC_GridColor DEFAULTO (0xA0A0A0L)
EXTERND unsigned long GDC_LineColor DEFAULTO (GDC_DFLTCOLOR)
EXTERND unsigned long GDC_VolColor DEFAULTO (0xA0A0FFL)
EXTERND unsigned long *GDC_ExtVolColor DEFAULTO ((unsigned long *) NULL)
EXTERND char *GDC_BGImage DEFAULTO ((char *) NULL)
int out_graph (short gifwidth, short gifheight, FILE *gif_fptr, GDC_CHART_T type, int num_points, char *xlbl[], int num_sets,...)

Variables

EXTERND char * GDC_ytitle
EXTERND char * GDC_xtitle
EXTERND char * GDC_ytitle2
EXTERND char * GDC_title
EXTERND char * GDC_thumblabel


Define Documentation

#define EXTERND   extern

Definition at line 69 of file gdchart.h.

#define MAX_NOTE_LEN   19

Definition at line 10 of file gdchart.h.

Referenced by main().


Enumeration Type Documentation

enum GDC_CHART_T

Enumerator:
GDC_LINE 
GDC_AREA 
GDC_BAR 
GDC_HILOCLOSE 
GDC_COMBO_LINE_BAR 
GDC_COMBO_HLC_BAR 
GDC_COMBO_LINE_AREA 
GDC_COMBO_HLC_AREA 
GDC_3DHILOCLOSE 
GDC_3DCOMBO_LINE_BAR 
GDC_3DCOMBO_LINE_AREA 
GDC_3DCOMBO_HLC_BAR 
GDC_3DCOMBO_HLC_AREA 
GDC_3DBAR 
GDC_3DAREA 
GDC_3DLINE 

Definition at line 12 of file gdchart.h.

00012              {
00013                          GDC_LINE,
00014                          GDC_AREA,
00015                          GDC_BAR,
00016                          GDC_HILOCLOSE,
00017                          GDC_COMBO_LINE_BAR,                    /* aka, VOL[ume] */
00018                          GDC_COMBO_HLC_BAR,
00019                          GDC_COMBO_LINE_AREA,
00020                          GDC_COMBO_HLC_AREA,
00021                          GDC_3DHILOCLOSE,
00022                          GDC_3DCOMBO_LINE_BAR,
00023                          GDC_3DCOMBO_LINE_AREA,
00024                          GDC_3DCOMBO_HLC_BAR,
00025                          GDC_3DCOMBO_HLC_AREA,
00026                          GDC_3DBAR,
00027                          GDC_3DAREA,
00028                          GDC_3DLINE
00029                          } GDC_CHART_T;

enum GDC_HLC_STYLE_T

Enumerator:
GDC_HLC_DIAMOND 
GDC_HLC_CLOSE_CONNECTED 
GDC_HLC_CONNECTING 
GDC_HLC_I_CAP 

Definition at line 38 of file gdchart.h.

00038              {
00039                          GDC_HLC_DIAMOND         = 1,
00040                          GDC_HLC_CLOSE_CONNECTED = 2,   /* can't be used w/ CONNECTING */
00041                          GDC_HLC_CONNECTING      = 4,   /* can't be used w/ CLOSE_CONNECTED */
00042                          GDC_HLC_I_CAP           = 8
00043                          } GDC_HLC_STYLE_T;                             /* can be OR'd */

enum GDC_SCATTER_IND_T

Enumerator:
GDC_SCATTER_TRIANGLE_DOWN 
GDC_SCATTER_TRIANGLE_UP 

Definition at line 53 of file gdchart.h.

enum GDC_STACK_T

Enumerator:
GDC_STACK_DEPTH 
GDC_STACK_SUM 
GDC_STACK_BESIDE 
GDC_STACK_LAYER 

Definition at line 31 of file gdchart.h.

00031              {
00032                          GDC_STACK_DEPTH,                               /* "behind" (even non-3D) */
00033                          GDC_STACK_SUM,
00034                          GDC_STACK_BESIDE,
00035                          GDC_STACK_LAYER
00036                          } GDC_STACK_T;                                 /* applies only to num_lines > 1 */


Function Documentation

EXTERND char* GDC_BGImage DEFAULTO ( (char *)  NULL  ) 

EXTERND unsigned long* GDC_ExtVolColor DEFAULTO ( (unsigned long *)  NULL  ) 

EXTERND unsigned long GDC_VolColor DEFAULTO ( 0xA0A0FFL   ) 

EXTERND unsigned long GDC_LineColor DEFAULTO ( GDC_DFLTCOLOR   ) 

EXTERND unsigned long GDC_GridColor DEFAULTO ( 0xA0A0A0L   ) 

EXTERND unsigned long GDC_BGColor DEFAULTO ( 0x000000L   ) 

EXTERND float GDC_thumbval DEFAULTO ( 100000  ) 

EXTERND char GDC_thumbnail DEFAULTO ( FALSE   ) 

EXTERND GDC_SCATTER_T* GDC_scatter DEFAULTO ( (GDC_SCATTER_T *)  NULL  ) 

EXTERND GDC_ANNOTATION_T* GDC_annotation DEFAULTO ( (GDC_ANNOTATION_T *)  NULL  ) 

EXTERND unsigned char GDC_HLC_cap_width DEFAULTO ( 25   ) 

EXTERND GDC_HLC_STYLE_T GDC_HLC_style DEFAULTO ( GDC_HLC_CLOSE_CONNECTED   ) 

EXTERND unsigned char GDC_bar_width DEFAULTO ( 75   ) 

EXTERND unsigned char GDC_3d_angle DEFAULTO ( 45   ) 

EXTERND float GDC_3d_depth DEFAULTO ( 5.  0  ) 

EXTERND GDC_STACK_T GDC_stack_type DEFAULTO ( GDC_STACK_DEPTH   ) 

EXTERND char GDC_0Shelf DEFAULTO ( TRUE   ) 

EXTERND float GDC_requested_ymin DEFAULTO (  ) 

EXTERND char GDC_ylabel_density DEFAULTO ( 80   ) 

EXTERND short GDC_xlabel_spacing DEFAULTO (  ) 

EXTERND char* GDC_ylabel_fmt DEFAULTO ( NULL   ) 

EXTERND enum GDC_font_size GDC_yaxisfont_size DEFAULTO ( GDC_SMALL   ) 

EXTERND enum GDC_font_size GDC_title_size DEFAULTO ( GDC_MEDBOLD   ) 

int out_graph ( short  gifwidth,
short  gifheight,
FILE *  gif_fptr,
GDC_CHART_T  type,
int  num_points,
char *  xlbl[],
int  num_sets,
  ... 
)

Definition at line 359 of file gdchart.cpp.

References ABS, cnt_nl(), FALSE, GDC_3DAREA, GDC_3DBAR, GDC_3DCOMBO_HLC_AREA, GDC_3DCOMBO_HLC_BAR, GDC_3DCOMBO_LINE_AREA, GDC_3DCOMBO_LINE_BAR, GDC_3DHILOCLOSE, GDC_3DLINE, GDC_AREA, GDC_BAR, GDC_COMBO_HLC_AREA, GDC_COMBO_HLC_BAR, GDC_COMBO_LINE_AREA, GDC_COMBO_LINE_BAR, GDC_fontc, GDC_generate_gif, GDC_HILOCLOSE, GDC_hold_img, GDC_image, GDC_NOVALUE, GDC_REUSE_IMAGE, GDC_STACK_DEPTH, GDC_STACK_LAYER, GDC_STACK_SUM, GDC_TINY, GDC_title, GDC_xtitle, GDC_ytitle, GDC_ytitle2, gdImageColorAllocate(), gdImageCopy(), gdImageCopyResized(), gdImageCreate(), gdImageCreateFromGif(), gdImageSX, gdImageSY, HYP_DEPTH, l2gdcal, load_font_conversions(), MAX, MIN, NUM_YPOINTS, out_err(), price_to_str(), PX, and RAD_DEPTH.

Referenced by main().

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   ||               // aka: combo
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 ||                                 // offset X objects to leave
00412                                                    type == GDC_BAR );                                   //  room at X(0) and X(n)
00413                                                                                                                                 //  i.e., not up against Y axes
00414         char            do_ylbl_fractions =                                                     // %f format not given, or
00415                                                  ( !GDC_ylabel_fmt ||                                   //  format doesn't have a %,g,e,E,f or F
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;             // affects PX()
00422         int                     ydepth_3D      = 0;             // affects PY() and PV()
00423         int                     hlf_barwdth        = 0;         // half bar widths
00424         int                     hlf_hlccapwdth = 0;             // half cap widths for HLC_I_CAP and DIAMOND
00425         int                     annote_len     = 0,
00426                                 annote_hgt     = 0;
00427 
00428         /* args */
00429         int                     setno = 0;                              // affects PX() and PY()
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:     // 1 more last set is vol
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:          // 1 more last set is vol
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 //                              ArrowDColor,
00458 //                              ArrowUColor,
00459                                 AnnoteColor,
00460                                 ExtColor[num_sets][num_points];
00461                                                                                                                                 // shade colors only with 3D
00462 //      int                     ExtColorShd[threeD?1:num_sets][threeD?1:num_points]; // compiler limitation
00463         int                     ExtColorShd[num_sets][num_points];
00464 
00465         /* idiot checks */
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         // ----- get args  va number of float arrays -----
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         /* ----- highest & lowest values ----- */
00491         if( GDC_stack_type == GDC_STACK_SUM )           // need to walk sideways
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 )         // need to walk sideways
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 )                                                            // for now only one combo set allowed
00533                 {
00534                 // vhighest = 1.0;
00535                 // vlowest  = 0.0;
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 )                     // no values
00543                         vhighest = 1.0;                                         // for scaling, need a range
00544                 else
00545                 if( vhighest < 0.0 )
00546                         vhighest = 0.0;
00547                 if( vlowest > 0.0 || vlowest == MAXFLOAT )
00548                         vlowest = 0.0;                                          // vol should always start at 0
00549                 }
00550 
00551         if( lowest == MAXFLOAT )
00552                 lowest = 0.0;
00553         if( highest == -MAXFLOAT )
00554                 highest = 1.0;                                                  // need a range
00555         if( type == GDC_AREA  ||                                        // bars and area should always start at 0
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 )                                              // negs should be drawn from 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         /* ----- graph height and width within the gif height width ----- */
00572         /* grapheight/height is the actual size of the scalable graph */
00573         {
00574         int     title_hgt  = GDC_title? 2                               /* title? horizontal text line(s) */
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 +                                                                                     /* space to note */
00602                                         (1+GDC_fontc[GDC_annotation_font].h) *          /* number of '\n' substrs */
00603                                         cnt_nl(GDC_annotation->note,&annote_len) +
00604                                         1 +                                                                                     /* space under note */
00605                                         2: 0;                                                                           /* space to chart */
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                                                                                                                                 // longest "...\n" segment
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 );                          // last seg
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 )                              /* user wants to use his */
00636                 grapheight = GDC_hard_grapheight;
00637         GDC_hard_grapheight = grapheight;
00638                                                                                                                         // before width can be known...
00639         /* ----- y labels intervals ----- */
00640         {
00641         float   tmp_highest;
00642                                                                                                                         /* possible y gridline points */
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                                                                                                                         /* maximum y lables that'll fit... */
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                 /* gdImageDestroy(im);          haven't yet created it */
00657                 out_err( GIFWIDTH, GIFHEIGHT,
00658                                  gif_fptr,
00659                                  GDC_BGColor, GDC_LineColor,
00660                                  "Insificient Height" );
00661                 return 2;
00662                 }
00663 
00664                                                                                                                 /* one "space" interval above + below */
00665         for( i=1; i<NUM_YPOINTS; ++i )
00666                 // if( ypoints[i] > ylbl_interval )
00667                 //      break;
00668                 if( (highest-lowest)/ypoints[i] < ((float)max_num_ylbls-(1.0+1.0))
00669                                                                                         * (float)GDC_ylabel_density/100.0 )
00670                         break;
00671         /* gotta go through the above loop to catch the 'tweeners :-| */
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                                                                                                                 /* perform floating point remainders */
00678                                                                                                                 /* gonculate largest interval-point < lowest */
00679         if( lowest != 0.0 &&
00680                 lowest != GDC_requested_ymin )
00681                 {
00682                 if( lowest < 0.0 )
00683                         lowest -= ylbl_interval;
00684                 // lowest = (lowest-ypoints[0]) -
00685                 //                      ( ( ((lowest-ypoints[0])/ylbl_interval)*ylbl_interval ) -
00686                 //                         ( (float)((int)((lowest-ypoints[0])/ylbl_interval))*ylbl_interval ) );
00687                 lowest = ylbl_interval * (float)(int)((lowest-ypoints[0])/ylbl_interval);
00688                 }
00689                                                                                                                 /* find smallest interval-point > highest */
00690         tmp_highest = lowest;
00691         do      // while( (tmp_highest += ylbl_interval) <= highest )
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                         {                                                                                       /* XPG2 compatibility */
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                                                                                                                         /* no skyscrapers */
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 )                              /* user wants to use his */
00743                 graphwidth = GDC_hard_graphwidth;
00744         GDC_hard_graphwidth = graphwidth;
00745 
00746         /* ----- scale to gif size ----- */
00747         /* offset to 0 at lower left (where it should be) */
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 //      yorig = (float)grapheight + ABS(yscl * lowest) + ydepth_3Dtotal + title_hgt;
00769         yorig = (float)grapheight
00770                                 + ABS(yscl) * MIN(lowest,highest)
00771                                 + ydepth_3Dtotal
00772                                 + title_hgt
00773                                 + annote_hgt;
00774 //????  if( GDC_hard_size && GDC_hard_yorig )                                   /* vyorig too? */
00775 //????          yorig = GDC_hard_yorig;
00776         GDC_hard_yorig = yorig;
00777 
00778         hlf_barwdth     = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_bar_width/100.0)/2.0) );   // used only for bars
00779         hlf_hlccapwdth  = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_HLC_cap_width/100.0)/2.0) );
00780         }
00781         // scaled, sized, ready
00782 
00783 
00784         /* ----- OK start the graphic ----- */
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 //      ArrowDColor    = gdImageColorAllocate( im, 0xFF,    0, 0 );
00806 //      ArrowUColor    = gdImageColorAllocate( im,    0, 0xFF, 0 );
00807         if( GDC_annotation )
00808                 AnnoteColor = clrallocate( im, GDC_annotation->color );
00809 
00810         /* attempt to import optional background image */
00811         if( GDC_BGImage )
00812                 {
00813                 FILE    *in = fopen(GDC_BGImage, "rb");
00814                 if( !in )
00815                         {
00816                         ; // Cant load background image, drop it
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 ||                             // resize only if too big
00827                                         gdImageSY(bg_img) > GIFHEIGHT )                         //  [and center]
00828                                         {
00829                                         gdImageCopyResized( im, bg_img,                         // dst, src
00830                                                                                 bgxpos, bgypos,                 // dstX, dstY
00831                                                                                 0, 0,                                   // srcX, srcY
00832                                                                                 GIFWIDTH, GIFHEIGHT,    // dstW, dstH
00833                                                                                 GIFWIDTH, GIFHEIGHT );  // srcW, srcH
00834                                         }
00835                                 else                                                                                    // just center
00836                                         gdImageCopy( im, bg_img,                                        // dst, src
00837                                                                  bgxpos, bgypos,                                // dstX, dstY
00838                                                                  0, 0,                                                  // srcX, srcY
00839                                                                  GIFWIDTH, GIFHEIGHT );                 // W, H
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         /* ----- start drawing ----- */
00901         /* ----- backmost first - grid & labels ----- */
00902         if( GDC_grid || GDC_yaxis )
00903                 {       /* grid lines & y label(s) */
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                 /* step from lowest to highest puting in labels and grid at interval points */
00911                 /* since now "odd" intervals may be requested, try to step starting at 0,   */
00912                 /* if lowest < 0 < highest                                                  */
00913                 for( i=-1; i<=1; i+=2 )                                                                 // -1, 1
00914                         {
00915                         if( i == -1 )   if( lowest >= 0.0 )                                     //      all pos plotting
00916                                                                 continue;
00917                                                         else
00918                                                                 tmp_y = MIN( 0, highest );              //      step down to lowest
00919 
00920                         if( i == 1 )    if( highest <= 0.0 )                            //      all neg plotting
00921                                                                 continue;
00922                                                         else
00923                                                                 tmp_y = MAX( 0, lowest );               //      step up to highest
00924 
00925 
00926 //                      if( !(highest > 0 && lowest < 0) )                                      // doesn't straddle 0
00927 //                              {
00928 //                              if( i == -1 )                                                                   // only do once: normal
00929 //                                      continue;
00930 //                              }
00931 //                      else
00932 //                              tmp_y = 0;
00933 
00934                         do      // while( (tmp_y (+-)= ylbl_interval) < [highest,lowest] )
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                                         // int  gridline_clr = tmp_y == 0.0? LineColor: GridColor;
00954                                                                                                                                                 // tics
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;                     // backmost
00960                                         x2 = PX(0);             y2 = PY(tmp_y);                                         // w/ new setno
00961                                         gdImageLine( im, x1, y1, x2, y2, GridColor );           // depth for 3Ds
00962                                         gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, GridColor );
00963                                         setno = 0;                                                                                      // set back to foremost
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                                                                                                                                                                 /* opposite of PV(y) */
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; // backmost
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 )                                                                        /* rounding can cause -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                 /* catch last (bottom) grid line - specific to an "off" requested interval */
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;                     // backmost
01050                         gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), GridColor );
01051                         setno = 0;                                                                                      // set back to foremost
01052                         }
01053 
01054                 /* vy axis title */
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                 /* y axis title */
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         /* interviening set grids */
01084         /*  0 < setno < num_sets   non-inclusive, they've already been covered */
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 ) &&                                                       /* line color grid at 0 */
01098                 ( (lowest < 0.0 && highest > 0.0) ||
01099                   (lowest < 0.0 && highest > 0.0) ) )
01100                 {
01101                 int     x1, x2, y1, y2;
01102                                                                                                                                 // tics
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;                             // backmost
01108                 x2 = PX(0);             y2 = PY(0);                                                             // w/ new setno
01109                 gdImageLine( im, x1, y1, x2, y2, LineColor );                   // depth for 3Ds
01110                 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, LineColor );
01111                 setno = 0;                                                                                              // set back to foremost
01112                 }
01113 
01114 
01115         /* x ticks and xlables */
01116         if( GDC_grid || GDC_xaxis )
01117                 {
01118                 int             num_xlbls =                                                                             /* maximum x lables that'll fit */
01119                                                                                                                                 /* each xlbl + avg due to num_lf_xlbls */
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) ||                                        // # x labels are regulated
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                                                                                                                                                 // tics
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; // backmost
01142                                         x2 = PX(i);             y2 = PY(lowest);
01143                                         gdImageLine( im, x1, y1, x2,  y2, GridColor );          // depth perspective
01144                                         gdImageLine( im, x2, y2, x2,  PY(highest), GridColor );
01145                                         setno = 0;                                                                                      // reset to foremost
01146                                         }
01147 
01148                                 if( !do_bar || (i>0 && xi<num_points) )
01149                                         if( GDC_xaxis && xlbl && xlbl[xi] && *(xlbl[xi]) )
01150                                                 {
01151                                                 /* waiting for GDCImageStringUpNL() */
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 //                                              int             xlbl_strt = -1+ PX((float)i+(float)(do_bar?((float)num_points/(float)num_xlbls):0.0)) - (int)((float)(LBX.h-2)*((float)xstrs_num/2.0));
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         /* ----- solid poly region (volume) ----- */
01187         /*  so that grid lines appear under solid */
01188         if( do_vol )
01189                 {
01190                 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets:
01191                                                                                                                            num_sets:
01192                                                                                                  1; // backmost
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                 }               // volume polys done
01232 
01233         if( GDC_annotation && threeD )          /* back half of annotation line */
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; // backmost
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         /* ---------- start plotting the data ---------- */
01247         switch( type )
01248                 {
01249                 case GDC_3DBAR:                                 /* depth, width, y interval need to allow for whitespace between bars */
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 )              // back sets first   PX, PY depth
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 //                              for( i=0; i<num_points; ++i )
01271 //                                      if( uvals[j][i] != GDC_NOVALUE )
01272 //                                              {
01273 //                                              lasty[i] = uvals[j][i];
01274 //                                              draw_3d_bar( im, PX(i+(do_bar?1:0))-hlf_barwdth, PX(i+(do_bar?1:0))+hlf_barwdth,
01275 //                                                                               PY(0), PY(uvals[j][i]),
01276 //                                                                               xdepth_3D, ydepth_3D,
01277 //                                                                               ExtColor[j][i],
01278 //                                                                               threeD? ExtColorShd[j][i]: ExtColor[j][i] );
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                                 {                                                                                               // h/.5, h/1, h/1.5, h/2, ...
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 )                       // all same plane
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];        /* fred */
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:                                                          // behind w/o depth
01465                                 for( j=num_sets-1; j>=0; --j )                                  // back sets 1st  (setno = 0)
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 )              // back sets first   PX, PY depth
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) &&                 // bottom half of 'I'
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                                                                                                                                          // all HLC have vert line
01509                                          if( uvals[LOWSET+j*3][i-1] != GDC_NOVALUE )
01510                                                  {                                                                                      // bottom 'half'
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                                                  {                                                                                      // top 'half'
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                                                                                                                                         // line at close
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                                                                                                                                  // top half 'I'
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 )  /* line from prev close */
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   // CLOSE_CONNECTED and CONNECTING are mutually exclusive
01554                                                  if( GDC_HLC_style & GDC_HLC_CONNECTING )       /* thin connecting line */
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,                                    // rem only 1 set
01562                                                                                    xdepth_3D, ydepth_3D,
01563                                                                                    1,
01564                                                                                    &(ExtColor[CLOSESET+j*3][i]),
01565                                                                                    &(ExtColorShd[CLOSESET+j*3][i]) );
01566                                                                                                                                          // edge font of it
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                                                                                                                                          // top half 'I' again
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                                                  {                                                                      // front
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                                                                                                                          // bottom side
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                                                  // gdImagePolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] );
01602                                                                                                                          // top side
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                                                 {                                                                                       /* all HLC have vert line */
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 )   // line from prev close
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    // CLOSE_CONNECTED and CONNECTING are mutually exclusive
01662                                                 if( GDC_HLC_style & GDC_HLC_CONNECTING )                // thin connecting line
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         /* ---------- scatter points  over all other plots ---------- */
01673         /* scatters, by their very nature, don't lend themselves to standard array of points */
01674         /* also, this affords the opportunity to include scatter points onto any type of chart */
01675         /* drawing of the scatter point should be an exposed function, so the user can */
01676         /*  use it to draw a legend, and/or add their own */
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 ||                             // invalid point
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 // overlay with a value and an arrow (e.g., total daily change)
01732 #ifdef THUMB_VALS
01733         /* put thmbl and thumbval over vol and plot lines */
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                                          +     // up/down arrow
01756                                                                    (w?strlen(whole)*SFONTWDTH: 0) +     // whole
01757                                                                    (n?strlen(nmrtr)*TFONTWDTH     +     // numerator
01758                                                                           SFONTWDTH                                       +     // /
01759                                                                           strlen(dmntr)*TFONTWDTH:              // denominator
01760                                                                           0);                                                   // no frac part
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)   +    // start
01777                                                            SFONTWDTH                                       +    // arrow
01778                                                            (w? strlen(whole)*SFONTWDTH: 0) +    // whole
01779                                                            2,
01780                                                            SFONTHGT+2-2,
01781                                                            nmrtr,
01782                                                            chgcolor );
01783                                 gdImageChar  ( im,
01784                                                            gdFontSmall,
01785                                                            (graphwidth/2-thmbvalwidth/2)  +             // start
01786                                                            SFONTWDTH                                      +             // arrow
01787                                                            (w? strlen(whole)*SFONTWDTH: 0) +    // whole
01788                                                            strlen(nmrtr)*TFONTWDTH,                             // numerator
01789                                                            SFONTHGT+2,
01790                                                            '/',
01791                                                            chgcolor );
01792                                 gdImageString( im,
01793                                                            gdFontTiny,
01794                                                            (graphwidth/2-thmbvalwidth/2)  +             // start
01795                                                            SFONTWDTH                                      +             // arrow
01796                                                            (w? strlen(whole)*SFONTWDTH: 0) +            // whole
01797                                                            strlen(nmrtr)*TFONTWDTH                +             // numerator
01798                                                            SFONTWDTH - 3,                                               // /
01799                                                            SFONTHGT+2+4,
01800                                                            dmntr,
01801                                                            chgcolor );
01802                                 }
01803                         }
01804                 }               // thumblabel, thumbval
01805 #endif
01806 
01807         /* box it off */
01808         /*  after plotting so the outline covers any plot lines */
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                 // if( !GDC_grid || do_vol || GDC_thumbnail )                                   // grid leaves right side Y open
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 &&                                                             /* front of 0 shelf */
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 );             // front line
01846                 setno = GDC_stack_type==GDC_STACK_DEPTH? num_hlc_sets? num_hlc_sets: num_sets:
01847                                                                                                  1;                             // backmost
01848                                                                                                                                 // depth for 3Ds
01849                 gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), PY(0), LineColor );
01850                 setno = 0;                                                                                              // set back to foremost
01851                 }
01852 
01853         if( GDC_annotation )                    /* front half of annotation line */
01854                 {
01855                 int             x1 = PX(GDC_annotation->point+(do_bar?1:0)),
01856                                 y1 = PY(highest);
01857                 int             x2;
01858                                                                                                                         // front line
01859                 gdImageLine( im, x1, PY(lowest)+1, x1, y1, AnnoteColor );
01860                 if( threeD )
01861                         {                                                                                               // on back plane
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                                                                                                                         // prspective line
01865                         gdImageLine( im, x1, y1, x2, PY(highest), AnnoteColor );
01866                         }
01867                 else                                                                                            // for 3D done with back line
01868                         {
01869                         x2 = PX(GDC_annotation->point+(do_bar?1:0));
01870                         gdImageLine( im, x1, y1, x1, y1-2, AnnoteColor );
01871                         }
01872                 /* line-to and note */
01873                 if( *(GDC_annotation->note) )                                           // any note?
01874                         {
01875                         if( GDC_annotation->point >= (num_points/2) )           /* note to the left */
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                                                                                            /* note to right */
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         /* usually GDC_generate_gif is used in conjunction with hard or hold options */
01907         if( GDC_generate_gif )
01908                 {
01909                 fflush(gif_fptr);                       // clear anything buffered 
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 }


Variable Documentation

EXTERND char* GDC_thumblabel

Definition at line 103 of file gdchart.h.

EXTERND char* GDC_title

Definition at line 73 of file gdchart.h.

EXTERND char* GDC_xtitle

Definition at line 71 of file gdchart.h.

EXTERND char* GDC_ytitle

Definition at line 70 of file gdchart.h.

EXTERND char* GDC_ytitle2

Definition at line 72 of file gdchart.h.


Generated on Sat Dec 15 00:01:28 2007 for BulmaGes by  doxygen 1.5.1