# Class PlotUtil

java.lang.Object
uk.ac.starlink.ttools.plot2.PlotUtil

public class PlotUtil extends Object
Miscellaneous utilities for use with the plotting classes.

Since:
  13 Feb 2013
Author:
  Mark Taylor

## Field Summary

Fields
Modifier and Type
Field
Description
`static SplitRunner<CoordSequence>`
`COORD_RUNNER`
Default SplitRunner for CoordSequences.
`static final int`
`DEFAULT_MAX_PIXELS`
Maximum size for autoscaled variable-size markers.
`static final Span`
`EMPTY_SPAN`
Span instance not initialised with any data.
`static final TupleSequence`
`EMPTY_TUPLE_SEQUENCE`
TupleSequence instance that contains no tuples.
`static final PdfGraphicExporter`
`LATEX_PDF_EXPORTER`
PDF GraphicExporter suitable for use with JLaTeXMath.
`static final short`
`MAX_MARKSIZE`
Absolute maximum number of pixels per marker.
`static final int`
`MIN_RAMP_UNIT`
Minimum number of input differences that fill up a colour ramp.
`static final double`
`NEAR_PIXELS`
Maximum distance from a click to a clicked-on position.

## Method Summary

Modifier and Type
Method
Description
`static boolean`
`approxEquals(double v0, double v1)`
Indicates whether two floating point numbers are approximately equal to each other.
`static <T> T[]`
`arrayConcat(T[] a1, T[] a2)`
Concatenates two arrays to form a single one.
`static String`
`concatLines(String[] lines)`
Concatentates lines, adding a newline character at the end of each.
`static ConfigMap`
`configLimits(ConfigKey<Double> minKey, ConfigKey<Double> maxKey, double min, double max, int npix)`
Utility method to set a minimum/maximum config key pair to a given pair of minimum/maximum values.
`static <P,A> A[]`
`createAspectArray(SurfaceFactory<P,A> surfFact, int length)`
Returns an empty array suitable (it has the right parameterised type) for containing elements that are aspects for a given surface factory.
`static Graphics`
`createLineGraphics(Graphics g, Color color)`
Provides a graphics context based on an existing one that is suitable for drawing lines that may have a sub-unity alpha component.
`static Icon`
`createPlotIcon(PlotPlacement placer, PlotLayer[] layers, Map<AuxScale,Span> auxSpans, DataStore dataStore, PaperType paperType, boolean cached, Collection<Object> storedPlans)`
Creates an icon which will paint a surface and the layers on it.
`static <P> P[]`
`createProfileArray(SurfaceFactory<P,?> surfFact, int length)`
Returns an empty array suitable (it has the right parameterised type) for containing elements that are profiles for a given surface factory.
`static Span`
`createSpan(double lo, double hi)`
Returns a basic span instance with a given lower and upper bound.
`static <P,A> ZoneContent<P,A>[]`
`createZoneContentArray(SurfaceFactory<P,A> surfFact, int length)`
Returns an empty array suitable (it has the right parameterised type) for containing elements that are ZoneContents for a given surface factory.
`static boolean`
`doubleEquals(double d1, double d2)`
Indicates whether two double values are equivalent.
`static boolean`
`equals(Object o1, Object o2)`
Compares two possibly null objects for equality.
`static void`
`extendCoordinateRanges(PlotLayer[] layers, Range[] ranges, boolean[] logFlags, boolean doPad, DataStore dataStore)`
Extends existing range objects using range information for a set of layers which have Cartesian (or similar) coordinates.
`static String[]`
`formatAxisRangeLimits(double lo, double hi, boolean isLog, int npix)`
Formats a pair of values representing data bounds of a range along a graphics axis.
`static String`
`formatNumber(double value, double epsilon)`
Formats a number so that it presents a number of significant figures corresponding to a supplied small difference.
`static String`
`formatNumber(double value, String baseFmt, int nFracDigits)`
Numeric formatting utility function.
`static String`
`formatNumberSf(double value, int nsf)`
Numeric formatting utility function for writing a given number of significant figures.
`static int`
`getButtonChangedIndex(MouseEvent evt)`
Determines which mouse button was changed at a given mouse event.
`static int`
`getButtonDownIndex(MouseEvent evt)`
Determines which single button is depressed at a given mouse event.
`static IndicatedRow`
`getClosestRow(Surface surface, DataGeom geom, int iPosCoord, Supplier<TupleSequence> tupleSupplier, TupleRunner runner, Point2D point)`
Scans a tuple sequence to identify the data point which is plotted closest to a given graphics position.
`static boolean`
`getDefaultTextAntialiasing()`
Indicates whether antialiasing of text is turned on or off by default.
`static Rectangle`
`getGangBounds(Gang gang)`
Determines the union of the data bounds of zones in a gang.
`static String`
`getIndexSuffix(int ipos)`
Returns a suffix to append to one of a set of similar coordinate names for disambiguation.
`static String`
`getScaleAxisLabel(PlotLayer[] layers, AuxScale scale)`
Attempts to return a suitable label for an aux axis that may be referenced in a given list of plot layers.
`static uk.ac.starlink.table.ValueInfo`
`getScaleInfo(PlotLayer[] layers, AuxScale scale)`
Attempts to return input-level metadata about an aux value that may be referenced in a given list of plot layers.
`static Tick[]`
`getShadowTicks(Tick[] ticks)`
Returns an array of tickmarks that resembles the supplied ones, but with no labels.
`static int`
`hashCode(Object obj)`
Returns a hash code for a possibly null object.
`static int`
`ifloor(double x)`
Determines the integer not larger than a given non-NaN floating point value.
`static boolean`
`isFinite(double value)`
Indicates whether a value is a definite number.
`static boolean`
`isPointFinite(Point2D.Double gp)`
Determines whether both coordinates of a graphics position are definite numbers.
`static boolean`
`isPointReal(Point2D.Double gp)`
Determines whether both coordinates of a graphics position are not NaNs.
`static void`
`logTimeElapsed(Logger logger, String phase, long elapsed)`
Writes a message through the logging system about the supplied elapsed time a named step has taken.
`static void`
`logTimeFromStart(Logger logger, String phase, long start)`
Writes a message through the logging system about the elapsed time a named step has taken given a start time.
`static double[]`
`orderPair(double p1, double p2)`
Returns a 2-element array consisting of the two input values in ascending order.
`static void`
`padRange(Range range, boolean logFlag)`
Pads a data range to provide a bit of extra space at each end using a standard padding fraction.
`static void`
`quantisePoint(Point2D.Double dpos, Point gpos)`
Maps a floating point graphics position to an integer graphics position, that is a 2-dimensional grid cell index.
`static double`
`roundNumber(double x, double epsilon)`
Rounds a number to a decimal round value.
`static double[]`
`scaleRange(double min, double max, Subrange subrange, boolean isLog)`
Returns a range determined by a fixed range and a subrange within it.
`static double`
`scaleValue(double min, double max, double frac)`
Does linear scaling between two values.
`static double`
`scaleValue(double min, double max, double frac, boolean isLog)`
Returns a value determined by a fixed range and a fractional scale point within it.
`static <T> T[]`
`singletonArray(T object)`
Returns a single-element array from an object with a parameterised type.
`static boolean`
`storeFullPrecision()`
Policy for whether to cache full precision coordinates.
`static Rectangle`
`subtractInsets(Rectangle base, Insets insets)`
Returns the rectangle that results from removing the insets from a given rectangle.
`static double`
`toDouble(Number value)`
Turns a Number object into a double primitive.
`static Picture`
`toPicture(Icon icon)`
Turns an Icon into a Picture.
`static double`
`toZoom(double unitFactor, int wheelrot)`
Determines a zoom factor from a mouse wheel event and a given unit zoom factor.
`static double`
`toZoom(double unitFactor, Point p0, Point p1, Boolean isY)`
Determines an X, Y or isotropic zoom factor from a pair of screen positions and a given unit zoom factor.
`static <A> A`
`tupleCollect(uk.ac.starlink.util.SplitCollector<TupleSequence, A> collector, DataSpec dataSpec, DataStore dataStore)`
Convenience TupleRunner collection method using a DataStore and DataSpec.
`static double`
`unscaleValue(double min, double max, double point, boolean isLog)`
Returns the proportional position of a point within a fixed range.

