[GRASS-SVN] r69677 - grass/trunk/display/d.linegraph
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Oct 5 17:47:22 PDT 2016
Author: wenzeslaus
Date: 2016-10-05 17:47:22 -0700 (Wed, 05 Oct 2016)
New Revision: 69677
Modified:
grass/trunk/display/d.linegraph/main.c
Log:
d.linegraph: let user provide Y tics [news]
Generated tics disabled when user provided.
No unlabeled tics generated. Printed as provided by
the user (strings, not numbers). Tics out of range simply
ignored.
This is also a workaround for tics with decimal places
(automatic tics work only with integers).
Modified: grass/trunk/display/d.linegraph/main.c
===================================================================
--- grass/trunk/display/d.linegraph/main.c 2016-10-04 19:59:10 UTC (rev 69676)
+++ grass/trunk/display/d.linegraph/main.c 2016-10-06 00:47:22 UTC (rev 69677)
@@ -61,6 +61,22 @@
return ((double)(x - y * d));
}
+/* TODO: remove constants */
+/* TODO: include X? (common fun for X and Y) */
+static void set_optimal_text_size(double text_width, double text_height,
+ const char* text, double *tt, double *tb,
+ double *tl, double *tr)
+{
+ D_text_size(text_width, text_height);
+ D_get_text_box(text, tt, tb, tl, tr);
+ while ((tt - tb) > YTIC_DIST) {
+ text_width *= 0.75;
+ text_height *= 0.75;
+ D_text_size(text_width, text_height);
+ D_get_text_box(text, tt, tb, tl, tr);
+ }
+}
+
int main(int argc, char **argv)
{
double xoffset; /* offset for x-axis */
@@ -121,6 +137,7 @@
struct Option *title[3];
struct Option *t_color_opt;
struct Option *y_range_opt;
+ struct Option *ytics_opt;
/* Initialize the GIS calls */
G_gisinit(argv[0]);
@@ -211,6 +228,13 @@
y_range_opt->key_desc = "min,max";
y_range_opt->required = NO;
+ ytics_opt = G_define_option();
+ ytics_opt->key = "y_tics";
+ ytics_opt->description = _("Tic values for the Y axis");
+ ytics_opt->type = TYPE_DOUBLE;
+ ytics_opt->required = NO;
+ ytics_opt->multiple = YES;
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -407,6 +431,7 @@
}
}
+ /* TODO: parse range option function */
/* parse and set y min max */
if (y_range_opt->answer != NULL) {
/* all checks should be done by the parser */
@@ -608,60 +633,91 @@
tic_every tells how often to place a tic-number. tic_unit tells
the unit to use in expressing tic-numbers. */
- if (yscale < YTIC_DIST) {
- max_tics = (y_line[1] - y_line[0]) / YTIC_DIST;
- i = 1;
- while (((max_y - min_y) / tics[i].every) > max_tics)
- i++;
- tic_every = tics[i].every;
- tic_unit = tics[i].unit;
- strcpy(tic_name, tics[i].name);
- }
- else {
- tic_every = 1;
- tic_unit = 1;
- strcpy(tic_name, "");
- }
+ /* user versus automatic Y tics */
+ if (ytics_opt->answer) {
+ /* user-provided Y tics, no intermediate tics supported */
+ char *text;
- /* Y-AXIS LOOP */
+ i = 0;
+ while ((text = ytics_opt->answers[i])) {
+ i++;
- for (i = (int)min_y; i <= (int)max_y; i += tic_unit) {
- if (rem(i, tic_every) == 0.0) {
- /* draw a tic-mark */
+ double val = atof(text);
+ /* using original user's text for the text later */
- D_begin();
- D_move_abs(x_line[0], yoffset - yscale * (i - min_y));
- D_cont_rel(-(r - l) * BIG_TIC, 0);
- D_end();
- D_stroke();
+ /* for scripting convenience ignore out of range */
+ if (val < min_y || val > max_y) {
+ G_debug(2, "tic %f out of range %f,%f", val, min_y, max_y);
+ continue;
+ }
+ /* we don't care about order, so just continue, not break */
- /* draw a tic-mark number */
+ D_begin();
+ D_move_abs(x_line[0], yoffset - yscale * val);
+ D_cont_rel((-(r - l) * BIG_TIC), 0);
+ D_end();
+ D_stroke();
- sprintf(txt, "%d", (i / tic_unit));
- text_height = (b - t) * TEXT_HEIGHT;
- text_width = (r - l) * TEXT_WIDTH;
- D_text_size(text_width, text_height);
- D_get_text_box(txt, &tt, &tb, &tl, &tr);
- while ((tt - tb) > YTIC_DIST) {
- text_width *= 0.75;
- text_height *= 0.75;
- D_text_size(text_width, text_height);
- D_get_text_box(txt, &tt, &tb, &tl, &tr);
- }
- D_pos_abs(l + (r - l) * YNUMS_X - (tr - tl) / 2,
- yoffset - (yscale * (i - min_y) + 0.5 * (tt - tb)));
- D_text(txt);
- }
- else if (rem(i, tic_unit) == 0.0) {
- /* draw a tic-mark */
- D_begin();
- D_move_abs(x_line[0], (yoffset - yscale * (i - min_y)));
- D_cont_rel(-(r - l) * SMALL_TIC, 0);
- D_end();
- D_stroke();
- }
+ /* draw a tic-mark number */
+ text_height = (b - t) * TEXT_HEIGHT;
+ text_width = (r - l) * TEXT_WIDTH;
+ /* this would be useful, but with some other numbers */
+ set_optimal_text_size(text_width, text_height, txt, &tt, &tb, &tl, &tr);
+ D_pos_abs(l + (r - l) * YNUMS_X - (tr - tl) / 2,
+ yoffset - (yscale * val + 0.5 * (tt - tb)));
+ D_text(text);
+ }
+ /* no automatic tics comment */
+ strcpy(tic_name, "");
}
+ else {
+ /* automatic Y tics, decimal places (e.g. range 0-1) not supported */
+ if (yscale < YTIC_DIST) {
+ max_tics = (y_line[1] - y_line[0]) / YTIC_DIST;
+ i = 1;
+ while (((max_y - min_y) / tics[i].every) > max_tics)
+ i++;
+ tic_every = tics[i].every;
+ tic_unit = tics[i].unit;
+ strcpy(tic_name, tics[i].name);
+ }
+ else {
+ tic_every = 1;
+ tic_unit = 1;
+ strcpy(tic_name, "");
+ }
+ /* Y-AXIS LOOP */
+ for (i = (int)min_y; i <= (int)max_y; i += tic_unit) {
+ if (rem(i, tic_every) == 0.0) {
+ /* draw a tic-mark */
+ D_begin();
+ D_move_abs(x_line[0], yoffset - yscale * (i - min_y));
+ D_cont_rel(-(r - l) * BIG_TIC, 0);
+ D_end();
+ D_stroke();
+
+ /* draw a tic-mark number */
+
+ sprintf(txt, "%d", (i / tic_unit));
+ text_height = (b - t) * TEXT_HEIGHT;
+ text_width = (r - l) * TEXT_WIDTH;
+ set_optimal_text_size(text_width, text_height, txt, &tt, &tb, &tl, &tr);
+ D_pos_abs(l + (r - l) * YNUMS_X - (tr - tl) / 2,
+ yoffset - (yscale * (i - min_y) + 0.5 * (tt - tb)));
+ D_text(txt);
+ }
+ else if (rem(i, tic_unit) == 0.0) {
+ /* draw a tic-mark */
+ D_begin();
+ D_move_abs(x_line[0], (yoffset - yscale * (i - min_y)));
+ D_cont_rel(-(r - l) * SMALL_TIC, 0);
+ D_end();
+ D_stroke();
+ }
+ }
+ }
+
/* draw the y-axis label */
if ((strcmp(title[1]->answer, "") == 0) && (strcmp(tic_name, "") == 0))
*xlabel = '\0';
More information about the grass-commit
mailing list