[goffice] New color maps for color and pseudo-3d axes.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] New color maps for color and pseudo-3d axes.
- Date: Sun, 28 Oct 2012 16:53:20 +0000 (UTC)
commit cc69b2c9a9cea371f229642ef388f4a380e9d739
Author: Jean Brefort <jean brefort normalesup org>
Date: Sun Oct 28 18:52:32 2012 +0100
New color maps for color and pseudo-3d axes.
ChangeLog | 24 +++++
goffice/Makefile.am | 6 +-
goffice/graph/goffice-graph.h | 5 +
goffice/graph/gog-axis-color-map.c | 155 ++++++++++++++++++++++++++++++
goffice/graph/gog-axis-color-map.h | 47 +++++++++
goffice/graph/gog-axis.c | 31 ++++++-
goffice/graph/gog-axis.h | 1 +
goffice/graph/gog-color-scale.c | 182 ++++++++++++++++++++++++++++++++++++
goffice/graph/gog-color-scale.h | 37 +++++++
goffice/graph/gog-theme.c | 118 +++++++++++++++--------
goffice/graph/gog-theme.h | 1 +
plugins/plot_surface/gog-contour.c | 43 +++------
plugins/plot_xy/gog-xy.c | 30 ++++---
13 files changed, 591 insertions(+), 89 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 57b6dfc..867fcef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2012-10-28 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/Makefile.am: new objects.
+ * goffice/graph/goffice-graph.h: ditto.
+ * goffice/graph/gog-axis.c (gog_axis_init_style), (gog_axis_init),
+ (gog_axis_get_color_map): add a color map to GogAxis.
+ * goffice/graph/gog-axis.h: ditto.
+ * goffice/graph/gog-axis-color-map.c: new objects.
+ * goffice/graph/gog-axis-color-map.h: ditto.
+ * goffice/graph/gog-color-scale.c: ditto.
+ * goffice/graph/gog-color-scale.h: ditto.
+ * goffice/graph/gog-theme.c (map_area_series_solid_default),
+ (map_area_series_solid_guppi), (build_predefined_themes),
+ (theme_load_from_uri), (_gog_themes_init), (_gog_themes_shutdown),
+ (gog_theme_get_color_map): add two color maps to themes.
+ * goffice/graph/gog-theme.h: ditto.
+ * plugins/plot_surface/gog-contour.c
+ (gog_contour_plot_foreach_elem), (gog_contour_view_render): use
+ GogAxisColorMap API for color plots.
+ * plugins/plot_xy/gog-xy.c (gog_2d_plot_update): fixed warning,
+ (gog_xy_view_render), (gog_xy_series_populate_editor): ditto for contour
+ plots.
+
+
2012-10-27 Morten Welinder <terra gnome org>
* goffice/graph/gog-axis-line.c (axis_line_get_bbox): Improve
diff --git a/goffice/Makefile.am b/goffice/Makefile.am
index ed65328..6878d91 100644
--- a/goffice/Makefile.am
+++ b/goffice/Makefile.am
@@ -171,7 +171,9 @@ graph_SOURCES = \
\
graph/gog-axis.c \
graph/gog-axis-line.c \
+ graph/gog-axis-color-map.c \
graph/gog-legend.c \
+ graph/gog-color-scale.c \
graph/gog-label.c \
graph/gog-grid.c \
graph/gog-grid-line.c \
@@ -215,8 +217,10 @@ graph_HEADERS = \
graph/gog-chart-map-3d.h \
graph/gog-3d-box.h \
graph/gog-axis.h \
- graph/gog-axis-line.h \
+ graph/gog-axis-line.h \
+ graph/gog-axis-color-map.h \
graph/gog-legend.h \
+ graph/gog-color-scale.h \
graph/gog-label.h \
graph/gog-grid.h \
graph/gog-grid-line.h \
diff --git a/goffice/graph/goffice-graph.h b/goffice/graph/goffice-graph.h
index 0e7c44d..b550056 100644
--- a/goffice/graph/goffice-graph.h
+++ b/goffice/graph/goffice-graph.h
@@ -49,6 +49,8 @@ typedef struct _GogStyledObject GogStyledObject;
typedef struct _GogAxisBase GogAxisBase;
typedef struct _GogAxis GogAxis;
typedef struct _GogAxisLine GogAxisLine;
+typedef struct _GogAxisColorMap GogAxisColorMap;
+typedef struct _GogColorScale GogColorScale;
typedef struct _GogGrid GogGrid;
typedef struct _GogGridLine GogGridLine;
typedef struct _GogErrorBar GogErrorBar;
@@ -251,8 +253,11 @@ G_END_DECLS
#include <goffice/graph/gog-chart-impl.h>
#include <goffice/graph/gog-chart-map.h>
#include <goffice/graph/gog-chart-map-3d.h>
+#include <goffice/graph/gog-axis-color-map.h>
+#include <goffice/graph/gog-color-scale.h>
#ifdef GOFFICE_WITH_GTK
#include <goffice/graph/gog-child-button.h>
+#include <goffice/graph/gog-color-scale.h>
#include <goffice/graph/gog-data-allocator.h>
#endif
#ifdef GOFFICE_WITH_LASEM
diff --git a/goffice/graph/gog-axis-color-map.c b/goffice/graph/gog-axis-color-map.c
new file mode 100644
index 0000000..8c2508a
--- /dev/null
+++ b/goffice/graph/gog-axis-color-map.c
@@ -0,0 +1,155 @@
+/*
+ * gog-axis-color-map.c
+ *
+ * Copyright (C) 2012 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include <goffice/goffice.h>
+
+#include <gsf/gsf-impl-utils.h>
+
+#ifdef GOFFICE_WITH_GTK
+#include <gtk/gtk.h>
+#endif
+
+struct _GogAxisColorMap {
+ GObject base;
+ char *name;
+ unsigned size; /* colors number */
+ unsigned *limits;
+ GOColor *colors;
+};
+typedef GObjectClass GogAxisColorMapClass;
+
+static GObjectClass *parent_klass;
+
+static void
+gog_axis_color_map_finalize (GObject *obj)
+{
+ GogAxisColorMap *map = GOG_AXIS_COLOR_MAP (obj);
+ g_free (map->name);
+ map->name = NULL;
+ g_free (map->limits);
+ map->limits = NULL;
+ g_free (map->colors);
+ map->colors = NULL;
+ parent_klass->finalize (obj);
+}
+
+static void
+gog_axis_color_map_class_init (GObjectClass *gobject_klass)
+{
+ parent_klass = g_type_class_peek_parent (gobject_klass);
+ /* GObjectClass */
+ gobject_klass->finalize = gog_axis_color_map_finalize;
+}
+
+static void
+gog_axis_color_map_init (GogAxisColorMap *map)
+{
+}
+
+GSF_CLASS (GogAxisColorMap, gog_axis_color_map,
+ gog_axis_color_map_class_init, gog_axis_color_map_init,
+ G_TYPE_OBJECT)
+
+GOColor
+gog_axis_color_map_get_color (GogAxisColorMap const *map, double x)
+{
+ unsigned n = 1;
+ double t;
+ g_return_val_if_fail (GOG_IS_AXIS_COLOR_MAP (map), (GOColor) 0x00000000);
+ if (x < 0. || map->size == 0)
+ return (GOColor) 0x00000000;
+ if (map->size == 1)
+ return map->colors[0];
+ if (x > map->limits[map->size-1])
+ x -= floor (x / map->limits[map->size-1]) * map->limits[map->size-1];
+ while (n < map->size && x > map->limits[n])
+ n++;
+ t = (x - map->limits[n-1]) / (map->limits[n] - map->limits[n-1]);
+ return GO_COLOR_INTERPOLATE (map->colors[n-1], map->colors[n], t);
+}
+
+unsigned
+gog_axis_color_map_get_max (GogAxisColorMap const *map)
+{
+ g_return_val_if_fail (GOG_IS_AXIS_COLOR_MAP (map), 0);
+ return (map->size > 0)? map->limits[map->size-1]: 0;
+}
+
+/**
+ * gog_axis_color_map_from_colors:
+ * @name: color map name
+ * @nb: colors number
+ * @colors: the colors.
+ *
+ * Creates a color map using @colors.
+ * Returns: (transfer full): the newly created color map.
+ **/
+GogAxisColorMap *
+gog_axis_color_map_from_colors (char const *name, unsigned nb, GOColor const *colors)
+{
+ unsigned i;
+ GogAxisColorMap *color_map = g_object_new (GOG_TYPE_AXIS_COLOR_MAP, NULL);
+ color_map->name = g_strdup (name);
+ color_map->size = nb;
+ color_map->limits = g_new (unsigned, nb);
+ color_map->colors = g_new (GOColor, nb);
+ for (i = 0; i < nb; i++) {
+ color_map->limits[i] = i;
+ color_map->colors[i] = colors[i];
+ }
+ return color_map;
+}
+
+static GogAxisColorMap *color_map = NULL;
+
+GogAxisColorMap const *
+_gog_axis_color_map_get_default ()
+{
+ return color_map;
+}
+
+void
+_gog_axis_color_maps_init (void)
+{
+ /* Default color map */
+ color_map = g_object_new (GOG_TYPE_AXIS_COLOR_MAP, NULL);
+ color_map->name = g_strdup ("Default");
+ color_map->size = 5;
+ color_map->limits = g_new (unsigned, 5);
+ color_map->colors = g_new (GOColor, 5);
+ color_map->limits[0] = 0;
+ color_map->colors[0] = GO_COLOR_BLUE;
+ color_map->limits[1] = 1;
+ color_map->colors[1] = GO_COLOR_FROM_RGB (0, 0xff, 0xff);
+ color_map->limits[2] = 2;
+ color_map->colors[2] = GO_COLOR_GREEN;
+ color_map->limits[3] = 4;
+ color_map->colors[3] = GO_COLOR_YELLOW;
+ color_map->limits[4] = 6;
+ color_map->colors[4] = GO_COLOR_RED;
+}
+
+void
+_gog_axis_color_maps_shutdown (void)
+{
+ g_object_unref (color_map);
+}
diff --git a/goffice/graph/gog-axis-color-map.h b/goffice/graph/gog-axis-color-map.h
new file mode 100644
index 0000000..8607367
--- /dev/null
+++ b/goffice/graph/gog-axis-color-map.h
@@ -0,0 +1,47 @@
+/*
+ * gog-axis-color-map.h
+ *
+ * Copyright (C) 2012 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GOG_AXIS_COLOR_MAP_H
+#define GOG_AXIS_COLOR_MAP_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+#define GOG_TYPE_AXIS_COLOR_MAP (gog_axis_color_map_get_type ())
+#define GOG_AXIS_COLOR_MAP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_AXIS_COLOR_MAP, GogAxisColorMap))
+#define GOG_IS_AXIS_COLOR_MAP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_AXIS_COLOR_MAP))
+
+GType gog_axis_color_map_get_type (void);
+
+GOColor gog_axis_color_map_get_color (GogAxisColorMap const *map, double x);
+unsigned gog_axis_color_map_get_max (GogAxisColorMap const *map);
+GogAxisColorMap *gog_axis_color_map_from_colors (char const *name, unsigned nb, GOColor const *colors);
+
+
+/* private */
+GogAxisColorMap const *_gog_axis_color_map_get_default (void);
+void _gog_axis_color_maps_init (void);
+void _gog_axis_color_maps_shutdown (void);
+
+G_END_DECLS
+
+#endif /* GOG_AXIS_COLOR_MAP_H */
diff --git a/goffice/graph/gog-axis.c b/goffice/graph/gog-axis.c
index 9eca247..f90d928 100644
--- a/goffice/graph/gog-axis.c
+++ b/goffice/graph/gog-axis.c
@@ -122,6 +122,8 @@ struct _GogAxis {
GogAxisTick *ticks;
unsigned tick_nbr;
double span_start, span_end; /* percent of used area */
+ GogAxisColorMap const *color_map; /* color map for color and pseudo-3d axis */
+ gboolean auto_color_map;
};
/*****************************************************************************/
@@ -2821,13 +2823,18 @@ gog_axis_populate_editor (GogObject *gobj,
static void
gog_axis_init_style (GogStyledObject *gso, GOStyle *style)
{
- if (gog_axis_get_atype (GOG_AXIS (gso)) != GOG_AXIS_PSEUDO_3D)
+ GogAxis *axis = GOG_AXIS (gso);
+ GogAxisType type = gog_axis_get_atype (axis);
+ GogTheme *theme = gog_object_get_theme (GOG_OBJECT (gso));
+ if (type != GOG_AXIS_PSEUDO_3D && type != GOG_AXIS_COLOR)
style->interesting_fields = GO_STYLE_LINE | GO_STYLE_FONT |
GO_STYLE_TEXT_LAYOUT;
- else
+ else {
style->interesting_fields = 0;
- gog_theme_fillin_style (gog_object_get_theme (GOG_OBJECT (gso)),
- style, GOG_OBJECT (gso), 0, GO_STYLE_LINE |
+ if (axis->auto_color_map)
+ axis->color_map = gog_theme_get_color_map (theme, type == GOG_AXIS_PSEUDO_3D);
+ }
+ gog_theme_fillin_style (theme, style, GOG_OBJECT (gso), 0, GO_STYLE_LINE |
GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT);
}
@@ -2942,6 +2949,7 @@ gog_axis_init (GogAxis *axis)
axis->tick_nbr = 0;
axis->span_start = 0.;
axis->span_end = 1.;
+ axis->auto_color_map = TRUE;
}
static void
@@ -3329,6 +3337,21 @@ gog_axis_get_circular_rotation (GogAxis *axis)
return axis->circular_rotation;
}
+/**
+ * gog_axis_get_color_map:
+ * @axis: a #GogAxis
+ *
+ * Returns: (transfer none): the color map used by the axis if any.
+ **/
+GogAxisColorMap const *
+gog_axis_get_color_map (GogAxis *axis)
+{
+ g_return_val_if_fail (GOG_IS_AXIS (axis), NULL);
+
+ return axis->color_map;
+
+}
+
/****************************************************************************/
typedef GogAxisBaseView GogAxisView;
diff --git a/goffice/graph/gog-axis.h b/goffice/graph/gog-axis.h
index 35526a3..4aaa99a 100644
--- a/goffice/graph/gog-axis.h
+++ b/goffice/graph/gog-axis.h
@@ -109,6 +109,7 @@ void gog_axis_set_polar_unit (GogAxis *axis, GogAxisPolarUnit unit);
GogAxisPolarUnit gog_axis_get_polar_unit (GogAxis *axis);
double gog_axis_get_polar_perimeter (GogAxis *axis);
double gog_axis_get_circular_rotation (GogAxis *axis);
+GogAxisColorMap const *gog_axis_get_color_map (GogAxis *axis);
G_END_DECLS
diff --git a/goffice/graph/gog-color-scale.c b/goffice/graph/gog-color-scale.c
new file mode 100644
index 0000000..a4dfd03
--- /dev/null
+++ b/goffice/graph/gog-color-scale.c
@@ -0,0 +1,182 @@
+/*
+ * gog-color-scale.h
+ *
+ * Copyright (C) 2012 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include <goffice/goffice.h>
+
+#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+
+#ifdef GOFFICE_WITH_GTK
+#include <gtk/gtk.h>
+#endif
+
+struct _GogColorScale {
+ GogStyledObject base;
+ GogAxis *color_axis; /* the color or pseudo-3d axis */
+ GogAxis *axis; /* the axis used to display the scale */
+ gboolean horizontal;
+ double width; /* will actually be height if horizontal */
+};
+typedef GogStyledObjectClass GogColorScaleClass;
+
+static GObjectClass *parent_klass;
+static GType gog_color_scale_view_get_type (void);
+
+static void
+gog_color_scale_init_style (GogStyledObject *gso, GOStyle *style)
+{
+ style->interesting_fields = GO_STYLE_LINE | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT;
+ gog_theme_fillin_style (gog_object_get_theme (GOG_OBJECT (gso)),
+ style, GOG_OBJECT (gso), 0, GO_STYLE_LINE |
+ GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT);
+}
+
+enum {
+ COLOR_SCALE_PROP_0,
+ COLOR_SCALE_PROP_HORIZONTAL,
+ COLOR_SCALE_PROP_WIDTH
+};
+
+static void
+gog_color_scale_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogColorScale *scale = GOG_COLOR_SCALE (obj);
+
+ switch (param_id) {
+ case COLOR_SCALE_PROP_HORIZONTAL:
+ scale->horizontal = g_value_get_boolean (value);
+ g_object_set (G_OBJECT (scale->axis), "type",
+ scale->horizontal? GOG_AXIS_X: GOG_AXIS_Y, NULL);
+ break;
+ case COLOR_SCALE_PROP_WIDTH:
+ scale->width = g_value_get_double (value);
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+ gog_object_emit_changed (GOG_OBJECT (obj), TRUE);
+}
+
+static void
+gog_color_scale_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogColorScale *scale = GOG_COLOR_SCALE (obj);
+
+ switch (param_id) {
+ case COLOR_SCALE_PROP_HORIZONTAL:
+ g_value_set_boolean (value, scale->horizontal);
+ break;
+ case COLOR_SCALE_PROP_WIDTH:
+ g_value_set_double (value, scale->width);
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+gog_color_scale_finalize (GObject *obj)
+{
+ GogColorScale *scale = GOG_COLOR_SCALE (obj);
+
+ g_object_unref (G_OBJECT (scale->axis));
+
+ parent_klass->finalize (obj);
+}
+
+static void
+gog_color_scale_class_init (GObjectClass *gobject_klass)
+{
+ GogObjectClass *gog_klass = (GogObjectClass *) gobject_klass;
+ GogStyledObjectClass *style_klass = (GogStyledObjectClass *) gog_klass;
+
+ parent_klass = g_type_class_peek_parent (gobject_klass);
+ /* GObjectClass */
+ gobject_klass->finalize = gog_color_scale_finalize;
+ gobject_klass->get_property = gog_color_scale_get_property;
+ gobject_klass->set_property = gog_color_scale_set_property;
+ g_object_class_install_property (gobject_klass, COLOR_SCALE_PROP_HORIZONTAL,
+ g_param_spec_boolean ("horizontal", _("Horizontal"),
+ _("Whether to display the scale horizontally"),
+ FALSE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, COLOR_SCALE_PROP_WIDTH,
+ g_param_spec_double ("width", _("Width"),
+ _("Color scale thickness."),
+ 0., 255., 10.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+
+ gog_klass->view_type = gog_color_scale_view_get_type ();
+
+ style_klass->init_style = gog_color_scale_init_style;
+}
+
+static void
+gog_color_scale_init (GogColorScale *scale)
+{
+ scale->width = 10;
+ scale->axis = (GogAxis *) g_object_new (GOG_TYPE_AXIS,
+ "type", GOG_AXIS_Y,
+ NULL);
+}
+
+GSF_CLASS (GogColorScale, gog_color_scale,
+ gog_color_scale_class_init, gog_color_scale_init,
+ GOG_TYPE_STYLED_OBJECT)
+
+/************************************************************************/
+
+typedef GogView GogColorScaleView;
+typedef GogViewClass GogColorScaleViewClass;
+
+#define GOG_TYPE_COLOR_SCALE_VIEW (gog_color_scale_view_get_type ())
+#define GOG_COLOR_SCALE_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_COLOR_SCALE_VIEW, GogColorScaleView))
+#define GOG_IS_COLOR_SCALE_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_COLOR_SCALE_VIEW))
+
+static void
+gog_color_scale_view_size_request (GogView *v,
+ GogViewRequisition const *available,
+ GogViewRequisition *req)
+{
+}
+
+static void
+gog_color_scale_view_render (GogView *view, GogViewAllocation const *bbox)
+{
+}
+
+static void
+gog_color_scale_view_class_init (GogColorScaleViewClass *gview_klass)
+{
+ GogViewClass *view_klass = (GogViewClass *) gview_klass;
+
+ view_klass->size_request = gog_color_scale_view_size_request;
+ view_klass->render = gog_color_scale_view_render;
+}
+
+static GSF_CLASS (GogColorScaleView, gog_color_scale_view,
+ gog_color_scale_view_class_init, NULL,
+ GOG_TYPE_VIEW)
diff --git a/goffice/graph/gog-color-scale.h b/goffice/graph/gog-color-scale.h
new file mode 100644
index 0000000..7076f86
--- /dev/null
+++ b/goffice/graph/gog-color-scale.h
@@ -0,0 +1,37 @@
+/*
+ * gog-color-scale.h
+ *
+ * Copyright (C) 2012 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GOG_COLOR_SCALE_H
+#define GOG_COLOR_SCALE_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+#define GOG_TYPE_COLOR_SCALE (gog_color_scale_get_type ())
+#define GOG_COLOR_SCALE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_COLOR_SCALE, GogColorScale))
+#define GOG_IS_COLOR_SCALE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_COLOR_SCALE))
+
+GType gog_color_scale_get_type (void);
+
+G_END_DECLS
+
+#endif /* GOG_COLOR_SCALE_H */
diff --git a/goffice/graph/gog-theme.c b/goffice/graph/gog-theme.c
index c7f0816..9b22607 100644
--- a/goffice/graph/gog-theme.c
+++ b/goffice/graph/gog-theme.c
@@ -23,11 +23,6 @@
#include <goffice/goffice-config.h>
#include <goffice/goffice-priv.h>
#include <goffice/graph/gog-theme.h>
-#include <goffice/graph/gog-object.h>
-#include <goffice/utils/go-color.h>
-#include <goffice/utils/go-gradient.h>
-#include <goffice/utils/go-units.h>
-#include <goffice/utils/go-marker.h>
#include <gsf/gsf-input-gio.h>
#include <gsf/gsf-impl-utils.h>
@@ -185,6 +180,10 @@ struct _GogTheme {
GHashTable *class_aliases;
GOStyle *default_style;
GPtrArray *palette;
+ GogAxisColorMap *cm, *dcm; /* cm: color map for color axis, dcm stands for discrete color map */
+ gboolean built_color_map; /* TRUE if color map is built from the palette */
+ gboolean writeable; /* TRUE if theme can be edited */
+ char *path; /* file path if any */
};
typedef GObjectClass GogThemeClass;
@@ -522,28 +521,28 @@ map_marker (GOStyleMark *mark, unsigned shape, unsigned palette_index,
? palette [palette_index] : 0);
}
+static GOColor const default_palette [] = {
+ 0x9c9cffff, 0x9c3163ff, 0xffffceff, 0xceffffff, 0x630063ff,
+ 0xff8080ff, 0x0063ceff, 0xceceffff, 0x000080ff, 0xff00ffff,
+ 0xffff00ff, 0x00ffffff, 0x800080ff, 0x800000ff, 0x008080ff,
+ 0x0000ffff, 0x00ceffff, 0xceffffff, 0xceffceff, 0xffff9cff,
+ 0x9cceffff, 0xff9cceff, 0xce9cffff, 0xffce9cff, 0x3163ffff,
+ 0x31ceceff, 0x9cce00ff, 0xffce00ff, 0xff9c00ff, 0xff6300ff,
+ 0x63639cff, 0x949494ff, 0x003163ff, 0x319c63ff, 0x003100ff,
+ 0x313100ff, 0x9c3100ff, 0x9c3163ff, 0x31319cff, 0x313131ff,
+ 0xffffffff, 0xff0000ff, 0x00ff00ff, 0x0000ffff, 0xffff00ff,
+ 0xff00ffff, 0x00ffffff, 0x800000ff, 0x008000ff, 0x000080ff,
+ 0x808000ff, 0x800080ff, 0x008080ff, 0xc6c6c6ff, 0x808080ff
+};
+
static void
map_area_series_solid_default (GOStyle *style, unsigned ind, G_GNUC_UNUSED GogTheme const *theme)
{
- static GOColor const palette [] = {
- 0x9c9cffff, 0x9c3163ff, 0xffffceff, 0xceffffff, 0x630063ff,
- 0xff8080ff, 0x0063ceff, 0xceceffff, 0x000080ff, 0xff00ffff,
- 0xffff00ff, 0x00ffffff, 0x800080ff, 0x800000ff, 0x008080ff,
- 0x0000ffff, 0x00ceffff, 0xceffffff, 0xceffceff, 0xffff9cff,
- 0x9cceffff, 0xff9cceff, 0xce9cffff, 0xffce9cff, 0x3163ffff,
- 0x31ceceff, 0x9cce00ff, 0xffce00ff, 0xff9c00ff, 0xff6300ff,
- 0x63639cff, 0x949494ff, 0x003163ff, 0x319c63ff, 0x003100ff,
- 0x313100ff, 0x9c3100ff, 0x9c3163ff, 0x31319cff, 0x313131ff,
- 0xffffffff, 0xff0000ff, 0x00ff00ff, 0x0000ffff, 0xffff00ff,
- 0xff00ffff, 0x00ffffff, 0x800000ff, 0x008000ff, 0x000080ff,
- 0x808000ff, 0x800080ff, 0x008080ff, 0xc6c6c6ff, 0x808080ff
- };
-
unsigned palette_index = ind;
- if (palette_index >= G_N_ELEMENTS (palette))
- palette_index %= G_N_ELEMENTS (palette);
+ if (palette_index >= G_N_ELEMENTS (default_palette))
+ palette_index %= G_N_ELEMENTS (default_palette);
if (style->fill.auto_back) {
- style->fill.pattern.back = palette [palette_index];
+ style->fill.pattern.back = default_palette [palette_index];
/* force the brightness to reinterpolate */
if (style->fill.type == GO_STYLE_FILL_GRADIENT &&
@@ -553,33 +552,33 @@ map_area_series_solid_default (GOStyle *style, unsigned ind, G_GNUC_UNUSED GogTh
}
palette_index += 8;
- if (palette_index >= G_N_ELEMENTS (palette))
- palette_index -= G_N_ELEMENTS (palette);
+ if (palette_index >= G_N_ELEMENTS (default_palette))
+ palette_index -= G_N_ELEMENTS (default_palette);
if (style->line.auto_color && !(style->disable_theming & GO_STYLE_LINE))
- style->line.color = palette [palette_index];
+ style->line.color = default_palette [palette_index];
if (!(style->disable_theming & GO_STYLE_MARKER))
- map_marker (&style->marker, ind, palette_index, palette);
+ map_marker (&style->marker, ind, palette_index, default_palette);
}
+static GOColor const guppi_palette[] = {
+ 0xff3000ff, 0x80ff00ff, 0x00ffcfff, 0x2000ffff,
+ 0xff008fff, 0xffbf00ff, 0x00ff10ff, 0x009fffff,
+ 0xaf00ffff, 0xff0000ff, 0xafff00ff, 0x00ff9fff,
+ 0x0010ffff, 0xff00bfff, 0xff8f00ff, 0x20ff00ff,
+ 0x00cfffff, 0x8000ffff, 0xff0030ff, 0xdfff00ff,
+ 0x00ff70ff, 0x0040ffff, 0xff00efff, 0xff6000ff,
+ 0x50ff00ff, 0x00ffffff, 0x5000ffff, 0xff0060ff,
+ 0xffef00ff, 0x00ff40ff, 0x0070ffff, 0xdf00ffff
+};
+
static void
map_area_series_solid_guppi (GOStyle *style, unsigned ind, G_GNUC_UNUSED GogTheme const *theme)
{
- static GOColor const palette[] = {
- 0xff3000ff, 0x80ff00ff, 0x00ffcfff, 0x2000ffff,
- 0xff008fff, 0xffbf00ff, 0x00ff10ff, 0x009fffff,
- 0xaf00ffff, 0xff0000ff, 0xafff00ff, 0x00ff9fff,
- 0x0010ffff, 0xff00bfff, 0xff8f00ff, 0x20ff00ff,
- 0x00cfffff, 0x8000ffff, 0xff0030ff, 0xdfff00ff,
- 0x00ff70ff, 0x0040ffff, 0xff00efff, 0xff6000ff,
- 0x50ff00ff, 0x00ffffff, 0x5000ffff, 0xff0060ff,
- 0xffef00ff, 0x00ff40ff, 0x0070ffff, 0xdf00ffff
- };
-
unsigned palette_index = ind;
- if (palette_index >= G_N_ELEMENTS (palette))
- palette_index %= G_N_ELEMENTS (palette);
+ if (palette_index >= G_N_ELEMENTS (guppi_palette))
+ palette_index %= G_N_ELEMENTS (guppi_palette);
if (style->fill.auto_back) {
- style->fill.pattern.back = palette [palette_index];
+ style->fill.pattern.back = guppi_palette [palette_index];
if (style->fill.type == GO_STYLE_FILL_GRADIENT &&
style->fill.gradient.brightness >= 0)
/* force the brightness to reinterpolate */
@@ -587,9 +586,9 @@ map_area_series_solid_guppi (GOStyle *style, unsigned ind, G_GNUC_UNUSED GogThem
style->fill.gradient.brightness);
}
if (style->line.auto_color && !(style->disable_theming & GO_STYLE_LINE))
- style->line.color = palette [palette_index];
+ style->line.color = guppi_palette [palette_index];
if (!(style->disable_theming & GO_STYLE_MARKER))
- map_marker (&style->marker, ind, palette_index, palette);
+ map_marker (&style->marker, ind, palette_index, guppi_palette);
}
static void
@@ -843,6 +842,10 @@ static void build_predefined_themes (void)
gog_theme_add_element (theme, style,
NULL, "GogEquation", NULL);
#endif
+ /* builds the default discrete color map */
+ theme->dcm = gog_axis_color_map_from_colors ("Default discrete",
+ G_N_ELEMENTS (default_palette),
+ default_palette);
/* Guppi */
theme = gog_theme_new (N_("Guppi"));
@@ -988,6 +991,10 @@ static void build_predefined_themes (void)
gog_theme_add_element (theme, style,
NULL, "GogEquation", NULL);
#endif
+
+ theme->dcm = gog_axis_color_map_from_colors ("Default discrete",
+ G_N_ELEMENTS (guppi_palette),
+ guppi_palette);
}
struct theme_load_state {
@@ -1113,6 +1120,14 @@ theme_load_from_uri (char const *uri)
if (!gsf_xml_in_doc_parse (xml, input, &state))
g_warning ("[GogTheme]: Could not parse %s", uri);
if (state.theme != NULL) {
+ if (state.theme->dcm == NULL) {
+ GOColor *colors = g_new (GOColor, state.theme->palette->len);
+ unsigned i;
+ for (i = 0; i < state.theme->palette->len; i++)
+ colors[i] = GO_STYLE (g_ptr_array_index (state.theme->palette, i))->fill.pattern.back;
+ state.theme->dcm = gog_axis_color_map_from_colors ("Default discrete", state.theme->palette->len, colors);
+ g_free (colors);
+ }
state.theme->local_name = state.local_name;
state.theme->description = state.desc;
gog_theme_registry_add (state.theme, FALSE);
@@ -1151,6 +1166,7 @@ _gog_themes_init (void)
{
char *path;
+ _gog_axis_color_maps_init ();
build_predefined_themes ();
/* Load themes from file */
@@ -1173,5 +1189,23 @@ _gog_themes_shutdown (void)
g_slist_free_full (g_slist_copy (themes), g_object_unref);
g_slist_free (themes);
+ _gog_axis_color_maps_shutdown ();
themes = NULL;
}
+
+/**
+ * gog_theme_get_color_map:
+ * @theme: #GogTheme
+ * @discrete:
+ *
+ * Returns: (transfer none): the requested color map.
+ **/
+GogAxisColorMap const *
+gog_theme_get_color_map (GogTheme const *theme, gboolean discrete)
+{
+ if (discrete)
+ return theme->dcm;
+ else
+ return (theme->cm)? theme->cm: _gog_axis_color_map_get_default ();
+ return NULL;
+}
diff --git a/goffice/graph/gog-theme.h b/goffice/graph/gog-theme.h
index 084cf26..8ae4a14 100644
--- a/goffice/graph/gog-theme.h
+++ b/goffice/graph/gog-theme.h
@@ -37,6 +37,7 @@ char const *gog_theme_get_description (GogTheme const *theme);
void gog_theme_fillin_style (GogTheme const *theme, GOStyle *style,
GogObject const *obj, int ind,
GOStyleFlag relevant_fields);
+GogAxisColorMap const *gog_theme_get_color_map (GogTheme const *theme, gboolean discrete);
GogTheme *gog_theme_registry_lookup (char const *name);
GSList *gog_theme_registry_get_theme_names (void);
diff --git a/plugins/plot_surface/gog-contour.c b/plugins/plot_surface/gog-contour.c
index 5ff2c84..c42c514 100644
--- a/plugins/plot_surface/gog-contour.c
+++ b/plugins/plot_surface/gog-contour.c
@@ -137,18 +137,19 @@ gog_contour_plot_foreach_elem (GogPlot *plot, gboolean only_visible,
{
unsigned i, j, nticks;
char *label;
- GOStyle *style = go_style_new ();
- GogTheme *theme = gog_object_get_theme (GOG_OBJECT (plot));
+ GOStyle *style;
GogAxis *axis = plot->axis[GOG_AXIS_PSEUDO_3D];
- GOColor *color;
+ GogAxisColorMap const *map = gog_axis_get_color_map (axis);
GogAxisTick *zticks;
double *limits;
double minimum, maximum, epsilon;
char const *separator = go_locale_get_decimal ()->str;
/* First get the series name and style */
- func (0, go_styled_object_get_style (plot->series->data),
- gog_object_get_name (plot->series->data), NULL, data);
+ style = go_style_dup (go_styled_object_get_style (plot->series->data));
+ if (gog_series_has_legend (GOG_SERIES (plot->series->data)))
+ func (0, style,
+ gog_object_get_name (plot->series->data), NULL, data);
gog_axis_get_bounds (axis, &minimum, &maximum);
@@ -169,32 +170,21 @@ gog_contour_plot_foreach_elem (GogPlot *plot, gboolean only_visible,
limits[j] = maximum;
else
j--;
- /* build the colors table */
- color = g_new0 (GOColor, (j > 0)? j: 1);
- if (j < 2)
- color[0] = GO_COLOR_WHITE;
- else for (i = 0; i < j; i++) {
- gog_theme_fillin_style (theme, style, GOG_OBJECT (plot->series->data), i, style->interesting_fields);
- color[i] = style->fill.pattern.back;
- }
- g_object_unref (style);
- style = go_style_new ();
- style->interesting_fields = GO_STYLE_FILL;
- style->disable_theming = GO_STYLE_ALL;
+ style->interesting_fields = GO_STYLE_FILL | GO_STYLE_OUTLINE;
style->fill.type = GO_STYLE_FILL_PATTERN;
style->fill.pattern.pattern = GO_PATTERN_SOLID;
if (gog_axis_is_inverted (axis)) {
for (i = 0; i < j; i++) {
- style->fill.pattern.back = color[i];
+ style->fill.pattern.back = (j < 2)? GO_COLOR_WHITE: gog_axis_color_map_get_color (map, i);
label = g_strdup_printf ("[%g%s %g%c", limits[j - i - 1], separator,
limits[j - i], (limits[i - j] - minimum > epsilon)? '[':']');
(func) (i, style, label, NULL, data);
g_free (label);
}
if (limits[i - j] - minimum > epsilon) {
- gog_theme_fillin_style (theme, style, GOG_OBJECT (plot->series->data), i, style->interesting_fields);
+ style->fill.pattern.back = (j < 2)? GO_COLOR_WHITE: gog_axis_color_map_get_color (map, i);
label = g_strdup_printf ("[%g%s %g]", minimum, separator,
limits[i - j]);
(func) (i + 1, style, label, NULL, data);
@@ -202,7 +192,7 @@ gog_contour_plot_foreach_elem (GogPlot *plot, gboolean only_visible,
}
} else {
if (epsilon < limits[0] - minimum) {
- style->fill.pattern.back = color[0];
+ style->fill.pattern.back = (j < 2)? GO_COLOR_WHITE: gog_axis_color_map_get_color (map, 0);
label = g_strdup_printf ("[%g%s %g]", minimum, separator,
limits[0]);
(func) (1, style, label, NULL, data);
@@ -212,7 +202,7 @@ gog_contour_plot_foreach_elem (GogPlot *plot, gboolean only_visible,
} else
i = 0;
for (; i < j; i++) {
- style->fill.pattern.back = color[i];
+ style->fill.pattern.back = (j < 2)? GO_COLOR_WHITE: gog_axis_color_map_get_color (map, i);
label = g_strdup_printf ("[%g%s %g%c", limits[i], separator,
limits[i + 1], (i == j - 1)? ']':'[');
(func) (i + 1, style, label, NULL, data);
@@ -221,7 +211,6 @@ gog_contour_plot_foreach_elem (GogPlot *plot, gboolean only_visible,
}
g_free (limits);
g_object_unref (style);
- g_free (color);
}
static void
@@ -268,6 +257,7 @@ gog_contour_view_render (GogView *view, GogViewAllocation const *bbox)
GogSeries const *series;
GOData *x_vec = NULL, *y_vec = NULL;
GogAxisMap *x_map, *y_map;
+ GogAxisColorMap const *color_map = gog_axis_get_color_map (gog_plot_get_axis (GOG_PLOT (view->model), GOG_AXIS_PSEUDO_3D));
double zval0, zval1, zval2 = 0., zval3, t;
double x[4], y[4], zval[4];
int z[4];
@@ -276,7 +266,6 @@ gog_contour_view_render (GogView *view, GogViewAllocation const *bbox)
unsigned i, imax, j, jmax;
GogRenderer *rend = view->renderer;
GOStyle *style;
- GogTheme *theme = gog_object_get_theme (GOG_OBJECT (plot));
double x0, x1, y0, y1;
GOPath *path, *lines;
GOColor *color;
@@ -342,18 +331,14 @@ gog_contour_view_render (GogView *view, GogViewAllocation const *bbox)
}
cw = (x1 > x0) == (y1 > y0);
- style = go_style_new ();
path = go_path_new ();
go_path_set_options (path, GO_PATH_OPTIONS_SHARP);
/* build the colors table */
color = g_new0 (GOColor, max);
if (max < 2)
color[0] = GO_COLOR_WHITE;
- else for (i = 0; i < (unsigned) max; i++) {
- gog_theme_fillin_style (theme, style, GOG_OBJECT (series), i, style->interesting_fields);
- color[i] = style->fill.pattern.back;
- }
- g_object_unref (style);
+ else for (i = 0; i < (unsigned) max; i++)
+ color[i] = gog_axis_color_map_get_color (color_map, i);
/* clip to avoid problems with logarithmic axes */
gog_renderer_push_clip_rectangle (rend, view->residual.x, view->residual.y,
diff --git a/plugins/plot_xy/gog-xy.c b/plugins/plot_xy/gog-xy.c
index 76ccdc0..110c36a 100644
--- a/plugins/plot_xy/gog-xy.c
+++ b/plugins/plot_xy/gog-xy.c
@@ -73,7 +73,6 @@ gog_2d_plot_update (GogObject *obj)
GogXYSeries const *series = NULL;
double x_min, x_max, y_min, y_max, tmp_min, tmp_max;
GSList *ptr;
- gboolean is_discrete = FALSE;
x_min = y_min = DBL_MAX;
x_max = y_max = -DBL_MAX;
@@ -98,7 +97,6 @@ gog_2d_plot_update (GogObject *obj)
tmp_min = 0;
tmp_max = go_data_get_vector_size (series->base.values[1].data);
- is_discrete = TRUE;
} else if (model->x.fmt == NULL)
model->x.fmt = go_data_preferred_fmt (series->base.values[0].data);
@@ -106,7 +104,6 @@ gog_2d_plot_update (GogObject *obj)
} else {
tmp_min = 0;
tmp_max = go_data_get_vector_size (series->base.values[1].data);
- is_discrete = TRUE;
}
if (x_min > tmp_min) x_min = tmp_min;
@@ -870,6 +867,7 @@ GSF_DYNAMIC_CLASS (GogXYColorPlot, gog_xy_color_plot,
typedef GogPlotView GogXYView;
typedef GogPlotViewClass GogXYViewClass;
+/*
static GOColor
get_map_color (double z, gboolean hide_outliers)
{
@@ -887,6 +885,7 @@ get_map_color (double z, gboolean hide_outliers)
return GO_COLOR_RED + ((int) ((3. - z / 2.) * 255) << 16);
return GO_COLOR_RED;
}
+*/
typedef struct {
double x, y;
@@ -1056,6 +1055,8 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
gboolean show_marks, show_lines, show_fill, show_negatives, in_3d, size_as_area = TRUE;
gboolean is_map = GOG_IS_XY_COLOR_PLOT (model), hide_outliers = TRUE;
GogObjectRole const *lbl_role = NULL;
+ GogAxisColorMap const *color_map = NULL;
+ double max = 0.;
MarkerData **markers;
unsigned *num_markers;
@@ -1081,8 +1082,10 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
y_map = gog_chart_map_get_axis_map (chart_map, 1);
if (is_map) {
- z_map = gog_axis_map_new (model->base.axis[GOG_AXIS_COLOR], 0, 6);
hide_outliers = GOG_XY_COLOR_PLOT (model)->hide_outliers;
+ color_map = gog_axis_get_color_map (model->base.axis[GOG_AXIS_COLOR]);
+ max = gog_axis_color_map_get_max (color_map);
+ z_map = gog_axis_map_new (model->base.axis[GOG_AXIS_COLOR], 0, max);
}
/* What we really want is to draw drop lines from point to
@@ -1157,15 +1160,12 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
next_series = ptr->next->data;
if (gog_series_is_valid (GOG_SERIES (next_series))) {
- GOStyle *next_style;
const double *next_x_vals, *next_y_vals;
unsigned int next_n_points;
next_n_points = gog_series_get_xy_data
(GOG_SERIES (next_series),
&next_x_vals, &next_y_vals);
- next_style = go_styled_object_get_style
- (GO_STYLED_OBJECT (next_series));
next_path = gog_chart_map_make_path
(chart_map, next_x_vals, next_y_vals,
@@ -1389,10 +1389,16 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
markers[j][k].x = x_canvas;
markers[j][k].y = y_canvas;
markers[j][k].index = i - 1;
- if (is_map)
- markers[j][k].color = (gog_axis_map_finite (z_map, z))?
- get_map_color (gog_axis_map_to_view (z_map, z), hide_outliers):
- 0;
+ if (is_map) {
+ if (gog_axis_map_finite (z_map, z)) {
+ double zc = gog_axis_map_to_view (z_map, z);
+ if (hide_outliers && (zc < 0 || zc > max))
+ markers[j][k].color = 0;
+ else
+ markers[j][k].color = gog_axis_color_map_get_color (color_map, CLAMP (zc, 0, max));
+ } else
+ markers[j][k].color = 0;
+ }
k++;
}
}
@@ -2072,7 +2078,6 @@ gog_xy_series_populate_editor (GogObject *obj,
GogDataAllocator *dalloc,
GOCmdContext *cc)
{
- GogXYSeries *series;
GtkWidget *w;
GtkBuilder *gui =
go_gtk_builder_load ("res:go:plot_xy/gog-xy-series-prefs.ui",
@@ -2087,7 +2092,6 @@ gog_xy_series_populate_editor (GogObject *obj,
g_signal_connect (G_OBJECT (w),
"toggled",
G_CALLBACK (invalid_toggled_cb), obj);
- series = GOG_XY_SERIES (obj);
w = go_gtk_builder_get_widget (gui, "gog_xy_series_prefs");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]