### Methods inherited from class Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### EMPTY_TUPLE_SEQUENCE

public static final TupleSequence EMPTY_TUPLE_SEQUENCE
TupleSequence instance that contains no tuples.

### EMPTY_SPAN

public static final Span EMPTY_SPAN
Span instance not initialised with any data.

### LATEX_PDF_EXPORTER

public static final PdfGraphicExporter LATEX_PDF_EXPORTER
PDF GraphicExporter suitable for use with JLaTeXMath.

### NEAR_PIXELS

public static final double NEAR_PIXELS
Maximum distance from a click to a clicked-on position.

See Also:
  - Constant Field Values

### DEFAULT_MAX_PIXELS

public static final int DEFAULT_MAX_PIXELS
Maximum size for autoscaled variable-size markers.

See Also:
  - Constant Field Values

### MAX_MARKSIZE

public static final short MAX_MARKSIZE
Absolute maximum number of pixels per marker.

See Also:
  - Constant Field Values

### MIN_RAMP_UNIT

public static final int MIN_RAMP_UNIT
Minimum number of input differences that fill up a colour ramp.

See Also:
  - Constant Field Values

### COORD_RUNNER

public static SplitRunner<CoordSequence> COORD_RUNNER
Default SplitRunner for CoordSequences.

## Method Details

