zoom out loses 2nd range axis values

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

zoom out loses 2nd range axis values

Post by Fred » Fri Jun 17, 2016 7:57 pm

Hello,

make this simple. I have the need to present a secondary domain (y) axis on the chart.
code snibbet below:

Code: Select all

XYPlot plot = new XYPlot();
int nextPlot = 0;
...
Date Axis yAxis2 = new DateAxis("Time (HH:mm:ss.SSS)");
yAxis2.setInverted(true);
yAxis2.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss.SSS"));
Date startDateandTime = firstDateandTime.toDate();
Date endDateandTime = endDateandTime.toDate();
yaxis2.setMinimumDate(startDateandTime);
yaxis2.setMaximumDate(endDateandTime);
plot.setRangeAxis(nextPlot, yAxis2, true);
The 2nd range axis appears (still need to get the scaling right).
The problem occurs not when zooming in but when selecting the
right-mouse option "auto range" and when it resets/scales the
secondary range axis is lost.

Ideas?

Fred

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

Re: zoom out loses 2nd range axis values

Post by paradoxoff » Sat Jun 18, 2016 12:06 pm

plot.setRangeAxis(nextPlot, yAxis2, true);
The name yAxis2 suggests that it is a secondary axis, but the only value for nextPlot that I can see is 0. Thats confusing.
the secondary range axis is lost
What does that mean? Is it removed from the plot or is just the range resetted?

Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

Re: zoom out loses 2nd range axis values

Post by Fred » Mon Jun 20, 2016 4:20 pm

Not sure if the "nextPlot" value matters. But the initial value is zero (0) for the "Y" axis defined by the following code snibbet:

Code: Select all

NumberAxis yAxis = new NumberAxis("tick units");
yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
yAxis.setLowMargin(0.1);
yAxis.setHighMargin(0.1);
yAxis.setAutoRangeIncludeZeros(false);

int nextPlot = 0;
VectorRender vr = new VectorRender();
vr.setAutoPopulateSeriesFillPaint(false);
..
plot.setDataset(nextPlot, vrDataset);
plot.setRenderer(nextPlot,vr);
plot.setDomainAxis(nextPlot, xAxis);
plot.setRangeAxis(nextPlot, yAxis);
nextPlot++;

Zoom in and out are NOT the problem. The secondary (time) range axis is there (still addressing scaling issue).
But the issue occurs when auto range both axis. The Tick Units are now lost. The setMinimumDate, setMaximumDate
are not presented though the setDateFormatOverride defines the secondary Y axis but the value is 00:00:00.000.

Fred

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

Re: zoom out loses 2nd range axis values

Post by paradoxoff » Mon Jun 20, 2016 9:05 pm

If you haven't assigned any dataset to a secondary axis, the value range of that axis will be reset to a default value upon using the auto range feature. In case of a DateAxis, this default range is a time range with a length of 1 millisecond, starting at january 1st, 1970, 00.00.00 UTC. This range is too small for multiple tick marks to appear (since a suitable DateFormat would have to be able to display a precision of better than 1 ms).
Solution: assign a secondary dataset to the plot.

Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

Re: zoom out loses 2nd range axis values

Post by Fred » Mon Jun 20, 2016 10:42 pm

Can I assign the same dataset assigned to the first Y axis to the 2nd?

Code: Select all

    NumberAxis yAxis = new NumberAxis("tick units");
    yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    yAxis.setLowMargin(0.1);
    yAxis.setHighMargin(0.1);
    yAxis.setAutoRangeIncludeZeros(false);

    int nextPlot = 0;
    VectorRender vr = new VectorRender();
    vr.setAutoPopulateSeriesFillPaint(false);
    ..
    plot.setDataset(nextPlot, vrDataset);
    plot.setRenderer(nextPlot,vr);
    plot.setDomainAxis(nextPlot, xAxis);
    plot.setRangeAxis(nextPlot, yAxis);
    nextPlot++;
    Date Axis yAxis2 = new DateAxis("Time (HH:mm:ss.SSS)");
    yAxis2.setInverted(true);
    yAxis2.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss.SSS"));
    Date startDateandTime = firstDateandTime.toDate();
    Date endDateandTime = endDateandTime.toDate();
    yaxis2.setMinimumDate(startDateandTime);
    yaxis2.setMaximumDate(endDateandTime);
    plot.setDataset(nextPlot, vrDataset);
    plot.setRenderer(nextPlot,vr);
    plot.setRangeAxis(nextPlot, yAxis2, true);

Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

Re: zoom out loses 2nd range axis values

Post by Fred » Mon Jun 20, 2016 10:53 pm

I also tried creating a second Dataset

Code: Select all

    plot.setDataset(nextPlot, vrDataset2);
and a second VectorRenderer

Code: Select all

    plot.setRenderer(nextPlot,vr2);
However, the results are the same.

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

Re: zoom out loses 2nd range axis values

Post by paradoxoff » Tue Jun 21, 2016 11:57 am

Fred wrote:Can I assign the same dataset assigned to the first Y axis to the 2nd?
Yes. Use XYPlot.mapDatasetToRangeAxes(int datasetIndex, java.util.List axisIndices). This simpler than adding the same dataset and renderer twice to the plot.
Note that an empty dataset will have the same effect as a null dataset, i.e. the ranges of the ValueAxes will be set to their default values upon autoRange.
Does your vrDataset contain any data?
You are apparently using a NumberAxis as primary range axis and the DateAxis as secondary range axis in the same dataset. That is a bit strange. I only see one case where this configuration could make sense, namely, if the numeric values do indeed represent milliseconds since january 1st, 1970, 00:00:00 UTC.
Without knowing if your dataset contains values, and if so, what they represent, I won't be able to help.

Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

Re: zoom out loses 2nd range axis values

