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