/** * Creates a new legend title with the specified arrangement. * * @param source the source. * @param hLayout the horizontal item arrangement ({@code null} not * permitted). * @param vLayout the vertical item arrangement ({@code null} not * permitted). */ public LegendTitle(LegendItemSource source, Arrangement hLayout, Arrangement vLayout) { this.sources = new LegendItemSource[] {source}; this.items = new BlockContainer(hLayout); this.hLayout = hLayout; this.vLayout = vLayout; this.backgroundPaint = null; this.legendItemGraphicEdge = RectangleEdge.LEFT; this.legendItemGraphicAnchor = RectangleAnchor.CENTER; this.legendItemGraphicLocation = RectangleAnchor.CENTER; this.legendItemGraphicPadding = new RectangleInsets(2.0, 2.0, 2.0, 2.0); this.itemFont = DEFAULT_ITEM_FONT; this.itemPaint = DEFAULT_ITEM_PAINT; this.itemLabelPadding = new RectangleInsets(2.0, 2.0, 2.0, 2.0); this.sortOrder = SortOrder.ASCENDING; }
private RectangleAnchor flipAnchorH(RectangleAnchor anchor) { RectangleAnchor result = anchor; if (anchor.equals(RectangleAnchor.TOP_LEFT)) { result = RectangleAnchor.TOP_RIGHT; } else if (anchor.equals(RectangleAnchor.TOP_RIGHT)) { result = RectangleAnchor.TOP_LEFT; } else if (anchor.equals(RectangleAnchor.LEFT)) { result = RectangleAnchor.RIGHT; } else if (anchor.equals(RectangleAnchor.RIGHT)) { result = RectangleAnchor.LEFT; } else if (anchor.equals(RectangleAnchor.BOTTOM_LEFT)) { result = RectangleAnchor.BOTTOM_RIGHT; } else if (anchor.equals(RectangleAnchor.BOTTOM_RIGHT)) { result = RectangleAnchor.BOTTOM_LEFT; } return result; }
private RectangleAnchor flipAnchorV(RectangleAnchor anchor) { RectangleAnchor result = anchor; if (anchor.equals(RectangleAnchor.TOP_LEFT)) { result = RectangleAnchor.BOTTOM_LEFT; } else if (anchor.equals(RectangleAnchor.TOP_RIGHT)) { result = RectangleAnchor.BOTTOM_RIGHT; } else if (anchor.equals(RectangleAnchor.TOP)) { result = RectangleAnchor.BOTTOM; } else if (anchor.equals(RectangleAnchor.BOTTOM)) { result = RectangleAnchor.TOP; } else if (anchor.equals(RectangleAnchor.BOTTOM_LEFT)) { result = RectangleAnchor.TOP_LEFT; } else if (anchor.equals(RectangleAnchor.BOTTOM_RIGHT)) { result = RectangleAnchor.TOP_RIGHT; } return result; }
/** * Calculates the {@code (x, y)} coordinates for drawing a marker label. * * @param g2 the graphics device. * @param orientation the plot orientation. * @param dataArea the data area. * @param markerArea the rectangle surrounding the marker area. * @param markerOffset the marker label offset. * @param labelOffsetType the label offset type. * @param anchor the label anchor. * * @return The coordinates for drawing the marker label. */ protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2, PlotOrientation orientation, Rectangle2D dataArea, Rectangle2D markerArea, RectangleInsets markerOffset, LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) { Rectangle2D anchorRect = null; if (orientation == PlotOrientation.HORIZONTAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, LengthAdjustmentType.CONTRACT, labelOffsetType); } else if (orientation == PlotOrientation.VERTICAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, labelOffsetType, LengthAdjustmentType.CONTRACT); } return anchor.getAnchorPoint(anchorRect); }
/** * Calculates the (x, y) coordinates for drawing a marker label. * * @param g2 the graphics device. * @param orientation the plot orientation. * @param dataArea the data area. * @param markerArea the marker area. * @param markerOffset the marker offset. * @param labelOffsetForRange ?? * @param anchor the label anchor. * * @return The coordinates for drawing the marker label. */ private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2, PlotOrientation orientation, Rectangle2D dataArea, Rectangle2D markerArea, RectangleInsets markerOffset, LengthAdjustmentType labelOffsetForRange, RectangleAnchor anchor) { Rectangle2D anchorRect = null; if (orientation == PlotOrientation.HORIZONTAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, labelOffsetForRange, LengthAdjustmentType.CONTRACT); } else if (orientation == PlotOrientation.VERTICAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, LengthAdjustmentType.CONTRACT, labelOffsetForRange); } return anchor.getAnchorPoint(anchorRect); }
/** * Calculates the {@code (x, y)} coordinates for drawing the label for a * marker on the range axis. * * @param g2 the graphics device. * @param orientation the plot orientation. * @param dataArea the data area. * @param markerArea the rectangle surrounding the marker. * @param markerOffset the marker offset. * @param labelOffsetType the label offset type. * @param anchor the label anchor. * * @return The coordinates for drawing the marker label. */ protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2, PlotOrientation orientation, Rectangle2D dataArea, Rectangle2D markerArea, RectangleInsets markerOffset, LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) { Rectangle2D anchorRect = null; if (orientation == PlotOrientation.HORIZONTAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, LengthAdjustmentType.CONTRACT, labelOffsetType); } else if (orientation == PlotOrientation.VERTICAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, labelOffsetType, LengthAdjustmentType.CONTRACT); } return anchor.getAnchorPoint(anchorRect); }
/** * Calculates the (x, y) coordinates for drawing a marker label. * * @param g2 the graphics device. * @param orientation the plot orientation. * @param dataArea the data area. * @param markerArea the rectangle surrounding the marker. * @param markerOffset the marker offset. * @param labelOffsetType the label offset type. * @param anchor the label anchor. * * @return The coordinates for drawing the marker label. */ protected Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2, PlotOrientation orientation, Rectangle2D dataArea, Rectangle2D markerArea, RectangleInsets markerOffset, LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) { Rectangle2D anchorRect = null; if (orientation == PlotOrientation.HORIZONTAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, labelOffsetType, LengthAdjustmentType.CONTRACT); } else if (orientation == PlotOrientation.VERTICAL) { anchorRect = markerOffset.createAdjustedRectangle(markerArea, LengthAdjustmentType.CONTRACT, labelOffsetType); } return anchor.getAnchorPoint(anchorRect); }
/** * Creates a new instance of {@code DialValueIndicator}. * * @param datasetIndex the dataset index. */ public DialValueIndicator(int datasetIndex) { this.datasetIndex = datasetIndex; this.angle = -90.0; this.radius = 0.3; this.frameAnchor = RectangleAnchor.CENTER; this.templateValue = new Double(100.0); this.maxTemplateValue = null; this.formatter = new DecimalFormat("0.0"); this.font = new Font("Dialog", Font.BOLD, 14); this.paint = Color.BLACK; this.backgroundPaint = Color.WHITE; this.outlineStroke = new BasicStroke(1.0f); this.outlinePaint = Color.BLUE; this.insets = new RectangleInsets(4, 4, 4, 4); this.valueAnchor = RectangleAnchor.RIGHT; this.textAnchor = TextAnchor.CENTER_RIGHT; }
/** * Creates a new crosshair value with the specified value and line style. * * @param value the value. * @param paint the line paint ({@code null} not permitted). * @param stroke the line stroke ({@code null} not permitted). */ public Crosshair(double value, Paint paint, Stroke stroke) { Args.nullNotPermitted(paint, "paint"); Args.nullNotPermitted(stroke, "stroke"); this.visible = true; this.value = value; this.paint = paint; this.stroke = stroke; this.labelVisible = false; this.labelGenerator = new StandardCrosshairLabelGenerator(); this.labelAnchor = RectangleAnchor.BOTTOM_LEFT; this.labelXOffset = 3.0; this.labelYOffset = 3.0; this.labelFont = new Font("Tahoma", Font.PLAIN, 12); this.labelPaint = Color.BLACK; this.labelBackgroundPaint = new Color(0, 0, 255, 63); this.labelOutlineVisible = true; this.labelOutlinePaint = Color.BLACK; this.labelOutlineStroke = new BasicStroke(0.5f); this.pcs = new PropertyChangeSupport(this); }
/** * Creates a new instance where the category labels angled upwards by the * specified amount. * * @param angle the rotation angle (should be < Math.PI / 2.0). * * @return A category label position specification. */ public static CategoryLabelPositions createUpRotationLabelPositions( double angle) { return new CategoryLabelPositions( new CategoryLabelPosition( RectangleAnchor.BOTTOM, TextBlockAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT, -angle, CategoryLabelWidthType.RANGE, 0.50f), // TOP new CategoryLabelPosition( RectangleAnchor.TOP, TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, -angle, CategoryLabelWidthType.RANGE, 0.50f), // BOTTOM new CategoryLabelPosition( RectangleAnchor.RIGHT, TextBlockAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT, -angle, CategoryLabelWidthType.RANGE, 0.50f), // LEFT new CategoryLabelPosition( RectangleAnchor.LEFT, TextBlockAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, -angle, CategoryLabelWidthType.RANGE, 0.50f) // RIGHT ); }
/** * Creates a new instance where the category labels angled downwards by the * specified amount. * * @param angle the rotation angle (should be < Math.PI / 2.0). * * @return A category label position specification. */ public static CategoryLabelPositions createDownRotationLabelPositions( double angle) { return new CategoryLabelPositions( new CategoryLabelPosition( RectangleAnchor.BOTTOM, TextBlockAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT, angle, CategoryLabelWidthType.RANGE, 0.50f), // TOP new CategoryLabelPosition( RectangleAnchor.TOP, TextBlockAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, angle, CategoryLabelWidthType.RANGE, 0.50f), // BOTTOM new CategoryLabelPosition( RectangleAnchor.RIGHT, TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, angle, CategoryLabelWidthType.RANGE, 0.50f), // LEFT new CategoryLabelPosition( RectangleAnchor.LEFT, TextBlockAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT, angle, CategoryLabelWidthType.RANGE, 0.50f) // RIGHT ); }
/** * Creates a new position record. The item label anchor is a point * relative to the data item (dot, bar or other visual item) on a chart. * The item label is aligned by aligning the text anchor with the item * label anchor. * * @param categoryAnchor the category anchor ({@code null} not * permitted). * @param labelAnchor the label anchor ({@code null} not permitted). * @param rotationAnchor the rotation anchor ({@code null} not * permitted). * @param angle the rotation angle ({@code null} not permitted). * @param widthType the width type ({@code null} not permitted). * @param widthRatio the maximum label width as a percentage (of the * category space or the range space). */ public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor, TextAnchor rotationAnchor, double angle, CategoryLabelWidthType widthType, float widthRatio) { Args.nullNotPermitted(categoryAnchor, "categoryAnchor"); Args.nullNotPermitted(labelAnchor, "labelAnchor"); Args.nullNotPermitted(rotationAnchor, "rotationAnchor"); Args.nullNotPermitted(widthType, "widthType"); this.categoryAnchor = categoryAnchor; this.labelAnchor = labelAnchor; this.rotationAnchor = rotationAnchor; this.angle = angle; this.widthType = widthType; this.widthRatio = widthRatio; }
/** * Some checks for the getLabelAnchor() and setLabelAnchor() methods. */ @Test public void testGetSetLabelAnchor() { // we use ValueMarker for the tests, because we need a concrete // subclass... ValueMarker m = new ValueMarker(1.1); m.addChangeListener(this); this.lastEvent = null; assertEquals(RectangleAnchor.TOP_LEFT, m.getLabelAnchor()); m.setLabelAnchor(RectangleAnchor.TOP); assertEquals(RectangleAnchor.TOP, m.getLabelAnchor()); assertEquals(m, this.lastEvent.getMarker()); // check null argument... try { m.setLabelAnchor(null); fail("Expected an IllegalArgumentException for null."); } catch (IllegalArgumentException e) { assertTrue(true); } }
/** * Creates a new legend graphic. * * @param shape the shape ({@code null} not permitted). * @param fillPaint the fill paint ({@code null} not permitted). */ public LegendGraphic(Shape shape, Paint fillPaint) { Args.nullNotPermitted(shape, "shape"); Args.nullNotPermitted(fillPaint, "fillPaint"); this.shapeVisible = true; this.shape = shape; this.shapeAnchor = RectangleAnchor.CENTER; this.shapeLocation = RectangleAnchor.CENTER; this.shapeFilled = true; this.fillPaint = fillPaint; this.fillPaintTransformer = new StandardGradientPaintTransformer(); setPadding(2.0, 2.0, 2.0, 2.0); }
/** * Returns the text anchor that is used to align a label to its anchor * point. * * @param anchor the anchor. * * @return The text alignment point. */ private TextAnchor textAlignPtForLabelAnchorV(RectangleAnchor anchor) { TextAnchor result = TextAnchor.CENTER; if (anchor.equals(RectangleAnchor.TOP_LEFT)) { result = TextAnchor.TOP_RIGHT; } else if (anchor.equals(RectangleAnchor.TOP)) { result = TextAnchor.TOP_CENTER; } else if (anchor.equals(RectangleAnchor.TOP_RIGHT)) { result = TextAnchor.TOP_LEFT; } else if (anchor.equals(RectangleAnchor.LEFT)) { result = TextAnchor.HALF_ASCENT_RIGHT; } else if (anchor.equals(RectangleAnchor.RIGHT)) { result = TextAnchor.HALF_ASCENT_LEFT; } else if (anchor.equals(RectangleAnchor.BOTTOM_LEFT)) { result = TextAnchor.BOTTOM_RIGHT; } else if (anchor.equals(RectangleAnchor.BOTTOM)) { result = TextAnchor.BOTTOM_CENTER; } else if (anchor.equals(RectangleAnchor.BOTTOM_RIGHT)) { result = TextAnchor.BOTTOM_LEFT; } return result; }
/** * Returns the text anchor that is used to align a label to its anchor * point. * * @param anchor the anchor. * * @return The text alignment point. */ private TextAnchor textAlignPtForLabelAnchorH(RectangleAnchor anchor) { TextAnchor result = TextAnchor.CENTER; if (anchor.equals(RectangleAnchor.TOP_LEFT)) { result = TextAnchor.BOTTOM_LEFT; } else if (anchor.equals(RectangleAnchor.TOP)) { result = TextAnchor.BOTTOM_CENTER; } else if (anchor.equals(RectangleAnchor.TOP_RIGHT)) { result = TextAnchor.BOTTOM_RIGHT; } else if (anchor.equals(RectangleAnchor.LEFT)) { result = TextAnchor.HALF_ASCENT_LEFT; } else if (anchor.equals(RectangleAnchor.RIGHT)) { result = TextAnchor.HALF_ASCENT_RIGHT; } else if (anchor.equals(RectangleAnchor.BOTTOM_LEFT)) { result = TextAnchor.TOP_LEFT; } else if (anchor.equals(RectangleAnchor.BOTTOM)) { result = TextAnchor.TOP_CENTER; } else if (anchor.equals(RectangleAnchor.BOTTOM_RIGHT)) { result = TextAnchor.TOP_RIGHT; } return result; }
/** * Sets the anchor point used to align a block at its (x, y) location and * sends a {@link RendererChangeEvent} to all registered listeners. * * @param anchor the anchor. * * @see #getBlockAnchor() */ public void setBlockAnchor(RectangleAnchor anchor) { Args.nullNotPermitted(anchor, "anchor"); if (this.blockAnchor.equals(anchor)) { return; // no change } this.blockAnchor = anchor; updateOffsets(); fireChangeEvent(); }
/** * Updates the offsets to take into account the block width, height and * anchor. */ private void updateOffsets() { if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_LEFT)) { this.xOffset = 0.0; this.yOffset = 0.0; } else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM)) { this.xOffset = -this.blockWidth / 2.0; this.yOffset = 0.0; } else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_RIGHT)) { this.xOffset = -this.blockWidth; this.yOffset = 0.0; } else if (this.blockAnchor.equals(RectangleAnchor.LEFT)) { this.xOffset = 0.0; this.yOffset = -this.blockHeight / 2.0; } else if (this.blockAnchor.equals(RectangleAnchor.CENTER)) { this.xOffset = -this.blockWidth / 2.0; this.yOffset = -this.blockHeight / 2.0; } else if (this.blockAnchor.equals(RectangleAnchor.RIGHT)) { this.xOffset = -this.blockWidth; this.yOffset = -this.blockHeight / 2.0; } else if (this.blockAnchor.equals(RectangleAnchor.TOP_LEFT)) { this.xOffset = 0.0; this.yOffset = -this.blockHeight; } else if (this.blockAnchor.equals(RectangleAnchor.TOP)) { this.xOffset = -this.blockWidth / 2.0; this.yOffset = -this.blockHeight; } else if (this.blockAnchor.equals(RectangleAnchor.TOP_RIGHT)) { this.xOffset = -this.blockWidth; this.yOffset = -this.blockHeight; } }
/** * Creates a new label block. * * @param text the text for the label ({@code null} not permitted). * @param font the font ({@code null} not permitted). * @param paint the paint ({@code null} not permitted). */ public LabelBlock(String text, Font font, Paint paint) { this.text = text; this.paint = paint; this.label = TextUtils.createTextBlock(text, font, this.paint); this.font = font; this.toolTipText = null; this.urlText = null; this.contentAlignmentPoint = TextBlockAnchor.CENTER; this.textAnchor = RectangleAnchor.CENTER; }
/** * Draws the text box. * * @param g2 the graphics device. * @param x the x-coordinate. * @param y the y-coordinate. * @param anchor the anchor point. */ public void draw(Graphics2D g2, float x, float y, RectangleAnchor anchor) { final Size2D d1 = this.textBlock.calculateDimensions(g2); final double w = this.interiorGap.extendWidth(d1.getWidth()); final double h = this.interiorGap.extendHeight(d1.getHeight()); final Size2D d2 = new Size2D(w, h); final Rectangle2D bounds = RectangleAnchor.createRectangle(d2, x, y, anchor); double xx = bounds.getX(); double yy = bounds.getY(); if (this.shadowPaint != null) { final Rectangle2D shadow = new Rectangle2D.Double( xx + this.shadowXOffset, yy + this.shadowYOffset, bounds.getWidth(), bounds.getHeight()); g2.setPaint(this.shadowPaint); g2.fill(shadow); } if (this.backgroundPaint != null) { g2.setPaint(this.backgroundPaint); g2.fill(bounds); } if (this.outlinePaint != null && this.outlineStroke != null) { g2.setPaint(this.outlinePaint); g2.setStroke(this.outlineStroke); g2.draw(bounds); } this.textBlock.draw(g2, (float) (xx + this.interiorGap.calculateLeftInset(w)), (float) (yy + this.interiorGap.calculateTopInset(h)), TextBlockAnchor.TOP_LEFT); }
/** * Constructs a new marker. * * @param paint the paint ({@code null} not permitted). * @param stroke the stroke ({@code null} not permitted). * @param outlinePaint the outline paint ({@code null} permitted). * @param outlineStroke the outline stroke ({@code null} permitted). * @param alpha the alpha transparency (must be in the range 0.0f to * 1.0f). * * @throws IllegalArgumentException if {@code paint} or * {@code stroke} is {@code null}, or {@code alpha} is * not in the specified range. */ protected Marker(Paint paint, Stroke stroke, Paint outlinePaint, Stroke outlineStroke, float alpha) { Args.nullNotPermitted(paint, "paint"); Args.nullNotPermitted(stroke, "stroke"); if (alpha < 0.0f || alpha > 1.0f) { throw new IllegalArgumentException( "The 'alpha' value must be in the range 0.0f to 1.0f"); } this.paint = paint; this.stroke = stroke; this.outlinePaint = outlinePaint; this.outlineStroke = outlineStroke; this.alpha = alpha; this.labelFont = new Font("SansSerif", Font.PLAIN, 9); this.labelPaint = Color.BLACK; this.labelBackgroundColor = new Color(100, 100, 100, 100); this.labelAnchor = RectangleAnchor.TOP_LEFT; this.labelOffset = new RectangleInsets(3.0, 3.0, 3.0, 3.0); this.labelOffsetType = LengthAdjustmentType.CONTRACT; this.labelTextAnchor = TextAnchor.CENTER; this.listenerList = new EventListenerList(); }
/** * Translates a shape to a new location such that the anchor point * (relative to the rectangular bounds of the shape) aligns with the * specified (x, y) coordinate in Java2D space. * * @param shape the shape ({@code null} not permitted). * @param anchor the anchor ({@code null} not permitted). * @param locationX the x-coordinate (in Java2D space). * @param locationY the y-coordinate (in Java2D space). * * @return A new and translated shape. */ public static Shape createTranslatedShape(Shape shape, RectangleAnchor anchor, double locationX, double locationY) { if (shape == null) { throw new IllegalArgumentException("Null 'shape' argument."); } if (anchor == null) { throw new IllegalArgumentException("Null 'anchor' argument."); } Point2D anchorPoint = anchor.getAnchorPoint(shape.getBounds2D()); final AffineTransform transform = AffineTransform.getTranslateInstance( locationX - anchorPoint.getX(), locationY - anchorPoint.getY()); return transform.createTransformedShape(shape); }
/** * Creates a new annotation to be displayed at the specified (x, y) * location. * * @param x the x-coordinate (in data space). * @param y the y-coordinate (in data space). * @param title the title ({@code null} not permitted). * @param anchor the title anchor ({@code null} not permitted). */ public XYTitleAnnotation(double x, double y, Title title, RectangleAnchor anchor) { super(); Args.nullNotPermitted(title, "title"); Args.nullNotPermitted(anchor, "anchor"); this.coordinateType = XYCoordinateType.RELATIVE; this.x = x; this.y = y; this.maxWidth = 0.0; this.maxHeight = 0.0; this.title = title; this.anchor = anchor; }
protected ValueMarker makeMarker( final double value ) { final ValueMarker valueMarker = new ValueMarker( value ); valueMarker.setStroke( new BasicStroke ( 2f ) ); valueMarker.setPaint( new Color( 0f/255f, 0f/255f, 255f/255f ) ); valueMarker.setLabel( " Distance=" + value ); valueMarker.setLabelPaint( Color.BLUE ); valueMarker.setLabelAnchor( RectangleAnchor.TOP ); valueMarker.setLabelTextAnchor( TextAnchor.TOP_LEFT ); return valueMarker; }
protected ValueMarker makeMarker( final int timePoint ) { final ValueMarker valueMarker = new ValueMarker( timePoint ); valueMarker.setStroke( new BasicStroke ( 1.5f ) ); valueMarker.setPaint( new Color( 0.0f, 93f/255f, 9f/255f ) ); valueMarker.setLabel( " Reference\n Timepoint " + timePoint ); valueMarker.setLabelAnchor(RectangleAnchor.BOTTOM ); valueMarker.setLabelTextAnchor( TextAnchor.BOTTOM_LEFT ); return valueMarker; }
/** * Draws a crosshair horizontally across the plot. * * @param g2 the graphics target. * @param dataArea the data area. * @param y the y-value in Java2D space. * @param crosshair the crosshair. */ protected void drawHorizontalCrosshair(Graphics2D g2, Rectangle2D dataArea, double y, Crosshair crosshair) { if (y >= dataArea.getMinY() && y <= dataArea.getMaxY()) { Line2D line = new Line2D.Double(dataArea.getMinX(), y, dataArea.getMaxX(), y); Paint savedPaint = g2.getPaint(); Stroke savedStroke = g2.getStroke(); g2.setPaint(crosshair.getPaint()); g2.setStroke(crosshair.getStroke()); g2.draw(line); if (crosshair.isLabelVisible()) { Font savedFont = g2.getFont(); g2.setFont(crosshair.getLabelFont()); String label = crosshair.getLabelGenerator().generateLabel( crosshair); RectangleAnchor anchor = crosshair.getLabelAnchor(); Point2D pt = calculateLabelPoint(line, anchor, 5, 5); float xx = (float) pt.getX(); float yy = (float) pt.getY(); TextAnchor alignPt = textAlignPtForLabelAnchorH(anchor); Shape hotspot = TextUtils.calculateRotatedStringBounds( label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER); if (!dataArea.contains(hotspot.getBounds2D())) { anchor = flipAnchorV(anchor); pt = calculateLabelPoint(line, anchor, 5, 5); xx = (float) pt.getX(); yy = (float) pt.getY(); alignPt = textAlignPtForLabelAnchorH(anchor); hotspot = TextUtils.calculateRotatedStringBounds( label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER); } g2.setPaint(crosshair.getLabelBackgroundPaint()); g2.fill(hotspot); if (crosshair.isLabelOutlineVisible()) { g2.setPaint(crosshair.getLabelOutlinePaint()); g2.setStroke(crosshair.getLabelOutlineStroke()); } g2.draw(hotspot); g2.setPaint(crosshair.getLabelPaint()); TextUtils.drawAlignedString(label, g2, xx, yy, alignPt); g2.setFont(savedFont); } g2.setPaint(savedPaint); g2.setStroke(savedStroke); } }
/** * Draws a crosshair vertically on the plot. * * @param g2 the graphics target. * @param dataArea the data area. * @param x the x-value in Java2D space. * @param crosshair the crosshair. */ protected void drawVerticalCrosshair(Graphics2D g2, Rectangle2D dataArea, double x, Crosshair crosshair) { if (x >= dataArea.getMinX() && x <= dataArea.getMaxX()) { Line2D line = new Line2D.Double(x, dataArea.getMinY(), x, dataArea.getMaxY()); Paint savedPaint = g2.getPaint(); Stroke savedStroke = g2.getStroke(); g2.setPaint(crosshair.getPaint()); g2.setStroke(crosshair.getStroke()); g2.draw(line); if (crosshair.isLabelVisible()) { Font savedFont = g2.getFont(); g2.setFont(crosshair.getLabelFont()); String label = crosshair.getLabelGenerator().generateLabel( crosshair); RectangleAnchor anchor = crosshair.getLabelAnchor(); Point2D pt = calculateLabelPoint(line, anchor, 5, 5); float xx = (float) pt.getX(); float yy = (float) pt.getY(); TextAnchor alignPt = textAlignPtForLabelAnchorV(anchor); Shape hotspot = TextUtils.calculateRotatedStringBounds( label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER); if (!dataArea.contains(hotspot.getBounds2D())) { anchor = flipAnchorH(anchor); pt = calculateLabelPoint(line, anchor, 5, 5); xx = (float) pt.getX(); yy = (float) pt.getY(); alignPt = textAlignPtForLabelAnchorV(anchor); hotspot = TextUtils.calculateRotatedStringBounds( label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER); } g2.setPaint(crosshair.getLabelBackgroundPaint()); g2.fill(hotspot); if (crosshair.isLabelOutlineVisible()) { g2.setPaint(crosshair.getLabelOutlinePaint()); g2.setStroke(crosshair.getLabelOutlineStroke()); g2.draw(hotspot); } g2.setPaint(crosshair.getLabelPaint()); TextUtils.drawAlignedString(label, g2, xx, yy, alignPt); g2.setFont(savedFont); } g2.setPaint(savedPaint); g2.setStroke(savedStroke); } }
/** * Calculates the anchor point for a label. * * @param line the line for the crosshair. * @param anchor the anchor point. * @param deltaX the x-offset. * @param deltaY the y-offset. * * @return The anchor point. */ private Point2D calculateLabelPoint(Line2D line, RectangleAnchor anchor, double deltaX, double deltaY) { double x, y; boolean left = (anchor == RectangleAnchor.BOTTOM_LEFT || anchor == RectangleAnchor.LEFT || anchor == RectangleAnchor.TOP_LEFT); boolean right = (anchor == RectangleAnchor.BOTTOM_RIGHT || anchor == RectangleAnchor.RIGHT || anchor == RectangleAnchor.TOP_RIGHT); boolean top = (anchor == RectangleAnchor.TOP_LEFT || anchor == RectangleAnchor.TOP || anchor == RectangleAnchor.TOP_RIGHT); boolean bottom = (anchor == RectangleAnchor.BOTTOM_LEFT || anchor == RectangleAnchor.BOTTOM || anchor == RectangleAnchor.BOTTOM_RIGHT); Rectangle rect = line.getBounds(); // we expect the line to be vertical or horizontal if (line.getX1() == line.getX2()) { // vertical x = line.getX1(); y = (line.getY1() + line.getY2()) / 2.0; if (left) { x = x - deltaX; } if (right) { x = x + deltaX; } if (top) { y = Math.min(line.getY1(), line.getY2()) + deltaY; } if (bottom) { y = Math.max(line.getY1(), line.getY2()) - deltaY; } } else { // horizontal x = (line.getX1() + line.getX2()) / 2.0; y = line.getY1(); if (left) { x = Math.min(line.getX1(), line.getX2()) + deltaX; } if (right) { x = Math.max(line.getX1(), line.getX2()) - deltaX; } if (top) { y = y - deltaY; } if (bottom) { y = y + deltaY; } } return new Point2D.Double(x, y); }
/** * Draws the background to the specified graphics device. If the dial * frame specifies a window, the clipping region will already have been * set to this window before this method is called. * * @param g2 the graphics device ({@code null} not permitted). * @param plot the plot (ignored here). * @param frame the dial frame (ignored here). * @param view the view rectangle ({@code null} not permitted). */ @Override public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame, Rectangle2D view) { // work out the anchor point Rectangle2D f = DialPlot.rectangleByRadius(frame, this.radius, this.radius); Arc2D arc = new Arc2D.Double(f, this.angle, 0.0, Arc2D.OPEN); Point2D pt = arc.getStartPoint(); // the indicator bounds is calculated from the templateValue (which // determines the minimum size), the maxTemplateValue (which, if // specified, provides a maximum size) and the actual value FontMetrics fm = g2.getFontMetrics(this.font); double value = plot.getValue(this.datasetIndex); String valueStr = this.formatter.format(value); Rectangle2D valueBounds = TextUtils.getTextBounds(valueStr, g2, fm); // calculate the bounds of the template value String s = this.formatter.format(this.templateValue); Rectangle2D tb = TextUtils.getTextBounds(s, g2, fm); double minW = tb.getWidth(); double minH = tb.getHeight(); double maxW = Double.MAX_VALUE; double maxH = Double.MAX_VALUE; if (this.maxTemplateValue != null) { s = this.formatter.format(this.maxTemplateValue); tb = TextUtils.getTextBounds(s, g2, fm); maxW = Math.max(tb.getWidth(), minW); maxH = Math.max(tb.getHeight(), minH); } double w = fixToRange(valueBounds.getWidth(), minW, maxW); double h = fixToRange(valueBounds.getHeight(), minH, maxH); // align this rectangle to the frameAnchor Rectangle2D bounds = RectangleAnchor.createRectangle(new Size2D(w, h), pt.getX(), pt.getY(), this.frameAnchor); // add the insets Rectangle2D fb = this.insets.createOutsetRectangle(bounds); // draw the background g2.setPaint(this.backgroundPaint); g2.fill(fb); // draw the border g2.setStroke(this.outlineStroke); g2.setPaint(this.outlinePaint); g2.draw(fb); // now find the text anchor point Shape savedClip = g2.getClip(); g2.clip(fb); Point2D pt2 = this.valueAnchor.getAnchorPoint(bounds); g2.setPaint(this.paint); g2.setFont(this.font); TextUtils.drawAlignedString(valueStr, g2, (float) pt2.getX(), (float) pt2.getY(), this.textAnchor); g2.setClip(savedClip); }
/** * Draws a section label on the left side of the pie chart. * * @param g2 the graphics device. * @param state the state. * @param record the label record. */ protected void drawLeftLabel(Graphics2D g2, PiePlotState state, PieLabelRecord record) { double anchorX = state.getLinkArea().getMinX(); double targetX = anchorX - record.getGap(); double targetY = record.getAllocatedY(); if (this.labelLinksVisible) { double theta = record.getAngle(); double linkX = state.getPieCenterX() + Math.cos(theta) * state.getPieWRadius() * record.getLinkPercent(); double linkY = state.getPieCenterY() - Math.sin(theta) * state.getPieHRadius() * record.getLinkPercent(); double elbowX = state.getPieCenterX() + Math.cos(theta) * state.getLinkArea().getWidth() / 2.0; double elbowY = state.getPieCenterY() - Math.sin(theta) * state.getLinkArea().getHeight() / 2.0; double anchorY = elbowY; g2.setPaint(this.labelLinkPaint); g2.setStroke(this.labelLinkStroke); PieLabelLinkStyle style = getLabelLinkStyle(); if (style.equals(PieLabelLinkStyle.STANDARD)) { g2.draw(new Line2D.Double(linkX, linkY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, targetX, targetY)); } else if (style.equals(PieLabelLinkStyle.QUAD_CURVE)) { QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(targetX, targetY, anchorX, anchorY, elbowX, elbowY); g2.draw(q); g2.draw(new Line2D.Double(elbowX, elbowY, linkX, linkY)); } else if (style.equals(PieLabelLinkStyle.CUBIC_CURVE)) { CubicCurve2D c = new CubicCurve2D .Float(); c.setCurve(targetX, targetY, anchorX, anchorY, elbowX, elbowY, linkX, linkY); g2.draw(c); } } TextBox tb = record.getLabel(); tb.draw(g2, (float) targetX, (float) targetY, RectangleAnchor.RIGHT); }
/** * Draws a section label on the right side of the pie chart. * * @param g2 the graphics device. * @param state the state. * @param record the label record. */ protected void drawRightLabel(Graphics2D g2, PiePlotState state, PieLabelRecord record) { double anchorX = state.getLinkArea().getMaxX(); double targetX = anchorX + record.getGap(); double targetY = record.getAllocatedY(); if (this.labelLinksVisible) { double theta = record.getAngle(); double linkX = state.getPieCenterX() + Math.cos(theta) * state.getPieWRadius() * record.getLinkPercent(); double linkY = state.getPieCenterY() - Math.sin(theta) * state.getPieHRadius() * record.getLinkPercent(); double elbowX = state.getPieCenterX() + Math.cos(theta) * state.getLinkArea().getWidth() / 2.0; double elbowY = state.getPieCenterY() - Math.sin(theta) * state.getLinkArea().getHeight() / 2.0; double anchorY = elbowY; g2.setPaint(this.labelLinkPaint); g2.setStroke(this.labelLinkStroke); PieLabelLinkStyle style = getLabelLinkStyle(); if (style.equals(PieLabelLinkStyle.STANDARD)) { g2.draw(new Line2D.Double(linkX, linkY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, targetX, targetY)); } else if (style.equals(PieLabelLinkStyle.QUAD_CURVE)) { QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(targetX, targetY, anchorX, anchorY, elbowX, elbowY); g2.draw(q); g2.draw(new Line2D.Double(elbowX, elbowY, linkX, linkY)); } else if (style.equals(PieLabelLinkStyle.CUBIC_CURVE)) { CubicCurve2D c = new CubicCurve2D .Float(); c.setCurve(targetX, targetY, anchorX, anchorY, elbowX, elbowY, linkX, linkY); g2.draw(c); } } TextBox tb = record.getLabel(); tb.draw(g2, (float) targetX, (float) targetY, RectangleAnchor.LEFT); }
/** * Creates a new position record with default settings. */ public CategoryLabelPosition() { this(RectangleAnchor.CENTER, TextBlockAnchor.BOTTOM_CENTER, TextAnchor.CENTER, 0.0, CategoryLabelWidthType.CATEGORY, 0.95f); }
/** * Check that the equals() method distinguishes all fields. */ @Test public void testEquals() { XYPlot plot1 = new XYPlot(); LegendTitle t1 = new LegendTitle(plot1); LegendTitle t2 = new LegendTitle(plot1); assertEquals(t1, t2); t1.setBackgroundPaint( new GradientPaint(1.0f, 2.0f, Color.RED, 3.0f, 4.0f, Color.YELLOW) ); assertFalse(t1.equals(t2)); t2.setBackgroundPaint( new GradientPaint(1.0f, 2.0f, Color.RED, 3.0f, 4.0f, Color.YELLOW) ); assertTrue(t1.equals(t2)); t1.setLegendItemGraphicEdge(RectangleEdge.BOTTOM); assertFalse(t1.equals(t2)); t2.setLegendItemGraphicEdge(RectangleEdge.BOTTOM); assertTrue(t1.equals(t2)); t1.setLegendItemGraphicAnchor(RectangleAnchor.BOTTOM_LEFT); assertFalse(t1.equals(t2)); t2.setLegendItemGraphicAnchor(RectangleAnchor.BOTTOM_LEFT); assertTrue(t1.equals(t2)); t1.setLegendItemGraphicLocation(RectangleAnchor.TOP_LEFT); assertFalse(t1.equals(t2)); t2.setLegendItemGraphicLocation(RectangleAnchor.TOP_LEFT); assertTrue(t1.equals(t2)); t1.setItemFont(new Font("Dialog", Font.PLAIN, 19)); assertFalse(t1.equals(t2)); t2.setItemFont(new Font("Dialog", Font.PLAIN, 19)); assertTrue(t1.equals(t2)); t1.setSortOrder(SortOrder.DESCENDING); assertFalse(t1.equals(t2)); t2.setSortOrder(SortOrder.DESCENDING); assertTrue(t1.equals(t2)); }
/** * Confirm that the equals() method can distinguish all the required fields. */ @Test public void testEquals() { LabelBlock b1 = new LabelBlock("ABC", new Font("Dialog", Font.PLAIN, 12), Color.RED); LabelBlock b2 = new LabelBlock("ABC", new Font("Dialog", Font.PLAIN, 12), Color.RED); assertTrue(b1.equals(b2)); assertTrue(b2.equals(b2)); b1 = new LabelBlock("XYZ", new Font("Dialog", Font.PLAIN, 12), Color.RED); assertFalse(b1.equals(b2)); b2 = new LabelBlock("XYZ", new Font("Dialog", Font.PLAIN, 12), Color.RED); assertTrue(b1.equals(b2)); b1 = new LabelBlock("XYZ", new Font("Dialog", Font.BOLD, 12), Color.RED); assertFalse(b1.equals(b2)); b2 = new LabelBlock("XYZ", new Font("Dialog", Font.BOLD, 12), Color.RED); assertTrue(b1.equals(b2)); b1 = new LabelBlock("XYZ", new Font("Dialog", Font.BOLD, 12), Color.BLUE); assertFalse(b1.equals(b2)); b2 = new LabelBlock("XYZ", new Font("Dialog", Font.BOLD, 12), Color.BLUE); assertTrue(b1.equals(b2)); b1.setToolTipText("Tooltip"); assertFalse(b1.equals(b2)); b2.setToolTipText("Tooltip"); assertTrue(b1.equals(b2)); b1.setURLText("URL"); assertFalse(b1.equals(b2)); b2.setURLText("URL"); assertTrue(b1.equals(b2)); b1.setContentAlignmentPoint(TextBlockAnchor.CENTER_RIGHT); assertFalse(b1.equals(b2)); b2.setContentAlignmentPoint(TextBlockAnchor.CENTER_RIGHT); assertTrue(b1.equals(b2)); b1.setTextAnchor(RectangleAnchor.BOTTOM_RIGHT); assertFalse(b1.equals(b2)); b2.setTextAnchor(RectangleAnchor.BOTTOM_RIGHT); assertTrue(b1.equals(b2)); }
/** * Check that the equals() method can distinguish all fields. */ @Test public void testEquals() { CategoryLabelPosition p1 = new CategoryLabelPosition( RectangleAnchor.BOTTOM_LEFT, TextBlockAnchor.CENTER_RIGHT, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); CategoryLabelPosition p2 = new CategoryLabelPosition( RectangleAnchor.BOTTOM_LEFT, TextBlockAnchor.CENTER_RIGHT, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertTrue(p1.equals(p2)); assertTrue(p2.equals(p1)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER_RIGHT, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER_RIGHT, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertTrue(p1.equals(p2)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.BASELINE_LEFT, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertTrue(p1.equals(p2)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 4.0, CategoryLabelWidthType.RANGE, 0.44f); assertTrue(p1.equals(p2)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.RANGE, 0.44f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.RANGE, 0.44f); assertTrue(p1.equals(p2)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.CATEGORY, 0.44f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.CATEGORY, 0.44f); assertTrue(p1.equals(p2)); p1 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.CATEGORY, 0.55f); assertFalse(p1.equals(p2)); p2 = new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER, TextAnchor.CENTER, Math.PI / 6.0, CategoryLabelWidthType.CATEGORY, 0.55f); assertTrue(p1.equals(p2)); }
/** * Creates a new category label position record. * * @param categoryAnchor the category anchor ({@code null} not * permitted). * @param labelAnchor the label anchor ({@code null} not permitted). */ public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor) { // argument checking delegated... this(categoryAnchor, labelAnchor, TextAnchor.CENTER, 0.0, CategoryLabelWidthType.CATEGORY, 0.95f); }
/** * Creates a new category label position record. * * @param categoryAnchor the category anchor ({@code null} not * permitted). * @param labelAnchor the label anchor ({@code null} not permitted). * @param widthType the width type ({@code null} not permitted). * @param widthRatio the maximum label width as a percentage (of the * category space or the range space). */ public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor, CategoryLabelWidthType widthType, float widthRatio) { // argument checking delegated... this(categoryAnchor, labelAnchor, TextAnchor.CENTER, 0.0, widthType, widthRatio); }
/** * Creates a new annotation to be displayed at the specified (x, y) * location. * * @param x the x-coordinate (in data space). * @param y the y-coordinate (in data space). * @param image the image ({@code null} not permitted). * @param anchor the image anchor ({@code null} not permitted). * * @since 1.0.4 */ public XYImageAnnotation(double x, double y, Image image, RectangleAnchor anchor) { super(); Args.nullNotPermitted(image, "image"); Args.nullNotPermitted(anchor, "anchor"); this.x = x; this.y = y; this.image = image; this.anchor = anchor; }
/** * Returns the legend item graphic anchor. * * @return The graphic anchor (never {@code null}). */ public RectangleAnchor getLegendItemGraphicAnchor() { return this.legendItemGraphicAnchor; }