[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r18529 - gnunet-gtk/src/statistics
From: |
gnunet |
Subject: |
[GNUnet-SVN] r18529 - gnunet-gtk/src/statistics |
Date: |
Fri, 9 Dec 2011 16:16:55 +0100 |
Author: grothoff
Date: 2011-12-09 16:16:55 +0100 (Fri, 09 Dec 2011)
New Revision: 18529
Modified:
gnunet-gtk/src/statistics/Makefile.am
gnunet-gtk/src/statistics/gtk_statistics.c
gnunet-gtk/src/statistics/gtk_statistics.h
gnunet-gtk/src/statistics/test.c
Log:
finishing statistics widget
Modified: gnunet-gtk/src/statistics/Makefile.am
===================================================================
--- gnunet-gtk/src/statistics/Makefile.am 2011-12-09 14:48:25 UTC (rev
18528)
+++ gnunet-gtk/src/statistics/Makefile.am 2011-12-09 15:16:55 UTC (rev
18529)
@@ -26,7 +26,7 @@
gtk_statistics.c gtk_statistics.h test.c
test_LDADD = \
@GTK_LIBS@ \
- @GLADE_LIBS@ @GNUNET_LIBS@ \
+ @GLADE_LIBS@ @GNUNET_LIBS@ -lm \
$(INTLLIBS)
test_LDFLAGS = \
-export-dynamic
\ No newline at end of file
Modified: gnunet-gtk/src/statistics/gtk_statistics.c
===================================================================
--- gnunet-gtk/src/statistics/gtk_statistics.c 2011-12-09 14:48:25 UTC (rev
18528)
+++ gnunet-gtk/src/statistics/gtk_statistics.c 2011-12-09 15:16:55 UTC (rev
18529)
@@ -30,6 +30,19 @@
#define MAX_HISTORY 1280
/**
+ * Number of ticks on the x-axis.
+ */
+#define XTICKS 4
+
+/**
+ * Number of ticks on the y-axis.
+ */
+#define YTICKS 5
+
+#define BORDER 10.0
+
+
+/**
* Information about a value we received.
*/
struct HistoricValue
@@ -58,9 +71,9 @@
char *label;
/**
- * Color name.
+ * Color values (rgb).
*/
- char *color_name;
+ double red, green, blue;
/**
* Recent values for this number.
@@ -100,7 +113,7 @@
static void gtk_statistics_finalize (GObject *object);
-G_DEFINE_TYPE (GtkStatistics, gtk_statistics, GTK_TYPE_MISC)
+G_DEFINE_TYPE (GtkStatistics, gtk_statistics, GTK_TYPE_WIDGET)
static void
@@ -114,6 +127,7 @@
gobject_class->finalize = gtk_statistics_finalize;
widget_class->draw = gtk_statistics_draw;
+
g_type_class_add_private (class, sizeof (GtkStatisticsPrivate));
}
@@ -152,6 +166,7 @@
priv = statistics->priv;
priv->values = NULL;
priv->num_values = 0;
+
return GTK_WIDGET (statistics);
}
@@ -165,14 +180,18 @@
{
GtkStatisticsPrivate *priv;
struct ValueHistory *vh;
+ GdkColor c;
g_return_if_fail (GTK_IS_STATISTICS (statistics));
+ g_return_if_fail (gdk_color_parse (color_name, &c));
priv = statistics->priv;
priv->values = g_realloc (priv->values,
sizeof (struct ValueHistory*) * (1 +
priv->num_values));
priv->values[priv->num_values++] = vh = g_malloc (sizeof (struct
ValueHistory));
vh->label = strdup (label);
- vh->color_name = strdup (color_name);
+ vh->red = c.red / 65535.0;
+ vh->green = c.green / 65535.0;
+ vh->blue = c.blue / 65535.0;
}
@@ -202,11 +221,6 @@
vh->history_size++;
vh->history[vh->last_history_offset].x = x;
vh->history[vh->last_history_offset].y = y;
-
- g_object_freeze_notify (G_OBJECT (statistics));
- g_object_notify (G_OBJECT (statistics), "statistics-value");
- g_object_thaw_notify (G_OBJECT (statistics));
-
widget = GTK_WIDGET (statistics);
if (gtk_widget_is_drawable (widget))
gtk_widget_queue_draw (widget);
@@ -214,38 +228,179 @@
}
+static void
+num_to_label (unsigned long long num,
+ char *label)
+{
+ if (num > 1000LL * 1000 * 1000 * 3)
+ sprintf (label, "%llu g", num / 1000LL / 1000LL / 1000LL);
+ else if (num > 1000LL * 1000 * 3)
+ sprintf (label, "%llu m", num / 1000LL / 1000LL);
+ else if (num > 1000LL * 3)
+ sprintf (label, "%llu k", num / 1000LL);
+ else
+ sprintf (label, "%llu", num);
+}
+
+
static gboolean
gtk_statistics_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkStatistics *statistics = GTK_STATISTICS (widget);
GtkStatisticsPrivate *priv = statistics->priv;
+ int width;
+ int height;
+ uint64_t xmin;
+ uint64_t xmax;
+ uint64_t ymax;
+ unsigned int i;
+ unsigned int j;
+ struct ValueHistory *vh;
+ struct HistoricValue *hv;
+ char label[64];
+ cairo_text_extents_t te;
+ cairo_text_extents_t tex_max;
+ cairo_text_extents_t tey_max;
+ double rx;
+ double ry;
- fprintf (stderr, "DRAW!\n");
-#if 0
- gdk_color_parse (info[i].color_name, &color);
- gdk_gc_set_foreground (gc, &color);
-#endif
- cairo_translate(cr, 0, 7);
+ /* collect basic data */
+ xmin = UINT64_MAX;
+ xmax = 0;
+ ymax = 0;
+ for (i=0;i<priv->num_values;i++)
+ {
+ vh = priv->values[i];
+ for (j=0;j<vh->history_size;j++)
+ {
+ hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) %
MAX_HISTORY];
+ xmin = GNUNET_MIN (hv->x, xmin);
+ xmax = GNUNET_MAX (hv->x, xmax);
+ ymax = GNUNET_MAX (hv->y, ymax);
+ }
+ }
+ /* round to 10x for nicer legends */
+ while (0 != (ymax % 10)) ymax++;
+ while (0 != (xmax % 10)) xmax++;
+ while (0 != (xmin % 10)) xmin--;
- cairo_set_source_rgb(cr, 0, 0, 0);
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+
+ /* fill with black background */
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_paint(cr);
+
+ if (0 == priv->num_values)
+ return FALSE; /* done */
+ /* select font */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_select_font_face (cr, "Georgia",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr,
+ GNUNET_MIN (20, height / (2 * XTICKS)));
- gint pos = priv->num_values;
- gint rect = pos / 5;
+ /* find out needed space for axis labels */
+ tex_max.width = 0;
+ tex_max.height = 0;
+ for (i=0;i<XTICKS;i++)
+ {
+ num_to_label ((unsigned long long) (xmin + (xmax - xmin) * ((uint64_t) i)
/ (XTICKS - 1)),
+ label);
+ cairo_text_extents (cr, label, &te);
+ tex_max.width = GNUNET_MAX (te.width, tex_max.width);
+ tex_max.height = GNUNET_MAX (te.height, tex_max.height);
+ }
+ tey_max.width = 0;
+ tey_max.height = 0;
+ for (i=0;i<YTICKS;i++)
+ {
+ num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1),
+ label);
+ cairo_text_extents (cr, label, &te);
+ tey_max.width = GNUNET_MAX (te.width, tey_max.width);
+ tey_max.height = GNUNET_MAX (te.height, tey_max.height);
+ }
- cairo_set_source_rgb(cr, 0.2, 0.4, 0);
+ /* draw y-axis labels */
+ for (i=0;i<YTICKS;i++)
+ {
+ num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1),
+ label);
+ cairo_text_extents (cr, label, &te);
+ cairo_move_to (cr,
+ BORDER + tey_max.width - te.width,
+ BORDER + tey_max.height + (YTICKS - i - 1) * (height - 2.0 *
BORDER - tey_max.height - tex_max.height) / (double) (YTICKS - 1));
+ cairo_show_text (cr, label);
- gint i;
- for ( i = 1; i <= 20; i++) {
- if (i > 20 - rect) {
- cairo_set_source_rgb(cr, 0.6, 1.0, 0);
- } else {
- cairo_set_source_rgb(cr, 0.2, 0.4, 0);
+
+ cairo_move_to (cr,
+ 2.0 * BORDER + tey_max.width,
+ BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height -
2.0 * BORDER - tex_max.height - tey_max.height) / (double) (YTICKS - 1));
+ cairo_line_to (cr,
+ 2.0 * BORDER + tey_max.width + BORDER / 2.0,
+ BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height -
2.0 * BORDER - tex_max.height - tey_max.height) / (double) (YTICKS - 1));
+
+ cairo_stroke (cr);
+ }
+
+ /* draw x-axis labels */
+ for (i=0;i<XTICKS;i++)
+ {
+ num_to_label ((unsigned long long) (xmin + (xmax - xmin) * ((uint64_t) i)
/ (XTICKS - 1)),
+ label);
+ cairo_text_extents (cr, label, &te);
+ if (i != 0)
+ {
+ cairo_move_to (cr,
+ 2.0 * BORDER + tey_max.width + (width - tey_max.width -
tex_max.width / 2.0 - 3.0 * BORDER) * i / (XTICKS - 1.0) - te.width / 2.0,
+ height - BORDER / 2.0 - tex_max.height / 2.0);
+ cairo_show_text (cr, label);
+ }
+ cairo_move_to (cr,
+ 2.0 * BORDER + tey_max.width + (width - tey_max.width -
tex_max.width / 2.0 - 3.0 * BORDER) * i / (XTICKS - 1.0),
+ height - BORDER - tey_max.height / 2.0 - tex_max.height);
+ cairo_line_to (cr,
+ 2.0 * BORDER + tey_max.width + (width - tey_max.width -
tex_max.width / 2.0 - 3.0 * BORDER) * i / (XTICKS - 1.0),
+ height - BORDER - tey_max.height / 2.0 - tex_max.height -
BORDER / 2.0);
+
+ cairo_stroke (cr);
+ }
+
+ /* plot border */
+ cairo_set_line_width (cr, 1.0);
+ cairo_rectangle (cr,
+ tey_max.width + BORDER * 2.0,
+ BORDER + tey_max.height / 2.0,
+ width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0,
+ height - BORDER * 2.0 - tey_max.height - tex_max.height);
+ cairo_stroke (cr);
+
+ /* finally, plot lines */
+ cairo_set_line_width (cr, 2.0);
+ for (i=0;i<priv->num_values;i++)
+ {
+ vh = priv->values[i];
+ cairo_set_source_rgb(cr, vh->red, vh->green, vh->blue);
+ for (j=0;j<vh->history_size;j++)
+ {
+ hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) %
MAX_HISTORY];
+ rx = (hv->x - xmin) / (double) (xmax - xmin);
+ ry = hv->y / (double) ymax;
+
+ rx = tey_max.width + BORDER * 2.0 + (rx * (width - BORDER * 3.0 -
tey_max.width - tex_max.width / 2.0));
+ ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0
- tey_max.height - tex_max.height);
+ if (j == 0)
+ {
+ cairo_move_to (cr, rx, ry);
}
- cairo_rectangle(cr, 8, i*4, 30, 3);
- cairo_rectangle(cr, 42, i*4, 30, 3);
- cairo_fill(cr);
+ else
+ {
+ cairo_line_to (cr, rx, ry);
+ }
+ }
+ cairo_stroke (cr);
}
return FALSE;
}
@@ -256,9 +411,14 @@
{
GtkStatistics *label = GTK_STATISTICS (object);
GtkStatisticsPrivate *priv = label->priv;
+ unsigned int i;
- g_free (priv->values);
-
+ for (i=0;i<priv->num_values;i++)
+ {
+ g_free (priv->values[i]->label);
+ g_free (priv->values[i]);
+ }
+ g_free (priv->values);
G_OBJECT_CLASS (gtk_statistics_parent_class)->finalize (object);
}
Modified: gnunet-gtk/src/statistics/gtk_statistics.h
===================================================================
--- gnunet-gtk/src/statistics/gtk_statistics.h 2011-12-09 14:48:25 UTC (rev
18528)
+++ gnunet-gtk/src/statistics/gtk_statistics.h 2011-12-09 15:16:55 UTC (rev
18529)
@@ -45,7 +45,7 @@
struct _GtkStatistics
{
- GtkMisc misc;
+ GtkWidget widget;
/*< private >*/
GtkStatisticsPrivate *priv;
@@ -53,7 +53,7 @@
struct _GtkStatisticsClass
{
- GtkMiscClass parent_class;
+ GtkWidgetClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
Modified: gnunet-gtk/src/statistics/test.c
===================================================================
--- gnunet-gtk/src/statistics/test.c 2011-12-09 14:48:25 UTC (rev 18528)
+++ gnunet-gtk/src/statistics/test.c 2011-12-09 15:16:55 UTC (rev 18529)
@@ -1,20 +1,64 @@
#include "gtk_statistics.h"
+#include <math.h>
+
+/**
+ * Update view (add more points).
+ */
+static gboolean
+update (GtkWidget *widget, GdkEvent *event, gpointer user_data)
+{
+ static unsigned int i = 600;
+ struct GtkStatistics *statistics = user_data;
+
+ gtk_statistics_update_value (GTK_STATISTICS (statistics),
+ "sin",
+ i,
+ (uint64_t) (500 * (1.0 + sin(i/100.0))));
+ gtk_statistics_update_value (GTK_STATISTICS (statistics),
+ "cos",
+ i * 2,
+ (uint64_t) (i * (1.0 + cos(i/100.0))));
+ i++;
+ return FALSE;
+}
+
+
int main (int argc, char ** argv)
{
GtkWidget *window;
GtkWidget *statistics;
+ unsigned int i;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "STATISTICS widget");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
- gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
+ gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
statistics = gtk_statistics_new();
+ gtk_statistics_add_line (GTK_STATISTICS (statistics),
+ "sin",
+ "red");
+ for (i=0;i<600;i++)
+ gtk_statistics_update_value (GTK_STATISTICS (statistics),
+ "sin",
+ i,
+ (uint64_t) (500 * (1.0 + sin(i/100.0))));
+ gtk_statistics_add_line (GTK_STATISTICS (statistics),
+ "cos",
+ "blue");
+ for (i=0;i<600;i++)
+ gtk_statistics_update_value (GTK_STATISTICS (statistics),
+ "cos",
+ i * 2,
+ (uint64_t) (i * (1.0 + cos(i/100.0))));
+ g_signal_connect (G_OBJECT(window), "motion-notify-event", G_CALLBACK
(update), statistics);
gtk_container_add(GTK_CONTAINER(window), statistics);
+ gtk_widget_add_events (GTK_WIDGET (window), GDK_POINTER_MOTION_MASK);
+
gtk_widget_show(statistics);
gtk_widget_show_all(window);
gtk_main();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r18529 - gnunet-gtk/src/statistics,
gnunet <=