"Fossies" - the Fresh Open Source Software Archive 
Member "gtkdatabox-1.0.0/gtk/gtkdatabox_xyc_graph.c" (31 Mar 2021, 22495 Bytes) of package /linux/privat/gtkdatabox-1.0.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "gtkdatabox_xyc_graph.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.9.3.1_vs_1.0.0.
1 /* $Id: gtkdatabox_xyc_graph.c 4 2008-06-22 09:19:11Z rbock $ */
2 /* GtkDatabox - An extension to the gtk+ library
3 * Copyright (C) 1998 - 2008 Dr. Roland Bock
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <gtkdatabox_xyc_graph.h>
21
22 static gint gtk_databox_xyc_graph_real_calculate_extrema (GtkDataboxGraph *
23 xyc_graph,
24 gfloat * min_x,
25 gfloat * max_x,
26 gfloat * min_y,
27 gfloat * max_y);
28
29 /* IDs of properties */
30 enum
31 {
32 PROP_X = 1,
33 PROP_Y,
34 PROP_LEN,
35 PROP_MAXLEN,
36 PROP_XSTART,
37 PROP_YSTART,
38 PROP_XSTRIDE,
39 PROP_YSTRIDE,
40 PROP_XTYPE,
41 PROP_YTYPE
42 };
43
44 /**
45 * GtkDataboxXYCGraphPrivate
46 *
47 * A private data structure used by the #GtkDataboxXYCGraph. It shields all internal things
48 * from developers who are just using the object.
49 *
50 **/
51 typedef struct _GtkDataboxXYCGraphPrivate GtkDataboxXYCGraphPrivate;
52
53 struct _GtkDataboxXYCGraphPrivate
54 {
55 gfloat *X;
56 gfloat *Y;
57 guint len;
58 guint maxlen;
59 guint xstart;
60 guint ystart;
61 guint xstride;
62 guint ystride;
63 GType xtype;
64 GType ytype;
65 };
66
67 G_DEFINE_TYPE_WITH_PRIVATE(GtkDataboxXYCGraph, gtk_databox_xyc_graph,
68 GTK_DATABOX_TYPE_GRAPH)
69
70 //static gpointer parent_class = NULL;
71
72 void
73 gtk_databox_xyc_graph_set_X_Y_length(GtkDataboxXYCGraph * xyc_graph, gfloat * X, gfloat * Y, guint len)
74 {
75 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
76 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
77 priv->X = X;
78 priv->Y = Y;
79 priv->len = len;
80 }
81
82 static void
83 gtk_databox_xyc_graph_set_X (GtkDataboxXYCGraph * xyc_graph, gfloat * X)
84 {
85 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
86 g_return_if_fail (X);
87 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
88 priv->X = X;
89
90 g_object_notify (G_OBJECT (xyc_graph), "X-Values");
91 }
92
93 static void
94 gtk_databox_xyc_graph_set_Y (GtkDataboxXYCGraph * xyc_graph, gfloat * Y)
95 {
96 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
97 g_return_if_fail (Y);
98 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
99 priv->Y = Y;
100
101 g_object_notify (G_OBJECT (xyc_graph), "Y-Values");
102 }
103
104 static void
105 gtk_databox_xyc_graph_set_length (GtkDataboxXYCGraph * xyc_graph, guint len)
106 {
107 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
108 g_return_if_fail (len > 0);
109 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
110 priv->len = len;
111
112 g_object_notify (G_OBJECT (xyc_graph), "length");
113 }
114
115 static void
116 gtk_databox_xyc_graph_set_maxlen (GtkDataboxXYCGraph * xyc_graph, guint maxlen)
117 {
118 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
119 g_return_if_fail (maxlen > 0);
120 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
121 priv->maxlen = maxlen;
122
123 g_object_notify (G_OBJECT (xyc_graph), "maxlen");
124 }
125
126 static void
127 gtk_databox_xyc_graph_set_xstart (GtkDataboxXYCGraph * xyc_graph, guint xstart)
128 {
129 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
130 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
131 priv->xstart = xstart;
132
133 g_object_notify (G_OBJECT (xyc_graph), "X-Values");
134 }
135
136 static void
137 gtk_databox_xyc_graph_set_ystart (GtkDataboxXYCGraph * xyc_graph, guint ystart)
138 {
139 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
140 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
141 priv->ystart = ystart;
142
143 g_object_notify (G_OBJECT (xyc_graph), "Y-Values");
144 }
145
146 static void
147 gtk_databox_xyc_graph_set_xstride (GtkDataboxXYCGraph * xyc_graph, guint xstride)
148 {
149 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
150 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
151 priv->xstride = xstride;
152
153 g_object_notify (G_OBJECT (xyc_graph), "X-Values");
154 }
155
156 static void
157 gtk_databox_xyc_graph_set_ystride (GtkDataboxXYCGraph * xyc_graph, guint ystride)
158 {
159 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
160 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
161 priv->ystride = ystride;
162
163 g_object_notify (G_OBJECT (xyc_graph), "Y-Values");
164 }
165
166 static void
167 gtk_databox_xyc_graph_set_xtype (GtkDataboxXYCGraph * xyc_graph, GType xtype)
168 {
169 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
170 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
171 priv->xtype = xtype;
172
173 g_object_notify (G_OBJECT (xyc_graph), "X-Values");
174 }
175
176 static void
177 gtk_databox_xyc_graph_set_ytype (GtkDataboxXYCGraph * xyc_graph, GType ytype)
178 {
179 g_return_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph));
180
181 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
182 priv->ytype = ytype;
183
184 g_object_notify (G_OBJECT (xyc_graph), "Y-Values");
185 }
186
187 static void
188 gtk_databox_xyc_graph_set_property (GObject * object,
189 guint property_id,
190 const GValue * value, GParamSpec * pspec)
191 {
192 GtkDataboxXYCGraph *xyc_graph = GTK_DATABOX_XYC_GRAPH (object);
193
194 switch (property_id)
195 {
196 case PROP_X:
197 gtk_databox_xyc_graph_set_X (xyc_graph, (gfloat *) g_value_get_pointer (value));
198 break;
199 case PROP_Y:
200 gtk_databox_xyc_graph_set_Y (xyc_graph, (gfloat *) g_value_get_pointer (value));
201 break;
202 case PROP_LEN:
203 gtk_databox_xyc_graph_set_length (xyc_graph, g_value_get_int (value));
204 break;
205 case PROP_MAXLEN:
206 gtk_databox_xyc_graph_set_maxlen (xyc_graph, g_value_get_int (value));
207 break;
208 case PROP_XSTART:
209 gtk_databox_xyc_graph_set_xstart (xyc_graph, g_value_get_int (value));
210 break;
211 case PROP_YSTART:
212 gtk_databox_xyc_graph_set_ystart (xyc_graph, g_value_get_int (value));
213 break;
214 case PROP_XSTRIDE:
215 gtk_databox_xyc_graph_set_xstride (xyc_graph, g_value_get_int (value));
216 break;
217 case PROP_YSTRIDE:
218 gtk_databox_xyc_graph_set_ystride (xyc_graph, g_value_get_int (value));
219 break;
220 case PROP_XTYPE:
221 gtk_databox_xyc_graph_set_xtype (xyc_graph, g_value_get_gtype (value));
222 break;
223 case PROP_YTYPE:
224 gtk_databox_xyc_graph_set_ytype (xyc_graph, g_value_get_gtype (value));
225 break;
226 default:
227 /* We don't have any other property... */
228 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
229 break;
230 }
231 }
232
233 /**
234 * gtk_databox_xyc_graph_get_X:
235 * @xyc_graph: A #GtkDataboxXYCGraph object
236 *
237 * Gets the X values of the @xzc_graph.
238 *
239 * Return value: Pointer to X values
240 */
241 gfloat *
242 gtk_databox_xyc_graph_get_X (GtkDataboxXYCGraph * xyc_graph)
243 {
244 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), NULL);
245 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
246 return priv->X;
247 }
248
249 /**
250 * gtk_databox_xyc_graph_get_Y:
251 * @xyc_graph: A #GtkDataboxXYCGraph object
252 *
253 * Gets the Y values of the @xzc_graph.
254 *
255 * Return value: Pointer to Y values
256 */
257 gfloat *
258 gtk_databox_xyc_graph_get_Y (GtkDataboxXYCGraph * xyc_graph)
259 {
260 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), NULL);
261 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
262 return priv->Y;
263 }
264
265 /**
266 * gtk_databox_xyc_graph_get_length:
267 * @xyc_graph: A #GtkDataboxXYCGraph object
268 *
269 * Gets the the length of the X and Y values arrays.
270 *
271 * Return value: Length of X/Y arrays.
272 */
273 guint
274 gtk_databox_xyc_graph_get_length (GtkDataboxXYCGraph * xyc_graph)
275 {
276 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
277 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
278 return priv->len;
279 }
280
281 /**
282 * gtk_databox_xyc_graph_get_maxlen:
283 * @xyc_graph: A #GtkDataboxXYCGraph object
284 *
285 * Gets the the maxlen of the X and Y values arrays.
286 *
287 * Return value: Size of X/Y arrays.
288 */
289 guint
290 gtk_databox_xyc_graph_get_maxlen (GtkDataboxXYCGraph * xyc_graph)
291 {
292 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
293 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
294 return priv->maxlen;
295 }
296
297 /**
298 * gtk_databox_xyc_graph_get_xstart:
299 * @xyc_graph: A #GtkDataboxXYCGraph object
300 *
301 * Gets the the start offset of the X values array. This is the element in the array pointed to by X that will be the first element plotted.
302 * If X is a pointer to a gfloat array, and xstart is 5, then x[5] will be the first data element. If Xstride is 1, then x[6] will be the
303 * second element. x[5 + len - 1] will be last element.
304 * Usually, xstart will be 0. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then X can point
305 * to the start of the matrix, xstart can be the column number, and xstride the number of columns.
306 *
307 * Return value: The xstart value.
308 */
309 guint
310 gtk_databox_xyc_graph_get_xstart (GtkDataboxXYCGraph * xyc_graph)
311 {
312 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
313 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
314 return priv->xstart;
315 }
316
317 /**
318 * gtk_databox_xyc_graph_get_ystart:
319 * @xyc_graph: A #GtkDataboxXYCGraph object
320 *
321 * Gets the the start offset of the Y values array. This is the element in the array pointed to by Y that will be the first element plotted.
322 * If Y is a pointer to a gfloat array, and ystart is 5, then y[5] will be the first data element. If Ystride is 1, then y[6] will be the
323 * second element. y[5 + len - 1] will be last element.
324 * Usually, ystart will be 0. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then Y can point
325 * to the start of the matrix, ystart can be the column number, and ystride the number of columns.
326 *
327 * Return value: The ystart value.
328 */
329 guint
330 gtk_databox_xyc_graph_get_ystart (GtkDataboxXYCGraph * xyc_graph)
331 {
332 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
333 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
334 return priv->ystart;
335 }
336
337 /**
338 * gtk_databox_xyc_graph_get_xstride:
339 * @xyc_graph: A #GtkDataboxXYCGraph object
340 *
341 * Gets the the stride offset of the X values array. This is the element in the array pointed to by X that will be the first element plotted.
342 * If X is a pointer to a gfloat array, and xstart is 5, then x[5] will be the first data element. If Xstride is 1, then x[6] will be the
343 * second element. x[5 + len - 1] will be last element.
344 * Usually, xstride will be 1. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then X can point
345 * to the start of the matrix, xstart can be the column number, and xstride the number of columns.
346 *
347 * Return value: The xstride value.
348 */
349 guint
350 gtk_databox_xyc_graph_get_xstride (GtkDataboxXYCGraph * xyc_graph)
351 {
352 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
353 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
354 return priv->xstride;
355 }
356
357 /**
358 * gtk_databox_xyc_graph_get_ystride:
359 * @xyc_graph: A #GtkDataboxXYCGraph object
360 *
361 * Gets the the stride offset of the Y values array. This is the element in the array pointed to by Y that will be the first element plotted.
362 * If Y is a pointer to a gfloat array, and ystart is 5, then y[5] will be the first data element. If Ystride is 1, then y[6] will be the
363 * second element. y[5 + len - 1] will be last element.
364 * Usually, ystride will be 1. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then Y can point
365 * to the start of the matrix, ystart can be the column number, and ystride the number of columns.
366 *
367 * Return value: The ystride value.
368 */
369 guint
370 gtk_databox_xyc_graph_get_ystride (GtkDataboxXYCGraph * xyc_graph)
371 {
372 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
373 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
374 return priv->ystride;
375 }
376
377 /**
378 * gtk_databox_xyc_graph_get_xtype:
379 * @xyc_graph: A #GtkDataboxXYCGraph object
380 *
381 * Gets the the GType of the X array elements. This may be G_TYPE_FLOAT, G_TYPE_DOUBLE, or similar.
382 *
383 * Return value: A GType, usually this is G_TYPE_FLOAT.
384 */
385 GType
386 gtk_databox_xyc_graph_get_xtype (GtkDataboxXYCGraph * xyc_graph)
387 {
388 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
389 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
390 return priv->xtype;
391 }
392
393 /**
394 * gtk_databox_xyc_graph_get_ytype:
395 * @xyc_graph: A #GtkDataboxXYCGraph object
396 *
397 * Gets the the GType of the Y array elements. This may be G_TYPE_FLOAT, G_TYPE_DOUBLE, or similar.
398 *
399 * Return value: A GType, usually this is G_TYPE_FLOAT.
400 */
401 GType
402 gtk_databox_xyc_graph_get_ytype (GtkDataboxXYCGraph * xyc_graph)
403 {
404 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (xyc_graph), 0);
405 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
406 return priv->ytype;
407 }
408
409 static void
410 gtk_databox_xyc_graph_get_property (GObject * object,
411 guint property_id,
412 GValue * value, GParamSpec * pspec)
413 {
414 GtkDataboxXYCGraph *xyc_graph = GTK_DATABOX_XYC_GRAPH (object);
415
416 switch (property_id)
417 {
418 case PROP_X:
419 g_value_set_pointer (value, gtk_databox_xyc_graph_get_X (xyc_graph));
420 break;
421 case PROP_Y:
422 g_value_set_pointer (value, gtk_databox_xyc_graph_get_Y (xyc_graph));
423 break;
424 case PROP_LEN:
425 g_value_set_int (value, gtk_databox_xyc_graph_get_length (xyc_graph));
426 break;
427 case PROP_MAXLEN:
428 g_value_set_int (value, gtk_databox_xyc_graph_get_maxlen (xyc_graph));
429 break;
430 case PROP_XSTART:
431 g_value_set_int (value, gtk_databox_xyc_graph_get_xstart (xyc_graph));
432 break;
433 case PROP_YSTART:
434 g_value_set_int (value, gtk_databox_xyc_graph_get_ystart (xyc_graph));
435 break;
436 case PROP_XSTRIDE:
437 g_value_set_int (value, gtk_databox_xyc_graph_get_xstride (xyc_graph));
438 break;
439 case PROP_YSTRIDE:
440 g_value_set_int (value, gtk_databox_xyc_graph_get_ystride (xyc_graph));
441 break;
442 case PROP_XTYPE:
443 g_value_set_gtype (value, gtk_databox_xyc_graph_get_xtype (xyc_graph));
444 break;
445 case PROP_YTYPE:
446 g_value_set_gtype (value, gtk_databox_xyc_graph_get_ytype (xyc_graph));
447 break;
448 default:
449 /* We don't have any other property... */
450 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
451 break;
452 }
453 }
454
455 static void
456 gtk_databox_xyc_graph_class_init (GtkDataboxXYCGraphClass *klass)
457 {
458 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
459 GtkDataboxGraphClass *graph_class = GTK_DATABOX_GRAPH_CLASS (klass);
460 GParamSpec *xyc_graph_param_spec;
461
462 gobject_class->set_property = gtk_databox_xyc_graph_set_property;
463 gobject_class->get_property = gtk_databox_xyc_graph_get_property;
464
465 xyc_graph_param_spec = g_param_spec_pointer ("X-Values",
466 "X coordinates",
467 "X values of data",
468 G_PARAM_CONSTRUCT_ONLY |
469 G_PARAM_READWRITE);
470
471 g_object_class_install_property (gobject_class,
472 PROP_X, xyc_graph_param_spec);
473
474 xyc_graph_param_spec = g_param_spec_pointer ("Y-Values",
475 "Y coordinates",
476 "Y values of data",
477 G_PARAM_CONSTRUCT_ONLY |
478 G_PARAM_READWRITE);
479
480 g_object_class_install_property (gobject_class,
481 PROP_Y, xyc_graph_param_spec);
482
483 xyc_graph_param_spec = g_param_spec_int ("length", "length of X and Y", "number of data points", G_MININT, G_MAXINT, 0, /* default value */
484 G_PARAM_CONSTRUCT_ONLY |
485 G_PARAM_READWRITE);
486
487 g_object_class_install_property (gobject_class,
488 PROP_LEN, xyc_graph_param_spec);
489
490 xyc_graph_param_spec = g_param_spec_int ("maxlen", "maxlen of X and Y", "maximal number of data points", G_MININT, G_MAXINT, 0, /* default value */
491 G_PARAM_CONSTRUCT_ONLY |
492 G_PARAM_READWRITE);
493 g_object_class_install_property (gobject_class,
494 PROP_MAXLEN, xyc_graph_param_spec);
495
496 xyc_graph_param_spec = g_param_spec_int ("xstart", "array index of first X", "array index of first X", G_MININT, G_MAXINT, 0, /* default value */
497 G_PARAM_CONSTRUCT_ONLY |
498 G_PARAM_READWRITE);
499 g_object_class_install_property (gobject_class,
500 PROP_XSTART, xyc_graph_param_spec);
501
502 xyc_graph_param_spec = g_param_spec_int ("ystart", "array index of first Y", "array index of first Y", G_MININT, G_MAXINT, 0, /* default value */
503 G_PARAM_CONSTRUCT_ONLY |
504 G_PARAM_READWRITE);
505 g_object_class_install_property (gobject_class,
506 PROP_YSTART, xyc_graph_param_spec);
507
508 xyc_graph_param_spec = g_param_spec_int ("xstride", "stride of X values", "stride of X values", G_MININT, G_MAXINT, 1, /* default value */
509 G_PARAM_CONSTRUCT_ONLY |
510 G_PARAM_READWRITE);
511 g_object_class_install_property (gobject_class,
512 PROP_XSTRIDE, xyc_graph_param_spec);
513
514 xyc_graph_param_spec = g_param_spec_int ("ystride", "stride of Y values", "stride of Y values", G_MININT, G_MAXINT, 1, /* default value */
515 G_PARAM_CONSTRUCT_ONLY |
516 G_PARAM_READWRITE);
517 g_object_class_install_property (gobject_class,
518 PROP_YSTRIDE, xyc_graph_param_spec);
519
520 xyc_graph_param_spec = g_param_spec_gtype ("xtype", "GType of X elements", "GType of X elements", G_TYPE_NONE,
521 G_PARAM_CONSTRUCT_ONLY |
522 G_PARAM_READWRITE);
523 g_object_class_install_property (gobject_class,
524 PROP_XTYPE, xyc_graph_param_spec);
525
526 xyc_graph_param_spec = g_param_spec_gtype ("ytype", "GType of Y elements", "GType of Y elements", G_TYPE_NONE,
527 G_PARAM_CONSTRUCT_ONLY |
528 G_PARAM_READWRITE);
529 g_object_class_install_property (gobject_class,
530 PROP_YTYPE, xyc_graph_param_spec);
531
532 graph_class->calculate_extrema =
533 gtk_databox_xyc_graph_real_calculate_extrema;
534 }
535
536 static void
537 gtk_databox_xyc_graph_init (GtkDataboxXYCGraph *xyc_graph)
538 {
539 if (xyc_graph == NULL) g_warning ("xyc_graph_init with NULL");
540 }
541
542 static gint
543 gtk_databox_xyc_graph_real_calculate_extrema (GtkDataboxGraph * graph,
544 gfloat * min_x, gfloat * max_x,
545 gfloat * min_y, gfloat * max_y)
546 {
547 GtkDataboxXYCGraph *xyc_graph = GTK_DATABOX_XYC_GRAPH (graph);
548 GtkDataboxXYCGraphPrivate *priv = gtk_databox_xyc_graph_get_instance_private (xyc_graph);
549 guint i, indx, len, maxlen, start, stride;
550 void *values;
551 GType vtype;
552 gfloat fval = 0.0, minval = 0.0, maxval = 0.0;
553
554 g_return_val_if_fail (GTK_DATABOX_IS_XYC_GRAPH (graph), -1);
555 g_return_val_if_fail (min_x, -1);
556 g_return_val_if_fail (max_x, -1);
557 g_return_val_if_fail (min_y, -1);
558 g_return_val_if_fail (max_y, -1);
559 g_return_val_if_fail (priv->len, -1);
560
561 len = priv->len;
562 maxlen = priv->maxlen;
563 values = priv->X;
564 vtype = priv->xtype;
565 start = priv->xstart;
566 stride = priv->xstride;
567
568 indx = start * stride;
569 i = 0;
570 do {
571 if (vtype == G_TYPE_FLOAT)
572 fval = ((gfloat *)values)[indx];
573 else if (vtype == G_TYPE_DOUBLE)
574 fval = ((gdouble *)values)[indx];
575 else if (vtype == G_TYPE_INT)
576 fval = ((gint *)values)[indx];
577 else if (vtype == G_TYPE_UINT)
578 fval = ((guint *)values)[indx];
579 else if (vtype == G_TYPE_LONG)
580 fval = ((glong *)values)[indx];
581 else if (vtype == G_TYPE_ULONG)
582 fval = ((gulong *)values)[indx];
583 else if (vtype == G_TYPE_INT64)
584 fval = ((gint64 *)values)[indx];
585 else if (vtype == G_TYPE_UINT64)
586 fval = ((guint64 *)values)[indx];
587 else if (vtype == G_TYPE_CHAR)
588 fval = ((gchar *)values)[indx];
589 else if (vtype == G_TYPE_UCHAR)
590 fval = ((guchar *)values)[indx];
591
592 if (i==0)
593 {
594 minval = maxval = fval;
595 }
596 else
597 {
598 if (fval < minval) minval = fval;
599 if (fval > maxval) maxval = fval;
600 }
601
602 /* handle the wrap-around (ring buffer) issue using modulus. for efficiency, don't do this for non-wraparound cases. */
603 /* note this allows multiple wrap-arounds. One could hold a single cycle of a sine wave, and plot a continuous wave */
604 /* This can be optimized using pointers later */
605 if (i + start > maxlen)
606 indx = ((i + start) % maxlen) * stride;
607 else
608 indx += stride;
609 } while (++i < len);
610
611 *min_x = minval;
612 *max_x = maxval;
613
614 values = priv->Y;
615 vtype = priv->ytype;
616 start = priv->ystart;
617 stride = priv->ystride;
618
619 indx = start * stride;
620 i = 0;
621 do {
622 if (vtype == G_TYPE_FLOAT)
623 fval = ((gfloat *)values)[indx];
624 else if (vtype == G_TYPE_DOUBLE)
625 fval = ((gdouble *)values)[indx];
626 else if (vtype == G_TYPE_INT)
627 fval = ((gint *)values)[indx];
628 else if (vtype == G_TYPE_UINT)
629 fval = ((guint *)values)[indx];
630 else if (vtype == G_TYPE_LONG)
631 fval = ((glong *)values)[indx];
632 else if (vtype == G_TYPE_ULONG)
633 fval = ((gulong *)values)[indx];
634 else if (vtype == G_TYPE_INT64)
635 fval = ((gint64 *)values)[indx];
636 else if (vtype == G_TYPE_UINT64)
637 fval = ((guint64 *)values)[indx];
638 else if (vtype == G_TYPE_CHAR)
639 fval = ((gchar *)values)[indx];
640 else if (vtype == G_TYPE_UCHAR)
641 fval = ((guchar *)values)[indx];
642
643 if (i==0) /* yes putting this check inside the loop is inefficient, but it makes the code simpler */
644 {
645 minval = maxval = fval;
646 }
647 else
648 {
649 if (fval < minval) minval = fval;
650 if (fval > maxval) maxval = fval;
651 }
652
653 /* handle the wrap-around (ring buffer) issue using modulus. for efficiency, don't do this for non-wraparound cases. */
654 /* note this allows multiple wrap-arounds. One could hold a single cycle of a sine wave, and plot a continuous wave */
655 /* This can be optimized using pointers later */
656 if (i + start > maxlen)
657 indx = ((i + start) % maxlen) * stride;
658 else
659 indx += stride;
660 } while (++i < len);
661
662 *min_y = minval;
663 *max_y = maxval;
664
665 return 0;
666 }