/* * Copyright 2006-2018 The MZmine 2 Development Team * * This file is part of MZmine 2. * * MZmine 2 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 2 of the * License, or (at your option) any later version. * * MZmine 2 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 MZmine 2; if not, * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ package net.sf.mzmine.modules.visualization.neutralloss; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Cursor; import java.awt.Font; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.text.NumberFormat; import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.filechooser.FileNameExtensionFilter; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.event.ChartProgressEvent; import org.jfree.chart.plot.SeriesRenderingOrder; import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.title.TextTitle; import com.google.common.collect.Range; import net.sf.mzmine.chartbasics.gui.swing.EChartPanel; import net.sf.mzmine.chartbasics.listener.ZoomHistory; import net.sf.mzmine.main.MZmineCore; import net.sf.mzmine.util.GUIUtils; import net.sf.mzmine.util.SaveImage; import net.sf.mzmine.util.SaveImage.FileType; class NeutralLossPlot extends EChartPanel { private static final long serialVersionUID = 1L; private JFreeChart chart; private XYPlot plot; private NeutralLossDataPointRenderer defaultRenderer; private boolean showSpectrumRequest = false; private NeutralLossVisualizerWindow visualizer; // crosshair (selection) color private static final Color crossHairColor = Color.gray; // crosshair stroke private static final BasicStroke crossHairStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1.0f, new float[] {5, 3}, 0); // title font private static final Font titleFont = new Font("SansSerif", Font.PLAIN, 11); // Item's shape, small circle private static final Shape dataPointsShape = new Ellipse2D.Double(-1, -1, 2, 2); private static final Shape dataPointsShape2 = new Ellipse2D.Double(-1, -1, 3, 3); // Series colors private static final Color pointColor = Color.blue; private static final Color searchPrecursorColor = Color.green; private static final Color searchNeutralLossColor = Color.orange; private TextTitle chartTitle; private Range<Double> highlightedPrecursorRange = Range.singleton(Double.NEGATIVE_INFINITY); private Range<Double> highlightedNeutralLossRange = Range.singleton(Double.NEGATIVE_INFINITY); NeutralLossPlot(NeutralLossVisualizerWindow visualizer, NeutralLossDataSet dataset, Object xAxisType) { super(null, true); this.visualizer = visualizer; setBackground(Color.white); setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); NumberFormat rtFormat = MZmineCore.getConfiguration().getRTFormat(); NumberFormat mzFormat = MZmineCore.getConfiguration().getMZFormat(); // set the X axis (retention time) properties NumberAxis xAxis; if (xAxisType.equals(NeutralLossParameters.xAxisPrecursor)) { xAxis = new NumberAxis("Precursor m/z"); xAxis.setNumberFormatOverride(mzFormat); } else { xAxis = new NumberAxis("Retention time"); xAxis.setNumberFormatOverride(rtFormat); } xAxis.setUpperMargin(0); xAxis.setLowerMargin(0); xAxis.setAutoRangeIncludesZero(false); // set the Y axis (intensity) properties NumberAxis yAxis = new NumberAxis("Neutral loss (Da)"); yAxis.setAutoRangeIncludesZero(false); yAxis.setNumberFormatOverride(mzFormat); yAxis.setUpperMargin(0); yAxis.setLowerMargin(0); // set the renderer properties defaultRenderer = new NeutralLossDataPointRenderer(false, true); defaultRenderer.setTransparency(0.4f); setSeriesColorRenderer(0, pointColor, dataPointsShape); setSeriesColorRenderer(1, searchPrecursorColor, dataPointsShape2); setSeriesColorRenderer(2, searchNeutralLossColor, dataPointsShape2); // tooltips defaultRenderer.setDefaultToolTipGenerator(dataset); // set the plot properties plot = new XYPlot(dataset, xAxis, yAxis, defaultRenderer); plot.setBackgroundPaint(Color.white); plot.setRenderer(defaultRenderer); plot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD); // chart properties chart = new JFreeChart("", titleFont, plot, false); chart.setBackgroundPaint(Color.white); setChart(chart); // title chartTitle = chart.getTitle(); chartTitle.setMargin(5, 0, 0, 0); chartTitle.setFont(titleFont); // disable maximum size (we don't want scaling) setMaximumDrawWidth(Integer.MAX_VALUE); setMaximumDrawHeight(Integer.MAX_VALUE); // set crosshair (selection) properties plot.setDomainCrosshairVisible(true); plot.setRangeCrosshairVisible(true); plot.setDomainCrosshairPaint(crossHairColor); plot.setRangeCrosshairPaint(crossHairColor); plot.setDomainCrosshairStroke(crossHairStroke); plot.setRangeCrosshairStroke(crossHairStroke); plot.addRangeMarker(new ValueMarker(0)); // set focusable state to receive key events setFocusable(true); // register key handlers GUIUtils.registerKeyHandler(this, KeyStroke.getKeyStroke("SPACE"), visualizer, "SHOW_SPECTRUM"); // add items to popup menu JPopupMenu popupMenu = getPopupMenu(); popupMenu.addSeparator(); // Add EMF and EPS options to the save as menu JMenuItem saveAsMenu = (JMenuItem) popupMenu.getComponent(3); GUIUtils.addMenuItem(saveAsMenu, "EMF...", this, "SAVE_EMF"); GUIUtils.addMenuItem(saveAsMenu, "EPS...", this, "SAVE_EPS"); JMenuItem highLightPrecursorRange = new JMenuItem("Highlight precursor m/z range..."); highLightPrecursorRange.addActionListener(visualizer); highLightPrecursorRange.setActionCommand("HIGHLIGHT_PRECURSOR"); popupMenu.add(highLightPrecursorRange); JMenuItem highLightNeutralLossRange = new JMenuItem("Highlight neutral loss m/z range..."); highLightNeutralLossRange.addActionListener(visualizer); highLightNeutralLossRange.setActionCommand("HIGHLIGHT_NEUTRALLOSS"); popupMenu.add(highLightNeutralLossRange); // reset zoom history ZoomHistory history = getZoomHistory(); if (history != null) history.clear(); } @Override public void actionPerformed(final ActionEvent event) { super.actionPerformed(event); final String command = event.getActionCommand(); if ("SAVE_EMF".equals(command)) { JFileChooser chooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("EMF Image", "EMF"); chooser.setFileFilter(filter); int returnVal = chooser.showSaveDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { String file = chooser.getSelectedFile().getPath(); if (!file.toLowerCase().endsWith(".emf")) file += ".emf"; int width = (int) this.getSize().getWidth(); int height = (int) this.getSize().getHeight(); // Save image SaveImage SI = new SaveImage(getChart(), file, width, height, FileType.EMF); new Thread(SI).start(); } } if ("SAVE_EPS".equals(command)) { JFileChooser chooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("EPS Image", "EPS"); chooser.setFileFilter(filter); int returnVal = chooser.showSaveDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { String file = chooser.getSelectedFile().getPath(); if (!file.toLowerCase().endsWith(".eps")) file += ".eps"; int width = (int) this.getSize().getWidth(); int height = (int) this.getSize().getHeight(); // Save image SaveImage SI = new SaveImage(getChart(), file, width, height, FileType.EPS); new Thread(SI).start(); } } } private void setSeriesColorRenderer(int series, Color color, Shape shape) { defaultRenderer.setSeriesPaint(series, color); defaultRenderer.setSeriesFillPaint(series, color); defaultRenderer.setSeriesShape(series, shape); } void setTitle(String title) { chartTitle.setText(title); } /** * @return Returns the highlightedPrecursorRange. */ Range<Double> getHighlightedPrecursorRange() { return highlightedPrecursorRange; } /** * @param range The highlightedPrecursorRange to set. */ void setHighlightedPrecursorRange(Range<Double> range) { this.highlightedPrecursorRange = range; } /** * @return Returns the highlightedNeutralLossRange. */ Range<Double> getHighlightedNeutralLossRange() { return highlightedNeutralLossRange; } /** * @param range The highlightedNeutralLossRange to set. */ void setHighlightedNeutralLossRange(Range<Double> range) { this.highlightedNeutralLossRange = range; } /** * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) */ public void mouseClicked(MouseEvent event) { // let the parent handle the event (selection etc.) super.mouseClicked(event); // request focus to receive key events requestFocus(); // if user double-clicked left button, place a request to open a // spectrum if ((event.getButton() == MouseEvent.BUTTON1) && (event.getClickCount() == 2)) { showSpectrumRequest = true; } } /** * @see org.jfree.chart.event.ChartProgressListener#chartProgress(org.jfree.chart.event.ChartProgressEvent) */ public void chartProgress(ChartProgressEvent event) { super.chartProgress(event); if (event.getType() == ChartProgressEvent.DRAWING_FINISHED) { visualizer.updateTitle(); if (showSpectrumRequest) { showSpectrumRequest = false; visualizer.actionPerformed( new ActionEvent(event.getSource(), ActionEvent.ACTION_PERFORMED, "SHOW_SPECTRUM")); } } } XYPlot getXYPlot() { return plot; } }