JFreeChart: data disappears after zooming and panning
Asked Answered
C

1

2

I have a JFreeChart time series chart, which displays a TimePeriodValuesCollection. The dataset contains two intervals. The data is appearing correctly and I am able to pan (with Ctrl-drag) the view. The problem is that if I zoom in, and I pan the view to the right in the zoomed view, the second interval suddenly disappears after the first interval is no longer visible.

Everything is OK, if there is only one interval, or if I don't zoom in.

Any thoughts?

SSCCE:

public class DisappearingTest {
    public static final SimpleDateFormat oracleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                buildFrame();
            }
        });
    }

    private static void buildFrame()  {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel chartPanel = null;
        try {
            chartPanel = createChartPanel();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        f.add(chartPanel);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    static JPanel createChartPanel() throws ParseException {
        TimePeriodValues timePeriodValues = new TimePeriodValues("Test");

        Date startDate1 = oracleDateFormat.parse("2011-01-01");
        Date endDate1 = oracleDateFormat.parse("2011-12-31");

        timePeriodValues.add(new Second(startDate1), 0.3);
        timePeriodValues.add(new Second(endDate1), 0.3);

        Date startDate2 = oracleDateFormat.parse("2012-01-01");
        Date endDate2 = oracleDateFormat.parse("2015-12-31");

        timePeriodValues.add(new Second(startDate2), 0.5);
        timePeriodValues.add(new Second(endDate2), 0.5);

        TimePeriodValuesCollection dataSet = new TimePeriodValuesCollection();
        dataSet.addSeries(timePeriodValues);

        JFreeChart chart = ChartFactory.createTimeSeriesChart("Title", "Time", "Value", dataSet, true, true, false);
        XYPlot plot = chart.getXYPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);

        ChartPanel chartPanel = new ChartPanel(chart);

        return chartPanel;
    }
}
Crossbar answered 21/8, 2012 at 14:15 Comment(9)
+1 for an sscce. Unable to reproduce using jfreechart-1.0.14 & jcommon-1.0.17. Note option-drag on Mac OS X.Lintel
I am also using jfreechart-1.0.14 & jcommon-1.0.17, but on Windows/Java 6 (I have seen it both on Windows 7 and XP)...Crossbar
Looks good on Ubuntu/OpenJDK, too. You might try changing the renderer's Stroke just to see if it makes difference.Lintel
No, after plot.getRenderer().setSeriesStroke(0, new BasicStroke(3)); it is still disappearing. I think it must be some optimization problem, because the line disappears exactly at the moment when the first interval is not visible anymore (as I pan slowly into the future). It is as if JFreeChart thought that "there is nothing to display" - ignoring the second interval.Crossbar
Ok, I can see it if I'm careful to zoom but still have both intervals visible before panning.Lintel
Cross-posted here.Lintel
Thank you, I will also watch that thread.Crossbar
The author's reply and proposed patch validates your insight about a possible optimization problem.Lintel
It works! Thank you very much (Also thank you David Gilbert, if you are reading this). If you post this link as an answer, I'll accept it as the answer to the question.Crossbar
L
4

Sadly, I have no idea why, but this variation may help characterize the anomaly. Click and drag to select slightly more than all of the range and all but n days of the domain, where n > 3. As you control-drag left, panning toward the future, you'll see the last segment disappear after day 3 and then re-appear about n days later. The Reset button allows starting over; note that ticks mark noon.

Addendum: In this forum thread, the author examines the problem and proposes a patch.

Addendum: Fixed in bug ID 3561093.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimePeriodValues;
import org.jfree.data.time.TimePeriodValuesCollection;

/**
 * @see https://mcmap.net/q/1021557/-jfreechart-data-disappears-after-zooming-and-panning
 */
public class DisappearingTest {

    private static ChartPanel chartPanel;
    private static ValueAxis range;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                buildFrame();
            }
        });
    }

    private static void buildFrame() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        initChartPanel();
        f.add(chartPanel, BorderLayout.CENTER);
        JPanel panel = new JPanel();
        panel.add(new JButton(new AbstractAction("Reset") {

            @Override
            public void actionPerformed(ActionEvent e) {
                chartPanel.restoreAutoBounds();
                range.setLowerBound(0);
                range.setUpperBound(1);
            }
        }));
        f.add(panel, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    static void initChartPanel() {
        TimePeriodValues values = new TimePeriodValues("Test");
        values.add(new Day(1, 1, 2012), 0.2);
        values.add(new Day(2, 1, 2012), 0.2);
        values.add(new Day(3, 1, 2012), 0.8);
        values.add(new Day(1, 2, 2012), 0.8);
        TimePeriodValuesCollection data = new TimePeriodValuesCollection();
        data.addSeries(values);
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Title", "Time", "Value", data, true, true, false);
        XYPlot plot = chart.getXYPlot();
        plot.setDomainPannable(true);
        range = plot.getRangeAxis();
        range.setLowerBound(0);
        range.setUpperBound(1);
        chartPanel = new ChartPanel(chart);
        chartPanel.setMouseWheelEnabled(true);
    }
}
Lintel answered 22/8, 2012 at 2:7 Comment(2)
Interesting observation, perhaps the criteria for the line to appear is that at least one of the defining points must be visible? Although if there are only two defining points, the line is visible even if none of the endpoints is visible...Crossbar
See also jfreechart-1.0.15.tar.gz.Lintel

© 2022 - 2024 — McMap. All rights reserved.