[goffice] Implement get_data_at_point for bar/columns.
- From: Jean Bréfort <jbrefort src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] Implement get_data_at_point for bar/columns.
- Date: Sat, 19 Dec 2009 12:25:28 +0000 (UTC)
commit 1f83846875a82417f605a94a154d8726d2ef3977
Author: Jean Brefort <jean brefort normalesup org>
Date: Sat Dec 19 13:26:18 2009 +0100
Implement get_data_at_point for bar/columns.
ChangeLog | 6 ++
plugins/plot_barcol/gog-barcol.c | 164 +++++++++++++++++++++++++++++++++++++-
2 files changed, 168 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b7b431b..dd69996 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-12-19 Jean Brefort <jean brefort normalesup org>
+
+ * plugins/plot_barcol/gog-barcol.c
+ (gog_barcol_view_get_data_at_point), (gog_barcol_view_render),
+ (gog_barcol_view_class_init): implement get_data_at_point for bar/columns.
+
2009-12-18 Jean Brefort <jean brefort normalesup org>
* goffice/canvas/goc-canvas.c (goc_canvas_c2w): fixed rounding to int.
diff --git a/plugins/plot_barcol/gog-barcol.c b/plugins/plot_barcol/gog-barcol.c
index f9b3732..40945f9 100644
--- a/plugins/plot_barcol/gog-barcol.c
+++ b/plugins/plot_barcol/gog-barcol.c
@@ -353,6 +353,165 @@ typedef struct {
double y;
} ErrorBarData;
+static int
+gog_barcol_view_get_data_at_point (GogPlotView *view, double x, double y, GogSeries **series)
+{
+ GogBarColPlot const *model = GOG_BARCOL_PLOT (view->base.model);
+ GogPlot1_5d const *gog_1_5d_model = GOG_PLOT1_5D (model);
+ GogSeries1_5d const *pseries;
+ GogChart *chart = GOG_CHART (view->base.model->parent);
+ GogChartMap *chart_map;
+ GogAxisMap *x_map, *y_map, *map;
+ GogViewAllocation work;
+ GogViewAllocation const *area;
+ unsigned num_elements = gog_1_5d_model->num_elements;
+ unsigned num_series = gog_1_5d_model->num_series;
+ gboolean is_vertical = ! (model->horizontal), valid;
+ double **vals, sum, neg_base, pos_base, tmp;
+ double col_step, group_step, offset, data_scale;
+ unsigned i, j, jinit, jend, jstep;
+ GogPlot1_5dType const type = gog_1_5d_model->type;
+ GSList *ptr;
+ unsigned *lengths;
+
+ if (num_elements <= 0 || num_series <= 0)
+ return -1;
+
+ area = gog_chart_view_get_plot_area (view->base.parent);
+ chart_map = gog_chart_map_new (chart, area,
+ GOG_PLOT (model)->axis[GOG_AXIS_X],
+ GOG_PLOT (model)->axis[GOG_AXIS_Y],
+ NULL, FALSE);
+ if (!gog_chart_map_is_valid (chart_map)) {
+ gog_chart_map_free (chart_map);
+ return -1;
+ }
+
+ x_map = gog_chart_map_get_axis_map (chart_map, 0);
+ y_map = gog_chart_map_get_axis_map (chart_map, 1);
+
+ map = is_vertical ? y_map : x_map;
+
+ vals = g_alloca (num_series * sizeof (double *));
+ lengths = g_alloca (num_series * sizeof (unsigned));
+
+ i = 0;
+ for (ptr = gog_1_5d_model->base.series ; ptr != NULL ; ptr = ptr->next) {
+ pseries = ptr->data;
+ if (!gog_series_is_valid (GOG_SERIES (pseries)))
+ continue;
+ vals[i] = go_data_get_values (pseries->base.values[1].data);
+ lengths[i] = go_data_get_vector_size (pseries->base.values[1].data);
+ i++;
+ }
+
+ /* work in coordinates drawing bars from the top */
+ col_step = 1. - model->overlap_percentage / 100.;
+ group_step = model->gap_percentage / 100.;
+ work.h = 1.0 / (1. + ((num_series - 1.0) * col_step) + group_step);
+ col_step *= work.h;
+ offset = (col_step * (num_series - 1.0) + work.h) / 2.0;
+ data_scale = 1.0;
+ if (type == GOG_1_5D_NORMAL) {
+ /* we need to start from last series because they may overlap */
+ jinit = num_series - 1;
+ jstep = jend = -1;
+ } else {
+ jinit = 0;
+ jend = num_series;
+ jstep = 1;
+ }
+
+ for (i = 0 ; i < num_elements ; i++) {
+ if (type == GOG_1_5D_AS_PERCENTAGE) {
+ sum = 0.;
+ for (j = num_series ; j-- > 0 ; ) {
+ if (i >= lengths[j])
+ continue;
+ tmp = vals[j][i];
+ if (!gog_axis_map_finite (map, tmp))
+ continue;
+ if (tmp > 0.)
+ sum += tmp;
+ else
+ sum -= tmp;
+ }
+
+ data_scale = (fabs (go_sub_epsilon (sum)) > 0.0) ? 1.0 / sum : 1.0;
+ }
+
+ pos_base = neg_base = 0.0;
+ for (j = jinit; j != jend; j += jstep) {
+ double x0, y0, x1, y1;
+ work.y = (double) j * col_step + (double) i - offset + 1.0;
+
+ if (i >= lengths[j])
+ continue;
+
+ tmp = vals[j][i];
+ valid = TRUE;
+ if (!gog_axis_map_finite (map, tmp)) {
+ tmp = 0;
+ valid = FALSE;
+ }
+ tmp *= data_scale;
+ if (tmp >= 0.) {
+ work.x = pos_base;
+ work.w = tmp;
+ if (GOG_1_5D_NORMAL != type)
+ pos_base += tmp;
+ } else {
+ work.x = neg_base + tmp;
+ work.w = -tmp;
+ if (GOG_1_5D_NORMAL != type)
+ neg_base += tmp;
+ }
+
+ if (is_vertical) {
+ x0 = gog_axis_map_to_view (x_map, work.y);
+ x1 = gog_axis_map_to_view (x_map, work.y + work.h);
+ if (gog_axis_map_finite (y_map, work.x))
+ y0 = gog_axis_map_to_view (y_map, work.x);
+ else
+ y0 = gog_axis_map_get_baseline (y_map);
+ if (gog_axis_map_finite (y_map, work.x + work.w))
+ y1 = gog_axis_map_to_view (y_map, work.x + work.w);
+ else
+ y1 = gog_axis_map_get_baseline (y_map);
+ } else {
+ if (gog_axis_map_finite (x_map, work.x))
+ x0 = gog_axis_map_to_view (x_map, work.x);
+ else
+ x0 = gog_axis_map_get_baseline (x_map);
+ if (gog_axis_map_finite (x_map, work.x + work.w))
+ x1 = gog_axis_map_to_view (x_map, work.x + work.w);
+ else
+ x1 = gog_axis_map_get_baseline (x_map);
+ y0 = gog_axis_map_to_view (y_map, work.y);
+ y1 = gog_axis_map_to_view (y_map, work.y + work.h);
+ }
+ if (x0 > x1) {
+ tmp = x0;
+ x0 = x1;
+ x1 = tmp;
+ }
+ if (y0 > y1) {
+ tmp = y0;
+ y0 = y1;
+ y1 = tmp;
+ }
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ *series = GOG_SERIES (g_slist_nth_data (gog_1_5d_model->base.series, j));
+ gog_chart_map_free (chart_map);
+ return i;
+ }
+ }
+ }
+
+ gog_chart_map_free (chart_map);
+ return -1;
+}
+
static void
gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
{
@@ -465,7 +624,6 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
}
pos_base = neg_base = 0.0;
- ptr = gog_1_5d_model->base.series;
for (j = 0 ; j < num_series ; j++) {
work.y = (double) j * col_step + (double) i - offset + 1.0;
@@ -539,7 +697,6 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
gog_axis_map_to_view (y_map, work.y + work.h));
}
}
- ptr = ptr->next;
}
}
/*Now draw error bars and clean*/
@@ -567,8 +724,11 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
static void
gog_barcol_view_class_init (GogViewClass *view_klass)
{
+ GogPlotViewClass *pv_klass = (GogPlotViewClass *) view_klass;
+
view_klass->render = gog_barcol_view_render;
view_klass->clip = TRUE;
+ pv_klass->get_data_at_point = gog_barcol_view_get_data_at_point;
}
GSF_DYNAMIC_CLASS (GogBarColView, gog_barcol_view,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]