示例#1
0
/**
 * uber_line_graph_add_line:
 * @graph: A #UberLineGraph.
 * @color: A #GdkColor for the line or %NULL.
 *
 * Adds a new line to the graph.  If color is %NULL, the next value
 * in the default color list will be used.
 *
 * See uber_line_graph_remove_line().
 *
 * Returns: The line identifier.
 * Side effects: None.
 */
gint
uber_line_graph_add_line (UberLineGraph  *graph, /* IN */
                          const GdkColor *color, /* IN */
                          UberLabel      *label) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo info = { 0 };

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), 0);

	priv = graph->priv;
	info.alpha = 1.0;
	info.width = 1.0;
	/*
	 * Retrieve the lines color.
	 */
	if (color) {
		info.color = *color;
	} else {
		gdk_color_parse("#729fcf", &info.color);
	}
	/*
	 * Allocate buffers for data points.
	 */
	info.raw_data = g_ring_sized_new(sizeof(gdouble), priv->stride, NULL);
	uber_line_graph_init_ring(info.raw_data);
	/*
	 * Store the newly crated line.
	 */
	g_array_append_val(priv->lines, info);
	/*
	 * Mark the graph for full redraw.
	 */
	uber_graph_redraw(UBER_GRAPH(graph));
	/*
	 * Attach label.
	 */
	if (label) {
		uber_line_graph_bind_label(graph, priv->lines->len, label);
		uber_graph_add_label(UBER_GRAPH(graph), label);
		uber_label_set_color(label, &info.color);
	}
	/*
	 * Line indexes start from 1.
	 */
	return priv->lines->len;
}
示例#2
0
/**
 * uber_window_show_labels:
 * @window: A #UberWindow.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
void
uber_window_show_labels (UberWindow *window, /* IN */
                         UberGraph  *graph)  /* IN */
{
	UberWindowPrivate *priv;
	GtkWidget *labels;
	GtkWidget *align;
	GList *list;
	gboolean show;

	g_return_if_fail(UBER_IS_WINDOW(window));
	g_return_if_fail(UBER_IS_GRAPH(graph));

	priv = window->priv;
	/*
	 * Get the widgets labels.
	 */
	labels = uber_graph_get_labels(graph);
	/*
	 * Show/hide ticks and labels.
	 */
	show = !!labels;
	if (labels) {
		align = gtk_bin_get_child(GTK_BIN(labels));
		list = gtk_container_get_children(GTK_CONTAINER(align));
		if (list) {
			gtk_widget_show(labels);
		} else {
			gtk_widget_hide(labels);
			show = FALSE;
		}
		g_list_free(list);
	}
	if (graph == (gpointer)g_list_last(priv->graphs)) {
		show = TRUE;
	}
	uber_graph_set_show_xlabels(graph, show);
	/*
	 * Hide labels/xlabels for other graphs.
	 */
	for (list = priv->graphs; list && list->next; list = list->next) {
		if (list->data != graph) {
			uber_graph_set_show_xlabels(list->data, FALSE);
			labels = uber_graph_get_labels(list->data);
			if (labels) {
				gtk_widget_hide(labels);
			}
		}
	}
	/*
	 * Ensure the last graph always has labels.
	 */
	if (list) {
		uber_graph_set_show_xlabels(UBER_GRAPH(list->data), TRUE);
	}
}
示例#3
0
/**
 * uber_line_graph_set_antialias:
 * @graph: A #UberLineGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
void
uber_line_graph_set_antialias (UberLineGraph     *graph,     /* IN */
                               cairo_antialias_t  antialias) /* IN */
{
	UberLineGraphPrivate *priv;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));

	priv = graph->priv;
	priv->antialias = antialias;
	uber_graph_redraw(UBER_GRAPH(graph));
}
示例#4
0
static gboolean
uber_window_graph_button_press_event (GtkWidget      *widget, /* IN */
                                      GdkEventButton *button, /* IN */
                                      UberWindow     *window) /* IN */
{
	GtkWidget *labels;

	g_return_val_if_fail(UBER_IS_WINDOW(window), FALSE);
	g_return_val_if_fail(UBER_IS_GRAPH(widget), FALSE);

	switch (button->button) {
	case 1: /* Left click */
		labels = uber_graph_get_labels(UBER_GRAPH(widget));
		if (gtk_widget_get_visible(labels)) {
			uber_window_hide_labels(window, UBER_GRAPH(widget));
		} else {
			uber_window_show_labels(window, UBER_GRAPH(widget));
		}
		break;
	default:
		break;
	}
	return FALSE;
}
示例#5
0
/**
 * uber_line_graph_set_line_width:
 * @graph: A #UberLineGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
void
uber_line_graph_set_line_width (UberLineGraph *graph, /* IN */
                                gint           line,  /* IN */
                                gdouble        width) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *info;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(line > 0);
	g_return_if_fail(line <= graph->priv->lines->len);

	priv = graph->priv;
	info = &g_array_index(graph->priv->lines, LineInfo, line - 1);
	info->width = width;
	uber_graph_redraw(UBER_GRAPH(graph));
}
示例#6
0
/**
 * uber_line_graph_color:
 * @graph: A #UberLineGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_color_changed (UberLabel     *label, /* IN */
                               GdkColor      *color, /* IN */
                               UberLineGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *info;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(color != NULL);

	priv = graph->priv;
	for (i = 0; i < priv->lines->len; i++) {
		info = &g_array_index(priv->lines, LineInfo, i);
		if (info->label == label) {
			info->color = *color;
		}
	}
	uber_graph_redraw(UBER_GRAPH(graph));
}
示例#7
0
/**
 * uber_line_graph_render:
 * @graph: A #UberGraph.
 * @cr: A #cairo_t context.
 * @area: Full area to render contents within.
 * @line: The line to render.
 *
 * Render a particular line to the graph.
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_render_line (UberLineGraph *graph, /* IN */
                             cairo_t       *cr,    /* IN */
                             GdkRectangle  *area,  /* IN */
                             LineInfo      *line,  /* IN */
                             guint          epoch, /* IN */
                             gfloat         each)  /* IN */
{
	UberLineGraphPrivate *priv;
	UberRange pixel_range;
	GdkRectangle vis;
	guint x;
	guint last_x;
	gdouble y;
	gdouble last_y;
	gdouble val;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));

	priv = graph->priv;
	uber_graph_get_content_area(UBER_GRAPH(graph), &vis);
	pixel_range.begin = area->y + 1;
	pixel_range.end = area->y + area->height;
	pixel_range.range = pixel_range.end - pixel_range.begin;
	/*
	 * Prepare cairo settings.
	 */
	uber_line_graph_stylize_line(graph, line, cr);
	/*
	 * Force a new path.
	 */
	cairo_new_path(cr);
	/*
	 * Draw the line contents as bezier curves.
	 */
	for (i = 0; i < line->raw_data->len; i++) {
		/*
		 * Retrieve data point.
		 */
		val = g_ring_get_index(line->raw_data, gdouble, i);
		/*
		 * Once we get to -INFINITY, we must be at the end of the data
		 * sequence.  This may not always be true in the future.
		 */
		if (val == -INFINITY) {
			break;
		}
		/*
		 * Translate value to coordinate system.
		 */
		if (!priv->scale(&priv->range, &pixel_range, &val, priv->scale_data)) {
			break;
		}
		/*
		 * Calculate X/Y coordinate.
		 */
		y = (gint)(RECT_BOTTOM(*area) - val) - .5;
		x = epoch - (each * i);
		if (i == 0) {
			/*
			 * Just move to the right position on first entry.
			 */
			cairo_move_to(cr, x, y);
			goto next;
		} else {
			/*
			 * Draw curve to data point using the last X/Y positions as
			 * control points.
			 */
			cairo_curve_to(cr,
			               last_x - (each / 2.),
			               last_y,
			               last_x - (each / 2.),
			               y, x, y);
		}
	  next:
		last_y = y;
		last_x = x;
	}
	/*
	 * Stroke the line content.
	 */
	cairo_stroke(cr);
}
示例#8
0
gint
main (gint   argc,   /* IN */
      gchar *argv[]) /* IN */
{
	gdouble dashes[] = { 1.0, 4.0 };
	UberRange cpu_range = { 0., 100., 100. };
	UberRange net_range = { 0., 512., 512. };
	UberRange ui_range = { 0., 10., 10. };
	GtkWidget *window;
	GtkWidget *cpu;
	GtkWidget *net;
	GtkWidget *line;
	GtkWidget *map;
	GtkWidget *scatter;
	GtkWidget *label;
	GtkAccelGroup *ag;
	GdkColor color;
	gint lineno;
	gint nprocs;
	gint i;
	gint mod;

	g_thread_init(NULL);
	gtk_init(&argc, &argv);
	nprocs = get_nprocs();
	/*
	 * Check for blktrace hack.
	 */
	if (argc > 1 && (g_strcmp0(argv[1], "--i-can-haz-blktrace") == 0)) {
		want_blktrace = TRUE;
	}
	/*
	 * Warm up differential samplers.
	 */
	smon_next_cpu_info();
	smon_next_cpu_freq_info();
	if (want_blktrace) {
		uber_blktrace_init();
	}
	/*
	 * Install event hook to track how many X events we are doing.
	 */
	gdk_event_handler_set(smon_gdk_event_hook, NULL, NULL);
	/*
	 * Create window and graphs.
	 */
	window = uber_window_new();
	cpu = uber_line_graph_new();
	net = uber_line_graph_new();
	line = uber_line_graph_new();
	map = uber_heat_map_new();
	scatter = uber_scatter_new();
	/*
	 * Configure CPU graph.
	 */
	uber_line_graph_set_autoscale(UBER_LINE_GRAPH(cpu), FALSE);
	uber_graph_set_format(UBER_GRAPH(cpu), UBER_GRAPH_FORMAT_PERCENT);
	uber_line_graph_set_range(UBER_LINE_GRAPH(cpu), &cpu_range);
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(cpu),
	                              smon_get_cpu_info, NULL, NULL);
	for (i = 0; i < nprocs; i++) {
		mod = i % G_N_ELEMENTS(default_colors);
		gdk_color_parse(default_colors[mod], &color);
		label = uber_label_new();
		uber_label_set_color(UBER_LABEL(label), &color);
		uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color,
		                         UBER_LABEL(label));
		cpu_info.labels[i] = label;
		/*
		 * XXX: Add the line regardless. Just dont populate it if we don't
		 *      have data.
		 */
		lineno = uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color, NULL);
		if (smon_cpu_has_freq_scaling(i)) {
			uber_line_graph_set_line_dash(UBER_LINE_GRAPH(cpu), lineno,
			                              dashes, G_N_ELEMENTS(dashes), 0);
			uber_line_graph_set_line_alpha(UBER_LINE_GRAPH(cpu), lineno, 1.);
		}
	}
	/*
	 * Add lines for GDK/X events.
	 */
	uber_line_graph_set_range(UBER_LINE_GRAPH(line), &ui_range);
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "GDK Events");
	gdk_color_parse("#729fcf", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(line), &color, UBER_LABEL(label));
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "X Events");
	gdk_color_parse("#a40000", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(line), &color, UBER_LABEL(label));
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(line),
	                              smon_get_xevent_info, NULL, NULL);
	/*
	 * Add lines for bytes in/out.
	 */
	uber_line_graph_set_range(UBER_LINE_GRAPH(net), &net_range);
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(net),
	                              smon_get_net_info, NULL, NULL);
	uber_graph_set_format(UBER_GRAPH(net), UBER_GRAPH_FORMAT_DIRECT1024);
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "Bytes In");
	gdk_color_parse("#a40000", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "Bytes Out");
	gdk_color_parse("#4e9a06", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));

	/*
	 * Configure heat map.
	 */
	uber_graph_set_show_ylines(UBER_GRAPH(map), FALSE);
	gdk_color_parse(default_colors[0], &color);
	uber_heat_map_set_fg_color(UBER_HEAT_MAP(map), &color);
	uber_heat_map_set_data_func(UBER_HEAT_MAP(map),
	                            (UberHeatMapFunc)dummy_scatter_func, NULL, NULL);
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(map), "IO Latency");
	uber_graph_set_show_xlabels(UBER_GRAPH(map), FALSE);
	gtk_widget_show(map);

	/*
	 * Configure scatter.
	 */
	if (want_blktrace) {
		uber_graph_set_show_ylines(UBER_GRAPH(scatter), FALSE);
		gdk_color_parse(default_colors[3], &color);
		uber_scatter_set_fg_color(UBER_SCATTER(scatter), &color);
		uber_scatter_set_data_func(UBER_SCATTER(scatter),
								   (UberScatterFunc)uber_blktrace_get, NULL, NULL);
		uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(scatter), "IOPS By Size");
		uber_graph_set_show_xlabels(UBER_GRAPH(scatter), TRUE);
		gtk_widget_show(scatter);
	}
	/*
	 * Add graphs.
	 */
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(cpu), "CPU");
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(net), "Network");
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(line), "UI Events");
	/*
	 * Disable X tick labels by default (except last).
	 */
	uber_graph_set_show_xlabels(UBER_GRAPH(cpu), FALSE);
	uber_graph_set_show_xlabels(UBER_GRAPH(net), FALSE);
	uber_graph_set_show_xlabels(UBER_GRAPH(line), FALSE);
	/*
	 * Show widgets.
	 */
	gtk_widget_show(net);
	gtk_widget_show(line);
	gtk_widget_show(cpu);
	gtk_widget_show(window);
	/*
	 * Show cpu labels by default.
	 */
	uber_window_show_labels(UBER_WINDOW(window), UBER_GRAPH(cpu));
	/*
	 * Setup accelerators.
	 */
	ag = gtk_accel_group_new();
	gtk_accel_group_connect(ag, GDK_KEY_w, GDK_CONTROL_MASK, GTK_ACCEL_MASK,
	                        g_cclosure_new(gtk_main_quit, NULL, NULL));
	gtk_window_add_accel_group(GTK_WINDOW(window), ag);
	/*
	 * Attach signals.
	 */
	g_signal_connect(window,
	                 "delete-event",
	                 G_CALLBACK(gtk_main_quit),
	                 NULL);
	/*
	 * Start sampling thread.
	 */
	g_thread_create((GThreadFunc)sample_thread, NULL, FALSE, NULL);
	gtk_main();
	/*
	 * Cleanup after blktrace.
	 */
	if (want_blktrace) {
		uber_blktrace_shutdown();
	}
	return EXIT_SUCCESS;
}