/** * 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 a range crosshair. * * @param g2 the graphics target. * @param dataArea the data area. * @param orientation the plot orientation. * @param value the crosshair value. * @param axis the axis against which the value is measured. * @param stroke the stroke used to draw the crosshair line. * @param paint the paint used to draw the crosshair line. * * @since 1.0.4 */ protected void drawRangeCrosshair(Graphics2D g2, Rectangle2D dataArea, PlotOrientation orientation, double value, ValueAxis axis, Stroke stroke, Paint paint) { if (axis.getRange().contains(value)) { Line2D line = null; if (orientation == PlotOrientation.HORIZONTAL) { double xx = axis.valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); } else { double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT); line = new Line2D.Double(dataArea.getMinX(), yy, dataArea.getMaxX(), yy); } g2.setStroke(stroke); g2.setPaint(paint); g2.draw(line); } }
/** * Returns a rectangle that encloses the axis label. This is typically * used for layout purposes (it gives the maximum dimensions of the label). * * @param g2 the graphics device. * @param edge the edge of the plot area along which the axis is measuring. * * @return The enclosing rectangle. */ protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) { Rectangle2D result = new Rectangle2D.Double(); String axisLabel = getLabel(); if (axisLabel != null && !axisLabel.equals("")) { FontMetrics fm = g2.getFontMetrics(getLabelFont()); Rectangle2D bounds = TextUtilities.getTextBounds(axisLabel, g2, fm); RectangleInsets insets = getLabelInsets(); bounds = insets.createOutsetRectangle(bounds); double angle = getLabelAngle(); if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) { angle = angle - Math.PI / 2.0; } double x = bounds.getCenterX(); double y = bounds.getCenterY(); AffineTransform transformer = AffineTransform.getRotateInstance(angle, x, y); Shape labelBounds = transformer.createTransformedShape(bounds); result = labelBounds.getBounds2D(); } return result; }
/** * Calculates the anchor point for a tick. * * @param tick the tick. * @param cursor the cursor. * @param dataArea the data area. * @param edge the side on which the axis is displayed. * * @return The anchor point. */ protected float[] calculateAnchorPoint(ValueTick tick, double cursor, Rectangle2D dataArea, RectangleEdge edge) { if (tick instanceof CycleBoundTick) { boolean mapsav = this.boundMappedToLastCycle; this.boundMappedToLastCycle = ((CycleBoundTick) tick).mapToLastCycle; float[] ret = super.calculateAnchorPoint( tick, cursor, dataArea, edge ); this.boundMappedToLastCycle = mapsav; return ret; } return super.calculateAnchorPoint(tick, cursor, dataArea, edge); }
/** * Draws the axis on a Java 2D graphics device (such as the screen or a * printer). * * @param g2 the graphics device (<code>null</code> not permitted). * @param cursor the cursor location (determines where to draw the axis). * @param plotArea the area within which the axes and plot should be drawn. * @param dataArea the area within which the data should be drawn. * @param edge the axis location (<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 axisState = new AxisState(cursor); if (isAxisLineVisible()) { drawAxisLine(g2, cursor, dataArea, edge); } drawTickMarks(g2, axisState, dataArea, edge); for (int band = 0; band < this.labelInfo.length; band++) { axisState = drawTickLabels(band, g2, axisState, dataArea, edge); } // draw the axis label (note that 'state' is passed in *and* // returned)... axisState = drawLabel(getLabel(), g2, plotArea, dataArea, edge, axisState); return axisState; }
/** * 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(this.axisLinePaint); g2.setStroke(this.axisLineStroke); g2.draw(axisLine); }
/** * Calculates the size (width or height, depending on the location of the axis) of a category * gap. * * @param categoryCount the number of categories. * @param area the area within which the categories will be drawn. * @param edge the axis location. * * @return the category gap width. */ protected double calculateCategoryGapSize(int categoryCount, Rectangle2D area, RectangleEdge edge) { double result = 0.0; double available = 0.0; if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) { available = area.getWidth(); } else if ((edge == RectangleEdge.LEFT) || (edge == RectangleEdge.RIGHT)) { available = area.getHeight(); } if (categoryCount > 1) { result = available * getCategoryMargin() / (categoryCount - 1); } return result; }
/** * Creates a new title. * * @param text the text for the title (<code>null</code> not permitted). * @param font the title font (<code>null</code> not permitted). * @param paint the title paint (<code>null</code> not permitted). * @param position the title position (<code>null</code> not permitted). * @param horizontalAlignment the horizontal alignment (<code>null</code> not permitted). * @param verticalAlignment the vertical alignment (<code>null</code> not permitted). * @param spacer the space to leave around the outside of the title. */ public TextTitle(String text, Font font, Paint paint, RectangleEdge position, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Spacer spacer) { super(position, horizontalAlignment, verticalAlignment, spacer); if (text == null) { throw new NullPointerException("Null 'text' argument."); } if (font == null) { throw new NullPointerException("Null 'font' argument."); } if (paint == null) { throw new NullPointerException("Null 'paint' argument."); } this.text = text; this.font = font; this.paint = paint; this.backgroundPaint = null; }
/** * Draws the title on a Java 2D graphics device (such as the screen or a printer). * * @param g2 the graphics device. * @param area the area allocated for the title. */ public void draw(Graphics2D g2, Rectangle2D area) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Drawing title to area " + area.toString()); } if (this.text.equals("")) { return; } if (this.backgroundPaint != null) { g2.setPaint(this.backgroundPaint); g2.fill(area); } RectangleEdge position = getPosition(); if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) { drawHorizontal(g2, area); } else if (position == RectangleEdge.LEFT || position == RectangleEdge.RIGHT) { drawVertical(g2, area); } }
/** * 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) { float[] result = new float[2]; if (edge == RectangleEdge.TOP) { result[0] = (float) this.valueToJava2D(tick.getValue(), dataArea, edge); result[1] = (float) (cursor - getTickLabelInsets().bottom - 2.0); } else if (edge == RectangleEdge.BOTTOM) { result[0] = (float) this.valueToJava2D(tick.getValue(), dataArea, edge); result[1] = (float) (cursor + getTickLabelInsets().top + 2.0); } else if (edge == RectangleEdge.LEFT) { result[0] = (float) (cursor - getTickLabelInsets().left - 2.0); result[1] = (float) this.valueToJava2D(tick.getValue(), dataArea, edge); } else if (edge == RectangleEdge.RIGHT) { result[0] = (float) (cursor + getTickLabelInsets().right + 2.0); result[1] = (float) this.valueToJava2D(tick.getValue(), dataArea, edge); } return result; }
/** * Test the translation of Java2D values to data values. */ public void testJava2DToValue() { DateAxis axis = new DateAxis(); axis.setRange(50.0, 100.0); Rectangle2D dataArea = new Rectangle2D.Double(10.0, 50.0, 400.0, 300.0); double y1 = axis.java2DToValue(75.0, dataArea, RectangleEdge.LEFT); assertTrue(same(y1, 95.8333333, 1.0)); double y2 = axis.java2DToValue(75.0, dataArea, RectangleEdge.RIGHT); assertTrue(same(y2, 95.8333333, 1.0)); double x1 = axis.java2DToValue(75.0, dataArea, RectangleEdge.TOP); assertTrue(same(x1, 58.125, 1.0)); double x2 = axis.java2DToValue(75.0, dataArea, RectangleEdge.BOTTOM); assertTrue(same(x2, 58.125, 1.0)); axis.setInverted(true); double y3 = axis.java2DToValue(75.0, dataArea, RectangleEdge.LEFT); assertTrue(same(y3, 54.1666667, 1.0)); double y4 = axis.java2DToValue(75.0, dataArea, RectangleEdge.RIGHT); assertTrue(same(y4, 54.1666667, 1.0)); double x3 = axis.java2DToValue(75.0, dataArea, RectangleEdge.TOP); assertTrue(same(x3, 91.875, 1.0)); double x4 = axis.java2DToValue(75.0, dataArea, RectangleEdge.BOTTOM); assertTrue(same(x4, 91.875, 1.0)); }
/** * Draws the annotation. * * @param g2 the graphics device. * @param plot the plot. * @param dataArea the data area. * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param rendererIndex the renderer index. * @param info if supplied, this info object will be populated with * entity information. */ public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) { PlotOrientation orientation = plot.getOrientation(); RectangleEdge domainEdge = Plot.resolveDomainAxisLocation( plot.getDomainAxisLocation(), orientation); RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation( plot.getRangeAxisLocation(), orientation); float j2DX = (float) domainAxis.valueToJava2D(this.x, dataArea, domainEdge); float j2DY = (float) rangeAxis.valueToJava2D(this.y, dataArea, rangeEdge); Rectangle2D area = new Rectangle2D.Double(j2DX - this.width / 2.0, j2DY - this.height / 2.0, this.width, this.height); this.drawable.draw(g2, area); String toolTip = getToolTipText(); String url = getURL(); if (toolTip != null || url != null) { addEntity(info, area, rendererIndex, toolTip, url); } }
/** * Handles a 'click' on the plot by updating the anchor value. * * @param x x-coordinate of the click (in Java2D space). * @param y y-coordinate of the click (in Java2D space). * @param info information about the plot's dimensions. * */ public void handleClick(int x, int y, PlotRenderingInfo info) { Rectangle2D dataArea = info.getDataArea(); if (dataArea.contains(x, y)) { // set the anchor value for the range axis... double java2D = 0.0; if (this.orientation == PlotOrientation.HORIZONTAL) { java2D = x; } else if (this.orientation == PlotOrientation.VERTICAL) { java2D = y; } RectangleEdge edge = Plot.resolveRangeAxisLocation( getRangeAxisLocation(), this.orientation); double value = getRangeAxis().java2DToValue( java2D, info.getDataArea(), edge); setAnchorValue(value); setRangeCrosshairValue(value); } }
/** * 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 state the axis state. * @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. * * @return A list of ticks. */ public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) { List ticks = null; if (RectangleEdge.isTopOrBottom(edge)) { ticks = refreshTicksHorizontal(g2, state.getCursor(), plotArea, dataArea, edge); } else if (RectangleEdge.isLeftOrRight(edge)) { ticks = refreshTicksVertical(g2, state.getCursor(), plotArea, dataArea, edge); } return ticks; }
/** * Returns the Java 2D coordinate for a category. * * @param anchor the anchor point. * @param category the category index. * @param categoryCount the category count. * @param area the data area. * @param edge the location of the axis. * * @return the coordinate. */ public double getCategoryJava2DCoordinate(CategoryAnchor anchor, int category, int categoryCount, Rectangle2D area, RectangleEdge edge) { double result = 0.0; if (anchor == CategoryAnchor.START) { result = getCategoryStart(category, categoryCount, area, edge); } else if (anchor == CategoryAnchor.MIDDLE) { result = getCategoryMiddle(category, categoryCount, area, edge); } else if (anchor == CategoryAnchor.END) { result = getCategoryEnd(category, categoryCount, area, edge); } return result; }
/** * Returns the starting coordinate for the specified category. * * @param category the category. * @param categoryCount the number of categories. * @param area the data area. * @param edge the axis location. * * @return The coordinate. * * @see #getCategoryMiddle(int, int, Rectangle2D, RectangleEdge) * @see #getCategoryEnd(int, int, Rectangle2D, RectangleEdge) */ public double getCategoryStart(int category, int categoryCount, Rectangle2D area, RectangleEdge edge) { double result = 0.0; if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) { result = area.getX() + area.getWidth() * getLowerMargin(); } else if ((edge == RectangleEdge.LEFT) || (edge == RectangleEdge.RIGHT)) { result = area.getMinY() + area.getHeight() * getLowerMargin(); } double categorySize = calculateCategorySize(categoryCount, area, edge); double categoryGapWidth = calculateCategoryGapSize(categoryCount, area, edge); result = result + category * (categorySize + categoryGapWidth); return result; }
/** * Adds space to the top, bottom, left or right edge of the plot area. * * @param space the space (in Java2D units). * @param edge the edge (<code>null</code> not permitted). */ public void add(double space, RectangleEdge edge) { if (edge == null) { throw new IllegalArgumentException("Null 'edge' argument."); } if (edge == RectangleEdge.TOP) { this.top += space; } else if (edge == RectangleEdge.BOTTOM) { this.bottom += space; } else if (edge == RectangleEdge.LEFT) { this.left += space; } else if (edge == RectangleEdge.RIGHT) { this.right += space; } else { throw new IllegalStateException("Unrecognised 'edge' argument."); } }
/** * Calculates the reserved area. * * @param area the area. * @param edge the edge. * * @return The reserved area. */ public Rectangle2D reserved(Rectangle2D area, RectangleEdge edge) { Rectangle2D result = null; if (edge == RectangleEdge.TOP) { result = new Rectangle2D.Double(area.getX(), area.getY(), area.getWidth(), this.top); } else if (edge == RectangleEdge.BOTTOM) { result = new Rectangle2D.Double(area.getX(), area.getMaxY() - this.top, area.getWidth(), this.bottom); } else if (edge == RectangleEdge.LEFT) { result = new Rectangle2D.Double(area.getX(), area.getY(), this.left, area.getHeight()); } else if (edge == RectangleEdge.RIGHT) { result = new Rectangle2D.Double(area.getMaxX() - this.right, area.getY(), this.right, area.getHeight()); } return result; }
/** * Converts a coordinate in Java2D space to the corresponding data value, * assuming that the axis runs along one edge of the specified dataArea. * * @param java2DValue the coordinate in Java2D space. * @param area the area in which the data is plotted. * @param edge the edge along which the axis lies. * * @return the data value. */ public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) { double result = Double.NaN; double min = 0.0; double max = 0.0; double axisMin = this.first.getFirstMillisecond(this.timeZone); double axisMax = this.last.getLastMillisecond(this.timeZone); if (RectangleEdge.isTopOrBottom(edge)) { min = area.getX(); max = area.getMaxX(); } else if (RectangleEdge.isLeftOrRight(edge)) { min = area.getMaxY(); max = area.getY(); } if (isInverted()) { result = axisMax - ((java2DValue - min) / (max - min) * (axisMax - axisMin)); } else { result = axisMin + ((java2DValue - min) / (max - min) * (axisMax - axisMin)); } return result; }
/** * Draws a range crosshair. * * @param g2 the graphics target. * @param dataArea the data area. * @param orientation the plot orientation. * @param value the crosshair value. * @param axis the axis against which the value is measured. * @param stroke the stroke used to draw the crosshair line. * @param paint the paint used to draw the crosshair line. * * @since 1.0.5 */ protected void drawRangeCrosshair(Graphics2D g2, Rectangle2D dataArea, PlotOrientation orientation, double value, ValueAxis axis, Stroke stroke, Paint paint) { if (!axis.getRange().contains(value)) { return; } Line2D line = null; if (orientation == PlotOrientation.HORIZONTAL) { double xx = axis.valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); } else { double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT); line = new Line2D.Double(dataArea.getMinX(), yy, dataArea.getMaxX(), yy); } g2.setStroke(stroke); g2.setPaint(paint); g2.draw(line); }
/** * Translates a data value to a Java2D value for the second section of the * axis. * * @param value the value. * @param area the data area. * @param edge the edge along which the axis lies. * @param length1 the length of the first section. * @param length2 the length of the second section. * * @return The Java2D coordinate. */ private double transEnd(double value, Rectangle2D area, RectangleEdge edge, double length1, double length2) { double min = 0.0; double max = 0.0; if (RectangleEdge.isTopOrBottom(edge)) { max = area.getMaxX(); min = area.getMaxX() - area.getWidth() * length2 / (length1 + length2); } else if (RectangleEdge.isLeftOrRight(edge)) { max = area.getMinY(); min = area.getMinY() + area.getHeight() * length2 / (length1 + length2); } if (isInverted()) { return max - ((value - this.fixedRange.getLowerBound()) / (this.displayEnd - this.fixedRange.getLowerBound())) * (max - min); } else { return min + ((value - this.fixedRange.getLowerBound()) / (this.displayEnd - this.fixedRange.getLowerBound())) * (max - min); } }
/** * Selects a tick unit when the axis is displayed vertically. * * @param g2 the graphics device. * @param drawArea the drawing area. * @param dataArea the data area. * @param edge the side of the rectangle on which the axis is displayed. */ protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D dataArea, RectangleEdge edge) { double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit()); // Compute number of labels double n = getRange().getLength() * tickLabelWidth / dataArea.getHeight(); setTickUnit( (NumberTickUnit) getStandardTickUnits().getCeilingTickUnit(n), false, false ); }
/** * Returns a new instance based on an existing instance but with the left position changed. * * @param base the base (<code>null</code> not permitted). * @param left the left position (<code>null</code> not permitted). * * @return a new instance (never <code>null</code>). */ public static CategoryLabelPositions replaceLeftPosition(CategoryLabelPositions base, CategoryLabelPosition left) { if (base == null) { throw new IllegalArgumentException("Null 'base' argument."); } if (left == null) { throw new IllegalArgumentException("Null 'left' argument."); } return new CategoryLabelPositions( base.getLabelPosition(RectangleEdge.TOP), base.getLabelPosition(RectangleEdge.BOTTOM), left, base.getLabelPosition(RectangleEdge.RIGHT) ); }
/** * Converts a data value to a coordinate in Java2D space, assuming that the * axis runs along one edge of the specified dataArea. * <p> * Note that it is possible for the coordinate to fall outside the plotArea. * * @param value the data value. * @param area the area for plotting the data. * @param edge the axis location. * * @return The Java2D coordinate. */ public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) { Range range = getRange(); double axisMin = range.getLowerBound(); double axisMax = range.getUpperBound(); double min = 0.0; double max = 0.0; if (RectangleEdge.isTopOrBottom(edge)) { min = area.getX(); max = area.getMaxX(); } else if (RectangleEdge.isLeftOrRight(edge)) { max = area.getMinY(); min = area.getMaxY(); } if (isInverted()) { return max - ((value - axisMin) / (axisMax - axisMin)) * (max - min); } else { return min + ((value - axisMin) / (axisMax - axisMin)) * (max - min); } }
/** * Converts a coordinate in Java2D space to the corresponding data value, * assuming that the axis runs along one edge of the specified dataArea. * * @param java2DValue the coordinate in Java2D space. * @param area the area in which the data is plotted. * @param edge the location. * * @return The data value. */ public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) { Range range = getRange(); double axisMin = range.getLowerBound(); double axisMax = range.getUpperBound(); double min = 0.0; double max = 0.0; if (RectangleEdge.isTopOrBottom(edge)) { min = area.getX(); max = area.getMaxX(); } else if (RectangleEdge.isLeftOrRight(edge)) { min = area.getMaxY(); max = area.getY(); } if (isInverted()) { return axisMax - (java2DValue - min) / (max - min) * (axisMax - axisMin); } else { return axisMin + (java2DValue - min) / (max - min) * (axisMax - axisMin); } }
/** * Utility method for drawing a crosshair on the chart (if required). * * @param g2 The graphics device. * @param dataArea The data area. * @param value The coordinate, where to draw the line. * @param stroke The stroke to use. * @param paint The paint to use. */ protected void drawVerticalLine(Graphics2D g2, Rectangle2D dataArea, double value, Stroke stroke, Paint paint) { double xx = getDomainAxis().valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); Line2D line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); g2.setStroke(stroke); g2.setPaint(paint); g2.draw(line); }
/** * 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; }
/** * Creates {@link LegendTitle}s for all dimensions from the PlotConfiguration of this Plotter2D. * Expects that all {@link ValueSource} s in the provided PlotConfiguration use the same * {@link DimensionConfig} s. */ private List<LegendTitle> createLegendTitles() { List<LegendTitle> legendTitles = new LinkedList<LegendTitle>(); LegendConfiguration legendConfiguration = plotInstance.getCurrentPlotConfigurationClone().getLegendConfiguration(); LegendTitle legendTitle = new SmartLegendTitle(this, new FlowArrangement(HorizontalAlignment.CENTER, VerticalAlignment.CENTER, 30, 2), new ColumnArrangement(HorizontalAlignment.LEFT, VerticalAlignment.CENTER, 0, 2)); legendTitle.setItemPaint(legendConfiguration.getLegendFontColor()); RectangleEdge position = legendConfiguration.getLegendPosition().getPosition(); if (position == null) { return legendTitles; } legendTitle.setPosition(position); if (legendConfiguration.isShowLegendFrame()) { legendTitle.setFrame(new BlockBorder(legendConfiguration.getLegendFrameColor())); } ColoredBlockContainer wrapper = new ColoredBlockContainer(legendConfiguration.getLegendBackgroundColor()); wrapper.add(legendTitle.getItemContainer()); wrapper.setPadding(3, 3, 3, 3); legendTitle.setWrapper(wrapper); legendTitles.add(legendTitle); return legendTitles; }
/** * Constructs a contour plot with the specified axes (other attributes take * default values). * * @param dataset The dataset. * @param domainAxis The domain axis. * @param rangeAxis The range axis. * @param colorBar The z-axis axis. */ public ContourPlot(ContourDataset dataset, ValueAxis domainAxis, ValueAxis rangeAxis, ColorBar colorBar) { super(); this.dataset = dataset; if (dataset != null) { dataset.addChangeListener(this); } this.domainAxis = domainAxis; if (domainAxis != null) { domainAxis.setPlot(this); domainAxis.addChangeListener(this); } this.rangeAxis = rangeAxis; if (rangeAxis != null) { rangeAxis.setPlot(this); rangeAxis.addChangeListener(this); } this.colorBar = colorBar; if (colorBar != null) { colorBar.getAxis().setPlot(this); colorBar.getAxis().addChangeListener(this); colorBar.configure(this); } this.colorBarLocation = RectangleEdge.LEFT; this.toolTipGenerator = new StandardContourToolTipGenerator(); }
/** * Creates a new image title with the given image scaled to the given * width and height in the given location. * * @param image the image (not null). * @param height the height used to draw the image. * @param width the width used to draw the image. * @param position the title position. * @param horizontalAlignment the horizontal alignment. * @param verticalAlignment the vertical alignment. * @param spacer the amount of space to leave around the outside of the title. */ public ImageTitle(Image image, int height, int width, RectangleEdge position, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Spacer spacer) { super(position, horizontalAlignment, verticalAlignment, spacer); if (image == null) { throw new NullPointerException("ImageTitle(..): Image argument is null."); } this.image = image; this.height = height; this.width = width; }
/** * Draws the title on a Java 2D graphics device (such as the screen or a printer). * * @param g2 the graphics device. * @param titleArea the area within which the title (and plot) should be drawn. */ public void draw(Graphics2D g2, Rectangle2D titleArea) { RectangleEdge position = getPosition(); if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) { drawHorizontal(g2, titleArea); } else if (position == RectangleEdge.LEFT || position == RectangleEdge.RIGHT) { drawVertical(g2, titleArea); } else { throw new RuntimeException("ImageTitle.draw(...) - invalid title position."); } }
/** * Converts a coordinate in Java2D space to the corresponding data * value, assuming that the axis runs along one edge of the specified plotArea. * * @param java2DValue the coordinate in Java2D space. * @param plotArea the area in which the data is plotted. * @param edge the axis location. * * @return the data value. */ public double java2DToValue(double java2DValue, Rectangle2D plotArea, RectangleEdge edge) { Range range = getRange(); double axisMin = switchedLog10(range.getLowerBound()); double axisMax = switchedLog10(range.getUpperBound()); double plotMin = 0.0; double plotMax = 0.0; if (RectangleEdge.isTopOrBottom(edge)) { plotMin = plotArea.getX(); plotMax = plotArea.getMaxX(); } else if (RectangleEdge.isLeftOrRight(edge)) { plotMin = plotArea.getMaxY(); plotMax = plotArea.getMinY(); } if (isInverted()) { return Math.pow( 10, axisMax - ((java2DValue - plotMin) / (plotMax - plotMin)) * (axisMax - axisMin) ); } else { return Math.pow( 10, axisMin + ((java2DValue - plotMin) / (plotMax - plotMin)) * (axisMax - axisMin) ); } }
/** * Creates a new title, using default attributes where necessary. * * @param position the position of the title (<code>null</code> not permitted). * @param horizontalAlignment the horizontal alignment of the title * (<code>null</code> not permitted). * @param verticalAlignment the vertical alignment of the title * (<code>null</code> not permitted). */ protected Title(RectangleEdge position, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { this(position, horizontalAlignment, verticalAlignment, Title.DEFAULT_SPACER); }
/** * Draws the gridlines for the plot. * * @param g2 the graphics device. * @param dataArea the area inside the axes. * * @see #drawRangeGridlines(Graphics2D, Rectangle2D, List) */ protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea) { // draw the domain grid lines, if any... if (isDomainGridlinesVisible()) { CategoryAnchor anchor = getDomainGridlinePosition(); RectangleEdge domainAxisEdge = getDomainAxisEdge(); Stroke gridStroke = getDomainGridlineStroke(); Paint gridPaint = getDomainGridlinePaint(); if ((gridStroke != null) && (gridPaint != null)) { // iterate over the categories CategoryDataset data = getDataset(); if (data != null) { CategoryAxis axis = getDomainAxis(); if (axis != null) { int columnCount = data.getColumnCount(); for (int c = 0; c < columnCount; c++) { double xx = axis.getCategoryJava2DCoordinate( anchor, c, columnCount, dataArea, domainAxisEdge); CategoryItemRenderer renderer1 = getRenderer(); if (renderer1 != null) { renderer1.drawDomainGridline(g2, this, dataArea, xx); } } } } } } }
/** * Initialises the renderer then returns the number of 'passes' through the data that the * renderer will require (usually just one). This method will be called before the first * item is rendered, giving the renderer an opportunity to initialise any * state information it wants to maintain. The renderer can do nothing if it chooses. * * @param g2 the graphics device. * @param dataArea the area inside the axes. * @param plot the plot. * @param dataset the data. * @param info an optional info collection object to return data back to the caller. * * @return The number of passes the renderer requires. */ public XYItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea, XYPlot plot, XYDataset dataset, PlotRenderingInfo info) { // calculate the maximum allowed candle width from the axis... ValueAxis axis = plot.getDomainAxis(); double x1 = axis.getLowerBound(); double x2 = x1 + this.maxCandleWidthInMilliseconds; RectangleEdge edge = plot.getDomainAxisEdge(); double xx1 = axis.valueToJava2D(x1, dataArea, edge); double xx2 = axis.valueToJava2D(x2, dataArea, edge); this.maxCandleWidth = Math.abs(xx2 - xx1); // Absolute value, since the relative x // positions are reversed for horizontal orientation // calculate the highest volume in the dataset... if (this.drawVolume) { OHLCDataset highLowDataset = (OHLCDataset) dataset; this.maxVolume = 0.0; for (int series = 0; series < highLowDataset.getSeriesCount(); series++) { for (int item = 0; item < highLowDataset.getItemCount(series); item++) { double volume = highLowDataset.getVolumeValue(series, item); if (volume > this.maxVolume) { this.maxVolume = volume; } } } } return new XYItemRendererState(info); }
protected float[] calculateAnchorPoint(ValueTick tick, double cursor, Rectangle2D dataArea, RectangleEdge edge) { if (tick instanceof CycleBoundTick) { boolean mapsav = this.boundMappedToLastCycle; this.boundMappedToLastCycle = ((CycleBoundTick) tick).mapToLastCycle; float[] ret = super.calculateAnchorPoint(tick, cursor, dataArea, edge); this.boundMappedToLastCycle = mapsav; return ret; } return super.calculateAnchorPoint(tick, cursor, dataArea, edge); }
/** * Adjusts the supplied y-value. * * @param y the x-value. * @param h1 height 1. * @param h2 height 2. * @param edge the edge (top or bottom). * * @return the adjusted y-value. */ protected double getRectY(double y, double h1, double h2, RectangleEdge edge) { double result = y; if (edge == RectangleEdge.TOP) { result = result + h1; } else if (edge == RectangleEdge.BOTTOM) { result = result + h2; } return result; }
/** * Sets the position info that applies when the axis is displayed at the right of the * plot area. * * @param position the position info. * * @deprecated Use setLabelPositions(...). */ public void setRightCategoryLabelPosition(CategoryLabelPosition position) { setCategoryLabelPositions(new CategoryLabelPositions( this.categoryLabelPositions.getLabelPosition(RectangleEdge.TOP), this.categoryLabelPositions.getLabelPosition(RectangleEdge.BOTTOM), this.categoryLabelPositions.getLabelPosition(RectangleEdge.LEFT), position ) ); }
/** * 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; }