org.jax.pubarray.gwtqueryapp.client.ProbeDetailsContainer.java Source code

Java tutorial

Introduction

Here is the source code for org.jax.pubarray.gwtqueryapp.client.ProbeDetailsContainer.java

Source

/*
 * Copyright (c) 2010 The Jackson Laboratory
 * 
 * This is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.jax.pubarray.gwtqueryapp.client;

import java.util.Arrays;
import java.util.List;

import org.jax.pubarray.gwtcommon.client.QualifiedColumnMetadata;
import org.jax.pubarray.gwtcommon.client.TableColumnMetadata;
import org.jax.pubarray.gwtcommon.client.TableColumnMetadataModelUtil;
import org.jax.pubarray.gwtqueryapp.client.ProbeIntensityGraphConfiguration.GroupedGraphType;

import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.form.AdapterField;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Image;

/**
 * @author <A HREF="mailto:keith.sheppard@jax.org">Keith Sheppard</A>
 */
public class ProbeDetailsContainer extends LayoutContainer {
    private static final String PROBE_INTENSITY_PLOT_IMG_PREFIX = "restful/graph-images/";
    private static final int DEFAULT_GRAPH_HEIGHT = 600;

    private static final String GROUP_GRAPH_ENUM_KEY = "GROUP_GRAPH_ENUM_KEY";
    private static final String GROUP_GRAPH_NAME_KEY = "GROUP_GRAPH_NAME_KEY";

    private final GraphingServiceAsync graphingService;

    private final LayoutContainer probeIntensityPlotContainer;
    private final Image probeIntensityPlot;

    private final ContentPanel mainPanel;

    private final ListStore<ModelData> designTermsStore;
    private final ComboBox<ModelData> orderByComboBox;
    private final CheckBox groupReplicatesCheckBox;
    private final ComboBox<ModelData> groupGraphTypeComboBox;

    private final ProbeIntensityGraphConfiguration graphConfiguration;

    private String plotKey;

