示例#1
0
/**
 * uber_line_graph_get_next_data:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static gboolean
uber_line_graph_get_next_data (UberGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gdouble val;
	gboolean ret = FALSE;
	gint i;

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), FALSE);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Retrieve the next data point.
	 */
	if (priv->func) {
		for (i = 0; i < priv->lines->len; i++) {
			val = 0.;
			line = &g_array_index(priv->lines, LineInfo, i);
			if (!(ret = priv->func(UBER_LINE_GRAPH(graph),
			                       i + 1, &val,
			                       priv->func_data))) {
				val = -INFINITY;
			}
			g_ring_append_val(line->raw_data, val);
			/*
			 * TODO: Scale value.
			 */
			g_ring_append_val(line->scaled_data, val);
		}
	}
	return ret;
}
示例#2
0
/**
 * uber_line_graph_get_next_data:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static gboolean
uber_line_graph_get_next_data (UberGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	gboolean scale_changed = FALSE;
	gboolean ret = FALSE;
	LineInfo *line;
	gdouble val;
	gint i;

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), FALSE);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Retrieve the next data point.
	 */
	if (priv->func) {
		for (i = 0; i < priv->lines->len; i++) {
			val = 0.;
			line = &g_array_index(priv->lines, LineInfo, i);
			if (!(ret = priv->func(UBER_LINE_GRAPH(graph),
			                       i + 1, &val,
			                       priv->func_data))) {
				val = -INFINITY;
			}
			g_ring_append_val(line->raw_data, val);
			if (priv->autoscale) {
				if (val < priv->range.begin) {
					priv->range.begin = val - (val * SCALE_FACTOR);
					priv->range.range = priv->range.end - priv->range.begin;
					scale_changed = TRUE;
				} else if (val > priv->range.end) {
					priv->range.end = val + (val * SCALE_FACTOR);
					priv->range.range = priv->range.end - priv->range.begin;
					scale_changed = TRUE;
				}
			}
		}
	}
	if (scale_changed) {
		uber_graph_scale_changed(graph);
	}
	return ret;
}
示例#3
0
/**
 * uber_line_graph_set_data_func:
 * @graph: A #UberLineGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
void
uber_line_graph_set_data_func (UberLineGraph     *graph,     /* IN */
                               UberLineGraphFunc  func,      /* IN */
                               gpointer           user_data, /* IN */
                               GDestroyNotify     notify)    /* IN */
{
	UberLineGraphPrivate *priv;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));

	priv = graph->priv;
	/*
	 * Free existing data func if neccessary.
	 */
	if (priv->func_notify) {
		priv->func_notify(priv->func_data);
	}
	/*
	 * Store data func.
	 */
	priv->func = func;
	priv->func_data = user_data;
	priv->func_notify = notify;
}
示例#4
0
/**
 * uber_line_graph_render_fast:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_render_fast (UberGraph    *graph, /* IN */
                             cairo_t      *cr,    /* IN */
                             GdkRectangle *rect,  /* IN */
                             guint         epoch, /* IN */
                             gfloat        each)  /* IN */
{
	UberLineGraphPrivate *priv;
	UberRange pixel_range;
	LineInfo *line;
	gdouble last_y;
	gdouble y;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(cr != NULL);
	g_return_if_fail(rect != NULL);

	priv = UBER_LINE_GRAPH(graph)->priv;
	pixel_range.begin = rect->y + 1;
	pixel_range.end = rect->y + rect->height;
	pixel_range.range = pixel_range.end - pixel_range.begin;
	/*
	 * Render most recent data point for each line.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		uber_line_graph_stylize_line(UBER_LINE_GRAPH(graph), line, cr);
		/*
		 * Calculate positions.
		 */
		y = g_ring_get_index(line->raw_data, gdouble, 0);
		last_y = g_ring_get_index(line->raw_data, gdouble, 1);
		/*
		 * Don't try to draw before we have real values.
		 */
		if ((isnan(y) || isinf(y)) || (isnan(last_y) || isinf(last_y))) {
			continue;
		}
		/*
		 * Translate to coordinate scale.
		 */
		if (!priv->scale(&priv->range, &pixel_range, &y, priv->scale_data) ||
		    !priv->scale(&priv->range, &pixel_range, &last_y, priv->scale_data)) {
			continue;
		}
		/*
		 * Translate position from bottom right corner.
		 */
		y = (gint)(RECT_BOTTOM(*rect) - y) - .5;
		last_y = (gint)(RECT_BOTTOM(*rect) - last_y) - .5;
		/*
		 * Convert relative position to fixed from bottom pixel.
		 */
		cairo_new_path(cr);
		cairo_move_to(cr, epoch, y);
		cairo_curve_to(cr,
		               epoch - (each / 2.),
		               y,
		               epoch - (each / 2.),
		               last_y,
		               epoch - each,
		               last_y);
		cairo_stroke(cr);
	}
}
示例#5
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);
}