Value Marker Labels get clipped

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
jfreeuser2006
Posts: 59
Joined: Mon Nov 20, 2006 1:00 pm

Value Marker Labels get clipped

Post by jfreeuser2006 » Sun Aug 12, 2007 9:12 am

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.

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Mon Aug 13, 2007 1:38 pm

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

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

markjtan
Posts: 1
Joined: Fri Oct 05, 2007 8:43 pm
Contact:

Workaround

Post by markjtan » Fri Oct 05, 2007 8:47 pm

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!

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);
		}
	}
Actually, hope this helps : )

Locked