Prevent a transparent jFreeChart from redrawing on click

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Pookah
Posts: 4
Joined: Fri Jul 03, 2009 2:18 pm

Prevent a transparent jFreeChart from redrawing on click

Post by Pookah » Mon Jul 06, 2009 5:17 pm

Hi all,

Apologies for something which might be a beginners problem - preventing the jFreeChart's behavior of redrawing on any click.
If the chart is transparent, multiple clicking decrease quality of the image because of the repeated anti-aliasing with the image from the buffer.

I cannot just perform "removeNotify()" on jFrame because the chart then becomes completely irresponsive to any clicks.

Background info: I am dealing with huge biological datasets, so I have a pane for the big plot, and a pane for the highlighted lines and extra details. Therefore, the top pane has to be clickable, and when it is redrawn it should not smudge, as it is doing now.

Any advice will be appriciated,

Nenad Bartonicek
EMBL-EBI

A sample code:

Code: Select all


import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * A demonstration application showing how to create a combined chart.
 */
public class XYLineAndShapeRendererDemo1 extends JPanel {

    
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
     * Creates a combined chart.
     *
     * @return The combined chart.
     */
    
    public static NumberAxis rangeAxis1 = new NumberAxis("Range 1");
    public static NumberAxis rangeAxis2 = new NumberAxis("Range 2");
    public static XYSeriesCollection dataset1Subset = new XYSeriesCollection();
    public static XYSeriesCollection dataset2Subset = new XYSeriesCollection();
    public static XYLineAndShapeRendererDemo1 lLayeredPanel = new XYLineAndShapeRendererDemo1(); 
    public static JFrame lFrame = new JFrame();
      private static JFreeChart createCombinedChart() {

        // create plot
    	XYSeriesCollection data1 = createDataset1();
        XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer(true,false);
        XYPlot subplot = new XYPlot(data1, null, rangeAxis1, renderer1);
        subplot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        subplot.setBackgroundPaint(null);          
        subplot.setDomainGridlinesVisible(false);
        subplot.setRangeGridlinesVisible(false);
        subplot.setBackgroundAlpha(0.0f);
        
        // parent plot...
        CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
        
        // add the subplot
        plot.add(subplot, 1);      
        plot.setOrientation(PlotOrientation.VERTICAL);

        // return a new chart containing the overlaid plot...
        return new JFreeChart(
            "CombinedDomainXYPlot Demo", JFreeChart.DEFAULT_TITLE_FONT, plot, false
        );
    }
    
    
    /**
     * Creates a sample dataset.
     *
     * @return Series 1.
     */
    private static XYSeriesCollection createDataset1() {

        // create dataset 1...
        XYSeries series1 = new XYSeries("Series 1");
        series1.add(10.0, 12353.3);
        series1.add(20.0, 13734.4);
        series1.add(30.0, 14525.3);
        series1.add(40.0, 13984.3);
        series1.add(50.0, 12999.4);
        series1.add(60.0, 14274.3);
        series1.add(70.0, 15943.5);
        series1.add(80.0, 14845.3);
        series1.add(90.0, 14645.4);
        series1.add(100.0, 16234.6);
        series1.add(110.0, 17232.3);
        series1.add(120.0, 14232.2);
        series1.add(130.0, 13102.2);
        series1.add(140.0, 14230.2);
        series1.add(150.0, 11235.2);

        
        XYSeries series4 = new XYSeries("Series 2");
        series4.add(10.0, 15000.3);
        series4.add(20.0, 11000.4);
        series4.add(30.0, 17000.3);
        series4.add(40.0, 15000.3);
        series4.add(50.0, 14000.4);
        series4.add(60.0, 12000.3);
        series4.add(70.0, 11000.5);
        series4.add(80.0, 12000.3);
        series4.add(90.0, 13000.4);
        series4.add(100.0, 12000.6);
        series4.add(110.0, 13000.3);
        series4.add(120.0, 12000.2);
        series4.add(130.0, 13000.2);
        series4.add(140.0, 11000.2);
        series4.add(150.0, 14000.2);

        XYSeriesCollection collection = new XYSeriesCollection();
        collection.addSeries(series1);
        collection.addSeries(series4);
        return collection;
        

    }
    
    /**
     * Starting point for the application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {
        
    	JFreeChart chart = createCombinedChart();   
        chart.setBackgroundPaint(null);//this line necessary for transparency of background
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setOpaque(false); //this line necessary for transparency of background
        chartPanel.setBackground(new Color(0, 0, 0, 0)); //this line necessary for transparency of background
        lLayeredPanel.add(chartPanel, new Integer(0));        
        lLayeredPanel.setSize(200, 250);        
        JLayeredPane layeredPane = new JLayeredPane();       
        layeredPane.add(lLayeredPanel, 0);
        lFrame.getContentPane().setLayout(new BorderLayout());
        lFrame.getContentPane().add(lLayeredPanel, BorderLayout.CENTER);
        lFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        lFrame.setSize(800, 650);
        lFrame.setVisible(true);
    }
}

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Prevent a transparent jFreeChart from redrawing on click

Post by david.gilbert » Mon Jul 06, 2009 8:27 pm

The problem here is with the BufferedImage that is used by the ChartPanel for the off-screen buffer. To clear the image between redraws, we're filling it with the same color as the background of the ChartPanel. But you just made that transparent, so that doesn't work anymore. A workaround would be to use a ChartPanel *without* the offscreen buffer:

Code: Select all

final ChartPanel chartPanel = new ChartPanel(chart, false);
I think the solution, though, is to modify the ChartPanel itself so that it clears the buffered image to fully transparent. I didn't do that before, because I didn't know how to do it efficiently. But I just found a solution I think:

http://blog.keilly.com/2007/09/clear-bu ... -java.html

I'll try it out and if it works I'll include it in the next release.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

Pookah
Posts: 4
Joined: Fri Jul 03, 2009 2:18 pm

Re: Prevent a transparent jFreeChart from redrawing on click

Post by Pookah » Tue Jul 07, 2009 9:36 am

So far, the first solution works like a charm! Thank you for the prompt reply, I was getting quite stuck with this.
I'll try to get the second solution working and post a reply here.

Locked