1 /* PSPP - computes sample statistics.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Written by John Darrington <john@darrington.wattle.id.au>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 static const double y_min = 15;
28 static const double y_max = 120.0;
29 static const double y_tick = 20.0;
33 static const double x_min = -11.0;
34 static const double x_max = 19.0;
35 static const double x_tick = 5.0;
45 static const struct datum data1[]=
65 static const struct datum data2[]=
85 const struct datum *data;
94 static const struct dataset dataset[DATASETS] =
97 {data2, 11, "female"},
102 typedef void (*plot_func) (struct chart *ch, const struct dataset *dataset);
105 void plot_line(struct chart *ch, const struct dataset *dataset);
107 void plot_scatter(struct chart *ch, const struct dataset *dataset);
112 write_legend(struct chart *chart, const char *heading, int n);
114 void draw_cartesian(struct chart *ch, const char *title,
115 const char *xlabel, const char *ylabel, plot_func pf);
120 draw_scatterplot(struct chart *ch, const char *title,
121 const char *xlabel, const char *ylabel)
123 draw_cartesian(ch, title, xlabel, ylabel, plot_scatter);
128 draw_lineplot(struct chart *ch, const char *title,
129 const char *xlabel, const char *ylabel)
131 draw_cartesian(ch, title, xlabel, ylabel, plot_scatter);
136 draw_cartesian(struct chart *ch, const char *title,
137 const char *xlabel, const char *ylabel, plot_func pf)
146 const double ordinate_scale =
147 fabs(ch->data_top - ch->data_bottom)
148 / fabs(y_max - y_min) ;
151 const double abscissa_scale =
152 fabs(ch->data_right - ch->data_left)
157 /* Move to data bottom-left */
158 pl_move_r(ch->lp, ch->data_left, ch->data_bottom);
160 pl_savestate_r(ch->lp);
163 for(x = x_tick * ceil(x_min / x_tick ) ;
166 draw_tick (ch, TICK_ABSCISSA, (x - x_min) * abscissa_scale, "%g", x);
168 for(y = y_tick * ceil(y_min / y_tick ) ;
171 draw_tick (ch, TICK_ORDINATE, (y - y_min) * ordinate_scale, "%g", y);
173 pl_savestate_r(ch->lp);
175 for (d = 0 ; d < DATASETS ; ++d )
177 pl_pencolorname_r(ch->lp,data_colour[d]);
181 pl_restorestate_r(ch->lp);
183 /* Write the abscissa label */
184 pl_move_r(ch->lp,ch->data_left, ch->abscissa_top);
185 pl_alabel_r(ch->lp,0,'t',xlabel);
188 /* Write the ordinate label */
189 pl_savestate_r(ch->lp);
190 pl_move_r(ch->lp,ch->data_bottom, ch->ordinate_right);
191 pl_textangle_r(ch->lp,90);
192 pl_alabel_r(ch->lp,0,0,ylabel);
193 pl_restorestate_r(ch->lp);
196 chart_write_title(ch, title);
198 write_legend(ch,"Key:",DATASETS);
200 pl_restorestate_r(ch->lp);
208 write_legend(struct chart *chart, const char *heading,
213 pl_savestate_r(chart->lp);
215 pl_filltype_r(chart->lp,1);
217 pl_move_r(chart->lp, chart->legend_left,
218 chart->data_bottom + chart->font_size * n * 1.5);
220 pl_alabel_r(chart->lp,0,'b',heading);
222 for (ds = 0 ; ds < n ; ++ds )
224 pl_fmove_r(chart->lp,
226 chart->data_bottom + chart->font_size * ds * 1.5);
228 pl_savestate_r(chart->lp);
229 pl_fillcolorname_r(chart->lp,data_colour[ds]);
230 pl_fboxrel_r (chart->lp,
232 chart->font_size, chart->font_size);
233 pl_restorestate_r(chart->lp);
235 pl_fmove_r(chart->lp,
236 chart->legend_left + chart->font_size * 1.5,
237 chart->data_bottom + chart->font_size * ds * 1.5);
239 pl_alabel_r(chart->lp,'l','b',dataset[ds].label);
243 pl_restorestate_r(chart->lp);
249 plot_line(struct chart *ch, const struct dataset *dataset)
253 const struct datum *data = dataset->data;
255 const double ordinate_scale =
256 fabs(ch->data_top - ch->data_bottom)
257 / fabs(y_max - y_min) ;
260 const double abscissa_scale =
261 fabs(ch->data_right - ch->data_left)
266 for( i = 0 ; i < dataset->n_data ; ++i )
269 (data[i].x - x_min) * abscissa_scale + ch->data_left ;
271 (data[i].y - y_min) * ordinate_scale + ch->data_bottom;
274 pl_move_r(ch->lp, x, y );
276 pl_fcont_r(ch->lp, x, y);
278 pl_endpath_r(ch->lp);
286 plot_scatter(struct chart *ch, const struct dataset *dataset)
290 const struct datum *data = dataset->data;
292 const double ordinate_scale =
293 fabs(ch->data_top - ch->data_bottom)
294 / fabs(y_max - y_min) ;
297 const double abscissa_scale =
298 fabs(ch->data_right - ch->data_left)
303 for( i = 0 ; i < dataset->n_data ; ++i )
306 (data[i].x - x_min) * abscissa_scale + ch->data_left ;
308 (data[i].y - y_min) * ordinate_scale + ch->data_bottom;
310 pl_fmarker_r(ch->lp, x, y, 6, 15);