aboutsummaryrefslogtreecommitdiff
path: root/loadgraph.c
diff options
context:
space:
mode:
Diffstat (limited to 'loadgraph.c')
-rw-r--r--loadgraph.c149
1 files changed, 119 insertions, 30 deletions
diff --git a/loadgraph.c b/loadgraph.c
index 53fb54f7..5f61fca3 100644
--- a/loadgraph.c
+++ b/loadgraph.c
@@ -33,6 +33,9 @@ LoadGraph *load_graph_new(gint size)
lg = g_new0(LoadGraph, 1);
+ size++;
+
+ lg->suffix = g_strdup("");
lg->area = gtk_drawing_area_new();
lg->size = size;
lg->data = g_new0(gint, size);
@@ -42,12 +45,28 @@ LoadGraph *load_graph_new(gint size)
lg->width = size * 4;
lg->height = size * 2;
+ lg->max_value = 1;
+ lg->remax_count = 0;
+
+ lg->layout = pango_layout_new(gtk_widget_get_pango_context (lg->area));
+
gtk_widget_set_size_request(lg->area, lg->width, lg->height);
gtk_widget_show(lg->area);
return lg;
}
+void load_graph_set_data_suffix(LoadGraph *lg, gchar *suffix)
+{
+ g_free(lg->suffix);
+ lg->suffix = g_strdup(suffix);
+}
+
+gchar *load_graph_get_data_suffix(LoadGraph *lg)
+{
+ return lg->suffix;
+}
+
GtkWidget *load_graph_get_framed(LoadGraph *lg)
{
GtkWidget *align, *frame;
@@ -73,6 +92,9 @@ void load_graph_clear(LoadGraph *lg)
lg->data[i] = 0;
lg->scale = 1.0;
+ lg->max_value = 1;
+ lg->remax_count = 0;
+
_draw(lg);
}
@@ -80,6 +102,8 @@ void load_graph_set_color(LoadGraph *lg, LoadGraphColor color)
{
lg->color = color;
gdk_rgb_gc_set_foreground(lg->trace, lg->color);
+ gdk_rgb_gc_set_foreground(lg->fill, lg->color - 0x303030);
+ gdk_rgb_gc_set_foreground(lg->grid, lg->color - 0x404040);
}
void load_graph_destroy(LoadGraph *lg)
@@ -89,6 +113,8 @@ void load_graph_destroy(LoadGraph *lg)
gdk_pixmap_unref(lg->buf);
g_object_unref(lg->trace);
g_object_unref(lg->grid);
+ g_object_unref(lg->fill);
+ g_object_unref(lg->layout);
g_free(lg);
}
@@ -116,6 +142,7 @@ void load_graph_configure_expose(LoadGraph *lg)
/* create the graphic contexts */
lg->grid = gdk_gc_new(GDK_DRAWABLE(lg->buf));
lg->trace = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+ lg->fill = gdk_gc_new(GDK_DRAWABLE(lg->buf));
/* the default color is green */
load_graph_set_color(lg, LG_COLOR_GREEN);
@@ -125,19 +152,49 @@ void load_graph_configure_expose(LoadGraph *lg)
1, GDK_LINE_ON_OFF_DASH,
GDK_CAP_NOT_LAST,
GDK_JOIN_ROUND);
+#if 0 /* old-style grid */
gdk_rgb_gc_set_foreground(lg->grid, 0x707070);
+#endif
gdk_gc_set_line_attributes(lg->trace,
- 2, GDK_LINE_SOLID,
- GDK_CAP_NOT_LAST,
+ 1, GDK_LINE_SOLID,
+ GDK_CAP_PROJECTING,
GDK_JOIN_ROUND);
+#if 0 /* old-style fill */
+ gdk_gc_set_line_attributes(lg->fill,
+ 1, GDK_LINE_SOLID,
+ GDK_CAP_BUTT,
+ GDK_JOIN_BEVEL);
+#endif
+
/* configures the expose event */
g_signal_connect(G_OBJECT(lg->area), "expose-event",
(GCallback) _expose, lg);
}
static void
+_draw_label_and_line(LoadGraph *lg, gint position, gint value)
+{
+ gchar *tmp;
+
+ /* draw lines */
+ if (position > 0)
+ gdk_draw_line(GDK_DRAWABLE(lg->buf), lg->grid, 0, position, lg->width, position);
+ else
+ position = -1 * position;
+
+ /* draw label */
+ tmp = g_strdup_printf("<span size=\"x-small\">%d%s</span>", value, lg->suffix);
+
+ pango_layout_set_markup(lg->layout, tmp, -1);
+ pango_layout_set_width(lg->layout, lg->area->allocation.width * PANGO_SCALE);
+ gdk_draw_layout(GDK_DRAWABLE(lg->buf), lg->trace, 2, position, lg->layout);
+
+ g_free(tmp);
+}
+
+static void
_draw(LoadGraph *lg)
{
GdkDrawable *draw = GDK_DRAWABLE(lg->buf);
@@ -147,45 +204,58 @@ _draw(LoadGraph *lg)
gdk_draw_rectangle(draw, lg->area->style->black_gc,
TRUE, 0, 0, lg->width, lg->height);
- /* horizontal bars; 25%, 50% and 75% */
- d = lg->height / 4;
- gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
- d = lg->height / 2;
- gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
- d = 3 * (lg->height / 4);
- gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
+
+ /* the graph */
+ GdkPoint *points = g_new0(GdkPoint, lg->size + 1);
+
+ for (i = 0; i < lg->size; i++) {
+ points[i].x = i * 4;
+ points[i].y = lg->height - lg->data[i] * lg->scale;
+ }
+
+ points[0].x = points[1].x = 0;
+ points[0].y = points[i].y = lg->height;
+ points[i].x = points[i-1].x = lg->width;
+
+ gdk_draw_polygon(draw, lg->fill, TRUE, points, lg->size + 1);
+ gdk_draw_polygon(draw, lg->trace, FALSE, points, lg->size + 1);
+
+ g_free(points);
/* vertical bars */
for (i = lg->width, d = 0; i > 1; i--, d++)
if ((d % 45) == 0 && d)
gdk_draw_line(draw, lg->grid, i, 0, i, lg->height);
- /* the graph */
+ /* horizontal bars and labels; 25%, 50% and 75% */
+ _draw_label_and_line(lg, -1, lg->max_value);
+ _draw_label_and_line(lg, lg->height / 4, 3 * (lg->max_value / 4));
+ _draw_label_and_line(lg, lg->height / 2, lg->max_value / 2);
+ _draw_label_and_line(lg, 3 * (lg->height / 4), lg->max_value / 4);
+
+#if 0 /* old-style drawing */
for (i = 0; i < lg->size; i++) {
gint this = lg->height - lg->data[i] * lg->scale;
gint next = lg->height - lg->data[i+1] * lg->scale;
+ gint i4 = i * 4;
- gdk_draw_line(draw, lg->trace, i * 4, this, i * 4 + 2,
- (this + next) / 2);
- gdk_draw_line(draw, lg->trace, i * 4 + 2, (this + next) / 2,
- i * 4 + 4, next);
+ gdk_draw_line(draw, lg->fill, i4, this, i4, lg->height);
+ gdk_draw_line(draw, lg->fill, i4 + 2, this, i4 + 2, lg->height);
}
-
- gtk_widget_queue_draw(lg->area);
-}
-static inline int
-_max(LoadGraph *lg)
-{
- gint i;
- gint max = 1.0;
+ for (i = 0; i < lg->size; i++) {
+ gint this = lg->height - lg->data[i] * lg->scale;
+ gint next = lg->height - lg->data[i+1] * lg->scale;
+ gint i4 = i * 4;
- for (i = 0; i < lg->size; i++) {
- if (lg->data[i] > max)
- max = lg->data[i];
+ gdk_draw_line(draw, lg->trace, i4, this, i4 + 2,
+ (this + next) / 2);
+ gdk_draw_line(draw, lg->trace, i4 + 2, (this + next) / 2,
+ i4 + 4, next);
}
-
- return max;
+#endif
+
+ gtk_widget_queue_draw(lg->area);
}
void
@@ -196,8 +266,6 @@ load_graph_update(LoadGraph *lg, gint value)
if (value < 0)
return;
- lg->scale = (gfloat)lg->height / (gfloat)_max(lg);
-
/* shift-right our data */
for (i = 0; i < lg->size; i++) {
lg->data[i] = lg->data[i+1];
@@ -206,6 +274,27 @@ load_graph_update(LoadGraph *lg, gint value)
/* insert the updated value */
lg->data[i] = value;
+ /* calculates the maximum value */
+ if (lg->remax_count++ > 20) {
+ /* only finds the maximum amongst the data every 20 times */
+ lg->remax_count = 0;
+
+ gint max = lg->data[0];
+ for (i = 1; i < lg->size; i++) {
+ if (lg->data[i] > max)
+ max = lg->data[i];
+ }
+
+ lg->max_value = max;
+ } else {
+ /* otherwise, select the maximum between the current maximum
+ and the supplied value */
+ lg->max_value = MAX(value, lg->max_value);
+ }
+
+ /* recalculates the scale; always use 90% of it */
+ lg->scale = 0.90 * ((gfloat)lg->height / (gfloat)lg->max_value);
+
/* redraw */
_draw(lg);
}
@@ -242,7 +331,7 @@ int main(int argc, char **argv)
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);
- lg = load_graph_new(200);
+ lg = load_graph_new(50);
gtk_container_add(GTK_CONTAINER(window), load_graph_get_framed(lg));
gtk_container_set_border_width(GTK_CONTAINER(window), 20);
load_graph_configure_expose(lg);