zoom on one chart - chartPanel update to all

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 on one chart - chartPanel update to all

Post by Fred » Fri Jan 20, 2017 2:47 pm

Hello,

First, I want to add I've reviewed the CombinedZoomTest class and though that does what I want,
I have VectorRenderer charts each representing an attribute from a data object class. There is way too
much data to use the CombinedZoomTest.

The data is a time/time raster. What is desired is to zoom to area on any of the chart panels with the plot change event
producing the same results on any of the others. All charts run under the same app/thread and data from
a plot change event could be shared. The question is how to force a plot change event on those
chart panels where the event did not take place.

Is this idea possible?

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by paradoxoff » Fri Jan 20, 2017 5:50 pm

Fred wrote:CombinedZoomTest
I don't know where I could find that class, but since it hasn't solved your problem, it is probably not necessary to know.

You could register a common AxisChangeListener on every axis that you want to monitor. This AxisChangeListener could manage an ArrayList of Axes.
If an AxisChangeEvent is fired, you could access the axis that generated the event, check whether it is a ValueAxis, if so, get its range, and set this range to all the other axes in the ArrayList.
Since every call to setRange() will trigger a new AxisChangeEvent, make sure that AxisChangeEvents are ignored while you iterate over the ArrayList and change the axis ranges.

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Fri Jan 20, 2017 10:01 pm

Paradoxoff thanks! I was wondering if you could give me a snippet of code.
I was think something like this..

Create the xAxis..

Code: Select all

NumberAxis xAxis = null;

xAxis = new NumberAxis("time");
xAxis.addChangeListener(<AxisChangeListener method>);
 
yAxis = new NumberAxis("short time");
yAxis.addChangeListener(<AxisChangeListener method>);

This would be defined for each x/y axis created on all chart panels (charts).
The AxisChangeListener <method> would be fired when the event occurs.
It would have to house/manage an ArrayList of axes from which to determine
what needs to be evaluated and fired. And like you said be sure to not allow when a
setRange() triggers a new AxisChangeEvent or a mutating trigger will cause havoc.

Not sure if this concept is correct.

Suggestions?

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Fri Jan 20, 2017 10:35 pm

Paradoxoff/All,

I have a PlotChangeListener on the primary chart (to add a secondary Y axis and update it when zooming occurs).
This works well. If I added this Listener to all plots (not just the primary) can I use it instead of a AxisChangeListener
and get the desired results? Seems there would need to be a AxisChangeListener (2) for each chart instead of 1 for each
plot/chart (1 for the X and 1 for the Y axis). Of course, it would have to be enhanced to iterate through all of the plots
and force a setRange().

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by paradoxoff » Sat Jan 21, 2017 2:50 pm

Fred wrote:I was wondering if you could give me a snippet of code.
Here it is:

Code: Select all

public class MultiWindowDemo {

    public static void main(String[] args) {
        AxisRangeAdjuster adj = new AxisRangeAdjuster();
        for (int i = 0; i < 4; i++) {
            JFrame f = createFrame(adj);
            f.pack();
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }

    private static JFrame createFrame(AxisRangeAdjuster adj) {
        long now = System.currentTimeMillis();
        DefaultXYDataset dataset1 = new DefaultXYDataset();
        int size = 10;
        double[][] data = new double[2][size];
        double[][] data1 = new double[2][size];
        for (int i = 0; i < size; i++) {
            data[0][i] = i;
            data[1][i] = i * 2;
        }
        dataset1.addSeries("Data1A", data);
        XYPlot plot = new XYPlot(dataset1, new NumberAxis("x"), new NumberAxis("y"), new XYLineAndShapeRenderer());
        adj.registerAxis(plot.getDomainAxis());
        JFrame frame = new JFrame();
        frame.getContentPane().add(new ChartPanel(new JFreeChart(plot)));
        return frame;
    }

    static class AxisRangeAdjuster implements AxisChangeListener {

        private ArrayList<ValueAxis> axes = new ArrayList<ValueAxis>();
        
        private boolean active = true;
        
        public void registerAxis(ValueAxis va){
            axes.add(va);
            va.addChangeListener(this);
        }
        public void axisChanged(AxisChangeEvent ace){
            if (!active) return;
            Axis a = ace.getAxis();
            if(!(a instanceof ValueAxis)) return;
            ValueAxis va = (ValueAxis)a;
            if(!axes.contains(va)) return;
            Range range = va.getRange();
            active = false;
            for(ValueAxis vax: axes){
                if(vax != va) vax.setRange(range);
            }
            active = true;
        }
    }
}


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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Mon Jan 23, 2017 6:27 pm

Thanks Paradoxoff. I've created the class and ran some tests. It works mostly.
I did see one issue. If I zoom on one chart but elect to AutoRange out on another,
the one chart that was used to do the initial zoom does not AutoRange out. Not sure
why that happens in looking at the code.

But this does do what I'm looking for. Evaluating my apps to see how to implement it.

Cheers!

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by paradoxoff » Tue Jan 24, 2017 6:26 pm

Fred wrote:I did see one issue. If I zoom on one chart but elect to AutoRange out on another,
the one chart that was used to do the initial zoom does not AutoRange out. Not sure
why that happens in looking at the code.
Though I have not completely understood what behaviour you are seeing and why you didn't understand it: keep in mind that whatever range will be set for the first value axis, will also be used for the others, regardless of whether the range for the first axis might come from. All what is done in the "others" is a simple setRange command, and this command ignores the autoRange setting completely.
If one of your charts happens to have no data, a "zoom out" will result in a range of 0-1.05 (auto range value of 0-1 plus a margin of 5 %). This range will then be set for the other charts as well, regardless of the autoRange flag.

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Tue Jan 24, 2017 8:12 pm

Thanks again Paradoxoff. I think the issue was that the 2 disparate charts do not represent time/time the same way.
However, I've created another chart that does and the issue I'm seeing now is the same regardless of which chart I do
the initial zoom on. The chart where the zoom is issued on works fine. However, only the domain (not range) axis
reflects the change. The domain (X) axis does change to the correct upper/lower bounds. But nothing is done to the range (Y) axis.

I've attempted to register with the range axis (adj.registerAxis(plot.getRangeAxis();) but this creates a problem when the data is
initially presented (acts like a zoom as already occurred).

I need both axis to reflect the zoom not just the domain axis.

Is that possible with this solution or possible at all with another idea?

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Tue Jan 24, 2017 8:38 pm

Paradoxoff/all,

here are a couple of other notes.
I have the range (Y) axis inverted.
I've turned this off but no change using the zoom feature.

I also have a PlotChangeListener and I've turned that off
and again no change when using this zoom feature.

Fred

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

Re: zoom on one chart - chartPanel update to all

Post by paradoxoff » Tue Jan 24, 2017 10:07 pm

What about creating two instances of AxisRangeAdjuster, and using one instance for the range and the other for the domain axes?

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Thu Jan 26, 2017 10:21 pm

Paradoxoff Thanks. I'll try that and see what comes from it.

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

Re: zoom on one chart - chartPanel update to all

Post by Fred » Fri Jan 27, 2017 6:28 pm

Paradoxoff.. your awesome dude!
It works perfectly.

Many Thanks!

Fred

Locked