Class AxisBuilder.Linear

java.lang.Object
org.bzdev.graphs.AxisBuilder<Graph.Axis>
org.bzdev.graphs.AxisBuilder.Linear
Enclosing class:
AxisBuilder<T extends Graph.Axis>

public static final class AxisBuilder.Linear extends AxisBuilder<Graph.Axis>
AxisBuilder for a linear axis. This axis builder created a linear axis whose tick marks (if any) mostly have spacings that are powers of 10. Tick marks will generally have different widths and heights, specified by a level. The coarsest spacing for possible tick locations is at values of X or Y that is some power of ten 10M. the remaining runs of tick marks are spaced at values equal to 10M-m, where m is a non-negative integer called the depth. The value of M is set by using the method setMaximumExponent(int). Tick marks at this spacing are specified by calling addTickSpec(int,int,boolean,String) or addTickSpec(int,int,boolean,String,String). with a second argument (the depth argument) set to 0. More closely spaced tick marks are specified by providing a depth that is larger than 0. The first argument to these methods is a small integer called the level. Increasing the level will generally result in thinner to shorter tick marks.

As a special case, the lowest power of 10 (corresponding to the maximum depth used), can be partitioned into n steps, The value of n must be set by calling setNumberOfSteps(int). One can then add additional tick marks by calling addTickSpec(int,int,String), where the first argument is a level and the second argument is a divisor of n. An example below uses this method to subdivide the lowest power of 10 into quarters.

Normally when the depth increases by 1, the level should increase by 1. When the boolean argument for addTickSpec(int,int,boolean,String) or addTickSpec(int,int,boolean,String,String) is true, both the specified level and the next highest level (1 + the specified level) are used, so for the next depth, the level should be increased by 2 instead of 1.

A call to addTickSpec will result in a sequence of tick marks with a specified spacing, tick width, and tick height. When multiple calls occur, more than one tick specification will apply to a given tick location. The tick mark specification corresponding to the largest spacing will be used. If there is a tie (a rare case in practice), other characteristics of the tick marks are used to resolve the conflict. The String arguments to addTickSpec are format strings appropriate for double-precision vales. As a summary for the use of addTickSpec,

  • for the 4-argument version, the first argument is a level that determines the dimensions of tick marks (higher levels produce smaller tick marks), the second argument is a depth (higher values correspond to closer tick marks), the third argument is a boolean indicating if marks halfway between the specified marks should be added (in this case, the next highest level will be used), and the forth argument is a format string. An optional fifth argument can be used for the format of the middle tick mark. When the third argument is true, two tick specifications are generated, one with the level specified and the other with a level that is higher by 1.
  • for the 3-argument version, the first argument is a level, the second argument is a divisor, and the third argument is a format string. When a divisor other than 1 is specified, the method setNumberOfSteps(int) must have been called previously with an argument larger than 0. The divisor must divide this method's argument. The three argument method allows a subsequence of tick marks to be defined, with some skipped, with the length of the sequence an positive integer that is not a prime number.
Be default, 5 levels are supported. One should call the method AxisBuilder.configureLevels(double[],double[],double[]) to set the tick-mark length factor, the tick-mark width factor, and the label separation for each level to different values or to change the number of levels that may be used.

To illustrate the effects of the addTickSpec methods, suppose an instance of Graph named graph was created. Also assume an instance of AccessBuilder.Linear named ab was created as follows:


    AxisBuilder.Linear ab =
      new AxisBuilder.Linear(graph, 0.0, 0.0, 10.0, true, LABEL);
    ab.setMaximumExponent(0);
 
where LABEL is a string providing a label for the graph. The graph will be 10 units long and the most coarsely spaced tick marks will be spaced by 1 unit in graph coordinate space. The following figure shows the effects of successive calls to addTickSpec when the first call's second argument is false.

axis example

The following figure shows the effects of successive calls to addTickSpec when the first call's second argument is true. In this case, the first call consumes two levels, so the second call to addTickSpec sets its level to 2.

axis example

For the use of a divisor, consider an axis builder created as follows:


    AxisBuilder.Linear ab =
      new AxisBuilder.Linear(graph, 0.0, 0.0, 10.0, true, LABEL);
    ab.setMaximumExponent(0);
    ab.setNumberOfSteps(4);
 
Successive calls to addTickSpec then behave as shown in the next figure:

axis example

Finally, the following provides examples of the full sequence of operations needed to create a graph and its axes.