### equals

public static boolean equals(Object o1, Object o2)
Compares two possibly null objects for equality.

Parameters:
  `o1` - one object or null
  `o2` - other object or null
Returns:
  true iff objects are equal or are both null

### doubleEquals

public static boolean doubleEquals(double d1, double d2)
Indicates whether two double values are equivalent. Unlike the == operator, this function returns true if both are NaN.

Parameters:
  `d1` - first value
  `d2` - second value
Returns:
  true iff inputs are both equal or both NaN

### hashCode

public static int hashCode(Object obj)
Returns a hash code for a possibly null object.

Parameters:
  `obj` - object or null
Returns:
  hash value

### storeFullPrecision

public static boolean storeFullPrecision()
Policy for whether to cache full precision coordinates.

Returns:
  if false, it's OK to truncate doubles to floats when it seems reasonable

### getDefaultTextAntialiasing

public static boolean getDefaultTextAntialiasing()
Indicates whether antialiasing of text is turned on or off by default. There are a few considerations here. Text generally looks nicer antialiased, but it is noticeably slower to paint. Furthermore, there is a serious bug in OSX Java text rendering (java 1.7+?) that means un-antialiased characters in non-horizontal strings are drawn in the wrong order or wrong places or something (text drawn vertically has the letters sdrawkcab, anyway); painting it with antialiasing turned on works round this for some reason.

So the current policy is to set the default true for OSX, and false for other platforms.

Returns:
  default antialiasing for potentially non-horizontal text

### getIndexSuffix

public static String getIndexSuffix(int ipos)
Returns a suffix to append to one of a set of similar coordinate names for disambiguation. Where there are several sets of positional coordinates that would otherwise have the same names, use this method to come up with a consistent suffix. It is only usual to invoke this method if there are in fact multiple positions, if there's only one just don't give it a suffix.

Parameters:
  `ipos` - zero-based position number
Returns:
  suffix; currently `1+ipos`

### logTimeElapsed

public static void logTimeElapsed(Logger logger, String phase, long elapsed)
Writes a message through the logging system about the supplied elapsed time a named step has taken. If the elapsed time is zero, nothing is logged.

Parameters:
  `logger` - log message destination
  `phase` - name of step to log time of
  `elapsed` - elapsed time to report (generally milliseconds)

### logTimeFromStart

public static void logTimeFromStart(Logger logger, String phase, long start)
Writes a message through the logging system about the elapsed time a named step has taken given a start time. The elapsed time is presumed to be the time between the supplied time and the time when this method is called. If the elapsed time is zero (to the nearest millisecond), nothing is logged.

