gtkdatabox  1.0.0
About: GtkDatabox is a Gtk+-widget for live display of large amounts of fluctuating numerical data.
  Fossies Dox: gtkdatabox-1.0.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

gtkdatabox_xyc_graph.c
Go to the documentation of this file.
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 
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,
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  **/
52 
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 
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
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
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
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
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
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
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
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
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
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
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
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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 =
534 }
535 
536 static void
538 {
539  if (xyc_graph == NULL) g_warning ("xyc_graph_init with NULL");
540 }
541 
542 static gint
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 }
#define GTK_DATABOX_TYPE_GRAPH
#define GTK_DATABOX_GRAPH_CLASS(klass)
@ PROP_YTYPE
@ PROP_XSTRIDE
@ PROP_XSTART
@ PROP_MAXLEN
@ PROP_LEN
@ PROP_YSTART
@ PROP_YSTRIDE
@ PROP_XTYPE
static void gtk_databox_xyc_graph_set_ytype(GtkDataboxXYCGraph *xyc_graph, GType ytype)
gfloat * gtk_databox_xyc_graph_get_Y(GtkDataboxXYCGraph *xyc_graph)
static void gtk_databox_xyc_graph_set_xtype(GtkDataboxXYCGraph *xyc_graph, GType xtype)
static void gtk_databox_xyc_graph_set_X(GtkDataboxXYCGraph *xyc_graph, gfloat *X)
static void gtk_databox_xyc_graph_set_length(GtkDataboxXYCGraph *xyc_graph, guint len)
static void gtk_databox_xyc_graph_init(GtkDataboxXYCGraph *xyc_graph)
guint gtk_databox_xyc_graph_get_xstride(GtkDataboxXYCGraph *xyc_graph)
static void gtk_databox_xyc_graph_set_ystride(GtkDataboxXYCGraph *xyc_graph, guint ystride)
static void gtk_databox_xyc_graph_set_xstart(GtkDataboxXYCGraph *xyc_graph, guint xstart)
guint gtk_databox_xyc_graph_get_ystride(GtkDataboxXYCGraph *xyc_graph)
guint gtk_databox_xyc_graph_get_xstart(GtkDataboxXYCGraph *xyc_graph)
gfloat * gtk_databox_xyc_graph_get_X(GtkDataboxXYCGraph *xyc_graph)
static gint gtk_databox_xyc_graph_real_calculate_extrema(GtkDataboxGraph *xyc_graph, gfloat *min_x, gfloat *max_x, gfloat *min_y, gfloat *max_y)
G_DEFINE_TYPE_WITH_PRIVATE(GtkDataboxXYCGraph, gtk_databox_xyc_graph, GTK_DATABOX_TYPE_GRAPH)
static void gtk_databox_xyc_graph_set_ystart(GtkDataboxXYCGraph *xyc_graph, guint ystart)
static void gtk_databox_xyc_graph_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
static void gtk_databox_xyc_graph_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
static void gtk_databox_xyc_graph_set_xstride(GtkDataboxXYCGraph *xyc_graph, guint xstride)
GType gtk_databox_xyc_graph_get_ytype(GtkDataboxXYCGraph *xyc_graph)
guint gtk_databox_xyc_graph_get_maxlen(GtkDataboxXYCGraph *xyc_graph)
static void gtk_databox_xyc_graph_set_maxlen(GtkDataboxXYCGraph *xyc_graph, guint maxlen)
GType gtk_databox_xyc_graph_get_xtype(GtkDataboxXYCGraph *xyc_graph)
guint gtk_databox_xyc_graph_get_length(GtkDataboxXYCGraph *xyc_graph)
static void gtk_databox_xyc_graph_class_init(GtkDataboxXYCGraphClass *klass)
guint gtk_databox_xyc_graph_get_ystart(GtkDataboxXYCGraph *xyc_graph)
static void gtk_databox_xyc_graph_set_Y(GtkDataboxXYCGraph *xyc_graph, gfloat *Y)
void gtk_databox_xyc_graph_set_X_Y_length(GtkDataboxXYCGraph *xyc_graph, gfloat *X, gfloat *Y, guint len)
#define GTK_DATABOX_IS_XYC_GRAPH(obj)
#define GTK_DATABOX_XYC_GRAPH(obj)
gint(* calculate_extrema)(GtkDataboxGraph *graph, gfloat *min_x, gfloat *max_x, gfloat *min_y, gfloat *max_y)