Problem adapting the MultipleAxisDemo2

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Eduardo Ramalho
Posts: 43
Joined: Fri Mar 14, 2003 3:14 pm
Location: Porto (Portugal)
Contact:

Problem adapting the MultipleAxisDemo2

Post by Eduardo Ramalho » Tue Sep 16, 2003 10:39 am

Hi!

I'm testing the MultipleAxisDemo2 demo bundle with JFreeChart.

I modified it to show 3 horizontal date axis and all are in the same bottom location. When I saw the results, the 3rd axis was hidden (as the window didn't know to resize itself vertically to accomodate the new axis)

Is there any property I'm forgetting to set?

If I applied this same construction to the vertical axis, all of them would show automatically.

Tia,

Eduardo

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 » Tue Sep 16, 2003 12:19 pm

Hi Eduardo,

If you post a small sample application, I'll run it and investigate...
David Gilbert
JFreeChart Project Leader

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

Eduardo Ramalho
Posts: 43
Joined: Fri Mar 14, 2003 3:14 pm
Location: Porto (Portugal)
Contact:

Post by Eduardo Ramalho » Tue Sep 16, 2003 1:14 pm

Hi!

Where is the code ... the second horizontal axis labels (red) aren't visible.

Code: Select all

/* ======================================
 * JFreeChart : a free Java chart library
 * ======================================
 *
 * Project Info:  http://www.jfree.org/jfreechart/index.html
 * Project Lead:  David Gilbert (david.gilbert@object-refinery.com);
 *
 * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * ----------------------
 * MultipleAxisDemo2.java
 * ----------------------
 * (C) Copyright 2003 by Object Refinery Limited and Contributors.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * $Id: MultipleAxisDemo2.java,v 1.4 2003/07/24 10:52:29 mungady Exp $
 *
 * Changes
 * -------
 * 15-Jul-2002 : Version 1 (DG);
 *
 */

package org.jfree.chart.demo;

import java.awt.Color;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.Spacer;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.AxisSpace;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.StandardXYItemRenderer;
import org.jfree.data.Range;
import org.jfree.data.XYDataset;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Minute;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

/**
 * An example of....
 *
 * @author David Gilbert
 */
public class MultipleAxisDemo2 extends ApplicationFrame {

    /**
     * A demonstration application showing how to create a time series chart with muliple axes.
     *
     * @param title  the frame title.
     */
    public MultipleAxisDemo2(String title) {

        super(title);
        JFreeChart chart = createChart();
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(600, 270));
        setContentPane(chartPanel);

    }

    /**
     * Creates the demo chart.
     * 
     * @return The chart.
     */
    private JFreeChart createChart() {

        Calendar cal = new GregorianCalendar(2000,06,01);
        TimeSeriesCollection dataset1 = createDataset("Series 1", 100.0, new Hour(cal.getTime()), 200);
        
		cal.set(Calendar.YEAR, 2001);
		TimeSeriesCollection dataset2 = createDataset("Series 2", 1000.0, new Hour(cal.getTime()), 100);
		
		Range maxRange1 = dataset1.getDomainRange();
		Range maxRange2 = dataset2.getDomainRange();
		double length = 0;
		if (maxRange1.getLength() > maxRange2.getLength()) {
			length = maxRange1.getLength();  
		}
		else {
			length = maxRange2.getLength();
		}
		
		JFreeChart chart =
			ChartFactory.createTimeSeriesChart(
				"OLA",
				null,
				null,
				dataset1,
				false,
				false,
				false);

        chart.setBackgroundPaint(Color.white);
        XYPlot plot = chart.getXYPlot();
        plot.setOrientation(PlotOrientation.VERTICAL);
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        
		// DOMAIN 1
        DateAxis xAxis1 = (DateAxis)plot.getDomainAxis();
//		xAxis1.setFixedDimension(length);
        xAxis1.setAxisLinePaint(Color.BLUE);
        xAxis1.setLowerMargin(0);
		xAxis1.setUpperMargin(0);
        
		// RANGE 2
		NumberAxis yAxis1 = (NumberAxis)plot.getRangeAxis();
		yAxis1.setAxisLinePaint(Color.BLUE);

        StandardXYItemRenderer renderer = (StandardXYItemRenderer) plot.getRenderer();
        renderer.setPaint(Color.BLUE);
        
        // DOMAIN AXIS 2
        // NumberAxis xAxis2 = new NumberAxis("Domain Axis 2");
		DateAxis xAxis2 = new DateAxis();
//		xAxis2.setFixedDimension(length);
		xAxis2.setAxisLinePaint(Color.RED);
		xAxis2.setLowerMargin(0);
		xAxis2.setUpperMargin(0);
        plot.setSecondaryDomainAxis(0, xAxis2);
        plot.setSecondaryDomainAxisLocation(0, AxisLocation.BOTTOM_OR_RIGHT);
      
        // RANGE AXIS 2
        NumberAxis yAxis2 = new NumberAxis();
		yAxis2.setAxisLinePaint(Color.RED);
        plot.setSecondaryRangeAxis(0, yAxis2);
        plot.setSecondaryRangeAxisLocation(0, AxisLocation.BOTTOM_OR_RIGHT);

        // DATASET 2
        plot.setSecondaryDataset(0, dataset2);    
        plot.mapSecondaryDatasetToDomainAxis(0, new Integer(0));
        plot.mapSecondaryDatasetToRangeAxis(0, new Integer(0));
        
        // RENDERER 2
		plot.setSecondaryRenderer(0, new StandardXYItemRenderer());
		plot.getSecondaryRenderer(0).setSeriesPaint(0, Color.red);
		         
        return chart;
        
    }
    
    /**
     * Creates a sample dataset.
     * 
     * @param name  the dataset name.
     * @param base  the starting value.
     * @param start  the starting period.
     * @param count  the number of values to generate.
     *
     * @return The dataset.
     */
    private TimeSeriesCollection createDataset(String name, double base, RegularTimePeriod start, int count) {

        TimeSeries series = new TimeSeries(name, start.getClass());
        RegularTimePeriod period = start;
        double value = base;
        for (int i = 0; i < count; i++) {
            series.add(period, value);    
            period = period.next();
            value = value * (1 + (Math.random() - 0.495) / 10.0);
        }

        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(series);
		
        return dataset;

    }

    /**
     * Starting point for the demonstration application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {

        MultipleAxisDemo2 demo = new MultipleAxisDemo2("Multiple Axis Demo 2");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }

}

Eduardo Ramalho
Posts: 43
Joined: Fri Mar 14, 2003 3:14 pm
Location: Porto (Portugal)
Contact:

Post by Eduardo Ramalho » Tue Sep 16, 2003 3:53 pm

Hello again,

I found another problem while adapting the same program.
The Horizontal Zoom doesn't work for the secondary axis.
Try zooming with the following code. You will see that the top horizontal axis, doesn't update and the chart just zooms vertically.

I took a look at XYPlot zoom implementation and I managed to correct the problem but now the zoom out doesn't work.

Regards,

Eduardo

Code: Select all

/* ======================================
 * JFreeChart : a free Java chart library
 * ======================================
 *
 * Project Info:  http://www.jfree.org/jfreechart/index.html
 * Project Lead:  David Gilbert (david.gilbert@object-refinery.com);
 *
 * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * ----------------------
 * MultipleAxisDemo2.java
 * ----------------------
 * (C) Copyright 2003 by Object Refinery Limited and Contributors.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * $Id: MultipleAxisDemo2.java,v 1.4 2003/07/24 10:52:29 mungady Exp $
 *
 * Changes
 * -------
 * 15-Jul-2002 : Version 1 (DG);
 *
 */

package org.jfree.chart.demo;

import java.awt.Color;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.Spacer;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.AxisSpace;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.StandardXYItemRenderer;
import org.jfree.data.DateRange;
import org.jfree.data.Range;
import org.jfree.data.XYDataset;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Minute;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.Week;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

/**
 * An example of....
 *
 * @author David Gilbert
 */
public class MultipleAxisDemo2 extends ApplicationFrame {

    /**
     * A demonstration application showing how to create a time series chart with muliple axes.
     *
     * @param title  the frame title.
     */
    public MultipleAxisDemo2(String title) {

        super(title);
        JFreeChart chart = createChart();
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(600, 270));
		chartPanel.setHorizontalZoom(true);
		chartPanel.setVerticalZoom(true);
		setContentPane(chartPanel);
    }

    /**
     * Creates the demo chart.
     * 
     * @return The chart.
     */
    private JFreeChart createChart() {

        Calendar cal = new GregorianCalendar(2000,06,01);
        TimeSeriesCollection dataset1 = createDataset("Series 1", 100.0, new Hour(cal.getTime()), 200);
        
		cal.set(Calendar.MONTH, 7);
		TimeSeriesCollection dataset2 = createDataset("Series 2", 1000.0, new Hour(cal.getTime()), 100);
		System.out.println(cal.getTimeInMillis());
		
		Range maxRange1 = dataset1.getDomainRange();
		Range maxRange2 = dataset2.getDomainRange();

		double length;
		if (maxRange1.getLength() > maxRange2.getLength()) {
			length = maxRange1.getLength();
		} 
		else {
			length = maxRange2.getLength();			 
		}
		System.out.println("length = " + (long)length);
		
		JFreeChart chart =
			ChartFactory.createTimeSeriesChart(
				"OLA",
				null,
				null,
				dataset1,
				false,
				false,
				false);

        chart.setBackgroundPaint(Color.white);
        XYPlot plot = chart.getXYPlot();
        plot.setOrientation(PlotOrientation.VERTICAL);
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        
		// DOMAIN 1
        DateAxis xAxis1 = (DateAxis)plot.getDomainAxis();
        xAxis1.setAxisLinePaint(Color.BLUE);
        xAxis1.setLowerMargin(0);
		xAxis1.setUpperMargin(0);
		Range dr = dataset1.getDomainRange();
		Range ddr =  new Range(dr.getLowerBound(), dr.getLowerBound() + length);
		xAxis1.setRange(ddr);

        
		// RANGE 2
		NumberAxis yAxis1 = (NumberAxis)plot.getRangeAxis();
		yAxis1.setAxisLinePaint(Color.BLUE);

        StandardXYItemRenderer renderer = (StandardXYItemRenderer) plot.getRenderer();
        renderer.setPaint(Color.BLUE);
        
        // DOMAIN AXIS 2
        // NumberAxis xAxis2 = new NumberAxis("Domain Axis 2");
		DateAxis xAxis2 = new DateAxis();
		xAxis2.setAxisLinePaint(Color.RED);
		xAxis2.setLowerMargin(0);
		xAxis2.setUpperMargin(0);
		
		dr = dataset2.getDomainRange();
		ddr =  new Range(dr.getLowerBound(), dr.getLowerBound() + length);
		xAxis2.setRange(ddr);

        plot.setSecondaryDomainAxis(0, xAxis2);
        plot.setSecondaryDomainAxisLocation(0, AxisLocation.TOP_OR_LEFT);
      
        // RANGE AXIS 2
        NumberAxis yAxis2 = new NumberAxis();
		yAxis2.setAxisLinePaint(Color.RED);
        plot.setSecondaryRangeAxis(0, yAxis2);
        plot.setSecondaryRangeAxisLocation(0, AxisLocation.BOTTOM_OR_RIGHT);

        // DATASET 2
        plot.setSecondaryDataset(0, dataset2);    
        plot.mapSecondaryDatasetToDomainAxis(0, new Integer(0));
        plot.mapSecondaryDatasetToRangeAxis(0, new Integer(0));
        
        // RENDERER 2
		plot.setSecondaryRenderer(0, new StandardXYItemRenderer());
		plot.getSecondaryRenderer(0).setSeriesPaint(0, Color.red);
		         
        return chart;
        
    }
    
    /**
     * Creates a sample dataset.
     * 
     * @param name  the dataset name.
     * @param base  the starting value.
     * @param start  the starting period.
     * @param count  the number of values to generate.
     *
     * @return The dataset.
     */
    private TimeSeriesCollection createDataset(String name, double base, RegularTimePeriod start, int count) {

        TimeSeries series = new TimeSeries(name, start.getClass());
        RegularTimePeriod period = start;
        double value = base;
        for (int i = 0; i < count; i++) {
            series.add(period, value);    
            period = period.next();
            value = value * (1 + (Math.random() - 0.495) / 10.0);
        }

        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(series);
		
        return dataset;

    }

    /**
     * Starting point for the demonstration application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {

        MultipleAxisDemo2 demo = new MultipleAxisDemo2("Multiple Axis Demo 2");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }

}

CSteere

DateAxis not set up to be a secondary axis

Post by CSteere » Tue Sep 16, 2003 9:20 pm

Eduardo,

I ran into the same problem you had with using the DateAxis as a secondary axis. The problem is that this class has not been updated to support multiple secondary axes like the NumberAxis class was. If you look at the reserveSpace() method, when the space object is being updated, it should use the add() method instead of ensureAtLeast(). See code snippet below:

Code: Select all

        // get the axis label size and update the space object...
        Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
        double labelHeight = 0.0;
        double labelWidth = 0.0;

        if (RectangleEdge.isTopOrBottom(edge)) {
            labelHeight = labelEnclosure.getHeight();
            this.reservedForAxisLabel = labelHeight;
            space.add(labelHeight + tickLabelHeight, edge);
        }
        else if (RectangleEdge.isLeftOrRight(edge)) {
            labelWidth = labelEnclosure.getWidth();
            this.reservedForAxisLabel = labelWidth;
            space.add(labelWidth + tickLabelWidth, edge);
        }
This seemed to solve my problem.

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 » Tue Sep 16, 2003 10:17 pm

With all this info, I should have no trouble fixing the bug(s). I'll be working on it tomorrow morning...
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: DateAxis not set up to be a secondary axis

Post by david.gilbert » Wed Sep 17, 2003 9:37 am

CSteere wrote:Eduardo,

I ran into the same problem you had with using the DateAxis as a secondary axis. The problem is that this class has not been updated to support multiple secondary axes like the NumberAxis class was. If you look at the reserveSpace() method, when the space object is being updated, it should use the add() method instead of ensureAtLeast(). See code snippet below:

Code: Select all

        // get the axis label size and update the space object...
        Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
        double labelHeight = 0.0;
        double labelWidth = 0.0;

        if (RectangleEdge.isTopOrBottom(edge)) {
            labelHeight = labelEnclosure.getHeight();
            this.reservedForAxisLabel = labelHeight;
            space.add(labelHeight + tickLabelHeight, edge);
        }
        else if (RectangleEdge.isLeftOrRight(edge)) {
            labelWidth = labelEnclosure.getWidth();
            this.reservedForAxisLabel = labelWidth;
            space.add(labelWidth + tickLabelWidth, edge);
        }
This seemed to solve my problem.
Exactly right! Thanks for the fix, it is committed to CVS now, ready for the 0.9.13 release.
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:

Post by david.gilbert » Wed Sep 17, 2003 10:00 am

Eduardo Ramalho wrote:I found another problem while adapting the same program.
The Horizontal Zoom doesn't work for the secondary axis.
Thanks for the report. This is fixed now, the changes will be in CVS shortly and will be included in the 0.9.13 release.
David Gilbert
JFreeChart Project Leader

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

Locked