Logo Search packages:      
Sourcecode: ygraph version File versions  Download package

GArray* axis_calc_ticks ( gdouble  min,
gdouble  max,
Axis axis 
)

Determine the location of tickmarks along an axis, given its range.

This is not an easy thing to do generally. The following algorithm tries to divide the range into intervals specified by the largest log10 division that will fit in the range. It tries to fit the number of ticks into an optimum range so that the numbers don't run together. The method is not always great, and will sometimes fail to put tickmarks on the axis where intuitively one would expect them. Maybe this could be generalised by allowing for log2 divisions if the number of ticks falls below an optimum number.

Parameters:
range A pointer to a pair of doubles specifying min and max values for the range.
Returns:
An array of *Ticks where tick-marks should be drawn.

Definition at line 209 of file axis.c.

References axis_tick_append().

Referenced by axis_create().

{
  GArray* ticks;
  gdouble d;
  gdouble e;
  gdouble div;
  gint n_ticks;
  gdouble a_min;
  gdouble a;
  gint i;
  gboolean exp_notation;

  ticks = g_array_new(FALSE, FALSE, sizeof(Tick*));

  min = axis_transformation(min, axis);
  max = axis_transformation(max, axis);
  if (max == min)
    {
      max += AXIS_EPSILON;
      min -= AXIS_EPSILON;
    }

  d = max - min;
  max += d/1000000;                         /* a*(b/a) !=(always) b */
  e = floor(log10(d));                      /* exponent of the range */
  
  div = pow(10,e);                          /* size of divisions */
  n_ticks = d/div;                          /* number of divisions */

  while (n_ticks < OPTIMUM_TICK_MARK_NUMBER)
    {
      div = 0.1*div;
      n_ticks = ceil(d/div);
    }

  if (n_ticks > 2*OPTIMUM_TICK_MARK_NUMBER)
    {
      while (n_ticks > OPTIMUM_TICK_MARK_NUMBER)
        {
          div = 5*div;
          n_ticks = (gint) d/div;
        }
    }

  /*
   * Very large and very small numbers are display with exponential notation,
   * but intermediate numbers not.
   */
  exp_notation = ( (fabs(max) > 1000) || (fabs(max) < 0.001) );

  i=0;
  a_min = ceil(min/div)*div;          /* leftmost axis label */
  for (a=a_min; a<=max; a+=div)
    {
      /* 
       * If any labels are sufficiently close to zero relative to the
       * extent of the axis (d) then display them as `0'. (Eg. This prevents
       * numbers such as 10-17 showing up when the range is -1...1)
       */
      if (fabs(a/d) < AXIS_EPSILON)
        a = 0;

      axis_tick_append(ticks, a, axis, exp_notation);
    }

  return ticks;
}


Generated by  Doxygen 1.6.0   Back to index