aboutsummaryrefslogtreecommitdiff
path: root/src/statistics/gtk_statistics.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/statistics/gtk_statistics.c')
-rw-r--r--src/statistics/gtk_statistics.c271
1 files changed, 147 insertions, 124 deletions
diff --git a/src/statistics/gtk_statistics.c b/src/statistics/gtk_statistics.c
index 4b75b1ef..fff37cfe 100644
--- a/src/statistics/gtk_statistics.c
+++ b/src/statistics/gtk_statistics.c
@@ -115,19 +115,17 @@ struct _GtkStatisticsPrivate
115}; 115};
116 116
117 117
118static gboolean gtk_statistics_draw (GtkWidget *widget, 118static gboolean
119 cairo_t *cr); 119gtk_statistics_draw (GtkWidget * widget, cairo_t * cr);
120 120
121static void gtk_statistics_finalize (GObject *object); 121static void
122gtk_statistics_finalize (GObject * object);
122 123
123 124
124G_DEFINE_TYPE (GtkStatistics, gtk_statistics, GTK_TYPE_WIDGET) 125G_DEFINE_TYPE (GtkStatistics, gtk_statistics, GTK_TYPE_WIDGET)
125
126
127#if GTK_MAJOR_VERSION < 3 126#if GTK_MAJOR_VERSION < 3
128static gboolean 127 static gboolean statistics_expose (GtkWidget * statistics,
129statistics_expose (GtkWidget *statistics, 128 GdkEventExpose * event)
130 GdkEventExpose *event)
131{ 129{
132 GtkAllocation alloc; 130 GtkAllocation alloc;
133 cairo_t *cr; 131 cairo_t *cr;
@@ -135,53 +133,51 @@ statistics_expose (GtkWidget *statistics,
135 gint y; 133 gint y;
136 134
137 gtk_widget_translate_coordinates (statistics, 135 gtk_widget_translate_coordinates (statistics,
138 GTK_WIDGET (gtk_widget_get_toplevel (statistics)), 136 GTK_WIDGET (gtk_widget_get_toplevel
139 0, 0, 137 (statistics)), 0, 0, &x, &y);
140 &x, &y);
141 gtk_widget_get_allocation (statistics, &alloc); 138 gtk_widget_get_allocation (statistics, &alloc);
142 cr = gdk_cairo_create (statistics->window); 139 cr = gdk_cairo_create (statistics->window);
143 cairo_translate (cr, x, y); 140 cairo_translate (cr, x, y);
144 cairo_rectangle (cr, 141 cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
145 0, 0,
146 alloc.width, alloc.height);
147 cairo_clip (cr); 142 cairo_clip (cr);
148 143
149 gtk_statistics_draw (statistics, cr); 144 gtk_statistics_draw (statistics, cr);
150 cairo_destroy (cr); 145 cairo_destroy (cr);
151 return FALSE; 146 return FALSE;
152} 147}
153#endif 148#endif
154 149
155 150
156static void 151static void
157gtk_statistics_class_init (GtkStatisticsClass *class) 152gtk_statistics_class_init (GtkStatisticsClass * class)
158{ 153{
159 GObjectClass *gobject_class; 154 GObjectClass *gobject_class;
160 GtkWidgetClass *widget_class; 155 GtkWidgetClass *widget_class;
161 156
162 gobject_class = (GObjectClass*) class; 157 gobject_class = (GObjectClass *) class;
163 widget_class = (GtkWidgetClass*) class; 158 widget_class = (GtkWidgetClass *) class;
164 159
165 gobject_class->finalize = gtk_statistics_finalize; 160 gobject_class->finalize = gtk_statistics_finalize;
166#if GTK_MAJOR_VERSION >= 3 161#if GTK_MAJOR_VERSION >= 3
167 widget_class->draw = gtk_statistics_draw; 162 widget_class->draw = gtk_statistics_draw;
168#endif 163#endif
169 164
170 g_type_class_add_private (class, sizeof (GtkStatisticsPrivate)); 165 g_type_class_add_private (class, sizeof (GtkStatisticsPrivate));
171} 166}
172 167
173 168
174static void 169static void
175gtk_statistics_init (GtkStatistics *statistics) 170gtk_statistics_init (GtkStatistics * statistics)
176{ 171{
177 GtkStatisticsPrivate *priv; 172 GtkStatisticsPrivate *priv;
178 173
179 statistics->priv = G_TYPE_INSTANCE_GET_PRIVATE (statistics, 174 statistics->priv =
180 GTK_TYPE_STATISTICS, 175 G_TYPE_INSTANCE_GET_PRIVATE (statistics, GTK_TYPE_STATISTICS,
181 GtkStatisticsPrivate); 176 GtkStatisticsPrivate);
182 priv = statistics->priv; 177 priv = statistics->priv;
183#if GTK_MAJOR_VERSION < 3 178#if GTK_MAJOR_VERSION < 3
184 g_signal_connect (statistics, "expose-event", G_CALLBACK (statistics_expose), statistics); 179 g_signal_connect (statistics, "expose-event", G_CALLBACK (statistics_expose),
180 statistics);
185#endif 181#endif
186 gtk_widget_set_has_window (GTK_WIDGET (statistics), FALSE); 182 gtk_widget_set_has_window (GTK_WIDGET (statistics), FALSE);
187 priv->values = NULL; 183 priv->values = NULL;
@@ -196,7 +192,7 @@ gtk_statistics_init (GtkStatistics *statistics)
196 * 192 *
197 * Returns: the new #GtkStatistics widget. 193 * Returns: the new #GtkStatistics widget.
198 */ 194 */
199GtkWidget* 195GtkWidget *
200gtk_statistics_new () 196gtk_statistics_new ()
201{ 197{
202 GtkStatisticsPrivate *priv; 198 GtkStatisticsPrivate *priv;
@@ -221,10 +217,8 @@ gtk_statistics_new ()
221 * @param color_name name of the color to use 217 * @param color_name name of the color to use
222 */ 218 */
223void 219void
224gtk_statistics_add_line (GtkStatistics *statistics, 220gtk_statistics_add_line (GtkStatistics * statistics, const char *id,
225 const char *id, 221 const char *label, const char *color_name)
226 const char *label,
227 const char *color_name)
228{ 222{
229 GtkStatisticsPrivate *priv; 223 GtkStatisticsPrivate *priv;
230 struct ValueHistory *vh; 224 struct ValueHistory *vh;
@@ -233,10 +227,12 @@ gtk_statistics_add_line (GtkStatistics *statistics,
233 g_return_if_fail (GTK_IS_STATISTICS (statistics)); 227 g_return_if_fail (GTK_IS_STATISTICS (statistics));
234 g_return_if_fail (gdk_color_parse (color_name, &c)); 228 g_return_if_fail (gdk_color_parse (color_name, &c));
235 priv = statistics->priv; 229 priv = statistics->priv;
236 priv->values = g_realloc (priv->values, 230 priv->values =
237 sizeof (struct ValueHistory*) * (1 + priv->num_values)); 231 g_realloc (priv->values,
238 priv->values[priv->num_values++] = vh = g_malloc (sizeof (struct ValueHistory)); 232 sizeof (struct ValueHistory *) * (1 + priv->num_values));
239 vh->id = strdup (id); 233 priv->values[priv->num_values++] = vh =
234 g_malloc (sizeof (struct ValueHistory));
235 vh->id = strdup (id);
240 vh->label = strdup (label); 236 vh->label = strdup (label);
241 vh->red = c.red / 65535.0; 237 vh->red = c.red / 65535.0;
242 vh->green = c.green / 65535.0; 238 vh->green = c.green / 65535.0;
@@ -248,17 +244,15 @@ gtk_statistics_add_line (GtkStatistics *statistics,
248 244
249/** 245/**
250 * Add another value to a data series. 246 * Add another value to a data series.
251 * 247 *
252 * @param statistics widget to update 248 * @param statistics widget to update
253 * @param id identifier of the series 249 * @param id identifier of the series
254 * @param x new x-value 250 * @param x new x-value
255 * @param y new y-value 251 * @param y new y-value
256 */ 252 */
257void 253void
258gtk_statistics_update_value (GtkStatistics *statistics, 254gtk_statistics_update_value (GtkStatistics * statistics, const char *id,
259 const char *id, 255 uint64_t x, uint64_t y)
260 uint64_t x,
261 uint64_t y)
262{ 256{
263 GtkStatisticsPrivate *priv; 257 GtkStatisticsPrivate *priv;
264 GtkWidget *widget; 258 GtkWidget *widget;
@@ -267,7 +261,7 @@ gtk_statistics_update_value (GtkStatistics *statistics,
267 261
268 g_return_if_fail (GTK_IS_STATISTICS (statistics)); 262 g_return_if_fail (GTK_IS_STATISTICS (statistics));
269 priv = statistics->priv; 263 priv = statistics->priv;
270 for (i=0;i<priv->num_values;i++) 264 for (i = 0; i < priv->num_values; i++)
271 { 265 {
272 vh = priv->values[i]; 266 vh = priv->values[i];
273 if (0 != strcmp (id, vh->id)) 267 if (0 != strcmp (id, vh->id))
@@ -278,7 +272,7 @@ gtk_statistics_update_value (GtkStatistics *statistics,
278 if (vh->history_size < MAX_HISTORY) 272 if (vh->history_size < MAX_HISTORY)
279 vh->history_size++; 273 vh->history_size++;
280 vh->history[vh->last_history_offset].x = x; 274 vh->history[vh->last_history_offset].x = x;
281 vh->history[vh->last_history_offset].y = y; 275 vh->history[vh->last_history_offset].y = y;
282 widget = GTK_WIDGET (statistics); 276 widget = GTK_WIDGET (statistics);
283 if (gtk_widget_is_drawable (widget)) 277 if (gtk_widget_is_drawable (widget))
284 gtk_widget_queue_draw (widget); 278 gtk_widget_queue_draw (widget);
@@ -293,8 +287,7 @@ gtk_statistics_update_value (GtkStatistics *statistics,
293 * @param label where to store the string (must be big enough!) 287 * @param label where to store the string (must be big enough!)
294 */ 288 */
295static void 289static void
296num_to_label (unsigned long long num, 290num_to_label (unsigned long long num, char *label)
297 char *label)
298{ 291{
299 if (num > 1000LL * 1000 * 1000 * 1000 * 3) 292 if (num > 1000LL * 1000 * 1000 * 1000 * 3)
300 sprintf (label, "%llu t", num / 1000LL / 1000LL / 1000LL / 1000LL); 293 sprintf (label, "%llu t", num / 1000LL / 1000LL / 1000LL / 1000LL);
@@ -316,8 +309,7 @@ num_to_label (unsigned long long num,
316 * @param cr drawing context 309 * @param cr drawing context
317 */ 310 */
318static gboolean 311static gboolean
319gtk_statistics_draw (GtkWidget *widget, 312gtk_statistics_draw (GtkWidget * widget, cairo_t * cr)
320 cairo_t *cr)
321{ 313{
322 GtkStatistics *statistics = GTK_STATISTICS (widget); 314 GtkStatistics *statistics = GTK_STATISTICS (widget);
323 GtkStatisticsPrivate *priv = statistics->priv; 315 GtkStatisticsPrivate *priv = statistics->priv;
@@ -343,168 +335,199 @@ gtk_statistics_draw (GtkWidget *widget,
343 xmin = UINT64_MAX; 335 xmin = UINT64_MAX;
344 xmax = 0; 336 xmax = 0;
345 ymax = 0; 337 ymax = 0;
346 for (i=0;i<priv->num_values;i++) 338 for (i = 0; i < priv->num_values; i++)
347 { 339 {
348 vh = priv->values[i]; 340 vh = priv->values[i];
349 for (j=0;j<vh->history_size;j++) 341 for (j = 0; j < vh->history_size; j++)
350 { 342 {
351 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) % MAX_HISTORY]; 343 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) %
344 MAX_HISTORY];
352 xmin = GNUNET_MIN (hv->x, xmin); 345 xmin = GNUNET_MIN (hv->x, xmin);
353 xmax = GNUNET_MAX (hv->x, xmax); 346 xmax = GNUNET_MAX (hv->x, xmax);
354 ymax = GNUNET_MAX (hv->y, ymax); 347 ymax = GNUNET_MAX (hv->y, ymax);
355 } 348 }
356 } 349 }
357 /* round to 10x for nicer legends */ 350 /* round to 10x for nicer legends */
358 while (0 != (ymax % 10)) ymax++; 351 while (0 != (ymax % 10))
359 while (0 != (xmax % 10)) xmax++; 352 ymax++;
360 while (0 != (xmin % 10)) xmin--; 353 while (0 != (xmax % 10))
354 xmax++;
355 while (0 != (xmin % 10))
356 xmin--;
361 357
362 gtk_widget_get_allocation (widget, &alloc); 358 gtk_widget_get_allocation (widget, &alloc);
363 width = alloc.width; 359 width = alloc.width;
364 height = alloc.height; 360 height = alloc.height;
365 361
366 /* fill with black background */ 362 /* fill with black background */
367 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); 363 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
368 cairo_paint(cr); 364 cairo_paint (cr);
369 365
370 if ( (0 == priv->num_values) || (ymax == 0) ) 366 if ((0 == priv->num_values) || (ymax == 0))
371 return FALSE; /* done */ 367 return FALSE; /* done */
372 /* select font */ 368 /* select font */
373 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); 369 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
374 cairo_select_font_face (cr, "Georgia", 370 cairo_select_font_face (cr, "Georgia", CAIRO_FONT_SLANT_NORMAL,
375 CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); 371 CAIRO_FONT_WEIGHT_BOLD);
376 cairo_set_font_size (cr, 372 cairo_set_font_size (cr, GNUNET_MIN (20, height / (2 * XTICKS)));
377 GNUNET_MIN (20, height / (2 * XTICKS)));
378 373
379 /* find out needed space for axis labels */ 374 /* find out needed space for axis labels */
380 tex_max.width = 0; 375 tex_max.width = 0;
381 tex_max.height = 0; 376 tex_max.height = 0;
382 for (i=0;i<XTICKS;i++) 377 for (i = 0; i < XTICKS; i++)
383 { 378 {
384 num_to_label ((unsigned long long) (xmin + (xmax - xmin) * ((uint64_t) i) / (XTICKS - 1)), 379 num_to_label ((unsigned long long) (xmin +
385 label); 380 (xmax -
381 xmin) * ((uint64_t) i) / (XTICKS - 1)),
382 label);
386 cairo_text_extents (cr, label, &te); 383 cairo_text_extents (cr, label, &te);
387 tex_max.width = GNUNET_MAX (te.width, tex_max.width); 384 tex_max.width = GNUNET_MAX (te.width, tex_max.width);
388 tex_max.height = GNUNET_MAX (te.height, tex_max.height); 385 tex_max.height = GNUNET_MAX (te.height, tex_max.height);
389 } 386 }
390 tey_max.width = 0; 387 tey_max.width = 0;
391 tey_max.height = 0; 388 tey_max.height = 0;
392 for (i=0;i<YTICKS;i++) 389 for (i = 0; i < YTICKS; i++)
393 { 390 {
394 num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1), 391 num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1),
395 label); 392 label);
396 cairo_text_extents (cr, label, &te); 393 cairo_text_extents (cr, label, &te);
397 tey_max.width = GNUNET_MAX (te.width, tey_max.width); 394 tey_max.width = GNUNET_MAX (te.width, tey_max.width);
398 tey_max.height = GNUNET_MAX (te.height, tey_max.height); 395 tey_max.height = GNUNET_MAX (te.height, tey_max.height);
399 } 396 }
400 397
401 /* draw y-axis labels */ 398 /* draw y-axis labels */
402 for (i=0;i<YTICKS;i++) 399 for (i = 0; i < YTICKS; i++)
403 { 400 {
404 num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1), 401 num_to_label ((unsigned long long) ymax * ((uint64_t) i) / (YTICKS - 1),
405 label); 402 label);
406 cairo_text_extents (cr, label, &te); 403 cairo_text_extents (cr, label, &te);
407 cairo_move_to (cr, 404 cairo_move_to (cr, BORDER + tey_max.width - te.width,
408 BORDER + tey_max.width - te.width, 405 BORDER + tey_max.height + (YTICKS - i - 1) * (height -
409 BORDER + tey_max.height + (YTICKS - i - 1) * (height - 2.0 * BORDER - tey_max.height - tex_max.height) / (double) (YTICKS - 1)); 406 2.0 * BORDER -
407 tey_max.height
408 -
409 tex_max.height)
410 / (double) (YTICKS - 1));
410 cairo_show_text (cr, label); 411 cairo_show_text (cr, label);
411 412
412 413
413 cairo_move_to (cr, 414 cairo_move_to (cr, 2.0 * BORDER + tey_max.width,
414 2.0 * BORDER + tey_max.width, 415 BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height -
415 BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height - 2.0 * BORDER - tex_max.height - tey_max.height) / (double) (YTICKS - 1)); 416 2.0 *
416 cairo_line_to (cr, 417 BORDER -
417 2.0 * BORDER + tey_max.width + BORDER / 2.0, 418 tex_max.height
418 BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height - 2.0 * BORDER - tex_max.height - tey_max.height) / (double) (YTICKS - 1)); 419 -
420 tey_max.height)
421 / (double) (YTICKS - 1));
422 cairo_line_to (cr, 2.0 * BORDER + tey_max.width + BORDER / 2.0,
423 BORDER + tey_max.height / 2.0 + (YTICKS - i - 1) * (height -
424 2.0 *
425 BORDER -
426 tex_max.height
427 -
428 tey_max.height)
429 / (double) (YTICKS - 1));
419 430
420 cairo_stroke (cr); 431 cairo_stroke (cr);
421 } 432 }
422 433
423 /* draw x-axis labels */ 434 /* draw x-axis labels */
424 for (i=0;i<XTICKS;i++) 435 for (i = 0; i < XTICKS; i++)
425 { 436 {
426 num_to_label ((unsigned long long) (xmin + (xmax - xmin) * ((uint64_t) i) / (XTICKS - 1)), 437 num_to_label ((unsigned long long) (xmin +
427 label); 438 (xmax -
439 xmin) * ((uint64_t) i) / (XTICKS - 1)),
440 label);
428 cairo_text_extents (cr, label, &te); 441 cairo_text_extents (cr, label, &te);
429 if (i != 0) 442 if (i != 0)
430 { 443 {
431 cairo_move_to (cr, 444 cairo_move_to (cr,
432 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, 445 2.0 * BORDER + tey_max.width + (width - tey_max.width -
433 height - BORDER / 2.0 - tex_max.height / 2.0); 446 tex_max.width / 2.0 -
447 3.0 * BORDER) * i /
448 (XTICKS - 1.0) - te.width / 2.0,
449 height - BORDER / 2.0 - tex_max.height / 2.0);
434 cairo_show_text (cr, label); 450 cairo_show_text (cr, label);
435 } 451 }
436 cairo_move_to (cr, 452 cairo_move_to (cr,
437 2.0 * BORDER + tey_max.width + (width - tey_max.width - tex_max.width / 2.0 - 3.0 * BORDER) * i / (XTICKS - 1.0), 453 2.0 * BORDER + tey_max.width + (width - tey_max.width -
438 height - BORDER - tey_max.height / 2.0 - tex_max.height); 454 tex_max.width / 2.0 -
439 cairo_line_to (cr, 455 3.0 * BORDER) * i / (XTICKS -
440 2.0 * BORDER + tey_max.width + (width - tey_max.width - tex_max.width / 2.0 - 3.0 * BORDER) * i / (XTICKS - 1.0), 456 1.0),
441 height - BORDER - tey_max.height / 2.0 - tex_max.height - BORDER / 2.0); 457 height - BORDER - tey_max.height / 2.0 - tex_max.height);
458 cairo_line_to (cr,
459 2.0 * BORDER + tey_max.width + (width - tey_max.width -
460 tex_max.width / 2.0 -
461 3.0 * BORDER) * i / (XTICKS -
462 1.0),
463 height - BORDER - tey_max.height / 2.0 - tex_max.height -
464 BORDER / 2.0);
442 465
443 cairo_stroke (cr); 466 cairo_stroke (cr);
444 } 467 }
445 468
446 /* plot border */ 469 /* plot border */
447 cairo_set_line_width (cr, 1.0); 470 cairo_set_line_width (cr, 1.0);
448 cairo_rectangle (cr, 471 cairo_rectangle (cr, tey_max.width + BORDER * 2.0,
449 tey_max.width + BORDER * 2.0, 472 BORDER + tey_max.height / 2.0,
450 BORDER + tey_max.height / 2.0, 473 width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0,
451 width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0, 474 height - BORDER * 2.0 - tey_max.height - tex_max.height);
452 height - BORDER * 2.0 - tey_max.height - tex_max.height);
453 cairo_stroke (cr); 475 cairo_stroke (cr);
454 476
455 /* finally, plot lines */ 477 /* finally, plot lines */
456 cairo_set_line_width (cr, 2.0); 478 cairo_set_line_width (cr, 2.0);
457 479
458 cairo_set_font_size (cr, 480 cairo_set_font_size (cr,
459 GNUNET_MIN (20, (height - 3.0 * BORDER - tex_max.height - tey_max.height / 2) / (priv->num_values + 1))); 481 GNUNET_MIN (20,
482 (height - 3.0 * BORDER - tex_max.height -
483 tey_max.height / 2) / (priv->num_values +
484 1)));
460 485
461 h = 2.0 * BORDER + tey_max.height / 2; 486 h = 2.0 * BORDER + tey_max.height / 2;
462 487
463 for (i=0;i<priv->num_values;i++) 488 for (i = 0; i < priv->num_values; i++)
464 { 489 {
465 vh = priv->values[i]; 490 vh = priv->values[i];
466 cairo_set_source_rgb(cr, vh->red, vh->green, vh->blue); 491 cairo_set_source_rgb (cr, vh->red, vh->green, vh->blue);
467 cairo_text_extents (cr, vh->label, &te); 492 cairo_text_extents (cr, vh->label, &te);
468 h += te.height / 2; 493 h += te.height / 2;
469 cairo_move_to (cr, 494 cairo_move_to (cr, 3.0 * BORDER + tey_max.width, h);
470 3.0 * BORDER + tey_max.width,
471 h);
472 h += te.height / 2 + 1.0; 495 h += te.height / 2 + 1.0;
473 cairo_show_text (cr, vh->label); 496 cairo_show_text (cr, vh->label);
474 if (xmax == xmin) 497 if (xmax == xmin)
475 { 498 {
476 hv = &vh->history[vh->last_history_offset % MAX_HISTORY]; 499 hv = &vh->history[vh->last_history_offset % MAX_HISTORY];
477 ry = hv->y / (double) ymax; 500 ry = hv->y / (double) ymax;
478 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 - tey_max.height - tex_max.height); 501 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 -
502 tey_max.height -
503 tex_max.height);
479 /* if y-values are small, offset y-values a bit to allow overlapping curves to still show up */ 504 /* if y-values are small, offset y-values a bit to allow overlapping curves to still show up */
480 if (ymax < height / (priv->num_values * 4)) 505 if (ymax < height / (priv->num_values * 4))
481 ry += priv->num_values * 2 - (4 * i); 506 ry += priv->num_values * 2 - (4 * i);
482 cairo_move_to (cr, 507 cairo_move_to (cr, width - BORDER - tex_max.width / 2.0, ry);
483 width - BORDER - tex_max.width / 2.0, 508 cairo_line_to (cr, rx = tey_max.width + BORDER * 2.0, ry);
484 ry);
485 cairo_line_to (cr,
486 rx = tey_max.width + BORDER * 2.0,
487 ry);
488 cairo_stroke (cr); 509 cairo_stroke (cr);
489 continue; 510 continue;
490 } 511 }
491 512
492 for (j=0;j<vh->history_size;j++) 513 for (j = 0; j < vh->history_size; j++)
493 { 514 {
494 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) % MAX_HISTORY]; 515 hv = &vh->history[(vh->last_history_offset - j + MAX_HISTORY) %
516 MAX_HISTORY];
495 rx = (hv->x - xmin) / (double) (xmax - xmin); 517 rx = (hv->x - xmin) / (double) (xmax - xmin);
496 ry = hv->y / (double) ymax; 518 ry = hv->y / (double) ymax;
497 519
498 rx = tey_max.width + BORDER * 2.0 + (rx * (width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0)); 520 rx = tey_max.width + BORDER * 2.0 +
499 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 - tey_max.height - tex_max.height); 521 (rx * (width - BORDER * 3.0 - tey_max.width - tex_max.width / 2.0));
522 ry = BORDER + tex_max.height / 2.0 + (1.0 - ry) * (height - BORDER * 2.0 -
523 tey_max.height -
524 tex_max.height);
500 525
501 /* if y-values are small, offset y-values a bit to allow overlapping curves to still show up */ 526 /* if y-values are small, offset y-values a bit to allow overlapping curves to still show up */
502 if (ymax < height / (priv->num_values * 4)) 527 if (ymax < height / (priv->num_values * 4))
503 ry += priv->num_values * 2 - (4 * i); 528 ry += priv->num_values * 2 - (4 * i);
504 if (j == 0) 529 if (j == 0)
505 cairo_move_to (cr, 530 cairo_move_to (cr, width - BORDER - tex_max.width / 2.0, ry);
506 width - BORDER - tex_max.width / 2.0,
507 ry);
508 cairo_line_to (cr, rx, ry); 531 cairo_line_to (cr, rx, ry);
509 } 532 }
510 cairo_stroke (cr); 533 cairo_stroke (cr);
@@ -519,19 +542,19 @@ gtk_statistics_draw (GtkWidget *widget,
519 * @param object object to release 542 * @param object object to release
520 */ 543 */
521static void 544static void
522gtk_statistics_finalize (GObject *object) 545gtk_statistics_finalize (GObject * object)
523{ 546{
524 GtkStatistics *label = GTK_STATISTICS (object); 547 GtkStatistics *label = GTK_STATISTICS (object);
525 GtkStatisticsPrivate *priv = label->priv; 548 GtkStatisticsPrivate *priv = label->priv;
526 unsigned int i; 549 unsigned int i;
527 550
528 for (i=0;i<priv->num_values;i++) 551 for (i = 0; i < priv->num_values; i++)
529 { 552 {
530 g_free (priv->values[i]->label); 553 g_free (priv->values[i]->label);
531 g_free (priv->values[i]->id); 554 g_free (priv->values[i]->id);
532 g_free (priv->values[i]); 555 g_free (priv->values[i]);
533 } 556 }
534 g_free (priv->values); 557 g_free (priv->values);
535 G_OBJECT_CLASS (gtk_statistics_parent_class)->finalize (object); 558 G_OBJECT_CLASS (gtk_statistics_parent_class)->finalize (object);
536} 559}
537 560