/********************************************************************
This file is part of the abs 0.907 distribution. abs is a spreadsheet
with graphical user interface.
Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version if in the same spirit as version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Concact: abs@pi.be
http://home.pi.be/bertin/abs.shtml
*********************************************************************/
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Intrinsic.h>
#include "plot.h"
#include <math.h>
#include <stdio.h>
#include "plot.h"
#include "graphic_gvar.h"
#include "graph.h"
#include "gr_interf.h"
#ifndef PI
#define PI 3.14
#endif
#ifdef mips
#define irint(x) rint(x)
#endif
#ifndef irint
#define irint(x) floor((x)+0.5)
#endif
extern char *textparsing (char *buf);
int D;
int curfontwidth, curfontheight;
#define Nwidths 10
unsigned int widths[Nwidths] =
{2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#define Ndashes 10
char dashes[Ndashes][5];
int plotcol[10] =
{20 + 5, 2 + 5, 17 + 5, 25 + 4, 27 + 4, 29 + 4, 31 + 4, 1 + 4, 24 + 4, 20 + 4};
enum JUSTIFY
{
LEFT, CENTRE, RIGHT
}
jmode;
extern int getpixmap ();
extern double get_value ();
extern char *get_text ();
static Pixmap gpixmap;
static Display *gdpy;
static Graph *ggr;
static int X0, Y0;
static double grvalue[10][100];
static char grtext[100][32];
static int imax, jmax;
int
newplot (Widget drawa, Graph * gr)
{
int gX, gY, W, H;
ggr = gr;
if (ggr == NULL)
return -1;
if (ggr->pixmap == 0)
return -2;
getpixmap (gr, &gX, &gY, &W, &H);
gpixmap = gr->pixmap;
X0 = gX;
Y0 = gY;
WIN_W = W;
WIN_H = H;
RECT_X = 40;
RECT_Y = 40;
RECT_W = W - 80;
RECT_H = H - 80;
D = 8;
gdpy = XtDisplay (drawa);
setfont2 (0, 1, 0, 2);
curfontheight = gettexth ("W", 1, 1, 0, 2);
curfontwidth = gettextw ("W", 1, 1, 0, 2);
fillrectangle (gdpy, gpixmap, 0, 0, 0, W, H, X0, Y0, -1);
setbackground (0, 0);
setforeground (0, 1);
drawrectangle (gdpy, gpixmap, 0, 0, 0, W, H, X0, Y0);
set_grvalue ();
switch (gr->type)
{
case 0:
plot_XY ();
break;
case 1:
plot_pie ();
break;
case 2:
plot_bar ();
break;
default:
plot_XY ();
break;
}
return 0;
}
int
set_grvalue ()
{
int ii, jj, i, j;
char *buf;
jmax = 0;
if (ggr->numrange == 1)
{
jj = 0;
for (i = (ggr->range[0]).i1; i <= (ggr->range[0]).i2; i++)
{
for (j = (ggr->range[0]).j1; j <= (ggr->range[0]).j2; j++)
{
if (jj < 100)
{
grvalue[1][jj] = get_value (i, j);
grvalue[0][jj] = jj + 1;
buf = get_text (i, j);
if (buf != NULL)
if (strlen (buf) > 0)
strncpy (grtext[jj], buf, 30);
j++;
}
if (jj > jmax)
jmax = jj;
}
}
imax = 2;
}
else if (ggr->numrange > 1)
{
for (ii = 0; ii < ggr->numrange && ii < 10; ii++)
{
jj = 0;
for (i = (ggr->range[ii]).i1; i <= (ggr->range[ii]).i2; i++)
{
for (j = (ggr->range[ii]).j1; j <= (ggr->range[ii]).j2; j++)
{
if (jj < 100 && ii < 11)
{
grvalue[ii][jj] = get_value (i, j);
if (ii == 0)
{
buf = get_text (i, j);
if (buf != NULL)
if (strlen (buf) > 0)
strncpy (grtext[jj], buf, 30);
}
jj++;
}
if (jj > jmax)
jmax = jj;
}
}
}
imax = ii;
}
return 0;
}
int
plot_XY ()
{
double x_max, x_min, y_max, y_min, x_unit, y_unit;
double x_range, y_range;
double y_power, x_power;
double xx, yy, x0, y0;
char label[256];
int i, j, k, len;
int grid_l_x, grid_l_y, grid_w, grid_h;
int text_w;
int legend_n;
int x, y, x1 = 0, y1 = 0;
int first_point;
double pv;
double xentv, yentv;
int cells = 0;
int cheight;
char str[100];
x_max = x_min = grvalue[0][0];
for (j = 1; j < jmax; j++)
{
pv = grvalue[0][j];
cells++;
x_max = Max (x_max, pv);
x_min = Min (x_min, pv);
}
if (cells < 2)
{
return -1;
}
y_max = y_min = grvalue[1][0];
for (i = 1; i < imax; i++)
{
for (j = 0; j <= jmax; j++)
{
pv = grvalue[i][j];
y_max = Max (y_max, pv);
y_min = Min (y_min, pv);
}
}
x_power = -floor (log10 ((x_max - x_min)));
y_power = -floor (log10 ((y_max - y_min)));
x_power = pow10 (x_power);
y_power = pow10 (y_power);
x_min = floor (x_min * x_power) / x_power;
x_max = ceil (x_max * x_power) / x_power;
y_min = floor (y_min * y_power) / y_power;
y_max = ceil (y_max * y_power) / y_power;
x_unit = (x_max - x_min) / (jmax - 1);
y_unit = (y_max - y_min) / 10;
if (!ggr->Axes[xlCategory].MinimumScaleIsAuto)
x_min = ggr->Axes[xlCategory].MinimumScale;
else
ggr->Axes[xlCategory].MinimumScale = x_min;
if (!ggr->Axes[xlCategory].MaximumScaleIsAuto)
x_max = ggr->Axes[xlCategory].MaximumScale;
else
ggr->Axes[xlCategory].MaximumScale = x_max;
if (!ggr->Axes[xlCategory].MajorUnitIsAuto)
x_unit = ggr->Axes[xlCategory].MajorUnit;
else
ggr->Axes[xlCategory].MajorUnit = x_unit;
if (!ggr->Axes[xlValue].MinimumScaleIsAuto)
y_min = ggr->Axes[xlValue].MinimumScale;
else
ggr->Axes[xlValue].MinimumScale = y_min;
if (!ggr->Axes[xlValue].MaximumScaleIsAuto)
y_max = ggr->Axes[xlValue].MaximumScale;
else
ggr->Axes[xlValue].MaximumScale = y_max;
if (!ggr->Axes[xlValue].MajorUnitIsAuto)
y_unit = ggr->Axes[xlValue].MajorUnit;
else
ggr->Axes[xlValue].MajorUnit = y_unit;
x_range = x_max - x_min;
y_range = y_max - y_min;
pad = PLBORDER;
bw = 1;
drawrectangle (gdpy, gpixmap, 1, RECT_X, RECT_Y, RECT_W, RECT_H, X0, Y0);
grid_l_x = 5;
grid_l_y = 5;
if (ggr->Axes[xlValue].HasMajorGridLines)
{
grid_l_x = RECT_W;
}
if (ggr->Axes[xlCategory].HasMajorGridLines)
{
grid_l_y = RECT_H;
}
grid_w = RECT_W;
grid_h = RECT_H;
xx = x_min;
while (xx <= x_max && x_min != x_max)
{
x0 = (xx - x_min) / x_range * grid_w;
x = (int) x0;
if (xx > x_min && xx < x_max)
{
drawline (gdpy, gpixmap, 2,
RECT_X + x, RECT_Y + 1,
RECT_X + x, RECT_Y + grid_l_y,
X0, Y0);
drawline (gdpy, gpixmap, 2, RECT_X + x, RECT_Y + RECT_H - 1,
RECT_X + x, RECT_Y + RECT_H - grid_l_y,
X0, Y0);
}
sprintf (str, "%g", xx);
len = strlen (str);
cheight = gettexth (str, len, 1, 0, 2);
text_w = gettextw (str, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1, RECT_X + x - text_w / 2,
RECT_H + RECT_Y * 8 / 6, str, len, X0, Y0);
xx += x_unit;
}
yy = y_min;
while (yy <= y_max && y_min != y_max)
{
y0 = (yy - y_min) / y_range * grid_h;
y = (int) y0;
if (yy > y_min && yy < y_max)
{
drawline (gdpy, gpixmap, 2,
RECT_X, RECT_Y + RECT_H - y,
RECT_X + grid_l_x, RECT_Y + RECT_H - y,
X0, Y0);
drawline (gdpy, gpixmap, 2,
RECT_X + RECT_W, RECT_Y + RECT_H - y,
RECT_X + RECT_W - grid_l_x, RECT_Y + RECT_H - y,
X0, Y0);
}
sprintf (str, "%g", yy);
len = strlen (str);
cheight = gettexth (str, len, 1, 0, 2);
text_w = gettextw (str, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1,
RECT_X - text_w * 8 / 6,
RECT_Y + RECT_H - y + curfontheight / 3,
str, len,
X0, Y0);
yy += y_unit;
}
if (ggr->HasTitle)
{
if (strlen (ggr->ChartTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->ChartTitle.Text));
else
strcpy (label, ggr->ChartTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1, (WIN_W - text_w) / 2, RECT_Y / 3,
label, len,
X0, Y0);
}
if (ggr->Axes[xlCategory].HasTitle)
{
if (strlen (ggr->Axes[xlCategory].AxisTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->Axes[xlCategory].AxisTitle.Text));
else
strcpy (label, ggr->Axes[xlCategory].AxisTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1,
(WIN_W - text_w) / 2, RECT_H + RECT_Y * 9 / 6 + curfontheight,
label, len,
X0, Y0);
}
if (ggr->Axes[xlValue].HasTitle)
{
if (strlen (ggr->Axes[xlValue].AxisTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->Axes[xlValue].AxisTitle.Text));
else
strcpy (label, ggr->Axes[xlValue].AxisTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
if ((RECT_X - text_w) < 0)
x = curfontwidth;
else
x = RECT_X - text_w;
drawimagestring (gdpy, gpixmap, 1,
x, RECT_Y - 2 * curfontheight,
label, len,
X0, Y0);
}
legend_n = 0;
curves_n = imax;
for (i = 1; i < imax; i++)
{
if (strlen ((ggr->range[i]).name) > 1)
strcpy (label, (char *) textparsing ((ggr->range[i]).name));
else
strcpy (label, (ggr->range[i]).name);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
if (imax == 2)
{
x = RECT_X + (RECT_W - text_w) / 2 - 25;
y = RECT_Y * 2 + RECT_H - curfontheight / 2;
switch (i - 1)
{
case 0:
DrawOpenSquare (x + 10, y, plotcol[i - 1]);
break;
case 1:
DrawOpenTriangle (x + 10, y, plotcol[i - 1]);
break;
case 2:
DrawOpenDiamon (x + 10, y, plotcol[i - 1]);
break;
case 3:
DrawCross (x + 10, y, plotcol[i - 1]);
break;
case 4:
DrawCloseSquare (x + 10, y, plotcol[i - 1]);
break;
case 5:
DrawCloseDiamon (x + 10, y, plotcol[i - 1]);
break;
}
drawline (gdpy, gpixmap, plotcol[i - 1],
x, y,
x + 20, y,
X0, Y0);
drawimagestring (gdpy, gpixmap, plotcol[i - 1],
RECT_X + (RECT_W - text_w) / 2, RECT_Y * 2 + RECT_H,
label, len,
X0, Y0);
break;
}
else
{
y = RECT_Y * 2 + RECT_H - curfontheight / 2;
switch (i - 1)
{
case 0:
DrawOpenSquare (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
case 1:
DrawOpenTriangle (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
case 2:
DrawOpenDiamon (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
case 3:
DrawCross (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
case 4:
DrawCloseSquare (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
case 5:
DrawCloseDiamon (RECT_X / 2 + legend_n * (WIN_W / curves_n - 10),
y, plotcol[i - 1]);
break;
}
drawline (gdpy, gpixmap, plotcol[i - 1],
RECT_X / 2 + legend_n * (WIN_W / curves_n - 10) - 10,
y,
RECT_X / 2 + legend_n * (WIN_W / curves_n - 10) + 10,
y,
X0, Y0);
drawimagestring (gdpy, gpixmap, plotcol[i - 1],
RECT_X / 2 + legend_n * (WIN_W / curves_n - 10) + 25,
y,
label, len,
X0, Y0);
legend_n++;
}
}
for (i = 1; i < imax; i++)
{
first_point = 1;
for (j = 0, k = 0; j < jmax && k < jmax; j++, k++)
{
xentv = grvalue[0][j];
if ((xentv < x_min) || (xentv > x_max))
continue;
yentv = grvalue[i][j];
if ((yentv < y_min) || (yentv > y_max))
continue;
if (first_point)
{
x1 = RECT_X + RECT_W * (xentv - x_min) / x_range;
y1 = RECT_Y + RECT_H - RECT_H * (yentv - y_min) / y_range;
if ((ggr->graphic_format[i] == grsymb) || (ggr->graphic_format[i] == grboth))
switch (i - 1)
{
case 0:
DrawOpenSquare (x1, y1, plotcol[i - 1]);
break;
case 1:
DrawOpenTriangle (x1, y1, plotcol[i - 1]);
break;
case 2:
DrawOpenDiamon (x1, y1, plotcol[i - 1]);
break;
case 3:
DrawCross (x1, y1, plotcol[i - 1]);
break;
case 4:
DrawCloseSquare (x1, y1, plotcol[i - 1]);
break;
case 5:
DrawCloseDiamon (x1, y1, plotcol[i - 1]);
break;
}
first_point = 0;
continue;
}
x = RECT_X + RECT_W * (xentv - x_min) / x_range;
y = RECT_Y + RECT_H - RECT_H * (yentv - y_min) / y_range;
if ((ggr->graphic_format[i] == grline) || (ggr->graphic_format[i] == grboth))
drawline (gdpy, gpixmap, plotcol[i - 1], x1, y1, x, y,
X0, Y0);
if ((ggr->graphic_format[i] == grsymb) || (ggr->graphic_format[i] == grboth))
switch (i - 1)
{
case 0:
DrawOpenSquare (x, y, plotcol[i - 1]);
break;
case 1:
DrawOpenTriangle (x, y, plotcol[i - 1]);
break;
case 2:
DrawOpenDiamon (x, y, plotcol[i - 1]);
break;
case 3:
DrawCross (x, y, plotcol[i - 1]);
break;
case 4:
DrawCloseSquare (x, y, plotcol[i - 1]);
break;
case 5:
DrawCloseDiamon (x, y, plotcol[i - 1]);
break;
}
x1 = x;
y1 = y;
}
}
return 0;
}
int
plot_pie ()
{
int i, j, len;
int text_w;
int X, Y, X1, Y1, Temp_X, Temp_Y;
double pv;
int cells = 0;
int slice;
double Range_Total = 0;
double Percentage = 0;
double Angle_Size = 0;
double Starting_Angle = 0;
double Rad_Angle = 0;
double Bisector_Angle = 0;
double Label_R = 0;
char label[256];
char str[100];
char per_str[10];
int PIE_D;
int PIE_R;
int col;
int a1, a2;
if (ggr->numrange > 1)
col = 1;
else
col = 0;
Range_Total = 0;
for (j = 0; j <= jmax; j++)
{
pv = grvalue[col][j];
cells++;
Range_Total = Range_Total + pv;
}
if (cells < 1)
{
return -1;
}
pad = PLBORDER;
bw = 1;
if (WIN_H > WIN_W)
PIE_D = WIN_W - 20;
else
PIE_D = WIN_H - 50;
if (WIN_H < 5)
return -1;
PIE_R = PIE_D / 2;
if (ggr->HasTitle)
{
if (strlen (ggr->ChartTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->ChartTitle.Text));
else
strcpy (label, ggr->ChartTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1, (WIN_W - text_w) / 2, RECT_Y / 3,
label, len,
X0, Y0);
}
Starting_Angle = 0;
slice = 1;
for (j = 0; j < jmax; j++)
{
pv = grvalue[col][j];
Percentage = (pv / Range_Total);
Angle_Size = Percentage * 360;
i = slice;
while (i > 9)
i -= 10;
setforeground (0, plotcol[i]);
i = slice;
while (i > 9)
i -= 10;
setforeground (0, plotcol[i]);
a1 = Starting_Angle * 64;
a2 = Angle_Size * 64;
fillarc (gdpy, gpixmap, plotcol[slice - 1],
(WIN_W / 2) - (PIE_R), (WIN_H / 2) - (PIE_R) + 10, PIE_D, PIE_D,
a1, a2, X0, Y0);
setforeground (0, 1);
setfillstyle (gdpy, 1, FillSolid);
Rad_Angle = (Starting_Angle) * PI / 180;
Temp_X = (PIE_R) * cos (Rad_Angle);
Temp_Y = -((PIE_R) * sin (Rad_Angle));
X = Temp_X + (WIN_W / 2);
Y = Temp_Y + (WIN_H / 2) + 10;
drawline (gdpy, gpixmap, 1, WIN_W / 2, (WIN_H / 2 + 10), X, Y,
X0, Y0);
setfillstyle (gdpy, 0, FillSolid);
drawarc (gdpy, gpixmap, 1, (WIN_W / 2) - (PIE_R), (WIN_H / 2) - (PIE_R) + 10,
PIE_D, PIE_D, 0, 360 * 64, X0, Y0);
Label_R = PIE_R - (PIE_R / 4);
Bisector_Angle = (Starting_Angle) + (Angle_Size / 2);
Rad_Angle = Bisector_Angle * PI / 180;
Temp_X = (Label_R) * cos (Rad_Angle);
Temp_Y = -((Label_R) * sin (Rad_Angle));
X1 = Temp_X + (WIN_W / 2);
Y1 = Temp_Y + (WIN_H / 2) + 10;
if (col > 0)
sprintf (str, "%s", grtext[j]);
else
str[0] = '\0';
sprintf (per_str, "%.0f", (Percentage * 100));
strcat (str, " (");
strcat (str, per_str);
strcat (str, "%)");
len = strlen (str);
text_w = gettextw (str, len, 1, 0, 2);
if ((Bisector_Angle > 90) && (Bisector_Angle <= 270))
X = X1 - text_w;
else
X = X1;
Y = Y1 + curfontheight / 2;
drawimagestring (gdpy, gpixmap, 1, X, Y, str, len,
X0, Y0);
Starting_Angle = (Starting_Angle) + (Angle_Size);
slice++;
}
return 0;
}
void
DrawOpenDiamon (x, y, col)
short x, y, col;
{
XPoint points[5];
points[0].x = x;
points[0].y = y - 3;
points[1].x = 3;
points[1].y = 3;
points[2].x = -3;
points[2].y = 3;
points[3].x = -3;
points[3].y = -3;
points[4].x = 3;
points[4].y = -3;
drawlines (gdpy, gpixmap, col, points, 5, CoordModePrevious, X0, Y0);
}
void
DrawCloseDiamon (x, y, col)
short x, y, col;
{
XPoint points[12];
points[0].x = x;
points[0].y = y;
points[1].x = -2;
points[1].y = 0;
points[2].x = 4;
points[2].y = 0;
points[3].x = -2;
points[3].y = 0;
points[4].x = 0;
points[4].y = -2;
points[5].x = 0;
points[5].y = 4;
points[6].x = 0;
points[6].y = -2;
points[7].x = 1;
points[7].y = 1;
points[8].x = -2;
points[8].y = -2;
points[9].x = 1;
points[9].y = 1;
points[10].x = -1;
points[10].y = 1;
points[11].x = 2;
points[11].y = -2;
drawlines (gdpy, gpixmap, col, points, 12, CoordModePrevious, X0, Y0);
}
void
DrawOpenSquare (x, y, col)
short x, y, col;
{
XPoint points[5];
points[0].x = x - 2;
points[0].y = y - 2;
points[1].x = 4;
points[1].y = 0;
points[2].x = 0;
points[2].y = 4;
points[3].x = -4;
points[3].y = 0;
points[4].x = 0;
points[4].y = -4;
drawlines (gdpy, gpixmap, col, points, 5, CoordModePrevious, X0, Y0);
}
void
DrawCloseSquare (x, y, col)
short x, y, col;
{
XPoint points[9];
points[0].x = x - 2;
points[0].y = y - 2;
points[1].x = 4;
points[1].y = 0;
points[2].x = 0;
points[2].y = 4;
points[3].x = -4;
points[3].y = 0;
points[4].x = 0;
points[4].y = -4;
points[5].x = 4;
points[5].y = 4;
points[6].x = -2;
points[6].y = -2;
points[7].x = -2;
points[7].y = 2;
points[8].x = 4;
points[8].y = -4;
drawlines (gdpy, gpixmap, col, points, 9, CoordModePrevious, X0, Y0);
}
void
DrawOpenTriangle (x, y, col)
short x, y, col;
{
XPoint points[4];
points[0].x = x;
points[0].y = y - 3;
points[1].x = 2;
points[1].y = 5;
points[2].x = -4;
points[2].y = 0;
points[3].x = 2;
points[3].y = -5;
drawlines (gdpy, gpixmap, col, points, 4, CoordModePrevious, X0, Y0);
}
void
DrawCross (x, y, col)
short x, y, col;
{
XPoint points[6];
points[0].x = x;
points[0].y = y;
points[1].x = -2;
points[1].y = 0;
points[2].x = 4;
points[2].y = 0;
points[3].x = -2;
points[3].y = 0;
points[4].x = 0;
points[4].y = -2;
points[5].x = 0;
points[5].y = 4;
drawlines (gdpy, gpixmap, col, points, 6, CoordModePrevious, X0, Y0);
}
double
pow10 (p)
double p;
{
double q;
if (p > 1e99 || p < -1e99)
return 0;
p = floor (p);
if (p >= 0)
{
for (q = 1; p > 0; --p)
q = q * 10;
}
else
{
p = -p;
for (q = 1; p > 0; --p)
q = q / 10;
}
return q;
}
char *
rm_tail_zero (s)
char *s;
{
char *t;
return s;
for (t = s; *t == ' ' || *t == '\t'; t++);
strcpy (s, t);
t = s;
while ((*t) && (*t != '\n'))
t++;
t--;
while ((t != s) && ((*t == ' ') || (*t == '0')))
t--;
if (*t != '.')
t++;
*t = '\0';
return s;
}
#define PIX_SEP 6
int
plot_bar ()
{
double max_y = 0;
double min_y = 0;
double y_power;
double Y_Range;
double pv;
char label[256];
int i, j, k;
int len;
int grid_l_x;
int grid_l_y;
int grid_h;
char str[100];
int height, width;
int text_w;
int x, y;
int first_bar = 1;
int num_rows = 0;
int num_cols = 0;
int row;
int bars;
int labelsize;
bars = 0;
for (j = 0; j < jmax; j++)
{
pv = grvalue[0][j];
bars++;
}
if (bars < 1)
{
fprintf (stderr, "\007");
fprintf (stderr, "Not enough valid X labels");
return -1;
}
for (i = 1; i < imax; i++)
{
num_cols++;
row = 0;
for (j = 0; j < jmax; j++)
{
pv = grvalue[i][j];
row++;
if (first_bar)
{
max_y = pv;
min_y = pv;
first_bar = 0;
}
else
{
max_y = Max (max_y, pv);
min_y = Min (min_y, pv);
}
num_rows = Max (row, num_rows);
}
}
min_y -= 0.1 * (fabs (min_y));
y_power = -floor (log10 ((max_y - min_y)));
y_power = pow10 (y_power);
min_y = floor (min_y * y_power) / y_power;
max_y = ceil (max_y * y_power) / y_power;
if (!ggr->Axes[xlValue].MinimumScaleIsAuto)
min_y = ggr->Axes[xlValue].MinimumScale;
else
ggr->Axes[xlValue].MinimumScale = min_y;
if (!ggr->Axes[xlValue].MaximumScaleIsAuto)
max_y = ggr->Axes[xlValue].MaximumScale;
else
ggr->Axes[xlValue].MaximumScale = max_y;
bw = 1;
drawrectangle (gdpy, gpixmap, 1,
RECT_X, RECT_Y, RECT_W, RECT_H, X0, Y0);
grid_l_x = 0;
grid_l_y = 0;
if (ggr->Axes[xlValue].HasMajorGridLines)
{
grid_l_x = RECT_W;
}
if (ggr->Axes[xlCategory].HasMajorGridLines)
{
grid_l_y = RECT_H;
}
grid_h = RECT_H;
Y_Range = max_y - min_y;
width = (RECT_W - (PIX_SEP * num_rows)) / (num_cols * num_rows);
for (i = 0; i < 11; i++)
{
if (i > 0 && i < 10)
drawline (gdpy, gpixmap, 2,
RECT_X - 4, RECT_Y + i * grid_h / 10,
RECT_X, RECT_Y + i * grid_h / 10, X0, Y0);
drawline (gdpy, gpixmap, 2,
RECT_X, RECT_Y + i * grid_h / 10,
RECT_X + grid_l_x, RECT_Y + i * grid_h / 10, X0, Y0);
drawline (gdpy, gpixmap, 2,
RECT_X + RECT_W, RECT_Y + i * grid_h / 10,
RECT_X + RECT_W - grid_l_x, RECT_Y + i * grid_h / 10, X0, Y0);
sprintf (str, "%.1f", (max_y - Y_Range * i / 10));
len = strlen (str);
text_w = gettextw (str, len + 2, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1,
RECT_X - text_w,
RECT_Y + i * grid_h / 10 + curfontheight / 3,
str, len, X0, Y0);
}
for (i = 1; i < num_rows; i++)
{
x = RECT_X + PIX_SEP * i + i * width * (num_cols);
drawline (gdpy, gpixmap, 1,
x, RECT_Y, x, RECT_Y + grid_l_y, X0, Y0);
drawline (gdpy, gpixmap, 1,
x, RECT_Y + RECT_H, x, RECT_Y + RECT_H - grid_l_y, X0, Y0);
}
if (ggr->HasTitle)
{
if (strlen (ggr->ChartTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->ChartTitle.Text));
else
strcpy (label, ggr->ChartTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1, (WIN_W - text_w) / 2, RECT_Y / 3,
label, len,
X0, Y0);
}
if (ggr->Axes[xlCategory].HasTitle)
{
if (strlen (ggr->Axes[xlCategory].AxisTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->Axes[xlCategory].AxisTitle.Text));
else
strcpy (label, ggr->Axes[xlCategory].AxisTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
drawimagestring (gdpy, gpixmap, 1,
(WIN_W - text_w) / 2, RECT_H + RECT_Y * 9 / 6 + curfontheight,
label, len,
X0, Y0);
}
if (ggr->Axes[xlValue].HasTitle)
{
if (strlen (ggr->Axes[xlValue].AxisTitle.Text) > 1)
strcpy (label, (char *) textparsing (ggr->Axes[xlValue].AxisTitle.Text));
else
strcpy (label, ggr->Axes[xlValue].AxisTitle.Text);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
if ((RECT_X - text_w) < 0)
x = curfontwidth;
else
x = RECT_X - text_w;
drawimagestring (gdpy, gpixmap, 1,
x, RECT_Y - 2 * curfontheight,
label, len,
X0, Y0);
}
labelsize = irint (floor ((width * num_cols) / (double) curfontwidth) - 1);
y = RECT_Y * 2 + RECT_H - curfontheight / 2;
bars = 0;
x = RECT_X + (PIX_SEP) * (bars - 1) + width * (bars - 1) * num_cols;
for (i = 1; i < imax; i++)
{
if (strlen ((ggr->range[i]).name) > 1)
strcpy (label, (char *) textparsing ((ggr->range[i]).name));
else
strcpy (label, (ggr->range[i]).name);
len = strlen (label);
text_w = gettextw (label, len, 1, 0, 2);
x = x + (width * num_cols / 2) + text_w + 25;
drawimagestring (gdpy, gpixmap, plotcol[i - 1],
x + 25, y,
label, len, X0, Y0);
fillrectangle (gdpy, gpixmap, plotcol[i - 1], x, y - curfontheight, 20, curfontheight, X0, Y0, 1);
}
for (i = 1; i < imax; i++)
{
row = 0;
for (j = 0, k = 0; j < jmax && k < jmax; j++, k++)
{
row++;
x = RECT_X + (row - 1) * (PIX_SEP) + (row - 1) * (num_cols) * width + width * (i - 1);
pv = grvalue[i][j];
height = (pv * RECT_H) / (max_y);
y = RECT_Y + RECT_H - height;
setforeground (0, plotcol[i - 1]);
fillrectangle (gdpy, gpixmap, plotcol[i - 1], x, y, width, height, X0, Y0, 1);
setforeground (0, 1);
drawrectangle (gdpy, gpixmap, plotcol[i - 1], x, y, width, height, X0, Y0);
}
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1