} acre_data_point_2d_t;
struct _acre_data {
+ /* The name of this data set. */
char *name;
+ /* Minimum and mximum extents of data. */
acre_data_point_2d_t min;
acre_data_point_2d_t max;
+ /* The data itself. */
acre_data_point_2d_t *points;
unsigned int points_size;
unsigned int num_points;
+
+ /* The names of data points (if any).
+ *
+ * This array is indexed with the same index as the 'points' array
+ * to provide names for points. It is legal for this array to be
+ * NULL or smaller than 'points', (in which case, the
+ * corresponding points simply have no names).
+ */
+ char **names;
+ unsigned int names_size;
+ unsigned int num_names;
};
typedef struct _acre_axis {
acre->font = NULL;
acre->colors = NULL;
acre->num_colors = 0;
+ acre->colors_size = 0;
acre->width = 0;
acre->height = 0;
{
PangoLayout *layout;
+ if (text == NULL)
+ text = "";
+
layout = pango_cairo_create_layout (acre->cr);
pango_layout_set_font_description (layout, acre->font);
pango_layout_set_text (layout, text, -1);
title_layout = _create_layout (acre, acre->title);
pango_layout_set_font_description (title_layout, title_font);
+ pango_font_description_free (title_font);
x_axis_layout = _create_layout (acre, acre->x_axis.label);
y_axis_layout = _create_layout (acre, acre->y_axis.label);
}
}
- /* Next, we want to ensure that the data never collides with the
- * ticks. So we expand each axis on its minimum side as needed. */
- cairo_save (cr);
- {
- double x, y;
-
- _set_transform_to_data_space (acre);
-
- x = ACRE_TICK_MAJOR_SIZE + 2.0;
- y = ACRE_TICK_MAJOR_SIZE + 2.0;
- cairo_device_to_user_distance (cr, &x, &y);
-
- acre->x_axis.view_min -= x;
- acre->y_axis.view_min += y;
- }
- cairo_restore (cr);
-
/* Then, increase the axis ranges just enough so that the step
* sizes for the ticks will be integers.
*/
cairo_restore (cr);
}
-static void
-_acre_color_from_hsv (acre_color_t *color,
- double hue,
- double saturation,
- double value)
-{
- double f, p, q, t;
- int hmod6;
-
- hmod6 = (int) floor (hue / 60) % 6;
- f = hue / 60 - floor (hue / 60);
- p = value * (1 - saturation);
- q = value * (1 - f * saturation);
- t = value * (1 - (1 - f) * saturation);
-
- switch (hmod6) {
- case 0:
- color->red = value;
- color->green = t;
- color->blue = p;
- break;
- case 1:
- color->red = q;
- color->green = value;
- color->blue = p;
- break;
- case 2:
- color->red = p;
- color->green = value;
- color->blue = t;
- break;
- case 3:
- color->red = p;
- color->green = q;
- color->blue = value;
- break;
- case 4:
- color->red = t;
- color->green = p;
- color->blue = value;
- break;
- case 5:
- color->red = value;
- color->green = p;
- color->blue = q;
- break;
- }
-}
-
static void
_choose_colors (acre_t *acre)
{
void
acre_data_destroy (acre_data_t *data)
{
+ unsigned i;
+
+ for (i = 0; i < data->num_names; i++) {
+ if (data->names[i])
+ free (data->names[i]);
+ }
+ free (data->names);
+
+ free (data->name);
+
free (data->points);
free (data);
data->num_points++;
}
+
+/* Add a datapoint with a name to the given dataset. */
+void
+acre_data_add_point_2d_named (acre_data_t *data, double x, double y, const char *name)
+{
+ unsigned i;
+
+ acre_data_add_point_2d (data, x, y);
+
+ if (data->names_size < data->points_size) {
+ data->names_size = data->points_size;
+ data->names = xrealloc_ab (data->names,
+ data->names_size,
+ sizeof (char *));
+ }
+
+ /* Initialize any newly-created holes in the array to NULL. */
+ for (i = data->num_names; i < data->num_points - 1; i++)
+ data->names[i] = NULL;
+
+ data->num_names = data->num_points;
+
+ data->names[data->num_names - 1] = xstrdup (name);
+}