[goffice] Display coordinates when moving the mouseover a graph. [#382666]



commit 407b422207468d3f85c8021438c9eaafc5e63e67
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sun Oct 18 14:19:59 2009 +0200

    Display coordinates when moving the mouseover a graph. [#382666]

 ChangeLog                               |   15 ++++
 NEWS                                    |    1 +
 docs/reference/goffice-0.8-sections.txt |   30 +++++++--
 goffice/app/go-service-impl.h           |    2 +-
 goffice/canvas/goc-graph.c              |  116 +++++++++++++++++++++++++++++++
 goffice/canvas/goc-graph.h              |    1 +
 goffice/graph/gog-axis.c                |   18 ++++-
 goffice/graph/gog-axis.h                |    1 +
 goffice/graph/gog-chart-map.c           |   64 ++++++++++++++++-
 goffice/graph/gog-chart-map.h           |    1 +
 10 files changed, 238 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4674388..c3434aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-10-18  Jean Brefort  <jean brefort normalesup org>
+
+	* goffice/app/go-service-impl.h: typo.
+	* goffice/canvas/goc-graph.c (goc_graph_motion),
+	(goc_graph_leave_notify), (goc_graph_class_init): display coordinates when
+	moving the mouse. [#382666]
+	* goffice/canvas/goc-graph.h: ditto/
+	* goffice/graph/gog-axis.c (map_discrete_from_view):return discrete values,
+	(gog_axis_map_is_discrete): new function.
+	* goffice/graph/gog-axis.h: ditto.
+	* goffice/graph/gog-chart-map.c (x_map_view_to_2D),
+	(xy_map_view_to_2D), (polar_map_view_to_2D), (gog_chart_map_new),
+	(gog_chart_map_view_to_2D): ditto.
+	* goffice/graph/gog-chart-map.h: ditto.
+
 2009-10-15  Morten Welinder  <terra gnome org>
 
 	* goffice/utils/go-line.c (go_line_dash_as_label): Translate here.
diff --git a/NEWS b/NEWS
index 122069f..046a8ae 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ goffice 0.7.15:
 Jean:
 	* Fix bounds update of GocItem. [#598091]
 	* Prepare for GSEAL_ENABLE.
+	* Display coordinates when moving the mouseover a graph. [#382666]
 
 Morten:
 	* Canvas improvements for arrows.
diff --git a/docs/reference/goffice-0.8-sections.txt b/docs/reference/goffice-0.8-sections.txt
index 549a4e8..3a3787b 100644
--- a/docs/reference/goffice-0.8-sections.txt
+++ b/docs/reference/goffice-0.8-sections.txt
@@ -828,6 +828,7 @@ gog_chart_map_free
 gog_chart_map_is_valid
 gog_chart_map_2D_to_view
 gog_chart_map_2D_derivative_to_view
+gog_chart_map_view_to_2D
 gog_chart_map_get_axis_map
 gog_chart_map_make_path
 gog_chart_map_make_close_path
@@ -873,6 +874,7 @@ gog_axis_map_get_bounds
 gog_axis_map_free
 gog_axis_map_is_valid
 gog_axis_map_is_inverted
+gog_axis_map_is_discrete
 </SECTION>
 
 ###############################################################################
@@ -1759,6 +1761,21 @@ go_marker_selector_set_colors
 </SECTION>
 
 <SECTION>
+GOArrow
+GOArrowType
+go_arrow_clear
+go_arrow_dup
+go_arrow_init
+go_arrow_init_kite
+go_arrow_init_oval
+go_arrow_type_as_str
+go_arrow_type_from_str
+<SUBSECTION Standard>
+GO_ARROW_TYPE
+go_arrow_get_type
+</SECTION>
+
+<SECTION>
 <FILE>go-pattern</FILE>
 <TITLE>GOPattern</TITLE>
 GOPattern
@@ -2154,7 +2171,7 @@ go_doc_init_read
 go_doc_read
 go_doc_end_read
 go_doc_image_fetch
-<SUBSECTION Private>
+<SUBSECTION Standard>
 GO_DOC_CLASS
 GO_IS_DOC_CLASS
 GO_DOC_GET_CLASS
@@ -2165,11 +2182,6 @@ GO_DOC_GET_CLASS
 <TITLE>GOComponent</TITLE>
 GOComponent
 GOComponentClass
-GO_TYPE_COMPONENT
-GO_COMPONENT
-GO_IS_COMPONENT
-GOC_PARAM_PERSISTENT
-go_component_get_type
 go_component_new_by_mime_type
 go_component_set_default_size
 go_component_needs_window
@@ -2184,6 +2196,12 @@ go_component_emit_changed
 go_component_set_command_context
 go_component_get_command_context
 go_component_render
+<SUBSECTION Standard>
+GO_TYPE_COMPONENT
+GO_COMPONENT
+GO_IS_COMPONENT
+GOC_PARAM_PERSISTENT
+go_component_get_type
 </SECTION>
 
 <SECTION>
diff --git a/goffice/app/go-service-impl.h b/goffice/app/go-service-impl.h
index c9382ac..00de6a6 100644
--- a/goffice/app/go-service-impl.h
+++ b/goffice/app/go-service-impl.h
@@ -48,5 +48,5 @@ typedef GOServiceClass GOServiceSimpleClass;
 
 G_END_DECLS
 
-#endif /* GO_GRAPH_ITEM_IMPL_H */
+#endif /* GO_SERVICE_IMPL_H */
 
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index e4c578b..41c6e8e 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -218,6 +218,120 @@ goc_graph_update_bounds (GocItem *item)
 	gog_renderer_update (graph->renderer, graph->w, graph->h);
 }
 
+static gboolean
+goc_graph_motion (GocItem *item, double x, double y)
+{
+	GdkEventMotion *event = (GdkEventMotion*) goc_canvas_get_cur_event (item->canvas);
+	GocGraph *graph = GOC_GRAPH (item);
+	GogView *view;
+	char *buf = NULL, *s1 = NULL, *s2 = NULL;
+	GogObject *obj;
+	GogTool *tool;
+	GogChart *chart;
+	GogViewAllocation alloc;
+	double xpos, ypos;
+	GogChartMap *map;
+	GogAxis *x_axis, *y_axis;
+	GogAxisSet set;
+	GSList *l;
+	GOFormat *format;
+
+	/* do not allow more than 20 updates per second */
+	if (event->time - graph->last_time < 50)
+		goto out;
+
+	graph->last_time = event->time;
+	/* translate x and y tovalues relative to the graph */
+	xpos = graph->x;
+	ypos = graph->y;
+	goc_group_adjust_coords (item->parent, &xpos, &ypos);
+	x -= xpos;
+	y -= ypos;
+	/* get the GogView at the cursor position */
+	g_object_get (G_OBJECT (graph->renderer), "view", &view, NULL);
+	gog_view_get_view_at_point (view, x, y, &obj, &tool);
+	if (!obj)
+		goto tooltip;
+	chart = GOG_CHART (gog_object_get_parent_typed (obj, GOG_TYPE_CHART));
+	if (!chart || gog_chart_is_3d (chart))
+		goto tooltip;
+	set = gog_chart_get_axis_set (chart) & GOG_AXIS_SET_FUNDAMENTAL;
+	/* get the plot allocation */
+	l = gog_object_get_children (GOG_OBJECT (chart), gog_object_find_role_by_name (GOG_OBJECT (chart), "Plot"));
+	view = gog_view_find_child_view (view, GOG_OBJECT (l->data));
+	g_slist_free (l);
+	alloc = view->allocation;
+	switch (set) {
+	case GOG_AXIS_SET_XY:
+		/* get the axis */
+		l = gog_chart_get_axes (chart, GOG_AXIS_X);
+		x_axis = GOG_AXIS (l->data);
+		g_slist_free (l);
+		l = gog_chart_get_axes (chart, GOG_AXIS_Y);
+		y_axis = GOG_AXIS (l->data);
+		g_slist_free (l);
+		break;
+	case GOG_AXIS_SET_RADAR:
+		/* get the axis */
+		l = gog_chart_get_axes (chart, GOG_AXIS_CIRCULAR);
+		x_axis = GOG_AXIS (l->data);
+		g_slist_free (l);
+		l = gog_chart_get_axes (chart, GOG_AXIS_RADIAL);
+		y_axis = GOG_AXIS (l->data);
+		g_slist_free (l);
+		break;
+	default:
+		goto tooltip;
+	}
+	map = gog_chart_map_new (chart, &alloc, x_axis, y_axis, NULL, FALSE);
+	if (gog_chart_map_is_valid (map) &&
+				x >= alloc.x && x < alloc.x + alloc.w &&
+				y >= alloc.y && y < alloc.y + alloc.h) {
+		gog_chart_map_view_to_2D (map, x, y, &x, &y);
+		if (gog_axis_is_discrete (x_axis)) {
+			GOData *labels = gog_axis_get_labels (x_axis, NULL);
+			if (labels)
+				s1 = go_data_vector_get_str (GO_DATA_VECTOR (labels), x - 1);
+			if (!s1 || *s1 == 0) {
+				g_free (s1);
+				s1 = g_strdup_printf ("%g", x);
+			}
+		} else {
+			format = gog_axis_get_format (x_axis);
+			s1 = (format == NULL)? g_strdup_printf ("%g", x): go_format_value (format, x);
+		}
+		if (gog_axis_is_discrete (y_axis)) {
+			GOData *labels = gog_axis_get_labels (y_axis, NULL);
+			if (labels)
+				s2 = go_data_vector_get_str (GO_DATA_VECTOR (labels), y - 1);
+			if (!s2 || *s2 == 0) {
+				g_free (s1);
+				s2 = g_strdup_printf ("%g", y);
+			}
+		} else {
+			format = gog_axis_get_format (y_axis);
+			s2 =  (format == NULL)? g_strdup_printf ("%g", y): go_format_value (format, y);
+		}
+		buf = g_strdup_printf ("(%s,%s)", s1, s2);
+		g_free (s1);
+		g_free (s2);
+	}
+	gog_chart_map_free (map);
+tooltip:
+	gtk_widget_set_tooltip_text (GTK_WIDGET (item->canvas), buf);
+	g_free (buf);
+out:
+	return ((GocItemClass*) parent_klass)->motion (item, x, y);
+}
+
+static gboolean
+goc_graph_leave_notify (GocItem *item, double x, double y)
+{
+	GOC_GRAPH (item)->last_time = 0;
+	gtk_widget_set_tooltip_text (GTK_WIDGET (item->canvas), NULL);
+	return ((GocItemClass*) parent_klass)->leave_notify (item, x, y);
+}
+
 static void
 goc_graph_class_init (GocItemClass *item_klass)
 {
@@ -269,6 +383,8 @@ goc_graph_class_init (GocItemClass *item_klass)
 	item_klass->draw = goc_graph_draw;
 	item_klass->update_bounds = goc_graph_update_bounds;
 	item_klass->distance = goc_graph_distance;
+	item_klass->leave_notify = goc_graph_leave_notify;
+	item_klass->motion = goc_graph_motion;
 }
 
 GSF_CLASS (GocGraph, goc_graph,
diff --git a/goffice/canvas/goc-graph.h b/goffice/canvas/goc-graph.h
index 3b0583c..3d2e0ee 100644
--- a/goffice/canvas/goc-graph.h
+++ b/goffice/canvas/goc-graph.h
@@ -31,6 +31,7 @@ struct _GocGraph {
 
 	double x, y, w, h;
 	GogRenderer *renderer;
+	guint32 last_time;
 };
 
 typedef GocItemClass GocGraphClass;
diff --git a/goffice/graph/gog-axis.c b/goffice/graph/gog-axis.c
index 08b5812..e96207a 100644
--- a/goffice/graph/gog-axis.c
+++ b/goffice/graph/gog-axis.c
@@ -246,8 +246,8 @@ map_discrete_from_view (GogAxisMap *map, double value)
 	const MapData *data = map->data;
 
 	return map->axis->inverted ?
-		data->min + data->max - (value - data->b) / data->a :
-		(value - data->b) / data->a;
+		go_rint (data->min + data->max - (value - data->b) / data->a) :
+		go_rint ((value - data->b) / data->a);
 }
 
 static void
@@ -1570,6 +1570,20 @@ gog_axis_map_is_inverted (GogAxisMap *map)
 }
 
 /**
+ * gog_axis_map_is_discrete:
+ * @map: a #GogAxisMap
+ *
+ * Returns: %TRUE is the axis is discrete;
+ **/
+gboolean
+gog_axis_map_is_discrete (GogAxisMap *map)
+{
+	g_return_val_if_fail (map != NULL, FALSE);
+
+	return map->axis->is_discrete;
+}
+
+/**
  * gog_axis_map_free :
  * @map : a #GogAxisMap
  *
diff --git a/goffice/graph/gog-axis.h b/goffice/graph/gog-axis.h
index d0ee3a4..2cf91b3 100644
--- a/goffice/graph/gog-axis.h
+++ b/goffice/graph/gog-axis.h
@@ -62,6 +62,7 @@ void	      gog_axis_map_get_bounds 	  (GogAxisMap *map, double *minimum, double
 void 	      gog_axis_map_free		  (GogAxisMap *map);
 gboolean      gog_axis_map_is_valid 	  (GogAxisMap *map);
 gboolean      gog_axis_map_is_inverted 	  (GogAxisMap *map);
+gboolean      gog_axis_map_is_discrete 	  (GogAxisMap *map);
 
 /*****************************************************************************/
 
diff --git a/goffice/graph/gog-chart-map.c b/goffice/graph/gog-chart-map.c
index 2b8e7a8..31882b8 100644
--- a/goffice/graph/gog-chart-map.c
+++ b/goffice/graph/gog-chart-map.c
@@ -30,6 +30,7 @@ struct _GogChartMap {
 	gboolean		 is_valid;
 
 	void 	 (*map_2D_to_view) 	(GogChartMap *map, double x, double y, double *u, double *v);
+	void 	 (*map_view_to_2D) 	(GogChartMap *map, double x, double y, double *u, double *v);
 	double 	 (*map_2D_derivative_to_view) (GogChartMap *map, double deriv, double x, double y);
 	GOPath  *(*make_path)	   	(GogChartMap *map, double const *x, double const *y, int n_points,
 					 GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data);
@@ -167,6 +168,15 @@ x_map_2D_to_view (GogChartMap *map, double x, double y, double *u, double *v)
 	*v = data->a * y + data->b;
 }
 
+static void
+x_map_view_to_2D (GogChartMap *map, double x, double y, double *u, double *v)
+{
+	XMapData *data = map->data;
+
+	*u = gog_axis_map_from_view (map->axis_map[0], x);
+	*v =  (y - data->b) / data->a;
+}
+
 typedef struct {
 	double		a[2][2];
 	double		b[2];
@@ -191,6 +201,13 @@ xy_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, double y
 	return (isnan (d))? go_nan: deriv * d;
 }
 
+static void
+xy_map_view_to_2D (GogChartMap *map, double x, double y, double *u, double *v)
+{
+	*u = gog_axis_map_from_view (map->axis_map[0], x);
+	*v = gog_axis_map_from_view (map->axis_map[1], y);
+}
+
 static GOPath *
 make_path_linear (GogChartMap *map,
 		  double const *x, double const *y,
@@ -582,6 +599,29 @@ polar_map_2D_to_view (GogChartMap *map, double x, double y, double *u, double *v
 	*v = data->cy + r * data->ry * sin (t);
 }
 
+static void
+polar_map_view_to_2D (GogChartMap *map, double x, double y, double *u, double *v)
+{
+	GogChartMapPolarData *data = (GogChartMapPolarData *) map->data;
+	double r, t;
+
+	x = (x - data->cx) / data->rx;
+	y = (y - data->cy) / data->ry;
+	r = hypot (x, y);
+	t = atan2 (y, x);
+	/* FIXME: following code looks like a kludge */
+	if (gog_axis_map_is_discrete (map->axis_map[0])) {
+		*u = gog_axis_map_from_view (map->axis_map[0], t);
+		if (*u < 1)
+			*u = data->th1;
+	} else {
+		if (t > 0)
+			t -= 2 * M_PI; /* Hmm, why? */
+		*u = gog_axis_map_from_view (map->axis_map[0], t);
+	}
+	*v = gog_axis_map_from_view (map->axis_map[1], r);
+}
+
 static GOPath *
 polar_make_path_step (GogChartMap *map, double const *x, double const *y, int n_points,
 		      GOLineInterpolation interpolation, gboolean skip_invalid)
@@ -774,7 +814,7 @@ gog_chart_map_get_polar_parms (GogChartMap *map)
  * Creates a new #GogChartMap, used for conversion from data space
  * to canvas space.
  *
- * returns: a new #GogChart object.
+ * returns: a new #GogChartMap object.
  **/
 
 GogChartMap *
@@ -810,6 +850,7 @@ gog_chart_map_new (GogChart *chart, GogViewAllocation const *area,
 				data->a = - area->h;
 
 				map->map_2D_to_view = x_map_2D_to_view;
+				map->map_view_to_2D = x_map_view_to_2D;
 				map->map_2D_derivative_to_view = NULL;
 				map->make_path = NULL;
 				map->make_close_path = NULL;
@@ -829,6 +870,7 @@ gog_chart_map_new (GogChart *chart, GogViewAllocation const *area,
 				map->data = NULL;
 				map->map_2D_to_view = xy_map_2D_to_view;
 				map->map_2D_derivative_to_view = xy_map_2D_derivative_to_view;
+				map->map_view_to_2D = xy_map_view_to_2D;
 				map->make_path = xy_make_path;
 				map->make_close_path = xy_make_close_path;
 
@@ -869,6 +911,7 @@ gog_chart_map_new (GogChart *chart, GogViewAllocation const *area,
 				map->data = data;
 				map->map_2D_to_view = polar_map_2D_to_view;
 				map->map_2D_derivative_to_view = NULL;
+				map->map_view_to_2D = polar_map_view_to_2D;
 				map->make_path = polar_make_path;
 				map->make_close_path = polar_make_close_path;
 
@@ -880,6 +923,7 @@ gog_chart_map_new (GogChart *chart, GogViewAllocation const *area,
 			g_warning ("[GogChartMap::new] unimplemented for axis set %d", axis_set);
 			map->map_2D_to_view = null_map_2D;
 			map->map_2D_derivative_to_view = NULL;
+			map->map_view_to_2D = null_map_2D;
 			break;
 	}
 
@@ -903,7 +947,6 @@ gog_chart_map_2D_to_view (GogChartMap *map, double x, double y, double *u, doubl
 	(map->map_2D_to_view) (map, x, y, u, v);
 }
 
-
 /**
  * gog_chart_map_2D_derivative_to_view:
  * @map: a #GogChartMap
@@ -924,6 +967,23 @@ gog_chart_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, d
 }
 
 /**
+ * gog_chart_map_view_to_2D:
+ * @map: a #GogChartMap
+ * @x: data x value
+ * @y: data y value
+ * @u: placeholder for x converted value
+ * @v: placeholder for y converted value
+ *
+ * Converts a 2D coordinate from canvas space to data space.
+ **/
+
+void
+gog_chart_map_view_to_2D (GogChartMap *map, double x, double y, double *u, double *v)
+{
+	(map->map_view_to_2D) (map, x, y, u, v);
+}
+
+/**
  * gog_chart_map_get_axis_map:
  * @map: a #GogChartMap
  * @index: axis index
diff --git a/goffice/graph/gog-chart-map.h b/goffice/graph/gog-chart-map.h
index 8e5f37a..cf0c59a 100644
--- a/goffice/graph/gog-chart-map.h
+++ b/goffice/graph/gog-chart-map.h
@@ -39,6 +39,7 @@ GogChartMap 	*gog_chart_map_new 		(GogChart *chart, GogViewAllocation const *are
 						 gboolean fill_area);
 void 		 gog_chart_map_2D_to_view	(GogChartMap *map, double x, double y, double *u, double *v);
 double		 gog_chart_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, double y) ;
+void		 gog_chart_map_view_to_2D       (GogChartMap *map, double x, double y, double *u, double *v);
 GogAxisMap	*gog_chart_map_get_axis_map 	(GogChartMap *map, unsigned int index);
 gboolean	 gog_chart_map_is_valid 	(GogChartMap *map);
 void		 gog_chart_map_free 		(GogChartMap *map);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]