Example 1:


      Graph graph = new Graph(...);
      graph.setRanges(...)
      graph.setOffsets(...);
      AxisBuild.Linear ab
         = new AxisBuilder.Linear(graph, 0.0, 0,0, 10.0, true,
                                  "X Axis");
      xab.setMaximumExponent(0);
      xab.addTickSpec(0, 0, true, "%3.0f");
      xab.addTickSpec(2, 1, false, null);
      graph.draw(xab.createAxis());

      AxisBuild.Linear yab =
         new AxisBuilder.Linear(graph, 0.0, 0,0, 10.0, false, "Y Axis");
      yab.setMaximumExponent(0);
      yab.addTickSpec(0, 0, true, "%3.0f");
      yab.addTickSpec(2, 1, false, null);
      ...
      graph.draw(xab.createAxis());
      graph.draw(yab.createAxis());
 
The code above creates axes with large tick marks at 0.0, 1.0, ... 10.0, a medium-length tick mark at 0.5, 1,5, etc., and small tick marks spaced by 0.1 units in graph coordinate space.

Example 2:


      Graph graph = new Graph(...);
      graph.setRanges(...)
      graph.setOffsets(...);
      AxisBuild.Linear xab
        =  new AxisBuilder.Linear(graph, 0.0, 0,0, 12.0, true, "Ruler");
      xab.setMaximumExponent(0);
      xab.setNumberOfSteps(4);
      xab.addTickSpec(0, 0, false, "%3.0f");
      xab.addTickSpec(1, 2, null);
      xab.addTickSpec(2, 4, null);
      graph.draw(xab.createAxis());
 