Post by Fred » Tue Jun 21, 2016 3:49 pm

Thanks Paradoxoff, it does contain Microseconds of data. What I want to do is
place the timeframe relative to the vector plots on the right "Y" axis while the left
side shows the numbered axis (a count).

I tried to download and use ChartPanel.java but it seems to have too many dependencies
for me to incorporate into my project either as a project or integrated into my package/project.
The plan was to Override the restoreAutoBounds or restoreAutoRangeBounds where I could
add in the secondary Y axis data.

do you have another suggestions?

Fred

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

Re: zoom out loses 2nd range axis values

Post by paradoxoff » Tue Jun 21, 2016 8:34 pm

Fred wrote: I tried to download and use ChartPanel.java but it seems to have too many dependencies
for me to incorporate into my project either as a project or integrated into my package/project.
The plan was to Override the restoreAutoBounds or restoreAutoRangeBounds where I could
add in the secondary Y axis data.
I thought you would already using a ChartPanel.
Lets make this short: Does that snippet works as expected?

Code: Select all

public class XYPlotDemo {

    public static void main(String[] args) {
        long now = System.currentTimeMillis();
        DefaultXYDataset dataset = new DefaultXYDataset();
        Random r = new Random();
        int size = 1000;
        double[][] data = new double[2][size];
        for(int i = 0; i < size; i++){
            data[0][i] = r.nextDouble()*100;
            data[1][i] = now + 60000 * i;
        }
        dataset.addSeries("Data", data);
        DateAxis yAxis1 = new DateAxis();
        yAxis1.setDateFormatOverride(new SimpleDateFormat("yy-MM-dd HH:mm:ss.sss"));
        NumberAxis yAxis2 = new NumberAxis("y");
        yAxis2.setAutoRangeIncludesZero(false);
        XYPlot plot = new XYPlot(dataset, new NumberAxis("x"), yAxis1, new XYLineAndShapeRenderer());
        plot.setRangeAxis(1, yAxis2);
        plot.mapDatasetToRangeAxes(0, Arrays.asList(new Integer[]{0,1}));
        JFrame frame = new JFrame();
        frame.getContentPane().add(new ChartPanel(new JFreeChart(plot)));
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
}

Fred
Posts: 38
Joined: Sat Dec 12, 2015 4:57 pm
antibot: No, of course not.

Re: zoom out loses 2nd range axis values

Post by Fred » Fri Jun 24, 2016 4:48 pm

Sorry Paraxodoff if I hadn't responded. I started down another rabbit hole and found my answer. I will share the code (basics) but it appears
to me more like a limitation not a bug in that secondary axises are not rendered when autorange is detected. So I wrote a plot addChangeListener not
just because I needed to retain the secondary range axis when autoranged, but would need to modify it when zoomed (engineering requirement).

Code: Select all

   final XYPlot nPlot = chartPanel.getChart().getXYPlot();

   nPlot.addChangeListener(new PlotChangedListener()){

        boolean autoRangeOut = false;
        boolean zoomed = false;

        @Override
        public void plotChanged(PlotChangeEvent e) {

            System.out.println("Event Type="+e.getType());

            ChartChangeEventType eType = e.getType();

            ValueAxis yAxis = (ValueAxis) nPlot.getRangeAxis();
            Range yAxisDataRange = nPlot.getDataRange(yAxis);
            ValueAxis yAxisRange = nPlot.getRangeAxis();

            if (eType.equals(ChartChangeEventType.GENERAL)){
               if ((yAxisRange.getLowerBound() >= yAxisDataRange.getLowerBound() &&
                   yAxisragne.getUpperBound() >= yAxisDataRange.getUpperBound())){
                     if (!autoRangeOut){
                         autoRangeOut = true;
                         DateAxis yAxis2 = build2ndRangeAxis(firstDateTime, lastDateTime);
                         nPlot.setRangeAxis(1, yAxis2);
                     }
               }else{
                       autoRangeOut =false;
                       if (!zoomed){
                          zoomed = true;
                          ArrayList<DateTime> minMaxValues = getMinMaxTimes();
                          DateTime minDate = minMaxValues.get(0);
                          DateTime maxDate = minMaxvalues.get(1);
                          DateAxis yAxis2 = build2ndRangeAxis(minDate,maxDate);
                          nPlot.setRangeAxis(1, yAxis2);
                          zoomed = false;
                      }
               }
           }
     }

     public ArrayList<DateTime> getMinMaxTimes(){
          ValueAxis yAxis = (ValueAxis) nPlot.getRangeAxis();
          ValueAxis xAxis = (ValueAxis) nPlot.getDomainAxis();

          double lowerX = xAxis.getRange().getLowerBound();
          double upperX = xAxis.getRange().getUpperBound();
        
          double lowerY = yAxis.getRange().getLowerBound();
          double upperY = yAxis.getRange().getUpperBound();

          ArrayList<DateTime> theRange = dataBaseDetails.getDataDateRange(lowerX, upperX, lowerY, upperY);

          return (theRange);
     }
There is obviously a lot more details like build2ndRangeAxis but that would be up to the data and what is desired on
the Range axis (i.e. Minutes, Seconds, Milliseconds) to define the Time Tick Units to use and how many.

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

Re: zoom out loses 2nd range axis values

Post by paradoxoff » Fri Jun 24, 2016 6:56 pm

Essentially, you haven´t responded to my question. Never mind.
Fred wrote:but it appears
to me more like a limitation not a bug in that secondary axises are not rendered when autorange is detected
As explained above, every ValueAxis that has no or an empty dataset for its range calculation will display a default range upon using the autoRange function, regardless of whether it is a primary or a higher order axis.
In your snippt above, I am still not seeing that you map a dataset to the secondary axis.

Locked