Java tutorial
/* * Copyright (C) 2013 Universitat Pompeu Fabra * * This program 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 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.gwaspi.gui.reports; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.List; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.DefaultComboBoxModel; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.LayoutStyle; import javax.swing.SwingConstants; import org.gwaspi.constants.NetCDFConstants.Defaults.OPType; import org.gwaspi.global.Config; import org.gwaspi.global.Text; import org.gwaspi.gui.GWASpiExplorerPanel; import org.gwaspi.gui.utils.CursorUtils; import org.gwaspi.gui.utils.Dialogs; import org.gwaspi.gui.utils.LinksExternalResouces; import org.gwaspi.gui.utils.URLInDefaultBrowser; import org.gwaspi.model.ChromosomeKey; import org.gwaspi.model.DataSetKey; import org.gwaspi.model.MarkerKey; import org.gwaspi.model.OperationKey; import org.gwaspi.model.Report; import org.gwaspi.model.ReportsList; import org.gwaspi.reports.GenericReportGenerator; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartMouseEvent; import org.jfree.chart.ChartMouseListener; import org.jfree.chart.ChartPanel; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.LogAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.TickUnitSource; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.AbstractXYItemLabelGenerator; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardXYToolTipGenerator; import org.jfree.chart.labels.XYItemLabelGenerator; import org.jfree.chart.labels.XYToolTipGenerator; import org.jfree.chart.plot.Marker; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.ui.RectangleAnchor; import org.jfree.ui.RectangleEdge; import org.jfree.ui.TextAnchor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class ManhattanPlotZoom extends JPanel { private final Logger log = LoggerFactory.getLogger(ManhattanPlotZoom.class); /** roughly 2000MB needed per 100.000 plotted markers */ public static final int MARKERS_NUM_DEFAULT = (int) Math .round(100000 * ((double) Config.getSingleton().getInteger(Config.PROPERTY_MAX_HEAP_MB, -1) / 2000)); private final OperationKey testOpKey; private Map<String, MarkerKey> labeler; private final MarkerKey origMarkerKey; private final ChromosomeKey origChr; private final ChromosomeKey currentChr; private final Integer nRows; private long centerPhysPos; private long startPhysPos; private long requestedSetSize; private long requestedPosWindow; private XYDataset initXYDataset; private JFreeChart zoomChart; private ChartPanel zoomPanel; private double threshold; private Color manhattan_back; private Color manhattan_dot; // Variables declaration - do not modify private JButton btn_Back; private JButton btn_Back2; private JButton btn_Reset; private JButton btn_Save; private JPanel pnl_Chart; private JPanel pnl_ChartNavigator; private JPanel pnl_SearchDB; private JComboBox cmb_SearchDB; private JPanel pnl_Footer; private JPanel pnl_FooterGroup1; private JScrollPane scrl_Chart; private ManhattanChartDisplay parent; // End of variables declaration public ManhattanPlotZoom(ManhattanChartDisplay parent, OperationKey operationKey, ChromosomeKey chr, long startPhysPos, long requestedPosWindow, Integer nRows) { this.parent = parent; this.testOpKey = operationKey; this.origMarkerKey = null; this.currentChr = chr; this.origChr = chr; this.nRows = nRows; this.startPhysPos = startPhysPos; this.requestedPosWindow = requestedPosWindow; initChart(true); setCursor(CursorUtils.DEFAULT_CURSOR); } public ManhattanPlotZoom(OperationKey testOpKey, ChromosomeKey chr, MarkerKey markerKey, long centerPhysPos, long requestedSetSize, Integer nRows) { this.testOpKey = testOpKey; this.origMarkerKey = markerKey; this.currentChr = chr; this.origChr = chr; this.nRows = nRows; this.centerPhysPos = centerPhysPos; this.requestedSetSize = requestedSetSize; initChart(false); } public void initChart(boolean usePhysicalPosition) { //<editor-fold defaultstate="expanded" desc="PLOT DEFAULTS"> this.threshold = Config.getSingleton().getDouble(GenericReportGenerator.PLOT_MANHATTAN_THRESHOLD_CONFIG, GenericReportGenerator.PLOT_MANHATTAN_THRESHOLD_DEFAULT); this.manhattan_back = Config.getSingleton().getColor( GenericReportGenerator.PLOT_MANHATTAN_BACKGROUND_CONFIG, GenericReportGenerator.PLOT_MANHATTAN_BACKGROUND_DEFAULT); this.manhattan_dot = Config.getSingleton().getColor(GenericReportGenerator.PLOT_MANHATTAN_MAIN_CONFIG, GenericReportGenerator.PLOT_MANHATTAN_MAIN_DEFAULT); //</editor-fold> final MarkerKey toUseMarkerKey; final long toUseRequestedPosWindow; if (usePhysicalPosition) { toUseMarkerKey = null; toUseRequestedPosWindow = requestedPosWindow; } else { toUseMarkerKey = origMarkerKey; toUseRequestedPosWindow = requestedSetSize; // XXX should this be requestedPosWindow instead? } initXYDataset = GenericReportGenerator.getManhattanZoomByChrAndPos(this, testOpKey, origChr, toUseMarkerKey, startPhysPos, toUseRequestedPosWindow); zoomChart = createChart(initXYDataset, currentChr); zoomPanel = new ChartPanel(zoomChart); zoomPanel.setInitialDelay(10); zoomPanel.setDismissDelay(5000); zoomPanel.addChartMouseListener(new ChartMouseListener() { @Override public void chartMouseClicked(ChartMouseEvent event) { int mouseX = event.getTrigger().getX(); int mouseY = event.getTrigger().getY(); final Point2D point = zoomPanel.translateScreenToJava2D(new Point(mouseX, mouseY)); XYPlot plot = (XYPlot) zoomChart.getPlot(); ChartRenderingInfo info = zoomPanel.getChartRenderingInfo(); Rectangle2D dataArea = info.getPlotInfo().getDataArea(); ValueAxis domainAxis = plot.getDomainAxis(); RectangleEdge domainAxisEdge = plot.getDomainAxisEdge(); long chartX = (long) domainAxis.java2DToValue(point.getX(), dataArea, domainAxisEdge); // ValueAxis rangeAxis = plot.getRangeAxis(); // RectangleEdge rangeAxisEdge = plot.getRangeAxisEdge(); // double chartY = rangeAxis.java2DToValue(p.getY(), dataArea, // rangeAxisEdge); try { if (LinksExternalResouces.checkIfRsNecessary(cmb_SearchDB.getSelectedIndex())) { // THE SELECTED EXTERNAL RESOURCE NEEDS RSID INFO String tooltip = zoomPanel.getToolTipText(event.getTrigger()); if (tooltip == null || tooltip.isEmpty()) { // CHECK IF THERE IS AN RSID Dialogs.showWarningDialogue(Text.Reports.warnExternalResource); } else { String rsId = tooltip.substring(6, tooltip.indexOf('<', 6)); URLInDefaultBrowser.browseGenericURL(LinksExternalResouces.getResourceLink( cmb_SearchDB.getSelectedIndex(), currentChr, // chr rsId, // rsId chartX) // pos ); } } else { // THE SELECTED EXTERNAL RESOURCE ONLY NEEDS CHR+POS INFO URLInDefaultBrowser.browseGenericURL( LinksExternalResouces.getResourceLink(cmb_SearchDB.getSelectedIndex(), currentChr, // chr "", // rsId chartX) // pos ); } // URLInDefaultBrowser.browseGenericURL(LinkEnsemblUrl.getHomoSapiensLink(currentChr, (int) chartX)); } catch (IOException ex) { log.error(Text.Reports.cannotOpenEnsembl, ex); } } /** * Receives chart mouse moved events. * * @param event the event. */ @Override public void chartMouseMoved(ChartMouseEvent event) { // ignore } }); initGUI(); } private void initGUI() { setCursor(CursorUtils.WAIT_CURSOR); pnl_ChartNavigator = new JPanel(); pnl_Chart = new JPanel(); pnl_SearchDB = new JPanel(); cmb_SearchDB = new JComboBox(); scrl_Chart = new JScrollPane(); pnl_Footer = new JPanel(); pnl_FooterGroup1 = new JPanel(); btn_Save = new JButton(); btn_Reset = new JButton(); btn_Back = new JButton(); btn_Back2 = new JButton(); final String titlePlot; if (origMarkerKey == null) { titlePlot = ": Chr" + currentChr + " - Pos: " + startPhysPos + " to " + (startPhysPos + requestedPosWindow); } else { titlePlot = ": " + origMarkerKey.toString() + " - Chr" + currentChr; } pnl_ChartNavigator .setBorder(GWASpiExplorerPanel.createMainTitledBorder("Manhattan Plot Navigator" + titlePlot)); // NOI18N pnl_Chart.setBorder(GWASpiExplorerPanel.createLineBorder()); scrl_Chart.getViewport().add(zoomPanel); pnl_Chart.add(scrl_Chart, BorderLayout.CENTER); // <editor-fold defaultstate="expanded" desc="LAYOUT1"> GroupLayout pnl_ChartLayout = new GroupLayout(pnl_Chart); pnl_Chart.setLayout(pnl_ChartLayout); pnl_ChartLayout.setHorizontalGroup(pnl_ChartLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(scrl_Chart, GroupLayout.DEFAULT_SIZE, 812, Short.MAX_VALUE)); pnl_ChartLayout.setVerticalGroup(pnl_ChartLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(scrl_Chart, GroupLayout.DEFAULT_SIZE, 437, Short.MAX_VALUE)); GroupLayout pnl_ChartNavigatorLayout = new GroupLayout(pnl_ChartNavigator); pnl_ChartNavigator.setLayout(pnl_ChartNavigatorLayout); pnl_ChartNavigatorLayout.setHorizontalGroup(pnl_ChartNavigatorLayout .createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, pnl_ChartNavigatorLayout .createSequentialGroup().addContainerGap().addComponent(pnl_Chart, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap())); pnl_ChartNavigatorLayout .setVerticalGroup(pnl_ChartNavigatorLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_ChartNavigatorLayout .createSequentialGroup().addContainerGap().addComponent(pnl_Chart, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap())); // </editor-fold> String lblChr = "Chr "; Long currPos = 0L; lblChr += currentChr; if (centerPhysPos > 0) { currPos = centerPhysPos; } else { currPos = Math.round((double) MARKERS_NUM_DEFAULT / 2); } //<editor-fold defaultstate="expanded" desc="TRACKER"> // pnl_Tracker.setBorder(GWASpiExplorerPanel.createRegularTitledBorder("Marker N on "+lblChr)); // // // slid_Tracker.setMaximum(max); // slid_Tracker.setValue(currPos); // slid_Tracker.addMouseListener(new event.MouseAdapter() { // public void mouseReleased(event.MouseEvent evt) { // actionSlide(); // } // }); // // GroupLayout pnl_TrackerLayout = new GroupLayout(pnl_Tracker); // pnl_Tracker.setLayout(pnl_TrackerLayout); // pnl_TrackerLayout.setHorizontalGroup( // pnl_TrackerLayout.createParallelGroup(GroupLayout.Alignment.LEADING) // .addGroup(GroupLayout.Alignment.TRAILING, pnl_TrackerLayout.createSequentialGroup() // .addGap(18, 18, 18) // .addComponent(slid_Tracker, GroupLayout.DEFAULT_SIZE, 814, Short.MAX_VALUE) // .addContainerGap()) // ); // pnl_TrackerLayout.setVerticalGroup( // pnl_TrackerLayout.createParallelGroup(GroupLayout.Alignment.LEADING) // .addGroup(pnl_TrackerLayout.createSequentialGroup() // .addContainerGap() // .addComponent(slid_Tracker, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) // .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) // ); //</editor-fold> //<editor-fold defaultstate="expanded" desc="EXTERNAL RESOURCE DBs"> pnl_SearchDB = new JPanel(); pnl_SearchDB.setBorder(GWASpiExplorerPanel.createRegularTitledBorder(Text.Reports.externalResourceDB)); cmb_SearchDB = new JComboBox(); cmb_SearchDB.setModel(new DefaultComboBoxModel(LinksExternalResouces.getLinkNames())); GroupLayout pnl_SearchDBLayout = new GroupLayout(pnl_SearchDB); pnl_SearchDB.setLayout(pnl_SearchDBLayout); pnl_SearchDBLayout.setHorizontalGroup(pnl_SearchDBLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_SearchDBLayout.createSequentialGroup().addContainerGap() .addComponent(cmb_SearchDB, 0, 614, Short.MAX_VALUE).addContainerGap())); pnl_SearchDBLayout.setVerticalGroup(pnl_SearchDBLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_SearchDBLayout .createSequentialGroup().addComponent(cmb_SearchDB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap(14, Short.MAX_VALUE))); //</editor-fold> btn_Save.setAction(new SampleQAHetzygPlotZoom.SaveAsAction("zoom_" + origMarkerKey + ".png", scrl_Chart, zoomChart, this)); btn_Reset.setAction(new ResetAction(testOpKey)); btn_Back.setAction(new BackToTableAction()); btn_Back2.setAction(new BackToManhattanPlotAction()); // <editor-fold defaultstate="expanded" desc="FOOTER"> GroupLayout pnl_FooterGroup1Layout = new GroupLayout(pnl_FooterGroup1); pnl_FooterGroup1.setLayout(pnl_FooterGroup1Layout); pnl_FooterGroup1Layout.setHorizontalGroup(pnl_FooterGroup1Layout .createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, pnl_FooterGroup1Layout.createSequentialGroup().addContainerGap() .addComponent(btn_Reset, GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE) .addGap(18, 18, 18) .addComponent(btn_Save, GroupLayout.PREFERRED_SIZE, 96, GroupLayout.PREFERRED_SIZE) .addContainerGap())); pnl_FooterGroup1Layout.linkSize(SwingConstants.HORIZONTAL, new Component[] { btn_Reset, btn_Save }); pnl_FooterGroup1Layout .setVerticalGroup(pnl_FooterGroup1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_FooterGroup1Layout.createSequentialGroup() .addGroup(pnl_FooterGroup1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(btn_Save).addComponent(btn_Reset)) .addContainerGap(16, Short.MAX_VALUE))); pnl_FooterGroup1Layout.linkSize(SwingConstants.VERTICAL, new Component[] { btn_Reset, btn_Save }); GroupLayout pnl_FooterLayout = new GroupLayout(pnl_Footer); pnl_Footer.setLayout(pnl_FooterLayout); pnl_FooterLayout.setHorizontalGroup(pnl_FooterLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_FooterLayout.createSequentialGroup().addContainerGap().addComponent(btn_Back) .addGap(18, 18, 18).addComponent(btn_Back2) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 368, Short.MAX_VALUE) .addComponent(pnl_FooterGroup1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap())); pnl_FooterLayout.setVerticalGroup(pnl_FooterLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(pnl_FooterLayout.createSequentialGroup().addContainerGap().addGroup(pnl_FooterLayout .createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(GroupLayout.Alignment.TRAILING, pnl_FooterLayout.createSequentialGroup() .addGroup(pnl_FooterLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(btn_Back).addComponent(btn_Back2)) .addGap(71, 71, 71)) .addGroup(GroupLayout.Alignment.TRAILING, pnl_FooterLayout.createSequentialGroup() .addComponent(pnl_FooterGroup1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addGap(55, 55, 55))))); // </editor-fold> // <editor-fold defaultstate="expanded" desc="LAYOUT"> // GroupLayout layout = new GroupLayout(this); // this.setLayout(layout); // layout.setHorizontalGroup( // layout.createParallelGroup(GroupLayout.Alignment.LEADING) // .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() // .addContainerGap() // .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) // .addComponent(pnl_Tracker, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) // .addComponent(pnl_ChartNavigator, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) // .addComponent(pnl_Footer, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) // .addContainerGap()) // ); // layout.setVerticalGroup( // layout.createParallelGroup(GroupLayout.Alignment.LEADING) // .addGroup(layout.createSequentialGroup() // .addComponent(pnl_ChartNavigator, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) // .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) // .addComponent(pnl_Tracker, GroupLayout.PREFERRED_SIZE, 86, GroupLayout.PREFERRED_SIZE) // .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) // .addComponent(pnl_Footer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) // .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) // ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(layout .createSequentialGroup().addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(pnl_SearchDB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(pnl_ChartNavigator, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pnl_Footer, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap())); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(pnl_ChartNavigator, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnl_SearchDB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(pnl_Footer, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE) .addContainerGap())); // </editor-fold> setCursor(CursorUtils.DEFAULT_CURSOR); } // <editor-fold defaultstate="expanded" desc="CHART GENERATOR"> private JFreeChart createChart(XYDataset dataset, ChromosomeKey chr) { JFreeChart chart = ChartFactory.createScatterPlot(null, "", "P value", dataset, PlotOrientation.VERTICAL, true, false, false); XYPlot plot = (XYPlot) chart.getPlot(); plot.setNoDataMessage("NO DATA"); plot.setDomainZeroBaselineVisible(true); plot.setRangeZeroBaselineVisible(true); // CHART BACKGROUD COLOR chart.setBackgroundPaint(Color.getHSBColor(0.1f, 0.1f, 1.0f)); // Hue, saturation, brightness plot.setBackgroundPaint(manhattan_back); // Hue, saturation, brightness 9 // GRIDLINES plot.setDomainGridlineStroke(new BasicStroke(0.0f)); plot.setDomainMinorGridlineStroke(new BasicStroke(0.0f)); plot.setDomainGridlinePaint(manhattan_back.darker().darker()); // Hue, saturation, brightness 7 plot.setDomainMinorGridlinePaint(manhattan_back); // Hue, saturation, brightness 9 plot.setRangeGridlineStroke(new BasicStroke(0.0f)); plot.setRangeMinorGridlineStroke(new BasicStroke(0.0f)); plot.setRangeGridlinePaint(manhattan_back.darker().darker()); // Hue, saturation, brightness 7 plot.setRangeMinorGridlinePaint(manhattan_back.darker()); // Hue, saturation, brightness 8 plot.setDomainMinorGridlinesVisible(true); plot.setRangeMinorGridlinesVisible(true); // DOTS RENDERER XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer(); renderer.setSeriesPaint(0, manhattan_dot); // renderer.setSeriesOutlinePaint(0, Color.DARK_GRAY); // renderer.setUseOutlinePaint(true); // Set dot shape of the currently appended Series renderer.setSeriesShape(0, new Rectangle2D.Double(0.0, 0.0, 2, 2)); renderer.setSeriesVisibleInLegend(0, false); NumberAxis positionAxis = (NumberAxis) plot.getDomainAxis(); // domainAxis.setAutoRangeIncludesZero(false); // domainAxis.setTickMarkInsideLength(2.0f); // domainAxis.setTickMarkOutsideLength(2.0f); // domainAxis.setMinorTickCount(2); // domainAxis.setMinorTickMarksVisible(true); positionAxis.setLabelAngle(1.0); positionAxis.setAutoRangeIncludesZero(false); positionAxis.setAxisLineVisible(true); positionAxis.setTickLabelsVisible(true); positionAxis.setTickMarksVisible(true); // ADD INVERSE LOG(10) Y AXIS LogAxis logPAxis = new LogAxis("P value"); logPAxis.setBase(10); logPAxis.setInverted(true); logPAxis.setNumberFormatOverride(GenericReportGenerator.FORMAT_P_VALUE); logPAxis.setTickMarkOutsideLength(2.0f); logPAxis.setMinorTickCount(2); logPAxis.setMinorTickMarksVisible(true); logPAxis.setAxisLineVisible(true); logPAxis.setUpperMargin(0); TickUnitSource units = NumberAxis.createIntegerTickUnits(); logPAxis.setStandardTickUnits(units); plot.setRangeAxis(0, logPAxis); // Add significance Threshold to subplot //threshold = 0.5/rdMatrixMetadata.getMarkerSetSize(); // (0.05/10? SNPs => 5*10-?) final Marker thresholdLine = new ValueMarker(threshold); thresholdLine.setPaint(Color.red); // Add legend to threshold thresholdLine.setLabel("P = " + GenericReportGenerator.FORMAT_P_VALUE.format(threshold)); thresholdLine.setLabelAnchor(RectangleAnchor.TOP_RIGHT); thresholdLine.setLabelTextAnchor(TextAnchor.BOTTOM_RIGHT); plot.addRangeMarker(thresholdLine); // Marker label if below threshold XYItemRenderer lblRenderer = plot.getRenderer(); // THRESHOLD AND SELECTED LABEL GENERATOR MySeriesItemLabelGenerator lblGenerator = new MySeriesItemLabelGenerator(threshold, chr); lblRenderer.setSeriesItemLabelGenerator(0, lblGenerator); lblRenderer.setSeriesItemLabelFont(0, new Font("SansSerif", Font.PLAIN, 12)); lblRenderer.setSeriesPositiveItemLabelPosition(0, new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.TOP_LEFT, TextAnchor.BOTTOM_LEFT, Math.PI / 4.0)); // TOOLTIP GENERATOR MyXYToolTipGenerator tooltipGenerator = new MyXYToolTipGenerator(chr); lblRenderer.setBaseToolTipGenerator(tooltipGenerator); lblRenderer.setSeriesItemLabelsVisible(0, true); return chart; } public Map<String, MarkerKey> getLabelerMap() { return labeler; } public void setLabelerMap(Map<String, MarkerKey> labelerMap) { this.labeler = labelerMap; } public long getCenterPhysPos() { return centerPhysPos; } public void setCenterPhysPos(long centerPhysPos) { this.centerPhysPos = centerPhysPos; } private class MyXYToolTipGenerator extends StandardXYToolTipGenerator implements XYToolTipGenerator { private final ChromosomeKey chr; MyXYToolTipGenerator(ChromosomeKey chr) { this.chr = chr; } @Override public String generateToolTip(XYDataset dataset, int series, int item) { StringBuilder toolTip = new StringBuilder(128); toolTip.append("<html>"); double position = dataset.getXValue(series, item); double pValue = dataset.getYValue(series, item); String chrPos = chr.getChromosome() + "_" + Report_Analysis.FORMAT_INTEGER.format(position); if (getLabelerMap().containsKey(chrPos)) { toolTip.append(getLabelerMap().get(chrPos)).append("<br>"); } toolTip.append("pVal: ").append(Report_Analysis.FORMAT_SCIENTIFIC.format(pValue)).append("<br>pos: ") .append(Report_Analysis.FORMAT_INTEGER.format(position)).append("</html>"); return toolTip.toString(); } @Override public boolean equals(Object other) { if (other == null) { return false; } if (!(other instanceof MyXYToolTipGenerator)) { return false; } final MyXYToolTipGenerator otherC = (MyXYToolTipGenerator) other; if (chr == null && otherC.chr == null) { return true; } else if (chr != null && chr.equals(otherC.chr)) { return true; } return false; } @Override public int hashCode() { int hash = 7; hash = 43 * hash + (this.chr != null ? this.chr.hashCode() : 0); return hash; } } private class MySeriesItemLabelGenerator extends AbstractXYItemLabelGenerator implements XYItemLabelGenerator { private final double threshold; private final ChromosomeKey chr; /** * Creates a new generator that only displays labels that are greater * than or equal to the threshold value. * * @param threshold the threshold value. */ MySeriesItemLabelGenerator(double threshold, ChromosomeKey chr) { this.threshold = threshold; this.chr = chr; } /** * Generates a label for the specified item. The label is typically a * formatted version of the data value, but any text can be used. * * @param dataset the dataset (<code>null</code> not permitted). * @param series the series index (zero-based). * @param category the category index (zero-based). * * @return the label (possibly <code>null</code>). */ @Override public String generateLabel(XYDataset dataset, int series, int item) { String rsLabel = null; Number pValue = dataset.getYValue(series, item); int position = (int) dataset.getXValue(series, item); if (pValue != null) { // TODO unnessesary test for null final double pValueDouble = pValue.doubleValue(); StringBuilder chrPos = new StringBuilder(chr.getChromosome()); chrPos.append('_').append(position); if (pValueDouble < this.threshold) { rsLabel = getLabelerMap().get(chrPos.toString()).toString(); //result = value.toString().substring(0, 4); // could apply formatting here } if (getLabelerMap().get(chrPos.toString()).equals(origMarkerKey)) { rsLabel = getLabelerMap().get(chrPos.toString()).toString(); rsLabel = " " + rsLabel; } } return rsLabel; } } // </editor-fold> //<editor-fold defaultstate="expanded" desc="HELPERS"> private class ResetAction extends AbstractAction { private final OperationKey operationKey; ResetAction(OperationKey operationKey) { this.operationKey = operationKey; putValue(NAME, Text.All.reset); } @Override public void actionPerformed(ActionEvent evt) { GWASpiExplorerPanel.getSingleton() .setPnlContent(new ManhattanPlotZoom(parent, operationKey, origChr, startPhysPos, // startPhysPos requestedPosWindow, // physPos window nRows)); GWASpiExplorerPanel.getSingleton().getScrlContent() .setViewportView(GWASpiExplorerPanel.getSingleton().getPnlContent()); } } private class BackToTableAction extends AbstractAction { BackToTableAction() { putValue(NAME, Text.Reports.backToTable); } @Override public void actionPerformed(ActionEvent evt) { try { GWASpiExplorerPanel.getSingleton() .setPnlContent(new Report_AnalysisPanel(testOpKey.getParentMatrixKey(), testOpKey, nRows)); GWASpiExplorerPanel.getSingleton().getScrlContent() .setViewportView(GWASpiExplorerPanel.getSingleton().getPnlContent()); } catch (IOException ex) { log.error(null, ex); } } } private class BackToManhattanPlotAction extends AbstractAction { BackToManhattanPlotAction() { putValue(NAME, Text.Reports.backToManhattanPlot); } @Override public void actionPerformed(ActionEvent evt) { try { parent.setFired(false); List<Report> manhattenPlotReports = ReportsList.getReportService() .getReports(new DataSetKey(testOpKey), OPType.MANHATTANPLOT); String reportFile = ""; if (!manhattenPlotReports.isEmpty()) { reportFile = manhattenPlotReports.get(0).getFileName(); } GWASpiExplorerPanel.getSingleton().setPnlContent(new ManhattanChartDisplay(reportFile, testOpKey)); GWASpiExplorerPanel.getSingleton().getScrlContent() .setViewportView(GWASpiExplorerPanel.getSingleton().getPnlContent()); } catch (IOException ex) { log.error(null, ex); } } } //</editor-fold> }