]> git.cworth.org Git - acre/blobdiff - acre.c
Add preliminary data plotting.
[acre] / acre.c
diff --git a/acre.c b/acre.c
index 6e75ab7ee8403cb537c682e069bdd0c26749850e..394b70035e9e5147516a7ec3ac3549c59edf7513 100644 (file)
--- a/acre.c
+++ b/acre.c
@@ -36,10 +36,16 @@ struct _acre_data {
     unsigned int num_points;
 };
 
+typedef struct _acre_axis {
+    char *label;
+    double min;
+    double max;
+} acre_axis_t;
+
 struct _acre {
     char *title;
-    char *x_axis_label;
-    char *y_axis_label;
+    acre_axis_t x_axis;
+    acre_axis_t y_axis;
 
     acre_data_t **data;
     unsigned int data_size;
@@ -65,8 +71,14 @@ acre_create (void)
     acre = xmalloc (sizeof (acre_t));
 
     acre->title = NULL;
-    acre->x_axis_label = NULL;
-    acre->y_axis_label = NULL;
+
+    acre->x_axis.label = NULL;
+    acre->x_axis.min = 0.0;
+    acre->x_axis.max = 0.0;
+
+    acre->y_axis.label = NULL;
+    acre->y_axis.min = 0.0;
+    acre->y_axis.max = 0.0;
 
     acre->data = NULL;
     acre->data_size = 0;
@@ -82,8 +94,8 @@ acre_destroy (acre_t *acre)
     unsigned int i;
 
     free (acre->title);
-    free (acre->x_axis_label);
-    free (acre->y_axis_label);
+    free (acre->x_axis.label);
+    free (acre->y_axis.label);
 
     for (i = 0; i < acre->num_data; i++)
        acre_data_destroy (acre->data[i]);
@@ -104,17 +116,17 @@ acre_set_title (acre_t *acre, const char *title)
 void
 acre_set_x_axis_label (acre_t *acre, const char *label)
 {
-    free (acre->x_axis_label);
+    free (acre->x_axis.label);
 
-    acre->x_axis_label = strdup (label);
+    acre->x_axis.label = strdup (label);
 }
 
 void
 acre_set_y_axis_label (acre_t *acre, const char *label)
 {
-    free (acre->y_axis_label);
+    free (acre->y_axis.label);
 
-    acre->y_axis_label = strdup (label);
+    acre->y_axis.label = strdup (label);
 }
 
 /* Add a dataset to the plot. The plot assumes ownership of the
@@ -152,6 +164,8 @@ _draw_title_and_labels (acre_t *acre)
     int y_axis_width, y_axis_height;
     PangoRectangle new_chart;
 
+    cairo_save (cr);
+
     acre_font = pango_font_description_new ();
     pango_font_description_set_family (acre_font, ACRE_FONT_FAMILY);
     pango_font_description_set_absolute_size (acre_font,
@@ -169,12 +183,12 @@ _draw_title_and_labels (acre_t *acre)
 
     x_axis_layout = pango_cairo_create_layout (cr);
     pango_layout_set_font_description (x_axis_layout, acre_font);
-    pango_layout_set_text (x_axis_layout, acre->x_axis_label, -1);
+    pango_layout_set_text (x_axis_layout, acre->x_axis.label, -1);
     pango_layout_set_alignment (x_axis_layout, PANGO_ALIGN_CENTER);
 
     y_axis_layout = pango_cairo_create_layout (cr);
     pango_layout_set_font_description (y_axis_layout, acre_font);
-    pango_layout_set_text (y_axis_layout, acre->y_axis_label, -1);
+    pango_layout_set_text (y_axis_layout, acre->y_axis.label, -1);
     pango_layout_set_alignment (y_axis_layout, PANGO_ALIGN_CENTER);
 
     /* Iterate with the layout of the title and axis labels until they
@@ -233,6 +247,86 @@ _draw_title_and_labels (acre_t *acre)
                   acre->chart.y + acre->chart.height +
                   ACRE_FONT_SIZE + ACRE_PAD);
     pango_cairo_show_layout (cr, x_axis_layout);
+
+    cairo_restore (cr);
+}
+
+static void
+_compute_axis_ranges (acre_t *acre)
+{
+    unsigned int d, i;
+    acre_data_t *data;
+
+    for (d = 0; d < acre->num_data; d++) {
+       data = acre->data[d];
+       for (i = 0; i < data->num_points; i++) {
+           if (data->points[i].x < acre->x_axis.min)
+               acre->x_axis.min = data->points[i].x;
+           if (data->points[i].x > acre->x_axis.max)
+               acre->x_axis.max = data->points[i].x;
+
+           if (data->points[i].y < acre->y_axis.min)
+               acre->y_axis.min = data->points[i].y;
+           if (data->points[i].y > acre->y_axis.max)
+               acre->y_axis.max = data->points[i].y;
+       }
+    }
+}
+
+static void
+_draw_data (acre_t *acre)
+{
+    cairo_t *cr = acre->cr;
+    unsigned int d, i;
+    acre_data_t *data;
+
+    cairo_save (cr);
+
+    cairo_set_source_rgb (cr, 0, 0, 0);
+
+    cairo_translate (cr,
+                    acre->chart.x + 0.5,
+                    acre->chart.y + acre->chart.height - 0.5);
+    cairo_scale (cr,
+                acre->chart.width / (acre->x_axis.max - acre->x_axis.min),
+                - acre->chart.height /(acre->y_axis.max - acre->y_axis.min));
+    cairo_translate (cr, -acre->x_axis.min, -acre->y_axis.min);
+
+    for (d = 0; d < acre->num_data; d++) {
+       data = acre->data[d];
+       cairo_new_path (cr);
+       for (i = 0; i < data->num_points; i++) {
+           cairo_line_to (cr,
+                          data->points[i].x,
+                          data->points[i].y);
+       }
+       cairo_save (cr);
+       {
+           cairo_identity_matrix (cr);
+           cairo_set_line_width (cr, 1.0);
+           cairo_stroke (cr);
+       }
+       cairo_restore (cr);
+    }
+
+    cairo_restore (cr);
+}
+
+static void
+_draw_frame_and_ticks (acre_t *acre)
+{
+    cairo_t *cr = acre->cr;
+
+    cairo_save (cr);
+
+    cairo_rectangle (cr,
+                    acre->chart.x - 0.5, acre->chart.y - 0.5,
+                    acre->chart.width + 1.0, acre->chart.height + 1.0);
+    cairo_set_line_width (cr, 1.0);
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    cairo_stroke (cr);
+
+    cairo_restore (cr);
 }
 
 /* Draw the plot to the given cairo context within a user-space
@@ -255,11 +349,11 @@ acre_draw (acre_t *acre, cairo_t *cr, int width, int height)
 
     _draw_title_and_labels (acre);
 
-    cairo_rectangle (cr,
-                    acre->chart.x - 0.5, acre->chart.y - 0.5,
-                    acre->chart.width + 1.0, acre->chart.height + 1.0);
-    cairo_set_line_width (cr, 1.0);
-    cairo_stroke (cr);
+    _compute_axis_ranges (acre);
+
+    _draw_data (acre);
+
+    _draw_frame_and_ticks (acre);
 }
 
 /* Create a new dataset---a collection of (x, y) datapoints. A single