package evoker; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.ButtonGroup; import javax.swing.JFileChooser; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.XYPlot; import org.jfree.data.xy.XYDataItem; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.ExtensionFileFilter; import evoker.Genoplot.MouseMode; public class EvokerChartPanel extends ChartPanel { /** Holding the last Point, the mouse was dragged to (for drawing a line while selecting) */ Point lastDragPoint = null; /** Will hold the lasso Object, while the selection is being made*/ Lasso lasso = null; /** Enable mouse listeners to perform zoom*/ public static final String ZOOM_ENABLE_COMMAND = "ZOOM_ENABLE"; /** Enable mouse listeners to perform lasso select*/ public static final String LASSO_SELECT_ENABLE_COMMAND = "LASSO_SELECT_ENABLE"; /*The genotype selection menu*/ private JPopupMenu genotypeSelectPopup; /** The genotype data being displayed */ private PlotData plotData = null; /** The panel calling the ChartPanel*/ private PlotPanel plotPanel = null; private boolean weAreLassoing = false; private JRadioButtonMenuItem jrbZoom; private JRadioButtonMenuItem jrbLasso; EvokerChartPanel(JFreeChart jfc, PlotData pdata, PlotPanel ppanel) { super(jfc); // set up genotype select menu (... :] ) this.genotypeSelectPopup = createGenotypeSelectPopup(); this.plotData = pdata; this.plotPanel = ppanel; createPopupMenu_(); } private double rescaleMouseClickX(Point p){ Rectangle2D plotArea = this.getScreenDataArea(); XYPlot plot = (XYPlot) super.getChart().getPlot(); double x = plot.getDomainAxis().java2DToValue(p.getX(), plotArea, plot.getDomainAxisEdge()); return(x); } private double rescaleMouseClickY(Point p){ Rectangle2D plotArea = this.getScreenDataArea(); XYPlot plot = (XYPlot) super.getChart().getPlot(); double y = plot.getRangeAxis().java2DToValue(p.getY(), plotArea, plot.getRangeAxisEdge()); return(y); } /** * Handles a 'mouse pressed' event. * <P> * This event is the popup trigger on Unix/Linux. For Windows, the popup * trigger is the 'mouse released' event. * * @param e The mouse event. */ public void mousePressed(MouseEvent e) { if(!e.isPopupTrigger()) { if (plotPanel.theGenoplot.getMouseMode() == MouseMode.LASSO) { lastDragPoint = e.getPoint(); lasso = new Lasso(rescaleMouseClickX(lastDragPoint),rescaleMouseClickY(lastDragPoint)); weAreLassoing = true; } else { super.mousePressed(e); } }else{ if (popup != null) { if (plotPanel.theGenoplot.getMouseMode() == MouseMode.ZOOM) jrbZoom.setSelected(true); if (plotPanel.theGenoplot.getMouseMode() == MouseMode.LASSO) jrbLasso.setSelected(true); displayPopupMenu(e.getX(), e.getY()); } } } /** * Handles a 'mouse dragged' event. * * @param e the mouse event. */ public void mouseDragged(MouseEvent e) { if(weAreLassoing) { // draw line from last Point to the current one if (lastDragPoint != null) { Graphics2D g2 = (Graphics2D) getGraphics(); g2.draw(new Line2D.Double(lastDragPoint.getX(), lastDragPoint.getY(), e.getX(), e.getY())); } lastDragPoint = new Point(e.getX(), e.getY()); lasso.addPoint(rescaleMouseClickX(lastDragPoint),rescaleMouseClickY(lastDragPoint)); }else { super.mouseDragged(e); } } /** * Handles a 'mouse released' event. On Windows, we need to check if this * is a popup trigger, but only if we haven't already been tracking a zoom * rectangle. * * @param e information about the event. */ public void mouseReleased(MouseEvent e) { if (weAreLassoing) { lastDragPoint = new Point(e.getX(), e.getY()); lasso.addPoint(rescaleMouseClickX(lastDragPoint),rescaleMouseClickY(lastDragPoint)); lastDragPoint = null; if (lasso != null) { lasso.close(); weAreLassoing = false; this.genotypeSelectPopup.show(this, e.getX(), e.getY()); } } else { super.mouseReleased(e); } } /** * Creates a popup menu for the panel. * * @param properties include a menu item for the chart property editor. * @param copy include a menu item for copying to the clipboard. * @param save include a menu item for saving the chart. * @param print include a menu item for printing the chart. * @param zoom include menu items for zooming. * * @return The popup menu. * * @since 1.0.13 */ protected void createPopupMenu_() { ButtonGroup group = new ButtonGroup(); jrbZoom = new JRadioButtonMenuItem("Zoom"); if (plotPanel.theGenoplot.getMouseMode() == MouseMode.ZOOM) jrbZoom.setSelected(true); jrbZoom.setMnemonic(KeyEvent.VK_O); jrbZoom.setActionCommand(ZOOM_ENABLE_COMMAND); jrbZoom.addActionListener(this); group.add(jrbZoom); popup.add(jrbZoom, 0); jrbLasso = new JRadioButtonMenuItem("Lasso Select"); if (plotPanel.theGenoplot.getMouseMode() == MouseMode.LASSO) jrbLasso.setSelected(true); jrbLasso.setMnemonic(KeyEvent.VK_R); jrbLasso.setActionCommand(LASSO_SELECT_ENABLE_COMMAND); jrbLasso.addActionListener(this); group.add(jrbLasso); popup.add(jrbLasso, 1); } protected JPopupMenu createGenotypeSelectPopup() { JPopupMenu result = new JPopupMenu("Chart:"); ButtonGroup group = new ButtonGroup(); JRadioButtonMenuItem jrbMenIt = new JRadioButtonMenuItem("Y Homozygous"); jrbMenIt.setSelected(true); jrbMenIt.setMnemonic(KeyEvent.VK_O); jrbMenIt.setActionCommand("GENOTYPE_YY"); jrbMenIt.addActionListener(this); group.add(jrbMenIt); result.add(jrbMenIt); jrbMenIt = new JRadioButtonMenuItem("Heterozygous"); jrbMenIt.setMnemonic(KeyEvent.VK_R); jrbMenIt.setActionCommand("GENOTYPE_XY"); jrbMenIt.addActionListener(this); group.add(jrbMenIt); result.add(jrbMenIt); jrbMenIt = new JRadioButtonMenuItem("X Homozygous"); jrbMenIt.setMnemonic(KeyEvent.VK_R); jrbMenIt.setActionCommand("GENOTYPE_XX"); jrbMenIt.addActionListener(this); group.add(jrbMenIt); result.add(jrbMenIt); jrbMenIt = new JRadioButtonMenuItem("Unknown"); jrbMenIt.setMnemonic(KeyEvent.VK_R); jrbMenIt.setActionCommand("GENOTYPE_UNKNOWN"); jrbMenIt.addActionListener(this); group.add(jrbMenIt); result.add(jrbMenIt); return result; } /** * Handles action events generated by the popup menu. * * @param event the event. */ public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals("GENOTYPE_XX")) { adjustDataSeries(0); } else if (command.equals("GENOTYPE_UNKNOWN")) { adjustDataSeries(1); } else if (command.equals("GENOTYPE_XY")) { adjustDataSeries(2); } else if (command.equals("GENOTYPE_YY")) { adjustDataSeries(3); } else if (command.equals(ZOOM_ENABLE_COMMAND)) { plotPanel.theGenoplot.setMouseMode(MouseMode.ZOOM); } else if (command.equals(LASSO_SELECT_ENABLE_COMMAND)) { plotPanel.theGenoplot.setMouseMode(MouseMode.LASSO); } else { super.actionPerformed(event); } } public double round3(double n) { double result = n * 100000; result = Math.round(result); result = result / 100000; return result; } void adjustDataSeries(int genotype) { //ArrayList<EvokerPoint2D> containedPoints = lasso.getContainedPoints(super.info.getEntityCollection()); HashMap<EvokerPoint2D, String> containedPointsInd = lasso.getContainedPointsInd(super.info.getEntityCollection()); ArrayList<String> al_s = new ArrayList<String>(); XYPlot plot = (XYPlot) super.getChart().getPlot(); XYSeriesCollection xyseriescoll = (XYSeriesCollection) plot.getDataset(); ArrayList<XYDataItem> l_di = new ArrayList<XYDataItem>(); int seriesCount = xyseriescoll.getSeriesCount(); for (int a = 0; a < seriesCount; a++) { XYSeries series = xyseriescoll.getSeries(a); List<XYDataItem> items = (List<XYDataItem>) series.getItems(); int itemsLength = items.size(); for (int b = 0; b < itemsLength; b++) { XYDataItem xydi = items.get(b); Point2D p = new Point2D.Double(round3(Double.parseDouble(xydi.getX() + "")), round3(Double.parseDouble(xydi.getY() + ""))); for (EvokerPoint2D p_ : containedPointsInd.keySet()) { if (p.getX() == p_.getX() && p.getY() == p_.getY()) { if (al_s.contains(containedPointsInd.get(p_))) continue; plotData.moveIndToClass(containedPointsInd.get(p_), a, b, genotype); al_s.add(containedPointsInd.get(p_)); l_di.add(xydi); items.remove(b); b--; itemsLength--; break; } } } } XYSeries series = xyseriescoll.getSeries(genotype); List<XYDataItem> items = (List<XYDataItem>) series.getItems(); for (XYDataItem xydi : l_di) { items.add(xydi); } lasso = null; this.chart.setNotify(true); // last thing, redraw. Applies changes and gets rid of the line. this.plotData.computeSummary(); this.plotPanel.updateInfo(); this.plotData.changed = true; } private void save() throws IOException { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory(super.defaultDirectoryForSaveAs); ExtensionFileFilter filter = new ExtensionFileFilter("BED Binary Files", ".bed"); fileChooser.addChoosableFileFilter(filter); int option = fileChooser.showSaveDialog(this); if (option == JFileChooser.APPROVE_OPTION) { String filename = fileChooser.getSelectedFile().getPath(); if (isEnforceFileExtensions()) { if (!filename.endsWith(".bed")) { filename = filename + ".bed"; } } try { BEDFileWriter bfw = new BEDFileWriter(new File(filename)); } catch (IOException ex) { throw new IOException("Could not write file."); } } } }