axis ticks move though they shouldn't

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
christopher.loerken
Posts: 16
Joined: Wed Aug 31, 2005 4:25 pm

axis ticks move though they shouldn't

Post by christopher.loerken » Wed Aug 31, 2005 4:45 pm

Hi,
I've got to write my own zooming method in a XYPlot using TimeSeries. Therefore, I want to simulate y-axis zooming by simply doubling the axis range.
The problem is that I want to have the axis tick units stay at exactly the same position and same distance to each other...
If defined a range for the axis by using setRange() and did set a custom tickUnit, resulting in the desired image on start of the program. However, if I change the settings for the axis during runtime by setting a larger Range and picking a larger tickunit, the position of the first tickunit does unfortunately not stay at the same position.
Instead, the axis shifts its ticks...

I'm using this code:

Code: Select all

adding data ...

NumberAxis rangeAxis = new NumberAxis();                    

rangeAxis.setRange(startY, endY);
double range = rangeAxis.getUpperBound() - rangeAxis.getLowerBound(); 
rangeAxis.setTickUnit(new NumberTickUnit(range / 10.0, numberFormatter)); 

... mapping sets etc.
So I'm basically trying to limit the ticks on the y-axis to exactly 10 with having the first starting at the origin.

But if I change startY and endY during runtime, the first tick moves away.

I've checked the settings in the axis after everthing was drawn and it its range is correct... So the problem has to lie somewhere within the tickhandling.

Thanks for reading and I would be happy to hear from you.

Cheers Christopher

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 » Thu Sep 01, 2005 10:58 am

Can you post a before and after chart image?
David Gilbert
JFreeChart Project Leader

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

christopher.loerken
Posts: 16
Joined: Wed Aug 31, 2005 4:25 pm

Post by christopher.loerken » Thu Sep 01, 2005 1:24 pm

Here you go:
Image

The left image is the initial axis how it is displayed using the code of the first post. (range = 1.2)

The second is after one y-axis zoom out step. Notice that the y-axis did in fact change the way I want it to behave. It shows twice the range (= 2.4) of the first axis without changing the position of the tick marks.

The right image, however, is after another zoom out step.
Here, the axis again has the right size being twice the size of the middle image.
According to lower / upper bound:
startY: -2.16
endY: 2.6400000000000006
The range is 4.800000000000001
resulting in a tickstep of : 0.4800000000000001

Therefore, the first Tickmark should be at: -1.68 (== startY+tickstep)
It has shifted, however, to -1.92.

And I don't know why...
I want it to stay fixed for not having the axis tickmarks to move due to zooming.

Have you got any idea?

Cheers Christopher

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 » Thu Sep 01, 2005 2:12 pm

The tick positions are calculated relative to the 0.0 value on the axis (so the -1.92 is the 4th tick mark away from zero, i.e. -4 x 0.48). You would have to override the refreshTicks() method in the axis to change that.
David Gilbert
JFreeChart Project Leader

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

christopher.loerken
Posts: 16
Joined: Wed Aug 31, 2005 4:25 pm

Post by christopher.loerken » Thu Sep 01, 2005 3:11 pm

Grant! :D

That's exactly the information I needed.

Actually it was not the refreshTicks() method I had to adjust but rather the calculateLowestVisibleTickValue() method.

So if anyone is interested on how to freeze the position of you tickunits on a range Numberaxis, here is the code that worked for me:

Code: Select all

    public static class CustomTickNumberAxis extends org.jfree.chart.axis.NumberAxis {
        
        /**
         * Holds value of property lowestVisibleTickValue.
         * The lowest visible tick unit is the bottom anchor for a vertical 
         * number axis.
         * NOTE: Make sure this value is >= the lowerBound of the NumberAxis, as
         * otherwise it will be ignored as it cannot be displayed correctly.
         * See {@link #calculateLowestVisibleTickValue}.
         */
        private Double lowestVisibleTickValue;        
        
       /**
        * Calculates the value of the lowest visible tick on the axis or
        * returns any previously specified. See {@link #lowestVisibleTickValue}.
        * If the specified value is smaller than the lower bound of the axis, the
        * default method (see {@link NumberAxis#calculateLowestVisibleTickValue})
        * is used.
        * @return The value of the lowest visible tick on the axis.
        */
        protected double calculateLowestVisibleTickValue() {
            if (lowestVisibleTickValue != null && lowestVisibleTickValue.doubleValue() >= getRange().getLowerBound()) {                                    
                return lowestVisibleTickValue.doubleValue();
            } else
                return super.calculateLowestVisibleTickValue();
        }
        
        /**
         * Getter for property lowestVisibleTickValue.
         * @return Value of property lowestVisibleTickValue.
         */
        public Double getLowestVisibleTickValue() {
            return this.lowestVisibleTickValue;
        }        
        
        /**
         * Setter for property lowestVisibleTickValue.
         * @param lowestVisibleTickValue New value of property lowestVisibleTickValue.
         */
        public void setLowestVisibleTickValue(Double lowestVisibleTickValue) {
            this.lowestVisibleTickValue = lowestVisibleTickValue;
        }
        
    }

In your program you will succeed by doing:

Code: Select all

CustomTickNumberAxis rangeAxis = (CustomTickNumberAxis) plot.getRangeAxis();
rangeAxis.setRange(startY, endY);
rangeAxis.setLowestVisibleTickValue(new Double(startY));

Dave, wouldn't it be nice to always have the posibility to assign a starting position to the axis ticks? I think that it really looks nicer if you're displaying dynamic data to keep the axis marks at fixed positions.

Anyway thx for your quick response,
Christopher

Locked