The code above creates an axis layed out like a ruler covering a distance of 12 inches with numbers labeling each inch, and with a shorter tick at half-inch points and the shortest tick at quarter-inch points.
  • Constructor Details

    • Linear

      public Linear(Graph g, double startX, double startY, double length, boolean horizontal, String label)
      Constructor.
      Parameters:
      g - the graph
      startX - the X value in graph coordinate space for the start of the axis.
      startY - the Y value in graph coordinate space for the start of the axis
      length - the length of the axis in graph coordinate space units
      horizontal - true if the axis is horizontal; false if it is vertical
      label - the level for an axis; null if none is provided
    • Linear

      public Linear(Graph g, double startX, double startY, double length, boolean horizontal, boolean flip, String label)
      Constructor with a "flip" option. Normally the tick marks for an axis are below the axis for a horizontal axis and to the left of an axis for a vertical axis. An option to flip the tick marks and labels to the opposite side of the axis is provided by this constructor for cases where an axis appears at the top of a graph or at its right side.
      Parameters:
      g - the graph
      startX - the X value in graph coordinate space for the start of the axis.
      startY - the Y value in graph coordinate space for the start of the axis
      length - the length of the axis in graph coordinate space units
      horizontal - true if the axis is horizontal; false if it is vertical
      flip - true of the tick marks should be flipped to the opposite side of the axis; false to use the default side
      label - the level for an axis; null if none is provided
  • Method Details

    • setMaximumExponent

      public void setMaximumExponent(int maxExponent)
      Set exponents to indicate the spacing between the set of tick marks with the widest separation. Tick marks may occur at the graph-coordinate-space values 10r where r is an integer. The maximum exponent is the largest value of r that is used. These values will frequently have a tick-mark label associated for them and will usually be the longest tick marks on an axis.

      If setNumberOfSteps(int) is called with an argument n larger than 1, then the smallest possible spacing between ticks will be 10m/n, where m is the minimum exponent. The minimum exponent is computed automatically.

      Parameters:
      maxExponent - the maximum allowable exponent for tick separations
      See Also:
    • setNumberOfSteps

      public void setNumberOfSteps(int n)
      Set the number of steps.

      By default, ticks will be placed at integral multiples of a minimum separation that is equal to 10m where m is the minimum exponent, computed by subtracting the maximum depth from the maximum exponent, which is set by calling {#setMaximumExponent(int)}. The maximum depth is the maximum value of the second argument to the methods addTickSpec(int,int,boolean,String) and addTickSpec(int,int,boolean,String,String) that were called for this axis builder.

      This method specifies the number of steps by which the minimum separation mentioned in the preceding paragraph should be subdivided. When set to a value larger than 1, additional levels of tick marks can be added. The second argument for addTickSpec(int,int,String) will then determine the steps at which tick marks will be shown.

      The default number of steps is 1. Higher values are useful when an interval should be divided into subintervals other than 10. For example, setting the number of steps to 4 will allow one to create ticks that divide 10m into quarters. A typical use is to set the number of steps to 10 and then call addTickSpec(int,int,String) with its second argument set to 5: this will provide 5 ticks in between the minimum-separation tick locations used by default.

      Parameters:
      n - the number of steps.
      See Also:
    • addTickSpec

      public void addTickSpec(int level, int depth, boolean middle, String format)
      Add a tick specification with one format specification. This method adds a tick specification for sets of ticks spaced by the distance 10n when the "middle" argument is false and the distance 10n/2 when the "middle" argument is true, where n equals the depth subtracted from the maximum exponent, and where n is larger than or equal to the minimum exponent provided by a previous call to setMaximumExponent(int). The level is an index for the set of parameters configured in a call to AxisBuilder.configureLevels(double[],double[],double[]) These arrays determine a tick mark's length, width, and the separation of the label form its tick mark (when the format argument is not null).
      Parameters:
      level - the level for this set of tick marks (level+1 will also be used if middle is true)
      depth - the depth
      middle - false if the tick marks are to be placed at the positions k (10M-m) and true if the tick mark is placed at the positions k (10M-m/2), with k an integer such that a tick mark touches the axis
      format - the format string used to create a label; null if there is no label
      Throws:
      IllegalArgumentException - the argument n was lower then the minimum exponent
    • addTickSpec

      public void addTickSpec(int level, int depth, boolean middle, String format, String mformat)
      Add a tick specification with two formats. This method adds a tick specification for sets of ticks spaced by the distance 10n when the "middle" argument is false and the distance 10n/2 when the "middle" argument is true, where n equals the depth subtracted from the maximum exponent that was set by a previous call to setMaximumExponent(int). The level is the index for a set of parameters configured in a call to AxisBuilder.configureLevels(double[],double[],double[]) These arrays determine a tick mark's length, width, and the separation of the label form its tick mark (when the format argument is not null).
      Parameters:
      level - the level for this set of tick marks (level+1 will also be used if middle is true)
      depth - the depth
      middle - false if the tick marks are to be placed at the positions m (10n and true if the tick mark is placed at the positions m (10n/2), with m an integer such that a tick mark touches the axis
      format - the format string used to create a label; null if there is no label
      mformat - the format used to create a label for ticks added due to the 'middle' argument being true; null if there are none.
      Throws:
      IllegalArgumentException - the argument n was lower then the minimum exponent
    • addTickSpec

      public void addTickSpec(int level, int divisor, String format)
      Add a tick specification using a divisor. This method adds a tick specification that places tick marks at intervals given by 10m / n, were m is the minimum exponent and n is a divisor of nsteps, the parameter set by calling setNumberOfSteps(int). Like other methods with this name, the level is the index for a set of parameters configured in a call to AxisBuilder.configureLevels(double[],double[],double[]) These arrays determine a tick mark's length and width
      Parameters:
      level - the level for this set of tick marks
      divisor - the divisor
      format - the format string used to create a label; null if there is no label
      See Also:
    • newAxisInstance

      protected Graph.Axis newAxisInstance(double startX, double startY, Graph.Axis.Dir direction, double length, double tickBase, double tickIncr, boolean counterclockwise)
      Description copied from class: AxisBuilder
      Create a new instance of an axis. This is called by implementations of AxisBuilder.createAxis() to create a new instance of an axis. This method is provided to reduce the necessity of reimplementing AxisBuilder.createAxis() in subclasses of (for example) AxisBuilder.Linear and AxisBuilder.Log that a user might write.

      Note: for AxisBuilder.Log, the tickBase argument for this method is ignored (the value is computed from the other parameters in this case).

      Specified by:
      newAxisInstance in class AxisBuilder<Graph.Axis>
      Parameters:
      startX - the x coordinate of the axis' starting point in graph coordinate space
      startY - the y coordinate of the axis' starting point in graph coordinate space
      direction - the direction of the graph
      length - the length of the axis in graph coordinate space
      tickBase - the starting coordinate along the axis for graph ticks, given in graph-coordinate space
      tickIncr - the increment between possible tick locations in graph coordinate space units
      counterclockwise - the angular direction to follow to reach a graph's labels and tick marks
      Returns:
      a new axis
    • createAxis

      public Graph.Axis createAxis()
      Description copied from class: AxisBuilder
      Create an axis. Users may add additional tick marks if desired.
      Specified by:
      createAxis in class AxisBuilder<Graph.Axis>
      Returns:
      the axis that was created with its tick marks added