[goffice] Axes can use only a part of available space. [#654392]
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Axes can use only a part of available space. [#654392]
- Date: Sun, 7 Aug 2011 15:08:05 +0000 (UTC)
commit 2d27e8ef37d7a6063b4a80270cc784ad95627d81
Author: Jean Brefort <jean brefort normalesup org>
Date: Sun Aug 7 17:12:23 2011 +0200
Axes can use only a part of available space. [#654392]
ChangeLog | 14 +++++
NEWS | 1 +
goffice/canvas/goc-graph.c | 89 ++++++++++++++++++++------------
goffice/graph/gog-axis-prefs.ui | 111 ++++++++++++++++++++++++++++++++------
goffice/graph/gog-axis.c | 107 ++++++++++++++++++++++++++++++++++++-
goffice/graph/gog-axis.h | 2 +
6 files changed, 270 insertions(+), 54 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0acd7fb..1efacc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-08-07 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-graph.c (goc_graph_do_tooltip): fix when an axis
+ does not use all the available space.
+ * goffice/graph/gog-axis-prefs.ui: allows an axis to use only part of
+ available space. [#654392]
+ * goffice/graph/gog-axis.c (gog_axis_map_new),
+ (gog_axis_map_get_extents), (gog_axis_map_get_bounds),
+ (gog_axis_set_property), (gog_axis_get_property),
+ (cb_start_changed), (cb_end_changed), (gog_axis_populate_editor),
+ (gog_axis_class_init), (gog_axis_init), (gog_axis_set_bounds),
+ (gog_axis_get_effective_span): ditto.
+ * goffice/graph/gog-axis.h: ditto.
+
2011-08-06 Jean Brefort <jean brefort normalesup org>
* goffice/graph/gog-label.c (gog_text_set_property),
diff --git a/NEWS b/NEWS
index 9cdd5e9..17f846a 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Jean:
* Add a plugin directory for extern plugins, independent from micro version.
* Allow the frame around a chart label to rotate with the text. [647147]
* Chart labels accept rich text. [#417631]
+ * Axes can use only a part of available space. [#654392]
Morten:
* Recognize scientific formats with longer exponents.
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index 16a71cd..41776d8 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -248,16 +248,17 @@ format_coordinate (GogAxis *axis, GOFormat *fmt, double x)
static void
goc_graph_do_tooltip (GocGraph *graph)
{
- GogView *view;
+ GogView *view, *base_view;
char *buf = NULL, *s1 = NULL, *s2 = NULL;
GogObject *obj;
GogChart *chart;
GogViewAllocation alloc;
double xpos, ypos;
- GogChartMap *map;
- GogAxis *x_axis, *y_axis;
+ GogChartMap *map = NULL;
+ GogAxis *x_axis, *y_axis = NULL;
GogAxisSet set;
- GSList *l;
+ GogPlot *plot;
+ GSList *l, *ptr;
GOFormat *format;
GocItem *item = (GocItem *)graph;
double x = graph->coords.x;
@@ -271,9 +272,9 @@ goc_graph_do_tooltip (GocGraph *graph)
y -= ypos;
/* get the GogView at the cursor position */
- g_object_get (G_OBJECT (graph->renderer), "view", &view, NULL);
- g_object_unref (view); /* we don't need a reference */
- gog_view_get_view_at_point (view, x, y, &obj, NULL);
+ g_object_get (G_OBJECT (graph->renderer), "view", &base_view, NULL);
+ g_object_unref (base_view); /* we don't need a reference */
+ gog_view_get_view_at_point (base_view, x, y, &obj, NULL);
if (!obj)
goto tooltip;
chart = GOG_CHART (gog_object_get_parent_typed (obj, GOG_TYPE_CHART));
@@ -284,35 +285,57 @@ goc_graph_do_tooltip (GocGraph *graph)
l = gog_object_get_children (GOG_OBJECT (chart), gog_object_find_role_by_name (GOG_OBJECT (chart), "Plot"));
if (l == NULL)
return;
- view = gog_view_find_child_view (view, GOG_OBJECT (l->data));
+ ptr = l;
+ while (ptr) {
+ view = gog_view_find_child_view (base_view, GOG_OBJECT (ptr->data));
+ if (view) {
+ double start, end;
+ alloc = view->allocation;
+ plot = GOG_PLOT (ptr->data);
+ switch (set) {
+ case GOG_AXIS_SET_XY:
+ /* get the axis */
+ x_axis = gog_plot_get_axis (plot, GOG_AXIS_X);
+ gog_axis_get_effective_span (x_axis, &start, &end);
+ if (x < alloc.x + alloc.w * start || x > alloc.x + alloc.w * end)
+ break;
+ y_axis = gog_plot_get_axis (plot, GOG_AXIS_Y);
+ gog_axis_get_effective_span (y_axis, &start, &end);
+ if (y < alloc.y + alloc.h * (1. - start) && y > alloc.y + alloc.h * (1. - end))
+ map = gog_chart_map_new (chart, &alloc, x_axis, y_axis, NULL, FALSE);
+ break;
+ case GOG_AXIS_SET_RADAR: {
+ double a, r, min, max;
+ /* get the axis */
+ x_axis = gog_plot_get_axis (plot, GOG_AXIS_CIRCULAR);
+ y_axis = gog_plot_get_axis (plot, GOG_AXIS_RADIAL);
+ map = gog_chart_map_new (chart, &alloc, x_axis, y_axis, NULL, FALSE);
+ gog_axis_get_bounds (y_axis, &min, &max);
+ r = min - 1;
+ if (gog_chart_map_is_valid (map))
+ gog_chart_map_view_to_2D (map, x, y, &a, &r);
+ if (r < min || r > max) {
+ gog_chart_map_free (map);
+ map = NULL;
+ }
+ break;
+ }
+ default:
+ buf = gog_view_get_tip_at_point (view, x, y);
+ g_slist_free (l);
+ goto tooltip;
+ }
+ if (map != NULL)
+ break;
+ view = NULL;
+ }
+ ptr = ptr->next;
+ }
g_slist_free (l);
- if (!view)
+ if (view == NULL) {
+ gtk_widget_set_tooltip_markup (GTK_WIDGET (item->canvas), NULL);
return;
- 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:
- buf = gog_view_get_tip_at_point (view, x, y);
- 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) {
diff --git a/goffice/graph/gog-axis-prefs.ui b/goffice/graph/gog-axis-prefs.ui
index ff49ff3..3667984 100644
--- a/goffice/graph/gog-axis-prefs.ui
+++ b/goffice/graph/gog-axis-prefs.ui
@@ -13,6 +13,99 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
+ <object class="GtkAdjustment" id="start-adj">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="end-adj">
+ <property name="upper">100</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkGrid" id="area-grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Effective area</b> (as % of available room)</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Start:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="start-btn">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">start-adj</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="end-btn">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">end-adj</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">End:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
<object class="GtkGrid" id="axis-base-pref-grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -205,9 +298,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="left_attach">0</property>
@@ -282,15 +372,6 @@
</packing>
</child>
<child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
<object class="GtkGrid" id="minor-tick-grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -536,9 +617,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="left_attach">0</property>
@@ -547,9 +625,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="left_attach">0</property>
diff --git a/goffice/graph/gog-axis.c b/goffice/graph/gog-axis.c
index be61241..293dc9f 100644
--- a/goffice/graph/gog-axis.c
+++ b/goffice/graph/gog-axis.c
@@ -92,6 +92,7 @@ struct _GogAxis {
GogAxisTick *ticks;
unsigned tick_nbr;
+ double span_start, span_end; /* percent of used area */
};
/*****************************************************************************/
@@ -1578,6 +1579,11 @@ gog_axis_map_new (GogAxis *axis, double offset, double length)
map->data = NULL;
map->is_valid = FALSE;
+ if (axis->type != GOG_AXIS_CIRCULAR) {
+ offset += axis->span_start * length;
+ length *= axis->span_end - axis->span_start;
+ }
+
if (map->desc->init != NULL)
map->is_valid = map->desc->init (map, offset, length);
@@ -1708,11 +1714,16 @@ void
gog_axis_map_get_extents (GogAxisMap *map, double *start, double *stop)
{
g_return_if_fail (map != NULL);
-
+
if (map->axis->inverted)
map->desc->map_bounds (map, stop, start);
else
map->desc->map_bounds (map, start, stop);
+ if (map->axis->type != GOG_AXIS_CIRCULAR) {
+ double buf = (*stop - *start) / (map->axis->span_end - map->axis->span_start);
+ *start -= map->axis->span_start * buf;
+ *stop = *start + buf;
+ }
}
/**
@@ -1731,8 +1742,13 @@ void
gog_axis_map_get_bounds (GogAxisMap *map, double *minimum, double *maximum)
{
g_return_if_fail (map != NULL);
-
+
map->desc->map_bounds (map, minimum, maximum);
+ if (map->axis->type != GOG_AXIS_CIRCULAR) {
+ double buf = (*minimum - *maximum) / (map->axis->span_end - map->axis->span_start);
+ *maximum -= map->axis->span_start * buf;
+ *minimum = *maximum + buf;
+ }
}
/**
@@ -1873,7 +1889,9 @@ enum {
AXIS_PROP_MAP,
AXIS_PROP_ASSIGNED_FORMAT_STR_XL,
AXIS_PROP_CIRCULAR_ROTATION,
- AXIS_PROP_POLAR_UNIT
+ AXIS_PROP_POLAR_UNIT,
+ AXIS_PROP_SPAN_START,
+ AXIS_PROP_SPAN_END
};
/*****************************************************************************/
@@ -2066,6 +2084,20 @@ gog_axis_set_property (GObject *obj, guint param_id,
}
break;
}
+ case AXIS_PROP_SPAN_START:
+ if (axis->type != GOG_AXIS_CIRCULAR) {
+ double new_value = g_value_get_double (value);
+ g_return_if_fail (new_value < axis->span_end);
+ axis->span_start = new_value;
+ }
+ break;
+ case AXIS_PROP_SPAN_END:
+ if (axis->type != GOG_AXIS_CIRCULAR) {
+ double new_value = g_value_get_double (value);
+ g_return_if_fail (new_value > axis->span_start);
+ axis->span_end = new_value;
+ }
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
return; /* NOTE : RETURN */
@@ -2109,6 +2141,12 @@ gog_axis_get_property (GObject *obj, guint param_id,
case AXIS_PROP_POLAR_UNIT:
g_value_set_string (value, polar_units[axis->polar_unit].name);
break;
+ case AXIS_PROP_SPAN_START:
+ g_value_set_double (value, axis->span_start);
+ break;
+ case AXIS_PROP_SPAN_END:
+ g_value_set_double (value, axis->span_end);
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
break;
@@ -2447,6 +2485,24 @@ cb_rotation_changed (GtkSpinButton *spin, GogAxis *axis)
}
static void
+cb_start_changed (GtkSpinButton *spin, GogAxis *axis)
+{
+ double val = gtk_spin_button_get_value (spin);
+ GtkAdjustment *adj = GTK_ADJUSTMENT (g_object_get_data (G_OBJECT (spin), "other-adj"));
+ gtk_adjustment_set_lower (adj, fmin (val + 1, axis->span_end * 100.));
+ g_object_set (axis, "span-start", val /100., NULL);
+}
+
+static void
+cb_end_changed (GtkSpinButton *spin, GogAxis *axis)
+{
+ double val = gtk_spin_button_get_value (spin);
+ GtkAdjustment *adj = GTK_ADJUSTMENT (g_object_get_data (G_OBJECT (spin), "other-adj"));
+ gtk_adjustment_set_upper (adj, fmax (val - 1, axis->span_start * 100.));
+ g_object_set (axis, "span-end", val /100., NULL);
+}
+
+static void
gog_axis_populate_editor (GogObject *gobj,
GOEditor *editor,
GogDataAllocator *dalloc,
@@ -2547,6 +2603,28 @@ gog_axis_populate_editor (GogObject *gobj,
go_gtk_builder_get_widget (gui, "axis-pref-grid"),
_("Scale"));
+ /* effective area */
+ if (axis->type != GOG_AXIS_CIRCULAR) {
+ GtkAdjustment *adj;
+ double start = axis->span_start * 100., end = axis->span_end * 100.;
+ w = go_gtk_builder_get_widget (gui, "start-btn");
+ adj = GTK_ADJUSTMENT (gtk_builder_get_object (gui, "end-adj"));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), start);
+ gtk_adjustment_set_lower (adj, fmin (start + 1., end));
+ g_signal_connect (w, "value_changed", G_CALLBACK (cb_start_changed), axis);
+ g_object_set_data (G_OBJECT (w), "other-adj", adj);
+ w = go_gtk_builder_get_widget (gui, "end-btn");
+ adj = GTK_ADJUSTMENT (gtk_builder_get_object (gui, "start-adj"));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), end);
+ gtk_adjustment_set_upper (adj, fmax (end - 1., start));
+ g_signal_connect (w, "value_changed", G_CALLBACK (cb_end_changed), axis);
+ g_object_set_data (G_OBJECT (w), "other-adj", adj);
+ go_editor_add_page (editor,
+ go_gtk_builder_get_widget (gui, "area-grid"),
+ _("Span"));
+ }
+
+
if (gog_object_is_visible (axis) && gog_axis_get_atype (axis) < GOG_AXIS_VIRTUAL) {
/* Style page */
(GOG_OBJECT_CLASS(parent_klass)->populate_editor) (gobj, editor, dalloc, cc);
@@ -2651,6 +2729,18 @@ gog_axis_class_init (GObjectClass *gobject_klass)
_("Polar axis set unit"),
polar_units[GOG_AXIS_POLAR_UNIT_DEGREES].name,
GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, AXIS_PROP_SPAN_START,
+ g_param_spec_double ("span-start",
+ _("Axis start position"),
+ _("Position of the plot area at which the axis effective area starts, expressed as a percentage of the available position. Defaults to 0.0"),
+ 0., 1., 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, AXIS_PROP_SPAN_END,
+ g_param_spec_double ("span-end",
+ _("Axis end position"),
+ _("Position of the plot area at which the axis effective area ends, expressed as a percentage of the available position. Defaults to 1.0"),
+ 0., 1., 1.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
gog_object_register_roles (gog_klass, roles, G_N_ELEMENTS (roles));
@@ -2686,6 +2776,8 @@ gog_axis_init (GogAxis *axis)
axis->ticks = NULL;
axis->tick_nbr = 0;
+ axis->span_start = 0.;
+ axis->span_end = 1.;
}
static void
@@ -2822,6 +2914,15 @@ gog_axis_set_bounds (GogAxis *axis, double minimum, double maximum)
}
}
+void
+gog_axis_get_effective_span (GogAxis const *axis, double *start, double *end)
+{
+ g_return_if_fail (GOG_IS_AXIS (axis));
+
+ *start = axis->span_start;
+ *end = axis->span_end;
+}
+
/**
* gog_axis_set_extents :
* @axis : #GogAxis
diff --git a/goffice/graph/gog-axis.h b/goffice/graph/gog-axis.h
index 8e531ee..f7b001d 100644
--- a/goffice/graph/gog-axis.h
+++ b/goffice/graph/gog-axis.h
@@ -81,6 +81,8 @@ gboolean gog_axis_get_bounds (GogAxis const *axis,
void gog_axis_set_bounds (GogAxis *axis,
double minimum, double maximum);
void gog_axis_set_extents (GogAxis *axis, double start, double stop);
+void gog_axis_get_effective_span (GogAxis const *axis,
+ double *start, double *end);
GOFormat *gog_axis_get_format (GogAxis const *axis);
GOFormat *gog_axis_get_effective_format (GogAxis const *axis);
gboolean gog_axis_set_format (GogAxis *axis, GOFormat *fmt);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]