problems getting an instance of DateAxis

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
robbinsk
Posts: 2
Joined: Wed Mar 18, 2015 6:03 pm
antibot: No, of course not.

problems getting an instance of DateAxis

Post by robbinsk » Wed Mar 18, 2015 6:15 pm

I'm brand new to JFreeChart, using version 1.0.19.
I tried this code which is right out of the developers guide, but the "instanceof" line evaluates false. Why?

Code: Select all

XYPlot plot = (XYPlot) chart.getPlot();
plot.setForegroundAlpha(0.65f);
ValueAxis domainAxis = plot.getDomainAxis(); //x axis
if (domainAxis instanceof DateAxis) {
    System.out.println("entering date formatter");
    DateAxis axis = (DateAxis) domainAxis;
    DateFormat formatter = new SimpleDateFormat("h a");
    axis.setDateFormatOverride(formatter);
    axis.setTickMarkPaint(Color.black);
    axis.setLowerMargin(0.0);
    axis.setUpperMargin(0.0);
}
So I added a cast like this:

Code: Select all

XYPlot plot = (XYPlot) chart.getPlot();
plot.setForegroundAlpha(0.65f);
ValueAxis domainAxis = (DateAxis) plot.getDomainAxis(); //x axis
if (domainAxis instanceof DateAxis) {
     System.out.println("entering date formatter");
     DateAxis axis = (DateAxis) domainAxis;
     DateFormat formatter = new SimpleDateFormat("h a");
     axis.setDateFormatOverride(formatter);
     axis.setTickMarkPaint(Color.black);
     axis.setLowerMargin(0.0);
     axis.setUpperMargin(0.0);
}
but I get a ClassCastException that says NumberAxis cannot be cast to DateAxis. But the api says that XYPlot.getDomainAxis() returns a ValueAxis, not a NumberAxis. What's going on here and how can I get a DateAxis from the XYPlot?
Thanks.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: problems getting an instance of DateAxis

Post by paradoxoff » Thu Mar 19, 2015 12:51 pm

ValueAxis is the superclass of both NumberAxis and DateAxis.
If the domain axis of your XYPlot is a NumberAxis, then you have constructed your XYPlot in this way. To replace that with a DateAxis, you can call plot.setDomainAxis(aDateAxis), using either a preconfigured DateAxis with the formatter of your choice, or you can call plot.setDomainAxis(new DateAxis()), then retrieve the axis using your code and format the axis according to your needs.

robbinsk
Posts: 2
Joined: Wed Mar 18, 2015 6:03 pm
antibot: No, of course not.

Re: problems getting an instance of DateAxis

Post by robbinsk » Thu Mar 19, 2015 2:45 pm

Thanks for replying. Let me say again that this is my first attempt to use this product, so I'm probably doing several things wrong.
paradoxoff wrote:If the domain axis of your XYPlot is a NumberAxis, then you have constructed your XYPlot in this way.
I constructed a XYSeries using the add() method. That requires a number; it won't take a String. Is that the wrong Series collection to be using?
paradoxoff wrote:To replace that with a DateAxis, you can call plot.setDomainAxis(aDateAxis), using either a preconfigured DateAxis with the formatter of your choice
I don't really understand this option. I don't know what a preconfigured DateAxis is.
paradoxoff wrote:or you can call plot.setDomainAxis(new DateAxis()), then retrieve the axis using your code and format the axis according to your needs.
I tried this but got "DateAxis cannot be converted to ValueAxis[]"

Let me back up and explain what my problem is, maybe that will help. The user enters a start date and time and ending date and time. Let's say the user chooses 7:00 am to 7:00 pm. The time in the database is stored as an integer in hhMMss format. So when I create the chart the axis labels get displayed as 70,000 to 190,000. I need to change these so the labels are "7 am" to "7 pm".

I create the dataset like so:

Code: Select all

    private XYDataset createDataset(Map<Integer, Double> data) {
        XYSeries dataSeries = new XYSeries("Series Key");
        for (Map.Entry<Integer, Double> entry : data.entrySet()) {
            dataSeries.add(entry.getKey(), entry.getValue());
        }
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(dataSeries);
        dataset.setIntervalWidth(0.0);
        return dataset;
    }
..and the chart like so:

Code: Select all

    private JFreeChart createAreaChart(XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYAreaChart(
                "DDM Speed and Efficiency",
                "Time",
                "Actual FPM",
                dataset,
                PlotOrientation.VERTICAL,
                false, true, false);
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setForegroundAlpha(0.65f);
        ValueAxis domainAxis = (DateAxis) plot.getDomainAxis(); //x axis
        //plot.setDomainAxes(new DateAxis());
        if (domainAxis instanceof DateAxis) {
            System.out.println("entering date formatter");            
            DateAxis axis = (DateAxis) domainAxis;
            DateFormat formatter = new SimpleDateFormat("h a");
            axis.setDateFormatOverride(formatter);
            axis.setTickMarkPaint(Color.black);
            axis.setLowerMargin(0.0);
            axis.setUpperMargin(0.0);
        }

        ValueAxis rangeAxis = plot.getRangeAxis(); //y axis        
        rangeAxis.setTickMarkPaint(Color.black);
        rangeAxis.setUpperMargin(0.4);

        return chart;
    }
Am I going about this all wrong? How can I get the x-axis labels that I need?
Thanks for your help.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: problems getting an instance of DateAxis

Post by paradoxoff » Thu Mar 19, 2015 6:11 pm

Ok, let me clarify a few things:
Though an XYSeries (and an XYSeriesCollection that contains one or more XYSeries) is intended to be used with numeric data, you should be able to use them with a DateAxis. The intended "SeriesCollection" for time data is a TimeSeriesCollection containing one or more TimeSeries. But since Dates are in fact just numbers (milliseconds since 01.01.1970), you can plot integer value using both axis types. I haven´t understodd your remark "That requires a number; it won't take a String". I haven´t mentioned Strings before.
A "preconfigured axis" is just my wording to indicate that you first create all the object that you need (for an XYPlot, that would be two ValueAxes, one dataset, and a renderer), configure them in the way you want (in case of the axes, including the tick mark paint, lower and upper margin, and a DateFormat), and the assemble these objects to create an XYPlot and finally a JFreeChart. In your case, you are using the ChartFactory methods to create a JFreeChart, and the retrieve from that chart the plot and the axes to change their appearance. IMHO, the first option is the faster one. I never became really familiar with the ChartFactory methods, because I always had to look up what parameter is used for what purpose.
Regarding you remark: "I tried this but got "DateAxis cannot be converted to ValueAxis[]". you have confused "plot.setDomainAxis()" (what I wrote) with "plot.setDomainAxes()".
plot.setDominAxis(new DateAxis()) still seems to be way to go.

Locked