aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-12-09 16:59:03 +0000
committerChristian Grothoff <christian@grothoff.org>2011-12-09 16:59:03 +0000
commitd6f936b6ed351a1db764351bd134f7ff5ff828e9 (patch)
treeaf2fc7c8527f3279adc4d6f683c1fc5428c2db84
parent80cff456f59a2f316bb8ef4acc60f0a3a2a92d42 (diff)
downloadgnunet-gtk-d6f936b6ed351a1db764351bd134f7ff5ff828e9.tar.gz
gnunet-gtk-d6f936b6ed351a1db764351bd134f7ff5ff828e9.zip
polishing statistics widget, integration with main gnunet-statistics-gtk GUI
-rw-r--r--src/statistics/gnunet-statistics-gtk.c69
-rw-r--r--src/statistics/gtk_statistics.c87
-rw-r--r--src/statistics/gtk_statistics.h3
-rw-r--r--src/statistics/test.c2
4 files changed, 140 insertions, 21 deletions
diff --git a/src/statistics/gnunet-statistics-gtk.c b/src/statistics/gnunet-statistics-gtk.c
index e73cd5e1..558e7baa 100644
--- a/src/statistics/gnunet-statistics-gtk.c
+++ b/src/statistics/gnunet-statistics-gtk.c
@@ -49,6 +49,11 @@ struct PlotInfo
49 const char *name; 49 const char *name;
50 50
51 /** 51 /**
52 * Label to use in legend.
53 */
54 const char *label;
55
56 /**
52 * Name of color to use when plotting. 57 * Name of color to use when plotting.
53 */ 58 */
54 const char *color_name; 59 const char *color_name;
@@ -58,7 +63,33 @@ struct PlotInfo
58 63
59static const struct PlotInfo connection_data[] = 64static const struct PlotInfo connection_data[] =
60 { 65 {
61 { "core", "entries in session map", "white" }, 66 { "fs", "# peers connected", "file-sharing connections", "blue" },
67 { "core", "# entries in session map", "encrypted connections (core)", "green" },
68 { "core", "# neighbour entries allocated", "transport connections (core)", "yellow" },
69 { "transport", "# peers connected", "total connections (transport)", "orange" },
70 { "transport", "# TCP sessions active", "tcp connections", "red" },
71 { "peerinfo", "# peers known", "peers known", "brown" },
72 { "nse", "# nodes in the network (estimate)", "network size (estimate)", "purple" },
73 { NULL, NULL, NULL}
74 };
75
76
77static const struct PlotInfo traffic_data[] =
78 {
79 { "core", "# bytes encrypted", "bytes encrypted", "blue" },
80 { "core", "# bytes decrypted", "bytes decrypted", "green" },
81 { "transport", "# bytes received via TCP", "received via tcp", "yellow" },
82 { "transport", "# bytes transmitted via TCP", "sent via tcp", "brown" },
83 { NULL, NULL, NULL}
84 };
85
86
87static const struct PlotInfo storage_data[] =
88 {
89 { "datastore", "# quota", "datastore capacity", "blue" },
90 { "datastore", "# bytes stored", "datastore utilization", "yellow" },
91 { "datastore", "# cache size", "reservation for datastore cache", "green" },
92 { "datastore", "# bytes purged (low-priority)", "discarded due to limited space", "red" },
62 { NULL, NULL, NULL} 93 { NULL, NULL, NULL}
63 }; 94 };
64 95
@@ -83,6 +114,11 @@ static struct GNUNET_STATISTICS_Handle *statistics;
83 */ 114 */
84static GNUNET_SCHEDULER_TaskIdentifier connection_task; 115static GNUNET_SCHEDULER_TaskIdentifier connection_task;
85 116
117/**
118 * When did this process start?
119 */
120static struct GNUNET_TIME_Absolute start_time;
121
86 122
87/** 123/**
88 * Callback function to process statistic values. 124 * Callback function to process statistic values.
@@ -103,8 +139,8 @@ process_value_update (void *cls, const char *subsystem,
103 139
104 gtk_statistics_update_value (stats, 140 gtk_statistics_update_value (stats,
105 name, 141 name,
106 value, 142 GNUNET_TIME_absolute_get_duration (start_time).rel_value / 1000LL,
107 GNUNET_TIME_absolute_get().abs_value); 143 value);
108 return GNUNET_OK; 144 return GNUNET_OK;
109} 145}
110 146
@@ -128,17 +164,22 @@ get_object (const char *name)
128 * @param widget size and style information for the plot 164 * @param widget size and style information for the plot
129 * @param info what to draw 165 * @param info what to draw
130 */ 166 */
131/* static */ GtkStatistics * 167static void
132create_plot (const struct PlotInfo *info) 168create_plot (const char *box_name,
169 const struct PlotInfo *info)
133{ 170{
171 GtkBox *box;
134 GtkStatistics *ret; 172 GtkStatistics *ret;
135 unsigned int i; 173 unsigned int i;
136 174
137 ret = GTK_STATISTICS (gtk_statistics_new ()); 175 ret = GTK_STATISTICS (gtk_statistics_new ());
176 box = GTK_BOX (get_object (box_name));
177
138 for (i=0; NULL != info[i].subsystem; i++) 178 for (i=0; NULL != info[i].subsystem; i++)
139 { 179 {
140 gtk_statistics_add_line (ret, 180 gtk_statistics_add_line (ret,
141 info[i].name, 181 info[i].name,
182 info[i].label,
142 info[i].color_name); 183 info[i].color_name);
143 GNUNET_STATISTICS_watch (statistics, 184 GNUNET_STATISTICS_watch (statistics,
144 info[i].subsystem, 185 info[i].subsystem,
@@ -146,7 +187,12 @@ create_plot (const struct PlotInfo *info)
146 &process_value_update, 187 &process_value_update,
147 ret); 188 ret);
148 } 189 }
149 return ret; 190 gtk_widget_show (GTK_WIDGET (ret));
191 gtk_box_pack_start (box,
192 GTK_WIDGET (ret),
193 TRUE,
194 TRUE,
195 0);
150} 196}
151 197
152 198
@@ -209,6 +255,14 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
209 GNUNET_GTK_tray_icon_create (GTK_WINDOW (main_window), 255 GNUNET_GTK_tray_icon_create (GTK_WINDOW (main_window),
210 "gnunet-gtk" /* FIXME: different icon? */ , 256 "gnunet-gtk" /* FIXME: different icon? */ ,
211 "gnunet-statistics-gtk"); 257 "gnunet-statistics-gtk");
258
259 create_plot ("GNUNET_STATISTICS_GTK_connectivity_box",
260 connection_data);
261 create_plot ("GNUNET_STATISTICS_GTK_traffic_box",
262 traffic_data);
263 create_plot ("GNUNET_STATISTICS_GTK_storage_box",
264 storage_data);
265
212 /* make GUI visible */ 266 /* make GUI visible */
213 if (!tray_only) 267 if (!tray_only)
214 { 268 {
@@ -228,6 +282,7 @@ main (int argc, char *const *argv)
228 GNUNET_GETOPT_OPTION_END 282 GNUNET_GETOPT_OPTION_END
229 }; 283 };
230 284
285 start_time = GNUNET_TIME_absolute_get ();
231 if (GNUNET_OK != 286 if (GNUNET_OK !=
232 GNUNET_GTK_main_loop_start ("gnunet-statistics-gtk", 287 GNUNET_GTK_main_loop_start ("gnunet-statistics-gtk",
233 "GTK GUI for viewing GNUnet statistics", argc, 288 "GTK GUI for viewing GNUnet statistics", argc,
diff --git a/src/statistics/gtk_statistics.c b/src/statistics/gtk_statistics.c
index b1d7fe84..c483794d 100644
--- a/src/statistics/gtk_statistics.c
+++ b/src/statistics/gtk_statistics.c
@@ -39,6 +39,9 @@
39 */ 39 */
40#define YTICKS 5 40#define YTICKS 5
41 41
42/**
43 * Additional distance between text and lines / borders in pixels.
44 */
42#define BORDER 10.0 45#define BORDER 10.0
43 46
44 47
@@ -66,6 +69,11 @@ struct ValueHistory
66{ 69{
67 70
68 /** 71 /**
72 * ID for value updates.
73 */
74 char *id;
75
76 /**
69 * Label for the subsystem. 77 * Label for the subsystem.
70 */ 78 */
71 char *label; 79 char *label;
@@ -172,9 +180,16 @@ gtk_statistics_new ()
172 180
173 181
174/** 182/**
183 * Add another data series to plot by the statistics widget.
184 *
185 * @param statistics widget to modify
186 * @param id identifier for the series
187 * @param label label to use
188 * @param color_name name of the color to use
175 */ 189 */
176void 190void
177gtk_statistics_add_line (GtkStatistics *statistics, 191gtk_statistics_add_line (GtkStatistics *statistics,
192 const char *id,
178 const char *label, 193 const char *label,
179 const char *color_name) 194 const char *color_name)
180{ 195{
@@ -188,6 +203,7 @@ gtk_statistics_add_line (GtkStatistics *statistics,
188 priv->values = g_realloc (priv->values, 203 priv->values = g_realloc (priv->values,
189 sizeof (struct ValueHistory*) * (1 + priv->num_values)); 204 sizeof (struct ValueHistory*) * (1 + priv->num_values));
190 priv->values[priv->num_values++] = vh = g_malloc (sizeof (struct ValueHistory)); 205 priv->values[priv->num_values++] = vh = g_malloc (sizeof (struct ValueHistory));
206 vh->id = strdup (id);
191 vh->label = strdup (label); 207 vh->label = strdup (label);
192 vh->red = c.red / 65535.0; 208 vh->red = c.red / 65535.0;
193 vh->green = c.green / 65535.0; 209 vh->green = c.green / 65535.0;
@@ -196,10 +212,16 @@ gtk_statistics_add_line (GtkStatistics *statistics,
196 212
197 213
198/** 214/**
215 * Add another value to a data series.
216 *
217 * @param statistics widget to update
218 * @param id identifier of the series
219 * @param x new x-value
220 * @param y new y-value
199 */ 221 */
200void 222void
201gtk_statistics_update_value (GtkStatistics *statistics, 223gtk_statistics_update_value (GtkStatistics *statistics,
202 const char *label, 224 const char *id,
203 uint64_t x, 225 uint64_t x,
204 uint64_t y) 226 uint64_t y)
205{ 227{
@@ -213,14 +235,15 @@ gtk_statistics_update_value (GtkStatistics *statistics,
213 for (i=0;i<priv->num_values;i++) 235 for (i=0;i<priv->num_values;i++)
214 { 236 {
215 vh = priv->values[i]; 237 vh = priv->values[i];
216 if (0 != strcmp (label, vh->label)) 238 if (0 != strcmp (id, vh->id))
217 continue; 239 continue;
240
218 if (++vh->last_history_offset == MAX_HISTORY) 241 if (++vh->last_history_offset == MAX_HISTORY)
219 vh->last_history_offset = 0; 242 vh->last_history_offset = 0;
220 if (vh->history_size < MAX_HISTORY) 243 if (vh->history_size < MAX_HISTORY)
221 vh->history_size++; 244 vh->history_size++;
222 vh->history[vh->last_history_offset].x = x; 245 vh->history[vh->last_history_offset].x = x;
223 vh->history[vh->last_history_offset].y = y; 246 vh->history[vh->last_history_offset].y = y;
224 widget = GTK_WIDGET (statistics); 247 widget = GTK_WIDGET (statistics);
225 if (gtk_widget_is_drawable (widget)) 248 if (gtk_widget_is_drawable (widget))
226 gtk_widget_queue_draw (widget); 249 gtk_widget_queue_draw (widget);
@@ -228,11 +251,19 @@ gtk_statistics_update_value (GtkStatistics *statistics,
228} 251}
229 252
230 253
254/**
255 * Convert a number to a nice label for the axis.
256 *
257 * @param num number to convert
258 * @param label where to store the string (must be big enough!)
259 */
231static void 260static void
232num_to_label (unsigned long long num, 261num_to_label (unsigned long long num,
233 char *label) 262 char *label)
234{ 263{
235 if (num > 1000LL * 1000 * 1000 * 3) 264 if (num > 1000LL * 1000 * 1000 * 1000 * 3)
265 sprintf (label, "%llu t", num / 1000LL / 1000LL / 1000LL / 1000LL);
266 else if (num > 1000LL * 1000 * 1000 * 3)
236 sprintf (label, "%llu g", num / 1000LL / 1000LL / 1000LL); 267 sprintf (label, "%llu g", num / 1000LL / 1000LL / 1000LL);
237 else if (num > 1000LL * 1000 * 3) 268 else if (num > 1000LL * 1000 * 3)
238 sprintf (label, "%llu m", num / 1000LL / 1000LL); 269 sprintf (label, "%llu m", num / 1000LL / 1000LL);
@@ -243,6 +274,12 @@ num_to_label (unsigned long long num,
243} 274}
244 275
245 276
277/**
278 * Draw the statistics widget.
279 *
280 * @param widget widget to draw
281 * @param cr drawing context
282 */
246static gboolean 283static gboolean
247gtk_statistics_draw (GtkWidget *widget, 284gtk_statistics_draw (GtkWidget *widget,
248 cairo_t *cr) 285 cairo_t *cr)
@@ -264,6 +301,7 @@ gtk_statistics_draw (GtkWidget *widget,
264 cairo_text_extents_t tey_max; 301 cairo_text_extents_t tey_max;
265 double rx; 302 double rx;
266 double ry; 303 double ry;
304 unsigned int h;
267 305
268 /* collect basic data */ 306 /* collect basic data */
269 xmin = UINT64_MAX; 307 xmin = UINT64_MAX;
@@ -292,7 +330,7 @@ gtk_statistics_draw (GtkWidget *widget,
292 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); 330 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
293 cairo_paint(cr); 331 cairo_paint(cr);
294 332
295 if (0 == priv->num_values) 333 if ( (0 == priv->num_values) || (ymax == 0) )
296 return FALSE; /* done */ 334 return FALSE; /* done */
297 /* select font */ 335 /* select font */
298 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); 336 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
@@ -379,10 +417,26 @@ gtk_statistics_draw (GtkWidget *widget,
379 417
380 /* finally, plot lines */ 418 /* finally, plot lines */
381 cairo_set_line_width (cr, 2.0); 419 cairo_set_line_width (cr, 2.0);
420
421 cairo_set_font_size (cr,
422 GNUNET_MIN (20, (height - 3.0 * BORDER - tex_max.height - tey_max.height / 2) / (priv->num_values + 1)));
423
424 h = 2.0 * BORDER + tey_max.height / 2;
425
382 for (i=0;i<priv->num_values;i++) 426 for (i=0;i<priv->num_values;i++)
383 { 427 {
384 vh = priv->values[i]; 428 vh = priv->values[i];
385 cairo_set_source_rgb(cr, vh->red, vh->green, vh->blue); 429 cairo_set_source_rgb(cr, vh->red, vh->green, vh->blue);
430 cairo_text_extents (cr, vh->label, &te);
431 h += te.height / 2;
432 cairo_move_to (cr,
433 3.0 * BORDER + tey_max.width,
434 h);
435 h += te.height / 2 + 1.0;
436 cairo_show_text (cr, vh->label);
437 if (xmax == xmin)
438 continue;
439
386 for (j=0;j<vh->history_size;j++) 440 for (j=0;j<vh->history_size;j++)
387 { 441 {
388 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) % MAX_HISTORY]; 442 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) % MAX_HISTORY];
@@ -391,14 +445,15 @@ gtk_statistics_draw (GtkWidget *widget,
391 445
392 rx = tey_max.width + BORDER * 2.0 + (rx * (width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0)); 446 rx = tey_max.width + BORDER * 2.0 + (rx * (width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0));
393 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 - tey_max.height - tex_max.height); 447 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 - tey_max.height - tex_max.height);
394 if (j == 0) 448
395 { 449 /* if y-values are small, offset y-values a bit to allow overlapping curves to still show up */
396 cairo_move_to (cr, rx, ry); 450 if (ymax < height / (priv->num_values * 4))
397 } 451 ry += priv->num_values * 2 - (4 * i);
398 else 452 if (j == 0)
399 { 453 cairo_move_to (cr,
400 cairo_line_to (cr, rx, ry); 454 width - BORDER - tex_max.width / 2.0,
401 } 455 ry);
456 cairo_line_to (cr, rx, ry);
402 } 457 }
403 cairo_stroke (cr); 458 cairo_stroke (cr);
404 } 459 }
@@ -406,6 +461,11 @@ gtk_statistics_draw (GtkWidget *widget,
406} 461}
407 462
408 463
464/**
465 * Free memory used by statistics object.
466 *
467 * @param object object to release
468 */
409static void 469static void
410gtk_statistics_finalize (GObject *object) 470gtk_statistics_finalize (GObject *object)
411{ 471{
@@ -416,6 +476,7 @@ gtk_statistics_finalize (GObject *object)
416 for (i=0;i<priv->num_values;i++) 476 for (i=0;i<priv->num_values;i++)
417 { 477 {
418 g_free (priv->values[i]->label); 478 g_free (priv->values[i]->label);
479 g_free (priv->values[i]->id);
419 g_free (priv->values[i]); 480 g_free (priv->values[i]);
420 } 481 }
421 g_free (priv->values); 482 g_free (priv->values);
diff --git a/src/statistics/gtk_statistics.h b/src/statistics/gtk_statistics.h
index 1cd46f59..88a897c8 100644
--- a/src/statistics/gtk_statistics.h
+++ b/src/statistics/gtk_statistics.h
@@ -66,10 +66,11 @@ struct _GtkStatisticsClass
66GType gtk_statistics_get_type (void) G_GNUC_CONST; 66GType gtk_statistics_get_type (void) G_GNUC_CONST;
67GtkWidget* gtk_statistics_new (void); 67GtkWidget* gtk_statistics_new (void);
68void gtk_statistics_add_line (GtkStatistics *statistics, 68void gtk_statistics_add_line (GtkStatistics *statistics,
69 const char *id,
69 const char *label, 70 const char *label,
70 const char *color_name); 71 const char *color_name);
71void gtk_statistics_update_value (GtkStatistics *statistics, 72void gtk_statistics_update_value (GtkStatistics *statistics,
72 const char *label, 73 const char *id,
73 uint64_t x, 74 uint64_t x,
74 uint64_t y); 75 uint64_t y);
75 76
diff --git a/src/statistics/test.c b/src/statistics/test.c
index 9bf87473..cdd61cd0 100644
--- a/src/statistics/test.c
+++ b/src/statistics/test.c
@@ -41,6 +41,7 @@ int main (int argc, char ** argv)
41 statistics = gtk_statistics_new(); 41 statistics = gtk_statistics_new();
42 gtk_statistics_add_line (GTK_STATISTICS (statistics), 42 gtk_statistics_add_line (GTK_STATISTICS (statistics),
43 "sin", 43 "sin",
44 "sin",
44 "red"); 45 "red");
45 for (i=0;i<600;i++) 46 for (i=0;i<600;i++)
46 gtk_statistics_update_value (GTK_STATISTICS (statistics), 47 gtk_statistics_update_value (GTK_STATISTICS (statistics),
@@ -49,6 +50,7 @@ int main (int argc, char ** argv)
49 (uint64_t) (500 * (1.0 + sin(i/100.0)))); 50 (uint64_t) (500 * (1.0 + sin(i/100.0))));
50 gtk_statistics_add_line (GTK_STATISTICS (statistics), 51 gtk_statistics_add_line (GTK_STATISTICS (statistics),
51 "cos", 52 "cos",
53 "cos",
52 "blue"); 54 "blue");
53 for (i=0;i<600;i++) 55 for (i=0;i<600;i++)
54 gtk_statistics_update_value (GTK_STATISTICS (statistics), 56 gtk_statistics_update_value (GTK_STATISTICS (statistics),