Hi all,
I have added value markers to my chart.
I asked this before but I didn't get a solution. I'm using version 1.0.5 of JFreeChart.
The problem is that when the value marker is near or is equal to the upper or lowerbound of the chart they get clipped.
I know one solution would be to override LabelAnchor and LabelTextAnchor. Can anybody show me how to do this?
Another would be to make use of annotations.
Personally I'd choose the former rather than the latter solution.
Value Marker Labels get clipped
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
I'd like to fix this (eventually) by having the renderers take into account the space required to display the item labels when determining the range required for the dataset (that is, in the findDomainBounds() and findRangeBounds() methods). That's a sizeable chunk of work, I think, and the (not ideal) workaround for now is to increase the upper margin for the axis to make more whitespace available at the top of the chart for the labels.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


Workaround
Hi,
You can prevent the clipping by creating a custom XYItemRenderer overriding the calculateDomainMarkerTextAnchorPoint() method. The implementation, however, requires the actual marker label string and the Font. Since these are not provided through the method parameters, it is passed in through the constructor. (An API request would be to allow the actual ValueMarker to be passed into this overrided method).
Here's the code!
Actually, hope this helps : )
You can prevent the clipping by creating a custom XYItemRenderer overriding the calculateDomainMarkerTextAnchorPoint() method. The implementation, however, requires the actual marker label string and the Font. Since these are not provided through the method parameters, it is passed in through the constructor. (An API request would be to allow the actual ValueMarker to be passed into this overrided method).
Here's the code!
Code: Select all
public static class CustomXYAreaRenderer extends XYAreaRenderer
{
private String exampleLabel;
private Font valueMarkerFont;
public CustomXYAreaRenderer(int area, String exampleLabel, Font valueMarkerFont)
{
super(area);
this.exampleLabel = exampleLabel;
this.valueMarkerFont = valueMarkerFont;
}
protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2, PlotOrientation orientation, Rectangle2D dataArea, Rectangle2D markerArea, RectangleInsets markerOffset, LengthAdjustmentType labelOffsetType, RectangleAnchor anchor)
{
double width = TextUtilities.getTextBounds(exampleLabel, g2, g2.getFontMetrics(valueMarkerFont)).getWidth();
Rectangle2D anchorRect = null;
if (orientation == PlotOrientation.HORIZONTAL)
{
anchorRect = markerOffset.createAdjustedRectangle(markerArea, LengthAdjustmentType.CONTRACT, labelOffsetType);
double upperBoundaryDiff = (width / 2) - Math.abs(markerArea.getY() - dataArea.getY());
double lowerBoundaryDiff = (width / 2) - Math.abs(dataArea.getY() + dataArea.getHeight() - markerArea.getY());
if (upperBoundaryDiff > 0)
{
anchorRect.setRect(anchorRect.getX(), anchorRect.getY() + upperBoundaryDiff, anchorRect.getWidth(), anchorRect.getHeight());
}
else if (lowerBoundaryDiff > 0)
{
anchorRect.setRect(anchorRect.getX(), anchorRect.getY() - lowerBoundaryDiff, anchorRect.getWidth(), anchorRect.getHeight());
}
}
else if (orientation == PlotOrientation.VERTICAL)
{
anchorRect = markerOffset.createAdjustedRectangle(markerArea, labelOffsetType, LengthAdjustmentType.CONTRACT);
double leftBoundaryDiff = (width / 2) - Math.abs(markerArea.getX() - dataArea.getX());
double rightBoundaryDiff = (width / 2) - Math.abs(dataArea.getX() + dataArea.getWidth() - markerArea.getX());
double extraPadding = 3;
if (leftBoundaryDiff > 0)
{
anchorRect.setRect(anchorRect.getX() + (leftBoundaryDiff + extraPadding), anchorRect.getY(), anchorRect.getWidth(), anchorRect.getHeight());
}
else if (rightBoundaryDiff > 0)
{
anchorRect.setRect(anchorRect.getX() - (rightBoundaryDiff + extraPadding), anchorRect.getY(), anchorRect.getWidth(), anchorRect.getHeight());
}
}
return RectangleAnchor.coordinates(anchorRect, anchor);
}
}