0

I am cloning a JFreeChart and then disabling one of the series using the setSeriesVisible() method. The series does not appear. However, the legend item still appears. How can make the legend item from not appearing. What am I doing wrong?

Here's my code:

package test;

import java.awt.Color;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class Test2 extends ApplicationFrame {


public Test2(final String title) {

    super(title);

    try {
        final XYDataset dataset = createDataset();
        final JFreeChart chart = createChart(dataset);
        JFreeChart tempChart = (JFreeChart) chart.clone();
        tempChart.getXYPlot().getRenderer().setSeriesVisible(1, false, true);
        final ChartPanel chartPanel = new ChartPanel(tempChart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
    }

}

private XYDataset createDataset() {

    final XYSeries series1 = new XYSeries("First");
    series1.add(1.0, 1.0);
    series1.add(2.0, 4.0);
    series1.add(3.0, 3.0);
    series1.add(4.0, 5.0);
    series1.add(5.0, 5.0);
    series1.add(6.0, 7.0);
    series1.add(7.0, 7.0);
    series1.add(8.0, 8.0);

    final XYSeries series2 = new XYSeries("Second");
    series2.add(1.0, 5.0);
    series2.add(2.0, 7.0);
    series2.add(3.0, 6.0);
    series2.add(4.0, 8.0);
    series2.add(5.0, 4.0);
    series2.add(6.0, 4.0);
    series2.add(7.0, 2.0);
    series2.add(8.0, 1.0);

    final XYSeries series3 = new XYSeries("Third");
    series3.add(3.0, 4.0);
    series3.add(4.0, 3.0);
    series3.add(5.0, 2.0);
    series3.add(6.0, 3.0);
    series3.add(7.0, 6.0);
    series3.add(8.0, 3.0);
    series3.add(9.0, 4.0);
    series3.add(10.0, 3.0);

    final XYSeriesCollection dataset = new XYSeriesCollection();
    dataset.addSeries(series1);
    dataset.addSeries(series2);
    dataset.addSeries(series3);

    return dataset;

}


private JFreeChart createChart(final XYDataset dataset) {

    final JFreeChart chart = ChartFactory.createXYLineChart(
        "Line Chart Demo 6",      // chart title
        "X",                      // x axis label
        "Y",                      // y axis label
        dataset,                  // data
        PlotOrientation.VERTICAL,
        true,                     // include legend
        true,                     // tooltips
        false                     // urls
    );


    chart.setBackgroundPaint(Color.white);

    final XYPlot plot = chart.getXYPlot();
    plot.setBackgroundPaint(Color.lightGray);
    plot.setDomainGridlinePaint(Color.white);
    plot.setRangeGridlinePaint(Color.white);

    final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
    renderer.setSeriesLinesVisible(0, false);
    renderer.setSeriesShapesVisible(1, false);
    plot.setRenderer(renderer);

    final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    return chart;

}

public static void main(final String[] args) {

    final Test2 demo = new Test2("Line Chart Demo 6");
    demo.pack();
    RefineryUtilities.centerFrameOnScreen(demo);
    demo.setVisible(true);

}

}
chrisrhyno2003
  • 3,906
  • 8
  • 53
  • 102

1 Answers1

0

As you know, by default in Java the clone() method performs a "shallow copy", meaning it does not clone each individual field of an object (it just copies a reference to them). Therefore it is never clear what the clone() method does when it is overriden by developpers, unless they unambiguously explain it in the documentation. In the present case, I would say it is still a bit ambiguous:

Clones the object, and takes care of listeners. Note: caller shall register its own listeners on cloned graph.

So I'm not sure what happens with the Plot objects, the renderers, the datasets, to the axes, the legend, etc.

My advice: Do not use clone(). Create fresh instances of the objects that need to be duplicated, so you'll control exactly which objects are unique, and which have siblings. And hopefully, the problem of inconsistent legend vs. visible series will disappear as well.

Eric Leibenguth
  • 4,167
  • 3
  • 24
  • 51
  • I need to create a duplicate of an existing chart. That's the only problem. Are you saying I create the new chart using the plot of the existing chart ? – chrisrhyno2003 Jul 15 '15 at 15:59
  • You probably need a new **renderer** (to control the series visibility), but also a new **plot** object (because it has the `getLegendItems()` method). All the **dataset** and **series** can be taken from the existing graph. – Eric Leibenguth Jul 15 '15 at 16:11
  • See also the implementation of [`JFreeChart#clone()`](http://www.jfree.org/jfreechart/api/javadoc/src-html/org/jfree/chart/JFreeChart.html#line.1691). – trashgod Jul 15 '15 at 19:33