Parameters:
  `logger` - log message destination
  `phase` - name of step to log time of
  `start` - start `currentTimeMillis`

### arrayConcat

public static <T> T[] arrayConcat(T[] a1, T[] a2)
Concatenates two arrays to form a single one.

Parameters:
  `a1` - first array
  `a2` - second array
Returns:
  concatenated array

### concatLines

public static String concatLines(String[] lines)
Concatentates lines, adding a newline character at the end of each.

Parameters:
  `lines` - lines of text
Returns:
  concatenation

### toDouble

public static double toDouble(Number value)
Turns a Number object into a double primitive. If the supplied value is null, Double.NaN is returned.

Parameters:
  `value` - number object
Returns:
  primitive value

### isFinite

public static boolean isFinite(double value)
Indicates whether a value is a definite number.

Parameters:
  `value` - value to test
Returns:
  true iff `value` is non-NaN and non-infinite

### isPointFinite

public static boolean isPointFinite(Point2D.Double gp)
Determines whether both coordinates of a graphics position are definite numbers.

Parameters:
  `gp` - position to test
Returns:
  true iff X and Y coordinates are both non-NaN and non-infinite

### isPointReal

public static boolean isPointReal(Point2D.Double gp)
Determines whether both coordinates of a graphics position are not NaNs.

Parameters:
  `gp` - position to test
Returns:
  true iff X and Y coordinates are both non-NaN

### quantisePoint

public static void quantisePoint(Point2D.Double dpos, Point gpos)
Maps a floating point graphics position to an integer graphics position, that is a 2-dimensional grid cell index. It does this by calling `ifloor(double)` on both coordinates. The input coordinates must not be NaN.

Parameters:
  `dpos` - input definite floating point graphics position
  `gpos` - output graphics position object

### ifloor

public static int ifloor(double x)
Determines the integer not larger than a given non-NaN floating point value.

Parameters:
  `x` - definite floating point value
Returns:
  floor of input
See Also:
  - `Math.floor(double)`

### orderPair

public static double[] orderPair(double p1, double p2)
Returns a 2-element array consisting of the two input values in ascending order. If either is NaN, behaviour is undefined.

Parameters:
  `p1` - one value
  `p2` - other value
Returns:
  2-element array [plo,phi]

### getGangBounds

public static Rectangle getGangBounds(Gang gang)
Determines the union of the data bounds of zones in a gang.

Parameters:
  `gang` - gang
Returns:
  rectangle containing all data bounds rectangles in gang, or null if no zones

### singletonArray

public static <T> T[] singletonArray(T object)
Returns a single-element array from an object with a parameterised type. The array element type is taken from the runtime type of the single element.

Parameters:
  `object` - array element
Returns:
  array containing element

### createProfileArray

public static <P> P[] createProfileArray(SurfaceFactory<P,?> surfFact, int length)
Returns an empty array suitable (it has the right parameterised type) for containing elements that are profiles for a given surface factory.

Parameters:
  `surfFact` - surface factory
  `length` - array size
Returns:
  new empty array

### createAspectArray

public static <P,A> A[] createAspectArray(SurfaceFactory<P,A> surfFact, int length)
Returns an empty array suitable (it has the right parameterised type) for containing elements that are aspects for a given surface factory.

Parameters:
  `surfFact` - surface factory
  `length` - array size
Returns:
  new empty array

### createZoneContentArray

public static <P,A> ZoneContent<P,A>[] createZoneContentArray(SurfaceFactory<P,A> surfFact, int length)
Returns an empty array suitable (it has the right parameterised type) for containing elements that are ZoneContents for a given surface factory.

Parameters:
  `surfFact` - surface factory
  `length` - array size
Returns:
  new empty array

### toPicture

public static Picture toPicture(Icon icon)
Turns an Icon into a Picture.

Parameters:
  `icon` - icon
Returns:
  picture picture

### tupleCollect

@Slow public static <A> A tupleCollect(uk.ac.starlink.util.SplitCollector<TupleSequence, A> collector, DataSpec dataSpec, DataStore dataStore)
Convenience TupleRunner collection method using a DataStore and DataSpec. Default accumulator pooling policy is used (no pool).

Parameters:
  `collector` - collector
  `dataSpec` - data spec
  `dataStore` - data store, supplying both the data and the runner
Returns:
  collected result

### extendCoordinateRanges

@Slow public static void extendCoordinateRanges(PlotLayer[] layers, Range[] ranges, boolean[] logFlags, boolean doPad, DataStore dataStore)
Extends existing range objects using range information for a set of layers which have Cartesian (or similar) coordinates.

Parameters:
  `layers` - plot layers
  `ranges` - `nDataDim`-element array of range objects to extend
  `logFlags` - `nDataDim`-element array indicating whether data dimensions are linear (false) or logarithmic (true),
  `doPad` - whether to add a small standard amount of padding to the result
  `dataStore` - data storage

### padRange

public static void padRange(Range range, boolean logFlag)
Pads a data range to provide a bit of extra space at each end using a standard padding fraction. If one of the limits extends nearly or exactly to zero, it is padded to (very nearly) zero instead of adding a fixed amount.

Parameters:
  `range` - range to pad
  `logFlag` - true for logarithmic scaling, false for linear

### getScaleInfo

public static uk.ac.starlink.table.ValueInfo getScaleInfo(PlotLayer[] layers, AuxScale scale)
Attempts to return input-level metadata about an aux value that may be referenced in a given list of plot layers.

Parameters:
  `layers` - list of layers
  `scale` - aux item of interest
Returns:
  input metadata for scale, or null if nothing suitable can be found

### getScaleAxisLabel

public static String getScaleAxisLabel(PlotLayer[] layers, AuxScale scale)
Attempts to return a suitable label for an aux axis that may be referenced in a given list of plot layers.

Parameters:
  `layers` - list of layers
  `scale` - aux item of interest
Returns:
  scale axis label, or null if nothing suitable could be found

### getClosestRow

@Slow public static IndicatedRow getClosestRow(Surface surface, DataGeom geom, int iPosCoord, Supplier<TupleSequence> tupleSupplier, TupleRunner runner, Point2D point)
Scans a tuple sequence to identify the data point which is plotted closest to a given graphics position. Note the result might still be a long way off - standard practice is to threshold the result against the value of `NEAR_PIXELS`.

Parameters:
  `surface` - plot surface
  `geom` - maps data positions to graphics positions
  `iPosCoord` - coordinate index of positional coords in tseq
  `tupleSupplier` - iterable over tuples
  `runner` - manages tuple iteration
  `point` - reference graphics position
Returns:
  object giving row index and distance; null is returned if no points are present

### createPlotIcon

@Slow public static Icon createPlotIcon(PlotPlacement placer, PlotLayer[] layers, Map<AuxScale,Span> auxSpans, DataStore dataStore, PaperType paperType, boolean cached, Collection<Object> storedPlans)
Creates an icon which will paint a surface and the layers on it. If the `storedPlans` object is supplied, it may contain plans from previous plots. On exit, it will contain the plans used for this plot.

Parameters:
  `placer` - plot placement
  `layers` - layers constituting plot content
  `auxSpans` - requested range information calculated from data
  `dataStore` - data storage object
  `paperType` - rendering type
  `cached` - whether to cache pixels for future use
  `storedPlans` - writable collection of plan objects, or null
Returns:
  icon containing complete plot

### getButtonChangedIndex

public static int getButtonChangedIndex(MouseEvent evt)
Determines which mouse button was changed at a given mouse event. It's not really clear across the landscape of different mouse types and different OSes what user gestures different mouse/keyboard gestures will generate. We collect all the logic in this method, so if it turns out it's not working properly it can be adjusted easily.

This method will return an integer in the range 0-3 with the following meaning:

- 0: no button pressed
- 1: left button pressed (normal primary button)
- 2: center button pressed (least likely to be present)
- 3: right button pressed (normal secondary button)

