[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