📄 numberaxis.java
字号:
*/
protected double estimateMaximumTickLabelWidth(Graphics2D g2, TickUnit tickUnit) {
Insets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.left + tickLabelInsets.right;
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of the font)...
result += tickLabelFont.getStringBounds("0", frc).getHeight();
}
else {
// look at lower and upper bounds...
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = tickUnit.valueToString(lower);
String upperStr = tickUnit.valueToString(upper);
double w1 = tickLabelFont.getStringBounds(lowerStr, frc).getWidth();
double w2 = tickLabelFont.getStringBounds(upperStr, frc).getWidth();
result += Math.max(w1, w2);
}
return result;
}
/**
* Selects an appropriate tick value for the axis. The strategy is to
* display as many ticks as possible (selected from an array of 'standard'
* tick units) without the labels overlapping.
*
* @param g2 the graphics device.
* @param drawArea the area in which the plot and axes should be drawn.
* @param dataArea the area defined by the axes.
* @param edge the axis location.
*/
protected void selectAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D dataArea,
RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
selectHorizontalAutoTickUnit(g2, drawArea, dataArea, edge);
}
else if (RectangleEdge.isLeftOrRight(edge)) {
selectVerticalAutoTickUnit(g2, drawArea, dataArea, edge);
}
}
/**
* Selects an appropriate tick value for the axis. The strategy is to
* display as many ticks as possible (selected from an array of 'standard'
* tick units) without the labels overlapping.
*
* @param g2 the graphics device.
* @param drawArea the area in which the plot and axes should be drawn.
* @param dataArea the area defined by the axes.
* @param edge the axis location.
*/
protected void selectHorizontalAutoTickUnit(Graphics2D g2,
Rectangle2D drawArea, Rectangle2D dataArea,
RectangleEdge edge) {
double zero = translateValueToJava2D(0.0, dataArea, edge);
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
// start with the current tick unit...
TickUnits tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double x1 = translateValueToJava2D(unit1.getSize(), dataArea, edge);
double unit1Width = Math.abs(x1 - zero);
// then extrapolate...
double guess = (tickLabelWidth / unit1Width) * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit) tickUnits.getCeilingTickUnit(guess);
double x2 = translateValueToJava2D(unit2.getSize(), dataArea, edge);
double unit2Width = Math.abs(x2 - zero);
tickLabelWidth = estimateMaximumTickLabelWidth(g2, unit2);
if (tickLabelWidth > unit2Width) {
unit2 = (NumberTickUnit) tickUnits.getLargerTickUnit(unit2);
}
setTickUnit(unit2, false, false);
}
/**
* Selects an appropriate tick value for the axis. The strategy is to
* display as many ticks as possible (selected from an array of 'standard'
* tick units) without the labels overlapping.
*
* @param g2 the graphics device.
* @param plotArea the area in which the plot and axes should be drawn.
* @param dataArea the area in which the plot should be drawn.
* @param edge the axis location.
*/
protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D plotArea,
Rectangle2D dataArea, RectangleEdge edge) {
double zero = translateValueToJava2D(0.0, dataArea, edge);
double tickLabelHeight = estimateMaximumTickLabelHeight(g2);
// start with the current tick unit...
TickUnits tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double y = translateValueToJava2D(unit1.getSize(), dataArea, edge);
double unitHeight = Math.abs(y - zero);
// then extrapolate...
double guess = (tickLabelHeight / unitHeight) * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit) tickUnits.getCeilingTickUnit(guess);
double y2 = translateValueToJava2D(unit2.getSize(), dataArea, edge);
double unit2Height = Math.abs(y2 - zero);
tickLabelHeight = estimateMaximumTickLabelHeight(g2);
if (tickLabelHeight > unit2Height) {
unit2 = (NumberTickUnit) tickUnits.getLargerTickUnit(unit2);
}
setTickUnit(unit2, false, false);
}
/**
* Calculates the positions of the tick labels for the axis, storing the results in the
* tick label list (ready for drawing).
*
* @param g2 the graphics device.
* @param cursor the cursor.
* @param plotArea the area in which the plot and the axes should be drawn.
* @param dataArea the area in which the plot should be drawn.
* @param edge the location of the axis.
*
*/
public void refreshTicks(Graphics2D g2, double cursor,
Rectangle2D plotArea, Rectangle2D dataArea,
RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
refreshHorizontalTicks(g2, cursor, plotArea, dataArea, edge);
}
else if (RectangleEdge.isLeftOrRight(edge)) {
refreshVerticalTicks(g2, cursor, plotArea, dataArea, edge);
}
}
/**
* Calculates the positions of the tick labels for the axis, storing the results in the
* tick label list (ready for drawing).
*
* @param g2 the graphics device.
* @param cursor the cursor.
* @param plotArea the area in which the plot (inlcuding axes) should be drawn.
* @param dataArea the area in which the data should be drawn.
* @param edge the location of the axis.
*/
protected void refreshHorizontalTicks(Graphics2D g2, double cursor,
Rectangle2D plotArea, Rectangle2D dataArea,
RectangleEdge edge) {
getTicks().clear();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
FontRenderContext frc = g2.getFontRenderContext();
if (isAutoTickUnitSelection()) {
selectAutoTickUnit(g2, plotArea, dataArea, edge);
}
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
for (int i = 0; i < count; i++) {
double currentTickValue = lowestTickValue + (i * size);
double xx = translateValueToJava2D(currentTickValue, dataArea, edge);
String tickLabel;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
}
else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
Rectangle2D tickLabelBounds = tickLabelFont.getStringBounds(tickLabel, frc);
LineMetrics metrics = tickLabelFont.getLineMetrics(tickLabel, frc);
float x = 0.0f;
float y = 0.0f;
Insets tickLabelInsets = getTickLabelInsets();
if (isVerticalTickLabels()) {
x = (float) (xx + tickLabelBounds.getHeight() / 2);
if (edge == RectangleEdge.TOP) {
y = (float) (cursor - tickLabelInsets.bottom
- tickLabelBounds.getWidth());
}
else {
y = (float) (cursor + tickLabelInsets.top
+ tickLabelBounds.getWidth());
}
}
else {
x = (float) (xx - tickLabelBounds.getWidth() / 2);
if (edge == RectangleEdge.TOP) {
y = (float) (cursor - tickLabelInsets.bottom
- metrics.getLeading()
- metrics.getDescent());
}
else {
y = (float) (cursor + tickLabelInsets.top
+ tickLabelBounds.getHeight());
}
}
Tick tick = new Tick(new Double(currentTickValue), tickLabel, x, y);
getTicks().add(tick);
}
}
}
/**
* Calculates the positions of the tick labels for the axis, storing the results in the
* tick label list (ready for drawing).
*
* @param g2 the graphics device.
* @param cursor the cursor location.
* @param plotArea the area in which the plot and the axes should be drawn.
* @param dataArea the area in which the plot should be drawn.
* @param edge the location of the axis.
*
*/
protected void refreshVerticalTicks(Graphics2D g2, double cursor,
Rectangle2D plotArea, Rectangle2D dataArea,
RectangleEdge edge) {
getTicks().clear();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection()) {
selectAutoTickUnit(g2, plotArea, dataArea, edge);
}
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
for (int i = 0; i < count; i++) {
double currentTickValue = lowestTickValue + (i * size);
double yy = translateValueToJava2D(currentTickValue, dataArea, edge);
String tickLabel;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
}
else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
FontRenderContext frc = g2.getFontRenderContext();
Rectangle2D tickLabelBounds = tickLabelFont.getStringBounds(tickLabel, frc);
LineMetrics lm = tickLabelFont.getLineMetrics(tickLabel, frc);
float x;
if (edge == RectangleEdge.LEFT) {
x = (float) (cursor
- tickLabelBounds.getWidth() - getTickLabelInsets().right);
}
else {
x = (float) (cursor + getTickLabelInsets().left);
}
float y = (float) (yy + (lm.getAscent() / 2));
Tick tick = new Tick(new Double(currentTickValue), tickLabel, x, y);
getTicks().add(tick);
}
}
}
/**
* Returns a clone of the axis.
*
* @return A clone
*
* @throws CloneNotSupportedException if some component of the axis does not support cloning.
*/
public Object clone() throws CloneNotSupportedException {
NumberAxis clone = (NumberAxis) super.clone();
if (this.numberFormatOverride != null) {
clone.numberFormatOverride = (NumberFormat) this.numberFormatOverride.clone();
}
return clone;
}
/**
* Tests an object for equality with this instance.
*
* @param object the object.
*
* @return A boolean.
*/
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (object == this) {
return true;
}
if (object instanceof NumberAxis) {
if (super.equals(object)) {
NumberAxis axis = (NumberAxis) object;
boolean b0 = (this.autoRangeIncludesZero == axis.autoRangeIncludesZero);
boolean b1 = (this.autoRangeStickyZero == axis.autoRangeStickyZero);
boolean b2 = ObjectUtils.equal(this.tickUnit, axis.tickUnit);
boolean b3 = ObjectUtils.equal(this.numberFormatOverride,
axis.numberFormatOverride);
//boolean b4 = ObjectUtils.equalOrBothNull(this.markerBand, axis.markerBand);
return b0 && b1 && b2 && b3;
}
}
return false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -