AxisLabelLocation - Inside?

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
rfuegen
Posts: 4
Joined: Mon Jul 21, 2014 12:20 am
antibot: No, of course not.

AxisLabelLocation - Inside?

Post by rfuegen » Mon Jul 21, 2014 4:47 pm

I need to make a XY chart as large as possible and therefore would like to place the Axis labels INSIDE the chart (even if they overlap chart data):

X Axis - label ABOVE axis instead of below
Y AXIS - label RIGHT of the axis instead of left

is there an easy way to achieve this?

new constants like AxisLabelLocation.INSIDE_HIGH_END would be fine ;-)

tnx

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

Re: AxisLabelLocation - Inside?

Post by david.gilbert » Wed Jul 23, 2014 9:21 am

There isn't anything in the API to support this, the only way to do it would be to modify the JFreeChart code directly.
David Gilbert
JFreeChart Project Leader

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

rfuegen
Posts: 4
Joined: Mon Jul 21, 2014 12:20 am
antibot: No, of course not.

Re: AxisLabelLocation - Inside?

Post by rfuegen » Wed Jul 23, 2014 4:03 pm

tnx for the information.

maybe I'll dig into the code and see what I can do, since implementing it this way seems to be the best solution.

rfuegen
Posts: 4
Joined: Mon Jul 21, 2014 12:20 am
antibot: No, of course not.

Re: AxisLabelLocation - Status Update

Post by rfuegen » Mon Jul 28, 2014 1:18 am

I managed to

- introduce a new class AxisLabelPosition(.INSIDE and .OUTSIDE)
- with getters and setters in org.jfree.chart.axis.Axis
- calculate reserveSpace() properly in org.jfree.chart.axis.ValueAxis
- locate the labels somewhere close to where they ought to be

What I couldn't figure out so far:

- there's still an offset missing. on the Y Axis, obviously the reference point is the center of the label; on the X Axis, an offset to move the label actually INTO the data area (a few pixels up) is still required
- the axes & labels are painted before the chart data and are therefore covered by the chart data - therefore the order in which the objects are drawn needs to be changed

sample screenshot:
http://www.oudeis.org/JFC-InsideLabels.PNG
I'll keep looking into this, but would be great if anyone could speed it up by pointing me in the right direction.

here are some blocks of modified code. let me know if you need more (or where/how to send the modified .java files)

Code: Select all

Axis.drawLabel():
        else if (edge == RectangleEdge.BOTTOM) {
            AffineTransform t = AffineTransform.getRotateInstance(
                    getLabelAngle(), labelBounds.getCenterX(),
                    labelBounds.getCenterY());
            Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
            labelBounds = rotatedLabelBounds.getBounds2D();            
            labelx = labelLocationX(this.labelLocation, dataArea);
            if (labelPosition == AxisLabelPosition.OUTSIDE) {
            	labely = state.getCursor()
            			+ insets.getTop() + labelBounds.getHeight() / 2.0;
            } else if (labelPosition == AxisLabelPosition.INSIDE) {
            	labely = state.getCursor()
                        - insets.getTop() - labelBounds.getHeight();
            }
            TextAnchor anchor = labelAnchorH(this.labelLocation);
            TextUtilities.drawRotatedString(label, g2, (float) labelx,
                    (float) labely, anchor, getLabelAngle(), TextAnchor.CENTER);
            state.cursorDown(insets.getTop() + labelBounds.getHeight()
                    + insets.getBottom());
        }
        else if (edge == RectangleEdge.LEFT) {
            AffineTransform t = AffineTransform.getRotateInstance(
                    getLabelAngle() - Math.PI / 2.0, labelBounds.getCenterX(),
                    labelBounds.getCenterY());
            Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
            labelBounds = rotatedLabelBounds.getBounds2D();
            if (labelPosition == AxisLabelPosition.OUTSIDE) {
            	labelx = state.getCursor()               
            			- insets.getRight() - labelBounds.getWidth() / 2.0;
            } else if (labelPosition == AxisLabelPosition.INSIDE) {
            	labelx = state.getCursor() 
            			+ insets.getRight() + labelBounds.getWidth();
            }
            labely = labelLocationY(this.labelLocation, dataArea);
            TextAnchor anchor = labelAnchorV(this.labelLocation);
            TextUtilities.drawRotatedString(label, g2, (float) labelx,
                    (float) labely, anchor, getLabelAngle() - Math.PI / 2.0, 
                    anchor);
            state.cursorLeft(insets.getLeft() + labelBounds.getWidth()
                    + insets.getRight());
        }
tnx.

Locked