[goffice] Make data labels work in bar/column charts.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Make data labels work in bar/column charts.
- Date: Sat, 20 Aug 2011 14:24:25 +0000 (UTC)
commit 51e2f91818c9af7bf65dd1633ad711447d23429b
Author: Jean Brefort <jean brefort normalesup org>
Date: Sat Aug 20 16:28:49 2011 +0200
Make data labels work in bar/column charts.
ChangeLog | 13 ++++
goffice/graph/goffice-graph.h | 2 +-
goffice/graph/gog-renderer.c | 145 +++++++++++++++++++++++++++++++++++++
goffice/graph/gog-renderer.h | 4 +
goffice/graph/gog-series-labels.c | 18 +----
goffice/graph/gog-series-labels.h | 2 +-
goffice/graph/gog-view.c | 6 ++
goffice/graph/gog-view.h | 2 +
plugins/plot_barcol/gog-barcol.c | 6 ++-
9 files changed, 181 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9c66037..92de6cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-08-20 Jean Brefort <jean brefort normalesup org>
+ * goffice/graph/goffice-graph.h: fix include order.
+ * goffice/graph/gog-renderer.c (gog_renderer_draw_data_label): new function.
+ * goffice/graph/gog-renderer.h: ditto.
+ * goffice/graph/gog-series-labels.c (gog_series_labels_update): make legend
+ entry in label work.
+ * goffice/graph/gog-series-labels.h: ditto.
+ * goffice/graph/gog-view.c (gog_view_get_natural_size): new function
+ (see #629794)
+ * goffice/graph/gog-view.h: ditto.
+ * plugins/plot_barcol/gog-barcol.c (gog_barcol_view_render): use
+ gog_renderer_draw_data_label.
+
2011-08-18 Andreas J. Guelzow <aguelzow pyrshep ca>
* goffice/app/go-cmd-context-impl.h (go_cmd_context_progress_set):
diff --git a/goffice/graph/goffice-graph.h b/goffice/graph/goffice-graph.h
index 9ad07fb..3cf1849 100644
--- a/goffice/graph/goffice-graph.h
+++ b/goffice/graph/goffice-graph.h
@@ -266,9 +266,9 @@ G_END_DECLS
#include <goffice/graph/gog-plot.h>
#include <goffice/graph/gog-plot-impl.h>
#include <goffice/graph/gog-reg-curve.h>
+#include <goffice/graph/gog-series-labels.h>
#include <goffice/graph/gog-renderer.h>
#include <goffice/graph/gog-series-lines.h>
-#include <goffice/graph/gog-series-labels.h>
#include <goffice/graph/gog-smoothed-curve.h>
#include <goffice/graph/gog-theme.h>
diff --git a/goffice/graph/gog-renderer.c b/goffice/graph/gog-renderer.c
index 7ea33d9..066e30c 100644
--- a/goffice/graph/gog-renderer.c
+++ b/goffice/graph/gog-renderer.c
@@ -1090,6 +1090,151 @@ gog_renderer_get_gostring_AABR (GogRenderer *rend, GOString *str,
go_geometry_OBR_to_AABR (&obr, aabr);
}
+void
+gog_renderer_draw_data_label (GogRenderer *rend, GogSeriesLabelElt const *elt,
+ GogViewAllocation const *pos, GOAnchorType anchor,
+ GOStyle *legend_style)
+{
+ /* things are a bit different from gog_renderer_draw_gostring, so the
+ * code must be copied */
+ PangoLayout *layout;
+ PangoContext *context;
+ cairo_t *cairo;
+ GOGeometryOBR obr;
+ GOGeometryAABR aabr;
+ GOStyle const *style;
+ int iw, ih;
+ PangoAttrList *attrs;
+ PangoRectangle rect;
+
+ g_return_if_fail (elt != NULL && elt->str != NULL);
+ g_return_if_fail (GOG_IS_RENDERER (rend));
+ g_return_if_fail (rend->cur_style != NULL);
+
+ cairo = rend->cairo;
+ style = rend->cur_style;
+
+ /* Note: orig layout may not have been created using cairo! */
+ layout = pango_cairo_create_layout (cairo);
+ context = pango_layout_get_context (layout);
+ pango_layout_set_text (layout, elt->str->str, -1);
+ attrs = pango_attr_list_copy (go_string_get_markup (elt->str));
+ pango_layout_set_font_description (layout, style->font.font->desc);
+ if (attrs)
+ pango_layout_set_attributes (layout, attrs);
+ pango_cairo_context_set_resolution (context, 72.0);
+ /*now get the real size */
+ pango_layout_get_size (layout, &iw, &ih);
+ if (elt->legend_pos >= 0) {
+ /* we need to add enough room to draw the legend entry */
+ PangoRectangle rect;
+ PangoAttribute *attr;
+ rect.x = rect.y = 0;
+ pango_layout_get_size (layout, &iw, &ih);
+ rect.height = 1; /* only the width is important */
+ rect.width = (legend_style->interesting_fields & GO_STYLE_LINE)? 2 * ih: ih;
+ attr = pango_attr_shape_new (&rect, &rect);
+ attr->start_index = elt->legend_pos;
+ attr->end_index = elt->legend_pos + 1;
+ pango_attr_list_insert (attrs, attr);
+ pango_layout_set_attributes (layout, attrs);
+ pango_layout_get_size (layout, &iw, &ih);
+ }
+ pango_attr_list_unref (attrs);
+
+ obr.w = rend->scale * ((double) iw + (double) PANGO_SCALE / 2.0)
+ / (double) PANGO_SCALE;
+ obr.h = rend->scale * ((double) ih + (double) PANGO_SCALE / 2.0)
+ /(double) PANGO_SCALE;
+ obr.alpha = -style->text_layout.angle * M_PI / 180.0;
+ obr.x = pos->x;
+ obr.y = pos->y;
+ go_geometry_OBR_to_AABR (&obr, &aabr);
+
+ switch (anchor) {
+ case GO_ANCHOR_NW: case GO_ANCHOR_W: case GO_ANCHOR_SW:
+ obr.x += aabr.w / 2.0;
+ break;
+ case GO_ANCHOR_NE : case GO_ANCHOR_SE : case GO_ANCHOR_E :
+ obr.x -= aabr.w / 2.0;
+ break;
+ default : break;
+ }
+
+ switch (anchor) {
+ case GO_ANCHOR_NW: case GO_ANCHOR_N: case GO_ANCHOR_NE:
+ obr.y += aabr.h / 2.0;
+ break;
+ case GO_ANCHOR_SE : case GO_ANCHOR_S : case GO_ANCHOR_SW :
+ obr.y -= aabr.h / 2.0;
+ break;
+ default : break;
+ }
+
+ cairo_save (cairo);
+ cairo_set_source_rgba (cairo, GO_COLOR_TO_CAIRO (style->font.color));
+ cairo_translate (cairo, obr.x - (obr.w / 2.0) * cos (obr.alpha) +
+ (obr.h / 2.0) * sin (obr.alpha),
+ obr.y - (obr.w / 2.0) * sin (obr.alpha) -
+ (obr.h / 2.0) * cos (obr.alpha));
+ cairo_rotate (cairo, obr.alpha);
+ cairo_scale (cairo, rend->scale, rend->scale);
+ pango_cairo_show_layout (cairo, layout);
+ /* now draw the legen entry if needed */
+ if (elt->legend_pos >= 0 && legend_style != NULL) {
+ GOStyle *style = go_style_dup (legend_style);
+ GogViewAllocation rectangle;
+ double x, y,w, h;
+ pango_layout_index_to_pos (layout, elt->legend_pos, &rect);
+ x = (double) rect.x / PANGO_SCALE;
+ y = (double) rect.y / PANGO_SCALE;
+ w = (double) rect.width / PANGO_SCALE;
+ h = (double) rect.height / PANGO_SCALE;
+ if (style->interesting_fields & GO_STYLE_LINE) { /* line and marker */
+ GOPath *line_path;
+ if (style->line.width > h / 3.)
+ style->line.width = h / 3.;
+ if (go_marker_get_size (style->marker.mark) > h)
+ go_marker_set_size (style->marker.mark, h);
+ gog_renderer_push_style (rend, style);
+ line_path = go_path_new ();
+ y += h / 2.;
+ go_path_move_to (line_path, x, y);
+ go_path_line_to (line_path, x + w, y);
+ if (style->interesting_fields & GO_STYLE_FILL) {
+ rectangle.x = x;
+ rectangle.y = y;
+ rectangle.w = w;
+ rectangle.h = h / 2.0;
+ gog_renderer_fill_rectangle (rend, &rectangle);
+ }
+ gog_renderer_stroke_serie (rend, line_path);
+ go_path_free (line_path);
+ gog_renderer_draw_marker (rend, x + w / 2., y);
+ } else if (style->interesting_fields & GO_STYLE_FILL) {/* area */
+ if (style->line.width > h / 3.)
+ style->line.width = h / 3.;
+
+ rectangle.x = x;
+ rectangle.y = y;
+ rectangle.w = w;
+ rectangle.h = h;
+
+ gog_renderer_push_style (rend, style);
+ gog_renderer_draw_rectangle (rend, &rectangle);
+ } else if (style->interesting_fields & GO_STYLE_MARKER) { /* markers only */
+ if (go_marker_get_size (style->marker.mark) > h)
+ go_marker_set_size (style->marker.mark, h);
+ gog_renderer_push_style (rend, style);
+ gog_renderer_draw_marker (rend, x + w / 2., y + h / 2.);
+ }
+ gog_renderer_pop_style (rend);
+ g_object_unref (style);
+ }
+ cairo_restore (cairo);
+ g_object_unref (layout);
+}
+
static void
_free_marker_data (GogRenderer *rend)
{
diff --git a/goffice/graph/gog-renderer.h b/goffice/graph/gog-renderer.h
index 2e31e6b..c0821b2 100644
--- a/goffice/graph/gog-renderer.h
+++ b/goffice/graph/gog-renderer.h
@@ -91,6 +91,10 @@ void gog_renderer_draw_text (GogRenderer *rend, char const *text,
GOAnchorType anchor,
gboolean use_markup);
+void gog_renderer_draw_data_label (GogRenderer *rend, GogSeriesLabelElt const *elt,
+ GogViewAllocation const *pos, GOAnchorType anchor,
+ GOStyle *legend_style);
+
void gog_renderer_draw_gostring (GogRenderer *rend,
GOString *str,
GogViewAllocation const *pos,
diff --git a/goffice/graph/gog-series-labels.c b/goffice/graph/gog-series-labels.c
index 7c32c5f..72ca1ff 100644
--- a/goffice/graph/gog-series-labels.c
+++ b/goffice/graph/gog-series-labels.c
@@ -21,7 +21,7 @@
*/
#include <goffice/goffice-config.h>
-#include <goffice/graph/gog-series-labels.h>
+#include <goffice/goffice.h>
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
@@ -599,8 +599,6 @@ gog_series_labels_update (GogObject *obj)
{
GogSeriesLabels *labels = GOG_SERIES_LABELS (obj);
GogObject *parent = gog_object_get_parent (GOG_OBJECT (obj));
- GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (obj));
- int height = pango_font_description_get_size (style->font.font->desc);
unsigned i, n;
if (labels->elements) {
n = labels->n_elts;
@@ -618,6 +616,7 @@ gog_series_labels_update (GogObject *obj)
PangoAttrList *markup = pango_attr_list_new (), *l;
char const *format = labels->format;
char *next;
+ labels->elements[i].legend_pos = -1;
while (*format) {
if (*format == '%') {
format++;
@@ -641,17 +640,8 @@ gog_series_labels_update (GogObject *obj)
}
break;
case 'l': {
- /* add room for the legend entry */
- PangoRectangle rect;
- PangoAttribute *attr;
- rect.x = rect.y = 0;
- rect.height = 1; /* only the width is important */
- rect.width = 2 * height; /* FIXME, should not always be 2 */
- attr = pango_attr_shape_new (&rect, &rect);
- attr->start_index = str->len;
- g_string_append_c (str, 'o');
- attr->end_index = str->len;
- pango_attr_list_insert (markup, attr);
+ labels->elements[i].legend_pos = str->len;
+ g_string_append_c (str, ' '); /* this one will be replaced by the legend entry */
break;
}
case '0':
diff --git a/goffice/graph/gog-series-labels.h b/goffice/graph/gog-series-labels.h
index caf2cd7..deed348 100644
--- a/goffice/graph/gog-series-labels.h
+++ b/goffice/graph/gog-series-labels.h
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
typedef struct {
GOString *str;
- double legend_offset, legend_width, width, height;
+ int legend_pos;
} GogSeriesLabelElt;
struct _GogSeriesLabels {
diff --git a/goffice/graph/gog-view.c b/goffice/graph/gog-view.c
index dd2ae99..7af8d3b 100644
--- a/goffice/graph/gog-view.c
+++ b/goffice/graph/gog-view.c
@@ -1024,3 +1024,9 @@ gog_view_get_tip_at_point (GogView *view, double x, double y)
GogViewClass *klass = GOG_VIEW_GET_CLASS (view);
return (klass->get_tip_at_point != NULL)? (klass->get_tip_at_point) (view, x, y): NULL;
}
+
+void
+gog_view_get_natural_size (GogView *view, GogViewRequisition *requisition)
+{
+ requisition->w = requisition->h = 0.; /*FIXME!!!*/
+}
diff --git a/goffice/graph/gog-view.h b/goffice/graph/gog-view.h
index 0ab1a69..1a9b31d 100644
--- a/goffice/graph/gog-view.h
+++ b/goffice/graph/gog-view.h
@@ -92,6 +92,7 @@ typedef struct {
void (*build_toolkit) (GogView *view);
char *(*get_tip_at_point) (GogView *view, double x, double y);
+ void (*natural_size) (GogView *view, GogViewRequisition *req);
} GogViewClass;
#define GOG_TYPE_VIEW (gog_view_get_type ())
@@ -114,6 +115,7 @@ void gog_view_size_allocate (GogView *view, GogViewAllocation const *al
gboolean gog_view_update_sizes (GogView *view);
GogView *gog_view_find_child_view (GogView const *container,
GogObject const *target_model);
+void gog_view_get_natural_size (GogView *view, GogViewRequisition *requisition);
GSList const *gog_view_get_toolkit (GogView *view);
void gog_view_render_toolkit (GogView *view);
diff --git a/plugins/plot_barcol/gog-barcol.c b/plugins/plot_barcol/gog-barcol.c
index 3113c5d..a07b055 100644
--- a/plugins/plot_barcol/gog-barcol.c
+++ b/plugins/plot_barcol/gog-barcol.c
@@ -862,7 +862,11 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
for (j = 0; j < lengths[i]; j++) {
alloc.x = label_pos[i][j].x;
alloc.y = label_pos[i][j].y;
- gog_renderer_draw_gostring (view->renderer, label_pos[i][j].elt->str, &alloc, label_pos[i][j].anchor);
+ gog_renderer_draw_data_label (view->renderer,
+ label_pos[i][j].elt,
+ &alloc,
+ label_pos[i][j].anchor,
+ styles[i]);
}
gog_renderer_pop_style (view->renderer);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]