10.000 pixel long image need's an Axis

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
bruehlicke
Posts: 25
Joined: Thu Apr 03, 2008 5:51 pm
Location: Houston, TX, USA

10.000 pixel long image need's an Axis

Post by bruehlicke » Wed Apr 23, 2008 3:58 pm

Hi,

I try to use JFreeChart a little out of its original design - maybe someone has tried this. (By the way Thanx to this fantastic package !)

I have an image which is 512x10000 in dimension. I would like to have a NumberAxis drawn next to it.

All looks perfect as long as I stick to small window sizes like 500x800 but when I increase the setPreferredSize(new Dimension(300, 10000)) the Labels and, tick marks, etc all get very much streched.

How would you suggest to make a XYPlot which should cover 300x10000 pixels and sits in a JScrollPane ?

B-)

skunk
Posts: 1087
Joined: Thu Jun 02, 2005 10:14 pm
Location: Brisbane, Australia

Post by skunk » Wed Apr 23, 2008 4:07 pm

Look at the docs/source for these methods in org.jfree.chart.ChartPanel

Code: Select all

public void setMaximumDrawWidth(int width)
public void setMaximumDrawHeight(int height)

bruehlicke
Posts: 25
Joined: Thu Apr 03, 2008 5:51 pm
Location: Houston, TX, USA

Post by bruehlicke » Wed Apr 23, 2008 4:15 pm

You are the man !!!!

I was soooo close to give up - but this fixed it !

THANX A LOT !
B-)

RichardWest
Posts: 844
Joined: Fri Oct 13, 2006 9:29 pm
Location: Sunnyvale, CA

Post by RichardWest » Wed Apr 23, 2008 5:24 pm

bruehlicke wrote:I was soooo close to give up - but this fixed it !
Never give up without reading the API otherwise you will never get anywhere as a developer.
Richard West
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA

bruehlicke
Posts: 25
Joined: Thu Apr 03, 2008 5:51 pm
Location: Houston, TX, USA

Re: 10.000 pixel long image need's an Axis

Post by bruehlicke » Wed Jul 08, 2009 6:23 pm

I run into another re-incarnation of this.

See Code example below.
This code should make ticks marks with value for every value. But nothing. If I set the tickunits variable (top of code) to 10.0 or even 5.0 it works - why ?

Any ideas would be great.
Thanx again for your fine suite of code.

B-)

Code: Select all

package demos;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;

import java.awt.Dimension;
import java.awt.Font;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;

/**
 *
 * @author Bernd Ruehlicke
 */
public class DepthScaleDemoScroll4 extends ApplicationFrame
{
    static int pixellenght = 268000;  // Yes I am serious
    static double tickunits = 1.0;   // 268000 pixels and 10.0 or 5.0 in Ticks works. But using 1.0 in ticks doese not (no ticks appear)

    public DepthScaleDemoScroll4(String s)
    {
        super(s);
        JScrollPane jScroll = new JScrollPane();
        JPanel jpanel = createDemoPanel();
        jpanel.setPreferredSize(new Dimension(200, pixellenght));
        jScroll.setPreferredSize(new Dimension(220, 500));
        jScroll.add(jpanel);
        jScroll.setViewportView(jpanel);
        jScroll.setVisible(true);
        setContentPane(jScroll);
        
    }


    private static JFreeChart createChart()
    {
        JFreeChart jfreechart = ChartFactory.createXYLineChart(
                null,
                null,
                null,
                null, PlotOrientation.HORIZONTAL, true, true, false);  
        
         XYPlot xyplot = (XYPlot)jfreechart.getPlot();
         xyplot.setOutlineVisible(false);
         xyplot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
         xyplot.setDomainGridlinesVisible(true);
         xyplot.setInsets(RectangleInsets.ZERO_INSETS);        
         
         NumberAxis depthAxis = (NumberAxis) xyplot.getDomainAxis();   
         depthAxis.setRange(2672.0, 4033.0);
                
         depthAxis.setInverted(true);
         depthAxis.setTickLabelInsets(new RectangleInsets(0D, 0D, 0D, -40D));
         depthAxis.setTickMarkOutsideLength(0.0F);
         depthAxis.setTickMarkInsideLength(5.0F);
         NumberFormat myFormatter = new DecimalFormat("######.0");
         depthAxis.setTickUnit(new NumberTickUnit(tickunits, myFormatter, 1));
   //      depthAxis.setTickUnit(new NumberTickUnit(tickunits));
         Font font = new Font("SansSerif",Font.PLAIN,12);
         depthAxis.setTickLabelFont(font);

         
         NumberAxis rangeAxis = (NumberAxis) xyplot.getRangeAxis();   
        rangeAxis.setAutoRangeIncludesZero(false);
        rangeAxis.setRange(0.0, 90.0);
        rangeAxis.setInverted(false);
        rangeAxis.setVisible(false);
         
         jfreechart.removeLegend();
         jfreechart.setPadding(RectangleInsets.ZERO_INSETS);
         jfreechart.setBorderVisible(false);
         
        return jfreechart;
    }

    public static JPanel createDemoPanel()
    {
        JFreeChart jfreechart = createChart();
        ChartPanel chartpanel = new ChartPanel(jfreechart);
        chartpanel.setMaximumDrawHeight(pixellenght);
        chartpanel.setMouseZoomable(false);
        return chartpanel;
    }

