From: Carl Worth <cworth@cworth.org>
Date: Sat, 9 Nov 2013 00:16:44 +0000 (-0800)
Subject: Add a new BARS_OR_LINE style for drawing data sets.
X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=4bb896b4ca75a5dd908da41455aabd3d6d864dd3;p=acre

Add a new BARS_OR_LINE style for drawing data sets.

If there is sufficient room, this will draw the dataset as a bar
chart. But if the bars would run into each other, it will draw as a
line chart instead.
---

diff --git a/acre.c b/acre.c
index 4e00bee..9a9851c 100644
--- a/acre.c
+++ b/acre.c
@@ -846,6 +846,48 @@ _draw_data_line (acre_t *acre, acre_data_t *data)
     cairo_restore (cr);
 }
 
+#define BARS_WIDTH 0.8
+
+/* Draw the given dataset as bars if there is room for that.
+ *
+ * Or, if the bars would run into each other, use a line instead.
+ */
+static void
+_draw_data_bars_or_line (acre_t *acre, acre_data_t *data)
+{
+    unsigned i;
+    cairo_t *cr = acre->cr;
+    double ignored, width;
+
+    /* Check device-space width available for inter-bad padding. */
+    width = 1.0 - BARS_WIDTH;
+    ignored = 0.0;
+    cairo_user_to_device_distance (cr, &width, &ignored);
+
+    /* If padding is less than two pixels, draw with a line instead. */
+    if (width < 2.0) {
+	_draw_data_line (acre, data);
+
+	return;
+    }
+
+    cairo_save (cr);
+
+    cairo_new_path (cr);
+
+    for (i = 0; i < data->num_points; i++) {
+	cairo_rectangle (cr,
+			 data->points[i].x - BARS_WIDTH / 2.0, 0.0,
+			 BARS_WIDTH, data->points[i].y);
+    }
+
+    cairo_identity_matrix (cr);
+    cairo_set_line_width (cr, 1.0);
+    cairo_stroke (cr);
+
+    cairo_restore (cr);
+}
+
 #define TIMELINE_BAR_HEIGHT 0.6
 
 /* Draw the given dataset as a timeline. Each (X,Y) point (potentially
@@ -942,6 +984,9 @@ _draw_data (acre_t *acre)
 	case ACRE_STYLE_LINE:
 	    _draw_data_line (acre, data);
 	    break;
+	case ACRE_STYLE_BARS_OR_LINE:
+	    _draw_data_bars_or_line (acre, data);
+	    break;
 	case ACRE_STYLE_TIMELINE:
 	    /* Position the timeline bars top-down */
 	    _draw_data_timeline (acre, data, acre->num_data - 1 - i);
diff --git a/acre.h b/acre.h
index 9611da3..4cd58d4 100644
--- a/acre.h
+++ b/acre.h
@@ -118,6 +118,9 @@ typedef enum
 	/* A simple line graph connection each (X,Y) pair in order. */
 	ACRE_STYLE_LINE,
 
+	/* Bars if there is room for them, a line otherwise. */
+	ACRE_STYLE_BARS_OR_LINE,
+
 	/* A timeline.
 	 *
 	 * Each (X,Y) pair specifies the (start,stop) time of a