cyclicnumberaxis.java
来自「JfreeChart 常用图表例子」· Java 代码 · 共 1,209 行 · 第 1/3 页
JAVA
1,209 行
jmax = dataArea.getMaxX(); } else if (RectangleEdge.isLeftOrRight(edge)) { jmax = dataArea.getMinY(); jmin = dataArea.getMaxY(); } if (isInverted()) { if (value == vp) { return this.boundMappedToLastCycle ? jmin : jmax; } else if (value > vp) { return jmax - (value - vp) * (jmax - jmin) / this.period; } else { return jmin + (vp - value) * (jmax - jmin) / this.period; } } else { if (value == vp) { return this.boundMappedToLastCycle ? jmax : jmin; } else if (value >= vp) { return jmin + (value - vp) * (jmax - jmin) / this.period; } else { return jmax - (vp - value) * (jmax - jmin) / this.period; } } } /** * Centers the range about the given value. * * @param value the data value. */ public void centerRange(double value) { setRange(value - this.period / 2.0, value + this.period / 2.0); } /** * This function is nearly useless since the auto range is fixed for this * class to the period. The period is extended if necessary to fit the * minimum size. * * @param size the size. * @param notify notify? * * @see org.jfree.chart.axis.ValueAxis#setAutoRangeMinimumSize(double, * boolean) */ public void setAutoRangeMinimumSize(double size, boolean notify) { if (size > this.period) { this.period = size; } super.setAutoRangeMinimumSize(size, notify); } /** * The auto range is fixed for this class to the period by default. * This function will thus set a new period. * * @param length the length. * * @see org.jfree.chart.axis.ValueAxis#setFixedAutoRange(double) */ public void setFixedAutoRange(double length) { this.period = length; super.setFixedAutoRange(length); } /** * Sets a new axis range. The period is extended to fit the range size, if * necessary. * * @param range the range. * @param turnOffAutoRange switch off the auto range. * @param notify notify? * * @see org.jfree.chart.axis.ValueAxis#setRange(Range, boolean, boolean) */ public void setRange(Range range, boolean turnOffAutoRange, boolean notify) { double size = range.getUpperBound() - range.getLowerBound(); if (size > this.period) { this.period = size; } super.setRange(range, turnOffAutoRange, notify); } /** * The cycle bound is defined as the higest value x such that * "offset + period * i = x", with i and integer and x < * range.getUpperBound() This is the value which is at both ends of the * axis : x...up|low...x * The values from x to up are the valued in the current cycle. * The values from low to x are the valued in the previous cycle. * * @return The cycle bound. */ public double getCycleBound() { return Math.floor( (getRange().getUpperBound() - this.offset) / this.period ) * this.period + this.offset; } /** * The cycle bound is a multiple of the period, plus optionally a start * offset. * <P> * <pre>cb = n * period + offset</pre><br> * * @return The current offset. * * @see #getCycleBound() */ public double getOffset() { return this.offset; } /** * The cycle bound is a multiple of the period, plus optionally a start * offset. * <P> * <pre>cb = n * period + offset</pre><br> * * @param offset The offset to set. * * @see #getCycleBound() */ public void setOffset(double offset) { this.offset = offset; } /** * The cycle bound is a multiple of the period, plus optionally a start * offset. * <P> * <pre>cb = n * period + offset</pre><br> * * @return The current period. * * @see #getCycleBound() */ public double getPeriod() { return this.period; } /** * The cycle bound is a multiple of the period, plus optionally a start * offset. * <P> * <pre>cb = n * period + offset</pre><br> * * @param period The period to set. * * @see #getCycleBound() */ public void setPeriod(double period) { this.period = period; } /** * Draws the tick marks and labels. * * @param g2 the graphics device. * @param cursor the cursor. * @param plotArea the plot area. * @param dataArea the area inside the axes. * @param edge the side on which the axis is displayed. * * @return The axis state. */ protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) { this.internalMarkerWhenTicksOverlap = false; AxisState ret = super.drawTickMarksAndLabels( g2, cursor, plotArea, dataArea, edge ); // continue and separate the labels only if necessary if (!this.internalMarkerWhenTicksOverlap) { return ret; } double ol = getTickMarkOutsideLength(); FontMetrics fm = g2.getFontMetrics(getTickLabelFont()); if (isVerticalTickLabels()) { ol = fm.getMaxAdvance(); } else { ol = fm.getHeight(); } double il = 0; if (isTickMarksVisible()) { float xx = (float) valueToJava2D( getRange().getUpperBound(), 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); } return ret; } /** * Draws the axis. * * @param g2 the graphics device (<code>null</code> not permitted). * @param cursor the cursor position. * @param plotArea the plot area (<code>null</code> not permitted). * @param dataArea the data area (<code>null</code> not permitted). * @param edge the edge (<code>null</code> not permitted). * @param plotState collects information about the plot * (<code>null</code> permitted). * * @return The axis state (never <code>null</code>). */ public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) { AxisState ret = super.draw( g2, cursor, plotArea, dataArea, edge, plotState ); if (isAdvanceLineVisible()) { double xx = valueToJava2D( getRange().getUpperBound(), dataArea, edge ); Line2D mark = null; g2.setStroke(getAdvanceLineStroke()); g2.setPaint(getAdvanceLinePaint()); if (edge == RectangleEdge.LEFT) { mark = new Line2D.Double( cursor, xx, cursor + dataArea.getWidth(), xx ); } else if (edge == RectangleEdge.RIGHT) { mark = new Line2D.Double( cursor - dataArea.getWidth(), xx, cursor, xx ); } else if (edge == RectangleEdge.TOP) { mark = new Line2D.Double( xx, cursor + dataArea.getHeight(), xx, cursor ); } else if (edge == RectangleEdge.BOTTOM) { mark = new Line2D.Double( xx, cursor, xx, cursor - dataArea.getHeight() ); } g2.draw(mark); } return ret; } /** * Reserve some space on each axis side because we draw a centered label at * each extremity. * * @param g2 the graphics device. * @param plot the plot. * @param plotArea the plot area. * @param edge the edge. * @param space the space already reserved. * * @return The reserved space. */ public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) { this.internalMarkerCycleBoundTick = null; AxisSpace ret = super.reserveSpace(g2, plot, plotArea, edge, space); if (this.internalMarkerCycleBoundTick == null) { return ret; } FontMetrics fm = g2.getFontMetrics(getTickLabelFont()); Rectangle2D r = TextUtilities.getTextBounds( this.internalMarkerCycleBoundTick.getText(), g2, fm ); if (RectangleEdge.isTopOrBottom(edge)) { if (isVerticalTickLabels()) { space.add(r.getHeight() / 2, RectangleEdge.RIGHT); } else { space.add(r.getWidth() / 2, RectangleEdge.RIGHT); } } else if (RectangleEdge.isLeftOrRight(edge)) { if (isVerticalTickLabels()) { space.add(r.getWidth() / 2, RectangleEdge.TOP); } else { space.add(r.getHeight() / 2, RectangleEdge.TOP); } } return ret; } /** * Provides serialization support. * * @param stream the output stream. * * @throws IOException if there is an I/O error. */ private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); SerialUtilities.writePaint(this.advanceLinePaint, stream); SerialUtilities.writeStroke(this.advanceLineStroke, stream); } /** * Provides serialization support. * * @param stream the input stream. * * @throws IOException if there is an I/O error. * @throws ClassNotFoundException if there is a classpath problem. */ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); this.advanceLinePaint = SerialUtilities.readPaint(stream); this.advanceLineStroke = SerialUtilities.readStroke(stream); } /** * Tests the axis for equality with another object. * * @param object the object to test against. * * @return A boolean. */ public boolean equals(Object object) { if (object == this) { return true; } if (!(object instanceof CyclicNumberAxis)) { return false; } if (!super.equals(object)) { return false; } CyclicNumberAxis axis = (CyclicNumberAxis) object; if (this.period != axis.period) { return false; } if (this.offset != axis.offset) { return false; } if (!ObjectUtilities.equal(this.advanceLinePaint, axis.advanceLinePaint)) { return false; } if (!ObjectUtilities.equal(this.advanceLineStroke, axis.advanceLineStroke)) { return false; } if (this.advanceLineVisible != axis.advanceLineVisible) { return false; } if (this.boundMappedToLastCycle != axis.boundMappedToLastCycle) { return false; } return true; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?