    public static void main(String args[])
    {
        DepthScaleDemoScroll4 demo = new DepthScaleDemoScroll4("Test");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}

bruehlicke
Posts: 25
Joined: Thu Apr 03, 2008 5:51 pm
Location: Houston, TX, USA

Re: 10.000 pixel long image need's an Axis

Post by bruehlicke » Wed Jul 08, 2009 7:16 pm

Hmm - it looks like it has to do with some max number of tick marks allowed.

When I changed the code and reduced the number of depth markers to 499 and used the 268000 pixels it worked. Using 500 markers has the effect of no markers at all (see top/bot variables below)

... will try to debug the code and find the magic limit ...

B-)

Code: Select all

package demos;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;

import java.awt.Dimension;
import java.awt.Font;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;

/**
 *
 * @author Bernd Ruehlicke
 */
public class DepthScaleDemoScroll4 extends ApplicationFrame
{
    static int pixellenght = 268000;  // Yes I am serious
    static double tickunits = 1.0;   // 268000 pixels and 10.0 or 5.0 in Ticks works. But using 1.0 in ticks doese not (no ticks appear)
    static double top = 2762.0;
    static double bot = 3261.0;    // this will trigger 499 markers - OK. Changing this number to 3262 will have the effect of no markers drawn at all.
    
    public DepthScaleDemoScroll4(String s)
    {
        super(s);
        JScrollPane jScroll = new JScrollPane();
        JPanel jpanel = createDemoPanel();
        jpanel.setPreferredSize(new Dimension(200, pixellenght));
        jScroll.setPreferredSize(new Dimension(220, 500));
        jScroll.add(jpanel);
        jScroll.setViewportView(jpanel);
        jScroll.setVisible(true);
        setContentPane(jScroll);
        
    }


    private static JFreeChart createChart()
    {
        JFreeChart jfreechart = ChartFactory.createXYLineChart(
                null,
                null,
                null,
                null, PlotOrientation.HORIZONTAL, true, true, false);  
        
         XYPlot xyplot = (XYPlot)jfreechart.getPlot();
         xyplot.setOutlineVisible(false);
         xyplot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
         xyplot.setDomainGridlinesVisible(true);
         xyplot.setInsets(RectangleInsets.ZERO_INSETS);        
         
         NumberAxis depthAxis = (NumberAxis) xyplot.getDomainAxis();   
         depthAxis.setRange(top, bot);
                
         depthAxis.setInverted(true);
         depthAxis.setTickLabelInsets(new RectangleInsets(0D, 0D, 0D, -40D));
         depthAxis.setTickMarkOutsideLength(0.0F);
         depthAxis.setTickMarkInsideLength(5.0F);
         NumberFormat myFormatter = new DecimalFormat("######.0");
         depthAxis.setTickUnit(new NumberTickUnit(tickunits, myFormatter, 1));
   //      depthAxis.setTickUnit(new NumberTickUnit(tickunits));
         Font font = new Font("SansSerif",Font.PLAIN,12);
         depthAxis.setTickLabelFont(font);

         
         NumberAxis rangeAxis = (NumberAxis) xyplot.getRangeAxis();   
        rangeAxis.setAutoRangeIncludesZero(false);
        rangeAxis.setRange(0.0, 90.0);
        rangeAxis.setInverted(false);
        rangeAxis.setVisible(false);
         
         jfreechart.removeLegend();
         jfreechart.setPadding(RectangleInsets.ZERO_INSETS);
         jfreechart.setBorderVisible(false);
         
        return jfreechart;
    }

    public static JPanel createDemoPanel()
    {
        JFreeChart jfreechart = createChart();
        ChartPanel chartpanel = new ChartPanel(jfreechart);
        chartpanel.setMaximumDrawHeight(pixellenght);
        chartpanel.setMouseZoomable(false);
        return chartpanel;
    }

    public static void main(String args[])
    {
        DepthScaleDemoScroll4 demo = new DepthScaleDemoScroll4("Test");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}

bruehlicke
Posts: 25
Joined: Thu Apr 03, 2008 5:51 pm
Location: Houston, TX, USA

Re: 10.000 pixel long image need's an Axis

Post by bruehlicke » Wed Jul 08, 2009 7:35 pm

OK - Problem solved (at least reason found)

ValueAxis has a hardcoded limit.

/** The maximum tick count. */
public static final int MAXIMUM_TICK_COUNT = 500;


Hmm. Any pitfall if I allow a bigger value ? I see there is no method to overwrite and I assume you guy's had a good reason..... we will see ...

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

Re: 10.000 pixel long image need's an Axis

Post by david.gilbert » Thu Jul 09, 2009 4:07 pm

You should be safe to increase the limit. The reason it exists is because the tick unit collection in the NumberAxis is finite. If your axis has an exceptionally long range, then the largest tick unit from the collection will be selected, but this might be quite small relative to the axis range, and result in many thousands of tick marks. In that case we throw up our hands and say "let's not draw any tick marks at all". Which is better than throwing an exception, or getting incredibly slow if 2 million ticks get generated, but only just. I've been back into this code a few times to try to fix the bad design, because the tick unit selection code should just use the sizes in the collection, but when it gets to the largest (or smallest) it should just start automatically generating other appropriate sizes as required (then no-one would get the surprise of the the tick labels disappearing). But so far I haven't come up with a fix that is good enough.

By the way, I chose 500 as the limit because I thought a wide chart would be about 2000 pixels max (a high resolution monitor) - and more than one tick per 4 pixels doesn't make much sense. I should have anticipated that someone (you, and some others) would create much wider charts.
David Gilbert
JFreeChart Project Leader

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

Locked