The output of this method is the 'logical' value, so 2 may be returned to indicate simultaneous press of both buttons on a 2-button mouse if it's set up that way. If users have set up their mice strangely then a physical left click might not yield a value of 1 - that's their lookout.

This method is only intended for use when a single button is expected; multi-button gestures are not supported.

We follow the (conventional) usage where ctrl-click means right-click on a single button mouse, and we also currently use shift-click to mean center button. These conventions may be noted in user documentation.

Parameters:
  `evt` - mouse event
Returns:
  button indicator, 0-3
See Also:
  - `getButtonDownIndex(MouseEvent)`

### getButtonDownIndex

public static int getButtonDownIndex(MouseEvent evt)
Determines which single button is depressed at a given mouse event. The output value and considerations are the same as for `getButtonChangedIndex(MouseEvent)`.

Parameters:
  `evt` - mouse event
Returns:
  button indicator, 0-3
See Also:
  - `getButtonChangedIndex(MouseEvent)`

### toZoom

public static double toZoom(double unitFactor, int wheelrot)
Determines a zoom factor from a mouse wheel event and a given unit zoom factor. It just raises the given unit factor to the power of the number of wheel rotations (and applies a sense adjustment).

Parameters:
  `unitFactor` - positive zoom factor corresponding to a single click
  `wheelrot` - mouse wheel rotation
Returns:
  zoom factor

### toZoom

public static double toZoom(double unitFactor, Point p0, Point p1, Boolean isY)
Determines an X, Y or isotropic zoom factor from a pair of screen positions and a given unit zoom factor. The absolute positions of the supplied points are not important, only their separation is used.

Parameters:
  `unitFactor` - positive zoom factor corresponding to a single click
  `p0` - origin point
  `p1` - destination point
  `isY` - direction flag; TRUE for Y zoom, FALSE for X zoom and null for isotropic zoom
Returns:
  zoom factor

### scaleValue

public static double scaleValue(double min, double max, double frac, boolean isLog)
Returns a value determined by a fixed range and a fractional scale point within it. If the point is zero the minimum value is returned, and if it is one the maximum value is returned.

Parameters:
  `min` - minimum of range
  `max` - maximum of range
  `frac` - fractional scale point
  `isLog` - true iff the range is logarithmic
Returns:
  data value corresponding to fractional scale point

### scaleValue

public static double scaleValue(double min, double max, double frac)
Does linear scaling between two values. This convenience method just calls `scaleValue(min, max, frac, false)`

Parameters:
  `min` - minimum of range
  `max` - maximum of range
  `frac` - fractional scale point
Returns:
  data value corresponding to fractional scale point

### unscaleValue

public static double unscaleValue(double min, double max, double point, boolean isLog)
Returns the proportional position of a point within a fixed range. If the point is equal to the minimum value zero is returned, and if it is equal to the maximum value one is returned. This is the inverse function of `scaleValue(double, double, double, boolean)`.

Parameters:
  `min` - minimum of range
  `max` - maximum of range
  `point` - data value
  `isLog` - true iff the range is logarithmic
Returns:
  fractional value corresponding to data point

### scaleRange

public static double[] scaleRange(double min, double max, Subrange subrange, boolean isLog)
Returns a range determined by a fixed range and a subrange within it. If the subrange is 0-1 the output range is the input range.

Parameters:
  `min` - minimum of range
  `max` - maximum of range
  `subrange` - sub-range, both ends between 0 and 1
  `isLog` - true iff the range is logarithmic
Returns:
  2-element array giving low, high values of scaled range

### createSpan

public static Span createSpan(double lo, double hi)
Returns a basic span instance with a given lower and upper bound.

Parameters:
  `lo` - lower bound, may be NaN
  `hi` - upper bound, may be NaN
Returns:
  new span

### approxEquals

public static boolean approxEquals(double v0, double v1)
Indicates whether two floating point numbers are approximately equal to each other. Exact semantics are intentionally not well-defined by this contract.

Parameters:
  `v0` - one value
  `v1` - other value
Returns:
  true if they are about the same

### formatNumber

public static String formatNumber(double value, String baseFmt, int nFracDigits)
Numeric formatting utility function. The output is not Locale-sensitive, so is suitable for formatting numbers that may be re-parsed as numbers (by non-Locale-sensitive code).

