org.eurocarbdb.application.glycoworkbench.plugin.reporting.ProfilesComparisonReportChartCanvas.java Source code

Java tutorial

Introduction

Here is the source code for org.eurocarbdb.application.glycoworkbench.plugin.reporting.ProfilesComparisonReportChartCanvas.java

Source

/*
*   EuroCarbDB, a framework for carbohydrate bioinformatics
*
*   Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
*   indicated by the @author tags or express copyright attribution
*   statements applied by the authors.  
*
*   This copyrighted material is made available to anyone wishing to use, modify,
*   copy, or redistribute it subject to the terms and conditions of the GNU
*   Lesser General Public License, as published by the Free Software Foundation.
*   A copy of this license accompanies this distribution in the file LICENSE.txt.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
*   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
*   for more details.
*
*   Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$  
*/

/**
   @author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/

package org.eurocarbdb.application.glycoworkbench.plugin.reporting;

import org.eurocarbdb.application.glycoworkbench.plugin.*;
import org.eurocarbdb.application.glycoworkbench.*;
import org.eurocarbdb.application.glycanbuilder.*;

import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.print.*;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.data.general.Dataset;
import org.jfree.data.category.CategoryDataset;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.ui.TextAnchor;

import static org.eurocarbdb.application.glycanbuilder.Geometry.*;

public class ProfilesComparisonReportChartCanvas extends JComponent implements SVGUtils.Renderable, Printable {

    private static final int DRAW_X_MARGIN = 20;
    private static final int DRAW_Y_MARGIN = 20;
    private static final int CHART_X_MARGIN = 20;
    private static final int CHART_Y_MARGIN = 20;
    private static final int CHART_WIDTH = 800;
    private static final int CHART_WIDTH_TICK = 15;
    private static final int CHART_HEIGHT = 600;

    private GlycoWorkbench theApplication;
    private ProfilesComparisonReportDocument theDocument;
    private GlycanRenderer theGlycanRenderer;
    private JScrollPane theScrollPane = null;
    private ProfilesComparisonReportOptions theOptions;
    private GraphicOptions theGraphicOptions;

    private CategoryDataset theDataset;
    private CategoryPlot thePlot;
    private JFreeChart theChart;

    // drawing  
    private double scale;
    private boolean is_printing;

    private Rectangle view_area;
    private Rectangle draw_area;
    private Rectangle chart_area;
    private Rectangle2D data_area;

    // construction

    public ProfilesComparisonReportChartCanvas(GlycoWorkbench application, ProfilesComparisonReportDocument doc,
            ProfilesComparisonReportOptions opt) {

        theApplication = application;
        theDocument = doc;
        theOptions = opt;
        theGraphicOptions = theApplication.getWorkspace().getGraphicOptions();
        theGlycanRenderer = theApplication.getWorkspace().getGlycanRenderer();

        // create chart
        createChart();

        // finish setting up
        is_printing = false;
        setScale(1.);
    }

    public void setScrollPane(JScrollPane sp) {
        theScrollPane = sp;
    }

    // drawing

    public void beforeRendering() {
        is_printing = true;
    }

    public void afterRendering() {
        is_printing = false;
    }

    public Dimension getRenderableSize() {
        return getPreferredSize();
    }

    public void paintRenderable(Graphics2D g2d) {
        paintComponent(g2d);
    }

    protected void paintComponent(Graphics g) {

        // prepare graphic object
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // set clipping area
        if (is_printing) {
            g2d.translate(-draw_area.x, -draw_area.y);
            g2d.setClip(draw_area);
        }

        //paint canvas background
        if (!is_printing) {
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }

        // paint white background on drawing area    
        g2d.setColor(Color.white);
        g2d.fillRect(draw_area.x, draw_area.y, draw_area.width, draw_area.height);
        if (!is_printing) {
            g2d.setColor(Color.black);
            g2d.draw(draw_area);
        }

        // paint
        paintChart(g2d);

        // dispose graphic object
        g2d.dispose();

        revalidate();
    }

    protected void paintChart(Graphics2D g2d) {
        org.jfree.chart.ChartRenderingInfo cri = new org.jfree.chart.ChartRenderingInfo();
        theChart.draw(g2d, chart_area, cri);
        data_area = cri.getPlotInfo().getDataArea();
    }

    public Dimension getPreferredSize() {
        if (is_printing)
            return draw_area.getSize();
        return view_area.getSize();
    }

    public Dimension getMinimumSize() {
        return new Dimension(0, 0);
    }

    // actions

    public void print(PrinterJob job) throws PrinterException {
        // do something before
        is_printing = true;

        job.print();

        // do something after
        is_printing = false;
    }

    public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if (pageIndex > 0) {
            return NO_SUCH_PAGE;
        } else {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setBackground(Color.white);
            g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

            Dimension td = this.getPreferredSize();
            double sx = pageFormat.getImageableWidth() / td.width;
            double sy = pageFormat.getImageableHeight() / td.height;
            double s = Math.min(sx, sy);
            if (s < 1.)
                g2d.scale(s, s);

            RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
            this.paint(g2d);
            RepaintManager.currentManager(this).setDoubleBufferingEnabled(true);

            return PAGE_EXISTS;
        }
    }

    public void setScale(double scale) {
        this.scale = scale;
        updateView();
    }

    public double getScale() {
        return this.scale;
    }

    public void getScreenshot() {
        ClipUtils.setContents(SVGUtils.getImage(this));
    }

    public void updateView() {
        updateDrawArea();
        repaint();
    }

    private void createChart() {

        // create dataset
        theDataset = createDataset();

        // create axis
        CategoryAxis categoryAxis = new CategoryAxis("");
        categoryAxis.setCategoryLabelPositions(org.jfree.chart.axis.CategoryLabelPositions.UP_45);
        ValueAxis valueAxis = new NumberAxis("Normalized Intensities");

        // create renderer
        CategoryItemRenderer renderer = null;
        if (theOptions.REPRESENTATION == theOptions.BARS)
            renderer = new org.jfree.chart.renderer.category.BarRenderer();
        else if (theOptions.REPRESENTATION == theOptions.ERRORBARS)
            renderer = new org.jfree.chart.renderer.category.StatisticalBarRenderer();
        else if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS)
            renderer = new org.jfree.chart.renderer.category.ScatterRenderer();

        ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
        renderer.setBasePositiveItemLabelPosition(position1);
        ItemLabelPosition position2 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
        renderer.setBaseNegativeItemLabelPosition(position2);

        // create plot
        thePlot = new CategoryPlot(theDataset, categoryAxis, valueAxis, renderer);
        thePlot.setOrientation(org.jfree.chart.plot.PlotOrientation.VERTICAL);

        // add mean values 
        if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS) {
            thePlot.setDataset(1, createMeansDataset());
            thePlot.mapDatasetToRangeAxis(1, 0);

            CategoryItemRenderer lr = new org.jfree.chart.renderer.category.LevelRenderer();
            lr.setPaint(Color.black);
            thePlot.setRenderer(1, lr);
        }

        // create chart
        theChart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, thePlot, true);
        theChart.setBackgroundPaint(Color.white);
        theChart.setBorderVisible(false);

    }

    private CategoryDataset createDataset() {
        GlycanRenderer theRenderer = theApplication.getWorkspace().getGlycanRenderer();
        if (theOptions.REPRESENTATION == theOptions.BARS) {
            org.jfree.data.category.DefaultCategoryDataset ret = new org.jfree.data.category.DefaultCategoryDataset();
            for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) {
                for (int i = 0; i < theDocument.getNoColumns(); i++)
                    ret.addValue(row.getColumn(i), theDocument.getNames().get(i), row.name);
            }
            return ret;
        } else if (theOptions.REPRESENTATION == theOptions.ERRORBARS) {
            org.jfree.data.statistics.DefaultStatisticalCategoryDataset ret = new org.jfree.data.statistics.DefaultStatisticalCategoryDataset();
            for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) {
                ret.add(mean(row.intensities_firstgroup), stddev(row.intensities_firstgroup), "First group",
                        row.name);
                ret.add(mean(row.intensities_secondgroup), stddev(row.intensities_secondgroup), "Second group",
                        row.name);
            }
            return ret;
        } else if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS) {
            org.jfree.data.statistics.DefaultMultiValueCategoryDataset ret = new org.jfree.data.statistics.DefaultMultiValueCategoryDataset();
            for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) {
                ret.add(tolist(row.intensities_firstgroup), "First group", row.name);
                ret.add(tolist(row.intensities_secondgroup), "Second group", row.name);
            }
            return ret;
        }
        return null;
    }

    private CategoryDataset createMeansDataset() {
        GlycanRenderer theRenderer = theApplication.getWorkspace().getGlycanRenderer();

        org.jfree.data.category.DefaultCategoryDataset ret = new org.jfree.data.category.DefaultCategoryDataset();
        for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) {
            ret.addValue(mean(row.intensities_firstgroup), "First group", row.name);
            ret.addValue(mean(row.intensities_secondgroup), "Second group", row.name);
        }
        return ret;
    }

    private ArrayList<Double> tolist(double[] array) {
        ArrayList<Double> ret = new ArrayList<Double>();
        for (double d : array)
            ret.add(d);
        return ret;
    }

    private ArrayList<Double> tolist(double value) {
        ArrayList<Double> ret = new ArrayList<Double>();
        ret.add(value);
        return ret;
    }

    private double mean(double[] array) {
        if (array == null || array.length == 0)
            return 0.;

        double mean = 0.;
        for (int i = 0; i < array.length; i++)
            mean += array[i];
        return mean / (double) array.length;
    }

    private double stddev(double[] array) {
        if (array == null || array.length == 0)
            return 0.;

        double mean = mean(array);

        double smean = 0.;
        for (int i = 0; i < array.length; i++)
            smean += array[i] * array[i];
        return Math.sqrt(smean / (double) array.length - mean * mean);
    }

    private Rectangle getViewArea(double scale) {
        int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows());
        return new Rectangle(0, 0, (int) (2 * DRAW_X_MARGIN + scale * (2 * CHART_X_MARGIN + chart_width)),
                (int) (2 * DRAW_Y_MARGIN + scale * (2 * CHART_X_MARGIN + CHART_HEIGHT)));
    }

    private Rectangle getDrawArea(double scale) {
        int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows());
        return new Rectangle(DRAW_X_MARGIN, DRAW_Y_MARGIN, (int) (scale * (2 * CHART_X_MARGIN + chart_width)),
                (int) (scale * (2 * CHART_Y_MARGIN + CHART_HEIGHT)));
    }

    private Rectangle getChartArea(double scale) {
        int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows());
        return new Rectangle((int) (DRAW_X_MARGIN + scale * CHART_X_MARGIN),
                (int) (DRAW_Y_MARGIN + scale * CHART_Y_MARGIN), (int) (scale * chart_width),
                (int) (scale * CHART_HEIGHT));
    }

    protected void updateDrawArea() {

        // update data area
        view_area = getViewArea(scale);
        draw_area = getDrawArea(scale);
        chart_area = getChartArea(scale);

        data_area = null;
        paintChart(GraphicUtils.createImage(view_area.getSize(), true).createGraphics());
    }

}