📄 valueaxis.java
字号:
* Sets the shape that can be displayed as an arrow pointing upwards at
* the end of an axis line and sends an {@link AxisChangeEvent} to all
* registered listeners.
*
* @param arrow the arrow shape (<code>null</code> not permitted).
*
* @see #getUpArrow()
*/
public void setUpArrow(Shape arrow) {
if (arrow == null) {
throw new IllegalArgumentException("Null 'arrow' argument.");
}
this.upArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Returns a shape that can be displayed as an arrow pointing downwards at
* the end of an axis line.
*
* @return A shape (never <code>null</code>).
*
* @see #setDownArrow(Shape)
*/
public Shape getDownArrow() {
return this.downArrow;
}
/**
* Sets the shape that can be displayed as an arrow pointing downwards at
* the end of an axis line and sends an {@link AxisChangeEvent} to all
* registered listeners.
*
* @param arrow the arrow shape (<code>null</code> not permitted).
*
* @see #getDownArrow()
*/
public void setDownArrow(Shape arrow) {
if (arrow == null) {
throw new IllegalArgumentException("Null 'arrow' argument.");
}
this.downArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Returns a shape that can be displayed as an arrow pointing left at the
* end of an axis line.
*
* @return A shape (never <code>null</code>).
*
* @see #setLeftArrow(Shape)
*/
public Shape getLeftArrow() {
return this.leftArrow;
}
/**
* Sets the shape that can be displayed as an arrow pointing left at the
* end of an axis line and sends an {@link AxisChangeEvent} to all
* registered listeners.
*
* @param arrow the arrow shape (<code>null</code> not permitted).
*
* @see #getLeftArrow()
*/
public void setLeftArrow(Shape arrow) {
if (arrow == null) {
throw new IllegalArgumentException("Null 'arrow' argument.");
}
this.leftArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Returns a shape that can be displayed as an arrow pointing right at the
* end of an axis line.
*
* @return A shape (never <code>null</code>).
*
* @see #setRightArrow(Shape)
*/
public Shape getRightArrow() {
return this.rightArrow;
}
/**
* Sets the shape that can be displayed as an arrow pointing rightwards at
* the end of an axis line and sends an {@link AxisChangeEvent} to all
* registered listeners.
*
* @param arrow the arrow shape (<code>null</code> not permitted).
*
* @see #getRightArrow()
*/
public void setRightArrow(Shape arrow) {
if (arrow == null) {
throw new IllegalArgumentException("Null 'arrow' argument.");
}
this.rightArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Draws an axis line at the current cursor position and edge.
*
* @param g2 the graphics device.
* @param cursor the cursor position.
* @param dataArea the data area.
* @param edge the edge.
*/
protected void drawAxisLine(Graphics2D g2, double cursor,
Rectangle2D dataArea, RectangleEdge edge) {
Line2D axisLine = null;
if (edge == RectangleEdge.TOP) {
axisLine = new Line2D.Double(dataArea.getX(), cursor,
dataArea.getMaxX(), cursor);
}
else if (edge == RectangleEdge.BOTTOM) {
axisLine = new Line2D.Double(dataArea.getX(), cursor,
dataArea.getMaxX(), cursor);
}
else if (edge == RectangleEdge.LEFT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor,
dataArea.getMaxY());
}
else if (edge == RectangleEdge.RIGHT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor,
dataArea.getMaxY());
}
g2.setPaint(getAxisLinePaint());
g2.setStroke(getAxisLineStroke());
g2.draw(axisLine);
boolean drawUpOrRight = false;
boolean drawDownOrLeft = false;
if (this.positiveArrowVisible) {
if (this.inverted) {
drawDownOrLeft = true;
}
else {
drawUpOrRight = true;
}
}
if (this.negativeArrowVisible) {
if (this.inverted) {
drawUpOrRight = true;
}
else {
drawDownOrLeft = true;
}
}
if (drawUpOrRight) {
double x = 0.0;
double y = 0.0;
Shape arrow = null;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
x = dataArea.getMaxX();
y = cursor;
arrow = this.rightArrow;
}
else if (edge == RectangleEdge.LEFT
|| edge == RectangleEdge.RIGHT) {
x = cursor;
y = dataArea.getMinY();
arrow = this.upArrow;
}
// draw the arrow...
AffineTransform transformer = new AffineTransform();
transformer.setToTranslation(x, y);
Shape shape = transformer.createTransformedShape(arrow);
g2.fill(shape);
g2.draw(shape);
}
if (drawDownOrLeft) {
double x = 0.0;
double y = 0.0;
Shape arrow = null;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
x = dataArea.getMinX();
y = cursor;
arrow = this.leftArrow;
}
else if (edge == RectangleEdge.LEFT
|| edge == RectangleEdge.RIGHT) {
x = cursor;
y = dataArea.getMaxY();
arrow = this.downArrow;
}
// draw the arrow...
AffineTransform transformer = new AffineTransform();
transformer.setToTranslation(x, y);
Shape shape = transformer.createTransformedShape(arrow);
g2.fill(shape);
g2.draw(shape);
}
}
/**
* Calculates the anchor point for a tick label.
*
* @param tick the tick.
* @param cursor the cursor.
* @param dataArea the data area.
* @param edge the edge on which the axis is drawn.
*
* @return The x and y coordinates of the anchor point.
*/
protected float[] calculateAnchorPoint(ValueTick tick,
double cursor,
Rectangle2D dataArea,
RectangleEdge edge) {
RectangleInsets insets = getTickLabelInsets();
float[] result = new float[2];
if (edge == RectangleEdge.TOP) {
result[0] = (float) valueToJava2D(tick.getValue(), dataArea, edge);
result[1] = (float) (cursor - insets.getBottom() - 2.0);
}
else if (edge == RectangleEdge.BOTTOM) {
result[0] = (float) valueToJava2D(tick.getValue(), dataArea, edge);
result[1] = (float) (cursor + insets.getTop() + 2.0);
}
else if (edge == RectangleEdge.LEFT) {
result[0] = (float) (cursor - insets.getLeft() - 2.0);
result[1] = (float) valueToJava2D(tick.getValue(), dataArea, edge);
}
else if (edge == RectangleEdge.RIGHT) {
result[0] = (float) (cursor + insets.getRight() + 2.0);
result[1] = (float) valueToJava2D(tick.getValue(), dataArea, edge);
}
return result;
}
/**
* Draws the axis line, tick marks and tick mark labels.
*
* @param g2 the graphics device.
* @param cursor the cursor.
* @param plotArea the plot area.
* @param dataArea the data area.
* @param edge the edge that the axis is aligned with.
*
* @return The width or height used to draw the axis.
*/
protected AxisState drawTickMarksAndLabels(Graphics2D g2,
double cursor,
Rectangle2D plotArea,
Rectangle2D dataArea,
RectangleEdge edge) {
AxisState state = new AxisState(cursor);
if (isAxisLineVisible()) {
drawAxisLine(g2, cursor, dataArea, edge);
}
double ol = getTickMarkOutsideLength();
double il = getTickMarkInsideLength();
List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
g2.setFont(getTickLabelFont());
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick) iterator.next();
if (isTickLabelsVisible()) {
g2.setPaint(getTickLabelPaint());
float[] anchorPoint = calculateAnchorPoint(tick, cursor,
dataArea, edge);
TextUtilities.drawRotatedString(tick.getText(), g2,
anchorPoint[0], anchorPoint[1], tick.getTextAnchor(),
tick.getAngle(), tick.getRotationAnchor());
}
if (isTickMarksVisible() && tick.getTickType().equals(
TickType.MAJOR)) {
float xx = (float) valueToJava2D(tick.getValue(), dataArea,
edge);
Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, xx, cursor + il, xx);
}
else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, xx, cursor - il, xx);
}
else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double(xx, cursor - ol, xx, cursor + il);
}
else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double(xx, cursor + ol, xx, cursor - il);
}
g2.draw(mark);
}
}
// need to work out the space used by the tick labels...
// so we can update the cursor...
double used = 0.0;
if (isTickLabelsVisible()) {
if (edge == RectangleEdge.LEFT) {
used += findMaximumTickLabelWidth(ticks, g2, plotArea,
isVerticalTickLabels());
state.cursorLeft(used);
}
else if (edge == RectangleEdge.RIGHT) {
used = findMaximumTickLabelWidth(ticks, g2, plotArea,
isVerticalTickLabels());
state.cursorRight(used);
}
else if (edge == RectangleEdge.TOP) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea,
isVerticalTickLabels());
state.cursorUp(used);
}
else if (edge == RectangleEdge.BOTTOM) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea,
isVerticalTickLabels());
state.cursorDown(used);
}
}
return state;
}
/**
* Returns the space required to draw the axis.
*
* @param g2 the graphics device.
* @param plot the plot that the axis belongs to.
* @param plotArea the area within which the plot should be drawn.
* @param edge the axis location.
* @param space the space already reserved (for other axes).
*
* @return The space required to draw the axis (including pre-reserved
* space).
*/
public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
Rectangle2D plotArea,
RectangleEdge edge, AxisSpace space) {
// create a new space object if one wasn't supplied...
if (space == null) {
space = new AxisSpace();
}
// if the axis is not visible, no additional space is required...
if (!isVisible()) {
return space;
}
// if the axis has a fixed dimension, return it...
double dimension = getFixedDimension();
if (dimension > 0.0) {
space.ensureAtLeast(dimension, edge);
}
// calculate the max size of the tick labels (if visible)...
double tickLabelHeight = 0.0;
double tickLabelWidth = 0.0;
if (isTickLabelsVisible()) {
g2.setFont(getTickLabelFont());
List ticks = refreshTicks(g2, new AxisState(), plotArea, edge);
if (RectangleEdge.isTopOrBottom(edge)) {
tickLabelHeight = findMaximumTickLabelHeight(ticks, g2,
plotArea, isVerticalTickLabels());
}
else if (RectangleEdge.isLeftOrRight(edge)) {
tickLabelWidth = findMaximumTickLabelWidth(ticks, g2, plotArea,
isVerticalTickLabels());
}
}
// get the axis label size and update the space object...
Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
double labelHeight = 0.0;
double labelWidth = 0.0;
if (RectangleEdge.isTopOrBottom(edge)) {
labelHeight = labelEnclosure.getHeight();
space.add(labelHeight + tickLabelHeight, edge);
}
else if (RectangleEdge.isLeftOrRight(edge)) {
labelWidth = labelEnclosure.getWidth();
space.add(labelWidth + tickLabelWidth, edge);
}
return space;
}
/**
* A utility method for determining the height of the tallest tick label.
*
* @param ticks the ticks.
* @param g2 the graphics device.
* @param drawArea the area within which the plot and axes should be drawn.
* @param vertical a flag that indicates whether or not the tick labels
* are 'vertical'.
*
* @return The height of the tallest tick label.
*/
protected double findMaximumTickLabelHeight(List ticks,
Graphics2D g2,
Rectangle2D drawArea,
boolean vertical) {
RectangleInsets insets = getTickLabelInsets();
Font font = getTickLabelFont();
double maxHeight = 0.0;
if (vertical) {
FontMetrics fm = g2.getFontMetrics(font);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -