//
// AxisScale.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad;
import java.awt.Color;
import java.awt.Font;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import visad.util.HersheyFont;
/**
* Class which defines the scales displayed along the spatial axes
* of a display. Each ScalarMap that has a DisplayScalar of the
* X, Y, or Z axis will have a non-null AxisScale.
* @see ScalarMap#getAxisScale()
* @author Don Murray
*/
public class AxisScale implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/** X_AXIS identifier */
public static final int X_AXIS = 0;
/** Y_AXIS identifier */
public static final int Y_AXIS = 1;
/** Z_AXIS identifier */
public static final int Z_AXIS = 2;
/** identifier for primary label side of axis*/
public static final int PRIMARY = 0;
/** identifier for secondary label side of axis*/
public static final int SECONDARY = 1;
/** identifier for tertiary label side of axis*/
public static final int TERTIARY = 2;
/** identifier for quaternary label side of axis*/
public static final int QUATERNARY = 3;
// WLH 12 July 2001
// true indicates axis is stationary relative to screen
// rather than graphics coordinates
private boolean screenBased = false;
private boolean gridLinesVisible = false;
private boolean ticksVisible = true;
private boolean labelBothSides = false;
private VisADLineArray scaleArray;
private VisADTriangleArray labelArray;
private ScalarMap scalarMap;
private Color myColor = Color.white;
private double[] dataRange = new double[2];
private int myAxis = -1;
private int axisOrdinal = -1;
private String myTitle;
private Hashtable labelTable;
private double[] majorTicks = null;
private double[] minorTicks = null;
private double majorTickSpacing = 0.0;
private double minorTickSpacing = 0.0;
private double tickBase = 0.0;
private boolean autoComputeTicks = true;
private boolean baseLineVisible = true;
private boolean snapToBox = false;
private boolean userLabels = false;
private boolean visibility = true;
private boolean labelAllTicks = false; // label major ticks
private Object labelFont = null;
private int labelSize = 12;
private int axisSide = PRIMARY;
private int tickOrient = PRIMARY;
private static final double TICKSIZE = .5; // major ticks are 1/2 char ht.
private NumberFormat labelFormat = null;
/** Is the label angled away from the axis or is it "flat"*/
private boolean labelRelief = true;
/**
* Construct a new AxisScale for the given ScalarMap
* @param map ScalarMap to monitor. Must be mapped to one of
* Display.XAxis, Display.YAxis, Display.ZAxis
* @throws VisADException bad ScalarMap or other VisAD problem
*/
public AxisScale(ScalarMap map)
throws VisADException
{
scalarMap = map;
DisplayRealType displayScalar = scalarMap.getDisplayScalar();
if (!displayScalar.equals(Display.XAxis) &&
!displayScalar.equals(Display.YAxis) &&
!displayScalar.equals(Display.ZAxis)) {
throw new DisplayException("AxisSale: DisplayScalar " +
"must be XAxis, YAxis or ZAxis");
}
myAxis = (displayScalar.equals(Display.XAxis)) ? X_AXIS :
(displayScalar.equals(Display.YAxis)) ? Y_AXIS : Z_AXIS;
myTitle = scalarMap.getScalarName();
visibility = scalarMap.getScaleEnable();
labelTable = new Hashtable();
DisplayImpl display = scalarMap.getDisplay();
if (display != null) {
DisplayRenderer displayRenderer = display.getDisplayRenderer();
if (displayRenderer != null) {
float[] rgb = displayRenderer.getRendererControl().getForegroundColor();
myColor = new Color(rgb[0], rgb[1], rgb[2]);
boolean ok = makeScale();
}
}
}
/**
* Get the position of this AxisScale on the Axis (first, second, third).
*
* @return position from the axis (first = 0, second = 1, etc)
*/
public int getAxisOrdinal()
{
return axisOrdinal;
}
/**
* Set the position of this AxisScale on the axis. Should only
* be called by ScalarMap
* @param ordinalValue axis position (0 = first, 1 = second, etc)
*/
void setAxisOrdinal(int ordinalValue)
{
axisOrdinal = ordinalValue;
}
/**
* @deprecated
* Set the label to be used for this axis. The default is the
* ScalarName of the ScalarMap.
* @param label label to be used
* @see #setTitle(String)
*/
public void setLabel(String label)
{
setTitle(label);
}
/**
* @deprecated
* Get the label of the AxisScale.
* @return label
* @see #getTitle()
*/
public String getLabel()
{
return getTitle();
}
/**
* Set the title to be used for this axis. The default is the
* ScalarName of the ScalarMap.
* @param title title to be used
*/
public void setTitle(String title)
{
String oldTitle = myTitle;
myTitle = title;
if (!myTitle.equals(oldTitle) ) {
try {
// check for case where this was called from scalarmap.setScalarName()
if ( !myTitle.equals(scalarMap.getScalarName()) )
{
scalarMap.setScalarName(myTitle);
}
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Get the title of the AxisScale.
* @return title
*/
public String getTitle()
{
return myTitle;
}
/**
* Get axis that the scale will be displayed on.
* @return axis (X_AXIS, Y_AXIS or Z_AXIS)
*/
public int getAxis()
{
return myAxis;
}
/**
* Get the Scale to pass to the renderer.
* @return VisADLineArray representing the scale
*/
public VisADLineArray getScaleArray()
{
return scaleArray;
}
/**
* Get the labels rendered with a font to pass to the renderer.
* @return VisADTriangleArray representing the labels
*/
public VisADTriangleArray getLabelArray()
{
return labelArray;
}
/**
* set screenBased mode
* true indicates axis is stationary relative to screen
*/
public void setScreenBased(boolean sb) {
screenBased = sb;
}
/**
* return screenBased mode
* @return true if axis is stationary relative to screen
*/
public boolean getScreenBased() {
return screenBased;
}
/**
* Create the scale for screen based.
* @return true if scale was successfully created, otherwise false
*/
public boolean makeScreenBasedScale(double xmin, double ymin,
double xmax, double ymax,
double XTMIN, double YTMIN,
double XTMAX, double YTMAX)
throws VisADException {
DisplayImpl display = scalarMap.getDisplay();
if (display == null) return false;
DisplayRenderer displayRenderer = display.getDisplayRenderer();
if (displayRenderer == null) return false;
if (axisOrdinal < 0) return false;
dataRange = scalarMap.getRange();
// boolean twoD = displayRenderer.getMode2D();
if (!displayRenderer.getMode2D()) return false;
boolean twoD = true;
ProjectionControl pcontrol = display.getProjectionControl();
double[] aspect = pcontrol.getAspectCartesian();
double oldMax = 1.0;
double oldMin = -1.0;
double newMax = 1.0;
double newMin = -1.0;
if (myAxis == X_AXIS) {
oldMax = aspect[0];
oldMin = -aspect[0];
newMax = XTMAX;
newMin = XTMIN;
}
else if (myAxis == Y_AXIS) {
oldMax = aspect[1];
oldMin = -aspect[1];
newMax = YTMAX;
newMin = YTMIN;
}
double mult = (dataRange[1] - dataRange[0]) / (oldMax - oldMin);
double d1 = (newMax - oldMin) * mult + dataRange[0];
double d0 = (newMin - oldMin) * mult + dataRange[0];
double[] dr = {d0, d1};
double zmin = 0.0;
double zmax = -zmin;
// set scale according to labelSize
double scale = labelSize/200.;
double offset = 1.05;
// WLH 20 Feb 2003 keep screen-based YAxis label in Frame
scale *= 0.6; // hack size for screen based
// scale *= 0.8; // hack size for screen based
// Add 16-APR-2001 DRM
int position = 0;
int myPosition = 0;
// Snap to the box edge instead of being offset
if (snapToBox) {
offset = 1.0;
}
else
{
for (Enumeration e = display.getMapVector().elements();
e.hasMoreElements();)
{
ScalarMap map = (ScalarMap) e.nextElement();
if (map.getDisplayScalar().equals(scalarMap.getDisplayScalar()))
{
if (getSide() == map.getAxisScale().getSide())
{
if (!map.equals(scalarMap)) // same side someone else
{
position++;
} else {
myPosition = position;
}
}
}
}
}
/*
System.out.println(scalarMap + "is at position " + (myPosition+1) +
" out of " + (position + 1));
*/
// End Add 16-APR-2001 DRM
// position of baseline for this scale
double line = 4.0 * myPosition * scale; // DRM 17-APR-2001
return makeScale(twoD, xmin, ymin, zmin, xmax, ymax, zmax,
scale, offset, line, dr);
}
/**
* Create the scale.
* @return true if scale was successfully created, otherwise false
*/
public boolean makeScale()
throws VisADException {
DisplayImpl display = scalarMap.getDisplay();
if (display == null) return false;
DisplayRenderer displayRenderer = display.getDisplayRenderer();
if (displayRenderer == null) return false;
if (axisOrdinal < 0) {
axisOrdinal = displayRenderer.getAxisOrdinal(myAxis);
}
dataRange = scalarMap.getRange();
boolean twoD = displayRenderer.getMode2D();
// now create scale along axis at axisOrdinal position in array
// twoD may help define orientation
// WLH 24 Nov 2000
ProjectionControl pcontrol = display.getProjectionControl();
double[] aspect = pcontrol.getAspectCartesian();
double xmin = -aspect[0];
double ymin = -aspect[1];
double zmin = -aspect[2];
double xmax = -xmin;
double ymax = -ymin;
double zmax = -zmin;
// set scale according to labelSize
double scale = labelSize/200.;
double offset = 1.05;
// Add 16-APR-2001 DRM
int position = 0;
int myPosition = 0;
// Snap to the box edge instead of being offset
if (snapToBox) {
offset = 1.0;
}
else
{
for (Enumeration e = display.getMapVector().elements();
e.hasMoreElements();)
{
ScalarMap map = (ScalarMap) e.nextElement();
if (map.getDisplayScalar().equals(scalarMap.getDisplayScalar()))
{
if (getSide() == map.getAxisScale().getSide()) {
if (!map.equals(scalarMap)) // same side someone else
{
position++;
} else {
myPosition = position;// this is me
}
}
}
}
}
/*
System.out.println(scalarMap + "is at position " + (myPosition+1) +
" out of " + (position + 1));
*/
// End Add 16-APR-2001 DRM
// position of baseline for this scale
double line = 4.0 * myPosition * scale; // DRM 17-APR-2001
/* Remove 16-APR-2001
double one = 1.0;
if (dataRange[0] > dataRange[1]) one = -1.0; // inverted range
int position = axisOrdinal;
if (snapToBox) {
offset = 1.0;
position = 0;
}
double line = 2.0 * position * scale;
*/
return makeScale(twoD, xmin, ymin, zmin, xmax, ymax, zmax,
scale, offset, line, dataRange);
}
/** inner logic of makeScale with no references to display, displayRenderer
or scalarMap, allwoing more flexible placement of scales */
public boolean makeScale(boolean twoD, double xmin, double ymin, double zmin,
double xmax, double ymax, double zmax,
double scale, double offset, double line,
double[] dataRange)
throws VisADException {
// start new method here
// no references to display, scalarMap, or displayRenderer past this point
// compute graphics positions
// these are {x, y, z} vectors
double[] base = null; // vector from one character to another
double[] up = null; // vector from bottom of character to top
double[] startn = null; // -1.0 position along axis
double[] startp = null; // +1.0 position along axis
double[] gridstartn = null; // -1.0 position along axis
double[] gridstartp = null; // +1.0 position along axis
int numSides = (getLabelBothSides()) ? 2 : 1;
Vector lineArrayVector = new Vector(4*numSides);
Vector labelArrayVector = new Vector();
double one = 1.0;
if (dataRange[0] > dataRange[1]) one = -1.0; // inverted range
for (int l = 0; l < numSides; l++) {
int side = getSide();
side = (side + l) % (twoD ? 2 : 4);
// set up the defaults for each of the axes. startp and startn are the
// endpoints of the axis line. base and up determine which way the
// tick marks are drawn along that line. For 2-D, base and up are changed
// later on so that the labels are right side up. DRM 16-APR-2001
if (myAxis == X_AXIS) {
if (side == PRIMARY) {
base = new double[] {scale, 0.0, 0.0};
up = new double[] {0.0, scale, scale};
startp = new double[] {one * xmax,
ymin - ((offset - 1.0) + line),
zmin - ((offset - 1.0) + line)};
startn = new double[] {one * xmin,
ymin - ((offset - 1.0) + line),
zmin - ((offset - 1.0) + line)};
gridstartp = new double[] {one * xmax, ymin, zmin};
gridstartn = new double[] {one * xmin, ymin, zmin};
}
else if (side == SECONDARY) {
base = new double[] {-scale, 0.0, 0.0};
up = new double[] {0.0, -scale, scale};
startp = new double[] {one * xmax,
ymax + ((offset - 1.0) + line),
zmin - ((offset - 1.0) + line)};
startn = new double[] {one * xmin,
ymax + ((offset - 1.0) + line),
zmin - ((offset - 1.0) + line)};
gridstartp = new double[] {one * xmax, ymax, zmin};
gridstartn = new double[] {one * xmin, ymax, zmin};
}
else if (side == TERTIARY) {
base = new double[] {scale, 0.0, 0.0};
up = new double[] {0.0, scale, -scale};
startp = new double[] {one * xmax,
ymin - ((offset - 1.0) + line),
zmax + ((offset - 1.0) + line)};
startn = new double[] {one * xmin,
ymin - ((offset - 1.0) + line),
zmax + ((offset - 1.0) + line)};
gridstartp = new double[] {one * xmax, ymin, zmax};
gridstartn = new double[] {one * xmin, ymin, zmax};
}
else { // side == QUATERNARY
base = new double[] {-scale, 0.0, 0.0};
up = new double[] {0.0, -scale, -scale};
startp = new double[] {one * xmax,
ymax + ((offset - 1.0) + line),
zmax + ((offset - 1.0) + line)};
startn = new double[] {one * xmin,
ymax + ((offset - 1.0) + line),
zmax + ((offset - 1.0) + line)};
gridstartp = new double[] {one * xmax, ymax, zmax};
gridstartn = new double[] {one * xmin, ymax, zmax};
}
}
else if (myAxis == Y_AXIS) {
if (side == PRIMARY) {
base = new double[] {0.0, -scale, 0.0};
up = new double[] {scale, 0.0, scale};
startp = new double[] {xmin - ((offset - 1.0) + line),
one * ymax,
zmin - ((offset - 1.0) + line)};
startn = new double[] {xmin - ((offset - 1.0) + line),
one * ymin,
zmin - ((offset - 1.0) + line)};
gridstartp = new double[] {xmin, one * ymax, zmin};
gridstartn = new double[] {xmin, one * ymin, zmin};
}
else if (side == SECONDARY) {
base = new double[] {0.0, scale, 0.0};
up = new double[] {-scale, 0.0, scale};
startp = new double[] {xmax + ((offset - 1.0) + line),
one * ymax,
zmin - ((offset - 1.0) + line)};
startn = new double[] {xmax + ((offset - 1.0) + line),
one * ymin,
zmin - ((offset - 1.0) + line)};
gridstartp = new double[] {xmax, one * ymax, zmin};
gridstartn = new double[] {xmax, one * ymin, zmin};
}
else if (side == TERTIARY) {
base = new double[] {0.0, -scale, 0.0};
up = new double[] {scale, 0.0, -scale};
startp = new double[] {xmin - ((offset - 1.0) + line),
one * ymax,
zmax + ((offset - 1.0) + line)};
startn = new double[] {xmin - ((offset - 1.0) + line),
one * ymin,
zmax + ((offset - 1.0) + line)};
gridstartp = new double[] {xmin, one * ymax, zmax};
gridstartn = new double[] {xmin, one * ymin, zmax};
}
else { // side == QUATERNARY
base = new double[] {0.0, scale, 0.0};
up = new double[] {-scale, 0.0, -scale};
startp = new double[] {xmax + ((offset - 1.0) + line),
one * ymax,
zmax + ((offset - 1.0) + line)};
startn = new double[] {xmax + ((offset - 1.0) + line),
one * ymin,
zmax + ((offset - 1.0) + line)};
gridstartp = new double[] {xmax, one * ymax, zmax};
gridstartn = new double[] {xmax, one * ymin, zmax};
}
}
else if (myAxis == Z_AXIS) {
if (side == PRIMARY) {
base = new double[] {0.0, 0.0, -scale};
up = new double[] {scale, scale, 0.0};
startp = new double[] {xmin - ((offset - 1.0) + line),
ymin - ((offset - 1.0) + line),
one * zmax};
startn = new double[] {xmin - ((offset - 1.0) + line),
ymin - ((offset - 1.0) + line),
one * zmin};
gridstartp = new double[] {xmin, ymin, one * zmax};
gridstartn = new double[] {xmin, ymin, one * zmin};
}
else if (side == SECONDARY) {
base = new double[] {0.0, 0.0, scale};
up = new double[] {-scale, scale, 0.0};
startp = new double[] {xmax + ((offset - 1.0) + line),
ymin - ((offset - 1.0) + line),
one * zmax};
startn = new double[] {xmax + ((offset - 1.0) + line),
ymin - ((offset - 1.0) + line),
one * zmin};
gridstartp = new double[] {xmax, ymin, one * zmax};
gridstartn = new double[] {xmax, ymin, one * zmin};
}
else if (side == TERTIARY) {
base = new double[] {0.0, 0.0, -scale};
up = new double[] {scale, -scale, 0.0};
startp = new double[] {xmin - ((offset - 1.0) + line),
ymax + ((offset - 1.0) + line),
one * zmax};
startn = new double[] {xmin - ((offset - 1.0) + line),
ymax + ((offset - 1.0) + line),
one * zmin};
gridstartp = new double[] {xmin, ymax, one * zmax};
gridstartn = new double[] {xmin, ymax, one * zmin};
}
else { // side == QUATERNARY
base = new double[] {0.0, 0.0, scale};
up = new double[] {-scale, -scale, 0.0};
startp = new double[] {xmax + ((offset - 1.0) + line),
ymax + ((offset - 1.0) + line),
one * zmax};
startn = new double[] {xmax + ((offset - 1.0) + line),
ymax + ((offset - 1.0) + line),
one * zmin};
gridstartp = new double[] {xmax, ymax, one * zmax};
gridstartn = new double[] {xmax, ymax, one * zmin};
}
}
if (twoD) {
if (myAxis == Z_AXIS) return false; // can't have Z in 2D
// zero out z coordinates
base[2] = 0.0;
up[2] = 0.0;
startn[2] = 0.0;
startp[2] = 0.0;
}
if (!labelRelief ) {
up[2] = 0.0;
}
// VisADLineArray coordinates have three entries for (x, y, z) of each point
// two points determine a line segment,
// hence 6 coordinates entries per segment
// base line for axis
if (baseLineVisible) // draw base line
{
VisADLineArray baseLineArray = new VisADLineArray();
float[] lineCoordinates = new float[6];
for (int i=0; i<3; i++) { // loop over x, y & z coordinates
lineCoordinates[i] = (float) startn[i];
lineCoordinates[3 + i] = (float) startp[i];
}
baseLineArray.vertexCount = 2;
baseLineArray.coordinates = lineCoordinates;
lineArrayVector.add(baseLineArray);
}
double range = Math.abs(dataRange[1] - dataRange[0]);
double min = Math.min(dataRange[0], dataRange[1]);
double max = Math.max(dataRange[0], dataRange[1]);
//System.out.println(
// "range = " + range + " min = " + min + " max = " + max);
// compute tick mark values
double tens = 1.0;
if (range < tens) {
tens /= 10.0;
while (range < tens) tens /= 10.0;
}
else {
while (10.0 * tens <= range) tens *= 10.0;
}
// now tens <= range < 10.0 * tens;
if (autoComputeTicks || majorTickSpacing <= 0)
{
double ratio = range / tens;
if (ratio < 2.0) {
tens = tens/5.0;
}
else if (ratio < 4.0) {
tens = tens/2.0;
}
majorTickSpacing = tens;
}
// now tens = interval between major tick marks (majorTickSpacing)
//System.out.println("computed ticks " + majorTickSpacing);
//double[] hilo = computeTicks(max, min, tickBase, majorTickSpacing);
double[] hilo;
if (majorTicks == null) {
hilo = computeTicks(max, min, tickBase, majorTickSpacing);
} else {
hilo = computeTicks(max,min,majorTicks);
}
// firstValue is the first Tick mark value
//double firstValue = hilo[0];
//double botval = hilo[0];
//double topval = hilo[hilo.length-1];
// draw major tick marks
VisADLineArray majorTickArray = new VisADLineArray();
//int nticks = (int) ((topval-botval)/majorTickSpacing) + 1;
int nticks = hilo.length;
float[] majorCoordinates = new float[6 * nticks];
double[] tickup = up;
if (getTickOrientation() != PRIMARY)
{
if (myAxis == X_AXIS) {
tickup = new double[] {up[0], -up[1], -up[2]};
}
else if (myAxis == Y_AXIS) {
tickup = new double[] {-up[0], up[1], -up[2]};
}
else if (myAxis == Z_AXIS) {
tickup = new double[] {-up[0], -up[1], up[2]};
}
}
// initialize some stuff
int k = 0;
if (ticksVisible) {
for (int j = 0; j< nticks; j++) //Change DRM 21-Feb-2001
{
//double value = firstValue + (j * majorTickSpacing);
double value = hilo[j];
double a = (value - min) / (max - min);
for (int i=0; i<3; i++) {
if ((k + 3 + i) < majorCoordinates.length) {
// guard against error that cannot happen, but was seen?
majorCoordinates[k + i] =
(float) ((1.0 - a) * startn[i] + a * startp[i]);
majorCoordinates[k + 3 + i] =
(float) (majorCoordinates[k + i] - TICKSIZE * tickup[i]);
}
}
k += 6;
}
majorTickArray.vertexCount = 2 * (nticks);
majorTickArray.coordinates = majorCoordinates;
lineArrayVector.add(majorTickArray);
}
if (gridLinesVisible && l == 0) {
VisADLineArray gridArray = new VisADLineArray();
float[] gridCoordinates = new float[6 * nticks];
// initialize some stuff
k = 0;
double[] gridup = null;
double gridLength = 1.0;
if (myAxis == X_AXIS) {
gridup = new double[] {0, up[1], 0};
gridLength = (ymax-ymin)/scale;
}
else if (myAxis == Y_AXIS) {
gridup = new double[] {up[0], 0, 0};
gridLength = (xmax-xmin)/scale;
}
else if (myAxis == Z_AXIS) {
gridup = new double[] {up[0], 0, 0};
gridLength = (xmax-xmin)/scale;
}
for (int j = 0; j< nticks; j++) //Change DRM 21-Feb-2001
{
//double value = firstValue + (j * majorTickSpacing);
double value = hilo[j];
double a = (value - min) / (max - min);
for (int i=0; i<3; i++) {
if ((k + 3 + i) < gridCoordinates.length) {
// guard against error that cannot happen, but was seen?
gridCoordinates[k + i] =
(float) ((1.0 - a) * gridstartn[i] + a * gridstartp[i]);
gridCoordinates[k + 3 + i] =
(float) (gridCoordinates[k + i] + gridLength*gridup[i]);
}
}
k += 6;
}
gridArray.vertexCount = 2 * (nticks);
gridArray.coordinates = gridCoordinates;
lineArrayVector.add(gridArray);
}
// create an array for the minor ticks
if ((getMinorTickSpacing() > 0 || minorTicks != null) && ticksVisible)
{
//hilo = computeTicks(max, min, tickBase, minorTickSpacing);
double[] minorTicksToDraw;
if (minorTicks == null) {
minorTicksToDraw = computeTicks(max, min, tickBase, minorTickSpacing);
} else {
minorTicksToDraw = computeTicks(max, min, minorTicks);
}
// now lower * minorTickSpacing = value of lowest tick mark, and
// upper * minorTickSpacing = values of highest tick mark
VisADLineArray minorTickArray = new VisADLineArray();
// Change DRM 21-Feb-2001
//nticks = (int) ((hilo[hilo.length-1]-hilo[0])/minorTickSpacing) + 1;
nticks = minorTicksToDraw.length;
float[] minorCoordinates = new float[6 * nticks];
// draw tick marks
k = 0;
//for (long j=lower; j<=upper; j++) { // Change DRM 21-Feb-2001
for (int j = 0; j < nticks; j++)
{
//double val = hilo[0] + (j * minorTickSpacing);
double val = minorTicksToDraw[j];
double a = (val - min) / (max - min);
for (int i=0; i<3; i++) {
if ((k + 3 + i) < minorCoordinates.length) {
// guard against error that cannot happen, but was seen?
minorCoordinates[k + i] =
(float) ((1.0 - a) * startn[i] + a * startp[i]);
// minor ticks are half the size of the major ticks
minorCoordinates[k + 3 + i] =
(float) (minorCoordinates[k + i] - TICKSIZE/2 * tickup[i]);
}
}
k += 6;
}
minorTickArray.vertexCount = 2 * (nticks);
minorTickArray.coordinates = minorCoordinates;
lineArrayVector.add(minorTickArray);
}
// Title and labels
// by default, all labels rendered centered
TextControl.Justification justification =
TextControl.Justification.CENTER;
// PlotText is controlled by the initial starting point, base (controls
// direction) and up (which way is up). We handle 2D and 3D differently.
// In 2-D, titles are drawn along the positive direction of the axis.
// Labels are drawn in the Y-positive direction.
// Labels first
if (twoD) {
if (myAxis == X_AXIS) {
up = new double[] {0.0, scale, 0.0};
}
else if (myAxis == Y_AXIS) {
up = new double[] {-scale, 0.0, 0.0};
}
}
// Draw the labels. If user hasn't defined their own, make defaults.
if (!userLabels) {
//createStandardLabels(topval, botval, botval,
// (labelAllTicks == false)
// ?(topval - botval):majorTickSpacing,
// false);
createLabels(hilo, false);
}
double dist = 1.0 + TICKSIZE; // dist from the line in the up direction;
double[] updir = (twoD != true) ? up : new double[] {0.0, scale, 0.0};
if (twoD) {
base = new double[] {scale, 0.0, 0.0};
if (myAxis == X_AXIS) {
dist = (side == PRIMARY)
? (1.0 + TICKSIZE + .15)
: -(TICKSIZE + .15);
}
else if (myAxis == Y_AXIS) {
dist = (side == PRIMARY)
? -(TICKSIZE + .15)
: (TICKSIZE + .15);
justification =
(side == PRIMARY)
? TextControl.Justification.RIGHT
: TextControl.Justification.LEFT;
}
}
// Added by Luke Catania on 05/07/2002
// Added maximumYAxisTickLabelSize & yAxisLabelLength to calculate
// offset for Y-Axis label.
//
int maximumYAxisTickLabelSize = 1;
int yAxisLabelLength=0;
Hashtable localTable;
synchronized(labelTable) {
localTable = new Hashtable(labelTable);
}
for (Enumeration e = localTable.keys(); e.hasMoreElements();)
{
Double value;
try {
value = (Double) e.nextElement();
} catch (ClassCastException cce) {
throw new VisADException("Invalid keys in label hashtable");
}
double test = value.doubleValue();
if (test > max || test < min) continue; // don't draw labels beyond range
// Added by Luke Catania on 05/07/2002 - mods by DRM 28-Oct-2002
// For Y-Axis only, calculate offset for axis label, so it does
// not overlap the tick labels.
if (myAxis == Y_AXIS) {
yAxisLabelLength = ((String) localTable.get(value)).length();
if (yAxisLabelLength > maximumYAxisTickLabelSize)
maximumYAxisTickLabelSize = yAxisLabelLength;
}
double val = (test - min) / (max - min);
// center label on tick if Y axis and 2D
if ((myAxis == Y_AXIS) && (twoD == true)) val -= .2 * scale; // HACK!!!!!
double[] point = new double[3];
for (int j=0; j < 3; j++) {
point[j] = (1.0 - val) * startn[j] + val * startp[j] - dist * up[j];
// if (myAxis == Y_AXIS) System.out.println("Axis & Tick Label Position for " + test + ": " + startn[j] + ":" + startp[j] + ":" + point[j]);
}
/*
System.out.println("For label = " + value.doubleValue() + "(" + val + "), point is (" + point[0] + "," + point[1] + "," + point[2] + ")");
*/
if (labelFont == null)
{
VisADLineArray label =
PlotText.render_label((String) localTable.get(value), point, base, updir, justification);
lineArrayVector.add(label);
}
else if (labelFont instanceof Font)
{
VisADTriangleArray label =
PlotText.render_font(
(String) localTable.get(value), (Font) labelFont, point, base,
updir, justification);
labelArrayVector.add(label);
} else if (labelFont instanceof HersheyFont) {
VisADLineArray label =
PlotText.render_font(
(String) localTable.get(value), (HersheyFont) labelFont,
point, base, updir, justification);
lineArrayVector.add(label);
}
}
// Title
double[] startlabel = new double[3];
dist = 2.0 + TICKSIZE; // dist from the line in the up direction;
justification =
TextControl.Justification.CENTER;
if (twoD) {
if (myAxis == X_AXIS) {
base = new double[] {scale, 0.0, 0.0};
up = new double[] {0.0, scale, 0.0};
dist = (side == PRIMARY)
? 2.5 + TICKSIZE
: -(1.5 + TICKSIZE - .05);
}
else if (myAxis == Y_AXIS) {
base = new double[] {0.0, scale, 0.0};
up = new double[] {-scale, 0.0, 0.0};
dist = (side == PRIMARY)
? -(.5 + TICKSIZE + maximumYAxisTickLabelSize)
: (.5 + TICKSIZE + maximumYAxisTickLabelSize) ;
}
}
for (int i=0; i<3; i++) {
startlabel[i] = 0.5 * (startn[i] + startp[i]) - dist * up[i];
}
/*
System.out.println("For title, point is (" +
startlabel[0] + "," + startlabel[1] + "," + startlabel[2] + ")");
*/
if (labelFont == null)
{
VisADLineArray plotArray =
PlotText.render_label(myTitle, startlabel, base, up, justification);
lineArrayVector.add(plotArray);
}
else if (labelFont instanceof java.awt.Font)
{
VisADTriangleArray nameArray =
PlotText.render_font(myTitle, (Font) labelFont,
startlabel, base, up, justification);
labelArrayVector.add(nameArray);
} else if (labelFont instanceof visad.util.HersheyFont) {
VisADLineArray plotArray =
PlotText.render_font(myTitle, (HersheyFont) labelFont,
startlabel, base, up, justification);
lineArrayVector.add(plotArray);
}
// merge the line arrays
VisADLineArray[] arrays =
(VisADLineArray[]) lineArrayVector.toArray(
new VisADLineArray[lineArrayVector.size()]);
scaleArray = VisADLineArray.merge(arrays);
// merge the label arrays
labelArray = new VisADTriangleArray();
if ( !(labelArrayVector.isEmpty()) )
{
VisADTriangleArray[] labelArrays =
(VisADTriangleArray[]) labelArrayVector.toArray(
new VisADTriangleArray[labelArrayVector.size()]);
labelArray = VisADTriangleArray.merge(labelArrays);
// set the color for the label arrays
float[] rgb = myColor.getColorComponents(null);
byte red = ShadowType.floatToByte(rgb[0]);
byte green = ShadowType.floatToByte(rgb[1]);
byte blue = ShadowType.floatToByte(rgb[2]);
int n = 3 * labelArray.vertexCount;
byte[] colors = new byte[n];
for (int i=0; i<n; i+=3) {
colors[i] = red;
colors[i+1] = green;
colors[i+2] = blue;
}
labelArray.colors = colors;
}
}
return true;
}
/**
* Get the color of this axis scale.
*
* @return Color of the scale.
*/
public Color getColor()
{
return myColor;
}
/**
* Set the color of this axis scale.
* @param color Color to use
*/
public void setColor(Color color)
{
Color oldColor = myColor;
myColor = color;
if (myColor != null && !myColor.equals(oldColor)) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Set the color of this axis scale.
* @param color array of red, green, and blue values in
* the range (0.0 - 1.0). color must be float[3].
*/
public void setColor(float[] color)
{
setColor(new Color(color[0], color[1], color[2]));
}
/**
* Clone the properties of this AxisScale. Should only be used
* by ScalarMap and map should have the same DisplayScalar as
* this scalar's
* @param map map to use for creating the new Axis
* @throws VisADException display scalars are not equal
*/
AxisScale clone(ScalarMap map)
throws VisADException
{
AxisScale newScale = new AxisScale(map);
if (!(map.getDisplayScalar().equals(scalarMap.getDisplayScalar())))
throw new VisADException(
"AxisScale: DisplayScalar for map is not" +
scalarMap.getDisplayScalar());
newScale.myColor = myColor;
newScale.axisOrdinal = axisOrdinal;
newScale.myAxis = myAxis;
newScale.myTitle = myTitle;
newScale.labelTable = (Hashtable) labelTable.clone();
newScale.majorTickSpacing = majorTickSpacing;
newScale.minorTickSpacing = minorTickSpacing;
newScale.autoComputeTicks = autoComputeTicks;
newScale.baseLineVisible = baseLineVisible;
newScale.snapToBox = snapToBox;
newScale.labelFont = labelFont;
newScale.labelSize = labelSize;
newScale.axisSide = axisSide;
newScale.tickOrient = tickOrient;
newScale.userLabels = userLabels;
newScale.labelAllTicks = labelAllTicks;
newScale.gridLinesVisible = gridLinesVisible;
newScale.ticksVisible = ticksVisible;
newScale.labelBothSides = labelBothSides;
return newScale;
}
/**
* Set major tick mark spacing. The number that is passed-in represents
* the distance, measured in values, between each major tick mark. If you
* have a ScalarMap with a range from 0 to 50 and the major tick spacing
* is set to 10, you will get major ticks next to the following values:
* 0, 10, 20, 30, 40, 50. This value will always be used unless
* you call {@link #setAutoComputeTicks(boolean) setAutoComputeTicks}
* with a <CODE>true</CODE> value.
* @param spacing spacing between major tick marks (must be > 0)
* @see #getMajorTickSpacing
* @see #setAutoComputeTicks
*/
public void setMajorTickSpacing(double spacing)
{
double oldValue = majorTickSpacing;
majorTickSpacing = Math.abs(spacing);
autoComputeTicks = false;
if (majorTickSpacing != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Set major tick marks. Tick marks will be placed at the values on
* the axis.
* @param majorTicks the tick values
*/
public void setMajorTicks(double[] majorTicks)
{
this.majorTicks = majorTicks;
autoComputeTicks = false;
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
/**
* Set minor tick marks. Tick marks will be placed at the values on
* the axis.
* @param minorTicks the tick values
*/
public void setMinorTicks(double[] minorTicks)
{
this.minorTicks = minorTicks;
autoComputeTicks = false;
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
/**
* This method returns the major tick spacing. The number that is returned
* represents the distance, measured in values, between each major tick mark.
*
* @return the number of values between major ticks
* @see #setMajorTickSpacing
*/
public double getMajorTickSpacing() {
return majorTickSpacing;
}
/**
* Set minor tick mark spacing. The number that is passed-in represents
* the distance, measured in values, between each minor tick mark. If you
* have a ScalarMap with a range from 0 to 50 and the minor tick spacing
* is set to 10, you will get minor ticks next to the following values:
* 0, 10, 20, 30, 40, 50. This value will always be used unless
* you call {@link #setAutoComputeTicks(boolean) setAutoComputeTicks}
* with a <CODE>true</CODE> value.
* @param spacing spacing between minor tick marks (must be > 0)
* @see #getMinorTickSpacing
* @see #setAutoComputeTicks
*/
public void setMinorTickSpacing(double spacing)
{
double oldValue = minorTickSpacing;
minorTickSpacing = Math.abs(spacing);
if (minorTickSpacing != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* This method returns the minor tick spacing. The number that is returned
* represents the distance, measured in values, between each minor tick mark.
*
* @return the number of values between minor ticks
* @see #setMinorTickSpacing
*/
public double getMinorTickSpacing() {
return minorTickSpacing;
}
/**
* Allow the AxisScale to automatically compute the desired majorTickSpacing
* based on the range of the ScalarMap.
* @param b if true, have majorTickSpacing automatically computed.
*/
public void setAutoComputeTicks(boolean b)
{
boolean oldValue = autoComputeTicks;
autoComputeTicks = b;
if (autoComputeTicks != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Creates a hashtable that will draw text labels starting at the
* starting point specified using the increment field.
* If you call createStandardLabels(100, 0, 2.0, 10.0), then it will
* make labels for the values 2, 12, 22, 32, etc.
*
* @see #setLabelTable
* @throws IllegalArgumentException if min > max, or increment is
* greater than max-min
*/
public void createStandardLabels(
double max, double min, double base, double increment)
{
if (min > max) {
throw new IllegalArgumentException("max must be greater than min");
}
if (increment > (max-min)) {
throw new IllegalArgumentException(
"increment must be less than or equal to range (max-min)");
}
createStandardLabels(max, min, base, increment, true);
}
/**
* private copy to allow program to create table, but not remake scale
*/
private void createStandardLabels(
double max, double min, double base, double increment, boolean byuser)
{
synchronized(labelTable) {
labelTable.clear();
double[] values = computeTicks(max, min, base, increment);
if (values != null) {
for (int i = 0; i < values.length; i++) {
labelTable.put(new Double(values[i]), createLabelString(values[i]));
}
}
}
if (byuser) {
try {
userLabels = true;
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* private copy to allow program to create table, but not remake scale
*/
private void createLabels(double[] values, boolean byuser)
{
synchronized(labelTable) {
labelTable.clear();
if (values != null) {
if (getLabelAllTicks()) {
for (int i = 0; i < values.length; i++) {
labelTable.put(new Double(values[i]), createLabelString(values[i]));
}
} else{
labelTable.put(new Double(values[0]), createLabelString(values[0]));
labelTable.put(new Double(values[values.length-1]), createLabelString(values[values.length-1]));
}
}
}
if (byuser) {
try {
userLabels = true;
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Used to specify what label will be drawn at any given value.
* The key-value pairs are of this format:
* <B>{ Double value, java.lang.String}</B>
*
* @param labels map of value/label pairs
* @throws VisADException invalid hashtable
* @see #getLabelTable
*/
public void setLabelTable( Hashtable labels )
throws VisADException
{
Map oldTable = labelTable;
labelTable = labels;
if (labels != oldTable) {
userLabels = true;
scalarMap.makeScale(); // update the display
}
}
/**
* Get the Hashtable used for labels
*/
public Hashtable getLabelTable()
{
return labelTable;
}
/**
* Set the font used for rendering the labels
* @param font new font to use
*/
public void setFont(Font font)
{
Object oldFont = labelFont;
labelFont = font;
if ((labelFont == null && oldFont != null) ||
(labelFont != null && !labelFont.equals(oldFont)))
//if (labelFont != null && !labelFont.equals(oldFont))
{
if (labelFont != null && labelFont instanceof java.awt.Font) {
labelSize = ((Font) labelFont).getSize();
}
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Set the font used for rendering the labels
* @param font new font to use
*/
public void setFont(HersheyFont font)
{
Object oldFont = labelFont;
labelFont = font;
if ((labelFont == null && oldFont != null) ||
(labelFont != null && !labelFont.equals(oldFont)))
//if (labelFont != null && !labelFont.equals(oldFont))
{
labelSize = 12;
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Get the font used for rendering the labels
* @return font use or null if using default text plot
*/
public Font getFont()
{
return (labelFont instanceof Font) ? (Font)labelFont : null;
}
/**
* Set visibility of base line.
* @param visible true to display (default), false to turn off
*/
public void setBaseLineVisible(boolean visible)
{
boolean oldValue = baseLineVisible;
baseLineVisible = visible;
if (baseLineVisible != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Determine whether the base line for the scale should be visible
* @return true if line is visible, otherwise false;
*/
public boolean getBaseLineVisible()
{
return baseLineVisible;
}
/**
* Toggle whether the scale is along the box edge or not
* @param b true to snap to the box
*/
public void setSnapToBox(boolean b)
{
boolean oldValue = snapToBox;
snapToBox = b;
if (snapToBox != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Determine whether this property is set.
* @return true if property is set, otherwise false;
*/
public boolean getSnapToBox()
{
return snapToBox;
}
/**
* Sets the size of the labels. You can use this to change the label
* size when a <CODE>Font</CODE> is not being used. If a <CODE>Font</CODE>
* is being used and you call setLabelSize(), a new <CODE>Font</CODE> is
* created using the old <CODE>Font</CODE> name and style, but with the
* new size.
* @param size font size to use
* @see #setFont
*/
public void setLabelSize(int size)
{
int oldSize = labelSize;
labelSize = size;
if (labelSize != oldSize) {
if (labelFont != null) {
if (labelFont instanceof java.awt.Font) labelFont =
new Font( ((Font)labelFont).getName(),
((Font)labelFont).getStyle(), labelSize);
}
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Gets the size of the labels.
* @return relative size of labels
*/
public int getLabelSize()
{
return labelSize;
}
/**
* Sets the base value for tick marks. This only applies when
* <CODE>setMajorTickSpacing</CODE> or <CODE>setMinorTickSpacing</CODE>
* have been called.
* @param base base value for drawing tick marks. For example, if
* your scale ranges from -4 to 18 and you set the
* major tick spacing to 5, you will get ticks at
* -4, 1, 6, 11, and 16 by default. If you set the tick
* base value to 0, you will get ticks at 0, 5, 10, 15.
*/
public void setTickBase(double base)
{
double oldBase = tickBase;
tickBase = base;
if (tickBase != oldBase) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Set side for axis (PRIMARY, SECONDARY)
* @param side side for axis to appear on
*/
public void setSide(int side)
{
// sanity check
if (side != PRIMARY && side != SECONDARY &&
side != TERTIARY && side != QUATERNARY)
{
return;
}
if (axisSide == side) return;
axisSide = side;
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
/**
* Get the alignment for the axis
* @return axis alignment (PRIMARY or SECONDARY)
*/
public int getSide()
{
return axisSide;
}
/**
* Set orientation of tick marks along the axis line.
* @param orient (PRIMARY or SECONDARY)
*/
public void setTickOrientation(int orient)
{
double oldOrient = tickOrient;
tickOrient =
(orient == SECONDARY) ? SECONDARY : PRIMARY; // sanity check
if (tickOrient != oldOrient) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Get the orientation for the ticks along the axis
* @return tick orientation (PRIMARY or SECONDARY)
*/
public int getTickOrientation()
{
return tickOrient;
}
/**
* Set the formatting for all labels
* @param format format string
*/
public void setNumberFormat(NumberFormat format)
{
labelFormat = format;
}
/**
* Get the formatting for labels. May be null (if not set)
* @return format used for labeling
*/
public NumberFormat getNumberFormat() { return labelFormat; }
/**
* Set the visibility of the AxisScale
* @param visible true to display the AxisScale
*/
public void setVisible(boolean visible) {
boolean oldVisibility = visibility;
visibility = visible;
if (!(oldVisibility == visibility) ) {
try {
// check for case if this was called from scalarmap.setScaleEnable()
if ( !(visible == scalarMap.getScaleEnable()) ) {
scalarMap.setScaleEnable(visible);
}
scalarMap.makeScale(); // update the display
} catch (VisADException ve) {;}
}
}
/**
* Get the visibility of the AxisScale
* @return true if AxisScale is being rendered
*/
public boolean isVisible() {
return scalarMap.getScaleEnable();
}
/**
* Set the visibility of the grid lines; Grid lines are placed
* at major tick marks.
* @param show true to display the grid lines
*/
public void setGridLinesVisible(boolean show) {
boolean oldShow = gridLinesVisible;
gridLinesVisible = show;
if (!(oldShow == show) ) {
try {
scalarMap.makeScale(); // update the display
} catch (VisADException ve) {;}
}
}
/**
* Get the visibility of the grid lines
* @return true if grid lines are being rendered
*/
public boolean getGridLinesVisible() {
return gridLinesVisible;
}
/**
* Set whether both sides are labeled.
* @param both true to label both sides
*/
public void setLabelBothSides(boolean both) {
boolean oldBoth = labelBothSides;
labelBothSides = both;
if (!(oldBoth == both) ) {
try {
scalarMap.makeScale(); // update the display
} catch (VisADException ve) {;}
}
}
/**
* See if both sides are labeled
* @return true if labelling is on both sides
*/
public boolean getLabelBothSides() {
return labelBothSides;
}
/**
* Set whether ticks are visible
* @param visible true to show ticks
*/
public void setTicksVisible(boolean visible) {
boolean oldValue = ticksVisible;
ticksVisible = visible;
if (!(oldValue == visible) ) {
try {
scalarMap.makeScale(); // update the display
} catch (VisADException ve) {;}
}
}
/**
* See if ticks are visible
* @return true if labeling is on both sides
*/
public boolean getTicksVisible() {
return ticksVisible;
}
/**
* Set whether all major ticks should be labeled. The default is
* to only label the first and last major tick. This setting is
* ignored if user labels are being used or if user manually
* calls {@link #createStandardLabels(double, double, double, double)
* createStandardLabels} or {@link #setLabelTable(Hashtable)
* setLabelTable}
* @see #getLabelAllTicks()
* @see #createStandardLabels(double, double, double, double)
* @see #setLabelTable(Hashtable)
*
* @param labelAll true to label all (major) ticks. Overridden
*/
public void setLabelAllTicks(boolean labelAll) {
boolean oldValue = labelAllTicks;
labelAllTicks = labelAll;
if (labelAllTicks != oldValue) {
try {
scalarMap.makeScale(); // update the display
}
catch (VisADException ve) {;}
}
}
/**
* Return whether all major ticks are to be labeled.
* @return true if ticks are to be labeled.
*/
public boolean getLabelAllTicks() {
return labelAllTicks;
}
/** compute the tick mark values */
private double[] computeTicks(double high, double low,
double base, double interval)
{
double[] vals = null;
// compute nlo and nhi, for low and high contour values in the box
long nlo = Math.round((Math.ceil((low - base) / Math.abs(interval))));
long nhi = Math.round((Math.floor((high - base) / Math.abs(interval))));
// how many contour lines are needed.
int numc = (int) (nhi - nlo) + 1;
if (numc < 1) return new double[] {low, high};
vals = new double[numc];
for(int i = 0; i < numc; i++) {
vals[i] = base + (nlo + i) * interval;
}
return vals;
}
/** compute the tick mark values that are between max and min */
private double[] computeTicks(double max, double min,
double[] ticks)
{
double[] vals = new double[ticks.length];
Arrays.sort(ticks);
int numTicks = 0;
for (int i = 0; i < ticks.length; i++) {
double tick = ticks[i];
if (tick <= max && tick >= min) {
vals[numTicks++] = tick;
}
}
if (numTicks < ticks.length) {
double[] newVals = new double[numTicks];
System.arraycopy(vals,0,newVals,0,numTicks);
return newVals;
}
return vals;
}
/** create the default string for a value */
private String createLabelString(double value)
{
String label = null;
ScalarType sType = scalarMap.getScalar();
if (sType instanceof RealType)
{
RealType rType = (RealType)sType;
Unit unit = rType.getDefaultUnit();
if (Unit.canConvert(CommonUnit.secondsSinceTheEpoch, unit) &&
!unit.getAbsoluteUnit().equals(unit))
{
label = new Real(rType, value).toValueString();
}
else
{
label =
(labelFormat != null)
? labelFormat.format(value)
: PlotText.shortString(value);
}
}
else
{
label =
(labelFormat != null)
? labelFormat.format(value)
: PlotText.shortString(value);
}
return label;
}
/**
* Checks if is label has relief.
*
* @return true, if is label has relief
*/
public boolean isLabelRelief() {
return labelRelief;
}
/**
* Sets the label relief.
*
* @param labelRelief the new label relief
*/
public void setLabelRelief(boolean labelRelief) {
this.labelRelief = labelRelief;
}
}