Rangeaxis: Ticks not displayed...

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

Rangeaxis: Ticks not displayed...

Post by christopher.loerken » Tue Sep 06, 2005 5:07 pm

I've got a problem while specifying custom TickUnits on my rangeaxis.
This works pretty well using this code:

Code: Select all

axis.setLowerBound(start);
axis.setUpperBound(end);
newRange = end-start;
axis.setTickUnit(new NumberTickUnit(newRange / 10, doubleFormatter)); 
However, sometimes the labes are not painted up to the top of the axis although there is certainly enough drawing space available...

Image

The left part of the image shows the Ticklabeling as I'd like to have it. The right image shows the Ticklabeling as it is sometimes.

It seems to depend on the range shown by the axis as the same code (sometimes) yields good results if the range is changed...

There exist three different cases I cannot explain:
- The topmost ticklabel is missing (happens very often)
- The two top ticklabels are missing (happens sometimes)
- The bottom most ticklabel is missing (again only sometimes)

Does anyone have any ideas?

Regards,
Christopher

Guest

Tick Label not visible.

Post by Guest » Wed Sep 07, 2005 12:57 pm

I have two value in Dataset

e.g.

1st = -2849382715582280D

i.e.

defaultcategorydataset.addValue(-2849382715582280D, "Series's 1", "Category 2");

2nd = 3251070542664.21D

i.e.

defaultcategorydataset.addValue(3251070542664.21D, "Series's 2", "Category 2");

When I create 3D Bar Chart it not showing vertical ticks for this range (i.e. from -2849382715582280D to 3251070542664.21D). Any help for resolving this issue will be highly appreciate.

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

Post by christopher.loerken » Thu Sep 08, 2005 10:40 am

Sadly, this is not actually an answer to my question. And I don't know an answer regarding this completely different topic either...

Noone for mine?

Regards,
C.

jmoors
Posts: 7
Joined: Fri Jul 29, 2005 11:29 am

Post by jmoors » Thu Sep 08, 2005 11:13 am

I'm having the same problem is this a bug?

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

Post by christopher.loerken » Fri Sep 09, 2005 11:49 am

I'd guess so. For me, it looks like a problem that should happen quite often actually.

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

Re: Tick Label not visible.

Post by david.gilbert » Fri Sep 09, 2005 1:29 pm

Guest wrote:When I create 3D Bar Chart it not showing vertical ticks for this range (i.e. from -2849382715582280D to 3251070542664.21D). Any help for resolving this issue will be highly appreciate.
The range on the axis is too great for the size of the tick units defined in the collection in createStandardTickUnits(). You can get around this problem by:

- using the setTickUnit() method in the NumberAxis class to set an appropriate tick size for the data range;
- create your own standard tick unit collection, making sure it includes some large tick units for the data ranges you need to cover, and pass it to the setStandardTickUnits() method in the NumberAxis class;
- create a new StandardTickUnitsSource object and pass that to the setStandardTickUnits() method in the NumberAxis class.
David Gilbert
JFreeChart Project Leader

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

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

Re: Rangeaxis: Ticks not displayed...

Post by david.gilbert » Fri Sep 09, 2005 1:31 pm

christopher.loerken wrote:I've got a problem while specifying custom TickUnits on my rangeaxis.
This works pretty well using this code:

Code: Select all

axis.setLowerBound(start);
axis.setUpperBound(end);
newRange = end-start;
axis.setTickUnit(new NumberTickUnit(newRange / 10, doubleFormatter)); 
Where do you put this code? It will help me to reproduce the problem.
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 » Fri Sep 09, 2005 3:01 pm

Unfortunately, the code grew pretty large. I tried to compress it to the main commands:

Basically, my data is stored in objects named trends, the graph is an XYPlot with a TimeSeriesCollection, each dataset holding exactly one series. The domainaxis is of type DateAxis while I use a custom extension of NumberAxis for the range axis. Maybe there lies the problem? I've posted the code before in this forum. It is again attached here. The main purpose of the extension was, that the tickunits actually all start at 0 but I wanted them to start at the bottom of my Valueaxis...

Code: Select all

 //get current curve
            trend = trends[i];
            set = new Integer(trend.getSet());
            trendID = new Integer(trend.getID());
            
            //get DataSet and Renderer for this Trend or create new ones: 
            dataset = (TimeSeriesCollection) this.datasets.get(trendID);
            renderer = (XYItemRenderer) this.renderer.get(trendID);

            if (dataset == null) {
                //--> create dataset
                dataset = new TimeSeriesCollection();                                  
                this.datasets.put(trendID, dataset);
            }
            if (renderer == null) {
                //--> create renderer
                renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);  
                this.renderer.put(trendID, renderer);
            }
            
            
            //set color.
	    renderer.setPaint(trend.getColor());			


            
            //Set larger stroke 
            renderer.setStroke(selectedStroke);
            
            // ---> Create series and fill it with data
            TimeSeries series = new TimeSeries(trend.getTagName(), Millisecond.class);
            for(int j=0; j<trend.getLength(); ++j){                                              
                series.addOrUpdate(trend.getTimeData(j),trend.doubleValue(j));
            }
            //Each Dataset has only one series. As we have just created a new one, remove the old!
            dataset.removeAllSeries();
            //Add new series to dataset of this trend
            dataset.addSeries(series);


        
            // Set or create the graph's range axis.
            NumberAxis rangeAxis = (NumberAxis) this.rangeAxes.get(trendID);


            rangeAxis.setRange(trend.getStartY(), trend.getEndY());

            ((CustomTickNumberAxis)rangeAxis).setLowestVisibleTickValue(new Double(trend.getStartY()));

            double range = rangeAxis.getUpperBound() - rangeAxis.getLowerBound(); 
            if (range < 10)
                rangeAxis.setTickUnit(new NumberTickUnit(range / 10.0, doubleFormatter)); 
            else
                rangeAxis.setTickUnit(new NumberTickUnit(range / 10.0, intFormatter)); 

 
            // Set this axis at the current next free position 
            rangeAxis.setLabel(""+trend.getSet());
            ((CustomTickNumberAxis)rangeAxis).setMarkerPaint(trend.getColor());
            ((CustomTickNumberAxis)rangeAxis).setSet(trend.getSet());

            plot.setRangeAxis(count, rangeAxis);             
            plot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
            
            
            domainAxis = (DateAxis) this.domainAxes.get(trendID);
            double end = trend.getEndX();
            double finalTick = ((end-start) / 1000) / 11;
            DateTickUnit tick = new DateTickUnit(DateTickUnit.SECOND, (int)finalTick);                    
            domainAxis.setTickUnit(tick);
            domainAxis.setRange(start, end);
            
            //take values of the trend.
	    // getTimeData(int) accesses a Millisecond[].
            long startX = trend.getTimeData(0).getFirstMillisecond();		
            long endX = trend.getTimeData(trend.getLength()-1).getFirstMillisecond();
            adjustDomainAxis(domainAxis, startX, endX);

            plot.setDomainAxis(count, domainAxis);
            plot.setDomainAxisLocation(count, AxisLocation.BOTTOM_OR_RIGHT);                   
            

            plot.getRangeAxis(count).setVisible(true);
            plot.getDomainAxis(count).setVisible(true);
            
            // .. then some annotations are added that I left out here ..

            plot.setDataset(count, dataset);
            plot.setRenderer(count, renderer);
            plot.mapDatasetToRangeAxis(count, count);
            plot.mapDatasetToDomainAxis(count, count);       
And here for the custom NumberAxis that is used (see setLowestVisibleTickUnit above.) :

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;
        }
        
 }
regards,
Christopher

P.S.: Ok, I just rechecked, the problem still appears if I'm using the normal NumberAxis... In that case it happens more frequently, that the lowest and highest tick value are left out...

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

Post by christopher.loerken » Mon Sep 12, 2005 10:49 am

Hi,
Do you simply fail to recreate the problem or do you have just absolutely no idea what the problem might be?

Is the problem maybe the java version of 1.4.2_06-b06 ?

I don't know...


regards,
christopher

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

Post by christopher.loerken » Fri Sep 16, 2005 10:11 am

Ok, I took a deeper look into the Numberaxis code myself and fixed the problem at last for my case.

The thing was, that the calculateVisibleTickCount() method did return a wrong number. As I've had the same problem without using my custom axis I think it might be a general issue.

Nevertheless, I've overwritten the method and fixed it for my purpose (that was starting the tic numbering at the bottom of the range axis). Heres the complete code:


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;        
        private Integer set;
        private java.awt.Paint markerPaint = java.awt.Color.BLACK;
        
        /**
         * Holds value of property owner.
         */
        private String owner;
        
       /**
        * 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();
        }
        
        /**
         * Calculates the number of visible ticks. Overwritten to avoid the dropping
         * of visible tics.
         *
         * @return The number of visible ticks on the axis.
         */
        protected int calculateVisibleTickCount() {            
            if (lowestVisibleTickValue != null && lowestVisibleTickValue.doubleValue() >= getRange().getLowerBound()){
                double unit = getTickUnit().getSize(); 
                return (int)(getRange().getLength() / unit +1);
            }
            else
                return super.calculateVisibleTickCount();
        }
        
        /**
         * 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;
        }
}
Regards, Christopher

Locked