1 /*
2  * Copyright (c) 2014 Benjamin Otte <ottte@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 
20 #include "graphdata.h"
21 
22 enum {
23   PROP_0,
24   PROP_N_VALUES
25 };
26 
27 struct _GtkGraphDataPrivate
28 {
29   guint n_values;
30   guint offset;
31   double *values;
32 };
33 
34 
G_DEFINE_TYPE_WITH_PRIVATE(GtkGraphData,gtk_graph_data,G_TYPE_OBJECT)35 G_DEFINE_TYPE_WITH_PRIVATE (GtkGraphData, gtk_graph_data, G_TYPE_OBJECT)
36 
37 static void
38 gtk_graph_data_get_property (GObject    *object,
39                              guint       param_id,
40                              GValue     *value,
41                              GParamSpec *pspec)
42 {
43   GtkGraphData *graph = GTK_GRAPH_DATA (object);
44   GtkGraphDataPrivate *priv = graph->priv;
45 
46   switch (param_id)
47     {
48       case PROP_N_VALUES:
49         g_value_set_boolean (value, priv->n_values);
50         break;
51       default:
52         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
53     }
54 }
55 
56 static void
gtk_graph_data_finalize(GObject * object)57 gtk_graph_data_finalize (GObject *object)
58 {
59   GtkGraphData *graph = GTK_GRAPH_DATA (object);
60   GtkGraphDataPrivate *priv = graph->priv;
61 
62   g_free (priv->values);
63 
64   G_OBJECT_CLASS (gtk_graph_data_parent_class)->finalize (object);
65 }
66 
67 static void
gtk_graph_data_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)68 gtk_graph_data_set_property (GObject      *object,
69                              guint         param_id,
70                              const GValue *value,
71                              GParamSpec   *pspec)
72 {
73   GtkGraphData *graph = GTK_GRAPH_DATA (object);
74   GtkGraphDataPrivate *priv = graph->priv;
75 
76   switch (param_id)
77     {
78       case PROP_N_VALUES:
79         priv->n_values = g_value_get_uint (value);
80         priv->values = g_new0 (double, priv->n_values);
81         break;
82       default:
83         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
84     }
85 }
86 
87 static void
gtk_graph_data_class_init(GtkGraphDataClass * klass)88 gtk_graph_data_class_init (GtkGraphDataClass *klass)
89 {
90   GObjectClass *object_class = G_OBJECT_CLASS (klass);
91 
92   object_class->finalize = gtk_graph_data_finalize;
93   object_class->get_property = gtk_graph_data_get_property;
94   object_class->set_property = gtk_graph_data_set_property;
95 
96   g_object_class_install_property (object_class,
97                                    PROP_N_VALUES,
98                                    g_param_spec_uint ("n-values",
99                                                       "n values",
100                                                       "Number of values in the graph",
101                                                       1, G_MAXUINT, 1,
102                                                       G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
103 }
104 
105 static void
gtk_graph_data_init(GtkGraphData * graph)106 gtk_graph_data_init (GtkGraphData *graph)
107 {
108   graph->priv = gtk_graph_data_get_instance_private (graph);
109 }
110 
111 GtkGraphData *
gtk_graph_data_new(guint n_values)112 gtk_graph_data_new (guint n_values)
113 {
114   return g_object_new (GTK_TYPE_GRAPH_DATA,
115                        "n-values", n_values,
116                        NULL);
117 }
118 
119 guint
gtk_graph_data_get_n_values(GtkGraphData * data)120 gtk_graph_data_get_n_values (GtkGraphData *data)
121 {
122   return data->priv->n_values;
123 }
124 
125 double
gtk_graph_data_get_value(GtkGraphData * data,guint i)126 gtk_graph_data_get_value (GtkGraphData   *data,
127                           guint           i)
128 {
129   GtkGraphDataPrivate *priv = data->priv;
130 
131   return priv->values[(priv->offset + i) % priv->n_values];
132 }
133 
134 double
gtk_graph_data_get_minimum(GtkGraphData * data)135 gtk_graph_data_get_minimum (GtkGraphData *data)
136 {
137   GtkGraphDataPrivate *priv = data->priv;
138   double minimum = G_MAXDOUBLE;
139   guint i;
140 
141   for (i = 0; i < priv->n_values; i++)
142     {
143       minimum = MIN (minimum, priv->values[i]);
144     }
145 
146   return minimum;
147 }
148 
149 double
gtk_graph_data_get_maximum(GtkGraphData * data)150 gtk_graph_data_get_maximum (GtkGraphData *data)
151 {
152   GtkGraphDataPrivate *priv = data->priv;
153   double maximum = -G_MAXDOUBLE;
154   guint i;
155 
156   for (i = 0; i < priv->n_values; i++)
157     {
158       maximum = MAX (maximum, priv->values[i]);
159     }
160 
161   return maximum;
162 }
163 
164 void
gtk_graph_data_prepend_value(GtkGraphData * data,double value)165 gtk_graph_data_prepend_value (GtkGraphData *data,
166                               double        value)
167 {
168   GtkGraphDataPrivate *priv = data->priv;
169 
170   priv->offset = (priv->offset + priv->n_values - 1) % priv->n_values;
171   priv->values[priv->offset] = value;
172 }
173 
174