Parameters:
  `value` - numeric value to format
  `baseFmt` - format string as for `DecimalFormat`
  `nFracDigits` - fixed number of digits after the decimal point
Returns:
  formatted string

### formatNumberSf

public static String formatNumberSf(double value, int nsf)
Numeric formatting utility function for writing a given number of significant figures. The output is not Locale-sensitive, so is suitable for formatting numbers that may be re-parsed as numbers (by non-Locale-sensitive code). Formatting is best-efforts and may suppress insignificant zeros.

Parameters:
  `value` - numeric value to format
  `nsf` - (approximate) number of significant figures
Returns:
  formatted string

### formatNumber

public static String formatNumber(double value, double epsilon)
Formats a number so that it presents a number of significant figures corresponding to a supplied small difference. The idea is that the output should be compact, but that applying this function to value and value+epsilon should give visibly different results. The number of significant figures is determined by epsilon, not further rounded (trailing zeroes are not truncated).

Parameters:
  `value` - value to format
  `epsilon` - small value
Returns:
  formatted value

### formatAxisRangeLimits

public static String[] formatAxisRangeLimits(double lo, double hi, boolean isLog, int npix)
Formats a pair of values representing data bounds of a range along a graphics axis. nge. The number of pixels separating the values is used to determine the formatting precision.

Parameters:
  `lo` - data lower bound
  `hi` - data upper bound
  `isLog` - true for logarithmic axis, false for linear
  `npix` - approximate number of pixels covered by the range
Returns:
  2-element array giving (lower,upper) bounds formatted and ready for presentation to the user

### roundNumber

public static double roundNumber(double x, double epsilon)
Rounds a number to a decimal round value. The number of decimal places is determined by the size of a supplied value, epsilon. When turned into a string, the final digit should be about the same size as epsilon. Given decimal->binary conversions and uncertain behaviour of library stringification methods like Double.toDouble() this isn't bulletproof and may require some adjustment, but it seems to work as desired most of the time.

Parameters:
  `x` - input value
  `epsilon` - indicates desired rounding amount
Returns:
  output value, presumably destined for stringification

### configLimits

public static ConfigMap configLimits(ConfigKey<Double> minKey, ConfigKey<Double> maxKey, double min, double max, int npix)
Utility method to set a minimum/maximum config key pair to a given pair of minimum/maximum values. This handles suitable rounding for presentation.

Parameters:
  `minKey` - config key for minimum value
  `maxKey` - config key for maximum value
  `min` - minimum value
  `max` - maximum value
  `npix` - number of pixels (quanta) between min and max; this is used to determine at what level of precision to round the config values

### subtractInsets

public static Rectangle subtractInsets(Rectangle base, Insets insets)
Returns the rectangle that results from removing the insets from a given rectangle.

Parameters:
  `base` - input rectangle
  `insets` - amount that should be excluded from the edges of the base rectangle
Returns:
  new, smaller rectangle

### getShadowTicks

public static Tick[] getShadowTicks(Tick[] ticks)
Returns an array of tickmarks that resembles the supplied ones, but with no labels. Major tickmarks are preserved though.

Parameters:
  `ticks` - input tick array
Returns:
  tick array without labels

### createLineGraphics

public static Graphics createLineGraphics(Graphics g, Color color)
Provides a graphics context based on an existing one that is suitable for drawing lines that may have a sub-unity alpha component.

For most purposes, this can be assumed to do the same as:

      Graphics g2 = g.create();
      g2.setColor(color);
      return g2;

However, it contains an additional hack that should improve output to graphics contexts that do not support transparency, such as to PostScript.

Briefly, for partially transparent colours in a PostScript context, the stroke width is multiplied by the supplied colour's alpha value, so that although the lines are still opaque, they are at least thin enough to look about right. It's better than nothing.

Parameters:
  `g` - input graphics context, unchanged on exit
  `color` - colour with which lines are to be drawn; may have a non-unity alpha component
Returns:
  graphics context to use for drawing lines