diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-12-09 16:59:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-12-09 16:59:03 +0000 |
commit | d6f936b6ed351a1db764351bd134f7ff5ff828e9 (patch) | |
tree | af2fc7c8527f3279adc4d6f683c1fc5428c2db84 | |
parent | 80cff456f59a2f316bb8ef4acc60f0a3a2a92d42 (diff) | |
download | gnunet-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.c | 69 | ||||
-rw-r--r-- | src/statistics/gtk_statistics.c | 87 | ||||
-rw-r--r-- | src/statistics/gtk_statistics.h | 3 | ||||
-rw-r--r-- | src/statistics/test.c | 2 |
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 | ||
59 | static const struct PlotInfo connection_data[] = | 64 | static 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 | |||
77 | static 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 | |||
87 | static 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 | */ |
84 | static GNUNET_SCHEDULER_TaskIdentifier connection_task; | 115 | static GNUNET_SCHEDULER_TaskIdentifier connection_task; |
85 | 116 | ||
117 | /** | ||
118 | * When did this process start? | ||
119 | */ | ||
120 | static 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 * | 167 | static void |
132 | create_plot (const struct PlotInfo *info) | 168 | create_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 | */ |
176 | void | 190 | void |
177 | gtk_statistics_add_line (GtkStatistics *statistics, | 191 | gtk_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 | */ |
200 | void | 222 | void |
201 | gtk_statistics_update_value (GtkStatistics *statistics, | 223 | gtk_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 | */ | ||
231 | static void | 260 | static void |
232 | num_to_label (unsigned long long num, | 261 | num_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 | */ | ||
246 | static gboolean | 283 | static gboolean |
247 | gtk_statistics_draw (GtkWidget *widget, | 284 | gtk_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 | */ | ||
409 | static void | 469 | static void |
410 | gtk_statistics_finalize (GObject *object) | 470 | gtk_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 | |||
66 | GType gtk_statistics_get_type (void) G_GNUC_CONST; | 66 | GType gtk_statistics_get_type (void) G_GNUC_CONST; |
67 | GtkWidget* gtk_statistics_new (void); | 67 | GtkWidget* gtk_statistics_new (void); |
68 | void gtk_statistics_add_line (GtkStatistics *statistics, | 68 | void 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); |
71 | void gtk_statistics_update_value (GtkStatistics *statistics, | 72 | void 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), |