+void
+pie_part(image_desc_t *im, gfx_color_t color,
+ double PieCenterX, double PieCenterY, double Radius,
+ double startangle, double endangle)
+{
+ gfx_node_t *node;
+ double angle;
+ double step=M_PI/50; /* Number of iterations for the circle;
+ ** 10 is definitely too low, more than
+ ** 50 seems to be overkill
+ */
+
+ /* Strange but true: we have to work clockwise or else
+ ** anti aliasing nor transparency don't work.
+ **
+ ** This test is here to make sure we do it right, also
+ ** this makes the for...next loop more easy to implement.
+ ** The return will occur if the user enters a negative number
+ ** (which shouldn't be done according to the specs) or if the
+ ** programmers do something wrong (which, as we all know, never
+ ** happens anyway :)
+ */
+ if (endangle<startangle) return;
+
+ /* Hidden feature: Radius decreases each full circle */
+ angle=startangle;
+ while (angle>=2*M_PI) {
+ angle -= 2*M_PI;
+ Radius *= 0.8;
+ }
+
+ node=gfx_new_area(im->canvas,
+ PieCenterX+sin(startangle)*Radius,
+ PieCenterY-cos(startangle)*Radius,
+ PieCenterX,
+ PieCenterY,
+ PieCenterX+sin(endangle)*Radius,
+ PieCenterY-cos(endangle)*Radius,
+ color);
+ for (angle=endangle;angle-startangle>=step;angle-=step) {
+ gfx_add_point(node,
+ PieCenterX+sin(angle)*Radius,
+ PieCenterY-cos(angle)*Radius );
+ }
+}
+
+int
+graph_size_location(image_desc_t *im, int elements, int piechart )
+{
+ /* The actual size of the image to draw is determined from
+ ** several sources. The size given on the command line is
+ ** the graph area but we need more as we have to draw labels
+ ** and other things outside the graph area
+ */
+
+ /* +-+-------------------------------------------+
+ ** |l|.................title.....................|
+ ** |e+--+-------------------------------+--------+
+ ** |b| b| | |
+ ** |a| a| | pie |
+ ** |l| l| main graph area | chart |
+ ** |.| .| | area |
+ ** |t| y| | |
+ ** |r+--+-------------------------------+--------+
+ ** |e| | x-axis labels | |
+ ** |v+--+-------------------------------+--------+
+ ** | |..............legends......................|
+ ** +-+-------------------------------------------+
+ */
+ int Xvertical=0, Yvertical=0,
+ Xtitle =0, Ytitle =0,
+ Xylabel =0, Yylabel =0,
+ Xmain =0, Ymain =0,
+ Xpie =0, Ypie =0,
+ Xxlabel =0, Yxlabel =0,
+#if 0
+ Xlegend =0, Ylegend =0,
+#endif
+ Xspacing =10, Yspacing =10;
+
+ if (im->ylegend[0] != '\0') {
+ Xvertical = im->text_prop[TEXT_PROP_LEGEND].size *2;
+ Yvertical = im->text_prop[TEXT_PROP_LEGEND].size * (strlen(im->ylegend)+1);
+ }
+
+ if (im->title[0] != '\0') {
+ /* The title is placed "inbetween" two text lines so it
+ ** automatically has some vertical spacing. The horizontal
+ ** spacing is added here, on each side.
+ */
+ Xtitle = gfx_get_text_width(im->canvas, 0,
+ im->text_prop[TEXT_PROP_TITLE].font,
+ im->text_prop[TEXT_PROP_TITLE].size,
+ im->tabwidth,
+ im->title) + 2*Xspacing;
+ Ytitle = im->text_prop[TEXT_PROP_TITLE].size*2;
+ }
+
+ if (elements) {
+ Xmain=im->xsize;
+ Ymain=im->ysize;
+ if (im->draw_x_grid) {
+ Xxlabel=Xmain;
+ Yxlabel=im->text_prop[TEXT_PROP_LEGEND].size *2;
+ }
+ if (im->draw_y_grid) {
+ Xylabel=im->text_prop[TEXT_PROP_LEGEND].size *6;
+ Yylabel=Ymain;
+ }
+ }
+
+ if (piechart) {
+ im->piesize=im->xsize<im->ysize?im->xsize:im->ysize;
+ Xpie=im->piesize;
+ Ypie=im->piesize;
+ }
+
+ /* Now calculate the total size. Insert some spacing where
+ desired. im->xorigin and im->yorigin need to correspond
+ with the lower left corner of the main graph area or, if
+ this one is not set, the imaginary box surrounding the
+ pie chart area. */
+
+ /* The legend width cannot yet be determined, as a result we
+ ** have problems adjusting the image to it. For now, we just
+ ** forget about it at all; the legend will have to fit in the
+ ** size already allocated.
+ */
+ im->ximg = Xylabel + Xmain + Xpie + Xspacing;
+ if (Xmain) im->ximg += Xspacing;
+ if (Xpie) im->ximg += Xspacing;
+ im->xorigin = Xspacing + Xylabel;
+ if (Xtitle > im->ximg) im->ximg = Xtitle;
+ if (Xvertical) {
+ im->ximg += Xvertical;
+ im->xorigin += Xvertical;
+ }
+ xtr(im,0);
+
+ /* The vertical size is interesting... we need to compare
+ ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend} with Yvertical
+ ** however we need to know {Ytitle+Ymain+Yxlabel} in order to
+ ** start even thinking about Ylegend.
+ **
+ ** Do it in three portions: First calculate the inner part,
+ ** then do the legend, then adjust the total height of the img.
+ */
+
+ /* reserve space for main and/or pie */
+ im->yimg = Ymain + Yxlabel;
+ if (im->yimg < Ypie) im->yimg = Ypie;
+ im->yorigin = im->yimg - Yxlabel;
+ /* reserve space for the title *or* some padding above the graph */
+ if (Ytitle) {
+ im->yimg += Ytitle;
+ im->yorigin += Ytitle;
+ } else {
+ im->yimg += Yspacing;
+ im->yorigin += Yspacing;
+ }
+ /* reserve space for padding below the graph */
+ im->yimg += Yspacing;
+ ytr(im,DNAN);
+
+ /* Determine where to place the legends onto the image.
+ ** Adjust im->yimg to match the space requirements.
+ */
+ if(leg_place(im)==-1)
+ return -1;
+
+ /* last of three steps: check total height of image */
+ if (im->yimg < Yvertical) im->yimg = Yvertical;
+
+#if 0
+ if (Xlegend > im->ximg) {
+ im->ximg = Xlegend;
+ /* reposition Pie */
+#endif
+
+ /* The pie is placed in the upper right hand corner,
+ ** just below the title (if any) and with sufficient
+ ** padding.
+ */
+ if (elements) {
+ im->pie_x = im->ximg - Xspacing - Xpie/2;
+ im->pie_y = im->yorigin-Ymain+Ypie/2;
+ } else {
+ im->pie_x = im->ximg/2;
+ im->pie_y = im->yorigin-Ypie/2;
+ }
+
+ return 0;
+}