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;
    }
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • +1 for an [sscce](http://sscce.org/). Unable to reproduce using `jfreechart-1.0.14` & `jcommon-1.0.17`. Note option-drag on Mac OS X. – trashgod Aug 21 '12 at 18:14
  • 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)... – lbalazscs Aug 21 '12 at 18:27
  • Looks good on Ubuntu/OpenJDK, too. You might try changing the renderer's `Stroke` just to see if it makes difference. – trashgod Aug 21 '12 at 18:51
  • 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. – lbalazscs Aug 21 '12 at 19:04
  • Ok, I can see it if I'm careful to zoom but still have both intervals visible before panning. – trashgod Aug 21 '12 at 19:14
  • Cross-posted [here](http://www.jfree.org/forum/viewtopic.php?f=3&t=115655). – trashgod Aug 22 '12 at 19:59
  • Thank you, I will also watch that thread. – lbalazscs Aug 22 '12 at 20:18
  • 2
    The author's reply and proposed [patch](http://www.jfree.org/forum/viewtopic.php?f=3&t=115655#p174646) validates your insight about a possible optimization problem. – trashgod Aug 23 '12 at 05:01
  • 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. – lbalazscs Aug 23 '12 at 14:22

1 Answers1

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 http://stackoverflow.com/a/12065474/230513
 */
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);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 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... – lbalazscs Aug 22 '12 at 07:42
  • See also [`jfreechart-1.0.15.tar.gz`](https://sourceforge.net/projects/jfreechart/files/). – trashgod Jul 08 '13 at 02:17