    /**
     * Constructor
     * @param graphingService
     *          the graphing service to use
     * @param designTerms
     *          the metadata
     */
    public ProbeDetailsContainer(GraphingServiceAsync graphingService, TableColumnMetadata[] designTerms) {
        this.graphingService = graphingService;
        this.probeIntensityPlotContainer = new LayoutContainer();
        this.probeIntensityPlot = new Image();
        this.mainPanel = new ContentPanel();

        this.graphConfiguration = new ProbeIntensityGraphConfiguration();

        this.designTermsStore = new ListStore<ModelData>();
        List<ModelData> designTermModels = TableColumnMetadataModelUtil.fromPojosToModels(true,
                Arrays.asList(designTerms));
        this.designTermsStore.add(designTermModels);

        this.orderByComboBox = new ComboBox<ModelData>();
        this.orderByComboBox.setStore(this.designTermsStore);
        this.orderByComboBox.setDisplayField(TableColumnMetadata.NAME_PROP_STRING);
        this.orderByComboBox.setEditable(false);
        this.orderByComboBox.setAllowBlank(true);
        this.orderByComboBox.setForceSelection(true);
        this.orderByComboBox.setTypeAhead(false);
        this.orderByComboBox.setEmptyText("Select Design Term");
        this.orderByComboBox.setTriggerAction(TriggerAction.ALL);
        this.orderByComboBox.addSelectionChangedListener(new SelectionChangedListener<ModelData>() {
            /**
             * {@inheritDoc}
             */
            @Override
            public void selectionChanged(SelectionChangedEvent<ModelData> se) {
                TableColumnMetadata selectedDesignTerm = TableColumnMetadataModelUtil
                        .fromModelToPojo(se.getSelectedItem());
                ProbeDetailsContainer.this.setSelectedDesignTerm(selectedDesignTerm);
                ProbeDetailsContainer.this.groupReplicatesCheckBox.setEnabled(true);
            }
        });

        this.groupReplicatesCheckBox = new CheckBox("Group Arrays Using");
        this.groupReplicatesCheckBox.setValue(Boolean.FALSE, true);
        this.groupReplicatesCheckBox.setEnabled(false);
        this.groupReplicatesCheckBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
            /**
             * {@inheritDoc}
             */
            public void onValueChange(ValueChangeEvent<Boolean> event) {
                ProbeDetailsContainer.this.groupReplicatesChanged();
            }
        });

        final ListStore<ModelData> groupGraphTypeStore = new ListStore<ModelData>();
        final BaseModel scatterPlotModel = new BaseModel();
        scatterPlotModel.set(GROUP_GRAPH_ENUM_KEY, GroupedGraphType.SCATTER_PLOT);
        scatterPlotModel.set(GROUP_GRAPH_NAME_KEY, "Scatter Plot");
        groupGraphTypeStore.add(scatterPlotModel);

        final BaseModel boxPlotModel = new BaseModel();
        boxPlotModel.set(GROUP_GRAPH_ENUM_KEY, GroupedGraphType.BOX_PLOT);
        boxPlotModel.set(GROUP_GRAPH_NAME_KEY, "Box Plot");
        groupGraphTypeStore.add(boxPlotModel);

        this.groupGraphTypeComboBox = new ComboBox<ModelData>();
        this.groupGraphTypeComboBox.setEnabled(false);
        this.groupGraphTypeComboBox.setStore(groupGraphTypeStore);
        this.groupGraphTypeComboBox.setDisplayField(GROUP_GRAPH_NAME_KEY);
        this.groupGraphTypeComboBox.setEditable(false);
        this.groupGraphTypeComboBox.setAllowBlank(false);
        this.groupGraphTypeComboBox.setForceSelection(true);
        this.groupGraphTypeComboBox.setTypeAhead(false);
        this.groupGraphTypeComboBox.setValue(scatterPlotModel);
        this.groupGraphTypeComboBox.setTriggerAction(TriggerAction.ALL);
        this.groupGraphTypeComboBox.addSelectionChangedListener(new SelectionChangedListener<ModelData>() {
            /**
             * {@inheritDoc}
             */
            @Override
            public void selectionChanged(SelectionChangedEvent<ModelData> se) {
                ProbeDetailsContainer.this.groupGraphTypeChanged();
            }
        });

        this.probeIntensityPlot.addLoadHandler(new LoadHandler() {
            /**
             * {@inheritDoc}
             */
            public void onLoad(LoadEvent event) {
                ProbeDetailsContainer.this.probeIntensityPlotLoaded();
            }
        });
        this.probeIntensityPlot.addErrorHandler(new ErrorHandler() {
            /**
             * {@inheritDoc}
             */
            public void onError(ErrorEvent event) {
                ProbeDetailsContainer.this.showErrorMask("Error Loading Image");
            }
        });
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);

        // add components to the content panel
        this.mainPanel.setHeading("Expression Details");
        this.mainPanel.setFrame(true);
        this.mainPanel.setCollapsible(true);
        this.mainPanel.setAnimCollapse(false);
        this.mainPanel.setIconStyle("icon-table");
        this.mainPanel.setAutoWidth(true);

        this.add(this.mainPanel);

        this.probeIntensityPlot.setVisible(false);
        this.probeIntensityPlotContainer.setHeight(DEFAULT_GRAPH_HEIGHT);
        this.probeIntensityPlotContainer.add(this.probeIntensityPlot);
        this.probeIntensityPlotContainer.setAutoWidth(true);
        this.mainPanel.add(this.probeIntensityPlotContainer);

        ToolBar toolBar = new ToolBar();
        toolBar.setSpacing(3);
        toolBar.add(new LabelToolItem("Order Arrays By:"));
        toolBar.add(this.orderByComboBox);
        toolBar.add(new SeparatorToolItem());
        toolBar.add(new AdapterField(this.groupReplicatesCheckBox));
        toolBar.add(this.groupGraphTypeComboBox);
        this.mainPanel.setTopComponent(toolBar);

        Window.addResizeHandler(new ResizeHandler() {
            /**
             * {@inheritDoc}
             */
            public void onResize(ResizeEvent event) {
                ProbeDetailsContainer.this.layout();

                if (ProbeDetailsContainer.this.probeIntensityPlot.isVisible()) {
                    ProbeDetailsContainer.this.updateProbeIntensityPlotURL();
                }
            }
        });
    }

    private void groupGraphTypeChanged() {
        ModelData selectedValue = this.groupGraphTypeComboBox.getValue();
        GroupedGraphType graphType = selectedValue.get(GROUP_GRAPH_ENUM_KEY);
        System.out.println("group replicates graph type changed: " + graphType);
        this.graphConfiguration.setGroupedGraphType(graphType);

        this.maybeRebuildProbeIntensityPlot();
    }

    private void groupReplicatesChanged() {
        Boolean value = this.groupReplicatesCheckBox.getValue();
        System.out.println("group replicates checkbox changed: " + value);
        this.graphConfiguration.setGroupReplicates(value);
        this.groupGraphTypeComboBox.setEnabled(value);

        this.maybeRebuildProbeIntensityPlot();
    }

    private void setSelectedDesignTerm(TableColumnMetadata selectedDesignTerm) {
        this.graphConfiguration.setOrderProbesBy(selectedDesignTerm);
        this.maybeRebuildProbeIntensityPlot();
    }

    /**
     * Update the probe intensity graph with new selected probes and terms of
     * interest
     * @param selectedProbes
     *          the selected probes
     * @param termsOfInterest
     *          the terms of interest
     */
    public void updateProbeIntensityGraph(String[] selectedProbes, QualifiedColumnMetadata[] termsOfInterest) {
        System.out.println("updating probe intensity graph");

        this.graphConfiguration.setProbeIds(selectedProbes);
        this.graphConfiguration.setTermsOfInterest(termsOfInterest);

        this.maybeRebuildProbeIntensityPlot();
    }

    private void maybeRebuildProbeIntensityPlot() {
        String[] selectedProbes = this.graphConfiguration.getProbeIds();

        if (selectedProbes == null || selectedProbes.length == 0) {
            this.probeIntensityPlotContainer.mask("No Probesets Selected");
            this.probeIntensityPlot.setVisible(false);
        } else {
            this.rebuildProbeIntensityPlot();
        }
    }

    private void rebuildProbeIntensityPlot() {
        this.graphingService.buildProbeIntensityGraph(this.graphConfiguration, new AsyncCallback<String>() {
            /**
             * {@inheritDoc}
             */
            public void onFailure(Throwable caught) {
                caught.printStackTrace();
                ProbeDetailsContainer.this.showErrorMask("Error: " + caught.getMessage());
            }

            /**
             * {@inheritDoc}
             */
            public void onSuccess(String key) {
                System.out.println("build graph succeeded. rewriting image url " + "for key: " + key);
                ProbeDetailsContainer.this.plotKey = key;
                ProbeDetailsContainer.this.updateProbeIntensityPlotURL();
            }
        });
    }

    private void showErrorMask(String message) {
        this.probeIntensityPlotContainer.mask(message);
    }

    private void probeIntensityPlotLoaded() {
        System.out.println("loaded probe graph of size: " + this.probeIntensityPlot.getWidth() + "x"
                + this.probeIntensityPlot.getHeight());
        this.probeIntensityPlotContainer.unmask();
        this.probeIntensityPlot.setVisible(true);
    }

    private void updateProbeIntensityPlotURL() {
        if (this.plotKey != null) {
            int plotWidth = this.probeIntensityPlotContainer.getWidth(true);
            int plotHeight = this.probeIntensityPlotContainer.getHeight(true);

            if (plotWidth >= 20 && plotHeight >= 20) {
                this.probeIntensityPlotContainer.mask("Loading Graph");
                this.probeIntensityPlot.setUrl(PROBE_INTENSITY_PLOT_IMG_PREFIX + "probe-intensity-graph-"
                        + this.plotKey + "-" + plotWidth + "x" + plotHeight + ".png");
            }
        }
    }
}